From f15f457476df3b4d3808977c2207b8dcd3c49498 Mon Sep 17 00:00:00 2001 From: Arnaud AMBROSELLI Date: Thu, 14 Dec 2023 17:43:23 +0100 Subject: [PATCH] fix: remove truplication --- .../templates/dashboard.sealed-secret.yaml | 5 - .kontinuous/env/prod/values.yaml | 15 - api/src/controllers/migration.js | 149 ------ dashboard/Dockerfile | 20 - dashboard/src/components/DataMigrator.js | 471 ------------------ 5 files changed, 660 deletions(-) diff --git a/.kontinuous/env/prod/templates/dashboard.sealed-secret.yaml b/.kontinuous/env/prod/templates/dashboard.sealed-secret.yaml index d0cc53f19..ebc4cbd93 100644 --- a/.kontinuous/env/prod/templates/dashboard.sealed-secret.yaml +++ b/.kontinuous/env/prod/templates/dashboard.sealed-secret.yaml @@ -8,11 +8,6 @@ metadata: spec: encryptedData: SENTRY_AUTH_TOKEN: AgCYmBko6+0bjL94Ok4xU0pQHeE8Ft45OzMHLlxOrK5bSXlwOK67SjFBlWLVcbnv8Hy8N+aUNRxMHD7dhD5yAyEDRWLTJUt6JojLP8f4OkX1hkt4nDI0pubzD5GRQTjLGnfS0mLHB5iIjbWc8gi2fnVx5TblhhmbbcPh8CEH12thKqFnI7TONLs3PVaieT2WTpWE8ZaxokngcERns/cEHJEuf6+744ee0QDgFNeaDxDWsrfcAUCHHo974QaYNhBI2qUxYXPnsiXyynS35f0HDJ3rVwtoQIwQYiM9YzD3BUMxK0evzGl6lciFEsq/69OK0PxFwClBndCyBVcThaKG4ikqgtQUZ1lW8QTdP8jN7k6sU/3sv9g+QkBqEc30YzVqbGjxpt1x5xIIjUu2Ub/NQ1T0KnC98I50DlN/48BWkoepDaWBGZEJ+5hPXwMQ9sF93jvBpF8dti/9Wv1dpcWxKqTNiPqosZ8A+Dt0nP/AVwxji7uLkXX7Df3KDZ0eLamEWO+Lth1a1D2IuYeYQoXk/H/XHvQxBEXKbOmx/g0KiuOMyl1c2pBT/R3A9GNasrV2dI3efcjsaopbtafsbDu5XvSsZt/1A3y4rGW6pEMYh4acr4WrF1X0EXT80n+jLSSCg0M7heMrbrChb4d680V5tPkMfvzNk6D8kVnK/QLmRp/FOjkF300/xR6+41TvbD3cg1z9ONY3N0rRoGp3nP5o1RPXYUQdBvGikOVA6dmUtY7X9SlB0J2MQTEctoabeW630D1vziZ6nV8/ozZn/eH017uu - REACT_APP_ORG_DUPLICATED_1_ID: AgBOGiMTOK1bgee3slAAO+93PTRUITKvITrn1zwIUwR5LvaEN2VG2EsNKxmb6NeghVQUOyeCRTWWT90qtN81iNVh0geryYN5OyLaxvSVKMfArLWM85lbjRVE3Quoqvwrj9uIG8zdwfXiJH6MR2XwG3q4Ycmx8T760VWAORwGcPFAEnfqYajvzaZ6po+tXRoTPy/GFt0KoMKS/GAU1NQqlWtfluZLDw7zc4V63siADqQk450KS9HFsakiAb1vF83nYVGps35o6p4I/M4YQ+nssOi3eyljvcSOJ5xV0gmx/wGSCWer0eXh8lsW2OY82HnXlSqn4C1cbbEyWA0SFW65wnZ9Ta5FqkbTNVZ6UDimFSIwu912dBmLclnpT7LYBXajq2rTpPLxOVMgf6iLlrERhVTSzBPnjBCmrkVpwemY2+bvBl2wf6y+4iR9CRrSvGCXqUSux602ogpnMBFYXY61bBSBxjwuO3m7atKoAsUFOoqsanJHUf5WvheFu00+P5cm2tmJv0QuThzXrLj9hhLJs3D9JWqNHcJ4ItAtYWcixrM6l+bliBD//n2EFZtxc36wXfbABU1lX2s/aRtjQN4U31VXDcCmrI6OJthcJaUgnbtTO+fIqa5LzTO0DhpvgiFtk2ToPI7+VvWwMEFMxf5a3A29VWURuVJHlWs0nT7dG2KpJrnMgemJtvKrEkh7Q/li7AADX0vsHm4ObMFtZL0rBIMbh80OOc8+0vldC23LvBC6tiT+eFg= - REACT_APP_ORG_DUPLICATED_1_NAME: AgCIKtphBqowL7Q5y9dVmcUu3zwocSHMUxSKC8NDIYc/2AWzF/LhIdbAO3Mn4o/rvtdyCNFhJYUOgAzH1yCkBsi3bJrS3ziYTkJXIPLlhRUcjfM9/gorehCvtVe2SnfV4SuMQ9FfVMCWbTazyy8pUkvqnr8/46lt16o3ss+jJcS32ijwgB3OLhT2iK9dfxTAAmQBymWkv1Y81h0lbUGwLqjA45F9p73kcblhEDjsFtxHpKvzGSjGMeXDjHV0yinC/5BP9+FoztKtW7In7U+/fkd4Lw72Vi8yH2ExilYNKi7cafGsUgc77L7I1dZe61s+K/yP44w3AlpdJtKjBIDyIqY529PGDTJs9qaBJrwxSbwiO/YVAbkVygty3fK5Ub3tCryUuB4SsT6zhgv9Vjf2SUP6TUksp4BWW/8e6e9/OBzJ7bQJv5LXlfAWH0sseu2SeAMc7tj7VgwPPD8FZ2qVl5hsqh9Zp6A/iKWmv+Bug2hFwBJxkzR6370OkBYCcNtjyHG98N/uQUyIwJzXhCVf3N2p+uNUw8pD5tGMun7TmGBq58jfkLd/bwDc2/+dXPP66IZVX04UQKy6WzbSGJMq5vWnFZxf5/CEdkm5QxZVr8kSb8tsBDxkxdQmxSPCA5YWnZcY/EEuy39XXlPIG97nUbZ9wHBeqyO+kalIJyngcfgUUo9R6yh/dY1qCpCnQLDJRm/vXhx4 - REACT_APP_ORG_DUPLICATED_2_ID: AgCuLVqDVv2SS9ChK7HyRasl2RAqOdr6vPqTP+74dAspfqJMCIL1Hi88tt4+dpR0LybE6Zi4rrTBpK2z82ifUgOkJ+IceBQjVDKq0hcufZETGLFef1xyEeZeRQwdyO9CrLtc2p6Za5iBCK01ppQn3iqstmU7ZNp2SrQC26pwaCFtiyeQu7wJEkS9a+ccE8iZ581kCF2qcViayShup+zqAwLvdn8QoKY4YurY+mIM4IKRgbLsNt7z3RR7sPfrDNqwUaZqH//5cwWIw3GDEbN2Ba93G3Ws+4sgVp4alJ0wX+LiPmZN/ZIF0LcQTmtFMtWI7dzp+Hx0nyIrDGUr32TLZrdXLAcE+xgoamBQSe/LfFADaDSOcnzqIOQZjiLXZsymLzQOyHWLwF5apnOxdm0AhivqedJPwAmBNXPuyTh1aVBCpvJjjnOyeZeK/2M05PQNviaaAcINF5Q4q0YWC82Dsd/9hddaoVh4aRM/lTd/kkeHs/yZ8Y0s+qSTgUG6VlCjgH45UexUhXIwjZ699e6DlxFouO0OyFwXBoMaZTPFstAgsuzEWe7QkglMkQ8oiEQ5YCoKly2k2Fg60qDApG7+wifmxuOOGmqC0xF3I71i2kGhcJCINGiVOXv/t2Q3PfISs4h7Kndw+5B1+29lgqLsUlSHxDHonwRCWDGnqhv5NLe50ZPMWtYTe460hfCyLyVjlSCjRw8Rl7uJYzra61leUpfpTX4fWPGaTR9pn2QakKNh7JOlEfQ= - REACT_APP_ORG_DUPLICATED_2_NAME: AgAgti76THJqW+FbjBvyh2+QfRzL9V7apOaQR3M9Mzr+VwT5lY5HsX4E52BqLWEbfGhcDf4pCktBRZ941I2Phofo8HaiKPdZTKYSptxEh4SqBRcbRmd4Wa9o5X3G9z+Ay4E5GZ/gLLSwU8PM4BrCqz95suRnJv41Do6qOxwAJKTJXJoGXWHWyDkVH2CyrIWbGOvUiRGF5w2WteRvKY46oKahKJEBY7iy0nXqhwlt+FMmdfozLKnRKkzpsUXgwFevMIqnucLWNK7QeBiJPT0H5rX3NklpTO9SC5KKbXU97/dPO3irDRtFNv4buQo9NPN5N+QkcEl9gPFW5K5QkXl7zT8riaxvR0zLxZHRIHg3cf8l/dIPT+Xbmz+SBBbLQeIQbDNFRCOf66q0F4wV9seenxwaQnACaO8SO0+QDbxt0ghGym0mTeDutdUq1BWG2Abga8H7Wsx9NOgshJyEOCiiTjpmyRCQf/VLtq8YuE98KF9koZq/I5fEHWIoIRZUXvgkHI46YCXmFC5YQ6BE1tdLeYhlki42f3nh7h6zElH98WOg28d/Hd7VXOh40ryFDb1DdfIsgVL0s5ygEdYS3VoXDpMpCui2QJbYt3kAyZ8BW0GkPXqO48buo11oU5ur37C7VuO8LvgBGoKTMnh+nos7ByMnmikcnMQTHRzfGshBoNT8xuOIKEhXK7eraoT8cPpJqXecM6s= - REACT_APP_ORG_ID_FOR_TRUPLICATION: AgCSHhr8mAitXC8yn1hzg7fKd9aUMV8x6Vipew1e+HXl5mcAVMx4XW2MY3aKXnGT/fV9QnR901Rc/UYqrGJnxzGeQI5LV0i/HcYK7/6f3pbA24kxZH48hG1YqpDsEcoR57K4xvmNEVrQ1uueJ34jtjF2+TJzLJCKB3/d5F1ZaCtDHau1Ev4CAAdtzqDhSW4Y++n2DK9btvMO5HYmD6Upp5vTN2flTSD1vAZ4pwMZ6FStKcyzUsOCVCcQgvydIvndadOD0wO/b5Xs6vmSf3ZClcaMMfvgvjLMHMFInDa3qpwu7RQTfYriKaG1DW/V2ARh7AcyTVMn23vdIdu+qW0B6ZeGOzbRinjUuyR8OINjZIUNFasAeFyW3H3xdKm818IZyvZZE2WUhB9GwedTsA2TcUjNoKnTulniGhKNAq0m3IyHL/2cmi4jkQ/Rq2r/u7/f5XU0ahh2N7jhVTILfka1JeHa75u17P5mBA+19xKi8ivYR7rtfD50NTK+xSJhgLG4gPNgqoZtvjB6hSCXITfylZ2xaknBIerbVwV/9knk2FRrtaF3W3NOZI4fEsaj3kn3e1WcU9hjpwZqcHfaAviaLgCC3qQn5w7px6N23B7SIhbYi9FH94Hg3ggcVTgiidADjHY02+1kfpP6eQVP4yVYvMHak5PehzYwqTzBK4Le+zj0vm8TCL7Ji53GHqV5Ag6FlO6m0PR4Zl/Lv8kcIkMft8zgf3aZWCyKxe6ilZ/6kQ8bDIUewlY= template: metadata: annotations: diff --git a/.kontinuous/env/prod/values.yaml b/.kontinuous/env/prod/values.yaml index b89d788b6..b23cab2c2 100644 --- a/.kontinuous/env/prod/values.yaml +++ b/.kontinuous/env/prod/values.yaml @@ -70,18 +70,3 @@ jobs: sentry_auth_token: secretName: dashboard secretKey: SENTRY_AUTH_TOKEN - react_app_org_duplicated_1_id: - secretName: dashboard - secretKey: REACT_APP_ORG_DUPLICATED_1_ID - react_app_org_duplicated_1_name: - secretName: dashboard - secretKey: REACT_APP_ORG_DUPLICATED_1_NAME - react_app_org_duplicated_2_id: - secretName: dashboard - secretKey: REACT_APP_ORG_DUPLICATED_2_ID - react_app_org_duplicated_2_name: - secretName: dashboard - secretKey: REACT_APP_ORG_DUPLICATED_2_NAME - react_app_org_id_for_truplication: - secretName: dashboard - secretKey: REACT_APP_ORG_ID_FOR_TRUPLICATION diff --git a/api/src/controllers/migration.js b/api/src/controllers/migration.js index f5f528782..0c96ed26a 100644 --- a/api/src/controllers/migration.js +++ b/api/src/controllers/migration.js @@ -89,155 +89,6 @@ router.put( } // End of example of migration. */ - if (req.params.migrationName === "truplicate-organisations") { - try { - const encryptedItemFields = z.object({ - _id: z.string().regex(looseUuidRegex), - organisation: z.string().regex(looseUuidRegex), - createdAt: z.string().regex(isoDateRegex), - updatedAt: z.string().regex(isoDateRegex), - deletedAt: z.string().regex(isoDateRegex).nullable().optional(), - encrypted: z.string(), - encryptedEntityKey: z.string(), - }); - - const nextOrganisation = z.object({ - organisationId: z.string().regex(looseUuidRegex), - teams: z.array( - z.object({ - _id: z.string().regex(looseUuidRegex), - name: z.string(), - nightSession: z.boolean(), - organisation: z.string().regex(looseUuidRegex), - }) - ), - users: z.array( - z.object({ - _id: z.string().regex(looseUuidRegex), - email: z.string().email(), - organisation: z.string().regex(looseUuidRegex), - role: z.enum(["admin", "normal", "restricted-access"]), - name: z.string().optional(), - phone: z.string().optional(), - healthcareProfessional: z.boolean().optional(), - }) - ), - relUserTeams: z.array( - z.object({ - _id: z.string().regex(looseUuidRegex), - user: z.string().regex(looseUuidRegex), - team: z.string().regex(looseUuidRegex), - }) - ), - persons: z.array(encryptedItemFields), - consultations: z.array(encryptedItemFields), - treatments: z.array(encryptedItemFields), - medicalFiles: z.array(encryptedItemFields), - actions: z.array(encryptedItemFields), - groups: z.array(encryptedItemFields), - comments: z.array(encryptedItemFields), - passages: z.array(encryptedItemFields), - rencontres: z.array(encryptedItemFields), - territories: z.array(encryptedItemFields), - observations: z.array(encryptedItemFields), - places: z.array(encryptedItemFields), - relsPersonPlace: z.array(encryptedItemFields), - reports: z.array(encryptedItemFields), - }); - - nextOrganisation.parse(req.body.organisation1); - nextOrganisation.parse(req.body.organisation2); - } catch (e) { - const error = new Error(`Invalid request in truplicate-organisations: ${e}`); - error.status = 400; - throw error; - } - const saveOrganisation = async (newOrganisation) => { - for (let item of newOrganisation.teams) { - await Team.create(item, { transaction: tx }); - } - - const password = crypto.randomBytes(60).toString("hex"); // A useless password., - const forgotPasswordResetExpires = new Date(Date.now() + 60 * 60 * 24 * 30 * 1000); // 30 days - for (let item of newOrganisation.users) { - item.email = item.email.toLocaleLowerCase(); - item.forgotPasswordResetToken = crypto.randomBytes(20).toString("hex"); - item.forgotPasswordResetExpires = forgotPasswordResetExpires; - item.password = password; - await User.create(item, { transaction: tx }); - } - - for (let item of newOrganisation.relUserTeams) { - await RelUserTeam.create(item, { transaction: tx }); - } - - for (let item of newOrganisation.persons) { - await Person.create(item, { transaction: tx }); - } - - for (let item of newOrganisation.groups) { - await Group.create(item, { transaction: tx }); - } - - for (let item of newOrganisation.actions) { - await Action.create(item, { transaction: tx }); - } - - for (let item of newOrganisation.consultations) { - await Consultation.create(item, { transaction: tx }); - } - - for (let item of newOrganisation.treatments) { - await Treatment.create(item, { transaction: tx }); - } - - for (let item of newOrganisation.medicalFiles) { - await MedicalFile.create(item, { transaction: tx }); - } - - for (let item of newOrganisation.comments) { - await Comment.create(item, { transaction: tx }); - } - - for (let item of newOrganisation.passages) { - await Passage.create(item, { transaction: tx }); - } - - for (let item of newOrganisation.rencontres) { - await Rencontre.create(item, { transaction: tx }); - } - - for (let item of newOrganisation.territories) { - await Territory.create(item, { transaction: tx }); - } - - for (let item of newOrganisation.observations) { - await TerritoryObservation.create(item, { transaction: tx }); - } - - for (let item of newOrganisation.places) { - await Place.create(item, { transaction: tx }); - } - - for (let item of newOrganisation.relsPersonPlace) { - await RelPersonPlace.create(item, { transaction: tx }); - } - - for (let item of newOrganisation.reports) { - await Report.create(item, { transaction: tx }); - } - }; - - const organisation1 = await Organisation.findOne({ where: { _id: req.body.organisation1.organisationId } }); - const organisation2 = await Organisation.findOne({ where: { _id: req.body.organisation2.organisationId } }); - if (!organisation1 || !organisation2) return res.status(404).send({ ok: false, error: "Not Found" }); - await saveOrganisation(req.body.organisation1); - await saveOrganisation(req.body.organisation2); - organisation.set({ - migrations: [...(organisation.migrations || []), req.params.migrationName], - migrationLastUpdateAt: new Date(), - }); - } organisation.set({ migrating: false }); await organisation.save({ transaction: tx }); diff --git a/dashboard/Dockerfile b/dashboard/Dockerfile index f2fd741f1..6ff789fde 100644 --- a/dashboard/Dockerfile +++ b/dashboard/Dockerfile @@ -17,26 +17,6 @@ COPY --chown=1000:1000 dashboard/. . ENV NODE_ENV=production RUN --mount=type=secret,id=sentry_auth_token,uid=1000 \ - --mount=type=secret,id=react_app_org_duplicated_1_id,uid=1000 \ - --mount=type=secret,id=react_app_org_duplicated_1_name,uid=1000 \ - --mount=type=secret,id=react_app_org_duplicated_2_id,uid=1000 \ - --mount=type=secret,id=react_app_org_duplicated_2_name,uid=1000 \ - --mount=type=secret,id=react_app_org_id_for_truplication,uid=1000 \ - if [ -f "/run/secrets/react_app_org_duplicated_1_id" ]; then \ - export REACT_APP_ORG_DUPLICATED_1_ID=$(cat /run/secrets/react_app_org_duplicated_1_id); \ - fi; \ - if [ -f "/run/secrets/react_app_org_duplicated_1_name" ]; then \ - export REACT_APP_ORG_DUPLICATED_1_NAME=$(cat /run/secrets/react_app_org_duplicated_1_name); \ - fi; \ - if [ -f "/run/secrets/react_app_org_duplicated_2_id" ]; then \ - export REACT_APP_ORG_DUPLICATED_2_ID=$(cat /run/secrets/react_app_org_duplicated_2_id); \ - fi; \ - if [ -f "/run/secrets/react_app_org_duplicated_2_name" ]; then \ - export REACT_APP_ORG_DUPLICATED_2_NAME=$(cat /run/secrets/react_app_org_duplicated_2_name); \ - fi; \ - if [ -f "/run/secrets/react_app_org_id_for_truplication" ]; then \ - export REACT_APP_ORG_ID_FOR_TRUPLICATION=$(cat /run/secrets/react_app_org_id_for_truplication); \ - fi; \ yarn build; \ if [ -f "/run/secrets/sentry_auth_token" ]; then \ export SENTRY_AUTH_TOKEN=$(cat /run/secrets/sentry_auth_token); \ diff --git a/dashboard/src/components/DataMigrator.js b/dashboard/src/components/DataMigrator.js index 680f3613b..af8ed3f1e 100644 --- a/dashboard/src/components/DataMigrator.js +++ b/dashboard/src/components/DataMigrator.js @@ -67,478 +67,7 @@ export default function useDataMigrator() { // End of example of migration. */ - console.log('process.env.REACT_APP_ORG_ID_FOR_TRUPLICATION'); - console.log(process.env.REACT_APP_ORG_ID_FOR_TRUPLICATION); - console.log('process.env.REACT_APP_ORG_DUPLICATED_1_ID'); - console.log(process.env.REACT_APP_ORG_DUPLICATED_1_ID); - console.log('process.env.REACT_APP_ORG_DUPLICATED_1_NAME'); - console.log(process.env.REACT_APP_ORG_DUPLICATED_1_NAME); - console.log('process.env.REACT_APP_ORG_DUPLICATED_2_ID'); - console.log(process.env.REACT_APP_ORG_DUPLICATED_2_ID); - console.log('process.env.REACT_APP_ORG_DUPLICATED_2_NAME'); - console.log(process.env.REACT_APP_ORG_DUPLICATED_2_NAME); - console.log('organisation._id'); - console.log(organisation._id); - if (organisation._id === process.env.REACT_APP_ORG_ID_FOR_TRUPLICATION && !organisation.migrations?.includes('truplicate-organisations')) { - setLoadingText("Truplication en cours: récupération des données de l'organisation originale…"); - - async function getItems(path) { - const response = await API.get({ - path, - query: { - organisation: organisation._id, - limit: String(Number.MAX_SAFE_INTEGER), - page: String(0), - after: String(0), - withDeleted: true, - }, - }); - return response.decryptedData; - } - - const dataToDuplicated = { - organisation, - users: await getItems('/user'), - teams: await getItems('/team'), - persons: await getItems('/person'), - consultations: await getItems('/consultation'), - treatments: await getItems('/treatment'), - medicalFiles: await getItems('/medical-file'), - groups: await getItems('/group'), - actions: await getItems('/action'), - comments: await getItems('/comment'), - passages: await getItems('/passage'), - rencontres: await getItems('/rencontre'), - territories: await getItems('/territory'), - territoryObservations: await getItems('/territory-observation'), - places: await getItems('/place'), - relPersonPlaces: await getItems('/relPersonPlace'), - reports: await getItems('/report'), - }; - - setLoadingText('Truplication en cours: duplication des données pour la première organisation…'); - - const duplicateEncryptedDataOrganisation1 = await duplicateDecryptedData({ - nextOrganisationId: process.env.REACT_APP_ORG_DUPLICATED_1_ID, - nextOrganisationName: process.env.REACT_APP_ORG_DUPLICATED_1_NAME, - preparePersonForEncryption, - ...dataToDuplicated, - }); - - setLoadingText('Truplication en cours: duplication des données pour la deuxième organisation…'); - - const duplicateEncryptedDataOrganisation2 = await duplicateDecryptedData({ - nextOrganisationId: process.env.REACT_APP_ORG_DUPLICATED_2_ID, - nextOrganisationName: process.env.REACT_APP_ORG_DUPLICATED_2_NAME, - preparePersonForEncryption, - ...dataToDuplicated, - }); - - setLoadingText('Truplication en cours: enregistrement des organisations fraichement créées'); - - const response = await API.put({ - path: `/migration/truplicate-organisations`, - body: { organisation1: duplicateEncryptedDataOrganisation1, organisation2: duplicateEncryptedDataOrganisation2 }, - query: { migrationLastUpdateAt }, - }); - if (response.ok) { - setOrganisation(response.organisation); - migrationLastUpdateAt = response.organisation.migrationLastUpdateAt; - } else { - return false; - } - } - return true; }, }; } - -const duplicateDecryptedData = async ({ - organisation, - nextOrganisationId, - nextOrganisationName, - persons, - users, - teams, - consultations, - treatments, - medicalFiles, - actions, - groups, - comments, - passages, - rencontres, - territories, - territoryObservations, - places, - relPersonPlaces, - reports, - preparePersonForEncryption, -}) => { - const teamIdsMapped = {}; - const newTeams = []; - for (const team of teams) { - const newTeamId = uuidv4(); - teamIdsMapped[team._id] = newTeamId; - const newTeam = { - ...team, - organisation: nextOrganisationId, - _id: newTeamId, - }; - newTeams.push(newTeam); - } - - const userIdsMapped = {}; - const newUsers = []; - const newRelUserTeams = []; - for (const user of users) { - const newUserId = uuidv4(); - userIdsMapped[user._id] = newUserId; - const newUser = { - ...user, - email: user.email.split('@')[0] + '+' + nextOrganisationName + '@' + user.email.split('@')[1], - organisation: nextOrganisationId, - _id: newUserId, - }; - newUsers.push(newUser); - for (const team of user.teams) { - if (!teamIdsMapped[team._id]) { - continue; - } - newRelUserTeams.push({ - user: newUserId, - team: teamIdsMapped[team._id], - organisation: nextOrganisationId, - _id: uuidv4(), - }); - } - } - - const personIdsMapped = {}; - const newPersons = []; - for (const person of persons) { - const newPersonId = uuidv4(); - personIdsMapped[person._id] = newPersonId; - if (!person.name && !person.deletedAt) { - continue; - } - const newPerson = { - ...person, - user: userIdsMapped[person.user], - documents: await recryptPersonRelatedDocuments(person, person._id, newPersonId), - assignedTeams: person.assignedTeams?.map((t) => teamIdsMapped[t]).filter(Boolean) ?? [], - organisation: nextOrganisationId, - _id: newPersonId, - }; - newPersons.push(newPerson); - } - const consultationIdsMapped = {}; - const newConsultations = []; - for (const consultation of consultations) { - if (!consultation.person && !consultation.deletedAt) { - continue; - } - const newConsultationId = uuidv4(); - consultationIdsMapped[consultation._id] = newConsultationId; - const newConsultation = { - ...consultation, - user: userIdsMapped[consultation.user], - documents: await recryptPersonRelatedDocuments(consultation, consultation.person, personIdsMapped[consultation.person]), - person: personIdsMapped[consultation.person], - teams: consultation.teams?.map((t) => teamIdsMapped[t]).filter(Boolean) ?? [], - organisation: nextOrganisationId, - _id: newConsultationId, - }; - if (!newConsultation.person && !newConsultation.deletedAt) { - continue; - } - newConsultations.push(newConsultation); - } - const treatmentIdsMapped = {}; - const newTreatments = []; - for (const treatment of treatments) { - const newTreatmentId = uuidv4(); - treatmentIdsMapped[treatment._id] = newTreatmentId; - const newTreatment = { - ...treatment, - user: userIdsMapped[treatment.user], - documents: await recryptPersonRelatedDocuments(treatment, treatment.person, personIdsMapped[treatment.person]), - person: personIdsMapped[treatment.person], - organisation: nextOrganisationId, - _id: newTreatmentId, - }; - if (!newTreatment.person && !newTreatment.deletedAt) { - continue; - } - newTreatments.push(newTreatment); - } - - const medicalFileIdsMapped = {}; - const newMedicalFiles = []; - for (const medicalFile of medicalFiles) { - const newMedicalFileId = uuidv4(); - medicalFileIdsMapped[medicalFile._id] = newMedicalFileId; - const newMedicalFile = { - ...medicalFile, - user: userIdsMapped[medicalFile.user], - documents: await recryptPersonRelatedDocuments(medicalFile, medicalFile.person, personIdsMapped[medicalFile.person]), - person: personIdsMapped[medicalFile.person], - organisation: nextOrganisationId, - _id: newMedicalFileId, - }; - if (!newMedicalFile.person && !newMedicalFile.deletedAt) { - continue; - } - newMedicalFiles.push(newMedicalFile); - } - - const actionIdsMapped = {}; - const newActions = []; - for (const action of actions) { - const newActionId = uuidv4(); - actionIdsMapped[action._id] = newActionId; - const newAction = { - ...action, - user: userIdsMapped[action.user], - person: personIdsMapped[action.person], - teams: action.teams?.map((t) => teamIdsMapped[t]).filter(Boolean) ?? [], - organisation: nextOrganisationId, - _id: newActionId, - }; - if (!newAction.person && !newAction.deletedAt) { - continue; - } - if (!newAction.teams?.length && !newAction.deletedAt) { - continue; - } - newActions.push(newAction); - } - - const groupIdsMapped = {}; - const newGroups = []; - for (const group of groups) { - const newGroupId = uuidv4(); - groupIdsMapped[group._id] = newGroupId; - const newGroup = { - persons: group.persons?.map((p) => personIdsMapped[p]), - relations: - group.relations?.map((r) => { - return { - ...r, - persons: r.persons?.map((p) => personIdsMapped[p]), - }; - }) ?? [], - organisation: nextOrganisationId, - _id: newGroupId, - }; - newGroups.push(newGroup); - } - - const commentIdsMapped = {}; - const newComments = []; - for (const comment of comments) { - const newCommentId = uuidv4(); - commentIdsMapped[comment._id] = newCommentId; - const newComment = { - ...comment, - user: userIdsMapped[comment.user], - team: teamIdsMapped[comment.team], - organisation: nextOrganisationId, - _id: newCommentId, - }; - if (!!comment.person) { - newComment.person = personIdsMapped[comment.person]; - } - if (!!comment.action) { - newComment.action = actionIdsMapped[comment.action]; - } - newComments.push(newComment); - } - - const passageIdsMapped = {}; - const newPassages = []; - for (const passage of passages) { - const newPassageId = uuidv4(); - passageIdsMapped[passage._id] = newPassageId; - const newPassage = { - ...passage, - user: userIdsMapped[passage.user], - team: teamIdsMapped[passage.team], - person: personIdsMapped[passage.person], - organisation: nextOrganisationId, - _id: newPassageId, - }; - newPassages.push(newPassage); - } - - const rencontreIdsMapped = {}; - const newRencontres = []; - for (const rencontre of rencontres) { - const newRencontreId = uuidv4(); - rencontreIdsMapped[rencontre._id] = newRencontreId; - const newRencontre = { - ...rencontre, - user: userIdsMapped[rencontre.user], - team: teamIdsMapped[rencontre.team], - person: personIdsMapped[rencontre.person], - organisation: nextOrganisationId, - _id: newRencontreId, - }; - newRencontres.push(newRencontre); - } - - const territoryIdsMapped = {}; - const newTerritories = []; - for (const territory of territories) { - const newTerritoryId = uuidv4(); - territoryIdsMapped[territory._id] = newTerritoryId; - const newTerritory = { - ...territory, - user: userIdsMapped[territory.user], - organisation: nextOrganisationId, - _id: newTerritoryId, - }; - newTerritories.push(newTerritory); - } - - const territoryObservationIdsMapped = {}; - const newObs = []; - - for (const territoryObservation of territoryObservations) { - const newTerritoryObservationId = uuidv4(); - territoryObservationIdsMapped[territoryObservation._id] = newTerritoryObservationId; - const newTerritoryObservation = { - ...territoryObservation, - user: userIdsMapped[territoryObservation.user], - territory: territoryIdsMapped[territoryObservation.territory], - team: teamIdsMapped[territoryObservation.team], - organisation: nextOrganisationId, - _id: newTerritoryObservationId, - }; - newObs.push(newTerritoryObservation); - } - - const placeIdsMapped = {}; - const newPlaces = []; - for (const place of places) { - const newPlaceId = uuidv4(); - placeIdsMapped[place._id] = newPlaceId; - const newPlace = { - ...place, - user: userIdsMapped[place.user], - organisation: nextOrganisationId, - _id: newPlaceId, - }; - newPlaces.push(newPlace); - } - - const relPersonPlaceIdsMapped = {}; - const newRelPersonPlaces = []; - for (const relPersonPlace of relPersonPlaces) { - const newRelPersonPlaceId = uuidv4(); - relPersonPlaceIdsMapped[relPersonPlace._id] = newRelPersonPlaceId; - const newRelPersonPlace = { - ...relPersonPlace, - user: userIdsMapped[relPersonPlace.user], - person: personIdsMapped[relPersonPlace.person], - place: placeIdsMapped[relPersonPlace.place], - organisation: nextOrganisationId, - _id: newRelPersonPlaceId, - }; - newRelPersonPlaces.push(newRelPersonPlace); - } - - const reportIdsMapped = {}; - const newReports = []; - for (const report of reports) { - const newReportId = uuidv4(); - reportIdsMapped[report._id] = newReportId; - const newReport = { - ...report, - user: userIdsMapped[report.user], - team: teamIdsMapped[report.team], - organisation: nextOrganisationId, - _id: newReportId, - }; - newReports.push(newReport); - } - - return { - organisationId: nextOrganisationId, - teams: newTeams, - users: newUsers, - relUserTeams: newRelUserTeams, - persons: await Promise.all(newPersons.map((item) => preparePersonForEncryption(item, { checkRequiredFields: false })).map(encryptItem)), - consultations: await Promise.all( - newConsultations - .map((item) => prepareConsultationForEncryption(organisation.consultations)(item, { checkRequiredFields: false })) - .map(encryptItem) - ), - treatments: await Promise.all(newTreatments.map((item) => prepareTreatmentForEncryption(item, { checkRequiredFields: false })).map(encryptItem)), - medicalFiles: await Promise.all( - newMedicalFiles - .map((item) => prepareMedicalFileForEncryption(organisation.customFieldsMedicalFile)(item, { checkRequiredFields: false })) - .map(encryptItem) - ), - actions: await Promise.all(newActions.map((item) => prepareActionForEncryption(item, { checkRequiredFields: false })).map(encryptItem)), - groups: await Promise.all(newGroups.map((item) => prepareGroupForEncryption(item, { checkRequiredFields: false })).map(encryptItem)), - comments: await Promise.all(newComments.map((item) => prepareCommentForEncryption(item, { checkRequiredFields: false })).map(encryptItem)), - passages: await Promise.all(newPassages.map((item) => preparePassageForEncryption(item, { checkRequiredFields: false })).map(encryptItem)), - rencontres: await Promise.all(newRencontres.map((item) => prepareRencontreForEncryption(item, { checkRequiredFields: false })).map(encryptItem)), - territories: await Promise.all( - newTerritories.map((item) => prepareTerritoryForEncryption(item, { checkRequiredFields: false })).map(encryptItem) - ), - observations: await Promise.all( - newObs.map((item) => prepareObsForEncryption(organisation.customFieldsObs)(item, { checkRequiredFields: false })).map(encryptItem) - ), - places: await Promise.all(newPlaces.map((item) => preparePlaceForEncryption(item, { checkRequiredFields: false })).map(encryptItem)), - relsPersonPlace: await Promise.all( - newRelPersonPlaces.map((item) => prepareRelPersonPlaceForEncryption(item, { checkRequiredFields: false })).map(encryptItem) - ), - reports: await Promise.all(newReports.map((item) => prepareReportForEncryption(item, { checkRequiredFields: false })).map(encryptItem)), - }; -}; - -const changeDocumentPersonId = async (doc, oldPersonId, newPersonId) => { - const content = await API.download({ - path: doc.downloadPath ?? `/person/${oldPersonId}/document/${doc.file.filename}`, - encryptedEntityKey: doc.encryptedEntityKey, - }); - const docResult = await API.upload({ - path: `/person/${newPersonId}/document`, - file: new File([content], doc.file.originalname, { type: doc.file.mimetype }), - }); - const { data: file, encryptedEntityKey } = docResult; - return { - _id: file.filename, - name: doc.file.originalname, - encryptedEntityKey, - createdAt: doc.createdAt, - createdBy: doc.createdBy, - downloadPath: `/person/${newPersonId}/document/${file.filename}`, - file, - }; -}; - -const recryptPersonRelatedDocuments = async (item, oldPersonId, newPersonId) => { - if (!item.documents || !item.documents.length) return []; - const updatedDocuments = []; - for (const doc of item.documents) { - try { - const recryptedDocument = await changeDocumentPersonId(doc, oldPersonId, newPersonId); - updatedDocuments.push(recryptedDocument); - } catch (e) { - // console.error(e); - // we need a temporary hack, for the organisations which already changed their encryption key - // but not all the documents were recrypted - // we told them to change back from `newKey` to `oldKey` to retrieve the old documents - // and then change back to `newKey` to recrypt them in the new key - // SO - // if the recryption failed, we assume the document might have been encrypted with the newKey already - // so we push it - updatedDocuments.push(doc); - } - } - return updatedDocuments; -};