diff --git a/.pnp.cjs b/.pnp.cjs index 1e4a2caae..5d3ff5085 100755 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -3065,16 +3065,6 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ - ["@mongodb-js/saslprep", [\ - ["npm:1.1.0", {\ - "packageLocation": "./.yarn/cache/@mongodb-js-saslprep-npm-1.1.0-3906c025b8-1a631b92d2.zip/node_modules/@mongodb-js/saslprep/",\ - "packageDependencies": [\ - ["@mongodb-js/saslprep", "npm:1.1.0"],\ - ["sparse-bitfield", "npm:3.0.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ ["@nodelib/fs.scandir", [\ ["npm:2.1.5", {\ "packageLocation": "./.yarn/cache/@nodelib-fs.scandir-npm-2.1.5-89c67370dd-6ab2a9b8a1.zip/node_modules/@nodelib/fs.scandir/",\ @@ -5897,13 +5887,12 @@ const RAW_RUNTIME_STATE = ["inversify-express-utils", "npm:6.4.3"],\ ["ioredis", "npm:5.3.2"],\ ["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.5.0"],\ - ["mongodb", "virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:6.0.0"],\ ["mysql2", "npm:3.3.3"],\ ["prettier", "npm:3.0.3"],\ ["reflect-metadata", "npm:0.1.13"],\ ["sqlite3", "virtual:31b5a94a105c89c9294c3d524a7f8929fe63ee5a2efadf21951ca4c0cfd2ecf02e8f4ef5a066bbda091f1e3a56e57c6749069a080618c96b22e51131a330fc4a#npm:5.1.6"],\ ["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.0"],\ - ["typeorm", "virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:0.3.17"],\ + ["typeorm", "virtual:31b5a94a105c89c9294c3d524a7f8929fe63ee5a2efadf21951ca4c0cfd2ecf02e8f4ef5a066bbda091f1e3a56e57c6749069a080618c96b22e51131a330fc4a#npm:0.3.17"],\ ["typescript", "patch:typescript@npm%3A5.0.4#optional!builtin::version=5.0.4&hash=b5f058"],\ ["winston", "npm:3.9.0"]\ ],\ @@ -6083,7 +6072,6 @@ const RAW_RUNTIME_STATE = ["ioredis", "npm:5.3.2"],\ ["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.5.0"],\ ["jsonwebtoken", "npm:9.0.0"],\ - ["mongodb", "virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:6.0.0"],\ ["mysql2", "npm:3.3.3"],\ ["prettier", "npm:3.0.3"],\ ["prettyjson", "npm:1.2.5"],\ @@ -6091,7 +6079,7 @@ const RAW_RUNTIME_STATE = ["semver", "npm:7.5.4"],\ ["sqlite3", "virtual:31b5a94a105c89c9294c3d524a7f8929fe63ee5a2efadf21951ca4c0cfd2ecf02e8f4ef5a066bbda091f1e3a56e57c6749069a080618c96b22e51131a330fc4a#npm:5.1.6"],\ ["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.0"],\ - ["typeorm", "virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:0.3.17"],\ + ["typeorm", "virtual:31b5a94a105c89c9294c3d524a7f8929fe63ee5a2efadf21951ca4c0cfd2ecf02e8f4ef5a066bbda091f1e3a56e57c6749069a080618c96b22e51131a330fc4a#npm:0.3.17"],\ ["typescript", "patch:typescript@npm%3A5.0.4#optional!builtin::version=5.0.4&hash=b5f058"],\ ["ua-parser-js", "npm:1.0.35"],\ ["uuid", "npm:9.0.0"],\ @@ -6729,26 +6717,6 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ - ["@types/webidl-conversions", [\ - ["npm:7.0.0", {\ - "packageLocation": "./.yarn/cache/@types-webidl-conversions-npm-7.0.0-0903313151-60142c7ddd.zip/node_modules/@types/webidl-conversions/",\ - "packageDependencies": [\ - ["@types/webidl-conversions", "npm:7.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@types/whatwg-url", [\ - ["npm:8.2.2", {\ - "packageLocation": "./.yarn/cache/@types-whatwg-url-npm-8.2.2-54c5c24e6c-5dc5afe078.zip/node_modules/@types/whatwg-url/",\ - "packageDependencies": [\ - ["@types/whatwg-url", "npm:8.2.2"],\ - ["@types/node", "npm:20.2.5"],\ - ["@types/webidl-conversions", "npm:7.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ ["@types/yargs", [\ ["npm:17.0.24", {\ "packageLocation": "./.yarn/cache/@types-yargs-npm-17.0.24-b034cf1d8b-03d9a985cb.zip/node_modules/@types/yargs/",\ @@ -7949,15 +7917,6 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ - ["bson", [\ - ["npm:6.0.0", {\ - "packageLocation": "./.yarn/cache/bson-npm-6.0.0-7b3cba060e-e7614bdc53.zip/node_modules/bson/",\ - "packageDependencies": [\ - ["bson", "npm:6.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ ["buffer", [\ ["npm:5.7.1", {\ "packageLocation": "./.yarn/cache/buffer-npm-5.7.1-513ef8259e-997434d3c6.zip/node_modules/buffer/",\ @@ -12561,15 +12520,6 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ - ["memory-pager", [\ - ["npm:1.5.0", {\ - "packageLocation": "./.yarn/cache/memory-pager-npm-1.5.0-46e20e6c81-ffe3461b6a.zip/node_modules/memory-pager/",\ - "packageDependencies": [\ - ["memory-pager", "npm:1.5.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ ["meow", [\ ["npm:8.1.2", {\ "packageLocation": "./.yarn/cache/meow-npm-8.1.2-bcfe48d4f3-d4770f9013.zip/node_modules/meow/",\ @@ -12914,66 +12864,6 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ - ["mongodb", [\ - ["npm:6.0.0", {\ - "packageLocation": "./.yarn/cache/mongodb-npm-6.0.0-7c1e74de91-501feaecb7.zip/node_modules/mongodb/",\ - "packageDependencies": [\ - ["mongodb", "npm:6.0.0"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:6.0.0", {\ - "packageLocation": "./.yarn/__virtual__/mongodb-virtual-789f2eaaac/0/cache/mongodb-npm-6.0.0-7c1e74de91-501feaecb7.zip/node_modules/mongodb/",\ - "packageDependencies": [\ - ["mongodb", "virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:6.0.0"],\ - ["@aws-sdk/credential-providers", null],\ - ["@mongodb-js/saslprep", "npm:1.1.0"],\ - ["@mongodb-js/zstd", null],\ - ["@types/aws-sdk__credential-providers", null],\ - ["@types/gcp-metadata", null],\ - ["@types/kerberos", null],\ - ["@types/mongodb-client-encryption", null],\ - ["@types/mongodb-js__zstd", null],\ - ["@types/snappy", null],\ - ["@types/socks", null],\ - ["bson", "npm:6.0.0"],\ - ["gcp-metadata", null],\ - ["kerberos", null],\ - ["mongodb-client-encryption", null],\ - ["mongodb-connection-string-url", "npm:2.6.0"],\ - ["snappy", null],\ - ["socks", null]\ - ],\ - "packagePeers": [\ - "@aws-sdk/credential-providers",\ - "@mongodb-js/zstd",\ - "@types/aws-sdk__credential-providers",\ - "@types/gcp-metadata",\ - "@types/kerberos",\ - "@types/mongodb-client-encryption",\ - "@types/mongodb-js__zstd",\ - "@types/snappy",\ - "@types/socks",\ - "gcp-metadata",\ - "kerberos",\ - "mongodb-client-encryption",\ - "snappy",\ - "socks"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["mongodb-connection-string-url", [\ - ["npm:2.6.0", {\ - "packageLocation": "./.yarn/cache/mongodb-connection-string-url-npm-2.6.0-af011ba17f-d0903b9824.zip/node_modules/mongodb-connection-string-url/",\ - "packageDependencies": [\ - ["mongodb-connection-string-url", "npm:2.6.0"],\ - ["@types/whatwg-url", "npm:8.2.2"],\ - ["whatwg-url", "npm:11.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ ["ms", [\ ["npm:2.0.0", {\ "packageLocation": "./.yarn/cache/ms-npm-2.0.0-9e1101a471-0e6a22b8b7.zip/node_modules/ms/",\ @@ -15055,16 +14945,6 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ - ["sparse-bitfield", [\ - ["npm:3.0.3", {\ - "packageLocation": "./.yarn/cache/sparse-bitfield-npm-3.0.3-cb80d0c89f-174da88dbb.zip/node_modules/sparse-bitfield/",\ - "packageDependencies": [\ - ["sparse-bitfield", "npm:3.0.3"],\ - ["memory-pager", "npm:1.5.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ ["spdx-correct", [\ ["npm:3.2.0", {\ "packageLocation": "./.yarn/cache/spdx-correct-npm-3.2.0-ffae008484-cc2e4dbef8.zip/node_modules/spdx-correct/",\ @@ -15714,14 +15594,6 @@ const RAW_RUNTIME_STATE = ["tr46", "npm:0.0.3"]\ ],\ "linkType": "HARD"\ - }],\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/tr46-npm-3.0.0-e1ae1ea7c9-b09a15886c.zip/node_modules/tr46/",\ - "packageDependencies": [\ - ["tr46", "npm:3.0.0"],\ - ["punycode", "npm:2.3.0"]\ - ],\ - "linkType": "HARD"\ }]\ ]],\ ["treeverse", [\ @@ -16175,98 +16047,6 @@ const RAW_RUNTIME_STATE = ],\ "linkType": "HARD"\ }],\ - ["virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:0.3.17", {\ - "packageLocation": "./.yarn/__virtual__/typeorm-virtual-bfb7ebf128/0/cache/typeorm-npm-0.3.17-f8c2578e7f-3a7fe2a5e9.zip/node_modules/typeorm/",\ - "packageDependencies": [\ - ["typeorm", "virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:0.3.17"],\ - ["@google-cloud/spanner", null],\ - ["@sap/hana-client", null],\ - ["@sqltools/formatter", "npm:1.2.5"],\ - ["@types/better-sqlite3", null],\ - ["@types/google-cloud__spanner", null],\ - ["@types/hdb-pool", null],\ - ["@types/ioredis", "npm:5.0.0"],\ - ["@types/mongodb", null],\ - ["@types/mssql", null],\ - ["@types/mysql2", null],\ - ["@types/oracledb", null],\ - ["@types/pg", null],\ - ["@types/pg-native", null],\ - ["@types/pg-query-stream", null],\ - ["@types/redis", null],\ - ["@types/sap__hana-client", null],\ - ["@types/sql.js", null],\ - ["@types/sqlite3", null],\ - ["@types/ts-node", null],\ - ["@types/typeorm-aurora-data-api-driver", null],\ - ["app-root-path", "npm:3.1.0"],\ - ["better-sqlite3", null],\ - ["buffer", "npm:6.0.3"],\ - ["chalk", "npm:4.1.2"],\ - ["cli-highlight", "npm:2.1.11"],\ - ["date-fns", "npm:2.30.0"],\ - ["debug", "virtual:ac3d8e680759ce54399273724d44e041d6c9b73454d191d411a8c44bb27e22f02aaf6ed9d3ad0ac1c298eac4833cff369c9c7b84c573016112c4f84be2cd8543#npm:4.3.4"],\ - ["dotenv", "npm:16.1.3"],\ - ["glob", "npm:8.1.0"],\ - ["hdb-pool", null],\ - ["ioredis", "npm:5.3.2"],\ - ["mkdirp", "npm:2.1.6"],\ - ["mongodb", "virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:6.0.0"],\ - ["mssql", null],\ - ["mysql2", "npm:3.3.3"],\ - ["oracledb", null],\ - ["pg", null],\ - ["pg-native", null],\ - ["pg-query-stream", null],\ - ["redis", null],\ - ["reflect-metadata", "npm:0.1.13"],\ - ["sha.js", "npm:2.4.11"],\ - ["sql.js", null],\ - ["sqlite3", "virtual:31b5a94a105c89c9294c3d524a7f8929fe63ee5a2efadf21951ca4c0cfd2ecf02e8f4ef5a066bbda091f1e3a56e57c6749069a080618c96b22e51131a330fc4a#npm:5.1.6"],\ - ["ts-node", null],\ - ["tslib", "npm:2.5.2"],\ - ["typeorm-aurora-data-api-driver", null],\ - ["uuid", "npm:9.0.0"],\ - ["yargs", "npm:17.7.2"]\ - ],\ - "packagePeers": [\ - "@google-cloud/spanner",\ - "@sap/hana-client",\ - "@types/better-sqlite3",\ - "@types/google-cloud__spanner",\ - "@types/hdb-pool",\ - "@types/ioredis",\ - "@types/mongodb",\ - "@types/mssql",\ - "@types/mysql2",\ - "@types/oracledb",\ - "@types/pg-native",\ - "@types/pg-query-stream",\ - "@types/pg",\ - "@types/redis",\ - "@types/sap__hana-client",\ - "@types/sql.js",\ - "@types/sqlite3",\ - "@types/ts-node",\ - "@types/typeorm-aurora-data-api-driver",\ - "better-sqlite3",\ - "hdb-pool",\ - "ioredis",\ - "mongodb",\ - "mssql",\ - "mysql2",\ - "oracledb",\ - "pg-native",\ - "pg-query-stream",\ - "pg",\ - "redis",\ - "sql.js",\ - "sqlite3",\ - "ts-node",\ - "typeorm-aurora-data-api-driver"\ - ],\ - "linkType": "HARD"\ - }],\ ["virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:0.3.17", {\ "packageLocation": "./.yarn/__virtual__/typeorm-virtual-bfa664706d/0/cache/typeorm-npm-0.3.17-f8c2578e7f-3a7fe2a5e9.zip/node_modules/typeorm/",\ "packageDependencies": [\ @@ -16659,13 +16439,6 @@ const RAW_RUNTIME_STATE = ["webidl-conversions", "npm:3.0.1"]\ ],\ "linkType": "HARD"\ - }],\ - ["npm:7.0.0", {\ - "packageLocation": "./.yarn/cache/webidl-conversions-npm-7.0.0-e8c8e30c68-4c4f65472c.zip/node_modules/webidl-conversions/",\ - "packageDependencies": [\ - ["webidl-conversions", "npm:7.0.0"]\ - ],\ - "linkType": "HARD"\ }]\ ]],\ ["webpack", [\ @@ -16724,15 +16497,6 @@ const RAW_RUNTIME_STATE = }]\ ]],\ ["whatwg-url", [\ - ["npm:11.0.0", {\ - "packageLocation": "./.yarn/cache/whatwg-url-npm-11.0.0-073529d93a-dfcd51c6f4.zip/node_modules/whatwg-url/",\ - "packageDependencies": [\ - ["whatwg-url", "npm:11.0.0"],\ - ["tr46", "npm:3.0.0"],\ - ["webidl-conversions", "npm:7.0.0"]\ - ],\ - "linkType": "HARD"\ - }],\ ["npm:5.0.0", {\ "packageLocation": "./.yarn/cache/whatwg-url-npm-5.0.0-374fb45e60-f95adbc1e8.zip/node_modules/whatwg-url/",\ "packageDependencies": [\ diff --git a/.yarn/cache/@mongodb-js-saslprep-npm-1.1.0-3906c025b8-1a631b92d2.zip b/.yarn/cache/@mongodb-js-saslprep-npm-1.1.0-3906c025b8-1a631b92d2.zip deleted file mode 100644 index 3a2dd36ae..000000000 Binary files a/.yarn/cache/@mongodb-js-saslprep-npm-1.1.0-3906c025b8-1a631b92d2.zip and /dev/null differ diff --git a/.yarn/cache/@types-webidl-conversions-npm-7.0.0-0903313151-60142c7ddd.zip b/.yarn/cache/@types-webidl-conversions-npm-7.0.0-0903313151-60142c7ddd.zip deleted file mode 100644 index 3da1d6225..000000000 Binary files a/.yarn/cache/@types-webidl-conversions-npm-7.0.0-0903313151-60142c7ddd.zip and /dev/null differ diff --git a/.yarn/cache/@types-whatwg-url-npm-8.2.2-54c5c24e6c-5dc5afe078.zip b/.yarn/cache/@types-whatwg-url-npm-8.2.2-54c5c24e6c-5dc5afe078.zip deleted file mode 100644 index cc6d5fd22..000000000 Binary files a/.yarn/cache/@types-whatwg-url-npm-8.2.2-54c5c24e6c-5dc5afe078.zip and /dev/null differ diff --git a/.yarn/cache/bson-npm-6.0.0-7b3cba060e-e7614bdc53.zip b/.yarn/cache/bson-npm-6.0.0-7b3cba060e-e7614bdc53.zip deleted file mode 100644 index df60a8348..000000000 Binary files a/.yarn/cache/bson-npm-6.0.0-7b3cba060e-e7614bdc53.zip and /dev/null differ diff --git a/.yarn/cache/memory-pager-npm-1.5.0-46e20e6c81-ffe3461b6a.zip b/.yarn/cache/memory-pager-npm-1.5.0-46e20e6c81-ffe3461b6a.zip deleted file mode 100644 index e29ea7f13..000000000 Binary files a/.yarn/cache/memory-pager-npm-1.5.0-46e20e6c81-ffe3461b6a.zip and /dev/null differ diff --git a/.yarn/cache/mongodb-connection-string-url-npm-2.6.0-af011ba17f-d0903b9824.zip b/.yarn/cache/mongodb-connection-string-url-npm-2.6.0-af011ba17f-d0903b9824.zip deleted file mode 100644 index 707bef6fc..000000000 Binary files a/.yarn/cache/mongodb-connection-string-url-npm-2.6.0-af011ba17f-d0903b9824.zip and /dev/null differ diff --git a/.yarn/cache/mongodb-npm-6.0.0-7c1e74de91-501feaecb7.zip b/.yarn/cache/mongodb-npm-6.0.0-7c1e74de91-501feaecb7.zip deleted file mode 100644 index 9fe1df774..000000000 Binary files a/.yarn/cache/mongodb-npm-6.0.0-7c1e74de91-501feaecb7.zip and /dev/null differ diff --git a/.yarn/cache/sparse-bitfield-npm-3.0.3-cb80d0c89f-174da88dbb.zip b/.yarn/cache/sparse-bitfield-npm-3.0.3-cb80d0c89f-174da88dbb.zip deleted file mode 100644 index 7c43c8bc9..000000000 Binary files a/.yarn/cache/sparse-bitfield-npm-3.0.3-cb80d0c89f-174da88dbb.zip and /dev/null differ diff --git a/.yarn/cache/tr46-npm-3.0.0-e1ae1ea7c9-b09a15886c.zip b/.yarn/cache/tr46-npm-3.0.0-e1ae1ea7c9-b09a15886c.zip deleted file mode 100644 index 01b8cdb07..000000000 Binary files a/.yarn/cache/tr46-npm-3.0.0-e1ae1ea7c9-b09a15886c.zip and /dev/null differ diff --git a/.yarn/cache/webidl-conversions-npm-7.0.0-e8c8e30c68-4c4f65472c.zip b/.yarn/cache/webidl-conversions-npm-7.0.0-e8c8e30c68-4c4f65472c.zip deleted file mode 100644 index 0c5c664fc..000000000 Binary files a/.yarn/cache/webidl-conversions-npm-7.0.0-e8c8e30c68-4c4f65472c.zip and /dev/null differ diff --git a/.yarn/cache/whatwg-url-npm-11.0.0-073529d93a-dfcd51c6f4.zip b/.yarn/cache/whatwg-url-npm-11.0.0-073529d93a-dfcd51c6f4.zip deleted file mode 100644 index 1588d5510..000000000 Binary files a/.yarn/cache/whatwg-url-npm-11.0.0-073529d93a-dfcd51c6f4.zip and /dev/null differ diff --git a/Dockerfile b/Dockerfile index 19da345b3..a401de86d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,6 +3,8 @@ FROM node:20.6.1-alpine ENV NODE_ENV production RUN apk add --update --no-cache \ + g++ \ + make \ openssl \ curl \ bash \ diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh index 379fc9a7a..43340ce44 100755 --- a/docker/docker-entrypoint.sh +++ b/docker/docker-entrypoint.sh @@ -57,9 +57,6 @@ fi if [ -z "$CACHE_TYPE" ]; then export CACHE_TYPE="redis" fi -if [ -z "$SECONDARY_DB_ENABLED" ]; then - export SECONDARY_DB_ENABLED=false -fi export DB_MIGRATIONS_PATH="dist/migrations/*.js" ######### diff --git a/packages/api-gateway/src/Controller/AuthMiddleware.ts b/packages/api-gateway/src/Controller/AuthMiddleware.ts index c2fe6316c..40b00618e 100644 --- a/packages/api-gateway/src/Controller/AuthMiddleware.ts +++ b/packages/api-gateway/src/Controller/AuthMiddleware.ts @@ -39,7 +39,7 @@ export abstract class AuthMiddleware extends BaseMiddleware { crossServiceToken = await this.crossServiceTokenCache.get(cacheKey) } - if (this.crossServiceTokenIsEmptyOrRequiresRevalidation(crossServiceToken)) { + if (crossServiceToken === null) { const authResponse = await this.serviceProxy.validateSession({ authorization: authHeaderValue, sharedVaultOwnerContext: sharedVaultOwnerContextHeaderValue, @@ -129,14 +129,4 @@ export abstract class AuthMiddleware extends BaseMiddleware { return Math.min(crossServiceTokenDefaultCacheExpiration, sessionAccessExpiration, sessionRefreshExpiration) } - - private crossServiceTokenIsEmptyOrRequiresRevalidation(crossServiceToken: string | null) { - if (crossServiceToken === null) { - return true - } - - const decodedToken = verify(crossServiceToken, this.jwtSecret, { algorithms: ['HS256'] }) - - return decodedToken.ongoing_transition === true - } } diff --git a/packages/api-gateway/src/Controller/v1/ItemsController.ts b/packages/api-gateway/src/Controller/v1/ItemsController.ts index a10f100a9..68dc05da2 100644 --- a/packages/api-gateway/src/Controller/v1/ItemsController.ts +++ b/packages/api-gateway/src/Controller/v1/ItemsController.ts @@ -34,16 +34,6 @@ export class ItemsController extends BaseHttpController { ) } - @httpPost('/transition') - async transition(request: Request, response: Response): Promise { - await this.serviceProxy.callSyncingServer( - request, - response, - this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'items/transition'), - request.body, - ) - } - @httpGet('/:uuid') async getItem(request: Request, response: Response): Promise { await this.serviceProxy.callSyncingServer( diff --git a/packages/api-gateway/src/Controller/v2/RevisionsControllerV2.ts b/packages/api-gateway/src/Controller/v2/RevisionsControllerV2.ts index 9f197aafd..c7c464b14 100644 --- a/packages/api-gateway/src/Controller/v2/RevisionsControllerV2.ts +++ b/packages/api-gateway/src/Controller/v2/RevisionsControllerV2.ts @@ -1,6 +1,6 @@ import { Request, Response } from 'express' import { inject } from 'inversify' -import { BaseHttpController, controller, httpDelete, httpGet, httpPost } from 'inversify-express-utils' +import { BaseHttpController, controller, httpDelete, httpGet } from 'inversify-express-utils' import { TYPES } from '../../Bootstrap/Types' import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface' @@ -55,14 +55,4 @@ export class RevisionsControllerV2 extends BaseHttpController { ), ) } - - @httpPost('/revisions/transition') - async transition(request: Request, response: Response): Promise { - await this.serviceProxy.callRevisionsServer( - request, - response, - this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'revisions/transition'), - request.body, - ) - } } diff --git a/packages/auth/bin/transition.ts b/packages/auth/bin/transition.ts deleted file mode 100644 index 2284f1412..000000000 --- a/packages/auth/bin/transition.ts +++ /dev/null @@ -1,170 +0,0 @@ -import 'reflect-metadata' - -import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra' -import { ServiceIdentifier, RoleName, TransitionStatus } from '@standardnotes/domain-core' - -const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AuthScheduledTask }) -sdk.start() - -import { Logger } from 'winston' -import * as dayjs from 'dayjs' -import * as utc from 'dayjs/plugin/utc' - -import { ContainerConfigLoader } from '../src/Bootstrap/Container' -import TYPES from '../src/Bootstrap/Types' -import { Env } from '../src/Bootstrap/Env' -import { DomainEventPublisherInterface } from '@standardnotes/domain-events' -import { DomainEventFactoryInterface } from '../src/Domain/Event/DomainEventFactoryInterface' -import { UserRepositoryInterface } from '../src/Domain/User/UserRepositoryInterface' -import { TimerInterface } from '@standardnotes/time' -import { TransitionStatusRepositoryInterface } from '../src/Domain/Transition/TransitionStatusRepositoryInterface' - -const inputArgs = process.argv.slice(2) -const startDateString = inputArgs[0] -const endDateString = inputArgs[1] -const forceRunParam = inputArgs[2] - -const requestTransition = async ( - transitionStatusRepository: TransitionStatusRepositoryInterface, - userRepository: UserRepositoryInterface, - logger: Logger, - domainEventFactory: DomainEventFactoryInterface, - domainEventPublisher: DomainEventPublisherInterface, - timer: TimerInterface, -): Promise => { - const startDate = new Date(startDateString) - const endDate = new Date(endDateString) - - const usersCount = await userRepository.countAllCreatedBetween(startDate, endDate) - - const timestamp = timer.getTimestampInMicroseconds() - - logger.info( - `[TRANSITION ${timestamp}] Found ${usersCount} users created between ${startDateString} and ${endDateString}`, - ) - - let itemTransitionsTriggered = 0 - let revisionTransitionsTriggered = 0 - const forceRun = forceRunParam === 'true' - - const pageLimit = 100 - const totalPages = Math.ceil(usersCount / pageLimit) - for (let currentPage = 1; currentPage <= totalPages; currentPage++) { - const users = await userRepository.findAllCreatedBetween({ - start: startDate, - end: endDate, - offset: (currentPage - 1) * pageLimit, - limit: pageLimit, - }) - - for (const user of users) { - const itemsTransitionStatus = await transitionStatusRepository.getStatus(user.uuid, 'items') - const revisionsTransitionStatus = await transitionStatusRepository.getStatus(user.uuid, 'revisions') - - const userRoles = await user.roles - - const userHasTransitionRole = userRoles.some((role) => role.name === RoleName.NAMES.TransitionUser) - const bothTransitionStatusesAreVerified = - itemsTransitionStatus?.value === TransitionStatus.STATUSES.Verified && - revisionsTransitionStatus?.value === TransitionStatus.STATUSES.Verified - - if (!userHasTransitionRole && bothTransitionStatusesAreVerified) { - continue - } - - logger.info( - `[TRANSITION ${timestamp}] Transition status for user ${user.uuid} - items status: ${itemsTransitionStatus?.value}, revisions status: ${revisionsTransitionStatus?.value}, has transition role: ${userHasTransitionRole}`, - ) - - if ( - itemsTransitionStatus === null || - itemsTransitionStatus.value === TransitionStatus.STATUSES.Failed || - (itemsTransitionStatus.value === TransitionStatus.STATUSES.InProgress && forceRun) - ) { - await transitionStatusRepository.remove(user.uuid, 'items') - - await domainEventPublisher.publish( - domainEventFactory.createTransitionRequestedEvent({ - userUuid: user.uuid, - type: 'items', - timestamp, - }), - ) - - itemTransitionsTriggered++ - } - - if ( - revisionsTransitionStatus === null || - revisionsTransitionStatus.value === TransitionStatus.STATUSES.Failed || - (revisionsTransitionStatus.value === TransitionStatus.STATUSES.InProgress && forceRun) - ) { - await transitionStatusRepository.remove(user.uuid, 'revisions') - - await domainEventPublisher.publish( - domainEventFactory.createTransitionRequestedEvent({ - userUuid: user.uuid, - type: 'revisions', - timestamp, - }), - ) - - revisionTransitionsTriggered++ - } - } - } - - logger.info( - `[TRANSITION ${timestamp}] Triggered ${itemTransitionsTriggered} item transitions and ${revisionTransitionsTriggered} revision transitions for users created between ${startDateString} and ${endDateString}`, - ) -} - -const container = new ContainerConfigLoader('worker') -void container.load().then((container) => { - dayjs.extend(utc) - - const env: Env = new Env() - env.load() - - const logger: Logger = container.get(TYPES.Auth_Logger) - - logger.info(`Starting transition request for users created between ${startDateString} and ${endDateString}`) - - const userRepository: UserRepositoryInterface = container.get(TYPES.Auth_UserRepository) - const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.Auth_DomainEventFactory) - const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.Auth_DomainEventPublisher) - const timer = container.get(TYPES.Auth_Timer) - const transitionStatusRepository = container.get( - TYPES.Auth_TransitionStatusRepository, - ) - - const tracer = new OpenTelemetryTracer() - tracer.startSpan(ServiceIdentifier.NAMES.AuthScheduledTask, 'transition') - - Promise.resolve( - requestTransition( - transitionStatusRepository, - userRepository, - logger, - domainEventFactory, - domainEventPublisher, - timer, - ), - ) - .then(() => { - logger.info(`Finished transition request for users created between ${startDateString} and ${endDateString}`) - - tracer.stopSpan() - - process.exit(0) - }) - .catch((error) => { - logger.error( - `Error while requesting transition for users created between ${startDateString} and ${endDateString}: ${error}`, - ) - - tracer.stopSpanWithError(error) - - process.exit(1) - }) -}) diff --git a/packages/auth/docker/entrypoint-transition.js b/packages/auth/docker/entrypoint-transition.js deleted file mode 100644 index 18b1ed77b..000000000 --- a/packages/auth/docker/entrypoint-transition.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict' - -const path = require('path') - -const pnp = require(path.normalize(path.resolve(__dirname, '../../..', '.pnp.cjs'))).setup() - -const index = require(path.normalize(path.resolve(__dirname, '../dist/bin/transition.js'))) - -Object.defineProperty(exports, '__esModule', { value: true }) - -exports.default = index diff --git a/packages/auth/docker/entrypoint.sh b/packages/auth/docker/entrypoint.sh index ffa2b52e2..76d5e2a87 100755 --- a/packages/auth/docker/entrypoint.sh +++ b/packages/auth/docker/entrypoint.sh @@ -55,13 +55,6 @@ case "$COMMAND" in node docker/entrypoint-backup.js one_drive daily ;; - 'transition' ) - START_DATE=$1 && shift 1 - END_DATE=$1 && shift 1 - echo "[Docker] Starting Transition..." - node docker/entrypoint-transition.js $START_DATE $END_DATE - ;; - * ) echo "[Docker] Unknown command" ;; diff --git a/packages/auth/migrations/mysql/1697704066569-remove-transition-role.ts b/packages/auth/migrations/mysql/1697704066569-remove-transition-role.ts new file mode 100644 index 000000000..d374f35e1 --- /dev/null +++ b/packages/auth/migrations/mysql/1697704066569-remove-transition-role.ts @@ -0,0 +1,11 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class RemoveTransitionRole1697704066569 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query('DELETE FROM `roles` WHERE name = "TRANSITION_USER"') + } + + public async down(): Promise { + return + } +} diff --git a/packages/auth/src/Bootstrap/Container.ts b/packages/auth/src/Bootstrap/Container.ts index 7550803ab..69cc854f3 100644 --- a/packages/auth/src/Bootstrap/Container.ts +++ b/packages/auth/src/Bootstrap/Container.ts @@ -258,11 +258,6 @@ import { UpdateStorageQuotaUsedForUser } from '../Domain/UseCase/UpdateStorageQu import { SharedVaultFileUploadedEventHandler } from '../Domain/Handler/SharedVaultFileUploadedEventHandler' import { SharedVaultFileRemovedEventHandler } from '../Domain/Handler/SharedVaultFileRemovedEventHandler' import { SharedVaultFileMovedEventHandler } from '../Domain/Handler/SharedVaultFileMovedEventHandler' -import { TransitionStatusRepositoryInterface } from '../Domain/Transition/TransitionStatusRepositoryInterface' -import { RedisTransitionStatusRepository } from '../Infra/Redis/RedisTransitionStatusRepository' -import { InMemoryTransitionStatusRepository } from '../Infra/InMemory/InMemoryTransitionStatusRepository' -import { TransitionStatusUpdatedEventHandler } from '../Domain/Handler/TransitionStatusUpdatedEventHandler' -import { UpdateTransitionStatus } from '../Domain/UseCase/UpdateTransitionStatus/UpdateTransitionStatus' import { TypeORMSharedVaultUser } from '../Infra/TypeORM/TypeORMSharedVaultUser' import { SharedVaultUserPersistenceMapper } from '../Mapping/SharedVaultUserPersistenceMapper' import { SharedVaultUserRepositoryInterface } from '../Domain/SharedVault/SharedVaultUserRepositoryInterface' @@ -645,9 +640,6 @@ export class ContainerConfigLoader { container.get(TYPES.Auth_Timer), ), ) - container - .bind(TYPES.Auth_TransitionStatusRepository) - .toConstantValue(new InMemoryTransitionStatusRepository()) } else { container.bind(TYPES.Auth_PKCERepository).to(RedisPKCERepository) container.bind(TYPES.Auth_LockRepository).to(LockRepository) @@ -660,9 +652,6 @@ export class ContainerConfigLoader { container .bind(TYPES.Auth_SubscriptionTokenRepository) .to(RedisSubscriptionTokenRepository) - container - .bind(TYPES.Auth_TransitionStatusRepository) - .toConstantValue(new RedisTransitionStatusRepository(container.get(TYPES.Auth_Redis))) } // Services @@ -985,15 +974,6 @@ export class ContainerConfigLoader { container.get(TYPES.Auth_SubscriptionSettingService), ), ) - container - .bind(TYPES.Auth_UpdateTransitionStatus) - .toConstantValue( - new UpdateTransitionStatus( - container.get(TYPES.Auth_TransitionStatusRepository), - container.get(TYPES.Auth_RoleService), - container.get(TYPES.Auth_Logger), - ), - ) container .bind(TYPES.Auth_AddSharedVaultUser) .toConstantValue( @@ -1174,14 +1154,6 @@ export class ContainerConfigLoader { container.get(TYPES.Auth_Logger), ), ) - container - .bind(TYPES.Auth_TransitionStatusUpdatedEventHandler) - .toConstantValue( - new TransitionStatusUpdatedEventHandler( - container.get(TYPES.Auth_UpdateTransitionStatus), - container.get(TYPES.Auth_Logger), - ), - ) container .bind(TYPES.Auth_UserAddedToSharedVaultEventHandler) .toConstantValue( @@ -1239,7 +1211,6 @@ export class ContainerConfigLoader { ['PREDICATE_VERIFICATION_REQUESTED', container.get(TYPES.Auth_PredicateVerificationRequestedEventHandler)], ['EMAIL_SUBSCRIPTION_UNSUBSCRIBED', container.get(TYPES.Auth_EmailSubscriptionUnsubscribedEventHandler)], ['PAYMENTS_ACCOUNT_DELETED', container.get(TYPES.Auth_PaymentsAccountDeletedEventHandler)], - ['TRANSITION_STATUS_UPDATED', container.get(TYPES.Auth_TransitionStatusUpdatedEventHandler)], ['USER_ADDED_TO_SHARED_VAULT', container.get(TYPES.Auth_UserAddedToSharedVaultEventHandler)], ['USER_REMOVED_FROM_SHARED_VAULT', container.get(TYPES.Auth_UserRemovedFromSharedVaultEventHandler)], [ diff --git a/packages/auth/src/Bootstrap/Types.ts b/packages/auth/src/Bootstrap/Types.ts index bb3310602..4a3314a0c 100644 --- a/packages/auth/src/Bootstrap/Types.ts +++ b/packages/auth/src/Bootstrap/Types.ts @@ -36,7 +36,6 @@ const TYPES = { Auth_AuthenticatorRepository: Symbol.for('Auth_AuthenticatorRepository'), Auth_AuthenticatorChallengeRepository: Symbol.for('Auth_AuthenticatorChallengeRepository'), Auth_CacheEntryRepository: Symbol.for('Auth_CacheEntryRepository'), - Auth_TransitionStatusRepository: Symbol.for('Auth_TransitionStatusRepository'), Auth_SharedVaultUserRepository: Symbol.for('Auth_SharedVaultUserRepository'), // ORM Auth_ORMOfflineSettingRepository: Symbol.for('Auth_ORMOfflineSettingRepository'), @@ -157,7 +156,6 @@ const TYPES = { Auth_SignInWithRecoveryCodes: Symbol.for('Auth_SignInWithRecoveryCodes'), Auth_GetUserKeyParamsRecovery: Symbol.for('Auth_GetUserKeyParamsRecovery'), Auth_UpdateStorageQuotaUsedForUser: Symbol.for('Auth_UpdateStorageQuotaUsedForUser'), - Auth_UpdateTransitionStatus: Symbol.for('Auth_UpdateTransitionStatus'), Auth_AddSharedVaultUser: Symbol.for('Auth_AddSharedVaultUser'), Auth_RemoveSharedVaultUser: Symbol.for('Auth_RemoveSharedVaultUser'), Auth_DesignateSurvivor: Symbol.for('Auth_DesignateSurvivor'), @@ -190,7 +188,6 @@ const TYPES = { Auth_PredicateVerificationRequestedEventHandler: Symbol.for('Auth_PredicateVerificationRequestedEventHandler'), Auth_EmailSubscriptionUnsubscribedEventHandler: Symbol.for('Auth_EmailSubscriptionUnsubscribedEventHandler'), Auth_PaymentsAccountDeletedEventHandler: Symbol.for('Auth_PaymentsAccountDeletedEventHandler'), - Auth_TransitionStatusUpdatedEventHandler: Symbol.for('Auth_TransitionStatusUpdatedEventHandler'), Auth_UserAddedToSharedVaultEventHandler: Symbol.for('Auth_UserAddedToSharedVaultEventHandler'), Auth_UserRemovedFromSharedVaultEventHandler: Symbol.for('Auth_UserRemovedFromSharedVaultEventHandler'), Auth_UserDesignatedAsSurvivorInSharedVaultEventHandler: Symbol.for( diff --git a/packages/auth/src/Domain/Event/DomainEventFactory.ts b/packages/auth/src/Domain/Event/DomainEventFactory.ts index 2e7f0fefc..2ab9d70b4 100644 --- a/packages/auth/src/Domain/Event/DomainEventFactory.ts +++ b/packages/auth/src/Domain/Event/DomainEventFactory.ts @@ -20,7 +20,6 @@ import { StatisticPersistenceRequestedEvent, SessionCreatedEvent, SessionRefreshedEvent, - TransitionRequestedEvent, } from '@standardnotes/domain-events' import { Predicate, PredicateVerificationResult } from '@standardnotes/predicates' import { TimerInterface } from '@standardnotes/time' @@ -34,25 +33,6 @@ import { KeyParamsData } from '@standardnotes/responses' export class DomainEventFactory implements DomainEventFactoryInterface { constructor(@inject(TYPES.Auth_Timer) private timer: TimerInterface) {} - createTransitionRequestedEvent(dto: { - userUuid: string - type: 'items' | 'revisions' - timestamp: number - }): TransitionRequestedEvent { - return { - type: 'TRANSITION_REQUESTED', - createdAt: this.timer.getUTCDate(), - meta: { - correlation: { - userIdentifier: dto.userUuid, - userIdentifierType: 'uuid', - }, - origin: DomainEventService.Auth, - }, - payload: dto, - } - } - createSessionCreatedEvent(dto: { userUuid: string }): SessionCreatedEvent { return { type: 'SESSION_CREATED', diff --git a/packages/auth/src/Domain/Event/DomainEventFactoryInterface.ts b/packages/auth/src/Domain/Event/DomainEventFactoryInterface.ts index 086f476a5..584155380 100644 --- a/packages/auth/src/Domain/Event/DomainEventFactoryInterface.ts +++ b/packages/auth/src/Domain/Event/DomainEventFactoryInterface.ts @@ -18,7 +18,6 @@ import { StatisticPersistenceRequestedEvent, SessionCreatedEvent, SessionRefreshedEvent, - TransitionRequestedEvent, } from '@standardnotes/domain-events' import { InviteeIdentifierType } from '../SharedSubscription/InviteeIdentifierType' import { KeyParamsData } from '@standardnotes/responses' @@ -92,9 +91,4 @@ export interface DomainEventFactoryInterface { }): StatisticPersistenceRequestedEvent createSessionCreatedEvent(dto: { userUuid: string }): SessionCreatedEvent createSessionRefreshedEvent(dto: { userUuid: string }): SessionRefreshedEvent - createTransitionRequestedEvent(dto: { - userUuid: string - type: 'items' | 'revisions' - timestamp: number - }): TransitionRequestedEvent } diff --git a/packages/auth/src/Domain/Handler/TransitionStatusUpdatedEventHandler.ts b/packages/auth/src/Domain/Handler/TransitionStatusUpdatedEventHandler.ts deleted file mode 100644 index f1133c369..000000000 --- a/packages/auth/src/Domain/Handler/TransitionStatusUpdatedEventHandler.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { DomainEventHandlerInterface, TransitionStatusUpdatedEvent } from '@standardnotes/domain-events' -import { UpdateTransitionStatus } from '../UseCase/UpdateTransitionStatus/UpdateTransitionStatus' -import { Logger } from 'winston' - -export class TransitionStatusUpdatedEventHandler implements DomainEventHandlerInterface { - constructor( - private updateTransitionStatusUseCase: UpdateTransitionStatus, - private logger: Logger, - ) {} - - async handle(event: TransitionStatusUpdatedEvent): Promise { - const result = await this.updateTransitionStatusUseCase.execute({ - status: event.payload.status, - userUuid: event.payload.userUuid, - transitionType: event.payload.transitionType, - transitionTimestamp: event.payload.transitionTimestamp, - }) - - if (result.isFailed()) { - this.logger.error(`Failed to update transition status for user ${event.payload.userUuid}`) - } - } -} diff --git a/packages/auth/src/Domain/Transition/TransitionStatusRepositoryInterface.ts b/packages/auth/src/Domain/Transition/TransitionStatusRepositoryInterface.ts deleted file mode 100644 index ee77e13cd..000000000 --- a/packages/auth/src/Domain/Transition/TransitionStatusRepositoryInterface.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { TransitionStatus } from '@standardnotes/domain-core' - -export interface TransitionStatusRepositoryInterface { - updateStatus(userUuid: string, transitionType: 'items' | 'revisions', status: TransitionStatus): Promise - getStatus(userUuid: string, transitionType: 'items' | 'revisions'): Promise - remove(userUuid: string, transitionType: 'items' | 'revisions'): Promise -} diff --git a/packages/auth/src/Domain/UseCase/CreateCrossServiceToken/CreateCrossServiceToken.spec.ts b/packages/auth/src/Domain/UseCase/CreateCrossServiceToken/CreateCrossServiceToken.spec.ts index c566723c1..89f4ede9c 100644 --- a/packages/auth/src/Domain/UseCase/CreateCrossServiceToken/CreateCrossServiceToken.spec.ts +++ b/packages/auth/src/Domain/UseCase/CreateCrossServiceToken/CreateCrossServiceToken.spec.ts @@ -9,15 +9,7 @@ import { UserRepositoryInterface } from '../../User/UserRepositoryInterface' import { CreateCrossServiceToken } from './CreateCrossServiceToken' import { GetSetting } from '../GetSetting/GetSetting' -import { - Result, - SharedVaultUser, - SharedVaultUserPermission, - Timestamps, - TransitionStatus, - Uuid, -} from '@standardnotes/domain-core' -import { TransitionStatusRepositoryInterface } from '../../Transition/TransitionStatusRepositoryInterface' +import { Result, SharedVaultUser, SharedVaultUserPermission, Timestamps, Uuid } from '@standardnotes/domain-core' import { SharedVaultUserRepositoryInterface } from '../../SharedVault/SharedVaultUserRepositoryInterface' describe('CreateCrossServiceToken', () => { @@ -27,7 +19,6 @@ describe('CreateCrossServiceToken', () => { let tokenEncoder: TokenEncoderInterface let userRepository: UserRepositoryInterface let getSettingUseCase: GetSetting - let transitionStatusRepository: TransitionStatusRepositoryInterface let sharedVaultUserRepository: SharedVaultUserRepositoryInterface const jwtTTL = 60 @@ -44,7 +35,6 @@ describe('CreateCrossServiceToken', () => { userRepository, jwtTTL, getSettingUseCase, - transitionStatusRepository, sharedVaultUserRepository, ) @@ -78,11 +68,6 @@ describe('CreateCrossServiceToken', () => { getSettingUseCase = {} as jest.Mocked getSettingUseCase.execute = jest.fn().mockReturnValue(Result.ok({ setting: { value: '100' } })) - transitionStatusRepository = {} as jest.Mocked - transitionStatusRepository.getStatus = jest - .fn() - .mockReturnValue(TransitionStatus.create(TransitionStatus.STATUSES.Verified).getValue()) - sharedVaultUserRepository = {} as jest.Mocked sharedVaultUserRepository.findByUserUuid = jest.fn().mockReturnValue([ SharedVaultUser.create({ @@ -122,46 +107,6 @@ describe('CreateCrossServiceToken', () => { email: 'test@test.te', uuid: '00000000-0000-0000-0000-000000000000', }, - ongoing_transition: false, - ongoing_revisions_transition: false, - }, - 60, - ) - }) - - it('should create a cross service token for user that has an ongoing transaction', async () => { - transitionStatusRepository.getStatus = jest - .fn() - .mockReturnValue(TransitionStatus.create(TransitionStatus.STATUSES.InProgress).getValue()) - - await createUseCase().execute({ - user, - session, - }) - - expect(tokenEncoder.encodeExpirableToken).toHaveBeenCalledWith( - { - roles: [ - { - name: 'role1', - uuid: '1-3-4', - }, - ], - belongs_to_shared_vaults: [ - { - shared_vault_uuid: '00000000-0000-0000-0000-000000000000', - permission: 'read', - }, - ], - session: { - test: 'test', - }, - user: { - email: 'test@test.te', - uuid: '00000000-0000-0000-0000-000000000000', - }, - ongoing_transition: true, - ongoing_revisions_transition: true, }, 60, ) @@ -190,8 +135,6 @@ describe('CreateCrossServiceToken', () => { email: 'test@test.te', uuid: '00000000-0000-0000-0000-000000000000', }, - ongoing_transition: false, - ongoing_revisions_transition: false, }, 60, ) @@ -220,8 +163,6 @@ describe('CreateCrossServiceToken', () => { email: 'test@test.te', uuid: '00000000-0000-0000-0000-000000000000', }, - ongoing_transition: false, - ongoing_revisions_transition: false, }, 60, ) @@ -277,8 +218,6 @@ describe('CreateCrossServiceToken', () => { email: 'test@test.te', uuid: '00000000-0000-0000-0000-000000000000', }, - ongoing_revisions_transition: false, - ongoing_transition: false, }, 60, ) diff --git a/packages/auth/src/Domain/UseCase/CreateCrossServiceToken/CreateCrossServiceToken.ts b/packages/auth/src/Domain/UseCase/CreateCrossServiceToken/CreateCrossServiceToken.ts index 5b4c08463..a6b694c13 100644 --- a/packages/auth/src/Domain/UseCase/CreateCrossServiceToken/CreateCrossServiceToken.ts +++ b/packages/auth/src/Domain/UseCase/CreateCrossServiceToken/CreateCrossServiceToken.ts @@ -1,6 +1,6 @@ import { TokenEncoderInterface, CrossServiceTokenData } from '@standardnotes/security' import { inject, injectable } from 'inversify' -import { Result, TransitionStatus, UseCaseInterface, Uuid } from '@standardnotes/domain-core' +import { Result, UseCaseInterface, Uuid } from '@standardnotes/domain-core' import TYPES from '../../../Bootstrap/Types' import { ProjectorInterface } from '../../../Projection/ProjectorInterface' @@ -12,7 +12,6 @@ import { UserRepositoryInterface } from '../../User/UserRepositoryInterface' import { CreateCrossServiceTokenDTO } from './CreateCrossServiceTokenDTO' import { GetSetting } from '../GetSetting/GetSetting' import { SettingName } from '@standardnotes/settings' -import { TransitionStatusRepositoryInterface } from '../../Transition/TransitionStatusRepositoryInterface' import { SharedVaultUserRepositoryInterface } from '../../SharedVault/SharedVaultUserRepositoryInterface' @injectable() @@ -26,8 +25,6 @@ export class CreateCrossServiceToken implements UseCaseInterface { @inject(TYPES.Auth_AUTH_JWT_TTL) private jwtTTL: number, @inject(TYPES.Auth_GetSetting) private getSettingUseCase: GetSetting, - @inject(TYPES.Auth_TransitionStatusRepository) - private transitionStatusRepository: TransitionStatusRepositoryInterface, @inject(TYPES.Auth_SharedVaultUserRepository) private sharedVaultUserRepository: SharedVaultUserRepositoryInterface, ) {} @@ -47,9 +44,6 @@ export class CreateCrossServiceToken implements UseCaseInterface { return Result.fail(`Could not find user with uuid ${dto.userUuid}`) } - const transitionStatus = await this.transitionStatusRepository.getStatus(user.uuid, 'items') - const revisionsTransitionStatus = await this.transitionStatusRepository.getStatus(user.uuid, 'revisions') - const roles = await user.roles const sharedVaultAssociations = await this.sharedVaultUserRepository.findByUserUuid( @@ -60,8 +54,6 @@ export class CreateCrossServiceToken implements UseCaseInterface { user: this.projectUser(user), roles: this.projectRoles(roles), shared_vault_owner_context: undefined, - ongoing_transition: transitionStatus?.value === TransitionStatus.STATUSES.InProgress, - ongoing_revisions_transition: revisionsTransitionStatus?.value === TransitionStatus.STATUSES.InProgress, belongs_to_shared_vaults: sharedVaultAssociations.map((association) => ({ shared_vault_uuid: association.props.sharedVaultUuid.value, permission: association.props.permission.value, diff --git a/packages/auth/src/Domain/UseCase/CreateValetToken/CreateValetToken.spec.ts b/packages/auth/src/Domain/UseCase/CreateValetToken/CreateValetToken.spec.ts index 48f221989..19e3ff3ab 100644 --- a/packages/auth/src/Domain/UseCase/CreateValetToken/CreateValetToken.spec.ts +++ b/packages/auth/src/Domain/UseCase/CreateValetToken/CreateValetToken.spec.ts @@ -1,6 +1,5 @@ import 'reflect-metadata' -import { TransitionStatus } from '@standardnotes/domain-core' import { TimerInterface } from '@standardnotes/time' import { TokenEncoderInterface, ValetTokenData, ValetTokenOperation } from '@standardnotes/security' @@ -11,7 +10,6 @@ import { User } from '../../User/User' import { UserSubscriptionType } from '../../Subscription/UserSubscriptionType' import { SubscriptionSettingsAssociationServiceInterface } from '../../Setting/SubscriptionSettingsAssociationServiceInterface' import { UserSubscriptionServiceInterface } from '../../Subscription/UserSubscriptionServiceInterface' -import { TransitionStatusRepositoryInterface } from '../../Transition/TransitionStatusRepositoryInterface' describe('CreateValetToken', () => { let tokenEncoder: TokenEncoderInterface @@ -23,7 +21,6 @@ describe('CreateValetToken', () => { let regularSubscription: UserSubscription let sharedSubscription: UserSubscription let user: User - let transitionStatusRepository: TransitionStatusRepositoryInterface const createUseCase = () => new CreateValetToken( @@ -33,7 +30,6 @@ describe('CreateValetToken', () => { userSubscriptionService, timer, valetTokenTTL, - transitionStatusRepository, ) beforeEach(() => { @@ -71,11 +67,6 @@ describe('CreateValetToken', () => { timer = {} as jest.Mocked timer.getTimestampInMicroseconds = jest.fn().mockReturnValue(100) - - transitionStatusRepository = {} as jest.Mocked - transitionStatusRepository.getStatus = jest - .fn() - .mockReturnValue(TransitionStatus.create(TransitionStatus.STATUSES.Verified).getValue()) }) it('should create a read valet token', async () => { @@ -176,7 +167,6 @@ describe('CreateValetToken', () => { { sharedSubscriptionUuid: undefined, regularSubscriptionUuid: '1-2-3', - ongoingTransition: false, permittedOperation: 'write', permittedResources: [ { @@ -217,7 +207,6 @@ describe('CreateValetToken', () => { { sharedSubscriptionUuid: '2-3-4', regularSubscriptionUuid: '1-2-3', - ongoingTransition: false, permittedOperation: 'write', permittedResources: [ { @@ -278,7 +267,6 @@ describe('CreateValetToken', () => { { sharedSubscriptionUuid: undefined, regularSubscriptionUuid: '1-2-3', - ongoingTransition: false, permittedOperation: 'write', permittedResources: [ { diff --git a/packages/auth/src/Domain/UseCase/CreateValetToken/CreateValetToken.ts b/packages/auth/src/Domain/UseCase/CreateValetToken/CreateValetToken.ts index 4e76a8bef..cc1901315 100644 --- a/packages/auth/src/Domain/UseCase/CreateValetToken/CreateValetToken.ts +++ b/packages/auth/src/Domain/UseCase/CreateValetToken/CreateValetToken.ts @@ -13,8 +13,6 @@ import { CreateValetTokenDTO } from './CreateValetTokenDTO' import { SubscriptionSettingsAssociationServiceInterface } from '../../Setting/SubscriptionSettingsAssociationServiceInterface' import { UserSubscriptionServiceInterface } from '../../Subscription/UserSubscriptionServiceInterface' import { CreateValetTokenPayload } from '../../ValetToken/CreateValetTokenPayload' -import { TransitionStatusRepositoryInterface } from '../../Transition/TransitionStatusRepositoryInterface' -import { TransitionStatus } from '@standardnotes/domain-core' @injectable() export class CreateValetToken implements UseCaseInterface { @@ -27,8 +25,6 @@ export class CreateValetToken implements UseCaseInterface { @inject(TYPES.Auth_UserSubscriptionService) private userSubscriptionService: UserSubscriptionServiceInterface, @inject(TYPES.Auth_Timer) private timer: TimerInterface, @inject(TYPES.Auth_VALET_TOKEN_TTL) private valetTokenTTL: number, - @inject(TYPES.Auth_TransitionStatusRepository) - private transitionStatusRepository: TransitionStatusRepositoryInterface, ) {} async execute(dto: CreateValetTokenDTO): Promise { @@ -87,8 +83,6 @@ export class CreateValetToken implements UseCaseInterface { sharedSubscriptionUuid = sharedSubscription.uuid } - const transitionStatus = await this.transitionStatusRepository.getStatus(userUuid, 'items') - const tokenData: ValetTokenData = { userUuid: dto.userUuid, permittedOperation: dto.operation, @@ -97,7 +91,6 @@ export class CreateValetToken implements UseCaseInterface { uploadBytesLimit, sharedSubscriptionUuid, regularSubscriptionUuid: regularSubscription.uuid, - ongoingTransition: transitionStatus?.value === TransitionStatus.STATUSES.InProgress, } const valetToken = this.tokenEncoder.encodeExpirableToken(tokenData, this.valetTokenTTL) diff --git a/packages/auth/src/Domain/UseCase/UpdateTransitionStatus/UpdateTransitionStatus.spec.ts b/packages/auth/src/Domain/UseCase/UpdateTransitionStatus/UpdateTransitionStatus.spec.ts deleted file mode 100644 index 6d2946b48..000000000 --- a/packages/auth/src/Domain/UseCase/UpdateTransitionStatus/UpdateTransitionStatus.spec.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { RoleName, TransitionStatus, Uuid } from '@standardnotes/domain-core' - -import { RoleServiceInterface } from '../../Role/RoleServiceInterface' -import { TransitionStatusRepositoryInterface } from '../../Transition/TransitionStatusRepositoryInterface' -import { UpdateTransitionStatus } from './UpdateTransitionStatus' -import { Logger } from 'winston' - -describe('UpdateTransitionStatus', () => { - let transitionStatusRepository: TransitionStatusRepositoryInterface - let roleService: RoleServiceInterface - let logger: Logger - - const createUseCase = () => new UpdateTransitionStatus(transitionStatusRepository, roleService, logger) - - beforeEach(() => { - logger = {} as jest.Mocked - logger.info = jest.fn() - - transitionStatusRepository = {} as jest.Mocked - transitionStatusRepository.updateStatus = jest.fn() - transitionStatusRepository.getStatus = jest.fn().mockResolvedValue(null) - - roleService = {} as jest.Mocked - roleService.removeRoleFromUser = jest.fn() - }) - - it('should add TRANSITION_USER role', async () => { - const useCase = createUseCase() - - const result = await useCase.execute({ - userUuid: '00000000-0000-0000-0000-000000000000', - status: 'VERIFIED', - transitionType: 'items', - transitionTimestamp: 123, - }) - - expect(result.isFailed()).toBeFalsy() - expect(roleService.removeRoleFromUser).toHaveBeenCalledWith( - Uuid.create('00000000-0000-0000-0000-000000000000').getValue(), - RoleName.create(RoleName.NAMES.TransitionUser).getValue(), - ) - }) - - it('should update transition status', async () => { - const useCase = createUseCase() - - const result = await useCase.execute({ - userUuid: '00000000-0000-0000-0000-000000000000', - status: TransitionStatus.STATUSES.InProgress, - transitionType: 'items', - transitionTimestamp: 123, - }) - - expect(result.isFailed()).toBeFalsy() - expect(transitionStatusRepository.updateStatus).toHaveBeenCalled() - }) - - it('should return error when user uuid is invalid', async () => { - const useCase = createUseCase() - - const result = await useCase.execute({ - userUuid: 'invalid', - status: 'STARTED', - transitionType: 'items', - transitionTimestamp: 123, - }) - - expect(result.isFailed()).toBeTruthy() - expect(result.getError()).toEqual('Given value is not a valid uuid: invalid') - }) - - it('should not update status if transition is already verified', async () => { - transitionStatusRepository.getStatus = jest - .fn() - .mockResolvedValue(TransitionStatus.create(TransitionStatus.STATUSES.Verified).getValue()) - - const useCase = createUseCase() - - const result = await useCase.execute({ - userUuid: '00000000-0000-0000-0000-000000000000', - status: TransitionStatus.STATUSES.InProgress, - transitionType: 'items', - transitionTimestamp: 123, - }) - - expect(result.isFailed()).toBeFalsy() - expect(transitionStatusRepository.updateStatus).not.toHaveBeenCalled() - }) - - it('should not update status if transition is already failed', async () => { - transitionStatusRepository.getStatus = jest - .fn() - .mockResolvedValue(TransitionStatus.create(TransitionStatus.STATUSES.Failed).getValue()) - - const useCase = createUseCase() - - const result = await useCase.execute({ - userUuid: '00000000-0000-0000-0000-000000000000', - status: TransitionStatus.STATUSES.InProgress, - transitionType: 'items', - transitionTimestamp: 123, - }) - - expect(result.isFailed()).toBeFalsy() - expect(transitionStatusRepository.updateStatus).not.toHaveBeenCalled() - }) -}) diff --git a/packages/auth/src/Domain/UseCase/UpdateTransitionStatus/UpdateTransitionStatus.ts b/packages/auth/src/Domain/UseCase/UpdateTransitionStatus/UpdateTransitionStatus.ts deleted file mode 100644 index 966daa5ce..000000000 --- a/packages/auth/src/Domain/UseCase/UpdateTransitionStatus/UpdateTransitionStatus.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Result, RoleName, TransitionStatus, UseCaseInterface, Uuid } from '@standardnotes/domain-core' -import { TransitionStatusRepositoryInterface } from '../../Transition/TransitionStatusRepositoryInterface' -import { UpdateTransitionStatusDTO } from './UpdateTransitionStatusDTO' -import { RoleServiceInterface } from '../../Role/RoleServiceInterface' -import { Logger } from 'winston' - -export class UpdateTransitionStatus implements UseCaseInterface { - constructor( - private transitionStatusRepository: TransitionStatusRepositoryInterface, - private roleService: RoleServiceInterface, - private logger: Logger, - ) {} - - async execute(dto: UpdateTransitionStatusDTO): Promise> { - const userUuidOrError = Uuid.create(dto.userUuid) - if (userUuidOrError.isFailed()) { - return Result.fail(userUuidOrError.getError()) - } - const userUuid = userUuidOrError.getValue() - - const currentStatus = await this.transitionStatusRepository.getStatus(dto.userUuid, dto.transitionType) - if ( - [TransitionStatus.STATUSES.Verified, TransitionStatus.STATUSES.Failed].includes(currentStatus?.value as string) - ) { - this.logger.info(`User ${dto.userUuid} transition already finished.`) - - return Result.ok() - } - - const transitionStatus = TransitionStatus.create(dto.status).getValue() - - await this.transitionStatusRepository.updateStatus(dto.userUuid, dto.transitionType, transitionStatus) - - if (dto.transitionType === 'items' && transitionStatus.value === TransitionStatus.STATUSES.Verified) { - await this.roleService.removeRoleFromUser(userUuid, RoleName.create(RoleName.NAMES.TransitionUser).getValue()) - } - - return Result.ok() - } -} diff --git a/packages/auth/src/Domain/UseCase/UpdateTransitionStatus/UpdateTransitionStatusDTO.ts b/packages/auth/src/Domain/UseCase/UpdateTransitionStatus/UpdateTransitionStatusDTO.ts deleted file mode 100644 index 215e69923..000000000 --- a/packages/auth/src/Domain/UseCase/UpdateTransitionStatus/UpdateTransitionStatusDTO.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface UpdateTransitionStatusDTO { - userUuid: string - transitionType: 'items' | 'revisions' - transitionTimestamp: number - status: string -} diff --git a/packages/auth/src/Infra/InMemory/InMemoryTransitionStatusRepository.ts b/packages/auth/src/Infra/InMemory/InMemoryTransitionStatusRepository.ts deleted file mode 100644 index 7e04cb03a..000000000 --- a/packages/auth/src/Infra/InMemory/InMemoryTransitionStatusRepository.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { TransitionStatus } from '@standardnotes/domain-core' -import { TransitionStatusRepositoryInterface } from '../../Domain/Transition/TransitionStatusRepositoryInterface' - -export class InMemoryTransitionStatusRepository implements TransitionStatusRepositoryInterface { - private itemStatuses: Map = new Map() - private revisionStatuses: Map = new Map() - - async updateStatus(userUuid: string, transitionType: 'items' | 'revisions', status: TransitionStatus): Promise { - if (transitionType === 'items') { - this.itemStatuses.set(userUuid, status.value) - } else { - this.revisionStatuses.set(userUuid, status.value) - } - } - - async remove(userUuid: string, transitionType: 'items' | 'revisions'): Promise { - if (transitionType === 'items') { - this.itemStatuses.delete(userUuid) - } else { - this.revisionStatuses.delete(userUuid) - } - } - - async getStatus(userUuid: string, transitionType: 'items' | 'revisions'): Promise { - let status: string | null - - if (transitionType === 'items') { - status = this.itemStatuses.get(userUuid) ?? null - } else { - status = this.revisionStatuses.get(userUuid) ?? null - } - - if (status === null) { - return null - } - - return TransitionStatus.create(status).getValue() - } -} diff --git a/packages/auth/src/Infra/Redis/RedisTransitionStatusRepository.ts b/packages/auth/src/Infra/Redis/RedisTransitionStatusRepository.ts deleted file mode 100644 index a640b6ba2..000000000 --- a/packages/auth/src/Infra/Redis/RedisTransitionStatusRepository.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as IORedis from 'ioredis' - -import { TransitionStatusRepositoryInterface } from '../../Domain/Transition/TransitionStatusRepositoryInterface' -import { TransitionStatus } from '@standardnotes/domain-core' - -export class RedisTransitionStatusRepository implements TransitionStatusRepositoryInterface { - private readonly PREFIX = 'transition-back' - - constructor(private redisClient: IORedis.Redis) {} - - async remove(userUuid: string, transitionType: 'items' | 'revisions'): Promise { - await this.redisClient.del(`${this.PREFIX}:${transitionType}:${userUuid}`) - } - - async updateStatus(userUuid: string, transitionType: 'items' | 'revisions', status: TransitionStatus): Promise { - switch (status.value) { - case TransitionStatus.STATUSES.Failed: - case TransitionStatus.STATUSES.Verified: - await this.redisClient.set(`${this.PREFIX}:${transitionType}:${userUuid}`, status.value) - break - case TransitionStatus.STATUSES.InProgress: { - const ttl24Hours = 86_400 - await this.redisClient.setex(`${this.PREFIX}:${transitionType}:${userUuid}`, ttl24Hours, status.value) - break - } - } - } - - async getStatus(userUuid: string, transitionType: 'items' | 'revisions'): Promise { - const status = await this.redisClient.get(`${this.PREFIX}:${transitionType}:${userUuid}`) - - if (status === null) { - return null - } - - const transitionStatusOrError = TransitionStatus.create(status) - if (transitionStatusOrError.isFailed()) { - return null - } - - return transitionStatusOrError.getValue() - } -} diff --git a/packages/domain-core/src/Domain/Common/RoleName.spec.ts b/packages/domain-core/src/Domain/Common/RoleName.spec.ts index 0e939803f..a03812a0d 100644 --- a/packages/domain-core/src/Domain/Common/RoleName.spec.ts +++ b/packages/domain-core/src/Domain/Common/RoleName.spec.ts @@ -21,36 +21,25 @@ describe('RoleName', () => { const plusUserRole = RoleName.create(RoleName.NAMES.PlusUser).getValue() const coreUser = RoleName.create(RoleName.NAMES.CoreUser).getValue() const internalTeamUser = RoleName.create(RoleName.NAMES.InternalTeamUser).getValue() - const transitionUser = RoleName.create(RoleName.NAMES.TransitionUser).getValue() expect(internalTeamUser.hasMoreOrEqualPowerTo(proUserRole)).toBeTruthy() expect(internalTeamUser.hasMoreOrEqualPowerTo(proUserRole)).toBeTruthy() expect(internalTeamUser.hasMoreOrEqualPowerTo(plusUserRole)).toBeTruthy() expect(internalTeamUser.hasMoreOrEqualPowerTo(coreUser)).toBeTruthy() - expect(internalTeamUser.hasMoreOrEqualPowerTo(transitionUser)).toBeTruthy() expect(proUserRole.hasMoreOrEqualPowerTo(internalTeamUser)).toBeFalsy() expect(proUserRole.hasMoreOrEqualPowerTo(proUserRole)).toBeTruthy() expect(proUserRole.hasMoreOrEqualPowerTo(plusUserRole)).toBeTruthy() expect(proUserRole.hasMoreOrEqualPowerTo(coreUser)).toBeTruthy() - expect(proUserRole.hasMoreOrEqualPowerTo(transitionUser)).toBeTruthy() expect(plusUserRole.hasMoreOrEqualPowerTo(internalTeamUser)).toBeFalsy() expect(plusUserRole.hasMoreOrEqualPowerTo(proUserRole)).toBeFalsy() expect(plusUserRole.hasMoreOrEqualPowerTo(plusUserRole)).toBeTruthy() expect(plusUserRole.hasMoreOrEqualPowerTo(coreUser)).toBeTruthy() - expect(plusUserRole.hasMoreOrEqualPowerTo(transitionUser)).toBeTruthy() expect(coreUser.hasMoreOrEqualPowerTo(internalTeamUser)).toBeFalsy() expect(coreUser.hasMoreOrEqualPowerTo(proUserRole)).toBeFalsy() expect(coreUser.hasMoreOrEqualPowerTo(plusUserRole)).toBeFalsy() expect(coreUser.hasMoreOrEqualPowerTo(coreUser)).toBeTruthy() - expect(coreUser.hasMoreOrEqualPowerTo(transitionUser)).toBeTruthy() - - expect(transitionUser.hasMoreOrEqualPowerTo(internalTeamUser)).toBeFalsy() - expect(transitionUser.hasMoreOrEqualPowerTo(proUserRole)).toBeFalsy() - expect(transitionUser.hasMoreOrEqualPowerTo(plusUserRole)).toBeFalsy() - expect(transitionUser.hasMoreOrEqualPowerTo(coreUser)).toBeTruthy() - expect(transitionUser.hasMoreOrEqualPowerTo(transitionUser)).toBeTruthy() }) }) diff --git a/packages/domain-core/src/Domain/Common/RoleName.ts b/packages/domain-core/src/Domain/Common/RoleName.ts index 5334f06d6..431441857 100644 --- a/packages/domain-core/src/Domain/Common/RoleName.ts +++ b/packages/domain-core/src/Domain/Common/RoleName.ts @@ -8,7 +8,6 @@ export class RoleName extends ValueObject { PlusUser: 'PLUS_USER', ProUser: 'PRO_USER', InternalTeamUser: 'INTERNAL_TEAM_USER', - TransitionUser: 'TRANSITION_USER', VaultsUser: 'VAULTS_USER', } @@ -21,20 +20,12 @@ export class RoleName extends ValueObject { case RoleName.NAMES.InternalTeamUser: return true case RoleName.NAMES.ProUser: - return [ - RoleName.NAMES.CoreUser, - RoleName.NAMES.PlusUser, - RoleName.NAMES.ProUser, - RoleName.NAMES.TransitionUser, - ].includes(roleName.value) + return [RoleName.NAMES.CoreUser, RoleName.NAMES.PlusUser, RoleName.NAMES.ProUser].includes(roleName.value) case RoleName.NAMES.PlusUser: - return [RoleName.NAMES.CoreUser, RoleName.NAMES.PlusUser, RoleName.NAMES.TransitionUser].includes( - roleName.value, - ) + return [RoleName.NAMES.CoreUser, RoleName.NAMES.PlusUser].includes(roleName.value) case RoleName.NAMES.CoreUser: - case RoleName.NAMES.TransitionUser: case RoleName.NAMES.VaultsUser: - return [RoleName.NAMES.CoreUser, RoleName.NAMES.TransitionUser].includes(roleName.value) + return [RoleName.NAMES.CoreUser].includes(roleName.value) /*istanbul ignore next*/ default: throw new Error(`Invalid role name: ${this.value}`) diff --git a/packages/domain-core/src/Domain/Transition/TransitionStatus.ts b/packages/domain-core/src/Domain/Transition/TransitionStatus.ts deleted file mode 100644 index 6c23ab866..000000000 --- a/packages/domain-core/src/Domain/Transition/TransitionStatus.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Result } from '../Core/Result' -import { ValueObject } from '../Core/ValueObject' -import { TransitionStatusProps } from './TransitionStatusProps' - -export class TransitionStatus extends ValueObject { - static readonly STATUSES = { - InProgress: 'IN_PROGRESS', - Failed: 'FAILED', - Verified: 'VERIFIED', - } - - get value(): string { - return this.props.value - } - - private constructor(props: TransitionStatusProps) { - super(props) - } - - static create(name: string): Result { - const isValidName = Object.values(this.STATUSES).includes(name) - if (!isValidName) { - return Result.fail('Invalid transition status name.') - } else { - return Result.ok(new TransitionStatus({ value: name })) - } - } -} diff --git a/packages/domain-core/src/Domain/Transition/TransitionStatusProps.ts b/packages/domain-core/src/Domain/Transition/TransitionStatusProps.ts deleted file mode 100644 index 01cd81986..000000000 --- a/packages/domain-core/src/Domain/Transition/TransitionStatusProps.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface TransitionStatusProps { - value: string -} diff --git a/packages/domain-core/src/Domain/index.ts b/packages/domain-core/src/Domain/index.ts index b4158b7a4..492b46311 100644 --- a/packages/domain-core/src/Domain/index.ts +++ b/packages/domain-core/src/Domain/index.ts @@ -69,8 +69,5 @@ export * from './SharedVault/SharedVaultUserProps' export * from './Subscription/SubscriptionPlanName' export * from './Subscription/SubscriptionPlanNameProps' -export * from './Transition/TransitionStatus' -export * from './Transition/TransitionStatusProps' - export * from './UseCase/SyncUseCaseInterface' export * from './UseCase/UseCaseInterface' diff --git a/packages/domain-events/src/Domain/Event/AccountDeletionRequestedEventPayload.ts b/packages/domain-events/src/Domain/Event/AccountDeletionRequestedEventPayload.ts index 537978d5e..fcbbb7a70 100644 --- a/packages/domain-events/src/Domain/Event/AccountDeletionRequestedEventPayload.ts +++ b/packages/domain-events/src/Domain/Event/AccountDeletionRequestedEventPayload.ts @@ -1,6 +1,5 @@ export interface AccountDeletionRequestedEventPayload { userUuid: string - roleNames: string[] userCreatedAtTimestamp: number regularSubscriptionUuid: string | undefined } diff --git a/packages/domain-events/src/Domain/Event/DuplicateItemSyncedEventPayload.ts b/packages/domain-events/src/Domain/Event/DuplicateItemSyncedEventPayload.ts index bb911da51..b3fa9f231 100644 --- a/packages/domain-events/src/Domain/Event/DuplicateItemSyncedEventPayload.ts +++ b/packages/domain-events/src/Domain/Event/DuplicateItemSyncedEventPayload.ts @@ -1,5 +1,4 @@ export interface DuplicateItemSyncedEventPayload { itemUuid: string userUuid: string - roleNames: string[] } diff --git a/packages/domain-events/src/Domain/Event/ItemDumpedEventPayload.ts b/packages/domain-events/src/Domain/Event/ItemDumpedEventPayload.ts index 431be2621..7c0164d1d 100644 --- a/packages/domain-events/src/Domain/Event/ItemDumpedEventPayload.ts +++ b/packages/domain-events/src/Domain/Event/ItemDumpedEventPayload.ts @@ -1,4 +1,3 @@ export interface ItemDumpedEventPayload { fileDumpPath: string - roleNames: string[] } diff --git a/packages/domain-events/src/Domain/Event/ItemRevisionCreationRequestedEventPayload.ts b/packages/domain-events/src/Domain/Event/ItemRevisionCreationRequestedEventPayload.ts index 90a6587ff..7854b1dfb 100644 --- a/packages/domain-events/src/Domain/Event/ItemRevisionCreationRequestedEventPayload.ts +++ b/packages/domain-events/src/Domain/Event/ItemRevisionCreationRequestedEventPayload.ts @@ -1,4 +1,3 @@ export interface ItemRevisionCreationRequestedEventPayload { itemUuid: string - roleNames: string[] } diff --git a/packages/domain-events/src/Domain/Event/RevisionsCopyRequestedEventPayload.ts b/packages/domain-events/src/Domain/Event/RevisionsCopyRequestedEventPayload.ts index a6ef147ae..09efb74f7 100644 --- a/packages/domain-events/src/Domain/Event/RevisionsCopyRequestedEventPayload.ts +++ b/packages/domain-events/src/Domain/Event/RevisionsCopyRequestedEventPayload.ts @@ -1,5 +1,4 @@ export interface RevisionsCopyRequestedEventPayload { newItemUuid: string originalItemUuid: string - roleNames: string[] } diff --git a/packages/domain-events/src/Domain/Event/TransitionRequestedEvent.ts b/packages/domain-events/src/Domain/Event/TransitionRequestedEvent.ts deleted file mode 100644 index 3a447a85a..000000000 --- a/packages/domain-events/src/Domain/Event/TransitionRequestedEvent.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { DomainEventInterface } from './DomainEventInterface' - -import { TransitionRequestedEventPayload } from './TransitionRequestedEventPayload' - -export interface TransitionRequestedEvent extends DomainEventInterface { - type: 'TRANSITION_REQUESTED' - payload: TransitionRequestedEventPayload -} diff --git a/packages/domain-events/src/Domain/Event/TransitionRequestedEventPayload.ts b/packages/domain-events/src/Domain/Event/TransitionRequestedEventPayload.ts deleted file mode 100644 index 7004d90b2..000000000 --- a/packages/domain-events/src/Domain/Event/TransitionRequestedEventPayload.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface TransitionRequestedEventPayload { - userUuid: string - type: 'items' | 'revisions' - timestamp: number -} diff --git a/packages/domain-events/src/Domain/Event/TransitionStatusUpdatedEvent.ts b/packages/domain-events/src/Domain/Event/TransitionStatusUpdatedEvent.ts deleted file mode 100644 index 73efbbfe4..000000000 --- a/packages/domain-events/src/Domain/Event/TransitionStatusUpdatedEvent.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { DomainEventInterface } from './DomainEventInterface' - -import { TransitionStatusUpdatedEventPayload } from './TransitionStatusUpdatedEventPayload' - -export interface TransitionStatusUpdatedEvent extends DomainEventInterface { - type: 'TRANSITION_STATUS_UPDATED' - payload: TransitionStatusUpdatedEventPayload -} diff --git a/packages/domain-events/src/Domain/Event/TransitionStatusUpdatedEventPayload.ts b/packages/domain-events/src/Domain/Event/TransitionStatusUpdatedEventPayload.ts deleted file mode 100644 index fa448285f..000000000 --- a/packages/domain-events/src/Domain/Event/TransitionStatusUpdatedEventPayload.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface TransitionStatusUpdatedEventPayload { - userUuid: string - transitionType: 'items' | 'revisions' - transitionTimestamp: number - status: string - page?: number -} diff --git a/packages/domain-events/src/Domain/index.ts b/packages/domain-events/src/Domain/index.ts index cb1a00e7a..3fabdff6d 100644 --- a/packages/domain-events/src/Domain/index.ts +++ b/packages/domain-events/src/Domain/index.ts @@ -98,10 +98,6 @@ export * from './Event/SubscriptionRevertRequestedEvent' export * from './Event/SubscriptionRevertRequestedEventPayload' export * from './Event/SubscriptionSyncRequestedEvent' export * from './Event/SubscriptionSyncRequestedEventPayload' -export * from './Event/TransitionRequestedEvent' -export * from './Event/TransitionRequestedEventPayload' -export * from './Event/TransitionStatusUpdatedEvent' -export * from './Event/TransitionStatusUpdatedEventPayload' export * from './Event/UserAddedToSharedVaultEvent' export * from './Event/UserAddedToSharedVaultEventPayload' export * from './Event/UserDesignatedAsSurvivorInSharedVaultEvent' diff --git a/packages/files/src/Infra/InversifyExpress/Middleware/ValetTokenAuthMiddleware.spec.ts b/packages/files/src/Infra/InversifyExpress/Middleware/ValetTokenAuthMiddleware.spec.ts index f5de824c9..4b1e2648b 100644 --- a/packages/files/src/Infra/InversifyExpress/Middleware/ValetTokenAuthMiddleware.spec.ts +++ b/packages/files/src/Infra/InversifyExpress/Middleware/ValetTokenAuthMiddleware.spec.ts @@ -223,27 +223,4 @@ describe('ValetTokenAuthMiddleware', () => { expect(next).toHaveBeenCalledWith(error) }) - - it('should throw an error if the valet token indicates an ongoing transition', async () => { - request.headers['x-valet-token'] = 'valet-token' - - tokenDecoder.decodeToken = jest.fn().mockReturnValue({ - userUuid: '1-2-3', - permittedResources: [ - { - remoteIdentifier: '00000000-0000-0000-0000-000000000000', - unencryptedFileSize: 30, - }, - ], - permittedOperation: 'write', - uploadBytesLimit: -1, - uploadBytesUsed: 80, - ongoingTransition: true, - }) - - await createMiddleware().handler(request, response, next) - - expect(response.status).toHaveBeenCalledWith(500) - expect(next).not.toHaveBeenCalled() - }) }) diff --git a/packages/files/src/Infra/InversifyExpress/Middleware/ValetTokenAuthMiddleware.ts b/packages/files/src/Infra/InversifyExpress/Middleware/ValetTokenAuthMiddleware.ts index 12ad9989a..8cb5c842d 100644 --- a/packages/files/src/Infra/InversifyExpress/Middleware/ValetTokenAuthMiddleware.ts +++ b/packages/files/src/Infra/InversifyExpress/Middleware/ValetTokenAuthMiddleware.ts @@ -46,19 +46,6 @@ export class ValetTokenAuthMiddleware extends BaseMiddleware { return } - if (valetTokenData.ongoingTransition === true) { - this.logger.error(`Cannot perform file operations for user ${valetTokenData.userUuid} during transition`) - - response.status(500).send({ - error: { - tag: 'ongoing-transition', - message: 'Cannot perform file operations during transition', - }, - }) - - return - } - for (const resource of valetTokenData.permittedResources) { const resourceUuidOrError = Uuid.create(resource.remoteIdentifier) if (resourceUuidOrError.isFailed()) { diff --git a/packages/home-server/.env.sample b/packages/home-server/.env.sample index c3e33576e..33bc977b0 100644 --- a/packages/home-server/.env.sample +++ b/packages/home-server/.env.sample @@ -9,10 +9,3 @@ PSEUDO_KEY_PARAMS_KEY= VALET_TOKEN_SECRET= FILES_SERVER_URL= - -SECONDARY_DB_ENABLED=false -MONGO_HOST=localhost -MONGO_PORT=27017 -MONGO_USERNAME=standardnotes -MONGO_PASSWORD=standardnotes -MONGO_DATABASE=standardnotes diff --git a/packages/revisions/.env.sample b/packages/revisions/.env.sample index 7081089d5..7788af870 100644 --- a/packages/revisions/.env.sample +++ b/packages/revisions/.env.sample @@ -17,20 +17,7 @@ DB_DEBUG_LEVEL=all # "all" | "query" | "schema" | "error" | "warn" | "info" | "l DB_MIGRATIONS_PATH=dist/migrations/*.js DB_TYPE=mysql -REDIS_URL=redis://cache -CACHE_TYPE=redis - -SNS_TOPIC_ARN= -SNS_AWS_REGION= SQS_QUEUE_URL= SQS_AWS_REGION= S3_AWS_REGION= S3_BACKUP_BUCKET_NAME= - -# (Optional) Mongo Setup -SECONDARY_DB_ENABLED=false -MONGO_HOST= -MONGO_PORT= -MONGO_USERNAME= -MONGO_PASSWORD= -MONGO_DATABASE= diff --git a/packages/revisions/package.json b/packages/revisions/package.json index d113d1530..d393e5ed4 100644 --- a/packages/revisions/package.json +++ b/packages/revisions/package.json @@ -42,7 +42,6 @@ "inversify": "^6.0.1", "inversify-express-utils": "^6.4.3", "ioredis": "^5.3.2", - "mongodb": "^6.0.0", "mysql2": "^3.0.1", "reflect-metadata": "0.1.13", "sqlite3": "^5.1.6", diff --git a/packages/revisions/src/Bootstrap/Container.ts b/packages/revisions/src/Bootstrap/Container.ts index 8bb8f0240..07736e23d 100644 --- a/packages/revisions/src/Bootstrap/Container.ts +++ b/packages/revisions/src/Bootstrap/Container.ts @@ -4,11 +4,9 @@ import { MapperInterface, ServiceIdentifier, } from '@standardnotes/domain-core' -import Redis from 'ioredis' import { Container, interfaces } from 'inversify' -import { MongoRepository, Repository } from 'typeorm' +import { Repository } from 'typeorm' import * as winston from 'winston' -import { SNSClient, SNSClientConfig } from '@aws-sdk/client-sns' import { Revision } from '../Domain/Revision/Revision' import { RevisionMetadata } from '../Domain/Revision/RevisionMetadata' @@ -38,7 +36,6 @@ import { SQSEventMessageHandler, DirectCallEventMessageHandler, DirectCallDomainEventPublisher, - SNSOpenTelemetryDomainEventPublisher, SQSOpenTelemetryDomainEventSubscriber, } from '@standardnotes/domain-events-infra' import { DumpRepositoryInterface } from '../Domain/Dump/DumpRepositoryInterface' @@ -51,30 +48,18 @@ import { S3DumpRepository } from '../Infra/S3/S3ItemDumpRepository' import { RevisionItemStringMapper } from '../Mapping/Backup/RevisionItemStringMapper' import { BaseRevisionsController } from '../Infra/InversifyExpress/Base/BaseRevisionsController' import { Transform } from 'stream' -import { MongoDBRevision } from '../Infra/TypeORM/MongoDB/MongoDBRevision' -import { MongoDBRevisionRepository } from '../Infra/TypeORM/MongoDB/MongoDBRevisionRepository' import { SQLLegacyRevisionMetadataPersistenceMapper } from '../Mapping/Persistence/SQL/SQLLegacyRevisionMetadataPersistenceMapper' import { SQLLegacyRevisionPersistenceMapper } from '../Mapping/Persistence/SQL/SQLLegacyRevisionPersistenceMapper' -import { MongoDBRevisionMetadataPersistenceMapper } from '../Mapping/Persistence/MongoDB/MongoDBRevisionMetadataPersistenceMapper' -import { MongoDBRevisionPersistenceMapper } from '../Mapping/Persistence/MongoDB/MongoDBRevisionPersistenceMapper' import { RevisionHttpMapper } from '../Mapping/Http/RevisionHttpMapper' -import { RevisionRepositoryResolverInterface } from '../Domain/Revision/RevisionRepositoryResolverInterface' -import { TypeORMRevisionRepositoryResolver } from '../Infra/TypeORM/TypeORMRevisionRepositoryResolver' import { RevisionMetadataHttpRepresentation } from '../Mapping/Http/RevisionMetadataHttpRepresentation' import { RevisionHttpRepresentation } from '../Mapping/Http/RevisionHttpRepresentation' -import { TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser } from '../Domain/UseCase/Transition/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser' -import { DomainEventFactoryInterface } from '../Domain/Event/DomainEventFactoryInterface' -import { DomainEventFactory } from '../Domain/Event/DomainEventFactory' import { SQLRevision } from '../Infra/TypeORM/SQL/SQLRevision' import { SQLRevisionRepository } from '../Infra/TypeORM/SQL/SQLRevisionRepository' import { SQLRevisionMetadataPersistenceMapper } from '../Mapping/Persistence/SQL/SQLRevisionMetadataPersistenceMapper' import { SQLRevisionPersistenceMapper } from '../Mapping/Persistence/SQL/SQLRevisionPersistenceMapper' import { RemoveRevisionsFromSharedVault } from '../Domain/UseCase/RemoveRevisionsFromSharedVault/RemoveRevisionsFromSharedVault' import { ItemRemovedFromSharedVaultEventHandler } from '../Domain/Handler/ItemRemovedFromSharedVaultEventHandler' -import { TransitionRequestedEventHandler } from '../Domain/Handler/TransitionRequestedEventHandler' import { SharedVaultRemovedEventHandler } from '../Domain/Handler/SharedVaultRemovedEventHandler' -import { TransitionRepositoryInterface } from '../Domain/Transition/TransitionRepositoryInterface' -import { RedisTransitionRepository } from '../Infra/Redis/RedisTransitionRepository' import { CreateRevisionFromDump } from '../Domain/UseCase/CreateRevisionFromDump/CreateRevisionFromDump' export class ContainerConfigLoader { @@ -95,8 +80,6 @@ export class ContainerConfigLoader { const isConfiguredForHomeServer = env.get('MODE', true) === 'home-server' const isConfiguredForSelfHosting = env.get('MODE', true) === 'self-hosted' const isConfiguredForHomeServerOrSelfHosting = isConfiguredForHomeServer || isConfiguredForSelfHosting - const isSecondaryDatabaseEnabled = env.get('SECONDARY_DB_ENABLED', true) === 'true' - const isConfiguredForInMemoryCache = env.get('CACHE_TYPE', true) === 'memory' const container = new Container({ defaultScope: 'Singleton', @@ -106,22 +89,6 @@ export class ContainerConfigLoader { .bind(TYPES.Revisions_IS_CONFIGURED_FOR_HOME_SERVER_OR_SELF_HOSTING) .toConstantValue(isConfiguredForHomeServerOrSelfHosting) - if (!isConfiguredForInMemoryCache) { - const redisUrl = env.get('REDIS_URL') - const isRedisInClusterMode = redisUrl.indexOf(',') > 0 - let redis - if (isRedisInClusterMode) { - redis = new Redis.Cluster(redisUrl.split(',')) - } else { - redis = new Redis(redisUrl) - } - - container.bind(TYPES.Revisions_Redis).toConstantValue(redis) - container - .bind(TYPES.Revisions_TransitionStatusRepository) - .toConstantValue(new RedisTransitionRepository(container.get(TYPES.Revisions_Redis))) - } - let logger: winston.Logger if (configuration?.logger) { logger = configuration.logger as winston.Logger @@ -150,41 +117,10 @@ export class ContainerConfigLoader { if (!isConfiguredForHomeServer) { // env vars - container.bind(TYPES.Revisions_SNS_TOPIC_ARN).toConstantValue(env.get('SNS_TOPIC_ARN')) - container.bind(TYPES.Revisions_SNS_AWS_REGION).toConstantValue(env.get('SNS_AWS_REGION', true)) container.bind(TYPES.Revisions_SQS_QUEUE_URL).toConstantValue(env.get('SQS_QUEUE_URL')) container.bind(TYPES.Revisions_S3_AWS_REGION).toConstantValue(env.get('S3_AWS_REGION', true)) container.bind(TYPES.Revisions_S3_BACKUP_BUCKET_NAME).toConstantValue(env.get('S3_BACKUP_BUCKET_NAME', true)) - container.bind(TYPES.Revisions_SNS).toDynamicValue((context: interfaces.Context) => { - const env: Env = context.container.get(TYPES.Revisions_Env) - - const snsConfig: SNSClientConfig = { - apiVersion: 'latest', - region: env.get('SNS_AWS_REGION', true), - } - if (env.get('SNS_ENDPOINT', true)) { - snsConfig.endpoint = env.get('SNS_ENDPOINT', true) - } - if (env.get('SNS_ACCESS_KEY_ID', true) && env.get('SNS_SECRET_ACCESS_KEY', true)) { - snsConfig.credentials = { - accessKeyId: env.get('SNS_ACCESS_KEY_ID', true), - secretAccessKey: env.get('SNS_SECRET_ACCESS_KEY', true), - } - } - - return new SNSClient(snsConfig) - }) - - container - .bind(TYPES.Revisions_DomainEventPublisher) - .toDynamicValue((context: interfaces.Context) => { - return new SNSOpenTelemetryDomainEventPublisher( - context.container.get(TYPES.Revisions_SNS), - context.container.get(TYPES.Revisions_SNS_TOPIC_ARN), - ) - }) - container.bind(TYPES.Revisions_SQS).toDynamicValue((context: interfaces.Context) => { const env: Env = context.container.get(TYPES.Revisions_Env) @@ -223,10 +159,6 @@ export class ContainerConfigLoader { .toConstantValue(directCallDomainEventPublisher) } - container - .bind(TYPES.Revisions_DomainEventFactory) - .toConstantValue(new DomainEventFactory(container.get(TYPES.Revisions_Timer))) - // Map container .bind>( @@ -242,14 +174,6 @@ export class ContainerConfigLoader { container .bind>(TYPES.Revisions_SQLRevisionPersistenceMapper) .toConstantValue(new SQLRevisionPersistenceMapper(container.get(TYPES.Revisions_Timer))) - container - .bind>( - TYPES.Revisions_MongoDBRevisionMetadataPersistenceMapper, - ) - .toConstantValue(new MongoDBRevisionMetadataPersistenceMapper()) - container - .bind>(TYPES.Revisions_MongoDBRevisionPersistenceMapper) - .toConstantValue(new MongoDBRevisionPersistenceMapper(container.get(TYPES.Revisions_Timer))) // ORM container @@ -284,36 +208,6 @@ export class ContainerConfigLoader { ), ) - if (isSecondaryDatabaseEnabled) { - container - .bind>(TYPES.Revisions_ORMMongoRevisionRepository) - .toConstantValue(appDataSource.getMongoRepository(MongoDBRevision)) - - container - .bind(TYPES.Revisions_MongoDBRevisionRepository) - .toConstantValue( - new MongoDBRevisionRepository( - container.get>(TYPES.Revisions_ORMMongoRevisionRepository), - container.get>( - TYPES.Revisions_MongoDBRevisionMetadataPersistenceMapper, - ), - container.get>(TYPES.Revisions_MongoDBRevisionPersistenceMapper), - container.get(TYPES.Revisions_Logger), - ), - ) - } - - container - .bind(TYPES.Revisions_RevisionRepositoryResolver) - .toConstantValue( - new TypeORMRevisionRepositoryResolver( - container.get(TYPES.Revisions_SQLRevisionRepository), - isSecondaryDatabaseEnabled - ? container.get(TYPES.Revisions_MongoDBRevisionRepository) - : null, - ), - ) - container .bind(TYPES.Revisions_GetRequiredRoleToViewRevision) .toDynamicValue((context: interfaces.Context) => { @@ -351,56 +245,28 @@ export class ContainerConfigLoader { container .bind(TYPES.Revisions_GetRevisionsMetada) .toConstantValue( - new GetRevisionsMetada( - container.get(TYPES.Revisions_RevisionRepositoryResolver), - ), + new GetRevisionsMetada(container.get(TYPES.Revisions_SQLRevisionRepository)), ) container .bind(TYPES.Revisions_GetRevision) .toConstantValue( - new GetRevision(container.get(TYPES.Revisions_RevisionRepositoryResolver)), + new GetRevision(container.get(TYPES.Revisions_SQLRevisionRepository)), ) container .bind(TYPES.Revisions_DeleteRevision) .toConstantValue( - new DeleteRevision( - container.get(TYPES.Revisions_RevisionRepositoryResolver), - ), + new DeleteRevision(container.get(TYPES.Revisions_SQLRevisionRepository)), ) container .bind(TYPES.Revisions_CopyRevisions) .toConstantValue( - new CopyRevisions( - container.get(TYPES.Revisions_RevisionRepositoryResolver), - ), - ) - container - .bind( - TYPES.Revisions_TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser, - ) - .toConstantValue( - new TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser( - container.get(TYPES.Revisions_SQLRevisionRepository), - isSecondaryDatabaseEnabled - ? container.get(TYPES.Revisions_MongoDBRevisionRepository) - : null, - isConfiguredForInMemoryCache - ? null - : container.get(TYPES.Revisions_TransitionStatusRepository), - container.get(TYPES.Revisions_Timer), - container.get(TYPES.Revisions_Logger), - env.get('MIGRATION_BATCH_SIZE', true) ? +env.get('MIGRATION_BATCH_SIZE', true) : 100, - container.get(TYPES.Revisions_DomainEventPublisher), - container.get(TYPES.Revisions_DomainEventFactory), - ), + new CopyRevisions(container.get(TYPES.Revisions_SQLRevisionRepository)), ) container .bind(TYPES.Revisions_RemoveRevisionsFromSharedVault) .toConstantValue( new RemoveRevisionsFromSharedVault( - isSecondaryDatabaseEnabled - ? container.get(TYPES.Revisions_MongoDBRevisionRepository) - : container.get(TYPES.Revisions_SQLRevisionRepository), + container.get(TYPES.Revisions_SQLRevisionRepository), ), ) container @@ -408,7 +274,7 @@ export class ContainerConfigLoader { .toConstantValue( new CreateRevisionFromDump( container.get(TYPES.Revisions_DumpRepository), - container.get(TYPES.Revisions_RevisionRepositoryResolver), + container.get(TYPES.Revisions_SQLRevisionRepository), ), ) @@ -448,7 +314,7 @@ export class ContainerConfigLoader { .bind(TYPES.Revisions_AccountDeletionRequestedEventHandler) .toConstantValue( new AccountDeletionRequestedEventHandler( - container.get(TYPES.Revisions_RevisionRepositoryResolver), + container.get(TYPES.Revisions_SQLRevisionRepository), container.get(TYPES.Revisions_Logger), ), ) @@ -468,17 +334,6 @@ export class ContainerConfigLoader { container.get(TYPES.Revisions_Logger), ), ) - container - .bind(TYPES.Revisions_TransitionRequestedEventHandler) - .toConstantValue( - new TransitionRequestedEventHandler( - false, - container.get( - TYPES.Revisions_TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser, - ), - container.get(TYPES.Revisions_Logger), - ), - ) container .bind(TYPES.Revisions_SharedVaultRemovedEventHandler) .toConstantValue( @@ -493,7 +348,6 @@ export class ContainerConfigLoader { ['ACCOUNT_DELETION_REQUESTED', container.get(TYPES.Revisions_AccountDeletionRequestedEventHandler)], ['REVISIONS_COPY_REQUESTED', container.get(TYPES.Revisions_RevisionsCopyRequestedEventHandler)], ['ITEM_REMOVED_FROM_SHARED_VAULT', container.get(TYPES.Revisions_ItemRemovedFromSharedVaultEventHandler)], - ['TRANSITION_REQUESTED', container.get(TYPES.Revisions_TransitionRequestedEventHandler)], ['SHARED_VAULT_REMOVED', container.get(TYPES.Revisions_SharedVaultRemovedEventHandler)], ]) diff --git a/packages/revisions/src/Bootstrap/DataSource.ts b/packages/revisions/src/Bootstrap/DataSource.ts index 0601a8d19..b17a0be0e 100644 --- a/packages/revisions/src/Bootstrap/DataSource.ts +++ b/packages/revisions/src/Bootstrap/DataSource.ts @@ -1,16 +1,14 @@ -import { DataSource, EntityTarget, LoggerOptions, MongoRepository, ObjectLiteral, Repository } from 'typeorm' +import { DataSource, EntityTarget, LoggerOptions, ObjectLiteral, Repository } from 'typeorm' import { MysqlConnectionOptions } from 'typeorm/driver/mysql/MysqlConnectionOptions' import { SQLLegacyRevision } from '../Infra/TypeORM/SQL/SQLLegacyRevision' import { Env } from './Env' import { SqliteConnectionOptions } from 'typeorm/driver/sqlite/SqliteConnectionOptions' -import { MongoDBRevision } from '../Infra/TypeORM/MongoDB/MongoDBRevision' import { SQLRevision } from '../Infra/TypeORM/SQL/SQLRevision' export class AppDataSource { private _dataSource: DataSource | undefined - private _secondaryDataSource: DataSource | undefined constructor( private configuration: { @@ -27,43 +25,8 @@ export class AppDataSource { return this._dataSource.getRepository(target) } - getMongoRepository(target: EntityTarget): MongoRepository { - if (!this._secondaryDataSource) { - throw new Error('Secondary DataSource not initialized') - } - - return this._secondaryDataSource.getMongoRepository(target) - } - async initialize(): Promise { await this.dataSource.initialize() - const secondaryDataSource = this.secondaryDataSource - if (secondaryDataSource) { - await secondaryDataSource.initialize() - } - } - - get secondaryDataSource(): DataSource | undefined { - this.configuration.env.load() - - if (this.configuration.env.get('SECONDARY_DB_ENABLED', true) !== 'true') { - return undefined - } - - this._secondaryDataSource = new DataSource({ - type: 'mongodb', - host: this.configuration.env.get('MONGO_HOST'), - authSource: 'admin', - port: parseInt(this.configuration.env.get('MONGO_PORT')), - username: this.configuration.env.get('MONGO_USERNAME'), - password: this.configuration.env.get('MONGO_PASSWORD', true), - database: this.configuration.env.get('MONGO_DATABASE'), - entities: [MongoDBRevision], - retryWrites: false, - synchronize: true, - }) - - return this._secondaryDataSource } get dataSource(): DataSource { diff --git a/packages/revisions/src/Bootstrap/Types.ts b/packages/revisions/src/Bootstrap/Types.ts index 1a2d116e9..f14f7f9ce 100644 --- a/packages/revisions/src/Bootstrap/Types.ts +++ b/packages/revisions/src/Bootstrap/Types.ts @@ -13,22 +13,15 @@ const TYPES = { Revisions_SQLRevisionMetadataPersistenceMapper: Symbol.for('Revisions_SQLRevisionMetadataPersistenceMapper'), Revisions_SQLLegacyRevisionPersistenceMapper: Symbol.for('Revisions_SQLLegacyRevisionPersistenceMapper'), Revisions_SQLRevisionPersistenceMapper: Symbol.for('Revisions_SQLRevisionPersistenceMapper'), - Revisions_MongoDBRevisionMetadataPersistenceMapper: Symbol.for('Revisions_MongoDBRevisionMetadataPersistenceMapper'), - Revisions_MongoDBRevisionPersistenceMapper: Symbol.for('Revisions_MongoDBRevisionPersistenceMapper'), Revisions_RevisionItemStringMapper: Symbol.for('Revisions_RevisionItemStringMapper'), Revisions_RevisionHttpMapper: Symbol.for('Revisions_RevisionHttpMapper'), Revisions_RevisionMetadataHttpMapper: Symbol.for('Revisions_RevisionMetadataHttpMapper'), // ORM Revisions_ORMRevisionRepository: Symbol.for('Revisions_ORMRevisionRepository'), Revisions_ORMLegacyRevisionRepository: Symbol.for('Revisions_ORMLegacyRevisionRepository'), - // Mongo - Revisions_ORMMongoRevisionRepository: Symbol.for('Revisions_ORMMongoRevisionRepository'), // Repositories Revisions_SQLRevisionRepository: Symbol.for('Revisions_SQLRevisionRepository'), - Revisions_MongoDBRevisionRepository: Symbol.for('Revisions_MongoDBRevisionRepository'), Revisions_DumpRepository: Symbol.for('Revisions_DumpRepository'), - Revisions_RevisionRepositoryResolver: Symbol.for('Revisions_RevisionRepositoryResolver'), - Revisions_TransitionStatusRepository: Symbol.for('Revisions_TransitionStatusRepository'), // env vars Revisions_AUTH_JWT_SECRET: Symbol.for('Revisions_AUTH_JWT_SECRET'), Revisions_SQS_QUEUE_URL: Symbol.for('Revisions_SQS_QUEUE_URL'), @@ -47,9 +40,6 @@ const TYPES = { Revisions_DeleteRevision: Symbol.for('Revisions_DeleteRevision'), Revisions_CopyRevisions: Symbol.for('Revisions_CopyRevisions'), Revisions_GetRequiredRoleToViewRevision: Symbol.for('Revisions_GetRequiredRoleToViewRevision'), - Revisions_TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser: Symbol.for( - 'Revisions_TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser', - ), Revisions_RemoveRevisionsFromSharedVault: Symbol.for('Revisions_RemoveRevisionsFromSharedVault'), Revisions_CreateRevisionFromDump: Symbol.for('Revisions_CreateRevisionFromDump'), // Controller @@ -61,7 +51,6 @@ const TYPES = { Revisions_AccountDeletionRequestedEventHandler: Symbol.for('Revisions_AccountDeletionRequestedEventHandler'), Revisions_RevisionsCopyRequestedEventHandler: Symbol.for('Revisions_RevisionsCopyRequestedEventHandler'), Revisions_ItemRemovedFromSharedVaultEventHandler: Symbol.for('Revisions_ItemRemovedFromSharedVaultEventHandler'), - Revisions_TransitionRequestedEventHandler: Symbol.for('Revisions_TransitionRequestedEventHandler'), Revisions_SharedVaultRemovedEventHandler: Symbol.for('Revisions_SharedVaultRemovedEventHandler'), // Services Revisions_CrossServiceTokenDecoder: Symbol.for('Revisions_CrossServiceTokenDecoder'), diff --git a/packages/revisions/src/Domain/Event/DomainEventFactory.ts b/packages/revisions/src/Domain/Event/DomainEventFactory.ts deleted file mode 100644 index 4d0265241..000000000 --- a/packages/revisions/src/Domain/Event/DomainEventFactory.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* istanbul ignore file */ -import { DomainEventService, TransitionStatusUpdatedEvent } from '@standardnotes/domain-events' -import { TimerInterface } from '@standardnotes/time' -import { DomainEventFactoryInterface } from './DomainEventFactoryInterface' - -export class DomainEventFactory implements DomainEventFactoryInterface { - constructor(private timer: TimerInterface) {} - - createTransitionStatusUpdatedEvent(dto: { - userUuid: string - transitionType: 'items' | 'revisions' - transitionTimestamp: number - status: string - }): TransitionStatusUpdatedEvent { - return { - type: 'TRANSITION_STATUS_UPDATED', - createdAt: this.timer.getUTCDate(), - meta: { - correlation: { - userIdentifier: dto.userUuid, - userIdentifierType: 'uuid', - }, - origin: DomainEventService.Revisions, - }, - payload: dto, - } - } -} diff --git a/packages/revisions/src/Domain/Event/DomainEventFactoryInterface.ts b/packages/revisions/src/Domain/Event/DomainEventFactoryInterface.ts deleted file mode 100644 index 858005fbb..000000000 --- a/packages/revisions/src/Domain/Event/DomainEventFactoryInterface.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { TransitionStatusUpdatedEvent } from '@standardnotes/domain-events' - -export interface DomainEventFactoryInterface { - createTransitionStatusUpdatedEvent(dto: { - userUuid: string - transitionType: 'items' | 'revisions' - transitionTimestamp: number - status: string - }): TransitionStatusUpdatedEvent -} diff --git a/packages/revisions/src/Domain/Handler/AccountDeletionRequestedEventHandler.spec.ts b/packages/revisions/src/Domain/Handler/AccountDeletionRequestedEventHandler.spec.ts index 12bf06e0c..f3901c313 100644 --- a/packages/revisions/src/Domain/Handler/AccountDeletionRequestedEventHandler.spec.ts +++ b/packages/revisions/src/Domain/Handler/AccountDeletionRequestedEventHandler.spec.ts @@ -4,23 +4,18 @@ import { AccountDeletionRequestedEvent } from '@standardnotes/domain-events' import { Logger } from 'winston' import { AccountDeletionRequestedEventHandler } from './AccountDeletionRequestedEventHandler' import { RevisionRepositoryInterface } from '../Revision/RevisionRepositoryInterface' -import { RevisionRepositoryResolverInterface } from '../Revision/RevisionRepositoryResolverInterface' describe('AccountDeletionRequestedEventHandler', () => { let revisionRepository: RevisionRepositoryInterface - let revisionRepositoryResolver: RevisionRepositoryResolverInterface let logger: Logger let event: AccountDeletionRequestedEvent - const createHandler = () => new AccountDeletionRequestedEventHandler(revisionRepositoryResolver, logger) + const createHandler = () => new AccountDeletionRequestedEventHandler(revisionRepository, logger) beforeEach(() => { revisionRepository = {} as jest.Mocked revisionRepository.removeByUserUuid = jest.fn() - revisionRepositoryResolver = {} as jest.Mocked - revisionRepositoryResolver.resolve = jest.fn().mockReturnValue(revisionRepository) - logger = {} as jest.Mocked logger.info = jest.fn() logger.warn = jest.fn() @@ -32,7 +27,6 @@ describe('AccountDeletionRequestedEventHandler', () => { userUuid: '2-3-4', userCreatedAtTimestamp: 1, regularSubscriptionUuid: '1-2-3', - roleNames: ['CORE_USER'], } }) @@ -49,13 +43,4 @@ describe('AccountDeletionRequestedEventHandler', () => { expect(revisionRepository.removeByUserUuid).not.toHaveBeenCalled() }) - - it('should do nothing if role names are not valid', async () => { - event.payload.userUuid = '84c0f8e8-544a-4c7e-9adf-26209303bc1d' - event.payload.roleNames = ['INVALID_ROLE_NAME'] - - await createHandler().handle(event) - - expect(revisionRepository.removeByUserUuid).not.toHaveBeenCalled() - }) }) diff --git a/packages/revisions/src/Domain/Handler/AccountDeletionRequestedEventHandler.ts b/packages/revisions/src/Domain/Handler/AccountDeletionRequestedEventHandler.ts index 129705f31..55e4dcb64 100644 --- a/packages/revisions/src/Domain/Handler/AccountDeletionRequestedEventHandler.ts +++ b/packages/revisions/src/Domain/Handler/AccountDeletionRequestedEventHandler.ts @@ -1,12 +1,11 @@ -import { RoleNameCollection, Uuid } from '@standardnotes/domain-core' +import { Uuid } from '@standardnotes/domain-core' import { AccountDeletionRequestedEvent, DomainEventHandlerInterface } from '@standardnotes/domain-events' import { Logger } from 'winston' - -import { RevisionRepositoryResolverInterface } from '../Revision/RevisionRepositoryResolverInterface' +import { RevisionRepositoryInterface } from '../Revision/RevisionRepositoryInterface' export class AccountDeletionRequestedEventHandler implements DomainEventHandlerInterface { constructor( - private revisionRepositoryResolver: RevisionRepositoryResolverInterface, + private revisionRepository: RevisionRepositoryInterface, private logger: Logger, ) {} @@ -19,17 +18,7 @@ export class AccountDeletionRequestedEventHandler implements DomainEventHandlerI } const userUuid = userUuidOrError.getValue() - const roleNamesOrError = RoleNameCollection.create(event.payload.roleNames) - if (roleNamesOrError.isFailed()) { - this.logger.error(`Failed account cleanup: ${roleNamesOrError.getError()}`) - - return - } - const roleNames = roleNamesOrError.getValue() - - const revisionRepository = this.revisionRepositoryResolver.resolve(roleNames) - - await revisionRepository.removeByUserUuid(userUuid) + await this.revisionRepository.removeByUserUuid(userUuid) this.logger.info(`Finished account cleanup for user: ${event.payload.userUuid}`) } diff --git a/packages/revisions/src/Domain/Handler/ItemDumpedEventHandler.ts b/packages/revisions/src/Domain/Handler/ItemDumpedEventHandler.ts index 9b7e844c7..e2d93ad73 100644 --- a/packages/revisions/src/Domain/Handler/ItemDumpedEventHandler.ts +++ b/packages/revisions/src/Domain/Handler/ItemDumpedEventHandler.ts @@ -12,7 +12,6 @@ export class ItemDumpedEventHandler implements DomainEventHandlerInterface { async handle(event: ItemDumpedEvent): Promise { const result = await this.createRevisionFromDump.execute({ filePath: event.payload.fileDumpPath, - roleNames: event.payload.roleNames, }) if (result.isFailed()) { diff --git a/packages/revisions/src/Domain/Handler/RevisionsCopyRequestedEventHandler.spec.ts b/packages/revisions/src/Domain/Handler/RevisionsCopyRequestedEventHandler.spec.ts index 80ba973f5..d729f17c7 100644 --- a/packages/revisions/src/Domain/Handler/RevisionsCopyRequestedEventHandler.spec.ts +++ b/packages/revisions/src/Domain/Handler/RevisionsCopyRequestedEventHandler.spec.ts @@ -23,7 +23,6 @@ describe('RevisionsCopyRequestedEventHandler', () => { event.payload = { newItemUuid: '1-2-3', originalItemUuid: '2-3-4', - roleNames: ['CORE_USER'], } }) diff --git a/packages/revisions/src/Domain/Handler/RevisionsCopyRequestedEventHandler.ts b/packages/revisions/src/Domain/Handler/RevisionsCopyRequestedEventHandler.ts index e62189c26..ebbba971d 100644 --- a/packages/revisions/src/Domain/Handler/RevisionsCopyRequestedEventHandler.ts +++ b/packages/revisions/src/Domain/Handler/RevisionsCopyRequestedEventHandler.ts @@ -12,7 +12,6 @@ export class RevisionsCopyRequestedEventHandler implements DomainEventHandlerInt const result = await this.copyRevisions.execute({ newItemUuid: event.payload.newItemUuid, originalItemUuid: event.payload.originalItemUuid, - roleNames: event.payload.roleNames, }) if (result.isFailed()) { diff --git a/packages/revisions/src/Domain/Handler/TransitionRequestedEventHandler.ts b/packages/revisions/src/Domain/Handler/TransitionRequestedEventHandler.ts deleted file mode 100644 index 07518312d..000000000 --- a/packages/revisions/src/Domain/Handler/TransitionRequestedEventHandler.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { DomainEventHandlerInterface, TransitionRequestedEvent } from '@standardnotes/domain-events' -import { Logger } from 'winston' -import { TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser } from '../UseCase/Transition/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser' - -export class TransitionRequestedEventHandler implements DomainEventHandlerInterface { - constructor( - private disabled: boolean, - private transitionRevisionsFromPrimaryToSecondaryDatabaseForUser: TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser, - private logger: Logger, - ) {} - - async handle(event: TransitionRequestedEvent): Promise { - if (this.disabled) { - return - } - - if (event.payload.type !== 'revisions') { - return - } - - const result = await this.transitionRevisionsFromPrimaryToSecondaryDatabaseForUser.execute({ - userUuid: event.payload.userUuid, - timestamp: event.payload.timestamp, - }) - - if (result.isFailed()) { - this.logger.error(`[${event.payload.userUuid}] Failed to transition: ${result.getError()}`) - } - } -} diff --git a/packages/revisions/src/Domain/Revision/RevisionRepositoryResolverInterface.ts b/packages/revisions/src/Domain/Revision/RevisionRepositoryResolverInterface.ts deleted file mode 100644 index 1c0c4e251..000000000 --- a/packages/revisions/src/Domain/Revision/RevisionRepositoryResolverInterface.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { RoleNameCollection } from '@standardnotes/domain-core' - -import { RevisionRepositoryInterface } from './RevisionRepositoryInterface' - -export interface RevisionRepositoryResolverInterface { - resolve(roleNames: RoleNameCollection): RevisionRepositoryInterface -} diff --git a/packages/revisions/src/Domain/Transition/TransitionRepositoryInterface.ts b/packages/revisions/src/Domain/Transition/TransitionRepositoryInterface.ts deleted file mode 100644 index dac285d7e..000000000 --- a/packages/revisions/src/Domain/Transition/TransitionRepositoryInterface.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface TransitionRepositoryInterface { - getPagingProgress(userUuid: string): Promise - setPagingProgress(userUuid: string, progress: number): Promise - getIntegrityProgress(userUuid: string): Promise - setIntegrityProgress(userUuid: string, progress: number): Promise -} diff --git a/packages/revisions/src/Domain/UseCase/CopyRevisions/CopyRevisions.spec.ts b/packages/revisions/src/Domain/UseCase/CopyRevisions/CopyRevisions.spec.ts index 96d397a87..7d5e3e5fc 100644 --- a/packages/revisions/src/Domain/UseCase/CopyRevisions/CopyRevisions.spec.ts +++ b/packages/revisions/src/Domain/UseCase/CopyRevisions/CopyRevisions.spec.ts @@ -2,21 +2,16 @@ import { Result } from '@standardnotes/domain-core' import { Revision } from '../../Revision/Revision' import { RevisionRepositoryInterface } from '../../Revision/RevisionRepositoryInterface' import { CopyRevisions } from './CopyRevisions' -import { RevisionRepositoryResolverInterface } from '../../Revision/RevisionRepositoryResolverInterface' describe('CopyRevisions', () => { let revisionRepository: RevisionRepositoryInterface - let revisionRepositoryResolver: RevisionRepositoryResolverInterface - const createUseCase = () => new CopyRevisions(revisionRepositoryResolver) + const createUseCase = () => new CopyRevisions(revisionRepository) beforeEach(() => { revisionRepository = {} as jest.Mocked revisionRepository.findByItemUuid = jest.fn().mockReturnValue([{} as jest.Mocked]) revisionRepository.insert = jest.fn() - - revisionRepositoryResolver = {} as jest.Mocked - revisionRepositoryResolver.resolve = jest.fn().mockReturnValue(revisionRepository) }) it('should not copy revisions to new item if revision creation fails', async () => { @@ -26,7 +21,6 @@ describe('CopyRevisions', () => { const result = await createUseCase().execute({ originalItemUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', newItemUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', - roleNames: ['CORE_USER'], }) expect(result.isFailed()).toBeTruthy() @@ -34,21 +28,10 @@ describe('CopyRevisions', () => { revisionMock.mockRestore() }) - it('should do nothing if the role names are not valid', async () => { - const result = await createUseCase().execute({ - originalItemUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', - newItemUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', - roleNames: ['INVALID_ROLE_NAME'], - }) - - expect(result.isFailed()).toBeTruthy() - }) - it('should copy revisions to new item', async () => { const result = await createUseCase().execute({ originalItemUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', newItemUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', - roleNames: ['CORE_USER'], }) expect(result.isFailed()).toBeFalsy() @@ -60,7 +43,6 @@ describe('CopyRevisions', () => { const result = await createUseCase().execute({ originalItemUuid: '1-2-3', newItemUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', - roleNames: ['CORE_USER'], }) expect(result.isFailed()).toBeTruthy() @@ -70,7 +52,6 @@ describe('CopyRevisions', () => { const result = await createUseCase().execute({ newItemUuid: '1-2-3', originalItemUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', - roleNames: ['CORE_USER'], }) expect(result.isFailed()).toBeTruthy() diff --git a/packages/revisions/src/Domain/UseCase/CopyRevisions/CopyRevisions.ts b/packages/revisions/src/Domain/UseCase/CopyRevisions/CopyRevisions.ts index 10f3a540b..c7ff25846 100644 --- a/packages/revisions/src/Domain/UseCase/CopyRevisions/CopyRevisions.ts +++ b/packages/revisions/src/Domain/UseCase/CopyRevisions/CopyRevisions.ts @@ -1,12 +1,12 @@ -import { Result, RoleNameCollection, UseCaseInterface, Uuid } from '@standardnotes/domain-core' +import { Result, UseCaseInterface, Uuid } from '@standardnotes/domain-core' import { Revision } from '../../Revision/Revision' import { CopyRevisionsDTO } from './CopyRevisionsDTO' -import { RevisionRepositoryResolverInterface } from '../../Revision/RevisionRepositoryResolverInterface' +import { RevisionRepositoryInterface } from '../../Revision/RevisionRepositoryInterface' export class CopyRevisions implements UseCaseInterface { - constructor(private revisionRepositoryResolver: RevisionRepositoryResolverInterface) {} + constructor(private revisionRepository: RevisionRepositoryInterface) {} async execute(dto: CopyRevisionsDTO): Promise> { const orignalItemUuidOrError = Uuid.create(dto.originalItemUuid) @@ -21,15 +21,7 @@ export class CopyRevisions implements UseCaseInterface { } const newItemUuid = newItemUuidOrError.getValue() - const roleNamesOrError = RoleNameCollection.create(dto.roleNames) - if (roleNamesOrError.isFailed()) { - return Result.fail(roleNamesOrError.getError()) - } - const roleNames = roleNamesOrError.getValue() - - const revisionRepository = this.revisionRepositoryResolver.resolve(roleNames) - - const revisions = await revisionRepository.findByItemUuid(originalItemUuid) + const revisions = await this.revisionRepository.findByItemUuid(originalItemUuid) for (const existingRevision of revisions) { const revisionCopyOrError = Revision.create({ @@ -43,7 +35,7 @@ export class CopyRevisions implements UseCaseInterface { const revisionCopy = revisionCopyOrError.getValue() - await revisionRepository.insert(revisionCopy) + await this.revisionRepository.insert(revisionCopy) } return Result.ok('Revisions copied') diff --git a/packages/revisions/src/Domain/UseCase/CopyRevisions/CopyRevisionsDTO.ts b/packages/revisions/src/Domain/UseCase/CopyRevisions/CopyRevisionsDTO.ts index 628cfb1fe..962a9b949 100644 --- a/packages/revisions/src/Domain/UseCase/CopyRevisions/CopyRevisionsDTO.ts +++ b/packages/revisions/src/Domain/UseCase/CopyRevisions/CopyRevisionsDTO.ts @@ -1,5 +1,4 @@ export interface CopyRevisionsDTO { originalItemUuid: string newItemUuid: string - roleNames: string[] } diff --git a/packages/revisions/src/Domain/UseCase/CreateRevisionFromDump/CreateRevisionFromDump.spec.ts b/packages/revisions/src/Domain/UseCase/CreateRevisionFromDump/CreateRevisionFromDump.spec.ts index b68d957f9..760dd105f 100644 --- a/packages/revisions/src/Domain/UseCase/CreateRevisionFromDump/CreateRevisionFromDump.spec.ts +++ b/packages/revisions/src/Domain/UseCase/CreateRevisionFromDump/CreateRevisionFromDump.spec.ts @@ -3,16 +3,14 @@ import { Uuid, ContentType, Dates, Result } from '@standardnotes/domain-core' import { DumpRepositoryInterface } from '../../Dump/DumpRepositoryInterface' import { Revision } from '../../Revision/Revision' import { RevisionRepositoryInterface } from '../../Revision/RevisionRepositoryInterface' -import { RevisionRepositoryResolverInterface } from '../../Revision/RevisionRepositoryResolverInterface' import { CreateRevisionFromDump } from './CreateRevisionFromDump' describe('CreateRevisionFromDump', () => { let revisionRepository: RevisionRepositoryInterface let revision: Revision let dumpRepository: DumpRepositoryInterface - let revisionRepositoryResolver: RevisionRepositoryResolverInterface - const createUseCase = () => new CreateRevisionFromDump(dumpRepository, revisionRepositoryResolver) + const createUseCase = () => new CreateRevisionFromDump(dumpRepository, revisionRepository) beforeEach(() => { revision = Revision.create({ @@ -33,15 +31,11 @@ describe('CreateRevisionFromDump', () => { revisionRepository = {} as jest.Mocked revisionRepository.insert = jest.fn().mockReturnValue(true) - - revisionRepositoryResolver = {} as jest.Mocked - revisionRepositoryResolver.resolve = jest.fn().mockReturnValue(revisionRepository) }) it('should create a revision from file dump', async () => { const result = await createUseCase().execute({ filePath: 'foobar', - roleNames: ['CORE_USER'], }) expect(result.isFailed()).toBeFalsy() @@ -52,7 +46,6 @@ describe('CreateRevisionFromDump', () => { it('should fail if file path is empty', async () => { const result = await createUseCase().execute({ filePath: '', - roleNames: ['CORE_USER'], }) expect(result.isFailed()).toBeTruthy() @@ -60,23 +53,11 @@ describe('CreateRevisionFromDump', () => { expect(dumpRepository.removeDump).not.toHaveBeenCalled() }) - it('should fail if role name is invalid', async () => { - const result = await createUseCase().execute({ - filePath: 'foobar', - roleNames: ['INVALID_ROLE_NAME'], - }) - - expect(result.isFailed()).toBeTruthy() - expect(revisionRepository.insert).not.toHaveBeenCalled() - expect(dumpRepository.removeDump).toHaveBeenCalled() - }) - it('should fail if revision cannot be found', async () => { dumpRepository.getRevisionFromDumpPath = jest.fn().mockReturnValue(Result.fail('Oops')) const result = await createUseCase().execute({ filePath: 'foobar', - roleNames: ['CORE_USER'], }) expect(result.isFailed()).toBeTruthy() @@ -89,7 +70,6 @@ describe('CreateRevisionFromDump', () => { const result = await createUseCase().execute({ filePath: 'foobar', - roleNames: ['CORE_USER'], }) expect(result.isFailed()).toBeTruthy() diff --git a/packages/revisions/src/Domain/UseCase/CreateRevisionFromDump/CreateRevisionFromDump.ts b/packages/revisions/src/Domain/UseCase/CreateRevisionFromDump/CreateRevisionFromDump.ts index 93857716a..4cc31bd36 100644 --- a/packages/revisions/src/Domain/UseCase/CreateRevisionFromDump/CreateRevisionFromDump.ts +++ b/packages/revisions/src/Domain/UseCase/CreateRevisionFromDump/CreateRevisionFromDump.ts @@ -1,12 +1,12 @@ -import { Result, RoleNameCollection, UseCaseInterface, Validator } from '@standardnotes/domain-core' +import { Result, UseCaseInterface, Validator } from '@standardnotes/domain-core' import { DumpRepositoryInterface } from '../../Dump/DumpRepositoryInterface' -import { RevisionRepositoryResolverInterface } from '../../Revision/RevisionRepositoryResolverInterface' import { CreateRevisionFromDumpDTO } from './CreateRevisionFromDumpDTO' +import { RevisionRepositoryInterface } from '../../Revision/RevisionRepositoryInterface' export class CreateRevisionFromDump implements UseCaseInterface { constructor( private dumpRepository: DumpRepositoryInterface, - private revisionRepositoryResolver: RevisionRepositoryResolverInterface, + private revisionRepository: RevisionRepositoryInterface, ) {} async execute(dto: CreateRevisionFromDumpDTO): Promise> { @@ -23,17 +23,7 @@ export class CreateRevisionFromDump implements UseCaseInterface { } const revision = revisionOrError.getValue() - const roleNamesOrError = RoleNameCollection.create(dto.roleNames) - if (roleNamesOrError.isFailed()) { - await this.dumpRepository.removeDump(dto.filePath) - - return Result.fail(`Could not create revision from dump: ${roleNamesOrError.getError()}`) - } - const roleNames = roleNamesOrError.getValue() - - const revisionRepository = this.revisionRepositoryResolver.resolve(roleNames) - - const successfullyInserted = await revisionRepository.insert(revision) + const successfullyInserted = await this.revisionRepository.insert(revision) if (!successfullyInserted) { await this.dumpRepository.removeDump(dto.filePath) diff --git a/packages/revisions/src/Domain/UseCase/CreateRevisionFromDump/CreateRevisionFromDumpDTO.ts b/packages/revisions/src/Domain/UseCase/CreateRevisionFromDump/CreateRevisionFromDumpDTO.ts index be3464b23..2b40b529f 100644 --- a/packages/revisions/src/Domain/UseCase/CreateRevisionFromDump/CreateRevisionFromDumpDTO.ts +++ b/packages/revisions/src/Domain/UseCase/CreateRevisionFromDump/CreateRevisionFromDumpDTO.ts @@ -1,4 +1,3 @@ export interface CreateRevisionFromDumpDTO { filePath: string - roleNames: string[] } diff --git a/packages/revisions/src/Domain/UseCase/DeleteRevision/DeleteRevision.spec.ts b/packages/revisions/src/Domain/UseCase/DeleteRevision/DeleteRevision.spec.ts index 93ebe9f4b..cd2123f46 100644 --- a/packages/revisions/src/Domain/UseCase/DeleteRevision/DeleteRevision.spec.ts +++ b/packages/revisions/src/Domain/UseCase/DeleteRevision/DeleteRevision.spec.ts @@ -1,47 +1,30 @@ import { RevisionRepositoryInterface } from '../../Revision/RevisionRepositoryInterface' -import { RevisionRepositoryResolverInterface } from '../../Revision/RevisionRepositoryResolverInterface' import { DeleteRevision } from './DeleteRevision' describe('DeleteRevision', () => { let revisionRepository: RevisionRepositoryInterface - let revisionRepositoryResolver: RevisionRepositoryResolverInterface - const createUseCase = () => new DeleteRevision(revisionRepositoryResolver) + const createUseCase = () => new DeleteRevision(revisionRepository) beforeEach(() => { revisionRepository = {} as jest.Mocked revisionRepository.removeOneByUuid = jest.fn() - - revisionRepositoryResolver = {} as jest.Mocked - revisionRepositoryResolver.resolve = jest.fn().mockReturnValue(revisionRepository) }) it('should delete revision', async () => { const result = await createUseCase().execute({ revisionUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', userUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', - roleNames: ['CORE_USER'], }) expect(result.isFailed()).toBeFalsy() expect(result.getValue()).toEqual('Revision removed') }) - it('should do nothing if role names are not valid', async () => { - const result = await createUseCase().execute({ - revisionUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', - userUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', - roleNames: ['INVALID_ROLE_NAME'], - }) - - expect(result.isFailed()).toBeTruthy() - }) - it('should not delete revision for an invalid item uuid', async () => { const result = await createUseCase().execute({ revisionUuid: '1-2-3', userUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', - roleNames: ['CORE_USER'], }) expect(result.isFailed()).toBeTruthy() @@ -51,7 +34,6 @@ describe('DeleteRevision', () => { const result = await createUseCase().execute({ userUuid: '1-2-3', revisionUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', - roleNames: ['CORE_USER'], }) expect(result.isFailed()).toBeTruthy() diff --git a/packages/revisions/src/Domain/UseCase/DeleteRevision/DeleteRevision.ts b/packages/revisions/src/Domain/UseCase/DeleteRevision/DeleteRevision.ts index f242ae70e..568b02b25 100644 --- a/packages/revisions/src/Domain/UseCase/DeleteRevision/DeleteRevision.ts +++ b/packages/revisions/src/Domain/UseCase/DeleteRevision/DeleteRevision.ts @@ -1,10 +1,10 @@ -import { Result, RoleNameCollection, UseCaseInterface, Uuid } from '@standardnotes/domain-core' +import { Result, UseCaseInterface, Uuid } from '@standardnotes/domain-core' import { DeleteRevisionDTO } from './DeleteRevisionDTO' -import { RevisionRepositoryResolverInterface } from '../../Revision/RevisionRepositoryResolverInterface' +import { RevisionRepositoryInterface } from '../../Revision/RevisionRepositoryInterface' export class DeleteRevision implements UseCaseInterface { - constructor(private revisionRepositoryResolver: RevisionRepositoryResolverInterface) {} + constructor(private revisionRepository: RevisionRepositoryInterface) {} async execute(dto: DeleteRevisionDTO): Promise> { const revisionUuidOrError = Uuid.create(dto.revisionUuid) @@ -19,15 +19,7 @@ export class DeleteRevision implements UseCaseInterface { } const userUuid = userUuidOrError.getValue() - const roleNamesOrError = RoleNameCollection.create(dto.roleNames) - if (roleNamesOrError.isFailed()) { - return Result.fail(roleNamesOrError.getError()) - } - const roleNames = roleNamesOrError.getValue() - - const revisionRepository = this.revisionRepositoryResolver.resolve(roleNames) - - await revisionRepository.removeOneByUuid(revisionUuid, userUuid) + await this.revisionRepository.removeOneByUuid(revisionUuid, userUuid) return Result.ok('Revision removed') } diff --git a/packages/revisions/src/Domain/UseCase/DeleteRevision/DeleteRevisionDTO.ts b/packages/revisions/src/Domain/UseCase/DeleteRevision/DeleteRevisionDTO.ts index c45b0206b..b1acf5a97 100644 --- a/packages/revisions/src/Domain/UseCase/DeleteRevision/DeleteRevisionDTO.ts +++ b/packages/revisions/src/Domain/UseCase/DeleteRevision/DeleteRevisionDTO.ts @@ -1,5 +1,4 @@ export interface DeleteRevisionDTO { userUuid: string revisionUuid: string - roleNames: string[] } diff --git a/packages/revisions/src/Domain/UseCase/GetRevision/GetRevision.spec.ts b/packages/revisions/src/Domain/UseCase/GetRevision/GetRevision.spec.ts index b35dd10cb..76106d0b6 100644 --- a/packages/revisions/src/Domain/UseCase/GetRevision/GetRevision.spec.ts +++ b/packages/revisions/src/Domain/UseCase/GetRevision/GetRevision.spec.ts @@ -1,27 +1,21 @@ import { Revision } from '../../Revision/Revision' import { RevisionRepositoryInterface } from '../../Revision/RevisionRepositoryInterface' -import { RevisionRepositoryResolverInterface } from '../../Revision/RevisionRepositoryResolverInterface' import { GetRevision } from './GetRevision' describe('GetRevision', () => { let revisionRepository: RevisionRepositoryInterface - let revisionRepositoryResolver: RevisionRepositoryResolverInterface - const createUseCase = () => new GetRevision(revisionRepositoryResolver) + const createUseCase = () => new GetRevision(revisionRepository) beforeEach(() => { revisionRepository = {} as jest.Mocked revisionRepository.findOneByUuid = jest.fn().mockReturnValue({} as jest.Mocked) - - revisionRepositoryResolver = {} as jest.Mocked - revisionRepositoryResolver.resolve = jest.fn().mockReturnValue(revisionRepository) }) it('should return revision for a given item', async () => { const result = await createUseCase().execute({ revisionUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', userUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', - roleNames: ['CORE_USER'], sharedVaultUuids: ['84c0f8e8-544a-4c7e-9adf-26209303bc1d'], }) @@ -33,31 +27,18 @@ describe('GetRevision', () => { const result = await createUseCase().execute({ revisionUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', userUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', - roleNames: ['CORE_USER'], sharedVaultUuids: ['INVALID_SHARED_VAULT_UUID'], }) expect(result.isFailed()).toBeTruthy() }) - it('should do nothing if role names are not valid', async () => { - const result = await createUseCase().execute({ - revisionUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', - userUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', - roleNames: ['INVALID_ROLE_NAME'], - sharedVaultUuids: ['84c0f8e8-544a-4c7e-9adf-26209303bc1d'], - }) - - expect(result.isFailed()).toBeTruthy() - }) - it('should not return revision for a given item if not found', async () => { revisionRepository.findOneByUuid = jest.fn().mockReturnValue(null) const result = await createUseCase().execute({ revisionUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', userUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', - roleNames: ['CORE_USER'], sharedVaultUuids: ['84c0f8e8-544a-4c7e-9adf-26209303bc1d'], }) @@ -68,7 +49,6 @@ describe('GetRevision', () => { const result = await createUseCase().execute({ revisionUuid: '1-2-3', userUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', - roleNames: ['CORE_USER'], sharedVaultUuids: ['84c0f8e8-544a-4c7e-9adf-26209303bc1d'], }) @@ -79,7 +59,6 @@ describe('GetRevision', () => { const result = await createUseCase().execute({ userUuid: '1-2-3', revisionUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', - roleNames: ['CORE_USER'], sharedVaultUuids: ['84c0f8e8-544a-4c7e-9adf-26209303bc1d'], }) diff --git a/packages/revisions/src/Domain/UseCase/GetRevision/GetRevision.ts b/packages/revisions/src/Domain/UseCase/GetRevision/GetRevision.ts index 084259145..a5bc5f773 100644 --- a/packages/revisions/src/Domain/UseCase/GetRevision/GetRevision.ts +++ b/packages/revisions/src/Domain/UseCase/GetRevision/GetRevision.ts @@ -1,11 +1,11 @@ -import { Result, RoleNameCollection, UseCaseInterface, Uuid } from '@standardnotes/domain-core' +import { Result, UseCaseInterface, Uuid } from '@standardnotes/domain-core' import { Revision } from '../../Revision/Revision' import { GetRevisionDTO } from './GetRevisionDTO' -import { RevisionRepositoryResolverInterface } from '../../Revision/RevisionRepositoryResolverInterface' +import { RevisionRepositoryInterface } from '../../Revision/RevisionRepositoryInterface' export class GetRevision implements UseCaseInterface { - constructor(private revisionRepositoryResolver: RevisionRepositoryResolverInterface) {} + constructor(private revisionRepository: RevisionRepositoryInterface) {} async execute(dto: GetRevisionDTO): Promise> { const revisionUuidOrError = Uuid.create(dto.revisionUuid) @@ -20,12 +20,6 @@ export class GetRevision implements UseCaseInterface { } const userUuid = userUuidOrError.getValue() - const roleNamesOrError = RoleNameCollection.create(dto.roleNames) - if (roleNamesOrError.isFailed()) { - return Result.fail(roleNamesOrError.getError()) - } - const roleNames = roleNamesOrError.getValue() - const sharedVaultUuids = [] for (const sharedVaultUuid of dto.sharedVaultUuids) { const sharedVaultUuidOrError = Uuid.create(sharedVaultUuid) @@ -35,9 +29,7 @@ export class GetRevision implements UseCaseInterface { sharedVaultUuids.push(sharedVaultUuidOrError.getValue()) } - const revisionRepository = this.revisionRepositoryResolver.resolve(roleNames) - - const revision = await revisionRepository.findOneByUuid(revisionUuid, userUuid, sharedVaultUuids) + const revision = await this.revisionRepository.findOneByUuid(revisionUuid, userUuid, sharedVaultUuids) if (revision === null) { return Result.fail(`Could not find revision with uuid: ${revisionUuid.value}`) diff --git a/packages/revisions/src/Domain/UseCase/GetRevision/GetRevisionDTO.ts b/packages/revisions/src/Domain/UseCase/GetRevision/GetRevisionDTO.ts index 3f0d122f6..6b823fecd 100644 --- a/packages/revisions/src/Domain/UseCase/GetRevision/GetRevisionDTO.ts +++ b/packages/revisions/src/Domain/UseCase/GetRevision/GetRevisionDTO.ts @@ -1,6 +1,5 @@ export interface GetRevisionDTO { userUuid: string revisionUuid: string - roleNames: string[] sharedVaultUuids: string[] } diff --git a/packages/revisions/src/Domain/UseCase/GetRevisionsMetada/GetRevisionsMetada.spec.ts b/packages/revisions/src/Domain/UseCase/GetRevisionsMetada/GetRevisionsMetada.spec.ts index e2150d399..999a505a5 100644 --- a/packages/revisions/src/Domain/UseCase/GetRevisionsMetada/GetRevisionsMetada.spec.ts +++ b/packages/revisions/src/Domain/UseCase/GetRevisionsMetada/GetRevisionsMetada.spec.ts @@ -1,27 +1,21 @@ import { RevisionMetadata } from '../../Revision/RevisionMetadata' import { RevisionRepositoryInterface } from '../../Revision/RevisionRepositoryInterface' -import { RevisionRepositoryResolverInterface } from '../../Revision/RevisionRepositoryResolverInterface' import { GetRevisionsMetada } from './GetRevisionsMetada' describe('GetRevisionsMetada', () => { let revisionRepository: RevisionRepositoryInterface - let revisionRepositoryResolver: RevisionRepositoryResolverInterface - const createUseCase = () => new GetRevisionsMetada(revisionRepositoryResolver) + const createUseCase = () => new GetRevisionsMetada(revisionRepository) beforeEach(() => { revisionRepository = {} as jest.Mocked revisionRepository.findMetadataByItemId = jest.fn().mockReturnValue([{} as jest.Mocked]) - - revisionRepositoryResolver = {} as jest.Mocked - revisionRepositoryResolver.resolve = jest.fn().mockReturnValue(revisionRepository) }) it('should return revisions metadata for a given item', async () => { const result = await createUseCase().execute({ itemUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', userUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', - roleNames: ['CORE_USER'], sharedVaultUuids: ['84c0f8e8-544a-4c7e-9adf-26209303bc1d'], }) @@ -33,7 +27,6 @@ describe('GetRevisionsMetada', () => { const result = await createUseCase().execute({ itemUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', userUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', - roleNames: ['CORE_USER'], sharedVaultUuids: ['1-2-3'], }) @@ -44,7 +37,6 @@ describe('GetRevisionsMetada', () => { const result = await createUseCase().execute({ itemUuid: '1-2-3', userUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', - roleNames: ['CORE_USER'], sharedVaultUuids: [], }) @@ -55,18 +47,6 @@ describe('GetRevisionsMetada', () => { const result = await createUseCase().execute({ userUuid: '1-2-3', itemUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', - roleNames: ['CORE_USER'], - sharedVaultUuids: [], - }) - - expect(result.isFailed()).toBeTruthy() - }) - - it('should do nothing if role names are not valid', async () => { - const result = await createUseCase().execute({ - itemUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', - userUuid: '84c0f8e8-544a-4c7e-9adf-26209303bc1d', - roleNames: ['INVALID_ROLE_NAME'], sharedVaultUuids: [], }) diff --git a/packages/revisions/src/Domain/UseCase/GetRevisionsMetada/GetRevisionsMetada.ts b/packages/revisions/src/Domain/UseCase/GetRevisionsMetada/GetRevisionsMetada.ts index 4ad6459fe..435d1d92f 100644 --- a/packages/revisions/src/Domain/UseCase/GetRevisionsMetada/GetRevisionsMetada.ts +++ b/packages/revisions/src/Domain/UseCase/GetRevisionsMetada/GetRevisionsMetada.ts @@ -1,12 +1,12 @@ -import { Result, RoleNameCollection, UseCaseInterface, Uuid } from '@standardnotes/domain-core' +import { Result, UseCaseInterface, Uuid } from '@standardnotes/domain-core' import { RevisionMetadata } from '../../Revision/RevisionMetadata' import { GetRevisionsMetadaDTO } from './GetRevisionsMetadaDTO' -import { RevisionRepositoryResolverInterface } from '../../Revision/RevisionRepositoryResolverInterface' +import { RevisionRepositoryInterface } from '../../Revision/RevisionRepositoryInterface' export class GetRevisionsMetada implements UseCaseInterface { - constructor(private revisionRepositoryResolver: RevisionRepositoryResolverInterface) {} + constructor(private revisionRepository: RevisionRepositoryInterface) {} async execute(dto: GetRevisionsMetadaDTO): Promise> { const itemUuidOrError = Uuid.create(dto.itemUuid) @@ -28,15 +28,7 @@ export class GetRevisionsMetada implements UseCaseInterface sharedVaultUuids.push(sharedVaultUuidOrError.getValue()) } - const roleNamesOrError = RoleNameCollection.create(dto.roleNames) - if (roleNamesOrError.isFailed()) { - return Result.fail(roleNamesOrError.getError()) - } - const roleNames = roleNamesOrError.getValue() - - const revisionRepository = this.revisionRepositoryResolver.resolve(roleNames) - - const revisionsMetdata = await revisionRepository.findMetadataByItemId( + const revisionsMetdata = await this.revisionRepository.findMetadataByItemId( itemUuidOrError.getValue(), userUuidOrError.getValue(), sharedVaultUuids, diff --git a/packages/revisions/src/Domain/UseCase/GetRevisionsMetada/GetRevisionsMetadaDTO.ts b/packages/revisions/src/Domain/UseCase/GetRevisionsMetada/GetRevisionsMetadaDTO.ts index c0b738168..73bf35e62 100644 --- a/packages/revisions/src/Domain/UseCase/GetRevisionsMetada/GetRevisionsMetadaDTO.ts +++ b/packages/revisions/src/Domain/UseCase/GetRevisionsMetada/GetRevisionsMetadaDTO.ts @@ -2,5 +2,4 @@ export interface GetRevisionsMetadaDTO { itemUuid: string sharedVaultUuids: string[] userUuid: string - roleNames: string[] } diff --git a/packages/revisions/src/Domain/UseCase/Transition/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser.ts b/packages/revisions/src/Domain/UseCase/Transition/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser.ts deleted file mode 100644 index 324049f34..000000000 --- a/packages/revisions/src/Domain/UseCase/Transition/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser.ts +++ /dev/null @@ -1,325 +0,0 @@ -/* istanbul ignore file */ -import { Result, TransitionStatus, UseCaseInterface, Uuid } from '@standardnotes/domain-core' -import { TimerInterface } from '@standardnotes/time' -import { Logger } from 'winston' - -import { TransitionRevisionsFromPrimaryToSecondaryDatabaseForUserDTO } from './TransitionRevisionsFromPrimaryToSecondaryDatabaseForUserDTO' -import { RevisionRepositoryInterface } from '../../../Revision/RevisionRepositoryInterface' -import { TransitionRepositoryInterface } from '../../../Transition/TransitionRepositoryInterface' -import { DomainEventPublisherInterface } from '@standardnotes/domain-events' -import { DomainEventFactoryInterface } from '../../../Event/DomainEventFactoryInterface' - -export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements UseCaseInterface { - constructor( - private primaryRevisionsRepository: RevisionRepositoryInterface, - private secondRevisionsRepository: RevisionRepositoryInterface | null, - private transitionStatusRepository: TransitionRepositoryInterface | null, - private timer: TimerInterface, - private logger: Logger, - private pageSize: number, - private domainEventPublisher: DomainEventPublisherInterface, - private domainEventFactory: DomainEventFactoryInterface, - ) {} - - async execute(dto: TransitionRevisionsFromPrimaryToSecondaryDatabaseForUserDTO): Promise> { - this.logger.info(`[TRANSITION][${dto.userUuid}] Transitioning revisions for user`) - - if (this.secondRevisionsRepository === null) { - return Result.fail('Secondary revision repository is not set') - } - - if (this.transitionStatusRepository === null) { - return Result.fail('Transition status repository is not set') - } - - const userUuidOrError = Uuid.create(dto.userUuid) - if (userUuidOrError.isFailed()) { - return Result.fail(userUuidOrError.getError()) - } - const userUuid = userUuidOrError.getValue() - - if (await this.isAlreadyMigrated(userUuid)) { - this.logger.info(`[TRANSITION][${userUuid.value}] User already migrated.`) - - await this.updateTransitionStatus(userUuid, TransitionStatus.STATUSES.Verified, dto.timestamp) - - return Result.ok() - } - - await this.updateTransitionStatus(userUuid, TransitionStatus.STATUSES.InProgress, dto.timestamp) - - const migrationTimeStart = this.timer.getTimestampInMicroseconds() - - this.logger.info(`[TRANSITION][${dto.userUuid}] Migrating revisions`) - - const migrationResult = await this.migrateRevisionsForUser(userUuid, dto.timestamp) - if (migrationResult.isFailed()) { - await this.updateTransitionStatus(userUuid, TransitionStatus.STATUSES.Failed, dto.timestamp) - - return Result.fail(migrationResult.getError()) - } - - this.logger.info(`[TRANSITION][${dto.userUuid}] Revisions migrated`) - - await this.allowForPrimaryDatabaseToCatchUp() - - this.logger.info(`[TRANSITION][${dto.userUuid}] Checking integrity between primary and secondary database`) - - const integrityCheckResult = await this.checkIntegrityBetweenPrimaryAndSecondaryDatabase(userUuid) - if (integrityCheckResult.isFailed()) { - await (this.transitionStatusRepository as TransitionRepositoryInterface).setPagingProgress(userUuid.value, 1) - await (this.transitionStatusRepository as TransitionRepositoryInterface).setIntegrityProgress(userUuid.value, 1) - - await this.updateTransitionStatus(userUuid, TransitionStatus.STATUSES.Failed, dto.timestamp) - - return Result.fail(integrityCheckResult.getError()) - } - - const cleanupResult = await this.deleteRevisionsForUser( - userUuid, - this.secondRevisionsRepository as RevisionRepositoryInterface, - ) - if (cleanupResult.isFailed()) { - await this.updateTransitionStatus(userUuid, TransitionStatus.STATUSES.Failed, dto.timestamp) - - this.logger.error( - `[TRANSITION][${dto.userUuid}] Failed to clean up secondary database revisions: ${cleanupResult.getError()}`, - ) - } - - const migrationTimeEnd = this.timer.getTimestampInMicroseconds() - - const migrationDuration = migrationTimeEnd - migrationTimeStart - const migrationDurationTimeStructure = this.timer.convertMicrosecondsToTimeStructure(migrationDuration) - - this.logger.info( - `[TRANSITION][${dto.userUuid}] Transitioned revisions in ${migrationDurationTimeStructure.hours}h ${migrationDurationTimeStructure.minutes}m ${migrationDurationTimeStructure.seconds}s ${migrationDurationTimeStructure.milliseconds}ms`, - ) - - await this.updateTransitionStatus(userUuid, TransitionStatus.STATUSES.Verified, dto.timestamp) - - return Result.ok() - } - - private async migrateRevisionsForUser(userUuid: Uuid, timestamp: number): Promise> { - try { - const initialPage = await (this.transitionStatusRepository as TransitionRepositoryInterface).getPagingProgress( - userUuid.value, - ) - - this.logger.info(`[TRANSITION][${userUuid.value}] Migrating from page ${initialPage}`) - - const totalRevisionsCountForUser = await ( - this.secondRevisionsRepository as RevisionRepositoryInterface - ).countByUserUuid(userUuid) - this.logger.info(`[TRANSITION][${userUuid.value}] Total revisions count for user: ${totalRevisionsCountForUser}`) - const totalPages = Math.ceil(totalRevisionsCountForUser / this.pageSize) - this.logger.info(`[TRANSITION][${userUuid.value}] Total pages: ${totalPages}`) - let insertedCount = 0 - let newerCount = 0 - let identicalCount = 0 - let updatedCount = 0 - for (let currentPage = initialPage; currentPage <= totalPages; currentPage++) { - const isPageInEvery10Percent = currentPage % Math.ceil(totalPages / 10) === 0 - if (isPageInEvery10Percent) { - this.logger.info( - `[TRANSITION][${userUuid.value}] Migrating revisions for user: ${Math.round( - (currentPage / totalPages) * 100, - )}% completed`, - ) - this.logger.info( - `[TRANSITION][${userUuid.value}] Inserted ${insertedCount} revisions so far. Skipped ${newerCount} revisions because they were newer in primary database. Skipped ${identicalCount} revisions because they were identical in primary and secondary database. Updated ${updatedCount} revisions because they were older in primary database.`, - ) - await this.updateTransitionStatus(userUuid, TransitionStatus.STATUSES.InProgress, timestamp) - } - - await (this.transitionStatusRepository as TransitionRepositoryInterface).setPagingProgress( - userUuid.value, - currentPage, - ) - - const query = { - userUuid: userUuid, - offset: (currentPage - 1) * this.pageSize, - limit: this.pageSize, - } - - const revisions = await (this.secondRevisionsRepository as RevisionRepositoryInterface).findByUserUuid(query) - for (const revision of revisions) { - try { - const revisionInPrimary = await this.primaryRevisionsRepository.findOneByUuid( - Uuid.create(revision.id.toString()).getValue(), - revision.props.userUuid as Uuid, - [], - ) - - if (!revisionInPrimary) { - await this.primaryRevisionsRepository.insert(revision) - - insertedCount++ - } else { - if (revisionInPrimary.props.dates.updatedAt > revision.props.dates.updatedAt) { - this.logger.info( - `[TRANSITION][${ - userUuid.value - }] Revision ${revision.id.toString()} is older in secondary than revision in primary database`, - ) - newerCount++ - - continue - } - - if (revisionInPrimary.isIdenticalTo(revision)) { - identicalCount++ - - continue - } - - await this.primaryRevisionsRepository.update(revision) - - updatedCount++ - } - } catch (error) { - this.logger.error( - `[TRANSITION][${ - userUuid.value - }] Errored when saving revision ${revision.id.toString()} to primary database: ${ - (error as Error).message - }`, - ) - } - } - } - - this.logger.info( - `[TRANSITION][${userUuid.value}] Inserted ${insertedCount} revisions. Skipped ${newerCount} revisions because they were newer in primary database. Skipped ${identicalCount} revisions because they were identical in primary and secondary database. Updated ${updatedCount} revisions because they were older in primary database.`, - ) - - return Result.ok() - } catch (error) { - return Result.fail(`Errored when migrating revisions for user ${userUuid.value}: ${(error as Error).message}`) - } - } - - private async deleteRevisionsForUser( - userUuid: Uuid, - revisionRepository: RevisionRepositoryInterface, - ): Promise> { - try { - this.logger.info(`[TRANSITION][${userUuid.value}] Deleting all revisions from secondary database`) - - await revisionRepository.removeByUserUuid(userUuid) - - return Result.ok() - } catch (error) { - return Result.fail(`Errored when deleting revisions for user ${userUuid.value}: ${(error as Error).message}`) - } - } - - private async allowForPrimaryDatabaseToCatchUp(): Promise { - const delay = 1_000 - await this.timer.sleep(delay) - } - - private async checkIntegrityBetweenPrimaryAndSecondaryDatabase(userUuid: Uuid): Promise> { - try { - const initialPage = await (this.transitionStatusRepository as TransitionRepositoryInterface).getIntegrityProgress( - userUuid.value, - ) - - this.logger.info(`[TRANSITION][${userUuid.value}] Checking integrity from page ${initialPage}`) - - const totalRevisionsCountForUserInSecondary = await ( - this.secondRevisionsRepository as RevisionRepositoryInterface - ).countByUserUuid(userUuid) - const totalRevisionsCountForUserInPrimary = await this.primaryRevisionsRepository.countByUserUuid(userUuid) - - if (totalRevisionsCountForUserInPrimary < totalRevisionsCountForUserInSecondary) { - return Result.fail( - `Total revisions count for user ${userUuid.value} in primary database (${totalRevisionsCountForUserInPrimary}) does not match total revisions count in secondary database (${totalRevisionsCountForUserInSecondary})`, - ) - } - - const totalPages = Math.ceil(totalRevisionsCountForUserInPrimary / this.pageSize) - for (let currentPage = initialPage; currentPage <= totalPages; currentPage++) { - await (this.transitionStatusRepository as TransitionRepositoryInterface).setIntegrityProgress( - userUuid.value, - currentPage, - ) - - const query = { - userUuid: userUuid, - offset: (currentPage - 1) * this.pageSize, - limit: this.pageSize, - } - - const revisions = await (this.secondRevisionsRepository as RevisionRepositoryInterface).findByUserUuid(query) - - for (const revision of revisions) { - const revisionUuidOrError = Uuid.create(revision.id.toString()) - /* istanbul ignore if */ - if (revisionUuidOrError.isFailed()) { - return Result.fail(revisionUuidOrError.getError()) - } - const revisionUuid = revisionUuidOrError.getValue() - - const revisionInPrimary = await this.primaryRevisionsRepository.findOneByUuid(revisionUuid, userUuid, []) - if (!revisionInPrimary) { - return Result.fail(`Revision ${revision.id.toString()} not found in primary database`) - } - - if (revisionInPrimary.props.dates.updatedAt > revision.props.dates.updatedAt) { - this.logger.info( - `[TRANSITION][${ - userUuid.value - }] Integrity check of revision ${revision.id.toString()} - is older in secondary than revision in primary database`, - ) - - continue - } - - if (revision.isIdenticalTo(revisionInPrimary)) { - continue - } - - return Result.fail( - `Revision ${revision.id.toString()} is not identical in primary and secondary database. Revision in primary database: ${JSON.stringify( - revisionInPrimary, - )}, revision in secondary database: ${JSON.stringify(revision)}`, - ) - } - } - - return Result.ok() - } catch (error) { - return Result.fail( - `Errored when checking integrity between primary and secondary database: ${(error as Error).message}`, - ) - } - } - - private async updateTransitionStatus(userUuid: Uuid, status: string, timestamp: number): Promise { - await this.domainEventPublisher.publish( - this.domainEventFactory.createTransitionStatusUpdatedEvent({ - userUuid: userUuid.value, - status, - transitionType: 'revisions', - transitionTimestamp: timestamp, - }), - ) - } - - private async isAlreadyMigrated(userUuid: Uuid): Promise { - const totalRevisionsCountForUserInSecondary = await ( - this.secondRevisionsRepository as RevisionRepositoryInterface - ).countByUserUuid(userUuid) - - if (totalRevisionsCountForUserInSecondary > 0) { - this.logger.info( - `[TRANSITION][${userUuid.value}] User has ${totalRevisionsCountForUserInSecondary} revisions in secondary database.`, - ) - } - - return totalRevisionsCountForUserInSecondary === 0 - } -} diff --git a/packages/revisions/src/Domain/UseCase/Transition/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUserDTO.ts b/packages/revisions/src/Domain/UseCase/Transition/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUserDTO.ts deleted file mode 100644 index d746b3961..000000000 --- a/packages/revisions/src/Domain/UseCase/Transition/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUserDTO.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface TransitionRevisionsFromPrimaryToSecondaryDatabaseForUserDTO { - userUuid: string - timestamp: number -} diff --git a/packages/revisions/src/Infra/InversifyExpress/Base/BaseRevisionsController.ts b/packages/revisions/src/Infra/InversifyExpress/Base/BaseRevisionsController.ts index cbfce8e97..41fccb098 100644 --- a/packages/revisions/src/Infra/InversifyExpress/Base/BaseRevisionsController.ts +++ b/packages/revisions/src/Infra/InversifyExpress/Base/BaseRevisionsController.ts @@ -1,5 +1,4 @@ import { HttpStatusCode } from '@standardnotes/responses' -import { Role } from '@standardnotes/security' import { BaseHttpController, results } from 'inversify-express-utils' import { Request, Response } from 'express' import { ControllerContainerInterface, MapperInterface } from '@standardnotes/domain-core' @@ -34,7 +33,6 @@ export class BaseRevisionsController extends BaseHttpController { const revisionMetadataOrError = await this.getRevisionsMetadata.execute({ itemUuid: request.params.itemUuid, userUuid: response.locals.user.uuid, - roleNames: response.locals.roles.map((role: Role) => role.name), sharedVaultUuids: response.locals.belongsToSharedVaults.map( (association: { shared_vault_uuid: string; permission: string }) => association.shared_vault_uuid, ), @@ -61,7 +59,6 @@ export class BaseRevisionsController extends BaseHttpController { const revisionOrError = await this.doGetRevision.execute({ revisionUuid: request.params.uuid, userUuid: response.locals.user.uuid, - roleNames: response.locals.roles.map((role: Role) => role.name), sharedVaultUuids: response.locals.belongsToSharedVaults.map( (association: { shared_vault_uuid: string; permission: string }) => association.shared_vault_uuid, ), @@ -87,7 +84,6 @@ export class BaseRevisionsController extends BaseHttpController { const revisionOrError = await this.doDeleteRevision.execute({ revisionUuid: request.params.uuid, userUuid: response.locals.user.uuid, - roleNames: response.locals.roles.map((role: Role) => role.name), }) if (revisionOrError.isFailed()) { diff --git a/packages/revisions/src/Infra/Redis/RedisTransitionRepository.ts b/packages/revisions/src/Infra/Redis/RedisTransitionRepository.ts deleted file mode 100644 index 8d1b77290..000000000 --- a/packages/revisions/src/Infra/Redis/RedisTransitionRepository.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as IORedis from 'ioredis' - -import { TransitionRepositoryInterface } from '../../Domain/Transition/TransitionRepositoryInterface' - -export class RedisTransitionRepository implements TransitionRepositoryInterface { - private readonly PREFIX = 'transition-revisions-migration-progress' - private readonly INTEGRITY_PREFIX = 'transition-revisions-integrity-progress' - - constructor(private redisClient: IORedis.Redis) {} - - async getIntegrityProgress(userUuid: string): Promise { - const progress = await this.redisClient.get(`${this.INTEGRITY_PREFIX}:${userUuid}`) - - if (progress === null) { - return 1 - } - - return parseInt(progress) - } - - async setIntegrityProgress(userUuid: string, progress: number): Promise { - await this.redisClient.setex(`${this.INTEGRITY_PREFIX}:${userUuid}`, 172_800, progress.toString()) - } - - async getPagingProgress(userUuid: string): Promise { - const progress = await this.redisClient.get(`${this.PREFIX}:${userUuid}`) - - if (progress === null) { - return 1 - } - - return parseInt(progress) - } - - async setPagingProgress(userUuid: string, progress: number): Promise { - await this.redisClient.setex(`${this.PREFIX}:${userUuid}`, 172_800, progress.toString()) - } -} diff --git a/packages/revisions/src/Infra/TypeORM/MongoDB/MongoDBRevision.ts b/packages/revisions/src/Infra/TypeORM/MongoDB/MongoDBRevision.ts deleted file mode 100644 index 44c8310c8..000000000 --- a/packages/revisions/src/Infra/TypeORM/MongoDB/MongoDBRevision.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { BSON } from 'mongodb' -import { Column, Entity, Index, ObjectIdColumn } from 'typeorm' - -@Entity({ name: 'revisions' }) -export class MongoDBRevision { - @ObjectIdColumn() - declare _id: BSON.UUID - - @Column() - @Index('item_uuid_on_revisions') - declare itemUuid: string - - @Column() - @Index('user_uuid_on_revisions') - declare userUuid: string | null - - @Column() - declare content: string | null - - @Column() - declare contentType: string | null - - @Column() - declare itemsKeyId: string | null - - @Column() - declare encItemKey: string | null - - @Column() - declare authHash: string | null - - @Column() - declare creationDate: Date - - @Column() - declare createdAt: Date - - @Column() - declare updatedAt: Date - - @Column() - declare editedBy: string | null - - @Column() - @Index('index_revisions_on_shared_vault_uuid') - declare sharedVaultUuid: string | null - - @Column() - declare keySystemIdentifier: string | null -} diff --git a/packages/revisions/src/Infra/TypeORM/MongoDB/MongoDBRevisionRepository.ts b/packages/revisions/src/Infra/TypeORM/MongoDB/MongoDBRevisionRepository.ts deleted file mode 100644 index 30a603135..000000000 --- a/packages/revisions/src/Infra/TypeORM/MongoDB/MongoDBRevisionRepository.ts +++ /dev/null @@ -1,209 +0,0 @@ -import { MapperInterface, Uuid } from '@standardnotes/domain-core' -import { MongoRepository, ObjectLiteral } from 'typeorm' -import { BSON } from 'mongodb' -import { Logger } from 'winston' - -import { MongoDBRevision } from './MongoDBRevision' -import { Revision } from '../../../Domain/Revision/Revision' -import { RevisionMetadata } from '../../../Domain/Revision/RevisionMetadata' -import { RevisionRepositoryInterface } from '../../../Domain/Revision/RevisionRepositoryInterface' - -export class MongoDBRevisionRepository implements RevisionRepositoryInterface { - constructor( - private mongoRepository: MongoRepository, - private revisionMetadataMapper: MapperInterface, - private revisionMapper: MapperInterface, - private logger: Logger, - ) {} - - async clearSharedVaultAndKeySystemAssociations(dto: { itemUuid?: Uuid; sharedVaultUuid: Uuid }): Promise { - let query: ObjectLiteral - if (dto.itemUuid !== undefined) { - query = { - itemUuid: { $eq: dto.itemUuid.value }, - sharedVaultUuid: { $eq: dto.sharedVaultUuid.value }, - } - } else { - query = { - sharedVaultUuid: { $eq: dto.sharedVaultUuid.value }, - } - } - - await this.mongoRepository.updateMany(query, { - $set: { - sharedVaultUuid: null, - keySystemIdentifier: null, - }, - }) - } - - async countByUserUuid(userUuid: Uuid): Promise { - return this.mongoRepository.count({ userUuid: { $eq: userUuid.value } }) - } - - async findByUserUuid(dto: { userUuid: Uuid; offset?: number; limit?: number }): Promise { - const mongoRevisions = await this.mongoRepository.find({ - where: { userUuid: { $eq: dto.userUuid.value } }, - order: { - createdAt: 'ASC', - _id: 'ASC', - }, - skip: dto.offset, - take: dto.limit, - }) - - const revisions = [] - for (const mongoRevision of mongoRevisions) { - revisions.push(this.revisionMapper.toDomain(mongoRevision)) - } - - return revisions - } - - async removeByUserUuid(userUuid: Uuid): Promise { - await this.mongoRepository.deleteMany({ userUuid: userUuid.value }) - } - - async removeOneByUuid(revisionUuid: Uuid, userUuid: Uuid): Promise { - await this.mongoRepository.deleteOne({ - _id: { $eq: BSON.UUID.createFromHexString(revisionUuid.value) }, - userUuid: { $eq: userUuid.value }, - }) - } - - async findOneByUuid(revisionUuid: Uuid, userUuid: Uuid, sharedVaultUuids: Uuid[]): Promise { - let persistence = null - if (sharedVaultUuids.length > 0) { - persistence = await this.mongoRepository.findOne({ - where: { - $and: [ - { _id: { $eq: BSON.UUID.createFromHexString(revisionUuid.value) } }, - { - $or: [ - { sharedVaultUuid: { $in: sharedVaultUuids.map((uuid) => uuid.value) } }, - { userUuid: { $eq: userUuid.value } }, - ], - }, - ], - }, - }) - } else { - persistence = await this.mongoRepository.findOne({ - where: { - $and: [ - { _id: { $eq: BSON.UUID.createFromHexString(revisionUuid.value) } }, - { userUuid: { $eq: userUuid.value } }, - ], - }, - }) - } - - if (persistence === null) { - return null - } - - return this.revisionMapper.toDomain(persistence) - } - - async findByItemUuid(itemUuid: Uuid): Promise { - const persistence = await this.mongoRepository.find({ - where: { - itemUuid: { $eq: itemUuid.value }, - }, - }) - - const revisions: Revision[] = [] - - for (const revision of persistence) { - try { - revisions.push(this.revisionMapper.toDomain(revision)) - } catch (error) { - this.logger.error(`Failed to map revision ${revision._id.toHexString()} to domain: ${(error as Error).message}`) - } - } - - return revisions - } - - async findMetadataByItemId( - itemUuid: Uuid, - userUuid: Uuid, - sharedVaultUuids: Uuid[], - ): Promise> { - let persistence = [] - if (sharedVaultUuids.length > 0) { - persistence = await this.mongoRepository.find({ - select: ['_id', 'contentType', 'createdAt', 'updatedAt', 'sharedVaultUuid', 'itemUuid'], - where: { - $and: [ - { itemUuid: { $eq: itemUuid.value } }, - { - $or: [ - { sharedVaultUuid: { $in: sharedVaultUuids.map((uuid) => uuid.value) } }, - { userUuid: { $eq: userUuid.value } }, - ], - }, - ], - }, - order: { - createdAt: 'DESC', - _id: 'DESC', - }, - }) - } else { - persistence = await this.mongoRepository.find({ - select: ['_id', 'contentType', 'createdAt', 'updatedAt', 'sharedVaultUuid', 'itemUuid'], - where: { - $and: [{ itemUuid: { $eq: itemUuid.value } }, { userUuid: { $eq: userUuid.value } }], - }, - order: { - createdAt: 'DESC', - _id: 'DESC', - }, - }) - } - - const revisions: RevisionMetadata[] = [] - - for (const revision of persistence) { - try { - revisions.push(this.revisionMetadataMapper.toDomain(revision)) - } catch (error) { - this.logger.error(`Failed to map revision ${revision._id.toHexString()} to domain: ${(error as Error).message}`) - } - } - - return revisions - } - - async updateUserUuid(itemUuid: Uuid, userUuid: Uuid): Promise { - await this.mongoRepository.updateMany( - { - itemUuid: { $eq: itemUuid.value }, - }, - { - $set: { - userUuid: userUuid.value, - }, - }, - ) - } - - async insert(revision: Revision): Promise { - const persistence = this.revisionMapper.toProjection(revision) - - const insertResult = await this.mongoRepository.insertOne(persistence) - - return insertResult.acknowledged - } - - async update(revision: Revision): Promise { - const persistence = this.revisionMapper.toProjection(revision) - - const { _id, ...rest } = persistence - - const updateResult = await this.mongoRepository.updateOne({ _id: _id }, { $set: rest }) - - return updateResult.acknowledged - } -} diff --git a/packages/revisions/src/Infra/TypeORM/TypeORMRevisionRepositoryResolver.ts b/packages/revisions/src/Infra/TypeORM/TypeORMRevisionRepositoryResolver.ts deleted file mode 100644 index 53bf58319..000000000 --- a/packages/revisions/src/Infra/TypeORM/TypeORMRevisionRepositoryResolver.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { RoleName, RoleNameCollection } from '@standardnotes/domain-core' - -import { RevisionRepositoryResolverInterface } from '../../Domain/Revision/RevisionRepositoryResolverInterface' -import { RevisionRepositoryInterface } from '../../Domain/Revision/RevisionRepositoryInterface' - -export class TypeORMRevisionRepositoryResolver implements RevisionRepositoryResolverInterface { - constructor( - private sqlRevisionRepository: RevisionRepositoryInterface, - private mongoDbRevisionRepository: RevisionRepositoryInterface | null, - ) {} - - resolve(roleNames: RoleNameCollection): RevisionRepositoryInterface { - if (!this.mongoDbRevisionRepository) { - return this.sqlRevisionRepository - } - - const transitionRoleName = RoleName.create(RoleName.NAMES.TransitionUser).getValue() - - if (roleNames.includes(transitionRoleName)) { - return this.mongoDbRevisionRepository - } - - return this.sqlRevisionRepository - } -} diff --git a/packages/revisions/src/Mapping/Persistence/MongoDB/MongoDBRevisionMetadataPersistenceMapper.ts b/packages/revisions/src/Mapping/Persistence/MongoDB/MongoDBRevisionMetadataPersistenceMapper.ts deleted file mode 100644 index 39a5e6221..000000000 --- a/packages/revisions/src/Mapping/Persistence/MongoDB/MongoDBRevisionMetadataPersistenceMapper.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { MapperInterface, Dates, UniqueEntityId, ContentType, Uuid } from '@standardnotes/domain-core' - -import { RevisionMetadata } from '../../../Domain/Revision/RevisionMetadata' -import { MongoDBRevision } from '../../../Infra/TypeORM/MongoDB/MongoDBRevision' - -export class MongoDBRevisionMetadataPersistenceMapper implements MapperInterface { - toDomain(projection: MongoDBRevision): RevisionMetadata { - const contentTypeOrError = ContentType.create(projection.contentType) - if (contentTypeOrError.isFailed()) { - throw new Error(`Could not create content type: ${contentTypeOrError.getError()}`) - } - const contentType = contentTypeOrError.getValue() - - const createdAt = projection.createdAt instanceof Date ? projection.createdAt : new Date(projection.createdAt) - const updatedAt = projection.updatedAt instanceof Date ? projection.updatedAt : new Date(projection.updatedAt) - - const datesOrError = Dates.create(createdAt, updatedAt) - if (datesOrError.isFailed()) { - throw new Error(`Could not create dates: ${datesOrError.getError()}`) - } - const dates = datesOrError.getValue() - - let sharedVaultUuid = null - if (projection.sharedVaultUuid) { - const sharedVaultUuidOrError = Uuid.create(projection.sharedVaultUuid) - if (sharedVaultUuidOrError.isFailed()) { - throw new Error(`Could not create shared vault uuid: ${sharedVaultUuidOrError.getError()}`) - } - sharedVaultUuid = sharedVaultUuidOrError.getValue() - } - - const itemUuidOrError = Uuid.create(projection.itemUuid) - if (itemUuidOrError.isFailed()) { - throw new Error(`Could not create item uuid: ${itemUuidOrError.getError()}`) - } - const itemUuid = itemUuidOrError.getValue() - - const revisionMetadataOrError = RevisionMetadata.create( - { - contentType, - dates, - sharedVaultUuid, - itemUuid, - }, - new UniqueEntityId(projection._id.toHexString()), - ) - - if (revisionMetadataOrError.isFailed()) { - throw new Error(`Could not create revision metdata: ${revisionMetadataOrError.getError()}`) - } - - return revisionMetadataOrError.getValue() - } - - toProjection(_domain: RevisionMetadata): MongoDBRevision { - throw new Error('Method not implemented.') - } -} diff --git a/packages/revisions/src/Mapping/Persistence/MongoDB/MongoDBRevisionPersistenceMapper.ts b/packages/revisions/src/Mapping/Persistence/MongoDB/MongoDBRevisionPersistenceMapper.ts deleted file mode 100644 index 63d3c9c47..000000000 --- a/packages/revisions/src/Mapping/Persistence/MongoDB/MongoDBRevisionPersistenceMapper.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { MapperInterface, Dates, UniqueEntityId, Uuid, ContentType } from '@standardnotes/domain-core' -import { BSON } from 'mongodb' - -import { MongoDBRevision } from '../../../Infra/TypeORM/MongoDB/MongoDBRevision' -import { Revision } from '../../../Domain/Revision/Revision' -import { SharedVaultAssociation } from '../../../Domain/SharedVault/SharedVaultAssociation' -import { KeySystemAssociation } from '../../../Domain/KeySystem/KeySystemAssociation' -import { TimerInterface } from '@standardnotes/time' - -export class MongoDBRevisionPersistenceMapper implements MapperInterface { - constructor(private timer: TimerInterface) {} - - toDomain(projection: MongoDBRevision): Revision { - const contentTypeOrError = ContentType.create(projection.contentType) - if (contentTypeOrError.isFailed()) { - throw new Error(`Could not map typeorm revision to domain revision: ${contentTypeOrError.getError()}`) - } - const contentType = contentTypeOrError.getValue() - - const datesOrError = Dates.create(projection.createdAt, projection.updatedAt) - if (datesOrError.isFailed()) { - throw new Error(`Could not map typeorm revision to domain revision: ${datesOrError.getError()}`) - } - const dates = datesOrError.getValue() - - const itemUuidOrError = Uuid.create(projection.itemUuid) - if (itemUuidOrError.isFailed()) { - throw new Error(`Could not map typeorm revision to domain revision: ${itemUuidOrError.getError()}`) - } - const itemUuid = itemUuidOrError.getValue() - - let userUuid = null - if (projection.userUuid !== null) { - const userUuidOrError = Uuid.create(projection.userUuid) - if (userUuidOrError.isFailed()) { - throw new Error(`Could not map typeorm revision to domain revision: ${userUuidOrError.getError()}`) - } - userUuid = userUuidOrError.getValue() - } - - let sharedVaultAssociation: SharedVaultAssociation | undefined = undefined - if (projection.sharedVaultUuid && projection.editedBy) { - const sharedVaultUuidOrError = Uuid.create(projection.sharedVaultUuid) - if (sharedVaultUuidOrError.isFailed()) { - throw new Error(`Failed to create revision from projection: ${sharedVaultUuidOrError.getError()}`) - } - const sharedVaultUuid = sharedVaultUuidOrError.getValue() - - const lastEditedByOrError = Uuid.create(projection.editedBy) - if (lastEditedByOrError.isFailed()) { - throw new Error(`Failed to create revision from projection: ${lastEditedByOrError.getError()}`) - } - const lastEditedBy = lastEditedByOrError.getValue() - - const sharedVaultAssociationOrError = SharedVaultAssociation.create({ - sharedVaultUuid, - editedBy: lastEditedBy, - }) - if (sharedVaultAssociationOrError.isFailed()) { - throw new Error(`Failed to create revision from projection: ${sharedVaultAssociationOrError.getError()}`) - } - sharedVaultAssociation = sharedVaultAssociationOrError.getValue() - } - - let keySystemAssociation: KeySystemAssociation | undefined = undefined - if (projection.keySystemIdentifier) { - const keySystemAssociationOrError = KeySystemAssociation.create(projection.keySystemIdentifier) - if (keySystemAssociationOrError.isFailed()) { - throw new Error(`Failed to create revision from projection: ${keySystemAssociationOrError.getError()}`) - } - keySystemAssociation = keySystemAssociationOrError.getValue() - } - - const revisionOrError = Revision.create( - { - authHash: projection.authHash, - content: projection.content, - contentType, - creationDate: new Date(this.timer.convertDateToFormattedString(projection.creationDate, 'YYYY-MM-DD')), - encItemKey: projection.encItemKey, - itemsKeyId: projection.itemsKeyId, - itemUuid, - userUuid, - dates, - sharedVaultAssociation, - keySystemAssociation, - }, - new UniqueEntityId(projection._id.toHexString()), - ) - if (revisionOrError.isFailed()) { - throw new Error(`Could not map typeorm revision to domain revision: ${revisionOrError.getError()}`) - } - - return revisionOrError.getValue() - } - - toProjection(domain: Revision): MongoDBRevision { - const mongoDBRevision = new MongoDBRevision() - - mongoDBRevision.authHash = domain.props.authHash - mongoDBRevision.content = domain.props.content - mongoDBRevision.contentType = domain.props.contentType.value - mongoDBRevision.createdAt = domain.props.dates.createdAt - mongoDBRevision.updatedAt = domain.props.dates.updatedAt - mongoDBRevision.creationDate = new Date( - this.timer.convertDateToFormattedString(domain.props.creationDate, 'YYYY-MM-DD'), - ) - mongoDBRevision.encItemKey = domain.props.encItemKey - mongoDBRevision.itemUuid = domain.props.itemUuid.value - mongoDBRevision.itemsKeyId = domain.props.itemsKeyId - mongoDBRevision.userUuid = domain.props.userUuid ? domain.props.userUuid.value : null - mongoDBRevision.sharedVaultUuid = domain.props.sharedVaultAssociation - ? domain.props.sharedVaultAssociation.props.sharedVaultUuid.value - : null - mongoDBRevision.editedBy = domain.props.sharedVaultAssociation - ? domain.props.sharedVaultAssociation.props.editedBy.value - : null - mongoDBRevision.keySystemIdentifier = domain.props.keySystemAssociation - ? domain.props.keySystemAssociation.props.keySystemIdentifier - : null - mongoDBRevision._id = BSON.UUID.createFromHexString(domain.id.toString()) - - return mongoDBRevision - } -} diff --git a/packages/security/src/Domain/Token/CrossServiceTokenData.ts b/packages/security/src/Domain/Token/CrossServiceTokenData.ts index f5edfa730..8064c74fa 100644 --- a/packages/security/src/Domain/Token/CrossServiceTokenData.ts +++ b/packages/security/src/Domain/Token/CrossServiceTokenData.ts @@ -24,6 +24,4 @@ export type CrossServiceTokenData = { refresh_expiration: string } extensionKey?: string - ongoing_transition?: boolean - ongoing_revisions_transition?: boolean } diff --git a/packages/security/src/Domain/Token/ValetTokenData.ts b/packages/security/src/Domain/Token/ValetTokenData.ts index 3c332fac5..6178a0874 100644 --- a/packages/security/src/Domain/Token/ValetTokenData.ts +++ b/packages/security/src/Domain/Token/ValetTokenData.ts @@ -11,5 +11,4 @@ export type ValetTokenData = { }> uploadBytesUsed: number uploadBytesLimit: number - ongoingTransition?: boolean } diff --git a/packages/syncing-server/.env.sample b/packages/syncing-server/.env.sample index 52ee237a6..29ed58497 100644 --- a/packages/syncing-server/.env.sample +++ b/packages/syncing-server/.env.sample @@ -17,9 +17,6 @@ DB_DEBUG_LEVEL=all # "all" | "query" | "schema" | "error" | "warn" | "info" | "l DB_MIGRATIONS_PATH=dist/migrations/*.js DB_TYPE=mysql -REDIS_URL=redis://cache -CACHE_TYPE=redis - VALET_TOKEN_SECRET=change-me-! VALET_TOKEN_TTL=1000 @@ -43,11 +40,3 @@ FILE_UPLOAD_PATH= VALET_TOKEN_SECRET=change-me-! VALET_TOKEN_TTL=7200 - -# (Optional) Mongo Setup -SECONDARY_DB_ENABLED=false -MONGO_HOST= -MONGO_PORT= -MONGO_USERNAME= -MONGO_PASSWORD= -MONGO_DATABASE= diff --git a/packages/syncing-server/package.json b/packages/syncing-server/package.json index e1f0bd726..0e3d33806 100644 --- a/packages/syncing-server/package.json +++ b/packages/syncing-server/package.json @@ -49,7 +49,6 @@ "inversify-express-utils": "^6.4.3", "ioredis": "^5.3.2", "jsonwebtoken": "^9.0.0", - "mongodb": "^6.0.0", "mysql2": "^3.0.1", "prettyjson": "^1.2.5", "reflect-metadata": "0.1.13", diff --git a/packages/syncing-server/src/Bootstrap/Container.ts b/packages/syncing-server/src/Bootstrap/Container.ts index e4c2847d1..7d20d8989 100644 --- a/packages/syncing-server/src/Bootstrap/Container.ts +++ b/packages/syncing-server/src/Bootstrap/Container.ts @@ -1,5 +1,4 @@ import * as winston from 'winston' -import Redis from 'ioredis' import { Container, interfaces } from 'inversify' import { Env } from './Env' @@ -8,7 +7,7 @@ import { AppDataSource } from './DataSource' import { SNSClient, SNSClientConfig } from '@aws-sdk/client-sns' import { ItemRepositoryInterface } from '../Domain/Item/ItemRepositoryInterface' import { SQLLegacyItemRepository } from '../Infra/TypeORM/SQLLegacyItemRepository' -import { MongoRepository, Repository } from 'typeorm' +import { Repository } from 'typeorm' import { Item } from '../Domain/Item/Item' import { DirectCallDomainEventPublisher, @@ -151,27 +150,18 @@ import { UpdateStorageQuotaUsedInSharedVault } from '../Domain/UseCase/SharedVau import { SharedVaultFileUploadedEventHandler } from '../Domain/Handler/SharedVaultFileUploadedEventHandler' import { SharedVaultFileRemovedEventHandler } from '../Domain/Handler/SharedVaultFileRemovedEventHandler' import { AddNotificationsForUsers } from '../Domain/UseCase/Messaging/AddNotificationsForUsers/AddNotificationsForUsers' -import { MongoDBItem } from '../Infra/TypeORM/MongoDBItem' -import { MongoDBItemRepository } from '../Infra/TypeORM/MongoDBItemRepository' -import { MongoDBItemPersistenceMapper } from '../Mapping/Persistence/MongoDB/MongoDBItemPersistenceMapper' import { Logger } from 'winston' -import { ItemRepositoryResolverInterface } from '../Domain/Item/ItemRepositoryResolverInterface' -import { TypeORMItemRepositoryResolver } from '../Infra/TypeORM/TypeORMItemRepositoryResolver' -import { TransitionItemsFromPrimaryToSecondaryDatabaseForUser } from '../Domain/UseCase/Transition/TransitionItemsFromPrimaryToSecondaryDatabaseForUser/TransitionItemsFromPrimaryToSecondaryDatabaseForUser' import { SharedVaultFileMovedEventHandler } from '../Domain/Handler/SharedVaultFileMovedEventHandler' import { SQLItem } from '../Infra/TypeORM/SQLItem' import { SQLItemPersistenceMapper } from '../Mapping/Persistence/SQLItemPersistenceMapper' import { SQLItemRepository } from '../Infra/TypeORM/SQLItemRepository' import { SendEventToClient } from '../Domain/UseCase/Syncing/SendEventToClient/SendEventToClient' -import { TransitionRequestedEventHandler } from '../Domain/Handler/TransitionRequestedEventHandler' import { DeleteSharedVaults } from '../Domain/UseCase/SharedVaults/DeleteSharedVaults/DeleteSharedVaults' import { RemoveItemsFromSharedVault } from '../Domain/UseCase/SharedVaults/RemoveItemsFromSharedVault/RemoveItemsFromSharedVault' import { SharedVaultRemovedEventHandler } from '../Domain/Handler/SharedVaultRemovedEventHandler' import { DesignateSurvivor } from '../Domain/UseCase/SharedVaults/DesignateSurvivor/DesignateSurvivor' import { RemoveUserFromSharedVaults } from '../Domain/UseCase/SharedVaults/RemoveUserFromSharedVaults/RemoveUserFromSharedVaults' import { TransferSharedVault } from '../Domain/UseCase/SharedVaults/TransferSharedVault/TransferSharedVault' -import { TransitionRepositoryInterface } from '../Domain/Transition/TransitionRepositoryInterface' -import { RedisTransitionRepository } from '../Infra/Redis/RedisTransitionRepository' import { TransferSharedVaultItems } from '../Domain/UseCase/SharedVaults/TransferSharedVaultItems/TransferSharedVaultItems' import { DumpItem } from '../Domain/UseCase/Syncing/DumpItem/DumpItem' @@ -223,29 +213,11 @@ export class ContainerConfigLoader { const isConfiguredForHomeServer = env.get('MODE', true) === 'home-server' const isConfiguredForSelfHosting = env.get('MODE', true) === 'self-hosted' const isConfiguredForHomeServerOrSelfHosting = isConfiguredForHomeServer || isConfiguredForSelfHosting - const isSecondaryDatabaseEnabled = env.get('SECONDARY_DB_ENABLED', true) === 'true' - const isConfiguredForInMemoryCache = env.get('CACHE_TYPE', true) === 'memory' container .bind(TYPES.Sync_IS_CONFIGURED_FOR_HOME_SERVER_OR_SELF_HOSTING) .toConstantValue(isConfiguredForHomeServerOrSelfHosting) - if (!isConfiguredForInMemoryCache) { - const redisUrl = env.get('REDIS_URL') - const isRedisInClusterMode = redisUrl.indexOf(',') > 0 - let redis - if (isRedisInClusterMode) { - redis = new Redis.Cluster(redisUrl.split(',')) - } else { - redis = new Redis(redisUrl) - } - - container.bind(TYPES.Sync_Redis).toConstantValue(redis) - container - .bind(TYPES.Sync_TransitionStatusRepository) - .toConstantValue(new RedisTransitionRepository(container.get(TYPES.Sync_Redis))) - } - container.bind(TYPES.Sync_Env).toConstantValue(env) if (isConfiguredForHomeServer) { @@ -413,27 +385,6 @@ export class ContainerConfigLoader { .bind>(TYPES.Sync_ORMMessageRepository) .toConstantValue(appDataSource.getRepository(TypeORMMessage)) - // Mongo - if (isSecondaryDatabaseEnabled) { - container - .bind>(TYPES.Sync_MongoDBItemPersistenceMapper) - .toConstantValue(new MongoDBItemPersistenceMapper()) - - container - .bind>(TYPES.Sync_ORMMongoItemRepository) - .toConstantValue(appDataSource.getMongoRepository(MongoDBItem)) - - container - .bind(TYPES.Sync_MongoDBItemRepository) - .toConstantValue( - new MongoDBItemRepository( - container.get>(TYPES.Sync_ORMMongoItemRepository), - container.get>(TYPES.Sync_MongoDBItemPersistenceMapper), - container.get(TYPES.Sync_Logger), - ), - ) - } - // Repositories container .bind(TYPES.Sync_SQLItemRepository) @@ -450,14 +401,6 @@ export class ContainerConfigLoader { container.get(TYPES.Sync_Logger), ), ) - container - .bind(TYPES.Sync_ItemRepositoryResolver) - .toConstantValue( - new TypeORMItemRepositoryResolver( - container.get(TYPES.Sync_SQLItemRepository), - isSecondaryDatabaseEnabled ? container.get(TYPES.Sync_MongoDBItemRepository) : null, - ), - ) container .bind(TYPES.Sync_SharedVaultRepository) .toConstantValue( @@ -603,7 +546,7 @@ export class ContainerConfigLoader { .bind(TYPES.Sync_GetItems) .toConstantValue( new GetItems( - container.get(TYPES.Sync_ItemRepositoryResolver), + container.get(TYPES.Sync_SQLItemRepository), container.get(TYPES.Sync_SharedVaultUserRepository), container.get(TYPES.Sync_CONTENT_SIZE_TRANSFER_LIMIT), container.get(TYPES.Sync_ItemTransferCalculator), @@ -615,7 +558,7 @@ export class ContainerConfigLoader { .bind(TYPES.Sync_SaveNewItem) .toConstantValue( new SaveNewItem( - container.get(TYPES.Sync_ItemRepositoryResolver), + container.get(TYPES.Sync_SQLItemRepository), container.get(TYPES.Sync_Timer), container.get(TYPES.Sync_DomainEventPublisher), container.get(TYPES.Sync_DomainEventFactory), @@ -655,7 +598,7 @@ export class ContainerConfigLoader { .bind(TYPES.Sync_UpdateExistingItem) .toConstantValue( new UpdateExistingItem( - container.get(TYPES.Sync_ItemRepositoryResolver), + container.get(TYPES.Sync_SQLItemRepository), container.get(TYPES.Sync_Timer), container.get(TYPES.Sync_DomainEventPublisher), container.get(TYPES.Sync_DomainEventFactory), @@ -670,7 +613,7 @@ export class ContainerConfigLoader { .toConstantValue( new SaveItems( container.get(TYPES.Sync_ItemSaveValidator), - container.get(TYPES.Sync_ItemRepositoryResolver), + container.get(TYPES.Sync_SQLItemRepository), container.get(TYPES.Sync_Timer), container.get(TYPES.Sync_SaveNewItem), container.get(TYPES.Sync_UpdateExistingItem), @@ -699,7 +642,7 @@ export class ContainerConfigLoader { .bind(TYPES.Sync_SyncItems) .toConstantValue( new SyncItems( - container.get(TYPES.Sync_ItemRepositoryResolver), + container.get(TYPES.Sync_SQLItemRepository), container.get(TYPES.Sync_GetItems), container.get(TYPES.Sync_SaveItems), container.get(TYPES.Sync_GetSharedVaults), @@ -710,10 +653,10 @@ export class ContainerConfigLoader { ), ) container.bind(TYPES.Sync_CheckIntegrity).toDynamicValue((context: interfaces.Context) => { - return new CheckIntegrity(context.container.get(TYPES.Sync_ItemRepositoryResolver)) + return new CheckIntegrity(context.container.get(TYPES.Sync_SQLItemRepository)) }) container.bind(TYPES.Sync_GetItem).toDynamicValue((context: interfaces.Context) => { - return new GetItem(context.container.get(TYPES.Sync_ItemRepositoryResolver)) + return new GetItem(context.container.get(TYPES.Sync_SQLItemRepository)) }) container .bind(TYPES.Sync_InviteUserToSharedVault) @@ -854,32 +797,10 @@ export class ContainerConfigLoader { container.get(TYPES.Sync_SharedVaultRepository), ), ) - container - .bind( - TYPES.Sync_TransitionItemsFromPrimaryToSecondaryDatabaseForUser, - ) - .toConstantValue( - new TransitionItemsFromPrimaryToSecondaryDatabaseForUser( - container.get(TYPES.Sync_SQLItemRepository), - isSecondaryDatabaseEnabled ? container.get(TYPES.Sync_MongoDBItemRepository) : null, - isConfiguredForInMemoryCache - ? null - : container.get(TYPES.Sync_TransitionStatusRepository), - container.get(TYPES.Sync_Timer), - container.get(TYPES.Sync_Logger), - env.get('MIGRATION_BATCH_SIZE', true) ? +env.get('MIGRATION_BATCH_SIZE', true) : 100, - container.get(TYPES.Sync_DomainEventPublisher), - container.get(TYPES.Sync_DomainEventFactory), - ), - ) container .bind(TYPES.Sync_RemoveItemsFromSharedVault) .toConstantValue( - new RemoveItemsFromSharedVault( - isSecondaryDatabaseEnabled - ? container.get(TYPES.Sync_MongoDBItemRepository) - : container.get(TYPES.Sync_SQLItemRepository), - ), + new RemoveItemsFromSharedVault(container.get(TYPES.Sync_SQLItemRepository)), ) container .bind(TYPES.Sync_DesignateSurvivor) @@ -905,11 +826,7 @@ export class ContainerConfigLoader { container .bind(TYPES.Sync_TransferSharedVaultItems) .toConstantValue( - new TransferSharedVaultItems( - isSecondaryDatabaseEnabled - ? container.get(TYPES.Sync_MongoDBItemRepository) - : container.get(TYPES.Sync_SQLItemRepository), - ), + new TransferSharedVaultItems(container.get(TYPES.Sync_SQLItemRepository)), ) container .bind(TYPES.Sync_TransferSharedVault) @@ -947,7 +864,7 @@ export class ContainerConfigLoader { .bind(TYPES.Sync_DumpItem) .toConstantValue( new DumpItem( - container.get(TYPES.Sync_ItemRepositoryResolver), + container.get(TYPES.Sync_SQLItemRepository), container.get(TYPES.Sync_ItemBackupService), container.get(TYPES.Sync_DomainEventFactory), container.get(TYPES.Sync_DomainEventPublisher), @@ -985,7 +902,7 @@ export class ContainerConfigLoader { .bind(TYPES.Sync_DuplicateItemSyncedEventHandler) .toConstantValue( new DuplicateItemSyncedEventHandler( - container.get(TYPES.Sync_ItemRepositoryResolver), + container.get(TYPES.Sync_SQLItemRepository), container.get(TYPES.Sync_DomainEventFactory), container.get(TYPES.Sync_DomainEventPublisher), container.get(TYPES.Sync_Logger), @@ -995,7 +912,7 @@ export class ContainerConfigLoader { .bind(TYPES.Sync_AccountDeletionRequestedEventHandler) .toConstantValue( new AccountDeletionRequestedEventHandler( - container.get(TYPES.Sync_ItemRepositoryResolver), + container.get(TYPES.Sync_SQLItemRepository), container.get(TYPES.Sync_DeleteSharedVaults), container.get(TYPES.Sync_RemoveUserFromSharedVaults), container.get(TYPES.Sync_Logger), @@ -1036,17 +953,6 @@ export class ContainerConfigLoader { container.get(TYPES.Sync_Logger), ), ) - container - .bind(TYPES.Sync_TransitionRequestedEventHandler) - .toConstantValue( - new TransitionRequestedEventHandler( - false, - container.get( - TYPES.Sync_TransitionItemsFromPrimaryToSecondaryDatabaseForUser, - ), - container.get(TYPES.Sync_Logger), - ), - ) container .bind(TYPES.Sync_SharedVaultRemovedEventHandler) .toConstantValue( @@ -1065,7 +971,6 @@ export class ContainerConfigLoader { new ExtensionsHttpService( container.get(TYPES.Sync_HTTPClient), container.get(TYPES.Sync_SQLItemRepository), - isSecondaryDatabaseEnabled ? container.get(TYPES.Sync_MongoDBItemRepository) : null, container.get(TYPES.Sync_ContentDecoder), container.get(TYPES.Sync_DomainEventPublisher), container.get(TYPES.Sync_DomainEventFactory), @@ -1089,10 +994,6 @@ export class ContainerConfigLoader { 'SHARED_VAULT_FILE_MOVED', container.get(TYPES.Sync_SharedVaultFileMovedEventHandler), ], - [ - 'TRANSITION_REQUESTED', - container.get(TYPES.Sync_TransitionRequestedEventHandler), - ], [ 'SHARED_VAULT_REMOVED', container.get(TYPES.Sync_SharedVaultRemovedEventHandler), @@ -1104,9 +1005,6 @@ export class ContainerConfigLoader { .toConstantValue( new EmailBackupRequestedEventHandler( container.get(TYPES.Sync_SQLItemRepository), - isSecondaryDatabaseEnabled - ? container.get(TYPES.Sync_MongoDBItemRepository) - : null, container.get(TYPES.Sync_ItemBackupService), container.get(TYPES.Sync_DomainEventPublisher), container.get(TYPES.Sync_DomainEventFactory), diff --git a/packages/syncing-server/src/Bootstrap/DataSource.ts b/packages/syncing-server/src/Bootstrap/DataSource.ts index e5e8eac4f..53acef819 100644 --- a/packages/syncing-server/src/Bootstrap/DataSource.ts +++ b/packages/syncing-server/src/Bootstrap/DataSource.ts @@ -1,4 +1,4 @@ -import { DataSource, EntityTarget, LoggerOptions, MongoRepository, ObjectLiteral, Repository } from 'typeorm' +import { DataSource, EntityTarget, LoggerOptions, ObjectLiteral, Repository } from 'typeorm' import { MysqlConnectionOptions } from 'typeorm/driver/mysql/MysqlConnectionOptions' import { Env } from './Env' import { SqliteConnectionOptions } from 'typeorm/driver/sqlite/SqliteConnectionOptions' @@ -8,12 +8,10 @@ import { TypeORMSharedVault } from '../Infra/TypeORM/TypeORMSharedVault' import { TypeORMSharedVaultUser } from '../Infra/TypeORM/TypeORMSharedVaultUser' import { TypeORMSharedVaultInvite } from '../Infra/TypeORM/TypeORMSharedVaultInvite' import { TypeORMMessage } from '../Infra/TypeORM/TypeORMMessage' -import { MongoDBItem } from '../Infra/TypeORM/MongoDBItem' import { SQLItem } from '../Infra/TypeORM/SQLItem' export class AppDataSource { private _dataSource: DataSource | undefined - private _secondaryDataSource: DataSource | undefined constructor( private configuration: { @@ -30,43 +28,8 @@ export class AppDataSource { return this._dataSource.getRepository(target) } - getMongoRepository(target: EntityTarget): MongoRepository { - if (!this._secondaryDataSource) { - throw new Error('Secondary DataSource not initialized') - } - - return this._secondaryDataSource.getMongoRepository(target) - } - async initialize(): Promise { await this.dataSource.initialize() - const secondaryDataSource = this.secondaryDataSource - if (secondaryDataSource) { - await secondaryDataSource.initialize() - } - } - - get secondaryDataSource(): DataSource | undefined { - this.configuration.env.load() - - if (this.configuration.env.get('SECONDARY_DB_ENABLED', true) !== 'true') { - return undefined - } - - this._secondaryDataSource = new DataSource({ - type: 'mongodb', - host: this.configuration.env.get('MONGO_HOST'), - authSource: 'admin', - port: parseInt(this.configuration.env.get('MONGO_PORT')), - username: this.configuration.env.get('MONGO_USERNAME'), - password: this.configuration.env.get('MONGO_PASSWORD', true), - database: this.configuration.env.get('MONGO_DATABASE'), - entities: [MongoDBItem], - retryWrites: false, - synchronize: true, - }) - - return this._secondaryDataSource } get dataSource(): DataSource { diff --git a/packages/syncing-server/src/Bootstrap/Types.ts b/packages/syncing-server/src/Bootstrap/Types.ts index 88bad977a..2e22eecba 100644 --- a/packages/syncing-server/src/Bootstrap/Types.ts +++ b/packages/syncing-server/src/Bootstrap/Types.ts @@ -7,15 +7,12 @@ const TYPES = { Sync_S3: Symbol.for('Sync_S3'), Sync_Env: Symbol.for('Sync_Env'), // Repositories - Sync_ItemRepositoryResolver: Symbol.for('Sync_ItemRepositoryResolver'), Sync_SQLItemRepository: Symbol.for('Sync_SQLItemRepository'), - Sync_MongoDBItemRepository: Symbol.for('Sync_MongoDBItemRepository'), Sync_SharedVaultRepository: Symbol.for('Sync_SharedVaultRepository'), Sync_SharedVaultInviteRepository: Symbol.for('Sync_SharedVaultInviteRepository'), Sync_SharedVaultUserRepository: Symbol.for('Sync_SharedVaultUserRepository'), Sync_NotificationRepository: Symbol.for('Sync_NotificationRepository'), Sync_MessageRepository: Symbol.for('Sync_MessageRepository'), - Sync_TransitionStatusRepository: Symbol.for('Sync_TransitionStatusRepository'), // ORM Sync_ORMItemRepository: Symbol.for('Sync_ORMItemRepository'), Sync_ORMLegacyItemRepository: Symbol.for('Sync_ORMLegacyItemRepository'), @@ -24,8 +21,6 @@ const TYPES = { Sync_ORMSharedVaultUserRepository: Symbol.for('Sync_ORMSharedVaultUserRepository'), Sync_ORMNotificationRepository: Symbol.for('Sync_ORMNotificationRepository'), Sync_ORMMessageRepository: Symbol.for('Sync_ORMMessageRepository'), - // Mongo - Sync_ORMMongoItemRepository: Symbol.for('Sync_ORMMongoItemRepository'), // Middleware Sync_AuthMiddleware: Symbol.for('Sync_AuthMiddleware'), // env vars @@ -82,9 +77,6 @@ const TYPES = { Sync_DetermineSharedVaultOperationOnItem: Symbol.for('Sync_DetermineSharedVaultOperationOnItem'), Sync_UpdateStorageQuotaUsedInSharedVault: Symbol.for('Sync_UpdateStorageQuotaUsedInSharedVault'), Sync_AddNotificationsForUsers: Symbol.for('Sync_AddNotificationsForUsers'), - Sync_TransitionItemsFromPrimaryToSecondaryDatabaseForUser: Symbol.for( - 'Sync_TransitionItemsFromPrimaryToSecondaryDatabaseForUser', - ), Sync_SendEventToClient: Symbol.for('Sync_SendEventToClient'), Sync_RemoveItemsFromSharedVault: Symbol.for('Sync_RemoveItemsFromSharedVault'), Sync_DesignateSurvivor: Symbol.for('Sync_DesignateSurvivor'), @@ -100,7 +92,6 @@ const TYPES = { Sync_SharedVaultFileRemovedEventHandler: Symbol.for('Sync_SharedVaultFileRemovedEventHandler'), Sync_SharedVaultFileUploadedEventHandler: Symbol.for('Sync_SharedVaultFileUploadedEventHandler'), Sync_SharedVaultFileMovedEventHandler: Symbol.for('Sync_SharedVaultFileMovedEventHandler'), - Sync_TransitionRequestedEventHandler: Symbol.for('Sync_TransitionRequestedEventHandler'), Sync_SharedVaultRemovedEventHandler: Symbol.for('Sync_SharedVaultRemovedEventHandler'), // Services Sync_ContentDecoder: Symbol.for('Sync_ContentDecoder'), @@ -139,7 +130,6 @@ const TYPES = { Sync_NotificationHttpMapper: Symbol.for('Sync_NotificationHttpMapper'), Sync_SQLLegacyItemPersistenceMapper: Symbol.for('Sync_SQLLegacyItemPersistenceMapper'), Sync_SQLItemPersistenceMapper: Symbol.for('Sync_SQLItemPersistenceMapper'), - Sync_MongoDBItemPersistenceMapper: Symbol.for('Sync_MongoDBItemPersistenceMapper'), Sync_ItemHttpMapper: Symbol.for('Sync_ItemHttpMapper'), Sync_ItemHashHttpMapper: Symbol.for('Sync_ItemHashHttpMapper'), Sync_SavedItemHttpMapper: Symbol.for('Sync_SavedItemHttpMapper'), diff --git a/packages/syncing-server/src/Domain/Event/DomainEventFactory.ts b/packages/syncing-server/src/Domain/Event/DomainEventFactory.ts index f2ef8d075..6bda70379 100644 --- a/packages/syncing-server/src/Domain/Event/DomainEventFactory.ts +++ b/packages/syncing-server/src/Domain/Event/DomainEventFactory.ts @@ -10,7 +10,6 @@ import { NotificationAddedForUserEvent, RevisionsCopyRequestedEvent, SharedVaultRemovedEvent, - TransitionStatusUpdatedEvent, UserAddedToSharedVaultEvent, UserDesignatedAsSurvivorInSharedVaultEvent, UserInvitedToSharedVaultEvent, @@ -204,32 +203,11 @@ export class DomainEventFactory implements DomainEventFactoryInterface { } } - createTransitionStatusUpdatedEvent(dto: { - userUuid: string - transitionType: 'items' | 'revisions' - transitionTimestamp: number - status: string - }): TransitionStatusUpdatedEvent { - return { - type: 'TRANSITION_STATUS_UPDATED', - createdAt: this.timer.getUTCDate(), - meta: { - correlation: { - userIdentifier: dto.userUuid, - userIdentifierType: 'uuid', - }, - origin: DomainEventService.SyncingServer, - }, - payload: dto, - } - } - createRevisionsCopyRequestedEvent( userUuid: string, dto: { originalItemUuid: string newItemUuid: string - roleNames: string[] }, ): RevisionsCopyRequestedEvent { return { @@ -246,7 +224,7 @@ export class DomainEventFactory implements DomainEventFactoryInterface { } } - createItemDumpedEvent(dto: { fileDumpPath: string; userUuid: string; roleNames: string[] }): ItemDumpedEvent { + createItemDumpedEvent(dto: { fileDumpPath: string; userUuid: string }): ItemDumpedEvent { return { type: 'ITEM_DUMPED', createdAt: this.timer.getUTCDate(), @@ -259,16 +237,11 @@ export class DomainEventFactory implements DomainEventFactoryInterface { }, payload: { fileDumpPath: dto.fileDumpPath, - roleNames: dto.roleNames, }, } } - createItemRevisionCreationRequested(dto: { - itemUuid: string - userUuid: string - roleNames: string[] - }): ItemRevisionCreationRequestedEvent { + createItemRevisionCreationRequested(dto: { itemUuid: string; userUuid: string }): ItemRevisionCreationRequestedEvent { return { type: 'ITEM_REVISION_CREATION_REQUESTED', createdAt: this.timer.getUTCDate(), @@ -281,16 +254,11 @@ export class DomainEventFactory implements DomainEventFactoryInterface { }, payload: { itemUuid: dto.itemUuid, - roleNames: dto.roleNames, }, } } - createDuplicateItemSyncedEvent(dto: { - itemUuid: string - userUuid: string - roleNames: string[] - }): DuplicateItemSyncedEvent { + createDuplicateItemSyncedEvent(dto: { itemUuid: string; userUuid: string }): DuplicateItemSyncedEvent { return { type: 'DUPLICATE_ITEM_SYNCED', createdAt: this.timer.getUTCDate(), diff --git a/packages/syncing-server/src/Domain/Event/DomainEventFactoryInterface.ts b/packages/syncing-server/src/Domain/Event/DomainEventFactoryInterface.ts index 73deaa48b..aed8cab7a 100644 --- a/packages/syncing-server/src/Domain/Event/DomainEventFactoryInterface.ts +++ b/packages/syncing-server/src/Domain/Event/DomainEventFactoryInterface.ts @@ -8,7 +8,6 @@ import { NotificationAddedForUserEvent, RevisionsCopyRequestedEvent, SharedVaultRemovedEvent, - TransitionStatusUpdatedEvent, UserAddedToSharedVaultEvent, UserDesignatedAsSurvivorInSharedVaultEvent, UserInvitedToSharedVaultEvent, @@ -51,12 +50,6 @@ export interface DomainEventFactoryInterface { updated_at_timestamp: number } }): NotificationAddedForUserEvent - createTransitionStatusUpdatedEvent(dto: { - userUuid: string - transitionType: 'items' | 'revisions' - transitionTimestamp: number - status: string - }): TransitionStatusUpdatedEvent createEmailRequestedEvent(dto: { userEmail: string messageIdentifier: string @@ -71,20 +64,12 @@ export interface DomainEventFactoryInterface { attachmentContentType: string }> }): EmailRequestedEvent - createDuplicateItemSyncedEvent(dto: { - itemUuid: string - userUuid: string - roleNames: string[] - }): DuplicateItemSyncedEvent - createItemRevisionCreationRequested(dto: { - itemUuid: string - userUuid: string - roleNames: string[] - }): ItemRevisionCreationRequestedEvent - createItemDumpedEvent(dto: { fileDumpPath: string; userUuid: string; roleNames: string[] }): ItemDumpedEvent + createDuplicateItemSyncedEvent(dto: { itemUuid: string; userUuid: string }): DuplicateItemSyncedEvent + createItemRevisionCreationRequested(dto: { itemUuid: string; userUuid: string }): ItemRevisionCreationRequestedEvent + createItemDumpedEvent(dto: { fileDumpPath: string; userUuid: string }): ItemDumpedEvent createRevisionsCopyRequestedEvent( userUuid: string, - dto: { originalItemUuid: string; newItemUuid: string; roleNames: string[] }, + dto: { originalItemUuid: string; newItemUuid: string }, ): RevisionsCopyRequestedEvent createUserAddedToSharedVaultEvent(dto: { sharedVaultUuid: string diff --git a/packages/syncing-server/src/Domain/Extension/ExtensionsHttpService.spec.ts b/packages/syncing-server/src/Domain/Extension/ExtensionsHttpService.spec.ts index de6de21a0..4d93c6149 100644 --- a/packages/syncing-server/src/Domain/Extension/ExtensionsHttpService.spec.ts +++ b/packages/syncing-server/src/Domain/Extension/ExtensionsHttpService.spec.ts @@ -14,7 +14,6 @@ import { Uuid, ContentType, Dates, Timestamps, UniqueEntityId } from '@standardn describe('ExtensionsHttpService', () => { let httpClient: AxiosInstance let primaryItemRepository: ItemRepositoryInterface - let secondaryItemRepository: ItemRepositoryInterface | null let contentDecoder: ContentDecoderInterface let domainEventPublisher: DomainEventPublisherInterface let domainEventFactory: DomainEventFactoryInterface @@ -26,7 +25,6 @@ describe('ExtensionsHttpService', () => { new ExtensionsHttpService( httpClient, primaryItemRepository, - secondaryItemRepository, contentDecoder, domainEventPublisher, domainEventFactory, @@ -193,31 +191,6 @@ describe('ExtensionsHttpService', () => { expect(domainEventFactory.createEmailRequestedEvent).toHaveBeenCalled() }) - it('should publish a failed backup event if the extension is in the secondary repository', async () => { - primaryItemRepository.findByUuidAndUserUuid = jest.fn().mockReturnValue(null) - secondaryItemRepository = {} as jest.Mocked - secondaryItemRepository.findByUuidAndUserUuid = jest.fn().mockReturnValue(item) - - httpClient.request = jest.fn().mockImplementation(() => { - throw new Error('Could not reach the extensions server') - }) - - await createService().sendItemsToExtensionsServer({ - userUuid: '1-2-3', - extensionId: '2-3-4', - extensionsServerUrl: '', - forceMute: false, - items: [item], - backupFilename: 'backup-file', - authParams, - }) - - expect(domainEventPublisher.publish).toHaveBeenCalled() - expect(domainEventFactory.createEmailRequestedEvent).toHaveBeenCalled() - - secondaryItemRepository = null - }) - it('should publish a failed Dropbox backup event if request was sent and extensions server responded not ok', async () => { contentDecoder.decode = jest.fn().mockReturnValue({ name: 'Dropbox' }) diff --git a/packages/syncing-server/src/Domain/Extension/ExtensionsHttpService.ts b/packages/syncing-server/src/Domain/Extension/ExtensionsHttpService.ts index 7f55807da..43c47cdde 100644 --- a/packages/syncing-server/src/Domain/Extension/ExtensionsHttpService.ts +++ b/packages/syncing-server/src/Domain/Extension/ExtensionsHttpService.ts @@ -18,7 +18,6 @@ export class ExtensionsHttpService implements ExtensionsHttpServiceInterface { constructor( private httpClient: AxiosInstance, private primaryItemRepository: ItemRepositoryInterface, - private secondaryItemRepository: ItemRepositoryInterface | null, private contentDecoder: ContentDecoderInterface, private domainEventPublisher: DomainEventPublisherInterface, private domainEventFactory: DomainEventFactoryInterface, @@ -140,14 +139,9 @@ export class ExtensionsHttpService implements ExtensionsHttpServiceInterface { userUuid: string, email: string, ): Promise { - let extension = await this.primaryItemRepository.findByUuidAndUserUuid(extensionId, userUuid) + const extension = await this.primaryItemRepository.findByUuidAndUserUuid(extensionId, userUuid) if (extension === null || !extension.props.content) { - if (this.secondaryItemRepository) { - extension = await this.secondaryItemRepository.findByUuidAndUserUuid(extensionId, userUuid) - } - if (extension === null || !extension.props.content) { - throw Error(`Could not find extensions with id ${extensionId}`) - } + throw Error(`Could not find extensions with id ${extensionId}`) } const content = this.contentDecoder.decode(extension.props.content) diff --git a/packages/syncing-server/src/Domain/Handler/AccountDeletionRequestedEventHandler.ts b/packages/syncing-server/src/Domain/Handler/AccountDeletionRequestedEventHandler.ts index 63992e4db..b14e3ab4e 100644 --- a/packages/syncing-server/src/Domain/Handler/AccountDeletionRequestedEventHandler.ts +++ b/packages/syncing-server/src/Domain/Handler/AccountDeletionRequestedEventHandler.ts @@ -1,14 +1,14 @@ import { AccountDeletionRequestedEvent, DomainEventHandlerInterface } from '@standardnotes/domain-events' -import { RoleNameCollection, Uuid } from '@standardnotes/domain-core' +import { Uuid } from '@standardnotes/domain-core' import { Logger } from 'winston' -import { ItemRepositoryResolverInterface } from '../Item/ItemRepositoryResolverInterface' import { DeleteSharedVaults } from '../UseCase/SharedVaults/DeleteSharedVaults/DeleteSharedVaults' import { RemoveUserFromSharedVaults } from '../UseCase/SharedVaults/RemoveUserFromSharedVaults/RemoveUserFromSharedVaults' +import { ItemRepositoryInterface } from '../Item/ItemRepositoryInterface' export class AccountDeletionRequestedEventHandler implements DomainEventHandlerInterface { constructor( - private itemRepositoryResolver: ItemRepositoryResolverInterface, + private itemRepository: ItemRepositoryInterface, private deleteSharedVaults: DeleteSharedVaults, private removeUserFromSharedVaults: RemoveUserFromSharedVaults, private logger: Logger, @@ -23,17 +23,7 @@ export class AccountDeletionRequestedEventHandler implements DomainEventHandlerI } const userUuid = userUuidOrError.getValue() - const roleNamesOrError = RoleNameCollection.create(event.payload.roleNames) - if (roleNamesOrError.isFailed()) { - this.logger.error(`AccountDeletionRequestedEventHandler failed: ${roleNamesOrError.getError()}`) - - return - } - const roleNames = roleNamesOrError.getValue() - - const itemRepository = this.itemRepositoryResolver.resolve(roleNames) - - await itemRepository.deleteByUserUuidAndNotInSharedVault(userUuid) + await this.itemRepository.deleteByUserUuidAndNotInSharedVault(userUuid) const deletingVaultsResult = await this.deleteSharedVaults.execute({ ownerUuid: event.payload.userUuid, @@ -52,7 +42,7 @@ export class AccountDeletionRequestedEventHandler implements DomainEventHandlerI ) if (deletedSharedVaultUuids.length !== 0) { - await itemRepository.deleteByUserUuidInSharedVaults(userUuid, deletedSharedVaultUuids) + await this.itemRepository.deleteByUserUuidInSharedVaults(userUuid, deletedSharedVaultUuids) } const deletingUserFromOtherVaultsResult = await this.removeUserFromSharedVaults.execute({ diff --git a/packages/syncing-server/src/Domain/Handler/DuplicateItemSyncedEventHandler.ts b/packages/syncing-server/src/Domain/Handler/DuplicateItemSyncedEventHandler.ts index b484d2391..20219fdd0 100644 --- a/packages/syncing-server/src/Domain/Handler/DuplicateItemSyncedEventHandler.ts +++ b/packages/syncing-server/src/Domain/Handler/DuplicateItemSyncedEventHandler.ts @@ -6,34 +6,17 @@ import { import { Logger } from 'winston' import { DomainEventFactoryInterface } from '../Event/DomainEventFactoryInterface' import { ItemRepositoryInterface } from '../Item/ItemRepositoryInterface' -import { ItemRepositoryResolverInterface } from '../Item/ItemRepositoryResolverInterface' -import { RoleNameCollection } from '@standardnotes/domain-core' export class DuplicateItemSyncedEventHandler implements DomainEventHandlerInterface { constructor( - private itemRepositoryResolver: ItemRepositoryResolverInterface, + private itemRepository: ItemRepositoryInterface, private domainEventFactory: DomainEventFactoryInterface, private domainEventPublisher: DomainEventPublisherInterface, private logger: Logger, ) {} async handle(event: DuplicateItemSyncedEvent): Promise { - const roleNamesOrError = RoleNameCollection.create(event.payload.roleNames) - if (roleNamesOrError.isFailed()) { - return - } - const roleNames = roleNamesOrError.getValue() - - const itemRepository = this.itemRepositoryResolver.resolve(roleNames) - - await this.requestRevisionsCopy(event, itemRepository) - } - - private async requestRevisionsCopy( - event: DuplicateItemSyncedEvent, - itemRepository: ItemRepositoryInterface, - ): Promise { - const item = await itemRepository.findByUuidAndUserUuid(event.payload.itemUuid, event.payload.userUuid) + const item = await this.itemRepository.findByUuidAndUserUuid(event.payload.itemUuid, event.payload.userUuid) if (item === null) { this.logger.debug(`Could not find item with uuid ${event.payload.itemUuid}`) @@ -47,7 +30,7 @@ export class DuplicateItemSyncedEventHandler implements DomainEventHandlerInterf return } - const existingOriginalItem = await itemRepository.findByUuidAndUserUuid( + const existingOriginalItem = await this.itemRepository.findByUuidAndUserUuid( item.props.duplicateOf.value, event.payload.userUuid, ) @@ -57,7 +40,6 @@ export class DuplicateItemSyncedEventHandler implements DomainEventHandlerInterf this.domainEventFactory.createRevisionsCopyRequestedEvent(event.payload.userUuid, { originalItemUuid: existingOriginalItem.id.toString(), newItemUuid: item.id.toString(), - roleNames: event.payload.roleNames, }), ) } diff --git a/packages/syncing-server/src/Domain/Handler/EmailBackupRequestedEventHandler.ts b/packages/syncing-server/src/Domain/Handler/EmailBackupRequestedEventHandler.ts index e586ca4b1..098d9beb5 100644 --- a/packages/syncing-server/src/Domain/Handler/EmailBackupRequestedEventHandler.ts +++ b/packages/syncing-server/src/Domain/Handler/EmailBackupRequestedEventHandler.ts @@ -15,7 +15,6 @@ import { getBody, getSubject } from '../Email/EmailBackupAttachmentCreated' export class EmailBackupRequestedEventHandler implements DomainEventHandlerInterface { constructor( private primaryItemRepository: ItemRepositoryInterface, - private secondaryItemRepository: ItemRepositoryInterface | null, private itemBackupService: ItemBackupServiceInterface, private domainEventPublisher: DomainEventPublisherInterface, private domainEventFactory: DomainEventFactoryInterface, @@ -27,10 +26,6 @@ export class EmailBackupRequestedEventHandler implements DomainEventHandlerInter async handle(event: EmailBackupRequestedEvent): Promise { await this.requestEmailWithBackupFile(event, this.primaryItemRepository) - - if (this.secondaryItemRepository) { - await this.requestEmailWithBackupFile(event, this.secondaryItemRepository) - } } private async requestEmailWithBackupFile( diff --git a/packages/syncing-server/src/Domain/Handler/ItemRevisionCreationRequestedEventHandler.ts b/packages/syncing-server/src/Domain/Handler/ItemRevisionCreationRequestedEventHandler.ts index fcc58db4b..0333da5de 100644 --- a/packages/syncing-server/src/Domain/Handler/ItemRevisionCreationRequestedEventHandler.ts +++ b/packages/syncing-server/src/Domain/Handler/ItemRevisionCreationRequestedEventHandler.ts @@ -12,7 +12,6 @@ export class ItemRevisionCreationRequestedEventHandler implements DomainEventHan async handle(event: ItemRevisionCreationRequestedEvent): Promise { const result = await this.dumpItem.execute({ itemUuid: event.payload.itemUuid, - roleNames: event.payload.roleNames, }) if (result.isFailed()) { diff --git a/packages/syncing-server/src/Domain/Handler/TransitionRequestedEventHandler.ts b/packages/syncing-server/src/Domain/Handler/TransitionRequestedEventHandler.ts deleted file mode 100644 index f631a880b..000000000 --- a/packages/syncing-server/src/Domain/Handler/TransitionRequestedEventHandler.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { DomainEventHandlerInterface, TransitionRequestedEvent } from '@standardnotes/domain-events' -import { Logger } from 'winston' - -import { TransitionItemsFromPrimaryToSecondaryDatabaseForUser } from '../UseCase/Transition/TransitionItemsFromPrimaryToSecondaryDatabaseForUser/TransitionItemsFromPrimaryToSecondaryDatabaseForUser' - -export class TransitionRequestedEventHandler implements DomainEventHandlerInterface { - constructor( - private disabled: boolean, - private transitionItemsFromPrimaryToSecondaryDatabaseForUser: TransitionItemsFromPrimaryToSecondaryDatabaseForUser, - private logger: Logger, - ) {} - - async handle(event: TransitionRequestedEvent): Promise { - if (this.disabled) { - return - } - - if (event.payload.type !== 'items') { - return - } - - const result = await this.transitionItemsFromPrimaryToSecondaryDatabaseForUser.execute({ - userUuid: event.payload.userUuid, - timestamp: event.payload.timestamp, - }) - - if (result.isFailed()) { - this.logger.error(`[${event.payload.userUuid}] Failed to trigger transition: ${result.getError()}`) - } - } -} diff --git a/packages/syncing-server/src/Domain/Item/ItemRepositoryResolverInterface.ts b/packages/syncing-server/src/Domain/Item/ItemRepositoryResolverInterface.ts deleted file mode 100644 index 9b4e62f56..000000000 --- a/packages/syncing-server/src/Domain/Item/ItemRepositoryResolverInterface.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { RoleNameCollection } from '@standardnotes/domain-core' - -import { ItemRepositoryInterface } from './ItemRepositoryInterface' - -export interface ItemRepositoryResolverInterface { - resolve(roleNames: RoleNameCollection): ItemRepositoryInterface -} diff --git a/packages/syncing-server/src/Domain/Transition/TransitionRepositoryInterface.ts b/packages/syncing-server/src/Domain/Transition/TransitionRepositoryInterface.ts deleted file mode 100644 index dac285d7e..000000000 --- a/packages/syncing-server/src/Domain/Transition/TransitionRepositoryInterface.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface TransitionRepositoryInterface { - getPagingProgress(userUuid: string): Promise - setPagingProgress(userUuid: string, progress: number): Promise - getIntegrityProgress(userUuid: string): Promise - setIntegrityProgress(userUuid: string, progress: number): Promise -} diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/CheckIntegrity/CheckIntegrity.spec.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/CheckIntegrity/CheckIntegrity.spec.ts index 1e1ee6c8f..1dba4c292 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/CheckIntegrity/CheckIntegrity.spec.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/CheckIntegrity/CheckIntegrity.spec.ts @@ -1,17 +1,15 @@ import 'reflect-metadata' -import { ContentType, RoleName } from '@standardnotes/domain-core' +import { ContentType } from '@standardnotes/domain-core' import { ItemRepositoryInterface } from '../../../Item/ItemRepositoryInterface' import { CheckIntegrity } from './CheckIntegrity' -import { ItemRepositoryResolverInterface } from '../../../Item/ItemRepositoryResolverInterface' describe('CheckIntegrity', () => { let itemRepository: ItemRepositoryInterface - let itemRepositoryResolver: ItemRepositoryResolverInterface - const createUseCase = () => new CheckIntegrity(itemRepositoryResolver) + const createUseCase = () => new CheckIntegrity(itemRepository) beforeEach(() => { itemRepository = {} as jest.Mocked @@ -42,9 +40,6 @@ describe('CheckIntegrity', () => { content_type: ContentType.TYPES.File, }, ]) - - itemRepositoryResolver = {} as jest.Mocked - itemRepositoryResolver.resolve = jest.fn().mockReturnValue(itemRepository) }) it('should return an empty result if there are no integrity mismatches', async () => { @@ -68,7 +63,6 @@ describe('CheckIntegrity', () => { updated_at_timestamp: 5, }, ], - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.getValue()).toEqual([]) }) @@ -94,7 +88,6 @@ describe('CheckIntegrity', () => { updated_at_timestamp: 5, }, ], - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.getValue()).toEqual([ { @@ -121,7 +114,6 @@ describe('CheckIntegrity', () => { updated_at_timestamp: 5, }, ], - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.getValue()).toEqual([ { @@ -130,27 +122,4 @@ describe('CheckIntegrity', () => { }, ]) }) - - it('should return error if the role names are invalid', async () => { - const result = await createUseCase().execute({ - userUuid: '1-2-3', - integrityPayloads: [ - { - uuid: '1-2-3', - updated_at_timestamp: 1, - }, - { - uuid: '2-3-4-A', - updated_at_timestamp: 2, - }, - { - uuid: '5-6-7', - updated_at_timestamp: 5, - }, - ], - roleNames: ['invalid-role-name'], - }) - expect(result.isFailed()).toBeTruthy() - expect(result.getError()).toEqual('Invalid role name: invalid-role-name') - }) }) diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/CheckIntegrity/CheckIntegrity.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/CheckIntegrity/CheckIntegrity.ts index e3e38a5a8..2e8ee0981 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/CheckIntegrity/CheckIntegrity.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/CheckIntegrity/CheckIntegrity.ts @@ -1,22 +1,15 @@ import { IntegrityPayload } from '@standardnotes/responses' -import { ContentType, Result, RoleNameCollection, UseCaseInterface } from '@standardnotes/domain-core' +import { ContentType, Result, UseCaseInterface } from '@standardnotes/domain-core' import { CheckIntegrityDTO } from './CheckIntegrityDTO' import { ExtendedIntegrityPayload } from '../../../Item/ExtendedIntegrityPayload' -import { ItemRepositoryResolverInterface } from '../../../Item/ItemRepositoryResolverInterface' +import { ItemRepositoryInterface } from '../../../Item/ItemRepositoryInterface' export class CheckIntegrity implements UseCaseInterface { - constructor(private itemRepositoryResolver: ItemRepositoryResolverInterface) {} + constructor(private itemRepository: ItemRepositoryInterface) {} async execute(dto: CheckIntegrityDTO): Promise> { - const roleNamesOrError = RoleNameCollection.create(dto.roleNames) - if (roleNamesOrError.isFailed()) { - return Result.fail(roleNamesOrError.getError()) - } - const roleNames = roleNamesOrError.getValue() - - const itemRepository = this.itemRepositoryResolver.resolve(roleNames) - const serverItemIntegrityPayloads = await itemRepository.findItemsForComputingIntegrityPayloads(dto.userUuid) + const serverItemIntegrityPayloads = await this.itemRepository.findItemsForComputingIntegrityPayloads(dto.userUuid) const serverItemIntegrityPayloadsMap = new Map() for (const serverItemIntegrityPayload of serverItemIntegrityPayloads) { diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/CheckIntegrity/CheckIntegrityDTO.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/CheckIntegrity/CheckIntegrityDTO.ts index 648dcdfbf..c9a645068 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/CheckIntegrity/CheckIntegrityDTO.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/CheckIntegrity/CheckIntegrityDTO.ts @@ -2,6 +2,5 @@ import { IntegrityPayload } from '@standardnotes/responses' export type CheckIntegrityDTO = { userUuid: string - roleNames: string[] integrityPayloads: IntegrityPayload[] } diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/DumpItem/DumpItem.spec.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/DumpItem/DumpItem.spec.ts index 7d5c8154a..d9c13a52b 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/DumpItem/DumpItem.spec.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/DumpItem/DumpItem.spec.ts @@ -2,22 +2,19 @@ import { DomainEventInterface, DomainEventPublisherInterface } from '@standardno import { DomainEventFactoryInterface } from '../../../Event/DomainEventFactoryInterface' import { ItemBackupServiceInterface } from '../../../Item/ItemBackupServiceInterface' -import { ItemRepositoryResolverInterface } from '../../../Item/ItemRepositoryResolverInterface' import { DumpItem } from './DumpItem' import { ItemRepositoryInterface } from '../../../Item/ItemRepositoryInterface' import { Item } from '../../../Item/Item' import { Uuid, ContentType, Dates, Timestamps, UniqueEntityId, Result } from '@standardnotes/domain-core' describe('DumpItem', () => { - let itemRepositoryResolver: ItemRepositoryResolverInterface let itemRepository: ItemRepositoryInterface let item: Item let itemBackupService: ItemBackupServiceInterface let domainEventFactory: DomainEventFactoryInterface let domainEventPublisher: DomainEventPublisherInterface - const createUseCase = () => - new DumpItem(itemRepositoryResolver, itemBackupService, domainEventFactory, domainEventPublisher) + const createUseCase = () => new DumpItem(itemRepository, itemBackupService, domainEventFactory, domainEventPublisher) beforeEach(() => { item = Item.create( @@ -40,9 +37,6 @@ describe('DumpItem', () => { itemRepository = {} as jest.Mocked itemRepository.findByUuid = jest.fn().mockResolvedValue(item) - itemRepositoryResolver = {} as jest.Mocked - itemRepositoryResolver.resolve = jest.fn().mockReturnValue(itemRepository) - itemBackupService = {} as jest.Mocked itemBackupService.dump = jest.fn().mockResolvedValue(Result.ok('dump-path')) @@ -58,7 +52,6 @@ describe('DumpItem', () => { const result = await useCase.execute({ itemUuid: '00000000-0000-0000-0000-000000000000', - roleNames: ['CORE_USER'], }) expect(result.isFailed()).toBe(false) @@ -74,7 +67,6 @@ describe('DumpItem', () => { const result = await useCase.execute({ itemUuid: '00000000-0000-0000-0000-000000000000', - roleNames: ['CORE_USER'], }) expect(result.isFailed()).toBe(true) @@ -87,7 +79,6 @@ describe('DumpItem', () => { const result = await useCase.execute({ itemUuid: '00000000-0000-0000-0000-000000000000', - roleNames: ['CORE_USER'], }) expect(result.isFailed()).toBe(true) @@ -98,18 +89,6 @@ describe('DumpItem', () => { const result = await useCase.execute({ itemUuid: 'invalid-uuid', - roleNames: ['CORE_USER'], - }) - - expect(result.isFailed()).toBe(true) - }) - - it('should fail if role names are invalid', async () => { - const useCase = createUseCase() - - const result = await useCase.execute({ - itemUuid: '00000000-0000-0000-0000-000000000000', - roleNames: ['invalid-role'], }) expect(result.isFailed()).toBe(true) diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/DumpItem/DumpItem.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/DumpItem/DumpItem.ts index e3f5c3f0b..d65deb16e 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/DumpItem/DumpItem.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/DumpItem/DumpItem.ts @@ -1,14 +1,13 @@ -import { Result, RoleNameCollection, UseCaseInterface, Uuid } from '@standardnotes/domain-core' +import { Result, UseCaseInterface, Uuid } from '@standardnotes/domain-core' import { DumpItemDTO } from './DumpItemDTO' import { DomainEventPublisherInterface } from '@standardnotes/domain-events' import { DomainEventFactoryInterface } from '../../../Event/DomainEventFactoryInterface' import { ItemBackupServiceInterface } from '../../../Item/ItemBackupServiceInterface' import { ItemRepositoryInterface } from '../../../Item/ItemRepositoryInterface' -import { ItemRepositoryResolverInterface } from '../../../Item/ItemRepositoryResolverInterface' export class DumpItem implements UseCaseInterface { constructor( - private itemRepositoryResolver: ItemRepositoryResolverInterface, + private itemRepository: ItemRepositoryInterface, private itemBackupService: ItemBackupServiceInterface, private domainEventFactory: DomainEventFactoryInterface, private domainEventPublisher: DomainEventPublisherInterface, @@ -21,13 +20,7 @@ export class DumpItem implements UseCaseInterface { } const itemUuid = itemUuidOrError.getValue() - const itemRepositoryOrError = this.getItemRepository(dto.roleNames) - if (itemRepositoryOrError.isFailed()) { - return Result.fail(`Failed to dump item: ${itemRepositoryOrError.getError()}`) - } - const itemRepository = itemRepositoryOrError.getValue() - - const item = await itemRepository.findByUuid(itemUuid) + const item = await this.itemRepository.findByUuid(itemUuid) if (item === null) { return Result.fail('Failed to dump item: Item not found') } @@ -42,22 +35,9 @@ export class DumpItem implements UseCaseInterface { this.domainEventFactory.createItemDumpedEvent({ fileDumpPath, userUuid: item.props.userUuid.value, - roleNames: dto.roleNames, }), ) return Result.ok() } - - private getItemRepository(stringRoleNames: string[]): Result { - const roleNamesOrError = RoleNameCollection.create(stringRoleNames) - if (roleNamesOrError.isFailed()) { - return Result.fail(`Could not obtain item repository based on role names: ${roleNamesOrError.getError()}`) - } - const roleNames = roleNamesOrError.getValue() - - const itemRepository = this.itemRepositoryResolver.resolve(roleNames) - - return Result.ok(itemRepository) - } } diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/DumpItem/DumpItemDTO.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/DumpItem/DumpItemDTO.ts index 94e7330f3..beec275bd 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/DumpItem/DumpItemDTO.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/DumpItem/DumpItemDTO.ts @@ -1,4 +1,3 @@ export interface DumpItemDTO { itemUuid: string - roleNames: string[] } diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/GetItem/GetItem.spec.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/GetItem/GetItem.spec.ts index ab0dadbf7..144cb2390 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/GetItem/GetItem.spec.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/GetItem/GetItem.spec.ts @@ -3,43 +3,26 @@ import { Item } from '../../../Item/Item' import { ItemRepositoryInterface } from '../../../Item/ItemRepositoryInterface' import { GetItem } from './GetItem' -import { ItemRepositoryResolverInterface } from '../../../Item/ItemRepositoryResolverInterface' -import { RoleName } from '@standardnotes/domain-core' describe('GetItem', () => { let itemRepository: ItemRepositoryInterface - let itemRepositoryResolver: ItemRepositoryResolverInterface - const createUseCase = () => new GetItem(itemRepositoryResolver) + const createUseCase = () => new GetItem(itemRepository) beforeEach(() => { itemRepository = {} as jest.Mocked itemRepository.findByUuidAndUserUuid = jest.fn().mockReturnValue(null) - - itemRepositoryResolver = {} as jest.Mocked - itemRepositoryResolver.resolve = jest.fn().mockReturnValue(itemRepository) }) it('should fail if item is not found', async () => { const result = await createUseCase().execute({ userUuid: '1-2-3', itemUuid: '2-3-4', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeTruthy() expect(result.getError()).toEqual('Could not find item with uuid 2-3-4') }) - it('should fail if the role names are invalid', async () => { - const result = await createUseCase().execute({ - userUuid: '1-2-3', - itemUuid: '2-3-4', - roleNames: ['invalid-role-name'], - }) - expect(result.isFailed()).toBeTruthy() - expect(result.getError()).toEqual('Invalid role name: invalid-role-name') - }) - it('should succeed if item is found', async () => { const item = {} as jest.Mocked itemRepository.findByUuidAndUserUuid = jest.fn().mockReturnValue(item) @@ -47,7 +30,6 @@ describe('GetItem', () => { const result = await createUseCase().execute({ userUuid: '1-2-3', itemUuid: '2-3-4', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.getValue()).toEqual(item) diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/GetItem/GetItem.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/GetItem/GetItem.ts index ca4f9e108..dacce573d 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/GetItem/GetItem.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/GetItem/GetItem.ts @@ -1,21 +1,14 @@ -import { Result, RoleNameCollection, UseCaseInterface } from '@standardnotes/domain-core' +import { Result, UseCaseInterface } from '@standardnotes/domain-core' import { GetItemDTO } from './GetItemDTO' import { Item } from '../../../Item/Item' -import { ItemRepositoryResolverInterface } from '../../../Item/ItemRepositoryResolverInterface' +import { ItemRepositoryInterface } from '../../../Item/ItemRepositoryInterface' export class GetItem implements UseCaseInterface { - constructor(private itemRepositoryResolver: ItemRepositoryResolverInterface) {} + constructor(private itemRepository: ItemRepositoryInterface) {} async execute(dto: GetItemDTO): Promise> { - const roleNamesOrError = RoleNameCollection.create(dto.roleNames) - if (roleNamesOrError.isFailed()) { - return Result.fail(roleNamesOrError.getError()) - } - const roleNames = roleNamesOrError.getValue() - - const itemRepository = this.itemRepositoryResolver.resolve(roleNames) - const item = await itemRepository.findByUuidAndUserUuid(dto.itemUuid, dto.userUuid) + const item = await this.itemRepository.findByUuidAndUserUuid(dto.itemUuid, dto.userUuid) if (item === null) { return Result.fail(`Could not find item with uuid ${dto.itemUuid}`) diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/GetItem/GetItemDTO.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/GetItem/GetItemDTO.ts index 43e86f1d5..13eb68106 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/GetItem/GetItemDTO.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/GetItem/GetItemDTO.ts @@ -1,5 +1,4 @@ export type GetItemDTO = { userUuid: string itemUuid: string - roleNames: string[] } diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/GetItems/GetItems.spec.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/GetItems/GetItems.spec.ts index 9676edff7..66c5cd069 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/GetItems/GetItems.spec.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/GetItems/GetItems.spec.ts @@ -3,14 +3,12 @@ import { ItemRepositoryInterface } from '../../../Item/ItemRepositoryInterface' import { ItemTransferCalculatorInterface } from '../../../Item/ItemTransferCalculatorInterface' import { GetItems } from './GetItems' import { Item } from '../../../Item/Item' -import { ContentType, Dates, RoleName, Timestamps, Uuid } from '@standardnotes/domain-core' +import { ContentType, Dates, Timestamps, Uuid } from '@standardnotes/domain-core' import { SharedVaultUserRepositoryInterface } from '../../../SharedVault/User/SharedVaultUserRepositoryInterface' -import { ItemRepositoryResolverInterface } from '../../../Item/ItemRepositoryResolverInterface' import { ItemContentSizeDescriptor } from '../../../Item/ItemContentSizeDescriptor' describe('GetItems', () => { let itemRepository: ItemRepositoryInterface - let itemRepositoryResolver: ItemRepositoryResolverInterface const contentSizeTransferLimit = 100 let itemTransferCalculator: ItemTransferCalculatorInterface let timer: TimerInterface @@ -20,7 +18,7 @@ describe('GetItems', () => { const createUseCase = () => new GetItems( - itemRepositoryResolver, + itemRepository, sharedVaultUserRepository, contentSizeTransferLimit, itemTransferCalculator, @@ -50,9 +48,6 @@ describe('GetItems', () => { .fn() .mockResolvedValue([ItemContentSizeDescriptor.create('00000000-0000-0000-0000-000000000000', 20).getValue()]) - itemRepositoryResolver = {} as jest.Mocked - itemRepositoryResolver.resolve = jest.fn().mockReturnValue(itemRepository) - itemTransferCalculator = {} as jest.Mocked itemTransferCalculator.computeItemUuidsToFetch = jest.fn().mockResolvedValue(['item-uuid']) @@ -69,7 +64,6 @@ describe('GetItems', () => { const result = await useCase.execute({ userUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], cursorToken: undefined, contentType: undefined, limit: 10, @@ -90,7 +84,6 @@ describe('GetItems', () => { const result = await useCase.execute({ userUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], cursorToken: undefined, contentType: undefined, limit: undefined, @@ -109,7 +102,6 @@ describe('GetItems', () => { const result = await useCase.execute({ userUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], cursorToken: 'MjowLjAwMDEyMw==', contentType: undefined, limit: undefined, @@ -131,7 +123,6 @@ describe('GetItems', () => { const result = await useCase.execute({ userUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], syncToken, contentType: undefined, limit: undefined, @@ -153,7 +144,6 @@ describe('GetItems', () => { const result = await useCase.execute({ userUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], syncToken, contentType: undefined, limit: undefined, @@ -168,7 +158,6 @@ describe('GetItems', () => { const result = await useCase.execute({ userUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], cursorToken: undefined, contentType: undefined, limit: 200, @@ -187,7 +176,6 @@ describe('GetItems', () => { const result = await useCase.execute({ userUuid: 'invalid', - roleNames: [RoleName.NAMES.CoreUser], cursorToken: undefined, contentType: undefined, limit: undefined, @@ -197,21 +185,6 @@ describe('GetItems', () => { expect(result.getError()).toEqual('Given value is not a valid uuid: invalid') }) - it('should return error for invalid role names', async () => { - const useCase = createUseCase() - - const result = await useCase.execute({ - userUuid: '00000000-0000-0000-0000-000000000000', - roleNames: ['invalid'], - cursorToken: undefined, - contentType: undefined, - limit: undefined, - }) - - expect(result.isFailed()).toBeTruthy() - expect(result.getError()).toEqual('Invalid role name: invalid') - }) - it('should filter shared vault uuids user wants to sync with the ones it has access to', async () => { sharedVaultUserRepository.findByUserUuid = jest.fn().mockResolvedValue([ { @@ -225,7 +198,6 @@ describe('GetItems', () => { const result = await useCase.execute({ userUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], cursorToken: undefined, contentType: undefined, limit: undefined, diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/GetItems/GetItems.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/GetItems/GetItems.ts index 3da86e6b8..0561dca04 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/GetItems/GetItems.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/GetItems/GetItems.ts @@ -1,4 +1,4 @@ -import { Result, RoleNameCollection, UseCaseInterface, Uuid } from '@standardnotes/domain-core' +import { Result, UseCaseInterface, Uuid } from '@standardnotes/domain-core' import { Time, TimerInterface } from '@standardnotes/time' import { Item } from '../../../Item/Item' @@ -7,14 +7,14 @@ import { ItemQuery } from '../../../Item/ItemQuery' import { ItemTransferCalculatorInterface } from '../../../Item/ItemTransferCalculatorInterface' import { GetItemsDTO } from './GetItemsDTO' import { SharedVaultUserRepositoryInterface } from '../../../SharedVault/User/SharedVaultUserRepositoryInterface' -import { ItemRepositoryResolverInterface } from '../../../Item/ItemRepositoryResolverInterface' +import { ItemRepositoryInterface } from '../../../Item/ItemRepositoryInterface' export class GetItems implements UseCaseInterface { private readonly DEFAULT_ITEMS_LIMIT = 150 private readonly SYNC_TOKEN_VERSION = 2 constructor( - private itemRepositoryResolver: ItemRepositoryResolverInterface, + private itemRepository: ItemRepositoryInterface, private sharedVaultUserRepository: SharedVaultUserRepositoryInterface, private contentSizeTransferLimit: number, private itemTransferCalculator: ItemTransferCalculatorInterface, @@ -35,12 +35,6 @@ export class GetItems implements UseCaseInterface { } const userUuid = userUuidOrError.getValue() - const roleNamesOrError = RoleNameCollection.create(dto.roleNames) - if (roleNamesOrError.isFailed()) { - return Result.fail(roleNamesOrError.getError()) - } - const roleNames = roleNamesOrError.getValue() - const syncTimeComparison = dto.cursorToken ? '>=' : '>' const limit = dto.limit === undefined || dto.limit < 1 ? this.DEFAULT_ITEMS_LIMIT : dto.limit const upperBoundLimit = limit < this.maxItemsSyncLimit ? limit : this.maxItemsSyncLimit @@ -65,22 +59,20 @@ export class GetItems implements UseCaseInterface { exclusiveSharedVaultUuids, } - const itemRepository = this.itemRepositoryResolver.resolve(roleNames) - - const itemContentSizeDescriptors = await itemRepository.findContentSizeForComputingTransferLimit(itemQuery) + const itemContentSizeDescriptors = await this.itemRepository.findContentSizeForComputingTransferLimit(itemQuery) const itemUuidsToFetch = await this.itemTransferCalculator.computeItemUuidsToFetch( itemContentSizeDescriptors, this.contentSizeTransferLimit, ) let items: Array = [] if (itemUuidsToFetch.length > 0) { - items = await itemRepository.findAll({ + items = await this.itemRepository.findAll({ uuids: itemUuidsToFetch, sortBy: 'updated_at_timestamp', sortOrder: 'ASC', }) } - const totalItemsCount = await itemRepository.countAll(itemQuery) + const totalItemsCount = await this.itemRepository.countAll(itemQuery) let cursorToken = undefined if (totalItemsCount > upperBoundLimit) { diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/GetItems/GetItemsDTO.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/GetItems/GetItemsDTO.ts index 760185dee..fb1044dd1 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/GetItems/GetItemsDTO.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/GetItems/GetItemsDTO.ts @@ -1,6 +1,5 @@ export interface GetItemsDTO { userUuid: string - roleNames: string[] syncToken?: string | null cursorToken?: string | null limit?: number diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/SaveItems/SaveItems.spec.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/SaveItems/SaveItems.spec.ts index 4ad1497cf..6abd0d56d 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/SaveItems/SaveItems.spec.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/SaveItems/SaveItems.spec.ts @@ -5,15 +5,13 @@ import { SaveItems } from './SaveItems' import { SaveNewItem } from '../SaveNewItem/SaveNewItem' import { UpdateExistingItem } from '../UpdateExistingItem/UpdateExistingItem' import { Logger } from 'winston' -import { ContentType, Dates, Result, RoleName, Timestamps, Uuid } from '@standardnotes/domain-core' +import { ContentType, Dates, Result, Timestamps, Uuid } from '@standardnotes/domain-core' import { ItemHash } from '../../../Item/ItemHash' import { Item } from '../../../Item/Item' -import { ItemRepositoryResolverInterface } from '../../../Item/ItemRepositoryResolverInterface' describe('SaveItems', () => { let itemSaveValidator: ItemSaveValidatorInterface let itemRepository: ItemRepositoryInterface - let itemRepositoryResolver: ItemRepositoryResolverInterface let timer: TimerInterface let saveNewItem: SaveNewItem let updateExistingItem: UpdateExistingItem @@ -22,7 +20,7 @@ describe('SaveItems', () => { let savedItem: Item const createUseCase = () => - new SaveItems(itemSaveValidator, itemRepositoryResolver, timer, saveNewItem, updateExistingItem, logger) + new SaveItems(itemSaveValidator, itemRepository, timer, saveNewItem, updateExistingItem, logger) beforeEach(() => { itemSaveValidator = {} as jest.Mocked @@ -31,9 +29,6 @@ describe('SaveItems', () => { itemRepository = {} as jest.Mocked itemRepository.findByUuid = jest.fn().mockResolvedValue(null) - itemRepositoryResolver = {} as jest.Mocked - itemRepositoryResolver.resolve = jest.fn().mockReturnValue(itemRepository) - timer = {} as jest.Mocked timer.getTimestampInMicroseconds = jest.fn().mockReturnValue(123) @@ -84,12 +79,10 @@ describe('SaveItems', () => { const result = await useCase.execute({ itemHashes: [itemHash1], userUuid: 'user-uuid', - onGoingRevisionsTransition: false, apiVersion: '1', readOnlyAccess: false, sessionUuid: 'session-uuid', snjsVersion: '2.200.0', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeFalsy() @@ -97,9 +90,7 @@ describe('SaveItems', () => { expect(saveNewItem.execute).toHaveBeenCalledWith({ itemHash: itemHash1, userUuid: 'user-uuid', - onGoingRevisionsTransition: false, sessionUuid: 'session-uuid', - roleNames: ['CORE_USER'], }) }) @@ -111,12 +102,10 @@ describe('SaveItems', () => { const result = await useCase.execute({ itemHashes: [itemHash1], userUuid: 'user-uuid', - onGoingRevisionsTransition: false, apiVersion: '1', readOnlyAccess: false, sessionUuid: 'session-uuid', snjsVersion: '2.200.0', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeFalsy() @@ -136,12 +125,10 @@ describe('SaveItems', () => { const result = await useCase.execute({ itemHashes: [itemHash1], userUuid: 'user-uuid', - onGoingRevisionsTransition: false, apiVersion: '1', readOnlyAccess: false, sessionUuid: 'session-uuid', snjsVersion: '2.200.0', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeFalsy() @@ -159,12 +146,10 @@ describe('SaveItems', () => { const result = await useCase.execute({ itemHashes: [itemHash1], userUuid: 'user-uuid', - onGoingRevisionsTransition: false, apiVersion: '1', readOnlyAccess: true, sessionUuid: 'session-uuid', snjsVersion: '2.200.0', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeFalsy() @@ -183,12 +168,10 @@ describe('SaveItems', () => { const result = await useCase.execute({ itemHashes: [itemHash1], userUuid: 'user-uuid', - onGoingRevisionsTransition: false, apiVersion: '1', readOnlyAccess: false, sessionUuid: 'session-uuid', snjsVersion: '2.200.0', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeFalsy() @@ -203,12 +186,10 @@ describe('SaveItems', () => { const result = await useCase.execute({ itemHashes: [itemHash1], userUuid: 'user-uuid', - onGoingRevisionsTransition: false, apiVersion: '1', readOnlyAccess: false, sessionUuid: 'session-uuid', snjsVersion: '2.200.0', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeFalsy() @@ -222,13 +203,11 @@ describe('SaveItems', () => { const result = await useCase.execute({ itemHashes: [itemHash1], - onGoingRevisionsTransition: false, userUuid: '00000000-0000-0000-0000-000000000000', apiVersion: '1', readOnlyAccess: false, sessionUuid: 'session-uuid', snjsVersion: '2.200.0', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeFalsy() @@ -237,8 +216,6 @@ describe('SaveItems', () => { existingItem: savedItem, sessionUuid: 'session-uuid', performingUserUuid: '00000000-0000-0000-0000-000000000000', - onGoingRevisionsTransition: false, - roleNames: ['CORE_USER'], }) }) @@ -251,12 +228,10 @@ describe('SaveItems', () => { const result = await useCase.execute({ itemHashes: [itemHash1], userUuid: 'user-uuid', - onGoingRevisionsTransition: false, apiVersion: '1', readOnlyAccess: false, sessionUuid: 'session-uuid', snjsVersion: '2.200.0', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeFalsy() @@ -277,12 +252,10 @@ describe('SaveItems', () => { const result = await useCase.execute({ itemHashes: [ItemHash.create({ ...itemHash1.props, uuid: 'invalid-uuid' }).getValue()], userUuid: 'user-uuid', - onGoingRevisionsTransition: false, apiVersion: '1', readOnlyAccess: false, sessionUuid: 'session-uuid', snjsVersion: '2.200.0', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeFalsy() @@ -324,33 +297,13 @@ describe('SaveItems', () => { ItemHash.create({ ...itemHash1.props, uuid: '00000000-0000-0000-0000-000000000003' }).getValue(), ], userUuid: 'user-uuid', - onGoingRevisionsTransition: false, apiVersion: '2', readOnlyAccess: false, sessionUuid: 'session-uuid', snjsVersion: '2.200.0', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeFalsy() expect(result.getValue().syncToken).toEqual('MjowLjAwMDE2') }) - - it('should fail if the role names are invalid', async () => { - const useCase = createUseCase() - - const result = await useCase.execute({ - itemHashes: [itemHash1], - userUuid: 'user-uuid', - onGoingRevisionsTransition: false, - apiVersion: '2', - readOnlyAccess: false, - sessionUuid: 'session-uuid', - snjsVersion: '2.200.0', - roleNames: ['invalid-role-name'], - }) - - expect(result.isFailed()).toBeTruthy() - expect(result.getError()).toEqual('Invalid role name: invalid-role-name') - }) }) diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/SaveItems/SaveItems.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/SaveItems/SaveItems.ts index 7190f4bd9..6703baeb8 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/SaveItems/SaveItems.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/SaveItems/SaveItems.ts @@ -1,4 +1,4 @@ -import { Result, RoleNameCollection, UseCaseInterface, Uuid } from '@standardnotes/domain-core' +import { Result, UseCaseInterface, Uuid } from '@standardnotes/domain-core' import { SaveItemsResult } from './SaveItemsResult' import { SaveItemsDTO } from './SaveItemsDTO' @@ -10,14 +10,14 @@ import { Logger } from 'winston' import { ItemSaveValidatorInterface } from '../../../Item/SaveValidator/ItemSaveValidatorInterface' import { SaveNewItem } from '../SaveNewItem/SaveNewItem' import { UpdateExistingItem } from '../UpdateExistingItem/UpdateExistingItem' -import { ItemRepositoryResolverInterface } from '../../../Item/ItemRepositoryResolverInterface' +import { ItemRepositoryInterface } from '../../../Item/ItemRepositoryInterface' export class SaveItems implements UseCaseInterface { private readonly SYNC_TOKEN_VERSION = 2 constructor( private itemSaveValidator: ItemSaveValidatorInterface, - private itemRepositoryResolver: ItemRepositoryResolverInterface, + private itemRepository: ItemRepositoryInterface, private timer: TimerInterface, private saveNewItem: SaveNewItem, private updateExistingItem: UpdateExistingItem, @@ -28,12 +28,6 @@ export class SaveItems implements UseCaseInterface { const savedItems: Array = [] const conflicts: Array = [] - const roleNamesOrError = RoleNameCollection.create(dto.roleNames) - if (roleNamesOrError.isFailed()) { - return Result.fail(roleNamesOrError.getError()) - } - const roleNames = roleNamesOrError.getValue() - const lastUpdatedTimestamp = this.timer.getTimestampInMicroseconds() for (const itemHash of dto.itemHashes) { @@ -48,8 +42,7 @@ export class SaveItems implements UseCaseInterface { } const itemUuid = itemUuidOrError.getValue() - const itemRepository = this.itemRepositoryResolver.resolve(roleNames) - const existingItem = await itemRepository.findByUuid(itemUuid) + const existingItem = await this.itemRepository.findByUuid(itemUuid) if (dto.readOnlyAccess) { conflicts.push({ @@ -85,8 +78,6 @@ export class SaveItems implements UseCaseInterface { itemHash, sessionUuid: dto.sessionUuid, performingUserUuid: dto.userUuid, - roleNames: dto.roleNames, - onGoingRevisionsTransition: dto.onGoingRevisionsTransition, }) if (udpatedItemOrError.isFailed()) { this.logger.error( @@ -109,8 +100,6 @@ export class SaveItems implements UseCaseInterface { userUuid: dto.userUuid, itemHash, sessionUuid: dto.sessionUuid, - roleNames: dto.roleNames, - onGoingRevisionsTransition: dto.onGoingRevisionsTransition, }) if (newItemOrError.isFailed()) { this.logger.error( diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/SaveItems/SaveItemsDTO.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/SaveItems/SaveItemsDTO.ts index 22d60a1e4..3e6938bb9 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/SaveItems/SaveItemsDTO.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/SaveItems/SaveItemsDTO.ts @@ -7,6 +7,4 @@ export interface SaveItemsDTO { readOnlyAccess: boolean sessionUuid: string | null snjsVersion: string - roleNames: string[] - onGoingRevisionsTransition: boolean } diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/SaveNewItem/SaveNewItem.spec.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/SaveNewItem/SaveNewItem.spec.ts index 6d1bb4ac2..269c401d0 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/SaveNewItem/SaveNewItem.spec.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/SaveNewItem/SaveNewItem.spec.ts @@ -4,22 +4,20 @@ import { SaveNewItem } from './SaveNewItem' import { DomainEventInterface, DomainEventPublisherInterface } from '@standardnotes/domain-events' import { DomainEventFactoryInterface } from '../../../Event/DomainEventFactoryInterface' import { ItemHash } from '../../../Item/ItemHash' -import { ContentType, Dates, Result, RoleName, Timestamps, UniqueEntityId, Uuid } from '@standardnotes/domain-core' +import { ContentType, Dates, Result, Timestamps, UniqueEntityId, Uuid } from '@standardnotes/domain-core' import { Item } from '../../../Item/Item' import { SharedVaultAssociation } from '../../../SharedVault/SharedVaultAssociation' import { KeySystemAssociation } from '../../../KeySystem/KeySystemAssociation' -import { ItemRepositoryResolverInterface } from '../../../Item/ItemRepositoryResolverInterface' describe('SaveNewItem', () => { let itemRepository: ItemRepositoryInterface - let itemRepositoryResolver: ItemRepositoryResolverInterface let timer: TimerInterface let domainEventPublisher: DomainEventPublisherInterface let domainEventFactory: DomainEventFactoryInterface let itemHash1: ItemHash let item1: Item - const createUseCase = () => new SaveNewItem(itemRepositoryResolver, timer, domainEventPublisher, domainEventFactory) + const createUseCase = () => new SaveNewItem(itemRepository, timer, domainEventPublisher, domainEventFactory) beforeEach(() => { const timeHelper = new Timer() @@ -64,9 +62,6 @@ describe('SaveNewItem', () => { itemRepository = {} as jest.Mocked itemRepository.insert = jest.fn() - itemRepositoryResolver = {} as jest.Mocked - itemRepositoryResolver.resolve = jest.fn().mockReturnValue(itemRepository) - timer = {} as jest.Mocked timer.getTimestampInMicroseconds = jest.fn().mockReturnValue(123456789) timer.convertMicrosecondsToDate = jest.fn().mockReturnValue(new Date(123456789)) @@ -90,8 +85,6 @@ describe('SaveNewItem', () => { const result = await useCase.execute({ userUuid: '00000000-0000-0000-0000-000000000000', - onGoingRevisionsTransition: false, - roleNames: [RoleName.NAMES.CoreUser], sessionUuid: '00000000-0000-0000-0000-000000000001', itemHash: itemHash1, }) @@ -113,8 +106,6 @@ describe('SaveNewItem', () => { const result = await useCase.execute({ userUuid: '00000000-0000-0000-0000-000000000000', - onGoingRevisionsTransition: true, - roleNames: [RoleName.NAMES.CoreUser], sessionUuid: '00000000-0000-0000-0000-000000000001', itemHash: itemHash1, }) @@ -134,8 +125,6 @@ describe('SaveNewItem', () => { const result = await useCase.execute({ userUuid: '00000000-0000-0000-0000-000000000000', - onGoingRevisionsTransition: false, - roleNames: [RoleName.NAMES.CoreUser], sessionUuid: '00000000-0000-0000-0000-000000000001', itemHash: itemHash1, }) @@ -153,8 +142,6 @@ describe('SaveNewItem', () => { const result = await useCase.execute({ userUuid: '00000000-0000-0000-0000-000000000000', - onGoingRevisionsTransition: false, - roleNames: [RoleName.NAMES.CoreUser], sessionUuid: '00000000-0000-0000-0000-000000000001', itemHash: itemHash1, }) @@ -174,8 +161,6 @@ describe('SaveNewItem', () => { const result = await useCase.execute({ userUuid: '00000000-0000-0000-0000-000000000000', - onGoingRevisionsTransition: false, - roleNames: [RoleName.NAMES.CoreUser], sessionUuid: '00000000-0000-0000-0000-000000000001', itemHash: itemHash1, }) @@ -195,8 +180,6 @@ describe('SaveNewItem', () => { const result = await useCase.execute({ userUuid: '00000000-0000-0000-0000-000000000000', - onGoingRevisionsTransition: false, - roleNames: [RoleName.NAMES.CoreUser], sessionUuid: '00000000-0000-0000-0000-000000000001', itemHash: itemHash1, }) @@ -213,22 +196,6 @@ describe('SaveNewItem', () => { userUuid: '00000000-0000-0000-0000-00000000000', sessionUuid: '00000000-0000-0000-0000-000000000001', itemHash: itemHash1, - roleNames: [RoleName.NAMES.CoreUser], - onGoingRevisionsTransition: false, - }) - - expect(result.isFailed()).toBeTruthy() - }) - - it('returns a failure if the role names are invalid', async () => { - const useCase = createUseCase() - - const result = await useCase.execute({ - userUuid: '00000000-0000-0000-0000-000000000000', - onGoingRevisionsTransition: false, - sessionUuid: '00000000-0000-0000-0000-000000000001', - itemHash: itemHash1, - roleNames: ['invalid'], }) expect(result.isFailed()).toBeTruthy() @@ -239,8 +206,6 @@ describe('SaveNewItem', () => { const result = await useCase.execute({ userUuid: '00000000-0000-0000-0000-000000000000', - onGoingRevisionsTransition: false, - roleNames: [RoleName.NAMES.CoreUser], sessionUuid: '00000000-0000-0000-0000-00000000000', itemHash: itemHash1, }) @@ -258,8 +223,6 @@ describe('SaveNewItem', () => { const result = await useCase.execute({ userUuid: '00000000-0000-0000-0000-000000000000', - onGoingRevisionsTransition: false, - roleNames: [RoleName.NAMES.CoreUser], sessionUuid: '00000000-0000-0000-0000-000000000001', itemHash: itemHash1, }) @@ -277,8 +240,6 @@ describe('SaveNewItem', () => { const result = await useCase.execute({ userUuid: '00000000-0000-0000-0000-000000000000', - onGoingRevisionsTransition: false, - roleNames: [RoleName.NAMES.CoreUser], sessionUuid: '00000000-0000-0000-0000-000000000001', itemHash: itemHash1, }) @@ -296,8 +257,6 @@ describe('SaveNewItem', () => { const result = await useCase.execute({ userUuid: '00000000-0000-0000-0000-000000000000', - onGoingRevisionsTransition: false, - roleNames: [RoleName.NAMES.CoreUser], sessionUuid: '00000000-0000-0000-0000-000000000001', itemHash: itemHash1, }) @@ -317,8 +276,6 @@ describe('SaveNewItem', () => { const result = await useCase.execute({ userUuid: '00000000-0000-0000-0000-000000000000', - onGoingRevisionsTransition: false, - roleNames: [RoleName.NAMES.CoreUser], sessionUuid: '00000000-0000-0000-0000-000000000001', itemHash: itemHash1, }) @@ -340,8 +297,6 @@ describe('SaveNewItem', () => { userUuid: '00000000-0000-0000-0000-00000000000', sessionUuid: '00000000-0000-0000-0000-000000000001', itemHash: itemHash1, - roleNames: [RoleName.NAMES.CoreUser], - onGoingRevisionsTransition: false, }) expect(result.isFailed()).toBeTruthy() @@ -358,8 +313,6 @@ describe('SaveNewItem', () => { const result = await useCase.execute({ userUuid: '00000000-0000-0000-0000-000000000000', - onGoingRevisionsTransition: false, - roleNames: [RoleName.NAMES.CoreUser], sessionUuid: '00000000-0000-0000-0000-000000000001', itemHash: itemHash1, }) @@ -386,8 +339,6 @@ describe('SaveNewItem', () => { const result = await useCase.execute({ userUuid: '00000000-0000-0000-0000-000000000000', - onGoingRevisionsTransition: false, - roleNames: [RoleName.NAMES.CoreUser], sessionUuid: '00000000-0000-0000-0000-000000000001', itemHash: itemHash1, }) @@ -409,8 +360,6 @@ describe('SaveNewItem', () => { const result = await useCase.execute({ userUuid: '00000000-0000-0000-0000-000000000000', - onGoingRevisionsTransition: false, - roleNames: [RoleName.NAMES.CoreUser], sessionUuid: '00000000-0000-0000-0000-000000000001', itemHash: itemHash1, }) @@ -429,8 +378,6 @@ describe('SaveNewItem', () => { const result = await useCase.execute({ userUuid: '00000000-0000-0000-0000-000000000000', - onGoingRevisionsTransition: false, - roleNames: [RoleName.NAMES.CoreUser], sessionUuid: '00000000-0000-0000-0000-000000000001', itemHash: itemHash1, }) @@ -453,8 +400,6 @@ describe('SaveNewItem', () => { const result = await useCase.execute({ userUuid: '00000000-0000-0000-0000-000000000000', - onGoingRevisionsTransition: false, - roleNames: [RoleName.NAMES.CoreUser], sessionUuid: '00000000-0000-0000-0000-000000000001', itemHash: itemHash1, }) diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/SaveNewItem/SaveNewItem.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/SaveNewItem/SaveNewItem.ts index 9ee19243a..1b8eb4cbf 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/SaveNewItem/SaveNewItem.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/SaveNewItem/SaveNewItem.ts @@ -2,7 +2,6 @@ import { ContentType, Dates, Result, - RoleNameCollection, Timestamps, UniqueEntityId, UseCaseInterface, @@ -17,11 +16,11 @@ import { SaveNewItemDTO } from './SaveNewItemDTO' import { DomainEventFactoryInterface } from '../../../Event/DomainEventFactoryInterface' import { SharedVaultAssociation } from '../../../SharedVault/SharedVaultAssociation' import { KeySystemAssociation } from '../../../KeySystem/KeySystemAssociation' -import { ItemRepositoryResolverInterface } from '../../../Item/ItemRepositoryResolverInterface' +import { ItemRepositoryInterface } from '../../../Item/ItemRepositoryInterface' export class SaveNewItem implements UseCaseInterface { constructor( - private itemRepositoryResolver: ItemRepositoryResolverInterface, + private itemRepository: ItemRepositoryInterface, private timer: TimerInterface, private domainEventPublisher: DomainEventPublisherInterface, private domainEventFactory: DomainEventFactoryInterface, @@ -48,12 +47,6 @@ export class SaveNewItem implements UseCaseInterface { } const userUuid = userUuidOrError.getValue() - const roleNamesOrError = RoleNameCollection.create(dto.roleNames) - if (roleNamesOrError.isFailed()) { - return Result.fail(roleNamesOrError.getError()) - } - const roleNames = roleNamesOrError.getValue() - const contentTypeOrError = ContentType.create(dto.itemHash.props.content_type) if (contentTypeOrError.isFailed()) { return Result.fail(contentTypeOrError.getError()) @@ -140,20 +133,15 @@ export class SaveNewItem implements UseCaseInterface { newItem.props.keySystemAssociation = keySystemAssociationOrError.getValue() } - const itemRepository = this.itemRepositoryResolver.resolve(roleNames) - - await itemRepository.insert(newItem) + await this.itemRepository.insert(newItem) if (contentType.value !== null && [ContentType.TYPES.Note, ContentType.TYPES.File].includes(contentType.value)) { - if (!dto.onGoingRevisionsTransition) { - await this.domainEventPublisher.publish( - this.domainEventFactory.createItemRevisionCreationRequested({ - itemUuid: newItem.id.toString(), - userUuid: newItem.props.userUuid.value, - roleNames: dto.roleNames, - }), - ) - } + await this.domainEventPublisher.publish( + this.domainEventFactory.createItemRevisionCreationRequested({ + itemUuid: newItem.id.toString(), + userUuid: newItem.props.userUuid.value, + }), + ) } if (duplicateOf) { @@ -161,7 +149,6 @@ export class SaveNewItem implements UseCaseInterface { this.domainEventFactory.createDuplicateItemSyncedEvent({ itemUuid: newItem.id.toString(), userUuid: newItem.props.userUuid.value, - roleNames: dto.roleNames, }), ) } diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/SaveNewItem/SaveNewItemDTO.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/SaveNewItem/SaveNewItemDTO.ts index a1ad1e9bf..3696d94fc 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/SaveNewItem/SaveNewItemDTO.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/SaveNewItem/SaveNewItemDTO.ts @@ -2,8 +2,6 @@ import { ItemHash } from '../../../Item/ItemHash' export interface SaveNewItemDTO { userUuid: string - roleNames: string[] itemHash: ItemHash sessionUuid: string | null - onGoingRevisionsTransition: boolean } diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/SyncItems/SyncItems.spec.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/SyncItems/SyncItems.spec.ts index 66a70df7c..d616686bc 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/SyncItems/SyncItems.spec.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/SyncItems/SyncItems.spec.ts @@ -5,7 +5,7 @@ import { Item } from '../../../Item/Item' import { ItemHash } from '../../../Item/ItemHash' import { SyncItems } from './SyncItems' -import { ContentType, Dates, Result, RoleName, Timestamps, UniqueEntityId, Uuid } from '@standardnotes/domain-core' +import { ContentType, Dates, Result, Timestamps, UniqueEntityId, Uuid } from '@standardnotes/domain-core' import { GetItems } from '../GetItems/GetItems' import { SaveItems } from '../SaveItems/SaveItems' import { ItemRepositoryInterface } from '../../../Item/ItemRepositoryInterface' @@ -13,14 +13,12 @@ import { GetSharedVaults } from '../../SharedVaults/GetSharedVaults/GetSharedVau import { GetMessagesSentToUser } from '../../Messaging/GetMessagesSentToUser/GetMessagesSentToUser' import { GetUserNotifications } from '../../Messaging/GetUserNotifications/GetUserNotifications' import { GetSharedVaultInvitesSentToUser } from '../../SharedVaults/GetSharedVaultInvitesSentToUser/GetSharedVaultInvitesSentToUser' -import { ItemRepositoryResolverInterface } from '../../../Item/ItemRepositoryResolverInterface' import { Logger } from 'winston' describe('SyncItems', () => { let getItemsUseCase: GetItems let saveItemsUseCase: SaveItems let itemRepository: ItemRepositoryInterface - let itemRepositoryResolver: ItemRepositoryResolverInterface let item1: Item let item2: Item let item3: Item @@ -33,7 +31,7 @@ describe('SyncItems', () => { const createUseCase = () => new SyncItems( - itemRepositoryResolver, + itemRepository, getItemsUseCase, saveItemsUseCase, getSharedVaultsUseCase, @@ -132,9 +130,6 @@ describe('SyncItems', () => { itemRepository = {} as jest.Mocked itemRepository.findAll = jest.fn().mockReturnValue([item3, item1]) - itemRepositoryResolver = {} as jest.Mocked - itemRepositoryResolver.resolve = jest.fn().mockReturnValue(itemRepository) - getSharedVaultsUseCase = {} as jest.Mocked getSharedVaultsUseCase.execute = jest.fn().mockReturnValue(Result.ok({ sharedVaults: [], designatedSurivors: [] })) @@ -151,7 +146,6 @@ describe('SyncItems', () => { it('should sync items', async () => { const result = await createUseCase().execute({ userUuid: '1-2-3', - onGoingRevisionsTransition: false, itemHashes: [itemHash], computeIntegrityHash: false, syncToken: 'foo', @@ -162,7 +156,6 @@ describe('SyncItems', () => { apiVersion: ApiVersion.v20200115, sessionUuid: null, snjsVersion: '1.2.3', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.getValue()).toEqual({ conflicts: [], @@ -182,15 +175,12 @@ describe('SyncItems', () => { limit: 10, syncToken: 'foo', userUuid: '1-2-3', - roleNames: ['CORE_USER'], }) expect(saveItemsUseCase.execute).toHaveBeenCalledWith({ itemHashes: [itemHash], userUuid: '1-2-3', - onGoingRevisionsTransition: false, apiVersion: '20200115', snjsVersion: '1.2.3', - roleNames: [RoleName.NAMES.CoreUser], readOnlyAccess: false, sessionUuid: null, }) @@ -205,7 +195,6 @@ describe('SyncItems', () => { try { await createUseCase().execute({ userUuid: '1-2-3', - onGoingRevisionsTransition: false, itemHashes: [itemHash], computeIntegrityHash: false, syncToken: 'foo', @@ -216,7 +205,6 @@ describe('SyncItems', () => { apiVersion: ApiVersion.v20200115, sessionUuid: null, snjsVersion: '1.2.3', - roleNames: [RoleName.NAMES.CoreUser], }) } catch (error) { caughtError = error @@ -228,7 +216,6 @@ describe('SyncItems', () => { it('should sync items and return items keys on top for first sync that is not a shared vault exclusive sync', async () => { const result = await createUseCase().execute({ userUuid: '1-2-3', - onGoingRevisionsTransition: false, itemHashes: [itemHash], computeIntegrityHash: false, limit: 10, @@ -237,7 +224,6 @@ describe('SyncItems', () => { contentType: 'Note', apiVersion: ApiVersion.v20200115, snjsVersion: '1.2.3', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.getValue()).toEqual({ conflicts: [], @@ -255,7 +241,6 @@ describe('SyncItems', () => { it('should sync items and not return items keys on top for first sync that is a shared vault exclusive sync', async () => { const result = await createUseCase().execute({ userUuid: '1-2-3', - onGoingRevisionsTransition: false, itemHashes: [itemHash], computeIntegrityHash: false, limit: 10, @@ -264,7 +249,6 @@ describe('SyncItems', () => { contentType: 'Note', apiVersion: ApiVersion.v20200115, snjsVersion: '1.2.3', - roleNames: [RoleName.NAMES.CoreUser], sharedVaultUuids: ['00000000-0000-0000-0000-000000000000'], }) expect(result.getValue()).toEqual({ @@ -307,7 +291,6 @@ describe('SyncItems', () => { const result = await createUseCase().execute({ userUuid: '1-2-3', - onGoingRevisionsTransition: false, itemHashes: [itemHash], computeIntegrityHash: false, syncToken: 'foo', @@ -318,7 +301,6 @@ describe('SyncItems', () => { contentType: 'Note', apiVersion: ApiVersion.v20200115, snjsVersion: '1.2.3', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.getValue()).toEqual({ @@ -348,7 +330,6 @@ describe('SyncItems', () => { const result = await createUseCase().execute({ userUuid: '1-2-3', - onGoingRevisionsTransition: false, itemHashes: [itemHash], computeIntegrityHash: false, syncToken: 'foo', @@ -359,7 +340,6 @@ describe('SyncItems', () => { contentType: 'Note', apiVersion: ApiVersion.v20200115, snjsVersion: '1.2.3', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeTruthy() @@ -370,7 +350,6 @@ describe('SyncItems', () => { const result = await createUseCase().execute({ userUuid: '1-2-3', - onGoingRevisionsTransition: false, itemHashes: [itemHash], computeIntegrityHash: false, syncToken: 'foo', @@ -381,25 +360,6 @@ describe('SyncItems', () => { contentType: 'Note', apiVersion: ApiVersion.v20200115, snjsVersion: '1.2.3', - roleNames: [RoleName.NAMES.CoreUser], - }) - - expect(result.isFailed()).toBeTruthy() - }) - - it('should return error if role names are invalid', async () => { - const result = await createUseCase().execute({ - userUuid: '1-2-3', - onGoingRevisionsTransition: false, - itemHashes: [itemHash], - computeIntegrityHash: false, - limit: 10, - readOnlyAccess: false, - sessionUuid: '2-3-4', - contentType: 'Note', - apiVersion: ApiVersion.v20200115, - snjsVersion: '1.2.3', - roleNames: ['invalid'], }) expect(result.isFailed()).toBeTruthy() @@ -410,7 +370,6 @@ describe('SyncItems', () => { const result = await createUseCase().execute({ userUuid: '1-2-3', - onGoingRevisionsTransition: false, itemHashes: [itemHash], computeIntegrityHash: false, syncToken: 'foo', @@ -421,7 +380,6 @@ describe('SyncItems', () => { contentType: 'Note', apiVersion: ApiVersion.v20200115, snjsVersion: '1.2.3', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeTruthy() @@ -432,7 +390,6 @@ describe('SyncItems', () => { const result = await createUseCase().execute({ userUuid: '1-2-3', - onGoingRevisionsTransition: false, itemHashes: [itemHash], computeIntegrityHash: false, syncToken: 'foo', @@ -443,7 +400,6 @@ describe('SyncItems', () => { contentType: 'Note', apiVersion: ApiVersion.v20200115, snjsVersion: '1.2.3', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeTruthy() @@ -454,7 +410,6 @@ describe('SyncItems', () => { const result = await createUseCase().execute({ userUuid: '1-2-3', - onGoingRevisionsTransition: false, itemHashes: [itemHash], computeIntegrityHash: false, syncToken: 'foo', @@ -465,7 +420,6 @@ describe('SyncItems', () => { contentType: 'Note', apiVersion: ApiVersion.v20200115, snjsVersion: '1.2.3', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeTruthy() @@ -476,7 +430,6 @@ describe('SyncItems', () => { const result = await createUseCase().execute({ userUuid: '1-2-3', - onGoingRevisionsTransition: false, itemHashes: [itemHash], computeIntegrityHash: false, syncToken: 'foo', @@ -487,7 +440,6 @@ describe('SyncItems', () => { contentType: 'Note', apiVersion: ApiVersion.v20200115, snjsVersion: '1.2.3', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeTruthy() diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/SyncItems/SyncItems.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/SyncItems/SyncItems.ts index e9c51deee..292a07f59 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/SyncItems/SyncItems.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/SyncItems/SyncItems.ts @@ -1,4 +1,4 @@ -import { ContentType, Result, RoleNameCollection, UseCaseInterface } from '@standardnotes/domain-core' +import { ContentType, Result, UseCaseInterface } from '@standardnotes/domain-core' import { Item } from '../../../Item/Item' import { ItemConflict } from '../../../Item/ItemConflict' @@ -10,12 +10,12 @@ import { GetSharedVaults } from '../../SharedVaults/GetSharedVaults/GetSharedVau import { GetSharedVaultInvitesSentToUser } from '../../SharedVaults/GetSharedVaultInvitesSentToUser/GetSharedVaultInvitesSentToUser' import { GetMessagesSentToUser } from '../../Messaging/GetMessagesSentToUser/GetMessagesSentToUser' import { GetUserNotifications } from '../../Messaging/GetUserNotifications/GetUserNotifications' -import { ItemRepositoryResolverInterface } from '../../../Item/ItemRepositoryResolverInterface' import { Logger } from 'winston' +import { ItemRepositoryInterface } from '../../../Item/ItemRepositoryInterface' export class SyncItems implements UseCaseInterface { constructor( - private itemRepositoryResolver: ItemRepositoryResolverInterface, + private itemRepository: ItemRepositoryInterface, private getItemsUseCase: GetItems, private saveItemsUseCase: SaveItems, private getSharedVaultsUseCase: GetSharedVaults, @@ -27,12 +27,6 @@ export class SyncItems implements UseCaseInterface { async execute(dto: SyncItemsDTO): Promise> { try { - const roleNamesOrError = RoleNameCollection.create(dto.roleNames) - if (roleNamesOrError.isFailed()) { - return Result.fail(roleNamesOrError.getError()) - } - const roleNames = roleNamesOrError.getValue() - const getItemsResultOrError = await this.getItemsUseCase.execute({ userUuid: dto.userUuid, syncToken: dto.syncToken, @@ -40,7 +34,6 @@ export class SyncItems implements UseCaseInterface { limit: dto.limit, contentType: dto.contentType, sharedVaultUuids: dto.sharedVaultUuids, - roleNames: dto.roleNames, }) if (getItemsResultOrError.isFailed()) { return Result.fail(getItemsResultOrError.getError()) @@ -54,8 +47,6 @@ export class SyncItems implements UseCaseInterface { readOnlyAccess: dto.readOnlyAccess, sessionUuid: dto.sessionUuid, snjsVersion: dto.snjsVersion, - roleNames: dto.roleNames, - onGoingRevisionsTransition: dto.onGoingRevisionsTransition, }) if (saveItemsResultOrError.isFailed()) { return Result.fail(saveItemsResultOrError.getError()) @@ -68,7 +59,7 @@ export class SyncItems implements UseCaseInterface { ) const isSharedVaultExclusiveSync = dto.sharedVaultUuids && dto.sharedVaultUuids.length > 0 if (this.isFirstSync(dto) && !isSharedVaultExclusiveSync) { - retrievedItems = await this.frontLoadKeysItemsToTop(dto.userUuid, roleNames, retrievedItems) + retrievedItems = await this.frontLoadKeysItemsToTop(dto.userUuid, retrievedItems) } const sharedVaultsOrError = await this.getSharedVaultsUseCase.execute({ @@ -148,13 +139,8 @@ export class SyncItems implements UseCaseInterface { return retrievedItems.filter((item: Item) => syncConflictIds.indexOf(item.id.toString()) === -1) } - private async frontLoadKeysItemsToTop( - userUuid: string, - roleNames: RoleNameCollection, - retrievedItems: Array, - ): Promise> { - const itemRepository = this.itemRepositoryResolver.resolve(roleNames) - const itemsKeys = await itemRepository.findAll({ + private async frontLoadKeysItemsToTop(userUuid: string, retrievedItems: Array): Promise> { + const itemsKeys = await this.itemRepository.findAll({ userUuid, contentType: ContentType.TYPES.ItemsKey, sortBy: 'updated_at_timestamp', diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/SyncItems/SyncItemsDTO.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/SyncItems/SyncItemsDTO.ts index 5ab331cc7..80c06d0cb 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/SyncItems/SyncItemsDTO.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/SyncItems/SyncItemsDTO.ts @@ -2,7 +2,6 @@ import { ItemHash } from '../../../Item/ItemHash' export type SyncItemsDTO = { userUuid: string - roleNames: string[] itemHashes: Array computeIntegrityHash: boolean limit: number @@ -14,5 +13,4 @@ export type SyncItemsDTO = { snjsVersion: string readOnlyAccess: boolean sessionUuid: string | null - onGoingRevisionsTransition: boolean } diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/UpdateExistingItem/UpdateExistingItem.spec.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/UpdateExistingItem/UpdateExistingItem.spec.ts index ed7b2d696..bc5be9ad6 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/UpdateExistingItem/UpdateExistingItem.spec.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/UpdateExistingItem/UpdateExistingItem.spec.ts @@ -13,19 +13,16 @@ import { UniqueEntityId, Result, NotificationPayload, - RoleName, } from '@standardnotes/domain-core' import { SharedVaultAssociation } from '../../../SharedVault/SharedVaultAssociation' import { KeySystemAssociation } from '../../../KeySystem/KeySystemAssociation' import { DetermineSharedVaultOperationOnItem } from '../../SharedVaults/DetermineSharedVaultOperationOnItem/DetermineSharedVaultOperationOnItem' import { RemoveNotificationsForUser } from '../../Messaging/RemoveNotificationsForUser/RemoveNotificationsForUser' import { SharedVaultOperationOnItem } from '../../../SharedVault/SharedVaultOperationOnItem' -import { ItemRepositoryResolverInterface } from '../../../Item/ItemRepositoryResolverInterface' import { AddNotificationsForUsers } from '../../Messaging/AddNotificationsForUsers/AddNotificationsForUsers' describe('UpdateExistingItem', () => { let itemRepository: ItemRepositoryInterface - let itemRepositoryResolver: ItemRepositoryResolverInterface let timer: TimerInterface let domainEventPublisher: DomainEventPublisherInterface let domainEventFactory: DomainEventFactoryInterface @@ -37,7 +34,7 @@ describe('UpdateExistingItem', () => { const createUseCase = () => new UpdateExistingItem( - itemRepositoryResolver, + itemRepository, timer, domainEventPublisher, domainEventFactory, @@ -91,9 +88,6 @@ describe('UpdateExistingItem', () => { itemRepository = {} as jest.Mocked itemRepository.update = jest.fn() - itemRepositoryResolver = {} as jest.Mocked - itemRepositoryResolver.resolve = jest.fn().mockReturnValue(itemRepository) - timer = {} as jest.Mocked timer.getTimestampInMicroseconds = jest.fn().mockReturnValue(123456789) timer.convertMicrosecondsToDate = jest.fn().mockReturnValue(new Date(123456789)) @@ -140,27 +134,9 @@ describe('UpdateExistingItem', () => { const result = await useCase.execute({ existingItem: item1, - onGoingRevisionsTransition: false, itemHash: itemHash1, sessionUuid: '00000000-0000-0000-0000-000000000000', performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], - }) - - expect(result.isFailed()).toBeFalsy() - expect(itemRepository.update).toHaveBeenCalled() - }) - - it('should not create a revision if user has an ongoin revisions transition', async () => { - const useCase = createUseCase() - - const result = await useCase.execute({ - existingItem: item1, - onGoingRevisionsTransition: true, - itemHash: itemHash1, - sessionUuid: '00000000-0000-0000-0000-000000000000', - performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeFalsy() @@ -172,26 +148,9 @@ describe('UpdateExistingItem', () => { const result = await useCase.execute({ existingItem: item1, - onGoingRevisionsTransition: false, itemHash: itemHash1, sessionUuid: 'invalid-uuid', performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], - }) - - expect(result.isFailed()).toBeTruthy() - }) - - it('should return error if role names are invalid', async () => { - const useCase = createUseCase() - - const result = await useCase.execute({ - existingItem: item1, - onGoingRevisionsTransition: false, - itemHash: itemHash1, - sessionUuid: '00000000-0000-0000-0000-000000000000', - performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: ['invalid-role'], }) expect(result.isFailed()).toBeTruthy() @@ -202,14 +161,12 @@ describe('UpdateExistingItem', () => { const result = await useCase.execute({ existingItem: item1, - onGoingRevisionsTransition: false, itemHash: ItemHash.create({ ...itemHash1.props, content_type: 'invalid', }).getValue(), sessionUuid: '00000000-0000-0000-0000-000000000000', performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeTruthy() @@ -220,14 +177,12 @@ describe('UpdateExistingItem', () => { const result = await useCase.execute({ existingItem: item1, - onGoingRevisionsTransition: false, itemHash: ItemHash.create({ ...itemHash1.props, deleted: true, }).getValue(), sessionUuid: '00000000-0000-0000-0000-000000000000', performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeFalsy() @@ -245,14 +200,12 @@ describe('UpdateExistingItem', () => { const result = await useCase.execute({ existingItem: item1, - onGoingRevisionsTransition: false, itemHash: ItemHash.create({ ...itemHash1.props, duplicate_of: '00000000-0000-0000-0000-000000000001', }).getValue(), sessionUuid: '00000000-0000-0000-0000-000000000000', performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeFalsy() @@ -265,14 +218,12 @@ describe('UpdateExistingItem', () => { const result = await useCase.execute({ existingItem: item1, - onGoingRevisionsTransition: false, itemHash: ItemHash.create({ ...itemHash1.props, duplicate_of: 'invalid-uuid', }).getValue(), sessionUuid: '00000000-0000-0000-0000-000000000000', performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeTruthy() @@ -283,7 +234,6 @@ describe('UpdateExistingItem', () => { const result = await useCase.execute({ existingItem: item1, - onGoingRevisionsTransition: false, itemHash: ItemHash.create({ ...itemHash1.props, updated_at_timestamp: 123, @@ -291,7 +241,6 @@ describe('UpdateExistingItem', () => { }).getValue(), sessionUuid: '00000000-0000-0000-0000-000000000000', performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeFalsy() @@ -303,7 +252,6 @@ describe('UpdateExistingItem', () => { const result = await useCase.execute({ existingItem: item1, - onGoingRevisionsTransition: false, itemHash: ItemHash.create({ ...itemHash1.props, created_at: undefined, @@ -312,7 +260,6 @@ describe('UpdateExistingItem', () => { }).getValue(), sessionUuid: '00000000-0000-0000-0000-000000000000', performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeFalsy() @@ -324,7 +271,6 @@ describe('UpdateExistingItem', () => { const result = await useCase.execute({ existingItem: item1, - onGoingRevisionsTransition: false, itemHash: ItemHash.create({ ...itemHash1.props, created_at: undefined, @@ -334,7 +280,6 @@ describe('UpdateExistingItem', () => { }).getValue(), sessionUuid: '00000000-0000-0000-0000-000000000000', performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeFalsy() @@ -346,7 +291,6 @@ describe('UpdateExistingItem', () => { const result = await useCase.execute({ existingItem: item1, - onGoingRevisionsTransition: false, itemHash: ItemHash.create({ ...itemHash1.props, created_at: undefined, @@ -356,7 +300,6 @@ describe('UpdateExistingItem', () => { }).getValue(), sessionUuid: '00000000-0000-0000-0000-000000000000', performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeFalsy() @@ -373,7 +316,6 @@ describe('UpdateExistingItem', () => { const result = await useCase.execute({ existingItem: item1, - onGoingRevisionsTransition: false, itemHash: ItemHash.create({ ...itemHash1.props, created_at_timestamp: 123, @@ -381,7 +323,6 @@ describe('UpdateExistingItem', () => { }).getValue(), sessionUuid: '00000000-0000-0000-0000-000000000000', performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeTruthy() @@ -399,7 +340,6 @@ describe('UpdateExistingItem', () => { const result = await useCase.execute({ existingItem: item1, - onGoingRevisionsTransition: false, itemHash: ItemHash.create({ ...itemHash1.props, created_at_timestamp: 123, @@ -407,7 +347,6 @@ describe('UpdateExistingItem', () => { }).getValue(), sessionUuid: '00000000-0000-0000-0000-000000000000', performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeTruthy() @@ -419,11 +358,9 @@ describe('UpdateExistingItem', () => { const result = await useCase.execute({ existingItem: item1, - onGoingRevisionsTransition: false, itemHash: itemHash1, sessionUuid: '00000000-0000-0000-0000-000000000000', performingUserUuid: 'invalid-uuid', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeTruthy() }) @@ -439,11 +376,9 @@ describe('UpdateExistingItem', () => { const result = await useCase.execute({ existingItem: item1, - onGoingRevisionsTransition: false, itemHash, sessionUuid: '00000000-0000-0000-0000-000000000000', performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeFalsy() expect(item1.props.sharedVaultAssociation).not.toBeUndefined() @@ -467,11 +402,9 @@ describe('UpdateExistingItem', () => { const result = await useCase.execute({ existingItem: item1, - onGoingRevisionsTransition: false, itemHash, sessionUuid: '00000000-0000-0000-0000-000000000000', performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeFalsy() @@ -506,11 +439,9 @@ describe('UpdateExistingItem', () => { const result = await useCase.execute({ existingItem: item1, - onGoingRevisionsTransition: false, itemHash, sessionUuid: '00000000-0000-0000-0000-000000000000', performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeFalsy() @@ -536,11 +467,9 @@ describe('UpdateExistingItem', () => { const result = await useCase.execute({ existingItem: item1, - onGoingRevisionsTransition: false, itemHash, sessionUuid: '00000000-0000-0000-0000-000000000000', performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeTruthy() mock.mockRestore() @@ -558,11 +487,9 @@ describe('UpdateExistingItem', () => { const result = await useCase.execute({ existingItem: item1, - onGoingRevisionsTransition: false, itemHash, sessionUuid: '00000000-0000-0000-0000-000000000000', performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeTruthy() }) @@ -591,11 +518,9 @@ describe('UpdateExistingItem', () => { const result = await useCase.execute({ existingItem: item1, - onGoingRevisionsTransition: false, itemHash, sessionUuid: '00000000-0000-0000-0000-000000000000', performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeTruthy() }) @@ -627,11 +552,9 @@ describe('UpdateExistingItem', () => { const result = await useCase.execute({ existingItem: item1, - onGoingRevisionsTransition: false, itemHash, sessionUuid: '00000000-0000-0000-0000-000000000000', performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeTruthy() @@ -650,11 +573,9 @@ describe('UpdateExistingItem', () => { const result = await useCase.execute({ existingItem: item1, - onGoingRevisionsTransition: false, itemHash, sessionUuid: '00000000-0000-0000-0000-000000000000', performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeTruthy() }) @@ -671,11 +592,9 @@ describe('UpdateExistingItem', () => { const result = await useCase.execute({ existingItem: item1, - onGoingRevisionsTransition: false, itemHash, sessionUuid: '00000000-0000-0000-0000-000000000000', performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeFalsy() expect(item1.props.keySystemAssociation).not.toBeUndefined() @@ -694,11 +613,9 @@ describe('UpdateExistingItem', () => { const result = await useCase.execute({ existingItem: item1, - onGoingRevisionsTransition: false, itemHash, sessionUuid: '00000000-0000-0000-0000-000000000000', performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeFalsy() @@ -716,11 +633,9 @@ describe('UpdateExistingItem', () => { const result = await useCase.execute({ existingItem: item1, - onGoingRevisionsTransition: false, itemHash, sessionUuid: '00000000-0000-0000-0000-000000000000', performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeTruthy() }) @@ -740,11 +655,9 @@ describe('UpdateExistingItem', () => { const result = await useCase.execute({ existingItem: item1, - onGoingRevisionsTransition: false, itemHash, sessionUuid: '00000000-0000-0000-0000-000000000000', performingUserUuid: '00000000-0000-0000-0000-000000000000', - roleNames: [RoleName.NAMES.CoreUser], }) expect(result.isFailed()).toBeTruthy() mock.mockRestore() diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/UpdateExistingItem/UpdateExistingItem.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/UpdateExistingItem/UpdateExistingItem.ts index 400767699..72d67a945 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/UpdateExistingItem/UpdateExistingItem.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/UpdateExistingItem/UpdateExistingItem.ts @@ -5,7 +5,6 @@ import { NotificationPayloadIdentifierType, NotificationType, Result, - RoleNameCollection, Timestamps, UseCaseInterface, Uuid, @@ -22,13 +21,13 @@ import { KeySystemAssociation } from '../../../KeySystem/KeySystemAssociation' import { DetermineSharedVaultOperationOnItem } from '../../SharedVaults/DetermineSharedVaultOperationOnItem/DetermineSharedVaultOperationOnItem' import { SharedVaultOperationOnItem } from '../../../SharedVault/SharedVaultOperationOnItem' import { RemoveNotificationsForUser } from '../../Messaging/RemoveNotificationsForUser/RemoveNotificationsForUser' -import { ItemRepositoryResolverInterface } from '../../../Item/ItemRepositoryResolverInterface' import { ItemHash } from '../../../Item/ItemHash' import { AddNotificationsForUsers } from '../../Messaging/AddNotificationsForUsers/AddNotificationsForUsers' +import { ItemRepositoryInterface } from '../../../Item/ItemRepositoryInterface' export class UpdateExistingItem implements UseCaseInterface { constructor( - private itemRepositoryResolver: ItemRepositoryResolverInterface, + private itemRepository: ItemRepositoryInterface, private timer: TimerInterface, private domainEventPublisher: DomainEventPublisherInterface, private domainEventFactory: DomainEventFactoryInterface, @@ -45,12 +44,6 @@ export class UpdateExistingItem implements UseCaseInterface { } const userUuid = userUuidOrError.getValue() - const roleNamesOrError = RoleNameCollection.create(dto.roleNames) - if (roleNamesOrError.isFailed()) { - return Result.fail(roleNamesOrError.getError()) - } - const roleNames = roleNamesOrError.getValue() - let sharedVaultOperation: SharedVaultOperationOnItem | null = null if (dto.itemHash.representsASharedVaultItem() || dto.existingItem.isAssociatedWithASharedVault()) { const sharedVaultOperationOrError = await this.determineSharedVaultOperationOnItem.execute({ @@ -174,24 +167,19 @@ export class UpdateExistingItem implements UseCaseInterface { dto.existingItem.props.itemsKeyId = null } - const itemRepository = this.itemRepositoryResolver.resolve(roleNames) - - await itemRepository.update(dto.existingItem) + await this.itemRepository.update(dto.existingItem) if (secondsFromLastUpdate >= this.revisionFrequency) { if ( dto.existingItem.props.contentType.value !== null && [ContentType.TYPES.Note, ContentType.TYPES.File].includes(dto.existingItem.props.contentType.value) ) { - if (!dto.onGoingRevisionsTransition) { - await this.domainEventPublisher.publish( - this.domainEventFactory.createItemRevisionCreationRequested({ - itemUuid: dto.existingItem.id.toString(), - userUuid: dto.existingItem.props.userUuid.value, - roleNames: dto.roleNames, - }), - ) - } + await this.domainEventPublisher.publish( + this.domainEventFactory.createItemRevisionCreationRequested({ + itemUuid: dto.existingItem.id.toString(), + userUuid: dto.existingItem.props.userUuid.value, + }), + ) } } @@ -200,7 +188,6 @@ export class UpdateExistingItem implements UseCaseInterface { this.domainEventFactory.createDuplicateItemSyncedEvent({ itemUuid: dto.existingItem.id.toString(), userUuid: dto.existingItem.props.userUuid.value, - roleNames: dto.roleNames, }), ) } diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/UpdateExistingItem/UpdateExistingItemDTO.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/UpdateExistingItem/UpdateExistingItemDTO.ts index 7b241b070..ad2c1de20 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/UpdateExistingItem/UpdateExistingItemDTO.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/UpdateExistingItem/UpdateExistingItemDTO.ts @@ -6,6 +6,4 @@ export interface UpdateExistingItemDTO { itemHash: ItemHash sessionUuid: string | null performingUserUuid: string - roleNames: string[] - onGoingRevisionsTransition: boolean } diff --git a/packages/syncing-server/src/Domain/UseCase/Transition/TransitionItemsFromPrimaryToSecondaryDatabaseForUser/TransitionItemsFromPrimaryToSecondaryDatabaseForUser.ts b/packages/syncing-server/src/Domain/UseCase/Transition/TransitionItemsFromPrimaryToSecondaryDatabaseForUser/TransitionItemsFromPrimaryToSecondaryDatabaseForUser.ts deleted file mode 100644 index 0439e4f7c..000000000 --- a/packages/syncing-server/src/Domain/UseCase/Transition/TransitionItemsFromPrimaryToSecondaryDatabaseForUser/TransitionItemsFromPrimaryToSecondaryDatabaseForUser.ts +++ /dev/null @@ -1,312 +0,0 @@ -/* istanbul ignore file */ -import { TimerInterface } from '@standardnotes/time' -import { Result, TransitionStatus, UseCaseInterface, Uuid } from '@standardnotes/domain-core' -import { Logger } from 'winston' - -import { TransitionItemsFromPrimaryToSecondaryDatabaseForUserDTO } from './TransitionItemsFromPrimaryToSecondaryDatabaseForUserDTO' -import { ItemRepositoryInterface } from '../../../Item/ItemRepositoryInterface' -import { ItemQuery } from '../../../Item/ItemQuery' -import { TransitionRepositoryInterface } from '../../../Transition/TransitionRepositoryInterface' -import { DomainEventPublisherInterface } from '@standardnotes/domain-events' -import { DomainEventFactoryInterface } from '../../../Event/DomainEventFactoryInterface' - -export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements UseCaseInterface { - constructor( - private primaryItemRepository: ItemRepositoryInterface, - private secondaryItemRepository: ItemRepositoryInterface | null, - private transitionStatusRepository: TransitionRepositoryInterface | null, - private timer: TimerInterface, - private logger: Logger, - private pageSize: number, - private domainEventPublisher: DomainEventPublisherInterface, - private domainEventFactory: DomainEventFactoryInterface, - ) {} - - async execute(dto: TransitionItemsFromPrimaryToSecondaryDatabaseForUserDTO): Promise> { - this.logger.info(`[TRANSITION][${dto.userUuid}] Transitioning items`) - - if (this.secondaryItemRepository === null) { - return Result.fail('Secondary item repository is not set') - } - - if (this.transitionStatusRepository === null) { - return Result.fail('Transition status repository is not set') - } - - const userUuidOrError = Uuid.create(dto.userUuid) - if (userUuidOrError.isFailed()) { - return Result.fail(userUuidOrError.getError()) - } - const userUuid = userUuidOrError.getValue() - - if (await this.isAlreadyMigrated(userUuid)) { - this.logger.info(`[TRANSITION][${userUuid.value}] User already migrated.`) - - await this.updateTransitionStatus(userUuid, TransitionStatus.STATUSES.Verified, dto.timestamp) - - return Result.ok() - } - - const migrationTimeStart = this.timer.getTimestampInMicroseconds() - - this.logger.info(`[TRANSITION][${dto.userUuid}] Migrating items`) - - const migrationResult = await this.migrateItemsForUser(userUuid, dto.timestamp) - if (migrationResult.isFailed()) { - await this.updateTransitionStatus(userUuid, TransitionStatus.STATUSES.Failed, dto.timestamp) - - return Result.fail(migrationResult.getError()) - } - - this.logger.info(`[TRANSITION][${dto.userUuid}] Items migrated`) - - await this.allowForPrimaryDatabaseToCatchUp() - - this.logger.info(`[TRANSITION][${dto.userUuid}] Checking integrity between primary and secondary database`) - - const integrityCheckResult = await this.checkIntegrityBetweenPrimaryAndSecondaryDatabase(userUuid) - if (integrityCheckResult.isFailed()) { - await (this.transitionStatusRepository as TransitionRepositoryInterface).setPagingProgress(userUuid.value, 1) - await (this.transitionStatusRepository as TransitionRepositoryInterface).setIntegrityProgress(userUuid.value, 1) - - await this.updateTransitionStatus(userUuid, TransitionStatus.STATUSES.Failed, dto.timestamp) - - return Result.fail(integrityCheckResult.getError()) - } - - const cleanupResult = await this.deleteItemsForUser( - userUuid, - this.secondaryItemRepository as ItemRepositoryInterface, - ) - if (cleanupResult.isFailed()) { - await this.updateTransitionStatus(userUuid, TransitionStatus.STATUSES.Failed, dto.timestamp) - - this.logger.error( - `[TRANSITION][${dto.userUuid}] Failed to clean up secondary database items: ${cleanupResult.getError()}`, - ) - } - - const migrationTimeEnd = this.timer.getTimestampInMicroseconds() - - const migrationDuration = migrationTimeEnd - migrationTimeStart - const migrationDurationTimeStructure = this.timer.convertMicrosecondsToTimeStructure(migrationDuration) - - this.logger.info( - `[TRANSITION][${dto.userUuid}] Transitioned items in ${migrationDurationTimeStructure.hours}h ${migrationDurationTimeStructure.minutes}m ${migrationDurationTimeStructure.seconds}s ${migrationDurationTimeStructure.milliseconds}ms`, - ) - - await this.updateTransitionStatus(userUuid, TransitionStatus.STATUSES.Verified, dto.timestamp) - - return Result.ok() - } - - private async allowForPrimaryDatabaseToCatchUp(): Promise { - const delay = 1_000 - await this.timer.sleep(delay) - } - - private async migrateItemsForUser(userUuid: Uuid, timestamp: number): Promise> { - try { - const initialPage = await (this.transitionStatusRepository as TransitionRepositoryInterface).getPagingProgress( - userUuid.value, - ) - - this.logger.info(`[TRANSITION][${userUuid.value}] Migrating from page ${initialPage}`) - - const totalItemsCountForUser = await (this.secondaryItemRepository as ItemRepositoryInterface).countAll({ - userUuid: userUuid.value, - }) - this.logger.info(`[TRANSITION][${userUuid.value}] Total items count for user: ${totalItemsCountForUser}`) - const totalPages = Math.ceil(totalItemsCountForUser / this.pageSize) - this.logger.info(`[TRANSITION][${userUuid.value}] Total pages: ${totalPages}`) - let insertedCount = 0 - let updatedCount = 0 - let newerCount = 0 - let identicalCount = 0 - for (let currentPage = initialPage; currentPage <= totalPages; currentPage++) { - const isPageInEvery10Percent = currentPage % Math.ceil(totalPages / 10) === 0 - if (isPageInEvery10Percent) { - this.logger.info( - `[TRANSITION][${userUuid.value}] Migrating items for user: ${Math.round( - (currentPage / totalPages) * 100, - )}% completed`, - ) - this.logger.info( - `[TRANSITION][${userUuid.value}] Inserted items count: ${insertedCount}. Newer items count: ${newerCount}. Identical items count: ${identicalCount}. Updated items count: ${updatedCount}`, - ) - await this.updateTransitionStatus(userUuid, TransitionStatus.STATUSES.InProgress, timestamp) - } - - await (this.transitionStatusRepository as TransitionRepositoryInterface).setPagingProgress( - userUuid.value, - currentPage, - ) - - const query: ItemQuery = { - userUuid: userUuid.value, - offset: (currentPage - 1) * this.pageSize, - limit: this.pageSize, - sortBy: 'created_at_timestamp', - sortOrder: 'ASC', - } - - const items = await (this.secondaryItemRepository as ItemRepositoryInterface).findAll(query) - - for (const item of items) { - try { - const itemInPrimary = await this.primaryItemRepository.findByUuid(item.uuid) - - if (!itemInPrimary) { - await this.primaryItemRepository.insert(item) - - insertedCount++ - } else { - if (itemInPrimary.props.timestamps.updatedAt > item.props.timestamps.updatedAt) { - this.logger.info( - `[TRANSITION][${userUuid.value}] Item ${item.uuid.value} is older in secondary than item in primary database`, - ) - newerCount++ - - continue - } - if (itemInPrimary.isIdenticalTo(item)) { - identicalCount++ - - continue - } - - await this.primaryItemRepository.update(item) - - updatedCount++ - } - } catch (error) { - this.logger.error( - `[TRANSITION][${userUuid.value}] Errored when saving item ${item.uuid.value} to primary database: ${ - (error as Error).message - }`, - ) - } - } - } - - this.logger.info( - `[TRANSITION][${userUuid.value}] Inserted items count: ${insertedCount}. Newer items count: ${newerCount}. Identical items count: ${identicalCount}. Updated items count: ${updatedCount}`, - ) - - return Result.ok() - } catch (error) { - return Result.fail((error as Error).message) - } - } - - private async deleteItemsForUser(userUuid: Uuid, itemRepository: ItemRepositoryInterface): Promise> { - try { - this.logger.info(`[TRANSITION][${userUuid.value}] Cleaning up secondary database items`) - - await itemRepository.deleteByUserUuidAndNotInSharedVault(userUuid) - - return Result.ok() - } catch (error) { - return Result.fail((error as Error).message) - } - } - - private async checkIntegrityBetweenPrimaryAndSecondaryDatabase(userUuid: Uuid): Promise> { - try { - const initialPage = await (this.transitionStatusRepository as TransitionRepositoryInterface).getIntegrityProgress( - userUuid.value, - ) - - this.logger.info(`[TRANSITION][${userUuid.value}] Checking integrity from page ${initialPage}`) - - const totalItemsCountForUserInSecondary = await ( - this.secondaryItemRepository as ItemRepositoryInterface - ).countAll({ - userUuid: userUuid.value, - }) - const totalItemsCountForUserInPrimary = await this.primaryItemRepository.countAll({ - userUuid: userUuid.value, - }) - - if (totalItemsCountForUserInPrimary < totalItemsCountForUserInSecondary) { - return Result.fail( - `Total items count for user ${userUuid.value} in primary database (${totalItemsCountForUserInPrimary}) does not match total items count in secondary database (${totalItemsCountForUserInSecondary})`, - ) - } - - const totalPages = Math.ceil(totalItemsCountForUserInPrimary / this.pageSize) - for (let currentPage = initialPage; currentPage <= totalPages; currentPage++) { - await (this.transitionStatusRepository as TransitionRepositoryInterface).setIntegrityProgress( - userUuid.value, - currentPage, - ) - - const query: ItemQuery = { - userUuid: userUuid.value, - offset: (currentPage - 1) * this.pageSize, - limit: this.pageSize, - sortBy: 'created_at_timestamp', - sortOrder: 'ASC', - } - - const items = await (this.secondaryItemRepository as ItemRepositoryInterface).findAll(query) - - for (const item of items) { - const itemInPrimary = await this.primaryItemRepository.findByUuid(item.uuid) - if (!itemInPrimary) { - return Result.fail(`Item ${item.uuid.value} not found in primary database`) - } - - if (itemInPrimary.props.timestamps.updatedAt > item.props.timestamps.updatedAt) { - this.logger.info( - `[TRANSITION][${userUuid.value}] Integrity check of Item ${item.uuid.value} - is older in secondary than item in primary database`, - ) - - continue - } - - if (item.isIdenticalTo(itemInPrimary)) { - continue - } - - return Result.fail( - `Item ${ - item.uuid.value - } is not identical in primary and secondary database. Item in secondary database: ${JSON.stringify( - item, - )}, item in primary database: ${JSON.stringify(itemInPrimary)}`, - ) - } - } - - return Result.ok() - } catch (error) { - return Result.fail((error as Error).message) - } - } - - private async updateTransitionStatus(userUuid: Uuid, status: string, timestamp: number): Promise { - await this.domainEventPublisher.publish( - this.domainEventFactory.createTransitionStatusUpdatedEvent({ - userUuid: userUuid.value, - status, - transitionType: 'items', - transitionTimestamp: timestamp, - }), - ) - } - - private async isAlreadyMigrated(userUuid: Uuid): Promise { - const totalItemsCountForUserInSecondary = await (this.secondaryItemRepository as ItemRepositoryInterface).countAll({ - userUuid: userUuid.value, - }) - - if (totalItemsCountForUserInSecondary > 0) { - this.logger.info( - `[TRANSITION][${userUuid.value}] User has ${totalItemsCountForUserInSecondary} items in secondary database.`, - ) - } - - return totalItemsCountForUserInSecondary === 0 - } -} diff --git a/packages/syncing-server/src/Domain/UseCase/Transition/TransitionItemsFromPrimaryToSecondaryDatabaseForUser/TransitionItemsFromPrimaryToSecondaryDatabaseForUserDTO.ts b/packages/syncing-server/src/Domain/UseCase/Transition/TransitionItemsFromPrimaryToSecondaryDatabaseForUser/TransitionItemsFromPrimaryToSecondaryDatabaseForUserDTO.ts deleted file mode 100644 index 0ea7f1d3e..000000000 --- a/packages/syncing-server/src/Domain/UseCase/Transition/TransitionItemsFromPrimaryToSecondaryDatabaseForUser/TransitionItemsFromPrimaryToSecondaryDatabaseForUserDTO.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface TransitionItemsFromPrimaryToSecondaryDatabaseForUserDTO { - userUuid: string - timestamp: number -} diff --git a/packages/syncing-server/src/Infra/InversifyExpressUtils/Base/BaseItemsController.ts b/packages/syncing-server/src/Infra/InversifyExpressUtils/Base/BaseItemsController.ts index 053ec0816..e623d0010 100644 --- a/packages/syncing-server/src/Infra/InversifyExpressUtils/Base/BaseItemsController.ts +++ b/packages/syncing-server/src/Infra/InversifyExpressUtils/Base/BaseItemsController.ts @@ -2,7 +2,6 @@ import { ControllerContainerInterface, MapperInterface, Validator } from '@stand import { BaseHttpController, results } from 'inversify-express-utils' import { Request, Response } from 'express' import { HttpStatusCode } from '@standardnotes/responses' -import { Role } from '@standardnotes/security' import { Item } from '../../../Domain/Item/Item' import { SyncResponseFactoryResolverInterface } from '../../../Domain/Item/SyncResponse/SyncResponseFactoryResolverInterface' @@ -32,10 +31,6 @@ export class BaseItemsController extends BaseHttpController { } async sync(request: Request, response: Response): Promise { - if (response.locals.ongoingTransition === true) { - throw new Error(`Cannot sync user ${response.locals.user.uuid} during transition`) - } - const itemHashes: ItemHash[] = [] if ('items' in request.body) { for (const itemHashInput of request.body.items) { @@ -64,7 +59,6 @@ export class BaseItemsController extends BaseHttpController { const syncResult = await this.syncItems.execute({ userUuid: response.locals.user.uuid, - roleNames: response.locals.roles.map((role: Role) => role.name), itemHashes, computeIntegrityHash: request.body.compute_integrity === true, syncToken: request.body.sync_token, @@ -76,7 +70,6 @@ export class BaseItemsController extends BaseHttpController { readOnlyAccess: response.locals.readOnlyAccess, sessionUuid: response.locals.session ? response.locals.session.uuid : null, sharedVaultUuids, - onGoingRevisionsTransition: response.locals.onGoingRevisionsTransition, }) if (syncResult.isFailed()) { return this.json({ error: { message: syncResult.getError() } }, HttpStatusCode.BadRequest) @@ -98,7 +91,6 @@ export class BaseItemsController extends BaseHttpController { const result = await this.checkIntegrity.execute({ userUuid: response.locals.user.uuid, integrityPayloads, - roleNames: response.locals.roles.map((role: Role) => role.name), }) if (result.isFailed()) { @@ -114,7 +106,6 @@ export class BaseItemsController extends BaseHttpController { const result = await this.getItem.execute({ userUuid: response.locals.user.uuid, itemUuid: request.params.uuid, - roleNames: response.locals.roles.map((role: Role) => role.name), }) if (result.isFailed()) { diff --git a/packages/syncing-server/src/Infra/InversifyExpressUtils/Middleware/InversifyExpressAuthMiddleware.ts b/packages/syncing-server/src/Infra/InversifyExpressUtils/Middleware/InversifyExpressAuthMiddleware.ts index d18bf8a8e..954135acb 100644 --- a/packages/syncing-server/src/Infra/InversifyExpressUtils/Middleware/InversifyExpressAuthMiddleware.ts +++ b/packages/syncing-server/src/Infra/InversifyExpressUtils/Middleware/InversifyExpressAuthMiddleware.ts @@ -29,8 +29,6 @@ export class InversifyExpressAuthMiddleware extends BaseMiddleware { response.locals.session = decodedToken.session response.locals.readOnlyAccess = decodedToken.session?.readonly_access ?? false response.locals.sharedVaultOwnerContext = decodedToken.shared_vault_owner_context - response.locals.ongoingTransition = decodedToken.ongoing_transition - response.locals.onGoingRevisionsTransition = decodedToken.ongoing_revisions_transition return next() } catch (error) { diff --git a/packages/syncing-server/src/Infra/Redis/RedisTransitionRepository.ts b/packages/syncing-server/src/Infra/Redis/RedisTransitionRepository.ts deleted file mode 100644 index 7ae59cbb5..000000000 --- a/packages/syncing-server/src/Infra/Redis/RedisTransitionRepository.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as IORedis from 'ioredis' - -import { TransitionRepositoryInterface } from '../../Domain/Transition/TransitionRepositoryInterface' - -export class RedisTransitionRepository implements TransitionRepositoryInterface { - private readonly PREFIX = 'transition-items-migration-progress' - private readonly INTEGRITY_PREFIX = 'transition-items-integrity-progress' - - constructor(private redisClient: IORedis.Redis) {} - - async getIntegrityProgress(userUuid: string): Promise { - const progress = await this.redisClient.get(`${this.INTEGRITY_PREFIX}:${userUuid}`) - - if (progress === null) { - return 1 - } - - return parseInt(progress) - } - - async setIntegrityProgress(userUuid: string, progress: number): Promise { - await this.redisClient.setex(`${this.INTEGRITY_PREFIX}:${userUuid}`, 172_800, progress.toString()) - } - - async getPagingProgress(userUuid: string): Promise { - const progress = await this.redisClient.get(`${this.PREFIX}:${userUuid}`) - - if (progress === null) { - return 1 - } - - return parseInt(progress) - } - - async setPagingProgress(userUuid: string, progress: number): Promise { - await this.redisClient.setex(`${this.PREFIX}:${userUuid}`, 172_800, progress.toString()) - } -} diff --git a/packages/syncing-server/src/Infra/TypeORM/MongoDBItem.ts b/packages/syncing-server/src/Infra/TypeORM/MongoDBItem.ts deleted file mode 100644 index d20018494..000000000 --- a/packages/syncing-server/src/Infra/TypeORM/MongoDBItem.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { BSON } from 'mongodb' -import { Column, Entity, Index, ObjectIdColumn } from 'typeorm' - -@Entity({ name: 'items' }) -@Index('index_items_on_user_uuid_and_content_type', ['userUuid', 'contentType']) -@Index('user_uuid_and_deleted', ['userUuid', 'deleted']) -export class MongoDBItem { - @ObjectIdColumn() - declare _id: BSON.UUID - - @Column() - declare duplicateOf: string | null - - @Column() - declare itemsKeyId: string | null - - @Column() - declare content: string | null - - @Column() - declare contentType: string | null - - @Column() - declare contentSize: number | null - - @Column() - declare encItemKey: string | null - - @Column() - declare authHash: string | null - - @Column() - @Index('index_items_on_user_uuid') - declare userUuid: string - - @Column() - @Index('index_items_on_deleted') - declare deleted: boolean - - @Column() - declare createdAt: Date - - @Column() - declare updatedAt: Date - - @Column() - declare createdAtTimestamp: number - - @Column() - @Index('updated_at_timestamp') - declare updatedAtTimestamp: number - - @Column() - declare updatedWithSession: string | null - - @Column() - declare lastEditedBy: string | null - - @Column() - @Index('index_items_on_shared_vault_uuid') - declare sharedVaultUuid: string | null - - @Column() - declare keySystemIdentifier: string | null -} diff --git a/packages/syncing-server/src/Infra/TypeORM/MongoDBItemRepository.ts b/packages/syncing-server/src/Infra/TypeORM/MongoDBItemRepository.ts deleted file mode 100644 index 2e9cec984..000000000 --- a/packages/syncing-server/src/Infra/TypeORM/MongoDBItemRepository.ts +++ /dev/null @@ -1,300 +0,0 @@ -import { MapperInterface, Uuid } from '@standardnotes/domain-core' -import { FilterOperators, FindManyOptions, MongoRepository } from 'typeorm' -import { Logger } from 'winston' -import { BSON } from 'mongodb' - -import { ExtendedIntegrityPayload } from '../../Domain/Item/ExtendedIntegrityPayload' -import { Item } from '../../Domain/Item/Item' -import { ItemQuery } from '../../Domain/Item/ItemQuery' -import { ItemRepositoryInterface } from '../../Domain/Item/ItemRepositoryInterface' -import { MongoDBItem } from './MongoDBItem' -import { ItemContentSizeDescriptor } from '../../Domain/Item/ItemContentSizeDescriptor' - -export class MongoDBItemRepository implements ItemRepositoryInterface { - constructor( - private mongoRepository: MongoRepository, - private mapper: MapperInterface, - private logger: Logger, - ) {} - - async deleteByUserUuidInSharedVaults(userUuid: Uuid, sharedVaultUuids: Uuid[]): Promise { - await this.mongoRepository.deleteMany({ - $and: [ - { userUuid: { $eq: userUuid.value } }, - { sharedVaultUuid: { $in: sharedVaultUuids.map((uuid) => uuid.value) } }, - ], - }) - } - - async updateSharedVaultOwner(dto: { sharedVaultUuid: Uuid; fromOwnerUuid: Uuid; toOwnerUuid: Uuid }): Promise { - await this.mongoRepository.updateMany( - { - $and: [{ sharedVaultUuid: { $eq: dto.sharedVaultUuid.value } }, { userUuid: { $eq: dto.fromOwnerUuid.value } }], - }, - { $set: { userUuid: dto.toOwnerUuid.value } }, - ) - } - - async unassignFromSharedVault(sharedVaultUuid: Uuid): Promise { - await this.mongoRepository.updateMany( - { sharedVaultUuid: { $eq: sharedVaultUuid.value } }, - { $set: { sharedVaultUuid: null } }, - ) - } - - async removeByUuid(uuid: Uuid): Promise { - await this.mongoRepository.deleteOne({ _id: { $eq: BSON.UUID.createFromHexString(uuid.value) } }) - } - - async deleteByUserUuidAndNotInSharedVault(userUuid: Uuid): Promise { - await this.mongoRepository.deleteMany({ - $and: [{ userUuid: { $eq: userUuid.value } }, { sharedVaultUuid: { $eq: null } }], - }) - } - - async findAll(query: ItemQuery): Promise { - const options = this.createFindOptions(query) - const persistence = await this.mongoRepository.find(options) - - const domainItems: Item[] = [] - for (const persistencItem of persistence) { - try { - domainItems.push(this.mapper.toDomain(persistencItem)) - } catch (error) { - this.logger.error( - `Failed to map item ${persistencItem._id.toHexString()} to domain: ${(error as Error).message}`, - ) - } - } - - return domainItems - } - - async countAll(query: ItemQuery): Promise { - const options = this.createFindOptions(query) - - return this.mongoRepository.count((options as FindManyOptions).where) - } - - async findContentSizeForComputingTransferLimit(query: ItemQuery): Promise { - const options = this.createFindOptions(query) - const rawItems = await this.mongoRepository.find({ - select: ['_id', 'contentSize'], - ...options, - }) - - const itemContentSizeDescriptors: ItemContentSizeDescriptor[] = [] - - for (const rawItem of rawItems) { - const itemContentSizeDescriptorOrError = ItemContentSizeDescriptor.create( - rawItem._id.toHexString(), - rawItem.contentSize, - ) - if (itemContentSizeDescriptorOrError.isFailed()) { - this.logger.error( - `Failed to create ItemContentSizeDescriptor for item ${rawItem._id.toHexString()}: ${itemContentSizeDescriptorOrError.getError()}`, - ) - continue - } - itemContentSizeDescriptors.push(itemContentSizeDescriptorOrError.getValue()) - } - - return itemContentSizeDescriptors - } - - async findDatesForComputingIntegrityHash(userUuid: string): Promise<{ updated_at_timestamp: number }[]> { - const rawItems = await this.mongoRepository.find({ - select: ['updatedAtTimestamp'], - where: { - $and: [{ userUuid: { $eq: userUuid } }, { deleted: { $eq: false } }], - }, - }) - - const items = rawItems.map((item) => { - return { - updated_at_timestamp: item.updatedAtTimestamp, - } - }) - - return items.sort((itemA, itemB) => itemB.updated_at_timestamp - itemA.updated_at_timestamp) - } - - async findItemsForComputingIntegrityPayloads(userUuid: string): Promise { - const items = await this.mongoRepository.find({ - select: ['uuid', 'updatedAtTimestamp', 'contentType', 'userUuid', 'deleted'], - where: { - $and: [{ userUuid: { $eq: userUuid } }, { deleted: { $eq: false } }], - }, - }) - - const integrityPayloads = items.map((item) => { - return { - uuid: item._id.toHexString(), - updated_at_timestamp: item.updatedAtTimestamp, - content_type: item.contentType, - user_uuid: item.userUuid, - deleted: item.deleted, - } - }) - - return integrityPayloads.sort((itemA, itemB) => itemB.updated_at_timestamp - itemA.updated_at_timestamp) - } - - async findByUuidAndUserUuid(uuid: string, userUuid: string): Promise { - const persistence = await this.mongoRepository.findOne({ - where: { - $and: [{ _id: { $eq: BSON.UUID.createFromHexString(uuid) } }, { userUuid: { $eq: userUuid } }], - }, - }) - - if (persistence === null) { - return null - } - - return this.mapper.toDomain(persistence) - } - - async findByUuid(uuid: Uuid): Promise { - const persistence = await this.mongoRepository.findOne({ - where: { _id: { $eq: BSON.UUID.createFromHexString(uuid.value) } }, - }) - - if (persistence === null) { - return null - } - - return this.mapper.toDomain(persistence) - } - - async remove(item: Item): Promise { - await this.mongoRepository.deleteOne({ _id: { $eq: BSON.UUID.createFromHexString(item.uuid.value) } }) - } - - async insert(item: Item): Promise { - const persistence = this.mapper.toProjection(item) - - await this.mongoRepository.insertOne(persistence) - } - - async update(item: Item): Promise { - const persistence = this.mapper.toProjection(item) - - const { _id, ...rest } = persistence - - await this.mongoRepository.updateOne( - { _id: _id }, - { - $set: rest, - }, - ) - } - - async markItemsAsDeleted(itemUuids: string[], updatedAtTimestamp: number): Promise { - await this.mongoRepository.updateMany( - { _id: { $in: itemUuids.map((uuid) => BSON.UUID.createFromHexString(uuid)) } }, - { - $set: { - deleted: true, - content: null, - encItemKey: null, - authHash: null, - updatedAtTimestamp, - }, - }, - ) - } - - async updateContentSize(itemUuid: string, contentSize: number): Promise { - await this.mongoRepository.updateOne( - { _id: { $eq: BSON.UUID.createFromHexString(itemUuid) } }, - { $set: { contentSize } }, - ) - } - - private createFindOptions( - query: ItemQuery, - ): FindManyOptions | Partial | FilterOperators { - const options: FindManyOptions | Partial | FilterOperators = { - order: undefined, - where: undefined, - } - if (query.sortBy !== undefined && query.sortOrder !== undefined) { - const sortBySnakeToCamelCase = query.sortBy - .toLowerCase() - .replace(/([-_][a-z])/g, (group) => group.toUpperCase().replace('-', '').replace('_', '')) - - options.order = { [sortBySnakeToCamelCase]: query.sortOrder, _id: 'ASC' } - } - - if (query.uuids && query.uuids.length > 0) { - options.where = { - ...options.where, - _id: { $in: query.uuids.map((uuid) => BSON.UUID.createFromHexString(uuid)) }, - } - } - if (query.deleted !== undefined) { - options.where = { ...options.where, deleted: { $eq: query.deleted } } - } - if (query.contentType) { - if (Array.isArray(query.contentType)) { - options.where = { ...options.where, contentType: { $in: query.contentType } } - } else { - options.where = { ...options.where, contentType: { $eq: query.contentType } } - } - } - if (query.lastSyncTime && query.syncTimeComparison) { - const mongoComparisonOperator = query.syncTimeComparison === '>' ? '$gt' : '$gte' - options.where = { - ...options.where, - updatedAtTimestamp: { [mongoComparisonOperator]: query.lastSyncTime }, - } - } - if (query.createdBetween !== undefined) { - options.where = { - ...options.where, - createdAt: { - $gte: query.createdBetween[0].toISOString(), - $lte: query.createdBetween[1].toISOString(), - }, - } - } - - if (query.includeSharedVaultUuids !== undefined && query.includeSharedVaultUuids.length > 0) { - if (query.userUuid) { - options.where = { - $and: [ - { ...options.where }, - { - $or: [{ sharedVaultUuid: { $in: query.includeSharedVaultUuids } }, { userUuid: { $eq: query.userUuid } }], - }, - ], - } - } else { - options.where = { - $and: [ - { ...options.where }, - { - $or: [{ sharedVaultUuid: { $in: query.includeSharedVaultUuids } }], - }, - ], - } - } - } else if (query.exclusiveSharedVaultUuids !== undefined && query.exclusiveSharedVaultUuids.length > 0) { - options.where = { - ...options.where, - sharedVaultUuid: { $in: query.exclusiveSharedVaultUuids }, - } - } else if (query.userUuid !== undefined) { - options.where = { ...options.where, userUuid: { $eq: query.userUuid } } - } - - if (query.offset !== undefined) { - options.skip = query.offset - } - if (query.limit !== undefined) { - options.take = query.limit - } - - return options - } -} diff --git a/packages/syncing-server/src/Infra/TypeORM/TypeORMItemRepositoryResolver.ts b/packages/syncing-server/src/Infra/TypeORM/TypeORMItemRepositoryResolver.ts deleted file mode 100644 index caeca537e..000000000 --- a/packages/syncing-server/src/Infra/TypeORM/TypeORMItemRepositoryResolver.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { RoleName, RoleNameCollection } from '@standardnotes/domain-core' - -import { ItemRepositoryInterface } from '../../Domain/Item/ItemRepositoryInterface' -import { ItemRepositoryResolverInterface } from '../../Domain/Item/ItemRepositoryResolverInterface' - -export class TypeORMItemRepositoryResolver implements ItemRepositoryResolverInterface { - constructor( - private sqlItemRepository: ItemRepositoryInterface, - private mongoDbItemRepository: ItemRepositoryInterface | null, - ) {} - - resolve(roleNames: RoleNameCollection): ItemRepositoryInterface { - if (!this.mongoDbItemRepository) { - return this.sqlItemRepository - } - - const transitionRoleName = RoleName.create(RoleName.NAMES.TransitionUser).getValue() - - if (roleNames.includes(transitionRoleName)) { - return this.mongoDbItemRepository - } - - return this.sqlItemRepository - } -} diff --git a/packages/syncing-server/src/Mapping/Persistence/MongoDB/MongoDBItemPersistenceMapper.ts b/packages/syncing-server/src/Mapping/Persistence/MongoDB/MongoDBItemPersistenceMapper.ts deleted file mode 100644 index 4d7ad3893..000000000 --- a/packages/syncing-server/src/Mapping/Persistence/MongoDB/MongoDBItemPersistenceMapper.ts +++ /dev/null @@ -1,148 +0,0 @@ -import { ContentType, Dates, MapperInterface, Timestamps, UniqueEntityId, Uuid } from '@standardnotes/domain-core' -import { BSON } from 'mongodb' - -import { MongoDBItem } from '../../../Infra/TypeORM/MongoDBItem' -import { Item } from '../../../Domain/Item/Item' -import { SharedVaultAssociation } from '../../../Domain/SharedVault/SharedVaultAssociation' -import { KeySystemAssociation } from '../../../Domain/KeySystem/KeySystemAssociation' - -export class MongoDBItemPersistenceMapper implements MapperInterface { - toDomain(projection: MongoDBItem): Item { - const uuidOrError = Uuid.create(projection._id.toHexString()) - if (uuidOrError.isFailed()) { - throw new Error(`Failed to create item from projection: ${uuidOrError.getError()}`) - } - const uuid = uuidOrError.getValue() - - let duplicateOf = null - if (projection.duplicateOf) { - const duplicateOfOrError = Uuid.create(projection.duplicateOf) - if (duplicateOfOrError.isFailed()) { - throw new Error(`Failed to create item from projection: ${duplicateOfOrError.getError()}`) - } - duplicateOf = duplicateOfOrError.getValue() - } - - const contentTypeOrError = ContentType.create(projection.contentType) - if (contentTypeOrError.isFailed()) { - throw new Error(`Failed to create item from projection: ${contentTypeOrError.getError()}`) - } - const contentType = contentTypeOrError.getValue() - - const userUuidOrError = Uuid.create(projection.userUuid) - if (userUuidOrError.isFailed()) { - throw new Error(`Failed to create item from projection: ${userUuidOrError.getError()}`) - } - const userUuid = userUuidOrError.getValue() - - const datesOrError = Dates.create(projection.createdAt, projection.updatedAt) - if (datesOrError.isFailed()) { - throw new Error(`Failed to create item from projection: ${datesOrError.getError()}`) - } - const dates = datesOrError.getValue() - - const timestampsOrError = Timestamps.create(projection.createdAtTimestamp, projection.updatedAtTimestamp) - if (timestampsOrError.isFailed()) { - throw new Error(`Failed to create item from projection: ${timestampsOrError.getError()}`) - } - const timestamps = timestampsOrError.getValue() - - let sharedVaultAssociation: SharedVaultAssociation | undefined = undefined - if (projection.sharedVaultUuid && projection.lastEditedBy) { - const sharedVaultUuidOrError = Uuid.create(projection.sharedVaultUuid) - if (sharedVaultUuidOrError.isFailed()) { - throw new Error(`Failed to create item from projection: ${sharedVaultUuidOrError.getError()}`) - } - const sharedVaultUuid = sharedVaultUuidOrError.getValue() - - const lastEditedByOrError = Uuid.create(projection.lastEditedBy) - if (lastEditedByOrError.isFailed()) { - throw new Error(`Failed to create item from projection: ${lastEditedByOrError.getError()}`) - } - const lastEditedBy = lastEditedByOrError.getValue() - - const sharedVaultAssociationOrError = SharedVaultAssociation.create({ - sharedVaultUuid, - lastEditedBy, - }) - if (sharedVaultAssociationOrError.isFailed()) { - throw new Error(`Failed to create item from projection: ${sharedVaultAssociationOrError.getError()}`) - } - sharedVaultAssociation = sharedVaultAssociationOrError.getValue() - } - - let keySystemAssociation: KeySystemAssociation | undefined = undefined - if (projection.keySystemIdentifier) { - const keySystemAssociationOrError = KeySystemAssociation.create(projection.keySystemIdentifier) - if (keySystemAssociationOrError.isFailed()) { - throw new Error(`Failed to create item from projection: ${keySystemAssociationOrError.getError()}`) - } - keySystemAssociation = keySystemAssociationOrError.getValue() - } - - let updatedWithSession = null - if (projection.updatedWithSession) { - const updatedWithSessionOrError = Uuid.create(projection.updatedWithSession) - if (updatedWithSessionOrError.isFailed()) { - throw new Error(`Failed to create item from projection: ${updatedWithSessionOrError.getError()}`) - } - updatedWithSession = updatedWithSessionOrError.getValue() - } - - const itemOrError = Item.create( - { - duplicateOf, - itemsKeyId: projection.itemsKeyId, - content: projection.content, - contentType, - contentSize: projection.contentSize ?? undefined, - encItemKey: projection.encItemKey, - authHash: projection.authHash, - userUuid, - deleted: !!projection.deleted, - dates, - timestamps, - updatedWithSession, - sharedVaultAssociation, - keySystemAssociation, - }, - new UniqueEntityId(uuid.value), - ) - if (itemOrError.isFailed()) { - throw new Error(`Failed to create item from projection: ${itemOrError.getError()}`) - } - - return itemOrError.getValue() - } - - toProjection(domain: Item): MongoDBItem { - const mongoDbItem = new MongoDBItem() - - mongoDbItem._id = BSON.UUID.createFromHexString(domain.uuid.value) - mongoDbItem.duplicateOf = domain.props.duplicateOf ? domain.props.duplicateOf.value : null - mongoDbItem.itemsKeyId = domain.props.itemsKeyId - mongoDbItem.content = domain.props.content - mongoDbItem.contentType = domain.props.contentType.value - mongoDbItem.contentSize = domain.props.contentSize ?? null - mongoDbItem.encItemKey = domain.props.encItemKey - mongoDbItem.authHash = domain.props.authHash - mongoDbItem.userUuid = domain.props.userUuid.value - mongoDbItem.deleted = !!domain.props.deleted - mongoDbItem.createdAt = domain.props.dates.createdAt - mongoDbItem.updatedAt = domain.props.dates.updatedAt - mongoDbItem.createdAtTimestamp = domain.props.timestamps.createdAt - mongoDbItem.updatedAtTimestamp = domain.props.timestamps.updatedAt - mongoDbItem.updatedWithSession = domain.props.updatedWithSession ? domain.props.updatedWithSession.value : null - mongoDbItem.lastEditedBy = domain.props.sharedVaultAssociation - ? domain.props.sharedVaultAssociation.props.lastEditedBy.value - : null - mongoDbItem.sharedVaultUuid = domain.props.sharedVaultAssociation - ? domain.props.sharedVaultAssociation.props.sharedVaultUuid.value - : null - mongoDbItem.keySystemIdentifier = domain.props.keySystemAssociation - ? domain.props.keySystemAssociation.props.keySystemIdentifier - : null - - return mongoDbItem - } -} diff --git a/yarn.lock b/yarn.lock index 8274daae4..79ace7227 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2449,15 +2449,6 @@ __metadata: languageName: node linkType: hard -"@mongodb-js/saslprep@npm:^1.1.0": - version: 1.1.0 - resolution: "@mongodb-js/saslprep@npm:1.1.0" - dependencies: - sparse-bitfield: "npm:^3.0.3" - checksum: 1a631b92d21691626a508e5eafafb43229d2d9bdafc454cda182ed8626f046df0ef8cf4fe545403f75bbeb991954dcef0554a51f2551dbadc54ced35f1df0192 - languageName: node - linkType: hard - "@nodelib/fs.scandir@npm:2.1.5": version: 2.1.5 resolution: "@nodelib/fs.scandir@npm:2.1.5" @@ -4693,7 +4684,6 @@ __metadata: inversify-express-utils: "npm:^6.4.3" ioredis: "npm:^5.3.2" jest: "npm:^29.5.0" - mongodb: "npm:^6.0.0" mysql2: "npm:^3.0.1" prettier: "npm:^3.0.3" reflect-metadata: "npm:0.1.13" @@ -4866,7 +4856,6 @@ __metadata: ioredis: "npm:^5.3.2" jest: "npm:^29.5.0" jsonwebtoken: "npm:^9.0.0" - mongodb: "npm:^6.0.0" mysql2: "npm:^3.0.1" prettier: "npm:^3.0.3" prettyjson: "npm:^1.2.5" @@ -5429,23 +5418,6 @@ __metadata: languageName: node linkType: hard -"@types/webidl-conversions@npm:*": - version: 7.0.0 - resolution: "@types/webidl-conversions@npm:7.0.0" - checksum: 60142c7ddd9eb6f907d232d6b3a81ecf990f73b5a62a004eba8bd0f54809a42ece68ce512e7e3e1d98af8b6393d66cddb96f3622d2fb223c4e9c8937c61bfed7 - languageName: node - linkType: hard - -"@types/whatwg-url@npm:^8.2.1": - version: 8.2.2 - resolution: "@types/whatwg-url@npm:8.2.2" - dependencies: - "@types/node": "npm:*" - "@types/webidl-conversions": "npm:*" - checksum: 5dc5afe078dfa1a8a266745586fa3db9baa8ce7cc904789211d1dca1d34d7f3dd17d0b7423c36bc9beab9d98aa99338f1fc60798c0af6cbb8356f20e20d9f243 - languageName: node - linkType: hard - "@types/yargs-parser@npm:*": version: 21.0.0 resolution: "@types/yargs-parser@npm:21.0.0" @@ -6361,13 +6333,6 @@ __metadata: languageName: node linkType: hard -"bson@npm:^6.0.0": - version: 6.0.0 - resolution: "bson@npm:6.0.0" - checksum: e7614bdc53c5de0a17b70e40d4739aba2ea9a0e7df4864020ab98e09db47846099e8dd31352280d10d4e62ee2a7fd1c9730afbf92e043e34724b2a3a0d0ebb6b - languageName: node - linkType: hard - "buffer-equal-constant-time@npm:1.0.1": version: 1.0.1 resolution: "buffer-equal-constant-time@npm:1.0.1" @@ -10402,13 +10367,6 @@ __metadata: languageName: node linkType: hard -"memory-pager@npm:^1.0.2": - version: 1.5.0 - resolution: "memory-pager@npm:1.5.0" - checksum: ffe3461b6aa4e400138d1d9c59890b1cbeae3256592a0dfae49577f4bec93952de65f31f682f0b15451d2a7cf018be775ed1e1411705e45514b14fb70883a66b - languageName: node - linkType: hard - "meow@npm:^8.0.0": version: 8.1.2 resolution: "meow@npm:8.1.2" @@ -10733,50 +10691,6 @@ __metadata: languageName: node linkType: hard -"mongodb-connection-string-url@npm:^2.6.0": - version: 2.6.0 - resolution: "mongodb-connection-string-url@npm:2.6.0" - dependencies: - "@types/whatwg-url": "npm:^8.2.1" - whatwg-url: "npm:^11.0.0" - checksum: d0903b98240e3a32a96091fd78d59de0616070c5e39881b598ff1c3cc9cd3335473c43d30e8b33c679ad0ab6133ff1112a7465f8c2f81b0d13b1b3f2174c9fe7 - languageName: node - linkType: hard - -"mongodb@npm:^6.0.0": - version: 6.0.0 - resolution: "mongodb@npm:6.0.0" - dependencies: - "@mongodb-js/saslprep": "npm:^1.1.0" - bson: "npm:^6.0.0" - mongodb-connection-string-url: "npm:^2.6.0" - peerDependencies: - "@aws-sdk/credential-providers": ^3.188.0 - "@mongodb-js/zstd": ^1.1.0 - gcp-metadata: ^5.2.0 - kerberos: ^2.0.1 - mongodb-client-encryption: ">=6.0.0 <7" - snappy: ^7.2.2 - socks: ^2.7.1 - peerDependenciesMeta: - "@aws-sdk/credential-providers": - optional: true - "@mongodb-js/zstd": - optional: true - gcp-metadata: - optional: true - kerberos: - optional: true - mongodb-client-encryption: - optional: true - snappy: - optional: true - socks: - optional: true - checksum: 501feaecb7c2605b2d61e4811df710996d706e1c38061a8629c6ff72a7494360edd4dc2d86b003b73c816984e8fba81d956d74134a17eca2e36076ccacb86738 - languageName: node - linkType: hard - "ms@npm:2.0.0": version: 2.0.0 resolution: "ms@npm:2.0.0" @@ -11904,7 +11818,7 @@ __metadata: languageName: node linkType: hard -"punycode@npm:^2.1.0, punycode@npm:^2.1.1": +"punycode@npm:^2.1.0": version: 2.3.0 resolution: "punycode@npm:2.3.0" checksum: d4e7fbb96f570c57d64b09a35a1182c879ac32833de7c6926a2c10619632c1377865af3dab5479f59d51da18bcd5035a20a5ef6ceb74020082a3e78025d9a9ca @@ -12682,15 +12596,6 @@ __metadata: languageName: node linkType: hard -"sparse-bitfield@npm:^3.0.3": - version: 3.0.3 - resolution: "sparse-bitfield@npm:3.0.3" - dependencies: - memory-pager: "npm:^1.0.2" - checksum: 174da88dbbcc783d5dbd26921931cc83830280b8055fb05333786ebe6fc015b9601b24972b3d55920dd2d9f5fb120576fbfa2469b08e5222c9cadf3f05210aab - languageName: node - linkType: hard - "spdx-correct@npm:^3.0.0": version: 3.2.0 resolution: "spdx-correct@npm:3.2.0" @@ -13242,15 +13147,6 @@ __metadata: languageName: node linkType: hard -"tr46@npm:^3.0.0": - version: 3.0.0 - resolution: "tr46@npm:3.0.0" - dependencies: - punycode: "npm:^2.1.1" - checksum: b09a15886cbfaee419a3469081223489051ce9dca3374dd9500d2378adedbee84a3c73f83bfdd6bb13d53657753fc0d4e20a46bfcd3f1b9057ef528426ad7ce4 - languageName: node - linkType: hard - "tr46@npm:~0.0.3": version: 0.0.3 resolution: "tr46@npm:0.0.3" @@ -13843,13 +13739,6 @@ __metadata: languageName: node linkType: hard -"webidl-conversions@npm:^7.0.0": - version: 7.0.0 - resolution: "webidl-conversions@npm:7.0.0" - checksum: 4c4f65472c010eddbe648c11b977d048dd96956a625f7f8b9d64e1b30c3c1f23ea1acfd654648426ce5c743c2108a5a757c0592f02902cf7367adb7d14e67721 - languageName: node - linkType: hard - "webpack-sources@npm:^3.2.3": version: 3.2.3 resolution: "webpack-sources@npm:3.2.3" @@ -13894,16 +13783,6 @@ __metadata: languageName: node linkType: hard -"whatwg-url@npm:^11.0.0": - version: 11.0.0 - resolution: "whatwg-url@npm:11.0.0" - dependencies: - tr46: "npm:^3.0.0" - webidl-conversions: "npm:^7.0.0" - checksum: dfcd51c6f4bfb54685528fb10927f3fd3d7c809b5671beef4a8cdd7b1408a7abf3343a35bc71dab83a1424f1c1e92cc2700d7930d95d231df0fac361de0c7648 - languageName: node - linkType: hard - "whatwg-url@npm:^5.0.0": version: 5.0.0 resolution: "whatwg-url@npm:5.0.0"