Compare commits

...

128 Commits

Author SHA1 Message Date
standardci
0057a5d6ff chore(release): publish new version
- @standardnotes/analytics@2.28.2
 - @standardnotes/api-gateway@1.77.2
 - @standardnotes/auth-server@1.152.2
 - @standardnotes/domain-events-infra@1.14.9
 - @standardnotes/event-store@1.12.12
 - @standardnotes/files-server@1.26.4
 - @standardnotes/home-server@1.16.36
 - @standardnotes/revisions-server@1.40.3
 - @standardnotes/scheduler-server@1.22.2
 - @standardnotes/syncing-server@1.112.4
 - @standardnotes/websockets-server@1.12.1
2023-10-09 08:12:19 +00:00
Karol Sójko
b736dab3c1 fix: remove xray sdk in favor of opentelemetry 2023-10-09 09:53:34 +02:00
standardci
951d965304 chore(release): publish new version
- @standardnotes/home-server@1.16.35
 - @standardnotes/revisions-server@1.40.2
 - @standardnotes/syncing-server@1.112.3
2023-10-09 06:45:04 +00:00
Karol Sójko
29e8de3238 fix: logs in transition 2023-10-09 08:26:18 +02:00
standardci
eeeacabaa8 chore(release): publish new version
- @standardnotes/home-server@1.16.34
 - @standardnotes/syncing-server@1.112.2
2023-10-06 14:30:24 +00:00
Karol Sójko
51ca8229b8 fix(syncing-server): calling auth server for user key params 2023-10-06 15:56:10 +02:00
Karol Sójko
a6a19a391e fix(syncing-server): error log on email backup requested 2023-10-06 15:44:11 +02:00
standardci
f6cdb7916c chore(release): publish new version
- @standardnotes/auth-server@1.152.1
 - @standardnotes/home-server@1.16.33
 - @standardnotes/revisions-server@1.40.1
 - @standardnotes/syncing-server@1.112.1
2023-10-06 13:34:07 +00:00
Karol Sójko
eafb064d79 fix(syncing-server): increase axios timeout on calling auth 2023-10-06 15:18:26 +02:00
Karol Sójko
ba050681f7 fix(syncing-server): logs on request backup handler 2023-10-06 15:16:38 +02:00
Karol Sójko
4780629549 fix(revisions): casting creation date from MongoDB 2023-10-06 15:14:11 +02:00
Karol Sójko
79a44aa51f fix(auth): checking for transition role when triggering transition 2023-10-06 14:56:45 +02:00
standardci
dd72769841 chore(release): publish new version
- @standardnotes/auth-server@1.152.0
 - @standardnotes/home-server@1.16.32
 - @standardnotes/revisions-server@1.40.0
 - @standardnotes/syncing-server@1.112.0
2023-10-06 11:22:47 +00:00
Karol Sójko
d8f1c66fd5 fix: enable TransitionRequestedEventHandler 2023-10-06 13:02:37 +02:00
Karol Sójko
afe9967d26 fix(auth): strip user from transition role after migration 2023-10-06 12:59:18 +02:00
Karol Sójko
27bea444cc feat: switch transition direction 2023-10-06 12:48:08 +02:00
standardci
7a571dec0a chore(release): publish new version
- @standardnotes/home-server@1.16.31
 - @standardnotes/syncing-server@1.111.5
2023-10-06 08:48:31 +00:00
Karol Sójko
8c57f505be fix(syncing-server): add more logs on successfull email backups requested 2023-10-06 10:28:50 +02:00
standardci
973612bf4f chore(release): publish new version
- @standardnotes/analytics@2.28.1
 - @standardnotes/auth-server@1.151.2
 - @standardnotes/home-server@1.16.30
 - @standardnotes/scheduler-server@1.22.1
 - @standardnotes/syncing-server@1.111.4
2023-10-06 08:01:50 +00:00
Karol Sójko
702a1286eb fix(syncing-server): error log on email backup request handler 2023-10-06 09:40:27 +02:00
Karol Sójko
a45b5b69b5 fix: add xray-sdk to background processors 2023-10-06 09:33:15 +02:00
standardci
321353f26c chore(release): publish new version
- @standardnotes/analytics@2.28.0
 - @standardnotes/api-gateway@1.77.1
 - @standardnotes/auth-server@1.151.1
 - @standardnotes/domain-core@1.35.0
 - @standardnotes/domain-events-infra@1.14.8
 - @standardnotes/event-store@1.12.11
 - @standardnotes/files-server@1.26.3
 - @standardnotes/home-server@1.16.29
 - @standardnotes/revisions-server@1.39.5
 - @standardnotes/scheduler-server@1.22.0
 - @standardnotes/settings@1.21.43
 - @standardnotes/syncing-server@1.111.3
 - @standardnotes/websockets-server@1.12.0
2023-10-06 05:44:00 +00:00
Karol Sójko
db4607d4aa chore: upgrade sqs-consumer 2023-10-06 07:26:59 +02:00
Karol Sójko
f0531d68cb feat: add xray to analytics scheduler and websockets 2023-10-06 07:23:06 +02:00
Karol Sójko
8a00d159a6 Revert "fix: naming of segments for sqs handlers"
This reverts commit d244cc0d5f.
2023-10-06 06:50:14 +02:00
Karol Sójko
d244cc0d5f fix: naming of segments for sqs handlers 2023-10-05 18:06:17 +02:00
standardci
6a2aa4b148 chore(release): publish new version
- @standardnotes/api-gateway@1.77.0
 - @standardnotes/auth-server@1.151.0
 - @standardnotes/home-server@1.16.28
2023-10-05 14:42:25 +00:00
Karol Sójko
3ee49416f8 feat: setting xray segment user on api-gateway level 2023-10-05 16:25:09 +02:00
standardci
ae1e86e19f chore(release): publish new version
- @standardnotes/home-server@1.16.27
 - @standardnotes/revisions-server@1.39.4
2023-10-05 13:20:33 +00:00
Karol Sójko
9f76e389e2 fix(revisions): capture mysql to xray 2023-10-05 13:22:39 +02:00
standardci
6e2240e60c chore(release): publish new version
- @standardnotes/analytics@2.27.10
 - @standardnotes/api-gateway@1.76.2
 - @standardnotes/auth-server@1.150.9
 - @standardnotes/domain-events-infra@1.14.7
 - @standardnotes/event-store@1.12.10
 - @standardnotes/files-server@1.26.2
 - @standardnotes/home-server@1.16.26
 - @standardnotes/revisions-server@1.39.3
 - @standardnotes/scheduler-server@1.21.10
 - @standardnotes/syncing-server@1.111.2
 - @standardnotes/websockets-server@1.11.10
2023-10-05 07:17:33 +00:00
Karol Sójko
cd37c951bb Revert "fix(domain-events-infra): setting user metadata on workers"
This reverts commit c4b6f17ebc.
2023-10-05 09:00:47 +02:00
standardci
c4c3dfb823 chore(release): publish new version
- @standardnotes/analytics@2.27.9
 - @standardnotes/api-gateway@1.76.1
 - @standardnotes/auth-server@1.150.8
 - @standardnotes/domain-events-infra@1.14.6
 - @standardnotes/event-store@1.12.9
 - @standardnotes/files-server@1.26.1
 - @standardnotes/home-server@1.16.25
 - @standardnotes/revisions-server@1.39.2
 - @standardnotes/scheduler-server@1.21.9
 - @standardnotes/syncing-server@1.111.1
 - @standardnotes/websockets-server@1.11.9
2023-10-05 05:36:39 +00:00
Karol Sójko
c4b6f17ebc fix(domain-events-infra): setting user metadata on workers 2023-10-05 07:16:18 +02:00
standardci
71ce938cb1 chore(release): publish new version
- @standardnotes/api-gateway@1.76.0
 - @standardnotes/files-server@1.26.0
 - @standardnotes/home-server@1.16.24
 - @standardnotes/syncing-server@1.111.0
2023-10-04 18:03:38 +00:00
Karol Sójko
dc76113915 feat(api-gateaway): configure aws-xray-sdk 2023-10-04 19:44:25 +02:00
Karol Sójko
6583ff6cd9 feat: add xray to syncing server and files 2023-10-04 19:39:16 +02:00
standardci
69ea947857 chore(release): publish new version
- @standardnotes/analytics@2.27.8
 - @standardnotes/api-gateway@1.75.13
 - @standardnotes/auth-server@1.150.7
 - @standardnotes/domain-core@1.34.2
 - @standardnotes/domain-events-infra@1.14.5
 - @standardnotes/event-store@1.12.8
 - @standardnotes/files-server@1.25.6
 - @standardnotes/home-server@1.16.23
 - @standardnotes/revisions-server@1.39.1
 - @standardnotes/scheduler-server@1.21.8
 - @standardnotes/settings@1.21.42
 - @standardnotes/syncing-server@1.110.8
 - @standardnotes/websockets-server@1.11.8
2023-10-04 16:36:09 +00:00
Karol Sójko
eab78b3a95 fix: identifying services in workers 2023-10-04 18:13:41 +02:00
standardci
3097f7f063 chore(release): publish new version
- @standardnotes/home-server@1.16.22
 - @standardnotes/revisions-server@1.39.0
2023-10-04 15:42:53 +00:00
Karol Sójko
126989df82 feat(revisions): add aws-xray-sdk 2023-10-04 17:22:40 +02:00
Karol Sójko
a25eb178c5 chore: fix env var replacement 2023-10-04 16:43:48 +02:00
standardci
18dae26b8e chore(release): publish new version
- @standardnotes/analytics@2.27.7
 - @standardnotes/api-gateway@1.75.12
 - @standardnotes/auth-server@1.150.6
 - @standardnotes/domain-events-infra@1.14.4
 - @standardnotes/event-store@1.12.7
 - @standardnotes/files-server@1.25.5
 - @standardnotes/home-server@1.16.21
 - @standardnotes/revisions-server@1.38.10
 - @standardnotes/scheduler-server@1.21.7
 - @standardnotes/syncing-server@1.110.7
 - @standardnotes/websockets-server@1.11.7
2023-10-04 14:30:55 +00:00
Karol Sójko
5bc8157d4d chore: disable vault tests temporarily 2023-10-04 16:09:27 +02:00
Karol Sójko
f29826e917 chore: add filling in the package version 2023-10-04 16:09:15 +02:00
Karol Sójko
ba7cbb989b fix(domain-events-infra): subsegment name 2023-10-04 15:51:33 +02:00
Karol Sójko
d4579ce21e fix(auth): disable users from registering to MongoDB 2023-10-04 15:51:32 +02:00
standardci
ed14d2dfb7 chore(release): publish new version
- @standardnotes/analytics@2.27.6
 - @standardnotes/api-gateway@1.75.11
 - @standardnotes/auth-server@1.150.5
 - @standardnotes/domain-events-infra@1.14.3
 - @standardnotes/event-store@1.12.6
 - @standardnotes/files-server@1.25.4
 - @standardnotes/home-server@1.16.20
 - @standardnotes/revisions-server@1.38.9
 - @standardnotes/scheduler-server@1.21.6
 - @standardnotes/syncing-server@1.110.6
 - @standardnotes/websockets-server@1.11.6
2023-10-04 13:17:42 +00:00
Karol Sójko
64f1fe59c2 fix(domain-events-infra): remove redundant flush 2023-10-04 14:49:49 +02:00
Karol Sójko
207ef9f3e5 fix(domain-events-infra): handling segments 2023-10-04 14:47:45 +02:00
standardci
3ea0435459 chore(release): publish new version
- @standardnotes/analytics@2.27.5
 - @standardnotes/api-gateway@1.75.10
 - @standardnotes/auth-server@1.150.4
 - @standardnotes/domain-events-infra@1.14.2
 - @standardnotes/event-store@1.12.5
 - @standardnotes/files-server@1.25.3
 - @standardnotes/home-server@1.16.19
 - @standardnotes/revisions-server@1.38.8
 - @standardnotes/scheduler-server@1.21.5
 - @standardnotes/syncing-server@1.110.5
 - @standardnotes/websockets-server@1.11.5
2023-10-04 12:38:32 +00:00
Karol Sójko
7668713dd6 fix(domain-events-infra): imports 2023-10-04 14:06:47 +02:00
Karol Sójko
f6bc1c3084 fix(domain-events-infra): handling async functions 2023-10-04 14:01:46 +02:00
standardci
4203ff9a0c chore(release): publish new version
- @standardnotes/auth-server@1.150.3
 - @standardnotes/home-server@1.16.18
2023-10-04 11:48:12 +00:00
Karol Sójko
0281724196 fix(auth): remove ec2 plugin from worker 2023-10-04 13:21:14 +02:00
standardci
94bd319279 chore(release): publish new version
- @standardnotes/auth-server@1.150.2
 - @standardnotes/home-server@1.16.17
2023-10-04 11:09:36 +00:00
Karol Sójko
373cfad1f7 fix(auth): remove ec2 plugin 2023-10-04 12:42:49 +02:00
standardci
59107f8553 chore(release): publish new version
- @standardnotes/analytics@2.27.4
 - @standardnotes/api-gateway@1.75.9
 - @standardnotes/auth-server@1.150.1
 - @standardnotes/domain-events-infra@1.14.1
 - @standardnotes/event-store@1.12.4
 - @standardnotes/files-server@1.25.2
 - @standardnotes/home-server@1.16.16
 - @standardnotes/revisions-server@1.38.7
 - @standardnotes/scheduler-server@1.21.4
 - @standardnotes/syncing-server@1.110.4
 - @standardnotes/websockets-server@1.11.4
2023-10-03 13:32:00 +00:00
Karol Sójko
e066b6a126 fix(domain-events-infra): change segment closing 2023-10-03 14:57:59 +02:00
standardci
a0e4926135 chore(release): publish new version
- @standardnotes/analytics@2.27.3
 - @standardnotes/api-gateway@1.75.8
 - @standardnotes/auth-server@1.150.0
 - @standardnotes/domain-events-infra@1.14.0
 - @standardnotes/event-store@1.12.3
 - @standardnotes/files-server@1.25.1
 - @standardnotes/home-server@1.16.15
 - @standardnotes/revisions-server@1.38.6
 - @standardnotes/scheduler-server@1.21.3
 - @standardnotes/syncing-server@1.110.3
 - @standardnotes/websockets-server@1.11.3
2023-10-03 06:53:13 +00:00
Karol Sójko
b1b244a2cf feat: add xray segment tracing on auth-worker 2023-10-03 08:21:57 +02:00
standardci
b4a38d9dcc chore(release): publish new version
- @standardnotes/auth-server@1.149.1
 - @standardnotes/home-server@1.16.14
2023-10-02 15:45:45 +00:00
Karol Sójko
71e2a4187e fix(auth): enable xray only for server 2023-10-02 16:53:03 +02:00
standardci
c94f9c1a60 chore(release): publish new version
- @standardnotes/auth-server@1.149.0
 - @standardnotes/home-server@1.16.13
 - @standardnotes/revisions-server@1.38.5
 - @standardnotes/syncing-server@1.110.2
