Compare commits

..

253 Commits

Author SHA1 Message Date
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
678 changed files with 22144 additions and 5690 deletions
+8 -1
View File
@@ -4,12 +4,13 @@ DB_USERNAME=std_notes_user
DB_PASSWORD=changeme123 DB_PASSWORD=changeme123
DB_DATABASE=standard_notes_db DB_DATABASE=standard_notes_db
DB_PORT=3306 DB_PORT=3306
DB_SQLITE_DATABASE_PATH=standard_notes_db
REDIS_PORT=6379 REDIS_PORT=6379
REDIS_HOST=cache REDIS_HOST=cache
AUTH_SERVER_ACCESS_TOKEN_AGE=4 AUTH_SERVER_ACCESS_TOKEN_AGE=4
AUTH_SERVER_REFRESH_TOKEN_AGE=10 AUTH_SERVER_REFRESH_TOKEN_AGE=10
AUTH_SERVER_EPHEMERAL_SESSION_AGE=300 AUTH_SERVER_EPHEMERAL_SESSION_AGE=300
SYNCING_SERVER_REVISIONS_FREQUENCY=5 SYNCING_SERVER_REVISIONS_FREQUENCY=2
AUTH_SERVER_LOG_LEVEL=debug AUTH_SERVER_LOG_LEVEL=debug
SYNCING_SERVER_LOG_LEVEL=debug SYNCING_SERVER_LOG_LEVEL=debug
FILES_SERVER_LOG_LEVEL=debug FILES_SERVER_LOG_LEVEL=debug
@@ -21,6 +22,12 @@ MYSQL_USER=std_notes_user
MYSQL_PASSWORD=changeme123 MYSQL_PASSWORD=changeme123
MYSQL_ROOT_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_JWT_SECRET=f95259c5e441f5a4646d76422cfb3df4c4488842901aa50b6c51b8be2e0040e9
AUTH_SERVER_ENCRYPTION_SERVER_KEY=1087415dfde3093797f9a7ca93a49e7d7aa1861735eb0d32aae9c303b8c3d060 AUTH_SERVER_ENCRYPTION_SERVER_KEY=1087415dfde3093797f9a7ca93a49e7d7aa1861735eb0d32aae9c303b8c3d060
VALET_TOKEN_SECRET=4b886819ebe1e908077c6cae96311b48a8416bd60cc91c03060e15bdf6b30d1f VALET_TOKEN_SECRET=4b886819ebe1e908077c6cae96311b48a8416bd60cc91c03060e15bdf6b30d1f
+67 -5
View File
@@ -20,6 +20,10 @@ on:
jobs: jobs:
e2e: e2e:
name: (Docker) E2E Test Suite name: (Docker) E2E Test Suite
strategy:
fail-fast: false
matrix:
secondary_db_enabled: [true, false]
runs-on: ubuntu-latest runs-on: ubuntu-latest
services: services:
@@ -45,15 +49,31 @@ jobs:
env: env:
DB_TYPE: mysql DB_TYPE: mysql
CACHE_TYPE: redis CACHE_TYPE: redis
SECONDARY_DB_ENABLED: ${{ matrix.secondary_db_enabled }}
- name: Wait for server to start - name: Wait for server to start
run: docker/is-available.sh http://localhost:3123 $(pwd)/logs run: docker/is-available.sh http://localhost:3123 $(pwd)/logs
- name: Run E2E Test Suite - 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
- 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: e2e-home-server:
name: (Home Server) E2E Test Suite name: (Home Server) E2E Test Suite
strategy:
fail-fast: false
matrix:
db_type: [mysql, sqlite]
cache_type: [redis, memory]
secondary_db_enabled: [true, false]
runs-on: ubuntu-latest runs-on: ubuntu-latest
services: services:
@@ -61,6 +81,27 @@ jobs:
image: standardnotes/snjs:${{ inputs.snjs_image_tag }} image: standardnotes/snjs:${{ inputs.snjs_image_tag }}
ports: ports:
- 9001:9001 - 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: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@@ -88,11 +129,28 @@ jobs:
sed -i "s/PSEUDO_KEY_PARAMS_KEY=/PSEUDO_KEY_PARAMS_KEY=$(openssl rand -hex 32)/g" packages/home-server/.env sed -i "s/PSEUDO_KEY_PARAMS_KEY=/PSEUDO_KEY_PARAMS_KEY=$(openssl rand -hex 32)/g" packages/home-server/.env
sed -i "s/VALET_TOKEN_SECRET=/VALET_TOKEN_SECRET=$(openssl rand -hex 32)/g" packages/home-server/.env 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 "ACCESS_TOKEN_AGE=4" >> packages/home-server/.env
echo "REFRESH_TOKEN_AGE=7" >> packages/home-server/.env echo "REFRESH_TOKEN_AGE=10" >> packages/home-server/.env
echo "REVISIONS_FREQUENCY=5" >> packages/home-server/.env echo "REVISIONS_FREQUENCY=2" >> packages/home-server/.env
echo "DB_HOST=localhost" >> packages/home-server/.env
echo "DB_PORT=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 "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 - 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: env:
PORT: 3123 PORT: 3123
@@ -100,4 +158,8 @@ jobs:
run: for i in {1..30}; do curl -s http://localhost:3123/healthcheck && break || sleep 1; done run: for i in {1..30}; do curl -s http://localhost:3123/healthcheck && break || sleep 1; done
- name: Run E2E Test Suite - 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
- name: Show logs on failure
if: ${{ failure() }}
run: tail -n 500 logs/output.log
Generated
+271 -55
View File
@@ -4560,17 +4560,16 @@ const RAW_RUNTIME_STATE =
}]\ }]\
]],\ ]],\
["@standardnotes/api", [\ ["@standardnotes/api", [\
["npm:1.26.10", {\ ["npm:1.26.26", {\
"packageLocation": "./.yarn/cache/@standardnotes-api-npm-1.26.10-f6165cafd3-3c3561aec8.zip/node_modules/@standardnotes/api/",\ "packageLocation": "./.yarn/cache/@standardnotes-api-npm-1.26.26-4338a5fe92-db41aedfa3.zip/node_modules/@standardnotes/api/",\
"packageDependencies": [\ "packageDependencies": [\
["@standardnotes/api", "npm:1.26.10"],\ ["@standardnotes/api", "npm:1.26.26"],\
["@standardnotes/common", "workspace:packages/common"],\ ["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\ ["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/encryption", "npm:1.21.38"],\ ["@standardnotes/models", "npm:1.46.8"],\
["@standardnotes/models", "npm:1.45.5"],\ ["@standardnotes/responses", "npm:1.13.27"],\
["@standardnotes/responses", "npm:1.13.24"],\
["@standardnotes/security", "workspace:packages/security"],\ ["@standardnotes/security", "workspace:packages/security"],\
["@standardnotes/utils", "npm:1.16.5"],\ ["@standardnotes/utils", "npm:1.17.5"],\
["reflect-metadata", "npm:0.1.13"]\ ["reflect-metadata", "npm:0.1.13"]\
],\ ],\
"linkType": "HARD"\ "linkType": "HARD"\
@@ -4635,17 +4634,17 @@ const RAW_RUNTIME_STATE =
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.1"],\ ["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.1"],\
["@simplewebauthn/server", "npm:7.2.0"],\ ["@simplewebauthn/server", "npm:7.2.0"],\
["@simplewebauthn/typescript-types", "npm:7.0.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/common", "workspace:packages/common"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\ ["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\ ["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\ ["@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/predicates", "workspace:packages/predicates"],\
["@standardnotes/responses", "npm:1.13.24"],\ ["@standardnotes/responses", "npm:1.13.27"],\
["@standardnotes/security", "workspace:packages/security"],\ ["@standardnotes/security", "workspace:packages/security"],\
["@standardnotes/settings", "workspace:packages/settings"],\ ["@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/sncrypto-node", "workspace:packages/sncrypto-node"],\
["@standardnotes/time", "workspace:packages/time"],\ ["@standardnotes/time", "workspace:packages/time"],\
["@types/bcryptjs", "npm:2.4.2"],\ ["@types/bcryptjs", "npm:2.4.2"],\
@@ -4781,21 +4780,6 @@ const RAW_RUNTIME_STATE =
"linkType": "SOFT"\ "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", [\ ["@standardnotes/event-store", [\
["workspace:packages/event-store", {\ ["workspace:packages/event-store", {\
"packageLocation": "./packages/event-store/",\ "packageLocation": "./packages/event-store/",\
@@ -4831,10 +4815,10 @@ const RAW_RUNTIME_STATE =
}]\ }]\
]],\ ]],\
["@standardnotes/features", [\ ["@standardnotes/features", [\
["npm:1.59.5", {\ ["npm:1.59.7", {\
"packageLocation": "./.yarn/cache/@standardnotes-features-npm-1.59.5-83c83acde9-173b1f5d52.zip/node_modules/@standardnotes/features/",\ "packageLocation": "./.yarn/cache/@standardnotes-features-npm-1.59.7-27c3e5296e-1632d64cc1.zip/node_modules/@standardnotes/features/",\
"packageDependencies": [\ "packageDependencies": [\
["@standardnotes/features", "npm:1.59.5"],\ ["@standardnotes/features", "npm:1.59.7"],\
["@standardnotes/common", "workspace:packages/common"],\ ["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\ ["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/security", "workspace:packages/security"],\ ["@standardnotes/security", "workspace:packages/security"],\
@@ -4855,7 +4839,7 @@ const RAW_RUNTIME_STATE =
["@standardnotes/domain-events", "workspace:packages/domain-events"],\ ["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\ ["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@standardnotes/security", "workspace:packages/security"],\ ["@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/sncrypto-node", "workspace:packages/sncrypto-node"],\
["@standardnotes/time", "workspace:packages/time"],\ ["@standardnotes/time", "workspace:packages/time"],\
["@types/connect-busboy", "npm:1.0.0"],\ ["@types/connect-busboy", "npm:1.0.0"],\
@@ -4935,14 +4919,16 @@ const RAW_RUNTIME_STATE =
}]\ }]\
]],\ ]],\
["@standardnotes/models", [\ ["@standardnotes/models", [\
["npm:1.45.5", {\ ["npm:1.46.8", {\
"packageLocation": "./.yarn/cache/@standardnotes-models-npm-1.45.5-29326e959c-15f26c11b2.zip/node_modules/@standardnotes/models/",\ "packageLocation": "./.yarn/cache/@standardnotes-models-npm-1.46.8-bc0390832e-8404340f27.zip/node_modules/@standardnotes/models/",\
"packageDependencies": [\ "packageDependencies": [\
["@standardnotes/models", "npm:1.45.5"],\ ["@standardnotes/models", "npm:1.46.8"],\
["@standardnotes/common", "workspace:packages/common"],\ ["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/features", "npm:1.59.5"],\ ["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/responses", "npm:1.13.24"],\ ["@standardnotes/features", "npm:1.59.7"],\
["@standardnotes/utils", "npm:1.16.5"],\ ["@standardnotes/responses", "npm:1.13.27"],\
["@standardnotes/sncrypto-common", "npm:1.13.4"],\
["@standardnotes/utils", "npm:1.17.5"],\
["lodash", "npm:4.17.21"]\ ["lodash", "npm:4.17.21"]\
],\ ],\
"linkType": "HARD"\ "linkType": "HARD"\
@@ -4967,12 +4953,12 @@ const RAW_RUNTIME_STATE =
}]\ }]\
]],\ ]],\
["@standardnotes/responses", [\ ["@standardnotes/responses", [\
["npm:1.13.24", {\ ["npm:1.13.27", {\
"packageLocation": "./.yarn/cache/@standardnotes-responses-npm-1.13.24-3b4167c7ea-3bcfee90f0.zip/node_modules/@standardnotes/responses/",\ "packageLocation": "./.yarn/cache/@standardnotes-responses-npm-1.13.27-829dec3e6e-9bf55e5f02.zip/node_modules/@standardnotes/responses/",\
"packageDependencies": [\ "packageDependencies": [\
["@standardnotes/responses", "npm:1.13.24"],\ ["@standardnotes/responses", "npm:1.13.27"],\
["@standardnotes/common", "workspace:packages/common"],\ ["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/features", "npm:1.59.5"],\ ["@standardnotes/features", "npm:1.59.7"],\
["@standardnotes/security", "workspace:packages/security"],\ ["@standardnotes/security", "workspace:packages/security"],\
["reflect-metadata", "npm:0.1.13"]\ ["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-s3", "npm:3.342.0"],\
["@aws-sdk/client-sqs", "npm:3.342.0"],\ ["@aws-sdk/client-sqs", "npm:3.342.0"],\
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.1"],\ ["@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/common", "workspace:packages/common"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\ ["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\ ["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\ ["@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/security", "workspace:packages/security"],\
["@standardnotes/time", "workspace:packages/time"],\ ["@standardnotes/time", "workspace:packages/time"],\
["@types/cors", "npm:2.8.13"],\ ["@types/cors", "npm:2.8.13"],\
@@ -5129,10 +5115,10 @@ const RAW_RUNTIME_STATE =
}]\ }]\
]],\ ]],\
["@standardnotes/sncrypto-common", [\ ["@standardnotes/sncrypto-common", [\
["npm:1.13.3", {\ ["npm:1.13.4", {\
"packageLocation": "./.yarn/cache/@standardnotes-sncrypto-common-npm-1.13.3-97ef3850ce-a73af90962.zip/node_modules/@standardnotes/sncrypto-common/",\ "packageLocation": "./.yarn/cache/@standardnotes-sncrypto-common-npm-1.13.4-3186513fa6-48e0e207f2.zip/node_modules/@standardnotes/sncrypto-common/",\
"packageDependencies": [\ "packageDependencies": [\
["@standardnotes/sncrypto-common", "npm:1.13.3"],\ ["@standardnotes/sncrypto-common", "npm:1.13.4"],\
["reflect-metadata", "npm:0.1.13"]\ ["reflect-metadata", "npm:0.1.13"]\
],\ ],\
"linkType": "HARD"\ "linkType": "HARD"\
@@ -5143,7 +5129,7 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/sncrypto-node/",\ "packageLocation": "./packages/sncrypto-node/",\
"packageDependencies": [\ "packageDependencies": [\
["@standardnotes/sncrypto-node", "workspace:packages/sncrypto-node"],\ ["@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/jest", "npm:29.5.2"],\
["@types/node", "npm:20.2.5"],\ ["@types/node", "npm:20.2.5"],\
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.59.8"],\ ["@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-sns", "npm:3.342.0"],\
["@aws-sdk/client-sqs", "npm:3.342.0"],\ ["@aws-sdk/client-sqs", "npm:3.342.0"],\
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.1"],\ ["@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/common", "workspace:packages/common"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\ ["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\ ["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\ ["@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/security", "workspace:packages/security"],\
["@standardnotes/settings", "workspace:packages/settings"],\ ["@standardnotes/settings", "workspace:packages/settings"],\
["@standardnotes/sncrypto-node", "workspace:packages/sncrypto-node"],\
["@standardnotes/time", "workspace:packages/time"],\ ["@standardnotes/time", "workspace:packages/time"],\
["@types/cors", "npm:2.8.13"],\ ["@types/cors", "npm:2.8.13"],\
["@types/dotenv", "npm:8.2.0"],\ ["@types/dotenv", "npm:8.2.0"],\
@@ -5188,6 +5175,7 @@ const RAW_RUNTIME_STATE =
["@types/newrelic", "npm:9.14.0"],\ ["@types/newrelic", "npm:9.14.0"],\
["@types/node", "npm:20.2.5"],\ ["@types/node", "npm:20.2.5"],\
["@types/prettyjson", "npm:0.0.30"],\ ["@types/prettyjson", "npm:0.0.30"],\
["@types/semver", "npm:7.5.0"],\
["@types/ua-parser-js", "npm:0.7.36"],\ ["@types/ua-parser-js", "npm:0.7.36"],\
["@types/uuid", "npm:8.3.4"],\ ["@types/uuid", "npm:8.3.4"],\
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.59.8"],\ ["@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"],\ ["inversify-express-utils", "npm:6.4.3"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.5.0"],\ ["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.5.0"],\
["jsonwebtoken", "npm:9.0.0"],\ ["jsonwebtoken", "npm:9.0.0"],\
["mongodb", "virtual:67ad3a1ca34e24ce4821cc48979e98af0c3e5dd7aabc7ad0b5d22d1d977d6f943f81c9f141a420105ebdc61ef777e508a96c7946081decd98f8c30543d468b33#npm:5.7.0"],\
["mysql2", "npm:3.3.3"],\ ["mysql2", "npm:3.3.3"],\
["newrelic", "npm:10.1.2"],\ ["newrelic", "npm:10.1.2"],\
["nodemon", "npm:2.0.22"],\ ["nodemon", "npm:2.0.22"],\
@@ -5210,9 +5199,10 @@ const RAW_RUNTIME_STATE =
["prettier", "npm:2.8.8"],\ ["prettier", "npm:2.8.8"],\
["prettyjson", "npm:1.2.5"],\ ["prettyjson", "npm:1.2.5"],\
["reflect-metadata", "npm:0.1.13"],\ ["reflect-metadata", "npm:0.1.13"],\
["semver", "npm:7.5.1"],\
["sqlite3", "virtual:31b5a94a105c89c9294c3d524a7f8929fe63ee5a2efadf21951ca4c0cfd2ecf02e8f4ef5a066bbda091f1e3a56e57c6749069a080618c96b22e51131a330fc4a#npm:5.1.6"],\ ["sqlite3", "virtual:31b5a94a105c89c9294c3d524a7f8929fe63ee5a2efadf21951ca4c0cfd2ecf02e8f4ef5a066bbda091f1e3a56e57c6749069a080618c96b22e51131a330fc4a#npm:5.1.6"],\
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.0"],\ ["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"],\ ["typescript", "patch:typescript@npm%3A5.0.4#optional!builtin<compat/typescript>::version=5.0.4&hash=b5f058"],\
["ua-parser-js", "npm:1.0.35"],\ ["ua-parser-js", "npm:1.0.35"],\
["uuid", "npm:9.0.0"],\ ["uuid", "npm:9.0.0"],\
@@ -5244,10 +5234,10 @@ const RAW_RUNTIME_STATE =
}]\ }]\
]],\ ]],\
["@standardnotes/utils", [\ ["@standardnotes/utils", [\
["npm:1.16.5", {\ ["npm:1.17.5", {\
"packageLocation": "./.yarn/cache/@standardnotes-utils-npm-1.16.5-47f537f49f-d5caa7181f.zip/node_modules/@standardnotes/utils/",\ "packageLocation": "./.yarn/cache/@standardnotes-utils-npm-1.17.5-210b60222d-47e8520174.zip/node_modules/@standardnotes/utils/",\
"packageDependencies": [\ "packageDependencies": [\
["@standardnotes/utils", "npm:1.16.5"],\ ["@standardnotes/utils", "npm:1.17.5"],\
["@standardnotes/common", "workspace:packages/common"],\ ["@standardnotes/common", "workspace:packages/common"],\
["dompurify", "npm:2.4.5"],\ ["dompurify", "npm:2.4.5"],\
["lodash", "npm:4.17.21"],\ ["lodash", "npm:4.17.21"],\
@@ -5263,14 +5253,13 @@ const RAW_RUNTIME_STATE =
["@standardnotes/websockets-server", "workspace:packages/websockets"],\ ["@standardnotes/websockets-server", "workspace:packages/websockets"],\
["@aws-sdk/client-sqs", "npm:3.342.0"],\ ["@aws-sdk/client-sqs", "npm:3.342.0"],\
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.1"],\ ["@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/common", "workspace:packages/common"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\ ["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\ ["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\ ["@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/security", "workspace:packages/security"],\
["@standardnotes/utils", "npm:1.16.5"],\
["@types/cors", "npm:2.8.13"],\ ["@types/cors", "npm:2.8.13"],\
["@types/express", "npm:4.17.17"],\ ["@types/express", "npm:4.17.17"],\
["@types/ioredis", "npm:5.0.0"],\ ["@types/ioredis", "npm:5.0.0"],\
@@ -5881,6 +5870,26 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\ "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", [\ ["@types/yargs", [\
["npm:17.0.24", {\ ["npm:17.0.24", {\
"packageLocation": "./.yarn/cache/@types-yargs-npm-17.0.24-b034cf1d8b-f7811cc0b9.zip/node_modules/@types/yargs/",\ "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"\ "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", [\ ["buffer", [\
["npm:5.7.1", {\ ["npm:5.7.1", {\
"packageLocation": "./.yarn/cache/buffer-npm-5.7.1-513ef8259e-8e611bed4d.zip/node_modules/buffer/",\ "packageLocation": "./.yarn/cache/buffer-npm-5.7.1-513ef8259e-8e611bed4d.zip/node_modules/buffer/",\
@@ -11944,6 +11962,15 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\ "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", [\ ["meow", [\
["npm:8.1.2", {\ ["npm:8.1.2", {\
"packageLocation": "./.yarn/cache/meow-npm-8.1.2-bcfe48d4f3-e36c879078.zip/node_modules/meow/",\ "packageLocation": "./.yarn/cache/meow-npm-8.1.2-bcfe48d4f3-e36c879078.zip/node_modules/meow/",\
@@ -12302,6 +12329,59 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\ "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", [\ ["ms", [\
["npm:2.0.0", {\ ["npm:2.0.0", {\
"packageLocation": "./.yarn/cache/ms-npm-2.0.0-9e1101a471-de027828fc.zip/node_modules/ms/",\ "packageLocation": "./.yarn/cache/ms-npm-2.0.0-9e1101a471-de027828fc.zip/node_modules/ms/",\
@@ -14261,6 +14341,16 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\ "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", [\ ["schema-utils", [\
["npm:3.1.2", {\ ["npm:3.1.2", {\
"packageLocation": "./.yarn/cache/schema-utils-npm-3.1.2-d97c6dc247-11d35f997e.zip/node_modules/schema-utils/",\ "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"\ "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", [\ ["spawn-please", [\
["npm:2.0.1", {\ ["npm:2.0.1", {\
"packageLocation": "./.yarn/cache/spawn-please-npm-2.0.1-265b6b5432-fe19a7ceb5.zip/node_modules/spawn-please/",\ "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"]\ ["tr46", "npm:0.0.3"]\
],\ ],\
"linkType": "HARD"\ "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", [\ ["treeverse", [\
@@ -15769,6 +15877,98 @@ const RAW_RUNTIME_STATE =
],\ ],\
"linkType": "HARD"\ "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", {\ ["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/",\ "packageLocation": "./.yarn/__virtual__/typeorm-virtual-fc9b7b780b/0/cache/typeorm-npm-0.3.16-5ac12a7afc-19803f935e.zip/node_modules/typeorm/",\
"packageDependencies": [\ "packageDependencies": [\
@@ -16203,6 +16403,13 @@ const RAW_RUNTIME_STATE =
["webidl-conversions", "npm:3.0.1"]\ ["webidl-conversions", "npm:3.0.1"]\
],\ ],\
"linkType": "HARD"\ "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", [\ ["webpack", [\
@@ -16261,6 +16468,15 @@ const RAW_RUNTIME_STATE =
}]\ }]\
]],\ ]],\
["whatwg-url", [\ ["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", {\ ["npm:5.0.0", {\
"packageLocation": "./.yarn/cache/whatwg-url-npm-5.0.0-374fb45e60-bd0cc6b75b.zip/node_modules/whatwg-url/",\ "packageLocation": "./.yarn/cache/whatwg-url-npm-5.0.0-374fb45e60-bd0cc6b75b.zip/node_modules/whatwg-url/",\
"packageDependencies": [\ "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.
+16
View File
@@ -23,6 +23,7 @@ services:
environment: environment:
DB_TYPE: "${DB_TYPE}" DB_TYPE: "${DB_TYPE}"
CACHE_TYPE: "${CACHE_TYPE}" CACHE_TYPE: "${CACHE_TYPE}"
SECONDARY_DB_ENABLED: "${SECONDARY_DB_ENABLED}"
container_name: server-ci container_name: server-ci
ports: ports:
- 3123:3000 - 3123:3000
@@ -61,6 +62,21 @@ services:
networks: networks:
- standardnotes_self_hosted - 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: cache:
image: redis:6.0-alpine image: redis:6.0-alpine
container_name: cache-ci container_name: cache-ci
+1
View File
@@ -3,6 +3,7 @@ services:
image: standardnotes/server image: standardnotes/server
env_file: .env env_file: .env
container_name: server_self_hosted container_name: server_self_hosted
restart: unless-stopped
ports: ports:
- 3000:3000 - 3000:3000
- 3125:3104 - 3125:3104
+3
View File
@@ -63,6 +63,9 @@ fi
if [ -z "$CACHE_TYPE" ]; then if [ -z "$CACHE_TYPE" ]; then
export CACHE_TYPE="redis" export CACHE_TYPE="redis"
fi fi
if [ -z "$SECONDARY_DB_ENABLED" ]; then
export SECONDARY_DB_ENABLED=false
fi
export DB_MIGRATIONS_PATH="dist/migrations/*.js" export DB_MIGRATIONS_PATH="dist/migrations/*.js"
######### #########
+4 -1
View File
@@ -12,12 +12,15 @@
}, },
"scripts": { "scripts": {
"lint": "yarn workspaces foreach -p -j 10 --verbose run lint", "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", "clean": "yarn workspaces foreach -p --verbose run clean",
"setup:env": "cp .env.sample .env && yarn workspaces foreach -p --verbose run setup:env", "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\"", "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", "publish": "lerna publish from-git --yes --no-verify-access --loglevel verbose",
"postversion": "./scripts/push-tags-one-by-one.sh", "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": { "devDependencies": {
"@commitlint/cli": "^17.0.2", "@commitlint/cli": "^17.0.2",
+90
View File
@@ -3,6 +3,96 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.25.13](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.12...@standardnotes/analytics@2.25.13) (2023-08-11)
**Note:** Version bump only for package @standardnotes/analytics
## [2.25.12](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.11...@standardnotes/analytics@2.25.12) (2023-08-09)
**Note:** Version bump only for package @standardnotes/analytics
## [2.25.11](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.10...@standardnotes/analytics@2.25.11) (2023-08-09)
**Note:** Version bump only for package @standardnotes/analytics
## [2.25.10](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.9...@standardnotes/analytics@2.25.10) (2023-08-09)
**Note:** Version bump only for package @standardnotes/analytics
## [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) ## [2.24.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.24.0...@standardnotes/analytics@2.24.1) (2023-06-02)
### Bug Fixes ### Bug Fixes
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@standardnotes/analytics", "name": "@standardnotes/analytics",
"version": "2.24.1", "version": "2.25.13",
"engines": { "engines": {
"node": ">=18.0.0 <21.0.0" "node": ">=18.0.0 <21.0.0"
}, },
@@ -3,10 +3,6 @@ import { Result, Entity, UniqueEntityId } from '@standardnotes/domain-core'
import { StatisticMeasureProps } from './StatisticMeasureProps' import { StatisticMeasureProps } from './StatisticMeasureProps'
export class StatisticMeasure extends Entity<StatisticMeasureProps> { export class StatisticMeasure extends Entity<StatisticMeasureProps> {
get id(): UniqueEntityId {
return this._id
}
get name(): string { get name(): string {
return this.props.name.value return this.props.name.value
} }
@@ -3,10 +3,6 @@ import { Entity, Result, UniqueEntityId } from '@standardnotes/domain-core'
import { SubscriptionProps } from './SubscriptionProps' import { SubscriptionProps } from './SubscriptionProps'
export class Subscription extends Entity<SubscriptionProps> { export class Subscription extends Entity<SubscriptionProps> {
get id(): UniqueEntityId {
return this._id
}
private constructor(props: SubscriptionProps, id?: UniqueEntityId) { private constructor(props: SubscriptionProps, id?: UniqueEntityId) {
super(props, id) super(props, id)
} }
@@ -3,10 +3,6 @@ import { Entity, Result, UniqueEntityId } from '@standardnotes/domain-core'
import { UserProps } from './UserProps' import { UserProps } from './UserProps'
export class User extends Entity<UserProps> { export class User extends Entity<UserProps> {
get id(): UniqueEntityId {
return this._id
}
private constructor(props: UserProps, id?: UniqueEntityId) { private constructor(props: UserProps, id?: UniqueEntityId) {
super(props, id) super(props, id)
} }
+1
View File
@@ -1,3 +1,4 @@
MODE=microservice # microservice | home-server
LOG_LEVEL=debug LOG_LEVEL=debug
NODE_ENV=development NODE_ENV=development
VERSION=development VERSION=development
+144
View File
@@ -3,6 +3,150 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.70.4](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.70.3...@standardnotes/api-gateway@1.70.4) (2023-08-09)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.70.3](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.70.2...@standardnotes/api-gateway@1.70.3) (2023-08-09)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.70.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.70.1...@standardnotes/api-gateway@1.70.2) (2023-08-09)
**Note:** Version bump only for package @standardnotes/api-gateway
## [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) ## [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 ### Bug Fixes
+29 -24
View File
@@ -16,6 +16,10 @@ import '../src/Controller/v1/OfflineController'
import '../src/Controller/v1/FilesController' import '../src/Controller/v1/FilesController'
import '../src/Controller/v1/SubscriptionInvitesController' import '../src/Controller/v1/SubscriptionInvitesController'
import '../src/Controller/v1/AuthenticatorsController' 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/PaymentsControllerV2'
import '../src/Controller/v2/ActionsControllerV2' import '../src/Controller/v2/ActionsControllerV2'
@@ -42,31 +46,32 @@ void container.load().then((container) => {
server.setConfig((app) => { server.setConfig((app) => {
app.use((_request: Request, response: Response, next: NextFunction) => { 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() next()
}) })
/* eslint-disable */ app.use(
app.use(helmet({ helmet({
contentSecurityPolicy: { contentSecurityPolicy: {
directives: { directives: {
defaultSrc: ["https: 'self'"], defaultSrc: ["https: 'self'"],
baseUri: ["'self'"], baseUri: ["'self'"],
childSrc: ["*", "blob:"], childSrc: ['*', 'blob:'],
connectSrc: ["*"], connectSrc: ['*'],
fontSrc: ["*", "'self'"], fontSrc: ['*', "'self'"],
formAction: ["'self'"], formAction: ["'self'"],
frameAncestors: ["*", "*.standardnotes.org", "*.standardnotes.com"], frameAncestors: ['*', '*.standardnotes.org', '*.standardnotes.com'],
frameSrc: ["*", "blob:"], frameSrc: ['*', 'blob:'],
imgSrc: ["'self'", "*", "data:"], imgSrc: ["'self'", '*', 'data:'],
manifestSrc: ["'self'"], manifestSrc: ["'self'"],
mediaSrc: ["'self'"], mediaSrc: ["'self'"],
objectSrc: ["'self'"], objectSrc: ["'self'"],
scriptSrc: ["'self'"], scriptSrc: ["'self'"],
styleSrc: ["'self'"] styleSrc: ["'self'"],
} },
} },
})) }),
/* eslint-enable */ )
app.use(json({ limit: '50mb' })) app.use(json({ limit: '50mb' }))
app.use( app.use(
text({ 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) => { server.setErrorConfig((app) => {
app.use((error: Record<string, unknown>, _request: Request, response: Response, _next: NextFunction) => { app.use((error: Record<string, unknown>, _request: Request, response: Response, _next: NextFunction) => {
+2 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@standardnotes/api-gateway", "name": "@standardnotes/api-gateway",
"version": "1.63.2", "version": "1.70.4",
"engines": { "engines": {
"node": ">=18.0.0 <21.0.0" "node": ">=18.0.0 <21.0.0"
}, },
@@ -21,6 +21,7 @@
"clean": "rm -fr dist", "clean": "rm -fr dist",
"build": "tsc --build", "build": "tsc --build",
"lint": "eslint . --ext .ts", "lint": "eslint . --ext .ts",
"lint:fix": "eslint . --fix --ext .ts",
"setup:env": "cp .env.sample .env", "setup:env": "cp .env.sample .env",
"start": "yarn node dist/bin/server.js", "start": "yarn node dist/bin/server.js",
"upgrade:snjs": "yarn ncu -u '@standardnotes/*'" "upgrade:snjs": "yarn ncu -u '@standardnotes/*'"
+39 -30
View File
@@ -34,7 +34,8 @@ export class ContainerConfigLoader {
const container = new Container() 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()] const winstonFormatters = [winston.format.splat(), winston.format.json()]
if (env.get('NEW_RELIC_ENABLED', true) === 'true') { if (env.get('NEW_RELIC_ENABLED', true) === 'true') {
@@ -45,19 +46,20 @@ export class ContainerConfigLoader {
winstonFormatters.push(newrelicWinstonFormatter()) winstonFormatters.push(newrelicWinstonFormatter())
} }
let logger: winston.Logger
if (configuration?.logger) { if (configuration?.logger) {
container.bind<winston.Logger>(TYPES.Logger).toConstantValue(configuration.logger as winston.Logger) logger = configuration.logger as winston.Logger
} else { } else {
const logger = winston.createLogger({ logger = winston.createLogger({
level: env.get('LOG_LEVEL', true) || 'info', level: env.get('LOG_LEVEL', true) || 'info',
format: winston.format.combine(...winstonFormatters), format: winston.format.combine(...winstonFormatters),
transports: [new winston.transports.Console({ level: env.get('LOG_LEVEL', true) || 'info' })], transports: [new winston.transports.Console({ level: env.get('LOG_LEVEL', true) || 'info' })],
defaultMeta: { service: 'api-gateway' }, 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 redisUrl = env.get('REDIS_URL')
const isRedisInClusterMode = redisUrl.indexOf(',') > 0 const isRedisInClusterMode = redisUrl.indexOf(',') > 0
let redis let redis
@@ -66,36 +68,39 @@ export class ContainerConfigLoader {
} else { } else {
redis = new Redis(redisUrl) 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 // env vars
container.bind(TYPES.SYNCING_SERVER_JS_URL).toConstantValue(env.get('SYNCING_SERVER_JS_URL', true)) container.bind(TYPES.ApiGateway_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.ApiGateway_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.ApiGateway_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.ApiGateway_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.ApiGateway_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.ApiGateway_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.ApiGateway_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_AUTH_JWT_SECRET).toConstantValue(env.get('AUTH_JWT_SECRET'))
container 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) .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.ApiGateway_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_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 // Middleware
container container
.bind<RequiredCrossServiceTokenMiddleware>(TYPES.RequiredCrossServiceTokenMiddleware) .bind<RequiredCrossServiceTokenMiddleware>(TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
.to(RequiredCrossServiceTokenMiddleware) .to(RequiredCrossServiceTokenMiddleware)
container container
.bind<OptionalCrossServiceTokenMiddleware>(TYPES.OptionalCrossServiceTokenMiddleware) .bind<OptionalCrossServiceTokenMiddleware>(TYPES.ApiGateway_OptionalCrossServiceTokenMiddleware)
.to(OptionalCrossServiceTokenMiddleware) .to(OptionalCrossServiceTokenMiddleware)
container.bind<WebSocketAuthMiddleware>(TYPES.WebSocketAuthMiddleware).to(WebSocketAuthMiddleware) container.bind<WebSocketAuthMiddleware>(TYPES.ApiGateway_WebSocketAuthMiddleware).to(WebSocketAuthMiddleware)
container container
.bind<SubscriptionTokenAuthMiddleware>(TYPES.SubscriptionTokenAuthMiddleware) .bind<SubscriptionTokenAuthMiddleware>(TYPES.ApiGateway_SubscriptionTokenAuthMiddleware)
.to(SubscriptionTokenAuthMiddleware) .to(SubscriptionTokenAuthMiddleware)
// Services // Services
@@ -104,26 +109,30 @@ export class ContainerConfigLoader {
throw new Error('Service container is required when configured for home server') throw new Error('Service container is required when configured for home server')
} }
container container
.bind<ServiceProxyInterface>(TYPES.ServiceProxy) .bind<ServiceProxyInterface>(TYPES.ApiGateway_ServiceProxy)
.toConstantValue( .toConstantValue(
new DirectCallServiceProxy(configuration.serviceContainer, container.get(TYPES.FILES_SERVER_URL)), new DirectCallServiceProxy(configuration.serviceContainer, container.get(TYPES.ApiGateway_FILES_SERVER_URL)),
) )
} else { } 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) { if (isConfiguredForHomeServer) {
container container
.bind<CrossServiceTokenCacheInterface>(TYPES.CrossServiceTokenCache) .bind<CrossServiceTokenCacheInterface>(TYPES.ApiGateway_CrossServiceTokenCache)
.toConstantValue(new InMemoryCrossServiceTokenCache(container.get(TYPES.Timer))) .toConstantValue(new InMemoryCrossServiceTokenCache(container.get(TYPES.ApiGateway_Timer)))
} else { } else {
container.bind<CrossServiceTokenCacheInterface>(TYPES.CrossServiceTokenCache).to(RedisCrossServiceTokenCache) container
.bind<CrossServiceTokenCacheInterface>(TYPES.ApiGateway_CrossServiceTokenCache)
.to(RedisCrossServiceTokenCache)
} }
container container
.bind<EndpointResolverInterface>(TYPES.EndpointResolver) .bind<EndpointResolverInterface>(TYPES.ApiGateway_EndpointResolver)
.toConstantValue(new EndpointResolver(isConfiguredForHomeServer)) .toConstantValue(new EndpointResolver(isConfiguredForHomeServer))
logger.debug('Configuration complete')
return container return container
} }
} }
+23 -24
View File
@@ -1,29 +1,28 @@
export const TYPES = { export const TYPES = {
Logger: Symbol.for('Logger'), ApiGateway_Logger: Symbol.for('ApiGateway_Logger'),
Redis: Symbol.for('Redis'), ApiGateway_Redis: Symbol.for('ApiGateway_Redis'),
HTTPClient: Symbol.for('HTTPClient'), ApiGateway_HTTPClient: Symbol.for('ApiGateway_HTTPClient'),
// env vars // env vars
SYNCING_SERVER_JS_URL: Symbol.for('SYNCING_SERVER_JS_URL'), ApiGateway_SYNCING_SERVER_JS_URL: Symbol.for('ApiGateway_SYNCING_SERVER_JS_URL'),
AUTH_SERVER_URL: Symbol.for('AUTH_SERVER_URL'), ApiGateway_AUTH_SERVER_URL: Symbol.for('ApiGateway_AUTH_SERVER_URL'),
PAYMENTS_SERVER_URL: Symbol.for('PAYMENTS_SERVER_URL'), ApiGateway_PAYMENTS_SERVER_URL: Symbol.for('ApiGateway_PAYMENTS_SERVER_URL'),
FILES_SERVER_URL: Symbol.for('FILES_SERVER_URL'), ApiGateway_FILES_SERVER_URL: Symbol.for('ApiGateway_FILES_SERVER_URL'),
REVISIONS_SERVER_URL: Symbol.for('REVISIONS_SERVER_URL'), ApiGateway_REVISIONS_SERVER_URL: Symbol.for('ApiGateway_REVISIONS_SERVER_URL'),
EMAIL_SERVER_URL: Symbol.for('EMAIL_SERVER_URL'), ApiGateway_EMAIL_SERVER_URL: Symbol.for('ApiGateway_EMAIL_SERVER_URL'),
WEB_SOCKET_SERVER_URL: Symbol.for('WEB_SOCKET_SERVER_URL'), ApiGateway_WEB_SOCKET_SERVER_URL: Symbol.for('ApiGateway_WEB_SOCKET_SERVER_URL'),
AUTH_JWT_SECRET: Symbol.for('AUTH_JWT_SECRET'), ApiGateway_AUTH_JWT_SECRET: Symbol.for('ApiGateway_AUTH_JWT_SECRET'),
HTTP_CALL_TIMEOUT: Symbol.for('HTTP_CALL_TIMEOUT'), ApiGateway_HTTP_CALL_TIMEOUT: Symbol.for('ApiGateway_HTTP_CALL_TIMEOUT'),
VERSION: Symbol.for('VERSION'), ApiGateway_VERSION: Symbol.for('ApiGateway_VERSION'),
CROSS_SERVICE_TOKEN_CACHE_TTL: Symbol.for('CROSS_SERVICE_TOKEN_CACHE_TTL'), 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 // Middleware
RequiredCrossServiceTokenMiddleware: Symbol.for('RequiredCrossServiceTokenMiddleware'), ApiGateway_RequiredCrossServiceTokenMiddleware: Symbol.for('ApiGateway_RequiredCrossServiceTokenMiddleware'),
OptionalCrossServiceTokenMiddleware: Symbol.for('OptionalCrossServiceTokenMiddleware'), ApiGateway_OptionalCrossServiceTokenMiddleware: Symbol.for('ApiGateway_OptionalCrossServiceTokenMiddleware'),
WebSocketAuthMiddleware: Symbol.for('WebSocketAuthMiddleware'), ApiGateway_WebSocketAuthMiddleware: Symbol.for('ApiGateway_WebSocketAuthMiddleware'),
SubscriptionTokenAuthMiddleware: Symbol.for('SubscriptionTokenAuthMiddleware'), ApiGateway_SubscriptionTokenAuthMiddleware: Symbol.for('ApiGateway_SubscriptionTokenAuthMiddleware'),
// Services // Services
ServiceProxy: Symbol.for('ServiceProxy'), ApiGateway_ServiceProxy: Symbol.for('ApiGateway_ServiceProxy'),
CrossServiceTokenCache: Symbol.for('CrossServiceTokenCache'), ApiGateway_CrossServiceTokenCache: Symbol.for('ApiGateway_CrossServiceTokenCache'),
Timer: Symbol.for('Timer'), ApiGateway_Timer: Symbol.for('ApiGateway_Timer'),
EndpointResolver: Symbol.for('EndpointResolver'), ApiGateway_EndpointResolver: Symbol.for('ApiGateway_EndpointResolver'),
} }
// export default TYPES
@@ -1,5 +1,4 @@
import { CrossServiceTokenData } from '@standardnotes/security' import { CrossServiceTokenData } from '@standardnotes/security'
import { RoleName } from '@standardnotes/domain-core'
import { TimerInterface } from '@standardnotes/time' import { TimerInterface } from '@standardnotes/time'
import { NextFunction, Request, Response } from 'express' import { NextFunction, Request, Response } from 'express'
import { BaseMiddleware } from 'inversify-express-utils' import { BaseMiddleware } from 'inversify-express-utils'
@@ -17,7 +16,7 @@ export abstract class AuthMiddleware extends BaseMiddleware {
private crossServiceTokenCacheTTL: number, private crossServiceTokenCacheTTL: number,
private crossServiceTokenCache: CrossServiceTokenCacheInterface, private crossServiceTokenCache: CrossServiceTokenCacheInterface,
private timer: TimerInterface, private timer: TimerInterface,
private logger: Logger, protected logger: Logger,
) { ) {
super() super()
} }
@@ -51,10 +50,6 @@ export abstract class AuthMiddleware extends BaseMiddleware {
const decodedToken = <CrossServiceTokenData>verify(crossServiceToken, this.jwtSecret, { algorithms: ['HS256'] }) 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) { if (this.crossServiceTokenCacheTTL && !crossServiceTokenFetchedFromCache) {
await this.crossServiceTokenCache.set({ await this.crossServiceTokenCache.set({
authorizationHeaderValue: authHeaderValue, authorizationHeaderValue: authHeaderValue,
@@ -9,7 +9,7 @@ export class LegacyController extends BaseHttpController {
private AUTH_ROUTES: Map<string, string> private AUTH_ROUTES: Map<string, string>
private PARAMETRIZED_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() super()
this.AUTH_ROUTES = new Map([ 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> { async legacyItemsSync(request: Request, response: Response): Promise<void> {
await this.httpService.callLegacySyncingServer(request, response, request.path.substring(1), request.body) 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> { async legacyGetRevisions(request: Request, response: Response): Promise<void> {
await this.httpService.callLegacySyncingServer(request, response, request.path.substring(1), request.body) 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> { async legacyGetRevision(request: Request, response: Response): Promise<void> {
await this.httpService.callLegacySyncingServer(request, response, request.path.substring(1), request.body) await this.httpService.callLegacySyncingServer(request, response, request.path.substring(1), request.body)
} }
@@ -11,12 +11,12 @@ import { AuthMiddleware } from './AuthMiddleware'
@injectable() @injectable()
export class OptionalCrossServiceTokenMiddleware extends AuthMiddleware { export class OptionalCrossServiceTokenMiddleware extends AuthMiddleware {
constructor( constructor(
@inject(TYPES.ServiceProxy) serviceProxy: ServiceProxyInterface, @inject(TYPES.ApiGateway_ServiceProxy) serviceProxy: ServiceProxyInterface,
@inject(TYPES.AUTH_JWT_SECRET) jwtSecret: string, @inject(TYPES.ApiGateway_AUTH_JWT_SECRET) jwtSecret: string,
@inject(TYPES.CROSS_SERVICE_TOKEN_CACHE_TTL) crossServiceTokenCacheTTL: number, @inject(TYPES.ApiGateway_CROSS_SERVICE_TOKEN_CACHE_TTL) crossServiceTokenCacheTTL: number,
@inject(TYPES.CrossServiceTokenCache) crossServiceTokenCache: CrossServiceTokenCacheInterface, @inject(TYPES.ApiGateway_CrossServiceTokenCache) crossServiceTokenCache: CrossServiceTokenCacheInterface,
@inject(TYPES.Timer) timer: TimerInterface, @inject(TYPES.ApiGateway_Timer) timer: TimerInterface,
@inject(TYPES.Logger) logger: Logger, @inject(TYPES.ApiGateway_Logger) logger: Logger,
) { ) {
super(serviceProxy, jwtSecret, crossServiceTokenCacheTTL, crossServiceTokenCache, timer, logger) super(serviceProxy, jwtSecret, crossServiceTokenCacheTTL, crossServiceTokenCache, timer, logger)
} }
@@ -11,12 +11,12 @@ import { AuthMiddleware } from './AuthMiddleware'
@injectable() @injectable()
export class RequiredCrossServiceTokenMiddleware extends AuthMiddleware { export class RequiredCrossServiceTokenMiddleware extends AuthMiddleware {
constructor( constructor(
@inject(TYPES.ServiceProxy) serviceProxy: ServiceProxyInterface, @inject(TYPES.ApiGateway_ServiceProxy) serviceProxy: ServiceProxyInterface,
@inject(TYPES.AUTH_JWT_SECRET) jwtSecret: string, @inject(TYPES.ApiGateway_AUTH_JWT_SECRET) jwtSecret: string,
@inject(TYPES.CROSS_SERVICE_TOKEN_CACHE_TTL) crossServiceTokenCacheTTL: number, @inject(TYPES.ApiGateway_CROSS_SERVICE_TOKEN_CACHE_TTL) crossServiceTokenCacheTTL: number,
@inject(TYPES.CrossServiceTokenCache) crossServiceTokenCache: CrossServiceTokenCacheInterface, @inject(TYPES.ApiGateway_CrossServiceTokenCache) crossServiceTokenCache: CrossServiceTokenCacheInterface,
@inject(TYPES.Timer) timer: TimerInterface, @inject(TYPES.ApiGateway_Timer) timer: TimerInterface,
@inject(TYPES.Logger) logger: Logger, @inject(TYPES.ApiGateway_Logger) logger: Logger,
) { ) {
super(serviceProxy, jwtSecret, crossServiceTokenCacheTTL, crossServiceTokenCache, timer, logger) super(serviceProxy, jwtSecret, crossServiceTokenCacheTTL, crossServiceTokenCache, timer, logger)
} }
@@ -42,6 +42,8 @@ export class RequiredCrossServiceTokenMiddleware extends AuthMiddleware {
_next: NextFunction, _next: NextFunction,
): boolean { ): boolean {
if (!authHeaderValue) { if (!authHeaderValue) {
this.logger.debug('Missing auth header')
response.status(401).send({ response.status(401).send({
error: { error: {
tag: 'invalid-auth', tag: 'invalid-auth',
@@ -11,10 +11,10 @@ import { TokenAuthenticationMethod } from './TokenAuthenticationMethod'
@injectable() @injectable()
export class SubscriptionTokenAuthMiddleware extends BaseMiddleware { export class SubscriptionTokenAuthMiddleware extends BaseMiddleware {
constructor( constructor(
@inject(TYPES.HTTPClient) private httpClient: AxiosInstance, @inject(TYPES.ApiGateway_HTTPClient) private httpClient: AxiosInstance,
@inject(TYPES.AUTH_SERVER_URL) private authServerUrl: string, @inject(TYPES.ApiGateway_AUTH_SERVER_URL) private authServerUrl: string,
@inject(TYPES.AUTH_JWT_SECRET) private jwtSecret: string, @inject(TYPES.ApiGateway_AUTH_JWT_SECRET) private jwtSecret: string,
@inject(TYPES.Logger) private logger: Logger, @inject(TYPES.ApiGateway_Logger) private logger: Logger,
) { ) {
super() super()
} }
@@ -1,5 +1,4 @@
import { CrossServiceTokenData } from '@standardnotes/security' import { CrossServiceTokenData } from '@standardnotes/security'
import { RoleName } from '@standardnotes/domain-core'
import { NextFunction, Request, Response } from 'express' import { NextFunction, Request, Response } from 'express'
import { inject, injectable } from 'inversify' import { inject, injectable } from 'inversify'
import { BaseMiddleware } from 'inversify-express-utils' import { BaseMiddleware } from 'inversify-express-utils'
@@ -12,10 +11,10 @@ import { TYPES } from '../Bootstrap/Types'
@injectable() @injectable()
export class WebSocketAuthMiddleware extends BaseMiddleware { export class WebSocketAuthMiddleware extends BaseMiddleware {
constructor( constructor(
@inject(TYPES.HTTPClient) private httpClient: AxiosInstance, @inject(TYPES.ApiGateway_HTTPClient) private httpClient: AxiosInstance,
@inject(TYPES.AUTH_SERVER_URL) private authServerUrl: string, @inject(TYPES.ApiGateway_AUTH_SERVER_URL) private authServerUrl: string,
@inject(TYPES.AUTH_JWT_SECRET) private jwtSecret: string, @inject(TYPES.ApiGateway_AUTH_JWT_SECRET) private jwtSecret: string,
@inject(TYPES.Logger) private logger: Logger, @inject(TYPES.ApiGateway_Logger) private logger: Logger,
) { ) {
super() super()
} }
@@ -60,9 +59,6 @@ export class WebSocketAuthMiddleware extends BaseMiddleware {
const decodedToken = <CrossServiceTokenData>verify(crossServiceToken, this.jwtSecret, { algorithms: ['HS256'] }) 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.user = decodedToken.user
response.locals.roles = decodedToken.roles response.locals.roles = decodedToken.roles
} catch (error) { } catch (error) {
@@ -4,6 +4,7 @@ export * from './SubscriptionTokenAuthMiddleware'
export * from './TokenAuthenticationMethod' export * from './TokenAuthenticationMethod'
export * from './WebSocketAuthMiddleware' export * from './WebSocketAuthMiddleware'
export * from './v1/ActionsController' export * from './v1/ActionsController'
export * from './v1/MessagesController'
export * from './v1/AuthenticatorsController' export * from './v1/AuthenticatorsController'
export * from './v1/FilesController' export * from './v1/FilesController'
export * from './v1/InvoicesController' export * from './v1/InvoicesController'
@@ -12,6 +13,9 @@ export * from './v1/OfflineController'
export * from './v1/PaymentsController' export * from './v1/PaymentsController'
export * from './v1/RevisionsController' export * from './v1/RevisionsController'
export * from './v1/SessionsController' export * from './v1/SessionsController'
export * from './v1/SharedVaultInvitesController'
export * from './v1/SharedVaultUsersController'
export * from './v1/SharedVaultsController'
export * from './v1/SubscriptionInvitesController' export * from './v1/SubscriptionInvitesController'
export * from './v1/TokensController' export * from './v1/TokensController'
export * from './v1/UsersController' export * from './v1/UsersController'
@@ -8,8 +8,8 @@ import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolv
@controller('/v1') @controller('/v1')
export class ActionsController extends BaseHttpController { export class ActionsController extends BaseHttpController {
constructor( constructor(
@inject(TYPES.ServiceProxy) private serviceProxy: ServiceProxyInterface, @inject(TYPES.ApiGateway_ServiceProxy) private serviceProxy: ServiceProxyInterface,
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface, @inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
) { ) {
super() 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> { async loginParams(request: Request, response: Response): Promise<void> {
await this.serviceProxy.callAuthServer( await this.serviceProxy.callAuthServer(
request, 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> { async logout(request: Request, response: Response): Promise<void> {
await this.serviceProxy.callAuthServer( await this.serviceProxy.callAuthServer(
request, 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> { async recoveryCodes(request: Request, response: Response): Promise<void> {
await this.serviceProxy.callAuthServer( await this.serviceProxy.callAuthServer(
request, request,
@@ -9,13 +9,13 @@ import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolv
@controller('/v1/authenticators') @controller('/v1/authenticators')
export class AuthenticatorsController extends BaseHttpController { export class AuthenticatorsController extends BaseHttpController {
constructor( constructor(
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface, @inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface, @inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
) { ) {
super() super()
} }
@httpDelete('/:authenticatorId', TYPES.RequiredCrossServiceTokenMiddleware) @httpDelete('/:authenticatorId', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async delete(request: Request, response: Response): Promise<void> { async delete(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, 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> { async list(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, 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> { async generateRegistrationOptions(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, 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> { async verifyRegistration(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, request,
@@ -9,13 +9,13 @@ import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolv
@controller('/v1/files') @controller('/v1/files')
export class FilesController extends BaseHttpController { export class FilesController extends BaseHttpController {
constructor( constructor(
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface, @inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface, @inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
) { ) {
super() super()
} }
@httpPost('/valet-tokens', TYPES.RequiredCrossServiceTokenMiddleware) @httpPost('/valet-tokens', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async createToken(request: Request, response: Response): Promise<void> { async createToken(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, request,
@@ -6,11 +6,11 @@ import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
@controller('/v1') @controller('/v1')
export class InvoicesController extends BaseHttpController { export class InvoicesController extends BaseHttpController {
constructor(@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface) { constructor(@inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface) {
super() super()
} }
@httpPost('/invoices/send-latest', TYPES.SubscriptionTokenAuthMiddleware) @httpPost('/invoices/send-latest', TYPES.ApiGateway_SubscriptionTokenAuthMiddleware)
async sendLatestInvoice(request: Request, response: Response): Promise<void> { async sendLatestInvoice(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer(request, response, 'api/pro_users/send-invoice', request.body) await this.httpService.callPaymentsServer(request, response, 'api/pro_users/send-invoice', request.body)
} }
@@ -5,11 +5,11 @@ import { TYPES } from '../../Bootstrap/Types'
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface' import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface' import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
@controller('/v1/items', TYPES.RequiredCrossServiceTokenMiddleware) @controller('/v1/items', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
export class ItemsController extends BaseHttpController { export class ItemsController extends BaseHttpController {
constructor( constructor(
@inject(TYPES.ServiceProxy) private serviceProxy: ServiceProxyInterface, @inject(TYPES.ApiGateway_ServiceProxy) private serviceProxy: ServiceProxyInterface,
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface, @inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
) { ) {
super() super()
} }
@@ -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,
)
}
}
@@ -9,8 +9,8 @@ import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolv
@controller('/v1/offline') @controller('/v1/offline')
export class OfflineController extends BaseHttpController { export class OfflineController extends BaseHttpController {
constructor( constructor(
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface, @inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface, @inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
) { ) {
super() super()
} }
@@ -6,7 +6,7 @@ import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
@controller('/v1') @controller('/v1')
export class PaymentsController extends BaseHttpController { export class PaymentsController extends BaseHttpController {
constructor(@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface) { constructor(@inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface) {
super() super()
} }
@@ -40,12 +40,12 @@ export class PaymentsController extends BaseHttpController {
await this.httpService.callPaymentsServer(request, response, 'api/extensions', request.body) 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> { async createTieredSubscription(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer(request, response, 'api/subscriptions/tiered', request.body) 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> { async appleIAPConfirm(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer(request, response, 'api/subscriptions/apple_iap_confirm', request.body) 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> { async createStripeSetupIntent(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer(request, response, 'api/pro_users/stripe-setup-intent', request.body) await this.httpService.callPaymentsServer(request, response, 'api/pro_users/stripe-setup-intent', request.body)
} }
@@ -1,7 +1,7 @@
import { BaseHttpController, controller, httpDelete, httpGet, results } from 'inversify-express-utils' import { BaseHttpController, controller, httpDelete, httpGet, results } from 'inversify-express-utils'
import { TYPES } from '../../Bootstrap/Types' 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 { export class RevisionsController extends BaseHttpController {
@httpGet('/') @httpGet('/')
async getRevisions(): Promise<results.JsonResult> { async getRevisions(): Promise<results.JsonResult> {
@@ -8,13 +8,13 @@ import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolv
@controller('/v1/sessions') @controller('/v1/sessions')
export class SessionsController extends BaseHttpController { export class SessionsController extends BaseHttpController {
constructor( constructor(
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface, @inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface, @inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
) { ) {
super() super()
} }
@httpGet('/', TYPES.RequiredCrossServiceTokenMiddleware) @httpGet('/', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async getSessions(request: Request, response: Response): Promise<void> { async getSessions(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, 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> { async deleteSession(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, 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> { async deleteSessions(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, request,
@@ -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,
)
}
}
@@ -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,
)
}
}
@@ -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,
)
}
}
@@ -9,13 +9,13 @@ import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolv
@controller('/v1/subscription-invites') @controller('/v1/subscription-invites')
export class SubscriptionInvitesController extends BaseHttpController { export class SubscriptionInvitesController extends BaseHttpController {
constructor( constructor(
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface, @inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface, @inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
) { ) {
super() super()
} }
@httpPost('/', TYPES.RequiredCrossServiceTokenMiddleware) @httpPost('/', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async inviteToSubscriptionSharing(request: Request, response: Response): Promise<void> { async inviteToSubscriptionSharing(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, 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> { async listInvites(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, 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> { async cancelSubscriptionSharing(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, 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> { async acceptInvite(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, request,
@@ -9,13 +9,13 @@ import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolv
@controller('/v1/subscription-tokens') @controller('/v1/subscription-tokens')
export class TokensController extends BaseHttpController { export class TokensController extends BaseHttpController {
constructor( constructor(
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface, @inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface, @inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
) { ) {
super() super()
} }
@httpPost('/', TYPES.RequiredCrossServiceTokenMiddleware) @httpPost('/', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async createToken(request: Request, response: Response): Promise<void> { async createToken(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, request,
@@ -20,9 +20,10 @@ import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolv
@controller('/v1/users') @controller('/v1/users')
export class UsersController extends BaseHttpController { export class UsersController extends BaseHttpController {
constructor( constructor(
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface, @inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface, @inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
@inject(TYPES.Logger) private logger: Logger, @inject(TYPES.ApiGateway_Logger) private logger: Logger,
@inject(TYPES.ApiGateway_IS_CONFIGURED_FOR_HOME_SERVER) private isConfiguredForHomeServer: boolean,
) { ) {
super() super()
} }
@@ -32,12 +33,12 @@ export class UsersController extends BaseHttpController {
await this.httpService.callPaymentsServer(request, response, 'api/pro_users/claim-account', request.body) 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> { async sendActivationCode(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer(request, response, 'api/pro_users/send-activation-code', request.body) 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> { async updateUser(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, 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> { async changePassword(request: Request, response: Response): Promise<void> {
this.logger.debug( this.logger.debug(
'[DEPRECATED] use endpoint /v1/users/:userUuid/attributes/credentials instead of /v1/users/:userUuid/password', '[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> { async changeCredentials(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, 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> { async getKeyParams(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, 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> { async blockMFA(): Promise<results.StatusCodeResult> {
return this.statusCode(401) 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> { async createListedAccount(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, 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> { async listSettings(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, 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> { async putSetting(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, 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> { async getSetting(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, 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> { async deleteSetting(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, 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> { async getSubscriptionSetting(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, 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> { async getFeatures(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, 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> { async getSubscription(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, 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> { async getSubscriptionBySubscriptionToken(request: Request, response: Response): Promise<void> {
if (response.locals.tokenAuthenticationMethod === TokenAuthenticationMethod.OfflineSubscriptionToken) { if (response.locals.tokenAuthenticationMethod === TokenAuthenticationMethod.OfflineSubscriptionToken) {
await this.httpService.callAuthServer( 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> { 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> { async submitRequest(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, request,
@@ -10,14 +10,14 @@ import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolv
@controller('/v1/sockets') @controller('/v1/sockets')
export class WebSocketsController extends BaseHttpController { export class WebSocketsController extends BaseHttpController {
constructor( constructor(
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface, @inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface, @inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
@inject(TYPES.Logger) private logger: Logger, @inject(TYPES.ApiGateway_Logger) private logger: Logger,
) { ) {
super() super()
} }
@httpPost('/tokens', TYPES.RequiredCrossServiceTokenMiddleware) @httpPost('/tokens', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async createWebSocketConnectionToken(request: Request, response: Response): Promise<void> { async createWebSocketConnectionToken(request: Request, response: Response): Promise<void> {
await this.httpService.callWebSocketServer( await this.httpService.callWebSocketServer(
request, 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> { async createWebSocketConnection(request: Request, response: Response): Promise<void> {
if (!request.headers.connectionid) { if (!request.headers.connectionid) {
this.logger.error('Could not create a websocket connection. Missing connection id header.') this.logger.error('Could not create a websocket connection. Missing connection id header.')
@@ -9,8 +9,8 @@ import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolv
@controller('/v2') @controller('/v2')
export class ActionsControllerV2 extends BaseHttpController { export class ActionsControllerV2 extends BaseHttpController {
constructor( constructor(
@inject(TYPES.ServiceProxy) private serviceProxy: ServiceProxyInterface, @inject(TYPES.ApiGateway_ServiceProxy) private serviceProxy: ServiceProxyInterface,
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface, @inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
) { ) {
super() 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> { async loginParams(request: Request, response: Response): Promise<void> {
await this.serviceProxy.callAuthServer( await this.serviceProxy.callAuthServer(
request, request,
@@ -6,7 +6,7 @@ import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
@controller('/v2') @controller('/v2')
export class PaymentsControllerV2 extends BaseHttpController { export class PaymentsControllerV2 extends BaseHttpController {
constructor(@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface) { constructor(@inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface) {
super() super()
} }
@@ -15,22 +15,22 @@ export class PaymentsControllerV2 extends BaseHttpController {
await this.httpService.callPaymentsServer(request, response, 'api/subscriptions/features', request.body) 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> { async getTailoredSubscriptionsWithFeatures(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer(request, response, 'api/subscriptions/features', request.body) 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> { async getSubscriptionDeltasForChangingPlan(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer(request, response, 'api/subscriptions/deltas', request.body) 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> { async applySubscriptionDelta(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer(request, response, 'api/subscriptions/deltas/apply', request.body) 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> { async changePaymentMethod(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer( await this.httpService.callPaymentsServer(
request, 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> { async getSubscription(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer( await this.httpService.callPaymentsServer(
request, 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> { async cancelSubscription(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer( await this.httpService.callPaymentsServer(
request, 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> { async updateSubscription(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer( await this.httpService.callPaymentsServer(
request, request,
@@ -6,11 +6,11 @@ import { TYPES } from '../../Bootstrap/Types'
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface' import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface' 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 { export class RevisionsControllerV2 extends BaseHttpController {
constructor( constructor(
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface, @inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface, @inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
) { ) {
super() super()
} }
@@ -9,7 +9,7 @@ export class RedisCrossServiceTokenCache implements CrossServiceTokenCacheInterf
private readonly PREFIX = 'cst' private readonly PREFIX = 'cst'
private readonly USER_CST_PREFIX = 'user-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: { async set(dto: {
authorizationHeaderValue: string authorizationHeaderValue: string
@@ -11,17 +11,17 @@ import { ServiceProxyInterface } from './ServiceProxyInterface'
@injectable() @injectable()
export class HttpServiceProxy implements ServiceProxyInterface { export class HttpServiceProxy implements ServiceProxyInterface {
constructor( constructor(
@inject(TYPES.HTTPClient) private httpClient: AxiosInstance, @inject(TYPES.ApiGateway_HTTPClient) private httpClient: AxiosInstance,
@inject(TYPES.AUTH_SERVER_URL) private authServerUrl: string, @inject(TYPES.ApiGateway_AUTH_SERVER_URL) private authServerUrl: string,
@inject(TYPES.SYNCING_SERVER_JS_URL) private syncingServerJsUrl: string, @inject(TYPES.ApiGateway_SYNCING_SERVER_JS_URL) private syncingServerJsUrl: string,
@inject(TYPES.PAYMENTS_SERVER_URL) private paymentsServerUrl: string, @inject(TYPES.ApiGateway_PAYMENTS_SERVER_URL) private paymentsServerUrl: string,
@inject(TYPES.FILES_SERVER_URL) private filesServerUrl: string, @inject(TYPES.ApiGateway_FILES_SERVER_URL) private filesServerUrl: string,
@inject(TYPES.WEB_SOCKET_SERVER_URL) private webSocketServerUrl: string, @inject(TYPES.ApiGateway_WEB_SOCKET_SERVER_URL) private webSocketServerUrl: string,
@inject(TYPES.REVISIONS_SERVER_URL) private revisionsServerUrl: string, @inject(TYPES.ApiGateway_REVISIONS_SERVER_URL) private revisionsServerUrl: string,
@inject(TYPES.EMAIL_SERVER_URL) private emailServerUrl: string, @inject(TYPES.ApiGateway_EMAIL_SERVER_URL) private emailServerUrl: string,
@inject(TYPES.HTTP_CALL_TIMEOUT) private httpCallTimeout: number, @inject(TYPES.ApiGateway_HTTP_CALL_TIMEOUT) private httpCallTimeout: number,
@inject(TYPES.CrossServiceTokenCache) private crossServiceTokenCache: CrossServiceTokenCacheInterface, @inject(TYPES.ApiGateway_CrossServiceTokenCache) private crossServiceTokenCache: CrossServiceTokenCacheInterface,
@inject(TYPES.Logger) private logger: Logger, @inject(TYPES.ApiGateway_Logger) private logger: Logger,
) {} ) {}
async validateSession( async validateSession(
@@ -130,19 +130,26 @@ export class HttpServiceProxy implements ServiceProxyInterface {
response: Response, response: Response,
endpointOrMethodIdentifier: string, endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string, payload?: Record<string, unknown> | string,
): Promise<void> { returnRawResponse?: boolean,
): Promise<void | Response<unknown, Record<string, unknown>>> {
if (!this.paymentsServerUrl) { if (!this.paymentsServerUrl) {
this.logger.debug('Payments Server URL not defined. Skipped request to Payments API.') this.logger.debug('Payments Server URL not defined. Skipped request to Payments API.')
return return
} }
await this.callServerWithLegacyFormat(
const rawResponse = await this.callServerWithLegacyFormat(
this.paymentsServerUrl, this.paymentsServerUrl,
request, request,
response, response,
endpointOrMethodIdentifier, endpointOrMethodIdentifier,
payload, payload,
returnRawResponse,
) )
if (returnRawResponse) {
return rawResponse
}
} }
async callAuthServerWithLegacyFormat( async callAuthServerWithLegacyFormat(
@@ -279,7 +286,8 @@ export class HttpServiceProxy implements ServiceProxyInterface {
response: Response, response: Response,
endpointOrMethodIdentifier: string, endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string, payload?: Record<string, unknown> | string,
): Promise<void> { returnRawResponse?: boolean,
): Promise<void | Response<unknown, Record<string, unknown>>> {
const serviceResponse = await this.getServerResponse( const serviceResponse = await this.getServerResponse(
serverUrl, serverUrl,
request, request,
@@ -295,9 +303,21 @@ export class HttpServiceProxy implements ServiceProxyInterface {
this.applyResponseHeaders(serviceResponse, response) this.applyResponseHeaders(serviceResponse, response)
if (serviceResponse.request._redirectable._redirectCount > 0) { 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 { } else {
response.status(serviceResponse.status).send(serviceResponse.data) response.status(serviceResponse.status)
if (returnRawResponse) {
return response
}
response.send(serviceResponse.data)
} }
} }
@@ -42,7 +42,8 @@ export interface ServiceProxyInterface {
response: Response, response: Response,
endpointOrMethodIdentifier: string, endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string, payload?: Record<string, unknown> | string,
): Promise<void> returnRawResponse?: boolean,
): Promise<void | Response<unknown, Record<string, unknown>>>
callWebSocketServer( callWebSocketServer(
request: Request, request: Request,
response: Response, response: Response,
@@ -1,7 +1,7 @@
import { Request, Response } from 'express' import { Request, Response } from 'express'
import { ServiceContainerInterface, ServiceIdentifier } from '@standardnotes/domain-core'
import { ServiceProxyInterface } from '../Http/ServiceProxyInterface' import { ServiceProxyInterface } from '../Http/ServiceProxyInterface'
import { ServiceContainerInterface, ServiceIdentifier } from '@standardnotes/domain-core'
export class DirectCallServiceProxy implements ServiceProxyInterface { export class DirectCallServiceProxy implements ServiceProxyInterface {
constructor(private serviceContainer: ServiceContainerInterface, private filesServerUrl: string) {} constructor(private serviceContainer: ServiceContainerInterface, private filesServerUrl: string) {}
@@ -34,8 +34,12 @@ export class DirectCallServiceProxy implements ServiceProxyInterface {
} }
} }
async callEmailServer(_request: Request, _response: Response, _endpointOrMethodIdentifier: string): Promise<void> { async callEmailServer(_request: Request, response: Response, _endpointOrMethodIdentifier: string): Promise<void> {
throw new Error('Email server is not available.') response.status(400).send({
error: {
message: 'Email server is not available.',
},
})
} }
async callAuthServer(request: never, response: never, endpointOrMethodIdentifier: string): Promise<void> { async callAuthServer(request: never, response: never, endpointOrMethodIdentifier: string): Promise<void> {
@@ -54,10 +58,14 @@ export class DirectCallServiceProxy implements ServiceProxyInterface {
async callAuthServerWithLegacyFormat( async callAuthServerWithLegacyFormat(
_request: Request, _request: Request,
_response: Response, response: Response,
_endpointOrMethodIdentifier: string, _endpointOrMethodIdentifier: string,
): Promise<void> { ): 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> { async callRevisionsServer(request: never, response: never, endpointOrMethodIdentifier: string): Promise<void> {
@@ -92,22 +100,30 @@ export class DirectCallServiceProxy implements ServiceProxyInterface {
async callLegacySyncingServer( async callLegacySyncingServer(
_request: Request, _request: Request,
_response: Response, response: Response,
_endpointOrMethodIdentifier: string, _endpointOrMethodIdentifier: string,
): Promise<void> { ): 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> { async callPaymentsServer(_request: Request, response: Response, _endpointOrMethodIdentifier: string): Promise<void> {
throw new Error('Payments server is not available.') response.status(400).send({
error: {
message: 'Payments server is not available.',
},
})
} }
async callWebSocketServer( async callWebSocketServer(_request: Request, response: Response, _endpointOrMethodIdentifier: string): Promise<void> {
_request: Request, response.status(400).send({
_response: Response, error: {
_endpointOrMethodIdentifier: string, message: 'Websockets server is not available.',
): Promise<void> { },
throw new Error('Websockets server is not available.') })
} }
private sendDecoratedResponse( private sendDecoratedResponse(
@@ -43,6 +43,7 @@ export class EndpointResolver implements EndpointResolverInterface {
['[PATCH]:users/:userId', 'auth.users.update'], ['[PATCH]:users/:userId', 'auth.users.update'],
['[PUT]:users/:userUuid/attributes/credentials', 'auth.users.updateCredentials'], ['[PUT]:users/:userUuid/attributes/credentials', 'auth.users.updateCredentials'],
['[PUT]:auth/params', 'auth.users.getKeyParams'], ['[PUT]:auth/params', 'auth.users.getKeyParams'],
['[DELETE]:users/:userUuid', 'auth.users.delete'],
['[POST]:listed', 'auth.users.createListedAccount'], ['[POST]:listed', 'auth.users.createListedAccount'],
['[POST]:auth', 'auth.users.register'], ['[POST]:auth', 'auth.users.register'],
['[GET]:users/:userUuid/settings', 'auth.users.getSettings'], ['[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', 'revisions.revisions.getRevisions'],
['[GET]:items/:itemUuid/revisions/:id', 'revisions.revisions.getRevision'], ['[GET]:items/:itemUuid/revisions/:id', 'revisions.revisions.getRevision'],
['[DELETE]:items/:itemUuid/revisions/:id', 'revisions.revisions.deleteRevision'], ['[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 { resolveEndpointOrMethodIdentifier(method: string, endpoint: string, ...params: string[]): string {
@@ -75,7 +102,7 @@ export class EndpointResolver implements EndpointResolverInterface {
const identifier = this.endpointToIdentifierMap.get(`[${method}]:${endpoint}`) const identifier = this.endpointToIdentifierMap.get(`[${method}]:${endpoint}`)
if (!identifier) { if (!identifier) {
throw new Error(`Endpoint ${endpoint} not found`) throw new Error(`Endpoint [${method}]:${endpoint} not found`)
} }
return identifier return identifier
+3
View File
@@ -1,3 +1,4 @@
MODE=microservice # microservice | home-server
LOG_LEVEL=debug LOG_LEVEL=debug
NODE_ENV=development NODE_ENV=development
VERSION=development VERSION=development
@@ -20,8 +21,10 @@ DB_USERNAME=auth
DB_PASSWORD=changeme123 DB_PASSWORD=changeme123
DB_DATABASE=auth DB_DATABASE=auth
DB_DEBUG_LEVEL=all # "all" | "query" | "schema" | "error" | "warn" | "info" | "log" | "migration" DB_DEBUG_LEVEL=all # "all" | "query" | "schema" | "error" | "warn" | "info" | "log" | "migration"
DB_TYPE=mysql
REDIS_URL=redis://cache REDIS_URL=redis://cache
CACHE_TYPE=redis
DISABLE_USER_REGISTRATION=false DISABLE_USER_REGISTRATION=false
+230
View File
@@ -3,6 +3,236 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.131.5](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.131.4...@standardnotes/auth-server@1.131.5) (2023-08-15)
### Bug Fixes
* **auth:** passing the invalidate cache header ([#697](https://github.com/standardnotes/server/issues/697)) ([83ad069](https://github.com/standardnotes/server/commit/83ad069c5dd9afa3a6db881f0d8a55a58d0642aa))
## [1.131.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.131.3...@standardnotes/auth-server@1.131.4) (2023-08-11)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.131.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.131.2...@standardnotes/auth-server@1.131.3) (2023-08-09)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.131.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.131.1...@standardnotes/auth-server@1.131.2) (2023-08-09)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.131.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.131.0...@standardnotes/auth-server@1.131.1) (2023-08-09)
**Note:** Version bump only for package @standardnotes/auth-server
# [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) ## [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 ### Bug Fixes
+18 -18
View File
@@ -1,23 +1,23 @@
import 'reflect-metadata' import 'reflect-metadata'
import '../src/Infra/InversifyExpressUtils/InversifyExpressAuthController' import '../src/Infra/InversifyExpressUtils/AnnotatedAuthController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressAuthenticatorsController' import '../src/Infra/InversifyExpressUtils/AnnotatedAuthenticatorsController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressSessionsController' import '../src/Infra/InversifyExpressUtils/AnnotatedSessionsController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressSubscriptionInvitesController' import '../src/Infra/InversifyExpressUtils/AnnotatedSubscriptionInvitesController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressUserRequestsController' import '../src/Infra/InversifyExpressUtils/AnnotatedUserRequestsController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressWebSocketsController' import '../src/Infra/InversifyExpressUtils/AnnotatedWebSocketsController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressUsersController' import '../src/Infra/InversifyExpressUtils/AnnotatedUsersController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressValetTokenController' import '../src/Infra/InversifyExpressUtils/AnnotatedValetTokenController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressAdminController' import '../src/Infra/InversifyExpressUtils/AnnotatedAdminController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressSubscriptionTokensController' import '../src/Infra/InversifyExpressUtils/AnnotatedSubscriptionTokensController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressSubscriptionSettingsController' import '../src/Infra/InversifyExpressUtils/AnnotatedSubscriptionSettingsController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressSettingsController' import '../src/Infra/InversifyExpressUtils/AnnotatedSettingsController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressSessionController' import '../src/Infra/InversifyExpressUtils/AnnotatedSessionController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressOfflineController' import '../src/Infra/InversifyExpressUtils/AnnotatedOfflineController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressListedController' import '../src/Infra/InversifyExpressUtils/AnnotatedListedController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressInternalController' import '../src/Infra/InversifyExpressUtils/AnnotatedInternalController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressHealthCheckController' import '../src/Infra/InversifyExpressUtils/AnnotatedHealthCheckController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressFeaturesController' import '../src/Infra/InversifyExpressUtils/AnnotatedFeaturesController'
import * as cors from 'cors' import * as cors from 'cors'
import { urlencoded, json, Request, Response, NextFunction } from 'express' import { urlencoded, json, Request, Response, NextFunction } from 'express'
Binary file not shown.
+7 -6
View File
@@ -1,6 +1,6 @@
{ {
"name": "@standardnotes/auth-server", "name": "@standardnotes/auth-server",
"version": "1.116.2", "version": "1.131.5",
"engines": { "engines": {
"node": ">=18.0.0 <21.0.0" "node": ">=18.0.0 <21.0.0"
}, },
@@ -32,7 +32,8 @@
"weekly-backup:email": "yarn node dist/bin/backup.js email weekly", "weekly-backup:email": "yarn node dist/bin/backup.js email weekly",
"content-recalculation": "yarn node dist/bin/content.js", "content-recalculation": "yarn node dist/bin/content.js",
"typeorm": "typeorm-ts-node-commonjs", "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": { "dependencies": {
"@aws-sdk/client-sns": "^3.332.0", "@aws-sdk/client-sns": "^3.332.0",
@@ -41,17 +42,17 @@
"@cbor-extract/cbor-extract-linux-x64": "^2.1.1", "@cbor-extract/cbor-extract-linux-x64": "^2.1.1",
"@simplewebauthn/server": "^7.2.0", "@simplewebauthn/server": "^7.2.0",
"@simplewebauthn/typescript-types": "^7.0.0", "@simplewebauthn/typescript-types": "^7.0.0",
"@standardnotes/api": "^1.25.3", "@standardnotes/api": "^1.26.26",
"@standardnotes/common": "workspace:*", "@standardnotes/common": "workspace:*",
"@standardnotes/domain-core": "workspace:^", "@standardnotes/domain-core": "workspace:^",
"@standardnotes/domain-events": "workspace:*", "@standardnotes/domain-events": "workspace:*",
"@standardnotes/domain-events-infra": "workspace:*", "@standardnotes/domain-events-infra": "workspace:*",
"@standardnotes/features": "^1.58.12", "@standardnotes/features": "^1.59.7",
"@standardnotes/predicates": "workspace:*", "@standardnotes/predicates": "workspace:*",
"@standardnotes/responses": "^1.13.9", "@standardnotes/responses": "^1.13.27",
"@standardnotes/security": "workspace:*", "@standardnotes/security": "workspace:*",
"@standardnotes/settings": "workspace:*", "@standardnotes/settings": "workspace:*",
"@standardnotes/sncrypto-common": "^1.9.0", "@standardnotes/sncrypto-common": "^1.13.4",
"@standardnotes/sncrypto-node": "workspace:*", "@standardnotes/sncrypto-node": "workspace:*",
"@standardnotes/time": "workspace:*", "@standardnotes/time": "workspace:*",
"axios": "^1.1.3", "axios": "^1.1.3",
@@ -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>>
}
+161 -89
View File
@@ -38,7 +38,7 @@ import { GetUserKeyParams } from '../Domain/UseCase/GetUserKeyParams/GetUserKeyP
import { UpdateUser } from '../Domain/UseCase/UpdateUser' import { UpdateUser } from '../Domain/UseCase/UpdateUser'
import { RedisEphemeralSessionRepository } from '../Infra/Redis/RedisEphemeralSessionRepository' import { RedisEphemeralSessionRepository } from '../Infra/Redis/RedisEphemeralSessionRepository'
import { GetActiveSessionsForUser } from '../Domain/UseCase/GetActiveSessionsForUser' 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 { DeleteSessionForUser } from '../Domain/UseCase/DeleteSessionForUser'
import { Register } from '../Domain/UseCase/Register' import { Register } from '../Domain/UseCase/Register'
import { LockRepository } from '../Infra/Redis/LockRepository' import { LockRepository } from '../Infra/Redis/LockRepository'
@@ -234,23 +234,28 @@ import { OfflineUserAuthMiddleware } from '../Infra/InversifyExpressUtils/Middle
import { LockMiddleware } from '../Infra/InversifyExpressUtils/Middleware/LockMiddleware' import { LockMiddleware } from '../Infra/InversifyExpressUtils/Middleware/LockMiddleware'
import { RequiredCrossServiceTokenMiddleware } from '../Infra/InversifyExpressUtils/Middleware/RequiredCrossServiceTokenMiddleware' import { RequiredCrossServiceTokenMiddleware } from '../Infra/InversifyExpressUtils/Middleware/RequiredCrossServiceTokenMiddleware'
import { OptionalCrossServiceTokenMiddleware } from '../Infra/InversifyExpressUtils/Middleware/OptionalCrossServiceTokenMiddleware' import { OptionalCrossServiceTokenMiddleware } from '../Infra/InversifyExpressUtils/Middleware/OptionalCrossServiceTokenMiddleware'
import { HomeServerSettingsController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerSettingsController' import { BaseSettingsController } from '../Infra/InversifyExpressUtils/Base/BaseSettingsController'
import { HomeServerAdminController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerAdminController' import { BaseAdminController } from '../Infra/InversifyExpressUtils/Base/BaseAdminController'
import { HomeServerAuthController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerAuthController' import { BaseAuthController } from '../Infra/InversifyExpressUtils/Base/BaseAuthController'
import { HomeServerAuthenticatorsController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerAuthenticatorsController' import { BaseAuthenticatorsController } from '../Infra/InversifyExpressUtils/Base/BaseAuthenticatorsController'
import { HomeServerFeaturesController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerFeaturesController' import { BaseFeaturesController } from '../Infra/InversifyExpressUtils/Base/BaseFeaturesController'
import { HomeServerListedController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerListedController' import { BaseListedController } from '../Infra/InversifyExpressUtils/Base/BaseListedController'
import { HomeServerOfflineController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerOfflineController' import { BaseOfflineController } from '../Infra/InversifyExpressUtils/Base/BaseOfflineController'
import { HomeServerSessionController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerSessionController' import { BaseSessionController } from '../Infra/InversifyExpressUtils/Base/BaseSessionController'
import { HomeServerSubscriptionInvitesController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerSubscriptionInvitesController' import { BaseSubscriptionInvitesController } from '../Infra/InversifyExpressUtils/Base/BaseSubscriptionInvitesController'
import { HomeServerSubscriptionSettingsController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerSubscriptionSettingsController' import { BaseSubscriptionSettingsController } from '../Infra/InversifyExpressUtils/Base/BaseSubscriptionSettingsController'
import { HomeServerSubscriptionTokensController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerSubscriptionTokensController' import { BaseSubscriptionTokensController } from '../Infra/InversifyExpressUtils/Base/BaseSubscriptionTokensController'
import { HomeServerUserRequestsController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerUserRequestsController' import { BaseUserRequestsController } from '../Infra/InversifyExpressUtils/Base/BaseUserRequestsController'
import { HomeServerUsersController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerUsersController' import { BaseUsersController } from '../Infra/InversifyExpressUtils/Base/BaseUsersController'
import { HomeServerValetTokenController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerValetTokenController' import { BaseValetTokenController } from '../Infra/InversifyExpressUtils/Base/BaseValetTokenController'
import { HomeServerWebSocketsController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerWebSocketsController' import { BaseWebSocketsController } from '../Infra/InversifyExpressUtils/Base/BaseWebSocketsController'
import { HomeServerSessionsController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerSessionsController' import { BaseSessionsController } from '../Infra/InversifyExpressUtils/Base/BaseSessionsController'
import { Transform } from 'stream' 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'
export class ContainerConfigLoader { export class ContainerConfigLoader {
async load(configuration?: { async load(configuration?: {
@@ -267,12 +272,37 @@ export class ContainerConfigLoader {
const container = new Container() 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) const appDataSource = new AppDataSource(env)
await appDataSource.initialize() 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 redisUrl = env.get('REDIS_URL')
const isRedisInClusterMode = redisUrl.indexOf(',') > 0 const isRedisInClusterMode = redisUrl.indexOf(',') > 0
let redis let redis
@@ -285,27 +315,6 @@ export class ContainerConfigLoader {
container.bind(TYPES.Auth_Redis).toConstantValue(redis) 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()) container.bind<TimerInterface>(TYPES.Auth_Timer).toConstantValue(new Timer())
if (!isConfiguredForHomeServer) { if (!isConfiguredForHomeServer) {
@@ -488,7 +497,9 @@ export class ContainerConfigLoader {
.bind(TYPES.Auth_AUTH_JWT_TTL) .bind(TYPES.Auth_AUTH_JWT_TTL)
.toConstantValue(env.get('AUTH_JWT_TTL', true) ? +env.get('AUTH_JWT_TTL') : 60_000) .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_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 container
.bind(TYPES.Auth_WEB_SOCKET_CONNECTION_TOKEN_SECRET) .bind(TYPES.Auth_WEB_SOCKET_CONNECTION_TOKEN_SECRET)
.toConstantValue(env.get('WEB_SOCKET_CONNECTION_TOKEN_SECRET', true)) .toConstantValue(env.get('WEB_SOCKET_CONNECTION_TOKEN_SECRET', true))
@@ -550,7 +561,16 @@ export class ContainerConfigLoader {
.bind(TYPES.Auth_READONLY_USERS) .bind(TYPES.Auth_READONLY_USERS)
.toConstantValue(env.get('READONLY_USERS', true) ? env.get('READONLY_USERS', true).split(',') : []) .toConstantValue(env.get('READONLY_USERS', true) ? env.get('READONLY_USERS', true).split(',') : [])
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 container
.bind<LockRepositoryInterface>(TYPES.Auth_LockRepository) .bind<LockRepositoryInterface>(TYPES.Auth_LockRepository)
.toConstantValue( .toConstantValue(
@@ -578,15 +598,6 @@ export class ContainerConfigLoader {
container.get(TYPES.Auth_Timer), 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 container
.bind<SubscriptionTokenRepositoryInterface>(TYPES.Auth_SubscriptionTokenRepository) .bind<SubscriptionTokenRepositoryInterface>(TYPES.Auth_SubscriptionTokenRepository)
.toConstantValue( .toConstantValue(
@@ -780,6 +791,17 @@ export class ContainerConfigLoader {
container.get(TYPES.Auth_CryptoNode), 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 container
.bind<CleanupSessionTraces>(TYPES.Auth_CleanupSessionTraces) .bind<CleanupSessionTraces>(TYPES.Auth_CleanupSessionTraces)
@@ -808,9 +830,7 @@ export class ContainerConfigLoader {
container.bind<UpdateUser>(TYPES.Auth_UpdateUser).to(UpdateUser) container.bind<UpdateUser>(TYPES.Auth_UpdateUser).to(UpdateUser)
container.bind<Register>(TYPES.Auth_Register).to(Register) container.bind<Register>(TYPES.Auth_Register).to(Register)
container.bind<GetActiveSessionsForUser>(TYPES.Auth_GetActiveSessionsForUser).to(GetActiveSessionsForUser) container.bind<GetActiveSessionsForUser>(TYPES.Auth_GetActiveSessionsForUser).to(GetActiveSessionsForUser)
container container.bind<DeleteOtherSessionsForUser>(TYPES.Auth_DeleteOtherSessionsForUser).to(DeleteOtherSessionsForUser)
.bind<DeletePreviousSessionsForUser>(TYPES.Auth_DeletePreviousSessionsForUser)
.to(DeletePreviousSessionsForUser)
container.bind<DeleteSessionForUser>(TYPES.Auth_DeleteSessionForUser).to(DeleteSessionForUser) container.bind<DeleteSessionForUser>(TYPES.Auth_DeleteSessionForUser).to(DeleteSessionForUser)
container.bind<ChangeCredentials>(TYPES.Auth_ChangeCredentials).to(ChangeCredentials) container.bind<ChangeCredentials>(TYPES.Auth_ChangeCredentials).to(ChangeCredentials)
container.bind<GetSettings>(TYPES.Auth_GetSettings).to(GetSettings) container.bind<GetSettings>(TYPES.Auth_GetSettings).to(GetSettings)
@@ -865,6 +885,15 @@ export class ContainerConfigLoader {
container.bind<VerifyPredicate>(TYPES.Auth_VerifyPredicate).to(VerifyPredicate) container.bind<VerifyPredicate>(TYPES.Auth_VerifyPredicate).to(VerifyPredicate)
container.bind<CreateCrossServiceToken>(TYPES.Auth_CreateCrossServiceToken).to(CreateCrossServiceToken) container.bind<CreateCrossServiceToken>(TYPES.Auth_CreateCrossServiceToken).to(CreateCrossServiceToken)
container.bind<ProcessUserRequest>(TYPES.Auth_ProcessUserRequest).to(ProcessUserRequest) 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 // Controller
container container
@@ -934,8 +963,38 @@ export class ContainerConfigLoader {
container container
.bind<UserEmailChangedEventHandler>(TYPES.Auth_UserEmailChangedEventHandler) .bind<UserEmailChangedEventHandler>(TYPES.Auth_UserEmailChangedEventHandler)
.to(UserEmailChangedEventHandler) .to(UserEmailChangedEventHandler)
container.bind<FileUploadedEventHandler>(TYPES.Auth_FileUploadedEventHandler).to(FileUploadedEventHandler) container
container.bind<FileRemovedEventHandler>(TYPES.Auth_FileRemovedEventHandler).to(FileRemovedEventHandler) .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<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 container
.bind<ListedAccountCreatedEventHandler>(TYPES.Auth_ListedAccountCreatedEventHandler) .bind<ListedAccountCreatedEventHandler>(TYPES.Auth_ListedAccountCreatedEventHandler)
.to(ListedAccountCreatedEventHandler) .to(ListedAccountCreatedEventHandler)
@@ -960,6 +1019,14 @@ export class ContainerConfigLoader {
container.get(TYPES.Auth_SettingService), 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([ const eventHandlers: Map<string, DomainEventHandlerInterface> = new Map([
['USER_REGISTERED', container.get(TYPES.Auth_UserRegisteredEventHandler)], ['USER_REGISTERED', container.get(TYPES.Auth_UserRegisteredEventHandler)],
@@ -974,7 +1041,9 @@ export class ContainerConfigLoader {
['SUBSCRIPTION_REASSIGNED', container.get(TYPES.Auth_SubscriptionReassignedEventHandler)], ['SUBSCRIPTION_REASSIGNED', container.get(TYPES.Auth_SubscriptionReassignedEventHandler)],
['USER_EMAIL_CHANGED', container.get(TYPES.Auth_UserEmailChangedEventHandler)], ['USER_EMAIL_CHANGED', container.get(TYPES.Auth_UserEmailChangedEventHandler)],
['FILE_UPLOADED', container.get(TYPES.Auth_FileUploadedEventHandler)], ['FILE_UPLOADED', container.get(TYPES.Auth_FileUploadedEventHandler)],
['SHARED_VAULT_FILE_UPLOADED', container.get(TYPES.Auth_SharedVaultFileUploadedEventHandler)],
['FILE_REMOVED', container.get(TYPES.Auth_FileRemovedEventHandler)], ['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_CREATED', container.get(TYPES.Auth_ListedAccountCreatedEventHandler)],
['LISTED_ACCOUNT_DELETED', container.get(TYPES.Auth_ListedAccountDeletedEventHandler)], ['LISTED_ACCOUNT_DELETED', container.get(TYPES.Auth_ListedAccountDeletedEventHandler)],
[ [
@@ -987,6 +1056,7 @@ export class ContainerConfigLoader {
], ],
['PREDICATE_VERIFICATION_REQUESTED', container.get(TYPES.Auth_PredicateVerificationRequestedEventHandler)], ['PREDICATE_VERIFICATION_REQUESTED', container.get(TYPES.Auth_PredicateVerificationRequestedEventHandler)],
['EMAIL_SUBSCRIPTION_UNSUBSCRIBED', container.get(TYPES.Auth_EmailSubscriptionUnsubscribedEventHandler)], ['EMAIL_SUBSCRIPTION_UNSUBSCRIBED', container.get(TYPES.Auth_EmailSubscriptionUnsubscribedEventHandler)],
['PAYMENTS_ACCOUNT_DELETED', container.get(TYPES.Auth_PaymentsAccountDeletedEventHandler)],
]) ])
if (isConfiguredForHomeServer) { if (isConfiguredForHomeServer) {
@@ -1019,9 +1089,9 @@ export class ContainerConfigLoader {
} }
container container
.bind<HomeServerAuthController>(TYPES.Auth_HomeServerAuthController) .bind<BaseAuthController>(TYPES.Auth_BaseAuthController)
.toConstantValue( .toConstantValue(
new HomeServerAuthController( new BaseAuthController(
container.get(TYPES.Auth_VerifyMFA), container.get(TYPES.Auth_VerifyMFA),
container.get(TYPES.Auth_SignIn), container.get(TYPES.Auth_SignIn),
container.get(TYPES.Auth_GetUserKeyParams), container.get(TYPES.Auth_GetUserKeyParams),
@@ -1036,42 +1106,42 @@ export class ContainerConfigLoader {
// Inversify Controllers // Inversify Controllers
if (isConfiguredForHomeServer) { if (isConfiguredForHomeServer) {
container container
.bind<HomeServerAuthenticatorsController>(TYPES.Auth_HomeServerAuthenticatorsController) .bind<BaseAuthenticatorsController>(TYPES.Auth_BaseAuthenticatorsController)
.toConstantValue( .toConstantValue(
new HomeServerAuthenticatorsController( new BaseAuthenticatorsController(
container.get(TYPES.Auth_AuthenticatorsController), container.get(TYPES.Auth_AuthenticatorsController),
container.get(TYPES.Auth_ControllerContainer), container.get(TYPES.Auth_ControllerContainer),
), ),
) )
container container
.bind<HomeServerSubscriptionInvitesController>(TYPES.Auth_HomeServerSubscriptionInvitesController) .bind<BaseSubscriptionInvitesController>(TYPES.Auth_BaseSubscriptionInvitesController)
.toConstantValue( .toConstantValue(
new HomeServerSubscriptionInvitesController( new BaseSubscriptionInvitesController(
container.get(TYPES.Auth_SubscriptionInvitesController), container.get(TYPES.Auth_SubscriptionInvitesController),
container.get(TYPES.Auth_ControllerContainer), container.get(TYPES.Auth_ControllerContainer),
), ),
) )
container container
.bind<HomeServerUserRequestsController>(TYPES.Auth_HomeServerUserRequestsController) .bind<BaseUserRequestsController>(TYPES.Auth_BaseUserRequestsController)
.toConstantValue( .toConstantValue(
new HomeServerUserRequestsController( new BaseUserRequestsController(
container.get(TYPES.Auth_UserRequestsController), container.get(TYPES.Auth_UserRequestsController),
container.get(TYPES.Auth_ControllerContainer), container.get(TYPES.Auth_ControllerContainer),
), ),
) )
container container
.bind<HomeServerWebSocketsController>(TYPES.Auth_HomeServerWebSocketsController) .bind<BaseWebSocketsController>(TYPES.Auth_BaseWebSocketsController)
.toConstantValue( .toConstantValue(
new HomeServerWebSocketsController( new BaseWebSocketsController(
container.get(TYPES.Auth_CreateCrossServiceToken), container.get(TYPES.Auth_CreateCrossServiceToken),
container.get(TYPES.Auth_WebSocketConnectionTokenDecoder), container.get(TYPES.Auth_WebSocketConnectionTokenDecoder),
container.get(TYPES.Auth_ControllerContainer), container.get(TYPES.Auth_ControllerContainer),
), ),
) )
container container
.bind<HomeServerSessionsController>(TYPES.Auth_HomeServerSessionsController) .bind<BaseSessionsController>(TYPES.Auth_BaseSessionsController)
.toConstantValue( .toConstantValue(
new HomeServerSessionsController( new BaseSessionsController(
container.get(TYPES.Auth_GetActiveSessionsForUser), container.get(TYPES.Auth_GetActiveSessionsForUser),
container.get(TYPES.Auth_AuthenticateRequest), container.get(TYPES.Auth_AuthenticateRequest),
container.get(TYPES.Auth_SessionProjector), container.get(TYPES.Auth_SessionProjector),
@@ -1080,17 +1150,17 @@ export class ContainerConfigLoader {
), ),
) )
container container
.bind<HomeServerValetTokenController>(TYPES.Auth_HomeServerValetTokenController) .bind<BaseValetTokenController>(TYPES.Auth_BaseValetTokenController)
.toConstantValue( .toConstantValue(
new HomeServerValetTokenController( new BaseValetTokenController(
container.get(TYPES.Auth_CreateValetToken), container.get(TYPES.Auth_CreateValetToken),
container.get(TYPES.Auth_ControllerContainer), container.get(TYPES.Auth_ControllerContainer),
), ),
) )
container container
.bind<HomeServerUsersController>(TYPES.Auth_HomeServerUsersController) .bind<BaseUsersController>(TYPES.Auth_BaseUsersController)
.toConstantValue( .toConstantValue(
new HomeServerUsersController( new BaseUsersController(
container.get(TYPES.Auth_UpdateUser), container.get(TYPES.Auth_UpdateUser),
container.get(TYPES.Auth_GetUserKeyParams), container.get(TYPES.Auth_GetUserKeyParams),
container.get(TYPES.Auth_DeleteAccount), container.get(TYPES.Auth_DeleteAccount),
@@ -1102,9 +1172,9 @@ export class ContainerConfigLoader {
), ),
) )
container container
.bind<HomeServerAdminController>(TYPES.Auth_HomeServerAdminController) .bind<BaseAdminController>(TYPES.Auth_BaseAdminController)
.toConstantValue( .toConstantValue(
new HomeServerAdminController( new BaseAdminController(
container.get(TYPES.Auth_DeleteSetting), container.get(TYPES.Auth_DeleteSetting),
container.get(TYPES.Auth_UserRepository), container.get(TYPES.Auth_UserRepository),
container.get(TYPES.Auth_CreateSubscriptionToken), container.get(TYPES.Auth_CreateSubscriptionToken),
@@ -1113,9 +1183,9 @@ export class ContainerConfigLoader {
), ),
) )
container container
.bind<HomeServerSubscriptionTokensController>(TYPES.Auth_HomeServerSubscriptionTokensController) .bind<BaseSubscriptionTokensController>(TYPES.Auth_BaseSubscriptionTokensController)
.toConstantValue( .toConstantValue(
new HomeServerSubscriptionTokensController( new BaseSubscriptionTokensController(
container.get(TYPES.Auth_CreateSubscriptionToken), container.get(TYPES.Auth_CreateSubscriptionToken),
container.get(TYPES.Auth_AuthenticateSubscriptionToken), container.get(TYPES.Auth_AuthenticateSubscriptionToken),
container.get(TYPES.Auth_SettingService), container.get(TYPES.Auth_SettingService),
@@ -1127,17 +1197,17 @@ export class ContainerConfigLoader {
), ),
) )
container container
.bind<HomeServerSubscriptionSettingsController>(TYPES.Auth_HomeServerSubscriptionSettingsController) .bind<BaseSubscriptionSettingsController>(TYPES.Auth_BaseSubscriptionSettingsController)
.toConstantValue( .toConstantValue(
new HomeServerSubscriptionSettingsController( new BaseSubscriptionSettingsController(
container.get(TYPES.Auth_GetSetting), container.get(TYPES.Auth_GetSetting),
container.get(TYPES.Auth_ControllerContainer), container.get(TYPES.Auth_ControllerContainer),
), ),
) )
container container
.bind<HomeServerSettingsController>(TYPES.Auth_HomeServerSettingsController) .bind<BaseSettingsController>(TYPES.Auth_BaseSettingsController)
.toConstantValue( .toConstantValue(
new HomeServerSettingsController( new BaseSettingsController(
container.get(TYPES.Auth_GetSettings), container.get(TYPES.Auth_GetSettings),
container.get(TYPES.Auth_GetSetting), container.get(TYPES.Auth_GetSetting),
container.get(TYPES.Auth_UpdateSetting), container.get(TYPES.Auth_UpdateSetting),
@@ -1146,19 +1216,19 @@ export class ContainerConfigLoader {
), ),
) )
container container
.bind<HomeServerSessionController>(TYPES.Auth_HomeServerSessionController) .bind<BaseSessionController>(TYPES.Auth_BaseSessionController)
.toConstantValue( .toConstantValue(
new HomeServerSessionController( new BaseSessionController(
container.get(TYPES.Auth_DeleteSessionForUser), container.get(TYPES.Auth_DeleteSessionForUser),
container.get(TYPES.Auth_DeletePreviousSessionsForUser), container.get(TYPES.Auth_DeleteOtherSessionsForUser),
container.get(TYPES.Auth_RefreshSessionToken), container.get(TYPES.Auth_RefreshSessionToken),
container.get(TYPES.Auth_ControllerContainer), container.get(TYPES.Auth_ControllerContainer),
), ),
) )
container container
.bind<HomeServerOfflineController>(TYPES.Auth_HomeServerOfflineController) .bind<BaseOfflineController>(TYPES.Auth_BaseOfflineController)
.toConstantValue( .toConstantValue(
new HomeServerOfflineController( new BaseOfflineController(
container.get(TYPES.Auth_GetUserFeatures), container.get(TYPES.Auth_GetUserFeatures),
container.get(TYPES.Auth_GetUserOfflineSubscription), container.get(TYPES.Auth_GetUserOfflineSubscription),
container.get(TYPES.Auth_CreateOfflineSubscriptionToken), container.get(TYPES.Auth_CreateOfflineSubscriptionToken),
@@ -1170,23 +1240,25 @@ export class ContainerConfigLoader {
), ),
) )
container container
.bind<HomeServerListedController>(TYPES.Auth_HomeServerListedController) .bind<BaseListedController>(TYPES.Auth_BaseListedController)
.toConstantValue( .toConstantValue(
new HomeServerListedController( new BaseListedController(
container.get(TYPES.Auth_CreateListedAccount), container.get(TYPES.Auth_CreateListedAccount),
container.get(TYPES.Auth_ControllerContainer), container.get(TYPES.Auth_ControllerContainer),
), ),
) )
container container
.bind<HomeServerFeaturesController>(TYPES.Auth_HomeServerFeaturesController) .bind<BaseFeaturesController>(TYPES.Auth_BaseFeaturesController)
.toConstantValue( .toConstantValue(
new HomeServerFeaturesController( new BaseFeaturesController(
container.get(TYPES.Auth_GetUserFeatures), container.get(TYPES.Auth_GetUserFeatures),
container.get(TYPES.Auth_ControllerContainer), container.get(TYPES.Auth_ControllerContainer),
), ),
) )
} }
logger.debug('Configuration complete')
return container return container
} }
} }
+13 -7
View File
@@ -20,19 +20,23 @@ import { Env } from './Env'
import { SqliteConnectionOptions } from 'typeorm/driver/sqlite/SqliteConnectionOptions' import { SqliteConnectionOptions } from 'typeorm/driver/sqlite/SqliteConnectionOptions'
export class AppDataSource { export class AppDataSource {
private dataSource: DataSource | undefined private _dataSource: DataSource | undefined
constructor(private env: Env) {} constructor(private env: Env) {}
getRepository<Entity extends ObjectLiteral>(target: EntityTarget<Entity>): Repository<Entity> { getRepository<Entity extends ObjectLiteral>(target: EntityTarget<Entity>): Repository<Entity> {
if (!this.dataSource) { if (!this._dataSource) {
throw new Error('DataSource not initialized') throw new Error('DataSource not initialized')
} }
return this.dataSource.getRepository(target) return this._dataSource.getRepository(target)
} }
async initialize(): Promise<void> { async initialize(): Promise<void> {
await this.dataSource.initialize()
}
get dataSource(): DataSource {
this.env.load() this.env.load()
const isConfiguredForMySQL = this.env.get('DB_TYPE') === 'mysql' const isConfiguredForMySQL = this.env.get('DB_TYPE') === 'mysql'
@@ -104,17 +108,19 @@ export class AppDataSource {
database: inReplicaMode ? undefined : this.env.get('DB_DATABASE'), database: inReplicaMode ? undefined : this.env.get('DB_DATABASE'),
} }
this.dataSource = new DataSource(mySQLDataSourceOptions) this._dataSource = new DataSource(mySQLDataSourceOptions)
} else { } else {
const sqliteDataSourceOptions: SqliteConnectionOptions = { const sqliteDataSourceOptions: SqliteConnectionOptions = {
...commonDataSourceOptions, ...commonDataSourceOptions,
type: 'sqlite', 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
} }
} }
@@ -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
+27 -3
View File
@@ -1,15 +1,21 @@
import { import {
ControllerContainerInterface, ControllerContainerInterface,
Result,
ServiceConfiguration, ServiceConfiguration,
ServiceContainerInterface, ServiceContainerInterface,
ServiceIdentifier, ServiceIdentifier,
ServiceInterface,
} from '@standardnotes/domain-core' } from '@standardnotes/domain-core'
import { ContainerConfigLoader } from './Container' import { ContainerConfigLoader } from './Container'
import { DirectCallDomainEventPublisher } from '@standardnotes/domain-events-infra' 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( constructor(
private serviceContainer: ServiceContainerInterface, private serviceContainer: ServiceContainerInterface,
private controllerContainer: ControllerContainerInterface, private controllerContainer: ControllerContainerInterface,
@@ -18,6 +24,20 @@ export class Service implements ServiceInterface {
this.serviceContainer.register(this.getId(), this) this.serviceContainer.register(this.getId(), this)
} }
async activatePremiumFeatures(dto: {
username: string
subscriptionPlanName?: string
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> { async handleRequest(request: never, response: never, endpointOrMethodIdentifier: string): Promise<unknown> {
const method = this.controllerContainer.get(endpointOrMethodIdentifier) const method = this.controllerContainer.get(endpointOrMethodIdentifier)
@@ -31,12 +51,16 @@ export class Service implements ServiceInterface {
async getContainer(configuration?: ServiceConfiguration): Promise<unknown> { async getContainer(configuration?: ServiceConfiguration): Promise<unknown> {
const config = new ContainerConfigLoader() const config = new ContainerConfigLoader()
return config.load({ const container = await config.load({
controllerConatiner: this.controllerContainer, controllerConatiner: this.controllerContainer,
directCallDomainEventPublisher: this.directCallDomainEventPublisher, directCallDomainEventPublisher: this.directCallDomainEventPublisher,
logger: configuration?.logger, logger: configuration?.logger,
environmentOverrides: configuration?.environmentOverrides, environmentOverrides: configuration?.environmentOverrides,
}) })
this.container = container
return container
} }
getId(): ServiceIdentifier { getId(): ServiceIdentifier {
+22 -17
View File
@@ -113,7 +113,7 @@ const TYPES = {
Auth_UpdateUser: Symbol.for('Auth_UpdateUser'), Auth_UpdateUser: Symbol.for('Auth_UpdateUser'),
Auth_Register: Symbol.for('Auth_Register'), Auth_Register: Symbol.for('Auth_Register'),
Auth_GetActiveSessionsForUser: Symbol.for('Auth_GetActiveSessionsForUser'), 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_DeleteSessionForUser: Symbol.for('Auth_DeleteSessionForUser'),
Auth_ChangeCredentials: Symbol.for('Auth_ChangePassword'), Auth_ChangeCredentials: Symbol.for('Auth_ChangePassword'),
Auth_GetSettings: Symbol.for('Auth_GetSettings'), Auth_GetSettings: Symbol.for('Auth_GetSettings'),
@@ -149,8 +149,10 @@ const TYPES = {
Auth_ListAuthenticators: Symbol.for('Auth_ListAuthenticators'), Auth_ListAuthenticators: Symbol.for('Auth_ListAuthenticators'),
Auth_DeleteAuthenticator: Symbol.for('Auth_DeleteAuthenticator'), Auth_DeleteAuthenticator: Symbol.for('Auth_DeleteAuthenticator'),
Auth_GenerateRecoveryCodes: Symbol.for('Auth_GenerateRecoveryCodes'), Auth_GenerateRecoveryCodes: Symbol.for('Auth_GenerateRecoveryCodes'),
Auth_ActivatePremiumFeatures: Symbol.for('Auth_ActivatePremiumFeatures'),
Auth_SignInWithRecoveryCodes: Symbol.for('Auth_SignInWithRecoveryCodes'), Auth_SignInWithRecoveryCodes: Symbol.for('Auth_SignInWithRecoveryCodes'),
Auth_GetUserKeyParamsRecovery: Symbol.for('Auth_GetUserKeyParamsRecovery'), Auth_GetUserKeyParamsRecovery: Symbol.for('Auth_GetUserKeyParamsRecovery'),
Auth_UpdateStorageQuotaUsedForUser: Symbol.for('Auth_UpdateStorageQuotaUsedForUser'),
// Handlers // Handlers
Auth_UserRegisteredEventHandler: Symbol.for('Auth_UserRegisteredEventHandler'), Auth_UserRegisteredEventHandler: Symbol.for('Auth_UserRegisteredEventHandler'),
Auth_AccountDeletionRequestedEventHandler: Symbol.for('Auth_AccountDeletionRequestedEventHandler'), Auth_AccountDeletionRequestedEventHandler: Symbol.for('Auth_AccountDeletionRequestedEventHandler'),
@@ -164,7 +166,9 @@ const TYPES = {
Auth_ExtensionKeyGrantedEventHandler: Symbol.for('Auth_ExtensionKeyGrantedEventHandler'), Auth_ExtensionKeyGrantedEventHandler: Symbol.for('Auth_ExtensionKeyGrantedEventHandler'),
Auth_UserEmailChangedEventHandler: Symbol.for('Auth_UserEmailChangedEventHandler'), Auth_UserEmailChangedEventHandler: Symbol.for('Auth_UserEmailChangedEventHandler'),
Auth_FileUploadedEventHandler: Symbol.for('Auth_FileUploadedEventHandler'), Auth_FileUploadedEventHandler: Symbol.for('Auth_FileUploadedEventHandler'),
Auth_SharedVaultFileUploadedEventHandler: Symbol.for('Auth_SharedVaultFileUploadedEventHandler'),
Auth_FileRemovedEventHandler: Symbol.for('Auth_FileRemovedEventHandler'), Auth_FileRemovedEventHandler: Symbol.for('Auth_FileRemovedEventHandler'),
Auth_SharedVaultFileRemovedEventHandler: Symbol.for('Auth_SharedVaultFileRemovedEventHandler'),
Auth_ListedAccountCreatedEventHandler: Symbol.for('Auth_ListedAccountCreatedEventHandler'), Auth_ListedAccountCreatedEventHandler: Symbol.for('Auth_ListedAccountCreatedEventHandler'),
Auth_ListedAccountDeletedEventHandler: Symbol.for('Auth_ListedAccountDeletedEventHandler'), Auth_ListedAccountDeletedEventHandler: Symbol.for('Auth_ListedAccountDeletedEventHandler'),
Auth_UserDisabledSessionUserAgentLoggingEventHandler: Symbol.for( Auth_UserDisabledSessionUserAgentLoggingEventHandler: Symbol.for(
@@ -175,6 +179,7 @@ const TYPES = {
), ),
Auth_PredicateVerificationRequestedEventHandler: Symbol.for('Auth_PredicateVerificationRequestedEventHandler'), Auth_PredicateVerificationRequestedEventHandler: Symbol.for('Auth_PredicateVerificationRequestedEventHandler'),
Auth_EmailSubscriptionUnsubscribedEventHandler: Symbol.for('Auth_EmailSubscriptionUnsubscribedEventHandler'), Auth_EmailSubscriptionUnsubscribedEventHandler: Symbol.for('Auth_EmailSubscriptionUnsubscribedEventHandler'),
Auth_PaymentsAccountDeletedEventHandler: Symbol.for('Auth_PaymentsAccountDeletedEventHandler'),
// Services // Services
Auth_DeviceDetector: Symbol.for('Auth_DeviceDetector'), Auth_DeviceDetector: Symbol.for('Auth_DeviceDetector'),
Auth_SessionService: Symbol.for('Auth_SessionService'), Auth_SessionService: Symbol.for('Auth_SessionService'),
@@ -216,22 +221,22 @@ const TYPES = {
Auth_ProtocolVersionSelector: Symbol.for('Auth_ProtocolVersionSelector'), Auth_ProtocolVersionSelector: Symbol.for('Auth_ProtocolVersionSelector'),
Auth_BooleanSelector: Symbol.for('Auth_BooleanSelector'), Auth_BooleanSelector: Symbol.for('Auth_BooleanSelector'),
Auth_UserSubscriptionService: Symbol.for('Auth_UserSubscriptionService'), Auth_UserSubscriptionService: Symbol.for('Auth_UserSubscriptionService'),
Auth_HomeServerAuthController: Symbol.for('Auth_HomeServerAuthController'), Auth_BaseAuthController: Symbol.for('Auth_BaseAuthController'),
Auth_HomeServerAuthenticatorsController: Symbol.for('Auth_HomeServerAuthenticatorsController'), Auth_BaseAuthenticatorsController: Symbol.for('Auth_BaseAuthenticatorsController'),
Auth_HomeServerSubscriptionInvitesController: Symbol.for('Auth_HomeServerSubscriptionInvitesController'), Auth_BaseSubscriptionInvitesController: Symbol.for('Auth_BaseSubscriptionInvitesController'),
Auth_HomeServerUserRequestsController: Symbol.for('Auth_HomeServerUserRequestsController'), Auth_BaseUserRequestsController: Symbol.for('Auth_BaseUserRequestsController'),
Auth_HomeServerWebSocketsController: Symbol.for('Auth_HomeServerWebSocketsController'), Auth_BaseWebSocketsController: Symbol.for('Auth_BaseWebSocketsController'),
Auth_HomeServerSessionsController: Symbol.for('Auth_HomeServerSessionsController'), Auth_BaseSessionsController: Symbol.for('Auth_BaseSessionsController'),
Auth_HomeServerValetTokenController: Symbol.for('Auth_HomeServerValetTokenController'), Auth_BaseValetTokenController: Symbol.for('Auth_BaseValetTokenController'),
Auth_HomeServerUsersController: Symbol.for('Auth_HomeServerUsersController'), Auth_BaseUsersController: Symbol.for('Auth_BaseUsersController'),
Auth_HomeServerAdminController: Symbol.for('Auth_HomeServerAdminController'), Auth_BaseAdminController: Symbol.for('Auth_BaseAdminController'),
Auth_HomeServerSubscriptionTokensController: Symbol.for('Auth_HomeServerSubscriptionTokensController'), Auth_BaseSubscriptionTokensController: Symbol.for('Auth_BaseSubscriptionTokensController'),
Auth_HomeServerSubscriptionSettingsController: Symbol.for('Auth_HomeServerSubscriptionSettingsController'), Auth_BaseSubscriptionSettingsController: Symbol.for('Auth_BaseSubscriptionSettingsController'),
Auth_HomeServerSettingsController: Symbol.for('Auth_HomeServerSettingsController'), Auth_BaseSettingsController: Symbol.for('Auth_BaseSettingsController'),
Auth_HomeServerSessionController: Symbol.for('Auth_HomeServerSessionController'), Auth_BaseSessionController: Symbol.for('Auth_BaseSessionController'),
Auth_HomeServerOfflineController: Symbol.for('Auth_HomeServerOfflineController'), Auth_BaseOfflineController: Symbol.for('Auth_BaseOfflineController'),
Auth_HomeServerListedController: Symbol.for('Auth_HomeServerListedController'), Auth_BaseListedController: Symbol.for('Auth_BaseListedController'),
Auth_HomeServerFeaturesController: Symbol.for('Auth_HomeServerFeaturesController'), Auth_BaseFeaturesController: Symbol.for('Auth_BaseFeaturesController'),
} }
export default TYPES export default TYPES
+1
View File
@@ -1 +1,2 @@
export * from './AuthServiceInterface'
export * from './Service' export * from './Service'
@@ -8,12 +8,12 @@ import { User } from '../Domain/User/User'
import { Register } from '../Domain/UseCase/Register' import { Register } from '../Domain/UseCase/Register'
import { DomainEventFactoryInterface } from '../Domain/Event/DomainEventFactoryInterface' import { DomainEventFactoryInterface } from '../Domain/Event/DomainEventFactoryInterface'
import { KeyParamsOrigination, ProtocolVersion } from '@standardnotes/common' import { KeyParamsOrigination, ProtocolVersion } from '@standardnotes/common'
import { ApiVersion } from '@standardnotes/api'
import { SignInWithRecoveryCodes } from '../Domain/UseCase/SignInWithRecoveryCodes/SignInWithRecoveryCodes' import { SignInWithRecoveryCodes } from '../Domain/UseCase/SignInWithRecoveryCodes/SignInWithRecoveryCodes'
import { GetUserKeyParamsRecovery } from '../Domain/UseCase/GetUserKeyParamsRecovery/GetUserKeyParamsRecovery' import { GetUserKeyParamsRecovery } from '../Domain/UseCase/GetUserKeyParamsRecovery/GetUserKeyParamsRecovery'
import { GenerateRecoveryCodes } from '../Domain/UseCase/GenerateRecoveryCodes/GenerateRecoveryCodes' import { GenerateRecoveryCodes } from '../Domain/UseCase/GenerateRecoveryCodes/GenerateRecoveryCodes'
import { Logger } from 'winston' import { Logger } from 'winston'
import { SessionServiceInterface } from '../Domain/Session/SessionServiceInterface' import { SessionServiceInterface } from '../Domain/Session/SessionServiceInterface'
import { ApiVersion } from '../Domain/Api/ApiVersion'
describe('AuthController', () => { describe('AuthController', () => {
let clearLoginAttempts: ClearLoginAttempts let clearLoginAttempts: ClearLoginAttempts
@@ -73,7 +73,7 @@ describe('AuthController', () => {
email: 'test@test.te', email: 'test@test.te',
password: 'asdzxc', password: 'asdzxc',
version: ProtocolVersion.V004, version: ProtocolVersion.V004,
api: ApiVersion.v0, api: ApiVersion.v20200115,
origination: KeyParamsOrigination.Registration, origination: KeyParamsOrigination.Registration,
userAgent: 'Google Chrome', userAgent: 'Google Chrome',
identifier: 'test@test.te', identifier: 'test@test.te',
@@ -103,7 +103,7 @@ describe('AuthController', () => {
email: 'test@test.te', email: 'test@test.te',
password: '', password: '',
version: ProtocolVersion.V004, version: ProtocolVersion.V004,
api: ApiVersion.v0, api: ApiVersion.v20200115,
origination: KeyParamsOrigination.Registration, origination: KeyParamsOrigination.Registration,
userAgent: 'Google Chrome', userAgent: 'Google Chrome',
identifier: 'test@test.te', identifier: 'test@test.te',
@@ -123,7 +123,7 @@ describe('AuthController', () => {
email: 'test@test.te', email: 'test@test.te',
password: 'test', password: 'test',
version: ProtocolVersion.V004, version: ProtocolVersion.V004,
api: ApiVersion.v0, api: ApiVersion.v20200115,
origination: KeyParamsOrigination.Registration, origination: KeyParamsOrigination.Registration,
userAgent: 'Google Chrome', userAgent: 'Google Chrome',
identifier: 'test@test.te', identifier: 'test@test.te',
@@ -1,10 +1,10 @@
import { DomainEventPublisherInterface } from '@standardnotes/domain-events' import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
import { import {
ApiVersion,
UserRegistrationRequestParams, UserRegistrationRequestParams,
UserServerInterface, UserServerInterface,
UserDeletionResponseBody, UserDeletionResponseBody,
UserRegistrationResponseBody, UserRegistrationResponseBody,
UserUpdateRequestParams,
} from '@standardnotes/api' } from '@standardnotes/api'
import { ErrorTag, HttpResponse, HttpStatusCode } from '@standardnotes/responses' import { ErrorTag, HttpResponse, HttpStatusCode } from '@standardnotes/responses'
import { ProtocolVersion } from '@standardnotes/common' import { ProtocolVersion } from '@standardnotes/common'
@@ -23,6 +23,8 @@ import { GenerateRecoveryCodes } from '../Domain/UseCase/GenerateRecoveryCodes/G
import { GenerateRecoveryCodesRequestParams } from '../Infra/Http/Request/GenerateRecoveryCodesRequestParams' import { GenerateRecoveryCodesRequestParams } from '../Infra/Http/Request/GenerateRecoveryCodesRequestParams'
import { Logger } from 'winston' import { Logger } from 'winston'
import { SessionServiceInterface } from '../Domain/Session/SessionServiceInterface' 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 { export class AuthController implements UserServerInterface {
constructor( constructor(
@@ -37,6 +39,10 @@ export class AuthController implements UserServerInterface {
private sessionService: SessionServiceInterface, private sessionService: SessionServiceInterface,
) {} ) {}
async update(_params: UserUpdateRequestParams): Promise<HttpResponse<UserUpdateResponse>> {
throw new Error('Method not implemented.')
}
async deleteAccount(_params: never): Promise<HttpResponse<UserDeletionResponseBody>> { async deleteAccount(_params: never): Promise<HttpResponse<UserDeletionResponseBody>> {
throw new Error('This method is implemented on the payments server.') throw new Error('This method is implemented on the payments server.')
} }
@@ -121,7 +127,7 @@ export class AuthController implements UserServerInterface {
async signInWithRecoveryCodes( async signInWithRecoveryCodes(
params: SignInWithRecoveryCodesRequestParams, params: SignInWithRecoveryCodesRequestParams,
): Promise<HttpResponse<SignInWithRecoveryCodesResponseBody>> { ): Promise<HttpResponse<SignInWithRecoveryCodesResponseBody>> {
if (params.apiVersion !== ApiVersion.v0) { if (params.apiVersion !== ApiVersion.v20200115) {
return { return {
status: HttpStatusCode.BadRequest, status: HttpStatusCode.BadRequest,
data: { data: {
@@ -162,7 +168,7 @@ export class AuthController implements UserServerInterface {
async recoveryKeyParams( async recoveryKeyParams(
params: RecoveryKeyParamsRequestParams, params: RecoveryKeyParamsRequestParams,
): Promise<HttpResponse<RecoveryKeyParamsResponseBody>> { ): Promise<HttpResponse<RecoveryKeyParamsResponseBody>> {
if (params.apiVersion !== ApiVersion.v0) { if (params.apiVersion !== ApiVersion.v20200115) {
return { return {
status: HttpStatusCode.BadRequest, status: HttpStatusCode.BadRequest,
data: { data: {
@@ -7,7 +7,7 @@ import { AcceptSharedSubscriptionInvitation } from '../Domain/UseCase/AcceptShar
import { DeclineSharedSubscriptionInvitation } from '../Domain/UseCase/DeclineSharedSubscriptionInvitation/DeclineSharedSubscriptionInvitation' import { DeclineSharedSubscriptionInvitation } from '../Domain/UseCase/DeclineSharedSubscriptionInvitation/DeclineSharedSubscriptionInvitation'
import { CancelSharedSubscriptionInvitation } from '../Domain/UseCase/CancelSharedSubscriptionInvitation/CancelSharedSubscriptionInvitation' import { CancelSharedSubscriptionInvitation } from '../Domain/UseCase/CancelSharedSubscriptionInvitation/CancelSharedSubscriptionInvitation'
import { ListSharedSubscriptionInvitations } from '../Domain/UseCase/ListSharedSubscriptionInvitations/ListSharedSubscriptionInvitations' import { ListSharedSubscriptionInvitations } from '../Domain/UseCase/ListSharedSubscriptionInvitations/ListSharedSubscriptionInvitations'
import { ApiVersion } from '@standardnotes/api' import { ApiVersion } from '../Domain/Api/ApiVersion'
describe('SubscriptionInvitesController', () => { describe('SubscriptionInvitesController', () => {
let inviteToSharedSubscription: InviteToSharedSubscription let inviteToSharedSubscription: InviteToSharedSubscription
@@ -53,7 +53,7 @@ describe('SubscriptionInvitesController', () => {
invitations: [], 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({ expect(listSharedSubscriptionInvitations.execute).toHaveBeenCalledWith({
inviterEmail: 'test@test.te', inviterEmail: 'test@test.te',
@@ -68,7 +68,7 @@ describe('SubscriptionInvitesController', () => {
}) })
const result = await createController().cancelInvite({ const result = await createController().cancelInvite({
api: ApiVersion.v0, api: ApiVersion.v20200115,
inviteUuid: '1-2-3', inviteUuid: '1-2-3',
inviterEmail: 'test@test.te', inviterEmail: 'test@test.te',
}) })
@@ -87,7 +87,7 @@ describe('SubscriptionInvitesController', () => {
}) })
const result = await createController().cancelInvite({ const result = await createController().cancelInvite({
api: ApiVersion.v0, api: ApiVersion.v20200115,
inviteUuid: '1-2-3', inviteUuid: '1-2-3',
}) })
@@ -100,7 +100,7 @@ describe('SubscriptionInvitesController', () => {
}) })
const result = await createController().declineInvite({ const result = await createController().declineInvite({
api: ApiVersion.v0, api: ApiVersion.v20200115,
inviteUuid: '1-2-3', inviteUuid: '1-2-3',
}) })
@@ -117,7 +117,7 @@ describe('SubscriptionInvitesController', () => {
}) })
const result = await createController().declineInvite({ const result = await createController().declineInvite({
api: ApiVersion.v0, api: ApiVersion.v20200115,
inviteUuid: '1-2-3', inviteUuid: '1-2-3',
}) })
@@ -134,7 +134,7 @@ describe('SubscriptionInvitesController', () => {
}) })
const result = await createController().acceptInvite({ const result = await createController().acceptInvite({
api: ApiVersion.v0, api: ApiVersion.v20200115,
inviteUuid: '1-2-3', inviteUuid: '1-2-3',
}) })
@@ -151,7 +151,7 @@ describe('SubscriptionInvitesController', () => {
}) })
const result = await createController().acceptInvite({ const result = await createController().acceptInvite({
api: ApiVersion.v0, api: ApiVersion.v20200115,
inviteUuid: '1-2-3', inviteUuid: '1-2-3',
}) })
@@ -168,7 +168,7 @@ describe('SubscriptionInvitesController', () => {
}) })
const result = await createController().invite({ const result = await createController().invite({
api: ApiVersion.v0, api: ApiVersion.v20200115,
identifier: 'invitee@test.te', identifier: 'invitee@test.te',
inviterUuid: '1-2-3', inviterUuid: '1-2-3',
inviterEmail: 'test@test.te', 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 () => { it('should not invite to user subscription if the identifier is missing in request', async () => {
const result = await createController().invite({ const result = await createController().invite({
api: ApiVersion.v0, api: ApiVersion.v20200115,
identifier: '', identifier: '',
inviterUuid: '1-2-3', inviterUuid: '1-2-3',
inviterEmail: 'test@test.te', inviterEmail: 'test@test.te',
@@ -205,7 +205,7 @@ describe('SubscriptionInvitesController', () => {
}) })
const result = await createController().invite({ const result = await createController().invite({
api: ApiVersion.v0, api: ApiVersion.v20200115,
identifier: 'invitee@test.te', identifier: 'invitee@test.te',
inviterUuid: '1-2-3', inviterUuid: '1-2-3',
inviterEmail: 'test@test.te', inviterEmail: 'test@test.te',
@@ -1,9 +1,5 @@
import { ProtocolVersion } from '@standardnotes/common' import { SimpleUserProjection } from '../../Projection/SimpleUserProjection'
export interface AuthResponse { export interface AuthResponse {
user: { user: SimpleUserProjection
uuid: string
email: string
protocolVersion: ProtocolVersion
}
} }
@@ -30,7 +30,7 @@ describe('AuthResponseFactory20161215', () => {
}) })
it('should create a 20161215 auth response', async () => { it('should create a 20161215 auth response', async () => {
const response = await createFactory().createResponse({ const result = await createFactory().createResponse({
user, user,
apiVersion: '20161215', apiVersion: '20161215',
userAgent: 'Google Chrome', userAgent: 'Google Chrome',
@@ -38,7 +38,7 @@ describe('AuthResponseFactory20161215', () => {
readonlyAccess: false, readonlyAccess: false,
}) })
expect(response).toEqual({ expect(result.response).toEqual({
user: { foo: 'bar' }, user: { foo: 'bar' },
token: 'foobar', token: 'foobar',
}) })
@@ -11,6 +11,7 @@ import { User } from '../User/User'
import { AuthResponse20161215 } from './AuthResponse20161215' import { AuthResponse20161215 } from './AuthResponse20161215'
import { AuthResponse20200115 } from './AuthResponse20200115' import { AuthResponse20200115 } from './AuthResponse20200115'
import { AuthResponseFactoryInterface } from './AuthResponseFactoryInterface' import { AuthResponseFactoryInterface } from './AuthResponseFactoryInterface'
import { Session } from '../Session/Session'
@injectable() @injectable()
export class AuthResponseFactory20161215 implements AuthResponseFactoryInterface { export class AuthResponseFactory20161215 implements AuthResponseFactoryInterface {
@@ -26,7 +27,7 @@ export class AuthResponseFactory20161215 implements AuthResponseFactoryInterface
userAgent: string userAgent: string
ephemeralSession: boolean ephemeralSession: boolean
readonlyAccess: boolean readonlyAccess: boolean
}): Promise<AuthResponse20161215 | AuthResponse20200115> { }): Promise<{ response: AuthResponse20161215 | AuthResponse20200115; session?: Session }> {
this.logger.debug(`Creating JWT auth response for user ${dto.user.uuid}`) this.logger.debug(`Creating JWT auth response for user ${dto.user.uuid}`)
const data: SessionTokenData = { const data: SessionTokenData = {
@@ -39,12 +40,14 @@ export class AuthResponseFactory20161215 implements AuthResponseFactoryInterface
this.logger.debug(`Created JWT token for user ${dto.user.uuid}: ${token}`) this.logger.debug(`Created JWT token for user ${dto.user.uuid}: ${token}`)
return { return {
user: this.userProjector.projectSimple(dto.user) as { response: {
uuid: string user: this.userProjector.projectSimple(dto.user) as {
email: string uuid: string
protocolVersion: ProtocolVersion email: string
protocolVersion: ProtocolVersion
},
token,
}, },
token,
} }
} }
} }
@@ -29,7 +29,7 @@ describe('AuthResponseFactory20190520', () => {
}) })
it('should create a 20161215 auth response', async () => { it('should create a 20161215 auth response', async () => {
const response = await createFactory().createResponse({ const result = await createFactory().createResponse({
user, user,
apiVersion: '20161215', apiVersion: '20161215',
userAgent: 'Google Chrome', userAgent: 'Google Chrome',
@@ -37,7 +37,7 @@ describe('AuthResponseFactory20190520', () => {
readonlyAccess: false, readonlyAccess: false,
}) })
expect(response).toEqual({ expect(result.response).toEqual({
user: { foo: 'bar' }, user: { foo: 'bar' },
token: 'foobar', token: 'foobar',
}) })
@@ -11,6 +11,7 @@ import { User } from '../User/User'
import { AuthResponseFactory20200115 } from './AuthResponseFactory20200115' import { AuthResponseFactory20200115 } from './AuthResponseFactory20200115'
import { DomainEventPublisherInterface } from '@standardnotes/domain-events' import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
import { DomainEventFactoryInterface } from '../Event/DomainEventFactoryInterface' import { DomainEventFactoryInterface } from '../Event/DomainEventFactoryInterface'
import { Session } from '../Session/Session'
describe('AuthResponseFactory20200115', () => { describe('AuthResponseFactory20200115', () => {
let sessionService: SessionServiceInterface let sessionService: SessionServiceInterface
@@ -48,8 +49,12 @@ describe('AuthResponseFactory20200115', () => {
} }
sessionService = {} as jest.Mocked<SessionServiceInterface> sessionService = {} as jest.Mocked<SessionServiceInterface>
sessionService.createNewSessionForUser = jest.fn().mockReturnValue(sessionPayload) sessionService.createNewSessionForUser = jest
sessionService.createNewEphemeralSessionForUser = jest.fn().mockReturnValue(sessionPayload) .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 = {} as jest.Mocked<KeyParamsFactoryInterface>
keyParamsFactory.create = jest.fn().mockReturnValue({ 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 () => { it('should create a 20161215 auth response if user does not support sessions', async () => {
user.supportsSessions = jest.fn().mockReturnValue(false) user.supportsSessions = jest.fn().mockReturnValue(false)
const response = await createFactory().createResponse({ const result = await createFactory().createResponse({
user, user,
apiVersion: '20161215', apiVersion: '20161215',
userAgent: 'Google Chrome', userAgent: 'Google Chrome',
@@ -84,7 +89,7 @@ describe('AuthResponseFactory20200115', () => {
readonlyAccess: false, readonlyAccess: false,
}) })
expect(response).toEqual({ expect(result.response).toEqual({
user: { foo: 'bar' }, user: { foo: 'bar' },
token: expect.any(String), token: expect.any(String),
}) })
@@ -93,7 +98,7 @@ describe('AuthResponseFactory20200115', () => {
it('should create a 20200115 auth response', async () => { it('should create a 20200115 auth response', async () => {
user.supportsSessions = jest.fn().mockReturnValue(true) user.supportsSessions = jest.fn().mockReturnValue(true)
const response = await createFactory().createResponse({ const result = await createFactory().createResponse({
user, user,
apiVersion: '20200115', apiVersion: '20200115',
userAgent: 'Google Chrome', userAgent: 'Google Chrome',
@@ -101,7 +106,7 @@ describe('AuthResponseFactory20200115', () => {
readonlyAccess: false, readonlyAccess: false,
}) })
expect(response).toEqual({ expect(result.response).toEqual({
key_params: { key_params: {
key1: 'value1', key1: 'value1',
key2: 'value2', key2: 'value2',
@@ -124,7 +129,7 @@ describe('AuthResponseFactory20200115', () => {
domainEventPublisher.publish = jest.fn().mockRejectedValue(new Error('test')) domainEventPublisher.publish = jest.fn().mockRejectedValue(new Error('test'))
user.supportsSessions = jest.fn().mockReturnValue(true) user.supportsSessions = jest.fn().mockReturnValue(true)
const response = await createFactory().createResponse({ const result = await createFactory().createResponse({
user, user,
apiVersion: '20200115', apiVersion: '20200115',
userAgent: 'Google Chrome', userAgent: 'Google Chrome',
@@ -132,7 +137,7 @@ describe('AuthResponseFactory20200115', () => {
readonlyAccess: false, readonlyAccess: false,
}) })
expect(response).toEqual({ expect(result.response).toEqual({
key_params: { key_params: {
key1: 'value1', key1: 'value1',
key2: 'value2', key2: 'value2',
@@ -153,7 +158,7 @@ describe('AuthResponseFactory20200115', () => {
it('should create a 20200115 auth response with an ephemeral session', async () => { it('should create a 20200115 auth response with an ephemeral session', async () => {
user.supportsSessions = jest.fn().mockReturnValue(true) user.supportsSessions = jest.fn().mockReturnValue(true)
const response = await createFactory().createResponse({ const result = await createFactory().createResponse({
user, user,
apiVersion: '20200115', apiVersion: '20200115',
userAgent: 'Google Chrome', userAgent: 'Google Chrome',
@@ -161,7 +166,7 @@ describe('AuthResponseFactory20200115', () => {
readonlyAccess: false, readonlyAccess: false,
}) })
expect(response).toEqual({ expect(result.response).toEqual({
key_params: { key_params: {
key1: 'value1', key1: 'value1',
key2: 'value2', key2: 'value2',
@@ -183,11 +188,14 @@ describe('AuthResponseFactory20200115', () => {
user.supportsSessions = jest.fn().mockReturnValue(true) user.supportsSessions = jest.fn().mockReturnValue(true)
sessionService.createNewSessionForUser = jest.fn().mockReturnValue({ sessionService.createNewSessionForUser = jest.fn().mockReturnValue({
...sessionPayload, sessionHttpRepresentation: {
readonly_access: true, ...sessionPayload,
readonly_access: true,
},
session: {} as jest.Mocked<Session>,
}) })
const response = await createFactory().createResponse({ const result = await createFactory().createResponse({
user, user,
apiVersion: '20200115', apiVersion: '20200115',
userAgent: 'Google Chrome', userAgent: 'Google Chrome',
@@ -195,7 +203,7 @@ describe('AuthResponseFactory20200115', () => {
readonlyAccess: true, readonlyAccess: true,
}) })
expect(response).toEqual({ expect(result.response).toEqual({
key_params: { key_params: {
key1: 'value1', key1: 'value1',
key2: 'value2', key2: 'value2',
@@ -4,13 +4,13 @@ import {
TokenEncoderInterface, TokenEncoderInterface,
} from '@standardnotes/security' } from '@standardnotes/security'
import { DomainEventPublisherInterface } from '@standardnotes/domain-events' import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
import { ProtocolVersion } from '@standardnotes/common'
import { SessionBody } from '@standardnotes/responses' import { SessionBody } from '@standardnotes/responses'
import { inject, injectable } from 'inversify' import { inject, injectable } from 'inversify'
import { Logger } from 'winston' import { Logger } from 'winston'
import TYPES from '../../Bootstrap/Types' import TYPES from '../../Bootstrap/Types'
import { ProjectorInterface } from '../../Projection/ProjectorInterface' import { ProjectorInterface } from '../../Projection/ProjectorInterface'
import { SimpleUserProjection } from '../../Projection/SimpleUserProjection'
import { SessionServiceInterface } from '../Session/SessionServiceInterface' import { SessionServiceInterface } from '../Session/SessionServiceInterface'
import { KeyParamsFactoryInterface } from '../User/KeyParamsFactoryInterface' import { KeyParamsFactoryInterface } from '../User/KeyParamsFactoryInterface'
import { User } from '../User/User' import { User } from '../User/User'
@@ -19,6 +19,7 @@ import { DomainEventFactoryInterface } from '../Event/DomainEventFactoryInterfac
import { AuthResponse20161215 } from './AuthResponse20161215' import { AuthResponse20161215 } from './AuthResponse20161215'
import { AuthResponse20200115 } from './AuthResponse20200115' import { AuthResponse20200115 } from './AuthResponse20200115'
import { Session } from '../Session/Session'
@injectable() @injectable()
export class AuthResponseFactory20200115 extends AuthResponseFactory20190520 { export class AuthResponseFactory20200115 extends AuthResponseFactory20190520 {
@@ -40,25 +41,28 @@ export class AuthResponseFactory20200115 extends AuthResponseFactory20190520 {
userAgent: string userAgent: string
ephemeralSession: boolean ephemeralSession: boolean
readonlyAccess: boolean readonlyAccess: boolean
}): Promise<AuthResponse20161215 | AuthResponse20200115> { }): Promise<{ response: AuthResponse20161215 | AuthResponse20200115; session?: Session }> {
if (!dto.user.supportsSessions()) { if (!dto.user.supportsSessions()) {
this.logger.debug(`User ${dto.user.uuid} does not support sessions. Falling back to JWT auth response`) this.logger.debug(`User ${dto.user.uuid} does not support sessions. Falling back to JWT auth response`)
return super.createResponse(dto) 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 { return {
session: sessionPayload, response: {
key_params: this.keyParamsFactory.create(dto.user, true), session: sessionCreationResult.sessionHttpRepresentation,
user: this.userProjector.projectSimple(dto.user) as { key_params: this.keyParamsFactory.create(dto.user, true),
uuid: string user: this.userProjector.projectSimple(dto.user) as SimpleUserProjection,
email: string
protocolVersion: ProtocolVersion
}, },
session: sessionCreationResult.session,
} }
} }
@@ -68,12 +72,12 @@ export class AuthResponseFactory20200115 extends AuthResponseFactory20190520 {
userAgent: string userAgent: string
ephemeralSession: boolean ephemeralSession: boolean
readonlyAccess: boolean readonlyAccess: boolean
}): Promise<SessionBody> { }): Promise<{ sessionHttpRepresentation: SessionBody; session: Session }> {
if (dto.ephemeralSession) { if (dto.ephemeralSession) {
return this.sessionService.createNewEphemeralSessionForUser(dto) return this.sessionService.createNewEphemeralSessionForUser(dto)
} }
const session = this.sessionService.createNewSessionForUser(dto) const sessionCreationResult = await this.sessionService.createNewSessionForUser(dto)
try { try {
await this.domainEventPublisher.publish( 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}`) this.logger.error(`Failed to publish session created event: ${(error as Error).message}`)
} }
return session return sessionCreationResult
} }
} }
@@ -1,3 +1,4 @@
import { Session } from '../Session/Session'
import { User } from '../User/User' import { User } from '../User/User'
import { AuthResponse20161215 } from './AuthResponse20161215' import { AuthResponse20161215 } from './AuthResponse20161215'
import { AuthResponse20200115 } from './AuthResponse20200115' import { AuthResponse20200115 } from './AuthResponse20200115'
@@ -9,5 +10,5 @@ export interface AuthResponseFactoryInterface {
userAgent: string userAgent: string
ephemeralSession: boolean ephemeralSession: boolean
readonlyAccess: boolean readonlyAccess: boolean
}): Promise<AuthResponse20161215 | AuthResponse20200115> }): Promise<{ response: AuthResponse20161215 | AuthResponse20200115; session?: Session }>
} }
@@ -9,6 +9,7 @@ import { User } from '../User/User'
import { UserRepositoryInterface } from '../User/UserRepositoryInterface' import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
import { AuthenticationMethodResolver } from './AuthenticationMethodResolver' import { AuthenticationMethodResolver } from './AuthenticationMethodResolver'
import { Logger } from 'winston'
describe('AuthenticationMethodResolver', () => { describe('AuthenticationMethodResolver', () => {
let userRepository: UserRepositoryInterface let userRepository: UserRepositoryInterface
@@ -18,14 +19,20 @@ describe('AuthenticationMethodResolver', () => {
let user: User let user: User
let session: Session let session: Session
let revokedSession: RevokedSession let revokedSession: RevokedSession
let logger: Logger
const createResolver = () => const createResolver = () =>
new AuthenticationMethodResolver(userRepository, sessionService, sessionTokenDecoder, fallbackTokenDecoder) new AuthenticationMethodResolver(userRepository, sessionService, sessionTokenDecoder, fallbackTokenDecoder, logger)
beforeEach(() => { beforeEach(() => {
logger = {} as jest.Mocked<Logger>
logger.debug = jest.fn()
user = {} as jest.Mocked<User> 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> revokedSession = {} as jest.Mocked<RevokedSession>
@@ -33,7 +40,7 @@ describe('AuthenticationMethodResolver', () => {
userRepository.findOneByUuid = jest.fn().mockReturnValue(user) userRepository.findOneByUuid = jest.fn().mockReturnValue(user)
sessionService = {} as jest.Mocked<SessionServiceInterface> sessionService = {} as jest.Mocked<SessionServiceInterface>
sessionService.getSessionFromToken = jest.fn() sessionService.getSessionFromToken = jest.fn().mockReturnValue({ session: undefined, isEphemeral: false })
sessionService.getRevokedSessionFromToken = jest.fn() sessionService.getRevokedSessionFromToken = jest.fn()
sessionService.markRevokedSessionAsReceived = jest.fn().mockReturnValue(revokedSession) sessionService.markRevokedSessionAsReceived = jest.fn().mockReturnValue(revokedSession)
@@ -45,19 +52,25 @@ describe('AuthenticationMethodResolver', () => {
}) })
it('should resolve jwt authentication method', async () => { 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({ expect(await createResolver().resolve('test')).toEqual({
claims: { claims: {
user_uuid: '123', user_uuid: '00000000-0000-0000-0000-000000000000',
}, },
type: 'jwt', type: 'jwt',
user, 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 () => { 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({ expect(await createResolver().resolve('test')).toEqual({
session, 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 () => { it('should resolve archvied session authentication method', async () => {
sessionService.getRevokedSessionFromToken = jest.fn().mockReturnValue(revokedSession) sessionService.getRevokedSessionFromToken = jest.fn().mockReturnValue(revokedSession)
@@ -5,6 +5,8 @@ import { SessionServiceInterface } from '../Session/SessionServiceInterface'
import { UserRepositoryInterface } from '../User/UserRepositoryInterface' import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
import { AuthenticationMethod } from './AuthenticationMethod' import { AuthenticationMethod } from './AuthenticationMethod'
import { AuthenticationMethodResolverInterface } from './AuthenticationMethodResolverInterface' import { AuthenticationMethodResolverInterface } from './AuthenticationMethodResolverInterface'
import { Logger } from 'winston'
import { Uuid } from '@standardnotes/domain-core'
@injectable() @injectable()
export class AuthenticationMethodResolver implements AuthenticationMethodResolverInterface { 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_SessionTokenDecoder) private sessionTokenDecoder: TokenDecoderInterface<SessionTokenData>,
@inject(TYPES.Auth_FallbackSessionTokenDecoder) @inject(TYPES.Auth_FallbackSessionTokenDecoder)
private fallbackSessionTokenDecoder: TokenDecoderInterface<SessionTokenData>, private fallbackSessionTokenDecoder: TokenDecoderInterface<SessionTokenData>,
@inject(TYPES.Auth_Logger) private logger: Logger,
) {} ) {}
async resolve(token: string): Promise<AuthenticationMethod | undefined> { async resolve(token: string): Promise<AuthenticationMethod | undefined> {
let decodedToken: SessionTokenData | undefined = this.sessionTokenDecoder.decodeToken(token) let decodedToken: SessionTokenData | undefined = this.sessionTokenDecoder.decodeToken(token)
if (decodedToken === undefined) { if (decodedToken === undefined) {
this.logger.debug('Could not decode token with primary decoder, trying fallback decoder.')
decodedToken = this.fallbackSessionTokenDecoder.decodeToken(token) decodedToken = this.fallbackSessionTokenDecoder.decodeToken(token)
} }
if (decodedToken) { 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 { return {
type: 'jwt', type: 'jwt',
user: await this.userRepository.findOneByUuid(<string>decodedToken.user_uuid), user: await this.userRepository.findOneByUuid(userUuid),
claims: decodedToken, claims: decodedToken,
} }
} }
const session = await this.sessionService.getSessionFromToken(token) const { session } = await this.sessionService.getSessionFromToken(token)
if (session) { 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 { return {
type: 'session_token', type: 'session_token',
user: await this.userRepository.findOneByUuid(session.userUuid), user: await this.userRepository.findOneByUuid(userUuid),
session: session, session: session,
} }
} }
const revokedSession = await this.sessionService.getRevokedSessionFromToken(token) const revokedSession = await this.sessionService.getRevokedSessionFromToken(token)
if (revokedSession) { if (revokedSession) {
this.logger.debug('Token decoded successfully. Revoked session found.')
return { return {
type: 'revoked', type: 'revoked',
revokedSession: await this.sessionService.markRevokedSessionAsReceived(revokedSession), revokedSession: await this.sessionService.markRevokedSessionAsReceived(revokedSession),
@@ -48,6 +71,8 @@ export class AuthenticationMethodResolver implements AuthenticationMethodResolve
} }
} }
this.logger.debug('Could not decode token.')
return undefined return undefined
} }
} }
@@ -3,10 +3,6 @@ import { Entity, Result, UniqueEntityId } from '@standardnotes/domain-core'
import { AuthenticatorProps } from './AuthenticatorProps' import { AuthenticatorProps } from './AuthenticatorProps'
export class Authenticator extends Entity<AuthenticatorProps> { export class Authenticator extends Entity<AuthenticatorProps> {
get id(): UniqueEntityId {
return this._id
}
private constructor(props: AuthenticatorProps, id?: UniqueEntityId) { private constructor(props: AuthenticatorProps, id?: UniqueEntityId) {
super(props, id) super(props, id)
} }
@@ -3,10 +3,6 @@ import { Entity, Result, UniqueEntityId } from '@standardnotes/domain-core'
import { AuthenticatorChallengeProps } from './AuthenticatorChallengeProps' import { AuthenticatorChallengeProps } from './AuthenticatorChallengeProps'
export class AuthenticatorChallenge extends Entity<AuthenticatorChallengeProps> { export class AuthenticatorChallenge extends Entity<AuthenticatorChallengeProps> {
get id(): UniqueEntityId {
return this._id
}
private constructor(props: AuthenticatorChallengeProps, id?: UniqueEntityId) { private constructor(props: AuthenticatorChallengeProps, id?: UniqueEntityId) {
super(props, id) super(props, id)
} }
@@ -3,10 +3,6 @@ import { Entity, Result, UniqueEntityId } from '@standardnotes/domain-core'
import { EmergencyAccessInvitationProps } from './EmergencyAccessInvitationProps' import { EmergencyAccessInvitationProps } from './EmergencyAccessInvitationProps'
export class EmergencyAccessInvitation extends Entity<EmergencyAccessInvitationProps> { export class EmergencyAccessInvitation extends Entity<EmergencyAccessInvitationProps> {
get id(): UniqueEntityId {
return this._id
}
private constructor(props: EmergencyAccessInvitationProps, id?: UniqueEntityId) { private constructor(props: EmergencyAccessInvitationProps, id?: UniqueEntityId) {
super(props, id) super(props, id)
} }
@@ -50,7 +50,7 @@ describe('AccountDeletionRequestedEventHandler', () => {
ephemeralSession = { ephemeralSession = {
uuid: '2-3-4', uuid: '2-3-4',
userUuid: '1-2-3', userUuid: '00000000-0000-0000-0000-000000000000',
} as jest.Mocked<EphemeralSession> } as jest.Mocked<EphemeralSession>
ephemeralSessionRepository = {} as jest.Mocked<EphemeralSessionRepositoryInterface> ephemeralSessionRepository = {} as jest.Mocked<EphemeralSessionRepositoryInterface>
@@ -68,7 +68,7 @@ describe('AccountDeletionRequestedEventHandler', () => {
event = {} as jest.Mocked<AccountDeletionRequestedEvent> event = {} as jest.Mocked<AccountDeletionRequestedEvent>
event.createdAt = new Date(1) event.createdAt = new Date(1)
event.payload = { event.payload = {
userUuid: '1-2-3', userUuid: '00000000-0000-0000-0000-000000000000',
userCreatedAtTimestamp: 1, userCreatedAtTimestamp: 1,
regularSubscriptionUuid: '2-3-4', regularSubscriptionUuid: '2-3-4',
} }
@@ -84,6 +84,14 @@ describe('AccountDeletionRequestedEventHandler', () => {
expect(userRepository.remove).toHaveBeenCalledWith(user) expect(userRepository.remove).toHaveBeenCalledWith(user)
}) })
it('should not remove a user with invalid uuid', async () => {
event.payload.userUuid = 'invalid'
await createHandler().handle(event)
expect(userRepository.remove).not.toHaveBeenCalled()
})
it('should not remove a user if one does not exist', async () => { it('should not remove a user if one does not exist', async () => {
userRepository.findOneByUuid = jest.fn().mockReturnValue(null) userRepository.findOneByUuid = jest.fn().mockReturnValue(null)
@@ -100,6 +108,6 @@ describe('AccountDeletionRequestedEventHandler', () => {
expect(sessionRepository.remove).toHaveBeenCalledWith(session) expect(sessionRepository.remove).toHaveBeenCalledWith(session)
expect(revokedSessionRepository.remove).toHaveBeenCalledWith(revokedSession) expect(revokedSessionRepository.remove).toHaveBeenCalledWith(revokedSession)
expect(ephemeralSessionRepository.deleteOne).toHaveBeenCalledWith('2-3-4', '1-2-3') expect(ephemeralSessionRepository.deleteOne).toHaveBeenCalledWith('2-3-4', '00000000-0000-0000-0000-000000000000')
}) })
}) })
@@ -6,6 +6,7 @@ import { EphemeralSessionRepositoryInterface } from '../Session/EphemeralSession
import { RevokedSessionRepositoryInterface } from '../Session/RevokedSessionRepositoryInterface' import { RevokedSessionRepositoryInterface } from '../Session/RevokedSessionRepositoryInterface'
import { SessionRepositoryInterface } from '../Session/SessionRepositoryInterface' import { SessionRepositoryInterface } from '../Session/SessionRepositoryInterface'
import { UserRepositoryInterface } from '../User/UserRepositoryInterface' import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
import { Uuid } from '@standardnotes/domain-core'
@injectable() @injectable()
export class AccountDeletionRequestedEventHandler implements DomainEventHandlerInterface { export class AccountDeletionRequestedEventHandler implements DomainEventHandlerInterface {
@@ -19,19 +20,27 @@ export class AccountDeletionRequestedEventHandler implements DomainEventHandlerI
) {} ) {}
async handle(event: AccountDeletionRequestedEvent): Promise<void> { async handle(event: AccountDeletionRequestedEvent): Promise<void> {
const user = await this.userRepository.findOneByUuid(event.payload.userUuid) const userUuidOrError = Uuid.create(event.payload.userUuid)
if (userUuidOrError.isFailed()) {
if (user === null) {
this.logger.warn(`Could not find user with uuid: ${event.payload.userUuid}`) this.logger.warn(`Could not find user with uuid: ${event.payload.userUuid}`)
return return
} }
const userUuid = userUuidOrError.getValue()
await this.removeSessions(event.payload.userUuid) const user = await this.userRepository.findOneByUuid(userUuid)
if (user === null) {
this.logger.warn(`Could not find user with uuid: ${userUuid.value}`)
return
}
await this.removeSessions(userUuid.value)
await this.userRepository.remove(user) await this.userRepository.remove(user)
this.logger.info(`Finished account cleanup for user: ${event.payload.userUuid}`) this.logger.info(`Finished account cleanup for user: ${userUuid.value}`)
} }
private async removeSessions(userUuid: string): Promise<void> { private async removeSessions(userUuid: string): Promise<void> {

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