Compare commits

..

90 Commits

Author SHA1 Message Date
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
231 changed files with 4992 additions and 1974 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

331
.pnp.cjs generated
View File

@@ -1605,6 +1605,13 @@ const RAW_RUNTIME_STATE =
["@aws-sdk/service-error-classification", "npm:3.342.0"]\
],\
"linkType": "HARD"\
}],\
["npm:3.370.0", {\
"packageLocation": "./.yarn/cache/@aws-sdk-service-error-classification-npm-3.370.0-0d5b615252-500f067ba1.zip/node_modules/@aws-sdk/service-error-classification/",\
"packageDependencies": [\
["@aws-sdk/service-error-classification", "npm:3.370.0"]\
],\
"linkType": "HARD"\
}]\
]],\
["@aws-sdk/shared-ini-file-loader", [\
@@ -1788,6 +1795,15 @@ const RAW_RUNTIME_STATE =
["tslib", "npm:2.5.2"]\
],\
"linkType": "HARD"\
}],\
["npm:3.418.0", {\
"packageLocation": "./.yarn/cache/@aws-sdk-types-npm-3.418.0-451c0cadd0-627955c2c9.zip/node_modules/@aws-sdk/types/",\
"packageDependencies": [\
["@aws-sdk/types", "npm:3.418.0"],\
["@smithy/types", "npm:2.3.4"],\
["tslib", "npm:2.5.2"]\
],\
"linkType": "HARD"\
}]\
]],\
["@aws-sdk/url-parser", [\
@@ -5488,6 +5504,14 @@ const RAW_RUNTIME_STATE =
["tslib", "npm:2.5.2"]\
],\
"linkType": "HARD"\
}],\
["npm:2.3.4", {\
"packageLocation": "./.yarn/cache/@smithy-types-npm-2.3.4-7d0b3a2a2f-8a5ad3b47e.zip/node_modules/@smithy/types/",\
"packageDependencies": [\
["@smithy/types", "npm:2.3.4"],\
["tslib", "npm:2.5.2"]\
],\
"linkType": "HARD"\
}]\
]],\
["@smithy/url-parser", [\
@@ -5773,6 +5797,7 @@ const RAW_RUNTIME_STATE =
["@types/prettyjson", "npm:0.0.30"],\
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\
["@typescript-eslint/parser", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\
["aws-xray-sdk", "npm:3.5.2"],\
["axios", "npm:1.4.0"],\
["cors", "npm:2.8.5"],\
["dotenv", "npm:16.1.3"],\
@@ -5835,6 +5860,7 @@ const RAW_RUNTIME_STATE =
["@types/uuid", "npm:9.0.3"],\
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\
["@typescript-eslint/parser", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\
["aws-xray-sdk", "npm:3.5.2"],\
["axios", "npm:1.4.0"],\
["bcryptjs", "npm:2.4.3"],\
["cors", "npm:2.8.5"],\
@@ -5938,6 +5964,7 @@ const RAW_RUNTIME_STATE =
["@types/newrelic", "npm:9.14.0"],\
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\
["@typescript-eslint/parser", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\
["aws-xray-sdk", "npm:3.5.2"],\
["eslint", "npm:8.41.0"],\
["eslint-plugin-prettier", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.0.0"],\
["ioredis", "npm:5.3.2"],\
@@ -6027,6 +6054,7 @@ const RAW_RUNTIME_STATE =
["@types/uuid", "npm:9.0.3"],\
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\
["@typescript-eslint/parser", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\
["aws-xray-sdk", "npm:3.5.2"],\
["connect-busboy", "npm:1.0.0"],\
["cors", "npm:2.8.5"],\
["dayjs", "npm:1.11.7"],\
@@ -6156,11 +6184,13 @@ 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"],\
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\
["@typescript-eslint/parser", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\
["aws-xray-sdk", "npm:3.5.2"],\
["cors", "npm:2.8.5"],\
["dotenv", "npm:16.1.3"],\
["eslint", "npm:8.41.0"],\
@@ -6168,6 +6198,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 +6371,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"],\
@@ -6350,6 +6382,7 @@ const RAW_RUNTIME_STATE =
["@types/uuid", "npm:9.0.3"],\
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\
["@typescript-eslint/parser", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\
["aws-xray-sdk", "npm:3.5.2"],\
["axios", "npm:1.4.0"],\
["cors", "npm:2.8.5"],\
["dotenv", "npm:16.1.3"],\
@@ -6359,6 +6392,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"],\
@@ -6605,6 +6639,16 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["@types/cls-hooked", [\
["npm:4.3.6", {\
"packageLocation": "./.yarn/cache/@types-cls-hooked-npm-4.3.6-8787b64e86-f5b9864348.zip/node_modules/@types/cls-hooked/",\
"packageDependencies": [\
["@types/cls-hooked", "npm:4.3.6"],\
["@types/node", "npm:20.2.5"]\
],\
"linkType": "HARD"\
}]\
]],\
["@types/concat-stream", [\
["npm:1.6.1", {\
"packageLocation": "./.yarn/cache/@types-concat-stream-npm-1.6.1-42cd06b019-7d211e7433.zip/node_modules/@types/concat-stream/",\
@@ -6864,6 +6908,16 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["@types/mysql", [\
["npm:2.15.22", {\
"packageLocation": "./.yarn/cache/@types-mysql-npm-2.15.22-d643eb999e-6be0aac58f.zip/node_modules/@types/mysql/",\
"packageDependencies": [\
["@types/mysql", "npm:2.15.22"],\
["@types/node", "npm:20.2.5"]\
],\
"linkType": "HARD"\
}]\
]],\
["@types/newrelic", [\
["npm:9.14.0", {\
"packageLocation": "./.yarn/cache/@types-newrelic-npm-9.14.0-4668da51a1-3a54ea75a4.zip/node_modules/@types/newrelic/",\
@@ -6932,6 +6986,18 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["@types/pg", [\
["npm:8.10.3", {\
"packageLocation": "./.yarn/cache/@types-pg-npm-8.10.3-3fc3365c7b-22d4836bd9.zip/node_modules/@types/pg/",\
"packageDependencies": [\
["@types/pg", "npm:8.10.3"],\
["@types/node", "npm:20.2.5"],\
["pg-protocol", "npm:1.6.0"],\
["pg-types", "npm:4.0.1"]\
],\
"linkType": "HARD"\
}]\
]],\
["@types/prettier", [\
["npm:2.7.3", {\
"packageLocation": "./.yarn/cache/@types-prettier-npm-2.7.3-497316f37c-cda84c19ac.zip/node_modules/@types/prettier/",\
@@ -7942,6 +8008,16 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["async-hook-jl", [\
["npm:1.7.6", {\
"packageLocation": "./.yarn/cache/async-hook-jl-npm-1.7.6-9999815029-f61a3bd4c3.zip/node_modules/async-hook-jl/",\
"packageDependencies": [\
["async-hook-jl", "npm:1.7.6"],\
["stack-chain", "npm:1.3.7"]\
],\
"linkType": "HARD"\
}]\
]],\
["asynckit", [\
["npm:0.4.0", {\
"packageLocation": "./.yarn/cache/asynckit-npm-0.4.0-c718858525-3ce727cbc7.zip/node_modules/asynckit/",\
@@ -7951,6 +8027,112 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["atomic-batcher", [\
["npm:1.0.2", {\
"packageLocation": "./.yarn/cache/atomic-batcher-npm-1.0.2-6fcd3a3097-025e334f1f.zip/node_modules/atomic-batcher/",\
"packageDependencies": [\
["atomic-batcher", "npm:1.0.2"]\
],\
"linkType": "HARD"\
}]\
]],\
["aws-xray-sdk", [\
["npm:3.5.2", {\
"packageLocation": "./.yarn/cache/aws-xray-sdk-npm-3.5.2-15fc4e54ee-576d0d5ccb.zip/node_modules/aws-xray-sdk/",\
"packageDependencies": [\
["aws-xray-sdk", "npm:3.5.2"],\
["aws-xray-sdk-core", "npm:3.5.2"],\
["aws-xray-sdk-express", "virtual:15fc4e54eec18d85ce3f22aa2405619072c35fbd500ad809cce2c9e4ead8a191fcc189cef6a5d76df3bea5576f09735fc4d32f086db561623afc56dd36794c8f#npm:3.5.2"],\
["aws-xray-sdk-mysql", "virtual:15fc4e54eec18d85ce3f22aa2405619072c35fbd500ad809cce2c9e4ead8a191fcc189cef6a5d76df3bea5576f09735fc4d32f086db561623afc56dd36794c8f#npm:3.5.2"],\
["aws-xray-sdk-postgres", "virtual:15fc4e54eec18d85ce3f22aa2405619072c35fbd500ad809cce2c9e4ead8a191fcc189cef6a5d76df3bea5576f09735fc4d32f086db561623afc56dd36794c8f#npm:3.5.2"]\
],\
"linkType": "HARD"\
}]\
]],\
["aws-xray-sdk-core", [\
["npm:3.5.2", {\
"packageLocation": "./.yarn/cache/aws-xray-sdk-core-npm-3.5.2-9083a0c00f-a643998187.zip/node_modules/aws-xray-sdk-core/",\
"packageDependencies": [\
["aws-xray-sdk-core", "npm:3.5.2"],\
["@aws-sdk/service-error-classification", "npm:3.370.0"],\
["@aws-sdk/types", "npm:3.418.0"],\
["@types/cls-hooked", "npm:4.3.6"],\
["atomic-batcher", "npm:1.0.2"],\
["cls-hooked", "npm:4.2.2"],\
["semver", "npm:7.5.4"]\
],\
"linkType": "HARD"\
}]\
]],\
["aws-xray-sdk-express", [\
["npm:3.5.2", {\
"packageLocation": "./.yarn/cache/aws-xray-sdk-express-npm-3.5.2-c4574a664b-62a07d0f3b.zip/node_modules/aws-xray-sdk-express/",\
"packageDependencies": [\
["aws-xray-sdk-express", "npm:3.5.2"]\
],\
"linkType": "SOFT"\
}],\
["virtual:15fc4e54eec18d85ce3f22aa2405619072c35fbd500ad809cce2c9e4ead8a191fcc189cef6a5d76df3bea5576f09735fc4d32f086db561623afc56dd36794c8f#npm:3.5.2", {\
"packageLocation": "./.yarn/__virtual__/aws-xray-sdk-express-virtual-36027c3d91/0/cache/aws-xray-sdk-express-npm-3.5.2-c4574a664b-62a07d0f3b.zip/node_modules/aws-xray-sdk-express/",\
"packageDependencies": [\
["aws-xray-sdk-express", "virtual:15fc4e54eec18d85ce3f22aa2405619072c35fbd500ad809cce2c9e4ead8a191fcc189cef6a5d76df3bea5576f09735fc4d32f086db561623afc56dd36794c8f#npm:3.5.2"],\
["@types/aws-xray-sdk-core", null],\
["@types/express", "npm:4.17.17"],\
["aws-xray-sdk-core", "npm:3.5.2"]\
],\
"packagePeers": [\
"@types/aws-xray-sdk-core",\
"aws-xray-sdk-core"\
],\
"linkType": "HARD"\
}]\
]],\
["aws-xray-sdk-mysql", [\
["npm:3.5.2", {\
"packageLocation": "./.yarn/cache/aws-xray-sdk-mysql-npm-3.5.2-095483ab95-f910a96630.zip/node_modules/aws-xray-sdk-mysql/",\
"packageDependencies": [\
["aws-xray-sdk-mysql", "npm:3.5.2"]\
],\
"linkType": "SOFT"\
}],\
["virtual:15fc4e54eec18d85ce3f22aa2405619072c35fbd500ad809cce2c9e4ead8a191fcc189cef6a5d76df3bea5576f09735fc4d32f086db561623afc56dd36794c8f#npm:3.5.2", {\
"packageLocation": "./.yarn/__virtual__/aws-xray-sdk-mysql-virtual-d8a5f29b75/0/cache/aws-xray-sdk-mysql-npm-3.5.2-095483ab95-f910a96630.zip/node_modules/aws-xray-sdk-mysql/",\
"packageDependencies": [\
["aws-xray-sdk-mysql", "virtual:15fc4e54eec18d85ce3f22aa2405619072c35fbd500ad809cce2c9e4ead8a191fcc189cef6a5d76df3bea5576f09735fc4d32f086db561623afc56dd36794c8f#npm:3.5.2"],\
["@types/aws-xray-sdk-core", null],\
["@types/mysql", "npm:2.15.22"],\
["aws-xray-sdk-core", "npm:3.5.2"]\
],\
"packagePeers": [\
"@types/aws-xray-sdk-core",\
"aws-xray-sdk-core"\
],\
"linkType": "HARD"\
}]\
]],\
["aws-xray-sdk-postgres", [\
["npm:3.5.2", {\
"packageLocation": "./.yarn/cache/aws-xray-sdk-postgres-npm-3.5.2-3a7e7bcc42-f2d6da22c7.zip/node_modules/aws-xray-sdk-postgres/",\
"packageDependencies": [\
["aws-xray-sdk-postgres", "npm:3.5.2"]\
],\
"linkType": "SOFT"\
}],\
["virtual:15fc4e54eec18d85ce3f22aa2405619072c35fbd500ad809cce2c9e4ead8a191fcc189cef6a5d76df3bea5576f09735fc4d32f086db561623afc56dd36794c8f#npm:3.5.2", {\
"packageLocation": "./.yarn/__virtual__/aws-xray-sdk-postgres-virtual-c6edb063fc/0/cache/aws-xray-sdk-postgres-npm-3.5.2-3a7e7bcc42-f2d6da22c7.zip/node_modules/aws-xray-sdk-postgres/",\
"packageDependencies": [\
["aws-xray-sdk-postgres", "virtual:15fc4e54eec18d85ce3f22aa2405619072c35fbd500ad809cce2c9e4ead8a191fcc189cef6a5d76df3bea5576f09735fc4d32f086db561623afc56dd36794c8f#npm:3.5.2"],\
["@types/aws-xray-sdk-core", null],\
["@types/pg", "npm:8.10.3"],\
["aws-xray-sdk-core", "npm:3.5.2"]\
],\
"packagePeers": [\
"@types/aws-xray-sdk-core",\
"aws-xray-sdk-core"\
],\
"linkType": "HARD"\
}]\
]],\
["axios", [\
["npm:0.21.4", {\
"packageLocation": "./.yarn/cache/axios-npm-0.21.4-e278873748-da644592cb.zip/node_modules/axios/",\
@@ -8741,6 +8923,18 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["cls-hooked", [\
["npm:4.2.2", {\
"packageLocation": "./.yarn/cache/cls-hooked-npm-4.2.2-db33b9b95f-59081fcc0f.zip/node_modules/cls-hooked/",\
"packageDependencies": [\
["cls-hooked", "npm:4.2.2"],\
["async-hook-jl", "npm:1.7.6"],\
["emitter-listener", "npm:1.1.2"],\
["semver", "npm:5.7.2"]\
],\
"linkType": "HARD"\
}]\
]],\
["cluster-key-slot", [\
["npm:1.1.2", {\
"packageLocation": "./.yarn/cache/cluster-key-slot-npm-1.1.2-0571a28825-516ed8b5e1.zip/node_modules/cluster-key-slot/",\
@@ -9631,6 +9825,16 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["emitter-listener", [\
["npm:1.1.2", {\
"packageLocation": "./.yarn/cache/emitter-listener-npm-1.1.2-0fe118d0b3-697f53c308.zip/node_modules/emitter-listener/",\
"packageDependencies": [\
["emitter-listener", "npm:1.1.2"],\
["shimmer", "npm:1.2.1"]\
],\
"linkType": "HARD"\
}]\
]],\
["emittery", [\
["npm:0.13.1", {\
"packageLocation": "./.yarn/cache/emittery-npm-0.13.1-cb6cd1bb03-fbe214171d.zip/node_modules/emittery/",\
@@ -14003,6 +14207,15 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["obuf", [\
["npm:1.1.2", {\
"packageLocation": "./.yarn/cache/obuf-npm-1.1.2-8db5fae8dd-53ff4ab3a1.zip/node_modules/obuf/",\
"packageDependencies": [\
["obuf", "npm:1.1.2"]\
],\
"linkType": "HARD"\
}]\
]],\
["on-finished", [\
["npm:2.4.1", {\
"packageLocation": "./.yarn/cache/on-finished-npm-2.4.1-907af70f88-8e81472c50.zip/node_modules/on-finished/",\
@@ -14463,6 +14676,49 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["pg-int8", [\
["npm:1.0.1", {\
"packageLocation": "./.yarn/cache/pg-int8-npm-1.0.1-5cd67f3e22-a1e3a05a69.zip/node_modules/pg-int8/",\
"packageDependencies": [\
["pg-int8", "npm:1.0.1"]\
],\
"linkType": "HARD"\
}]\
]],\
["pg-numeric", [\
["npm:1.0.2", {\
"packageLocation": "./.yarn/cache/pg-numeric-npm-1.0.2-9026ec3427-8899f8200c.zip/node_modules/pg-numeric/",\
"packageDependencies": [\
["pg-numeric", "npm:1.0.2"]\
],\
"linkType": "HARD"\
}]\
]],\
["pg-protocol", [\
["npm:1.6.0", {\
"packageLocation": "./.yarn/cache/pg-protocol-npm-1.6.0-089a4b1d3c-995864cc2a.zip/node_modules/pg-protocol/",\
"packageDependencies": [\
["pg-protocol", "npm:1.6.0"]\
],\
"linkType": "HARD"\
}]\
]],\
["pg-types", [\
["npm:4.0.1", {\
"packageLocation": "./.yarn/cache/pg-types-npm-4.0.1-8f922557d3-2c686ef361.zip/node_modules/pg-types/",\
"packageDependencies": [\
["pg-types", "npm:4.0.1"],\
["pg-int8", "npm:1.0.1"],\
["pg-numeric", "npm:1.0.2"],\
["postgres-array", "npm:3.0.2"],\
["postgres-bytea", "npm:3.0.0"],\
["postgres-date", "npm:2.0.1"],\
["postgres-interval", "npm:3.0.0"],\
["postgres-range", "npm:1.1.3"]\
],\
"linkType": "HARD"\
}]\
]],\
["picocolors", [\
["npm:1.0.0", {\
"packageLocation": "./.yarn/cache/picocolors-npm-1.0.0-d81e0b1927-a2e8092dd8.zip/node_modules/picocolors/",\
@@ -14534,6 +14790,52 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["postgres-array", [\
["npm:3.0.2", {\
"packageLocation": "./.yarn/cache/postgres-array-npm-3.0.2-da6a3f1fed-0159517e4e.zip/node_modules/postgres-array/",\
"packageDependencies": [\
["postgres-array", "npm:3.0.2"]\
],\
"linkType": "HARD"\
}]\
]],\
["postgres-bytea", [\
["npm:3.0.0", {\
"packageLocation": "./.yarn/cache/postgres-bytea-npm-3.0.0-5de4c664f6-f5c01758fd.zip/node_modules/postgres-bytea/",\
"packageDependencies": [\
["postgres-bytea", "npm:3.0.0"],\
["obuf", "npm:1.1.2"]\
],\
"linkType": "HARD"\
}]\
]],\
["postgres-date", [\
["npm:2.0.1", {\
"packageLocation": "./.yarn/cache/postgres-date-npm-2.0.1-00e0e0bc9e-908eacec35.zip/node_modules/postgres-date/",\
"packageDependencies": [\
["postgres-date", "npm:2.0.1"]\
],\
"linkType": "HARD"\
}]\
]],\
["postgres-interval", [\
["npm:3.0.0", {\
"packageLocation": "./.yarn/cache/postgres-interval-npm-3.0.0-936c769b98-c7a1cf006d.zip/node_modules/postgres-interval/",\
"packageDependencies": [\
["postgres-interval", "npm:3.0.0"]\
],\
"linkType": "HARD"\
}]\
]],\
["postgres-range", [\
["npm:1.1.3", {\
"packageLocation": "./.yarn/cache/postgres-range-npm-1.1.3-46f68e1a9e-356a46d97e.zip/node_modules/postgres-range/",\
"packageDependencies": [\
["postgres-range", "npm:1.1.3"]\
],\
"linkType": "HARD"\
}]\
]],\
["prelude-ls", [\
["npm:1.2.1", {\
"packageLocation": "./.yarn/cache/prelude-ls-npm-1.2.1-3e4d272a55-0b9d2c7680.zip/node_modules/prelude-ls/",\
@@ -15293,6 +15595,13 @@ const RAW_RUNTIME_STATE =
],\
"linkType": "HARD"\
}],\
["npm:5.7.2", {\
"packageLocation": "./.yarn/cache/semver-npm-5.7.2-938ee91eaa-fca14418a1.zip/node_modules/semver/",\
"packageDependencies": [\
["semver", "npm:5.7.2"]\
],\
"linkType": "HARD"\
}],\
["npm:6.3.0", {\
"packageLocation": "./.yarn/cache/semver-npm-6.3.0-b3eace8bfd-8dd72e7c7c.zip/node_modules/semver/",\
"packageDependencies": [\
@@ -15437,6 +15746,15 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["shimmer", [\
["npm:1.2.1", {\
"packageLocation": "./.yarn/cache/shimmer-npm-1.2.1-8b50bf3206-aa0d6252ad.zip/node_modules/shimmer/",\
"packageDependencies": [\
["shimmer", "npm:1.2.1"]\
],\
"linkType": "HARD"\
}]\
]],\
["side-channel", [\
["npm:1.0.4", {\
"packageLocation": "./.yarn/cache/side-channel-npm-1.0.4-e1f38b9e06-c4998d9fc5.zip/node_modules/side-channel/",\
@@ -15761,6 +16079,15 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["stack-chain", [\
["npm:1.3.7", {\
"packageLocation": "./.yarn/cache/stack-chain-npm-1.3.7-c803ef2abb-6420637b76.zip/node_modules/stack-chain/",\
"packageDependencies": [\
["stack-chain", "npm:1.3.7"]\
],\
"linkType": "HARD"\
}]\
]],\
["stack-trace", [\
["npm:0.0.10", {\
"packageLocation": "./.yarn/cache/stack-trace-npm-0.0.10-9460b173e1-7bd633f0e9.zip/node_modules/stack-trace/",\
@@ -16772,7 +17099,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 +17123,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.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -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

@@ -3,8 +3,6 @@ module.exports = {
testEnvironment: 'node',
testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.ts$',
testTimeout: 20000,
coverageReporters: ['text-summary'],
reporters: ['summary'],
coverageThreshold: {
global: {
branches: 100,

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,64 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [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

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/analytics",
"version": "2.26.20",
"version": "2.27.9",
"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

@@ -3,6 +3,68 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [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

View File

@@ -29,6 +29,7 @@ import helmet from 'helmet'
import * as cors from 'cors'
import { text, json, Request, Response, NextFunction } from 'express'
import * as winston from 'winston'
import * as AWSXRay from 'aws-xray-sdk'
// eslint-disable-next-line @typescript-eslint/no-var-requires
const robots = require('express-robots-txt')
@@ -36,15 +37,27 @@ import { InversifyExpressServer } from 'inversify-express-utils'
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
import { TYPES } from '../src/Bootstrap/Types'
import { Env } from '../src/Bootstrap/Env'
import { ServiceIdentifier } from '@standardnotes/domain-core'
const container = new ContainerConfigLoader()
void container.load().then((container) => {
const env: Env = new Env()
env.load()
const isConfiguredForAWSProduction =
env.get('MODE', true) !== 'home-server' && env.get('MODE', true) !== 'self-hosted'
if (isConfiguredForAWSProduction) {
AWSXRay.config([AWSXRay.plugins.ECSPlugin])
}
const server = new InversifyExpressServer(container)
server.setConfig((app) => {
if (isConfiguredForAWSProduction) {
app.use(AWSXRay.express.openSegment(ServiceIdentifier.NAMES.ApiGateway))
}
app.use((_request: Request, response: Response, next: NextFunction) => {
response.setHeader('X-API-Gateway-Version', container.get(TYPES.ApiGateway_VERSION))
next()
@@ -104,6 +117,10 @@ void container.load().then((container) => {
const serverInstance = server.build()
if (isConfiguredForAWSProduction) {
serverInstance.use(AWSXRay.express.closeSegment())
}
serverInstance.listen(env.get('PORT'))
logger.info(`Server started on port ${process.env.PORT}`)

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/api-gateway",
"version": "1.75.0",
"version": "1.76.1",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
@@ -31,6 +31,7 @@
"@standardnotes/domain-events-infra": "workspace:*",
"@standardnotes/security": "workspace:*",
"@standardnotes/time": "workspace:*",
"aws-xray-sdk": "^3.5.2",
"axios": "^1.1.3",
"cors": "2.8.5",
"dotenv": "^16.0.1",

View File

@@ -3,6 +3,129 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [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

View File

@@ -24,11 +24,13 @@ import { urlencoded, json, Request, Response, NextFunction } from 'express'
import * as winston from 'winston'
import * as dayjs from 'dayjs'
import * as utc from 'dayjs/plugin/utc'
import * as AWSXRay from 'aws-xray-sdk'
import { InversifyExpressServer } from 'inversify-express-utils'
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
import TYPES from '../src/Bootstrap/Types'
import { Env } from '../src/Bootstrap/Env'
import { ServiceIdentifier } from '@standardnotes/domain-core'
const container = new ContainerConfigLoader()
void container.load().then((container) => {
@@ -37,9 +39,20 @@ void container.load().then((container) => {
const env: Env = new Env()
env.load()
const isConfiguredForAWSProduction =
env.get('MODE', true) !== 'home-server' && env.get('MODE', true) !== 'self-hosted'
if (isConfiguredForAWSProduction) {
AWSXRay.config([AWSXRay.plugins.ECSPlugin])
}
const server = new InversifyExpressServer(container)
server.setConfig((app) => {
if (isConfiguredForAWSProduction) {
app.use(AWSXRay.express.openSegment(ServiceIdentifier.NAMES.Auth))
}
app.use((_request: Request, response: Response, next: NextFunction) => {
response.setHeader('X-Auth-Version', container.get(TYPES.Auth_VERSION))
next()
@@ -66,6 +79,10 @@ void container.load().then((container) => {
const serverInstance = server.build()
if (isConfiguredForAWSProduction) {
serverInstance.use(AWSXRay.express.closeSegment())
}
serverInstance.listen(env.get('PORT'))
logger.info(`Server started on port ${process.env.PORT}`)

View File

@@ -55,7 +55,7 @@ const requestTransition = async (
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')

View File

@@ -8,6 +8,7 @@ import { Env } from '../src/Bootstrap/Env'
import { DomainEventSubscriberFactoryInterface } from '@standardnotes/domain-events'
import * as dayjs from 'dayjs'
import * as utc from 'dayjs/plugin/utc'
import * as AWSXRay from 'aws-xray-sdk'
const container = new ContainerConfigLoader('worker')
void container.load().then((container) => {
@@ -16,6 +17,14 @@ void container.load().then((container) => {
const env: Env = new Env()
env.load()
const isConfiguredForAWSProduction =
env.get('MODE', true) !== 'home-server' && env.get('MODE', true) !== 'self-hosted'
if (isConfiguredForAWSProduction) {
AWSXRay.enableManualMode()
AWSXRay.config([AWSXRay.plugins.ECSPlugin])
}
const logger: Logger = container.get(TYPES.Auth_Logger)
logger.info('Starting worker...')

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/auth-server",
"version": "1.144.0",
"version": "1.150.8",
"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",
@@ -54,6 +54,7 @@
"@standardnotes/sncrypto-common": "^1.13.4",
"@standardnotes/sncrypto-node": "workspace:*",
"@standardnotes/time": "workspace:*",
"aws-xray-sdk": "^3.5.2",
"axios": "^1.1.3",
"bcryptjs": "2.4.3",
"cors": "2.8.5",

View File

@@ -1,5 +1,6 @@
import * as winston from 'winston'
import Redis from 'ioredis'
import { captureAWSv3Client } from 'aws-xray-sdk'
import { SNSClient, SNSClientConfig } from '@aws-sdk/client-sns'
import { SQSClient, SQSClientConfig } from '@aws-sdk/client-sqs'
import { Container } from 'inversify'
@@ -92,7 +93,7 @@ import {
SNSDomainEventPublisher,
SQSDomainEventSubscriberFactory,
SQSEventMessageHandler,
SQSNewRelicEventMessageHandler,
SQSXRayEventMessageHandler,
} from '@standardnotes/domain-events-infra'
import { GetUserSubscription } from '../Domain/UseCase/GetUserSubscription/GetUserSubscription'
import { ChangeCredentials } from '../Domain/UseCase/ChangeCredentials/ChangeCredentials'
@@ -189,6 +190,7 @@ import {
ControllerContainer,
ControllerContainerInterface,
MapperInterface,
ServiceIdentifier,
SharedVaultUser,
} from '@standardnotes/domain-core'
import { SessionTracePersistenceMapper } from '../Mapping/SessionTracePersistenceMapper'
@@ -273,6 +275,7 @@ import { UserAddedToSharedVaultEventHandler } from '../Domain/Handler/UserAddedT
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') {}
@@ -319,6 +322,8 @@ export class ContainerConfigLoader {
logger.debug('Database initialized')
const isConfiguredForHomeServer = env.get('MODE', true) === 'home-server'
const isConfiguredForSelfHosting = env.get('MODE', true) === 'self-hosted'
const isConfiguredForAWSProduction = !isConfiguredForHomeServer && !isConfiguredForSelfHosting
const isConfiguredForInMemoryCache = env.get('CACHE_TYPE', true) === 'memory'
if (!isConfiguredForInMemoryCache) {
@@ -349,7 +354,11 @@ export class ContainerConfigLoader {
secretAccessKey: env.get('SNS_SECRET_ACCESS_KEY', true),
}
}
container.bind<SNSClient>(TYPES.Auth_SNS).toConstantValue(new SNSClient(snsConfig))
let snsClient = new SNSClient(snsConfig)
if (isConfiguredForAWSProduction) {
snsClient = captureAWSv3Client(snsClient)
}
container.bind<SNSClient>(TYPES.Auth_SNS).toConstantValue(snsClient)
const sqsConfig: SQSClientConfig = {
region: env.get('SQS_AWS_REGION', true),
@@ -363,13 +372,17 @@ export class ContainerConfigLoader {
secretAccessKey: env.get('SQS_SECRET_ACCESS_KEY', true),
}
}
container.bind<SQSClient>(TYPES.Auth_SQS).toConstantValue(new SQSClient(sqsConfig))
let sqsClient = new SQSClient(sqsConfig)
if (isConfiguredForAWSProduction) {
sqsClient = captureAWSv3Client(sqsClient)
}
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())
@@ -458,8 +471,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
@@ -497,20 +511,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)
@@ -595,9 +595,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
@@ -742,6 +739,32 @@ 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),
isConfiguredForAWSProduction && this.mode === 'server',
container.get<winston.Logger>(TYPES.Auth_Logger),
),
)
container
.bind<OptionalCrossServiceTokenMiddleware>(TYPES.Auth_OptionalCrossServiceTokenMiddleware)
.toConstantValue(
new OptionalCrossServiceTokenMiddleware(
container.get<TokenDecoderInterface<CrossServiceTokenData>>(TYPES.Auth_CrossServiceTokenDecoder),
isConfiguredForAWSProduction && this.mode === 'server',
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)
@@ -967,6 +990,15 @@ export class ContainerConfigLoader {
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
@@ -1008,7 +1040,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)
@@ -1096,8 +1136,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
@@ -1195,8 +1237,12 @@ export class ContainerConfigLoader {
container
.bind<DomainEventMessageHandlerInterface>(TYPES.Auth_DomainEventMessageHandler)
.toConstantValue(
env.get('NEW_RELIC_ENABLED', true) === 'true'
? new SQSNewRelicEventMessageHandler(eventHandlers, container.get(TYPES.Auth_Logger))
isConfiguredForAWSProduction
? new SQSXRayEventMessageHandler(
ServiceIdentifier.NAMES.AuthWorker,
eventHandlers,
container.get(TYPES.Auth_Logger),
)
: new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Auth_Logger)),
)

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'),
@@ -162,6 +161,7 @@ const TYPES = {
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'),

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

@@ -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

@@ -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

@@ -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,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
}

View File

@@ -21,19 +21,9 @@ describe('Register', () => {
let user: User
let crypter: CrypterInterface
let timer: TimerInterface
let transitionModeEnabled = false
const createUseCase = () =>
new Register(
userRepository,
roleRepository,
authResponseFactory,
crypter,
false,
settingService,
timer,
transitionModeEnabled,
)
new Register(userRepository, roleRepository, authResponseFactory, crypter, false, settingService, timer)
beforeEach(() => {
userRepository = {} as jest.Mocked<UserRepositoryInterface>
@@ -94,10 +84,11 @@ describe('Register', () => {
expect(settingService.applyDefaultSettingsUponRegistration).toHaveBeenCalled()
})
it('should register a new user with default role', async () => {
it('should register a new user with default set of roles', async () => {
const role = new Role()
role.name = 'role1'
roleRepository.findOneByName = jest.fn().mockReturnValue(role)
role.name = RoleName.NAMES.CoreUser
roleRepository.findOneByName = jest.fn().mockReturnValueOnce(role)
expect(
await createUseCase().execute({
@@ -130,48 +121,6 @@ describe('Register', () => {
})
})
it('should register a new user with default role and transition role', async () => {
transitionModeEnabled = true
const role = new Role()
role.name = RoleName.NAMES.CoreUser
const transitionRole = new Role()
transitionRole.name = RoleName.NAMES.TransitionUser
roleRepository.findOneByName = jest.fn().mockReturnValueOnce(role).mockReturnValueOnce(transitionRole)
expect(
await createUseCase().execute({
email: 'test@test.te',
password: 'asdzxc',
updatedWithUserAgent: 'Mozilla',
apiVersion: '20200115',
ephemeralSession: false,
version: '004',
pwCost: 11,
pwSalt: 'qweqwe',
pwNonce: undefined,
}),
).toEqual({ success: true, authResponse: { foo: 'bar' } })
expect(userRepository.save).toHaveBeenCalledWith({
email: 'test@test.te',
encryptedPassword: expect.any(String),
encryptedServerKey: 'test',
serverEncryptionVersion: 1,
pwCost: 11,
pwNonce: undefined,
pwSalt: 'qweqwe',
updatedWithUserAgent: 'Mozilla',
uuid: expect.any(String),
version: '004',
createdAt: new Date(1),
updatedAt: new Date(1),
roles: Promise.resolve([role, transitionRole]),
})
})
it('should fail to register if username is invalid', async () => {
expect(
await createUseCase().execute({
@@ -249,7 +198,6 @@ describe('Register', () => {
true,
settingService,
timer,
transitionModeEnabled,
).execute({
email: 'test@test.te',
password: 'asdzxc',

View File

@@ -27,7 +27,6 @@ export class Register implements UseCaseInterface {
@inject(TYPES.Auth_DISABLE_USER_REGISTRATION) private disableUserRegistration: boolean,
@inject(TYPES.Auth_SettingService) private settingService: SettingServiceInterface,
@inject(TYPES.Auth_Timer) private timer: TimerInterface,
@inject(TYPES.Auth_TRANSITION_MODE_ENABLED) private transitionModeEnabled: boolean,
) {}
async execute(dto: RegisterDTO): Promise<RegisterResponse> {
@@ -78,12 +77,6 @@ export class Register implements UseCaseInterface {
if (defaultRole) {
roles.push(defaultRole)
}
if (this.transitionModeEnabled) {
const transitionRole = await this.roleRepository.findOneByName(RoleName.NAMES.TransitionUser)
if (transitionRole) {
roles.push(transitionRole)
}
}
user.roles = Promise.resolve(roles)
Object.assign(user, registrationFields)

View File

@@ -13,6 +13,7 @@ describe('RemoveSharedVaultUser', () => {
sharedVaultUserRepository.findByUserUuidAndSharedVaultUuid = jest
.fn()
.mockReturnValue({} as jest.Mocked<SharedVaultUser>)
sharedVaultUserRepository.findByUserUuid = jest.fn().mockReturnValue([{} as jest.Mocked<SharedVaultUser>])
sharedVaultUserRepository.remove = jest.fn()
})
@@ -28,6 +29,17 @@ describe('RemoveSharedVaultUser', () => {
expect(sharedVaultUserRepository.remove).toHaveBeenCalled()
})
it('should remove all shared vault users', async () => {
const useCase = createUseCase()
const result = await useCase.execute({
userUuid: '00000000-0000-0000-0000-000000000000',
})
expect(result.isFailed()).toBeFalsy()
expect(sharedVaultUserRepository.remove).toHaveBeenCalled()
})
it('should fail when user uuid is invalid', async () => {
const useCase = createUseCase()

View File

@@ -13,21 +13,31 @@ export class RemoveSharedVaultUser implements UseCaseInterface<void> {
}
const userUuid = userUuidOrError.getValue()
const sharedVaultUuidOrError = Uuid.create(dto.sharedVaultUuid)
if (sharedVaultUuidOrError.isFailed()) {
return Result.fail(sharedVaultUuidOrError.getError())
}
const sharedVaultUuid = sharedVaultUuidOrError.getValue()
const sharedVaultUser = await this.sharedVaultUserRepository.findByUserUuidAndSharedVaultUuid({
userUuid,
sharedVaultUuid,
})
if (!sharedVaultUser) {
return Result.fail('Shared vault user not found')
let sharedVaultUuid: Uuid | undefined
if (dto.sharedVaultUuid !== undefined) {
const sharedVaultUuidOrError = Uuid.create(dto.sharedVaultUuid)
if (sharedVaultUuidOrError.isFailed()) {
return Result.fail(sharedVaultUuidOrError.getError())
}
sharedVaultUuid = sharedVaultUuidOrError.getValue()
}
await this.sharedVaultUserRepository.remove(sharedVaultUser)
if (sharedVaultUuid) {
const sharedVaultUser = await this.sharedVaultUserRepository.findByUserUuidAndSharedVaultUuid({
userUuid,
sharedVaultUuid,
})
if (!sharedVaultUser) {
return Result.fail('Shared vault user not found')
}
await this.sharedVaultUserRepository.remove(sharedVaultUser)
} else {
const sharedVaultUsers = await this.sharedVaultUserRepository.findByUserUuid(userUuid)
for (const sharedVaultUser of sharedVaultUsers) {
await this.sharedVaultUserRepository.remove(sharedVaultUser)
}
}
return Result.ok()
}

View File

@@ -1,4 +1,4 @@
export interface RemoveSharedVaultUserDTO {
sharedVaultUuid: string
sharedVaultUuid?: string
userUuid: string
}

View File

@@ -15,7 +15,7 @@ describe('TraceSession', () => {
beforeEach(() => {
sessionTraceRepository = {} as jest.Mocked<SessionTraceRepositoryInterface>
sessionTraceRepository.findOneByUserUuidAndDate = jest.fn().mockReturnValue(null)
sessionTraceRepository.save = jest.fn()
sessionTraceRepository.insert = jest.fn()
timer = {} as jest.Mocked<TimerInterface>
timer.getUTCDateNDaysAhead = jest.fn().mockReturnValue(new Date())
@@ -30,7 +30,7 @@ describe('TraceSession', () => {
expect(result.isFailed()).toBe(false)
expect(result.getValue().props.userUuid.value).toEqual('0702b137-4f5c-438a-915e-8f8b46572ce5')
expect(sessionTraceRepository.save).toHaveBeenCalledTimes(1)
expect(sessionTraceRepository.insert).toHaveBeenCalledTimes(1)
})
it('should not save a session trace if one already exists for the same user and date', async () => {
@@ -43,7 +43,7 @@ describe('TraceSession', () => {
})
expect(result.isFailed()).toBe(false)
expect(sessionTraceRepository.save).not.toHaveBeenCalled()
expect(sessionTraceRepository.insert).not.toHaveBeenCalled()
})
it('should return an error if userUuid is invalid', async () => {
@@ -54,7 +54,7 @@ describe('TraceSession', () => {
})
expect(result.isFailed()).toBe(true)
expect(sessionTraceRepository.save).not.toHaveBeenCalled()
expect(sessionTraceRepository.insert).not.toHaveBeenCalled()
})
it('should return an error if username is invalid', async () => {
@@ -65,7 +65,7 @@ describe('TraceSession', () => {
})
expect(result.isFailed()).toBe(true)
expect(sessionTraceRepository.save).not.toHaveBeenCalled()
expect(sessionTraceRepository.insert).not.toHaveBeenCalled()
})
it('should return an error if subscriptionPlanName is invalid', async () => {
@@ -76,7 +76,7 @@ describe('TraceSession', () => {
})
expect(result.isFailed()).toBe(true)
expect(sessionTraceRepository.save).not.toHaveBeenCalled()
expect(sessionTraceRepository.insert).not.toHaveBeenCalled()
})
it('should not save a session trace if creating of the session trace fails', async () => {
@@ -90,7 +90,7 @@ describe('TraceSession', () => {
})
expect(result.isFailed()).toBe(true)
expect(sessionTraceRepository.save).not.toHaveBeenCalled()
expect(sessionTraceRepository.insert).not.toHaveBeenCalled()
mock.mockRestore()
})

View File

@@ -53,7 +53,7 @@ export class TraceSession implements UseCaseInterface<SessionTrace> {
}
const sessionTrace = sessionTraceOrError.getValue()
await this.sessionTraceRepository.save(sessionTrace)
await this.sessionTraceRepository.insert(sessionTrace)
return Result.ok<SessionTrace>(sessionTrace)
}

View File

@@ -2,10 +2,12 @@ import { CrossServiceTokenData, TokenDecoderInterface } from '@standardnotes/sec
import { NextFunction, Request, Response } from 'express'
import { BaseMiddleware } from 'inversify-express-utils'
import { Logger } from 'winston'
import { Segment, getSegment } from 'aws-xray-sdk'
export abstract class ApiGatewayAuthMiddleware extends BaseMiddleware {
constructor(
private tokenDecoder: TokenDecoderInterface<CrossServiceTokenData>,
private isConfiguredForAWSProduction: boolean,
private logger: Logger,
) {
super()
@@ -39,6 +41,13 @@ export abstract class ApiGatewayAuthMiddleware extends BaseMiddleware {
response.locals.session = token.session
response.locals.readOnlyAccess = token.session?.readonly_access ?? false
if (this.isConfiguredForAWSProduction) {
const segment = getSegment()
if (segment instanceof Segment) {
segment.setUser(token.user.uuid)
}
}
return next()
} catch (error) {
return next(error)

View File

@@ -1,18 +1,16 @@
import { CrossServiceTokenData, TokenDecoderInterface } from '@standardnotes/security'
import { NextFunction, Request, Response } from 'express'
import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
import TYPES from '../../../Bootstrap/Types'
import { ApiGatewayAuthMiddleware } from './ApiGatewayAuthMiddleware'
@injectable()
export class OptionalCrossServiceTokenMiddleware extends ApiGatewayAuthMiddleware {
constructor(
@inject(TYPES.Auth_CrossServiceTokenDecoder) tokenDecoder: TokenDecoderInterface<CrossServiceTokenData>,
@inject(TYPES.Auth_Logger) logger: Logger,
tokenDecoder: TokenDecoderInterface<CrossServiceTokenData>,
isConfiguredForAWSProduction: boolean,
logger: Logger,
) {
super(tokenDecoder, logger)
super(tokenDecoder, isConfiguredForAWSProduction, logger)
}
protected override handleMissingToken(request: Request, _response: Response, next: NextFunction): boolean {

View File

@@ -1,18 +1,16 @@
import { CrossServiceTokenData, TokenDecoderInterface } from '@standardnotes/security'
import { NextFunction, Request, Response } from 'express'
import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
import TYPES from '../../../Bootstrap/Types'
import { ApiGatewayAuthMiddleware } from './ApiGatewayAuthMiddleware'
@injectable()
export class RequiredCrossServiceTokenMiddleware extends ApiGatewayAuthMiddleware {
constructor(
@inject(TYPES.Auth_CrossServiceTokenDecoder) tokenDecoder: TokenDecoderInterface<CrossServiceTokenData>,
@inject(TYPES.Auth_Logger) logger: Logger,
tokenDecoder: TokenDecoderInterface<CrossServiceTokenData>,
isConfiguredForAWSProduction: boolean,
logger: Logger,
) {
super(tokenDecoder, logger)
super(tokenDecoder, isConfiguredForAWSProduction, logger)
}
protected override handleMissingToken(request: Request, response: Response, _next: NextFunction): boolean {

View File

@@ -19,8 +19,8 @@ export class RedisTransitionStatusRepository implements TransitionStatusReposito
await this.redisClient.set(`${this.PREFIX}:${transitionType}:${userUuid}`, status.value)
break
case TransitionStatus.STATUSES.InProgress: {
const ttl2Hourse = 7_200
await this.redisClient.setex(`${this.PREFIX}:${transitionType}:${userUuid}`, ttl2Hourse, status.value)
const ttl24Hours = 86_400
await this.redisClient.setex(`${this.PREFIX}:${transitionType}:${userUuid}`, ttl24Hours, status.value)
break
}
}

View File

@@ -1,5 +1,7 @@
import { MapperInterface, SubscriptionPlanName, Uuid } from '@standardnotes/domain-core'
import { TimerInterface } from '@standardnotes/time'
import { Repository } from 'typeorm'
import { SessionTrace } from '../../Domain/Session/SessionTrace'
import { SessionTraceRepositoryInterface } from '../../Domain/Session/SessionTraceRepositoryInterface'
import { TypeORMSessionTrace } from './TypeORMSessionTrace'
@@ -8,13 +10,14 @@ export class TypeORMSessionTraceRepository implements SessionTraceRepositoryInte
constructor(
private ormRepository: Repository<TypeORMSessionTrace>,
private mapper: MapperInterface<SessionTrace, TypeORMSessionTrace>,
private timer: TimerInterface,
) {}
async countByDateAndSubscriptionPlanName(date: Date, subscriptionPlanName: SubscriptionPlanName): Promise<number> {
return this.ormRepository
.createQueryBuilder('trace')
.where('trace.creation_date = :creationDate', {
creationDate: `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`,
creationDate: this.timer.convertDateToFormattedString(date, 'YYYY-MM-DD'),
})
.andWhere('trace.subscription_plan_name = :subscriptionPlanName', {
subscriptionPlanName: subscriptionPlanName.value,
@@ -26,7 +29,7 @@ export class TypeORMSessionTraceRepository implements SessionTraceRepositoryInte
return this.ormRepository
.createQueryBuilder('trace')
.where('trace.creation_date = :creationDate', {
creationDate: `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`,
creationDate: this.timer.convertDateToFormattedString(date, 'YYYY-MM-DD'),
})
.getCount()
}
@@ -44,7 +47,7 @@ export class TypeORMSessionTraceRepository implements SessionTraceRepositoryInte
.createQueryBuilder('trace')
.where('trace.user_uuid = :userUuid AND trace.creation_date = :creationDate', {
userUuid: userUuid.value,
creationDate: `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`,
creationDate: this.timer.convertDateToFormattedString(date, 'YYYY-MM-DD'),
})
.getOne()
@@ -55,9 +58,9 @@ export class TypeORMSessionTraceRepository implements SessionTraceRepositoryInte
return this.mapper.toDomain(typeOrm)
}
async save(sessionTrace: SessionTrace): Promise<void> {
async insert(sessionTrace: SessionTrace): Promise<void> {
const persistence = this.mapper.toProjection(sessionTrace)
await this.ormRepository.save(persistence)
await this.ormRepository.insert(persistence)
}
}

View File

@@ -1,8 +1,11 @@
import { MapperInterface, SubscriptionPlanName, UniqueEntityId, Username, Uuid } from '@standardnotes/domain-core'
import { SessionTrace } from '../Domain/Session/SessionTrace'
import { TypeORMSessionTrace } from '../Infra/TypeORM/TypeORMSessionTrace'
import { TimerInterface } from '@standardnotes/time'
export class SessionTracePersistenceMapper implements MapperInterface<SessionTrace, TypeORMSessionTrace> {
constructor(private timer: TimerInterface) {}
toDomain(projection: TypeORMSessionTrace): SessionTrace {
const userUuidOrError = Uuid.create(projection.userUuid)
if (userUuidOrError.isFailed()) {
@@ -50,11 +53,7 @@ export class SessionTracePersistenceMapper implements MapperInterface<SessionTra
typeOrm.username = domain.props.username.value
typeOrm.subscriptionPlanName = domain.props.subscriptionPlanName ? domain.props.subscriptionPlanName.value : null
typeOrm.createdAt = domain.props.createdAt
typeOrm.creationDate = new Date(
domain.props.createdAt.getFullYear(),
domain.props.createdAt.getMonth(),
domain.props.createdAt.getDate(),
)
typeOrm.creationDate = new Date(this.timer.convertDateToFormattedString(domain.props.createdAt, 'YYYY-MM-DD'))
typeOrm.expiresAt = domain.props.expiresAt
return typeOrm

View File

@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.51.0](https://github.com/standardnotes/server/compare/@standardnotes/common@1.50.4...@standardnotes/common@1.51.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.50.4](https://github.com/standardnotes/server/compare/@standardnotes/common@1.50.3...@standardnotes/common@1.50.4) (2023-09-04)
**Note:** Version bump only for package @standardnotes/common

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/common",
"version": "1.50.4",
"version": "1.51.0",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
@@ -20,7 +20,7 @@
"clean": "rm -fr dist",
"build": "tsc --build",
"lint": "eslint . --ext .ts",
"test": "jest spec --coverage"
"test": "jest --coverage --no-cache"
},
"devDependencies": {
"@types/jest": "^29.5.1",

View File

@@ -3,6 +3,36 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.34.2](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.34.1...@standardnotes/domain-core@1.34.2) (2023-10-04)
### Bug Fixes
* identifying services in workers ([eab78b3](https://github.com/standardnotes/server/commit/eab78b3a95ec82cb779d069d172169bfa92368c9))
## [1.34.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.34.0...@standardnotes/domain-core@1.34.1) (2023-09-27)
### Bug Fixes
* removing items in a vault and notifying about designated survivor ([#855](https://github.com/standardnotes/server/issues/855)) ([1d06ffe](https://github.com/standardnotes/server/commit/1d06ffe9d51722ada7baa040e1d5ed351fc28f39))
# [1.34.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.33.2...@standardnotes/domain-core@1.34.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.33.2](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.33.1...@standardnotes/domain-core@1.33.2) (2023-09-25)
### Bug Fixes
* **domain-core:** notification paylod to string casting ([a02a287](https://github.com/standardnotes/server/commit/a02a28774b6d500200043faefb9ebac3719e7661))
## [1.33.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.33.0...@standardnotes/domain-core@1.33.1) (2023-09-25)
### Bug Fixes
* refactor the structure of notifications ([#853](https://github.com/standardnotes/server/issues/853)) ([cebab59](https://github.com/standardnotes/server/commit/cebab59a026c6868886e0945787a8ddb0442fbc3))
# [1.33.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.32.0...@standardnotes/domain-core@1.33.0) (2023-09-21)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/domain-core",
"version": "1.33.0",
"version": "1.34.2",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
@@ -21,7 +21,7 @@
"build": "tsc --build",
"lint": "eslint . --ext .ts",
"lint:fix": "eslint . --ext .ts --fix",
"test": "jest spec --coverage --passWithNoTests"
"test": "jest --coverage --no-cache --passWithNoTests"
},
"dependencies": {
"uuid": "^9.0.0"

View File

@@ -4,6 +4,7 @@ import { Result } from '../Core/Result'
import { NotificationPayloadProps } from './NotificationPayloadProps'
import { NotificationType } from './NotificationType'
import { Uuid } from '../Common/Uuid'
import { NotificationPayloadIdentifierType } from './NotificationPayloadIdentifierType'
export class NotificationPayload extends ValueObject<NotificationPayloadProps> {
private constructor(props: NotificationPayloadProps) {
@@ -14,8 +15,10 @@ export class NotificationPayload extends ValueObject<NotificationPayloadProps> {
return JSON.stringify({
version: this.props.version,
type: this.props.type.value,
sharedVaultUuid: this.props.sharedVaultUuid.value,
itemUuid: this.props.itemUuid ? this.props.itemUuid.value : undefined,
primaryIdentifier: this.props.primaryIdentifier.value,
primaryIndentifierType: this.props.primaryIndentifierType.value,
secondaryIdentifier: this.props.secondaryIdentifier?.value,
secondaryIdentifierType: this.props.secondaryIdentifierType?.value,
})
}
@@ -29,26 +32,43 @@ export class NotificationPayload extends ValueObject<NotificationPayloadProps> {
}
const type = typeOrError.getValue()
const sharedVaultUuidOrError = Uuid.create(props.sharedVaultUuid)
if (sharedVaultUuidOrError.isFailed()) {
return Result.fail<NotificationPayload>(sharedVaultUuidOrError.getError())
const primaryIdentifierOrError = Uuid.create(props.primaryIdentifier)
if (primaryIdentifierOrError.isFailed()) {
return Result.fail<NotificationPayload>(primaryIdentifierOrError.getError())
}
const sharedVaultUuid = sharedVaultUuidOrError.getValue()
const primaryIdentifier = primaryIdentifierOrError.getValue()
let itemUuid: Uuid | undefined = undefined
if (props.itemUuid) {
const itemUuidOrError = Uuid.create(props.itemUuid)
if (itemUuidOrError.isFailed()) {
return Result.fail<NotificationPayload>(itemUuidOrError.getError())
const primaryIndentifierTypeOrError = NotificationPayloadIdentifierType.create(props.primaryIndentifierType)
if (primaryIndentifierTypeOrError.isFailed()) {
return Result.fail<NotificationPayload>(primaryIndentifierTypeOrError.getError())
}
const primaryIndentifierType = primaryIndentifierTypeOrError.getValue()
let secondaryIdentifier: Uuid | undefined
if (props.secondaryIdentifier) {
const secondaryIdentifierOrError = Uuid.create(props.secondaryIdentifier)
if (secondaryIdentifierOrError.isFailed()) {
return Result.fail<NotificationPayload>(secondaryIdentifierOrError.getError())
}
itemUuid = itemUuidOrError.getValue()
secondaryIdentifier = secondaryIdentifierOrError.getValue()
}
let secondaryIdentifierType: NotificationPayloadIdentifierType | undefined
if (props.secondaryIdentifierType) {
const secondaryIdentifierTypeOrError = NotificationPayloadIdentifierType.create(props.secondaryIdentifierType)
if (secondaryIdentifierTypeOrError.isFailed()) {
return Result.fail<NotificationPayload>(secondaryIdentifierTypeOrError.getError())
}
secondaryIdentifierType = secondaryIdentifierTypeOrError.getValue()
}
return NotificationPayload.create({
version: props.version,
type,
sharedVaultUuid,
itemUuid,
primaryIdentifier,
primaryIndentifierType,
secondaryIdentifier,
secondaryIdentifierType,
})
} catch (error) {
return Result.fail<NotificationPayload>((error as Error).message)
@@ -57,7 +77,7 @@ export class NotificationPayload extends ValueObject<NotificationPayloadProps> {
static create(props: NotificationPayloadProps): Result<NotificationPayload> {
if (
props.itemUuid === undefined &&
props.secondaryIdentifier === undefined &&
props.type.equals(NotificationType.create(NotificationType.TYPES.SharedVaultItemRemoved).getValue())
) {
return Result.fail<NotificationPayload>(

View File

@@ -0,0 +1,28 @@
import { Result } from '../Core/Result'
import { ValueObject } from '../Core/ValueObject'
import { NotificationPayloadIdentifierTypeProps } from './NotificationPayloadIdentifierTypeProps'
export class NotificationPayloadIdentifierType extends ValueObject<NotificationPayloadIdentifierTypeProps> {
static readonly TYPES = {
SharedVaultUuid: 'shared_vault_uuid',
UserUuid: 'user_uuid',
SharedVaultInviteUuid: 'shared_vault_invite_uuid',
ItemUuid: 'item_uuid',
}
private constructor(props: NotificationPayloadIdentifierTypeProps) {
super(props)
}
get value(): string {
return this.props.value
}
static create(type: string): Result<NotificationPayloadIdentifierType> {
if (!Object.values(this.TYPES).includes(type)) {
return Result.fail<NotificationPayloadIdentifierType>(`Invalid notification payload identifier type: ${type}`)
}
return Result.ok<NotificationPayloadIdentifierType>(new NotificationPayloadIdentifierType({ value: type }))
}
}

View File

@@ -0,0 +1,3 @@
export interface NotificationPayloadIdentifierTypeProps {
value: string
}

View File

@@ -1,9 +1,12 @@
import { Uuid } from '../Common/Uuid'
import { NotificationPayloadIdentifierType } from './NotificationPayloadIdentifierType'
import { NotificationType } from './NotificationType'
export interface NotificationPayloadProps {
type: NotificationType
sharedVaultUuid: Uuid
primaryIdentifier: Uuid
primaryIndentifierType: NotificationPayloadIdentifierType
secondaryIdentifier?: Uuid
secondaryIdentifierType?: NotificationPayloadIdentifierType
version: string
itemUuid?: Uuid
}

View File

@@ -7,8 +7,9 @@ export class NotificationType extends ValueObject<NotificationTypeProps> {
SharedVaultItemRemoved: 'shared_vault_item_removed',
SelfRemovedFromSharedVault: 'self_removed_from_shared_vault',
UserRemovedFromSharedVault: 'user_removed_from_shared_vault',
UserDesignatedAsSurvivor: 'user_designated_as_survivor',
UserAddedToSharedVault: 'user_added_to_shared_vault',
SharedVaultInviteDeclined: 'shared_vault_invite_declined',
SharedVaultInviteCanceled: 'shared_vault_invite_canceled',
SharedVaultFileUploaded: 'shared_vault_file_uploaded',
SharedVaultFileRemoved: 'shared_vault_file_removed',
}

View File

@@ -6,9 +6,13 @@ export class ServiceIdentifier extends ValueObject<ServiceIdentifierProps> {
static readonly NAMES = {
ApiGateway: 'ApiGateway',
Auth: 'Auth',
AuthWorker: 'AuthWorker',
SyncingServer: 'SyncingServer',
SyncingServerWorker: 'SyncingServerWorker',
Revisions: 'Revisions',
RevisionsWorker: 'RevisionsWorker',
Files: 'Files',
FilesWorker: 'FilesWorker',
}
get value(): string {

View File

@@ -48,6 +48,8 @@ export * from './Env/AbstractEnv'
export * from './Mapping/MapperInterface'
export * from './Notification/NotificationPayload'
export * from './Notification/NotificationPayloadIdentifierType'
export * from './Notification/NotificationPayloadIdentifierTypeProps'
export * from './Notification/NotificationPayloadProps'
export * from './Notification/NotificationType'
export * from './Notification/NotificationTypeProps'

View File

@@ -3,6 +3,68 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.14.6](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.14.5...@standardnotes/domain-events-infra@1.14.6) (2023-10-05)
### Bug Fixes
* **domain-events-infra:** setting user metadata on workers ([c4b6f17](https://github.com/standardnotes/server/commit/c4b6f17ebcfe7bd77b6741f881a0d1f13ba809a4))
## [1.14.5](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.14.4...@standardnotes/domain-events-infra@1.14.5) (2023-10-04)
### Bug Fixes
* identifying services in workers ([eab78b3](https://github.com/standardnotes/server/commit/eab78b3a95ec82cb779d069d172169bfa92368c9))
## [1.14.4](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.14.3...@standardnotes/domain-events-infra@1.14.4) (2023-10-04)
### Bug Fixes
* **domain-events-infra:** subsegment name ([ba7cbb9](https://github.com/standardnotes/server/commit/ba7cbb989ba3592ea0c13fc39f85e314517fbb2d))
## [1.14.3](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.14.2...@standardnotes/domain-events-infra@1.14.3) (2023-10-04)
### Bug Fixes
* **domain-events-infra:** handling segments ([207ef9f](https://github.com/standardnotes/server/commit/207ef9f3e531b730f3f4869fb128354dbd659f46))
* **domain-events-infra:** remove redundant flush ([64f1fe5](https://github.com/standardnotes/server/commit/64f1fe59c23894bda9ad40c6bdeaf2997a8b48ce))
## [1.14.2](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.14.1...@standardnotes/domain-events-infra@1.14.2) (2023-10-04)
### Bug Fixes
* **domain-events-infra:** handling async functions ([f6bc1c3](https://github.com/standardnotes/server/commit/f6bc1c30846ecfb159f7fb1cdd8bfc3ab15b2dde))
* **domain-events-infra:** imports ([7668713](https://github.com/standardnotes/server/commit/7668713dd6f65b65e546152828f5f52ea34f8bf5))
## [1.14.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.14.0...@standardnotes/domain-events-infra@1.14.1) (2023-10-03)
### Bug Fixes
* **domain-events-infra:** change segment closing ([e066b6a](https://github.com/standardnotes/server/commit/e066b6a126754e5b1ea73b8ef5ce9068dc424d77))
# [1.14.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.13.1...@standardnotes/domain-events-infra@1.14.0) (2023-10-03)
### Features
* add xray segment tracing on auth-worker ([b1b244a](https://github.com/standardnotes/server/commit/b1b244a2cf1e17ddf67fc9b238b4b25a1bc5a190))
## [1.13.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.13.0...@standardnotes/domain-events-infra@1.13.1) (2023-09-28)
**Note:** Version bump only for package @standardnotes/domain-events-infra
# [1.13.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.12.34...@standardnotes/domain-events-infra@1.13.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.12.34](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.12.33...@standardnotes/domain-events-infra@1.12.34) (2023-09-25)
**Note:** Version bump only for package @standardnotes/domain-events-infra
## [1.12.33](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.12.32...@standardnotes/domain-events-infra@1.12.33) (2023-09-25)
**Note:** Version bump only for package @standardnotes/domain-events-infra
## [1.12.32](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.12.31...@standardnotes/domain-events-infra@1.12.32) (2023-09-21)
**Note:** Version bump only for package @standardnotes/domain-events-infra

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/domain-events-infra",
"version": "1.12.32",
"version": "1.14.6",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
@@ -21,12 +21,13 @@
"build": "tsc --build",
"lint": "eslint . --ext .ts",
"lint:fix": "eslint . --ext .ts --fix",
"test": "jest spec --coverage"
"test": "jest --coverage --no-cache"
},
"dependencies": {
"@aws-sdk/client-sns": "^3.332.0",
"@aws-sdk/client-sqs": "^3.332.0",
"@standardnotes/domain-events": "workspace:*",
"aws-xray-sdk": "^3.5.2",
"ioredis": "^5.2.4",
"reflect-metadata": "^0.1.13",
"sqs-consumer": "^6.2.1",

View File

@@ -0,0 +1,60 @@
import { Logger } from 'winston'
import * as zlib from 'zlib'
import { Segment, Subsegment, captureAsyncFunc } from 'aws-xray-sdk'
import {
DomainEventHandlerInterface,
DomainEventInterface,
DomainEventMessageHandlerInterface,
} from '@standardnotes/domain-events'
export class SQSXRayEventMessageHandler implements DomainEventMessageHandlerInterface {
constructor(
private serviceName: string,
private handlers: Map<string, DomainEventHandlerInterface>,
private logger: Logger,
) {}
async handleMessage(message: string): Promise<void> {
const messageParsed = JSON.parse(message)
const domainEventJson = zlib.unzipSync(Buffer.from(messageParsed.Message, 'base64')).toString()
const domainEvent: DomainEventInterface = JSON.parse(domainEventJson)
domainEvent.createdAt = new Date(domainEvent.createdAt)
const handler = this.handlers.get(domainEvent.type)
if (!handler) {
this.logger.debug(`Event handler for event type ${domainEvent.type} does not exist`)
return
}
this.logger.debug(`Received event: ${domainEvent.type}`)
const xRaySegment = new Segment(this.serviceName)
if (domainEvent.meta.correlation.userIdentifierType === 'uuid') {
xRaySegment.addMetadata('userUuid', domainEvent.meta.correlation.userIdentifier)
}
await captureAsyncFunc(
domainEvent.type,
async (subsegment?: Subsegment) => {
await handler.handle(domainEvent)
if (subsegment) {
subsegment.close()
}
},
xRaySegment,
)
xRaySegment.close()
}
async handleError(error: Error): Promise<void> {
this.logger.error('Error occured while handling SQS message: %O', error)
}
}

View File

@@ -12,3 +12,4 @@ export * from './SQS/SQSNewRelicBounceNotificiationHandler'
export * from './SQS/SQSDomainEventSubscriberFactory'
export * from './SQS/SQSEventMessageHandler'
export * from './SQS/SQSNewRelicEventMessageHandler'
export * from './SQS/SQSXRayEventMessageHandler'

View File

@@ -3,6 +3,28 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.131.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.131.0...@standardnotes/domain-events@2.131.1) (2023-09-28)
**Note:** Version bump only for package @standardnotes/domain-events
# [2.131.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.130.0...@standardnotes/domain-events@2.131.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.130.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.129.1...@standardnotes/domain-events@2.130.0) (2023-09-25)
### Features
* remove shared vault files upon shared vault removal ([#852](https://github.com/standardnotes/server/issues/852)) ([7b1eec2](https://github.com/standardnotes/server/commit/7b1eec21e54330bebbeebb80cec3ba4284112aab))
## [2.129.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.129.0...@standardnotes/domain-events@2.129.1) (2023-09-25)
### Bug Fixes
* remember paging progress on transitioning ([1d73e4f](https://github.com/standardnotes/server/commit/1d73e4f0720d41029af4d4b2b7a10d101add6c82))
# [2.129.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.128.0...@standardnotes/domain-events@2.129.0) (2023-09-21)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/domain-events",
"version": "2.129.0",
"version": "2.131.1",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
@@ -20,7 +20,7 @@
"clean": "rm -fr dist",
"build": "tsc --build",
"lint": "eslint . --ext .ts",
"test": "jest spec --coverage --passWithNoTests"
"test": "jest --coverage --no-cache --passWithNoTests"
},
"dependencies": {
"@standardnotes/predicates": "workspace:*",

View File

@@ -1,3 +1,4 @@
export interface SharedVaultRemovedEventPayload {
sharedVaultUuid: string
vaultOwnerUuid: string
}

View File

@@ -3,4 +3,5 @@ export interface TransitionStatusUpdatedEventPayload {
transitionType: 'items' | 'revisions'
transitionTimestamp: number
status: string
page?: number
}

View File

@@ -3,6 +3,64 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.12.9](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.12.8...@standardnotes/event-store@1.12.9) (2023-10-05)
**Note:** Version bump only for package @standardnotes/event-store
## [1.12.8](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.12.7...@standardnotes/event-store@1.12.8) (2023-10-04)
**Note:** Version bump only for package @standardnotes/event-store
## [1.12.7](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.12.6...@standardnotes/event-store@1.12.7) (2023-10-04)
**Note:** Version bump only for package @standardnotes/event-store
## [1.12.6](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.12.5...@standardnotes/event-store@1.12.6) (2023-10-04)
**Note:** Version bump only for package @standardnotes/event-store
## [1.12.5](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.12.4...@standardnotes/event-store@1.12.5) (2023-10-04)
**Note:** Version bump only for package @standardnotes/event-store
## [1.12.4](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.12.3...@standardnotes/event-store@1.12.4) (2023-10-03)
**Note:** Version bump only for package @standardnotes/event-store
## [1.12.3](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.12.2...@standardnotes/event-store@1.12.3) (2023-10-03)
**Note:** Version bump only for package @standardnotes/event-store
## [1.12.2](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.12.1...@standardnotes/event-store@1.12.2) (2023-09-28)
**Note:** Version bump only for package @standardnotes/event-store
## [1.12.1](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.12.0...@standardnotes/event-store@1.12.1) (2023-09-27)
**Note:** Version bump only for package @standardnotes/event-store
# [1.12.0](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.11.52...@standardnotes/event-store@1.12.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.11.52](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.11.51...@standardnotes/event-store@1.11.52) (2023-09-25)
**Note:** Version bump only for package @standardnotes/event-store
## [1.11.51](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.11.50...@standardnotes/event-store@1.11.51) (2023-09-25)
**Note:** Version bump only for package @standardnotes/event-store
## [1.11.50](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.11.49...@standardnotes/event-store@1.11.50) (2023-09-25)
**Note:** Version bump only for package @standardnotes/event-store
## [1.11.49](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.11.48...@standardnotes/event-store@1.11.49) (2023-09-25)
**Note:** Version bump only for package @standardnotes/event-store
## [1.11.48](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.11.47...@standardnotes/event-store@1.11.48) (2023-09-21)
**Note:** Version bump only for package @standardnotes/event-store

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/event-store",
"version": "1.11.48",
"version": "1.12.9",
"description": "Event Store Service",
"private": true,
"main": "dist/src/index.js",
@@ -13,7 +13,7 @@
"build": "tsc --build",
"lint": "eslint . --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%",
"worker": "yarn node dist/bin/worker.js"
},
"author": "Karol Sójko <karol@standardnotes.com>",

View File

@@ -3,6 +3,74 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.26.1](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.26.0...@standardnotes/files-server@1.26.1) (2023-10-05)
**Note:** Version bump only for package @standardnotes/files-server
# [1.26.0](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.25.6...@standardnotes/files-server@1.26.0) (2023-10-04)
### Features
* add xray to syncing server and files ([6583ff6](https://github.com/standardnotes/files/commit/6583ff6cd90f7881c1a79c0f904f1b1db96fc5b3))
## [1.25.6](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.25.5...@standardnotes/files-server@1.25.6) (2023-10-04)
**Note:** Version bump only for package @standardnotes/files-server
## [1.25.5](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.25.4...@standardnotes/files-server@1.25.5) (2023-10-04)
**Note:** Version bump only for package @standardnotes/files-server
## [1.25.4](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.25.3...@standardnotes/files-server@1.25.4) (2023-10-04)
**Note:** Version bump only for package @standardnotes/files-server
## [1.25.3](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.25.2...@standardnotes/files-server@1.25.3) (2023-10-04)
**Note:** Version bump only for package @standardnotes/files-server
## [1.25.2](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.25.1...@standardnotes/files-server@1.25.2) (2023-10-03)
**Note:** Version bump only for package @standardnotes/files-server
## [1.25.1](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.25.0...@standardnotes/files-server@1.25.1) (2023-10-03)
**Note:** Version bump only for package @standardnotes/files-server
# [1.25.0](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.24.1...@standardnotes/files-server@1.25.0) (2023-09-28)
### Features
* block file operations during transition ([#856](https://github.com/standardnotes/files/issues/856)) ([676cf36](https://github.com/standardnotes/files/commit/676cf36f8d769aa433880b2800f0457d06fbbf14))
## [1.24.1](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.24.0...@standardnotes/files-server@1.24.1) (2023-09-27)
**Note:** Version bump only for package @standardnotes/files-server
# [1.24.0](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.23.2...@standardnotes/files-server@1.24.0) (2023-09-26)
### Features
* refactor handling revision creation from dump ([#854](https://github.com/standardnotes/files/issues/854)) ([ca6dbc0](https://github.com/standardnotes/files/commit/ca6dbc00537bb20f508f9310b1a838421f53a643))
## [1.23.2](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.23.1...@standardnotes/files-server@1.23.2) (2023-09-25)
**Note:** Version bump only for package @standardnotes/files-server
## [1.23.1](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.23.0...@standardnotes/files-server@1.23.1) (2023-09-25)
**Note:** Version bump only for package @standardnotes/files-server
# [1.23.0](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.22.28...@standardnotes/files-server@1.23.0) (2023-09-25)
### Features
* remove shared vault files upon shared vault removal ([#852](https://github.com/standardnotes/files/issues/852)) ([7b1eec2](https://github.com/standardnotes/files/commit/7b1eec21e54330bebbeebb80cec3ba4284112aab))
## [1.22.28](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.22.27...@standardnotes/files-server@1.22.28) (2023-09-25)
**Note:** Version bump only for package @standardnotes/files-server
## [1.22.27](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.22.26...@standardnotes/files-server@1.22.27) (2023-09-21)
**Note:** Version bump only for package @standardnotes/files-server

View File

@@ -10,6 +10,7 @@ import helmet from 'helmet'
import * as cors from 'cors'
import { urlencoded, json, raw, Request, Response, NextFunction } from 'express'
import * as winston from 'winston'
import * as AWSXRay from 'aws-xray-sdk'
// eslint-disable-next-line @typescript-eslint/no-var-requires
const robots = require('express-robots-txt')
@@ -17,15 +18,27 @@ import { InversifyExpressServer } from 'inversify-express-utils'
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
import TYPES from '../src/Bootstrap/Types'
import { Env } from '../src/Bootstrap/Env'
import { ServiceIdentifier } from '@standardnotes/domain-core'
const container = new ContainerConfigLoader()
void container.load().then((container) => {
const env: Env = new Env()
env.load()
const isConfiguredForAWSProduction =
env.get('MODE', true) !== 'home-server' && env.get('MODE', true) !== 'self-hosted'
if (isConfiguredForAWSProduction) {
AWSXRay.config([AWSXRay.plugins.ECSPlugin])
}
const server = new InversifyExpressServer(container)
server.setConfig((app) => {
if (isConfiguredForAWSProduction) {
app.use(AWSXRay.express.openSegment(ServiceIdentifier.NAMES.Files))
}
app.use((_request: Request, response: Response, next: NextFunction) => {
response.setHeader('X-Files-Version', container.get(TYPES.Files_VERSION))
next()
@@ -90,6 +103,10 @@ void container.load().then((container) => {
const serverInstance = server.build()
if (isConfiguredForAWSProduction) {
serverInstance.use(AWSXRay.express.closeSegment())
}
serverInstance.listen(env.get('PORT'))
logger.info(`Server started on port ${process.env.PORT}`)

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