Compare commits

...

269 Commits

Author SHA1 Message Date
standardci
b510284e01 chore(release): publish new version
- @standardnotes/analytics@2.25.16
 - @standardnotes/api-gateway@1.71.1
 - @standardnotes/auth-server@1.134.0
 - @standardnotes/domain-events-infra@1.12.13
 - @standardnotes/domain-events@2.116.0
 - @standardnotes/event-store@1.11.22
 - @standardnotes/files-server@1.22.0
 - @standardnotes/home-server@1.15.0
 - @standardnotes/revisions-server@1.26.10
 - @standardnotes/scheduler-server@1.20.26
 - @standardnotes/security@1.11.0
 - @standardnotes/syncing-server@1.83.0
 - @standardnotes/websockets-server@1.10.20
2023-08-23 06:47:38 +00:00
Karol Sójko
205a1ed637 feat: add handling file moving and updating storage quota (#705)
* feat: add handling file moving and updating storage quota

* fix: getting file metada when moving files

* fix: missing event handler binding
2023-08-23 08:09:34 +02:00
standardci
2073c735a5 chore(release): publish new version
- @standardnotes/analytics@2.25.15
 - @standardnotes/api-gateway@1.71.0
 - @standardnotes/auth-server@1.133.0
 - @standardnotes/domain-events-infra@1.12.12
 - @standardnotes/domain-events@2.115.1
 - @standardnotes/event-store@1.11.21
 - @standardnotes/files-server@1.21.0
 - @standardnotes/home-server@1.14.2
 - @standardnotes/revisions-server@1.26.9
 - @standardnotes/scheduler-server@1.20.25
 - @standardnotes/security@1.10.0
 - @standardnotes/syncing-server@1.82.0
 - @standardnotes/websockets-server@1.10.19
2023-08-22 09:23:30 +00:00
Karol Sójko
34085ac6fb feat: consider shared vault owner quota when uploading files to shared vault (#704)
* fix(auth): updating storage quota on shared subscriptions

* fix(syncing-server): turn shared vault and key associations into value objects

* feat: consider shared vault owner quota when uploading files to shared vault

* fix: add passing x-shared-vault-owner-context value

* fix: refactor creating cross service token to not throw errors

* fix: caching cross service token

* fix: missing header in http service proxy
2023-08-22 10:49:58 +02:00
standardci
3d6559921b chore(release): publish new version
- @standardnotes/home-server@1.14.1
 - @standardnotes/scheduler-server@1.20.24
 - @standardnotes/syncing-server@1.81.0
2023-08-21 09:00:52 +00:00
Karol Sójko
15a7f0e71a fix(syncing-server): DocumentDB retry writes support (#703)
* fix(syncing-server): DocumentDB retry writes support

* fix: auth source for mongo
2023-08-21 10:25:56 +02:00
Karol Sójko
3e56243d6f fix(scheduler): remove exit interview form link (#702) 2023-08-21 08:42:21 +02:00
Karol Sójko
032fcb938d feat(syncing-server): add use case for migrating items from one database to another (#701) 2023-08-18 17:25:24 +02:00
standardci
e98393452b chore(release): publish new version
- @standardnotes/analytics@2.25.14
 - @standardnotes/api-gateway@1.70.5
 - @standardnotes/auth-server@1.132.0
 - @standardnotes/domain-core@1.26.0
 - @standardnotes/event-store@1.11.20
 - @standardnotes/files-server@1.20.4
 - @standardnotes/home-server@1.14.0
 - @standardnotes/revisions-server@1.26.8
 - @standardnotes/scheduler-server@1.20.23
 - @standardnotes/settings@1.21.25
 - @standardnotes/syncing-server@1.80.0
 - @standardnotes/websockets-server@1.10.18
2023-08-18 15:15:20 +00:00
Karol Sójko
302b624504 feat: add mechanism for determining if a user should use the primary or secondary items database (#700)
* feat(domain-core): introduce new role for users transitioning to new mechanisms

* feat: add mechanism for determining if a user should use the primary or secondary items database

* fix: add transition mode enabled switch in docker entrypoint

* fix(syncing-server): mapping roles from middleware

* fix: mongodb item repository binding

* fix: item backups service binding

* fix: passing transition mode enabled variable to docker setup
2023-08-18 16:45:10 +02:00
Karol Sójko
e00d9d2ca0 fix: e2e parameter for running vault tests 2023-08-18 11:11:54 +02:00
Karol Sójko
9ab4601c8d feat: add transition mode switch to e2e test suite 2023-08-18 11:00:36 +02:00
Karol Sójko
19e43bdb1a fix: run vault tests based on secondary db usage (#699) 2023-08-17 13:21:50 +02:00
standardci
49832e7944 chore(release): publish new version
- @standardnotes/home-server@1.13.51
 - @standardnotes/syncing-server@1.79.1
2023-08-17 10:15:43 +00:00
Karol Sójko
916e98936a fix(home-server): add default env values for secondary database 2023-08-17 11:56:56 +02:00
Karol Sójko
31d1eef7f7 fix(syncing-server): refactor shared vault and key system associations (#698)
* feat(syncing-server): refactor persistence of shared vault and key system associations

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

* fix: typeorm annotations for mongodb entity

* wip mongo repo

* feat: add mongodb queries

* fix(syncing-server): env sample

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

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

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

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

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

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

* fix(syncing-server): finding method for existing members
2023-08-08 14:31:23 +02:00
standardci
22b00479b4 chore(release): publish new version
- @standardnotes/analytics@2.25.9
 - @standardnotes/api-gateway@1.70.1
 - @standardnotes/auth-server@1.131.0
 - @standardnotes/domain-events-infra@1.12.11
 - @standardnotes/domain-events@2.115.0
 - @standardnotes/event-store@1.11.16
 - @standardnotes/files-server@1.20.0
 - @standardnotes/home-server@1.13.34
 - @standardnotes/revisions-server@1.26.3
 - @standardnotes/scheduler-server@1.20.18
 - @standardnotes/security@1.9.0
 - @standardnotes/syncing-server@1.77.0
 - @standardnotes/websockets-server@1.10.13
2023-08-08 12:06:10 +00:00
Karol Sójko
5311e74266 feat: update storage quota used for user based on shared vault files (#689)
* feat: update storage quota used for user based on shared vault files

* fix: use case binding

* fix: increase file upload bytes limit for shared vaults
2023-08-08 13:36:35 +02:00
standardci
5be7db7788 chore(release): publish new version
- @standardnotes/home-server@1.13.33
 - @standardnotes/syncing-server@1.76.1
2023-08-08 09:29:54 +00:00
Karol Sójko
3bd1547ce3 fix(syncing-server): race condition when adding admin user to newly created shared vault (#688) 2023-08-08 11:02:10 +02:00
standardci
a1fe15f7a9 chore(release): publish new version
- @standardnotes/api-gateway@1.70.0
 - @standardnotes/home-server@1.13.32
 - @standardnotes/syncing-server@1.76.0
2023-08-07 16:09:21 +00:00
Karol Sójko
19b8921f28 feat(syncing-server): limit shared vaults creation based on role (#687)
* feat(syncing-server): limit shared vaults creation based on role

* fix: add role names emptyness validation

* fix: roles passing to response locals
2023-08-07 17:35:47 +02:00
standardci
6b7879ba15 chore(release): publish new version
- @standardnotes/auth-server@1.130.1
 - @standardnotes/home-server@1.13.31
2023-08-07 11:50:26 +00:00
Karol Sójko
bd5f492a73 fix(auth): update user agent upon refreshing session token (#685) 2023-08-07 13:21:21 +02:00
standardci
67311cc002 chore(release): publish new version
- @standardnotes/auth-server@1.130.0
 - @standardnotes/home-server@1.13.30
2023-08-07 08:32:08 +00:00
Karol Sójko
f39d3aca5b feat(auth): invalidate other sessions for user if the email or password are changed (#684)
* feat(auth): invalidate other sessions for user if the email or password are changed

* fix(auth): handling credentials change in a legacy protocol scenario

* fix(auth): leave only the newly created session when changing credentials
2023-08-07 10:02:47 +02:00
standardci
8e47491e3c chore(release): publish new version
- @standardnotes/home-server@1.13.29
 - @standardnotes/syncing-server@1.75.4
2023-08-03 13:38:37 +00:00
Karol Sójko
0036d527bd fix(syncing-server): skip retrieval of items with invalid uuids (#683) 2023-08-03 15:05:59 +02:00
standardci
f565f1d950 chore(release): publish new version
- @standardnotes/analytics@2.25.8
 - @standardnotes/api-gateway@1.69.3
 - @standardnotes/auth-server@1.129.0
 - @standardnotes/domain-events-infra@1.12.10
 - @standardnotes/domain-events@2.114.0
 - @standardnotes/event-store@1.11.15
 - @standardnotes/files-server@1.19.18
 - @standardnotes/home-server@1.13.28
 - @standardnotes/revisions-server@1.26.2
 - @standardnotes/scheduler-server@1.20.17
 - @standardnotes/syncing-server@1.75.3
 - @standardnotes/websockets-server@1.10.12
2023-08-03 10:34:26 +00:00
Karol Sójko
8e35dfa4b7 feat(auth): add handling payments account deleted events STA-1769 (#682)
* feat(auth): add handling payments account deleted events

* fix(auth): result type for accounts already deleted

---------

Co-authored-by: Karol Sójko <karolsojko@proton.me>
2023-08-03 12:01:42 +02:00
standardci
f911473be9 chore(release): publish new version
- @standardnotes/analytics@2.25.7
 - @standardnotes/api-gateway@1.69.2
 - @standardnotes/auth-server@1.128.1
 - @standardnotes/domain-core@1.24.2
 - @standardnotes/event-store@1.11.14
 - @standardnotes/files-server@1.19.17
 - @standardnotes/home-server@1.13.27
 - @standardnotes/revisions-server@1.26.1
 - @standardnotes/scheduler-server@1.20.16
 - @standardnotes/settings@1.21.21
 - @standardnotes/syncing-server@1.75.2
 - @standardnotes/websockets-server@1.10.11
2023-08-02 15:51:56 +00:00
Karol Sójko
71624f1897 fix(domain-core): remove unused content types 2023-08-02 17:34:40 +02:00
standardci
17de6ea7e1 chore(release): publish new version
- @standardnotes/home-server@1.13.26
 - @standardnotes/syncing-server@1.75.1
2023-08-02 11:41:20 +00:00
Karol Sójko
6aad7cd207 fix(syncing-server): update unknown content type on items migration 2023-08-02 13:24:14 +02:00
standardci
63af335877 chore(release): publish new version
- @standardnotes/auth-server@1.128.0
 - @standardnotes/home-server@1.13.25
 - @standardnotes/revisions-server@1.26.0
 - @standardnotes/syncing-server@1.75.0
2023-08-02 08:09:24 +00:00
Karol Sójko
8cd7a138ab feat: enable Write Ahead Log mode for SQLite (#681)
Co-authored-by: Karol Sójko <karolsojko@proton.me>
2023-08-02 09:47:37 +02:00
standardci
f69cdc7b03 chore(release): publish new version
- @standardnotes/home-server@1.13.24
 - @standardnotes/syncing-server@1.74.1
 - @standardnotes/websockets-server@1.10.10
2023-08-02 07:35:12 +00:00
Karol Sójko
2ca649cf31 fix(syncing-server): encapsulate delete queries into transactions 2023-08-02 08:35:19 +02:00
Mo
f2ada08201 chore: remove unused package (#680) 2023-08-02 07:46:10 +02:00
Mo
54ba1f69e5 chore: bump mocha timeout 2023-08-01 16:46:19 -05:00
standardci
f13a99f5fd chore(release): publish new version
- @standardnotes/home-server@1.13.23
 - @standardnotes/syncing-server@1.74.0
2023-08-01 16:32:29 +00:00
Karol Sójko
e9bba6fd3a feat(syncing-server): remove legacy privileges items (#679)
Co-authored-by: Karol Sójko <karolsojko@proton.me>
2023-08-01 18:15:16 +02:00
standardci
f0d1a70c87 chore(release): publish new version
- @standardnotes/auth-server@1.127.2
 - @standardnotes/files-server@1.19.16
 - @standardnotes/home-server@1.13.22
 - @standardnotes/revisions-server@1.25.7
 - @standardnotes/syncing-server@1.73.1
 - @standardnotes/websockets-server@1.10.9
2023-08-01 07:53:07 +00:00
Karol Sójko
56f0aef21d fix: controller naming (#678)
* fix: rename home server controllers to base controllers

* fix: rename inversify express controllers to annotated controllers
2023-08-01 09:34:52 +02:00
standardci
75e266cb9e chore(release): publish new version
- @standardnotes/home-server@1.13.21
 - @standardnotes/syncing-server@1.73.0
2023-08-01 05:16:33 +00:00
Karol Sójko
b9bb83c0ce feat(syncing-server): add shared vault snjs filter (#677)
Co-authored-by: Mo <mo@standardnotes.com>
2023-08-01 07:00:14 +02:00
standardci
da645c5ab3 chore(release): publish new version
- @standardnotes/auth-server@1.127.1
 - @standardnotes/home-server@1.13.20
2023-07-31 13:33:09 +00:00
Karol Sójko
318af5757d fix(auth): auth middleware on delete account 2023-07-31 15:09:52 +02:00
standardci
b1cc156a25 chore(release): publish new version
- @standardnotes/api-gateway@1.69.1
 - @standardnotes/home-server@1.13.19
2023-07-31 12:35:22 +00:00
Karol Sójko
79d71ca161 fix(api-gateway): remove duplicating req/res objects on return raw response from payments 2023-07-31 14:19:01 +02:00
standardci
cedd50b366 chore(release): publish new version
- @standardnotes/api-gateway@1.69.0
 - @standardnotes/auth-server@1.127.0
 - @standardnotes/home-server@1.13.18
2023-07-31 11:41:55 +00:00
Karol Sójko
0d5dcdd8ec feat: refactor deleting account (#676)
* fix(api-gateway): TYPES aliases

* feat: refactor account deleting
2023-07-31 13:23:39 +02:00
standardci
d2b0fb144b chore(release): publish new version
- @standardnotes/home-server@1.13.17
 - @standardnotes/syncing-server@1.72.2
2023-07-30 13:24:19 +00:00
Mo
053852b46c fix: missing var reference and brackets (#675) 2023-07-30 08:09:23 -05:00
Karol Sójko
6ad349d379 fix: db name encapsulation 2023-07-28 13:32:13 +02:00
Karol Sójko
f7d33c7164 fix: separate databases and redis instances 2023-07-28 12:00:17 +02:00
Karol Sójko
b53b67328f fix: displaying logs on docker failure 2023-07-28 11:23:16 +02:00
Karol Sójko
573ffbfcf3 fix: add showing logs on docker error 2023-07-28 10:19:32 +02:00
Karol Sójko
501ac0e99f fix: env vars for database runs 2023-07-27 14:32:55 +02:00
Karol Sójko
959a11293a fix: separate database for different configuration 2023-07-27 14:19:21 +02:00
standardci
fee1f1a3a7 chore(release): publish new version
- @standardnotes/analytics@2.25.6
 - @standardnotes/api-gateway@1.68.1
 - @standardnotes/auth-server@1.126.5
 - @standardnotes/domain-core@1.24.1
 - @standardnotes/event-store@1.11.13
 - @standardnotes/files-server@1.19.15
 - @standardnotes/home-server@1.13.16
 - @standardnotes/revisions-server@1.25.6
 - @standardnotes/scheduler-server@1.20.15
 - @standardnotes/settings@1.21.20
 - @standardnotes/syncing-server@1.72.1
 - @standardnotes/websockets-server@1.10.8
2023-07-27 11:10:28 +00:00
Karol Sójko
b0fbe0bb58 fix: extended access token refresh ttl during home server e2e 2023-07-27 12:54:50 +02:00
Karol Sójko
0087c70007 fix: missing env var on e2e 2023-07-27 12:25:31 +02:00
Karol Sójko
36e496dd7c fix: remove dns aliases on accessing mysql and redis in home server e2e 2023-07-27 12:19:01 +02:00
Karol Sójko
f2e2030e85 fix: disable fail-fast on common e2e suite 2023-07-27 12:11:38 +02:00
Karol Sójko
0c3737dc19 fix: redirect STDERR for e2e to common output 2023-07-27 12:07:32 +02:00
Karol Sójko
f7471119e1 fix: add logging error stack on home server failure 2023-07-27 12:00:40 +02:00
Karol Sójko
9bd97b95e9 fix: unset the custom dbsqlite path for e2e 2023-07-27 11:46:48 +02:00
Karol Sójko
b7400c198f fix: setting env vars on common-e2e test suite 2023-07-27 11:30:49 +02:00
Karol Sójko
f87036e3a8 fix: setting env vars on home server in e2e environment 2023-07-27 11:26:05 +02:00
Karol Sójko
a43e5ef724 fix: outputing logs on e2e - already existing logs directory 2023-07-27 10:32:43 +02:00
Karol Sójko
913ced70b0 fix: outputing logs on e2e 2023-07-27 08:33:49 +02:00
standardci
6ffce30a36 chore(release): publish new version
- @standardnotes/api-gateway@1.68.0
 - @standardnotes/home-server@1.13.15
 - @standardnotes/syncing-server@1.72.0
2023-07-27 06:28:46 +00:00
Karol Sójko
f5a57d886c fix: show logs on failing suite 2023-07-27 08:13:49 +02:00
Karol Sójko
e8ba49ecca feat(syncing-server): add deleting outbound messages
Co-authored-by: Mo <mo@standardnotes.com>
2023-07-27 08:06:56 +02:00
Karol Sójko
c79a5dc94b fix: add e2e yarn command for convenience 2023-07-26 15:23:08 +02:00
standardci
4db83ae678 chore(release): publish new version
- @standardnotes/analytics@2.25.5
 - @standardnotes/api-gateway@1.67.4
 - @standardnotes/auth-server@1.126.4
 - @standardnotes/domain-core@1.24.0
 - @standardnotes/event-store@1.11.12
 - @standardnotes/files-server@1.19.14
 - @standardnotes/home-server@1.13.14
 - @standardnotes/revisions-server@1.25.5
 - @standardnotes/scheduler-server@1.20.14
 - @standardnotes/settings@1.21.19
 - @standardnotes/syncing-server@1.71.0
 - @standardnotes/websockets-server@1.10.7
2023-07-26 12:07:57 +00:00
basiljelly
84ceb7ffd2 Update docker-compose.example.yml (#673)
added restart policy for container server_self_hosted so it restarts after rebooting system
2023-07-26 13:52:40 +02:00
Karol Sójko
e215ac4343 feat: extract shared vault user permission to domain-core 2023-07-26 13:45:53 +02:00
standardci
bc8048790f chore(release): publish new version
- @standardnotes/home-server@1.13.13
 - @standardnotes/syncing-server@1.70.5
2023-07-26 11:19:11 +00:00
Karol Sójko
886ccf84c1 fix(syncing-server): uuid comparison when removing user 2023-07-26 13:02:03 +02:00
standardci
c067cb9fe4 chore(release): publish new version
- @standardnotes/home-server@1.13.12
 - @standardnotes/syncing-server@1.70.4
2023-07-26 10:54:46 +00:00
Karol Sójko
6b2389cdc3 fix(syncing-serve): removing other users from shared vault 2023-07-26 12:39:24 +02:00
standardci
d93916b159 chore(release): publish new version
- @standardnotes/analytics@2.25.4
 - @standardnotes/api-gateway@1.67.3
 - @standardnotes/auth-server@1.126.3
 - @standardnotes/domain-core@1.23.4
 - @standardnotes/event-store@1.11.11
 - @standardnotes/files-server@1.19.13
 - @standardnotes/home-server@1.13.11
 - @standardnotes/revisions-server@1.25.4
 - @standardnotes/scheduler-server@1.20.13
 - @standardnotes/settings@1.21.18
 - @standardnotes/syncing-server@1.70.3
 - @standardnotes/websockets-server@1.10.6
2023-07-26 10:38:44 +00:00
Karol Sójko
c34f548e45 fix(syncing-server): persisting aggregate changes from root (#674) 2023-07-26 12:23:10 +02:00
standardci
6fcd56cc86 chore(release): publish new version
- @standardnotes/home-server@1.13.10
 - @standardnotes/syncing-server@1.70.2
2023-07-25 14:07:10 +00:00
Karol Sójko
8f88a87c93 fix(syncing-server): remove notifications after adding item to vault (#672) 2023-07-25 15:51:42 +02:00
standardci
f8c2f84322 chore(release): publish new version
- @standardnotes/home-server@1.13.9
 - @standardnotes/syncing-server@1.70.1
2023-07-25 11:25:55 +00:00
Karol Sójko
46c4947871 fix(syncing-server): allow sender to decline the invite (#671) 2023-07-25 13:05:10 +02:00
standardci
64759ec2da chore(release): publish new version
- @standardnotes/home-server@1.13.8
 - @standardnotes/syncing-server@1.70.0
2023-07-25 11:03:19 +00:00
Karol Sójko
5f7e768e64 feat(syncing-server): filtering items by shared vault permissions (#670)
Co-authored-by: Mo <mo@standardnotes.com>
2023-07-25 12:45:49 +02:00
standardci
4bc189f1c5 chore(release): publish new version
- @standardnotes/home-server@1.13.7
 - @standardnotes/syncing-server@1.69.0
2023-07-24 14:29:21 +00:00
Karol Sójko
71721ab198 feat(syncing-server): determin shared vault operation type (#669)
Co-authored-by: Mo <mo@standardnotes.com>
2023-07-24 15:29:56 +02:00
standardci
5536a48966 chore(release): publish new version
- @standardnotes/home-server@1.13.6
 - @standardnotes/syncing-server@1.68.4
2023-07-24 09:15:15 +00:00
Karol Sójko
f77e29d3c9 fix(syncing-server): force remove shared vault owner when removing shared vault 2023-07-24 10:59:03 +02:00
standardci
4b1fc718a2 chore(release): publish new version
- @standardnotes/analytics@2.25.3
 - @standardnotes/api-gateway@1.67.2
 - @standardnotes/auth-server@1.126.2
 - @standardnotes/domain-core@1.23.3
 - @standardnotes/event-store@1.11.10
 - @standardnotes/files-server@1.19.12
 - @standardnotes/home-server@1.13.5
 - @standardnotes/revisions-server@1.25.3
 - @standardnotes/scheduler-server@1.20.12
 - @standardnotes/settings@1.21.17
 - @standardnotes/syncing-server@1.68.3
 - @standardnotes/websockets-server@1.10.5
2023-07-21 12:03:05 +00:00
Karol Sójko
1708c3f8a0 fix(domain-core): notification payload creation from string 2023-07-21 13:44:44 +02:00
standardci
352e02028d chore(release): publish new version
- @standardnotes/analytics@2.25.2
 - @standardnotes/api-gateway@1.67.1
 - @standardnotes/auth-server@1.126.1
 - @standardnotes/domain-core@1.23.2
 - @standardnotes/event-store@1.11.9
 - @standardnotes/files-server@1.19.11
 - @standardnotes/home-server@1.13.4
 - @standardnotes/revisions-server@1.25.2
 - @standardnotes/scheduler-server@1.20.11
 - @standardnotes/settings@1.21.16
 - @standardnotes/syncing-server@1.68.2
 - @standardnotes/websockets-server@1.10.4
2023-07-21 10:53:53 +00:00
Karol Sójko
1bbb639c83 fix: user notifications structure (#667) 2023-07-21 12:39:19 +02:00
standardci
c14265f103 chore(release): publish new version
- @standardnotes/home-server@1.13.3
 - @standardnotes/syncing-server@1.68.1
2023-07-21 07:37:04 +00:00
Karol Sójko
c030a6b3d8 fix(syncing-server): fetching items associated with shared vaults (#666) 2023-07-20 14:29:31 +02:00
standardci
af997ea658 chore(release): publish new version
- @standardnotes/api-gateway@1.67.0
 - @standardnotes/auth-server@1.126.0
 - @standardnotes/home-server@1.13.2
 - @standardnotes/syncing-server@1.68.0
2023-07-20 10:07:30 +00:00
Karol Sójko
efa4d7fc60 feat(syncing-server): add shared vaults, invites, messages and notifications to sync response (#665)
* feat(syncing-server): add shared vaults, invites, messages and notifications to sync response

* fix(syncing-server): migration timestamps

* fix: issue with migrations for notifications
2023-07-20 11:52:45 +02:00
standardci
f714aaa0e9 chore(release): publish new version
- @standardnotes/api-gateway@1.66.1
 - @standardnotes/home-server@1.13.1
 - @standardnotes/syncing-server@1.67.1
2023-07-19 07:42:57 +00:00
Karol Sójko
aee6e60583 fix: add missing imports and exports for controllers (#664) 2023-07-19 09:28:09 +02:00
standardci
4e602687d5 chore(release): publish new version
- @standardnotes/analytics@2.25.1
 - @standardnotes/api-gateway@1.66.0
 - @standardnotes/auth-server@1.125.1
 - @standardnotes/domain-core@1.23.1
 - @standardnotes/event-store@1.11.8
 - @standardnotes/files-server@1.19.10
 - @standardnotes/home-server@1.13.0
 - @standardnotes/revisions-server@1.25.1
 - @standardnotes/scheduler-server@1.20.10
 - @standardnotes/settings@1.21.15
 - @standardnotes/syncing-server@1.67.0
 - @standardnotes/websockets-server@1.10.3
2023-07-19 06:47:26 +00:00
Karol Sójko
d026152ac8 fix(syncing-server): add missing messages and key system identifier sql representations (#663) 2023-07-19 08:31:23 +02:00
Karol Sójko
3f21a358d2 feat(syncing-server): add persistence of shared vaults with users and invites + controllers (#662)
* feat(syncing-server): associating existing items with key systems and shared vaults

* fix(syncing-server): find item query

* feat(syncing-server): add persistence of shared vaults with users and invites

* feat: shared vault controllers
2023-07-19 07:28:03 +02:00
standardci
dc55e47c98 chore(release): publish new version
- @standardnotes/home-server@1.12.6
 - @standardnotes/syncing-server@1.66.0
2023-07-18 11:39:37 +00:00
Karol Sójko
3b804e2321 feat(syncing-server): associating existing items with key systems and shared vaults (#661)
* feat(syncing-server): associating existing items with key systems and shared vaults

* fix(syncing-server): find item query

* feat(syncing-server): add persistence of shared vaults with users and invites
2023-07-18 13:21:30 +02:00
standardci
b32f851a90 chore(release): publish new version
- @standardnotes/home-server@1.12.5
 - @standardnotes/syncing-server@1.65.0
2023-07-18 09:55:28 +00:00
Karol Sójko
479d20e76f feat(syncing-server): persisting shared vault and key system associations (#660) 2023-07-18 11:39:02 +02:00
standardci
fae4553fc8 chore(release): publish new version
- @standardnotes/analytics@2.25.0
 - @standardnotes/api-gateway@1.65.7
 - @standardnotes/auth-server@1.125.0
 - @standardnotes/domain-core@1.23.0
 - @standardnotes/event-store@1.11.7
 - @standardnotes/files-server@1.19.9
 - @standardnotes/home-server@1.12.4
 - @standardnotes/revisions-server@1.25.0
 - @standardnotes/scheduler-server@1.20.9
 - @standardnotes/settings@1.21.14
 - @standardnotes/syncing-server@1.64.0
 - @standardnotes/websockets-server@1.10.2
2023-07-17 11:46:13 +00:00
Karol Sójko
cb74b23e45 feat(syncing-server): refactor syncing to decouple getting and saving items (#659)
* feat(syncing-server): refactor syncing to decouple getting and saving items

* fix(syncing-server): item hash http representation mapping

* fix(syncing-server): remove redundant specs for inversify express controller
2023-07-17 13:28:50 +02:00
Karol Sójko
af8f12c33a fix: remove skip_paid_features flag from home server e2e testing 2023-07-14 10:30:22 +02:00
standardci
a148c4d1f6 chore(release): publish new version
- @standardnotes/auth-server@1.124.2
 - @standardnotes/home-server@1.12.3
2023-07-14 08:14:31 +00:00
Karol Sójko
f7190c0c9c fix(home-server): allow custom atributtes for activating premium features 2023-07-14 09:59:20 +02:00
Karol Sójko
c00d7765a9 fix: add missing files server url env var to e2e test suite 2023-07-14 09:34:31 +02:00
standardci
2b651d86e2 chore(release): publish new version
- @standardnotes/auth-server@1.124.1
 - @standardnotes/files-server@1.19.8
 - @standardnotes/home-server@1.12.2
2023-07-13 12:30:31 +00:00
Karol Sójko
9be3517093 fix(files): handling unlimited storage quota on home server 2023-07-13 14:16:05 +02:00
standardci
fcfedaf7e7 chore(release): publish new version
- @standardnotes/auth-server@1.124.0
 - @standardnotes/home-server@1.12.1
2023-07-13 12:08:15 +00:00
Karol Sójko
0b82794e9c feat(auth): add overriding subscription settings on home server (#656) 2023-07-13 13:53:33 +02:00
standardci
2a52e398cb chore(release): publish new version
- @standardnotes/home-server@1.12.0
2023-07-13 09:22:59 +00:00
Karol Sójko
c31e882ad2 chore: fix workflow to run e2e test suite mode in home server 2023-07-13 11:05:37 +02:00
Karol Sójko
2f0903e0eb feat(home-server): add activating premium features during an e2e test suite run 2023-07-13 10:58:35 +02:00
standardci
2396053bc1 chore(release): publish new version
- @standardnotes/auth-server@1.123.2
 - @standardnotes/files-server@1.19.7
 - @standardnotes/home-server@1.11.41
 - @standardnotes/revisions-server@1.24.1
 - @standardnotes/sncrypto-node@1.15.3
 - @standardnotes/syncing-server@1.63.1
 - @standardnotes/websockets-server@1.10.1
2023-07-12 12:42:08 +00:00
Karol Sójko
17fd12305e chore(deps): upgrade @standardnotes deps 2023-07-12 14:25:23 +02:00
standardci
425ea4374d chore(release): publish new version
- @standardnotes/auth-server@1.123.1
 - @standardnotes/home-server@1.11.40
2023-07-12 09:20:55 +00:00
Karol Sójko
c076c3c74a chore(deps): upgrade @standardnotes/features 2023-07-12 11:05:44 +02:00
standardci
547cdfd8ec chore(release): publish new version
- @standardnotes/analytics@2.24.9
 - @standardnotes/api-gateway@1.65.6
 - @standardnotes/auth-server@1.123.0
 - @standardnotes/common@1.50.0
 - @standardnotes/domain-core@1.22.0
 - @standardnotes/event-store@1.11.6
 - @standardnotes/files-server@1.19.6
 - @standardnotes/home-server@1.11.39
 - @standardnotes/revisions-server@1.24.0
 - @standardnotes/scheduler-server@1.20.8
 - @standardnotes/settings@1.21.13
 - @standardnotes/syncing-server@1.63.0
 - @standardnotes/websockets-server@1.10.0
2023-07-12 08:34:32 +00:00
Karol Sójko
a0af8f0025 feat: domain items (#655)
* feat: content type as a value object

* feat: turn items into domain entities

* fix: update @standardnotes/api

* fix(syncing-server): bindings order
2023-07-12 10:19:22 +02:00
standardci
c970b1ea68 chore(release): publish new version
- @standardnotes/home-server@1.11.38
 - @standardnotes/syncing-server@1.62.1
2023-07-11 15:22:11 +00:00
Karol Sójko
4d1e2dec26 fix: unify use case usage (#654) 2023-07-11 17:05:45 +02:00
standardci
108408a944 chore(release): publish new version
- @standardnotes/home-server@1.11.37
 - @standardnotes/syncing-server@1.62.0
2023-07-10 12:37:48 +00:00
Karol Sójko
18d07d431f feat: messages controller. (#653)
Co-authored-by: Mo <mo@standardnotes.com>
2023-07-10 14:21:59 +02:00
standardci
cbc024f67a chore(release): publish new version
- @standardnotes/home-server@1.11.36
 - @standardnotes/syncing-server@1.61.0
2023-07-10 11:54:54 +00:00
Karol Sójko
55ec5970da feat: message operations use cases. (#652)
Co-authored-by: Mo <mo@standardnotes.com>
2023-07-10 13:38:07 +02:00
standardci
58bdca6659 chore(release): publish new version
- @standardnotes/home-server@1.11.35
 - @standardnotes/syncing-server@1.60.0
2023-07-10 11:25:21 +00:00
Karol Sójko
ef49b0d3f8 feat: sending messages. (#651)
* feat: sending messages.

Co-authored-by: Mo <mo@standardnotes.com>

* fix: messages repository.

Co-authored-by: Mo <mo@standardnotes.com>

---------

Co-authored-by: Mo <mo@standardnotes.com>
2023-07-10 13:10:31 +02:00
standardci
9cb691e5ad chore(release): publish new version
- @standardnotes/home-server@1.11.34
 - @standardnotes/syncing-server@1.59.1
2023-07-10 10:58:38 +00:00
Karol Sójko
04d09582d4 fix: restructure use cases (#650) 2023-07-10 12:43:20 +02:00
standardci
8f90dc172b chore(release): publish new version
- @standardnotes/home-server@1.11.33
 - @standardnotes/syncing-server@1.59.0
2023-07-10 10:27:47 +00:00
Karol Sójko
f759261919 feat: user to user message model. (#649)
Co-authored-by: Mo <mo@standardnotes.com>
2023-07-10 12:10:25 +02:00
standardci
2606f6d929 chore(release): publish new version
- @standardnotes/analytics@2.24.8
 - @standardnotes/api-gateway@1.65.5
 - @standardnotes/auth-server@1.122.2
 - @standardnotes/domain-core@1.21.1
 - @standardnotes/domain-events-infra@1.12.9
 - @standardnotes/domain-events@2.113.1
 - @standardnotes/event-store@1.11.5
 - @standardnotes/files-server@1.19.5
 - @standardnotes/home-server@1.11.32
 - @standardnotes/revisions-server@1.23.9
 - @standardnotes/scheduler-server@1.20.7
 - @standardnotes/settings@1.21.12
 - @standardnotes/syncing-server@1.58.1
 - @standardnotes/websockets-server@1.9.8
2023-07-07 13:30:56 +00:00
Karol Sójko
c288e5d8dc fix: transfer notifications from auth to syncing-server. (#648)
* fix: transfer notifications from auth to syncing-server.

Co-authored-by: Mo <mo@standardnotes.com>

* fix: add notification to data source init

---------

Co-authored-by: Mo <mo@standardnotes.com>
2023-07-07 15:12:27 +02:00
standardci
4b76d4b71e chore(release): publish new version
- @standardnotes/home-server@1.11.31
 - @standardnotes/syncing-server@1.58.0
2023-07-07 11:53:44 +00:00
Karol Sójko
72310130d2 feat: shared vault invites controller and use cases (#647)
* feat: get shared vault invites sent by user.

Co-authored-by: Mo <mo@standardnotes.com>

* feat: shared vault invites controller.

Co-authored-by: Mo <mo@standardnotes.com>

---------

Co-authored-by: Mo <mo@standardnotes.com>
2023-07-07 13:39:43 +02:00
standardci
f9e51ef06e chore(release): publish new version
- @standardnotes/home-server@1.11.30
 - @standardnotes/syncing-server@1.57.0
2023-07-06 12:09:05 +00:00
Karol Sójko
92a5eb0d98 feat: remove inbound shared vault invites. (#646)
Co-authored-by: Mo <mo@standardnotes.com>
2023-07-06 13:53:52 +02:00
standardci
77d2ea1a1f chore(release): publish new version
- @standardnotes/home-server@1.11.29
 - @standardnotes/syncing-server@1.56.0
2023-07-06 11:06:03 +00:00
Karol Sójko
92f96ddb84 feat: accept and decline shared vault invites (#645)
* feat: accept shared vault invite.

Co-authored-by: Mo <mo@standardnotes.com>

* feat: decline shared vault invite.

Co-authored-by: Mo <mo@standardnotes.com>

---------

Co-authored-by: Mo <mo@standardnotes.com>
2023-07-06 12:47:48 +02:00
standardci
15a914e25e chore(release): publish new version
- @standardnotes/home-server@1.11.28
 - @standardnotes/syncing-server@1.55.0
2023-07-06 10:12:49 +00:00
Karol Sójko
912a29d091 feat: update shared vault invite. (#644)
Co-authored-by: Mo <mo@standardnotes.com>
2023-07-06 11:58:45 +02:00
Karol Sójko
b2c32ce70e feat: shared vault users controller. (#643)
Co-authored-by: Mo <mo@standardnotes.com>
2023-07-06 11:41:36 +02:00
standardci
ed1a708c40 chore(release): publish new version
- @standardnotes/analytics@2.24.7
 - @standardnotes/api-gateway@1.65.4
 - @standardnotes/auth-server@1.122.1
 - @standardnotes/domain-core@1.21.0
 - @standardnotes/event-store@1.11.4
 - @standardnotes/files-server@1.19.4
 - @standardnotes/home-server@1.11.27
 - @standardnotes/revisions-server@1.23.8
 - @standardnotes/scheduler-server@1.20.6
 - @standardnotes/settings@1.21.11
 - @standardnotes/syncing-server@1.54.0
 - @standardnotes/websockets-server@1.9.7
2023-07-06 09:34:50 +00:00
Karol Sójko
e905128d45 feat: getting shared vault users and removing shared vault user (#642)
* feat: getting shared vault users.

Co-authored-by: Mo <mo@standardnotes.com>

* feat: removing shared vault user.

Co-authored-by: Mo <mo@standardnotes.com>

---------

Co-authored-by: Mo <mo@standardnotes.com>
2023-07-06 11:18:06 +02:00
standardci
fd598f372a chore(release): publish new version
- @standardnotes/home-server@1.11.26
 - @standardnotes/syncing-server@1.53.0
2023-07-05 13:33:44 +00:00
Karol Sójko
7a3946a9e2 feat: http controllers for shared vaults. (#641)
Co-authored-by: Mo <mo@standardnotes.com>
2023-07-05 15:17:43 +02:00
standardci
cbdd2584d0 chore(release): publish new version
- @standardnotes/analytics@2.24.6
 - @standardnotes/api-gateway@1.65.3
 - @standardnotes/auth-server@1.122.0
 - @standardnotes/domain-core@1.20.0
 - @standardnotes/domain-events-infra@1.12.8
 - @standardnotes/domain-events@2.113.0
 - @standardnotes/event-store@1.11.3
 - @standardnotes/files-server@1.19.3
 - @standardnotes/home-server@1.11.25
 - @standardnotes/revisions-server@1.23.7
 - @standardnotes/scheduler-server@1.20.5
 - @standardnotes/settings@1.21.10
 - @standardnotes/syncing-server@1.52.0
 - @standardnotes/websockets-server@1.9.6
2023-07-05 11:59:55 +00:00
Karol Sójko
f3161c2712 feat: deleting shared vaults. (#640)
Co-authored-by: Mo <mo@standardnotes.com>
2023-07-05 13:45:49 +02:00
standardci
148542dd5a chore(release): publish new version
- @standardnotes/home-server@1.11.24
 - @standardnotes/syncing-server@1.51.0
2023-07-05 09:17:53 +00:00
Karol Sójko
d2b2c339f2 feat: add getting shared vaults for a user (#639) 2023-07-05 11:01:21 +02:00
standardci
d2578c48f0 chore(release): publish new version
- @standardnotes/auth-server@1.121.0
 - @standardnotes/home-server@1.11.23
2023-07-05 08:21:19 +00:00
Karol Sójko
fecfd54728 feat(auth): add notifications model (#638) 2023-07-05 10:03:01 +02:00
Karol Sójko
17e4162d3e Revert "fix: unplug node-gyp based deps (#637)"
This reverts commit 742209d773.
2023-07-04 12:56:10 +02:00
Karol Sójko
742209d773 fix: unplug node-gyp based deps (#637) 2023-07-04 10:42:44 +02:00
standardci
1fa4b7cf27 chore(release): publish new version
- @standardnotes/home-server@1.11.22
 - @standardnotes/syncing-server@1.50.0
2023-07-03 17:55:21 +00:00
Karol Sójko
5dc5507039 feat: add invite users to a shared vault. (#636)
Co-authored-by: Mo <mo@standardnotes.com>
2023-07-03 19:40:36 +02:00
standardci
3035a20b9f chore(release): publish new version
- @standardnotes/home-server@1.11.21
 - @standardnotes/syncing-server@1.49.0
2023-07-03 16:58:01 +00:00
Karol Sójko
04b3bb034f feat: add creating shared vault file valet tokens. (#635)
Co-authored-by: Mo <mo@standardnotes.com>
2023-07-03 18:43:32 +02:00
standardci
bf84be0136 chore(release): publish new version
- @standardnotes/home-server@1.11.20
 - @standardnotes/syncing-server@1.48.0
2023-07-03 10:14:10 +00:00
Karol Sójko
890cf48749 feat: add shared vault invite model. (#634)
Co-authored-by: Mo <mo@standardnotes.com>
2023-07-03 11:54:52 +02:00
standardci
2b3436c6ce chore(release): publish new version
- @standardnotes/home-server@1.11.19
 - @standardnotes/syncing-server@1.47.0
2023-06-30 13:25:38 +00:00
Karol Sójko
4df8c3b2e5 feat: add use case for creating shared vaults and adding users to it. (#633)
Co-authored-by: Mo <mo@standardnotes.com>
2023-06-30 15:11:12 +02:00
standardci
25a2696c32 chore(release): publish new version
- @standardnotes/home-server@1.11.18
 - @standardnotes/syncing-server@1.46.0
2023-06-30 11:33:49 +00:00
Karol Sójko
52f879f842 feat: add shared vaults user model. (#632)
Co-authored-by: Mo <mo@standardnotes.com>
2023-06-30 13:19:31 +02:00
standardci
4f70fa156d chore(release): publish new version
- @standardnotes/analytics@2.24.5
 - @standardnotes/api-gateway@1.65.2
 - @standardnotes/auth-server@1.120.2
 - @standardnotes/domain-core@1.19.0
 - @standardnotes/event-store@1.11.2
 - @standardnotes/files-server@1.19.2
 - @standardnotes/home-server@1.11.17
 - @standardnotes/revisions-server@1.23.6
 - @standardnotes/scheduler-server@1.20.4
 - @standardnotes/settings@1.21.9
 - @standardnotes/syncing-server@1.45.0
 - @standardnotes/websockets-server@1.9.5
2023-06-30 11:00:32 +00:00
Karol Sójko
38e77f04be feat: add shared vaults model. (#631)
Co-authored-by: Mo <mo@standardnotes.com>
2023-06-30 12:44:27 +02:00
standardci
060206ddd4 chore(release): publish new version
- @standardnotes/analytics@2.24.4
 - @standardnotes/api-gateway@1.65.1
 - @standardnotes/auth-server@1.120.1
 - @standardnotes/domain-events-infra@1.12.7
 - @standardnotes/domain-events@2.112.1
 - @standardnotes/event-store@1.11.1
 - @standardnotes/files-server@1.19.1
 - @standardnotes/home-server@1.11.16
 - @standardnotes/revisions-server@1.23.5
 - @standardnotes/scheduler-server@1.20.3
 - @standardnotes/security@1.8.1
 - @standardnotes/syncing-server@1.44.6
 - @standardnotes/websockets-server@1.9.4
2023-06-30 10:24:00 +00:00
Mo
0bc0909386 chore: types lint (#630) 2023-06-30 05:07:47 -05:00
standardci
667d528a8c chore(release): publish new version
- @standardnotes/analytics@2.24.3
 - @standardnotes/api-gateway@1.65.0
 - @standardnotes/auth-server@1.120.0
 - @standardnotes/common@1.49.0
 - @standardnotes/domain-events-infra@1.12.6
 - @standardnotes/domain-events@2.112.0
 - @standardnotes/event-store@1.11.0
 - @standardnotes/files-server@1.19.0
 - @standardnotes/home-server@1.11.15
 - @standardnotes/revisions-server@1.23.4
 - @standardnotes/scheduler-server@1.20.2
 - @standardnotes/security@1.8.0
 - @standardnotes/syncing-server@1.44.5
 - @standardnotes/websockets-server@1.9.3
2023-06-30 09:47:02 +00:00
Karol Sójko
fa7fbe26e7 feat: shared vaults functionality in api-gateway,auth,files,common,security,domain-events. (#629)
Co-authored-by: Mo <mo@standardnotes.com>
2023-06-30 11:31:25 +02:00
standardci
ba422a29d0 chore(release): publish new version
- @standardnotes/auth-server@1.119.6
 - @standardnotes/home-server@1.11.14
2023-06-28 16:11:23 +00:00
Karol Sójko
d220ec5bf7 fix(auth): add debug logs for authentication method resolver 2023-06-28 17:56:59 +02:00
standardci
7baf5492bc chore(release): publish new version
- @standardnotes/api-gateway@1.64.3
 - @standardnotes/auth-server@1.119.5
 - @standardnotes/home-server@1.11.13
 - @standardnotes/syncing-server@1.44.4
2023-06-28 12:45:50 +00:00
Karol Sójko
d5a8409bb5 fix: add debug logs for invalid-auth responses 2023-06-28 14:30:39 +02:00
standardci
f58f90667c chore(release): publish new version
- @standardnotes/analytics@2.24.2
 - @standardnotes/auth-server@1.119.4
 - @standardnotes/common@1.48.3
 - @standardnotes/home-server@1.11.12
 - @standardnotes/revisions-server@1.23.3
 - @standardnotes/syncing-server@1.44.3
 - @standardnotes/websockets-server@1.9.2
2023-06-28 11:17:34 +00:00
Mo
a388e1a802 chore: add new content types 2023-06-28 06:02:18 -05:00
standardci
8811d10a73 chore(release): publish new version
- @standardnotes/home-server@1.11.11
2023-06-22 12:10:36 +00:00
Karol Sójko
c7a394cd1a fix(home-server): destroy winston loggers upon server shutdown 2023-06-22 13:56:05 +02:00
standardci
b7615a7f2e chore(release): publish new version
- @standardnotes/home-server@1.11.10
2023-06-22 11:30:12 +00:00
Karol Sójko
1ca70c1e50 fix(home-server): pass the log stream callback before loggers are created 2023-06-22 13:15:33 +02:00
standardci
253cbb1d0c chore(release): publish new version
- @standardnotes/home-server@1.11.9
2023-06-22 10:52:11 +00:00
Karol Sójko
e38a16404c fix(home-server): listening on log stream 2023-06-22 12:37:19 +02:00
Karol Sójko
f17a1f875c fix(home-server): passthrough stream for loggers 2023-06-22 12:33:23 +02:00
standardci
2237e0f5df chore(release): publish new version
- @standardnotes/api-gateway@1.64.2
 - @standardnotes/auth-server@1.119.3
 - @standardnotes/files-server@1.18.3
 - @standardnotes/home-server@1.11.8
 - @standardnotes/revisions-server@1.23.2
 - @standardnotes/syncing-server@1.44.2
2023-06-22 10:05:28 +00:00
Karol Sójko
0df471585f fix(home-server): add debug logs about container initalizations 2023-06-22 11:50:59 +02:00
standardci
95aac1a7bf chore(release): publish new version
- @standardnotes/home-server@1.11.7
2023-06-22 08:23:45 +00:00
Karol Sójko
c078bc958d fix(home-server): add default log level to overrides 2023-06-22 10:06:54 +02:00
Karol Sójko
49c27924ea fix(home-server): add log leve information to starting the home server information 2023-06-22 09:08:37 +02:00
standardci
c9dd8e7338 chore(release): publish new version
- @standardnotes/home-server@1.11.6
2023-06-16 09:44:09 +00:00
Karol Sójko
5ef90cc75b fix(home-server): unref the server instance when stopping the home server 2023-06-16 11:30:04 +02:00
standardci
063c61d96c chore(release): publish new version
- @standardnotes/auth-server@1.119.2
 - @standardnotes/home-server@1.11.5
 - @standardnotes/revisions-server@1.23.1
 - @standardnotes/syncing-server@1.44.1
2023-06-14 06:19:56 +00:00
Karol Sójko
0cb5e36b20 fix(home-server): env var determining the sqlite database location (#626) 2023-06-14 08:05:48 +02:00
standardci
319bab5b34 chore(release): publish new version
- @standardnotes/home-server@1.11.4
2023-06-13 12:19:56 +00:00
Karol Sójko
90a4f2111f fix(home-server): encapsulate starting the server with a result return 2023-06-13 14:03:39 +02:00
standardci
3aba202970 chore(release): publish new version
- @standardnotes/files-server@1.18.2
 - @standardnotes/home-server@1.11.3
2023-06-12 10:09:28 +00:00
Karol Sójko
c8974b7fa2 fix(home-server): accept application/octet-stream requests for files (#625)
* fix(home-server): accept application/octet-stream requests for files

* fix(files): check for empty chunks
2023-06-12 11:55:18 +02:00
standardci
3654a19586 chore(release): publish new version
- @standardnotes/files-server@1.18.1
 - @standardnotes/home-server@1.11.2
2023-06-09 11:51:44 +00:00
Karol Sójko
5f0929c1aa fix(files): add debug logs for checking chunks upon finishing upload session 2023-06-09 13:37:30 +02:00
standardci
c0fa83bce6 chore(release): publish new version
- @standardnotes/api-gateway@1.64.1
 - @standardnotes/auth-server@1.119.1
 - @standardnotes/home-server@1.11.1
2023-06-09 11:14:28 +00:00
Karol Sójko
c201ee42a0 fix(home-server): add default value for valet token ttl 2023-06-09 12:56:57 +02:00
Karol Sójko
e6a4cc3098 fix(api-gateway): direct call service proxy to return 400 responses instead of throwing errors 2023-06-09 12:52:58 +02:00
standardci
39f2fe2ba1 chore(release): publish new version
- @standardnotes/auth-server@1.119.0
 - @standardnotes/home-server@1.11.0
2023-06-09 06:13:41 +00:00
Karol Sójko
72ce190996 feat(home-server): add activating premium features (#624) 2023-06-09 07:59:07 +02:00
standardci
527dd1b61b chore(release): publish new version
- @standardnotes/auth-server@1.118.0
 - @standardnotes/home-server@1.10.0
 - @standardnotes/revisions-server@1.23.0
 - @standardnotes/syncing-server@1.44.0
2023-06-07 08:53:34 +00:00
Karol Sójko
af8feaadfe feat: configurable path for uploads and db (#623)
* fix(home-server): passing the database path

* fix(home-server): passing the file upload path
2023-06-07 10:39:33 +02:00
standardci
3164f76662 chore(release): publish new version
- @standardnotes/api-gateway@1.64.0
 - @standardnotes/auth-server@1.117.0
 - @standardnotes/files-server@1.18.0
 - @standardnotes/home-server@1.9.0
 - @standardnotes/revisions-server@1.22.0
 - @standardnotes/syncing-server@1.43.0
2023-06-05 10:01:28 +00:00
Karol Sójko
d6e531d4b6 feat(home-server): allow running the home server with a mysql and redis configuration (#622)
* feat(home-server): allow running the home server with a mysql and redis configuration

* fix(files): config for file uploader

* fix(files): if condition on fs file uploader bootstrap
2023-06-05 11:47:10 +02:00
710 changed files with 24453 additions and 6372 deletions

9
.github/ci.env vendored
View File

@@ -4,12 +4,13 @@ DB_USERNAME=std_notes_user
DB_PASSWORD=changeme123
DB_DATABASE=standard_notes_db
DB_PORT=3306
DB_SQLITE_DATABASE_PATH=standard_notes_db
REDIS_PORT=6379
REDIS_HOST=cache
AUTH_SERVER_ACCESS_TOKEN_AGE=4
AUTH_SERVER_REFRESH_TOKEN_AGE=10
AUTH_SERVER_EPHEMERAL_SESSION_AGE=300
SYNCING_SERVER_REVISIONS_FREQUENCY=5
SYNCING_SERVER_REVISIONS_FREQUENCY=2
AUTH_SERVER_LOG_LEVEL=debug
SYNCING_SERVER_LOG_LEVEL=debug
FILES_SERVER_LOG_LEVEL=debug
@@ -21,6 +22,12 @@ MYSQL_USER=std_notes_user
MYSQL_PASSWORD=changeme123
MYSQL_ROOT_PASSWORD=changeme123
MONGO_HOST=secondary_db
MONGO_PORT=27017
MONGO_USERNAME=standardnotes
MONGO_PASSWORD=standardnotes
MONGO_DATABASE=standardnotes
AUTH_JWT_SECRET=f95259c5e441f5a4646d76422cfb3df4c4488842901aa50b6c51b8be2e0040e9
AUTH_SERVER_ENCRYPTION_SERVER_KEY=1087415dfde3093797f9a7ca93a49e7d7aa1861735eb0d32aae9c303b8c3d060
VALET_TOKEN_SECRET=4b886819ebe1e908077c6cae96311b48a8416bd60cc91c03060e15bdf6b30d1f

View File

@@ -20,6 +20,11 @@ on:
jobs:
e2e:
name: (Docker) E2E Test Suite
strategy:
fail-fast: false
matrix:
secondary_db_enabled: [true, false]
transition_mode_enabled: [true, false]
runs-on: ubuntu-latest
services:
@@ -45,15 +50,42 @@ jobs:
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: Define if vault tests are enabled
id: vaults
run: |
if [ "${{ matrix.secondary_db_enabled }}" = "true" ] && [ "${{ matrix.transition_mode_enabled }}" = "true" ]; then
echo "vault-tests=enabled" >> $GITHUB_OUTPUT
else
echo "vault-tests=disabled" >> $GITHUB_OUTPUT
fi
- name: Run E2E Test Suite
run: yarn dlx mocha-headless-chrome --timeout 1200000 -f http://localhost:9001/mocha/test.html
run: yarn dlx mocha-headless-chrome --timeout 1800000 -f http://localhost:9001/mocha/test.html?vaults=${{ steps.vaults.outputs.vault-tests }}
- name: Show logs on failure
if: ${{ failure() }}
run: |
echo "# Errors:"
tail -n 100 logs/*.err
echo "# Logs:"
tail -n 100 logs/*.log
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:
@@ -61,6 +93,27 @@ jobs:
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
@@ -88,16 +141,47 @@ jobs:
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=7" >> packages/home-server/.env
echo "REVISIONS_FREQUENCY=5" >> 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 "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 &
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: Define if vault tests are enabled
id: vaults
run: |
if [ "${{ matrix.secondary_db_enabled }}" = "true" ] && [ "${{ matrix.transition_mode_enabled }}" = "true" ]; then
echo "vault-tests=enabled" >> $GITHUB_OUTPUT
else
echo "vault-tests=disabled" >> $GITHUB_OUTPUT
fi
- name: Run E2E Test Suite
run: yarn dlx mocha-headless-chrome --timeout 1200000 -f http://localhost:9001/mocha/test.html?skip_paid_features=true
run: yarn dlx mocha-headless-chrome --timeout 1800000 -f http://localhost:9001/mocha/test.html?vaults=${{ steps.vaults.outputs.vault-tests }}
- name: Show logs on failure
if: ${{ failure() }}
run: tail -n 500 logs/output.log

326
.pnp.cjs generated
View File

@@ -4560,17 +4560,16 @@ const RAW_RUNTIME_STATE =
}]\
]],\
["@standardnotes/api", [\
["npm:1.26.10", {\
"packageLocation": "./.yarn/cache/@standardnotes-api-npm-1.26.10-f6165cafd3-3c3561aec8.zip/node_modules/@standardnotes/api/",\
["npm:1.26.26", {\
"packageLocation": "./.yarn/cache/@standardnotes-api-npm-1.26.26-4338a5fe92-db41aedfa3.zip/node_modules/@standardnotes/api/",\
"packageDependencies": [\
["@standardnotes/api", "npm:1.26.10"],\
["@standardnotes/api", "npm:1.26.26"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/encryption", "npm:1.21.38"],\
["@standardnotes/models", "npm:1.45.5"],\
["@standardnotes/responses", "npm:1.13.24"],\
["@standardnotes/models", "npm:1.46.8"],\
["@standardnotes/responses", "npm:1.13.27"],\
["@standardnotes/security", "workspace:packages/security"],\
["@standardnotes/utils", "npm:1.16.5"],\
["@standardnotes/utils", "npm:1.17.5"],\
["reflect-metadata", "npm:0.1.13"]\
],\
"linkType": "HARD"\
@@ -4635,17 +4634,17 @@ const RAW_RUNTIME_STATE =
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.1"],\
["@simplewebauthn/server", "npm:7.2.0"],\
["@simplewebauthn/typescript-types", "npm:7.0.0"],\
["@standardnotes/api", "npm:1.26.10"],\
["@standardnotes/api", "npm:1.26.26"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@standardnotes/features", "npm:1.59.5"],\
["@standardnotes/features", "npm:1.59.7"],\
["@standardnotes/predicates", "workspace:packages/predicates"],\
["@standardnotes/responses", "npm:1.13.24"],\
["@standardnotes/responses", "npm:1.13.27"],\
["@standardnotes/security", "workspace:packages/security"],\
["@standardnotes/settings", "workspace:packages/settings"],\
["@standardnotes/sncrypto-common", "npm:1.13.3"],\
["@standardnotes/sncrypto-common", "npm:1.13.4"],\
["@standardnotes/sncrypto-node", "workspace:packages/sncrypto-node"],\
["@standardnotes/time", "workspace:packages/time"],\
["@types/bcryptjs", "npm:2.4.2"],\
@@ -4781,21 +4780,6 @@ const RAW_RUNTIME_STATE =
"linkType": "SOFT"\
}]\
]],\
["@standardnotes/encryption", [\
["npm:1.21.38", {\
"packageLocation": "./.yarn/cache/@standardnotes-encryption-npm-1.21.38-d08c3d4766-1393840523.zip/node_modules/@standardnotes/encryption/",\
"packageDependencies": [\
["@standardnotes/encryption", "npm:1.21.38"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/models", "npm:1.45.5"],\
["@standardnotes/responses", "npm:1.13.24"],\
["@standardnotes/sncrypto-common", "npm:1.13.3"],\
["@standardnotes/utils", "npm:1.16.5"],\
["reflect-metadata", "npm:0.1.13"]\
],\
"linkType": "HARD"\
}]\
]],\
["@standardnotes/event-store", [\
["workspace:packages/event-store", {\
"packageLocation": "./packages/event-store/",\
@@ -4831,10 +4815,10 @@ const RAW_RUNTIME_STATE =
}]\
]],\
["@standardnotes/features", [\
["npm:1.59.5", {\
"packageLocation": "./.yarn/cache/@standardnotes-features-npm-1.59.5-83c83acde9-173b1f5d52.zip/node_modules/@standardnotes/features/",\
["npm:1.59.7", {\
"packageLocation": "./.yarn/cache/@standardnotes-features-npm-1.59.7-27c3e5296e-1632d64cc1.zip/node_modules/@standardnotes/features/",\
"packageDependencies": [\
["@standardnotes/features", "npm:1.59.5"],\
["@standardnotes/features", "npm:1.59.7"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/security", "workspace:packages/security"],\
@@ -4855,7 +4839,7 @@ const RAW_RUNTIME_STATE =
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@standardnotes/security", "workspace:packages/security"],\
["@standardnotes/sncrypto-common", "npm:1.13.3"],\
["@standardnotes/sncrypto-common", "npm:1.13.4"],\
["@standardnotes/sncrypto-node", "workspace:packages/sncrypto-node"],\
["@standardnotes/time", "workspace:packages/time"],\
["@types/connect-busboy", "npm:1.0.0"],\
@@ -4935,14 +4919,16 @@ const RAW_RUNTIME_STATE =
}]\
]],\
["@standardnotes/models", [\
["npm:1.45.5", {\
"packageLocation": "./.yarn/cache/@standardnotes-models-npm-1.45.5-29326e959c-15f26c11b2.zip/node_modules/@standardnotes/models/",\
["npm:1.46.8", {\
"packageLocation": "./.yarn/cache/@standardnotes-models-npm-1.46.8-bc0390832e-8404340f27.zip/node_modules/@standardnotes/models/",\
"packageDependencies": [\
["@standardnotes/models", "npm:1.45.5"],\
["@standardnotes/models", "npm:1.46.8"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/features", "npm:1.59.5"],\
["@standardnotes/responses", "npm:1.13.24"],\
["@standardnotes/utils", "npm:1.16.5"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/features", "npm:1.59.7"],\
["@standardnotes/responses", "npm:1.13.27"],\
["@standardnotes/sncrypto-common", "npm:1.13.4"],\
["@standardnotes/utils", "npm:1.17.5"],\
["lodash", "npm:4.17.21"]\
],\
"linkType": "HARD"\
@@ -4967,12 +4953,12 @@ const RAW_RUNTIME_STATE =
}]\
]],\
["@standardnotes/responses", [\
["npm:1.13.24", {\
"packageLocation": "./.yarn/cache/@standardnotes-responses-npm-1.13.24-3b4167c7ea-3bcfee90f0.zip/node_modules/@standardnotes/responses/",\
["npm:1.13.27", {\
"packageLocation": "./.yarn/cache/@standardnotes-responses-npm-1.13.27-829dec3e6e-9bf55e5f02.zip/node_modules/@standardnotes/responses/",\
"packageDependencies": [\
["@standardnotes/responses", "npm:1.13.24"],\
["@standardnotes/responses", "npm:1.13.27"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/features", "npm:1.59.5"],\
["@standardnotes/features", "npm:1.59.7"],\
["@standardnotes/security", "workspace:packages/security"],\
["reflect-metadata", "npm:0.1.13"]\
],\
@@ -4987,12 +4973,12 @@ const RAW_RUNTIME_STATE =
["@aws-sdk/client-s3", "npm:3.342.0"],\
["@aws-sdk/client-sqs", "npm:3.342.0"],\
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.1"],\
["@standardnotes/api", "npm:1.26.10"],\
["@standardnotes/api", "npm:1.26.26"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@standardnotes/responses", "npm:1.13.24"],\
["@standardnotes/responses", "npm:1.13.27"],\
["@standardnotes/security", "workspace:packages/security"],\
["@standardnotes/time", "workspace:packages/time"],\
["@types/cors", "npm:2.8.13"],\
@@ -5129,10 +5115,10 @@ const RAW_RUNTIME_STATE =
}]\
]],\
["@standardnotes/sncrypto-common", [\
["npm:1.13.3", {\
"packageLocation": "./.yarn/cache/@standardnotes-sncrypto-common-npm-1.13.3-97ef3850ce-a73af90962.zip/node_modules/@standardnotes/sncrypto-common/",\
["npm:1.13.4", {\
"packageLocation": "./.yarn/cache/@standardnotes-sncrypto-common-npm-1.13.4-3186513fa6-48e0e207f2.zip/node_modules/@standardnotes/sncrypto-common/",\
"packageDependencies": [\
["@standardnotes/sncrypto-common", "npm:1.13.3"],\
["@standardnotes/sncrypto-common", "npm:1.13.4"],\
["reflect-metadata", "npm:0.1.13"]\
],\
"linkType": "HARD"\
@@ -5143,7 +5129,7 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/sncrypto-node/",\
"packageDependencies": [\
["@standardnotes/sncrypto-node", "workspace:packages/sncrypto-node"],\
["@standardnotes/sncrypto-common", "npm:1.13.3"],\
["@standardnotes/sncrypto-common", "npm:1.13.4"],\
["@types/jest", "npm:29.5.2"],\
["@types/node", "npm:20.2.5"],\
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.59.8"],\
@@ -5171,14 +5157,15 @@ const RAW_RUNTIME_STATE =
["@aws-sdk/client-sns", "npm:3.342.0"],\
["@aws-sdk/client-sqs", "npm:3.342.0"],\
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.1"],\
["@standardnotes/api", "npm:1.26.10"],\
["@standardnotes/api", "npm:1.26.26"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@standardnotes/responses", "npm:1.13.24"],\
["@standardnotes/responses", "npm:1.13.27"],\
["@standardnotes/security", "workspace:packages/security"],\
["@standardnotes/settings", "workspace:packages/settings"],\
["@standardnotes/sncrypto-node", "workspace:packages/sncrypto-node"],\
["@standardnotes/time", "workspace:packages/time"],\
["@types/cors", "npm:2.8.13"],\
["@types/dotenv", "npm:8.2.0"],\
@@ -5188,6 +5175,7 @@ const RAW_RUNTIME_STATE =
["@types/newrelic", "npm:9.14.0"],\
["@types/node", "npm:20.2.5"],\
["@types/prettyjson", "npm:0.0.30"],\
["@types/semver", "npm:7.5.0"],\
["@types/ua-parser-js", "npm:0.7.36"],\
["@types/uuid", "npm:8.3.4"],\
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.59.8"],\
@@ -5203,6 +5191,7 @@ const RAW_RUNTIME_STATE =
["inversify-express-utils", "npm:6.4.3"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.5.0"],\
["jsonwebtoken", "npm:9.0.0"],\
["mongodb", "virtual:67ad3a1ca34e24ce4821cc48979e98af0c3e5dd7aabc7ad0b5d22d1d977d6f943f81c9f141a420105ebdc61ef777e508a96c7946081decd98f8c30543d468b33#npm:5.7.0"],\
["mysql2", "npm:3.3.3"],\
["newrelic", "npm:10.1.2"],\
["nodemon", "npm:2.0.22"],\
@@ -5210,9 +5199,10 @@ const RAW_RUNTIME_STATE =
["prettier", "npm:2.8.8"],\
["prettyjson", "npm:1.2.5"],\
["reflect-metadata", "npm:0.1.13"],\
["semver", "npm:7.5.1"],\
["sqlite3", "virtual:31b5a94a105c89c9294c3d524a7f8929fe63ee5a2efadf21951ca4c0cfd2ecf02e8f4ef5a066bbda091f1e3a56e57c6749069a080618c96b22e51131a330fc4a#npm:5.1.6"],\
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.0"],\
["typeorm", "virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:0.3.16"],\
["typeorm", "virtual:67ad3a1ca34e24ce4821cc48979e98af0c3e5dd7aabc7ad0b5d22d1d977d6f943f81c9f141a420105ebdc61ef777e508a96c7946081decd98f8c30543d468b33#npm:0.3.16"],\
["typescript", "patch:typescript@npm%3A5.0.4#optional!builtin<compat/typescript>::version=5.0.4&hash=b5f058"],\
["ua-parser-js", "npm:1.0.35"],\
["uuid", "npm:9.0.0"],\
@@ -5244,10 +5234,10 @@ const RAW_RUNTIME_STATE =
}]\
]],\
["@standardnotes/utils", [\
["npm:1.16.5", {\
"packageLocation": "./.yarn/cache/@standardnotes-utils-npm-1.16.5-47f537f49f-d5caa7181f.zip/node_modules/@standardnotes/utils/",\
["npm:1.17.5", {\
"packageLocation": "./.yarn/cache/@standardnotes-utils-npm-1.17.5-210b60222d-47e8520174.zip/node_modules/@standardnotes/utils/",\
"packageDependencies": [\
["@standardnotes/utils", "npm:1.16.5"],\
["@standardnotes/utils", "npm:1.17.5"],\
["@standardnotes/common", "workspace:packages/common"],\
["dompurify", "npm:2.4.5"],\
["lodash", "npm:4.17.21"],\
@@ -5263,14 +5253,13 @@ const RAW_RUNTIME_STATE =
["@standardnotes/websockets-server", "workspace:packages/websockets"],\
["@aws-sdk/client-sqs", "npm:3.342.0"],\
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.1"],\
["@standardnotes/api", "npm:1.26.10"],\
["@standardnotes/api", "npm:1.26.26"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@standardnotes/responses", "npm:1.13.24"],\
["@standardnotes/responses", "npm:1.13.27"],\
["@standardnotes/security", "workspace:packages/security"],\
["@standardnotes/utils", "npm:1.16.5"],\
["@types/cors", "npm:2.8.13"],\
["@types/express", "npm:4.17.17"],\
["@types/ioredis", "npm:5.0.0"],\
@@ -5881,6 +5870,26 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["@types/webidl-conversions", [\
["npm:7.0.0", {\
"packageLocation": "./.yarn/cache/@types-webidl-conversions-npm-7.0.0-0903313151-86c337dc1e.zip/node_modules/@types/webidl-conversions/",\
"packageDependencies": [\
["@types/webidl-conversions", "npm:7.0.0"]\
],\
"linkType": "HARD"\
}]\
]],\
["@types/whatwg-url", [\
["npm:8.2.2", {\
"packageLocation": "./.yarn/cache/@types-whatwg-url-npm-8.2.2-54c5c24e6c-25f20f5649.zip/node_modules/@types/whatwg-url/",\
"packageDependencies": [\
["@types/whatwg-url", "npm:8.2.2"],\
["@types/node", "npm:20.2.5"],\
["@types/webidl-conversions", "npm:7.0.0"]\
],\
"linkType": "HARD"\
}]\
]],\
["@types/yargs", [\
["npm:17.0.24", {\
"packageLocation": "./.yarn/cache/@types-yargs-npm-17.0.24-b034cf1d8b-f7811cc0b9.zip/node_modules/@types/yargs/",\
@@ -7086,6 +7095,15 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["bson", [\
["npm:5.4.0", {\
"packageLocation": "./.yarn/cache/bson-npm-5.4.0-2f854c8216-2c913a45c0.zip/node_modules/bson/",\
"packageDependencies": [\
["bson", "npm:5.4.0"]\
],\
"linkType": "HARD"\
}]\
]],\
["buffer", [\
["npm:5.7.1", {\
"packageLocation": "./.yarn/cache/buffer-npm-5.7.1-513ef8259e-8e611bed4d.zip/node_modules/buffer/",\
@@ -11944,6 +11962,15 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["memory-pager", [\
["npm:1.5.0", {\
"packageLocation": "./.yarn/cache/memory-pager-npm-1.5.0-46e20e6c81-6b00ff499b.zip/node_modules/memory-pager/",\
"packageDependencies": [\
["memory-pager", "npm:1.5.0"]\
],\
"linkType": "HARD"\
}]\
]],\
["meow", [\
["npm:8.1.2", {\
"packageLocation": "./.yarn/cache/meow-npm-8.1.2-bcfe48d4f3-e36c879078.zip/node_modules/meow/",\
@@ -12302,6 +12329,59 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["mongodb", [\
["npm:5.7.0", {\
"packageLocation": "./.yarn/cache/mongodb-npm-5.7.0-c5e415a2e7-23a291ffe7.zip/node_modules/mongodb/",\
"packageDependencies": [\
["mongodb", "npm:5.7.0"]\
],\
"linkType": "SOFT"\
}],\
["virtual:67ad3a1ca34e24ce4821cc48979e98af0c3e5dd7aabc7ad0b5d22d1d977d6f943f81c9f141a420105ebdc61ef777e508a96c7946081decd98f8c30543d468b33#npm:5.7.0", {\
"packageLocation": "./.yarn/__virtual__/mongodb-virtual-eb0cd47e23/0/cache/mongodb-npm-5.7.0-c5e415a2e7-23a291ffe7.zip/node_modules/mongodb/",\
"packageDependencies": [\
["mongodb", "virtual:67ad3a1ca34e24ce4821cc48979e98af0c3e5dd7aabc7ad0b5d22d1d977d6f943f81c9f141a420105ebdc61ef777e508a96c7946081decd98f8c30543d468b33#npm:5.7.0"],\
["@aws-sdk/credential-providers", null],\
["@mongodb-js/zstd", null],\
["@types/aws-sdk__credential-providers", null],\
["@types/kerberos", null],\
["@types/mongodb-client-encryption", null],\
["@types/mongodb-js__zstd", null],\
["@types/snappy", null],\
["bson", "npm:5.4.0"],\
["kerberos", null],\
["mongodb-client-encryption", null],\
["mongodb-connection-string-url", "npm:2.6.0"],\
["saslprep", "npm:1.0.3"],\
["snappy", null],\
["socks", "npm:2.7.1"]\
],\
"packagePeers": [\
"@aws-sdk/credential-providers",\
"@mongodb-js/zstd",\
"@types/aws-sdk__credential-providers",\
"@types/kerberos",\
"@types/mongodb-client-encryption",\
"@types/mongodb-js__zstd",\
"@types/snappy",\
"kerberos",\
"mongodb-client-encryption",\
"snappy"\
],\
"linkType": "HARD"\
}]\
]],\
["mongodb-connection-string-url", [\
["npm:2.6.0", {\
"packageLocation": "./.yarn/cache/mongodb-connection-string-url-npm-2.6.0-af011ba17f-8a9186dd1b.zip/node_modules/mongodb-connection-string-url/",\
"packageDependencies": [\
["mongodb-connection-string-url", "npm:2.6.0"],\
["@types/whatwg-url", "npm:8.2.2"],\
["whatwg-url", "npm:11.0.0"]\
],\
"linkType": "HARD"\
}]\
]],\
["ms", [\
["npm:2.0.0", {\
"packageLocation": "./.yarn/cache/ms-npm-2.0.0-9e1101a471-de027828fc.zip/node_modules/ms/",\
@@ -14261,6 +14341,16 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["saslprep", [\
["npm:1.0.3", {\
"packageLocation": "./.yarn/cache/saslprep-npm-1.0.3-8db649c346-23ebcda091.zip/node_modules/saslprep/",\
"packageDependencies": [\
["saslprep", "npm:1.0.3"],\
["sparse-bitfield", "npm:3.0.3"]\
],\
"linkType": "HARD"\
}]\
]],\
["schema-utils", [\
["npm:3.1.2", {\
"packageLocation": "./.yarn/cache/schema-utils-npm-3.1.2-d97c6dc247-11d35f997e.zip/node_modules/schema-utils/",\
@@ -14616,6 +14706,16 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["sparse-bitfield", [\
["npm:3.0.3", {\
"packageLocation": "./.yarn/cache/sparse-bitfield-npm-3.0.3-cb80d0c89f-625ecdf6f4.zip/node_modules/sparse-bitfield/",\
"packageDependencies": [\
["sparse-bitfield", "npm:3.0.3"],\
["memory-pager", "npm:1.5.0"]\
],\
"linkType": "HARD"\
}]\
]],\
["spawn-please", [\
["npm:2.0.1", {\
"packageLocation": "./.yarn/cache/spawn-please-npm-2.0.1-265b6b5432-fe19a7ceb5.zip/node_modules/spawn-please/",\
@@ -15258,6 +15358,14 @@ const RAW_RUNTIME_STATE =
["tr46", "npm:0.0.3"]\
],\
"linkType": "HARD"\
}],\
["npm:3.0.0", {\
"packageLocation": "./.yarn/cache/tr46-npm-3.0.0-e1ae1ea7c9-3a481676bf.zip/node_modules/tr46/",\
"packageDependencies": [\
["tr46", "npm:3.0.0"],\
["punycode", "npm:2.3.0"]\
],\
"linkType": "HARD"\
}]\
]],\
["treeverse", [\
@@ -15769,6 +15877,98 @@ const RAW_RUNTIME_STATE =
],\
"linkType": "HARD"\
}],\
["virtual:67ad3a1ca34e24ce4821cc48979e98af0c3e5dd7aabc7ad0b5d22d1d977d6f943f81c9f141a420105ebdc61ef777e508a96c7946081decd98f8c30543d468b33#npm:0.3.16", {\
"packageLocation": "./.yarn/__virtual__/typeorm-virtual-13b6364fde/0/cache/typeorm-npm-0.3.16-5ac12a7afc-19803f935e.zip/node_modules/typeorm/",\
"packageDependencies": [\
["typeorm", "virtual:67ad3a1ca34e24ce4821cc48979e98af0c3e5dd7aabc7ad0b5d22d1d977d6f943f81c9f141a420105ebdc61ef777e508a96c7946081decd98f8c30543d468b33#npm:0.3.16"],\
["@google-cloud/spanner", null],\
["@sap/hana-client", null],\
["@sqltools/formatter", "npm:1.2.5"],\
["@types/better-sqlite3", null],\
["@types/google-cloud__spanner", null],\
["@types/hdb-pool", null],\
["@types/ioredis", null],\
["@types/mongodb", null],\
["@types/mssql", null],\
["@types/mysql2", null],\
["@types/oracledb", null],\
["@types/pg", null],\
["@types/pg-native", null],\
["@types/pg-query-stream", null],\
["@types/redis", null],\
["@types/sap__hana-client", null],\
["@types/sql.js", null],\
["@types/sqlite3", null],\
["@types/ts-node", null],\
["@types/typeorm-aurora-data-api-driver", null],\
["app-root-path", "npm:3.1.0"],\
["better-sqlite3", null],\
["buffer", "npm:6.0.3"],\
["chalk", "npm:4.1.2"],\
["cli-highlight", "npm:2.1.11"],\
["date-fns", "npm:2.30.0"],\
["debug", "virtual:ac3d8e680759ce54399273724d44e041d6c9b73454d191d411a8c44bb27e22f02aaf6ed9d3ad0ac1c298eac4833cff369c9c7b84c573016112c4f84be2cd8543#npm:4.3.4"],\
["dotenv", "npm:16.1.3"],\
["glob", "npm:8.1.0"],\
["hdb-pool", null],\
["ioredis", null],\
["mkdirp", "npm:2.1.6"],\
["mongodb", "virtual:67ad3a1ca34e24ce4821cc48979e98af0c3e5dd7aabc7ad0b5d22d1d977d6f943f81c9f141a420105ebdc61ef777e508a96c7946081decd98f8c30543d468b33#npm:5.7.0"],\
["mssql", null],\
["mysql2", "npm:3.3.3"],\
["oracledb", null],\
["pg", null],\
["pg-native", null],\
["pg-query-stream", null],\
["redis", null],\
["reflect-metadata", "npm:0.1.13"],\
["sha.js", "npm:2.4.11"],\
["sql.js", null],\
["sqlite3", "virtual:31b5a94a105c89c9294c3d524a7f8929fe63ee5a2efadf21951ca4c0cfd2ecf02e8f4ef5a066bbda091f1e3a56e57c6749069a080618c96b22e51131a330fc4a#npm:5.1.6"],\
["ts-node", null],\
["tslib", "npm:2.5.2"],\
["typeorm-aurora-data-api-driver", null],\
["uuid", "npm:9.0.0"],\
["yargs", "npm:17.7.2"]\
],\
"packagePeers": [\
"@google-cloud/spanner",\
"@sap/hana-client",\
"@types/better-sqlite3",\
"@types/google-cloud__spanner",\
"@types/hdb-pool",\
"@types/ioredis",\
"@types/mongodb",\
"@types/mssql",\
"@types/mysql2",\
"@types/oracledb",\
"@types/pg-native",\
"@types/pg-query-stream",\
"@types/pg",\
"@types/redis",\
"@types/sap__hana-client",\
"@types/sql.js",\
"@types/sqlite3",\
"@types/ts-node",\
"@types/typeorm-aurora-data-api-driver",\
"better-sqlite3",\
"hdb-pool",\
"ioredis",\
"mongodb",\
"mssql",\
"mysql2",\
"oracledb",\
"pg-native",\
"pg-query-stream",\
"pg",\
"redis",\
"sql.js",\
"sqlite3",\
"ts-node",\
"typeorm-aurora-data-api-driver"\
],\
"linkType": "HARD"\
}],\
["virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:0.3.16", {\
"packageLocation": "./.yarn/__virtual__/typeorm-virtual-fc9b7b780b/0/cache/typeorm-npm-0.3.16-5ac12a7afc-19803f935e.zip/node_modules/typeorm/",\
"packageDependencies": [\
@@ -16203,6 +16403,13 @@ const RAW_RUNTIME_STATE =
["webidl-conversions", "npm:3.0.1"]\
],\
"linkType": "HARD"\
}],\
["npm:7.0.0", {\
"packageLocation": "./.yarn/cache/webidl-conversions-npm-7.0.0-e8c8e30c68-bdbe11c68c.zip/node_modules/webidl-conversions/",\
"packageDependencies": [\
["webidl-conversions", "npm:7.0.0"]\
],\
"linkType": "HARD"\
}]\
]],\
["webpack", [\
@@ -16261,6 +16468,15 @@ const RAW_RUNTIME_STATE =
}]\
]],\
["whatwg-url", [\
["npm:11.0.0", {\
"packageLocation": "./.yarn/cache/whatwg-url-npm-11.0.0-073529d93a-ee3a532bfb.zip/node_modules/whatwg-url/",\
"packageDependencies": [\
["whatwg-url", "npm:11.0.0"],\
["tr46", "npm:3.0.0"],\
["webidl-conversions", "npm:7.0.0"]\
],\
"linkType": "HARD"\
}],\
["npm:5.0.0", {\
"packageLocation": "./.yarn/cache/whatwg-url-npm-5.0.0-374fb45e60-bd0cc6b75b.zip/node_modules/whatwg-url/",\
"packageDependencies": [\

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -23,6 +23,8 @@ services:
environment:
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
@@ -61,6 +63,21 @@ services:
networks:
- standardnotes_self_hosted
secondary_db:
image: mongo:5.0
container_name: secondary_db-ci
expose:
- 27017
restart: unless-stopped
volumes:
- ./data/mongo:/data/db
environment:
MONGO_INITDB_ROOT_USERNAME: standardnotes
MONGO_INITDB_ROOT_PASSWORD: standardnotes
MONGO_INITDB_DATABASE: standardnotes
networks:
- standardnotes_self_hosted
cache:
image: redis:6.0-alpine
container_name: cache-ci

View File

@@ -3,6 +3,7 @@ services:
image: standardnotes/server
env_file: .env
container_name: server_self_hosted
restart: unless-stopped
ports:
- 3000:3000
- 3125:3104

View File

@@ -63,6 +63,12 @@ fi
if [ -z "$CACHE_TYPE" ]; then
export CACHE_TYPE="redis"
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

@@ -12,12 +12,15 @@
},
"scripts": {
"lint": "yarn workspaces foreach -p -j 10 --verbose run lint",
"lint:fix": "yarn workspaces foreach -p -j 10 --verbose run lint:fix",
"clean": "yarn workspaces foreach -p --verbose run clean",
"setup:env": "cp .env.sample .env && yarn workspaces foreach -p --verbose run setup:env",
"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",
"upgrade:snjs": "yarn workspaces foreach --verbose run upgrade:snjs"
"upgrade:snjs": "yarn workspaces foreach --verbose run upgrade:snjs",
"e2e": "yarn build packages/home-server && PORT=3123 yarn workspace @standardnotes/home-server start",
"start": "yarn build packages/home-server && yarn workspace @standardnotes/home-server start"
},
"devDependencies": {
"@commitlint/cli": "^17.0.2",

View File

@@ -3,6 +3,108 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.25.16](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.15...@standardnotes/analytics@2.25.16) (2023-08-23)
**Note:** Version bump only for package @standardnotes/analytics
## [2.25.15](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.14...@standardnotes/analytics@2.25.15) (2023-08-22)
**Note:** Version bump only for package @standardnotes/analytics
## [2.25.14](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.13...@standardnotes/analytics@2.25.14) (2023-08-18)
**Note:** Version bump only for package @standardnotes/analytics
## [2.25.13](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.12...@standardnotes/analytics@2.25.13) (2023-08-11)
**Note:** Version bump only for package @standardnotes/analytics
## [2.25.12](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.11...@standardnotes/analytics@2.25.12) (2023-08-09)
**Note:** Version bump only for package @standardnotes/analytics
## [2.25.11](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.10...@standardnotes/analytics@2.25.11) (2023-08-09)
**Note:** Version bump only for package @standardnotes/analytics
## [2.25.10](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.9...@standardnotes/analytics@2.25.10) (2023-08-09)
**Note:** Version bump only for package @standardnotes/analytics
## [2.25.9](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.8...@standardnotes/analytics@2.25.9) (2023-08-08)
**Note:** Version bump only for package @standardnotes/analytics
## [2.25.8](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.7...@standardnotes/analytics@2.25.8) (2023-08-03)
**Note:** Version bump only for package @standardnotes/analytics
## [2.25.7](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.6...@standardnotes/analytics@2.25.7) (2023-08-02)
**Note:** Version bump only for package @standardnotes/analytics
## [2.25.6](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.5...@standardnotes/analytics@2.25.6) (2023-07-27)
**Note:** Version bump only for package @standardnotes/analytics
## [2.25.5](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.4...@standardnotes/analytics@2.25.5) (2023-07-26)
**Note:** Version bump only for package @standardnotes/analytics
## [2.25.4](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.3...@standardnotes/analytics@2.25.4) (2023-07-26)
**Note:** Version bump only for package @standardnotes/analytics
## [2.25.3](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.2...@standardnotes/analytics@2.25.3) (2023-07-21)
**Note:** Version bump only for package @standardnotes/analytics
## [2.25.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.1...@standardnotes/analytics@2.25.2) (2023-07-21)
**Note:** Version bump only for package @standardnotes/analytics
## [2.25.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.0...@standardnotes/analytics@2.25.1) (2023-07-19)
**Note:** Version bump only for package @standardnotes/analytics
# [2.25.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.24.9...@standardnotes/analytics@2.25.0) (2023-07-17)
### Features
* **syncing-server:** refactor syncing to decouple getting and saving items ([#659](https://github.com/standardnotes/server/issues/659)) ([cb74b23](https://github.com/standardnotes/server/commit/cb74b23e45b207136e299ce8a3db2c04dc87e21e))
## [2.24.9](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.24.8...@standardnotes/analytics@2.24.9) (2023-07-12)
**Note:** Version bump only for package @standardnotes/analytics
## [2.24.8](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.24.7...@standardnotes/analytics@2.24.8) (2023-07-07)
**Note:** Version bump only for package @standardnotes/analytics
## [2.24.7](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.24.6...@standardnotes/analytics@2.24.7) (2023-07-06)
**Note:** Version bump only for package @standardnotes/analytics
## [2.24.6](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.24.5...@standardnotes/analytics@2.24.6) (2023-07-05)
**Note:** Version bump only for package @standardnotes/analytics
## [2.24.5](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.24.4...@standardnotes/analytics@2.24.5) (2023-06-30)
**Note:** Version bump only for package @standardnotes/analytics
## [2.24.4](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.24.3...@standardnotes/analytics@2.24.4) (2023-06-30)
**Note:** Version bump only for package @standardnotes/analytics
## [2.24.3](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.24.2...@standardnotes/analytics@2.24.3) (2023-06-30)
**Note:** Version bump only for package @standardnotes/analytics
## [2.24.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.24.1...@standardnotes/analytics@2.24.2) (2023-06-28)
**Note:** Version bump only for package @standardnotes/analytics
## [2.24.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.24.0...@standardnotes/analytics@2.24.1) (2023-06-02)
### Bug Fixes

View File

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

View File

@@ -3,10 +3,6 @@ import { Result, Entity, UniqueEntityId } from '@standardnotes/domain-core'
import { StatisticMeasureProps } from './StatisticMeasureProps'
export class StatisticMeasure extends Entity<StatisticMeasureProps> {
get id(): UniqueEntityId {
return this._id
}
get name(): string {
return this.props.name.value
}

View File

@@ -3,10 +3,6 @@ import { Entity, Result, UniqueEntityId } from '@standardnotes/domain-core'
import { SubscriptionProps } from './SubscriptionProps'
export class Subscription extends Entity<SubscriptionProps> {
get id(): UniqueEntityId {
return this._id
}
private constructor(props: SubscriptionProps, id?: UniqueEntityId) {
super(props, id)
}

View File

@@ -3,10 +3,6 @@ import { Entity, Result, UniqueEntityId } from '@standardnotes/domain-core'
import { UserProps } from './UserProps'
export class User extends Entity<UserProps> {
get id(): UniqueEntityId {
return this._id
}
private constructor(props: UserProps, id?: UniqueEntityId) {
super(props, id)
}

View File

@@ -1,3 +1,4 @@
MODE=microservice # microservice | home-server
LOG_LEVEL=debug
NODE_ENV=development
VERSION=development

View File

@@ -3,6 +3,164 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.71.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.71.0...@standardnotes/api-gateway@1.71.1) (2023-08-23)
**Note:** Version bump only for package @standardnotes/api-gateway
# [1.71.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.70.5...@standardnotes/api-gateway@1.71.0) (2023-08-22)
### Features
* consider shared vault owner quota when uploading files to shared vault ([#704](https://github.com/standardnotes/api-gateway/issues/704)) ([34085ac](https://github.com/standardnotes/api-gateway/commit/34085ac6fb7e61d471bd3b4ae8e72112df25c3ee))
## [1.70.5](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.70.4...@standardnotes/api-gateway@1.70.5) (2023-08-18)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.70.4](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.70.3...@standardnotes/api-gateway@1.70.4) (2023-08-09)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.70.3](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.70.2...@standardnotes/api-gateway@1.70.3) (2023-08-09)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.70.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.70.1...@standardnotes/api-gateway@1.70.2) (2023-08-09)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.70.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.70.0...@standardnotes/api-gateway@1.70.1) (2023-08-08)
**Note:** Version bump only for package @standardnotes/api-gateway
# [1.70.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.69.3...@standardnotes/api-gateway@1.70.0) (2023-08-07)
### Features
* **syncing-server:** limit shared vaults creation based on role ([#687](https://github.com/standardnotes/api-gateway/issues/687)) ([19b8921](https://github.com/standardnotes/api-gateway/commit/19b8921f286ff8f88c427e8ddd4512a8d61edb4f))
## [1.69.3](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.69.2...@standardnotes/api-gateway@1.69.3) (2023-08-03)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.69.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.69.1...@standardnotes/api-gateway@1.69.2) (2023-08-02)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.69.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.69.0...@standardnotes/api-gateway@1.69.1) (2023-07-31)
### Bug Fixes
* **api-gateway:** remove duplicating req/res objects on return raw response from payments ([79d71ca](https://github.com/standardnotes/api-gateway/commit/79d71ca161cc18135fcd1a83b021662e189b3ddb))
# [1.69.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.68.1...@standardnotes/api-gateway@1.69.0) (2023-07-31)
### Features
* refactor deleting account ([#676](https://github.com/standardnotes/api-gateway/issues/676)) ([0d5dcdd](https://github.com/standardnotes/api-gateway/commit/0d5dcdd8ec2336e41e7604c4157f79a89163ed29))
## [1.68.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.68.0...@standardnotes/api-gateway@1.68.1) (2023-07-27)
**Note:** Version bump only for package @standardnotes/api-gateway
# [1.68.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.67.4...@standardnotes/api-gateway@1.68.0) (2023-07-27)
### Features
* **syncing-server:** add deleting outbound messages ([e8ba49e](https://github.com/standardnotes/api-gateway/commit/e8ba49ecca38ab10c0ea0e1f4cf4db9fb17366db))
## [1.67.4](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.67.3...@standardnotes/api-gateway@1.67.4) (2023-07-26)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.67.3](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.67.2...@standardnotes/api-gateway@1.67.3) (2023-07-26)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.67.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.67.1...@standardnotes/api-gateway@1.67.2) (2023-07-21)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.67.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.67.0...@standardnotes/api-gateway@1.67.1) (2023-07-21)
**Note:** Version bump only for package @standardnotes/api-gateway
# [1.67.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.66.1...@standardnotes/api-gateway@1.67.0) (2023-07-20)
### Features
* **syncing-server:** add shared vaults, invites, messages and notifications to sync response ([#665](https://github.com/standardnotes/api-gateway/issues/665)) ([efa4d7f](https://github.com/standardnotes/api-gateway/commit/efa4d7fc6007ef668e3de3b04853ac11b2d13c30))
## [1.66.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.66.0...@standardnotes/api-gateway@1.66.1) (2023-07-19)
### Bug Fixes
* add missing imports and exports for controllers ([#664](https://github.com/standardnotes/api-gateway/issues/664)) ([aee6e60](https://github.com/standardnotes/api-gateway/commit/aee6e6058359e2b5231cc13387656f837699300f))
# [1.66.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.65.7...@standardnotes/api-gateway@1.66.0) (2023-07-19)
### Features
* **syncing-server:** add persistence of shared vaults with users and invites + controllers ([#662](https://github.com/standardnotes/api-gateway/issues/662)) ([3f21a35](https://github.com/standardnotes/api-gateway/commit/3f21a358d24d70daf541aa62dc86cd9e29500e62))
## [1.65.7](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.65.6...@standardnotes/api-gateway@1.65.7) (2023-07-17)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.65.6](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.65.5...@standardnotes/api-gateway@1.65.6) (2023-07-12)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.65.5](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.65.4...@standardnotes/api-gateway@1.65.5) (2023-07-07)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.65.4](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.65.3...@standardnotes/api-gateway@1.65.4) (2023-07-06)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.65.3](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.65.2...@standardnotes/api-gateway@1.65.3) (2023-07-05)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.65.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.65.1...@standardnotes/api-gateway@1.65.2) (2023-06-30)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.65.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.65.0...@standardnotes/api-gateway@1.65.1) (2023-06-30)
**Note:** Version bump only for package @standardnotes/api-gateway
# [1.65.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.64.3...@standardnotes/api-gateway@1.65.0) (2023-06-30)
### Features
* shared vaults functionality in api-gateway,auth,files,common,security,domain-events. ([#629](https://github.com/standardnotes/api-gateway/issues/629)) ([fa7fbe2](https://github.com/standardnotes/api-gateway/commit/fa7fbe26e7b0707fc21d71e04af76870f5248baf))
## [1.64.3](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.64.2...@standardnotes/api-gateway@1.64.3) (2023-06-28)
### Bug Fixes
* add debug logs for invalid-auth responses ([d5a8409](https://github.com/standardnotes/api-gateway/commit/d5a8409bb5d35b9caf410a36ea0d5cb747129e8d))
## [1.64.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.64.1...@standardnotes/api-gateway@1.64.2) (2023-06-22)
### Bug Fixes
* **home-server:** add debug logs about container initalizations ([0df4715](https://github.com/standardnotes/api-gateway/commit/0df471585fd5b4626ec2972f3b9a3e33b2830e65))
## [1.64.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.64.0...@standardnotes/api-gateway@1.64.1) (2023-06-09)
### Bug Fixes
* **api-gateway:** direct call service proxy to return 400 responses instead of throwing errors ([e6a4cc3](https://github.com/standardnotes/api-gateway/commit/e6a4cc3098bdf84fc9d48ed0d9098ebb52afb0e7))
# [1.64.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.63.2...@standardnotes/api-gateway@1.64.0) (2023-06-05)
### Features
* **home-server:** allow running the home server with a mysql and redis configuration ([#622](https://github.com/standardnotes/api-gateway/issues/622)) ([d6e531d](https://github.com/standardnotes/api-gateway/commit/d6e531d4b6c1c80a894f6d7ec93632595268dd64))
## [1.63.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.63.1...@standardnotes/api-gateway@1.63.2) (2023-06-02)
### Bug Fixes

View File

@@ -16,6 +16,10 @@ import '../src/Controller/v1/OfflineController'
import '../src/Controller/v1/FilesController'
import '../src/Controller/v1/SubscriptionInvitesController'
import '../src/Controller/v1/AuthenticatorsController'
import '../src/Controller/v1/MessagesController'
import '../src/Controller/v1/SharedVaultsController'
import '../src/Controller/v1/SharedVaultInvitesController'
import '../src/Controller/v1/SharedVaultUsersController'
import '../src/Controller/v2/PaymentsControllerV2'
import '../src/Controller/v2/ActionsControllerV2'
@@ -42,31 +46,32 @@ void container.load().then((container) => {
server.setConfig((app) => {
app.use((_request: Request, response: Response, next: NextFunction) => {
response.setHeader('X-API-Gateway-Version', container.get(TYPES.VERSION))
response.setHeader('X-API-Gateway-Version', container.get(TYPES.ApiGateway_VERSION))
next()
})
/* eslint-disable */
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["https: 'self'"],
baseUri: ["'self'"],
childSrc: ["*", "blob:"],
connectSrc: ["*"],
fontSrc: ["*", "'self'"],
formAction: ["'self'"],
frameAncestors: ["*", "*.standardnotes.org", "*.standardnotes.com"],
frameSrc: ["*", "blob:"],
imgSrc: ["'self'", "*", "data:"],
manifestSrc: ["'self'"],
mediaSrc: ["'self'"],
objectSrc: ["'self'"],
scriptSrc: ["'self'"],
styleSrc: ["'self'"]
}
}
}))
/* eslint-enable */
app.use(
helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["https: 'self'"],
baseUri: ["'self'"],
childSrc: ['*', 'blob:'],
connectSrc: ['*'],
fontSrc: ['*', "'self'"],
formAction: ["'self'"],
frameAncestors: ['*', '*.standardnotes.org', '*.standardnotes.com'],
frameSrc: ['*', 'blob:'],
imgSrc: ["'self'", '*', 'data:'],
manifestSrc: ["'self'"],
mediaSrc: ["'self'"],
objectSrc: ["'self'"],
scriptSrc: ["'self'"],
styleSrc: ["'self'"],
},
},
}),
)
app.use(json({ limit: '50mb' }))
app.use(
text({
@@ -82,7 +87,7 @@ void container.load().then((container) => {
)
})
const logger: winston.Logger = container.get(TYPES.Logger)
const logger: winston.Logger = container.get(TYPES.ApiGateway_Logger)
server.setErrorConfig((app) => {
app.use((error: Record<string, unknown>, _request: Request, response: Response, _next: NextFunction) => {

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/api-gateway",
"version": "1.63.2",
"version": "1.71.1",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
@@ -21,6 +21,7 @@
"clean": "rm -fr dist",
"build": "tsc --build",
"lint": "eslint . --ext .ts",
"lint:fix": "eslint . --fix --ext .ts",
"setup:env": "cp .env.sample .env",
"start": "yarn node dist/bin/server.js",
"upgrade:snjs": "yarn ncu -u '@standardnotes/*'"

View File

@@ -34,7 +34,8 @@ export class ContainerConfigLoader {
const container = new Container()
const isConfiguredForHomeServer = env.get('CACHE_TYPE') === 'memory'
const isConfiguredForHomeServer = env.get('MODE', true) === 'home-server'
const isConfiguredForInMemoryCache = env.get('CACHE_TYPE', true) === 'memory'
const winstonFormatters = [winston.format.splat(), winston.format.json()]
if (env.get('NEW_RELIC_ENABLED', true) === 'true') {
@@ -45,19 +46,20 @@ export class ContainerConfigLoader {
winstonFormatters.push(newrelicWinstonFormatter())
}
let logger: winston.Logger
if (configuration?.logger) {
container.bind<winston.Logger>(TYPES.Logger).toConstantValue(configuration.logger as winston.Logger)
logger = configuration.logger as winston.Logger
} else {
const logger = winston.createLogger({
logger = winston.createLogger({
level: env.get('LOG_LEVEL', true) || 'info',
format: winston.format.combine(...winstonFormatters),
transports: [new winston.transports.Console({ level: env.get('LOG_LEVEL', true) || 'info' })],
defaultMeta: { service: 'api-gateway' },
})
container.bind<winston.Logger>(TYPES.Logger).toConstantValue(logger)
}
container.bind<winston.Logger>(TYPES.ApiGateway_Logger).toConstantValue(logger)
if (!isConfiguredForHomeServer) {
if (!isConfiguredForInMemoryCache) {
const redisUrl = env.get('REDIS_URL')
const isRedisInClusterMode = redisUrl.indexOf(',') > 0
let redis
@@ -66,36 +68,39 @@ export class ContainerConfigLoader {
} else {
redis = new Redis(redisUrl)
}
container.bind(TYPES.Redis).toConstantValue(redis)
container.bind(TYPES.ApiGateway_Redis).toConstantValue(redis)
}
container.bind<AxiosInstance>(TYPES.HTTPClient).toConstantValue(axios.create())
container.bind<AxiosInstance>(TYPES.ApiGateway_HTTPClient).toConstantValue(axios.create())
// env vars
container.bind(TYPES.SYNCING_SERVER_JS_URL).toConstantValue(env.get('SYNCING_SERVER_JS_URL', true))
container.bind(TYPES.AUTH_SERVER_URL).toConstantValue(env.get('AUTH_SERVER_URL', true))
container.bind(TYPES.REVISIONS_SERVER_URL).toConstantValue(env.get('REVISIONS_SERVER_URL', true))
container.bind(TYPES.EMAIL_SERVER_URL).toConstantValue(env.get('EMAIL_SERVER_URL', true))
container.bind(TYPES.PAYMENTS_SERVER_URL).toConstantValue(env.get('PAYMENTS_SERVER_URL', true))
container.bind(TYPES.FILES_SERVER_URL).toConstantValue(env.get('FILES_SERVER_URL', true))
container.bind(TYPES.WEB_SOCKET_SERVER_URL).toConstantValue(env.get('WEB_SOCKET_SERVER_URL', true))
container.bind(TYPES.AUTH_JWT_SECRET).toConstantValue(env.get('AUTH_JWT_SECRET'))
container.bind(TYPES.ApiGateway_SYNCING_SERVER_JS_URL).toConstantValue(env.get('SYNCING_SERVER_JS_URL', true))
container.bind(TYPES.ApiGateway_AUTH_SERVER_URL).toConstantValue(env.get('AUTH_SERVER_URL', true))
container.bind(TYPES.ApiGateway_REVISIONS_SERVER_URL).toConstantValue(env.get('REVISIONS_SERVER_URL', true))
container.bind(TYPES.ApiGateway_EMAIL_SERVER_URL).toConstantValue(env.get('EMAIL_SERVER_URL', true))
container.bind(TYPES.ApiGateway_PAYMENTS_SERVER_URL).toConstantValue(env.get('PAYMENTS_SERVER_URL', true))
container.bind(TYPES.ApiGateway_FILES_SERVER_URL).toConstantValue(env.get('FILES_SERVER_URL', true))
container.bind(TYPES.ApiGateway_WEB_SOCKET_SERVER_URL).toConstantValue(env.get('WEB_SOCKET_SERVER_URL', true))
container.bind(TYPES.ApiGateway_AUTH_JWT_SECRET).toConstantValue(env.get('AUTH_JWT_SECRET'))
container
.bind(TYPES.HTTP_CALL_TIMEOUT)
.bind(TYPES.ApiGateway_HTTP_CALL_TIMEOUT)
.toConstantValue(env.get('HTTP_CALL_TIMEOUT', true) ? +env.get('HTTP_CALL_TIMEOUT', true) : 60_000)
container.bind(TYPES.VERSION).toConstantValue(env.get('VERSION', true) ?? 'development')
container.bind(TYPES.CROSS_SERVICE_TOKEN_CACHE_TTL).toConstantValue(+env.get('CROSS_SERVICE_TOKEN_CACHE_TTL', true))
container.bind(TYPES.ApiGateway_VERSION).toConstantValue(env.get('VERSION', true) ?? 'development')
container
.bind(TYPES.ApiGateway_CROSS_SERVICE_TOKEN_CACHE_TTL)
.toConstantValue(+env.get('CROSS_SERVICE_TOKEN_CACHE_TTL', true))
container.bind(TYPES.ApiGateway_IS_CONFIGURED_FOR_HOME_SERVER).toConstantValue(isConfiguredForHomeServer)
// Middleware
container
.bind<RequiredCrossServiceTokenMiddleware>(TYPES.RequiredCrossServiceTokenMiddleware)
.bind<RequiredCrossServiceTokenMiddleware>(TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
.to(RequiredCrossServiceTokenMiddleware)
container
.bind<OptionalCrossServiceTokenMiddleware>(TYPES.OptionalCrossServiceTokenMiddleware)
.bind<OptionalCrossServiceTokenMiddleware>(TYPES.ApiGateway_OptionalCrossServiceTokenMiddleware)
.to(OptionalCrossServiceTokenMiddleware)
container.bind<WebSocketAuthMiddleware>(TYPES.WebSocketAuthMiddleware).to(WebSocketAuthMiddleware)
container.bind<WebSocketAuthMiddleware>(TYPES.ApiGateway_WebSocketAuthMiddleware).to(WebSocketAuthMiddleware)
container
.bind<SubscriptionTokenAuthMiddleware>(TYPES.SubscriptionTokenAuthMiddleware)
.bind<SubscriptionTokenAuthMiddleware>(TYPES.ApiGateway_SubscriptionTokenAuthMiddleware)
.to(SubscriptionTokenAuthMiddleware)
// Services
@@ -104,26 +109,30 @@ export class ContainerConfigLoader {
throw new Error('Service container is required when configured for home server')
}
container
.bind<ServiceProxyInterface>(TYPES.ServiceProxy)
.bind<ServiceProxyInterface>(TYPES.ApiGateway_ServiceProxy)
.toConstantValue(
new DirectCallServiceProxy(configuration.serviceContainer, container.get(TYPES.FILES_SERVER_URL)),
new DirectCallServiceProxy(configuration.serviceContainer, container.get(TYPES.ApiGateway_FILES_SERVER_URL)),
)
} else {
container.bind<ServiceProxyInterface>(TYPES.ServiceProxy).to(HttpServiceProxy)
container.bind<ServiceProxyInterface>(TYPES.ApiGateway_ServiceProxy).to(HttpServiceProxy)
}
container.bind<TimerInterface>(TYPES.Timer).toConstantValue(new Timer())
container.bind<TimerInterface>(TYPES.ApiGateway_Timer).toConstantValue(new Timer())
if (isConfiguredForHomeServer) {
container
.bind<CrossServiceTokenCacheInterface>(TYPES.CrossServiceTokenCache)
.toConstantValue(new InMemoryCrossServiceTokenCache(container.get(TYPES.Timer)))
.bind<CrossServiceTokenCacheInterface>(TYPES.ApiGateway_CrossServiceTokenCache)
.toConstantValue(new InMemoryCrossServiceTokenCache(container.get(TYPES.ApiGateway_Timer)))
} else {
container.bind<CrossServiceTokenCacheInterface>(TYPES.CrossServiceTokenCache).to(RedisCrossServiceTokenCache)
container
.bind<CrossServiceTokenCacheInterface>(TYPES.ApiGateway_CrossServiceTokenCache)
.to(RedisCrossServiceTokenCache)
}
container
.bind<EndpointResolverInterface>(TYPES.EndpointResolver)
.bind<EndpointResolverInterface>(TYPES.ApiGateway_EndpointResolver)
.toConstantValue(new EndpointResolver(isConfiguredForHomeServer))
logger.debug('Configuration complete')
return container
}
}

View File

@@ -1,29 +1,28 @@
export const TYPES = {
Logger: Symbol.for('Logger'),
Redis: Symbol.for('Redis'),
HTTPClient: Symbol.for('HTTPClient'),
ApiGateway_Logger: Symbol.for('ApiGateway_Logger'),
ApiGateway_Redis: Symbol.for('ApiGateway_Redis'),
ApiGateway_HTTPClient: Symbol.for('ApiGateway_HTTPClient'),
// env vars
SYNCING_SERVER_JS_URL: Symbol.for('SYNCING_SERVER_JS_URL'),
AUTH_SERVER_URL: Symbol.for('AUTH_SERVER_URL'),
PAYMENTS_SERVER_URL: Symbol.for('PAYMENTS_SERVER_URL'),
FILES_SERVER_URL: Symbol.for('FILES_SERVER_URL'),
REVISIONS_SERVER_URL: Symbol.for('REVISIONS_SERVER_URL'),
EMAIL_SERVER_URL: Symbol.for('EMAIL_SERVER_URL'),
WEB_SOCKET_SERVER_URL: Symbol.for('WEB_SOCKET_SERVER_URL'),
AUTH_JWT_SECRET: Symbol.for('AUTH_JWT_SECRET'),
HTTP_CALL_TIMEOUT: Symbol.for('HTTP_CALL_TIMEOUT'),
VERSION: Symbol.for('VERSION'),
CROSS_SERVICE_TOKEN_CACHE_TTL: Symbol.for('CROSS_SERVICE_TOKEN_CACHE_TTL'),
ApiGateway_SYNCING_SERVER_JS_URL: Symbol.for('ApiGateway_SYNCING_SERVER_JS_URL'),
ApiGateway_AUTH_SERVER_URL: Symbol.for('ApiGateway_AUTH_SERVER_URL'),
ApiGateway_PAYMENTS_SERVER_URL: Symbol.for('ApiGateway_PAYMENTS_SERVER_URL'),
ApiGateway_FILES_SERVER_URL: Symbol.for('ApiGateway_FILES_SERVER_URL'),
ApiGateway_REVISIONS_SERVER_URL: Symbol.for('ApiGateway_REVISIONS_SERVER_URL'),
ApiGateway_EMAIL_SERVER_URL: Symbol.for('ApiGateway_EMAIL_SERVER_URL'),
ApiGateway_WEB_SOCKET_SERVER_URL: Symbol.for('ApiGateway_WEB_SOCKET_SERVER_URL'),
ApiGateway_AUTH_JWT_SECRET: Symbol.for('ApiGateway_AUTH_JWT_SECRET'),
ApiGateway_HTTP_CALL_TIMEOUT: Symbol.for('ApiGateway_HTTP_CALL_TIMEOUT'),
ApiGateway_VERSION: Symbol.for('ApiGateway_VERSION'),
ApiGateway_CROSS_SERVICE_TOKEN_CACHE_TTL: Symbol.for('ApiGateway_CROSS_SERVICE_TOKEN_CACHE_TTL'),
ApiGateway_IS_CONFIGURED_FOR_HOME_SERVER: Symbol.for('ApiGateway_IS_CONFIGURED_FOR_HOME_SERVER'),
// Middleware
RequiredCrossServiceTokenMiddleware: Symbol.for('RequiredCrossServiceTokenMiddleware'),
OptionalCrossServiceTokenMiddleware: Symbol.for('OptionalCrossServiceTokenMiddleware'),
WebSocketAuthMiddleware: Symbol.for('WebSocketAuthMiddleware'),
SubscriptionTokenAuthMiddleware: Symbol.for('SubscriptionTokenAuthMiddleware'),
ApiGateway_RequiredCrossServiceTokenMiddleware: Symbol.for('ApiGateway_RequiredCrossServiceTokenMiddleware'),
ApiGateway_OptionalCrossServiceTokenMiddleware: Symbol.for('ApiGateway_OptionalCrossServiceTokenMiddleware'),
ApiGateway_WebSocketAuthMiddleware: Symbol.for('ApiGateway_WebSocketAuthMiddleware'),
ApiGateway_SubscriptionTokenAuthMiddleware: Symbol.for('ApiGateway_SubscriptionTokenAuthMiddleware'),
// Services
ServiceProxy: Symbol.for('ServiceProxy'),
CrossServiceTokenCache: Symbol.for('CrossServiceTokenCache'),
Timer: Symbol.for('Timer'),
EndpointResolver: Symbol.for('EndpointResolver'),
ApiGateway_ServiceProxy: Symbol.for('ApiGateway_ServiceProxy'),
ApiGateway_CrossServiceTokenCache: Symbol.for('ApiGateway_CrossServiceTokenCache'),
ApiGateway_Timer: Symbol.for('ApiGateway_Timer'),
ApiGateway_EndpointResolver: Symbol.for('ApiGateway_EndpointResolver'),
}
// export default TYPES

View File

@@ -1,5 +1,4 @@
import { CrossServiceTokenData } from '@standardnotes/security'
import { RoleName } from '@standardnotes/domain-core'
import { TimerInterface } from '@standardnotes/time'
import { NextFunction, Request, Response } from 'express'
import { BaseMiddleware } from 'inversify-express-utils'
@@ -17,7 +16,7 @@ export abstract class AuthMiddleware extends BaseMiddleware {
private crossServiceTokenCacheTTL: number,
private crossServiceTokenCache: CrossServiceTokenCacheInterface,
private timer: TimerInterface,
private logger: Logger,
protected logger: Logger,
) {
super()
}
@@ -28,16 +27,23 @@ export abstract class AuthMiddleware extends BaseMiddleware {
}
const authHeaderValue = request.headers.authorization as string
const sharedVaultOwnerContextHeaderValue = request.headers['x-shared-vault-owner-context'] as string | undefined
const cacheKey = `${authHeaderValue}${
sharedVaultOwnerContextHeaderValue ? `:${sharedVaultOwnerContextHeaderValue}` : ''
}`
try {
let crossServiceTokenFetchedFromCache = true
let crossServiceToken = null
if (this.crossServiceTokenCacheTTL) {
crossServiceToken = await this.crossServiceTokenCache.get(authHeaderValue)
crossServiceToken = await this.crossServiceTokenCache.get(cacheKey)
}
if (crossServiceToken === null) {
const authResponse = await this.serviceProxy.validateSession(authHeaderValue)
const authResponse = await this.serviceProxy.validateSession({
authorization: authHeaderValue,
sharedVaultOwnerContext: sharedVaultOwnerContextHeaderValue,
})
if (!this.handleSessionValidationResponse(authResponse, response, next)) {
return
@@ -51,13 +57,9 @@ export abstract class AuthMiddleware extends BaseMiddleware {
const decodedToken = <CrossServiceTokenData>verify(crossServiceToken, this.jwtSecret, { algorithms: ['HS256'] })
response.locals.freeUser =
decodedToken.roles.length === 1 &&
decodedToken.roles.find((role) => role.name === RoleName.NAMES.CoreUser) !== undefined
if (this.crossServiceTokenCacheTTL && !crossServiceTokenFetchedFromCache) {
await this.crossServiceTokenCache.set({
authorizationHeaderValue: authHeaderValue,
key: cacheKey,
encodedCrossServiceToken: crossServiceToken,
expiresAtInSeconds: this.getCrossServiceTokenCacheExpireTimestamp(decodedToken),
userUuid: decodedToken.user.uuid,
@@ -67,6 +69,7 @@ export abstract class AuthMiddleware extends BaseMiddleware {
response.locals.user = decodedToken.user
response.locals.session = decodedToken.session
response.locals.roles = decodedToken.roles
response.locals.sharedVaultOwnerContext = decodedToken.shared_vault_owner_context
} catch (error) {
const errorMessage = (error as AxiosError).isAxiosError
? JSON.stringify((error as AxiosError).response?.data)

View File

@@ -9,7 +9,7 @@ export class LegacyController extends BaseHttpController {
private AUTH_ROUTES: Map<string, string>
private PARAMETRIZED_AUTH_ROUTES: Map<string, string>
constructor(@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface) {
constructor(@inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface) {
super()
this.AUTH_ROUTES = new Map([
@@ -29,17 +29,17 @@ export class LegacyController extends BaseHttpController {
])
}
@httpPost('/items/sync', TYPES.RequiredCrossServiceTokenMiddleware)
@httpPost('/items/sync', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async legacyItemsSync(request: Request, response: Response): Promise<void> {
await this.httpService.callLegacySyncingServer(request, response, request.path.substring(1), request.body)
}
@httpGet('/items/:item_id/revisions', TYPES.RequiredCrossServiceTokenMiddleware)
@httpGet('/items/:item_id/revisions', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async legacyGetRevisions(request: Request, response: Response): Promise<void> {
await this.httpService.callLegacySyncingServer(request, response, request.path.substring(1), request.body)
}
@httpGet('/items/:item_id/revisions/:id', TYPES.RequiredCrossServiceTokenMiddleware)
@httpGet('/items/:item_id/revisions/:id', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async legacyGetRevision(request: Request, response: Response): Promise<void> {
await this.httpService.callLegacySyncingServer(request, response, request.path.substring(1), request.body)
}

View File

@@ -11,12 +11,12 @@ import { AuthMiddleware } from './AuthMiddleware'
@injectable()
export class OptionalCrossServiceTokenMiddleware extends AuthMiddleware {
constructor(
@inject(TYPES.ServiceProxy) serviceProxy: ServiceProxyInterface,
@inject(TYPES.AUTH_JWT_SECRET) jwtSecret: string,
@inject(TYPES.CROSS_SERVICE_TOKEN_CACHE_TTL) crossServiceTokenCacheTTL: number,
@inject(TYPES.CrossServiceTokenCache) crossServiceTokenCache: CrossServiceTokenCacheInterface,
@inject(TYPES.Timer) timer: TimerInterface,
@inject(TYPES.Logger) logger: Logger,
@inject(TYPES.ApiGateway_ServiceProxy) serviceProxy: ServiceProxyInterface,
@inject(TYPES.ApiGateway_AUTH_JWT_SECRET) jwtSecret: string,
@inject(TYPES.ApiGateway_CROSS_SERVICE_TOKEN_CACHE_TTL) crossServiceTokenCacheTTL: number,
@inject(TYPES.ApiGateway_CrossServiceTokenCache) crossServiceTokenCache: CrossServiceTokenCacheInterface,
@inject(TYPES.ApiGateway_Timer) timer: TimerInterface,
@inject(TYPES.ApiGateway_Logger) logger: Logger,
) {
super(serviceProxy, jwtSecret, crossServiceTokenCacheTTL, crossServiceTokenCache, timer, logger)
}

View File

@@ -11,12 +11,12 @@ import { AuthMiddleware } from './AuthMiddleware'
@injectable()
export class RequiredCrossServiceTokenMiddleware extends AuthMiddleware {
constructor(
@inject(TYPES.ServiceProxy) serviceProxy: ServiceProxyInterface,
@inject(TYPES.AUTH_JWT_SECRET) jwtSecret: string,
@inject(TYPES.CROSS_SERVICE_TOKEN_CACHE_TTL) crossServiceTokenCacheTTL: number,
@inject(TYPES.CrossServiceTokenCache) crossServiceTokenCache: CrossServiceTokenCacheInterface,
@inject(TYPES.Timer) timer: TimerInterface,
@inject(TYPES.Logger) logger: Logger,
@inject(TYPES.ApiGateway_ServiceProxy) serviceProxy: ServiceProxyInterface,
@inject(TYPES.ApiGateway_AUTH_JWT_SECRET) jwtSecret: string,
@inject(TYPES.ApiGateway_CROSS_SERVICE_TOKEN_CACHE_TTL) crossServiceTokenCacheTTL: number,
@inject(TYPES.ApiGateway_CrossServiceTokenCache) crossServiceTokenCache: CrossServiceTokenCacheInterface,
@inject(TYPES.ApiGateway_Timer) timer: TimerInterface,
@inject(TYPES.ApiGateway_Logger) logger: Logger,
) {
super(serviceProxy, jwtSecret, crossServiceTokenCacheTTL, crossServiceTokenCache, timer, logger)
}
@@ -42,6 +42,8 @@ export class RequiredCrossServiceTokenMiddleware extends AuthMiddleware {
_next: NextFunction,
): boolean {
if (!authHeaderValue) {
this.logger.debug('Missing auth header')
response.status(401).send({
error: {
tag: 'invalid-auth',

View File

@@ -11,10 +11,10 @@ import { TokenAuthenticationMethod } from './TokenAuthenticationMethod'
@injectable()
export class SubscriptionTokenAuthMiddleware extends BaseMiddleware {
constructor(
@inject(TYPES.HTTPClient) private httpClient: AxiosInstance,
@inject(TYPES.AUTH_SERVER_URL) private authServerUrl: string,
@inject(TYPES.AUTH_JWT_SECRET) private jwtSecret: string,
@inject(TYPES.Logger) private logger: Logger,
@inject(TYPES.ApiGateway_HTTPClient) private httpClient: AxiosInstance,
@inject(TYPES.ApiGateway_AUTH_SERVER_URL) private authServerUrl: string,
@inject(TYPES.ApiGateway_AUTH_JWT_SECRET) private jwtSecret: string,
@inject(TYPES.ApiGateway_Logger) private logger: Logger,
) {
super()
}

View File

@@ -1,5 +1,4 @@
import { CrossServiceTokenData } from '@standardnotes/security'
import { RoleName } from '@standardnotes/domain-core'
import { NextFunction, Request, Response } from 'express'
import { inject, injectable } from 'inversify'
import { BaseMiddleware } from 'inversify-express-utils'
@@ -12,10 +11,10 @@ import { TYPES } from '../Bootstrap/Types'
@injectable()
export class WebSocketAuthMiddleware extends BaseMiddleware {
constructor(
@inject(TYPES.HTTPClient) private httpClient: AxiosInstance,
@inject(TYPES.AUTH_SERVER_URL) private authServerUrl: string,
@inject(TYPES.AUTH_JWT_SECRET) private jwtSecret: string,
@inject(TYPES.Logger) private logger: Logger,
@inject(TYPES.ApiGateway_HTTPClient) private httpClient: AxiosInstance,
@inject(TYPES.ApiGateway_AUTH_SERVER_URL) private authServerUrl: string,
@inject(TYPES.ApiGateway_AUTH_JWT_SECRET) private jwtSecret: string,
@inject(TYPES.ApiGateway_Logger) private logger: Logger,
) {
super()
}
@@ -60,9 +59,6 @@ export class WebSocketAuthMiddleware extends BaseMiddleware {
const decodedToken = <CrossServiceTokenData>verify(crossServiceToken, this.jwtSecret, { algorithms: ['HS256'] })
response.locals.freeUser =
decodedToken.roles.length === 1 &&
decodedToken.roles.find((role) => role.name === RoleName.NAMES.CoreUser) !== undefined
response.locals.user = decodedToken.user
response.locals.roles = decodedToken.roles
} catch (error) {

View File

@@ -4,6 +4,7 @@ export * from './SubscriptionTokenAuthMiddleware'
export * from './TokenAuthenticationMethod'
export * from './WebSocketAuthMiddleware'
export * from './v1/ActionsController'
export * from './v1/MessagesController'
export * from './v1/AuthenticatorsController'
export * from './v1/FilesController'
export * from './v1/InvoicesController'
@@ -12,6 +13,9 @@ export * from './v1/OfflineController'
export * from './v1/PaymentsController'
export * from './v1/RevisionsController'
export * from './v1/SessionsController'
export * from './v1/SharedVaultInvitesController'
export * from './v1/SharedVaultUsersController'
export * from './v1/SharedVaultsController'
export * from './v1/SubscriptionInvitesController'
export * from './v1/TokensController'
export * from './v1/UsersController'

View File

@@ -8,8 +8,8 @@ import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolv
@controller('/v1')
export class ActionsController extends BaseHttpController {
constructor(
@inject(TYPES.ServiceProxy) private serviceProxy: ServiceProxyInterface,
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
@inject(TYPES.ApiGateway_ServiceProxy) private serviceProxy: ServiceProxyInterface,
@inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
) {
super()
}
@@ -24,7 +24,7 @@ export class ActionsController extends BaseHttpController {
)
}
@httpGet('/login-params', TYPES.OptionalCrossServiceTokenMiddleware)
@httpGet('/login-params', TYPES.ApiGateway_OptionalCrossServiceTokenMiddleware)
async loginParams(request: Request, response: Response): Promise<void> {
await this.serviceProxy.callAuthServer(
request,
@@ -34,7 +34,7 @@ export class ActionsController extends BaseHttpController {
)
}
@httpPost('/logout', TYPES.OptionalCrossServiceTokenMiddleware)
@httpPost('/logout', TYPES.ApiGateway_OptionalCrossServiceTokenMiddleware)
async logout(request: Request, response: Response): Promise<void> {
await this.serviceProxy.callAuthServer(
request,
@@ -54,7 +54,7 @@ export class ActionsController extends BaseHttpController {
)
}
@httpPost('/recovery/codes', TYPES.RequiredCrossServiceTokenMiddleware)
@httpPost('/recovery/codes', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async recoveryCodes(request: Request, response: Response): Promise<void> {
await this.serviceProxy.callAuthServer(
request,

View File

@@ -9,13 +9,13 @@ import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolv
@controller('/v1/authenticators')
export class AuthenticatorsController extends BaseHttpController {
constructor(
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
@inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
) {
super()
}
@httpDelete('/:authenticatorId', TYPES.RequiredCrossServiceTokenMiddleware)
@httpDelete('/:authenticatorId', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async delete(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(
request,
@@ -29,7 +29,7 @@ export class AuthenticatorsController extends BaseHttpController {
)
}
@httpGet('/', TYPES.RequiredCrossServiceTokenMiddleware)
@httpGet('/', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async list(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(
request,
@@ -39,7 +39,7 @@ export class AuthenticatorsController extends BaseHttpController {
)
}
@httpGet('/generate-registration-options', TYPES.RequiredCrossServiceTokenMiddleware)
@httpGet('/generate-registration-options', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async generateRegistrationOptions(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(
request,
@@ -59,7 +59,7 @@ export class AuthenticatorsController extends BaseHttpController {
)
}
@httpPost('/verify-registration', TYPES.RequiredCrossServiceTokenMiddleware)
@httpPost('/verify-registration', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async verifyRegistration(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(
request,

View File

@@ -9,13 +9,13 @@ import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolv
@controller('/v1/files')
export class FilesController extends BaseHttpController {
constructor(
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
@inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
) {
super()
}
@httpPost('/valet-tokens', TYPES.RequiredCrossServiceTokenMiddleware)
@httpPost('/valet-tokens', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async createToken(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(
request,

View File

@@ -6,11 +6,11 @@ import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
@controller('/v1')
export class InvoicesController extends BaseHttpController {
constructor(@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface) {
constructor(@inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface) {
super()
}
@httpPost('/invoices/send-latest', TYPES.SubscriptionTokenAuthMiddleware)
@httpPost('/invoices/send-latest', TYPES.ApiGateway_SubscriptionTokenAuthMiddleware)
async sendLatestInvoice(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer(request, response, 'api/pro_users/send-invoice', request.body)
}

View File

@@ -5,11 +5,11 @@ import { TYPES } from '../../Bootstrap/Types'
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
@controller('/v1/items', TYPES.RequiredCrossServiceTokenMiddleware)
@controller('/v1/items', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
export class ItemsController extends BaseHttpController {
constructor(
@inject(TYPES.ServiceProxy) private serviceProxy: ServiceProxyInterface,
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
@inject(TYPES.ApiGateway_ServiceProxy) private serviceProxy: ServiceProxyInterface,
@inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
) {
super()
}

View File

@@ -0,0 +1,70 @@
import { Request, Response } from 'express'
import { inject } from 'inversify'
import { BaseHttpController, controller, httpDelete, httpGet, httpPost } from 'inversify-express-utils'
import { TYPES } from '../../Bootstrap/Types'
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
@controller('/v1/messages', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
export class MessagesController extends BaseHttpController {
constructor(
@inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
) {
super()
}
@httpGet('/')
async getMessages(request: Request, response: Response): Promise<void> {
await this.httpService.callSyncingServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'messages/'),
request.body,
)
}
@httpGet('/outbound')
async getMessagesSent(request: Request, response: Response): Promise<void> {
await this.httpService.callSyncingServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'messages/outbound'),
request.body,
)
}
@httpPost('/')
async sendMessage(request: Request, response: Response): Promise<void> {
await this.httpService.callSyncingServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'messages/'),
request.body,
)
}
@httpDelete('/inbound')
async deleteMessagesSentToUser(request: Request, response: Response): Promise<void> {
await this.httpService.callSyncingServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier('DELETE', 'messages/inbound'),
request.body,
)
}
@httpDelete('/:messageUuid')
async deleteMessage(request: Request, response: Response): Promise<void> {
await this.httpService.callSyncingServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier(
'DELETE',
'messages/:messageUuid',
request.params.messageUuid,
),
request.body,
)
}
}

View File

@@ -9,8 +9,8 @@ import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolv
@controller('/v1/offline')
export class OfflineController extends BaseHttpController {
constructor(
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
@inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
) {
super()
}

View File

@@ -6,7 +6,7 @@ import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
@controller('/v1')
export class PaymentsController extends BaseHttpController {
constructor(@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface) {
constructor(@inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface) {
super()
}
@@ -40,12 +40,12 @@ export class PaymentsController extends BaseHttpController {
await this.httpService.callPaymentsServer(request, response, 'api/extensions', request.body)
}
@httpPost('/subscriptions/tiered', TYPES.SubscriptionTokenAuthMiddleware)
@httpPost('/subscriptions/tiered', TYPES.ApiGateway_SubscriptionTokenAuthMiddleware)
async createTieredSubscription(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer(request, response, 'api/subscriptions/tiered', request.body)
}
@httpPost('/subscriptions/apple_iap_confirm', TYPES.SubscriptionTokenAuthMiddleware)
@httpPost('/subscriptions/apple_iap_confirm', TYPES.ApiGateway_SubscriptionTokenAuthMiddleware)
async appleIAPConfirm(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer(request, response, 'api/subscriptions/apple_iap_confirm', request.body)
}
@@ -140,7 +140,7 @@ export class PaymentsController extends BaseHttpController {
)
}
@httpPost('/payments/stripe-setup-intent', TYPES.SubscriptionTokenAuthMiddleware)
@httpPost('/payments/stripe-setup-intent', TYPES.ApiGateway_SubscriptionTokenAuthMiddleware)
async createStripeSetupIntent(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer(request, response, 'api/pro_users/stripe-setup-intent', request.body)
}

View File

@@ -1,7 +1,7 @@
import { BaseHttpController, controller, httpDelete, httpGet, results } from 'inversify-express-utils'
import { TYPES } from '../../Bootstrap/Types'
@controller('/v1/items/:item_id/revisions', TYPES.RequiredCrossServiceTokenMiddleware)
@controller('/v1/items/:item_id/revisions', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
export class RevisionsController extends BaseHttpController {
@httpGet('/')
async getRevisions(): Promise<results.JsonResult> {

View File

@@ -8,13 +8,13 @@ import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolv
@controller('/v1/sessions')
export class SessionsController extends BaseHttpController {
constructor(
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
@inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
) {
super()
}
@httpGet('/', TYPES.RequiredCrossServiceTokenMiddleware)
@httpGet('/', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async getSessions(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(
request,
@@ -23,7 +23,7 @@ export class SessionsController extends BaseHttpController {
)
}
@httpDelete('/:uuid', TYPES.RequiredCrossServiceTokenMiddleware)
@httpDelete('/:uuid', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async deleteSession(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(
request,
@@ -35,7 +35,7 @@ export class SessionsController extends BaseHttpController {
)
}
@httpDelete('/', TYPES.RequiredCrossServiceTokenMiddleware)
@httpDelete('/', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async deleteSessions(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(
request,

View File

@@ -0,0 +1,158 @@
import { Request, Response } from 'express'
import { inject } from 'inversify'
import { BaseHttpController, controller, httpDelete, httpGet, httpPatch, httpPost } from 'inversify-express-utils'
import { TYPES } from '../../Bootstrap/Types'
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
@controller('/v1/shared-vaults', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
export class SharedVaultInvitesController extends BaseHttpController {
constructor(
@inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
) {
super()
}
@httpPost('/:sharedVaultUuid/invites')
async createSharedVaultInvite(request: Request, response: Response): Promise<void> {
await this.httpService.callSyncingServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier(
'POST',
'shared-vaults/:sharedVaultUuid/invites',
request.params.sharedVaultUuid,
),
request.body,
)
}
@httpPatch('/:sharedVaultUuid/invites/:inviteUuid')
async updateSharedVaultInvite(request: Request, response: Response): Promise<void> {
await this.httpService.callSyncingServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier(
'PATCH',
'shared-vaults/:sharedVaultUuid/invites/:inviteUuid',
request.params.sharedVaultUuid,
request.params.inviteUuid,
),
request.body,
)
}
@httpPost('/:sharedVaultUuid/invites/:inviteUuid/accept')
async acceptSharedVaultInvite(request: Request, response: Response): Promise<void> {
await this.httpService.callSyncingServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier(
'POST',
'shared-vaults/:sharedVaultUuid/invites/:inviteUuid/accept',
request.params.sharedVaultUuid,
request.params.inviteUuid,
),
request.body,
)
}
@httpPost('/:sharedVaultUuid/invites/:inviteUuid/decline')
async declineSharedVaultInvite(request: Request, response: Response): Promise<void> {
await this.httpService.callSyncingServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier(
'POST',
'shared-vaults/:sharedVaultUuid/invites/:inviteUuid/decline',
request.params.sharedVaultUuid,
request.params.inviteUuid,
),
request.body,
)
}
@httpDelete('/invites/inbound')
async deleteInboundUserInvites(request: Request, response: Response): Promise<void> {
await this.httpService.callSyncingServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier('DELETE', 'shared-vaults/invites/inbound'),
request.body,
)
}
@httpDelete('/invites/outbound')
async deleteOutboundUserInvites(request: Request, response: Response): Promise<void> {
await this.httpService.callSyncingServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier('DELETE', 'shared-vaults/invites/outbound'),
request.body,
)
}
@httpGet('/invites/outbound')
async getOutboundUserInvites(request: Request, response: Response): Promise<void> {
await this.httpService.callSyncingServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'shared-vaults/invites/outbound'),
request.body,
)
}
@httpGet('/invites')
async getUserInvites(request: Request, response: Response): Promise<void> {
await this.httpService.callSyncingServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'shared-vaults/invites'),
request.body,
)
}
@httpGet('/:sharedVaultUuid/invites')
async getSharedVaultInvites(request: Request, response: Response): Promise<void> {
await this.httpService.callSyncingServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier(
'GET',
'shared-vaults/:sharedVaultUuid/invites',
request.params.sharedVaultUuid,
),
request.body,
)
}
@httpDelete('/:sharedVaultUuid/invites/:inviteUuid')
async deleteSharedVaultInvite(request: Request, response: Response): Promise<void> {
await this.httpService.callSyncingServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier(
'DELETE',
'shared-vaults/:sharedVaultUuid/invites/:inviteUuid',
request.params.sharedVaultUuid,
request.params.inviteUuid,
),
request.body,
)
}
@httpDelete('/:sharedVaultUuid/invites')
async deleteAllSharedVaultInvites(request: Request, response: Response): Promise<void> {
await this.httpService.callSyncingServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier(
'DELETE',
'shared-vaults/:sharedVaultUuid/invites',
request.params.sharedVaultUuid,
),
request.body,
)
}
}

View File

@@ -0,0 +1,45 @@
import { Request, Response } from 'express'
import { inject } from 'inversify'
import { BaseHttpController, controller, httpDelete, httpGet } from 'inversify-express-utils'
import { TYPES } from '../../Bootstrap/Types'
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
@controller('/v1/shared-vaults/:sharedVaultUuid/users', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
export class SharedVaultUsersController extends BaseHttpController {
constructor(
@inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
) {
super()
}
@httpGet('/')
async getSharedVaultUsers(request: Request, response: Response): Promise<void> {
await this.httpService.callSyncingServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier(
'GET',
'shared-vaults/:sharedVaultUuid/users',
request.params.sharedVaultUuid,
),
request.body,
)
}
@httpDelete('/:userUuid')
async removeUserFromSharedVault(request: Request, response: Response): Promise<void> {
await this.httpService.callSyncingServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier(
'DELETE',
'shared-vaults/:sharedVaultUuid/users/:userUuid',
request.params.sharedVaultUuid,
request.params.userUuid,
),
request.body,
)
}
}

View File

@@ -0,0 +1,64 @@
import { Request, Response } from 'express'
import { inject } from 'inversify'
import { BaseHttpController, controller, httpDelete, httpGet, httpPost } from 'inversify-express-utils'
import { TYPES } from '../../Bootstrap/Types'
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
@controller('/v1/shared-vaults', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
export class SharedVaultsController extends BaseHttpController {
constructor(
@inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
) {
super()
}
@httpGet('/')
async getSharedVaults(request: Request, response: Response): Promise<void> {
await this.httpService.callSyncingServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'shared-vaults/'),
request.body,
)
}
@httpPost('/')
async createSharedVault(request: Request, response: Response): Promise<void> {
await this.httpService.callSyncingServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'shared-vaults/'),
request.body,
)
}
@httpDelete('/:sharedVaultUuid')
async deleteSharedVault(request: Request, response: Response): Promise<void> {
await this.httpService.callSyncingServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier(
'DELETE',
'shared-vaults/:sharedVaultUuid',
request.params.sharedVaultUuid,
),
request.body,
)
}
@httpPost('/:sharedVaultUuid/valet-tokens')
async createValetTokenForSharedVaultFile(request: Request, response: Response): Promise<void> {
await this.httpService.callSyncingServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier(
'POST',
'shared-vaults/:sharedVaultUuid/valet-tokens',
request.params.sharedVaultUuid,
),
request.body,
)
}
}

View File

@@ -9,13 +9,13 @@ import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolv
@controller('/v1/subscription-invites')
export class SubscriptionInvitesController extends BaseHttpController {
constructor(
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
@inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
) {
super()
}
@httpPost('/', TYPES.RequiredCrossServiceTokenMiddleware)
@httpPost('/', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async inviteToSubscriptionSharing(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(
request,
@@ -25,7 +25,7 @@ export class SubscriptionInvitesController extends BaseHttpController {
)
}
@httpGet('/', TYPES.RequiredCrossServiceTokenMiddleware)
@httpGet('/', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async listInvites(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(
request,
@@ -35,7 +35,7 @@ export class SubscriptionInvitesController extends BaseHttpController {
)
}
@httpDelete('/:inviteUuid', TYPES.RequiredCrossServiceTokenMiddleware)
@httpDelete('/:inviteUuid', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async cancelSubscriptionSharing(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(
request,
@@ -48,7 +48,7 @@ export class SubscriptionInvitesController extends BaseHttpController {
)
}
@httpPost('/:inviteUuid/accept', TYPES.RequiredCrossServiceTokenMiddleware)
@httpPost('/:inviteUuid/accept', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async acceptInvite(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(
request,

View File

@@ -9,13 +9,13 @@ import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolv
@controller('/v1/subscription-tokens')
export class TokensController extends BaseHttpController {
constructor(
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
@inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
) {
super()
}
@httpPost('/', TYPES.RequiredCrossServiceTokenMiddleware)
@httpPost('/', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async createToken(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(
request,

View File

@@ -20,9 +20,10 @@ import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolv
@controller('/v1/users')
export class UsersController extends BaseHttpController {
constructor(
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
@inject(TYPES.Logger) private logger: Logger,
@inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
@inject(TYPES.ApiGateway_Logger) private logger: Logger,
@inject(TYPES.ApiGateway_IS_CONFIGURED_FOR_HOME_SERVER) private isConfiguredForHomeServer: boolean,
) {
super()
}
@@ -32,12 +33,12 @@ export class UsersController extends BaseHttpController {
await this.httpService.callPaymentsServer(request, response, 'api/pro_users/claim-account', request.body)
}
@httpPost('/send-activation-code', TYPES.SubscriptionTokenAuthMiddleware)
@httpPost('/send-activation-code', TYPES.ApiGateway_SubscriptionTokenAuthMiddleware)
async sendActivationCode(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer(request, response, 'api/pro_users/send-activation-code', request.body)
}
@httpPatch('/:userId', TYPES.RequiredCrossServiceTokenMiddleware)
@httpPatch('/:userId', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async updateUser(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(
request,
@@ -47,7 +48,7 @@ export class UsersController extends BaseHttpController {
)
}
@httpPut('/:userUuid/password', TYPES.RequiredCrossServiceTokenMiddleware)
@httpPut('/:userUuid/password', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async changePassword(request: Request, response: Response): Promise<void> {
this.logger.debug(
'[DEPRECATED] use endpoint /v1/users/:userUuid/attributes/credentials instead of /v1/users/:userUuid/password',
@@ -65,7 +66,7 @@ export class UsersController extends BaseHttpController {
)
}
@httpPut('/:userUuid/attributes/credentials', TYPES.RequiredCrossServiceTokenMiddleware)
@httpPut('/:userUuid/attributes/credentials', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async changeCredentials(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(
request,
@@ -79,7 +80,7 @@ export class UsersController extends BaseHttpController {
)
}
@httpGet('/:userId/params', TYPES.RequiredCrossServiceTokenMiddleware)
@httpGet('/:userId/params', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async getKeyParams(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(
request,
@@ -88,12 +89,12 @@ export class UsersController extends BaseHttpController {
)
}
@all('/:userId/mfa', TYPES.RequiredCrossServiceTokenMiddleware)
@all('/:userId/mfa', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async blockMFA(): Promise<results.StatusCodeResult> {
return this.statusCode(401)
}
@httpPost('/:userUuid/integrations/listed', TYPES.RequiredCrossServiceTokenMiddleware)
@httpPost('/:userUuid/integrations/listed', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async createListedAccount(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(
request,
@@ -113,7 +114,7 @@ export class UsersController extends BaseHttpController {
)
}
@httpGet('/:userUuid/settings', TYPES.RequiredCrossServiceTokenMiddleware)
@httpGet('/:userUuid/settings', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async listSettings(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(
request,
@@ -126,7 +127,7 @@ export class UsersController extends BaseHttpController {
)
}
@httpPut('/:userUuid/settings', TYPES.RequiredCrossServiceTokenMiddleware)
@httpPut('/:userUuid/settings', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async putSetting(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(
request,
@@ -140,7 +141,7 @@ export class UsersController extends BaseHttpController {
)
}
@httpGet('/:userUuid/settings/:settingName', TYPES.RequiredCrossServiceTokenMiddleware)
@httpGet('/:userUuid/settings/:settingName', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async getSetting(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(
request,
@@ -154,7 +155,7 @@ export class UsersController extends BaseHttpController {
)
}
@httpDelete('/:userUuid/settings/:settingName', TYPES.RequiredCrossServiceTokenMiddleware)
@httpDelete('/:userUuid/settings/:settingName', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async deleteSetting(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(
request,
@@ -169,7 +170,10 @@ export class UsersController extends BaseHttpController {
)
}
@httpGet('/:userUuid/subscription-settings/:subscriptionSettingName', TYPES.RequiredCrossServiceTokenMiddleware)
@httpGet(
'/:userUuid/subscription-settings/:subscriptionSettingName',
TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware,
)
async getSubscriptionSetting(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(
request,
@@ -183,7 +187,7 @@ export class UsersController extends BaseHttpController {
)
}
@httpGet('/:userUuid/features', TYPES.RequiredCrossServiceTokenMiddleware)
@httpGet('/:userUuid/features', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async getFeatures(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(
request,
@@ -196,7 +200,7 @@ export class UsersController extends BaseHttpController {
)
}
@httpGet('/:userUuid/subscription', TYPES.RequiredCrossServiceTokenMiddleware)
@httpGet('/:userUuid/subscription', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async getSubscription(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(
request,
@@ -209,7 +213,7 @@ export class UsersController extends BaseHttpController {
)
}
@httpGet('/subscription', TYPES.SubscriptionTokenAuthMiddleware)
@httpGet('/subscription', TYPES.ApiGateway_SubscriptionTokenAuthMiddleware)
async getSubscriptionBySubscriptionToken(request: Request, response: Response): Promise<void> {
if (response.locals.tokenAuthenticationMethod === TokenAuthenticationMethod.OfflineSubscriptionToken) {
await this.httpService.callAuthServer(
@@ -232,12 +236,20 @@ export class UsersController extends BaseHttpController {
)
}
@httpDelete('/:userUuid', TYPES.RequiredCrossServiceTokenMiddleware)
@httpDelete('/:userUuid', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async deleteUser(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer(request, response, 'api/account', request.body)
if (!this.isConfiguredForHomeServer) {
await this.httpService.callPaymentsServer(request, response, 'api/account', request.body, true)
}
await this.httpService.callAuthServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier('DELETE', 'users/:userUuid', request.params.userUuid),
)
}
@httpPost('/:userUuid/requests', TYPES.RequiredCrossServiceTokenMiddleware)
@httpPost('/:userUuid/requests', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async submitRequest(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(
request,

View File

@@ -10,14 +10,14 @@ import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolv
@controller('/v1/sockets')
export class WebSocketsController extends BaseHttpController {
constructor(
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
@inject(TYPES.Logger) private logger: Logger,
@inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
@inject(TYPES.ApiGateway_Logger) private logger: Logger,
) {
super()
}
@httpPost('/tokens', TYPES.RequiredCrossServiceTokenMiddleware)
@httpPost('/tokens', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async createWebSocketConnectionToken(request: Request, response: Response): Promise<void> {
await this.httpService.callWebSocketServer(
request,
@@ -27,7 +27,7 @@ export class WebSocketsController extends BaseHttpController {
)
}
@httpPost('/connections', TYPES.WebSocketAuthMiddleware)
@httpPost('/connections', TYPES.ApiGateway_WebSocketAuthMiddleware)
async createWebSocketConnection(request: Request, response: Response): Promise<void> {
if (!request.headers.connectionid) {
this.logger.error('Could not create a websocket connection. Missing connection id header.')

View File

@@ -9,8 +9,8 @@ import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolv
@controller('/v2')
export class ActionsControllerV2 extends BaseHttpController {
constructor(
@inject(TYPES.ServiceProxy) private serviceProxy: ServiceProxyInterface,
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
@inject(TYPES.ApiGateway_ServiceProxy) private serviceProxy: ServiceProxyInterface,
@inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
) {
super()
}
@@ -25,7 +25,7 @@ export class ActionsControllerV2 extends BaseHttpController {
)
}
@httpPost('/login-params', TYPES.OptionalCrossServiceTokenMiddleware)
@httpPost('/login-params', TYPES.ApiGateway_OptionalCrossServiceTokenMiddleware)
async loginParams(request: Request, response: Response): Promise<void> {
await this.serviceProxy.callAuthServer(
request,

View File

@@ -6,7 +6,7 @@ import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
@controller('/v2')
export class PaymentsControllerV2 extends BaseHttpController {
constructor(@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface) {
constructor(@inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface) {
super()
}
@@ -15,22 +15,22 @@ export class PaymentsControllerV2 extends BaseHttpController {
await this.httpService.callPaymentsServer(request, response, 'api/subscriptions/features', request.body)
}
@httpGet('/subscriptions/tailored', TYPES.SubscriptionTokenAuthMiddleware)
@httpGet('/subscriptions/tailored', TYPES.ApiGateway_SubscriptionTokenAuthMiddleware)
async getTailoredSubscriptionsWithFeatures(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer(request, response, 'api/subscriptions/features', request.body)
}
@httpGet('/subscriptions/deltas', TYPES.SubscriptionTokenAuthMiddleware)
@httpGet('/subscriptions/deltas', TYPES.ApiGateway_SubscriptionTokenAuthMiddleware)
async getSubscriptionDeltasForChangingPlan(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer(request, response, 'api/subscriptions/deltas', request.body)
}
@httpPost('/subscriptions/deltas/apply', TYPES.SubscriptionTokenAuthMiddleware)
@httpPost('/subscriptions/deltas/apply', TYPES.ApiGateway_SubscriptionTokenAuthMiddleware)
async applySubscriptionDelta(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer(request, response, 'api/subscriptions/deltas/apply', request.body)
}
@httpPost('/subscriptions/change-payment-method', TYPES.SubscriptionTokenAuthMiddleware)
@httpPost('/subscriptions/change-payment-method', TYPES.ApiGateway_SubscriptionTokenAuthMiddleware)
async changePaymentMethod(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer(
request,
@@ -40,7 +40,7 @@ export class PaymentsControllerV2 extends BaseHttpController {
)
}
@httpGet('/subscriptions/:subscriptionId', TYPES.SubscriptionTokenAuthMiddleware)
@httpGet('/subscriptions/:subscriptionId', TYPES.ApiGateway_SubscriptionTokenAuthMiddleware)
async getSubscription(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer(
request,
@@ -50,7 +50,7 @@ export class PaymentsControllerV2 extends BaseHttpController {
)
}
@httpDelete('/subscriptions/:subscriptionId', TYPES.SubscriptionTokenAuthMiddleware)
@httpDelete('/subscriptions/:subscriptionId', TYPES.ApiGateway_SubscriptionTokenAuthMiddleware)
async cancelSubscription(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer(
request,
@@ -60,7 +60,7 @@ export class PaymentsControllerV2 extends BaseHttpController {
)
}
@httpPatch('/subscriptions/:subscriptionId', TYPES.SubscriptionTokenAuthMiddleware)
@httpPatch('/subscriptions/:subscriptionId', TYPES.ApiGateway_SubscriptionTokenAuthMiddleware)
async updateSubscription(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer(
request,

View File

@@ -6,11 +6,11 @@ import { TYPES } from '../../Bootstrap/Types'
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
@controller('/v2/items/:itemUuid/revisions', TYPES.RequiredCrossServiceTokenMiddleware)
@controller('/v2/items/:itemUuid/revisions', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
export class RevisionsControllerV2 extends BaseHttpController {
constructor(
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
@inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
) {
super()
}

View File

@@ -12,29 +12,29 @@ export class InMemoryCrossServiceTokenCache implements CrossServiceTokenCacheInt
constructor(private timer: TimerInterface) {}
async set(dto: {
authorizationHeaderValue: string
key: string
encodedCrossServiceToken: string
expiresAtInSeconds: number
userUuid: string
}): Promise<void> {
let userAuthHeaders = []
const userAuthHeadersJSON = this.crossServiceTokenCache.get(`${this.USER_CST_PREFIX}:${dto.userUuid}`)
if (userAuthHeadersJSON) {
userAuthHeaders = JSON.parse(userAuthHeadersJSON)
let userKeys = []
const userKeysJSON = this.crossServiceTokenCache.get(`${this.USER_CST_PREFIX}:${dto.userUuid}`)
if (userKeysJSON) {
userKeys = JSON.parse(userKeysJSON)
}
userAuthHeaders.push(dto.authorizationHeaderValue)
userKeys.push(dto.key)
this.crossServiceTokenCache.set(`${this.USER_CST_PREFIX}:${dto.userUuid}`, JSON.stringify(userAuthHeaders))
this.crossServiceTokenCache.set(`${this.USER_CST_PREFIX}:${dto.userUuid}`, JSON.stringify(userKeys))
this.crossServiceTokenTTLCache.set(`${this.USER_CST_PREFIX}:${dto.userUuid}`, dto.expiresAtInSeconds)
this.crossServiceTokenCache.set(`${this.PREFIX}:${dto.authorizationHeaderValue}`, dto.encodedCrossServiceToken)
this.crossServiceTokenTTLCache.set(`${this.PREFIX}:${dto.authorizationHeaderValue}`, dto.expiresAtInSeconds)
this.crossServiceTokenCache.set(`${this.PREFIX}:${dto.key}`, dto.encodedCrossServiceToken)
this.crossServiceTokenTTLCache.set(`${this.PREFIX}:${dto.key}`, dto.expiresAtInSeconds)
}
async get(authorizationHeaderValue: string): Promise<string | null> {
async get(key: string): Promise<string | null> {
this.invalidateExpiredTokens()
const cachedToken = this.crossServiceTokenCache.get(`${this.PREFIX}:${authorizationHeaderValue}`)
const cachedToken = this.crossServiceTokenCache.get(`${this.PREFIX}:${key}`)
if (!cachedToken) {
return null
}
@@ -43,15 +43,15 @@ export class InMemoryCrossServiceTokenCache implements CrossServiceTokenCacheInt
}
async invalidate(userUuid: string): Promise<void> {
let userAuthorizationHeaderValues = []
const userAuthHeadersJSON = this.crossServiceTokenCache.get(`${this.USER_CST_PREFIX}:${userUuid}`)
if (userAuthHeadersJSON) {
userAuthorizationHeaderValues = JSON.parse(userAuthHeadersJSON)
let userKeyValues = []
const userKeysJSON = this.crossServiceTokenCache.get(`${this.USER_CST_PREFIX}:${userUuid}`)
if (userKeysJSON) {
userKeyValues = JSON.parse(userKeysJSON)
}
for (const authorizationHeaderValue of userAuthorizationHeaderValues) {
this.crossServiceTokenCache.delete(`${this.PREFIX}:${authorizationHeaderValue}`)
this.crossServiceTokenTTLCache.delete(`${this.PREFIX}:${authorizationHeaderValue}`)
for (const key of userKeyValues) {
this.crossServiceTokenCache.delete(`${this.PREFIX}:${key}`)
this.crossServiceTokenTTLCache.delete(`${this.PREFIX}:${key}`)
}
this.crossServiceTokenCache.delete(`${this.USER_CST_PREFIX}:${userUuid}`)
this.crossServiceTokenTTLCache.delete(`${this.USER_CST_PREFIX}:${userUuid}`)

View File

@@ -9,35 +9,35 @@ export class RedisCrossServiceTokenCache implements CrossServiceTokenCacheInterf
private readonly PREFIX = 'cst'
private readonly USER_CST_PREFIX = 'user-cst'
constructor(@inject(TYPES.Redis) private redisClient: IORedis.Redis) {}
constructor(@inject(TYPES.ApiGateway_Redis) private redisClient: IORedis.Redis) {}
async set(dto: {
authorizationHeaderValue: string
key: string
encodedCrossServiceToken: string
expiresAtInSeconds: number
userUuid: string
}): Promise<void> {
const pipeline = this.redisClient.pipeline()
pipeline.sadd(`${this.USER_CST_PREFIX}:${dto.userUuid}`, dto.authorizationHeaderValue)
pipeline.sadd(`${this.USER_CST_PREFIX}:${dto.userUuid}`, dto.key)
pipeline.expireat(`${this.USER_CST_PREFIX}:${dto.userUuid}`, dto.expiresAtInSeconds)
pipeline.set(`${this.PREFIX}:${dto.authorizationHeaderValue}`, dto.encodedCrossServiceToken)
pipeline.expireat(`${this.PREFIX}:${dto.authorizationHeaderValue}`, dto.expiresAtInSeconds)
pipeline.set(`${this.PREFIX}:${dto.key}`, dto.encodedCrossServiceToken)
pipeline.expireat(`${this.PREFIX}:${dto.key}`, dto.expiresAtInSeconds)
await pipeline.exec()
}
async get(authorizationHeaderValue: string): Promise<string | null> {
return this.redisClient.get(`${this.PREFIX}:${authorizationHeaderValue}`)
async get(key: string): Promise<string | null> {
return this.redisClient.get(`${this.PREFIX}:${key}`)
}
async invalidate(userUuid: string): Promise<void> {
const userAuthorizationHeaderValues = await this.redisClient.smembers(`${this.USER_CST_PREFIX}:${userUuid}`)
const userKeyValues = await this.redisClient.smembers(`${this.USER_CST_PREFIX}:${userUuid}`)
const pipeline = this.redisClient.pipeline()
for (const authorizationHeaderValue of userAuthorizationHeaderValues) {
pipeline.del(`${this.PREFIX}:${authorizationHeaderValue}`)
for (const key of userKeyValues) {
pipeline.del(`${this.PREFIX}:${key}`)
}
pipeline.del(`${this.USER_CST_PREFIX}:${userUuid}`)

View File

@@ -1,10 +1,10 @@
export interface CrossServiceTokenCacheInterface {
set(dto: {
authorizationHeaderValue: string
key: string
encodedCrossServiceToken: string
expiresAtInSeconds: number
userUuid: string
}): Promise<void>
get(authorizationHeaderValue: string): Promise<string | null>
get(key: string): Promise<string | null>
invalidate(userUuid: string): Promise<void>
}

View File

@@ -11,27 +11,29 @@ import { ServiceProxyInterface } from './ServiceProxyInterface'
@injectable()
export class HttpServiceProxy implements ServiceProxyInterface {
constructor(
@inject(TYPES.HTTPClient) private httpClient: AxiosInstance,
@inject(TYPES.AUTH_SERVER_URL) private authServerUrl: string,
@inject(TYPES.SYNCING_SERVER_JS_URL) private syncingServerJsUrl: string,
@inject(TYPES.PAYMENTS_SERVER_URL) private paymentsServerUrl: string,
@inject(TYPES.FILES_SERVER_URL) private filesServerUrl: string,
@inject(TYPES.WEB_SOCKET_SERVER_URL) private webSocketServerUrl: string,
@inject(TYPES.REVISIONS_SERVER_URL) private revisionsServerUrl: string,
@inject(TYPES.EMAIL_SERVER_URL) private emailServerUrl: string,
@inject(TYPES.HTTP_CALL_TIMEOUT) private httpCallTimeout: number,
@inject(TYPES.CrossServiceTokenCache) private crossServiceTokenCache: CrossServiceTokenCacheInterface,
@inject(TYPES.Logger) private logger: Logger,
@inject(TYPES.ApiGateway_HTTPClient) private httpClient: AxiosInstance,
@inject(TYPES.ApiGateway_AUTH_SERVER_URL) private authServerUrl: string,
@inject(TYPES.ApiGateway_SYNCING_SERVER_JS_URL) private syncingServerJsUrl: string,
@inject(TYPES.ApiGateway_PAYMENTS_SERVER_URL) private paymentsServerUrl: string,
@inject(TYPES.ApiGateway_FILES_SERVER_URL) private filesServerUrl: string,
@inject(TYPES.ApiGateway_WEB_SOCKET_SERVER_URL) private webSocketServerUrl: string,
@inject(TYPES.ApiGateway_REVISIONS_SERVER_URL) private revisionsServerUrl: string,
@inject(TYPES.ApiGateway_EMAIL_SERVER_URL) private emailServerUrl: string,
@inject(TYPES.ApiGateway_HTTP_CALL_TIMEOUT) private httpCallTimeout: number,
@inject(TYPES.ApiGateway_CrossServiceTokenCache) private crossServiceTokenCache: CrossServiceTokenCacheInterface,
@inject(TYPES.ApiGateway_Logger) private logger: Logger,
) {}
async validateSession(
authorizationHeaderValue: string,
): Promise<{ status: number; data: unknown; headers: { contentType: string } }> {
async validateSession(headers: {
authorization: string
sharedVaultOwnerContext?: string
}): Promise<{ status: number; data: unknown; headers: { contentType: string } }> {
const authResponse = await this.httpClient.request({
method: 'POST',
headers: {
Authorization: authorizationHeaderValue,
Authorization: headers.authorization,
Accept: 'application/json',
'x-shared-vault-owner-context': headers.sharedVaultOwnerContext,
},
validateStatus: (status: number) => {
return status >= 200 && status < 500
@@ -130,19 +132,26 @@ export class HttpServiceProxy implements ServiceProxyInterface {
response: Response,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
): Promise<void> {
returnRawResponse?: boolean,
): Promise<void | Response<unknown, Record<string, unknown>>> {
if (!this.paymentsServerUrl) {
this.logger.debug('Payments Server URL not defined. Skipped request to Payments API.')
return
}
await this.callServerWithLegacyFormat(
const rawResponse = await this.callServerWithLegacyFormat(
this.paymentsServerUrl,
request,
response,
endpointOrMethodIdentifier,
payload,
returnRawResponse,
)
if (returnRawResponse) {
return rawResponse
}
}
async callAuthServerWithLegacyFormat(
@@ -279,7 +288,8 @@ export class HttpServiceProxy implements ServiceProxyInterface {
response: Response,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
): Promise<void> {
returnRawResponse?: boolean,
): Promise<void | Response<unknown, Record<string, unknown>>> {
const serviceResponse = await this.getServerResponse(
serverUrl,
request,
@@ -295,9 +305,21 @@ export class HttpServiceProxy implements ServiceProxyInterface {
this.applyResponseHeaders(serviceResponse, response)
if (serviceResponse.request._redirectable._redirectCount > 0) {
response.status(302).redirect(serviceResponse.request.res.responseUrl)
response.status(302)
if (returnRawResponse) {
return response
}
response.redirect(serviceResponse.request.res.responseUrl)
} else {
response.status(serviceResponse.status).send(serviceResponse.data)
response.status(serviceResponse.status)
if (returnRawResponse) {
return response
}
response.send(serviceResponse.data)
}
}

View File

@@ -42,14 +42,15 @@ export interface ServiceProxyInterface {
response: Response,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
): Promise<void>
returnRawResponse?: boolean,
): Promise<void | Response<unknown, Record<string, unknown>>>
callWebSocketServer(
request: Request,
response: Response,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
): Promise<void>
validateSession(authorizationHeaderValue: string): Promise<{
validateSession(headers: { authorization: string; sharedVaultOwnerContext?: string }): Promise<{
status: number
data: unknown
headers: {

View File

@@ -1,14 +1,15 @@
import { Request, Response } from 'express'
import { ServiceContainerInterface, ServiceIdentifier } from '@standardnotes/domain-core'
import { ServiceProxyInterface } from '../Http/ServiceProxyInterface'
import { ServiceContainerInterface, ServiceIdentifier } from '@standardnotes/domain-core'
export class DirectCallServiceProxy implements ServiceProxyInterface {
constructor(private serviceContainer: ServiceContainerInterface, private filesServerUrl: string) {}
async validateSession(
authorizationHeaderValue: string,
): Promise<{ status: number; data: unknown; headers: { contentType: string } }> {
async validateSession(headers: {
authorization: string
sharedVaultOwnerContext?: string
}): Promise<{ status: number; data: unknown; headers: { contentType: string } }> {
const authService = this.serviceContainer.get(ServiceIdentifier.create(ServiceIdentifier.NAMES.Auth).getValue())
if (!authService) {
throw new Error('Auth service not found')
@@ -17,7 +18,8 @@ export class DirectCallServiceProxy implements ServiceProxyInterface {
const serviceResponse = (await authService.handleRequest(
{
headers: {
authorization: authorizationHeaderValue,
authorization: headers.authorization,
'x-shared-vault-owner-context': headers.sharedVaultOwnerContext,
},
} as never,
{} as never,
@@ -34,8 +36,12 @@ export class DirectCallServiceProxy implements ServiceProxyInterface {
}
}
async callEmailServer(_request: Request, _response: Response, _endpointOrMethodIdentifier: string): Promise<void> {
throw new Error('Email server is not available.')
async callEmailServer(_request: Request, response: Response, _endpointOrMethodIdentifier: string): Promise<void> {
response.status(400).send({
error: {
message: 'Email server is not available.',
},
})
}
async callAuthServer(request: never, response: never, endpointOrMethodIdentifier: string): Promise<void> {
@@ -54,10 +60,14 @@ export class DirectCallServiceProxy implements ServiceProxyInterface {
async callAuthServerWithLegacyFormat(
_request: Request,
_response: Response,
response: Response,
_endpointOrMethodIdentifier: string,
): Promise<void> {
throw new Error('Legacy auth endpoints are no longer available.')
response.status(400).send({
error: {
message: 'Legacy auth endpoints are no longer available.',
},
})
}
async callRevisionsServer(request: never, response: never, endpointOrMethodIdentifier: string): Promise<void> {
@@ -92,22 +102,30 @@ export class DirectCallServiceProxy implements ServiceProxyInterface {
async callLegacySyncingServer(
_request: Request,
_response: Response,
response: Response,
_endpointOrMethodIdentifier: string,
): Promise<void> {
throw new Error('Legacy syncing server endpoints are no longer available.')
response.status(400).send({
error: {
message: 'Legacy syncing server endpoints are no longer available.',
},
})
}
async callPaymentsServer(_request: Request, _response: Response, _endpointOrMethodIdentifier: string): Promise<void> {
throw new Error('Payments server is not available.')
async callPaymentsServer(_request: Request, response: Response, _endpointOrMethodIdentifier: string): Promise<void> {
response.status(400).send({
error: {
message: 'Payments server is not available.',
},
})
}
async callWebSocketServer(
_request: Request,
_response: Response,
_endpointOrMethodIdentifier: string,
): Promise<void> {
throw new Error('Websockets server is not available.')
async callWebSocketServer(_request: Request, response: Response, _endpointOrMethodIdentifier: string): Promise<void> {
response.status(400).send({
error: {
message: 'Websockets server is not available.',
},
})
}
private sendDecoratedResponse(

View File

@@ -43,6 +43,7 @@ export class EndpointResolver implements EndpointResolverInterface {
['[PATCH]:users/:userId', 'auth.users.update'],
['[PUT]:users/:userUuid/attributes/credentials', 'auth.users.updateCredentials'],
['[PUT]:auth/params', 'auth.users.getKeyParams'],
['[DELETE]:users/:userUuid', 'auth.users.delete'],
['[POST]:listed', 'auth.users.createListedAccount'],
['[POST]:auth', 'auth.users.register'],
['[GET]:users/:userUuid/settings', 'auth.users.getSettings'],
@@ -62,6 +63,32 @@ export class EndpointResolver implements EndpointResolverInterface {
['[GET]:items/:itemUuid/revisions', 'revisions.revisions.getRevisions'],
['[GET]:items/:itemUuid/revisions/:id', 'revisions.revisions.getRevision'],
['[DELETE]:items/:itemUuid/revisions/:id', 'revisions.revisions.deleteRevision'],
// Messages Controller
['[GET]:messages/', 'sync.messages.get-received'],
['[GET]:messages/outbound', 'sync.messages.get-sent'],
['[POST]:messages/', 'sync.messages.send'],
['[DELETE]:messages/inbound', 'sync.messages.delete-all'],
['[DELETE]:messages/:messageUuid', 'sync.messages.delete'],
// Shared Vaults Controller
['[GET]:shared-vaults/', 'sync.shared-vaults.get-vaults'],
['[POST]:shared-vaults/', 'sync.shared-vaults.create-vault'],
['[DELETE]:shared-vaults/:sharedVaultUuid', 'sync.shared-vaults.delete-vault'],
['[POST]:shared-vaults/:sharedVaultUuid/valet-tokens', 'sync.shared-vaults.create-file-valet-token'],
// Shared Vault Invites Controller
['[POST]:shared-vaults/:sharedVaultUuid/invites', 'sync.shared-vault-invites.create'],
['[PATCH]:shared-vaults/:sharedVaultUuid/invites/:inviteUuid', 'sync.shared-vault-invites.update'],
['[POST]:shared-vaults/:sharedVaultUuid/invites/:inviteUuid/accept', 'sync.shared-vault-invites.accept'],
['[POST]:shared-vaults/:sharedVaultUuid/invites/:inviteUuid/decline', 'sync.shared-vault-invites.decline'],
['[DELETE]:shared-vaults/invites/inbound', 'sync.shared-vault-invites.delete-inbound'],
['[DELETE]:shared-vaults/invites/outbound', 'sync.shared-vault-invites.delete-outbound'],
['[GET]:shared-vaults/invites/outbound', 'sync.shared-vault-invites.get-outbound'],
['[GET]:shared-vaults/invites', 'sync.shared-vault-invites.get-user-invites'],
['[GET]:shared-vaults/:sharedVaultUuid/invites', 'sync.shared-vault-invites.get-vault-invites'],
['[DELETE]:shared-vaults/:sharedVaultUuid/invites/:inviteUuid', 'sync.shared-vault-invites.delete-invite'],
['[DELETE]:shared-vaults/:sharedVaultUuid/invites', 'sync.shared-vault-invites.delete-all'],
// Shared Vault Users Controller
['[GET]:shared-vaults/:sharedVaultUuid/users', 'sync.shared-vault-users.get-users'],
['[DELETE]:shared-vaults/:sharedVaultUuid/users/:userUuid', 'sync.shared-vault-users.remove-user'],
])
resolveEndpointOrMethodIdentifier(method: string, endpoint: string, ...params: string[]): string {
@@ -75,7 +102,7 @@ export class EndpointResolver implements EndpointResolverInterface {
const identifier = this.endpointToIdentifierMap.get(`[${method}]:${endpoint}`)
if (!identifier) {
throw new Error(`Endpoint ${endpoint} not found`)
throw new Error(`Endpoint [${method}]:${endpoint} not found`)
}
return identifier

View File

@@ -1,3 +1,4 @@
MODE=microservice # microservice | home-server
LOG_LEVEL=debug
NODE_ENV=development
VERSION=development
@@ -20,8 +21,10 @@ DB_USERNAME=auth
DB_PASSWORD=changeme123
DB_DATABASE=auth
DB_DEBUG_LEVEL=all # "all" | "query" | "schema" | "error" | "warn" | "info" | "log" | "migration"
DB_TYPE=mysql
REDIS_URL=redis://cache
CACHE_TYPE=redis
DISABLE_USER_REGISTRATION=false

View File

@@ -3,6 +3,254 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.134.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.133.0...@standardnotes/auth-server@1.134.0) (2023-08-23)
### Features
* add handling file moving and updating storage quota ([#705](https://github.com/standardnotes/server/issues/705)) ([205a1ed](https://github.com/standardnotes/server/commit/205a1ed637b626be13fc656276508f3c7791024f))
# [1.133.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.132.0...@standardnotes/auth-server@1.133.0) (2023-08-22)
### Features
* consider shared vault owner quota when uploading files to shared vault ([#704](https://github.com/standardnotes/server/issues/704)) ([34085ac](https://github.com/standardnotes/server/commit/34085ac6fb7e61d471bd3b4ae8e72112df25c3ee))
# [1.132.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.131.5...@standardnotes/auth-server@1.132.0) (2023-08-18)
### Features
* add mechanism for determining if a user should use the primary or secondary items database ([#700](https://github.com/standardnotes/server/issues/700)) ([302b624](https://github.com/standardnotes/server/commit/302b624504f4c87fd7c3ddfee77cbdc14a61018b))
## [1.131.5](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.131.4...@standardnotes/auth-server@1.131.5) (2023-08-15)
### Bug Fixes
* **auth:** passing the invalidate cache header ([#697](https://github.com/standardnotes/server/issues/697)) ([83ad069](https://github.com/standardnotes/server/commit/83ad069c5dd9afa3a6db881f0d8a55a58d0642aa))
## [1.131.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.131.3...@standardnotes/auth-server@1.131.4) (2023-08-11)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.131.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.131.2...@standardnotes/auth-server@1.131.3) (2023-08-09)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.131.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.131.1...@standardnotes/auth-server@1.131.2) (2023-08-09)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.131.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.131.0...@standardnotes/auth-server@1.131.1) (2023-08-09)
**Note:** Version bump only for package @standardnotes/auth-server
# [1.131.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.130.1...@standardnotes/auth-server@1.131.0) (2023-08-08)
### Features
* update storage quota used for user based on shared vault files ([#689](https://github.com/standardnotes/server/issues/689)) ([5311e74](https://github.com/standardnotes/server/commit/5311e7426617da6fc75593dd0fcbff589ca4fc22))
## [1.130.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.130.0...@standardnotes/auth-server@1.130.1) (2023-08-07)
### Bug Fixes
* **auth:** update user agent upon refreshing session token ([#685](https://github.com/standardnotes/server/issues/685)) ([bd5f492](https://github.com/standardnotes/server/commit/bd5f492a733f783c64fa4bc5840b4a9f5c913d3d))
# [1.130.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.129.0...@standardnotes/auth-server@1.130.0) (2023-08-07)
### Features
* **auth:** invalidate other sessions for user if the email or password are changed ([#684](https://github.com/standardnotes/server/issues/684)) ([f39d3ac](https://github.com/standardnotes/server/commit/f39d3aca5b7bb9e5f9c1c24cbe2359f30dea835c))
# [1.129.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.128.1...@standardnotes/auth-server@1.129.0) (2023-08-03)
### Features
* **auth:** add handling payments account deleted events STA-1769 ([#682](https://github.com/standardnotes/server/issues/682)) ([8e35dfa](https://github.com/standardnotes/server/commit/8e35dfa4b77256f4c0a3294b296a5526fd1020ad))
## [1.128.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.128.0...@standardnotes/auth-server@1.128.1) (2023-08-02)
**Note:** Version bump only for package @standardnotes/auth-server
# [1.128.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.127.2...@standardnotes/auth-server@1.128.0) (2023-08-02)
### Features
* enable Write Ahead Log mode for SQLite ([#681](https://github.com/standardnotes/server/issues/681)) ([8cd7a13](https://github.com/standardnotes/server/commit/8cd7a138ab56f6a2b0d6c06ef6041ab9b85ae540))
## [1.127.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.127.1...@standardnotes/auth-server@1.127.2) (2023-08-01)
### Bug Fixes
* controller naming ([#678](https://github.com/standardnotes/server/issues/678)) ([56f0aef](https://github.com/standardnotes/server/commit/56f0aef21d3fcec7ac7e968cb1c1b071becbbe26))
## [1.127.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.127.0...@standardnotes/auth-server@1.127.1) (2023-07-31)
### Bug Fixes
* **auth:** auth middleware on delete account ([318af57](https://github.com/standardnotes/server/commit/318af5757d6c42f580157647b22112a9936765e7))
# [1.127.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.126.5...@standardnotes/auth-server@1.127.0) (2023-07-31)
### Features
* refactor deleting account ([#676](https://github.com/standardnotes/server/issues/676)) ([0d5dcdd](https://github.com/standardnotes/server/commit/0d5dcdd8ec2336e41e7604c4157f79a89163ed29))
## [1.126.5](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.126.4...@standardnotes/auth-server@1.126.5) (2023-07-27)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.126.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.126.3...@standardnotes/auth-server@1.126.4) (2023-07-26)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.126.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.126.2...@standardnotes/auth-server@1.126.3) (2023-07-26)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.126.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.126.1...@standardnotes/auth-server@1.126.2) (2023-07-21)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.126.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.126.0...@standardnotes/auth-server@1.126.1) (2023-07-21)
**Note:** Version bump only for package @standardnotes/auth-server
# [1.126.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.125.1...@standardnotes/auth-server@1.126.0) (2023-07-20)
### Features
* **syncing-server:** add shared vaults, invites, messages and notifications to sync response ([#665](https://github.com/standardnotes/server/issues/665)) ([efa4d7f](https://github.com/standardnotes/server/commit/efa4d7fc6007ef668e3de3b04853ac11b2d13c30))
## [1.125.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.125.0...@standardnotes/auth-server@1.125.1) (2023-07-19)
**Note:** Version bump only for package @standardnotes/auth-server
# [1.125.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.124.2...@standardnotes/auth-server@1.125.0) (2023-07-17)
### Features
* **syncing-server:** refactor syncing to decouple getting and saving items ([#659](https://github.com/standardnotes/server/issues/659)) ([cb74b23](https://github.com/standardnotes/server/commit/cb74b23e45b207136e299ce8a3db2c04dc87e21e))
## [1.124.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.124.1...@standardnotes/auth-server@1.124.2) (2023-07-14)
### Bug Fixes
* **home-server:** allow custom atributtes for activating premium features ([f7190c0](https://github.com/standardnotes/server/commit/f7190c0c9c2d105f97d1cf980ce6a4f0dae34805))
## [1.124.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.124.0...@standardnotes/auth-server@1.124.1) (2023-07-13)
### Bug Fixes
* **files:** handling unlimited storage quota on home server ([9be3517](https://github.com/standardnotes/server/commit/9be3517093f8dd7bbdd7507c1e2ff059e6c9a889))
# [1.124.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.123.2...@standardnotes/auth-server@1.124.0) (2023-07-13)
### Features
* **auth:** add overriding subscription settings on home server ([#656](https://github.com/standardnotes/server/issues/656)) ([0b82794](https://github.com/standardnotes/server/commit/0b82794e9c7ed82cfc08a92eafc016fbde5c4fcc))
## [1.123.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.123.1...@standardnotes/auth-server@1.123.2) (2023-07-12)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.123.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.123.0...@standardnotes/auth-server@1.123.1) (2023-07-12)
**Note:** Version bump only for package @standardnotes/auth-server
# [1.123.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.122.2...@standardnotes/auth-server@1.123.0) (2023-07-12)
### Features
* domain items ([#655](https://github.com/standardnotes/server/issues/655)) ([a0af8f0](https://github.com/standardnotes/server/commit/a0af8f00252e1219e58cb7e066c11a8e71692e9d))
## [1.122.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.122.1...@standardnotes/auth-server@1.122.2) (2023-07-07)
### Bug Fixes
* transfer notifications from auth to syncing-server. ([#648](https://github.com/standardnotes/server/issues/648)) ([c288e5d](https://github.com/standardnotes/server/commit/c288e5d8dc54778a96a9fc33e3c9cae00583fade))
## [1.122.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.122.0...@standardnotes/auth-server@1.122.1) (2023-07-06)
**Note:** Version bump only for package @standardnotes/auth-server
# [1.122.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.121.0...@standardnotes/auth-server@1.122.0) (2023-07-05)
### Features
* deleting shared vaults. ([#640](https://github.com/standardnotes/server/issues/640)) ([f3161c2](https://github.com/standardnotes/server/commit/f3161c271296159331639814b2dbb2e566cc54c9))
# [1.121.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.120.2...@standardnotes/auth-server@1.121.0) (2023-07-05)
### Features
* **auth:** add notifications model ([#638](https://github.com/standardnotes/server/issues/638)) ([fecfd54](https://github.com/standardnotes/server/commit/fecfd5472824b5adae708db95d351e4ad65ee87b))
## [1.120.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.120.1...@standardnotes/auth-server@1.120.2) (2023-06-30)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.120.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.120.0...@standardnotes/auth-server@1.120.1) (2023-06-30)
**Note:** Version bump only for package @standardnotes/auth-server
# [1.120.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.119.6...@standardnotes/auth-server@1.120.0) (2023-06-30)
### Features
* shared vaults functionality in api-gateway,auth,files,common,security,domain-events. ([#629](https://github.com/standardnotes/server/issues/629)) ([fa7fbe2](https://github.com/standardnotes/server/commit/fa7fbe26e7b0707fc21d71e04af76870f5248baf))
## [1.119.6](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.119.5...@standardnotes/auth-server@1.119.6) (2023-06-28)
### Bug Fixes
* **auth:** add debug logs for authentication method resolver ([d220ec5](https://github.com/standardnotes/server/commit/d220ec5bf7509f9eb19dcda71c3667aaf388a35b))
## [1.119.5](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.119.4...@standardnotes/auth-server@1.119.5) (2023-06-28)
### Bug Fixes
* add debug logs for invalid-auth responses ([d5a8409](https://github.com/standardnotes/server/commit/d5a8409bb5d35b9caf410a36ea0d5cb747129e8d))
## [1.119.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.119.3...@standardnotes/auth-server@1.119.4) (2023-06-28)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.119.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.119.2...@standardnotes/auth-server@1.119.3) (2023-06-22)
### Bug Fixes
* **home-server:** add debug logs about container initalizations ([0df4715](https://github.com/standardnotes/server/commit/0df471585fd5b4626ec2972f3b9a3e33b2830e65))
## [1.119.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.119.1...@standardnotes/auth-server@1.119.2) (2023-06-14)
### Bug Fixes
* **home-server:** env var determining the sqlite database location ([#626](https://github.com/standardnotes/server/issues/626)) ([0cb5e36](https://github.com/standardnotes/server/commit/0cb5e36b20d9b095ea0edbcd877387e6c0069856))
## [1.119.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.119.0...@standardnotes/auth-server@1.119.1) (2023-06-09)
### Bug Fixes
* **home-server:** add default value for valet token ttl ([c201ee4](https://github.com/standardnotes/server/commit/c201ee42a00d9e5402afea2f2c5848a362c1529e))
# [1.119.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.118.0...@standardnotes/auth-server@1.119.0) (2023-06-09)
### Features
* **home-server:** add activating premium features ([#624](https://github.com/standardnotes/server/issues/624)) ([72ce190](https://github.com/standardnotes/server/commit/72ce1909960fbd2ec6a47b8dbdfbe53a4f10e776))
# [1.118.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.117.0...@standardnotes/auth-server@1.118.0) (2023-06-07)
### Features
* configurable path for uploads and db ([#623](https://github.com/standardnotes/server/issues/623)) ([af8feaa](https://github.com/standardnotes/server/commit/af8feaadfe2dd58baab4cca217d6307b4a221326))
# [1.117.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.116.2...@standardnotes/auth-server@1.117.0) (2023-06-05)
### Features
* **home-server:** allow running the home server with a mysql and redis configuration ([#622](https://github.com/standardnotes/server/issues/622)) ([d6e531d](https://github.com/standardnotes/server/commit/d6e531d4b6c1c80a894f6d7ec93632595268dd64))
## [1.116.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.116.1...@standardnotes/auth-server@1.116.2) (2023-06-02)
### Bug Fixes

View File

@@ -1,23 +1,23 @@
import 'reflect-metadata'
import '../src/Infra/InversifyExpressUtils/InversifyExpressAuthController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressAuthenticatorsController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressSessionsController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressSubscriptionInvitesController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressUserRequestsController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressWebSocketsController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressUsersController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressValetTokenController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressAdminController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressSubscriptionTokensController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressSubscriptionSettingsController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressSettingsController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressSessionController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressOfflineController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressListedController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressInternalController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressHealthCheckController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressFeaturesController'
import '../src/Infra/InversifyExpressUtils/AnnotatedAuthController'
import '../src/Infra/InversifyExpressUtils/AnnotatedAuthenticatorsController'
import '../src/Infra/InversifyExpressUtils/AnnotatedSessionsController'
import '../src/Infra/InversifyExpressUtils/AnnotatedSubscriptionInvitesController'
import '../src/Infra/InversifyExpressUtils/AnnotatedUserRequestsController'
import '../src/Infra/InversifyExpressUtils/AnnotatedWebSocketsController'
import '../src/Infra/InversifyExpressUtils/AnnotatedUsersController'
import '../src/Infra/InversifyExpressUtils/AnnotatedValetTokenController'
import '../src/Infra/InversifyExpressUtils/AnnotatedAdminController'
import '../src/Infra/InversifyExpressUtils/AnnotatedSubscriptionTokensController'
import '../src/Infra/InversifyExpressUtils/AnnotatedSubscriptionSettingsController'
import '../src/Infra/InversifyExpressUtils/AnnotatedSettingsController'
import '../src/Infra/InversifyExpressUtils/AnnotatedSessionController'
import '../src/Infra/InversifyExpressUtils/AnnotatedOfflineController'
import '../src/Infra/InversifyExpressUtils/AnnotatedListedController'
import '../src/Infra/InversifyExpressUtils/AnnotatedInternalController'
import '../src/Infra/InversifyExpressUtils/AnnotatedHealthCheckController'
import '../src/Infra/InversifyExpressUtils/AnnotatedFeaturesController'
import * as cors from 'cors'
import { urlencoded, json, Request, Response, NextFunction } from 'express'

Binary file not shown.

View File

@@ -0,0 +1,13 @@
import { MigrationInterface, QueryRunner } from 'typeorm'
export class AddTransitionRole1692348191367 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
'INSERT INTO `roles` (uuid, name, version) VALUES ("e7381dc5-3d67-49e9-b7bd-f2407b2f726e", "TRANSITION_USER", 1)',
)
}
public async down(): Promise<void> {
return
}
}

View File

@@ -0,0 +1,13 @@
import { MigrationInterface, QueryRunner } from 'typeorm'
export class AddTransitionRole1692348280258 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
'INSERT INTO `roles` (uuid, name, version) VALUES ("e7381dc5-3d67-49e9-b7bd-f2407b2f726e", "TRANSITION_USER", 1)',
)
}
public async down(): Promise<void> {
return
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/auth-server",
"version": "1.116.2",
"version": "1.134.0",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
@@ -32,7 +32,8 @@
"weekly-backup:email": "yarn node dist/bin/backup.js email weekly",
"content-recalculation": "yarn node dist/bin/content.js",
"typeorm": "typeorm-ts-node-commonjs",
"upgrade:snjs": "yarn ncu -u '@standardnotes/*'"
"upgrade:snjs": "yarn ncu -u '@standardnotes/*'",
"migrate": "yarn build && yarn typeorm migration:run -d dist/src/Bootstrap/DataSource.js"
},
"dependencies": {
"@aws-sdk/client-sns": "^3.332.0",
@@ -41,17 +42,17 @@
"@cbor-extract/cbor-extract-linux-x64": "^2.1.1",
"@simplewebauthn/server": "^7.2.0",
"@simplewebauthn/typescript-types": "^7.0.0",
"@standardnotes/api": "^1.25.3",
"@standardnotes/api": "^1.26.26",
"@standardnotes/common": "workspace:*",
"@standardnotes/domain-core": "workspace:^",
"@standardnotes/domain-events": "workspace:*",
"@standardnotes/domain-events-infra": "workspace:*",
"@standardnotes/features": "^1.58.12",
"@standardnotes/features": "^1.59.7",
"@standardnotes/predicates": "workspace:*",
"@standardnotes/responses": "^1.13.9",
"@standardnotes/responses": "^1.13.27",
"@standardnotes/security": "workspace:*",
"@standardnotes/settings": "workspace:*",
"@standardnotes/sncrypto-common": "^1.9.0",
"@standardnotes/sncrypto-common": "^1.13.4",
"@standardnotes/sncrypto-node": "workspace:*",
"@standardnotes/time": "workspace:*",
"axios": "^1.1.3",

View File

@@ -0,0 +1,9 @@
import { Result, ServiceInterface } from '@standardnotes/domain-core'
export interface AuthServiceInterface extends ServiceInterface {
activatePremiumFeatures(dto: {
username: string
subscriptionPlanName?: string
endsAt?: Date
}): Promise<Result<string>>
}

View File

@@ -38,7 +38,7 @@ import { GetUserKeyParams } from '../Domain/UseCase/GetUserKeyParams/GetUserKeyP
import { UpdateUser } from '../Domain/UseCase/UpdateUser'
import { RedisEphemeralSessionRepository } from '../Infra/Redis/RedisEphemeralSessionRepository'
import { GetActiveSessionsForUser } from '../Domain/UseCase/GetActiveSessionsForUser'
import { DeletePreviousSessionsForUser } from '../Domain/UseCase/DeletePreviousSessionsForUser'
import { DeleteOtherSessionsForUser } from '../Domain/UseCase/DeleteOtherSessionsForUser'
import { DeleteSessionForUser } from '../Domain/UseCase/DeleteSessionForUser'
import { Register } from '../Domain/UseCase/Register'
import { LockRepository } from '../Infra/Redis/LockRepository'
@@ -234,23 +234,29 @@ import { OfflineUserAuthMiddleware } from '../Infra/InversifyExpressUtils/Middle
import { LockMiddleware } from '../Infra/InversifyExpressUtils/Middleware/LockMiddleware'
import { RequiredCrossServiceTokenMiddleware } from '../Infra/InversifyExpressUtils/Middleware/RequiredCrossServiceTokenMiddleware'
import { OptionalCrossServiceTokenMiddleware } from '../Infra/InversifyExpressUtils/Middleware/OptionalCrossServiceTokenMiddleware'
import { HomeServerSettingsController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerSettingsController'
import { HomeServerAdminController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerAdminController'
import { HomeServerAuthController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerAuthController'
import { HomeServerAuthenticatorsController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerAuthenticatorsController'
import { HomeServerFeaturesController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerFeaturesController'
import { HomeServerListedController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerListedController'
import { HomeServerOfflineController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerOfflineController'
import { HomeServerSessionController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerSessionController'
import { HomeServerSubscriptionInvitesController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerSubscriptionInvitesController'
import { HomeServerSubscriptionSettingsController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerSubscriptionSettingsController'
import { HomeServerSubscriptionTokensController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerSubscriptionTokensController'
import { HomeServerUserRequestsController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerUserRequestsController'
import { HomeServerUsersController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerUsersController'
import { HomeServerValetTokenController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerValetTokenController'
import { HomeServerWebSocketsController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerWebSocketsController'
import { HomeServerSessionsController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerSessionsController'
import { BaseSettingsController } from '../Infra/InversifyExpressUtils/Base/BaseSettingsController'
import { BaseAdminController } from '../Infra/InversifyExpressUtils/Base/BaseAdminController'
import { BaseAuthController } from '../Infra/InversifyExpressUtils/Base/BaseAuthController'
import { BaseAuthenticatorsController } from '../Infra/InversifyExpressUtils/Base/BaseAuthenticatorsController'
import { BaseFeaturesController } from '../Infra/InversifyExpressUtils/Base/BaseFeaturesController'
import { BaseListedController } from '../Infra/InversifyExpressUtils/Base/BaseListedController'
import { BaseOfflineController } from '../Infra/InversifyExpressUtils/Base/BaseOfflineController'
import { BaseSessionController } from '../Infra/InversifyExpressUtils/Base/BaseSessionController'
import { BaseSubscriptionInvitesController } from '../Infra/InversifyExpressUtils/Base/BaseSubscriptionInvitesController'
import { BaseSubscriptionSettingsController } from '../Infra/InversifyExpressUtils/Base/BaseSubscriptionSettingsController'
import { BaseSubscriptionTokensController } from '../Infra/InversifyExpressUtils/Base/BaseSubscriptionTokensController'
import { BaseUserRequestsController } from '../Infra/InversifyExpressUtils/Base/BaseUserRequestsController'
import { BaseUsersController } from '../Infra/InversifyExpressUtils/Base/BaseUsersController'
import { BaseValetTokenController } from '../Infra/InversifyExpressUtils/Base/BaseValetTokenController'
import { BaseWebSocketsController } from '../Infra/InversifyExpressUtils/Base/BaseWebSocketsController'
import { BaseSessionsController } from '../Infra/InversifyExpressUtils/Base/BaseSessionsController'
import { Transform } from 'stream'
import { ActivatePremiumFeatures } from '../Domain/UseCase/ActivatePremiumFeatures/ActivatePremiumFeatures'
import { PaymentsAccountDeletedEventHandler } from '../Domain/Handler/PaymentsAccountDeletedEventHandler'
import { UpdateStorageQuotaUsedForUser } from '../Domain/UseCase/UpdateStorageQuotaUsedForUser/UpdateStorageQuotaUsedForUser'
import { SharedVaultFileUploadedEventHandler } from '../Domain/Handler/SharedVaultFileUploadedEventHandler'
import { SharedVaultFileRemovedEventHandler } from '../Domain/Handler/SharedVaultFileRemovedEventHandler'
import { SharedVaultFileMovedEventHandler } from '../Domain/Handler/SharedVaultFileMovedEventHandler'
export class ContainerConfigLoader {
async load(configuration?: {
@@ -267,12 +273,37 @@ export class ContainerConfigLoader {
const container = new Container()
const winstonFormatters = [winston.format.splat(), winston.format.json()]
if (env.get('NEW_RELIC_ENABLED', true) === 'true') {
await import('newrelic')
// eslint-disable-next-line @typescript-eslint/no-var-requires
const newrelicFormatter = require('@newrelic/winston-enricher')
const newrelicWinstonFormatter = newrelicFormatter(winston)
winstonFormatters.push(newrelicWinstonFormatter())
}
let logger: winston.Logger
if (configuration?.logger) {
logger = configuration.logger as winston.Logger
} else {
logger = winston.createLogger({
level: env.get('LOG_LEVEL', true) || 'info',
format: winston.format.combine(...winstonFormatters),
transports: [new winston.transports.Console({ level: env.get('LOG_LEVEL', true) || 'info' })],
defaultMeta: { service: 'auth' },
})
}
container.bind<winston.Logger>(TYPES.Auth_Logger).toConstantValue(logger)
const appDataSource = new AppDataSource(env)
await appDataSource.initialize()
const isConfiguredForHomeServer = env.get('DB_TYPE') === 'sqlite'
logger.debug('Database initialized')
if (!isConfiguredForHomeServer) {
const isConfiguredForHomeServer = env.get('MODE', true) === 'home-server'
const isConfiguredForInMemoryCache = env.get('CACHE_TYPE', true) === 'memory'
if (!isConfiguredForInMemoryCache) {
const redisUrl = env.get('REDIS_URL')
const isRedisInClusterMode = redisUrl.indexOf(',') > 0
let redis
@@ -285,27 +316,6 @@ export class ContainerConfigLoader {
container.bind(TYPES.Auth_Redis).toConstantValue(redis)
}
const winstonFormatters = [winston.format.splat(), winston.format.json()]
if (env.get('NEW_RELIC_ENABLED', true) === 'true') {
await import('newrelic')
// eslint-disable-next-line @typescript-eslint/no-var-requires
const newrelicFormatter = require('@newrelic/winston-enricher')
const newrelicWinstonFormatter = newrelicFormatter(winston)
winstonFormatters.push(newrelicWinstonFormatter())
}
if (configuration?.logger) {
container.bind<winston.Logger>(TYPES.Auth_Logger).toConstantValue(configuration.logger as winston.Logger)
} else {
const logger = winston.createLogger({
level: env.get('LOG_LEVEL', true) || 'info',
format: winston.format.combine(...winstonFormatters),
transports: [new winston.transports.Console({ level: env.get('LOG_LEVEL', true) || 'info' })],
defaultMeta: { service: 'auth' },
})
container.bind<winston.Logger>(TYPES.Auth_Logger).toConstantValue(logger)
}
container.bind<TimerInterface>(TYPES.Auth_Timer).toConstantValue(new Timer())
if (!isConfiguredForHomeServer) {
@@ -488,7 +498,9 @@ export class ContainerConfigLoader {
.bind(TYPES.Auth_AUTH_JWT_TTL)
.toConstantValue(env.get('AUTH_JWT_TTL', true) ? +env.get('AUTH_JWT_TTL') : 60_000)
container.bind(TYPES.Auth_VALET_TOKEN_SECRET).toConstantValue(env.get('VALET_TOKEN_SECRET', true))
container.bind(TYPES.Auth_VALET_TOKEN_TTL).toConstantValue(+env.get('VALET_TOKEN_TTL', true))
container
.bind(TYPES.Auth_VALET_TOKEN_TTL)
.toConstantValue(env.get('VALET_TOKEN_TTL', true) ? +env.get('VALET_TOKEN_TTL', true) : 7200)
container
.bind(TYPES.Auth_WEB_SOCKET_CONNECTION_TOKEN_SECRET)
.toConstantValue(env.get('WEB_SOCKET_CONNECTION_TOKEN_SECRET', true))
@@ -549,8 +561,20 @@ 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 (isConfiguredForHomeServer) {
if (isConfiguredForInMemoryCache) {
container
.bind<PKCERepositoryInterface>(TYPES.Auth_PKCERepository)
.toConstantValue(
new TypeORMPKCERepository(
container.get(TYPES.Auth_CacheEntryRepository),
container.get(TYPES.Auth_Logger),
container.get(TYPES.Auth_Timer),
),
)
container
.bind<LockRepositoryInterface>(TYPES.Auth_LockRepository)
.toConstantValue(
@@ -578,15 +602,6 @@ export class ContainerConfigLoader {
container.get(TYPES.Auth_Timer),
),
)
container
.bind<PKCERepositoryInterface>(TYPES.Auth_PKCERepository)
.toConstantValue(
new TypeORMPKCERepository(
container.get(TYPES.Auth_CacheEntryRepository),
container.get(TYPES.Auth_Logger),
container.get(TYPES.Auth_Timer),
),
)
container
.bind<SubscriptionTokenRepositoryInterface>(TYPES.Auth_SubscriptionTokenRepository)
.toConstantValue(
@@ -780,6 +795,17 @@ export class ContainerConfigLoader {
container.get(TYPES.Auth_CryptoNode),
),
)
container
.bind<ActivatePremiumFeatures>(TYPES.Auth_ActivatePremiumFeatures)
.toConstantValue(
new ActivatePremiumFeatures(
container.get(TYPES.Auth_UserRepository),
container.get(TYPES.Auth_UserSubscriptionRepository),
container.get(TYPES.Auth_SubscriptionSettingService),
container.get(TYPES.Auth_RoleService),
container.get(TYPES.Auth_Timer),
),
)
container
.bind<CleanupSessionTraces>(TYPES.Auth_CleanupSessionTraces)
@@ -808,9 +834,7 @@ export class ContainerConfigLoader {
container.bind<UpdateUser>(TYPES.Auth_UpdateUser).to(UpdateUser)
container.bind<Register>(TYPES.Auth_Register).to(Register)
container.bind<GetActiveSessionsForUser>(TYPES.Auth_GetActiveSessionsForUser).to(GetActiveSessionsForUser)
container
.bind<DeletePreviousSessionsForUser>(TYPES.Auth_DeletePreviousSessionsForUser)
.to(DeletePreviousSessionsForUser)
container.bind<DeleteOtherSessionsForUser>(TYPES.Auth_DeleteOtherSessionsForUser).to(DeleteOtherSessionsForUser)
container.bind<DeleteSessionForUser>(TYPES.Auth_DeleteSessionForUser).to(DeleteSessionForUser)
container.bind<ChangeCredentials>(TYPES.Auth_ChangeCredentials).to(ChangeCredentials)
container.bind<GetSettings>(TYPES.Auth_GetSettings).to(GetSettings)
@@ -865,6 +889,15 @@ export class ContainerConfigLoader {
container.bind<VerifyPredicate>(TYPES.Auth_VerifyPredicate).to(VerifyPredicate)
container.bind<CreateCrossServiceToken>(TYPES.Auth_CreateCrossServiceToken).to(CreateCrossServiceToken)
container.bind<ProcessUserRequest>(TYPES.Auth_ProcessUserRequest).to(ProcessUserRequest)
container
.bind<UpdateStorageQuotaUsedForUser>(TYPES.Auth_UpdateStorageQuotaUsedForUser)
.toConstantValue(
new UpdateStorageQuotaUsedForUser(
container.get(TYPES.Auth_UserRepository),
container.get(TYPES.Auth_UserSubscriptionService),
container.get(TYPES.Auth_SubscriptionSettingService),
),
)
// Controller
container
@@ -934,8 +967,46 @@ export class ContainerConfigLoader {
container
.bind<UserEmailChangedEventHandler>(TYPES.Auth_UserEmailChangedEventHandler)
.to(UserEmailChangedEventHandler)
container.bind<FileUploadedEventHandler>(TYPES.Auth_FileUploadedEventHandler).to(FileUploadedEventHandler)
container.bind<FileRemovedEventHandler>(TYPES.Auth_FileRemovedEventHandler).to(FileRemovedEventHandler)
container
.bind<FileUploadedEventHandler>(TYPES.Auth_FileUploadedEventHandler)
.toConstantValue(
new FileUploadedEventHandler(
container.get(TYPES.Auth_UpdateStorageQuotaUsedForUser),
container.get(TYPES.Auth_Logger),
),
)
container
.bind<SharedVaultFileUploadedEventHandler>(TYPES.Auth_SharedVaultFileUploadedEventHandler)
.toConstantValue(
new SharedVaultFileUploadedEventHandler(
container.get(TYPES.Auth_UpdateStorageQuotaUsedForUser),
container.get(TYPES.Auth_Logger),
),
)
container
.bind<SharedVaultFileMovedEventHandler>(TYPES.Auth_SharedVaultFileMovedEventHandler)
.toConstantValue(
new SharedVaultFileMovedEventHandler(
container.get(TYPES.Auth_UpdateStorageQuotaUsedForUser),
container.get(TYPES.Auth_Logger),
),
)
container
.bind<FileRemovedEventHandler>(TYPES.Auth_FileRemovedEventHandler)
.toConstantValue(
new FileRemovedEventHandler(
container.get(TYPES.Auth_UpdateStorageQuotaUsedForUser),
container.get(TYPES.Auth_Logger),
),
)
container
.bind<SharedVaultFileRemovedEventHandler>(TYPES.Auth_SharedVaultFileRemovedEventHandler)
.toConstantValue(
new SharedVaultFileRemovedEventHandler(
container.get(TYPES.Auth_UpdateStorageQuotaUsedForUser),
container.get(TYPES.Auth_Logger),
),
)
container
.bind<ListedAccountCreatedEventHandler>(TYPES.Auth_ListedAccountCreatedEventHandler)
.to(ListedAccountCreatedEventHandler)
@@ -960,6 +1031,14 @@ export class ContainerConfigLoader {
container.get(TYPES.Auth_SettingService),
),
)
container
.bind<PaymentsAccountDeletedEventHandler>(TYPES.Auth_PaymentsAccountDeletedEventHandler)
.toConstantValue(
new PaymentsAccountDeletedEventHandler(
container.get(TYPES.Auth_DeleteAccount),
container.get(TYPES.Auth_Logger),
),
)
const eventHandlers: Map<string, DomainEventHandlerInterface> = new Map([
['USER_REGISTERED', container.get(TYPES.Auth_UserRegisteredEventHandler)],
@@ -974,7 +1053,10 @@ export class ContainerConfigLoader {
['SUBSCRIPTION_REASSIGNED', container.get(TYPES.Auth_SubscriptionReassignedEventHandler)],
['USER_EMAIL_CHANGED', container.get(TYPES.Auth_UserEmailChangedEventHandler)],
['FILE_UPLOADED', container.get(TYPES.Auth_FileUploadedEventHandler)],
['SHARED_VAULT_FILE_UPLOADED', container.get(TYPES.Auth_SharedVaultFileUploadedEventHandler)],
['SHARED_VAULT_FILE_MOVED', container.get(TYPES.Auth_SharedVaultFileMovedEventHandler)],
['FILE_REMOVED', container.get(TYPES.Auth_FileRemovedEventHandler)],
['SHARED_VAULT_FILE_REMOVED', container.get(TYPES.Auth_SharedVaultFileRemovedEventHandler)],
['LISTED_ACCOUNT_CREATED', container.get(TYPES.Auth_ListedAccountCreatedEventHandler)],
['LISTED_ACCOUNT_DELETED', container.get(TYPES.Auth_ListedAccountDeletedEventHandler)],
[
@@ -987,6 +1069,7 @@ export class ContainerConfigLoader {
],
['PREDICATE_VERIFICATION_REQUESTED', container.get(TYPES.Auth_PredicateVerificationRequestedEventHandler)],
['EMAIL_SUBSCRIPTION_UNSUBSCRIBED', container.get(TYPES.Auth_EmailSubscriptionUnsubscribedEventHandler)],
['PAYMENTS_ACCOUNT_DELETED', container.get(TYPES.Auth_PaymentsAccountDeletedEventHandler)],
])
if (isConfiguredForHomeServer) {
@@ -1019,9 +1102,9 @@ export class ContainerConfigLoader {
}
container
.bind<HomeServerAuthController>(TYPES.Auth_HomeServerAuthController)
.bind<BaseAuthController>(TYPES.Auth_BaseAuthController)
.toConstantValue(
new HomeServerAuthController(
new BaseAuthController(
container.get(TYPES.Auth_VerifyMFA),
container.get(TYPES.Auth_SignIn),
container.get(TYPES.Auth_GetUserKeyParams),
@@ -1036,42 +1119,42 @@ export class ContainerConfigLoader {
// Inversify Controllers
if (isConfiguredForHomeServer) {
container
.bind<HomeServerAuthenticatorsController>(TYPES.Auth_HomeServerAuthenticatorsController)
.bind<BaseAuthenticatorsController>(TYPES.Auth_BaseAuthenticatorsController)
.toConstantValue(
new HomeServerAuthenticatorsController(
new BaseAuthenticatorsController(
container.get(TYPES.Auth_AuthenticatorsController),
container.get(TYPES.Auth_ControllerContainer),
),
)
container
.bind<HomeServerSubscriptionInvitesController>(TYPES.Auth_HomeServerSubscriptionInvitesController)
.bind<BaseSubscriptionInvitesController>(TYPES.Auth_BaseSubscriptionInvitesController)
.toConstantValue(
new HomeServerSubscriptionInvitesController(
new BaseSubscriptionInvitesController(
container.get(TYPES.Auth_SubscriptionInvitesController),
container.get(TYPES.Auth_ControllerContainer),
),
)
container
.bind<HomeServerUserRequestsController>(TYPES.Auth_HomeServerUserRequestsController)
.bind<BaseUserRequestsController>(TYPES.Auth_BaseUserRequestsController)
.toConstantValue(
new HomeServerUserRequestsController(
new BaseUserRequestsController(
container.get(TYPES.Auth_UserRequestsController),
container.get(TYPES.Auth_ControllerContainer),
),
)
container
.bind<HomeServerWebSocketsController>(TYPES.Auth_HomeServerWebSocketsController)
.bind<BaseWebSocketsController>(TYPES.Auth_BaseWebSocketsController)
.toConstantValue(
new HomeServerWebSocketsController(
new BaseWebSocketsController(
container.get(TYPES.Auth_CreateCrossServiceToken),
container.get(TYPES.Auth_WebSocketConnectionTokenDecoder),
container.get(TYPES.Auth_ControllerContainer),
),
)
container
.bind<HomeServerSessionsController>(TYPES.Auth_HomeServerSessionsController)
.bind<BaseSessionsController>(TYPES.Auth_BaseSessionsController)
.toConstantValue(
new HomeServerSessionsController(
new BaseSessionsController(
container.get(TYPES.Auth_GetActiveSessionsForUser),
container.get(TYPES.Auth_AuthenticateRequest),
container.get(TYPES.Auth_SessionProjector),
@@ -1080,17 +1163,17 @@ export class ContainerConfigLoader {
),
)
container
.bind<HomeServerValetTokenController>(TYPES.Auth_HomeServerValetTokenController)
.bind<BaseValetTokenController>(TYPES.Auth_BaseValetTokenController)
.toConstantValue(
new HomeServerValetTokenController(
new BaseValetTokenController(
container.get(TYPES.Auth_CreateValetToken),
container.get(TYPES.Auth_ControllerContainer),
),
)
container
.bind<HomeServerUsersController>(TYPES.Auth_HomeServerUsersController)
.bind<BaseUsersController>(TYPES.Auth_BaseUsersController)
.toConstantValue(
new HomeServerUsersController(
new BaseUsersController(
container.get(TYPES.Auth_UpdateUser),
container.get(TYPES.Auth_GetUserKeyParams),
container.get(TYPES.Auth_DeleteAccount),
@@ -1102,9 +1185,9 @@ export class ContainerConfigLoader {
),
)
container
.bind<HomeServerAdminController>(TYPES.Auth_HomeServerAdminController)
.bind<BaseAdminController>(TYPES.Auth_BaseAdminController)
.toConstantValue(
new HomeServerAdminController(
new BaseAdminController(
container.get(TYPES.Auth_DeleteSetting),
container.get(TYPES.Auth_UserRepository),
container.get(TYPES.Auth_CreateSubscriptionToken),
@@ -1113,9 +1196,9 @@ export class ContainerConfigLoader {
),
)
container
.bind<HomeServerSubscriptionTokensController>(TYPES.Auth_HomeServerSubscriptionTokensController)
.bind<BaseSubscriptionTokensController>(TYPES.Auth_BaseSubscriptionTokensController)
.toConstantValue(
new HomeServerSubscriptionTokensController(
new BaseSubscriptionTokensController(
container.get(TYPES.Auth_CreateSubscriptionToken),
container.get(TYPES.Auth_AuthenticateSubscriptionToken),
container.get(TYPES.Auth_SettingService),
@@ -1127,17 +1210,17 @@ export class ContainerConfigLoader {
),
)
container
.bind<HomeServerSubscriptionSettingsController>(TYPES.Auth_HomeServerSubscriptionSettingsController)
.bind<BaseSubscriptionSettingsController>(TYPES.Auth_BaseSubscriptionSettingsController)
.toConstantValue(
new HomeServerSubscriptionSettingsController(
new BaseSubscriptionSettingsController(
container.get(TYPES.Auth_GetSetting),
container.get(TYPES.Auth_ControllerContainer),
),
)
container
.bind<HomeServerSettingsController>(TYPES.Auth_HomeServerSettingsController)
.bind<BaseSettingsController>(TYPES.Auth_BaseSettingsController)
.toConstantValue(
new HomeServerSettingsController(
new BaseSettingsController(
container.get(TYPES.Auth_GetSettings),
container.get(TYPES.Auth_GetSetting),
container.get(TYPES.Auth_UpdateSetting),
@@ -1146,19 +1229,19 @@ export class ContainerConfigLoader {
),
)
container
.bind<HomeServerSessionController>(TYPES.Auth_HomeServerSessionController)
.bind<BaseSessionController>(TYPES.Auth_BaseSessionController)
.toConstantValue(
new HomeServerSessionController(
new BaseSessionController(
container.get(TYPES.Auth_DeleteSessionForUser),
container.get(TYPES.Auth_DeletePreviousSessionsForUser),
container.get(TYPES.Auth_DeleteOtherSessionsForUser),
container.get(TYPES.Auth_RefreshSessionToken),
container.get(TYPES.Auth_ControllerContainer),
),
)
container
.bind<HomeServerOfflineController>(TYPES.Auth_HomeServerOfflineController)
.bind<BaseOfflineController>(TYPES.Auth_BaseOfflineController)
.toConstantValue(
new HomeServerOfflineController(
new BaseOfflineController(
container.get(TYPES.Auth_GetUserFeatures),
container.get(TYPES.Auth_GetUserOfflineSubscription),
container.get(TYPES.Auth_CreateOfflineSubscriptionToken),
@@ -1170,23 +1253,25 @@ export class ContainerConfigLoader {
),
)
container
.bind<HomeServerListedController>(TYPES.Auth_HomeServerListedController)
.bind<BaseListedController>(TYPES.Auth_BaseListedController)
.toConstantValue(
new HomeServerListedController(
new BaseListedController(
container.get(TYPES.Auth_CreateListedAccount),
container.get(TYPES.Auth_ControllerContainer),
),
)
container
.bind<HomeServerFeaturesController>(TYPES.Auth_HomeServerFeaturesController)
.bind<BaseFeaturesController>(TYPES.Auth_BaseFeaturesController)
.toConstantValue(
new HomeServerFeaturesController(
new BaseFeaturesController(
container.get(TYPES.Auth_GetUserFeatures),
container.get(TYPES.Auth_ControllerContainer),
),
)
}
logger.debug('Configuration complete')
return container
}
}

View File

@@ -20,19 +20,23 @@ import { Env } from './Env'
import { SqliteConnectionOptions } from 'typeorm/driver/sqlite/SqliteConnectionOptions'
export class AppDataSource {
private dataSource: DataSource | undefined
private _dataSource: DataSource | undefined
constructor(private env: Env) {}
getRepository<Entity extends ObjectLiteral>(target: EntityTarget<Entity>): Repository<Entity> {
if (!this.dataSource) {
if (!this._dataSource) {
throw new Error('DataSource not initialized')
}
return this.dataSource.getRepository(target)
return this._dataSource.getRepository(target)
}
async initialize(): Promise<void> {
await this.dataSource.initialize()
}
get dataSource(): DataSource {
this.env.load()
const isConfiguredForMySQL = this.env.get('DB_TYPE') === 'mysql'
@@ -104,17 +108,19 @@ export class AppDataSource {
database: inReplicaMode ? undefined : this.env.get('DB_DATABASE'),
}
this.dataSource = new DataSource(mySQLDataSourceOptions)
this._dataSource = new DataSource(mySQLDataSourceOptions)
} else {
const sqliteDataSourceOptions: SqliteConnectionOptions = {
...commonDataSourceOptions,
type: 'sqlite',
database: `data/${this.env.get('DB_DATABASE')}.sqlite`,
database: this.env.get('DB_SQLITE_DATABASE_PATH'),
enableWAL: true,
busyErrorRetry: 2000,
}
this.dataSource = new DataSource(sqliteDataSourceOptions)
this._dataSource = new DataSource(sqliteDataSourceOptions)
}
await this.dataSource.initialize()
return this._dataSource
}
}

View File

@@ -0,0 +1,7 @@
import { AppDataSource } from './DataSource'
import { Env } from './Env'
const env: Env = new Env()
env.load()
export const MigrationsDataSource = new AppDataSource(env).dataSource

View File

@@ -1,15 +1,21 @@
import {
ControllerContainerInterface,
Result,
ServiceConfiguration,
ServiceContainerInterface,
ServiceIdentifier,
ServiceInterface,
} from '@standardnotes/domain-core'
import { ContainerConfigLoader } from './Container'
import { DirectCallDomainEventPublisher } from '@standardnotes/domain-events-infra'
import TYPES from './Types'
import { Container } from 'inversify'
import { ActivatePremiumFeatures } from '../Domain/UseCase/ActivatePremiumFeatures/ActivatePremiumFeatures'
import { AuthServiceInterface } from './AuthServiceInterface'
export class Service implements AuthServiceInterface {
private container: Container | undefined
export class Service implements ServiceInterface {
constructor(
private serviceContainer: ServiceContainerInterface,
private controllerContainer: ControllerContainerInterface,
@@ -18,6 +24,21 @@ export class Service implements ServiceInterface {
this.serviceContainer.register(this.getId(), this)
}
async activatePremiumFeatures(dto: {
username: string
subscriptionPlanName?: string
uploadBytesLimit?: number
endsAt?: Date
}): Promise<Result<string>> {
if (!this.container) {
return Result.fail('Container not initialized')
}
const activatePremiumFeatures = this.container.get(TYPES.Auth_ActivatePremiumFeatures) as ActivatePremiumFeatures
return activatePremiumFeatures.execute(dto)
}
async handleRequest(request: never, response: never, endpointOrMethodIdentifier: string): Promise<unknown> {
const method = this.controllerContainer.get(endpointOrMethodIdentifier)
@@ -31,12 +52,16 @@ export class Service implements ServiceInterface {
async getContainer(configuration?: ServiceConfiguration): Promise<unknown> {
const config = new ContainerConfigLoader()
return config.load({
const container = await config.load({
controllerConatiner: this.controllerContainer,
directCallDomainEventPublisher: this.directCallDomainEventPublisher,
logger: configuration?.logger,
environmentOverrides: configuration?.environmentOverrides,
})
this.container = container
return container
}
getId(): ServiceIdentifier {

View File

@@ -101,6 +101,7 @@ 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'),
@@ -113,7 +114,7 @@ const TYPES = {
Auth_UpdateUser: Symbol.for('Auth_UpdateUser'),
Auth_Register: Symbol.for('Auth_Register'),
Auth_GetActiveSessionsForUser: Symbol.for('Auth_GetActiveSessionsForUser'),
Auth_DeletePreviousSessionsForUser: Symbol.for('Auth_DeletePreviousSessionsForUser'),
Auth_DeleteOtherSessionsForUser: Symbol.for('Auth_DeleteOtherSessionsForUser'),
Auth_DeleteSessionForUser: Symbol.for('Auth_DeleteSessionForUser'),
Auth_ChangeCredentials: Symbol.for('Auth_ChangePassword'),
Auth_GetSettings: Symbol.for('Auth_GetSettings'),
@@ -149,8 +150,10 @@ const TYPES = {
Auth_ListAuthenticators: Symbol.for('Auth_ListAuthenticators'),
Auth_DeleteAuthenticator: Symbol.for('Auth_DeleteAuthenticator'),
Auth_GenerateRecoveryCodes: Symbol.for('Auth_GenerateRecoveryCodes'),
Auth_ActivatePremiumFeatures: Symbol.for('Auth_ActivatePremiumFeatures'),
Auth_SignInWithRecoveryCodes: Symbol.for('Auth_SignInWithRecoveryCodes'),
Auth_GetUserKeyParamsRecovery: Symbol.for('Auth_GetUserKeyParamsRecovery'),
Auth_UpdateStorageQuotaUsedForUser: Symbol.for('Auth_UpdateStorageQuotaUsedForUser'),
// Handlers
Auth_UserRegisteredEventHandler: Symbol.for('Auth_UserRegisteredEventHandler'),
Auth_AccountDeletionRequestedEventHandler: Symbol.for('Auth_AccountDeletionRequestedEventHandler'),
@@ -164,7 +167,10 @@ const TYPES = {
Auth_ExtensionKeyGrantedEventHandler: Symbol.for('Auth_ExtensionKeyGrantedEventHandler'),
Auth_UserEmailChangedEventHandler: Symbol.for('Auth_UserEmailChangedEventHandler'),
Auth_FileUploadedEventHandler: Symbol.for('Auth_FileUploadedEventHandler'),
Auth_SharedVaultFileUploadedEventHandler: Symbol.for('Auth_SharedVaultFileUploadedEventHandler'),
Auth_SharedVaultFileMovedEventHandler: Symbol.for('Auth_SharedVaultFileMovedEventHandler'),
Auth_FileRemovedEventHandler: Symbol.for('Auth_FileRemovedEventHandler'),
Auth_SharedVaultFileRemovedEventHandler: Symbol.for('Auth_SharedVaultFileRemovedEventHandler'),
Auth_ListedAccountCreatedEventHandler: Symbol.for('Auth_ListedAccountCreatedEventHandler'),
Auth_ListedAccountDeletedEventHandler: Symbol.for('Auth_ListedAccountDeletedEventHandler'),
Auth_UserDisabledSessionUserAgentLoggingEventHandler: Symbol.for(
@@ -175,6 +181,7 @@ const TYPES = {
),
Auth_PredicateVerificationRequestedEventHandler: Symbol.for('Auth_PredicateVerificationRequestedEventHandler'),
Auth_EmailSubscriptionUnsubscribedEventHandler: Symbol.for('Auth_EmailSubscriptionUnsubscribedEventHandler'),
Auth_PaymentsAccountDeletedEventHandler: Symbol.for('Auth_PaymentsAccountDeletedEventHandler'),
// Services
Auth_DeviceDetector: Symbol.for('Auth_DeviceDetector'),
Auth_SessionService: Symbol.for('Auth_SessionService'),
@@ -216,22 +223,22 @@ const TYPES = {
Auth_ProtocolVersionSelector: Symbol.for('Auth_ProtocolVersionSelector'),
Auth_BooleanSelector: Symbol.for('Auth_BooleanSelector'),
Auth_UserSubscriptionService: Symbol.for('Auth_UserSubscriptionService'),
Auth_HomeServerAuthController: Symbol.for('Auth_HomeServerAuthController'),
Auth_HomeServerAuthenticatorsController: Symbol.for('Auth_HomeServerAuthenticatorsController'),
Auth_HomeServerSubscriptionInvitesController: Symbol.for('Auth_HomeServerSubscriptionInvitesController'),
Auth_HomeServerUserRequestsController: Symbol.for('Auth_HomeServerUserRequestsController'),
Auth_HomeServerWebSocketsController: Symbol.for('Auth_HomeServerWebSocketsController'),
Auth_HomeServerSessionsController: Symbol.for('Auth_HomeServerSessionsController'),
Auth_HomeServerValetTokenController: Symbol.for('Auth_HomeServerValetTokenController'),
Auth_HomeServerUsersController: Symbol.for('Auth_HomeServerUsersController'),
Auth_HomeServerAdminController: Symbol.for('Auth_HomeServerAdminController'),
Auth_HomeServerSubscriptionTokensController: Symbol.for('Auth_HomeServerSubscriptionTokensController'),
Auth_HomeServerSubscriptionSettingsController: Symbol.for('Auth_HomeServerSubscriptionSettingsController'),
Auth_HomeServerSettingsController: Symbol.for('Auth_HomeServerSettingsController'),
Auth_HomeServerSessionController: Symbol.for('Auth_HomeServerSessionController'),
Auth_HomeServerOfflineController: Symbol.for('Auth_HomeServerOfflineController'),
Auth_HomeServerListedController: Symbol.for('Auth_HomeServerListedController'),
Auth_HomeServerFeaturesController: Symbol.for('Auth_HomeServerFeaturesController'),
Auth_BaseAuthController: Symbol.for('Auth_BaseAuthController'),
Auth_BaseAuthenticatorsController: Symbol.for('Auth_BaseAuthenticatorsController'),
Auth_BaseSubscriptionInvitesController: Symbol.for('Auth_BaseSubscriptionInvitesController'),
Auth_BaseUserRequestsController: Symbol.for('Auth_BaseUserRequestsController'),
Auth_BaseWebSocketsController: Symbol.for('Auth_BaseWebSocketsController'),
Auth_BaseSessionsController: Symbol.for('Auth_BaseSessionsController'),
Auth_BaseValetTokenController: Symbol.for('Auth_BaseValetTokenController'),
Auth_BaseUsersController: Symbol.for('Auth_BaseUsersController'),
Auth_BaseAdminController: Symbol.for('Auth_BaseAdminController'),
Auth_BaseSubscriptionTokensController: Symbol.for('Auth_BaseSubscriptionTokensController'),
Auth_BaseSubscriptionSettingsController: Symbol.for('Auth_BaseSubscriptionSettingsController'),
Auth_BaseSettingsController: Symbol.for('Auth_BaseSettingsController'),
Auth_BaseSessionController: Symbol.for('Auth_BaseSessionController'),
Auth_BaseOfflineController: Symbol.for('Auth_BaseOfflineController'),
Auth_BaseListedController: Symbol.for('Auth_BaseListedController'),
Auth_BaseFeaturesController: Symbol.for('Auth_BaseFeaturesController'),
}
export default TYPES

View File

@@ -1 +1,2 @@
export * from './AuthServiceInterface'
export * from './Service'

View File

@@ -8,12 +8,12 @@ import { User } from '../Domain/User/User'
import { Register } from '../Domain/UseCase/Register'
import { DomainEventFactoryInterface } from '../Domain/Event/DomainEventFactoryInterface'
import { KeyParamsOrigination, ProtocolVersion } from '@standardnotes/common'
import { ApiVersion } from '@standardnotes/api'
import { SignInWithRecoveryCodes } from '../Domain/UseCase/SignInWithRecoveryCodes/SignInWithRecoveryCodes'
import { GetUserKeyParamsRecovery } from '../Domain/UseCase/GetUserKeyParamsRecovery/GetUserKeyParamsRecovery'
import { GenerateRecoveryCodes } from '../Domain/UseCase/GenerateRecoveryCodes/GenerateRecoveryCodes'
import { Logger } from 'winston'
import { SessionServiceInterface } from '../Domain/Session/SessionServiceInterface'
import { ApiVersion } from '../Domain/Api/ApiVersion'
describe('AuthController', () => {
let clearLoginAttempts: ClearLoginAttempts
@@ -73,7 +73,7 @@ describe('AuthController', () => {
email: 'test@test.te',
password: 'asdzxc',
version: ProtocolVersion.V004,
api: ApiVersion.v0,
api: ApiVersion.v20200115,
origination: KeyParamsOrigination.Registration,
userAgent: 'Google Chrome',
identifier: 'test@test.te',
@@ -103,7 +103,7 @@ describe('AuthController', () => {
email: 'test@test.te',
password: '',
version: ProtocolVersion.V004,
api: ApiVersion.v0,
api: ApiVersion.v20200115,
origination: KeyParamsOrigination.Registration,
userAgent: 'Google Chrome',
identifier: 'test@test.te',
@@ -123,7 +123,7 @@ describe('AuthController', () => {
email: 'test@test.te',
password: 'test',
version: ProtocolVersion.V004,
api: ApiVersion.v0,
api: ApiVersion.v20200115,
origination: KeyParamsOrigination.Registration,
userAgent: 'Google Chrome',
identifier: 'test@test.te',

View File

@@ -1,10 +1,10 @@
import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
import {
ApiVersion,
UserRegistrationRequestParams,
UserServerInterface,
UserDeletionResponseBody,
UserRegistrationResponseBody,
UserUpdateRequestParams,
} from '@standardnotes/api'
import { ErrorTag, HttpResponse, HttpStatusCode } from '@standardnotes/responses'
import { ProtocolVersion } from '@standardnotes/common'
@@ -23,6 +23,8 @@ import { GenerateRecoveryCodes } from '../Domain/UseCase/GenerateRecoveryCodes/G
import { GenerateRecoveryCodesRequestParams } from '../Infra/Http/Request/GenerateRecoveryCodesRequestParams'
import { Logger } from 'winston'
import { SessionServiceInterface } from '../Domain/Session/SessionServiceInterface'
import { ApiVersion } from '../Domain/Api/ApiVersion'
import { UserUpdateResponse } from '@standardnotes/api/dist/Domain/Response/User/UserUpdateResponse'
export class AuthController implements UserServerInterface {
constructor(
@@ -37,6 +39,10 @@ export class AuthController implements UserServerInterface {
private sessionService: SessionServiceInterface,
) {}
async update(_params: UserUpdateRequestParams): Promise<HttpResponse<UserUpdateResponse>> {
throw new Error('Method not implemented.')
}
async deleteAccount(_params: never): Promise<HttpResponse<UserDeletionResponseBody>> {
throw new Error('This method is implemented on the payments server.')
}
@@ -121,7 +127,7 @@ export class AuthController implements UserServerInterface {
async signInWithRecoveryCodes(
params: SignInWithRecoveryCodesRequestParams,
): Promise<HttpResponse<SignInWithRecoveryCodesResponseBody>> {
if (params.apiVersion !== ApiVersion.v0) {
if (params.apiVersion !== ApiVersion.v20200115) {
return {
status: HttpStatusCode.BadRequest,
data: {
@@ -162,7 +168,7 @@ export class AuthController implements UserServerInterface {
async recoveryKeyParams(
params: RecoveryKeyParamsRequestParams,
): Promise<HttpResponse<RecoveryKeyParamsResponseBody>> {
if (params.apiVersion !== ApiVersion.v0) {
if (params.apiVersion !== ApiVersion.v20200115) {
return {
status: HttpStatusCode.BadRequest,
data: {

View File

@@ -7,7 +7,7 @@ import { AcceptSharedSubscriptionInvitation } from '../Domain/UseCase/AcceptShar
import { DeclineSharedSubscriptionInvitation } from '../Domain/UseCase/DeclineSharedSubscriptionInvitation/DeclineSharedSubscriptionInvitation'
import { CancelSharedSubscriptionInvitation } from '../Domain/UseCase/CancelSharedSubscriptionInvitation/CancelSharedSubscriptionInvitation'
import { ListSharedSubscriptionInvitations } from '../Domain/UseCase/ListSharedSubscriptionInvitations/ListSharedSubscriptionInvitations'
import { ApiVersion } from '@standardnotes/api'
import { ApiVersion } from '../Domain/Api/ApiVersion'
describe('SubscriptionInvitesController', () => {
let inviteToSharedSubscription: InviteToSharedSubscription
@@ -53,7 +53,7 @@ describe('SubscriptionInvitesController', () => {
invitations: [],
})
const result = await createController().listInvites({ api: ApiVersion.v0, inviterEmail: 'test@test.te' })
const result = await createController().listInvites({ api: ApiVersion.v20200115, inviterEmail: 'test@test.te' })
expect(listSharedSubscriptionInvitations.execute).toHaveBeenCalledWith({
inviterEmail: 'test@test.te',
@@ -68,7 +68,7 @@ describe('SubscriptionInvitesController', () => {
})
const result = await createController().cancelInvite({
api: ApiVersion.v0,
api: ApiVersion.v20200115,
inviteUuid: '1-2-3',
inviterEmail: 'test@test.te',
})
@@ -87,7 +87,7 @@ describe('SubscriptionInvitesController', () => {
})
const result = await createController().cancelInvite({
api: ApiVersion.v0,
api: ApiVersion.v20200115,
inviteUuid: '1-2-3',
})
@@ -100,7 +100,7 @@ describe('SubscriptionInvitesController', () => {
})
const result = await createController().declineInvite({
api: ApiVersion.v0,
api: ApiVersion.v20200115,
inviteUuid: '1-2-3',
})
@@ -117,7 +117,7 @@ describe('SubscriptionInvitesController', () => {
})
const result = await createController().declineInvite({
api: ApiVersion.v0,
api: ApiVersion.v20200115,
inviteUuid: '1-2-3',
})
@@ -134,7 +134,7 @@ describe('SubscriptionInvitesController', () => {
})
const result = await createController().acceptInvite({
api: ApiVersion.v0,
api: ApiVersion.v20200115,
inviteUuid: '1-2-3',
})
@@ -151,7 +151,7 @@ describe('SubscriptionInvitesController', () => {
})
const result = await createController().acceptInvite({
api: ApiVersion.v0,
api: ApiVersion.v20200115,
inviteUuid: '1-2-3',
})
@@ -168,7 +168,7 @@ describe('SubscriptionInvitesController', () => {
})
const result = await createController().invite({
api: ApiVersion.v0,
api: ApiVersion.v20200115,
identifier: 'invitee@test.te',
inviterUuid: '1-2-3',
inviterEmail: 'test@test.te',
@@ -187,7 +187,7 @@ describe('SubscriptionInvitesController', () => {
it('should not invite to user subscription if the identifier is missing in request', async () => {
const result = await createController().invite({
api: ApiVersion.v0,
api: ApiVersion.v20200115,
identifier: '',
inviterUuid: '1-2-3',
inviterEmail: 'test@test.te',
@@ -205,7 +205,7 @@ describe('SubscriptionInvitesController', () => {
})
const result = await createController().invite({
api: ApiVersion.v0,
api: ApiVersion.v20200115,
identifier: 'invitee@test.te',
inviterUuid: '1-2-3',
inviterEmail: 'test@test.te',

View File

@@ -1,9 +1,5 @@
import { ProtocolVersion } from '@standardnotes/common'
import { SimpleUserProjection } from '../../Projection/SimpleUserProjection'
export interface AuthResponse {
user: {
uuid: string
email: string
protocolVersion: ProtocolVersion
}
user: SimpleUserProjection
}

View File

@@ -30,7 +30,7 @@ describe('AuthResponseFactory20161215', () => {
})
it('should create a 20161215 auth response', async () => {
const response = await createFactory().createResponse({
const result = await createFactory().createResponse({
user,
apiVersion: '20161215',
userAgent: 'Google Chrome',
@@ -38,7 +38,7 @@ describe('AuthResponseFactory20161215', () => {
readonlyAccess: false,
})
expect(response).toEqual({
expect(result.response).toEqual({
user: { foo: 'bar' },
token: 'foobar',
})

View File

@@ -11,6 +11,7 @@ import { User } from '../User/User'
import { AuthResponse20161215 } from './AuthResponse20161215'
import { AuthResponse20200115 } from './AuthResponse20200115'
import { AuthResponseFactoryInterface } from './AuthResponseFactoryInterface'
import { Session } from '../Session/Session'
@injectable()
export class AuthResponseFactory20161215 implements AuthResponseFactoryInterface {
@@ -26,7 +27,7 @@ export class AuthResponseFactory20161215 implements AuthResponseFactoryInterface
userAgent: string
ephemeralSession: boolean
readonlyAccess: boolean
}): Promise<AuthResponse20161215 | AuthResponse20200115> {
}): Promise<{ response: AuthResponse20161215 | AuthResponse20200115; session?: Session }> {
this.logger.debug(`Creating JWT auth response for user ${dto.user.uuid}`)
const data: SessionTokenData = {
@@ -39,12 +40,14 @@ export class AuthResponseFactory20161215 implements AuthResponseFactoryInterface
this.logger.debug(`Created JWT token for user ${dto.user.uuid}: ${token}`)
return {
user: this.userProjector.projectSimple(dto.user) as {
uuid: string
email: string
protocolVersion: ProtocolVersion
response: {
user: this.userProjector.projectSimple(dto.user) as {
uuid: string
email: string
protocolVersion: ProtocolVersion
},
token,
},
token,
}
}
}

View File

@@ -29,7 +29,7 @@ describe('AuthResponseFactory20190520', () => {
})
it('should create a 20161215 auth response', async () => {
const response = await createFactory().createResponse({
const result = await createFactory().createResponse({
user,
apiVersion: '20161215',
userAgent: 'Google Chrome',
@@ -37,7 +37,7 @@ describe('AuthResponseFactory20190520', () => {
readonlyAccess: false,
})
expect(response).toEqual({
expect(result.response).toEqual({
user: { foo: 'bar' },
token: 'foobar',
})

View File

@@ -11,6 +11,7 @@ import { User } from '../User/User'
import { AuthResponseFactory20200115 } from './AuthResponseFactory20200115'
import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
import { DomainEventFactoryInterface } from '../Event/DomainEventFactoryInterface'
import { Session } from '../Session/Session'
describe('AuthResponseFactory20200115', () => {
let sessionService: SessionServiceInterface
@@ -48,8 +49,12 @@ describe('AuthResponseFactory20200115', () => {
}
sessionService = {} as jest.Mocked<SessionServiceInterface>
sessionService.createNewSessionForUser = jest.fn().mockReturnValue(sessionPayload)
sessionService.createNewEphemeralSessionForUser = jest.fn().mockReturnValue(sessionPayload)
sessionService.createNewSessionForUser = jest
.fn()
.mockReturnValue({ sessionHttpRepresentation: sessionPayload, session: {} as jest.Mocked<Session> })
sessionService.createNewEphemeralSessionForUser = jest
.fn()
.mockReturnValue({ sessionHttpRepresentation: sessionPayload, session: {} as jest.Mocked<Session> })
keyParamsFactory = {} as jest.Mocked<KeyParamsFactoryInterface>
keyParamsFactory.create = jest.fn().mockReturnValue({
@@ -76,7 +81,7 @@ describe('AuthResponseFactory20200115', () => {
it('should create a 20161215 auth response if user does not support sessions', async () => {
user.supportsSessions = jest.fn().mockReturnValue(false)
const response = await createFactory().createResponse({
const result = await createFactory().createResponse({
user,
apiVersion: '20161215',
userAgent: 'Google Chrome',
@@ -84,7 +89,7 @@ describe('AuthResponseFactory20200115', () => {
readonlyAccess: false,
})
expect(response).toEqual({
expect(result.response).toEqual({
user: { foo: 'bar' },
token: expect.any(String),
})
@@ -93,7 +98,7 @@ describe('AuthResponseFactory20200115', () => {
it('should create a 20200115 auth response', async () => {
user.supportsSessions = jest.fn().mockReturnValue(true)
const response = await createFactory().createResponse({
const result = await createFactory().createResponse({
user,
apiVersion: '20200115',
userAgent: 'Google Chrome',
@@ -101,7 +106,7 @@ describe('AuthResponseFactory20200115', () => {
readonlyAccess: false,
})
expect(response).toEqual({
expect(result.response).toEqual({
key_params: {
key1: 'value1',
key2: 'value2',
@@ -124,7 +129,7 @@ describe('AuthResponseFactory20200115', () => {
domainEventPublisher.publish = jest.fn().mockRejectedValue(new Error('test'))
user.supportsSessions = jest.fn().mockReturnValue(true)
const response = await createFactory().createResponse({
const result = await createFactory().createResponse({
user,
apiVersion: '20200115',
userAgent: 'Google Chrome',
@@ -132,7 +137,7 @@ describe('AuthResponseFactory20200115', () => {
readonlyAccess: false,
})
expect(response).toEqual({
expect(result.response).toEqual({
key_params: {
key1: 'value1',
key2: 'value2',
@@ -153,7 +158,7 @@ describe('AuthResponseFactory20200115', () => {
it('should create a 20200115 auth response with an ephemeral session', async () => {
user.supportsSessions = jest.fn().mockReturnValue(true)
const response = await createFactory().createResponse({
const result = await createFactory().createResponse({
user,
apiVersion: '20200115',
userAgent: 'Google Chrome',
@@ -161,7 +166,7 @@ describe('AuthResponseFactory20200115', () => {
readonlyAccess: false,
})
expect(response).toEqual({
expect(result.response).toEqual({
key_params: {
key1: 'value1',
key2: 'value2',
@@ -183,11 +188,14 @@ describe('AuthResponseFactory20200115', () => {
user.supportsSessions = jest.fn().mockReturnValue(true)
sessionService.createNewSessionForUser = jest.fn().mockReturnValue({
...sessionPayload,
readonly_access: true,
sessionHttpRepresentation: {
...sessionPayload,
readonly_access: true,
},
session: {} as jest.Mocked<Session>,
})
const response = await createFactory().createResponse({
const result = await createFactory().createResponse({
user,
apiVersion: '20200115',
userAgent: 'Google Chrome',
@@ -195,7 +203,7 @@ describe('AuthResponseFactory20200115', () => {
readonlyAccess: true,
})
expect(response).toEqual({
expect(result.response).toEqual({
key_params: {
key1: 'value1',
key2: 'value2',

View File

@@ -4,13 +4,13 @@ import {
TokenEncoderInterface,
} from '@standardnotes/security'
import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
import { ProtocolVersion } from '@standardnotes/common'
import { SessionBody } from '@standardnotes/responses'
import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
import TYPES from '../../Bootstrap/Types'
import { ProjectorInterface } from '../../Projection/ProjectorInterface'
import { SimpleUserProjection } from '../../Projection/SimpleUserProjection'
import { SessionServiceInterface } from '../Session/SessionServiceInterface'
import { KeyParamsFactoryInterface } from '../User/KeyParamsFactoryInterface'
import { User } from '../User/User'
@@ -19,6 +19,7 @@ import { DomainEventFactoryInterface } from '../Event/DomainEventFactoryInterfac
import { AuthResponse20161215 } from './AuthResponse20161215'
import { AuthResponse20200115 } from './AuthResponse20200115'
import { Session } from '../Session/Session'
@injectable()
export class AuthResponseFactory20200115 extends AuthResponseFactory20190520 {
@@ -40,25 +41,28 @@ export class AuthResponseFactory20200115 extends AuthResponseFactory20190520 {
userAgent: string
ephemeralSession: boolean
readonlyAccess: boolean
}): Promise<AuthResponse20161215 | AuthResponse20200115> {
}): Promise<{ response: AuthResponse20161215 | AuthResponse20200115; session?: Session }> {
if (!dto.user.supportsSessions()) {
this.logger.debug(`User ${dto.user.uuid} does not support sessions. Falling back to JWT auth response`)
return super.createResponse(dto)
}
const sessionPayload = await this.createSession(dto)
const sessionCreationResult = await this.createSession(dto)
this.logger.debug('Created session payload for user %s: %O', dto.user.uuid, sessionPayload)
this.logger.debug(
'Created session payload for user %s: %O',
dto.user.uuid,
sessionCreationResult.sessionHttpRepresentation,
)
return {
session: sessionPayload,
key_params: this.keyParamsFactory.create(dto.user, true),
user: this.userProjector.projectSimple(dto.user) as {
uuid: string
email: string
protocolVersion: ProtocolVersion
response: {
session: sessionCreationResult.sessionHttpRepresentation,
key_params: this.keyParamsFactory.create(dto.user, true),
user: this.userProjector.projectSimple(dto.user) as SimpleUserProjection,
},
session: sessionCreationResult.session,
}
}
@@ -68,12 +72,12 @@ export class AuthResponseFactory20200115 extends AuthResponseFactory20190520 {
userAgent: string
ephemeralSession: boolean
readonlyAccess: boolean
}): Promise<SessionBody> {
}): Promise<{ sessionHttpRepresentation: SessionBody; session: Session }> {
if (dto.ephemeralSession) {
return this.sessionService.createNewEphemeralSessionForUser(dto)
}
const session = this.sessionService.createNewSessionForUser(dto)
const sessionCreationResult = await this.sessionService.createNewSessionForUser(dto)
try {
await this.domainEventPublisher.publish(
@@ -83,6 +87,6 @@ export class AuthResponseFactory20200115 extends AuthResponseFactory20190520 {
this.logger.error(`Failed to publish session created event: ${(error as Error).message}`)
}
return session
return sessionCreationResult
}
}

View File

@@ -1,3 +1,4 @@
import { Session } from '../Session/Session'
import { User } from '../User/User'
import { AuthResponse20161215 } from './AuthResponse20161215'
import { AuthResponse20200115 } from './AuthResponse20200115'
@@ -9,5 +10,5 @@ export interface AuthResponseFactoryInterface {
userAgent: string
ephemeralSession: boolean
readonlyAccess: boolean
}): Promise<AuthResponse20161215 | AuthResponse20200115>
}): Promise<{ response: AuthResponse20161215 | AuthResponse20200115; session?: Session }>
}

View File

@@ -9,6 +9,7 @@ import { User } from '../User/User'
import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
import { AuthenticationMethodResolver } from './AuthenticationMethodResolver'
import { Logger } from 'winston'
describe('AuthenticationMethodResolver', () => {
let userRepository: UserRepositoryInterface
@@ -18,14 +19,20 @@ describe('AuthenticationMethodResolver', () => {
let user: User
let session: Session
let revokedSession: RevokedSession
let logger: Logger
const createResolver = () =>
new AuthenticationMethodResolver(userRepository, sessionService, sessionTokenDecoder, fallbackTokenDecoder)
new AuthenticationMethodResolver(userRepository, sessionService, sessionTokenDecoder, fallbackTokenDecoder, logger)
beforeEach(() => {
logger = {} as jest.Mocked<Logger>
logger.debug = jest.fn()
user = {} as jest.Mocked<User>
session = {} as jest.Mocked<Session>
session = {
userUuid: '00000000-0000-0000-0000-000000000000',
} as jest.Mocked<Session>
revokedSession = {} as jest.Mocked<RevokedSession>
@@ -33,7 +40,7 @@ describe('AuthenticationMethodResolver', () => {
userRepository.findOneByUuid = jest.fn().mockReturnValue(user)
sessionService = {} as jest.Mocked<SessionServiceInterface>
sessionService.getSessionFromToken = jest.fn()
sessionService.getSessionFromToken = jest.fn().mockReturnValue({ session: undefined, isEphemeral: false })
sessionService.getRevokedSessionFromToken = jest.fn()
sessionService.markRevokedSessionAsReceived = jest.fn().mockReturnValue(revokedSession)
@@ -45,19 +52,25 @@ describe('AuthenticationMethodResolver', () => {
})
it('should resolve jwt authentication method', async () => {
sessionTokenDecoder.decodeToken = jest.fn().mockReturnValue({ user_uuid: '123' })
sessionTokenDecoder.decodeToken = jest.fn().mockReturnValue({ user_uuid: '00000000-0000-0000-0000-000000000000' })
expect(await createResolver().resolve('test')).toEqual({
claims: {
user_uuid: '123',
user_uuid: '00000000-0000-0000-0000-000000000000',
},
type: 'jwt',
user,
})
})
it('should not resolve jwt authentication method with invalid user uuid', async () => {
sessionTokenDecoder.decodeToken = jest.fn().mockReturnValue({ user_uuid: 'invalid' })
expect(await createResolver().resolve('test')).toBeUndefined
})
it('should resolve session authentication method', async () => {
sessionService.getSessionFromToken = jest.fn().mockReturnValue(session)
sessionService.getSessionFromToken = jest.fn().mockReturnValue({ session, isEphemeral: false })
expect(await createResolver().resolve('test')).toEqual({
session,
@@ -66,6 +79,14 @@ describe('AuthenticationMethodResolver', () => {
})
})
it('should not resolve session authentication method with invalid user uuid on session', async () => {
sessionService.getSessionFromToken = jest
.fn()
.mockReturnValue({ session: { userUuid: 'invalid' }, isEphemeral: false })
expect(await createResolver().resolve('test')).toBeUndefined
})
it('should resolve archvied session authentication method', async () => {
sessionService.getRevokedSessionFromToken = jest.fn().mockReturnValue(revokedSession)

View File

@@ -5,6 +5,8 @@ import { SessionServiceInterface } from '../Session/SessionServiceInterface'
import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
import { AuthenticationMethod } from './AuthenticationMethod'
import { AuthenticationMethodResolverInterface } from './AuthenticationMethodResolverInterface'
import { Logger } from 'winston'
import { Uuid } from '@standardnotes/domain-core'
@injectable()
export class AuthenticationMethodResolver implements AuthenticationMethodResolverInterface {
@@ -14,33 +16,54 @@ export class AuthenticationMethodResolver implements AuthenticationMethodResolve
@inject(TYPES.Auth_SessionTokenDecoder) private sessionTokenDecoder: TokenDecoderInterface<SessionTokenData>,
@inject(TYPES.Auth_FallbackSessionTokenDecoder)
private fallbackSessionTokenDecoder: TokenDecoderInterface<SessionTokenData>,
@inject(TYPES.Auth_Logger) private logger: Logger,
) {}
async resolve(token: string): Promise<AuthenticationMethod | undefined> {
let decodedToken: SessionTokenData | undefined = this.sessionTokenDecoder.decodeToken(token)
if (decodedToken === undefined) {
this.logger.debug('Could not decode token with primary decoder, trying fallback decoder.')
decodedToken = this.fallbackSessionTokenDecoder.decodeToken(token)
}
if (decodedToken) {
this.logger.debug('Token decoded successfully. User found.')
const userUuidOrError = Uuid.create(decodedToken.user_uuid as string)
if (userUuidOrError.isFailed()) {
return undefined
}
const userUuid = userUuidOrError.getValue()
return {
type: 'jwt',
user: await this.userRepository.findOneByUuid(<string>decodedToken.user_uuid),
user: await this.userRepository.findOneByUuid(userUuid),
claims: decodedToken,
}
}
const session = await this.sessionService.getSessionFromToken(token)
const { session } = await this.sessionService.getSessionFromToken(token)
if (session) {
this.logger.debug('Token decoded successfully. Session found.')
const userUuidOrError = Uuid.create(session.userUuid)
if (userUuidOrError.isFailed()) {
return undefined
}
const userUuid = userUuidOrError.getValue()
return {
type: 'session_token',
user: await this.userRepository.findOneByUuid(session.userUuid),
user: await this.userRepository.findOneByUuid(userUuid),
session: session,
}
}
const revokedSession = await this.sessionService.getRevokedSessionFromToken(token)
if (revokedSession) {
this.logger.debug('Token decoded successfully. Revoked session found.')
return {
type: 'revoked',
revokedSession: await this.sessionService.markRevokedSessionAsReceived(revokedSession),
@@ -48,6 +71,8 @@ export class AuthenticationMethodResolver implements AuthenticationMethodResolve
}
}
this.logger.debug('Could not decode token.')
return undefined
}
}

View File

@@ -3,10 +3,6 @@ import { Entity, Result, UniqueEntityId } from '@standardnotes/domain-core'
import { AuthenticatorProps } from './AuthenticatorProps'
export class Authenticator extends Entity<AuthenticatorProps> {
get id(): UniqueEntityId {
return this._id
}
private constructor(props: AuthenticatorProps, id?: UniqueEntityId) {
super(props, id)
}

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