2023-10-02 13:56:17 +00:00
Karol Sójko
b9907924be chore: fix run name for e2e test suite to include suite 2023-10-02 14:37:10 +02:00
Karol Sójko
d4c188c096 feat: divide suites furthermore 2023-10-02 14:19:12 +02:00
Karol Sójko
2ccaf490df feat: divide test suites on a higher level 2023-10-02 13:47:32 +02:00
Karol Sójko
cd893b41d7 fix: temproarily disable transitions to empty overpopulated queues 2023-10-02 13:05:54 +02:00
Karol Sójko
3838358081 fix(auth): add aws xray ecs and ec2 plugins 2023-10-02 12:56:06 +02:00
Karol Sójko
1a388f00c3 feat(auth): introduce AWS X-Ray SDK (#859)
* feat(auth): configure aws-xray-sdk for express

* configured aws sdk clients

* configure setting user metadata on segment

* fix binding

* fix binding order
2023-10-02 12:52:49 +02:00
Karol Sójko
bd71422fab fix(auth): prevent from loop disabling of email settings (#858) 2023-10-02 10:56:35 +02:00
standardci
3e1697f47f chore(release): publish new version
- @standardnotes/home-server@1.16.12
 - @standardnotes/revisions-server@1.38.4
 - @standardnotes/syncing-server@1.110.1
2023-09-29 13:13:19 +00:00
Karol Sójko
032cde7723 fix: keep transition in-progress status alive 2023-09-29 14:08:31 +02:00
standardci
34b956b482 chore(release): publish new version
- @standardnotes/auth-server@1.148.2
 - @standardnotes/home-server@1.16.11
 - @standardnotes/revisions-server@1.38.3
 - @standardnotes/syncing-server@1.110.0
2023-09-29 10:23:26 +00:00
Karol Sójko
681e0378ae fix(auth): increase ttl for in progress duration of transitions 2023-09-29 11:05:54 +02:00
Karol Sójko
609e85f926 feat(syncing-server): allow surviving only upon account deletion (#857) 2023-09-29 10:51:26 +02:00
Karol Sójko
e4ca310707 fix: add paging memory to integrity check 2023-09-29 10:47:50 +02:00
standardci
d606493356 chore(release): publish new version
- @standardnotes/auth-server@1.148.1
 - @standardnotes/home-server@1.16.10
2023-09-29 08:14:08 +00:00
Karol Sójko
5ef6c5c14a fix(auth): disable transitions retriggering if they are in progress 2023-09-28 14:40:37 +02:00
standardci
0188f290f9 chore(release): publish new version
- @standardnotes/analytics@2.27.2
 - @standardnotes/api-gateway@1.75.7
 - @standardnotes/auth-server@1.148.0
 - @standardnotes/domain-events-infra@1.13.1
 - @standardnotes/domain-events@2.131.1
 - @standardnotes/event-store@1.12.2
 - @standardnotes/files-server@1.25.0
 - @standardnotes/home-server@1.16.9
 - @standardnotes/revisions-server@1.38.2
 - @standardnotes/scheduler-server@1.21.2
 - @standardnotes/security@1.15.0
 - @standardnotes/syncing-server@1.109.2
 - @standardnotes/time@1.17.0
 - @standardnotes/websockets-server@1.11.2
2023-09-28 11:39:49 +00:00
Karol Sójko
676cf36f8d feat: block file operations during transition (#856)
* feat: block file operations during transition

* fix: tracing sessions

* fix fs file removal

* fix: checking if directory exists before listing files

* fix: removing shared vault user on auth side
2023-09-28 13:10:58 +02:00
Karol Sójko
f8aef6c8ef feat: archiving failed run logs 2023-09-27 14:20:34 +02:00
Karol Sójko
5bf8cf49c1 feat: parametrize test suite to be run 2023-09-27 12:14:33 +02:00
standardci
51cd0a4dad chore(release): publish new version
- @standardnotes/analytics@2.27.1
 - @standardnotes/api-gateway@1.75.6
 - @standardnotes/auth-server@1.147.1
 - @standardnotes/domain-core@1.34.1
 - @standardnotes/event-store@1.12.1
 - @standardnotes/files-server@1.24.1
 - @standardnotes/home-server@1.16.8
 - @standardnotes/revisions-server@1.38.1
 - @standardnotes/scheduler-server@1.21.1
 - @standardnotes/settings@1.21.41
 - @standardnotes/syncing-server@1.109.1
 - @standardnotes/websockets-server@1.11.1
2023-09-27 09:45:40 +00:00
Karol Sójko
1d06ffe9d5 fix: removing items in a vault and notifying about designated survivor (#855)
* fix: removing items in a vault and notifying about designated survivor

* fix deleting shared vault items
2023-09-27 11:10:41 +02:00
standardci
dbf532f55e chore(release): publish new version
- @standardnotes/analytics@2.27.0
 - @standardnotes/api-gateway@1.75.5
 - @standardnotes/auth-server@1.147.0
 - @standardnotes/common@1.51.0
 - @standardnotes/domain-core@1.34.0
 - @standardnotes/domain-events-infra@1.13.0
 - @standardnotes/domain-events@2.131.0
 - @standardnotes/event-store@1.12.0
 - @standardnotes/files-server@1.24.0
 - @standardnotes/home-server@1.16.7
 - @standardnotes/predicates@1.7.0
 - @standardnotes/revisions-server@1.38.0
 - @standardnotes/scheduler-server@1.21.0
 - @standardnotes/security@1.14.0
 - @standardnotes/settings@1.21.40
 - @standardnotes/syncing-server@1.109.0
 - @standardnotes/time@1.16.0
 - @standardnotes/websockets-server@1.11.0
2023-09-26 10:05:20 +00:00
Karol Sójko
ca6dbc0053 feat: refactor handling revision creation from dump (#854)
* feat: refactor handling revision creation from dump

* fix: dump repository handling
2023-09-26 11:47:41 +02:00
standardci
1bb5980b45 chore(release): publish new version
- @standardnotes/analytics@2.26.24
 - @standardnotes/api-gateway@1.75.4
 - @standardnotes/auth-server@1.146.4
 - @standardnotes/domain-core@1.33.2
 - @standardnotes/event-store@1.11.52
 - @standardnotes/files-server@1.23.2
 - @standardnotes/home-server@1.16.6
 - @standardnotes/revisions-server@1.37.3
 - @standardnotes/scheduler-server@1.20.56
 - @standardnotes/settings@1.21.39
 - @standardnotes/syncing-server@1.108.2
 - @standardnotes/websockets-server@1.10.53
2023-09-25 16:42:43 +00:00
Karol Sójko
a02a28774b fix(domain-core): notification paylod to string casting 2023-09-25 18:24:38 +02:00
standardci
2d9b3578b6 chore(release): publish new version
- @standardnotes/analytics@2.26.23
 - @standardnotes/api-gateway@1.75.3
 - @standardnotes/auth-server@1.146.3
 - @standardnotes/domain-core@1.33.1
 - @standardnotes/event-store@1.11.51
 - @standardnotes/files-server@1.23.1
 - @standardnotes/home-server@1.16.5
 - @standardnotes/revisions-server@1.37.2
 - @standardnotes/scheduler-server@1.20.55
 - @standardnotes/settings@1.21.38
 - @standardnotes/syncing-server@1.108.1
 - @standardnotes/websockets-server@1.10.52
2023-09-25 15:28:21 +00:00
Karol Sójko
3d5e747590 fix(syncing-server): another spec 2023-09-25 17:10:30 +02:00
Karol Sójko
94467747ac fix(syncing-server): specs 2023-09-25 15:52:35 +02:00
Karol Sójko
cebab59a02 fix: refactor the structure of notifications (#853) 2023-09-25 15:40:51 +02:00
standardci
09e1a892ca chore(release): publish new version
- @standardnotes/analytics@2.26.22
 - @standardnotes/api-gateway@1.75.2
 - @standardnotes/auth-server@1.146.2
 - @standardnotes/domain-events-infra@1.12.34
 - @standardnotes/domain-events@2.130.0
 - @standardnotes/event-store@1.11.50
 - @standardnotes/files-server@1.23.0
 - @standardnotes/home-server@1.16.4
 - @standardnotes/revisions-server@1.37.1
 - @standardnotes/scheduler-server@1.20.54
 - @standardnotes/syncing-server@1.108.0
 - @standardnotes/websockets-server@1.10.51
2023-09-25 11:53:52 +00:00
Karol Sójko
7b1eec21e5 feat: remove shared vault files upon shared vault removal (#852)
* feat: remove shared vault files upon shared vault removal

* fix: link files queue with syncing-server-js topic
2023-09-25 12:56:31 +02:00
standardci
a58262d584 chore(release): publish new version
- @standardnotes/home-server@1.16.3
 - @standardnotes/syncing-server@1.107.0
2023-09-25 09:43:23 +00:00
Karol Sójko
a8f03e157b feat(syncing-server): transfer shared vault items (#851) 2023-09-25 11:09:33 +02:00
standardci
a401962bcd chore(release): publish new version
- @standardnotes/home-server@1.16.2
 - @standardnotes/revisions-server@1.37.0
 - @standardnotes/syncing-server@1.106.0
2023-09-25 08:15:14 +00:00
Karol Sójko
9759814f63 feat: add storing paging progress in redis 2023-09-25 09:40:49 +02:00
standardci
c7cf53722c chore(release): publish new version
- @standardnotes/analytics@2.26.21
 - @standardnotes/api-gateway@1.75.1
 - @standardnotes/auth-server@1.146.1
 - @standardnotes/domain-events-infra@1.12.33
 - @standardnotes/domain-events@2.129.1
 - @standardnotes/event-store@1.11.49
 - @standardnotes/files-server@1.22.28
 - @standardnotes/home-server@1.16.1
 - @standardnotes/revisions-server@1.36.7
 - @standardnotes/scheduler-server@1.20.53
 - @standardnotes/syncing-server@1.105.1
 - @standardnotes/websockets-server@1.10.50
2023-09-25 07:30:06 +00:00
Karol Sójko
8cb33dc906 fix: add paging progress log 2023-09-25 08:51:33 +02:00
Karol Sójko
1d73e4f072 fix: remember paging progress on transitioning 2023-09-25 08:50:59 +02:00
standardci
0a0f82ea3d chore(release): publish new version
- @standardnotes/auth-server@1.146.0
 - @standardnotes/home-server@1.16.0
 - @standardnotes/revisions-server@1.36.6
 - @standardnotes/syncing-server@1.105.0
2023-09-22 12:43:13 +00:00
Karol Sójko
f9b1f40ddf fix(auth): register specs 2023-09-22 14:23:21 +02:00
Karol Sójko
0562b0a621 fix: add more logs to transition process 2023-09-22 14:19:14 +02:00
Karol Sójko
15ed1fd789 fix: remove excessive logs 2023-09-22 14:16:51 +02:00
Karol Sójko
5001496c7b feat: remove transition mode from code 2023-09-22 14:13:32 +02:00
Karol Sójko
0a1080ce2a feat(syncing-server): transfer shared vault ownership to designated survivor upon account deletion (#845) 2023-09-22 14:11:01 +02:00
standardci
4802d7e876 chore(release): publish new version
- @standardnotes/home-server@1.15.80
 - @standardnotes/syncing-server@1.104.0
2023-09-22 11:33:45 +00:00
Karol Sójko
bcd95cdbe9 feat(syncing-server): add designated survivors in fetching shared vaults response (#844) 2023-09-22 13:15:11 +02:00
standardci
d50c4440c2 chore(release): publish new version
- @standardnotes/home-server@1.15.79
 - @standardnotes/revisions-server@1.36.5
 - @standardnotes/syncing-server@1.103.1
2023-09-22 09:57:54 +00:00
Karol Sójko
921c30f641 fix: integrity check during transition 2023-09-22 11:27:54 +02:00
Karol Sójko
22540ee834 fix: processing migration optimization 2023-09-22 11:17:03 +02:00
Karol Sójko
4f4443a882 fix: disable cleaning secondary database on transition 2023-09-22 11:17:02 +02:00
standardci
80dbacf933 chore(release): publish new version
- @standardnotes/auth-server@1.145.0
 - @standardnotes/home-server@1.15.78
 - @standardnotes/syncing-server@1.103.0
2023-09-22 09:07:07 +00:00
Karol Sójko
dc77ff3e45 feat: remove user from all shared vaults upon account deletion (#843) 2023-09-22 10:49:53 +02:00
standardci
6515dcf487 chore(release): publish new version
- @standardnotes/home-server@1.15.77
 - @standardnotes/syncing-server@1.102.2
2023-09-22 07:54:08 +00:00
Karol Sójko
d0fd6b98df fix(syncing-server): error message 2023-09-22 09:35:37 +02:00
standardci
345efacb44 chore(release): publish new version
- @standardnotes/home-server@1.15.76
 - @standardnotes/revisions-server@1.36.4
2023-09-21 13:20:19 +00:00
Karol Sójko
d0dba1b66d fix(revisions): add log info about skipping already existing revision 2023-09-21 15:00:05 +02:00
standardci
da119af8b2 chore(release): publish new version
- @standardnotes/home-server@1.15.75
 - @standardnotes/syncing-server@1.102.1
2023-09-21 12:46:35 +00:00
Karol Sójko
a5da42bddd fix(syncing-server): add missing binding 2023-09-21 14:28:36 +02:00
standardci
12767237d2 chore(release): publish new version
- @standardnotes/analytics@2.26.20
 - @standardnotes/api-gateway@1.75.0
 - @standardnotes/auth-server@1.144.0
 - @standardnotes/domain-core@1.33.0
 - @standardnotes/domain-events-infra@1.12.32
 - @standardnotes/domain-events@2.129.0
 - @standardnotes/event-store@1.11.48
 - @standardnotes/files-server@1.22.27
 - @standardnotes/home-server@1.15.74
 - @standardnotes/revisions-server@1.36.3
 - @standardnotes/scheduler-server@1.20.52
 - @standardnotes/settings@1.21.37
 - @standardnotes/syncing-server@1.102.0
 - @standardnotes/websockets-server@1.10.49
2023-09-21 11:12:44 +00:00
Karol Sójko
230c96dcf1 feat: add designating a survivor in shared vault (#841)
* feat: add designating a survivor in shared vault

* add designated survivor property to http representation

* fix: specs

* fix: more specs

* fix: another spec fix

* fix: yet another spec fix
2023-09-21 12:26:08 +02:00
standardci
e2696fcd1a chore(release): publish new version
- @standardnotes/home-server@1.15.73
 - @standardnotes/revisions-server@1.36.2
2023-09-21 10:13:33 +00:00
Karol Sójko
a621cf1e3b fix(revisions): rename revisions table to all users stuck mid-migration process - fixes #836 (#842) 2023-09-21 11:55:55 +02:00
standardci
db35b9fcab chore(release): publish new version
- @standardnotes/home-server@1.15.72
 - @standardnotes/revisions-server@1.36.1
 - @standardnotes/syncing-server@1.101.1
2023-09-21 07:34:07 +00:00
Karol Sójko
880db1038a fix: secondary database catch up time 2023-09-21 09:17:00 +02:00
295 changed files with 6300 additions and 2381 deletions

View File

@@ -38,6 +38,10 @@ jobs:
run: |
jq '(.containerDefinitions[] | select(.name=="${{ inputs.service_name }}-prod") | .environment[] | select(.name=="VERSION")).value = "${{ github.sha }}"' task-definition.json > tmp.json && mv tmp.json task-definition.json
- name: Fill in the new package version in the Amazon ECS task definition
run: |
jq '(.containerDefinitions[] | select(.name=="${{ inputs.service_name }}-prod") | .environment[] | select(.name=="npm_package_version")).value = "${{ github.sha }}"' task-definition.json > tmp.json && mv tmp.json task-definition.json
- name: Fill in the new image ID in the Amazon ECS task definition
id: task-def-prod
uses: aws-actions/amazon-ecs-render-task-definition@v1

View File

@@ -7,6 +7,10 @@ on:
type: string
default: latest
description: The Docker image tag used for SNJS container
suite:
type: string
default: all
description: The test suite to run
secrets:
DOCKER_USERNAME:
required: true
@@ -18,153 +22,16 @@ on:
required: true
jobs:
e2e:
name: (Self Hosting) E2E Test Suite
strategy:
fail-fast: false
matrix:
secondary_db_enabled: [true, false]
transition_mode_enabled: [true, false]
runs-on: ubuntu-latest
services:
snjs:
image: standardnotes/snjs:${{ inputs.snjs_image_tag }}
ports:
- 9001:9001
steps:
- uses: actions/checkout@v3
- name: Set up Node
uses: actions/setup-node@v3
with:
registry-url: 'https://registry.npmjs.org'
node-version-file: '.nvmrc'
- name: Install
run: yarn install --immutable
- name: Run Server
run: docker compose -f docker-compose.ci.yml up -d
env:
DB_TYPE: mysql
CACHE_TYPE: redis
SECONDARY_DB_ENABLED: ${{ matrix.secondary_db_enabled }}
TRANSITION_MODE_ENABLED: ${{ matrix.transition_mode_enabled }}
- name: Wait for server to start
run: docker/is-available.sh http://localhost:3123 $(pwd)/logs
- name: Run E2E Test Suite
run: yarn dlx mocha-headless-chrome --timeout 3600000 -f http://localhost:9001/mocha/test.html
- name: Show logs on failure
if: ${{ failure() }}
run: |
echo "# Errors:"
tail -n 100 logs/*.err
echo "# Logs:"
tail -n 100 logs/*.log
e2e-self-hosted:
uses: standardnotes/server/.github/workflows/e2e-self-hosted.yml@main
with:
snjs_image_tag: ${{ inputs.snjs_image_tag }}
suite: ${{ inputs.suite }}
secrets: inherit
e2e-home-server:
name: (Home Server) E2E Test Suite
strategy:
fail-fast: false
matrix:
db_type: [mysql, sqlite]
cache_type: [redis, memory]
secondary_db_enabled: [true, false]
transition_mode_enabled: [true, false]
runs-on: ubuntu-latest
services:
snjs:
image: standardnotes/snjs:${{ inputs.snjs_image_tag }}
ports:
- 9001:9001
cache:
image: redis
ports:
- 6379:6379
db:
image: mysql
ports:
- 3306:3306
env:
MYSQL_ROOT_PASSWORD: root
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
- name: Set up Node
uses: actions/setup-node@v3
with:
registry-url: 'https://registry.npmjs.org'
node-version-file: '.nvmrc'
- name: Install Dependencies
run: yarn install --immutable
- name: Build
run: yarn build
- name: Copy dotenv file
run: cp packages/home-server/.env.sample packages/home-server/.env
- name: Fill in env variables
run: |
sed -i "s/JWT_SECRET=/JWT_SECRET=$(openssl rand -hex 32)/g" packages/home-server/.env
sed -i "s/AUTH_JWT_SECRET=/AUTH_JWT_SECRET=$(openssl rand -hex 32)/g" packages/home-server/.env
sed -i "s/ENCRYPTION_SERVER_KEY=/ENCRYPTION_SERVER_KEY=$(openssl rand -hex 32)/g" packages/home-server/.env
sed -i "s/PSEUDO_KEY_PARAMS_KEY=/PSEUDO_KEY_PARAMS_KEY=$(openssl rand -hex 32)/g" packages/home-server/.env
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=2" >> packages/home-server/.env
echo "DB_HOST=localhost" >> 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 "DB_DEBUG_LEVEL=all" >> 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 "TRANSITION_MODE_ENABLED=${{ matrix.transition_mode_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
- name: Run Server
run: nohup yarn workspace @standardnotes/home-server start > logs/output.log 2>&1 &
env:
PORT: 3123
- name: Wait for server to start
run: for i in {1..30}; do curl -s http://localhost:3123/healthcheck && break || sleep 1; done
- name: Run E2E Test Suite
run: yarn dlx mocha-headless-chrome --timeout 3600000 -f http://localhost:9001/mocha/test.html
- name: Show logs on failure
if: ${{ failure() }}
run: tail -n 500 logs/output.log
uses: standardnotes/server/.github/workflows/e2e-home-server.yml@main
with:
snjs_image_tag: ${{ inputs.snjs_image_tag }}
suite: ${{ inputs.suite }}
secrets: inherit

128
.github/workflows/e2e-home-server.yml vendored Normal file
View File

@@ -0,0 +1,128 @@
name: E2E Home Server Test Suite
on:
workflow_call:
inputs:
snjs_image_tag:
type: string
default: latest
description: The Docker image tag used for SNJS container
suite:
type: string
default: all
description: The test suite to run
secrets:
DOCKER_USERNAME:
required: true
DOCKER_PASSWORD:
required: true
AWS_ACCESS_KEY_ID:
required: true
AWS_SECRET_ACCESS_KEY:
required: true
jobs:
e2e-home-server:
name: (Home Server) E2E Test Suite
strategy:
fail-fast: false
matrix:
db_type: [mysql, sqlite]
cache_type: [redis, memory]
secondary_db_enabled: [true, false]
runs-on: ubuntu-latest
services:
snjs:
image: standardnotes/snjs:${{ inputs.snjs_image_tag }}
ports:
- 9001:9001
cache:
image: redis
ports:
- 6379:6379
db:
image: mysql
ports:
- 3306:3306
env:
MYSQL_ROOT_PASSWORD: root
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
- name: Set up Node
uses: actions/setup-node@v3
with:
registry-url: 'https://registry.npmjs.org'
node-version-file: '.nvmrc'
- name: Install Dependencies
run: yarn install --immutable
- name: Build
run: yarn build
- name: Copy dotenv file
run: cp packages/home-server/.env.sample packages/home-server/.env
- name: Fill in env variables
run: |
sed -i "s/JWT_SECRET=/JWT_SECRET=$(openssl rand -hex 32)/g" packages/home-server/.env
sed -i "s/AUTH_JWT_SECRET=/AUTH_JWT_SECRET=$(openssl rand -hex 32)/g" packages/home-server/.env
sed -i "s/ENCRYPTION_SERVER_KEY=/ENCRYPTION_SERVER_KEY=$(openssl rand -hex 32)/g" packages/home-server/.env
sed -i "s/PSEUDO_KEY_PARAMS_KEY=/PSEUDO_KEY_PARAMS_KEY=$(openssl rand -hex 32)/g" packages/home-server/.env
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=2" >> packages/home-server/.env
echo "DB_HOST=localhost" >> 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 "DB_DEBUG_LEVEL=all" >> 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
- name: Run Server
run: nohup yarn workspace @standardnotes/home-server start > logs/output.log 2>&1 &
env:
PORT: 3123
- name: Wait for server to start
run: for i in {1..30}; do curl -s http://localhost:3123/healthcheck && break || sleep 1; done
- name: Run E2E Test Suite
run: yarn dlx mocha-headless-chrome --timeout 3600000 -f http://localhost:9001/mocha/test.html?suite=${{ inputs.suite }}
- name: Archive failed run logs
if: ${{ failure() }}
uses: actions/upload-artifact@v3
with:
name: home-server-failure-logs-${{ inputs.suite }}-${{ matrix.db_type }}-${{ matrix.cache_type }}-${{ matrix.secondary_db_enabled }}
retention-days: 5
path: |
logs/output.log

72
.github/workflows/e2e-self-hosted.yml vendored Normal file
View File

@@ -0,0 +1,72 @@
name: E2E Self Hosted Test Suite
on:
workflow_call:
inputs:
snjs_image_tag:
type: string
default: latest
description: The Docker image tag used for SNJS container
suite:
type: string
default: all
description: The test suite to run
secrets:
DOCKER_USERNAME:
required: true
DOCKER_PASSWORD:
required: true
AWS_ACCESS_KEY_ID:
required: true
AWS_SECRET_ACCESS_KEY:
required: true
jobs:
e2e:
name: (Self Hosting) E2E Test Suite
strategy:
fail-fast: false
matrix:
secondary_db_enabled: [true, false]
runs-on: ubuntu-latest
services:
snjs:
image: standardnotes/snjs:${{ inputs.snjs_image_tag }}
ports:
- 9001:9001
steps:
- uses: actions/checkout@v3
- name: Set up Node
uses: actions/setup-node@v3
with:
registry-url: 'https://registry.npmjs.org'
node-version-file: '.nvmrc'
- name: Install
run: yarn install --immutable
- name: Run Server
run: docker compose -f docker-compose.ci.yml up -d
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
- name: Run E2E Test Suite
run: yarn dlx mocha-headless-chrome --timeout 3600000 -f http://localhost:9001/mocha/test.html?suite=${{ inputs.suite }}
- name: Archive failed run logs
if: ${{ failure() }}
uses: actions/upload-artifact@v3
with:
name: self-hosted-failure-logs-${{ inputs.suite }}-${{ matrix.secondary_db_enabled }}
retention-days: 5
path: |
logs/*.err
logs/*.log

View File

@@ -1,6 +1,6 @@
name: E2E Test Suite On Self Hosted Server
name: E2E Test Suite
run-name: E2E Test Suite against ${{ inputs.ref_name }} by ${{ inputs.author }}
run-name: E2E ${{ inputs.suite }} Test Suite against ${{ inputs.ref_name }} by ${{ inputs.author }}
on:
schedule:
@@ -11,6 +11,10 @@ on:
type: string
default: latest
description: The Docker image tag used for SNJS container
suite:
type: string
default: all
description: The test suite to run
author:
type: string
default: unknown
@@ -26,4 +30,5 @@ jobs:
uses: standardnotes/server/.github/workflows/common-e2e.yml@main
with:
snjs_image_tag: ${{ inputs.snjs_image_tag || 'latest' }}
suite: ${{ inputs.suite || 'all' }}
secrets: inherit

View File

@@ -95,9 +95,20 @@ jobs:
- name: Test
run: yarn test
e2e:
e2e-base:
needs: build
name: E2E
name: E2E Base Suite
uses: standardnotes/server/.github/workflows/common-e2e.yml@main
with:
snjs_image_tag: 'latest'
suite: 'base'
secrets: inherit
# e2e-vaults:
# needs: build
# name: E2E Vaults Suite
# uses: standardnotes/server/.github/workflows/common-e2e.yml@main
# with:
# snjs_image_tag: 'latest'
# suite: 'vaults'
# secrets: inherit

View File

@@ -95,20 +95,32 @@ jobs:
- name: Test
run: yarn test
e2e:
e2e-base:
needs: build
name: E2E
name: E2E Base Suite
uses: standardnotes/server/.github/workflows/common-e2e.yml@main
with:
snjs_image_tag: 'latest'
suite: 'base'
secrets: inherit
# e2e-vaults:
# needs: build
# name: E2E Vaults Suite
# uses: standardnotes/server/.github/workflows/common-e2e.yml@main
# with:
# snjs_image_tag: 'latest'
# suite: 'vaults'
# secrets: inherit
publish-self-hosting:
needs: [ test, lint, e2e ]
needs: [ test, lint, e2e-base ]
name: Publish Self Hosting Docker Image
uses: standardnotes/server/.github/workflows/common-self-hosting.yml@main
secrets: inherit
publish-services:
needs: [ test, lint, e2e ]
needs: [ test, lint, e2e-base ]
runs-on: ubuntu-latest

22
.pnp.cjs generated
View File

@@ -5945,7 +5945,7 @@ const RAW_RUNTIME_STATE =
["newrelic", "npm:11.0.0"],\
["prettier", "npm:3.0.3"],\
["reflect-metadata", "npm:0.1.13"],\
["sqs-consumer", "virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:6.2.1"],\
["sqs-consumer", "virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:7.3.0"],\
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.0"],\
["typescript", "patch:typescript@npm%3A5.0.4#optional!builtin<compat/typescript>::version=5.0.4&hash=b5f058"],\
["winston", "npm:3.9.0"]\
@@ -6156,6 +6156,7 @@ const RAW_RUNTIME_STATE =
["@types/cors", "npm:2.8.13"],\
["@types/dotenv", "npm:8.2.0"],\
["@types/express", "npm:4.17.17"],\
["@types/ioredis", "npm:5.0.0"],\
["@types/jest", "npm:29.5.2"],\
["@types/newrelic", "npm:9.14.0"],\
["@types/node", "npm:20.5.7"],\
@@ -6168,6 +6169,7 @@ const RAW_RUNTIME_STATE =
["express", "npm:4.18.2"],\
["inversify", "npm:6.0.1"],\
["inversify-express-utils", "npm:6.4.3"],\
["ioredis", "npm:5.3.2"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.5.0"],\
["mongodb", "virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:6.0.0"],\
["mysql2", "npm:3.3.3"],\
@@ -6340,6 +6342,7 @@ const RAW_RUNTIME_STATE =
["@types/cors", "npm:2.8.13"],\
["@types/dotenv", "npm:8.2.0"],\
["@types/express", "npm:4.17.17"],\
["@types/ioredis", "npm:5.0.0"],\
["@types/jest", "npm:29.5.2"],\
["@types/jsonwebtoken", "npm:9.0.2"],\
["@types/newrelic", "npm:9.14.0"],\
@@ -6359,6 +6362,7 @@ const RAW_RUNTIME_STATE =
["helmet", "npm:7.0.0"],\
["inversify", "npm:6.0.1"],\
["inversify-express-utils", "npm:6.4.3"],\
["ioredis", "npm:5.3.2"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.5.0"],\
["jsonwebtoken", "npm:9.0.0"],\
["mongodb", "virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:6.0.0"],\
@@ -15713,17 +15717,17 @@ const RAW_RUNTIME_STATE =
}]\
]],\
["sqs-consumer", [\
["npm:6.2.1", {\
"packageLocation": "./.yarn/cache/sqs-consumer-npm-6.2.1-857abd3d30-a903daa836.zip/node_modules/sqs-consumer/",\
["npm:7.3.0", {\
"packageLocation": "./.yarn/cache/sqs-consumer-npm-7.3.0-a47c08ef71-367ea2a6f3.zip/node_modules/sqs-consumer/",\
"packageDependencies": [\
["sqs-consumer", "npm:6.2.1"]\
["sqs-consumer", "npm:7.3.0"]\
],\
"linkType": "SOFT"\
}],\
["virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:6.2.1", {\
"packageLocation": "./.yarn/__virtual__/sqs-consumer-virtual-603a7c5831/0/cache/sqs-consumer-npm-6.2.1-857abd3d30-a903daa836.zip/node_modules/sqs-consumer/",\
["virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:7.3.0", {\
"packageLocation": "./.yarn/__virtual__/sqs-consumer-virtual-bf07118bf0/0/cache/sqs-consumer-npm-7.3.0-a47c08ef71-367ea2a6f3.zip/node_modules/sqs-consumer/",\
"packageDependencies": [\
["sqs-consumer", "virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:6.2.1"],\
["sqs-consumer", "virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:7.3.0"],\
["@aws-sdk/client-sqs", "npm:3.342.0"],\
["@types/aws-sdk__client-sqs", null],\
["debug", "virtual:ac3d8e680759ce54399273724d44e041d6c9b73454d191d411a8c44bb27e22f02aaf6ed9d3ad0ac1c298eac4833cff369c9c7b84c573016112c4f84be2cd8543#npm:4.3.4"]\
@@ -16772,7 +16776,7 @@ const RAW_RUNTIME_STATE =
["@types/better-sqlite3", null],\
["@types/google-cloud__spanner", null],\
["@types/hdb-pool", null],\
["@types/ioredis", null],\
["@types/ioredis", "npm:5.0.0"],\
["@types/mongodb", null],\
["@types/mssql", null],\
["@types/mysql2", null],\
@@ -16796,7 +16800,7 @@ const RAW_RUNTIME_STATE =
["dotenv", "npm:16.1.3"],\
["glob", "npm:8.1.0"],\
["hdb-pool", null],\
["ioredis", null],\
["ioredis", "npm:5.3.2"],\
["mkdirp", "npm:2.1.6"],\
["mongodb", "virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:6.0.0"],\
["mssql", null],\

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

@@ -24,7 +24,6 @@ services:
DB_TYPE: "${DB_TYPE}"
CACHE_TYPE: "${CACHE_TYPE}"
SECONDARY_DB_ENABLED: "${SECONDARY_DB_ENABLED}"
TRANSITION_MODE_ENABLED: "${TRANSITION_MODE_ENABLED}"
container_name: server-ci
ports:
- 3123:3000

View File

@@ -68,9 +68,6 @@ fi
if [ -z "$SECONDARY_DB_ENABLED" ]; then
export SECONDARY_DB_ENABLED=false
fi
if [ -z "$TRANSITION_MODE_ENABLED" ]; then
export TRANSITION_MODE_ENABLED=false
fi
export DB_MIGRATIONS_PATH="dist/migrations/*.js"
#########

View File

@@ -139,6 +139,11 @@ LINKING_RESULT=$(link_queue_and_topic $AUTH_TOPIC_ARN $FILES_QUEUE_ARN)
echo "linking done:"
echo "$LINKING_RESULT"
echo "linking topic $SYNCING_SERVER_TOPIC_ARN to queue $FILES_QUEUE_ARN"
LINKING_RESULT=$(link_queue_and_topic $SYNCING_SERVER_TOPIC_ARN $FILES_QUEUE_ARN)
echo "linking done:"
echo "$LINKING_RESULT"
QUEUE_NAME="syncing-server-local-queue"
echo "creating queue $QUEUE_NAME"

View File

@@ -20,7 +20,7 @@
"release": "lerna version --conventional-graduate --conventional-commits --yes -m \"chore(release): publish new version\"",
"publish": "lerna publish from-git --yes --no-verify-access --loglevel verbose",
"postversion": "./scripts/push-tags-one-by-one.sh",
"e2e": "yarn workspace @standardnotes/home-server run build && PORT=3123 yarn workspace @standardnotes/home-server start",
"e2e": "yarn build && PORT=3123 yarn workspace @standardnotes/home-server start",
"start": "yarn workspace @standardnotes/home-server run build && yarn workspace @standardnotes/home-server start"
},
"devDependencies": {

View File

@@ -3,6 +3,90 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.28.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.28.1...@standardnotes/analytics@2.28.2) (2023-10-09)
### Bug Fixes
* remove xray sdk in favor of opentelemetry ([b736dab](https://github.com/standardnotes/server/commit/b736dab3c1f76c9e03c4bc7bbf153dcb3309b7cb))
## [2.28.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.28.0...@standardnotes/analytics@2.28.1) (2023-10-06)
### Bug Fixes
* add xray-sdk to background processors ([a45b5b6](https://github.com/standardnotes/server/commit/a45b5b69b5d68c2e696c30f0ba5ad22d313321e6))
# [2.28.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.27.10...@standardnotes/analytics@2.28.0) (2023-10-06)
### Features
* add xray to analytics scheduler and websockets ([f0531d6](https://github.com/standardnotes/server/commit/f0531d68cb77036222f2a34602819f11e6a2697d))
## [2.27.10](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.27.9...@standardnotes/analytics@2.27.10) (2023-10-05)
**Note:** Version bump only for package @standardnotes/analytics
## [2.27.9](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.27.8...@standardnotes/analytics@2.27.9) (2023-10-05)
**Note:** Version bump only for package @standardnotes/analytics
## [2.27.8](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.27.7...@standardnotes/analytics@2.27.8) (2023-10-04)
**Note:** Version bump only for package @standardnotes/analytics
## [2.27.7](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.27.6...@standardnotes/analytics@2.27.7) (2023-10-04)
**Note:** Version bump only for package @standardnotes/analytics
## [2.27.6](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.27.5...@standardnotes/analytics@2.27.6) (2023-10-04)
**Note:** Version bump only for package @standardnotes/analytics
## [2.27.5](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.27.4...@standardnotes/analytics@2.27.5) (2023-10-04)
**Note:** Version bump only for package @standardnotes/analytics
## [2.27.4](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.27.3...@standardnotes/analytics@2.27.4) (2023-10-03)
**Note:** Version bump only for package @standardnotes/analytics
## [2.27.3](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.27.2...@standardnotes/analytics@2.27.3) (2023-10-03)
**Note:** Version bump only for package @standardnotes/analytics
## [2.27.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.27.1...@standardnotes/analytics@2.27.2) (2023-09-28)
**Note:** Version bump only for package @standardnotes/analytics
## [2.27.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.27.0...@standardnotes/analytics@2.27.1) (2023-09-27)
**Note:** Version bump only for package @standardnotes/analytics
# [2.27.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.24...@standardnotes/analytics@2.27.0) (2023-09-26)
### Features
* refactor handling revision creation from dump ([#854](https://github.com/standardnotes/server/issues/854)) ([ca6dbc0](https://github.com/standardnotes/server/commit/ca6dbc00537bb20f508f9310b1a838421f53a643))
## [2.26.24](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.23...@standardnotes/analytics@2.26.24) (2023-09-25)
**Note:** Version bump only for package @standardnotes/analytics
## [2.26.23](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.22...@standardnotes/analytics@2.26.23) (2023-09-25)
**Note:** Version bump only for package @standardnotes/analytics
## [2.26.22](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.21...@standardnotes/analytics@2.26.22) (2023-09-25)
**Note:** Version bump only for package @standardnotes/analytics
## [2.26.21](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.20...@standardnotes/analytics@2.26.21) (2023-09-25)
**Note:** Version bump only for package @standardnotes/analytics
## [2.26.20](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.19...@standardnotes/analytics@2.26.20) (2023-09-21)
**Note:** Version bump only for package @standardnotes/analytics
## [2.26.19](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.18...@standardnotes/analytics@2.26.19) (2023-09-20)
**Note:** Version bump only for package @standardnotes/analytics

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/analytics",
"version": "2.26.19",
"version": "2.28.2",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
@@ -18,7 +18,7 @@
"build": "tsc --build",
"lint": "eslint . --ext .ts",
"lint:fix": "eslint . --ext .ts --fix",
"test": "jest --coverage --config=./jest.config.js --maxWorkers=50%",
"test": "jest --coverage --no-cache --config=./jest.config.js --maxWorkers=50%",
"worker": "yarn node dist/bin/worker.js",
"report": "yarn node dist/bin/report.js",
"setup:env": "cp .env.sample .env",

View File

@@ -18,7 +18,6 @@ import {
SNSDomainEventPublisher,
SQSDomainEventSubscriberFactory,
SQSEventMessageHandler,
SQSNewRelicEventMessageHandler,
} from '@standardnotes/domain-events-infra'
import { Timer, TimerInterface } from '@standardnotes/time'
import { PeriodKeyGeneratorInterface } from '../Domain/Time/PeriodKeyGeneratorInterface'
@@ -244,11 +243,7 @@ export class ContainerConfigLoader {
container
.bind<DomainEventMessageHandlerInterface>(TYPES.DomainEventMessageHandler)
.toConstantValue(
env.get('NEW_RELIC_ENABLED', true) === 'true'
? new SQSNewRelicEventMessageHandler(eventHandlers, container.get(TYPES.Logger))
: new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Logger)),
)
.toConstantValue(new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Logger)))
container
.bind<DomainEventSubscriberFactoryInterface>(TYPES.DomainEventSubscriberFactory)
.toConstantValue(

View File

@@ -3,6 +3,94 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.77.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.77.1...@standardnotes/api-gateway@1.77.2) (2023-10-09)
### Bug Fixes
* remove xray sdk in favor of opentelemetry ([b736dab](https://github.com/standardnotes/api-gateway/commit/b736dab3c1f76c9e03c4bc7bbf153dcb3309b7cb))
## [1.77.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.77.0...@standardnotes/api-gateway@1.77.1) (2023-10-06)
**Note:** Version bump only for package @standardnotes/api-gateway
# [1.77.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.76.2...@standardnotes/api-gateway@1.77.0) (2023-10-05)
### Features
* setting xray segment user on api-gateway level ([3ee4941](https://github.com/standardnotes/api-gateway/commit/3ee49416f8e19207540141d98baa7f68880929bd))
## [1.76.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.76.1...@standardnotes/api-gateway@1.76.2) (2023-10-05)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.76.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.76.0...@standardnotes/api-gateway@1.76.1) (2023-10-05)
**Note:** Version bump only for package @standardnotes/api-gateway
# [1.76.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.13...@standardnotes/api-gateway@1.76.0) (2023-10-04)
### Features
* **api-gateaway:** configure aws-xray-sdk ([dc76113](https://github.com/standardnotes/api-gateway/commit/dc7611391515dd49a8e9b7ce8ac5e128cd7af0a8))
## [1.75.13](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.12...@standardnotes/api-gateway@1.75.13) (2023-10-04)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.75.12](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.11...@standardnotes/api-gateway@1.75.12) (2023-10-04)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.75.11](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.10...@standardnotes/api-gateway@1.75.11) (2023-10-04)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.75.10](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.9...@standardnotes/api-gateway@1.75.10) (2023-10-04)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.75.9](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.8...@standardnotes/api-gateway@1.75.9) (2023-10-03)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.75.8](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.7...@standardnotes/api-gateway@1.75.8) (2023-10-03)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.75.7](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.6...@standardnotes/api-gateway@1.75.7) (2023-09-28)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.75.6](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.5...@standardnotes/api-gateway@1.75.6) (2023-09-27)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.75.5](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.4...@standardnotes/api-gateway@1.75.5) (2023-09-26)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.75.4](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.3...@standardnotes/api-gateway@1.75.4) (2023-09-25)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.75.3](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.2...@standardnotes/api-gateway@1.75.3) (2023-09-25)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.75.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.1...@standardnotes/api-gateway@1.75.2) (2023-09-25)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.75.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.0...@standardnotes/api-gateway@1.75.1) (2023-09-25)
**Note:** Version bump only for package @standardnotes/api-gateway
# [1.75.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.74.17...@standardnotes/api-gateway@1.75.0) (2023-09-21)
### Features
* add designating a survivor in shared vault ([#841](https://github.com/standardnotes/api-gateway/issues/841)) ([230c96d](https://github.com/standardnotes/api-gateway/commit/230c96dcf1d8faed9ce8fe288549226da70317e6))
## [1.74.17](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.74.16...@standardnotes/api-gateway@1.74.17) (2023-09-20)
**Note:** Version bump only for package @standardnotes/api-gateway

View File

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

View File

@@ -1,6 +1,6 @@
import { Request, Response } from 'express'
import { inject } from 'inversify'
import { BaseHttpController, controller, httpDelete, httpGet } from 'inversify-express-utils'
import { BaseHttpController, controller, httpDelete, httpGet, httpPost } from 'inversify-express-utils'
import { TYPES } from '../../Bootstrap/Types'
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
@@ -42,4 +42,19 @@ export class SharedVaultUsersController extends BaseHttpController {
request.body,
)
}
@httpPost('/:userUuid/designate-survivor')
async designateSurvivor(request: Request, response: Response): Promise<void> {
await this.httpService.callSyncingServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier(
'POST',
'shared-vaults/:sharedVaultUuid/users/:userUuid/designate-survivor',
request.params.sharedVaultUuid,
request.params.userUuid,
),
request.body,
)
}
}

View File

@@ -89,6 +89,10 @@ export class EndpointResolver implements EndpointResolverInterface {
// Shared Vault Users Controller
['[GET]:shared-vaults/:sharedVaultUuid/users', 'sync.shared-vault-users.get-users'],
['[DELETE]:shared-vaults/:sharedVaultUuid/users/:userUuid', 'sync.shared-vault-users.remove-user'],
[
'[POST]:shared-vaults/:sharedVaultUuid/users/:userUuid/designate-survivor',
'sync.shared-vault-users.designate-survivor',
],
])
resolveEndpointOrMethodIdentifier(method: string, endpoint: string, ...params: string[]): string {

View File

@@ -3,6 +3,177 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.152.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.152.1...@standardnotes/auth-server@1.152.2) (2023-10-09)
### Bug Fixes
* remove xray sdk in favor of opentelemetry ([b736dab](https://github.com/standardnotes/server/commit/b736dab3c1f76c9e03c4bc7bbf153dcb3309b7cb))
## [1.152.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.152.0...@standardnotes/auth-server@1.152.1) (2023-10-06)
### Bug Fixes
* **auth:** checking for transition role when triggering transition ([79a44aa](https://github.com/standardnotes/server/commit/79a44aa51f15311fcaf76c39f93d1934ec1d135d))
# [1.152.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.151.2...@standardnotes/auth-server@1.152.0) (2023-10-06)
### Bug Fixes
* **auth:** strip user from transition role after migration ([afe9967](https://github.com/standardnotes/server/commit/afe9967d26b5be02d1dc76a740df614d81a6984e))
### Features
* switch transition direction ([27bea44](https://github.com/standardnotes/server/commit/27bea444cce4964feda04bad64e5f12a07415e0c))
## [1.151.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.151.1...@standardnotes/auth-server@1.151.2) (2023-10-06)
### Bug Fixes
* add xray-sdk to background processors ([a45b5b6](https://github.com/standardnotes/server/commit/a45b5b69b5d68c2e696c30f0ba5ad22d313321e6))
## [1.151.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.151.0...@standardnotes/auth-server@1.151.1) (2023-10-06)
**Note:** Version bump only for package @standardnotes/auth-server
# [1.151.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.150.9...@standardnotes/auth-server@1.151.0) (2023-10-05)
### Features
* setting xray segment user on api-gateway level ([3ee4941](https://github.com/standardnotes/server/commit/3ee49416f8e19207540141d98baa7f68880929bd))
## [1.150.9](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.150.8...@standardnotes/auth-server@1.150.9) (2023-10-05)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.150.8](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.150.7...@standardnotes/auth-server@1.150.8) (2023-10-05)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.150.7](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.150.6...@standardnotes/auth-server@1.150.7) (2023-10-04)
### Bug Fixes
* identifying services in workers ([eab78b3](https://github.com/standardnotes/server/commit/eab78b3a95ec82cb779d069d172169bfa92368c9))
## [1.150.6](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.150.5...@standardnotes/auth-server@1.150.6) (2023-10-04)
### Bug Fixes
* **auth:** disable users from registering to MongoDB ([d4579ce](https://github.com/standardnotes/server/commit/d4579ce21ed34ba433deb1fe2ff25c073fbe9622))
## [1.150.5](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.150.4...@standardnotes/auth-server@1.150.5) (2023-10-04)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.150.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.150.3...@standardnotes/auth-server@1.150.4) (2023-10-04)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.150.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.150.2...@standardnotes/auth-server@1.150.3) (2023-10-04)
### Bug Fixes
* **auth:** remove ec2 plugin from worker ([0281724](https://github.com/standardnotes/server/commit/02817241965db06cc02e9cca1d068446db0dee4e))
## [1.150.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.150.1...@standardnotes/auth-server@1.150.2) (2023-10-04)
### Bug Fixes
* **auth:** remove ec2 plugin ([373cfad](https://github.com/standardnotes/server/commit/373cfad1f7c26d3a0ec2a69e720bbce535170359))
## [1.150.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.150.0...@standardnotes/auth-server@1.150.1) (2023-10-03)
**Note:** Version bump only for package @standardnotes/auth-server
# [1.150.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.149.1...@standardnotes/auth-server@1.150.0) (2023-10-03)
### Features
* add xray segment tracing on auth-worker ([b1b244a](https://github.com/standardnotes/server/commit/b1b244a2cf1e17ddf67fc9b238b4b25a1bc5a190))
## [1.149.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.149.0...@standardnotes/auth-server@1.149.1) (2023-10-02)
### Bug Fixes
* **auth:** enable xray only for server ([71e2a41](https://github.com/standardnotes/server/commit/71e2a4187e8f79b2a3055f502310ed0b6a6d82ea))
# [1.149.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.148.2...@standardnotes/auth-server@1.149.0) (2023-10-02)
### Bug Fixes
* **auth:** add aws xray ecs and ec2 plugins ([3838358](https://github.com/standardnotes/server/commit/383835808165aba58d15e79f03b5ba4e1c899f4c))
* **auth:** prevent from loop disabling of email settings ([#858](https://github.com/standardnotes/server/issues/858)) ([bd71422](https://github.com/standardnotes/server/commit/bd71422fabc4b5b47cca6dd071e3332943adc81d))
### Features
* **auth:** introduce AWS X-Ray SDK ([#859](https://github.com/standardnotes/server/issues/859)) ([1a388f0](https://github.com/standardnotes/server/commit/1a388f00c3897d1ebb1411793cfb23c3d305ac2e))
## [1.148.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.148.1...@standardnotes/auth-server@1.148.2) (2023-09-29)
### Bug Fixes
* **auth:** increase ttl for in progress duration of transitions ([681e037](https://github.com/standardnotes/server/commit/681e0378ae6b97c838b0b34ccc630194b304b81a))
## [1.148.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.148.0...@standardnotes/auth-server@1.148.1) (2023-09-29)
### Bug Fixes
* **auth:** disable transitions retriggering if they are in progress ([5ef6c5c](https://github.com/standardnotes/server/commit/5ef6c5c14a9f7a558de7ac9ff0ab99a5f831c127))
# [1.148.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.147.1...@standardnotes/auth-server@1.148.0) (2023-09-28)
### Features
* block file operations during transition ([#856](https://github.com/standardnotes/server/issues/856)) ([676cf36](https://github.com/standardnotes/server/commit/676cf36f8d769aa433880b2800f0457d06fbbf14))
## [1.147.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.147.0...@standardnotes/auth-server@1.147.1) (2023-09-27)
**Note:** Version bump only for package @standardnotes/auth-server
# [1.147.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.146.4...@standardnotes/auth-server@1.147.0) (2023-09-26)
### Features
* refactor handling revision creation from dump ([#854](https://github.com/standardnotes/server/issues/854)) ([ca6dbc0](https://github.com/standardnotes/server/commit/ca6dbc00537bb20f508f9310b1a838421f53a643))
## [1.146.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.146.3...@standardnotes/auth-server@1.146.4) (2023-09-25)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.146.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.146.2...@standardnotes/auth-server@1.146.3) (2023-09-25)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.146.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.146.1...@standardnotes/auth-server@1.146.2) (2023-09-25)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.146.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.146.0...@standardnotes/auth-server@1.146.1) (2023-09-25)
**Note:** Version bump only for package @standardnotes/auth-server
# [1.146.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.145.0...@standardnotes/auth-server@1.146.0) (2023-09-22)
### Bug Fixes
* **auth:** register specs ([f9b1f40](https://github.com/standardnotes/server/commit/f9b1f40ddf2d733d106ea64b9a7c4b38c5ec43ce))
### Features
* remove transition mode from code ([5001496](https://github.com/standardnotes/server/commit/5001496c7bc1df9e20c2d88ebf52ed77f868110c))
# [1.145.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.144.0...@standardnotes/auth-server@1.145.0) (2023-09-22)
### Features
* remove user from all shared vaults upon account deletion ([#843](https://github.com/standardnotes/server/issues/843)) ([dc77ff3](https://github.com/standardnotes/server/commit/dc77ff3e45983d231bc9c132802428e77b4be431))
# [1.144.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.143.9...@standardnotes/auth-server@1.144.0) (2023-09-21)
### Features
* add designating a survivor in shared vault ([#841](https://github.com/standardnotes/server/issues/841)) ([230c96d](https://github.com/standardnotes/server/commit/230c96dcf1d8faed9ce8fe288549226da70317e6))
## [1.143.9](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.143.8...@standardnotes/auth-server@1.143.9) (2023-09-20)
**Note:** Version bump only for package @standardnotes/auth-server

View File

@@ -49,13 +49,13 @@ const requestTransition = async (
itemsTransitionStatus?.value === TransitionStatus.STATUSES.Verified &&
revisionsTransitionStatus?.value === TransitionStatus.STATUSES.Verified
if (userHasTransitionRole && bothTransitionStatusesAreVerified) {
if (!userHasTransitionRole && bothTransitionStatusesAreVerified) {
continue
}
let wasTransitionRequested = false
if (itemsTransitionStatus?.value !== TransitionStatus.STATUSES.Verified) {
if (itemsTransitionStatus === null || itemsTransitionStatus.value === TransitionStatus.STATUSES.Failed) {
wasTransitionRequested = true
await transitionStatusRepository.remove(user.uuid, 'items')
@@ -68,7 +68,7 @@ const requestTransition = async (
)
}
if (revisionsTransitionStatus?.value !== TransitionStatus.STATUSES.Verified) {
if (revisionsTransitionStatus === null || revisionsTransitionStatus.value === TransitionStatus.STATUSES.Failed) {
wasTransitionRequested = true
await transitionStatusRepository.remove(user.uuid, 'revisions')

Binary file not shown.

View File

@@ -0,0 +1,15 @@
import { MigrationInterface, QueryRunner } from 'typeorm'
export class AddDesignatedSurvivor1695283870612 implements MigrationInterface {
name = 'AddDesignatedSurvivor1695283870612'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
'ALTER TABLE `auth_shared_vault_users` ADD `is_designated_survivor` tinyint NOT NULL DEFAULT 0',
)
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query('ALTER TABLE `auth_shared_vault_users` DROP COLUMN `is_designated_survivor`')
}
}

View File

@@ -0,0 +1,43 @@
import { MigrationInterface, QueryRunner } from 'typeorm'
export class AddDesignatedSurvivor1695283961201 implements MigrationInterface {
name = 'AddDesignatedSurvivor1695283961201'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query('DROP INDEX "user_uuid_on_auth_shared_vault_users"')
await queryRunner.query('DROP INDEX "shared_vault_uuid_on_auth_shared_vault_users"')
await queryRunner.query(
'CREATE TABLE "temporary_auth_shared_vault_users" ("uuid" varchar PRIMARY KEY NOT NULL, "shared_vault_uuid" varchar(36) NOT NULL, "user_uuid" varchar(36) NOT NULL, "permission" varchar(24) NOT NULL, "created_at_timestamp" bigint NOT NULL, "updated_at_timestamp" bigint NOT NULL, "is_designated_survivor" boolean NOT NULL DEFAULT (0))',
)
await queryRunner.query(
'INSERT INTO "temporary_auth_shared_vault_users"("uuid", "shared_vault_uuid", "user_uuid", "permission", "created_at_timestamp", "updated_at_timestamp") SELECT "uuid", "shared_vault_uuid", "user_uuid", "permission", "created_at_timestamp", "updated_at_timestamp" FROM "auth_shared_vault_users"',
)
await queryRunner.query('DROP TABLE "auth_shared_vault_users"')
await queryRunner.query('ALTER TABLE "temporary_auth_shared_vault_users" RENAME TO "auth_shared_vault_users"')
await queryRunner.query(
'CREATE INDEX "user_uuid_on_auth_shared_vault_users" ON "auth_shared_vault_users" ("user_uuid") ',
)
await queryRunner.query(
'CREATE INDEX "shared_vault_uuid_on_auth_shared_vault_users" ON "auth_shared_vault_users" ("shared_vault_uuid") ',
)
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query('DROP INDEX "shared_vault_uuid_on_auth_shared_vault_users"')
await queryRunner.query('DROP INDEX "user_uuid_on_auth_shared_vault_users"')
await queryRunner.query('ALTER TABLE "auth_shared_vault_users" RENAME TO "temporary_auth_shared_vault_users"')
await queryRunner.query(
'CREATE TABLE "auth_shared_vault_users" ("uuid" varchar PRIMARY KEY NOT NULL, "shared_vault_uuid" varchar(36) NOT NULL, "user_uuid" varchar(36) NOT NULL, "permission" varchar(24) NOT NULL, "created_at_timestamp" bigint NOT NULL, "updated_at_timestamp" bigint NOT NULL)',
)
await queryRunner.query(
'INSERT INTO "auth_shared_vault_users"("uuid", "shared_vault_uuid", "user_uuid", "permission", "created_at_timestamp", "updated_at_timestamp") SELECT "uuid", "shared_vault_uuid", "user_uuid", "permission", "created_at_timestamp", "updated_at_timestamp" FROM "temporary_auth_shared_vault_users"',
)
await queryRunner.query('DROP TABLE "temporary_auth_shared_vault_users"')
await queryRunner.query(
'CREATE INDEX "shared_vault_uuid_on_auth_shared_vault_users" ON "auth_shared_vault_users" ("shared_vault_uuid") ',
)
await queryRunner.query(
'CREATE INDEX "user_uuid_on_auth_shared_vault_users" ON "auth_shared_vault_users" ("user_uuid") ',
)
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/auth-server",
"version": "1.143.9",
"version": "1.152.2",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
@@ -19,7 +19,7 @@
"lint": "eslint . --ext .ts",
"lint:fix": "eslint . --fix --ext .ts",
"pretest": "yarn lint && yarn build",
"test": "jest --coverage --config=./jest.config.js --maxWorkers=50%",
"test": "jest --coverage --no-cache --config=./jest.config.js --maxWorkers=50%",
"start": "yarn node dist/bin/server.js",
"worker": "yarn node dist/bin/worker.js",
"cleanup": "yarn node dist/bin/cleanup.js",

View File

@@ -92,7 +92,6 @@ import {
SNSDomainEventPublisher,
SQSDomainEventSubscriberFactory,
SQSEventMessageHandler,
SQSNewRelicEventMessageHandler,
} from '@standardnotes/domain-events-infra'
import { GetUserSubscription } from '../Domain/UseCase/GetUserSubscription/GetUserSubscription'
import { ChangeCredentials } from '../Domain/UseCase/ChangeCredentials/ChangeCredentials'
@@ -271,6 +270,9 @@ import { AddSharedVaultUser } from '../Domain/UseCase/AddSharedVaultUser/AddShar
import { RemoveSharedVaultUser } from '../Domain/UseCase/RemoveSharedVaultUser/RemoveSharedVaultUser'
import { UserAddedToSharedVaultEventHandler } from '../Domain/Handler/UserAddedToSharedVaultEventHandler'
import { UserRemovedFromSharedVaultEventHandler } from '../Domain/Handler/UserRemovedFromSharedVaultEventHandler'
import { DesignateSurvivor } from '../Domain/UseCase/DesignateSurvivor/DesignateSurvivor'
import { UserDesignatedAsSurvivorInSharedVaultEventHandler } from '../Domain/Handler/UserDesignatedAsSurvivorInSharedVaultEventHandler'
import { DisableEmailSettingBasedOnEmailSubscription } from '../Domain/UseCase/DisableEmailSettingBasedOnEmailSubscription/DisableEmailSettingBasedOnEmailSubscription'
export class ContainerConfigLoader {
constructor(private mode: 'server' | 'worker' = 'server') {}
@@ -347,7 +349,8 @@ export class ContainerConfigLoader {
secretAccessKey: env.get('SNS_SECRET_ACCESS_KEY', true),
}
}
container.bind<SNSClient>(TYPES.Auth_SNS).toConstantValue(new SNSClient(snsConfig))
const snsClient = new SNSClient(snsConfig)
container.bind<SNSClient>(TYPES.Auth_SNS).toConstantValue(snsClient)
const sqsConfig: SQSClientConfig = {
region: env.get('SQS_AWS_REGION', true),
@@ -361,13 +364,14 @@ export class ContainerConfigLoader {
secretAccessKey: env.get('SQS_SECRET_ACCESS_KEY', true),
}
}
container.bind<SQSClient>(TYPES.Auth_SQS).toConstantValue(new SQSClient(sqsConfig))
const sqsClient = new SQSClient(sqsConfig)
container.bind<SQSClient>(TYPES.Auth_SQS).toConstantValue(sqsClient)
}
// Mapping
container
.bind<MapperInterface<SessionTrace, TypeORMSessionTrace>>(TYPES.Auth_SessionTracePersistenceMapper)
.toConstantValue(new SessionTracePersistenceMapper())
.toConstantValue(new SessionTracePersistenceMapper(container.get<TimerInterface>(TYPES.Auth_Timer)))
container
.bind<MapperInterface<Authenticator, TypeORMAuthenticator>>(TYPES.Auth_AuthenticatorPersistenceMapper)
.toConstantValue(new AuthenticatorPersistenceMapper())
@@ -456,8 +460,9 @@ export class ContainerConfigLoader {
.bind<SessionTraceRepositoryInterface>(TYPES.Auth_SessionTraceRepository)
.toConstantValue(
new TypeORMSessionTraceRepository(
container.get(TYPES.Auth_ORMSessionTraceRepository),
container.get(TYPES.Auth_SessionTracePersistenceMapper),
container.get<Repository<TypeORMSessionTrace>>(TYPES.Auth_ORMSessionTraceRepository),
container.get<MapperInterface<SessionTrace, TypeORMSessionTrace>>(TYPES.Auth_SessionTracePersistenceMapper),
container.get<TimerInterface>(TYPES.Auth_Timer),
),
)
container
@@ -495,20 +500,6 @@ export class ContainerConfigLoader {
),
)
// Middleware
container.bind<SessionMiddleware>(TYPES.Auth_SessionMiddleware).to(SessionMiddleware)
container.bind<LockMiddleware>(TYPES.Auth_LockMiddleware).to(LockMiddleware)
container
.bind<RequiredCrossServiceTokenMiddleware>(TYPES.Auth_RequiredCrossServiceTokenMiddleware)
.to(RequiredCrossServiceTokenMiddleware)
container
.bind<OptionalCrossServiceTokenMiddleware>(TYPES.Auth_OptionalCrossServiceTokenMiddleware)
.to(OptionalCrossServiceTokenMiddleware)
container
.bind<ApiGatewayOfflineAuthMiddleware>(TYPES.Auth_ApiGatewayOfflineAuthMiddleware)
.to(ApiGatewayOfflineAuthMiddleware)
container.bind<OfflineUserAuthMiddleware>(TYPES.Auth_OfflineUserAuthMiddleware).to(OfflineUserAuthMiddleware)
// Projectors
container.bind<SessionProjector>(TYPES.Auth_SessionProjector).to(SessionProjector)
container.bind<UserProjector>(TYPES.Auth_UserProjector).to(UserProjector)
@@ -593,9 +584,6 @@ export class ContainerConfigLoader {
container
.bind(TYPES.Auth_READONLY_USERS)
.toConstantValue(env.get('READONLY_USERS', true) ? env.get('READONLY_USERS', true).split(',') : [])
container
.bind(TYPES.Auth_TRANSITION_MODE_ENABLED)
.toConstantValue(env.get('TRANSITION_MODE_ENABLED', true) === 'true')
if (isConfiguredForInMemoryCache) {
container
@@ -740,6 +728,30 @@ export class ContainerConfigLoader {
: new SNSDomainEventPublisher(container.get(TYPES.Auth_SNS), container.get(TYPES.Auth_SNS_TOPIC_ARN)),
)
// Middleware
container.bind<SessionMiddleware>(TYPES.Auth_SessionMiddleware).to(SessionMiddleware)
container.bind<LockMiddleware>(TYPES.Auth_LockMiddleware).to(LockMiddleware)
container
.bind<RequiredCrossServiceTokenMiddleware>(TYPES.Auth_RequiredCrossServiceTokenMiddleware)
.toConstantValue(
new RequiredCrossServiceTokenMiddleware(
container.get<TokenDecoderInterface<CrossServiceTokenData>>(TYPES.Auth_CrossServiceTokenDecoder),
container.get<winston.Logger>(TYPES.Auth_Logger),
),
)
container
.bind<OptionalCrossServiceTokenMiddleware>(TYPES.Auth_OptionalCrossServiceTokenMiddleware)
.toConstantValue(
new OptionalCrossServiceTokenMiddleware(
container.get<TokenDecoderInterface<CrossServiceTokenData>>(TYPES.Auth_CrossServiceTokenDecoder),
container.get<winston.Logger>(TYPES.Auth_Logger),
),
)
container
.bind<ApiGatewayOfflineAuthMiddleware>(TYPES.Auth_ApiGatewayOfflineAuthMiddleware)
.to(ApiGatewayOfflineAuthMiddleware)
container.bind<OfflineUserAuthMiddleware>(TYPES.Auth_OfflineUserAuthMiddleware).to(OfflineUserAuthMiddleware)
// use cases
container
.bind<TraceSession>(TYPES.Auth_TraceSession)
@@ -957,6 +969,23 @@ export class ContainerConfigLoader {
container.get<SharedVaultUserRepositoryInterface>(TYPES.Auth_SharedVaultUserRepository),
),
)
container
.bind<DesignateSurvivor>(TYPES.Auth_DesignateSurvivor)
.toConstantValue(
new DesignateSurvivor(
container.get<SharedVaultUserRepositoryInterface>(TYPES.Auth_SharedVaultUserRepository),
container.get<TimerInterface>(TYPES.Auth_Timer),
),
)
container
.bind<DisableEmailSettingBasedOnEmailSubscription>(TYPES.Auth_DisableEmailSettingBasedOnEmailSubscription)
.toConstantValue(
new DisableEmailSettingBasedOnEmailSubscription(
container.get<UserRepositoryInterface>(TYPES.Auth_UserRepository),
container.get<SettingRepositoryInterface>(TYPES.Auth_SettingRepository),
container.get<SettingFactoryInterface>(TYPES.Auth_SettingFactory),
),
)
// Controller
container
@@ -998,7 +1027,15 @@ export class ContainerConfigLoader {
container.bind<UserRegisteredEventHandler>(TYPES.Auth_UserRegisteredEventHandler).to(UserRegisteredEventHandler)
container
.bind<AccountDeletionRequestedEventHandler>(TYPES.Auth_AccountDeletionRequestedEventHandler)
.to(AccountDeletionRequestedEventHandler)
.toConstantValue(
new AccountDeletionRequestedEventHandler(
container.get<UserRepositoryInterface>(TYPES.Auth_UserRepository),
container.get<SessionRepositoryInterface>(TYPES.Auth_SessionRepository),
container.get<EphemeralSessionRepositoryInterface>(TYPES.Auth_EphemeralSessionRepository),
container.get<RevokedSessionRepositoryInterface>(TYPES.Auth_RevokedSessionRepository),
container.get<winston.Logger>(TYPES.Auth_Logger),
),
)
container
.bind<SubscriptionPurchasedEventHandler>(TYPES.Auth_SubscriptionPurchasedEventHandler)
.to(SubscriptionPurchasedEventHandler)
@@ -1086,8 +1123,10 @@ export class ContainerConfigLoader {
.bind<EmailSubscriptionUnsubscribedEventHandler>(TYPES.Auth_EmailSubscriptionUnsubscribedEventHandler)
.toConstantValue(
new EmailSubscriptionUnsubscribedEventHandler(
container.get(TYPES.Auth_UserRepository),
container.get(TYPES.Auth_SettingService),
container.get<DisableEmailSettingBasedOnEmailSubscription>(
TYPES.Auth_DisableEmailSettingBasedOnEmailSubscription,
),
container.get<winston.Logger>(TYPES.Auth_Logger),
),
)
container
@@ -1122,6 +1161,16 @@ export class ContainerConfigLoader {
container.get<winston.Logger>(TYPES.Auth_Logger),
),
)
container
.bind<UserDesignatedAsSurvivorInSharedVaultEventHandler>(
TYPES.Auth_UserDesignatedAsSurvivorInSharedVaultEventHandler,
)
.toConstantValue(
new UserDesignatedAsSurvivorInSharedVaultEventHandler(
container.get<DesignateSurvivor>(TYPES.Auth_DesignateSurvivor),
container.get<winston.Logger>(TYPES.Auth_Logger),
),
)
const eventHandlers: Map<string, DomainEventHandlerInterface> = new Map([
['USER_REGISTERED', container.get(TYPES.Auth_UserRegisteredEventHandler)],
@@ -1156,6 +1205,10 @@ export class ContainerConfigLoader {
['TRANSITION_STATUS_UPDATED', container.get(TYPES.Auth_TransitionStatusUpdatedEventHandler)],
['USER_ADDED_TO_SHARED_VAULT', container.get(TYPES.Auth_UserAddedToSharedVaultEventHandler)],
['USER_REMOVED_FROM_SHARED_VAULT', container.get(TYPES.Auth_UserRemovedFromSharedVaultEventHandler)],
[
'USER_DESIGNATED_AS_SURVIVOR_IN_SHARED_VAULT',
container.get(TYPES.Auth_UserDesignatedAsSurvivorInSharedVaultEventHandler),
],
])
if (isConfiguredForHomeServer) {
@@ -1170,11 +1223,7 @@ export class ContainerConfigLoader {
} else {
container
.bind<DomainEventMessageHandlerInterface>(TYPES.Auth_DomainEventMessageHandler)
.toConstantValue(
env.get('NEW_RELIC_ENABLED', true) === 'true'
? new SQSNewRelicEventMessageHandler(eventHandlers, container.get(TYPES.Auth_Logger))
: new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Auth_Logger)),
)
.toConstantValue(new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Auth_Logger)))
container
.bind<DomainEventSubscriberFactoryInterface>(TYPES.Auth_DomainEventSubscriberFactory)

View File

@@ -105,7 +105,6 @@ const TYPES = {
Auth_U2F_EXPECTED_ORIGIN: Symbol.for('Auth_U2F_EXPECTED_ORIGIN'),
Auth_U2F_REQUIRE_USER_VERIFICATION: Symbol.for('Auth_U2F_REQUIRE_USER_VERIFICATION'),
Auth_READONLY_USERS: Symbol.for('Auth_READONLY_USERS'),
Auth_TRANSITION_MODE_ENABLED: Symbol.for('Auth_TRANSITION_MODE_ENABLED'),
// use cases
Auth_AuthenticateUser: Symbol.for('Auth_AuthenticateUser'),
Auth_AuthenticateRequest: Symbol.for('Auth_AuthenticateRequest'),
@@ -161,6 +160,8 @@ const TYPES = {
Auth_UpdateTransitionStatus: Symbol.for('Auth_UpdateTransitionStatus'),
Auth_AddSharedVaultUser: Symbol.for('Auth_AddSharedVaultUser'),
Auth_RemoveSharedVaultUser: Symbol.for('Auth_RemoveSharedVaultUser'),
Auth_DesignateSurvivor: Symbol.for('Auth_DesignateSurvivor'),
Auth_DisableEmailSettingBasedOnEmailSubscription: Symbol.for('Auth_DisableEmailSettingBasedOnEmailSubscription'),
// Handlers
Auth_UserRegisteredEventHandler: Symbol.for('Auth_UserRegisteredEventHandler'),
Auth_AccountDeletionRequestedEventHandler: Symbol.for('Auth_AccountDeletionRequestedEventHandler'),
@@ -192,6 +193,9 @@ const TYPES = {
Auth_TransitionStatusUpdatedEventHandler: Symbol.for('Auth_TransitionStatusUpdatedEventHandler'),
Auth_UserAddedToSharedVaultEventHandler: Symbol.for('Auth_UserAddedToSharedVaultEventHandler'),
Auth_UserRemovedFromSharedVaultEventHandler: Symbol.for('Auth_UserRemovedFromSharedVaultEventHandler'),
Auth_UserDesignatedAsSurvivorInSharedVaultEventHandler: Symbol.for(
'Auth_UserDesignatedAsSurvivorInSharedVaultEventHandler',
),
// Services
Auth_DeviceDetector: Symbol.for('Auth_DeviceDetector'),
Auth_SessionService: Symbol.for('Auth_SessionService'),

View File

@@ -1,114 +0,0 @@
import 'reflect-metadata'
import { AccountDeletionRequestedEvent } from '@standardnotes/domain-events'
import { Logger } from 'winston'
import { EphemeralSession } from '../Session/EphemeralSession'
import { EphemeralSessionRepositoryInterface } from '../Session/EphemeralSessionRepositoryInterface'
import { RevokedSession } from '../Session/RevokedSession'
import { RevokedSessionRepositoryInterface } from '../Session/RevokedSessionRepositoryInterface'
import { Session } from '../Session/Session'
import { SessionRepositoryInterface } from '../Session/SessionRepositoryInterface'
import { User } from '../User/User'
import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
import { AccountDeletionRequestedEventHandler } from './AccountDeletionRequestedEventHandler'
describe('AccountDeletionRequestedEventHandler', () => {
let userRepository: UserRepositoryInterface
let sessionRepository: SessionRepositoryInterface
let ephemeralSessionRepository: EphemeralSessionRepositoryInterface
let revokedSessionRepository: RevokedSessionRepositoryInterface
let logger: Logger
let session: Session
let ephemeralSession: EphemeralSession
let revokedSession: RevokedSession
let user: User
let event: AccountDeletionRequestedEvent
const createHandler = () =>
new AccountDeletionRequestedEventHandler(
userRepository,
sessionRepository,
ephemeralSessionRepository,
revokedSessionRepository,
logger,
)
beforeEach(() => {
user = {} as jest.Mocked<User>
userRepository = {} as jest.Mocked<UserRepositoryInterface>
userRepository.findOneByUuid = jest.fn().mockReturnValue(user)
userRepository.remove = jest.fn()
session = {
uuid: '1-2-3',
} as jest.Mocked<Session>
sessionRepository = {} as jest.Mocked<SessionRepositoryInterface>
sessionRepository.findAllByUserUuid = jest.fn().mockReturnValue([session])
sessionRepository.remove = jest.fn()
ephemeralSession = {
uuid: '2-3-4',
userUuid: '00000000-0000-0000-0000-000000000000',
} as jest.Mocked<EphemeralSession>
ephemeralSessionRepository = {} as jest.Mocked<EphemeralSessionRepositoryInterface>
ephemeralSessionRepository.findAllByUserUuid = jest.fn().mockReturnValue([ephemeralSession])
ephemeralSessionRepository.deleteOne = jest.fn()
revokedSession = {
uuid: '3-4-5',
} as jest.Mocked<RevokedSession>
revokedSessionRepository = {} as jest.Mocked<RevokedSessionRepositoryInterface>
revokedSessionRepository.findAllByUserUuid = jest.fn().mockReturnValue([revokedSession])
revokedSessionRepository.remove = jest.fn()
event = {} as jest.Mocked<AccountDeletionRequestedEvent>
event.createdAt = new Date(1)
event.payload = {
userUuid: '00000000-0000-0000-0000-000000000000',
userCreatedAtTimestamp: 1,
regularSubscriptionUuid: '2-3-4',
roleNames: ['CORE_USER'],
}
logger = {} as jest.Mocked<Logger>
logger.info = jest.fn()
logger.warn = jest.fn()
})
it('should remove a user', async () => {
await createHandler().handle(event)
expect(userRepository.remove).toHaveBeenCalledWith(user)
})
it('should not remove a user with invalid uuid', async () => {
event.payload.userUuid = 'invalid'
await createHandler().handle(event)
expect(userRepository.remove).not.toHaveBeenCalled()
})
it('should not remove a user if one does not exist', async () => {
userRepository.findOneByUuid = jest.fn().mockReturnValue(null)
await createHandler().handle(event)
expect(userRepository.remove).not.toHaveBeenCalled()
expect(sessionRepository.remove).not.toHaveBeenCalled()
expect(revokedSessionRepository.remove).not.toHaveBeenCalled()
expect(ephemeralSessionRepository.deleteOne).not.toHaveBeenCalled()
})
it('should remove all user sessions', async () => {
await createHandler().handle(event)
expect(sessionRepository.remove).toHaveBeenCalledWith(session)
expect(revokedSessionRepository.remove).toHaveBeenCalledWith(revokedSession)
expect(ephemeralSessionRepository.deleteOne).toHaveBeenCalledWith('2-3-4', '00000000-0000-0000-0000-000000000000')
})
})

View File

@@ -1,22 +1,19 @@
import { AccountDeletionRequestedEvent, DomainEventHandlerInterface } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify'
import { Uuid } from '@standardnotes/domain-core'
import { Logger } from 'winston'
import TYPES from '../../Bootstrap/Types'
import { EphemeralSessionRepositoryInterface } from '../Session/EphemeralSessionRepositoryInterface'
import { RevokedSessionRepositoryInterface } from '../Session/RevokedSessionRepositoryInterface'
import { SessionRepositoryInterface } from '../Session/SessionRepositoryInterface'
import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
import { Uuid } from '@standardnotes/domain-core'
@injectable()
export class AccountDeletionRequestedEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.Auth_SessionRepository) private sessionRepository: SessionRepositoryInterface,
@inject(TYPES.Auth_EphemeralSessionRepository)
private userRepository: UserRepositoryInterface,
private sessionRepository: SessionRepositoryInterface,
private ephemeralSessionRepository: EphemeralSessionRepositoryInterface,
@inject(TYPES.Auth_RevokedSessionRepository) private revokedSessionRepository: RevokedSessionRepositoryInterface,
@inject(TYPES.Auth_Logger) private logger: Logger,
private revokedSessionRepository: RevokedSessionRepositoryInterface,
private logger: Logger,
) {}
async handle(event: AccountDeletionRequestedEvent): Promise<void> {

View File

@@ -1,117 +0,0 @@
import { EmailLevel } from '@standardnotes/domain-core'
import { EmailSubscriptionUnsubscribedEvent } from '@standardnotes/domain-events'
import { SettingServiceInterface } from '../Setting/SettingServiceInterface'
import { User } from '../User/User'
import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
import { EmailSubscriptionUnsubscribedEventHandler } from './EmailSubscriptionUnsubscribedEventHandler'
describe('EmailSubscriptionUnsubscribedEventHandler', () => {
let userRepository: UserRepositoryInterface
let settingsService: SettingServiceInterface
let event: EmailSubscriptionUnsubscribedEvent
const createHandler = () => new EmailSubscriptionUnsubscribedEventHandler(userRepository, settingsService)
beforeEach(() => {
userRepository = {} as jest.Mocked<UserRepositoryInterface>
userRepository.findOneByUsernameOrEmail = jest.fn().mockReturnValue({} as jest.Mocked<User>)
settingsService = {} as jest.Mocked<SettingServiceInterface>
settingsService.createOrReplace = jest.fn()
event = {
payload: {
userEmail: 'test@test.te',
level: EmailLevel.LEVELS.Marketing,
},
} as jest.Mocked<EmailSubscriptionUnsubscribedEvent>
})
it('should not do anything if username is invalid', async () => {
event.payload.userEmail = ''
await createHandler().handle(event)
expect(settingsService.createOrReplace).not.toHaveBeenCalled()
})
it('should not do anything if user is not found', async () => {
userRepository.findOneByUsernameOrEmail = jest.fn().mockReturnValue(null)
await createHandler().handle(event)
expect(settingsService.createOrReplace).not.toHaveBeenCalled()
})
it('should update user marketing email settings', async () => {
await createHandler().handle(event)
expect(settingsService.createOrReplace).toHaveBeenCalledWith({
user: {},
props: {
name: 'MUTE_MARKETING_EMAILS',
unencryptedValue: 'muted',
sensitive: false,
},
})
})
it('should update user sign in email settings', async () => {
event.payload.level = EmailLevel.LEVELS.SignIn
await createHandler().handle(event)
expect(settingsService.createOrReplace).toHaveBeenCalledWith({
user: {},
props: {
name: 'MUTE_SIGN_IN_EMAILS',
unencryptedValue: 'muted',
sensitive: false,
},
})
})
it('should update user email backup email settings', async () => {
event.payload.level = EmailLevel.LEVELS.FailedEmailBackup
await createHandler().handle(event)
expect(settingsService.createOrReplace).toHaveBeenCalledWith({
user: {},
props: {
name: 'MUTE_FAILED_BACKUPS_EMAILS',
unencryptedValue: 'muted',
sensitive: false,
},
})
})
it('should update user email backup email settings', async () => {
event.payload.level = EmailLevel.LEVELS.FailedCloudBackup
await createHandler().handle(event)
expect(settingsService.createOrReplace).toHaveBeenCalledWith({
user: {},
props: {
name: 'MUTE_FAILED_CLOUD_BACKUPS_EMAILS',
unencryptedValue: 'muted',
sensitive: false,
},
})
})
it('should throw error for unrecognized level', async () => {
event.payload.level = 'foobar'
let caughtError = null
try {
await createHandler().handle(event)
} catch (error) {
caughtError = error
}
expect(caughtError).not.toBeNull()
})
})

View File

@@ -1,50 +1,21 @@
import { EmailLevel, Username } from '@standardnotes/domain-core'
import { DomainEventHandlerInterface, EmailSubscriptionUnsubscribedEvent } from '@standardnotes/domain-events'
import { SettingName } from '@standardnotes/settings'
import { SettingServiceInterface } from '../Setting/SettingServiceInterface'
import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
import { Logger } from 'winston'
import { DisableEmailSettingBasedOnEmailSubscription } from '../UseCase/DisableEmailSettingBasedOnEmailSubscription/DisableEmailSettingBasedOnEmailSubscription'
export class EmailSubscriptionUnsubscribedEventHandler implements DomainEventHandlerInterface {
constructor(
private userRepository: UserRepositoryInterface,
private settingsService: SettingServiceInterface,
private disableEmailSettingBasedOnEmailSubscription: DisableEmailSettingBasedOnEmailSubscription,
private logger: Logger,
) {}
async handle(event: EmailSubscriptionUnsubscribedEvent): Promise<void> {
const usernameOrError = Username.create(event.payload.userEmail)
if (usernameOrError.isFailed()) {
return
}
const username = usernameOrError.getValue()
const user = await this.userRepository.findOneByUsernameOrEmail(username)
if (user === null) {
return
}
await this.settingsService.createOrReplace({
user,
props: {
name: this.getSettingNameFromLevel(event.payload.level),
unencryptedValue: 'muted',
sensitive: false,
},
const result = await this.disableEmailSettingBasedOnEmailSubscription.execute({
userEmail: event.payload.userEmail,
level: event.payload.level,
})
}
private getSettingNameFromLevel(level: string): string {
switch (level) {
case EmailLevel.LEVELS.FailedCloudBackup:
return SettingName.NAMES.MuteFailedCloudBackupsEmails
case EmailLevel.LEVELS.FailedEmailBackup:
return SettingName.NAMES.MuteFailedBackupsEmails
case EmailLevel.LEVELS.Marketing:
return SettingName.NAMES.MuteMarketingEmails
case EmailLevel.LEVELS.SignIn:
return SettingName.NAMES.MuteSignInEmails
default:
throw new Error(`Unknown level: ${level}`)
if (result.isFailed()) {
this.logger.error(`Failed to disable email setting for user ${event.payload.userEmail}: ${result.getError()}`)
}
}
}

View File

@@ -0,0 +1,26 @@
import { DomainEventHandlerInterface, UserDesignatedAsSurvivorInSharedVaultEvent } from '@standardnotes/domain-events'
import { Logger } from 'winston'
import { DesignateSurvivor } from '../UseCase/DesignateSurvivor/DesignateSurvivor'
export class UserDesignatedAsSurvivorInSharedVaultEventHandler implements DomainEventHandlerInterface {
constructor(
private designateSurvivorUseCase: DesignateSurvivor,
private logger: Logger,
) {}
async handle(event: UserDesignatedAsSurvivorInSharedVaultEvent): Promise<void> {
const result = await this.designateSurvivorUseCase.execute({
sharedVaultUuid: event.payload.sharedVaultUuid,
userUuid: event.payload.userUuid,
timestamp: event.payload.timestamp,
})
if (result.isFailed()) {
this.logger.error(
`Failed designate survivor for user ${event.payload.userUuid} and shared vault ${
event.payload.sharedVaultUuid
}: ${result.getError()}`,
)
}
}
}

View File

@@ -10,6 +10,12 @@ export class UserRemovedFromSharedVaultEventHandler implements DomainEventHandle
) {}
async handle(event: UserRemovedFromSharedVaultEvent): Promise<void> {
if (!event.payload.sharedVaultUuid) {
this.logger.error(`Shared vault uuid is missing from event: ${JSON.stringify(event)}`)
return
}
const result = await this.removeSharedVaultUser.execute({
userUuid: event.payload.userUuid,
sharedVaultUuid: event.payload.sharedVaultUuid,

View File

@@ -118,6 +118,40 @@ describe('RoleService', () => {
})
})
describe('removing roles', () => {
beforeEach(() => {
user = {
uuid: '123',
email: 'test@test.com',
roles: Promise.resolve([basicRole]),
} as jest.Mocked<User>
userRepository.findOneByUuid = jest.fn().mockReturnValue(user)
userRepository.save = jest.fn().mockReturnValue(user)
})
it('should remove a role from a user', async () => {
await createService().removeRoleFromUser(
Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
RoleName.create(RoleName.NAMES.CoreUser).getValue(),
)
user.roles = Promise.resolve([])
expect(userRepository.save).toHaveBeenCalledWith(user)
})
it('should not remove a role from a user if the user could not be found', async () => {
userRepository.findOneByUuid = jest.fn().mockReturnValue(null)
await createService().removeRoleFromUser(
Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
RoleName.create(RoleName.NAMES.CoreUser).getValue(),
)
expect(userRepository.save).not.toHaveBeenCalled()
})
})
describe('adding roles based on subscription', () => {
beforeEach(() => {
user = {

View File

@@ -65,6 +65,17 @@ export class RoleService implements RoleServiceInterface {
await this.addToExistingRoles(user, roleName.value)
}
async removeRoleFromUser(userUuid: Uuid, roleName: RoleName): Promise<void> {
const user = await this.userRepository.findOneByUuid(userUuid)
if (user === null) {
this.logger.error(`Could not find user with uuid ${userUuid.value} to remove role ${roleName.value}`)
return
}
await this.removeUserRole(user, roleName.value)
}
async addUserRoleBasedOnSubscription(user: User, subscriptionName: SubscriptionName): Promise<void> {
const roleName = this.roleToSubscriptionMap.getRoleNameForSubscriptionName(subscriptionName)
@@ -108,9 +119,15 @@ export class RoleService implements RoleServiceInterface {
return
}
await this.removeUserRole(user, roleName)
}
private async removeUserRole(user: User, roleName: string): Promise<void> {
const currentRoles = await user.roles
user.roles = Promise.resolve(currentRoles.filter((role) => role.name !== roleName))
await this.userRepository.save(user)
await this.webSocketsClientService.sendUserRolesChangedEvent(user)
}

View File

@@ -5,6 +5,7 @@ import { User } from '../User/User'
export interface RoleServiceInterface {
addRoleToUser(userUuid: Uuid, roleName: RoleName): Promise<void>
removeRoleFromUser(userUuid: Uuid, roleName: RoleName): Promise<void>
addUserRoleBasedOnSubscription(user: User, subscriptionName: string): Promise<void>
setOfflineUserRole(offlineUserSubscription: OfflineUserSubscription): Promise<void>
removeUserRoleBasedOnSubscription(user: User, subscriptionName: string): Promise<void>

View File

@@ -3,7 +3,7 @@ import { SubscriptionPlanName, Uuid } from '@standardnotes/domain-core'
import { SessionTrace } from './SessionTrace'
export interface SessionTraceRepositoryInterface {
save(sessionTrace: SessionTrace): Promise<void>
insert(sessionTrace: SessionTrace): Promise<void>
removeExpiredBefore(date: Date): Promise<void>
findOneByUserUuidAndDate(userUuid: Uuid, date: Date): Promise<SessionTrace | null>
countByDate(date: Date): Promise<number>

View File

@@ -3,6 +3,7 @@ import { SharedVaultUser, Uuid } from '@standardnotes/domain-core'
export interface SharedVaultUserRepositoryInterface {
findByUserUuidAndSharedVaultUuid(dto: { userUuid: Uuid; sharedVaultUuid: Uuid }): Promise<SharedVaultUser | null>
findByUserUuid(userUuid: Uuid): Promise<SharedVaultUser[]>
findDesignatedSurvivorBySharedVaultUuid(sharedVaultUuid: Uuid): Promise<SharedVaultUser | null>
save(sharedVaultUser: SharedVaultUser): Promise<void>
remove(sharedVault: SharedVaultUser): Promise<void>
}

View File

@@ -43,6 +43,7 @@ export class AddSharedVaultUser implements UseCaseInterface<void> {
sharedVaultUuid,
permission,
timestamps,
isDesignatedSurvivor: false,
})
if (sharedVaultUserOrError.isFailed()) {
return Result.fail(sharedVaultUserOrError.getError())

View File

@@ -90,6 +90,7 @@ describe('CreateCrossServiceToken', () => {
sharedVaultUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
timestamps: Timestamps.create(123456789, 123456789).getValue(),
userUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
isDesignatedSurvivor: false,
}).getValue(),
])
})

View File

@@ -1,14 +1,17 @@
import 'reflect-metadata'
import { TokenEncoderInterface, ValetTokenData, ValetTokenOperation } from '@standardnotes/security'
import { CreateValetToken } from './CreateValetToken'
import { TransitionStatus } from '@standardnotes/domain-core'
import { TimerInterface } from '@standardnotes/time'
import { TokenEncoderInterface, ValetTokenData, ValetTokenOperation } from '@standardnotes/security'
import { CreateValetToken } from './CreateValetToken'
import { UserSubscription } from '../../Subscription/UserSubscription'
import { SubscriptionSettingServiceInterface } from '../../Setting/SubscriptionSettingServiceInterface'
import { User } from '../../User/User'
import { UserSubscriptionType } from '../../Subscription/UserSubscriptionType'
import { SubscriptionSettingsAssociationServiceInterface } from '../../Setting/SubscriptionSettingsAssociationServiceInterface'
import { UserSubscriptionServiceInterface } from '../../Subscription/UserSubscriptionServiceInterface'
import { TransitionStatusRepositoryInterface } from '../../Transition/TransitionStatusRepositoryInterface'
describe('CreateValetToken', () => {
let tokenEncoder: TokenEncoderInterface<ValetTokenData>
@@ -20,6 +23,7 @@ describe('CreateValetToken', () => {
let regularSubscription: UserSubscription
let sharedSubscription: UserSubscription
let user: User
let transitionStatusRepository: TransitionStatusRepositoryInterface
const createUseCase = () =>
new CreateValetToken(
@@ -29,6 +33,7 @@ describe('CreateValetToken', () => {
userSubscriptionService,
timer,
valetTokenTTL,
transitionStatusRepository,
)
beforeEach(() => {
@@ -66,6 +71,11 @@ describe('CreateValetToken', () => {
timer = {} as jest.Mocked<TimerInterface>
timer.getTimestampInMicroseconds = jest.fn().mockReturnValue(100)
transitionStatusRepository = {} as jest.Mocked<TransitionStatusRepositoryInterface>
transitionStatusRepository.getStatus = jest
.fn()
.mockReturnValue(TransitionStatus.create(TransitionStatus.STATUSES.Verified).getValue())
})
it('should create a read valet token', async () => {
@@ -166,6 +176,7 @@ describe('CreateValetToken', () => {
{
sharedSubscriptionUuid: undefined,
regularSubscriptionUuid: '1-2-3',
ongoingTransition: false,
permittedOperation: 'write',
permittedResources: [
{
@@ -206,6 +217,7 @@ describe('CreateValetToken', () => {
{
sharedSubscriptionUuid: '2-3-4',
regularSubscriptionUuid: '1-2-3',
ongoingTransition: false,
permittedOperation: 'write',
permittedResources: [
{
@@ -266,6 +278,7 @@ describe('CreateValetToken', () => {
{
sharedSubscriptionUuid: undefined,
regularSubscriptionUuid: '1-2-3',
ongoingTransition: false,
permittedOperation: 'write',
permittedResources: [
{

View File

@@ -13,6 +13,8 @@ import { CreateValetTokenDTO } from './CreateValetTokenDTO'
import { SubscriptionSettingsAssociationServiceInterface } from '../../Setting/SubscriptionSettingsAssociationServiceInterface'
import { UserSubscriptionServiceInterface } from '../../Subscription/UserSubscriptionServiceInterface'
import { CreateValetTokenPayload } from '../../ValetToken/CreateValetTokenPayload'
import { TransitionStatusRepositoryInterface } from '../../Transition/TransitionStatusRepositoryInterface'
import { TransitionStatus } from '@standardnotes/domain-core'
@injectable()
export class CreateValetToken implements UseCaseInterface {
@@ -25,6 +27,8 @@ export class CreateValetToken implements UseCaseInterface {
@inject(TYPES.Auth_UserSubscriptionService) private userSubscriptionService: UserSubscriptionServiceInterface,
@inject(TYPES.Auth_Timer) private timer: TimerInterface,
@inject(TYPES.Auth_VALET_TOKEN_TTL) private valetTokenTTL: number,
@inject(TYPES.Auth_TransitionStatusRepository)
private transitionStatusRepository: TransitionStatusRepositoryInterface,
) {}
async execute(dto: CreateValetTokenDTO): Promise<CreateValetTokenResponseData> {
@@ -83,6 +87,8 @@ export class CreateValetToken implements UseCaseInterface {
sharedSubscriptionUuid = sharedSubscription.uuid
}
const transitionStatus = await this.transitionStatusRepository.getStatus(userUuid, 'items')
const tokenData: ValetTokenData = {
userUuid: dto.userUuid,
permittedOperation: dto.operation,
@@ -91,6 +97,7 @@ export class CreateValetToken implements UseCaseInterface {
uploadBytesLimit,
sharedSubscriptionUuid,
regularSubscriptionUuid: regularSubscription.uuid,
ongoingTransition: transitionStatus?.value === TransitionStatus.STATUSES.InProgress,
}
const valetToken = this.tokenEncoder.encodeExpirableToken(tokenData, this.valetTokenTTL)

View File

@@ -0,0 +1,156 @@
import { SharedVaultUser, SharedVaultUserPermission, Timestamps, Uuid } from '@standardnotes/domain-core'
import { DesignateSurvivor } from './DesignateSurvivor'
import { TimerInterface } from '@standardnotes/time'
import { SharedVaultUserRepositoryInterface } from '../../SharedVault/SharedVaultUserRepositoryInterface'
describe('DesignateSurvivor', () => {
let sharedVaultUserRepository: SharedVaultUserRepositoryInterface
let sharedVaultUser: SharedVaultUser
let timer: TimerInterface
const createUseCase = () => new DesignateSurvivor(sharedVaultUserRepository, timer)
beforeEach(() => {
timer = {} as jest.Mocked<TimerInterface>
timer.getTimestampInMicroseconds = jest.fn().mockReturnValue(123)
sharedVaultUser = SharedVaultUser.create({
permission: SharedVaultUserPermission.create(SharedVaultUserPermission.PERMISSIONS.Write).getValue(),
sharedVaultUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
userUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
timestamps: Timestamps.create(123, 123).getValue(),
isDesignatedSurvivor: false,
}).getValue()
sharedVaultUserRepository = {} as jest.Mocked<SharedVaultUserRepositoryInterface>
sharedVaultUserRepository.findDesignatedSurvivorBySharedVaultUuid = jest.fn().mockReturnValue(null)
sharedVaultUserRepository.findByUserUuidAndSharedVaultUuid = jest.fn().mockReturnValue(sharedVaultUser)
sharedVaultUserRepository.save = jest.fn()
})
it('should fail if shared vault uuid is invalid', async () => {
const useCase = createUseCase()
const result = await useCase.execute({
sharedVaultUuid: 'invalid',
userUuid: '00000000-0000-0000-0000-000000000000',
timestamp: 123,
})
expect(result.isFailed()).toBe(true)
})
it('should fail if user uuid is invalid', async () => {
const useCase = createUseCase()
const result = await useCase.execute({
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
userUuid: 'invalid',
timestamp: 123,
})
expect(result.isFailed()).toBe(true)
})
it('should fail if shared vault user is not found', async () => {
sharedVaultUserRepository.findByUserUuidAndSharedVaultUuid = jest.fn().mockReturnValue(null)
const useCase = createUseCase()
const result = await useCase.execute({
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
userUuid: '00000000-0000-0000-0000-000000000000',
timestamp: 123,
})
expect(result.isFailed()).toBe(true)
})
it('should designate a survivor if the user is a member', async () => {
sharedVaultUserRepository.findByUserUuidAndSharedVaultUuid = jest.fn().mockReturnValue(sharedVaultUser)
const useCase = createUseCase()
const result = await useCase.execute({
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
userUuid: '00000000-0000-0000-0000-000000000000',
timestamp: 123,
})
expect(result.isFailed()).toBe(false)
expect(sharedVaultUser.props.isDesignatedSurvivor).toBe(true)
expect(sharedVaultUserRepository.save).toBeCalledTimes(1)
})
it('should designate a survivor if the user is a member and there is already a survivor', async () => {
sharedVaultUserRepository.findDesignatedSurvivorBySharedVaultUuid = jest.fn().mockReturnValue(
SharedVaultUser.create({
permission: SharedVaultUserPermission.create(SharedVaultUserPermission.PERMISSIONS.Write).getValue(),
sharedVaultUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
userUuid: Uuid.create('00000000-0000-0000-0000-000000000001').getValue(),
timestamps: Timestamps.create(123, 123).getValue(),
isDesignatedSurvivor: true,
}).getValue(),
)
sharedVaultUserRepository.findByUserUuidAndSharedVaultUuid = jest.fn().mockReturnValue(sharedVaultUser)
const useCase = createUseCase()
const result = await useCase.execute({
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
userUuid: '00000000-0000-0000-0000-000000000000',
timestamp: 123,
})
expect(result.isFailed()).toBe(false)
expect(sharedVaultUser.props.isDesignatedSurvivor).toBe(true)
expect(sharedVaultUserRepository.save).toBeCalledTimes(2)
})
it('should fail if the timestamp is older than the existing survivor', async () => {
sharedVaultUserRepository.findDesignatedSurvivorBySharedVaultUuid = jest.fn().mockReturnValue(
SharedVaultUser.create({
permission: SharedVaultUserPermission.create(SharedVaultUserPermission.PERMISSIONS.Write).getValue(),
sharedVaultUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
userUuid: Uuid.create('00000000-0000-0000-0000-000000000001').getValue(),
timestamps: Timestamps.create(123, 123).getValue(),
isDesignatedSurvivor: true,
}).getValue(),
)
sharedVaultUserRepository.findByUserUuidAndSharedVaultUuid = jest.fn().mockReturnValue(sharedVaultUser)
const useCase = createUseCase()
const result = await useCase.execute({
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
userUuid: '00000000-0000-0000-0000-000000000000',
timestamp: 122,
})
expect(result.isFailed()).toBe(true)
})
it('should do nothing if the user is already a survivor', async () => {
sharedVaultUserRepository.findDesignatedSurvivorBySharedVaultUuid = jest.fn().mockReturnValue(
SharedVaultUser.create({
permission: SharedVaultUserPermission.create(SharedVaultUserPermission.PERMISSIONS.Write).getValue(),
sharedVaultUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
userUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
timestamps: Timestamps.create(123, 123).getValue(),
isDesignatedSurvivor: true,
}).getValue(),
)
sharedVaultUserRepository.findByUserUuidAndSharedVaultUuid = jest.fn().mockReturnValue(sharedVaultUser)
const useCase = createUseCase()
const result = await useCase.execute({
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
userUuid: '00000000-0000-0000-0000-000000000000',
timestamp: 200,
})
expect(result.isFailed()).toBe(false)
})
})

View File

@@ -0,0 +1,66 @@
import { TimerInterface } from '@standardnotes/time'
import { Result, Timestamps, UseCaseInterface, Uuid } from '@standardnotes/domain-core'
import { DesignateSurvivorDTO } from './DesignateSurvivorDTO'
import { SharedVaultUserRepositoryInterface } from '../../SharedVault/SharedVaultUserRepositoryInterface'
export class DesignateSurvivor implements UseCaseInterface<void> {
constructor(
private sharedVaultUserRepository: SharedVaultUserRepositoryInterface,
private timer: TimerInterface,
) {}
async execute(dto: DesignateSurvivorDTO): Promise<Result<void>> {
const sharedVaultUuidOrError = Uuid.create(dto.sharedVaultUuid)
if (sharedVaultUuidOrError.isFailed()) {
return Result.fail(sharedVaultUuidOrError.getError())
}
const sharedVaultUuid = sharedVaultUuidOrError.getValue()
const userUuidOrError = Uuid.create(dto.userUuid)
if (userUuidOrError.isFailed()) {
return Result.fail(userUuidOrError.getError())
}
const userUuid = userUuidOrError.getValue()
const existingSurvivor =
await this.sharedVaultUserRepository.findDesignatedSurvivorBySharedVaultUuid(sharedVaultUuid)
if (existingSurvivor) {
if (existingSurvivor.props.timestamps.updatedAt > dto.timestamp) {
return Result.fail(
'Cannot designate survivor to a previous version of the shared vault. Most probably a race condition.',
)
}
if (existingSurvivor.props.userUuid.value === userUuid.value) {
return Result.ok()
}
existingSurvivor.props.isDesignatedSurvivor = false
existingSurvivor.props.timestamps = Timestamps.create(
existingSurvivor.props.timestamps.createdAt,
this.timer.getTimestampInMicroseconds(),
).getValue()
await this.sharedVaultUserRepository.save(existingSurvivor)
}
const toBeDesignatedAsASurvivor = await this.sharedVaultUserRepository.findByUserUuidAndSharedVaultUuid({
userUuid,
sharedVaultUuid,
})
if (!toBeDesignatedAsASurvivor) {
return Result.fail('User is not a member of the shared vault')
}
toBeDesignatedAsASurvivor.props.isDesignatedSurvivor = true
toBeDesignatedAsASurvivor.props.timestamps = Timestamps.create(
toBeDesignatedAsASurvivor.props.timestamps.createdAt,
this.timer.getTimestampInMicroseconds(),
).getValue()
await this.sharedVaultUserRepository.save(toBeDesignatedAsASurvivor)
return Result.ok()
}
}

View File

@@ -0,0 +1,5 @@
export interface DesignateSurvivorDTO {
sharedVaultUuid: string
userUuid: string
timestamp: number
}

View File

@@ -0,0 +1,96 @@
import { EmailLevel } from '@standardnotes/domain-core'
import { Setting } from '../../Setting/Setting'
import { SettingFactoryInterface } from '../../Setting/SettingFactoryInterface'
import { SettingRepositoryInterface } from '../../Setting/SettingRepositoryInterface'
import { User } from '../../User/User'
import { UserRepositoryInterface } from '../../User/UserRepositoryInterface'
import { DisableEmailSettingBasedOnEmailSubscription } from './DisableEmailSettingBasedOnEmailSubscription'
describe('DisableEmailSettingBasedOnEmailSubscription', () => {
let userRepository: UserRepositoryInterface
let settingRepository: SettingRepositoryInterface
let factory: SettingFactoryInterface
let user: User
const createUseCase = () =>
new DisableEmailSettingBasedOnEmailSubscription(userRepository, settingRepository, factory)
beforeEach(() => {
user = {} as jest.Mocked<User>
user.uuid = 'userUuid'
userRepository = {} as jest.Mocked<UserRepositoryInterface>
userRepository.findOneByUsernameOrEmail = jest.fn().mockResolvedValue(user)
settingRepository = {} as jest.Mocked<SettingRepositoryInterface>
settingRepository.findLastByNameAndUserUuid = jest.fn().mockResolvedValue({} as jest.Mocked<Setting>)
settingRepository.save = jest.fn()
factory = {} as jest.Mocked<SettingFactoryInterface>
factory.create = jest.fn().mockResolvedValue({} as jest.Mocked<Setting>)
factory.createReplacement = jest.fn().mockResolvedValue({} as jest.Mocked<Setting>)
})
it('should fail if the username is empty', async () => {
const useCase = createUseCase()
const result = await useCase.execute({
userEmail: '',
level: EmailLevel.LEVELS.Marketing,
})
expect(result.isFailed()).toBeTruthy()
})
it('should fail if the user is not found', async () => {
userRepository.findOneByUsernameOrEmail = jest.fn().mockResolvedValue(null)
const useCase = createUseCase()
const result = await useCase.execute({
userEmail: 'test@test.te',
level: EmailLevel.LEVELS.Marketing,
})
expect(result.isFailed()).toBeTruthy()
})
it('should fail if the setting name cannot be determined', async () => {
const useCase = createUseCase()
const result = await useCase.execute({
userEmail: 'test@test.te',
level: 'invalid',
})
expect(result.isFailed()).toBeTruthy()
})
it('should create a new setting if it does not exist', async () => {
settingRepository.findLastByNameAndUserUuid = jest.fn().mockResolvedValue(null)
const useCase = createUseCase()
const result = await useCase.execute({
userEmail: 'test@test.te',
level: EmailLevel.LEVELS.Marketing,
})
expect(result.isFailed()).toBeFalsy()
expect(factory.create).toHaveBeenCalled()
expect(factory.createReplacement).not.toHaveBeenCalled()
})
it('should replace the setting if it exists', async () => {
const useCase = createUseCase()
const result = await useCase.execute({
userEmail: 'test@test.te',
level: EmailLevel.LEVELS.Marketing,
})
expect(result.isFailed()).toBeFalsy()
expect(factory.create).not.toHaveBeenCalled()
expect(factory.createReplacement).toHaveBeenCalled()
})
})

View File

@@ -0,0 +1,72 @@
import { EmailLevel, Result, UseCaseInterface, Username } from '@standardnotes/domain-core'
import { SettingName } from '@standardnotes/settings'
import { DisableEmailSettingBasedOnEmailSubscriptionDTO } from './DisableEmailSettingBasedOnEmailSubscriptionDTO'
import { UserRepositoryInterface } from '../../User/UserRepositoryInterface'
import { SettingRepositoryInterface } from '../../Setting/SettingRepositoryInterface'
import { SettingFactoryInterface } from '../../Setting/SettingFactoryInterface'
export class DisableEmailSettingBasedOnEmailSubscription implements UseCaseInterface<void> {
constructor(
private userRepository: UserRepositoryInterface,
private settingRepository: SettingRepositoryInterface,
private factory: SettingFactoryInterface,
) {}
async execute(dto: DisableEmailSettingBasedOnEmailSubscriptionDTO): Promise<Result<void>> {
const usernameOrError = Username.create(dto.userEmail)
if (usernameOrError.isFailed()) {
return Result.fail(usernameOrError.getError())
}
const username = usernameOrError.getValue()
const user = await this.userRepository.findOneByUsernameOrEmail(username)
if (user === null) {
return Result.fail(`User not found for email ${dto.userEmail}`)
}
const settingNameOrError = this.getSettingNameFromLevel(dto.level)
if (settingNameOrError.isFailed()) {
return Result.fail(settingNameOrError.getError())
}
const settingName = settingNameOrError.getValue()
let setting = await this.settingRepository.findLastByNameAndUserUuid(settingName, user.uuid)
if (!setting) {
setting = await this.factory.create(
{
name: settingName,
unencryptedValue: 'muted',
sensitive: false,
},
user,
)
} else {
setting = await this.factory.createReplacement(setting, {
name: settingName,
unencryptedValue: 'muted',
sensitive: false,
})
}
await this.settingRepository.save(setting)
return Result.ok()
}
private getSettingNameFromLevel(level: string): Result<string> {
/* istanbul ignore next */
switch (level) {
case EmailLevel.LEVELS.FailedCloudBackup:
return Result.ok(SettingName.NAMES.MuteFailedCloudBackupsEmails)
case EmailLevel.LEVELS.FailedEmailBackup:
return Result.ok(SettingName.NAMES.MuteFailedBackupsEmails)
case EmailLevel.LEVELS.Marketing:
return Result.ok(SettingName.NAMES.MuteMarketingEmails)
case EmailLevel.LEVELS.SignIn:
return Result.ok(SettingName.NAMES.MuteSignInEmails)
default:
return Result.fail(`Unknown level: ${level}`)
}
}
}

View File

@@ -0,0 +1,4 @@
export interface DisableEmailSettingBasedOnEmailSubscriptionDTO {
userEmail: string
level: string
}

Some files were not shown because too many files have changed in this diff Show More