mirror of
https://github.com/standardnotes/server
synced 2026-01-17 14:04:28 -05:00
Compare commits
109 Commits
@standardn
...
@standardn
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6778a80f21 | ||
|
|
d4d49454a6 | ||
|
|
04b52e6773 | ||
|
|
2a1859e4be | ||
|
|
dd9a9c68cb | ||
|
|
9147ff5d49 | ||
|
|
503b84531b | ||
|
|
fe8ca828fb | ||
|
|
03a4a3f2ab | ||
|
|
3a8607d146 | ||
|
|
93b6e65554 | ||
|
|
5984e4c3e7 | ||
|
|
b4257c10ea | ||
|
|
c164bde847 | ||
|
|
883df939dd | ||
|
|
c7807d0f9e | ||
|
|
fc90343aaa | ||
|
|
fbcb45c3a2 | ||
|
|
179d8eaaa1 | ||
|
|
38685c1861 | ||
|
|
cdf42fbe2d | ||
|
|
9be4c002b7 | ||
|
|
a16c5307a0 | ||
|
|
d5536f5430 | ||
|
|
b1d88b15be | ||
|
|
ff78285e43 | ||
|
|
1a26221385 | ||
|
|
54113abe2a | ||
|
|
afe385aed4 | ||
|
|
f055e52e06 | ||
|
|
fab5d18064 | ||
|
|
a1e654a0d0 | ||
|
|
aa835268ea | ||
|
|
74b4312928 | ||
|
|
e91a832152 | ||
|
|
4f95bbee3f | ||
|
|
b9c9f74d0c | ||
|
|
e535cd504c | ||
|
|
db0360860a | ||
|
|
aa2b5f3b74 | ||
|
|
6241661e27 | ||
|
|
25047bf46d | ||
|
|
a1820ed212 | ||
|
|
0a1d1624e8 | ||
|
|
7367de6832 | ||
|
|
f0abfe89fc | ||
|
|
d1244d165a | ||
|
|
106d8f9192 | ||
|
|
1d86ba8fcb | ||
|
|
f20a947f8a | ||
|
|
19b9de05ae | ||
|
|
1d751c0fbe | ||
|
|
fa2564e164 | ||
|
|
330bff0124 | ||
|
|
ca57c8e7b5 | ||
|
|
a82b9a0c8a | ||
|
|
ea7e9d73c4 | ||
|
|
117b7b4b99 | ||
|
|
b4bf11d9da | ||
|
|
0306e10469 | ||
|
|
0ab47013f2 | ||
|
|
836883b82d | ||
|
|
ed671be9c5 | ||
|
|
9676a2586c | ||
|
|
e95ba61c7f | ||
|
|
a0718aea26 | ||
|
|
156fa7a618 | ||
|
|
8d006ece30 | ||
|
|
037c994040 | ||
|
|
a164ba291d | ||
|
|
610fba2601 | ||
|
|
398338c8f8 | ||
|
|
34be157d8e | ||
|
|
76372fe357 | ||
|
|
46879c336b | ||
|
|
aef9e936bd | ||
|
|
8cb92d9678 | ||
|
|
52db89de81 | ||
|
|
c5af8dfc05 | ||
|
|
27ad8e6959 | ||
|
|
c4a1502f70 | ||
|
|
d1d6c753c4 | ||
|
|
3bd63f7674 | ||
|
|
376466d9b2 | ||
|
|
e100c52bbc | ||
|
|
d4830dec01 | ||
|
|
7e11821021 | ||
|
|
4715e019a2 | ||
|
|
794cd8734a | ||
|
|
14d42b26bb | ||
|
|
6bb44afd91 | ||
|
|
c82345aeeb | ||
|
|
72ab08a0d0 | ||
|
|
f2d1b47e40 | ||
|
|
d9ee2c5be2 | ||
|
|
eb59902cf7 | ||
|
|
002074e4d1 | ||
|
|
45b55068f9 | ||
|
|
157eee5d93 | ||
|
|
d5f2b4f6eb | ||
|
|
a7a93497e8 | ||
|
|
8f96f0ed7a | ||
|
|
3f064176f2 | ||
|
|
c7b0c7dfa8 | ||
|
|
df20dd46db | ||
|
|
6dfd09989e | ||
|
|
fc821709e2 | ||
|
|
e986abaab5 | ||
|
|
a006fb3119 |
1
.github/ci.env
vendored
1
.github/ci.env
vendored
@@ -4,6 +4,7 @@ DB_USERNAME=std_notes_user
|
||||
DB_PASSWORD=changeme123
|
||||
DB_DATABASE=standard_notes_db
|
||||
DB_PORT=3306
|
||||
DB_DEBUG_LEVEL=all
|
||||
DB_SQLITE_DATABASE_PATH=standard_notes_db
|
||||
REDIS_PORT=6379
|
||||
REDIS_HOST=cache
|
||||
|
||||
2
.github/workflows/common-docker-image.yml
vendored
2
.github/workflows/common-docker-image.yml
vendored
@@ -90,7 +90,7 @@ jobs:
|
||||
uses: docker/setup-buildx-action@master
|
||||
|
||||
- name: Publish Docker image
|
||||
uses: docker/build-push-action@v3
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
context: ${{ steps.bundle-dir.outputs.temp_dir }}
|
||||
|
||||
9
.github/workflows/common-e2e.yml
vendored
9
.github/workflows/common-e2e.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
e2e:
|
||||
name: (Self Hosting) E2E Test Suite
|
||||
strategy:
|
||||
fail-fast: true
|
||||
fail-fast: false
|
||||
matrix:
|
||||
secondary_db_enabled: [true, false]
|
||||
transition_mode_enabled: [true, false]
|
||||
@@ -57,7 +57,7 @@ jobs:
|
||||
run: docker/is-available.sh http://localhost:3123 $(pwd)/logs
|
||||
|
||||
- name: Run E2E Test Suite
|
||||
run: yarn dlx mocha-headless-chrome --timeout 1800000 -f http://localhost:9001/mocha/test.html
|
||||
run: yarn dlx mocha-headless-chrome --timeout 3600000 -f http://localhost:9001/mocha/test.html
|
||||
|
||||
- name: Show logs on failure
|
||||
if: ${{ failure() }}
|
||||
@@ -70,7 +70,7 @@ jobs:
|
||||
e2e-home-server:
|
||||
name: (Home Server) E2E Test Suite
|
||||
strategy:
|
||||
fail-fast: true
|
||||
fail-fast: false
|
||||
matrix:
|
||||
db_type: [mysql, sqlite]
|
||||
cache_type: [redis, memory]
|
||||
@@ -141,6 +141,7 @@ jobs:
|
||||
echo "DB_USERNAME=standardnotes" >> packages/home-server/.env
|
||||
echo "DB_PASSWORD=standardnotes" >> packages/home-server/.env
|
||||
echo "DB_TYPE=${{ matrix.db_type }}" >> packages/home-server/.env
|
||||
echo "DB_DEBUG_LEVEL=all" >> packages/home-server/.env
|
||||
echo "REDIS_URL=redis://localhost:6379" >> packages/home-server/.env
|
||||
echo "CACHE_TYPE=${{ matrix.cache_type }}" >> packages/home-server/.env
|
||||
echo "SECONDARY_DB_ENABLED=${{ matrix.secondary_db_enabled }}" >> packages/home-server/.env
|
||||
@@ -162,7 +163,7 @@ jobs:
|
||||
run: for i in {1..30}; do curl -s http://localhost:3123/healthcheck && break || sleep 1; done
|
||||
|
||||
- name: Run E2E Test Suite
|
||||
run: yarn dlx mocha-headless-chrome --timeout 1800000 -f http://localhost:9001/mocha/test.html
|
||||
run: yarn dlx mocha-headless-chrome --timeout 3600000 -f http://localhost:9001/mocha/test.html
|
||||
|
||||
- name: Show logs on failure
|
||||
if: ${{ failure() }}
|
||||
|
||||
2
.github/workflows/common-self-hosting.yml
vendored
2
.github/workflows/common-self-hosting.yml
vendored
@@ -35,7 +35,7 @@ jobs:
|
||||
uses: docker/setup-buildx-action@master
|
||||
|
||||
- name: Publish Docker image
|
||||
uses: docker/build-push-action@v3
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
context: .
|
||||
|
||||
10
.github/workflows/e2e-test-suite.yml
vendored
10
.github/workflows/e2e-test-suite.yml
vendored
@@ -1,5 +1,7 @@
|
||||
name: E2E Test Suite On Self Hosted Server
|
||||
|
||||
run-name: E2E Test Suite against ${{ inputs.ref_name }} by ${{ inputs.author }}
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 */12 * * *'
|
||||
@@ -9,6 +11,14 @@ on:
|
||||
type: string
|
||||
default: latest
|
||||
description: The Docker image tag used for SNJS container
|
||||
author:
|
||||
type: string
|
||||
default: unknown
|
||||
description: The author that triggered the workflow
|
||||
ref_name:
|
||||
type: string
|
||||
default: unknown
|
||||
description: The ref name from which the workflow was triggered
|
||||
|
||||
jobs:
|
||||
e2e:
|
||||
|
||||
BIN
.yarn/cache/@aws-sdk-client-apigatewaymanagementapi-npm-3.405.0-e4e17d811f-d7103d0b37.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-client-apigatewaymanagementapi-npm-3.405.0-e4e17d811f-d7103d0b37.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-client-sso-npm-3.405.0-0b22768239-323f99e024.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-client-sso-npm-3.405.0-0b22768239-323f99e024.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-client-sts-npm-3.405.0-b83c3faf19-01ea2a8695.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-client-sts-npm-3.405.0-b83c3faf19-01ea2a8695.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-credential-provider-ini-npm-3.405.0-759c2d9674-0d2694b969.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-credential-provider-ini-npm-3.405.0-759c2d9674-0d2694b969.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-credential-provider-node-npm-3.405.0-33a4e3c01f-58cf90600d.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-credential-provider-node-npm-3.405.0-33a4e3c01f-58cf90600d.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-credential-provider-process-npm-3.405.0-ed6dc867ed-bd23e267bd.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-credential-provider-process-npm-3.405.0-ed6dc867ed-bd23e267bd.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-credential-provider-sso-npm-3.405.0-24b76ee82f-754f796b2a.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-credential-provider-sso-npm-3.405.0-24b76ee82f-754f796b2a.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-token-providers-npm-3.405.0-29e68d4065-08e30dbc7b.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-token-providers-npm-3.405.0-29e68d4065-08e30dbc7b.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-util-user-agent-node-npm-3.405.0-160b854f92-6422874d9e.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-util-user-agent-node-npm-3.405.0-160b854f92-6422874d9e.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@eslint-community-regexpp-npm-4.8.0-92ece47e3d-f6bfb776ff.zip
vendored
Normal file
BIN
.yarn/cache/@eslint-community-regexpp-npm-4.8.0-92ece47e3d-f6bfb776ff.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@simplewebauthn-server-npm-8.1.1-106d3bd108-a07c2a067b.zip
vendored
Normal file
BIN
.yarn/cache/@simplewebauthn-server-npm-8.1.1-106d3bd108-a07c2a067b.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@simplewebauthn-typescript-types-npm-8.0.0-f3b313c27b-21e0b13268.zip
vendored
Normal file
BIN
.yarn/cache/@simplewebauthn-typescript-types-npm-8.0.0-f3b313c27b-21e0b13268.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@smithy-credential-provider-imds-npm-2.0.7-46bd1e8858-61c59aea7e.zip
vendored
Normal file
BIN
.yarn/cache/@smithy-credential-provider-imds-npm-2.0.7-46bd1e8858-61c59aea7e.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@smithy-node-config-provider-npm-2.0.7-806b68f393-d4b58ee69f.zip
vendored
Normal file
BIN
.yarn/cache/@smithy-node-config-provider-npm-2.0.7-806b68f393-d4b58ee69f.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@smithy-property-provider-npm-2.0.6-4f294049d1-b9a4aff1f0.zip
vendored
Normal file
BIN
.yarn/cache/@smithy-property-provider-npm-2.0.6-4f294049d1-b9a4aff1f0.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@smithy-shared-ini-file-loader-npm-2.0.6-ebbee54019-4b538ef59a.zip
vendored
Normal file
BIN
.yarn/cache/@smithy-shared-ini-file-loader-npm-2.0.6-ebbee54019-4b538ef59a.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@smithy-util-defaults-mode-browser-npm-2.0.6-d40f165a01-286295e6e9.zip
vendored
Normal file
BIN
.yarn/cache/@smithy-util-defaults-mode-browser-npm-2.0.6-d40f165a01-286295e6e9.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@smithy-util-defaults-mode-node-npm-2.0.7-8a9d03e11c-b1c74a3b41.zip
vendored
Normal file
BIN
.yarn/cache/@smithy-util-defaults-mode-node-npm-2.0.7-8a9d03e11c-b1c74a3b41.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@types-uuid-npm-9.0.3-988861045e-a5357c6447.zip
vendored
Normal file
BIN
.yarn/cache/@types-uuid-npm-9.0.3-988861045e-a5357c6447.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@typescript-eslint-eslint-plugin-npm-6.5.0-f2e890b07d-971ee3f9d2.zip
vendored
Normal file
BIN
.yarn/cache/@typescript-eslint-eslint-plugin-npm-6.5.0-f2e890b07d-971ee3f9d2.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@typescript-eslint-type-utils-npm-6.5.0-805fdd8cb3-1c542cc1dd.zip
vendored
Normal file
BIN
.yarn/cache/@typescript-eslint-type-utils-npm-6.5.0-805fdd8cb3-1c542cc1dd.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@typescript-eslint-utils-npm-6.5.0-653e9ae1c1-5bddf2feb9.zip
vendored
Normal file
BIN
.yarn/cache/@typescript-eslint-utils-npm-6.5.0-653e9ae1c1-5bddf2feb9.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/cbor-x-npm-1.5.4-2d5a649a4b-742aea498a.zip
vendored
Normal file
BIN
.yarn/cache/cbor-x-npm-1.5.4-2d5a649a4b-742aea498a.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/cross-fetch-npm-4.0.0-9c67668db4-30e86b703a.zip
vendored
Normal file
BIN
.yarn/cache/cross-fetch-npm-4.0.0-9c67668db4-30e86b703a.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/node-fetch-npm-2.7.0-587d57004e-a3ad788903.zip
vendored
Normal file
BIN
.yarn/cache/node-fetch-npm-2.7.0-587d57004e-a3ad788903.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -53,7 +53,7 @@ services:
|
||||
image: mysql:8
|
||||
container_name: db-ci
|
||||
env_file: .github/ci.env
|
||||
expose:
|
||||
ports:
|
||||
- 3306
|
||||
restart: unless-stopped
|
||||
command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci
|
||||
@@ -66,7 +66,7 @@ services:
|
||||
secondary_db:
|
||||
image: mongo:5.0
|
||||
container_name: secondary_db-ci
|
||||
expose:
|
||||
ports:
|
||||
- 27017
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
@@ -83,7 +83,7 @@ services:
|
||||
container_name: cache-ci
|
||||
volumes:
|
||||
- ./data/redis/:/data
|
||||
expose:
|
||||
ports:
|
||||
- 6379
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
|
||||
@@ -3,6 +3,50 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.26.13](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.12...@standardnotes/analytics@2.26.13) (2023-09-15)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.26.12](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.11...@standardnotes/analytics@2.26.12) (2023-09-13)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.26.11](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.10...@standardnotes/analytics@2.26.11) (2023-09-12)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.26.10](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.9...@standardnotes/analytics@2.26.10) (2023-09-12)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.26.9](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.8...@standardnotes/analytics@2.26.9) (2023-09-12)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.26.8](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.7...@standardnotes/analytics@2.26.8) (2023-09-12)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.26.7](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.6...@standardnotes/analytics@2.26.7) (2023-09-08)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.26.6](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.5...@standardnotes/analytics@2.26.6) (2023-09-07)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.26.5](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.4...@standardnotes/analytics@2.26.5) (2023-09-07)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.26.4](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.3...@standardnotes/analytics@2.26.4) (2023-09-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.26.3](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.2...@standardnotes/analytics@2.26.3) (2023-09-04)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.26.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.1...@standardnotes/analytics@2.26.2) (2023-09-01)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/analytics",
|
||||
"version": "2.26.2",
|
||||
"version": "2.26.13",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
@@ -29,7 +29,7 @@
|
||||
"@types/jest": "^29.5.1",
|
||||
"@types/mixpanel": "^2.14.4",
|
||||
"@types/node": "^20.5.7",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.2",
|
||||
"@typescript-eslint/eslint-plugin": "^6.5.0",
|
||||
"@typescript-eslint/parser": "^6.5.0",
|
||||
"eslint": "^8.39.0",
|
||||
"eslint-plugin-prettier": "^5.0.0",
|
||||
|
||||
@@ -3,6 +3,64 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.74.11](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.74.10...@standardnotes/api-gateway@1.74.11) (2023-09-15)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
## [1.74.10](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.74.9...@standardnotes/api-gateway@1.74.10) (2023-09-13)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* adjust transition timestamps to be universal ([c7807d0](https://github.com/standardnotes/api-gateway/commit/c7807d0f9e69ce572c4c03ff606375d706f24d9f))
|
||||
|
||||
## [1.74.9](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.74.8...@standardnotes/api-gateway@1.74.9) (2023-09-13)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
## [1.74.8](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.74.7...@standardnotes/api-gateway@1.74.8) (2023-09-12)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
## [1.74.7](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.74.6...@standardnotes/api-gateway@1.74.7) (2023-09-12)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
## [1.74.6](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.74.5...@standardnotes/api-gateway@1.74.6) (2023-09-12)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
## [1.74.5](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.74.4...@standardnotes/api-gateway@1.74.5) (2023-09-12)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
## [1.74.4](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.74.3...@standardnotes/api-gateway@1.74.4) (2023-09-11)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **api-gateway:** awaiting for other services to start ([0ab4701](https://github.com/standardnotes/api-gateway/commit/0ab47013f210dca7aa404966798011947fb5c362))
|
||||
|
||||
## [1.74.3](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.74.2...@standardnotes/api-gateway@1.74.3) (2023-09-08)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
## [1.74.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.74.1...@standardnotes/api-gateway@1.74.2) (2023-09-07)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
## [1.74.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.74.0...@standardnotes/api-gateway@1.74.1) (2023-09-07)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
# [1.74.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.73.7...@standardnotes/api-gateway@1.74.0) (2023-09-06)
|
||||
|
||||
### Features
|
||||
|
||||
* should be able to access shared item revisions as third party user ([#807](https://github.com/standardnotes/api-gateway/issues/807)) ([794cd87](https://github.com/standardnotes/api-gateway/commit/794cd8734acf89fb29f09dfb169a3f08f252bb6a))
|
||||
|
||||
## [1.73.7](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.73.6...@standardnotes/api-gateway@1.73.7) (2023-09-04)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
## [1.73.6](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.73.5...@standardnotes/api-gateway@1.73.6) (2023-09-01)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/api-gateway",
|
||||
"version": "1.73.6",
|
||||
"version": "1.74.11",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
@@ -54,12 +54,11 @@
|
||||
"@types/jsonwebtoken": "^9.0.1",
|
||||
"@types/node": "^20.5.7",
|
||||
"@types/prettyjson": "^0.0.30",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.2",
|
||||
"@typescript-eslint/eslint-plugin": "^6.5.0",
|
||||
"@typescript-eslint/parser": "^6.5.0",
|
||||
"eslint": "^8.39.0",
|
||||
"eslint-plugin-prettier": "^5.0.0",
|
||||
"jest": "^29.5.0",
|
||||
"nodemon": "^2.0.19",
|
||||
"npm-check-updates": "^16.13.2",
|
||||
"prettier": "^3.0.3",
|
||||
"ts-jest": "^29.1.0",
|
||||
|
||||
@@ -72,6 +72,7 @@ export abstract class AuthMiddleware extends BaseMiddleware {
|
||||
response.locals.session = decodedToken.session
|
||||
response.locals.roles = decodedToken.roles
|
||||
response.locals.sharedVaultOwnerContext = decodedToken.shared_vault_owner_context
|
||||
response.locals.belongsToSharedVaults = decodedToken.belongs_to_shared_vaults ?? []
|
||||
} catch (error) {
|
||||
const errorMessage = (error as AxiosError).isAxiosError
|
||||
? JSON.stringify((error as AxiosError).response?.data)
|
||||
|
||||
@@ -80,15 +80,6 @@ export class UsersController extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/transition-status', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
|
||||
async getTransitionStatus(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'users/transition-status'),
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/:userId/params', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
|
||||
async getKeyParams(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
|
||||
@@ -43,7 +43,6 @@ export class EndpointResolver implements EndpointResolverInterface {
|
||||
['[PATCH]:users/:userId', 'auth.users.update'],
|
||||
['[PUT]:users/:userUuid/attributes/credentials', 'auth.users.updateCredentials'],
|
||||
['[GET]:users/params', 'auth.users.getKeyParams'],
|
||||
['[GET]:users/transition-status', 'auth.users.transition-status'],
|
||||
['[DELETE]:users/:userUuid', 'auth.users.delete'],
|
||||
['[POST]:listed', 'auth.users.createListedAccount'],
|
||||
['[POST]:auth', 'auth.users.register'],
|
||||
@@ -59,13 +58,11 @@ export class EndpointResolver implements EndpointResolverInterface {
|
||||
// Syncing Server
|
||||
['[POST]:items/sync', 'sync.items.sync'],
|
||||
['[POST]:items/check-integrity', 'sync.items.check_integrity'],
|
||||
['[POST]:items/transition', 'sync.items.transition'],
|
||||
['[GET]:items/:uuid', 'sync.items.get_item'],
|
||||
// Revisions Controller V2
|
||||
['[GET]:items/:itemUuid/revisions', 'revisions.revisions.getRevisions'],
|
||||
['[GET]:items/:itemUuid/revisions/:id', 'revisions.revisions.getRevision'],
|
||||
['[DELETE]:items/:itemUuid/revisions/:id', 'revisions.revisions.deleteRevision'],
|
||||
['[POST]:revisions/transition', 'revisions.revisions.transition'],
|
||||
// Messages Controller
|
||||
['[GET]:messages/', 'sync.messages.get-received'],
|
||||
['[GET]:messages/outbound', 'sync.messages.get-sent'],
|
||||
|
||||
@@ -2,5 +2,8 @@
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
sh supervisor/wait-for.sh localhost $AUTH_SERVER_PORT
|
||||
sh supervisor/wait-for.sh localhost $FILES_SERVER_PORT
|
||||
sh supervisor/wait-for.sh localhost $REVISIONS_SERVER_PORT
|
||||
sh supervisor/wait-for.sh localhost $SYNCING_SERVER_PORT
|
||||
node docker/entrypoint-server.js
|
||||
|
||||
@@ -3,6 +3,138 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.142.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.141.14...@standardnotes/auth-server@1.142.0) (2023-09-15)
|
||||
|
||||
### Features
|
||||
|
||||
* add skipping verified transitions ([#827](https://github.com/standardnotes/server/issues/827)) ([d4d4945](https://github.com/standardnotes/server/commit/d4d49454a68de0acdf440dc202fa14b9743905f6))
|
||||
|
||||
## [1.141.14](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.141.13...@standardnotes/auth-server@1.141.14) (2023-09-15)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** remove extensive logs from updating transitions ([2a1859e](https://github.com/standardnotes/server/commit/2a1859e4beff4cc7c4348ebbff8357a8e061bf5e))
|
||||
* **auth:** upgrade simplewebauthn dependency ([#826](https://github.com/standardnotes/server/issues/826)) ([dd9a9c6](https://github.com/standardnotes/server/commit/dd9a9c68cb431a61700a8e5d8247eb1b505a9d62))
|
||||
|
||||
## [1.141.13](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.141.12...@standardnotes/auth-server@1.141.13) (2023-09-14)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** set ttl for started and not picked up transitions to 10h ([fe8ca82](https://github.com/standardnotes/server/commit/fe8ca828fb37306e0e5056627e67366885e86861))
|
||||
|
||||
## [1.141.12](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.141.11...@standardnotes/auth-server@1.141.12) (2023-09-13)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** remove re-triggering revisions transition ([5984e4c](https://github.com/standardnotes/server/commit/5984e4c3e7e550e5ed53805bde1e6dabcbe54da8))
|
||||
|
||||
## [1.141.11](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.141.10...@standardnotes/auth-server@1.141.11) (2023-09-13)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** passing transition timestamp ([c164bde](https://github.com/standardnotes/server/commit/c164bde847b5974e74fd439f0d439526ad439443))
|
||||
|
||||
## [1.141.10](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.141.9...@standardnotes/auth-server@1.141.10) (2023-09-13)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* adjust transition timestamps to be universal ([c7807d0](https://github.com/standardnotes/server/commit/c7807d0f9e69ce572c4c03ff606375d706f24d9f))
|
||||
|
||||
## [1.141.9](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.141.8...@standardnotes/auth-server@1.141.9) (2023-09-13)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* display transition progress in logs ([38685c1](https://github.com/standardnotes/server/commit/38685c1861b13e398dd96aa39f2cf1aece2090fb))
|
||||
|
||||
## [1.141.8](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.141.7...@standardnotes/auth-server@1.141.8) (2023-09-12)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** add transition role only if the items transition has completed ([f055e52](https://github.com/standardnotes/server/commit/f055e52e06b6e93501abd340dfce214d5363bc30))
|
||||
* **auth:** remove the transition role constraint ([afe385a](https://github.com/standardnotes/server/commit/afe385aed4ba5ca53d8ef429ae4154f4ccf81419))
|
||||
* imports ([54113ab](https://github.com/standardnotes/server/commit/54113abe2a961720a3561e5ff3a0069046ea8d25))
|
||||
|
||||
## [1.141.7](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.141.6...@standardnotes/auth-server@1.141.7) (2023-09-12)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* retry failed revision transitions ([e535cd5](https://github.com/standardnotes/server/commit/e535cd504cf1929539ff7faf13e9c1fdd2b7bfd1))
|
||||
|
||||
## [1.141.6](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.141.5...@standardnotes/auth-server@1.141.6) (2023-09-12)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/auth-server
|
||||
|
||||
## [1.141.5](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.141.4...@standardnotes/auth-server@1.141.5) (2023-09-12)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* domain event values ([f0abfe8](https://github.com/standardnotes/server/commit/f0abfe89fca0049c47131389683efe2f5aff23f8))
|
||||
|
||||
## [1.141.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.141.3...@standardnotes/auth-server@1.141.4) (2023-09-12)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* adjust transitions to not create revisions during ongoing revisions transition ([106d8f9](https://github.com/standardnotes/server/commit/106d8f9192f630794ca4ddc2c4503f2c6cd196e7))
|
||||
|
||||
## [1.141.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.141.2...@standardnotes/auth-server@1.141.3) (2023-09-12)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* transition adjustments ([f20a947](https://github.com/standardnotes/server/commit/f20a947f8a555c074d8dc1543c7a8bf61d1d887e))
|
||||
|
||||
## [1.141.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.141.1...@standardnotes/auth-server@1.141.2) (2023-09-11)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** remove transitioning upon sign out ([#819](https://github.com/standardnotes/server/issues/819)) ([330bff0](https://github.com/standardnotes/server/commit/330bff0124f5f49c3441304d166ea43c21fea7bc))
|
||||
|
||||
## [1.141.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.141.0...@standardnotes/auth-server@1.141.1) (2023-09-11)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* disable running migrations in worker mode of a given service ([a82b9a0](https://github.com/standardnotes/server/commit/a82b9a0c8a023ba8a450ff9e34bcd62f928fcab3))
|
||||
|
||||
# [1.141.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.140.0...@standardnotes/auth-server@1.141.0) (2023-09-11)
|
||||
|
||||
### Features
|
||||
|
||||
* **auth:** add procedure to transition users created between dates ([#816](https://github.com/standardnotes/server/issues/816)) ([e95ba61](https://github.com/standardnotes/server/commit/e95ba61c7f769736698ebbc38179d6dc05a8cc5e))
|
||||
|
||||
# [1.140.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.139.0...@standardnotes/auth-server@1.140.0) (2023-09-08)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** specs ([a164ba2](https://github.com/standardnotes/server/commit/a164ba291d4893b5a0bb4b39a8795d654212a1a6))
|
||||
* **auth:** transition users only when transition mode enabled ([610fba2](https://github.com/standardnotes/server/commit/610fba260150d0757020e01ac0c8967feeadd4d6))
|
||||
|
||||
### Features
|
||||
|
||||
* transition users after sign out ([398338c](https://github.com/standardnotes/server/commit/398338c8f81b12406c7ab3bf1654e60b94d7cfd0))
|
||||
|
||||
# [1.139.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.138.2...@standardnotes/auth-server@1.139.0) (2023-09-08)
|
||||
|
||||
### Features
|
||||
|
||||
* **auth:** add vaults user role into database ([aef9e93](https://github.com/standardnotes/server/commit/aef9e936bdbd1f4ccc32658d3d892e7675ec0e0e))
|
||||
|
||||
## [1.138.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.138.1...@standardnotes/auth-server@1.138.2) (2023-09-07)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/auth-server
|
||||
|
||||
## [1.138.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.138.0...@standardnotes/auth-server@1.138.1) (2023-09-07)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/auth-server
|
||||
|
||||
# [1.138.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.137.6...@standardnotes/auth-server@1.138.0) (2023-09-06)
|
||||
|
||||
### Features
|
||||
|
||||
* should be able to access shared item revisions as third party user ([#807](https://github.com/standardnotes/server/issues/807)) ([794cd87](https://github.com/standardnotes/server/commit/794cd8734acf89fb29f09dfb169a3f08f252bb6a))
|
||||
|
||||
## [1.137.6](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.137.5...@standardnotes/auth-server@1.137.6) (2023-09-04)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/auth-server
|
||||
|
||||
## [1.137.5](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.137.4...@standardnotes/auth-server@1.137.5) (2023-09-01)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/auth-server
|
||||
|
||||
@@ -75,7 +75,7 @@ const requestBackups = async (
|
||||
})
|
||||
}
|
||||
|
||||
const container = new ContainerConfigLoader()
|
||||
const container = new ContainerConfigLoader('worker')
|
||||
void container.load().then((container) => {
|
||||
dayjs.extend(utc)
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ const cleanup = async (
|
||||
await cleanupExpiredSessions.execute({ date })
|
||||
}
|
||||
|
||||
const container = new ContainerConfigLoader()
|
||||
const container = new ContainerConfigLoader('worker')
|
||||
void container.load().then((container) => {
|
||||
const env: Env = new Env()
|
||||
env.load()
|
||||
|
||||
@@ -8,7 +8,7 @@ import TYPES from '../src/Bootstrap/Types'
|
||||
import { Env } from '../src/Bootstrap/Env'
|
||||
import { PersistStatistics } from '../src/Domain/UseCase/PersistStatistics/PersistStatistics'
|
||||
|
||||
const container = new ContainerConfigLoader()
|
||||
const container = new ContainerConfigLoader('worker')
|
||||
void container.load().then((container) => {
|
||||
const env: Env = new Env()
|
||||
env.load()
|
||||
|
||||
112
packages/auth/bin/transition.ts
Normal file
112
packages/auth/bin/transition.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { Logger } from 'winston'
|
||||
import * as dayjs from 'dayjs'
|
||||
import * as utc from 'dayjs/plugin/utc'
|
||||
|
||||
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
|
||||
import TYPES from '../src/Bootstrap/Types'
|
||||
import { Env } from '../src/Bootstrap/Env'
|
||||
import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
|
||||
import { DomainEventFactoryInterface } from '../src/Domain/Event/DomainEventFactoryInterface'
|
||||
import { UserRepositoryInterface } from '../src/Domain/User/UserRepositoryInterface'
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
import { TransitionStatusRepositoryInterface } from '../src/Domain/Transition/TransitionStatusRepositoryInterface'
|
||||
import { RoleName } from '@standardnotes/domain-core'
|
||||
|
||||
const inputArgs = process.argv.slice(2)
|
||||
const startDateString = inputArgs[0]
|
||||
const endDateString = inputArgs[1]
|
||||
|
||||
const requestTransition = async (
|
||||
transitionStatusRepository: TransitionStatusRepositoryInterface,
|
||||
userRepository: UserRepositoryInterface,
|
||||
logger: Logger,
|
||||
domainEventFactory: DomainEventFactoryInterface,
|
||||
domainEventPublisher: DomainEventPublisherInterface,
|
||||
timer: TimerInterface,
|
||||
): Promise<void> => {
|
||||
const startDate = new Date(startDateString)
|
||||
const endDate = new Date(endDateString)
|
||||
|
||||
const users = await userRepository.findAllCreatedBetween(startDate, endDate)
|
||||
|
||||
const timestamp = timer.getTimestampInMicroseconds()
|
||||
|
||||
logger.info(
|
||||
`[TRANSITION ${timestamp}] Found ${users.length} users created between ${startDateString} and ${endDateString}`,
|
||||
)
|
||||
|
||||
let usersTriggered = 0
|
||||
for (const user of users) {
|
||||
const itemsTransitionStatus = await transitionStatusRepository.getStatus(user.uuid, 'items')
|
||||
const revisionsTransitionStatus = await transitionStatusRepository.getStatus(user.uuid, 'revisions')
|
||||
|
||||
const userRoles = await user.roles
|
||||
|
||||
const userHasTransitionRole = userRoles.some((role) => role.name === RoleName.NAMES.TransitionUser)
|
||||
const bothTransitionStatusesAreVerified =
|
||||
itemsTransitionStatus === 'VERIFIED' && revisionsTransitionStatus === 'VERIFIED'
|
||||
|
||||
if (userHasTransitionRole && bothTransitionStatusesAreVerified) {
|
||||
continue
|
||||
}
|
||||
|
||||
const transitionRequestedEvent = domainEventFactory.createTransitionRequestedEvent({
|
||||
userUuid: user.uuid,
|
||||
type: 'items',
|
||||
timestamp,
|
||||
})
|
||||
|
||||
usersTriggered += 1
|
||||
|
||||
await domainEventPublisher.publish(transitionRequestedEvent)
|
||||
}
|
||||
|
||||
logger.info(
|
||||
`[TRANSITION ${timestamp}] Triggered transition for ${usersTriggered} users created between ${startDateString} and ${endDateString}`,
|
||||
)
|
||||
}
|
||||
|
||||
const container = new ContainerConfigLoader('worker')
|
||||
void container.load().then((container) => {
|
||||
dayjs.extend(utc)
|
||||
|
||||
const env: Env = new Env()
|
||||
env.load()
|
||||
|
||||
const logger: Logger = container.get(TYPES.Auth_Logger)
|
||||
|
||||
logger.info(`Starting transition request for users created between ${startDateString} and ${endDateString}`)
|
||||
|
||||
const userRepository: UserRepositoryInterface = container.get(TYPES.Auth_UserRepository)
|
||||
const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.Auth_DomainEventFactory)
|
||||
const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.Auth_DomainEventPublisher)
|
||||
const timer = container.get<TimerInterface>(TYPES.Auth_Timer)
|
||||
const transitionStatusRepository = container.get<TransitionStatusRepositoryInterface>(
|
||||
TYPES.Auth_TransitionStatusRepository,
|
||||
)
|
||||
|
||||
Promise.resolve(
|
||||
requestTransition(
|
||||
transitionStatusRepository,
|
||||
userRepository,
|
||||
logger,
|
||||
domainEventFactory,
|
||||
domainEventPublisher,
|
||||
timer,
|
||||
),
|
||||
)
|
||||
.then(() => {
|
||||
logger.info(`Finished transition request for users created between ${startDateString} and ${endDateString}`)
|
||||
|
||||
process.exit(0)
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error(
|
||||
`Error while requesting transition for users created between ${startDateString} and ${endDateString}: ${error}`,
|
||||
)
|
||||
|
||||
process.exit(1)
|
||||
})
|
||||
})
|
||||
@@ -63,7 +63,7 @@ const requestBackups = async (
|
||||
return
|
||||
}
|
||||
|
||||
const container = new ContainerConfigLoader()
|
||||
const container = new ContainerConfigLoader('worker')
|
||||
void container.load().then((container) => {
|
||||
dayjs.extend(utc)
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import { DomainEventSubscriberFactoryInterface } from '@standardnotes/domain-eve
|
||||
import * as dayjs from 'dayjs'
|
||||
import * as utc from 'dayjs/plugin/utc'
|
||||
|
||||
const container = new ContainerConfigLoader()
|
||||
const container = new ContainerConfigLoader('worker')
|
||||
void container.load().then((container) => {
|
||||
dayjs.extend(utc)
|
||||
|
||||
|
||||
11
packages/auth/docker/entrypoint-transition.js
Normal file
11
packages/auth/docker/entrypoint-transition.js
Normal file
@@ -0,0 +1,11 @@
|
||||
'use strict'
|
||||
|
||||
const path = require('path')
|
||||
|
||||
const pnp = require(path.normalize(path.resolve(__dirname, '../../..', '.pnp.cjs'))).setup()
|
||||
|
||||
const index = require(path.normalize(path.resolve(__dirname, '../dist/bin/transition.js')))
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true })
|
||||
|
||||
exports.default = index
|
||||
@@ -55,6 +55,13 @@ case "$COMMAND" in
|
||||
node docker/entrypoint-backup.js one_drive daily
|
||||
;;
|
||||
|
||||
'transition' )
|
||||
START_DATE=$1 && shift 1
|
||||
END_DATE=$1 && shift 1
|
||||
echo "[Docker] Starting Transition..."
|
||||
node docker/entrypoint-transition.js $START_DATE $END_DATE
|
||||
;;
|
||||
|
||||
* )
|
||||
echo "[Docker] Unknown command"
|
||||
;;
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||
|
||||
export class AddSharedVaultUsers1694000575425 implements MigrationInterface {
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
'CREATE TABLE `auth_shared_vault_users` (`uuid` varchar(36) NOT NULL, `shared_vault_uuid` varchar(36) NOT NULL, `user_uuid` varchar(36) NOT NULL, `permission` varchar(24) NOT NULL, `created_at_timestamp` bigint NOT NULL, `updated_at_timestamp` bigint NOT NULL, INDEX `shared_vault_uuid_on_auth_shared_vault_users` (`shared_vault_uuid`), INDEX `user_uuid_on_auth_shared_vault_users` (`user_uuid`), PRIMARY KEY (`uuid`)) ENGINE=InnoDB',
|
||||
)
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('DROP INDEX `user_uuid_on_auth_shared_vault_users` ON `auth_shared_vault_users`')
|
||||
await queryRunner.query('DROP INDEX `shared_vault_uuid_on_auth_shared_vault_users` ON `auth_shared_vault_users`')
|
||||
await queryRunner.query('DROP TABLE `auth_shared_vault_users`')
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||
|
||||
export class AddVaultsUser1694157482134 implements MigrationInterface {
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
'INSERT INTO `roles` (uuid, name, version) VALUES ("35669f45-a2d8-4172-bdab-b7b3d42044ce", "VAULTS_USER", 1)',
|
||||
)
|
||||
}
|
||||
|
||||
public async down(): Promise<void> {
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||
|
||||
export class AddSharedVaultUsers1694000640645 implements MigrationInterface {
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
'CREATE TABLE "auth_shared_vault_users" ("uuid" varchar PRIMARY KEY NOT NULL, "shared_vault_uuid" varchar(36) NOT NULL, "user_uuid" varchar(36) NOT NULL, "permission" varchar(24) NOT NULL, "created_at_timestamp" bigint NOT NULL, "updated_at_timestamp" bigint NOT NULL)',
|
||||
)
|
||||
await queryRunner.query(
|
||||
'CREATE INDEX "shared_vault_uuid_on_auth_shared_vault_users" ON "auth_shared_vault_users" ("shared_vault_uuid") ',
|
||||
)
|
||||
await queryRunner.query(
|
||||
'CREATE INDEX "user_uuid_on_auth_shared_vault_users" ON "auth_shared_vault_users" ("user_uuid") ',
|
||||
)
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('DROP INDEX "user_uuid_on_auth_shared_vault_users"')
|
||||
await queryRunner.query('DROP INDEX "shared_vault_uuid_on_auth_shared_vault_users"')
|
||||
await queryRunner.query('DROP TABLE "auth_shared_vault_users"')
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/auth-server",
|
||||
"version": "1.137.5",
|
||||
"version": "1.142.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
@@ -40,8 +40,8 @@
|
||||
"@aws-sdk/client-sqs": "^3.332.0",
|
||||
"@cbor-extract/cbor-extract-linux-arm64": "^2.1.1",
|
||||
"@cbor-extract/cbor-extract-linux-x64": "^2.1.1",
|
||||
"@simplewebauthn/server": "^7.2.0",
|
||||
"@simplewebauthn/typescript-types": "^7.0.0",
|
||||
"@simplewebauthn/server": "^8.1.1",
|
||||
"@simplewebauthn/typescript-types": "^8.0.0",
|
||||
"@standardnotes/api": "^1.26.26",
|
||||
"@standardnotes/common": "workspace:*",
|
||||
"@standardnotes/domain-core": "workspace:^",
|
||||
@@ -84,13 +84,12 @@
|
||||
"@types/otplib": "^10.0.0",
|
||||
"@types/prettyjson": "^0.0.30",
|
||||
"@types/ua-parser-js": "^0.7.36",
|
||||
"@types/uuid": "^9.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.2",
|
||||
"@types/uuid": "^9.0.3",
|
||||
"@typescript-eslint/eslint-plugin": "^6.5.0",
|
||||
"@typescript-eslint/parser": "^6.5.0",
|
||||
"eslint": "^8.39.0",
|
||||
"eslint-plugin-prettier": "^5.0.0",
|
||||
"jest": "^29.5.0",
|
||||
"nodemon": "^2.0.19",
|
||||
"npm-check-updates": "^16.13.2",
|
||||
"prettier": "^3.0.3",
|
||||
"ts-jest": "^29.1.0",
|
||||
|
||||
@@ -189,6 +189,7 @@ import {
|
||||
ControllerContainer,
|
||||
ControllerContainerInterface,
|
||||
MapperInterface,
|
||||
SharedVaultUser,
|
||||
} from '@standardnotes/domain-core'
|
||||
import { SessionTracePersistenceMapper } from '../Mapping/SessionTracePersistenceMapper'
|
||||
import { SessionTrace } from '../Domain/Session/SessionTrace'
|
||||
@@ -262,9 +263,18 @@ import { RedisTransitionStatusRepository } from '../Infra/Redis/RedisTransitionS
|
||||
import { InMemoryTransitionStatusRepository } from '../Infra/InMemory/InMemoryTransitionStatusRepository'
|
||||
import { TransitionStatusUpdatedEventHandler } from '../Domain/Handler/TransitionStatusUpdatedEventHandler'
|
||||
import { UpdateTransitionStatus } from '../Domain/UseCase/UpdateTransitionStatus/UpdateTransitionStatus'
|
||||
import { GetTransitionStatus } from '../Domain/UseCase/GetTransitionStatus/GetTransitionStatus'
|
||||
import { TypeORMSharedVaultUser } from '../Infra/TypeORM/TypeORMSharedVaultUser'
|
||||
import { SharedVaultUserPersistenceMapper } from '../Mapping/SharedVaultUserPersistenceMapper'
|
||||
import { SharedVaultUserRepositoryInterface } from '../Domain/SharedVault/SharedVaultUserRepositoryInterface'
|
||||
import { TypeORMSharedVaultUserRepository } from '../Infra/TypeORM/TypeORMSharedVaultUserRepository'
|
||||
import { AddSharedVaultUser } from '../Domain/UseCase/AddSharedVaultUser/AddSharedVaultUser'
|
||||
import { RemoveSharedVaultUser } from '../Domain/UseCase/RemoveSharedVaultUser/RemoveSharedVaultUser'
|
||||
import { UserAddedToSharedVaultEventHandler } from '../Domain/Handler/UserAddedToSharedVaultEventHandler'
|
||||
import { UserRemovedFromSharedVaultEventHandler } from '../Domain/Handler/UserRemovedFromSharedVaultEventHandler'
|
||||
|
||||
export class ContainerConfigLoader {
|
||||
constructor(private mode: 'server' | 'worker' = 'server') {}
|
||||
|
||||
async load(configuration?: {
|
||||
controllerConatiner?: ControllerContainerInterface
|
||||
directCallDomainEventPublisher?: DirectCallDomainEventPublisher
|
||||
@@ -301,7 +311,7 @@ export class ContainerConfigLoader {
|
||||
}
|
||||
container.bind<winston.Logger>(TYPES.Auth_Logger).toConstantValue(logger)
|
||||
|
||||
const appDataSource = new AppDataSource(env)
|
||||
const appDataSource = new AppDataSource({ env, runMigrations: this.mode === 'server' })
|
||||
await appDataSource.initialize()
|
||||
|
||||
logger.debug('Database initialized')
|
||||
@@ -372,6 +382,9 @@ export class ContainerConfigLoader {
|
||||
container
|
||||
.bind<MapperInterface<CacheEntry, TypeORMCacheEntry>>(TYPES.Auth_CacheEntryPersistenceMapper)
|
||||
.toConstantValue(new CacheEntryPersistenceMapper())
|
||||
container
|
||||
.bind<MapperInterface<SharedVaultUser, TypeORMSharedVaultUser>>(TYPES.Auth_SharedVaultUserPersistenceMapper)
|
||||
.toConstantValue(new SharedVaultUserPersistenceMapper())
|
||||
|
||||
// ORM
|
||||
container
|
||||
@@ -412,6 +425,9 @@ export class ContainerConfigLoader {
|
||||
container
|
||||
.bind<Repository<TypeORMCacheEntry>>(TYPES.Auth_ORMCacheEntryRepository)
|
||||
.toConstantValue(appDataSource.getRepository(TypeORMCacheEntry))
|
||||
container
|
||||
.bind<Repository<TypeORMSharedVaultUser>>(TYPES.Auth_ORMSharedVaultUserRepository)
|
||||
.toConstantValue(appDataSource.getRepository(TypeORMSharedVaultUser))
|
||||
|
||||
// Repositories
|
||||
container.bind<SessionRepositoryInterface>(TYPES.Auth_SessionRepository).to(TypeORMSessionRepository)
|
||||
@@ -468,6 +484,16 @@ export class ContainerConfigLoader {
|
||||
container.get(TYPES.Auth_CacheEntryPersistenceMapper),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<SharedVaultUserRepositoryInterface>(TYPES.Auth_SharedVaultUserRepository)
|
||||
.toConstantValue(
|
||||
new TypeORMSharedVaultUserRepository(
|
||||
container.get<Repository<TypeORMSharedVaultUser>>(TYPES.Auth_ORMSharedVaultUserRepository),
|
||||
container.get<MapperInterface<SharedVaultUser, TypeORMSharedVaultUser>>(
|
||||
TYPES.Auth_SharedVaultUserPersistenceMapper,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
// Middleware
|
||||
container.bind<SessionMiddleware>(TYPES.Auth_SessionMiddleware).to(SessionMiddleware)
|
||||
@@ -919,11 +945,15 @@ export class ContainerConfigLoader {
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<GetTransitionStatus>(TYPES.Auth_GetTransitionStatus)
|
||||
.bind<AddSharedVaultUser>(TYPES.Auth_AddSharedVaultUser)
|
||||
.toConstantValue(
|
||||
new GetTransitionStatus(
|
||||
container.get<TransitionStatusRepositoryInterface>(TYPES.Auth_TransitionStatusRepository),
|
||||
container.get<UserRepositoryInterface>(TYPES.Auth_UserRepository),
|
||||
new AddSharedVaultUser(container.get<SharedVaultUserRepositoryInterface>(TYPES.Auth_SharedVaultUserRepository)),
|
||||
)
|
||||
container
|
||||
.bind<RemoveSharedVaultUser>(TYPES.Auth_RemoveSharedVaultUser)
|
||||
.toConstantValue(
|
||||
new RemoveSharedVaultUser(
|
||||
container.get<SharedVaultUserRepositoryInterface>(TYPES.Auth_SharedVaultUserRepository),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -1075,6 +1105,22 @@ export class ContainerConfigLoader {
|
||||
container.get<winston.Logger>(TYPES.Auth_Logger),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<UserAddedToSharedVaultEventHandler>(TYPES.Auth_UserAddedToSharedVaultEventHandler)
|
||||
.toConstantValue(
|
||||
new UserAddedToSharedVaultEventHandler(
|
||||
container.get<AddSharedVaultUser>(TYPES.Auth_AddSharedVaultUser),
|
||||
container.get<winston.Logger>(TYPES.Auth_Logger),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<UserRemovedFromSharedVaultEventHandler>(TYPES.Auth_UserRemovedFromSharedVaultEventHandler)
|
||||
.toConstantValue(
|
||||
new UserRemovedFromSharedVaultEventHandler(
|
||||
container.get<RemoveSharedVaultUser>(TYPES.Auth_RemoveSharedVaultUser),
|
||||
container.get<winston.Logger>(TYPES.Auth_Logger),
|
||||
),
|
||||
)
|
||||
|
||||
const eventHandlers: Map<string, DomainEventHandlerInterface> = new Map([
|
||||
['USER_REGISTERED', container.get(TYPES.Auth_UserRegisteredEventHandler)],
|
||||
@@ -1107,6 +1153,8 @@ export class ContainerConfigLoader {
|
||||
['EMAIL_SUBSCRIPTION_UNSUBSCRIBED', container.get(TYPES.Auth_EmailSubscriptionUnsubscribedEventHandler)],
|
||||
['PAYMENTS_ACCOUNT_DELETED', container.get(TYPES.Auth_PaymentsAccountDeletedEventHandler)],
|
||||
['TRANSITION_STATUS_UPDATED', container.get(TYPES.Auth_TransitionStatusUpdatedEventHandler)],
|
||||
['USER_ADDED_TO_SHARED_VAULT', container.get(TYPES.Auth_UserAddedToSharedVaultEventHandler)],
|
||||
['USER_REMOVED_FROM_SHARED_VAULT', container.get(TYPES.Auth_UserRemovedFromSharedVaultEventHandler)],
|
||||
])
|
||||
|
||||
if (isConfiguredForHomeServer) {
|
||||
@@ -1218,7 +1266,6 @@ export class ContainerConfigLoader {
|
||||
container.get<ClearLoginAttempts>(TYPES.Auth_ClearLoginAttempts),
|
||||
container.get<IncreaseLoginAttempts>(TYPES.Auth_IncreaseLoginAttempts),
|
||||
container.get<ChangeCredentials>(TYPES.Auth_ChangeCredentials),
|
||||
container.get<GetTransitionStatus>(TYPES.Auth_GetTransitionStatus),
|
||||
container.get<ControllerContainerInterface>(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -18,11 +18,17 @@ import { TypeORMEmergencyAccessInvitation } from '../Infra/TypeORM/TypeORMEmerge
|
||||
import { TypeORMSessionTrace } from '../Infra/TypeORM/TypeORMSessionTrace'
|
||||
import { Env } from './Env'
|
||||
import { SqliteConnectionOptions } from 'typeorm/driver/sqlite/SqliteConnectionOptions'
|
||||
import { TypeORMSharedVaultUser } from '../Infra/TypeORM/TypeORMSharedVaultUser'
|
||||
|
||||
export class AppDataSource {
|
||||
private _dataSource: DataSource | undefined
|
||||
|
||||
constructor(private env: Env) {}
|
||||
constructor(
|
||||
private configuration: {
|
||||
env: Env
|
||||
runMigrations: boolean
|
||||
},
|
||||
) {}
|
||||
|
||||
getRepository<Entity extends ObjectLiteral>(target: EntityTarget<Entity>): Repository<Entity> {
|
||||
if (!this._dataSource) {
|
||||
@@ -37,12 +43,12 @@ export class AppDataSource {
|
||||
}
|
||||
|
||||
get dataSource(): DataSource {
|
||||
this.env.load()
|
||||
this.configuration.env.load()
|
||||
|
||||
const isConfiguredForMySQL = this.env.get('DB_TYPE') === 'mysql'
|
||||
const isConfiguredForMySQL = this.configuration.env.get('DB_TYPE') === 'mysql'
|
||||
|
||||
const maxQueryExecutionTime = this.env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
|
||||
? +this.env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
|
||||
const maxQueryExecutionTime = this.configuration.env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
|
||||
? +this.configuration.env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
|
||||
: 45_000
|
||||
|
||||
const commonDataSourceOptions = {
|
||||
@@ -64,30 +70,31 @@ export class AppDataSource {
|
||||
TypeORMAuthenticatorChallenge,
|
||||
TypeORMEmergencyAccessInvitation,
|
||||
TypeORMCacheEntry,
|
||||
TypeORMSharedVaultUser,
|
||||
],
|
||||
migrations: [`${__dirname}/../../migrations/${isConfiguredForMySQL ? 'mysql' : 'sqlite'}/*.js`],
|
||||
migrationsRun: true,
|
||||
logging: <LoggerOptions>this.env.get('DB_DEBUG_LEVEL', true) ?? 'info',
|
||||
migrationsRun: this.configuration.runMigrations,
|
||||
logging: <LoggerOptions>this.configuration.env.get('DB_DEBUG_LEVEL', true) ?? 'info',
|
||||
}
|
||||
|
||||
if (isConfiguredForMySQL) {
|
||||
const inReplicaMode = this.env.get('DB_REPLICA_HOST', true) ? true : false
|
||||
const inReplicaMode = this.configuration.env.get('DB_REPLICA_HOST', true) ? true : false
|
||||
|
||||
const replicationConfig = {
|
||||
master: {
|
||||
host: this.env.get('DB_HOST'),
|
||||
port: parseInt(this.env.get('DB_PORT')),
|
||||
username: this.env.get('DB_USERNAME'),
|
||||
password: this.env.get('DB_PASSWORD'),
|
||||
database: this.env.get('DB_DATABASE'),
|
||||
host: this.configuration.env.get('DB_HOST'),
|
||||
port: parseInt(this.configuration.env.get('DB_PORT')),
|
||||
username: this.configuration.env.get('DB_USERNAME'),
|
||||
password: this.configuration.env.get('DB_PASSWORD'),
|
||||
database: this.configuration.env.get('DB_DATABASE'),
|
||||
},
|
||||
slaves: [
|
||||
{
|
||||
host: this.env.get('DB_REPLICA_HOST', true),
|
||||
port: parseInt(this.env.get('DB_PORT')),
|
||||
username: this.env.get('DB_USERNAME'),
|
||||
password: this.env.get('DB_PASSWORD'),
|
||||
database: this.env.get('DB_DATABASE'),
|
||||
host: this.configuration.env.get('DB_REPLICA_HOST', true),
|
||||
port: parseInt(this.configuration.env.get('DB_PORT')),
|
||||
username: this.configuration.env.get('DB_USERNAME'),
|
||||
password: this.configuration.env.get('DB_PASSWORD'),
|
||||
database: this.configuration.env.get('DB_DATABASE'),
|
||||
},
|
||||
],
|
||||
removeNodeErrorCount: 10,
|
||||
@@ -101,11 +108,11 @@ export class AppDataSource {
|
||||
supportBigNumbers: true,
|
||||
bigNumberStrings: false,
|
||||
replication: inReplicaMode ? replicationConfig : undefined,
|
||||
host: inReplicaMode ? undefined : this.env.get('DB_HOST'),
|
||||
port: inReplicaMode ? undefined : parseInt(this.env.get('DB_PORT')),
|
||||
username: inReplicaMode ? undefined : this.env.get('DB_USERNAME'),
|
||||
password: inReplicaMode ? undefined : this.env.get('DB_PASSWORD'),
|
||||
database: inReplicaMode ? undefined : this.env.get('DB_DATABASE'),
|
||||
host: inReplicaMode ? undefined : this.configuration.env.get('DB_HOST'),
|
||||
port: inReplicaMode ? undefined : parseInt(this.configuration.env.get('DB_PORT')),
|
||||
username: inReplicaMode ? undefined : this.configuration.env.get('DB_USERNAME'),
|
||||
password: inReplicaMode ? undefined : this.configuration.env.get('DB_PASSWORD'),
|
||||
database: inReplicaMode ? undefined : this.configuration.env.get('DB_DATABASE'),
|
||||
}
|
||||
|
||||
this._dataSource = new DataSource(mySQLDataSourceOptions)
|
||||
@@ -113,7 +120,7 @@ export class AppDataSource {
|
||||
const sqliteDataSourceOptions: SqliteConnectionOptions = {
|
||||
...commonDataSourceOptions,
|
||||
type: 'sqlite',
|
||||
database: this.env.get('DB_SQLITE_DATABASE_PATH'),
|
||||
database: this.configuration.env.get('DB_SQLITE_DATABASE_PATH'),
|
||||
enableWAL: true,
|
||||
busyErrorRetry: 2000,
|
||||
}
|
||||
|
||||
@@ -4,4 +4,4 @@ import { Env } from './Env'
|
||||
const env: Env = new Env()
|
||||
env.load()
|
||||
|
||||
export const MigrationsDataSource = new AppDataSource(env).dataSource
|
||||
export const MigrationsDataSource = new AppDataSource({ env, runMigrations: true }).dataSource
|
||||
|
||||
@@ -9,6 +9,7 @@ const TYPES = {
|
||||
Auth_AuthenticatorPersistenceMapper: Symbol.for('Auth_AuthenticatorPersistenceMapper'),
|
||||
Auth_AuthenticatorHttpMapper: Symbol.for('Auth_AuthenticatorHttpMapper'),
|
||||
Auth_CacheEntryPersistenceMapper: Symbol.for('Auth_CacheEntryPersistenceMapper'),
|
||||
Auth_SharedVaultUserPersistenceMapper: Symbol.for('Auth_SharedVaultUserPersistenceMapper'),
|
||||
// Controller
|
||||
Auth_ControllerContainer: Symbol.for('Auth_ControllerContainer'),
|
||||
Auth_AuthController: Symbol.for('Auth_AuthController'),
|
||||
@@ -36,6 +37,7 @@ const TYPES = {
|
||||
Auth_AuthenticatorChallengeRepository: Symbol.for('Auth_AuthenticatorChallengeRepository'),
|
||||
Auth_CacheEntryRepository: Symbol.for('Auth_CacheEntryRepository'),
|
||||
Auth_TransitionStatusRepository: Symbol.for('Auth_TransitionStatusRepository'),
|
||||
Auth_SharedVaultUserRepository: Symbol.for('Auth_SharedVaultUserRepository'),
|
||||
// ORM
|
||||
Auth_ORMOfflineSettingRepository: Symbol.for('Auth_ORMOfflineSettingRepository'),
|
||||
Auth_ORMOfflineUserSubscriptionRepository: Symbol.for('Auth_ORMOfflineUserSubscriptionRepository'),
|
||||
@@ -51,6 +53,7 @@ const TYPES = {
|
||||
Auth_ORMAuthenticatorRepository: Symbol.for('Auth_ORMAuthenticatorRepository'),
|
||||
Auth_ORMAuthenticatorChallengeRepository: Symbol.for('Auth_ORMAuthenticatorChallengeRepository'),
|
||||
Auth_ORMCacheEntryRepository: Symbol.for('Auth_ORMCacheEntryRepository'),
|
||||
Auth_ORMSharedVaultUserRepository: Symbol.for('Auth_ORMSharedVaultUserRepository'),
|
||||
// Middleware
|
||||
Auth_RequiredCrossServiceTokenMiddleware: Symbol.for('Auth_RequiredCrossServiceTokenMiddleware'),
|
||||
Auth_OptionalCrossServiceTokenMiddleware: Symbol.for('Auth_OptionalCrossServiceTokenMiddleware'),
|
||||
@@ -156,7 +159,8 @@ const TYPES = {
|
||||
Auth_GetUserKeyParamsRecovery: Symbol.for('Auth_GetUserKeyParamsRecovery'),
|
||||
Auth_UpdateStorageQuotaUsedForUser: Symbol.for('Auth_UpdateStorageQuotaUsedForUser'),
|
||||
Auth_UpdateTransitionStatus: Symbol.for('Auth_UpdateTransitionStatus'),
|
||||
Auth_GetTransitionStatus: Symbol.for('Auth_GetTransitionStatus'),
|
||||
Auth_AddSharedVaultUser: Symbol.for('Auth_AddSharedVaultUser'),
|
||||
Auth_RemoveSharedVaultUser: Symbol.for('Auth_RemoveSharedVaultUser'),
|
||||
// Handlers
|
||||
Auth_UserRegisteredEventHandler: Symbol.for('Auth_UserRegisteredEventHandler'),
|
||||
Auth_AccountDeletionRequestedEventHandler: Symbol.for('Auth_AccountDeletionRequestedEventHandler'),
|
||||
@@ -186,6 +190,8 @@ const TYPES = {
|
||||
Auth_EmailSubscriptionUnsubscribedEventHandler: Symbol.for('Auth_EmailSubscriptionUnsubscribedEventHandler'),
|
||||
Auth_PaymentsAccountDeletedEventHandler: Symbol.for('Auth_PaymentsAccountDeletedEventHandler'),
|
||||
Auth_TransitionStatusUpdatedEventHandler: Symbol.for('Auth_TransitionStatusUpdatedEventHandler'),
|
||||
Auth_UserAddedToSharedVaultEventHandler: Symbol.for('Auth_UserAddedToSharedVaultEventHandler'),
|
||||
Auth_UserRemovedFromSharedVaultEventHandler: Symbol.for('Auth_UserRemovedFromSharedVaultEventHandler'),
|
||||
// Services
|
||||
Auth_DeviceDetector: Symbol.for('Auth_DeviceDetector'),
|
||||
Auth_SessionService: Symbol.for('Auth_SessionService'),
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
StatisticPersistenceRequestedEvent,
|
||||
SessionCreatedEvent,
|
||||
SessionRefreshedEvent,
|
||||
TransitionRequestedEvent,
|
||||
} from '@standardnotes/domain-events'
|
||||
import { Predicate, PredicateVerificationResult } from '@standardnotes/predicates'
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
@@ -32,6 +33,25 @@ import { DomainEventFactoryInterface } from './DomainEventFactoryInterface'
|
||||
export class DomainEventFactory implements DomainEventFactoryInterface {
|
||||
constructor(@inject(TYPES.Auth_Timer) private timer: TimerInterface) {}
|
||||
|
||||
createTransitionRequestedEvent(dto: {
|
||||
userUuid: string
|
||||
type: 'items' | 'revisions'
|
||||
timestamp: number
|
||||
}): TransitionRequestedEvent {
|
||||
return {
|
||||
type: 'TRANSITION_REQUESTED',
|
||||
createdAt: this.timer.getUTCDate(),
|
||||
meta: {
|
||||
correlation: {
|
||||
userIdentifier: dto.userUuid,
|
||||
userIdentifierType: 'uuid',
|
||||
},
|
||||
origin: DomainEventService.Auth,
|
||||
},
|
||||
payload: dto,
|
||||
}
|
||||
}
|
||||
|
||||
createSessionCreatedEvent(dto: { userUuid: string }): SessionCreatedEvent {
|
||||
return {
|
||||
type: 'SESSION_CREATED',
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
StatisticPersistenceRequestedEvent,
|
||||
SessionCreatedEvent,
|
||||
SessionRefreshedEvent,
|
||||
TransitionRequestedEvent,
|
||||
} from '@standardnotes/domain-events'
|
||||
import { InviteeIdentifierType } from '../SharedSubscription/InviteeIdentifierType'
|
||||
|
||||
@@ -89,4 +90,9 @@ export interface DomainEventFactoryInterface {
|
||||
}): StatisticPersistenceRequestedEvent
|
||||
createSessionCreatedEvent(dto: { userUuid: string }): SessionCreatedEvent
|
||||
createSessionRefreshedEvent(dto: { userUuid: string }): SessionRefreshedEvent
|
||||
createTransitionRequestedEvent(dto: {
|
||||
userUuid: string
|
||||
type: 'items' | 'revisions'
|
||||
timestamp: number
|
||||
}): TransitionRequestedEvent
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ export class TransitionStatusUpdatedEventHandler implements DomainEventHandlerIn
|
||||
status: event.payload.status,
|
||||
userUuid: event.payload.userUuid,
|
||||
transitionType: event.payload.transitionType,
|
||||
transitionTimestamp: event.payload.transitionTimestamp,
|
||||
})
|
||||
|
||||
if (result.isFailed()) {
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import { DomainEventHandlerInterface, UserAddedToSharedVaultEvent } from '@standardnotes/domain-events'
|
||||
import { Logger } from 'winston'
|
||||
import { AddSharedVaultUser } from '../UseCase/AddSharedVaultUser/AddSharedVaultUser'
|
||||
|
||||
export class UserAddedToSharedVaultEventHandler implements DomainEventHandlerInterface {
|
||||
constructor(
|
||||
private addSharedVaultUser: AddSharedVaultUser,
|
||||
private logger: Logger,
|
||||
) {}
|
||||
|
||||
async handle(event: UserAddedToSharedVaultEvent): Promise<void> {
|
||||
const result = await this.addSharedVaultUser.execute({
|
||||
userUuid: event.payload.userUuid,
|
||||
sharedVaultUuid: event.payload.sharedVaultUuid,
|
||||
permission: event.payload.permission,
|
||||
createdAt: event.payload.createdAt,
|
||||
updatedAt: event.payload.updatedAt,
|
||||
})
|
||||
|
||||
if (result.isFailed()) {
|
||||
this.logger.error(`Failed to add user to shared vault: ${result.getError()}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { DomainEventHandlerInterface, UserRemovedFromSharedVaultEvent } from '@standardnotes/domain-events'
|
||||
import { Logger } from 'winston'
|
||||
|
||||
import { RemoveSharedVaultUser } from '../UseCase/RemoveSharedVaultUser/RemoveSharedVaultUser'
|
||||
|
||||
export class UserRemovedFromSharedVaultEventHandler implements DomainEventHandlerInterface {
|
||||
constructor(
|
||||
private removeSharedVaultUser: RemoveSharedVaultUser,
|
||||
private logger: Logger,
|
||||
) {}
|
||||
|
||||
async handle(event: UserRemovedFromSharedVaultEvent): Promise<void> {
|
||||
const result = await this.removeSharedVaultUser.execute({
|
||||
userUuid: event.payload.userUuid,
|
||||
sharedVaultUuid: event.payload.sharedVaultUuid,
|
||||
})
|
||||
|
||||
if (result.isFailed()) {
|
||||
this.logger.error(`Failed to remove user from shared vault: ${result.getError()}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { SharedVaultUser, Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
export interface SharedVaultUserRepositoryInterface {
|
||||
findByUserUuidAndSharedVaultUuid(dto: { userUuid: Uuid; sharedVaultUuid: Uuid }): Promise<SharedVaultUser | null>
|
||||
findByUserUuid(userUuid: Uuid): Promise<SharedVaultUser[]>
|
||||
save(sharedVaultUser: SharedVaultUser): Promise<void>
|
||||
remove(sharedVault: SharedVaultUser): Promise<void>
|
||||
}
|
||||
@@ -1,5 +1,11 @@
|
||||
export interface TransitionStatusRepositoryInterface {
|
||||
updateStatus(userUuid: string, transitionType: 'items' | 'revisions', status: 'STARTED' | 'FAILED'): Promise<void>
|
||||
removeStatus(userUuid: string, transitionType: 'items' | 'revisions'): Promise<void>
|
||||
getStatus(userUuid: string, transitionType: 'items' | 'revisions'): Promise<'STARTED' | 'FAILED' | null>
|
||||
updateStatus(
|
||||
userUuid: string,
|
||||
transitionType: 'items' | 'revisions',
|
||||
status: 'STARTED' | 'IN_PROGRESS' | 'FINISHED' | 'FAILED' | 'VERIFIED',
|
||||
): Promise<void>
|
||||
getStatus(
|
||||
userUuid: string,
|
||||
transitionType: 'items' | 'revisions',
|
||||
): Promise<'STARTED' | 'IN_PROGRESS' | 'FINISHED' | 'FAILED' | 'VERIFIED' | null>
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
import { Result, SharedVaultUser } from '@standardnotes/domain-core'
|
||||
import { SharedVaultUserRepositoryInterface } from '../../SharedVault/SharedVaultUserRepositoryInterface'
|
||||
import { AddSharedVaultUser } from './AddSharedVaultUser'
|
||||
|
||||
describe('AddSharedVaultUser', () => {
|
||||
let sharedVaultUserRepository: SharedVaultUserRepositoryInterface
|
||||
|
||||
const createUseCase = () => new AddSharedVaultUser(sharedVaultUserRepository)
|
||||
|
||||
beforeEach(() => {
|
||||
sharedVaultUserRepository = {} as jest.Mocked<SharedVaultUserRepositoryInterface>
|
||||
sharedVaultUserRepository.save = jest.fn()
|
||||
})
|
||||
|
||||
it('should save shared vault user', async () => {
|
||||
const useCase = createUseCase()
|
||||
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
|
||||
permission: 'read',
|
||||
createdAt: 1,
|
||||
updatedAt: 2,
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBeFalsy()
|
||||
expect(sharedVaultUserRepository.save).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should fail when user uuid is invalid', async () => {
|
||||
const useCase = createUseCase()
|
||||
|
||||
const result = await useCase.execute({
|
||||
userUuid: 'invalid',
|
||||
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
|
||||
permission: 'read',
|
||||
createdAt: 1,
|
||||
updatedAt: 2,
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBeTruthy()
|
||||
expect(sharedVaultUserRepository.save).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should fail when shared vault uuid is invalid', async () => {
|
||||
const useCase = createUseCase()
|
||||
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
sharedVaultUuid: 'invalid',
|
||||
permission: 'read',
|
||||
createdAt: 1,
|
||||
updatedAt: 2,
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBeTruthy()
|
||||
expect(sharedVaultUserRepository.save).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should fail when permission is invalid', async () => {
|
||||
const useCase = createUseCase()
|
||||
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
|
||||
permission: 'invalid',
|
||||
createdAt: 1,
|
||||
updatedAt: 2,
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBeTruthy()
|
||||
expect(sharedVaultUserRepository.save).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should fail when timestamps are invalid', async () => {
|
||||
const useCase = createUseCase()
|
||||
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
|
||||
permission: 'read',
|
||||
createdAt: 'invalid' as unknown as number,
|
||||
updatedAt: 1,
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBeTruthy()
|
||||
expect(sharedVaultUserRepository.save).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should fail when shared vault user is invalid', async () => {
|
||||
const mock = jest.spyOn(SharedVaultUser, 'create')
|
||||
mock.mockReturnValue(Result.fail('Oops'))
|
||||
|
||||
const result = await createUseCase().execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
sharedVaultUuid: '00000000-0000-0000-0000-000000000000',
|
||||
permission: 'read',
|
||||
createdAt: 2,
|
||||
updatedAt: 1,
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBeTruthy()
|
||||
|
||||
mock.mockRestore()
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,56 @@
|
||||
import {
|
||||
Result,
|
||||
SharedVaultUser,
|
||||
SharedVaultUserPermission,
|
||||
Timestamps,
|
||||
UseCaseInterface,
|
||||
Uuid,
|
||||
} from '@standardnotes/domain-core'
|
||||
|
||||
import { SharedVaultUserRepositoryInterface } from '../../SharedVault/SharedVaultUserRepositoryInterface'
|
||||
import { AddSharedVaultUserDTO } from './AddSharedVaultUserDTO'
|
||||
|
||||
export class AddSharedVaultUser implements UseCaseInterface<void> {
|
||||
constructor(private sharedVaultUserRepository: SharedVaultUserRepositoryInterface) {}
|
||||
|
||||
async execute(dto: AddSharedVaultUserDTO): Promise<Result<void>> {
|
||||
const userUuidOrError = Uuid.create(dto.userUuid)
|
||||
if (userUuidOrError.isFailed()) {
|
||||
return Result.fail(userUuidOrError.getError())
|
||||
}
|
||||
const userUuid = userUuidOrError.getValue()
|
||||
|
||||
const sharedVaultUuidOrError = Uuid.create(dto.sharedVaultUuid)
|
||||
if (sharedVaultUuidOrError.isFailed()) {
|
||||
return Result.fail(sharedVaultUuidOrError.getError())
|
||||
}
|
||||
const sharedVaultUuid = sharedVaultUuidOrError.getValue()
|
||||
|
||||
const permissionOrError = SharedVaultUserPermission.create(dto.permission)
|
||||
if (permissionOrError.isFailed()) {
|
||||
return Result.fail(permissionOrError.getError())
|
||||
}
|
||||
const permission = permissionOrError.getValue()
|
||||
|
||||
const timestampsOrError = Timestamps.create(dto.createdAt, dto.updatedAt)
|
||||
if (timestampsOrError.isFailed()) {
|
||||
return Result.fail(timestampsOrError.getError())
|
||||
}
|
||||
const timestamps = timestampsOrError.getValue()
|
||||
|
||||
const sharedVaultUserOrError = SharedVaultUser.create({
|
||||
userUuid,
|
||||
sharedVaultUuid,
|
||||
permission,
|
||||
timestamps,
|
||||
})
|
||||
if (sharedVaultUserOrError.isFailed()) {
|
||||
return Result.fail(sharedVaultUserOrError.getError())
|
||||
}
|
||||
const sharedVaultUser = sharedVaultUserOrError.getValue()
|
||||
|
||||
await this.sharedVaultUserRepository.save(sharedVaultUser)
|
||||
|
||||
return Result.ok()
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user