Compare commits

..

47 Commits

Author SHA1 Message Date
standardci
49832e7944 chore(release): publish new version
- @standardnotes/home-server@1.13.51
 - @standardnotes/syncing-server@1.79.1
2023-08-17 10:15:43 +00:00
Karol Sójko
916e98936a fix(home-server): add default env values for secondary database 2023-08-17 11:56:56 +02:00
Karol Sójko
31d1eef7f7 fix(syncing-server): refactor shared vault and key system associations (#698)
* feat(syncing-server): refactor persistence of shared vault and key system associations

* fix(syncing-server): refactor shared vault and key system associations
2023-08-17 11:56:16 +02:00
standardci
2648d9a813 chore(release): publish new version
- @standardnotes/home-server@1.13.50
 - @standardnotes/syncing-server@1.79.0
2023-08-16 11:16:38 +00:00
Karol Sójko
b24b576209 feat: add mongodb initial support (#696)
* feat: add mongodb initial support

* fix: typeorm annotations for mongodb entity

* wip mongo repo

* feat: add mongodb queries

* fix(syncing-server): env sample

* fix(syncing-server): Mongo connection auth source

* fix(syncing-server): db switch env var name

* fix(syncing-server): persisting and querying by _id as UUID in MongoDB

* fix(syncing-server): items upserts on MongoDB

* fix: remove foreign key migration
2023-08-16 13:00:16 +02:00
Karol Sójko
faee38bffd fix: hosts for home-server e2e ci setup 2023-08-15 13:17:20 +02:00
Karol Sójko
65f3503fe8 fix: docker compose ci setup 2023-08-15 13:11:14 +02:00
Karol Sójko
054023b791 fix: host variables 2023-08-15 12:59:13 +02:00
Karol Sójko
383c3a68fa fix: default value for SECONDARY_DB_ENABLED 2023-08-15 12:56:55 +02:00
Karol Sójko
7d22b1c15c feat: run mongo db secondary database in e2e 2023-08-15 12:50:38 +02:00
standardci
c71e7cd926 chore(release): publish new version
- @standardnotes/auth-server@1.131.5
 - @standardnotes/home-server@1.13.49
2023-08-15 10:34:11 +00:00
Karol Sójko
83ad069c5d fix(auth): passing the invalidate cache header (#697) 2023-08-15 12:16:01 +02:00
standardci
081108d9ba chore(release): publish new version
- @standardnotes/home-server@1.13.48
 - @standardnotes/syncing-server@1.78.11
2023-08-11 11:52:27 +00:00
Karol Sójko
8f3df56a2b chore: fix revisions frequency 2023-08-11 13:22:11 +02:00
Karol Sójko
d02124f4e5 Revert "tmp: disable shared vaults"
This reverts commit c49dc35ab5.
2023-08-11 12:28:57 +02:00
Karol Sójko
09e351fedb Revert "tmp: ci"
This reverts commit 06cedd11d8.
2023-08-11 12:27:12 +02:00
Karol Sójko
ad4b85b095 Revert "tmp: disable decorating with associations on revisions"
This reverts commit ac3646836c.
2023-08-11 12:26:44 +02:00
Karol Sójko
0bf7d8beae Revert "tmp: disable decorating items completely"
This reverts commit bc1c7a8ae1.
2023-08-11 12:25:35 +02:00
standardci
1ae7cca394 chore(release): publish new version
- @standardnotes/home-server@1.13.47
 - @standardnotes/syncing-server@1.78.10
2023-08-11 09:00:00 +00:00
Karol Sójko
bc1c7a8ae1 tmp: disable decorating items completely 2023-08-11 10:54:12 +02:00
standardci
c22c5e4584 chore(release): publish new version
- @standardnotes/home-server@1.13.46
 - @standardnotes/syncing-server@1.78.9
2023-08-11 08:46:28 +00:00
Karol Sójko
ac3646836c tmp: disable decorating with associations on revisions 2023-08-11 10:40:03 +02:00
standardci
7a31ab75d6 chore(release): publish new version
- @standardnotes/home-server@1.13.45
 - @standardnotes/syncing-server@1.78.8
2023-08-11 08:23:28 +00:00
Karol Sójko
c49dc35ab5 tmp: disable shared vaults 2023-08-11 10:15:55 +02:00
Karol Sójko
06cedd11d8 tmp: ci 2023-08-11 10:15:55 +02:00
standardci
f496376fb3 chore(release): publish new version
- @standardnotes/scheduler-server@1.20.22
2023-08-11 08:14:41 +00:00
Karol Sójko
091e2a57e8 fix(scheduler): adjust email backups encouraging email schedule (#695) 2023-08-11 09:35:51 +02:00
standardci
0d40ef6796 chore(release): publish new version
- @standardnotes/analytics@2.25.13
 - @standardnotes/auth-server@1.131.4
 - @standardnotes/common@1.50.1
 - @standardnotes/home-server@1.13.44
 - @standardnotes/revisions-server@1.26.7
 - @standardnotes/syncing-server@1.78.7
 - @standardnotes/websockets-server@1.10.17
2023-08-11 07:35:15 +00:00
Mo
1be33ba4c3 refactor: remove unused functions (#694)
* refactor: remove unused functions

* refactor: remove unused functions
2023-08-11 08:58:39 +02:00
Mo
aaeb311928 chore: reduce ci revisions timeout 2023-08-10 13:09:49 -05:00
standardci
a7a38c07ac chore(release): publish new version
- @standardnotes/home-server@1.13.43
 - @standardnotes/syncing-server@1.78.6
2023-08-10 11:37:24 +00:00
Karol Sójko
56f49752b4 fix(syncing-server): setting user uuid in notifications 2023-08-10 13:04:51 +02:00
Mo
892d8b6fe2 chore: update email template 2023-08-10 05:49:30 -05:00
standardci
cec2005436 chore(release): publish new version
- @standardnotes/analytics@2.25.12
 - @standardnotes/api-gateway@1.70.4
 - @standardnotes/auth-server@1.131.3
 - @standardnotes/domain-core@1.25.2
 - @standardnotes/event-store@1.11.19
 - @standardnotes/files-server@1.20.3
 - @standardnotes/home-server@1.13.42
 - @standardnotes/revisions-server@1.26.6
 - @standardnotes/scheduler-server@1.20.21
 - @standardnotes/settings@1.21.24
 - @standardnotes/syncing-server@1.78.5
 - @standardnotes/websockets-server@1.10.16
2023-08-09 16:31:35 +00:00
Karol Sójko
0eb86c0096 Revert "tmp: disable fetching shared vault items"
This reverts commit 18eddea6f8.
2023-08-09 18:01:16 +02:00
Karol Sójko
b8e39d76c1 Revert "tmp: skip ci"
This reverts commit f8c9e67063.
2023-08-09 18:01:09 +02:00
Karol Sójko
1c3ff526b7 Revert "Revert "feat(syncing-server): notify shared vault users upon file uploads or removals (#692)""
This reverts commit d261c81cd0.
2023-08-09 18:00:49 +02:00
standardci
373767248c chore(release): publish new version
- @standardnotes/home-server@1.13.41
 - @standardnotes/syncing-server@1.78.4
2023-08-09 15:47:05 +00:00
Karol Sójko
d7965b2748 fix(syncing-server): casting handlers 2023-08-09 17:40:48 +02:00
Karol Sójko
cbcd2ec87a Revert "Revert "fix(syncing-server): update storage quota used in a shared vault (#691)""
This reverts commit 66f9352a06.
2023-08-09 17:36:59 +02:00
standardci
c74d37fc48 chore(release): publish new version
- @standardnotes/home-server@1.13.40
 - @standardnotes/syncing-server@1.78.3
2023-08-09 15:29:30 +00:00
Karol Sójko
66f9352a06 Revert "fix(syncing-server): update storage quota used in a shared vault (#691)"
This reverts commit 3415cae093.
2023-08-09 17:21:59 +02:00
standardci
e5eef3aba0 chore(release): publish new version
- @standardnotes/analytics@2.25.11
 - @standardnotes/api-gateway@1.70.3
 - @standardnotes/auth-server@1.131.2
 - @standardnotes/domain-core@1.25.1
 - @standardnotes/event-store@1.11.18
 - @standardnotes/files-server@1.20.2
 - @standardnotes/home-server@1.13.39
 - @standardnotes/revisions-server@1.26.5
 - @standardnotes/scheduler-server@1.20.20
 - @standardnotes/settings@1.21.23
 - @standardnotes/syncing-server@1.78.2
 - @standardnotes/websockets-server@1.10.15
2023-08-09 14:51:38 +00:00
Karol Sójko
d261c81cd0 Revert "feat(syncing-server): notify shared vault users upon file uploads or removals (#692)"
This reverts commit 46867c1a4d.
2023-08-09 16:43:33 +02:00
standardci
634e3bbb67 chore(release): publish new version
- @standardnotes/home-server@1.13.38
 - @standardnotes/syncing-server@1.78.1
2023-08-09 14:41:32 +00:00
Karol Sójko
f8c9e67063 tmp: skip ci 2023-08-09 16:33:59 +02:00
Karol Sójko
18eddea6f8 tmp: disable fetching shared vault items 2023-08-09 16:17:53 +02:00
82 changed files with 1301 additions and 527 deletions

8
.github/ci.env vendored
View File

@@ -10,7 +10,7 @@ REDIS_HOST=cache
AUTH_SERVER_ACCESS_TOKEN_AGE=4
AUTH_SERVER_REFRESH_TOKEN_AGE=10
AUTH_SERVER_EPHEMERAL_SESSION_AGE=300
SYNCING_SERVER_REVISIONS_FREQUENCY=5
SYNCING_SERVER_REVISIONS_FREQUENCY=2
AUTH_SERVER_LOG_LEVEL=debug
SYNCING_SERVER_LOG_LEVEL=debug
FILES_SERVER_LOG_LEVEL=debug
@@ -22,6 +22,12 @@ MYSQL_USER=std_notes_user
MYSQL_PASSWORD=changeme123
MYSQL_ROOT_PASSWORD=changeme123
MONGO_HOST=secondary_db
MONGO_PORT=27017
MONGO_USERNAME=standardnotes
MONGO_PASSWORD=standardnotes
MONGO_DATABASE=standardnotes
AUTH_JWT_SECRET=f95259c5e441f5a4646d76422cfb3df4c4488842901aa50b6c51b8be2e0040e9
AUTH_SERVER_ENCRYPTION_SERVER_KEY=1087415dfde3093797f9a7ca93a49e7d7aa1861735eb0d32aae9c303b8c3d060
VALET_TOKEN_SECRET=4b886819ebe1e908077c6cae96311b48a8416bd60cc91c03060e15bdf6b30d1f

View File

@@ -20,6 +20,10 @@ on:
jobs:
e2e:
name: (Docker) E2E Test Suite
strategy:
fail-fast: false
matrix:
secondary_db_enabled: [true, false]
runs-on: ubuntu-latest
services:
@@ -45,6 +49,7 @@ jobs:
env:
DB_TYPE: mysql
CACHE_TYPE: redis
SECONDARY_DB_ENABLED: ${{ matrix.secondary_db_enabled }}
- name: Wait for server to start
run: docker/is-available.sh http://localhost:3123 $(pwd)/logs
@@ -67,13 +72,7 @@ jobs:
matrix:
db_type: [mysql, sqlite]
cache_type: [redis, memory]
include:
- cache_type: redis
db_type: mysql
redis_port: 6380
- cache_type: redis
db_type: sqlite
redis_port: 6381
secondary_db_enabled: [true, false]
runs-on: ubuntu-latest
@@ -85,16 +84,24 @@ jobs:
cache:
image: redis
ports:
- ${{ matrix.redis_port }}:6379
- 6379:6379
db:
image: mysql
ports:
- 3307:3306
- 3306:3306
env:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: standardnotes_${{ matrix.cache_type }}
MYSQL_DATABASE: standardnotes
MYSQL_USER: standardnotes
MYSQL_PASSWORD: standardnotes
secondary_db:
image: mongo:5.0
ports:
- 27017:27017
env:
MONGO_INITDB_ROOT_USERNAME: standardnotes
MONGO_INITDB_ROOT_PASSWORD: standardnotes
MONGO_INITDB_DATABASE: standardnotes
steps:
- uses: actions/checkout@v3
@@ -123,16 +130,22 @@ jobs:
sed -i "s/VALET_TOKEN_SECRET=/VALET_TOKEN_SECRET=$(openssl rand -hex 32)/g" packages/home-server/.env
echo "ACCESS_TOKEN_AGE=4" >> packages/home-server/.env
echo "REFRESH_TOKEN_AGE=10" >> packages/home-server/.env
echo "REVISIONS_FREQUENCY=5" >> packages/home-server/.env
echo "REVISIONS_FREQUENCY=2" >> packages/home-server/.env
echo "DB_HOST=localhost" >> packages/home-server/.env
echo "DB_PORT=3307" >> packages/home-server/.env
echo "DB_DATABASE=standardnotes_${{ matrix.cache_type }}" >> packages/home-server/.env
echo "DB_SQLITE_DATABASE_PATH=sqlite_${{ matrix.cache_type }}.db" >> packages/home-server/.env
echo "DB_PORT=3306" >> packages/home-server/.env
echo "DB_DATABASE=standardnotes" >> packages/home-server/.env
echo "DB_SQLITE_DATABASE_PATH=homeserver.db" >> packages/home-server/.env
echo "DB_USERNAME=standardnotes" >> packages/home-server/.env
echo "DB_PASSWORD=standardnotes" >> packages/home-server/.env
echo "DB_TYPE=${{ matrix.db_type }}" >> packages/home-server/.env
echo "REDIS_URL=redis://localhost:${{ matrix.redis_port }}" >> packages/home-server/.env
echo "REDIS_URL=redis://localhost:6379" >> packages/home-server/.env
echo "CACHE_TYPE=${{ matrix.cache_type }}" >> packages/home-server/.env
echo "SECONDARY_DB_ENABLED=${{ matrix.secondary_db_enabled }}" >> packages/home-server/.env
echo "MONGO_HOST=localhost" >> packages/home-server/.env
echo "MONGO_PORT=27017" >> packages/home-server/.env
echo "MONGO_DATABASE=standardnotes" >> packages/home-server/.env
echo "MONGO_USERNAME=standardnotes" >> packages/home-server/.env
echo "MONGO_PASSWORD=standardnotes" >> packages/home-server/.env
echo "FILES_SERVER_URL=http://localhost:3123" >> packages/home-server/.env
echo "E2E_TESTING=true" >> packages/home-server/.env

230
.pnp.cjs generated
View File

@@ -5191,6 +5191,7 @@ const RAW_RUNTIME_STATE =
["inversify-express-utils", "npm:6.4.3"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.5.0"],\
["jsonwebtoken", "npm:9.0.0"],\
["mongodb", "virtual:67ad3a1ca34e24ce4821cc48979e98af0c3e5dd7aabc7ad0b5d22d1d977d6f943f81c9f141a420105ebdc61ef777e508a96c7946081decd98f8c30543d468b33#npm:5.7.0"],\
["mysql2", "npm:3.3.3"],\
["newrelic", "npm:10.1.2"],\
["nodemon", "npm:2.0.22"],\
@@ -5201,7 +5202,7 @@ const RAW_RUNTIME_STATE =
["semver", "npm:7.5.1"],\
["sqlite3", "virtual:31b5a94a105c89c9294c3d524a7f8929fe63ee5a2efadf21951ca4c0cfd2ecf02e8f4ef5a066bbda091f1e3a56e57c6749069a080618c96b22e51131a330fc4a#npm:5.1.6"],\
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.0"],\
["typeorm", "virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:0.3.16"],\
["typeorm", "virtual:67ad3a1ca34e24ce4821cc48979e98af0c3e5dd7aabc7ad0b5d22d1d977d6f943f81c9f141a420105ebdc61ef777e508a96c7946081decd98f8c30543d468b33#npm:0.3.16"],\
["typescript", "patch:typescript@npm%3A5.0.4#optional!builtin<compat/typescript>::version=5.0.4&hash=b5f058"],\
["ua-parser-js", "npm:1.0.35"],\
["uuid", "npm:9.0.0"],\
@@ -5869,6 +5870,26 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["@types/webidl-conversions", [\
["npm:7.0.0", {\
"packageLocation": "./.yarn/cache/@types-webidl-conversions-npm-7.0.0-0903313151-86c337dc1e.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-25f20f5649.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-f7811cc0b9.zip/node_modules/@types/yargs/",\
@@ -7074,6 +7095,15 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["bson", [\
["npm:5.4.0", {\
"packageLocation": "./.yarn/cache/bson-npm-5.4.0-2f854c8216-2c913a45c0.zip/node_modules/bson/",\
"packageDependencies": [\
["bson", "npm:5.4.0"]\
],\
"linkType": "HARD"\
}]\
]],\
["buffer", [\
["npm:5.7.1", {\
"packageLocation": "./.yarn/cache/buffer-npm-5.7.1-513ef8259e-8e611bed4d.zip/node_modules/buffer/",\
@@ -11932,6 +11962,15 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["memory-pager", [\
["npm:1.5.0", {\
"packageLocation": "./.yarn/cache/memory-pager-npm-1.5.0-46e20e6c81-6b00ff499b.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-e36c879078.zip/node_modules/meow/",\
@@ -12290,6 +12329,59 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["mongodb", [\
["npm:5.7.0", {\
"packageLocation": "./.yarn/cache/mongodb-npm-5.7.0-c5e415a2e7-23a291ffe7.zip/node_modules/mongodb/",\
"packageDependencies": [\
["mongodb", "npm:5.7.0"]\
],\
"linkType": "SOFT"\
}],\
["virtual:67ad3a1ca34e24ce4821cc48979e98af0c3e5dd7aabc7ad0b5d22d1d977d6f943f81c9f141a420105ebdc61ef777e508a96c7946081decd98f8c30543d468b33#npm:5.7.0", {\
"packageLocation": "./.yarn/__virtual__/mongodb-virtual-eb0cd47e23/0/cache/mongodb-npm-5.7.0-c5e415a2e7-23a291ffe7.zip/node_modules/mongodb/",\
"packageDependencies": [\
["mongodb", "virtual:67ad3a1ca34e24ce4821cc48979e98af0c3e5dd7aabc7ad0b5d22d1d977d6f943f81c9f141a420105ebdc61ef777e508a96c7946081decd98f8c30543d468b33#npm:5.7.0"],\
["@aws-sdk/credential-providers", null],\
["@mongodb-js/zstd", null],\
["@types/aws-sdk__credential-providers", null],\
["@types/kerberos", null],\
["@types/mongodb-client-encryption", null],\
["@types/mongodb-js__zstd", null],\
["@types/snappy", null],\
["bson", "npm:5.4.0"],\
["kerberos", null],\
["mongodb-client-encryption", null],\
["mongodb-connection-string-url", "npm:2.6.0"],\
["saslprep", "npm:1.0.3"],\
["snappy", null],\
["socks", "npm:2.7.1"]\
],\
"packagePeers": [\
"@aws-sdk/credential-providers",\
"@mongodb-js/zstd",\
"@types/aws-sdk__credential-providers",\
"@types/kerberos",\
"@types/mongodb-client-encryption",\
"@types/mongodb-js__zstd",\
"@types/snappy",\
"kerberos",\
"mongodb-client-encryption",\
"snappy"\
],\
"linkType": "HARD"\
}]\
]],\
["mongodb-connection-string-url", [\
["npm:2.6.0", {\
"packageLocation": "./.yarn/cache/mongodb-connection-string-url-npm-2.6.0-af011ba17f-8a9186dd1b.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-de027828fc.zip/node_modules/ms/",\
@@ -14249,6 +14341,16 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["saslprep", [\
["npm:1.0.3", {\
"packageLocation": "./.yarn/cache/saslprep-npm-1.0.3-8db649c346-23ebcda091.zip/node_modules/saslprep/",\
"packageDependencies": [\
["saslprep", "npm:1.0.3"],\
["sparse-bitfield", "npm:3.0.3"]\
],\
"linkType": "HARD"\
}]\
]],\
["schema-utils", [\
["npm:3.1.2", {\
"packageLocation": "./.yarn/cache/schema-utils-npm-3.1.2-d97c6dc247-11d35f997e.zip/node_modules/schema-utils/",\
@@ -14604,6 +14706,16 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["sparse-bitfield", [\
["npm:3.0.3", {\
"packageLocation": "./.yarn/cache/sparse-bitfield-npm-3.0.3-cb80d0c89f-625ecdf6f4.zip/node_modules/sparse-bitfield/",\
"packageDependencies": [\
["sparse-bitfield", "npm:3.0.3"],\
["memory-pager", "npm:1.5.0"]\
],\
"linkType": "HARD"\
}]\
]],\
["spawn-please", [\
["npm:2.0.1", {\
"packageLocation": "./.yarn/cache/spawn-please-npm-2.0.1-265b6b5432-fe19a7ceb5.zip/node_modules/spawn-please/",\
@@ -15246,6 +15358,14 @@ const RAW_RUNTIME_STATE =
["tr46", "npm:0.0.3"]\
],\
"linkType": "HARD"\
}],\
["npm:3.0.0", {\
"packageLocation": "./.yarn/cache/tr46-npm-3.0.0-e1ae1ea7c9-3a481676bf.zip/node_modules/tr46/",\
"packageDependencies": [\
["tr46", "npm:3.0.0"],\
["punycode", "npm:2.3.0"]\
],\
"linkType": "HARD"\
}]\
]],\
["treeverse", [\
@@ -15757,6 +15877,98 @@ const RAW_RUNTIME_STATE =
],\
"linkType": "HARD"\
}],\
["virtual:67ad3a1ca34e24ce4821cc48979e98af0c3e5dd7aabc7ad0b5d22d1d977d6f943f81c9f141a420105ebdc61ef777e508a96c7946081decd98f8c30543d468b33#npm:0.3.16", {\
"packageLocation": "./.yarn/__virtual__/typeorm-virtual-13b6364fde/0/cache/typeorm-npm-0.3.16-5ac12a7afc-19803f935e.zip/node_modules/typeorm/",\
"packageDependencies": [\
["typeorm", "virtual:67ad3a1ca34e24ce4821cc48979e98af0c3e5dd7aabc7ad0b5d22d1d977d6f943f81c9f141a420105ebdc61ef777e508a96c7946081decd98f8c30543d468b33#npm:0.3.16"],\
["@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", null],\
["@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", null],\
["mkdirp", "npm:2.1.6"],\
["mongodb", "virtual:67ad3a1ca34e24ce4821cc48979e98af0c3e5dd7aabc7ad0b5d22d1d977d6f943f81c9f141a420105ebdc61ef777e508a96c7946081decd98f8c30543d468b33#npm:5.7.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.16", {\
"packageLocation": "./.yarn/__virtual__/typeorm-virtual-fc9b7b780b/0/cache/typeorm-npm-0.3.16-5ac12a7afc-19803f935e.zip/node_modules/typeorm/",\
"packageDependencies": [\
@@ -16191,6 +16403,13 @@ 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-bdbe11c68c.zip/node_modules/webidl-conversions/",\
"packageDependencies": [\
["webidl-conversions", "npm:7.0.0"]\
],\
"linkType": "HARD"\
}]\
]],\
["webpack", [\
@@ -16249,6 +16468,15 @@ const RAW_RUNTIME_STATE =
}]\
]],\
["whatwg-url", [\
["npm:11.0.0", {\
"packageLocation": "./.yarn/cache/whatwg-url-npm-11.0.0-073529d93a-ee3a532bfb.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-bd0cc6b75b.zip/node_modules/whatwg-url/",\
"packageDependencies": [\

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -23,6 +23,7 @@ services:
environment:
DB_TYPE: "${DB_TYPE}"
CACHE_TYPE: "${CACHE_TYPE}"
SECONDARY_DB_ENABLED: "${SECONDARY_DB_ENABLED}"
container_name: server-ci
ports:
- 3123:3000
@@ -61,6 +62,21 @@ services:
networks:
- standardnotes_self_hosted
secondary_db:
image: mongo:5.0
container_name: secondary_db-ci
expose:
- 27017
restart: unless-stopped
volumes:
- ./data/mongo:/data/db
environment:
MONGO_INITDB_ROOT_USERNAME: standardnotes
MONGO_INITDB_ROOT_PASSWORD: standardnotes
MONGO_INITDB_DATABASE: standardnotes
networks:
- standardnotes_self_hosted
cache:
image: redis:6.0-alpine
container_name: cache-ci

View File

@@ -63,6 +63,9 @@ 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"
#########

View File

@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.25.13](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.12...@standardnotes/analytics@2.25.13) (2023-08-11)
**Note:** Version bump only for package @standardnotes/analytics
## [2.25.12](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.11...@standardnotes/analytics@2.25.12) (2023-08-09)
**Note:** Version bump only for package @standardnotes/analytics
## [2.25.11](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.10...@standardnotes/analytics@2.25.11) (2023-08-09)
**Note:** Version bump only for package @standardnotes/analytics
## [2.25.10](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.9...@standardnotes/analytics@2.25.10) (2023-08-09)
**Note:** Version bump only for package @standardnotes/analytics

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/analytics",
"version": "2.25.10",
"version": "2.25.13",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.70.4](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.70.3...@standardnotes/api-gateway@1.70.4) (2023-08-09)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.70.3](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.70.2...@standardnotes/api-gateway@1.70.3) (2023-08-09)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.70.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.70.1...@standardnotes/api-gateway@1.70.2) (2023-08-09)
**Note:** Version bump only for package @standardnotes/api-gateway

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/api-gateway",
"version": "1.70.2",
"version": "1.70.4",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -3,6 +3,24 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.131.5](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.131.4...@standardnotes/auth-server@1.131.5) (2023-08-15)
### Bug Fixes
* **auth:** passing the invalidate cache header ([#697](https://github.com/standardnotes/server/issues/697)) ([83ad069](https://github.com/standardnotes/server/commit/83ad069c5dd9afa3a6db881f0d8a55a58d0642aa))
## [1.131.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.131.3...@standardnotes/auth-server@1.131.4) (2023-08-11)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.131.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.131.2...@standardnotes/auth-server@1.131.3) (2023-08-09)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.131.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.131.1...@standardnotes/auth-server@1.131.2) (2023-08-09)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.131.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.131.0...@standardnotes/auth-server@1.131.1) (2023-08-09)
**Note:** Version bump only for package @standardnotes/auth-server

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/auth-server",
"version": "1.131.1",
"version": "1.131.5",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -285,6 +285,10 @@ export class BaseAuthController extends BaseHttpController {
authorizationHeader: <string>request.headers.authorization,
})
if (result.headers?.has('x-invalidate-cache')) {
response.setHeader('x-invalidate-cache', result.headers.get('x-invalidate-cache') as string)
}
return this.json(result.data, result.status)
}

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.50.1](https://github.com/standardnotes/server/compare/@standardnotes/common@1.50.0...@standardnotes/common@1.50.1) (2023-08-11)
**Note:** Version bump only for package @standardnotes/common
# [1.50.0](https://github.com/standardnotes/server/compare/@standardnotes/common@1.49.0...@standardnotes/common@1.50.0) (2023-07-12)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/common",
"version": "1.50.0",
"version": "1.50.1",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -1 +0,0 @@
export type ApplicationIdentifier = string

View File

@@ -5,43 +5,12 @@ export enum ProtocolVersion {
V004 = '004',
}
export const ProtocolVersionLatest = ProtocolVersion.V004
/** The last protocol version to not use root-key based items keys */
export const ProtocolVersionLastNonrootItemsKey = ProtocolVersion.V003
export const ProtocolExpirationDates: Partial<Record<ProtocolVersion, number>> = Object.freeze({
[ProtocolVersion.V001]: Date.parse('2018-01-01'),
[ProtocolVersion.V002]: Date.parse('2020-01-01'),
})
export function isProtocolVersionExpired(version: ProtocolVersion) {
const expireDate = ProtocolExpirationDates[version]
if (!expireDate) {
return false
}
const expired = new Date().getTime() > expireDate
return expired
}
export const ProtocolVersionLength = 3
export function protocolVersionFromEncryptedString(string: string): ProtocolVersion {
const version = string.substring(0, ProtocolVersionLength) as ProtocolVersion
if (Object.values(ProtocolVersion).includes(version)) {
return version
}
throw Error(`Unrecognized protocol version ${version}`)
}
/**
* -1 if a < b
* 0 if a == b
* 1 if a > b
*/
export function compareVersions(a: ProtocolVersion, b: ProtocolVersion): number {
function compareVersions(a: ProtocolVersion, b: ProtocolVersion): number {
const aNum = Number(a)
const bNum = Number(b)
return aNum - bNum
@@ -50,7 +19,3 @@ export function compareVersions(a: ProtocolVersion, b: ProtocolVersion): number
export function leftVersionGreaterThanOrEqualToRight(a: ProtocolVersion, b: ProtocolVersion): boolean {
return compareVersions(a, b) >= 0
}
export function isVersionLessThanOrEqualTo(input: ProtocolVersion, compareTo: ProtocolVersion): boolean {
return compareVersions(input, compareTo) <= 0
}

View File

@@ -3,7 +3,6 @@ export * from './Content/ContentDecoderInterface'
export * from './DataType/AnyRecord'
export * from './DataType/JSONString'
export * from './DataType/MicrosecondsTimestamp'
export * from './DataType/ApplicationIdentifier'
export * from './Email/EmailMessageIdentifier'
export * from './KeyParams/AnyKeyParamsContent'
export * from './KeyParams/BaseKeyParams'

View File

@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.25.2](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.25.1...@standardnotes/domain-core@1.25.2) (2023-08-09)
### Reverts
* Revert "Revert "feat(syncing-server): notify shared vault users upon file uploads or removals (#692)"" ([1c3ff52](https://github.com/standardnotes/server/commit/1c3ff526b7c4885f71f019f6c01142f522a6f8ad)), closes [#692](https://github.com/standardnotes/server/issues/692)
## [1.25.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.25.0...@standardnotes/domain-core@1.25.1) (2023-08-09)
### Reverts
* Revert "feat(syncing-server): notify shared vault users upon file uploads or removals (#692)" ([d261c81](https://github.com/standardnotes/server/commit/d261c81cd0bdbb9001c8589224f007ed2d338903)), closes [#692](https://github.com/standardnotes/server/issues/692)
# [1.25.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.24.2...@standardnotes/domain-core@1.25.0) (2023-08-09)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/domain-core",
"version": "1.25.0",
"version": "1.25.2",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.11.19](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.11.18...@standardnotes/event-store@1.11.19) (2023-08-09)
**Note:** Version bump only for package @standardnotes/event-store
## [1.11.18](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.11.17...@standardnotes/event-store@1.11.18) (2023-08-09)
**Note:** Version bump only for package @standardnotes/event-store
## [1.11.17](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.11.16...@standardnotes/event-store@1.11.17) (2023-08-09)
**Note:** Version bump only for package @standardnotes/event-store

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/event-store",
"version": "1.11.17",
"version": "1.11.19",
"description": "Event Store Service",
"private": true,
"main": "dist/src/index.js",

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.20.3](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.20.2...@standardnotes/files-server@1.20.3) (2023-08-09)
**Note:** Version bump only for package @standardnotes/files-server
## [1.20.2](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.20.1...@standardnotes/files-server@1.20.2) (2023-08-09)
**Note:** Version bump only for package @standardnotes/files-server
## [1.20.1](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.20.0...@standardnotes/files-server@1.20.1) (2023-08-09)
**Note:** Version bump only for package @standardnotes/files-server

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/files-server",
"version": "1.20.1",
"version": "1.20.3",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -9,3 +9,10 @@ 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

View File

@@ -3,6 +3,64 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.13.51](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.50...@standardnotes/home-server@1.13.51) (2023-08-17)
### Bug Fixes
* **home-server:** add default env values for secondary database ([916e989](https://github.com/standardnotes/server/commit/916e98936a276a3960d949c5b70803214c945686))
## [1.13.50](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.49...@standardnotes/home-server@1.13.50) (2023-08-16)
**Note:** Version bump only for package @standardnotes/home-server
## [1.13.49](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.48...@standardnotes/home-server@1.13.49) (2023-08-15)
**Note:** Version bump only for package @standardnotes/home-server
## [1.13.48](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.47...@standardnotes/home-server@1.13.48) (2023-08-11)
**Note:** Version bump only for package @standardnotes/home-server
## [1.13.47](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.46...@standardnotes/home-server@1.13.47) (2023-08-11)
**Note:** Version bump only for package @standardnotes/home-server
## [1.13.46](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.45...@standardnotes/home-server@1.13.46) (2023-08-11)
**Note:** Version bump only for package @standardnotes/home-server
## [1.13.45](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.44...@standardnotes/home-server@1.13.45) (2023-08-11)
**Note:** Version bump only for package @standardnotes/home-server
## [1.13.44](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.43...@standardnotes/home-server@1.13.44) (2023-08-11)
**Note:** Version bump only for package @standardnotes/home-server
## [1.13.43](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.42...@standardnotes/home-server@1.13.43) (2023-08-10)
**Note:** Version bump only for package @standardnotes/home-server
## [1.13.42](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.41...@standardnotes/home-server@1.13.42) (2023-08-09)
**Note:** Version bump only for package @standardnotes/home-server
## [1.13.41](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.40...@standardnotes/home-server@1.13.41) (2023-08-09)
**Note:** Version bump only for package @standardnotes/home-server
## [1.13.40](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.39...@standardnotes/home-server@1.13.40) (2023-08-09)
**Note:** Version bump only for package @standardnotes/home-server
## [1.13.39](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.38...@standardnotes/home-server@1.13.39) (2023-08-09)
**Note:** Version bump only for package @standardnotes/home-server
## [1.13.38](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.37...@standardnotes/home-server@1.13.38) (2023-08-09)
**Note:** Version bump only for package @standardnotes/home-server
## [1.13.37](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.36...@standardnotes/home-server@1.13.37) (2023-08-09)
**Note:** Version bump only for package @standardnotes/home-server

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/home-server",
"version": "1.13.37",
"version": "1.13.51",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.26.7](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.26.6...@standardnotes/revisions-server@1.26.7) (2023-08-11)
**Note:** Version bump only for package @standardnotes/revisions-server
## [1.26.6](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.26.5...@standardnotes/revisions-server@1.26.6) (2023-08-09)
**Note:** Version bump only for package @standardnotes/revisions-server
## [1.26.5](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.26.4...@standardnotes/revisions-server@1.26.5) (2023-08-09)
**Note:** Version bump only for package @standardnotes/revisions-server
## [1.26.4](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.26.3...@standardnotes/revisions-server@1.26.4) (2023-08-09)
**Note:** Version bump only for package @standardnotes/revisions-server

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/revisions-server",
"version": "1.26.4",
"version": "1.26.7",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -3,6 +3,20 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.20.22](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.20.21...@standardnotes/scheduler-server@1.20.22) (2023-08-11)
### Bug Fixes
* **scheduler:** adjust email backups encouraging email schedule ([#695](https://github.com/standardnotes/server/issues/695)) ([091e2a5](https://github.com/standardnotes/server/commit/091e2a57e81bb335286807bba4b0fcfc04a086bb))
## [1.20.21](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.20.20...@standardnotes/scheduler-server@1.20.21) (2023-08-09)
**Note:** Version bump only for package @standardnotes/scheduler-server
## [1.20.20](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.20.19...@standardnotes/scheduler-server@1.20.20) (2023-08-09)
**Note:** Version bump only for package @standardnotes/scheduler-server
## [1.20.19](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.20.18...@standardnotes/scheduler-server@1.20.19) (2023-08-09)
**Note:** Version bump only for package @standardnotes/scheduler-server

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/scheduler-server",
"version": "1.20.19",
"version": "1.20.22",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -33,7 +33,7 @@ export class UserRegisteredEventHandler implements DomainEventHandlerInterface {
private async scheduleEncourageEmailBackupsJob(event: UserRegisteredEvent): Promise<void> {
const job = new Job()
job.name = JobName.ENCOURAGE_EMAIL_BACKUPS
job.scheduledAt = this.timer.convertDateToMicroseconds(this.timer.getUTCDateNDaysAhead(7))
job.scheduledAt = this.timer.convertDateToMicroseconds(this.timer.getUTCDateNDaysAhead(2))
job.createdAt = this.timer.getTimestampInMicroseconds()
job.status = JobStatus.Pending
job.userIdentifier = event.payload.email

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.21.24](https://github.com/standardnotes/server/compare/@standardnotes/settings@1.21.23...@standardnotes/settings@1.21.24) (2023-08-09)
**Note:** Version bump only for package @standardnotes/settings
## [1.21.23](https://github.com/standardnotes/server/compare/@standardnotes/settings@1.21.22...@standardnotes/settings@1.21.23) (2023-08-09)
**Note:** Version bump only for package @standardnotes/settings
## [1.21.22](https://github.com/standardnotes/server/compare/@standardnotes/settings@1.21.21...@standardnotes/settings@1.21.22) (2023-08-09)
**Note:** Version bump only for package @standardnotes/settings

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/settings",
"version": "1.21.22",
"version": "1.21.24",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -52,3 +52,11 @@ 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=

View File

@@ -3,6 +3,81 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.79.1](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.79.0...@standardnotes/syncing-server@1.79.1) (2023-08-17)
### Bug Fixes
* **syncing-server:** refactor shared vault and key system associations ([#698](https://github.com/standardnotes/syncing-server-js/issues/698)) ([31d1eef](https://github.com/standardnotes/syncing-server-js/commit/31d1eef7f74310b176085311fc04c2efc4a7059f))
# [1.79.0](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.78.11...@standardnotes/syncing-server@1.79.0) (2023-08-16)
### Features
* add mongodb initial support ([#696](https://github.com/standardnotes/syncing-server-js/issues/696)) ([b24b576](https://github.com/standardnotes/syncing-server-js/commit/b24b5762093c0f48a28dfb879339c1b9927c9333))
## [1.78.11](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.78.10...@standardnotes/syncing-server@1.78.11) (2023-08-11)
### Reverts
* Revert "tmp: disable shared vaults" ([d02124f](https://github.com/standardnotes/syncing-server-js/commit/d02124f4e505e4f7e7510637c461fdd0552c381a))
* Revert "tmp: disable decorating with associations on revisions" ([ad4b85b](https://github.com/standardnotes/syncing-server-js/commit/ad4b85b095a8539955f7b47d51643121d33eed6a))
* Revert "tmp: disable decorating items completely" ([0bf7d8b](https://github.com/standardnotes/syncing-server-js/commit/0bf7d8beae2de1b86d95711a4e15e84b8bf5e9c0))
## [1.78.10](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.78.9...@standardnotes/syncing-server@1.78.10) (2023-08-11)
**Note:** Version bump only for package @standardnotes/syncing-server
## [1.78.9](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.78.8...@standardnotes/syncing-server@1.78.9) (2023-08-11)
**Note:** Version bump only for package @standardnotes/syncing-server
## [1.78.8](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.78.7...@standardnotes/syncing-server@1.78.8) (2023-08-11)
**Note:** Version bump only for package @standardnotes/syncing-server
## [1.78.7](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.78.6...@standardnotes/syncing-server@1.78.7) (2023-08-11)
**Note:** Version bump only for package @standardnotes/syncing-server
## [1.78.6](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.78.5...@standardnotes/syncing-server@1.78.6) (2023-08-10)
### Bug Fixes
* **syncing-server:** setting user uuid in notifications ([56f4975](https://github.com/standardnotes/syncing-server-js/commit/56f49752b43fa1d3dff4f1e3a8f07cd7739516a9))
## [1.78.5](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.78.4...@standardnotes/syncing-server@1.78.5) (2023-08-09)
### Reverts
* Revert "tmp: disable fetching shared vault items" ([0eb86c0](https://github.com/standardnotes/syncing-server-js/commit/0eb86c009678a468bf9a7d0079dac58eff48f4d7))
* Revert "Revert "feat(syncing-server): notify shared vault users upon file uploads or removals (#692)"" ([1c3ff52](https://github.com/standardnotes/syncing-server-js/commit/1c3ff526b7c4885f71f019f6c01142f522a6f8ad)), closes [#692](https://github.com/standardnotes/syncing-server-js/issues/692)
## [1.78.4](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.78.3...@standardnotes/syncing-server@1.78.4) (2023-08-09)
### Bug Fixes
* **syncing-server:** casting handlers ([d7965b2](https://github.com/standardnotes/syncing-server-js/commit/d7965b2748ad59b1bff0cd6c0bf691303d9a6a76))
### Reverts
* Revert "Revert "fix(syncing-server): update storage quota used in a shared vault (#691)"" ([cbcd2ec](https://github.com/standardnotes/syncing-server-js/commit/cbcd2ec87ac5b94e06608da0426d7c27e5e56146)), closes [#691](https://github.com/standardnotes/syncing-server-js/issues/691)
## [1.78.3](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.78.2...@standardnotes/syncing-server@1.78.3) (2023-08-09)
### Reverts
* Revert "fix(syncing-server): update storage quota used in a shared vault (#691)" ([66f9352](https://github.com/standardnotes/syncing-server-js/commit/66f9352a062f45b5c66e7aae9681a56ca3ec6084)), closes [#691](https://github.com/standardnotes/syncing-server-js/issues/691)
## [1.78.2](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.78.1...@standardnotes/syncing-server@1.78.2) (2023-08-09)
### Reverts
* Revert "feat(syncing-server): notify shared vault users upon file uploads or removals (#692)" ([d261c81](https://github.com/standardnotes/syncing-server-js/commit/d261c81cd0bdbb9001c8589224f007ed2d338903)), closes [#692](https://github.com/standardnotes/syncing-server-js/issues/692)
## [1.78.1](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.78.0...@standardnotes/syncing-server@1.78.1) (2023-08-09)
**Note:** Version bump only for package @standardnotes/syncing-server
# [1.78.0](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.77.2...@standardnotes/syncing-server@1.78.0) (2023-08-09)
### Features

View File

@@ -0,0 +1,22 @@
import { MigrationInterface, QueryRunner } from 'typeorm'
export class RemoveRevisionsForeignKey1692176803410 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
const revisionsTableExistsQueryResult = await queryRunner.manager.query(
'SELECT COUNT(*) as count FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = "revisions"',
)
const revisionsTableExists = revisionsTableExistsQueryResult[0].count === 1
if (revisionsTableExists) {
try {
await queryRunner.query('ALTER TABLE `revisions` DROP FOREIGN KEY `FK_ab3b92e54701fe3010022a31d90`')
} catch (error) {
// eslint-disable-next-line no-console
console.log('Error dropping foreign key: ', (error as Error).message)
}
}
}
public async down(): Promise<void> {
return
}
}

View File

@@ -0,0 +1,21 @@
import { MigrationInterface, QueryRunner } from 'typeorm'
export class RemoveAssociations1692264556858 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
'DROP INDEX `key_system_identifier_on_key_system_associations` ON `key_system_associations`',
)
await queryRunner.query('DROP INDEX `item_uuid_on_key_system_associations` ON `key_system_associations`')
await queryRunner.query('DROP TABLE `key_system_associations`')
await queryRunner.query('DROP INDEX `item_uuid_on_shared_vault_associations` ON `shared_vault_associations`')
await queryRunner.query(
'DROP INDEX `shared_vault_uuid_on_shared_vault_associations` ON `shared_vault_associations`',
)
await queryRunner.query('DROP TABLE `shared_vault_associations`')
}
public async down(): Promise<void> {
return
}
}

View File

@@ -0,0 +1,17 @@
import { MigrationInterface, QueryRunner } from 'typeorm'
export class RemoveAssociations1692264735730 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query('DROP INDEX "key_system_identifier_on_key_system_associations"')
await queryRunner.query('DROP INDEX "item_uuid_on_key_system_associations"')
await queryRunner.query('DROP TABLE "key_system_associations"')
await queryRunner.query('DROP INDEX "item_uuid_on_shared_vault_associations"')
await queryRunner.query('DROP INDEX "shared_vault_uuid_on_shared_vault_associations"')
await queryRunner.query('DROP TABLE "shared_vault_associations"')
}
public async down(): Promise<void> {
return
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/syncing-server",
"version": "1.78.0",
"version": "1.79.1",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
@@ -49,6 +49,7 @@
"inversify": "^6.0.1",
"inversify-express-utils": "^6.4.3",
"jsonwebtoken": "^9.0.0",
"mongodb": "^5.7.0",
"mysql2": "^3.0.1",
"nodemon": "^2.0.19",
"prettyjson": "^1.2.5",

View File

@@ -7,7 +7,7 @@ import { AppDataSource } from './DataSource'
import { SNSClient, SNSClientConfig } from '@aws-sdk/client-sns'
import { ItemRepositoryInterface } from '../Domain/Item/ItemRepositoryInterface'
import { TypeORMItemRepository } from '../Infra/TypeORM/TypeORMItemRepository'
import { Repository } from 'typeorm'
import { MongoRepository, Repository } from 'typeorm'
import { Item } from '../Domain/Item/Item'
import {
DirectCallDomainEventPublisher,
@@ -79,15 +79,7 @@ import { ItemHashHttpMapper } from '../Mapping/Http/ItemHashHttpMapper'
import { ItemHash } from '../Domain/Item/ItemHash'
import { ItemHashHttpRepresentation } from '../Mapping/Http/ItemHashHttpRepresentation'
import { TypeORMKeySystemAssociation } from '../Infra/TypeORM/TypeORMKeySystemAssociation'
import { SharedVaultAssociation } from '../Domain/SharedVault/SharedVaultAssociation'
import { TypeORMSharedVaultAssociation } from '../Infra/TypeORM/TypeORMSharedVaultAssociation'
import { SharedVaultAssociationPersistenceMapper } from '../Mapping/Persistence/SharedVaultAssociationPersistenceMapper'
import { TypeORMKeySystemAssociationRepository } from '../Infra/TypeORM/TypeORMKeySystemAssociationRepository'
import { SharedVaultAssociationRepositoryInterface } from '../Domain/SharedVault/SharedVaultAssociationRepositoryInterface'
import { TypeORMSharedVaultAssociationRepository } from '../Infra/TypeORM/TypeORMSharedVaultAssociationRepository'
import { KeySystemAssociation } from '../Domain/KeySystem/KeySystemAssociation'
import { KeySystemAssociationRepositoryInterface } from '../Domain/KeySystem/KeySystemAssociationRepositoryInterface'
import { KeySystemAssociationPersistenceMapper } from '../Mapping/Persistence/KeySystemAssociationPersistenceMapper'
import { BaseSharedVaultInvitesController } from '../Infra/InversifyExpressUtils/Base/BaseSharedVaultInvitesController'
import { InviteUserToSharedVault } from '../Domain/UseCase/SharedVaults/InviteUserToSharedVault/InviteUserToSharedVault'
import { TypeORMSharedVaultRepository } from '../Infra/TypeORM/TypeORMSharedVaultRepository'
@@ -158,6 +150,9 @@ 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'
export class ContainerConfigLoader {
private readonly DEFAULT_CONTENT_SIZE_TRANSFER_LIMIT = 10_000_000
@@ -210,6 +205,7 @@ export class ContainerConfigLoader {
container.bind<TimerInterface>(TYPES.Sync_Timer).toConstantValue(new Timer())
const isConfiguredForHomeServer = env.get('MODE', true) === 'home-server'
const isSecondaryDatabaseEnabled = env.get('SECONDARY_DB_ENABLED', true) === 'true'
container.bind<Env>(TYPES.Sync_Env).toConstantValue(env)
@@ -312,16 +308,6 @@ export class ContainerConfigLoader {
container
.bind<MapperInterface<Item, ItemBackupRepresentation>>(TYPES.Sync_ItemBackupMapper)
.toConstantValue(new ItemBackupMapper(container.get(TYPES.Sync_Timer)))
container
.bind<MapperInterface<KeySystemAssociation, TypeORMKeySystemAssociation>>(
TYPES.Sync_KeySystemAssociationPersistenceMapper,
)
.toConstantValue(new KeySystemAssociationPersistenceMapper())
container
.bind<MapperInterface<SharedVaultAssociation, TypeORMSharedVaultAssociation>>(
TYPES.Sync_SharedVaultAssociationPersistenceMapper,
)
.toConstantValue(new SharedVaultAssociationPersistenceMapper())
container
.bind<MapperInterface<SharedVault, TypeORMSharedVault>>(TYPES.Sync_SharedVaultPersistenceMapper)
.toConstantValue(new SharedVaultPersistenceMapper())
@@ -381,33 +367,32 @@ export class ContainerConfigLoader {
.bind<Repository<TypeORMMessage>>(TYPES.Sync_ORMMessageRepository)
.toConstantValue(appDataSource.getRepository(TypeORMMessage))
// Mongo
if (isSecondaryDatabaseEnabled) {
container
.bind<MapperInterface<Item, MongoDBItem>>(TYPES.Sync_MongoDBItemPersistenceMapper)
.toConstantValue(new MongoDBItemPersistenceMapper())
container
.bind<MongoRepository<MongoDBItem>>(TYPES.Sync_MongoItemRepository)
.toConstantValue(appDataSource.getMongoRepository(MongoDBItem))
}
// Repositories
container
.bind<KeySystemAssociationRepositoryInterface>(TYPES.Sync_KeySystemAssociationRepository)
.toConstantValue(
new TypeORMKeySystemAssociationRepository(
container.get(TYPES.Sync_ORMKeySystemAssociationRepository),
container.get(TYPES.Sync_KeySystemAssociationPersistenceMapper),
),
)
container
.bind<SharedVaultAssociationRepositoryInterface>(TYPES.Sync_SharedVaultAssociationRepository)
.toConstantValue(
new TypeORMSharedVaultAssociationRepository(
container.get(TYPES.Sync_ORMSharedVaultAssociationRepository),
container.get(TYPES.Sync_SharedVaultAssociationPersistenceMapper),
),
)
container
.bind<ItemRepositoryInterface>(TYPES.Sync_ItemRepository)
.toConstantValue(
new TypeORMItemRepository(
container.get(TYPES.Sync_ORMItemRepository),
container.get(TYPES.Sync_ItemPersistenceMapper),
container.get(TYPES.Sync_KeySystemAssociationRepository),
container.get(TYPES.Sync_SharedVaultAssociationRepository),
container.get(TYPES.Sync_Logger),
),
isSecondaryDatabaseEnabled
? new MongoDBItemRepository(
container.get(TYPES.Sync_MongoItemRepository),
container.get(TYPES.Sync_MongoDBItemPersistenceMapper),
container.get(TYPES.Sync_Logger),
)
: new TypeORMItemRepository(
container.get(TYPES.Sync_ORMItemRepository),
container.get(TYPES.Sync_ItemPersistenceMapper),
container.get(TYPES.Sync_Logger),
),
)
container
.bind<SharedVaultRepositoryInterface>(TYPES.Sync_SharedVaultRepository)
@@ -567,8 +552,8 @@ export class ContainerConfigLoader {
.bind<AddNotificationsForUsers>(TYPES.Sync_AddNotificationsForUsers)
.toConstantValue(
new AddNotificationsForUsers(
container.get(TYPES.Sync_SharedVaultUserRepository),
container.get(TYPES.Sync_AddNotificationForUser),
container.get<SharedVaultUserRepositoryInterface>(TYPES.Sync_SharedVaultUserRepository),
container.get<AddNotificationForUser>(TYPES.Sync_AddNotificationForUser),
),
)
container
@@ -761,7 +746,11 @@ export class ContainerConfigLoader {
)
container
.bind<UpdateStorageQuotaUsedInSharedVault>(TYPES.Sync_UpdateStorageQuotaUsedInSharedVault)
.toConstantValue(new UpdateStorageQuotaUsedInSharedVault(container.get(TYPES.Sync_SharedVaultRepository)))
.toConstantValue(
new UpdateStorageQuotaUsedInSharedVault(
container.get<SharedVaultRepositoryInterface>(TYPES.Sync_SharedVaultRepository),
),
)
// Services
container
@@ -835,18 +824,18 @@ export class ContainerConfigLoader {
.bind<SharedVaultFileUploadedEventHandler>(TYPES.Sync_SharedVaultFileUploadedEventHandler)
.toConstantValue(
new SharedVaultFileUploadedEventHandler(
container.get(TYPES.Sync_UpdateStorageQuotaUsedInSharedVault),
container.get(TYPES.Sync_AddNotificationsForUsers),
container.get(TYPES.Sync_Logger),
container.get<UpdateStorageQuotaUsedInSharedVault>(TYPES.Sync_UpdateStorageQuotaUsedInSharedVault),
container.get<AddNotificationsForUsers>(TYPES.Sync_AddNotificationsForUsers),
container.get<winston.Logger>(TYPES.Sync_Logger),
),
)
container
.bind<SharedVaultFileRemovedEventHandler>(TYPES.Sync_SharedVaultFileRemovedEventHandler)
.toConstantValue(
new SharedVaultFileRemovedEventHandler(
container.get(TYPES.Sync_UpdateStorageQuotaUsedInSharedVault),
container.get(TYPES.Sync_AddNotificationsForUsers),
container.get(TYPES.Sync_Logger),
container.get<UpdateStorageQuotaUsedInSharedVault>(TYPES.Sync_UpdateStorageQuotaUsedInSharedVault),
container.get<AddNotificationsForUsers>(TYPES.Sync_AddNotificationsForUsers),
container.get<winston.Logger>(TYPES.Sync_Logger),
),
)
@@ -892,8 +881,14 @@ export class ContainerConfigLoader {
['DUPLICATE_ITEM_SYNCED', container.get(TYPES.Sync_DuplicateItemSyncedEventHandler)],
['ACCOUNT_DELETION_REQUESTED', container.get(TYPES.Sync_AccountDeletionRequestedEventHandler)],
['ITEM_REVISION_CREATION_REQUESTED', container.get(TYPES.Sync_ItemRevisionCreationRequestedEventHandler)],
['SHARED_VAULT_FILE_UPLOADED', container.get(TYPES.Sync_SharedVaultFileUploadedEventHandler)],
['SHARED_VAULT_FILE_REMOVED', container.get(TYPES.Sync_SharedVaultFileRemovedEventHandler)],
[
'SHARED_VAULT_FILE_UPLOADED',
container.get<SharedVaultFileUploadedEventHandler>(TYPES.Sync_SharedVaultFileUploadedEventHandler),
],
[
'SHARED_VAULT_FILE_REMOVED',
container.get<SharedVaultFileRemovedEventHandler>(TYPES.Sync_SharedVaultFileRemovedEventHandler),
],
])
if (!isConfiguredForHomeServer) {
container.bind(TYPES.Sync_AUTH_SERVER_URL).toConstantValue(env.get('AUTH_SERVER_URL'))

View File

@@ -1,4 +1,4 @@
import { DataSource, EntityTarget, LoggerOptions, ObjectLiteral, Repository } from 'typeorm'
import { DataSource, EntityTarget, LoggerOptions, MongoRepository, ObjectLiteral, Repository } from 'typeorm'
import { MysqlConnectionOptions } from 'typeorm/driver/mysql/MysqlConnectionOptions'
import { Env } from './Env'
import { SqliteConnectionOptions } from 'typeorm/driver/sqlite/SqliteConnectionOptions'
@@ -10,9 +10,11 @@ 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'
export class AppDataSource {
private _dataSource: DataSource | undefined
private _secondaryDataSource: DataSource | undefined
constructor(private env: Env) {}
@@ -24,8 +26,42 @@ export class AppDataSource {
return this._dataSource.getRepository(target)
}
getMongoRepository<Entity extends ObjectLiteral>(target: EntityTarget<Entity>): MongoRepository<Entity> {
if (!this._secondaryDataSource) {
throw new Error('Secondary DataSource not initialized')
}
return this._secondaryDataSource.getMongoRepository(target)
}
async initialize(): Promise<void> {
await this.dataSource.initialize()
const secondaryDataSource = this.secondaryDataSource
if (secondaryDataSource) {
await secondaryDataSource.initialize()
}
}
get secondaryDataSource(): DataSource | undefined {
this.env.load()
if (this.env.get('SECONDARY_DB_ENABLED', true) !== 'true') {
return undefined
}
this._secondaryDataSource = new DataSource({
type: 'mongodb',
host: this.env.get('MONGO_HOST'),
authSource: 'admin',
port: parseInt(this.env.get('MONGO_PORT')),
username: this.env.get('MONGO_USERNAME'),
password: this.env.get('MONGO_PASSWORD', true),
database: this.env.get('MONGO_DATABASE'),
entities: [MongoDBItem],
synchronize: true,
})
return this._secondaryDataSource
}
get dataSource(): DataSource {

View File

@@ -8,8 +8,6 @@ const TYPES = {
Sync_Env: Symbol.for('Sync_Env'),
// Repositories
Sync_ItemRepository: Symbol.for('Sync_ItemRepository'),
Sync_KeySystemAssociationRepository: Symbol.for('Sync_KeySystemAssociationRepository'),
Sync_SharedVaultAssociationRepository: Symbol.for('Sync_SharedVaultAssociationRepository'),
Sync_SharedVaultRepository: Symbol.for('Sync_SharedVaultRepository'),
Sync_SharedVaultInviteRepository: Symbol.for('Sync_SharedVaultInviteRepository'),
Sync_SharedVaultUserRepository: Symbol.for('Sync_SharedVaultUserRepository'),
@@ -24,6 +22,8 @@ const TYPES = {
Sync_ORMSharedVaultUserRepository: Symbol.for('Sync_ORMSharedVaultUserRepository'),
Sync_ORMNotificationRepository: Symbol.for('Sync_ORMNotificationRepository'),
Sync_ORMMessageRepository: Symbol.for('Sync_ORMMessageRepository'),
// Mongo
Sync_MongoItemRepository: Symbol.for('Sync_MongoItemRepository'),
// Middleware
Sync_AuthMiddleware: Symbol.for('Sync_AuthMiddleware'),
// env vars
@@ -124,13 +124,12 @@ const TYPES = {
Sync_MessageHttpMapper: Symbol.for('Sync_MessageHttpMapper'),
Sync_NotificationHttpMapper: Symbol.for('Sync_NotificationHttpMapper'),
Sync_ItemPersistenceMapper: Symbol.for('Sync_ItemPersistenceMapper'),
Sync_MongoDBItemPersistenceMapper: Symbol.for('Sync_MongoDBItemPersistenceMapper'),
Sync_ItemHttpMapper: Symbol.for('Sync_ItemHttpMapper'),
Sync_ItemHashHttpMapper: Symbol.for('Sync_ItemHashHttpMapper'),
Sync_SavedItemHttpMapper: Symbol.for('Sync_SavedItemHttpMapper'),
Sync_ItemConflictHttpMapper: Symbol.for('Sync_ItemConflictHttpMapper'),
Sync_ItemBackupMapper: Symbol.for('Sync_ItemBackupMapper'),
Sync_KeySystemAssociationPersistenceMapper: Symbol.for('Sync_KeySystemAssociationPersistenceMapper'),
Sync_SharedVaultAssociationPersistenceMapper: Symbol.for('Sync_SharedVaultAssociationPersistenceMapper'),
Sync_SharedVaultPersistenceMapper: Symbol.for('Sync_SharedVaultPersistenceMapper'),
Sync_SharedVaultUserPersistenceMapper: Symbol.for('Sync_SharedVaultUserPersistenceMapper'),
Sync_SharedVaultInvitePersistenceMapper: Symbol.for('Sync_SharedVaultInvitePersistenceMapper'),

View File

@@ -2,7 +2,7 @@ export const html = (email: string) => `
<p>
Your encrypted data backup is attached for ${email}. You can import this file using
the Standard Notes web or desktop app, or by using the offline decryption script available at
<a style="text-decoration:none !important; text-decoration:none;">standardnotes.org/offline</a>.
<a style="text-decoration:none !important; text-decoration:none;">standardnotes.com/offline</a>.
</p>
<p>

View File

@@ -61,10 +61,8 @@ describe('Item', () => {
dates: Dates.create(new Date(123), new Date(123)).getValue(),
timestamps: Timestamps.create(123, 123).getValue(),
sharedVaultAssociation: SharedVaultAssociation.create({
itemUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
sharedVaultUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
lastEditedBy: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
timestamps: Timestamps.create(123, 123).getValue(),
}).getValue(),
})
@@ -113,9 +111,7 @@ describe('Item', () => {
dates: Dates.create(new Date(123), new Date(123)).getValue(),
timestamps: Timestamps.create(123, 123).getValue(),
keySystemAssociation: KeySystemAssociation.create({
itemUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
keySystemIdentifier: 'key-system-identifier',
timestamps: Timestamps.create(123, 123).getValue(),
}).getValue(),
})
@@ -144,10 +140,8 @@ describe('Item', () => {
it('should set shared vault association', () => {
const sharedVaultAssociation = SharedVaultAssociation.create({
itemUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
sharedVaultUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
lastEditedBy: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
timestamps: Timestamps.create(123, 123).getValue(),
}).getValue()
const entity = Item.create({
@@ -184,10 +178,8 @@ describe('Item', () => {
dates: Dates.create(new Date(123), new Date(123)).getValue(),
timestamps: Timestamps.create(123, 123).getValue(),
sharedVaultAssociation: SharedVaultAssociation.create({
itemUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
sharedVaultUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
lastEditedBy: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
timestamps: Timestamps.create(123, 123).getValue(),
}).getValue(),
}).getValue()
@@ -199,9 +191,7 @@ describe('Item', () => {
it('should set key system association', () => {
const keySystemAssociation = KeySystemAssociation.create({
itemUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
keySystemIdentifier: 'key-system-identifier',
timestamps: Timestamps.create(123, 123).getValue(),
}).getValue()
const entity = Item.create({
@@ -238,9 +228,7 @@ describe('Item', () => {
dates: Dates.create(new Date(123), new Date(123)).getValue(),
timestamps: Timestamps.create(123, 123).getValue(),
keySystemAssociation: KeySystemAssociation.create({
itemUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
keySystemIdentifier: 'key-system-identifier',
timestamps: Timestamps.create(123, 123).getValue(),
}).getValue(),
}).getValue()

View File

@@ -10,7 +10,6 @@ export type ItemQuery = {
offset?: number
limit?: number
createdBetween?: Date[]
selectString?: string
includeSharedVaultUuids?: string[]
exclusiveSharedVaultUuids?: string[]
}

View File

@@ -1,5 +1,4 @@
import { Uuid } from '@standardnotes/domain-core'
import { ReadStream } from 'fs'
import { Item } from './Item'
import { ItemQuery } from './ItemQuery'
@@ -8,8 +7,6 @@ import { ExtendedIntegrityPayload } from './ExtendedIntegrityPayload'
export interface ItemRepositoryInterface {
deleteByUserUuid(userUuid: string): Promise<void>
findAll(query: ItemQuery): Promise<Item[]>
findAllRaw<T>(query: ItemQuery): Promise<T[]>
streamAll(query: ItemQuery): Promise<ReadStream>
countAll(query: ItemQuery): Promise<number>
findContentSizeForComputingTransferLimit(
query: ItemQuery,

View File

@@ -40,10 +40,8 @@ describe('SharedVaultFilter', () => {
dates: Dates.create(new Date(1616164633241311), new Date(1616164633241311)).getValue(),
timestamps: Timestamps.create(1616164633241311, 1616164633241311).getValue(),
sharedVaultAssociation: SharedVaultAssociation.create({
itemUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
lastEditedBy: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
sharedVaultUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
timestamps: Timestamps.create(123, 123).getValue(),
}).getValue(),
},
new UniqueEntityId('00000000-0000-0000-0000-000000000000'),
@@ -254,10 +252,8 @@ describe('SharedVaultFilter', () => {
dates: Dates.create(new Date(1616164633241311), new Date(1616164633241311)).getValue(),
timestamps: Timestamps.create(1616164633241311, 1616164633241311).getValue(),
sharedVaultAssociation: SharedVaultAssociation.create({
itemUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
lastEditedBy: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
sharedVaultUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
timestamps: Timestamps.create(123, 123).getValue(),
}).getValue(),
},
new UniqueEntityId('00000000-0000-0000-0000-000000000000'),
@@ -427,10 +423,8 @@ describe('SharedVaultFilter', () => {
dates: Dates.create(new Date(1616164633241311), new Date(1616164633241311)).getValue(),
timestamps: Timestamps.create(1616164633241311, 1616164633241311).getValue(),
sharedVaultAssociation: SharedVaultAssociation.create({
itemUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
lastEditedBy: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
sharedVaultUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
timestamps: Timestamps.create(123, 123).getValue(),
}).getValue(),
},
new UniqueEntityId('00000000-0000-0000-0000-000000000000'),
@@ -589,10 +583,8 @@ describe('SharedVaultFilter', () => {
dates: Dates.create(new Date(1616164633241311), new Date(1616164633241311)).getValue(),
timestamps: Timestamps.create(1616164633241311, 1616164633241311).getValue(),
sharedVaultAssociation: SharedVaultAssociation.create({
itemUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
lastEditedBy: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
sharedVaultUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
timestamps: Timestamps.create(123, 123).getValue(),
}).getValue(),
},
new UniqueEntityId('00000000-0000-0000-0000-000000000000'),

View File

@@ -26,10 +26,8 @@ describe('SharedVaultSnjsFilter', () => {
dates: Dates.create(new Date(1616164633241311), new Date(1616164633241311)).getValue(),
timestamps: Timestamps.create(1616164633241311, 1616164633241311).getValue(),
sharedVaultAssociation: SharedVaultAssociation.create({
itemUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
lastEditedBy: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
sharedVaultUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
timestamps: Timestamps.create(123, 123).getValue(),
}).getValue(),
},
new UniqueEntityId('00000000-0000-0000-0000-000000000000'),

View File

@@ -1,7 +1,3 @@
import { Timestamps, Uuid } from '@standardnotes/domain-core'
export interface KeySystemAssociationProps {
itemUuid: Uuid
keySystemIdentifier: string
timestamps: Timestamps
}

View File

@@ -1,12 +1,8 @@
import { Timestamps, Uuid } from '@standardnotes/domain-core'
import { KeySystemAssociation } from './KeySystemAssociation'
describe('KeySystemAssociation', () => {
it('should create an entity', () => {
const entityOrError = KeySystemAssociation.create({
timestamps: Timestamps.create(123456789, 123456789).getValue(),
itemUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
keySystemIdentifier: '00000000-0000-0000-0000-000000000000',
})

View File

@@ -1,9 +0,0 @@
import { Uuid } from '@standardnotes/domain-core'
import { KeySystemAssociation } from './KeySystemAssociation'
export interface KeySystemAssociationRepositoryInterface {
save(keySystem: KeySystemAssociation): Promise<void>
remove(keySystem: KeySystemAssociation): Promise<void>
findByItemUuid(itemUuid: Uuid): Promise<KeySystemAssociation | null>
}

View File

@@ -1,12 +1,10 @@
import { Timestamps, Uuid } from '@standardnotes/domain-core'
import { Uuid } from '@standardnotes/domain-core'
import { SharedVaultAssociation } from './SharedVaultAssociation'
describe('SharedVaultAssociation', () => {
it('should create an entity', () => {
const entityOrError = SharedVaultAssociation.create({
timestamps: Timestamps.create(123456789, 123456789).getValue(),
itemUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
lastEditedBy: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
sharedVaultUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
})

View File

@@ -1,8 +1,6 @@
import { Timestamps, Uuid } from '@standardnotes/domain-core'
import { Uuid } from '@standardnotes/domain-core'
export interface SharedVaultAssociationProps {
lastEditedBy: Uuid
sharedVaultUuid: Uuid
itemUuid: Uuid
timestamps: Timestamps
}

View File

@@ -1,9 +0,0 @@
import { Uuid } from '@standardnotes/domain-core'
import { SharedVaultAssociation } from './SharedVaultAssociation'
export interface SharedVaultAssociationRepositoryInterface {
save(sharedVaultAssociation: SharedVaultAssociation): Promise<void>
remove(sharedVaultAssociation: SharedVaultAssociation): Promise<void>
findByItemUuid(itemUuid: Uuid): Promise<SharedVaultAssociation | null>
}

View File

@@ -20,7 +20,7 @@ export class AddNotificationsForUsers implements UseCaseInterface<void> {
const sharedVaultUsers = await this.sharedVaultUserRepository.findBySharedVaultUuid(sharedVaultUuid)
for (const sharedVaultUser of sharedVaultUsers) {
const result = await this.addNotificationForUser.execute({
userUuid: sharedVaultUser.id.toString(),
userUuid: sharedVaultUser.props.userUuid.value,
type: dto.type,
payload: dto.payload,
version: dto.version,

View File

@@ -60,10 +60,8 @@ describe('DetermineSharedVaultOperationOnItem', () => {
existingItem = Item.create({
...existingItem.props,
sharedVaultAssociation: SharedVaultAssociation.create({
itemUuid: existingItem.uuid,
lastEditedBy: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
sharedVaultUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
timestamps: Timestamps.create(123, 123).getValue(),
}).getValue(),
}).getValue()
@@ -88,10 +86,8 @@ describe('DetermineSharedVaultOperationOnItem', () => {
existingItem = Item.create({
...existingItem.props,
sharedVaultAssociation: SharedVaultAssociation.create({
itemUuid: existingItem.uuid,
lastEditedBy: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
sharedVaultUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
timestamps: Timestamps.create(123, 123).getValue(),
}).getValue(),
}).getValue()
@@ -132,10 +128,8 @@ describe('DetermineSharedVaultOperationOnItem', () => {
existingItem = Item.create({
...existingItem.props,
sharedVaultAssociation: SharedVaultAssociation.create({
itemUuid: existingItem.uuid,
lastEditedBy: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
sharedVaultUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
timestamps: Timestamps.create(123, 123).getValue(),
}).getValue(),
}).getValue()

View File

@@ -365,9 +365,6 @@ describe('SaveNewItem', () => {
})
expect(result.isFailed()).toBeFalsy()
expect(result.getValue().props.keySystemAssociation?.props.itemUuid.value).toEqual(
'00000000-0000-0000-0000-000000000000',
)
expect(itemRepository.save).toHaveBeenCalled()
})

View File

@@ -112,11 +112,6 @@ export class SaveNewItem implements UseCaseInterface<Item> {
const sharedVaultAssociationOrError = SharedVaultAssociation.create({
lastEditedBy: userUuid,
sharedVaultUuid: dto.itemHash.sharedVaultUuid as Uuid,
timestamps: Timestamps.create(
this.timer.getTimestampInMicroseconds(),
this.timer.getTimestampInMicroseconds(),
).getValue(),
itemUuid: uuid,
})
if (sharedVaultAssociationOrError.isFailed()) {
return Result.fail(sharedVaultAssociationOrError.getError())
@@ -132,11 +127,6 @@ export class SaveNewItem implements UseCaseInterface<Item> {
const keySystemIdentifier = dto.itemHash.props.key_system_identifier as string
const keySystemAssociationOrError = KeySystemAssociation.create({
itemUuid: uuid,
timestamps: Timestamps.create(
this.timer.getTimestampInMicroseconds(),
this.timer.getTimestampInMicroseconds(),
).getValue(),
keySystemIdentifier,
})
if (keySystemAssociationOrError.isFailed()) {

View File

@@ -352,10 +352,8 @@ describe('UpdateExistingItem', () => {
item1.setSharedVaultAssociation(
SharedVaultAssociation.create({
itemUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
sharedVaultUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
lastEditedBy: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
timestamps: Timestamps.create(123, 123).getValue(),
}).getValue(),
)
const idBefore = item1.props.sharedVaultAssociation?.id.toString()
@@ -532,9 +530,7 @@ describe('UpdateExistingItem', () => {
item1.setKeySystemAssociation(
KeySystemAssociation.create({
itemUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
keySystemIdentifier: '00000000-0000-0000-0000-000000000000',
timestamps: Timestamps.create(123, 123).getValue(),
}).getValue(),
)
const idBefore = item1.props.keySystemAssociation?.id.toString()

View File

@@ -128,13 +128,6 @@ export class UpdateExistingItem implements UseCaseInterface<Item> {
{
lastEditedBy: userUuid,
sharedVaultUuid: dto.itemHash.sharedVaultUuid as Uuid,
timestamps: Timestamps.create(
dto.existingItem.props.sharedVaultAssociation
? dto.existingItem.props.sharedVaultAssociation.props.timestamps.createdAt
: this.timer.getTimestampInMicroseconds(),
this.timer.getTimestampInMicroseconds(),
).getValue(),
itemUuid: Uuid.create(dto.existingItem.id.toString()).getValue(),
},
new UniqueEntityId(
dto.existingItem.props.sharedVaultAssociation
@@ -171,11 +164,6 @@ export class UpdateExistingItem implements UseCaseInterface<Item> {
const keySystemAssociationOrError = KeySystemAssociation.create(
{
itemUuid: Uuid.create(dto.existingItem.id.toString()).getValue(),
timestamps: Timestamps.create(
this.timer.getTimestampInMicroseconds(),
this.timer.getTimestampInMicroseconds(),
).getValue(),
keySystemIdentifier,
},
new UniqueEntityId(

View File

@@ -0,0 +1,65 @@
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()
@Index('index_items_on_content_type')
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()
declare sharedVaultUuid: string | null
@Column()
declare keySystemIdentifier: string | null
}

View File

@@ -0,0 +1,244 @@
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'
export class MongoDBItemRepository implements ItemRepositoryInterface {
constructor(
private mongoRepository: MongoRepository<MongoDBItem>,
private mapper: MapperInterface<Item, MongoDBItem>,
private logger: Logger,
) {}
async deleteByUserUuid(userUuid: string): Promise<void> {
await this.mongoRepository.deleteMany({ where: { userUuid } })
}
async findAll(query: ItemQuery): Promise<Item[]> {
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<number> {
const options = this.createFindOptions(query)
return this.mongoRepository.count((options as FindManyOptions<MongoDBItem>).where)
}
async findContentSizeForComputingTransferLimit(
query: ItemQuery,
): Promise<{ uuid: string; contentSize: number | null }[]> {
const options = this.createFindOptions(query)
const rawItems = await this.mongoRepository.find({
select: ['uuid', 'contentSize'],
...options,
})
const items = rawItems.map((item) => {
return {
uuid: item._id.toHexString(),
contentSize: item.contentSize,
}
})
return items
}
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<ExtendedIntegrityPayload[]> {
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<Item | null> {
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<Item | null> {
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<void> {
await this.mongoRepository.deleteOne({ where: { _id: { $eq: BSON.UUID.createFromHexString(item.uuid.value) } } })
}
async save(item: Item): Promise<void> {
const persistence = this.mapper.toProjection(item)
const { _id, ...rest } = persistence
await this.mongoRepository.updateOne(
{ _id: { $eq: _id } },
{
$set: rest,
},
{ upsert: true },
)
}
async markItemsAsDeleted(itemUuids: string[], updatedAtTimestamp: number): Promise<void> {
await this.mongoRepository.updateMany(
{ where: { _id: { $in: itemUuids.map((uuid) => BSON.UUID.createFromHexString(uuid)) } } },
{ deleted: true, content: null, encItemKey: null, authHash: null, updatedAtTimestamp },
)
}
async updateContentSize(itemUuid: string, contentSize: number): Promise<void> {
await this.mongoRepository.updateOne(
{ where: { _id: { $eq: BSON.UUID.createFromHexString(itemUuid) } } },
{ contentSize },
)
}
private createFindOptions(
query: ItemQuery,
): FindManyOptions<MongoDBItem> | Partial<MongoDBItem> | FilterOperators<MongoDBItem> {
const options: FindManyOptions<MongoDBItem> | Partial<MongoDBItem> | FilterOperators<MongoDBItem> = {
order: undefined,
where: undefined,
}
if (query.sortBy !== undefined && query.sortOrder !== undefined) {
options.order = { [query.sortBy]: query.sortOrder }
}
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
}
}

View File

@@ -1,6 +1,5 @@
import { ReadStream } from 'fs'
import { Repository, SelectQueryBuilder, Brackets } from 'typeorm'
import { Change, MapperInterface, Uuid } from '@standardnotes/domain-core'
import { Repository, SelectQueryBuilder } from 'typeorm'
import { MapperInterface, Uuid } from '@standardnotes/domain-core'
import { Logger } from 'winston'
import { Item } from '../../Domain/Item/Item'
@@ -8,18 +7,11 @@ import { ItemQuery } from '../../Domain/Item/ItemQuery'
import { ItemRepositoryInterface } from '../../Domain/Item/ItemRepositoryInterface'
import { ExtendedIntegrityPayload } from '../../Domain/Item/ExtendedIntegrityPayload'
import { TypeORMItem } from './TypeORMItem'
import { KeySystemAssociationRepositoryInterface } from '../../Domain/KeySystem/KeySystemAssociationRepositoryInterface'
import { SharedVaultAssociationRepositoryInterface } from '../../Domain/SharedVault/SharedVaultAssociationRepositoryInterface'
import { TypeORMSharedVaultAssociation } from './TypeORMSharedVaultAssociation'
import { SharedVaultAssociation } from '../../Domain/SharedVault/SharedVaultAssociation'
import { KeySystemAssociation } from '../../Domain/KeySystem/KeySystemAssociation'
export class TypeORMItemRepository implements ItemRepositoryInterface {
constructor(
private ormRepository: Repository<TypeORMItem>,
private mapper: MapperInterface<Item, TypeORMItem>,
private keySystemAssociationRepository: KeySystemAssociationRepositoryInterface,
private sharedVaultAssociationRepository: SharedVaultAssociationRepositoryInterface,
private logger: Logger,
) {}
@@ -27,19 +19,9 @@ export class TypeORMItemRepository implements ItemRepositoryInterface {
const persistence = this.mapper.toProjection(item)
await this.ormRepository.save(persistence)
await this.persistAssociationChanges(item)
}
async remove(item: Item): Promise<void> {
if (item.props.keySystemAssociation) {
await this.keySystemAssociationRepository.remove(item.props.keySystemAssociation)
}
if (item.props.sharedVaultAssociation) {
await this.sharedVaultAssociationRepository.remove(item.props.sharedVaultAssociation)
}
await this.ormRepository.remove(this.mapper.toProjection(item))
}
@@ -92,8 +74,6 @@ export class TypeORMItemRepository implements ItemRepositoryInterface {
try {
const item = this.mapper.toDomain(persistence)
await this.decorateItemWithAssociations(item)
return item
} catch (error) {
this.logger.error(`Failed to find item ${uuid.value} by uuid: ${(error as Error).message}`)
@@ -142,8 +122,6 @@ export class TypeORMItemRepository implements ItemRepositoryInterface {
try {
const item = this.mapper.toDomain(persistence)
await this.decorateItemWithAssociations(item)
return item
} catch (error) {
this.logger.error(`Failed to find item ${uuid} by uuid and userUuid: ${(error as Error).message}`)
@@ -164,19 +142,9 @@ export class TypeORMItemRepository implements ItemRepositoryInterface {
}
}
await Promise.all(domainItems.map((item) => this.decorateItemWithAssociations(item)))
return domainItems
}
async findAllRaw<T>(query: ItemQuery): Promise<T[]> {
return this.createFindAllQueryBuilder(query).getRawMany<T>()
}
async streamAll(query: ItemQuery): Promise<ReadStream> {
return this.createFindAllQueryBuilder(query).stream()
}
async countAll(query: ItemQuery): Promise<number> {
return this.createFindAllQueryBuilder(query).getCount()
}
@@ -205,41 +173,10 @@ export class TypeORMItemRepository implements ItemRepositoryInterface {
queryBuilder.orderBy(`item.${query.sortBy}`, query.sortOrder)
}
if (query.includeSharedVaultUuids !== undefined && query.includeSharedVaultUuids.length > 0) {
queryBuilder
.leftJoin(
TypeORMSharedVaultAssociation,
'sharedVaultAssociation',
'sharedVaultAssociation.itemUuid = item.uuid',
)
.where(
new Brackets((qb) => {
qb.where('sharedVaultAssociation.sharedVaultUuid IN (:...sharedVaultUuids)', {
sharedVaultUuids: query.includeSharedVaultUuids,
})
if (query.userUuid) {
qb.orWhere('item.user_uuid = :userUuid', { userUuid: query.userUuid })
}
}),
)
} else if (query.exclusiveSharedVaultUuids !== undefined && query.exclusiveSharedVaultUuids.length > 0) {
queryBuilder
.innerJoin(
TypeORMSharedVaultAssociation,
'sharedVaultAssociation',
'sharedVaultAssociation.itemUuid = item.uuid',
)
.where('sharedVaultAssociation.sharedVaultUuid IN (:...sharedVaultUuids)', {
sharedVaultUuids: query.exclusiveSharedVaultUuids,
})
} else if (query.userUuid !== undefined) {
if (query.userUuid !== undefined) {
queryBuilder.where('item.user_uuid = :userUuid', { userUuid: query.userUuid })
}
if (query.selectString !== undefined) {
queryBuilder.select(query.selectString)
}
if (query.uuids && query.uuids.length > 0) {
queryBuilder.andWhere('item.uuid IN (:...uuids)', { uuids: query.uuids })
}
@@ -273,48 +210,4 @@ export class TypeORMItemRepository implements ItemRepositoryInterface {
return queryBuilder
}
private async decorateItemWithAssociations(item: Item): Promise<void> {
await Promise.all([
this.decorateItemWithKeySystemAssociation(item),
this.decorateItemWithSharedVaultAssociation(item),
])
}
private async decorateItemWithKeySystemAssociation(item: Item): Promise<void> {
const keySystemAssociation = await this.keySystemAssociationRepository.findByItemUuid(item.uuid)
if (keySystemAssociation) {
item.props.keySystemAssociation = keySystemAssociation
}
}
private async decorateItemWithSharedVaultAssociation(item: Item): Promise<void> {
const sharedVaultAssociation = await this.sharedVaultAssociationRepository.findByItemUuid(item.uuid)
if (sharedVaultAssociation) {
item.props.sharedVaultAssociation = sharedVaultAssociation
}
}
private async persistAssociationChanges(item: Item): Promise<void> {
for (const change of item.getChanges()) {
if (change.props.changeData instanceof SharedVaultAssociation) {
if ([Change.TYPES.Add, Change.TYPES.Modify].includes(change.props.changeType)) {
await this.sharedVaultAssociationRepository.save(change.props.changeData)
}
if (change.props.changeType === Change.TYPES.Remove) {
await this.sharedVaultAssociationRepository.remove(change.props.changeData)
}
}
if (change.props.changeData instanceof KeySystemAssociation) {
if ([Change.TYPES.Add, Change.TYPES.Modify].includes(change.props.changeType)) {
await this.keySystemAssociationRepository.save(change.props.changeData)
}
if (change.props.changeType === Change.TYPES.Remove) {
await this.keySystemAssociationRepository.remove(change.props.changeData)
}
}
}
item.flushChanges()
}
}

View File

@@ -1,36 +0,0 @@
import { Repository } from 'typeorm'
import { MapperInterface, Uuid } from '@standardnotes/domain-core'
import { KeySystemAssociation } from '../../Domain/KeySystem/KeySystemAssociation'
import { KeySystemAssociationRepositoryInterface } from '../../Domain/KeySystem/KeySystemAssociationRepositoryInterface'
import { TypeORMKeySystemAssociation } from './TypeORMKeySystemAssociation'
export class TypeORMKeySystemAssociationRepository implements KeySystemAssociationRepositoryInterface {
constructor(
private ormRepository: Repository<TypeORMKeySystemAssociation>,
private mapper: MapperInterface<KeySystemAssociation, TypeORMKeySystemAssociation>,
) {}
async findByItemUuid(itemUuid: Uuid): Promise<KeySystemAssociation | null> {
const persistence = await this.ormRepository
.createQueryBuilder('key_system_association')
.where('key_system_association.item_uuid = :itemUuid', {
itemUuid: itemUuid.value,
})
.getOne()
if (persistence === null) {
return null
}
return this.mapper.toDomain(persistence)
}
async save(keySystemAssociation: KeySystemAssociation): Promise<void> {
await this.ormRepository.save(this.mapper.toProjection(keySystemAssociation))
}
async remove(keySystemAssociation: KeySystemAssociation): Promise<void> {
await this.ormRepository.remove(this.mapper.toProjection(keySystemAssociation))
}
}

View File

@@ -1,36 +0,0 @@
import { Repository } from 'typeorm'
import { MapperInterface, Uuid } from '@standardnotes/domain-core'
import { SharedVaultAssociation } from '../../Domain/SharedVault/SharedVaultAssociation'
import { SharedVaultAssociationRepositoryInterface } from '../../Domain/SharedVault/SharedVaultAssociationRepositoryInterface'
import { TypeORMSharedVaultAssociation } from './TypeORMSharedVaultAssociation'
export class TypeORMSharedVaultAssociationRepository implements SharedVaultAssociationRepositoryInterface {
constructor(
private ormRepository: Repository<TypeORMSharedVaultAssociation>,
private mapper: MapperInterface<SharedVaultAssociation, TypeORMSharedVaultAssociation>,
) {}
async findByItemUuid(itemUuid: Uuid): Promise<SharedVaultAssociation | null> {
const persistence = await this.ormRepository
.createQueryBuilder('shared_vault_association')
.where('shared_vault_association.item_uuid = :itemUuid', {
itemUuid: itemUuid.value,
})
.getOne()
if (persistence === null) {
return null
}
return this.mapper.toDomain(persistence)
}
async save(sharedVaultAssociation: SharedVaultAssociation): Promise<void> {
await this.ormRepository.save(this.mapper.toProjection(sharedVaultAssociation))
}
async remove(sharedVaultAssociation: SharedVaultAssociation): Promise<void> {
await this.ormRepository.remove(this.mapper.toProjection(sharedVaultAssociation))
}
}

View File

@@ -1,56 +0,0 @@
import { MapperInterface, Timestamps, UniqueEntityId, Uuid, Validator } from '@standardnotes/domain-core'
import { KeySystemAssociation } from '../../Domain/KeySystem/KeySystemAssociation'
import { TypeORMKeySystemAssociation } from '../../Infra/TypeORM/TypeORMKeySystemAssociation'
export class KeySystemAssociationPersistenceMapper
implements MapperInterface<KeySystemAssociation, TypeORMKeySystemAssociation>
{
toDomain(projection: TypeORMKeySystemAssociation): KeySystemAssociation {
const itemUuidOrError = Uuid.create(projection.itemUuid)
if (itemUuidOrError.isFailed()) {
throw new Error(`Failed to create key system from projection: ${itemUuidOrError.getError()}`)
}
const itemUuid = itemUuidOrError.getValue()
const keySystemIdentifiedValidationResult = Validator.isNotEmptyString(projection.keySystemIdentifier)
if (keySystemIdentifiedValidationResult.isFailed()) {
throw new Error(`Failed to create key system from projection: ${keySystemIdentifiedValidationResult.getError()}`)
}
const timestampsOrError = Timestamps.create(projection.createdAtTimestamp, projection.updatedAtTimestamp)
if (timestampsOrError.isFailed()) {
throw new Error(`Failed to create key system from projection: ${timestampsOrError.getError()}`)
}
const timestamps = timestampsOrError.getValue()
const keySystemOrError = KeySystemAssociation.create(
{
itemUuid,
timestamps,
keySystemIdentifier: projection.keySystemIdentifier,
},
new UniqueEntityId(projection.uuid),
)
if (keySystemOrError.isFailed()) {
throw new Error(`Failed to create key system from projection: ${keySystemOrError.getError()}`)
}
const keySystem = keySystemOrError.getValue()
return keySystem
}
toProjection(domain: KeySystemAssociation): TypeORMKeySystemAssociation {
const typeorm = new TypeORMKeySystemAssociation()
typeorm.uuid = domain.id.toString()
typeorm.itemUuid = domain.props.itemUuid.value
typeorm.keySystemIdentifier = domain.props.keySystemIdentifier
typeorm.createdAtTimestamp = domain.props.timestamps.createdAt
typeorm.updatedAtTimestamp = domain.props.timestamps.updatedAt
return typeorm
}
}

View File

@@ -0,0 +1,150 @@
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<Item, MongoDBItem> {
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({
keySystemIdentifier: 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
}
}

View File

@@ -1,65 +0,0 @@
import { MapperInterface, Timestamps, UniqueEntityId, Uuid } from '@standardnotes/domain-core'
import { TypeORMSharedVaultAssociation } from '../../Infra/TypeORM/TypeORMSharedVaultAssociation'
import { SharedVaultAssociation } from '../../Domain/SharedVault/SharedVaultAssociation'
export class SharedVaultAssociationPersistenceMapper
implements MapperInterface<SharedVaultAssociation, TypeORMSharedVaultAssociation>
{
toDomain(projection: TypeORMSharedVaultAssociation): SharedVaultAssociation {
const itemUuidOrError = Uuid.create(projection.itemUuid)
if (itemUuidOrError.isFailed()) {
throw new Error(`Failed to create shared vault association from projection: ${itemUuidOrError.getError()}`)
}
const itemUuid = itemUuidOrError.getValue()
const sharedVaultUuidOrError = Uuid.create(projection.sharedVaultUuid)
if (sharedVaultUuidOrError.isFailed()) {
throw new Error(`Failed to create shared vault association from projection: ${sharedVaultUuidOrError.getError()}`)
}
const sharedVaultUuid = sharedVaultUuidOrError.getValue()
const lastEditedByOrError = Uuid.create(projection.lastEditedBy)
if (lastEditedByOrError.isFailed()) {
throw new Error(`Failed to create shared vault association from projection: ${lastEditedByOrError.getError()}`)
}
const lastEditedBy = lastEditedByOrError.getValue()
const timestampsOrError = Timestamps.create(projection.createdAtTimestamp, projection.updatedAtTimestamp)
if (timestampsOrError.isFailed()) {
throw new Error(`Failed to create shared vault association from projection: ${timestampsOrError.getError()}`)
}
const timestamps = timestampsOrError.getValue()
const sharedVaultAssociationOrError = SharedVaultAssociation.create(
{
itemUuid,
lastEditedBy,
sharedVaultUuid,
timestamps,
},
new UniqueEntityId(projection.uuid),
)
if (sharedVaultAssociationOrError.isFailed()) {
throw new Error(
`Failed to create shared vault association from projection: ${sharedVaultAssociationOrError.getError()}`,
)
}
const sharedVaultAssociation = sharedVaultAssociationOrError.getValue()
return sharedVaultAssociation
}
toProjection(domain: SharedVaultAssociation): TypeORMSharedVaultAssociation {
const typeorm = new TypeORMSharedVaultAssociation()
typeorm.uuid = domain.id.toString()
typeorm.sharedVaultUuid = domain.props.sharedVaultUuid.value
typeorm.itemUuid = domain.props.itemUuid.value
typeorm.lastEditedBy = domain.props.lastEditedBy.value
typeorm.createdAtTimestamp = domain.props.timestamps.createdAt
typeorm.updatedAtTimestamp = domain.props.timestamps.updatedAt
return typeorm
}
}

View File

@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.10.17](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.10.16...@standardnotes/websockets-server@1.10.17) (2023-08-11)
**Note:** Version bump only for package @standardnotes/websockets-server
## [1.10.16](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.10.15...@standardnotes/websockets-server@1.10.16) (2023-08-09)
**Note:** Version bump only for package @standardnotes/websockets-server
## [1.10.15](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.10.14...@standardnotes/websockets-server@1.10.15) (2023-08-09)
**Note:** Version bump only for package @standardnotes/websockets-server
## [1.10.14](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.10.13...@standardnotes/websockets-server@1.10.14) (2023-08-09)
**Note:** Version bump only for package @standardnotes/websockets-server

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/websockets-server",
"version": "1.10.14",
"version": "1.10.17",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

122
yarn.lock
View File

@@ -4101,6 +4101,7 @@ __metadata:
inversify-express-utils: "npm:^6.4.3"
jest: "npm:^29.5.0"
jsonwebtoken: "npm:^9.0.0"
mongodb: "npm:^5.7.0"
mysql2: "npm:^3.0.1"
newrelic: "npm:^10.1.2"
nodemon: "npm:^2.0.19"
@@ -4700,6 +4701,23 @@ __metadata:
languageName: node
linkType: hard
"@types/webidl-conversions@npm:*":
version: 7.0.0
resolution: "@types/webidl-conversions@npm:7.0.0"
checksum: 86c337dc1edd0db2a9e278cb2ddb3b577559c8a282348bedf8505be0435be86354bb83fe858e959e2ce12ab2aa02eb5698d5e1a35454182637e776982013a5d1
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: 25f20f5649f0e4a3242bf8f59c8e1b3d057f93ac1039e3aeea49cd6e4eed33517f228b412bfb048670421c11d2198e45cd9e09fe7921a263b6c8a9eb4b833ad1
languageName: node
linkType: hard
"@types/yargs-parser@npm:*":
version: 21.0.0
resolution: "@types/yargs-parser@npm:21.0.0"
@@ -5628,6 +5646,13 @@ __metadata:
languageName: node
linkType: hard
"bson@npm:^5.4.0":
version: 5.4.0
resolution: "bson@npm:5.4.0"
checksum: 2c913a45c05bf8f1f8120c05e0e4ac9a864928853193c4794634b0c941a7d64397b9cbfe9fa9aba7249eb89d075911c5953efbb1be6b4e0848a0760660dca628
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"
@@ -9863,6 +9888,13 @@ __metadata:
languageName: node
linkType: hard
"memory-pager@npm:^1.0.2":
version: 1.5.0
resolution: "memory-pager@npm:1.5.0"
checksum: 6b00ff499b3b6a168d8b713d5c33f3ea08fd24c19a8b42adc64847cfa62acdf7a3cfd81f02d6eab51773b6e118c628ba6694ecb55647d4c1efe7b11e67017e35
languageName: node
linkType: hard
"meow@npm:^8.0.0":
version: 8.1.2
resolution: "meow@npm:8.1.2"
@@ -10201,6 +10233,48 @@ __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: 8a9186dd1b72dfa1ca8e2e7deeec2e412b3682c923d9f887e07a19b2366174e50c1c9f3657353eef62e7acce26f7e6ec16c3cc320fc1c12aab5d4890fa368ce3
languageName: node
linkType: hard
"mongodb@npm:^5.7.0":
version: 5.7.0
resolution: "mongodb@npm:5.7.0"
dependencies:
bson: "npm:^5.4.0"
mongodb-connection-string-url: "npm:^2.6.0"
saslprep: "npm:^1.0.3"
socks: "npm:^2.7.1"
peerDependencies:
"@aws-sdk/credential-providers": ^3.201.0
"@mongodb-js/zstd": ^1.1.0
kerberos: ^2.0.1
mongodb-client-encryption: ">=2.3.0 <3"
snappy: ^7.2.2
dependenciesMeta:
saslprep:
optional: true
peerDependenciesMeta:
"@aws-sdk/credential-providers":
optional: true
"@mongodb-js/zstd":
optional: true
kerberos:
optional: true
mongodb-client-encryption:
optional: true
snappy:
optional: true
checksum: 23a291ffe7e990f25b527f2d4bd1a848b866211596cc30a36cbe86d773f3bcd74d688aa0a7158b35e24271264d15c35832fcced639b81df4cab7303cdd8442c0
languageName: node
linkType: hard
"ms@npm:2.0.0":
version: 2.0.0
resolution: "ms@npm:2.0.0"
@@ -11480,7 +11554,7 @@ __metadata:
languageName: node
linkType: hard
"punycode@npm:^2.1.0":
"punycode@npm:^2.1.0, punycode@npm:^2.1.1":
version: 2.3.0
resolution: "punycode@npm:2.3.0"
checksum: c2b408c805927a6614ef581bd3d00deca1fef9f2da0ec95cecaedf6a985d8596a29e931e31f80f7313f94257895f9ac6cf4c2ae81cdca04964daf9c3c3d221c1
@@ -12003,6 +12077,15 @@ __metadata:
languageName: node
linkType: hard
"saslprep@npm:^1.0.3":
version: 1.0.3
resolution: "saslprep@npm:1.0.3"
dependencies:
sparse-bitfield: "npm:^3.0.3"
checksum: 23ebcda091621541fb9db9635ff36b9be81dc35a79a2adbf2a8309e162bcc9607513488aa3a9da757f11e856592ab8a727ac45c98c6084ff93d627509a882b84
languageName: node
linkType: hard
"schema-utils@npm:^3.1.1, schema-utils@npm:^3.1.2":
version: 3.1.2
resolution: "schema-utils@npm:3.1.2"
@@ -12292,7 +12375,7 @@ __metadata:
languageName: node
linkType: hard
"socks@npm:^2.6.2":
"socks@npm:^2.6.2, socks@npm:^2.7.1":
version: 2.7.1
resolution: "socks@npm:2.7.1"
dependencies:
@@ -12338,6 +12421,15 @@ __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: 625ecdf6f4b2652afac82dec575d575cafe492aa06a3010c12cb1f312fb78e62a916df933885a2a4151f1347646d490c87cf3404ce3afc7a3031bd6b622225fc
languageName: node
linkType: hard
"spawn-please@npm:^2.0.1":
version: 2.0.1
resolution: "spawn-please@npm:2.0.1"
@@ -12886,6 +12978,15 @@ __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: 3a481676bf6956ca7ffd4b21c5826f61d7dd57dcad56ee202a5d9d5a34f5ddd1a98ee938366f7964e8dfabc640377d53725164724da49a7a2331694270a1b7d8
languageName: node
linkType: hard
"tr46@npm:~0.0.3":
version: 0.0.3
resolution: "tr46@npm:0.0.3"
@@ -13518,6 +13619,13 @@ __metadata:
languageName: node
linkType: hard
"webidl-conversions@npm:^7.0.0":
version: 7.0.0
resolution: "webidl-conversions@npm:7.0.0"
checksum: bdbe11c68c3136ce4e720182d2434215cff65d619de7e7ddcbdc17c7d62aaaf0e16c3a84b2c6e55ffe347e77dea2d55299c7e3690fb07148a8fbe46ead27c55f
languageName: node
linkType: hard
"webpack-sources@npm:^3.2.3":
version: 3.2.3
resolution: "webpack-sources@npm:3.2.3"
@@ -13562,6 +13670,16 @@ __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: ee3a532bfb026d307b1c7f75413a45d19292e4eff4f9db62e020ac67d00f6ac81032011604832e3b1e65665c603e6024148570dbe883a71ba93ea4838beeb162
languageName: node
linkType: hard
"whatwg-url@npm:^5.0.0":
version: 5.0.0
resolution: "whatwg-url@npm:5.0.0"