mirror of
https://github.com/standardnotes/server
synced 2026-05-02 12:01:24 -04:00
Compare commits
177 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8dea171115 | |||
| aef9254713 | |||
| 31b7396006 | |||
| be0a2649da | |||
| bf8f91f83d | |||
| effdfebc19 | |||
| f4816e6c9a | |||
| 152a5cbd27 | |||
| 1488763115 | |||
| bbb35d16fc | |||
| ef07045ee9 | |||
| 3ba673b424 | |||
| 9c4032ebea | |||
| 05bb12c978 | |||
| df957f07e3 | |||
| b510284e01 | |||
| 205a1ed637 | |||
| 2073c735a5 | |||
| 34085ac6fb | |||
| 3d6559921b | |||
| 15a7f0e71a | |||
| 3e56243d6f | |||
| 032fcb938d | |||
| e98393452b | |||
| 302b624504 | |||
| e00d9d2ca0 | |||
| 9ab4601c8d | |||
| 19e43bdb1a | |||
| 49832e7944 | |||
| 916e98936a | |||
| 31d1eef7f7 | |||
| 2648d9a813 | |||
| b24b576209 | |||
| faee38bffd | |||
| 65f3503fe8 | |||
| 054023b791 | |||
| 383c3a68fa | |||
| 7d22b1c15c | |||
| c71e7cd926 | |||
| 83ad069c5d | |||
| 081108d9ba | |||
| 8f3df56a2b | |||
| d02124f4e5 | |||
| 09e351fedb | |||
| ad4b85b095 | |||
| 0bf7d8beae | |||
| 1ae7cca394 | |||
| bc1c7a8ae1 | |||
| c22c5e4584 | |||
| ac3646836c | |||
| 7a31ab75d6 | |||
| c49dc35ab5 | |||
| 06cedd11d8 | |||
| f496376fb3 | |||
| 091e2a57e8 | |||
| 0d40ef6796 | |||
| 1be33ba4c3 | |||
| aaeb311928 | |||
| a7a38c07ac | |||
| 56f49752b4 | |||
| 892d8b6fe2 | |||
| cec2005436 | |||
| 0eb86c0096 | |||
| b8e39d76c1 | |||
| 1c3ff526b7 | |||
| 373767248c | |||
| d7965b2748 | |||
| cbcd2ec87a | |||
| c74d37fc48 | |||
| 66f9352a06 | |||
| e5eef3aba0 | |||
| d261c81cd0 | |||
| 634e3bbb67 | |||
| f8c9e67063 | |||
| 18eddea6f8 | |||
| c6d655c5f5 | |||
| 46867c1a4d | |||
| d29903bab6 | |||
| 3415cae093 | |||
| 408fd5a0c6 | |||
| 0a16ee64fe | |||
| 22b00479b4 | |||
| 5311e74266 | |||
| 5be7db7788 | |||
| 3bd1547ce3 | |||
| a1fe15f7a9 | |||
| 19b8921f28 | |||
| 6b7879ba15 | |||
| bd5f492a73 | |||
| 67311cc002 | |||
| f39d3aca5b | |||
| 8e47491e3c | |||
| 0036d527bd | |||
| f565f1d950 | |||
| 8e35dfa4b7 | |||
| f911473be9 | |||
| 71624f1897 | |||
| 17de6ea7e1 | |||
| 6aad7cd207 | |||
| 63af335877 | |||
| 8cd7a138ab | |||
| f69cdc7b03 | |||
| 2ca649cf31 | |||
| f2ada08201 | |||
| 54ba1f69e5 | |||
| f13a99f5fd | |||
| e9bba6fd3a | |||
| f0d1a70c87 | |||
| 56f0aef21d | |||
| 75e266cb9e | |||
| b9bb83c0ce | |||
| da645c5ab3 | |||
| 318af5757d | |||
| b1cc156a25 | |||
| 79d71ca161 | |||
| cedd50b366 | |||
| 0d5dcdd8ec | |||
| d2b0fb144b | |||
| 053852b46c | |||
| 6ad349d379 | |||
| f7d33c7164 | |||
| b53b67328f | |||
| 573ffbfcf3 | |||
| 501ac0e99f | |||
| 959a11293a | |||
| fee1f1a3a7 | |||
| b0fbe0bb58 | |||
| 0087c70007 | |||
| 36e496dd7c | |||
| f2e2030e85 | |||
| 0c3737dc19 | |||
| f7471119e1 | |||
| 9bd97b95e9 | |||
| b7400c198f | |||
| f87036e3a8 | |||
| a43e5ef724 | |||
| 913ced70b0 | |||
| 6ffce30a36 | |||
| f5a57d886c | |||
| e8ba49ecca | |||
| c79a5dc94b | |||
| 4db83ae678 | |||
| 84ceb7ffd2 | |||
| e215ac4343 | |||
| bc8048790f | |||
| 886ccf84c1 | |||
| c067cb9fe4 | |||
| 6b2389cdc3 | |||
| d93916b159 | |||
| c34f548e45 | |||
| 6fcd56cc86 | |||
| 8f88a87c93 | |||
| f8c2f84322 | |||
| 46c4947871 | |||
| 64759ec2da | |||
| 5f7e768e64 | |||
| 4bc189f1c5 | |||
| 71721ab198 | |||
| 5536a48966 | |||
| f77e29d3c9 | |||
| 4b1fc718a2 | |||
| 1708c3f8a0 | |||
| 352e02028d | |||
| 1bbb639c83 | |||
| c14265f103 | |||
| c030a6b3d8 | |||
| af997ea658 | |||
| efa4d7fc60 | |||
| f714aaa0e9 | |||
| aee6e60583 | |||
| 4e602687d5 | |||
| d026152ac8 | |||
| 3f21a358d2 | |||
| dc55e47c98 | |||
| 3b804e2321 | |||
| b32f851a90 | |||
| 479d20e76f |
+7
-1
@@ -10,7 +10,7 @@ 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
|
||||||
@@ -22,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
|
||||||
|
|||||||
@@ -19,7 +19,12 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
e2e:
|
e2e:
|
||||||
name: (Docker) E2E Test Suite
|
name: (Self Hosting) E2E Test Suite
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
secondary_db_enabled: [true, false]
|
||||||
|
transition_mode_enabled: [true, false]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
services:
|
services:
|
||||||
@@ -45,19 +50,32 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
DB_TYPE: mysql
|
DB_TYPE: mysql
|
||||||
CACHE_TYPE: redis
|
CACHE_TYPE: redis
|
||||||
|
SECONDARY_DB_ENABLED: ${{ matrix.secondary_db_enabled }}
|
||||||
|
TRANSITION_MODE_ENABLED: ${{ matrix.transition_mode_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?vaults=enabled
|
||||||
|
|
||||||
|
- 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:
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
db_type: [mysql, sqlite]
|
db_type: [mysql, sqlite]
|
||||||
cache_type: [redis, memory]
|
cache_type: [redis, memory]
|
||||||
|
secondary_db_enabled: [true, false]
|
||||||
|
transition_mode_enabled: [true, false]
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
@@ -79,6 +97,14 @@ jobs:
|
|||||||
MYSQL_DATABASE: standardnotes
|
MYSQL_DATABASE: standardnotes
|
||||||
MYSQL_USER: standardnotes
|
MYSQL_USER: standardnotes
|
||||||
MYSQL_PASSWORD: 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
|
||||||
@@ -106,20 +132,29 @@ 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=db" >> packages/home-server/.env
|
echo "DB_HOST=localhost" >> packages/home-server/.env
|
||||||
echo "DB_PORT=3306" >> 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_USERNAME=standardnotes" >> packages/home-server/.env
|
||||||
echo "DB_PASSWORD=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_TYPE=${{ matrix.db_type }}" >> packages/home-server/.env
|
||||||
echo "REDIS_URL=redis://cache" >> 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 "CACHE_TYPE=${{ matrix.cache_type }}" >> packages/home-server/.env
|
||||||
|
echo "SECONDARY_DB_ENABLED=${{ matrix.secondary_db_enabled }}" >> packages/home-server/.env
|
||||||
|
echo "TRANSITION_MODE_ENABLED=${{ matrix.transition_mode_enabled }}" >> packages/home-server/.env
|
||||||
|
echo "MONGO_HOST=localhost" >> packages/home-server/.env
|
||||||
|
echo "MONGO_PORT=27017" >> packages/home-server/.env
|
||||||
|
echo "MONGO_DATABASE=standardnotes" >> packages/home-server/.env
|
||||||
|
echo "MONGO_USERNAME=standardnotes" >> packages/home-server/.env
|
||||||
|
echo "MONGO_PASSWORD=standardnotes" >> packages/home-server/.env
|
||||||
echo "FILES_SERVER_URL=http://localhost:3123" >> packages/home-server/.env
|
echo "FILES_SERVER_URL=http://localhost:3123" >> packages/home-server/.env
|
||||||
echo "E2E_TESTING=true" >> 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
|
||||||
|
|
||||||
@@ -127,4 +162,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
|
run: yarn dlx mocha-headless-chrome --timeout 1800000 -f http://localhost:9001/mocha/test.html?vaults=enabled
|
||||||
|
|
||||||
|
- name: Show logs on failure
|
||||||
|
if: ${{ failure() }}
|
||||||
|
run: tail -n 500 logs/output.log
|
||||||
|
|||||||
@@ -5191,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"],\
|
||||||
@@ -5201,7 +5202,7 @@ const RAW_RUNTIME_STATE =
|
|||||||
["semver", "npm:7.5.1"],\
|
["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"],\
|
||||||
@@ -5259,7 +5260,6 @@ const RAW_RUNTIME_STATE =
|
|||||||
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
|
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
|
||||||
["@standardnotes/responses", "npm:1.13.27"],\
|
["@standardnotes/responses", "npm:1.13.27"],\
|
||||||
["@standardnotes/security", "workspace:packages/security"],\
|
["@standardnotes/security", "workspace:packages/security"],\
|
||||||
["@standardnotes/utils", "npm:1.17.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"],\
|
||||||
@@ -5870,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/",\
|
||||||
@@ -7075,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/",\
|
||||||
@@ -11933,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/",\
|
||||||
@@ -12291,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/",\
|
||||||
@@ -14250,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/",\
|
||||||
@@ -14605,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/",\
|
||||||
@@ -15247,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", [\
|
||||||
@@ -15758,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": [\
|
||||||
@@ -16192,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", [\
|
||||||
@@ -16250,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.
BIN
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.
@@ -23,6 +23,8 @@ 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}"
|
||||||
|
TRANSITION_MODE_ENABLED: "${TRANSITION_MODE_ENABLED}"
|
||||||
container_name: server-ci
|
container_name: server-ci
|
||||||
ports:
|
ports:
|
||||||
- 3123:3000
|
- 3123:3000
|
||||||
@@ -61,6 +63,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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
# Setup environment variables
|
# Setup environment variables
|
||||||
|
|
||||||
|
export MODE="self-hosted"
|
||||||
|
|
||||||
#########
|
#########
|
||||||
# PORTS #
|
# PORTS #
|
||||||
#########
|
#########
|
||||||
@@ -63,6 +65,12 @@ 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
|
||||||
|
if [ -z "$TRANSITION_MODE_ENABLED" ]; then
|
||||||
|
export TRANSITION_MODE_ENABLED=false
|
||||||
|
fi
|
||||||
export DB_MIGRATIONS_PATH="dist/migrations/*.js"
|
export DB_MIGRATIONS_PATH="dist/migrations/*.js"
|
||||||
|
|
||||||
#########
|
#########
|
||||||
|
|||||||
@@ -147,10 +147,16 @@ LINKING_RESULT=$(link_queue_and_topic $SYNCING_SERVER_TOPIC_ARN $SYNCING_SERVER_
|
|||||||
echo "linking done:"
|
echo "linking done:"
|
||||||
echo "$LINKING_RESULT"
|
echo "$LINKING_RESULT"
|
||||||
|
|
||||||
echo "linking topic $SYNCING_SERVER_TOPIC_ARN to queue $SYNCING_SERVER_QUEUE_ARN"
|
echo "linking topic $FILES_TOPIC_ARN to queue $SYNCING_SERVER_QUEUE_ARN"
|
||||||
LINKING_RESULT=$(link_queue_and_topic $SYNCING_SERVER_TOPIC_ARN $SYNCING_SERVER_QUEUE_ARN)
|
LINKING_RESULT=$(link_queue_and_topic $FILES_TOPIC_ARN $SYNCING_SERVER_QUEUE_ARN)
|
||||||
echo "linking done:"
|
echo "linking done:"
|
||||||
echo "$LINKING_RESULT"
|
echo "$LINKING_RESULT"
|
||||||
|
|
||||||
|
echo "linking topic $SYNCING_SERVER_TOPIC_ARN to queue $AUTH_QUEUE_ARN"
|
||||||
|
LINKING_RESULT=$(link_queue_and_topic $SYNCING_SERVER_TOPIC_ARN $AUTH_QUEUE_ARN)
|
||||||
|
echo "linking done:"
|
||||||
|
echo "$LINKING_RESULT"
|
||||||
|
|
||||||
echo "linking topic $AUTH_TOPIC_ARN to queue $SYNCING_SERVER_QUEUE_ARN"
|
echo "linking topic $AUTH_TOPIC_ARN to queue $SYNCING_SERVER_QUEUE_ARN"
|
||||||
LINKING_RESULT=$(link_queue_and_topic $AUTH_TOPIC_ARN $SYNCING_SERVER_QUEUE_ARN)
|
LINKING_RESULT=$(link_queue_and_topic $AUTH_TOPIC_ARN $SYNCING_SERVER_QUEUE_ARN)
|
||||||
echo "linking done:"
|
echo "linking done:"
|
||||||
|
|||||||
+4
-1
@@ -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",
|
||||||
|
|||||||
@@ -3,6 +3,74 @@
|
|||||||
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.17](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.16...@standardnotes/analytics@2.25.17) (2023-08-24)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.25.16](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.15...@standardnotes/analytics@2.25.16) (2023-08-23)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.25.15](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.14...@standardnotes/analytics@2.25.15) (2023-08-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.25.14](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.13...@standardnotes/analytics@2.25.14) (2023-08-18)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.25.13](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.12...@standardnotes/analytics@2.25.13) (2023-08-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.25.12](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.11...@standardnotes/analytics@2.25.12) (2023-08-09)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.25.11](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.10...@standardnotes/analytics@2.25.11) (2023-08-09)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.25.10](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.9...@standardnotes/analytics@2.25.10) (2023-08-09)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.25.9](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.8...@standardnotes/analytics@2.25.9) (2023-08-08)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.25.8](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.7...@standardnotes/analytics@2.25.8) (2023-08-03)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.25.7](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.6...@standardnotes/analytics@2.25.7) (2023-08-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.25.6](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.5...@standardnotes/analytics@2.25.6) (2023-07-27)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.25.5](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.4...@standardnotes/analytics@2.25.5) (2023-07-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.25.4](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.3...@standardnotes/analytics@2.25.4) (2023-07-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.25.3](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.2...@standardnotes/analytics@2.25.3) (2023-07-21)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.25.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.1...@standardnotes/analytics@2.25.2) (2023-07-21)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.25.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.0...@standardnotes/analytics@2.25.1) (2023-07-19)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
# [2.25.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.24.9...@standardnotes/analytics@2.25.0) (2023-07-17)
|
# [2.25.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.24.9...@standardnotes/analytics@2.25.0) (2023-07-17)
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/analytics",
|
"name": "@standardnotes/analytics",
|
||||||
"version": "2.25.0",
|
"version": "2.25.17",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <21.0.0"
|
"node": ">=18.0.0 <21.0.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
MODE=microservice # microservice | home-server
|
MODE=microservice # microservice | home-server | self-hosted
|
||||||
LOG_LEVEL=debug
|
LOG_LEVEL=debug
|
||||||
NODE_ENV=development
|
NODE_ENV=development
|
||||||
VERSION=development
|
VERSION=development
|
||||||
|
|||||||
@@ -3,6 +3,118 @@
|
|||||||
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.72.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.72.0...@standardnotes/api-gateway@1.72.1) (2023-08-28)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* allow self hosted to use new model of items ([#714](https://github.com/standardnotes/api-gateway/issues/714)) ([aef9254](https://github.com/standardnotes/api-gateway/commit/aef9254713560c00a90a3e84e3cd94417e8f30d2))
|
||||||
|
|
||||||
|
# [1.72.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.71.1...@standardnotes/api-gateway@1.72.0) (2023-08-24)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add trigerring items transition and checking status of it ([#707](https://github.com/standardnotes/api-gateway/issues/707)) ([05bb12c](https://github.com/standardnotes/api-gateway/commit/05bb12c97899824f06e6d01d105dec75fc328440))
|
||||||
|
|
||||||
|
## [1.71.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.71.0...@standardnotes/api-gateway@1.71.1) (2023-08-23)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
# [1.71.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.70.5...@standardnotes/api-gateway@1.71.0) (2023-08-22)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* consider shared vault owner quota when uploading files to shared vault ([#704](https://github.com/standardnotes/api-gateway/issues/704)) ([34085ac](https://github.com/standardnotes/api-gateway/commit/34085ac6fb7e61d471bd3b4ae8e72112df25c3ee))
|
||||||
|
|
||||||
|
## [1.70.5](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.70.4...@standardnotes/api-gateway@1.70.5) (2023-08-18)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
## [1.70.4](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.70.3...@standardnotes/api-gateway@1.70.4) (2023-08-09)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
## [1.70.3](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.70.2...@standardnotes/api-gateway@1.70.3) (2023-08-09)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
## [1.70.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.70.1...@standardnotes/api-gateway@1.70.2) (2023-08-09)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
## [1.70.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.70.0...@standardnotes/api-gateway@1.70.1) (2023-08-08)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
# [1.70.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.69.3...@standardnotes/api-gateway@1.70.0) (2023-08-07)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **syncing-server:** limit shared vaults creation based on role ([#687](https://github.com/standardnotes/api-gateway/issues/687)) ([19b8921](https://github.com/standardnotes/api-gateway/commit/19b8921f286ff8f88c427e8ddd4512a8d61edb4f))
|
||||||
|
|
||||||
|
## [1.69.3](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.69.2...@standardnotes/api-gateway@1.69.3) (2023-08-03)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
## [1.69.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.69.1...@standardnotes/api-gateway@1.69.2) (2023-08-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
## [1.69.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.69.0...@standardnotes/api-gateway@1.69.1) (2023-07-31)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **api-gateway:** remove duplicating req/res objects on return raw response from payments ([79d71ca](https://github.com/standardnotes/api-gateway/commit/79d71ca161cc18135fcd1a83b021662e189b3ddb))
|
||||||
|
|
||||||
|
# [1.69.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.68.1...@standardnotes/api-gateway@1.69.0) (2023-07-31)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* refactor deleting account ([#676](https://github.com/standardnotes/api-gateway/issues/676)) ([0d5dcdd](https://github.com/standardnotes/api-gateway/commit/0d5dcdd8ec2336e41e7604c4157f79a89163ed29))
|
||||||
|
|
||||||
|
## [1.68.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.68.0...@standardnotes/api-gateway@1.68.1) (2023-07-27)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
# [1.68.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.67.4...@standardnotes/api-gateway@1.68.0) (2023-07-27)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **syncing-server:** add deleting outbound messages ([e8ba49e](https://github.com/standardnotes/api-gateway/commit/e8ba49ecca38ab10c0ea0e1f4cf4db9fb17366db))
|
||||||
|
|
||||||
|
## [1.67.4](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.67.3...@standardnotes/api-gateway@1.67.4) (2023-07-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
## [1.67.3](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.67.2...@standardnotes/api-gateway@1.67.3) (2023-07-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
## [1.67.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.67.1...@standardnotes/api-gateway@1.67.2) (2023-07-21)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
## [1.67.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.67.0...@standardnotes/api-gateway@1.67.1) (2023-07-21)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
# [1.67.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.66.1...@standardnotes/api-gateway@1.67.0) (2023-07-20)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **syncing-server:** add shared vaults, invites, messages and notifications to sync response ([#665](https://github.com/standardnotes/api-gateway/issues/665)) ([efa4d7f](https://github.com/standardnotes/api-gateway/commit/efa4d7fc6007ef668e3de3b04853ac11b2d13c30))
|
||||||
|
|
||||||
|
## [1.66.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.66.0...@standardnotes/api-gateway@1.66.1) (2023-07-19)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* add missing imports and exports for controllers ([#664](https://github.com/standardnotes/api-gateway/issues/664)) ([aee6e60](https://github.com/standardnotes/api-gateway/commit/aee6e6058359e2b5231cc13387656f837699300f))
|
||||||
|
|
||||||
|
# [1.66.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.65.7...@standardnotes/api-gateway@1.66.0) (2023-07-19)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **syncing-server:** add persistence of shared vaults with users and invites + controllers ([#662](https://github.com/standardnotes/api-gateway/issues/662)) ([3f21a35](https://github.com/standardnotes/api-gateway/commit/3f21a358d24d70daf541aa62dc86cd9e29500e62))
|
||||||
|
|
||||||
## [1.65.7](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.65.6...@standardnotes/api-gateway@1.65.7) (2023-07-17)
|
## [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
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|||||||
@@ -16,8 +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/AsymmetricMessagesController'
|
import '../src/Controller/v1/MessagesController'
|
||||||
import '../src/Controller/v1/SharedVaultsController'
|
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'
|
||||||
@@ -44,7 +46,7 @@ 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()
|
||||||
})
|
})
|
||||||
app.use(
|
app.use(
|
||||||
@@ -85,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) => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/api-gateway",
|
"name": "@standardnotes/api-gateway",
|
||||||
"version": "1.65.7",
|
"version": "1.72.1",
|
||||||
"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/*'"
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ export class ContainerConfigLoader {
|
|||||||
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 (!isConfiguredForInMemoryCache) {
|
if (!isConfiguredForInMemoryCache) {
|
||||||
const redisUrl = env.get('REDIS_URL')
|
const redisUrl = env.get('REDIS_URL')
|
||||||
@@ -68,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
|
||||||
@@ -106,24 +109,26 @@ 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')
|
logger.debug('Configuration complete')
|
||||||
|
|||||||
@@ -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'
|
||||||
@@ -28,16 +27,23 @@ export abstract class AuthMiddleware extends BaseMiddleware {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const authHeaderValue = request.headers.authorization as string
|
const authHeaderValue = request.headers.authorization as string
|
||||||
|
const sharedVaultOwnerContextHeaderValue = request.headers['x-shared-vault-owner-context'] as string | undefined
|
||||||
|
const cacheKey = `${authHeaderValue}${
|
||||||
|
sharedVaultOwnerContextHeaderValue ? `:${sharedVaultOwnerContextHeaderValue}` : ''
|
||||||
|
}`
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let crossServiceTokenFetchedFromCache = true
|
let crossServiceTokenFetchedFromCache = true
|
||||||
let crossServiceToken = null
|
let crossServiceToken = null
|
||||||
if (this.crossServiceTokenCacheTTL) {
|
if (this.crossServiceTokenCacheTTL) {
|
||||||
crossServiceToken = await this.crossServiceTokenCache.get(authHeaderValue)
|
crossServiceToken = await this.crossServiceTokenCache.get(cacheKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (crossServiceToken === null) {
|
if (this.crossServiceTokenIsEmptyOrRequiresRevalidation(crossServiceToken)) {
|
||||||
const authResponse = await this.serviceProxy.validateSession(authHeaderValue)
|
const authResponse = await this.serviceProxy.validateSession({
|
||||||
|
authorization: authHeaderValue,
|
||||||
|
sharedVaultOwnerContext: sharedVaultOwnerContextHeaderValue,
|
||||||
|
})
|
||||||
|
|
||||||
if (!this.handleSessionValidationResponse(authResponse, response, next)) {
|
if (!this.handleSessionValidationResponse(authResponse, response, next)) {
|
||||||
return
|
return
|
||||||
@@ -49,16 +55,14 @@ export abstract class AuthMiddleware extends BaseMiddleware {
|
|||||||
|
|
||||||
response.locals.authToken = crossServiceToken
|
response.locals.authToken = crossServiceToken
|
||||||
|
|
||||||
const decodedToken = <CrossServiceTokenData>verify(crossServiceToken, this.jwtSecret, { algorithms: ['HS256'] })
|
const decodedToken = <CrossServiceTokenData>(
|
||||||
|
verify(response.locals.authToken, 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,
|
key: cacheKey,
|
||||||
encodedCrossServiceToken: crossServiceToken,
|
encodedCrossServiceToken: response.locals.authToken,
|
||||||
expiresAtInSeconds: this.getCrossServiceTokenCacheExpireTimestamp(decodedToken),
|
expiresAtInSeconds: this.getCrossServiceTokenCacheExpireTimestamp(decodedToken),
|
||||||
userUuid: decodedToken.user.uuid,
|
userUuid: decodedToken.user.uuid,
|
||||||
})
|
})
|
||||||
@@ -67,6 +71,7 @@ export abstract class AuthMiddleware extends BaseMiddleware {
|
|||||||
response.locals.user = decodedToken.user
|
response.locals.user = decodedToken.user
|
||||||
response.locals.session = decodedToken.session
|
response.locals.session = decodedToken.session
|
||||||
response.locals.roles = decodedToken.roles
|
response.locals.roles = decodedToken.roles
|
||||||
|
response.locals.sharedVaultOwnerContext = decodedToken.shared_vault_owner_context
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorMessage = (error as AxiosError).isAxiosError
|
const errorMessage = (error as AxiosError).isAxiosError
|
||||||
? JSON.stringify((error as AxiosError).response?.data)
|
? JSON.stringify((error as AxiosError).response?.data)
|
||||||
@@ -123,4 +128,14 @@ export abstract class AuthMiddleware extends BaseMiddleware {
|
|||||||
|
|
||||||
return Math.min(crossServiceTokenDefaultCacheExpiration, sessionAccessExpiration, sessionRefreshExpiration)
|
return Math.min(crossServiceTokenDefaultCacheExpiration, sessionAccessExpiration, sessionRefreshExpiration)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private crossServiceTokenIsEmptyOrRequiresRevalidation(crossServiceToken: string | null) {
|
||||||
|
if (crossServiceToken === null) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
const decodedToken = <CrossServiceTokenData>verify(crossServiceToken, this.jwtSecret, { algorithms: ['HS256'] })
|
||||||
|
|
||||||
|
return decodedToken.ongoing_transition === true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,7 +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/AsymmetricMessagesController'
|
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'
|
||||||
@@ -13,6 +13,8 @@ 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/SharedVaultsController'
|
||||||
export * from './v1/SubscriptionInvitesController'
|
export * from './v1/SubscriptionInvitesController'
|
||||||
export * from './v1/TokensController'
|
export * from './v1/TokensController'
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
import { Request, Response } from 'express'
|
|
||||||
import { inject } from 'inversify'
|
|
||||||
import { BaseHttpController, controller, all } from 'inversify-express-utils'
|
|
||||||
import { TYPES } from '../../Bootstrap/Types'
|
|
||||||
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
|
|
||||||
|
|
||||||
@controller('/v1/asymmetric-messages')
|
|
||||||
export class AsymmetricMessagesController extends BaseHttpController {
|
|
||||||
constructor(@inject(TYPES.ServiceProxy) private serviceProxy: ServiceProxyInterface) {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
@all('*', TYPES.RequiredCrossServiceTokenMiddleware)
|
|
||||||
async subscriptions(request: Request, response: Response): Promise<void> {
|
|
||||||
await this.serviceProxy.callSyncingServer(request, response, request.path.replace('/v1/', ''), request.body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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()
|
||||||
}
|
}
|
||||||
@@ -34,6 +34,16 @@ export class ItemsController extends BaseHttpController {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@httpPost('/transition')
|
||||||
|
async transition(request: Request, response: Response): Promise<void> {
|
||||||
|
await this.serviceProxy.callSyncingServer(
|
||||||
|
request,
|
||||||
|
response,
|
||||||
|
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'items/transition'),
|
||||||
|
request.body,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@httpGet('/:uuid')
|
@httpGet('/:uuid')
|
||||||
async getItem(request: Request, response: Response): Promise<void> {
|
async getItem(request: Request, response: Response): Promise<void> {
|
||||||
await this.serviceProxy.callSyncingServer(
|
await this.serviceProxy.callSyncingServer(
|
||||||
|
|||||||
@@ -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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,17 +1,64 @@
|
|||||||
import { Request, Response } from 'express'
|
import { Request, Response } from 'express'
|
||||||
import { inject } from 'inversify'
|
import { inject } from 'inversify'
|
||||||
import { BaseHttpController, controller, all } from 'inversify-express-utils'
|
import { BaseHttpController, controller, httpDelete, httpGet, httpPost } from 'inversify-express-utils'
|
||||||
import { TYPES } from '../../Bootstrap/Types'
|
import { TYPES } from '../../Bootstrap/Types'
|
||||||
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
|
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
|
||||||
|
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
|
||||||
|
|
||||||
@controller('/v1/shared-vaults')
|
@controller('/v1/shared-vaults', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
|
||||||
export class SharedVaultsController extends BaseHttpController {
|
export class SharedVaultsController extends BaseHttpController {
|
||||||
constructor(@inject(TYPES.ServiceProxy) private serviceProxy: ServiceProxyInterface) {
|
constructor(
|
||||||
|
@inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface,
|
||||||
|
@inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
|
||||||
|
) {
|
||||||
super()
|
super()
|
||||||
}
|
}
|
||||||
|
|
||||||
@all('*', TYPES.RequiredCrossServiceTokenMiddleware)
|
@httpGet('/')
|
||||||
async subscriptions(request: Request, response: Response): Promise<void> {
|
async getSharedVaults(request: Request, response: Response): Promise<void> {
|
||||||
await this.serviceProxy.callSyncingServer(request, response, request.path.replace('/v1/', ''), request.body)
|
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,16 @@ export class UsersController extends BaseHttpController {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@httpGet('/:userId/params', TYPES.RequiredCrossServiceTokenMiddleware)
|
@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> {
|
async getKeyParams(request: Request, response: Response): Promise<void> {
|
||||||
await this.httpService.callAuthServer(
|
await this.httpService.callAuthServer(
|
||||||
request,
|
request,
|
||||||
@@ -88,12 +98,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 +123,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 +136,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 +150,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 +164,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 +179,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 +196,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 +209,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 +222,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 +245,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()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,29 +12,29 @@ export class InMemoryCrossServiceTokenCache implements CrossServiceTokenCacheInt
|
|||||||
constructor(private timer: TimerInterface) {}
|
constructor(private timer: TimerInterface) {}
|
||||||
|
|
||||||
async set(dto: {
|
async set(dto: {
|
||||||
authorizationHeaderValue: string
|
key: string
|
||||||
encodedCrossServiceToken: string
|
encodedCrossServiceToken: string
|
||||||
expiresAtInSeconds: number
|
expiresAtInSeconds: number
|
||||||
userUuid: string
|
userUuid: string
|
||||||
}): Promise<void> {
|
}): Promise<void> {
|
||||||
let userAuthHeaders = []
|
let userKeys = []
|
||||||
const userAuthHeadersJSON = this.crossServiceTokenCache.get(`${this.USER_CST_PREFIX}:${dto.userUuid}`)
|
const userKeysJSON = this.crossServiceTokenCache.get(`${this.USER_CST_PREFIX}:${dto.userUuid}`)
|
||||||
if (userAuthHeadersJSON) {
|
if (userKeysJSON) {
|
||||||
userAuthHeaders = JSON.parse(userAuthHeadersJSON)
|
userKeys = JSON.parse(userKeysJSON)
|
||||||
}
|
}
|
||||||
userAuthHeaders.push(dto.authorizationHeaderValue)
|
userKeys.push(dto.key)
|
||||||
|
|
||||||
this.crossServiceTokenCache.set(`${this.USER_CST_PREFIX}:${dto.userUuid}`, JSON.stringify(userAuthHeaders))
|
this.crossServiceTokenCache.set(`${this.USER_CST_PREFIX}:${dto.userUuid}`, JSON.stringify(userKeys))
|
||||||
this.crossServiceTokenTTLCache.set(`${this.USER_CST_PREFIX}:${dto.userUuid}`, dto.expiresAtInSeconds)
|
this.crossServiceTokenTTLCache.set(`${this.USER_CST_PREFIX}:${dto.userUuid}`, dto.expiresAtInSeconds)
|
||||||
|
|
||||||
this.crossServiceTokenCache.set(`${this.PREFIX}:${dto.authorizationHeaderValue}`, dto.encodedCrossServiceToken)
|
this.crossServiceTokenCache.set(`${this.PREFIX}:${dto.key}`, dto.encodedCrossServiceToken)
|
||||||
this.crossServiceTokenTTLCache.set(`${this.PREFIX}:${dto.authorizationHeaderValue}`, dto.expiresAtInSeconds)
|
this.crossServiceTokenTTLCache.set(`${this.PREFIX}:${dto.key}`, dto.expiresAtInSeconds)
|
||||||
}
|
}
|
||||||
|
|
||||||
async get(authorizationHeaderValue: string): Promise<string | null> {
|
async get(key: string): Promise<string | null> {
|
||||||
this.invalidateExpiredTokens()
|
this.invalidateExpiredTokens()
|
||||||
|
|
||||||
const cachedToken = this.crossServiceTokenCache.get(`${this.PREFIX}:${authorizationHeaderValue}`)
|
const cachedToken = this.crossServiceTokenCache.get(`${this.PREFIX}:${key}`)
|
||||||
if (!cachedToken) {
|
if (!cachedToken) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -43,15 +43,15 @@ export class InMemoryCrossServiceTokenCache implements CrossServiceTokenCacheInt
|
|||||||
}
|
}
|
||||||
|
|
||||||
async invalidate(userUuid: string): Promise<void> {
|
async invalidate(userUuid: string): Promise<void> {
|
||||||
let userAuthorizationHeaderValues = []
|
let userKeyValues = []
|
||||||
const userAuthHeadersJSON = this.crossServiceTokenCache.get(`${this.USER_CST_PREFIX}:${userUuid}`)
|
const userKeysJSON = this.crossServiceTokenCache.get(`${this.USER_CST_PREFIX}:${userUuid}`)
|
||||||
if (userAuthHeadersJSON) {
|
if (userKeysJSON) {
|
||||||
userAuthorizationHeaderValues = JSON.parse(userAuthHeadersJSON)
|
userKeyValues = JSON.parse(userKeysJSON)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const authorizationHeaderValue of userAuthorizationHeaderValues) {
|
for (const key of userKeyValues) {
|
||||||
this.crossServiceTokenCache.delete(`${this.PREFIX}:${authorizationHeaderValue}`)
|
this.crossServiceTokenCache.delete(`${this.PREFIX}:${key}`)
|
||||||
this.crossServiceTokenTTLCache.delete(`${this.PREFIX}:${authorizationHeaderValue}`)
|
this.crossServiceTokenTTLCache.delete(`${this.PREFIX}:${key}`)
|
||||||
}
|
}
|
||||||
this.crossServiceTokenCache.delete(`${this.USER_CST_PREFIX}:${userUuid}`)
|
this.crossServiceTokenCache.delete(`${this.USER_CST_PREFIX}:${userUuid}`)
|
||||||
this.crossServiceTokenTTLCache.delete(`${this.USER_CST_PREFIX}:${userUuid}`)
|
this.crossServiceTokenTTLCache.delete(`${this.USER_CST_PREFIX}:${userUuid}`)
|
||||||
|
|||||||
@@ -9,35 +9,35 @@ 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
|
key: string
|
||||||
encodedCrossServiceToken: string
|
encodedCrossServiceToken: string
|
||||||
expiresAtInSeconds: number
|
expiresAtInSeconds: number
|
||||||
userUuid: string
|
userUuid: string
|
||||||
}): Promise<void> {
|
}): Promise<void> {
|
||||||
const pipeline = this.redisClient.pipeline()
|
const pipeline = this.redisClient.pipeline()
|
||||||
|
|
||||||
pipeline.sadd(`${this.USER_CST_PREFIX}:${dto.userUuid}`, dto.authorizationHeaderValue)
|
pipeline.sadd(`${this.USER_CST_PREFIX}:${dto.userUuid}`, dto.key)
|
||||||
pipeline.expireat(`${this.USER_CST_PREFIX}:${dto.userUuid}`, dto.expiresAtInSeconds)
|
pipeline.expireat(`${this.USER_CST_PREFIX}:${dto.userUuid}`, dto.expiresAtInSeconds)
|
||||||
|
|
||||||
pipeline.set(`${this.PREFIX}:${dto.authorizationHeaderValue}`, dto.encodedCrossServiceToken)
|
pipeline.set(`${this.PREFIX}:${dto.key}`, dto.encodedCrossServiceToken)
|
||||||
pipeline.expireat(`${this.PREFIX}:${dto.authorizationHeaderValue}`, dto.expiresAtInSeconds)
|
pipeline.expireat(`${this.PREFIX}:${dto.key}`, dto.expiresAtInSeconds)
|
||||||
|
|
||||||
await pipeline.exec()
|
await pipeline.exec()
|
||||||
}
|
}
|
||||||
|
|
||||||
async get(authorizationHeaderValue: string): Promise<string | null> {
|
async get(key: string): Promise<string | null> {
|
||||||
return this.redisClient.get(`${this.PREFIX}:${authorizationHeaderValue}`)
|
return this.redisClient.get(`${this.PREFIX}:${key}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
async invalidate(userUuid: string): Promise<void> {
|
async invalidate(userUuid: string): Promise<void> {
|
||||||
const userAuthorizationHeaderValues = await this.redisClient.smembers(`${this.USER_CST_PREFIX}:${userUuid}`)
|
const userKeyValues = await this.redisClient.smembers(`${this.USER_CST_PREFIX}:${userUuid}`)
|
||||||
|
|
||||||
const pipeline = this.redisClient.pipeline()
|
const pipeline = this.redisClient.pipeline()
|
||||||
for (const authorizationHeaderValue of userAuthorizationHeaderValues) {
|
for (const key of userKeyValues) {
|
||||||
pipeline.del(`${this.PREFIX}:${authorizationHeaderValue}`)
|
pipeline.del(`${this.PREFIX}:${key}`)
|
||||||
}
|
}
|
||||||
pipeline.del(`${this.USER_CST_PREFIX}:${userUuid}`)
|
pipeline.del(`${this.USER_CST_PREFIX}:${userUuid}`)
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
export interface CrossServiceTokenCacheInterface {
|
export interface CrossServiceTokenCacheInterface {
|
||||||
set(dto: {
|
set(dto: {
|
||||||
authorizationHeaderValue: string
|
key: string
|
||||||
encodedCrossServiceToken: string
|
encodedCrossServiceToken: string
|
||||||
expiresAtInSeconds: number
|
expiresAtInSeconds: number
|
||||||
userUuid: string
|
userUuid: string
|
||||||
}): Promise<void>
|
}): Promise<void>
|
||||||
get(authorizationHeaderValue: string): Promise<string | null>
|
get(key: string): Promise<string | null>
|
||||||
invalidate(userUuid: string): Promise<void>
|
invalidate(userUuid: string): Promise<void>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,27 +11,29 @@ 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(headers: {
|
||||||
authorizationHeaderValue: string,
|
authorization: string
|
||||||
): Promise<{ status: number; data: unknown; headers: { contentType: string } }> {
|
sharedVaultOwnerContext?: string
|
||||||
|
}): Promise<{ status: number; data: unknown; headers: { contentType: string } }> {
|
||||||
const authResponse = await this.httpClient.request({
|
const authResponse = await this.httpClient.request({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: authorizationHeaderValue,
|
Authorization: headers.authorization,
|
||||||
Accept: 'application/json',
|
Accept: 'application/json',
|
||||||
|
'x-shared-vault-owner-context': headers.sharedVaultOwnerContext,
|
||||||
},
|
},
|
||||||
validateStatus: (status: number) => {
|
validateStatus: (status: number) => {
|
||||||
return status >= 200 && status < 500
|
return status >= 200 && status < 500
|
||||||
@@ -130,19 +132,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 +288,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 +305,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,14 +42,15 @@ 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,
|
||||||
endpointOrMethodIdentifier: string,
|
endpointOrMethodIdentifier: string,
|
||||||
payload?: Record<string, unknown> | string,
|
payload?: Record<string, unknown> | string,
|
||||||
): Promise<void>
|
): Promise<void>
|
||||||
validateSession(authorizationHeaderValue: string): Promise<{
|
validateSession(headers: { authorization: string; sharedVaultOwnerContext?: string }): Promise<{
|
||||||
status: number
|
status: number
|
||||||
data: unknown
|
data: unknown
|
||||||
headers: {
|
headers: {
|
||||||
|
|||||||
@@ -6,9 +6,10 @@ import { ServiceProxyInterface } from '../Http/ServiceProxyInterface'
|
|||||||
export class DirectCallServiceProxy implements ServiceProxyInterface {
|
export class DirectCallServiceProxy implements ServiceProxyInterface {
|
||||||
constructor(private serviceContainer: ServiceContainerInterface, private filesServerUrl: string) {}
|
constructor(private serviceContainer: ServiceContainerInterface, private filesServerUrl: string) {}
|
||||||
|
|
||||||
async validateSession(
|
async validateSession(headers: {
|
||||||
authorizationHeaderValue: string,
|
authorization: string
|
||||||
): Promise<{ status: number; data: unknown; headers: { contentType: string } }> {
|
sharedVaultOwnerContext?: string
|
||||||
|
}): Promise<{ status: number; data: unknown; headers: { contentType: string } }> {
|
||||||
const authService = this.serviceContainer.get(ServiceIdentifier.create(ServiceIdentifier.NAMES.Auth).getValue())
|
const authService = this.serviceContainer.get(ServiceIdentifier.create(ServiceIdentifier.NAMES.Auth).getValue())
|
||||||
if (!authService) {
|
if (!authService) {
|
||||||
throw new Error('Auth service not found')
|
throw new Error('Auth service not found')
|
||||||
@@ -17,7 +18,8 @@ export class DirectCallServiceProxy implements ServiceProxyInterface {
|
|||||||
const serviceResponse = (await authService.handleRequest(
|
const serviceResponse = (await authService.handleRequest(
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
authorization: authorizationHeaderValue,
|
authorization: headers.authorization,
|
||||||
|
'x-shared-vault-owner-context': headers.sharedVaultOwnerContext,
|
||||||
},
|
},
|
||||||
} as never,
|
} as never,
|
||||||
{} as never,
|
{} as never,
|
||||||
|
|||||||
@@ -42,7 +42,9 @@ export class EndpointResolver implements EndpointResolverInterface {
|
|||||||
// Users Controller
|
// Users Controller
|
||||||
['[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'],
|
['[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]: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'],
|
||||||
@@ -57,11 +59,38 @@ export class EndpointResolver implements EndpointResolverInterface {
|
|||||||
// Syncing Server
|
// Syncing Server
|
||||||
['[POST]:items/sync', 'sync.items.sync'],
|
['[POST]:items/sync', 'sync.items.sync'],
|
||||||
['[POST]:items/check-integrity', 'sync.items.check_integrity'],
|
['[POST]:items/check-integrity', 'sync.items.check_integrity'],
|
||||||
|
['[POST]:items/transition', 'sync.items.transition'],
|
||||||
['[GET]:items/:uuid', 'sync.items.get_item'],
|
['[GET]:items/:uuid', 'sync.items.get_item'],
|
||||||
// Revisions Controller V2
|
// Revisions Controller V2
|
||||||
['[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 +104,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
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
MODE=microservice # microservice | home-server
|
MODE=microservice # microservice | home-server | self-hosted
|
||||||
LOG_LEVEL=debug
|
LOG_LEVEL=debug
|
||||||
NODE_ENV=development
|
NODE_ENV=development
|
||||||
VERSION=development
|
VERSION=development
|
||||||
|
|||||||
@@ -3,6 +3,146 @@
|
|||||||
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.135.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.135.1...@standardnotes/auth-server@1.135.2) (2023-08-28)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* allow self hosted to use new model of items ([#714](https://github.com/standardnotes/server/issues/714)) ([aef9254](https://github.com/standardnotes/server/commit/aef9254713560c00a90a3e84e3cd94417e8f30d2))
|
||||||
|
|
||||||
|
## [1.135.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.135.0...@standardnotes/auth-server@1.135.1) (2023-08-25)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **auth:** account enumeration with pseudo u2f and mfa ([#709](https://github.com/standardnotes/server/issues/709)) ([bbb35d1](https://github.com/standardnotes/server/commit/bbb35d16fc4f6a57fe774a648fbda13ec64a8865))
|
||||||
|
|
||||||
|
# [1.135.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.134.0...@standardnotes/auth-server@1.135.0) (2023-08-24)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add trigerring items transition and checking status of it ([#707](https://github.com/standardnotes/server/issues/707)) ([05bb12c](https://github.com/standardnotes/server/commit/05bb12c97899824f06e6d01d105dec75fc328440))
|
||||||
|
|
||||||
|
# [1.134.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.133.0...@standardnotes/auth-server@1.134.0) (2023-08-23)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add handling file moving and updating storage quota ([#705](https://github.com/standardnotes/server/issues/705)) ([205a1ed](https://github.com/standardnotes/server/commit/205a1ed637b626be13fc656276508f3c7791024f))
|
||||||
|
|
||||||
|
# [1.133.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.132.0...@standardnotes/auth-server@1.133.0) (2023-08-22)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* consider shared vault owner quota when uploading files to shared vault ([#704](https://github.com/standardnotes/server/issues/704)) ([34085ac](https://github.com/standardnotes/server/commit/34085ac6fb7e61d471bd3b4ae8e72112df25c3ee))
|
||||||
|
|
||||||
|
# [1.132.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.131.5...@standardnotes/auth-server@1.132.0) (2023-08-18)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add mechanism for determining if a user should use the primary or secondary items database ([#700](https://github.com/standardnotes/server/issues/700)) ([302b624](https://github.com/standardnotes/server/commit/302b624504f4c87fd7c3ddfee77cbdc14a61018b))
|
||||||
|
|
||||||
|
## [1.131.5](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.131.4...@standardnotes/auth-server@1.131.5) (2023-08-15)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **auth:** passing the invalidate cache header ([#697](https://github.com/standardnotes/server/issues/697)) ([83ad069](https://github.com/standardnotes/server/commit/83ad069c5dd9afa3a6db881f0d8a55a58d0642aa))
|
||||||
|
|
||||||
|
## [1.131.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.131.3...@standardnotes/auth-server@1.131.4) (2023-08-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/auth-server
|
||||||
|
|
||||||
|
## [1.131.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.131.2...@standardnotes/auth-server@1.131.3) (2023-08-09)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/auth-server
|
||||||
|
|
||||||
|
## [1.131.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.131.1...@standardnotes/auth-server@1.131.2) (2023-08-09)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/auth-server
|
||||||
|
|
||||||
|
## [1.131.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.131.0...@standardnotes/auth-server@1.131.1) (2023-08-09)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/auth-server
|
||||||
|
|
||||||
|
# [1.131.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.130.1...@standardnotes/auth-server@1.131.0) (2023-08-08)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* update storage quota used for user based on shared vault files ([#689](https://github.com/standardnotes/server/issues/689)) ([5311e74](https://github.com/standardnotes/server/commit/5311e7426617da6fc75593dd0fcbff589ca4fc22))
|
||||||
|
|
||||||
|
## [1.130.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.130.0...@standardnotes/auth-server@1.130.1) (2023-08-07)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **auth:** update user agent upon refreshing session token ([#685](https://github.com/standardnotes/server/issues/685)) ([bd5f492](https://github.com/standardnotes/server/commit/bd5f492a733f783c64fa4bc5840b4a9f5c913d3d))
|
||||||
|
|
||||||
|
# [1.130.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.129.0...@standardnotes/auth-server@1.130.0) (2023-08-07)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **auth:** invalidate other sessions for user if the email or password are changed ([#684](https://github.com/standardnotes/server/issues/684)) ([f39d3ac](https://github.com/standardnotes/server/commit/f39d3aca5b7bb9e5f9c1c24cbe2359f30dea835c))
|
||||||
|
|
||||||
|
# [1.129.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.128.1...@standardnotes/auth-server@1.129.0) (2023-08-03)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **auth:** add handling payments account deleted events STA-1769 ([#682](https://github.com/standardnotes/server/issues/682)) ([8e35dfa](https://github.com/standardnotes/server/commit/8e35dfa4b77256f4c0a3294b296a5526fd1020ad))
|
||||||
|
|
||||||
|
## [1.128.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.128.0...@standardnotes/auth-server@1.128.1) (2023-08-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/auth-server
|
||||||
|
|
||||||
|
# [1.128.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.127.2...@standardnotes/auth-server@1.128.0) (2023-08-02)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* enable Write Ahead Log mode for SQLite ([#681](https://github.com/standardnotes/server/issues/681)) ([8cd7a13](https://github.com/standardnotes/server/commit/8cd7a138ab56f6a2b0d6c06ef6041ab9b85ae540))
|
||||||
|
|
||||||
|
## [1.127.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.127.1...@standardnotes/auth-server@1.127.2) (2023-08-01)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* controller naming ([#678](https://github.com/standardnotes/server/issues/678)) ([56f0aef](https://github.com/standardnotes/server/commit/56f0aef21d3fcec7ac7e968cb1c1b071becbbe26))
|
||||||
|
|
||||||
|
## [1.127.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.127.0...@standardnotes/auth-server@1.127.1) (2023-07-31)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **auth:** auth middleware on delete account ([318af57](https://github.com/standardnotes/server/commit/318af5757d6c42f580157647b22112a9936765e7))
|
||||||
|
|
||||||
|
# [1.127.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.126.5...@standardnotes/auth-server@1.127.0) (2023-07-31)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* refactor deleting account ([#676](https://github.com/standardnotes/server/issues/676)) ([0d5dcdd](https://github.com/standardnotes/server/commit/0d5dcdd8ec2336e41e7604c4157f79a89163ed29))
|
||||||
|
|
||||||
|
## [1.126.5](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.126.4...@standardnotes/auth-server@1.126.5) (2023-07-27)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/auth-server
|
||||||
|
|
||||||
|
## [1.126.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.126.3...@standardnotes/auth-server@1.126.4) (2023-07-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/auth-server
|
||||||
|
|
||||||
|
## [1.126.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.126.2...@standardnotes/auth-server@1.126.3) (2023-07-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/auth-server
|
||||||
|
|
||||||
|
## [1.126.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.126.1...@standardnotes/auth-server@1.126.2) (2023-07-21)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/auth-server
|
||||||
|
|
||||||
|
## [1.126.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.126.0...@standardnotes/auth-server@1.126.1) (2023-07-21)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/auth-server
|
||||||
|
|
||||||
|
# [1.126.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.125.1...@standardnotes/auth-server@1.126.0) (2023-07-20)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **syncing-server:** add shared vaults, invites, messages and notifications to sync response ([#665](https://github.com/standardnotes/server/issues/665)) ([efa4d7f](https://github.com/standardnotes/server/commit/efa4d7fc6007ef668e3de3b04853ac11b2d13c30))
|
||||||
|
|
||||||
|
## [1.125.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.125.0...@standardnotes/auth-server@1.125.1) (2023-07-19)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/auth-server
|
||||||
|
|
||||||
# [1.125.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.124.2...@standardnotes/auth-server@1.125.0) (2023-07-17)
|
# [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
|
### Features
|
||||||
|
|||||||
+18
-18
@@ -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'
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
|
||||||
|
|
||||||
export class AddNotifications1688540448427 implements MigrationInterface {
|
|
||||||
name = 'AddNotifications1688540448427'
|
|
||||||
|
|
||||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
||||||
await queryRunner.query(
|
|
||||||
'CREATE TABLE `notifications` (`uuid` varchar(36) NOT NULL, `user_uuid` varchar(36) NOT NULL, `type` varchar(36) NOT NULL, `payload` text NOT NULL, `created_at_timestamp` bigint NOT NULL, `updated_at_timestamp` bigint NOT NULL, INDEX `index_notifications_on_user_uuid` (`user_uuid`), PRIMARY KEY (`uuid`)) ENGINE=InnoDB',
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
||||||
await queryRunner.query('DROP INDEX `index_notifications_on_user_uuid` ON `notifications`')
|
|
||||||
await queryRunner.query('DROP TABLE `notifications`')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
|
||||||
|
|
||||||
export class RemoveNotifications1688540448428 implements MigrationInterface {
|
|
||||||
name = 'RemoveNotifications1688540448428'
|
|
||||||
|
|
||||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
||||||
await queryRunner.query('DROP INDEX `index_notifications_on_user_uuid` ON `notifications`')
|
|
||||||
await queryRunner.query('DROP TABLE `notifications`')
|
|
||||||
}
|
|
||||||
|
|
||||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
||||||
await queryRunner.query(
|
|
||||||
'CREATE TABLE `notifications` (`uuid` varchar(36) NOT NULL, `user_uuid` varchar(36) NOT NULL, `type` varchar(36) NOT NULL, `payload` text NOT NULL, `created_at_timestamp` bigint NOT NULL, `updated_at_timestamp` bigint NOT NULL, INDEX `index_notifications_on_user_uuid` (`user_uuid`), PRIMARY KEY (`uuid`)) ENGINE=InnoDB',
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||||
|
|
||||||
|
export class AddTransitionRole1692348191367 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
'INSERT INTO `roles` (uuid, name, version) VALUES ("e7381dc5-3d67-49e9-b7bd-f2407b2f726e", "TRANSITION_USER", 1)',
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(): Promise<void> {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
|
||||||
|
|
||||||
export class AddNotifications1688540623272 implements MigrationInterface {
|
|
||||||
name = 'AddNotifications1688540623272'
|
|
||||||
|
|
||||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
||||||
await queryRunner.query(
|
|
||||||
'CREATE TABLE "notifications" ("uuid" varchar PRIMARY KEY NOT NULL, "user_uuid" varchar(36) NOT NULL, "type" varchar(36) NOT NULL, "payload" text NOT NULL, "created_at_timestamp" bigint NOT NULL, "updated_at_timestamp" bigint NOT NULL)',
|
|
||||||
)
|
|
||||||
await queryRunner.query('CREATE INDEX "index_notifications_on_user_uuid" ON "notifications" ("user_uuid") ')
|
|
||||||
}
|
|
||||||
|
|
||||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
||||||
await queryRunner.query('DROP INDEX "index_notifications_on_user_uuid"')
|
|
||||||
await queryRunner.query('DROP TABLE "notifications"')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
|
||||||
|
|
||||||
export class RemoveNotifications1688540623273 implements MigrationInterface {
|
|
||||||
name = 'RemoveNotifications1688540623273'
|
|
||||||
|
|
||||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
||||||
await queryRunner.query('DROP INDEX "index_notifications_on_user_uuid"')
|
|
||||||
await queryRunner.query('DROP TABLE "notifications"')
|
|
||||||
}
|
|
||||||
|
|
||||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
||||||
await queryRunner.query(
|
|
||||||
'CREATE TABLE "notifications" ("uuid" varchar PRIMARY KEY NOT NULL, "user_uuid" varchar(36) NOT NULL, "type" varchar(36) NOT NULL, "payload" text NOT NULL, "created_at_timestamp" bigint NOT NULL, "updated_at_timestamp" bigint NOT NULL)',
|
|
||||||
)
|
|
||||||
await queryRunner.query('CREATE INDEX "index_notifications_on_user_uuid" ON "notifications" ("user_uuid") ')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||||
|
|
||||||
|
export class AddTransitionRole1692348280258 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
'INSERT INTO `roles` (uuid, name, version) VALUES ("e7381dc5-3d67-49e9-b7bd-f2407b2f726e", "TRANSITION_USER", 1)',
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(): Promise<void> {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/auth-server",
|
"name": "@standardnotes/auth-server",
|
||||||
"version": "1.125.0",
|
"version": "1.135.2",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <21.0.0"
|
"node": ">=18.0.0 <21.0.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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,24 +234,35 @@ 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 { ActivatePremiumFeatures } from '../Domain/UseCase/ActivatePremiumFeatures/ActivatePremiumFeatures'
|
||||||
|
import { PaymentsAccountDeletedEventHandler } from '../Domain/Handler/PaymentsAccountDeletedEventHandler'
|
||||||
|
import { UpdateStorageQuotaUsedForUser } from '../Domain/UseCase/UpdateStorageQuotaUsedForUser/UpdateStorageQuotaUsedForUser'
|
||||||
|
import { SharedVaultFileUploadedEventHandler } from '../Domain/Handler/SharedVaultFileUploadedEventHandler'
|
||||||
|
import { SharedVaultFileRemovedEventHandler } from '../Domain/Handler/SharedVaultFileRemovedEventHandler'
|
||||||
|
import { SharedVaultFileMovedEventHandler } from '../Domain/Handler/SharedVaultFileMovedEventHandler'
|
||||||
|
import { TransitionStatusRepositoryInterface } from '../Domain/Transition/TransitionStatusRepositoryInterface'
|
||||||
|
import { RedisTransitionStatusRepository } from '../Infra/Redis/RedisTransitionStatusRepository'
|
||||||
|
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'
|
||||||
|
|
||||||
export class ContainerConfigLoader {
|
export class ContainerConfigLoader {
|
||||||
async load(configuration?: {
|
async load(configuration?: {
|
||||||
@@ -556,6 +567,9 @@ export class ContainerConfigLoader {
|
|||||||
container
|
container
|
||||||
.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(',') : [])
|
||||||
|
container
|
||||||
|
.bind(TYPES.Auth_TRANSITION_MODE_ENABLED)
|
||||||
|
.toConstantValue(env.get('TRANSITION_MODE_ENABLED', true) === 'true')
|
||||||
|
|
||||||
if (isConfiguredForInMemoryCache) {
|
if (isConfiguredForInMemoryCache) {
|
||||||
container
|
container
|
||||||
@@ -602,6 +616,9 @@ export class ContainerConfigLoader {
|
|||||||
container.get(TYPES.Auth_Timer),
|
container.get(TYPES.Auth_Timer),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
container
|
||||||
|
.bind<TransitionStatusRepositoryInterface>(TYPES.Auth_TransitionStatusRepository)
|
||||||
|
.toConstantValue(new InMemoryTransitionStatusRepository())
|
||||||
} else {
|
} else {
|
||||||
container.bind<PKCERepositoryInterface>(TYPES.Auth_PKCERepository).to(RedisPKCERepository)
|
container.bind<PKCERepositoryInterface>(TYPES.Auth_PKCERepository).to(RedisPKCERepository)
|
||||||
container.bind<LockRepositoryInterface>(TYPES.Auth_LockRepository).to(LockRepository)
|
container.bind<LockRepositoryInterface>(TYPES.Auth_LockRepository).to(LockRepository)
|
||||||
@@ -614,6 +631,9 @@ export class ContainerConfigLoader {
|
|||||||
container
|
container
|
||||||
.bind<SubscriptionTokenRepositoryInterface>(TYPES.Auth_SubscriptionTokenRepository)
|
.bind<SubscriptionTokenRepositoryInterface>(TYPES.Auth_SubscriptionTokenRepository)
|
||||||
.to(RedisSubscriptionTokenRepository)
|
.to(RedisSubscriptionTokenRepository)
|
||||||
|
container
|
||||||
|
.bind<TransitionStatusRepositoryInterface>(TYPES.Auth_TransitionStatusRepository)
|
||||||
|
.toConstantValue(new RedisTransitionStatusRepository(container.get<Redis>(TYPES.Auth_Redis)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Services
|
// Services
|
||||||
@@ -826,9 +846,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)
|
||||||
@@ -883,6 +901,31 @@ 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),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
container
|
||||||
|
.bind<UpdateTransitionStatus>(TYPES.Auth_UpdateTransitionStatus)
|
||||||
|
.toConstantValue(
|
||||||
|
new UpdateTransitionStatus(
|
||||||
|
container.get<TransitionStatusRepositoryInterface>(TYPES.Auth_TransitionStatusRepository),
|
||||||
|
container.get<RoleServiceInterface>(TYPES.Auth_RoleService),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
container
|
||||||
|
.bind<GetTransitionStatus>(TYPES.Auth_GetTransitionStatus)
|
||||||
|
.toConstantValue(
|
||||||
|
new GetTransitionStatus(
|
||||||
|
container.get<TransitionStatusRepositoryInterface>(TYPES.Auth_TransitionStatusRepository),
|
||||||
|
container.get<UserRepositoryInterface>(TYPES.Auth_UserRepository),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
// Controller
|
// Controller
|
||||||
container
|
container
|
||||||
@@ -952,8 +995,46 @@ 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<SharedVaultFileMovedEventHandler>(TYPES.Auth_SharedVaultFileMovedEventHandler)
|
||||||
|
.toConstantValue(
|
||||||
|
new SharedVaultFileMovedEventHandler(
|
||||||
|
container.get(TYPES.Auth_UpdateStorageQuotaUsedForUser),
|
||||||
|
container.get(TYPES.Auth_Logger),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
container
|
||||||
|
.bind<FileRemovedEventHandler>(TYPES.Auth_FileRemovedEventHandler)
|
||||||
|
.toConstantValue(
|
||||||
|
new FileRemovedEventHandler(
|
||||||
|
container.get(TYPES.Auth_UpdateStorageQuotaUsedForUser),
|
||||||
|
container.get(TYPES.Auth_Logger),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
container
|
||||||
|
.bind<SharedVaultFileRemovedEventHandler>(TYPES.Auth_SharedVaultFileRemovedEventHandler)
|
||||||
|
.toConstantValue(
|
||||||
|
new SharedVaultFileRemovedEventHandler(
|
||||||
|
container.get(TYPES.Auth_UpdateStorageQuotaUsedForUser),
|
||||||
|
container.get(TYPES.Auth_Logger),
|
||||||
|
),
|
||||||
|
)
|
||||||
container
|
container
|
||||||
.bind<ListedAccountCreatedEventHandler>(TYPES.Auth_ListedAccountCreatedEventHandler)
|
.bind<ListedAccountCreatedEventHandler>(TYPES.Auth_ListedAccountCreatedEventHandler)
|
||||||
.to(ListedAccountCreatedEventHandler)
|
.to(ListedAccountCreatedEventHandler)
|
||||||
@@ -978,6 +1059,22 @@ 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),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
container
|
||||||
|
.bind<TransitionStatusUpdatedEventHandler>(TYPES.Auth_TransitionStatusUpdatedEventHandler)
|
||||||
|
.toConstantValue(
|
||||||
|
new TransitionStatusUpdatedEventHandler(
|
||||||
|
container.get<UpdateTransitionStatus>(TYPES.Auth_UpdateTransitionStatus),
|
||||||
|
container.get<winston.Logger>(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)],
|
||||||
@@ -992,7 +1089,10 @@ 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)],
|
||||||
|
['SHARED_VAULT_FILE_MOVED', container.get(TYPES.Auth_SharedVaultFileMovedEventHandler)],
|
||||||
['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)],
|
||||||
[
|
[
|
||||||
@@ -1005,6 +1105,8 @@ 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)],
|
||||||
|
['TRANSITION_STATUS_UPDATED', container.get(TYPES.Auth_TransitionStatusUpdatedEventHandler)],
|
||||||
])
|
])
|
||||||
|
|
||||||
if (isConfiguredForHomeServer) {
|
if (isConfiguredForHomeServer) {
|
||||||
@@ -1037,9 +1139,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),
|
||||||
@@ -1054,42 +1156,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),
|
||||||
@@ -1098,31 +1200,32 @@ 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<UpdateUser>(TYPES.Auth_UpdateUser),
|
||||||
container.get(TYPES.Auth_GetUserKeyParams),
|
container.get<GetUserKeyParams>(TYPES.Auth_GetUserKeyParams),
|
||||||
container.get(TYPES.Auth_DeleteAccount),
|
container.get<DeleteAccount>(TYPES.Auth_DeleteAccount),
|
||||||
container.get(TYPES.Auth_GetUserSubscription),
|
container.get<GetUserSubscription>(TYPES.Auth_GetUserSubscription),
|
||||||
container.get(TYPES.Auth_ClearLoginAttempts),
|
container.get<ClearLoginAttempts>(TYPES.Auth_ClearLoginAttempts),
|
||||||
container.get(TYPES.Auth_IncreaseLoginAttempts),
|
container.get<IncreaseLoginAttempts>(TYPES.Auth_IncreaseLoginAttempts),
|
||||||
container.get(TYPES.Auth_ChangeCredentials),
|
container.get<ChangeCredentials>(TYPES.Auth_ChangeCredentials),
|
||||||
container.get(TYPES.Auth_ControllerContainer),
|
container.get<GetTransitionStatus>(TYPES.Auth_GetTransitionStatus),
|
||||||
|
container.get<ControllerContainerInterface>(TYPES.Auth_ControllerContainer),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
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),
|
||||||
@@ -1131,9 +1234,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),
|
||||||
@@ -1145,17 +1248,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),
|
||||||
@@ -1164,19 +1267,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),
|
||||||
@@ -1188,17 +1291,17 @@ 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),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -114,6 +114,8 @@ export class AppDataSource {
|
|||||||
...commonDataSourceOptions,
|
...commonDataSourceOptions,
|
||||||
type: 'sqlite',
|
type: 'sqlite',
|
||||||
database: this.env.get('DB_SQLITE_DATABASE_PATH'),
|
database: this.env.get('DB_SQLITE_DATABASE_PATH'),
|
||||||
|
enableWAL: true,
|
||||||
|
busyErrorRetry: 2000,
|
||||||
}
|
}
|
||||||
|
|
||||||
this._dataSource = new DataSource(sqliteDataSourceOptions)
|
this._dataSource = new DataSource(sqliteDataSourceOptions)
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ export class Service implements AuthServiceInterface {
|
|||||||
async activatePremiumFeatures(dto: {
|
async activatePremiumFeatures(dto: {
|
||||||
username: string
|
username: string
|
||||||
subscriptionPlanName?: string
|
subscriptionPlanName?: string
|
||||||
|
uploadBytesLimit?: number
|
||||||
endsAt?: Date
|
endsAt?: Date
|
||||||
}): Promise<Result<string>> {
|
}): Promise<Result<string>> {
|
||||||
if (!this.container) {
|
if (!this.container) {
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ const TYPES = {
|
|||||||
Auth_AuthenticatorRepository: Symbol.for('Auth_AuthenticatorRepository'),
|
Auth_AuthenticatorRepository: Symbol.for('Auth_AuthenticatorRepository'),
|
||||||
Auth_AuthenticatorChallengeRepository: Symbol.for('Auth_AuthenticatorChallengeRepository'),
|
Auth_AuthenticatorChallengeRepository: Symbol.for('Auth_AuthenticatorChallengeRepository'),
|
||||||
Auth_CacheEntryRepository: Symbol.for('Auth_CacheEntryRepository'),
|
Auth_CacheEntryRepository: Symbol.for('Auth_CacheEntryRepository'),
|
||||||
|
Auth_TransitionStatusRepository: Symbol.for('Auth_TransitionStatusRepository'),
|
||||||
// ORM
|
// ORM
|
||||||
Auth_ORMOfflineSettingRepository: Symbol.for('Auth_ORMOfflineSettingRepository'),
|
Auth_ORMOfflineSettingRepository: Symbol.for('Auth_ORMOfflineSettingRepository'),
|
||||||
Auth_ORMOfflineUserSubscriptionRepository: Symbol.for('Auth_ORMOfflineUserSubscriptionRepository'),
|
Auth_ORMOfflineUserSubscriptionRepository: Symbol.for('Auth_ORMOfflineUserSubscriptionRepository'),
|
||||||
@@ -101,6 +102,7 @@ const TYPES = {
|
|||||||
Auth_U2F_EXPECTED_ORIGIN: Symbol.for('Auth_U2F_EXPECTED_ORIGIN'),
|
Auth_U2F_EXPECTED_ORIGIN: Symbol.for('Auth_U2F_EXPECTED_ORIGIN'),
|
||||||
Auth_U2F_REQUIRE_USER_VERIFICATION: Symbol.for('Auth_U2F_REQUIRE_USER_VERIFICATION'),
|
Auth_U2F_REQUIRE_USER_VERIFICATION: Symbol.for('Auth_U2F_REQUIRE_USER_VERIFICATION'),
|
||||||
Auth_READONLY_USERS: Symbol.for('Auth_READONLY_USERS'),
|
Auth_READONLY_USERS: Symbol.for('Auth_READONLY_USERS'),
|
||||||
|
Auth_TRANSITION_MODE_ENABLED: Symbol.for('Auth_TRANSITION_MODE_ENABLED'),
|
||||||
// use cases
|
// use cases
|
||||||
Auth_AuthenticateUser: Symbol.for('Auth_AuthenticateUser'),
|
Auth_AuthenticateUser: Symbol.for('Auth_AuthenticateUser'),
|
||||||
Auth_AuthenticateRequest: Symbol.for('Auth_AuthenticateRequest'),
|
Auth_AuthenticateRequest: Symbol.for('Auth_AuthenticateRequest'),
|
||||||
@@ -113,7 +115,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'),
|
||||||
@@ -152,6 +154,9 @@ const TYPES = {
|
|||||||
Auth_ActivatePremiumFeatures: Symbol.for('Auth_ActivatePremiumFeatures'),
|
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'),
|
||||||
|
Auth_UpdateTransitionStatus: Symbol.for('Auth_UpdateTransitionStatus'),
|
||||||
|
Auth_GetTransitionStatus: Symbol.for('Auth_GetTransitionStatus'),
|
||||||
// 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'),
|
||||||
@@ -165,7 +170,10 @@ 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_SharedVaultFileMovedEventHandler: Symbol.for('Auth_SharedVaultFileMovedEventHandler'),
|
||||||
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(
|
||||||
@@ -176,6 +184,8 @@ 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'),
|
||||||
|
Auth_TransitionStatusUpdatedEventHandler: Symbol.for('Auth_TransitionStatusUpdatedEventHandler'),
|
||||||
// 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'),
|
||||||
@@ -217,22 +227,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
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
@@ -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,21 +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 SimpleUserProjection,
|
key_params: this.keyParamsFactory.create(dto.user, true),
|
||||||
|
user: this.userProjector.projectSimple(dto.user) as SimpleUserProjection,
|
||||||
|
},
|
||||||
|
session: sessionCreationResult.session,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,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(
|
||||||
@@ -79,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 }>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,9 @@ describe('AuthenticationMethodResolver', () => {
|
|||||||
|
|
||||||
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>
|
||||||
|
|
||||||
@@ -38,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)
|
||||||
|
|
||||||
@@ -50,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,
|
||||||
@@ -71,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)
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ 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 { Logger } from 'winston'
|
||||||
|
import { Uuid } from '@standardnotes/domain-core'
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class AuthenticationMethodResolver implements AuthenticationMethodResolverInterface {
|
export class AuthenticationMethodResolver implements AuthenticationMethodResolverInterface {
|
||||||
@@ -29,20 +30,32 @@ export class AuthenticationMethodResolver implements AuthenticationMethodResolve
|
|||||||
if (decodedToken) {
|
if (decodedToken) {
|
||||||
this.logger.debug('Token decoded successfully. User found.')
|
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.')
|
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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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> {
|
||||||
|
|||||||
@@ -1,150 +0,0 @@
|
|||||||
import 'reflect-metadata'
|
|
||||||
|
|
||||||
import { FileRemovedEvent } from '@standardnotes/domain-events'
|
|
||||||
import { Logger } from 'winston'
|
|
||||||
|
|
||||||
import { User } from '../User/User'
|
|
||||||
import { FileRemovedEventHandler } from './FileRemovedEventHandler'
|
|
||||||
import { SubscriptionSettingServiceInterface } from '../Setting/SubscriptionSettingServiceInterface'
|
|
||||||
import { UserSubscription } from '../Subscription/UserSubscription'
|
|
||||||
import { UserSubscriptionType } from '../Subscription/UserSubscriptionType'
|
|
||||||
import { UserSubscriptionServiceInterface } from '../Subscription/UserSubscriptionServiceInterface'
|
|
||||||
|
|
||||||
describe('FileRemovedEventHandler', () => {
|
|
||||||
let userSubscriptionService: UserSubscriptionServiceInterface
|
|
||||||
let logger: Logger
|
|
||||||
let regularUser: User
|
|
||||||
let sharedUser: User
|
|
||||||
let event: FileRemovedEvent
|
|
||||||
let subscriptionSettingService: SubscriptionSettingServiceInterface
|
|
||||||
let regularSubscription: UserSubscription
|
|
||||||
let sharedSubscription: UserSubscription
|
|
||||||
|
|
||||||
const createHandler = () => new FileRemovedEventHandler(userSubscriptionService, subscriptionSettingService, logger)
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
regularUser = {
|
|
||||||
uuid: '123',
|
|
||||||
} as jest.Mocked<User>
|
|
||||||
|
|
||||||
sharedUser = {
|
|
||||||
uuid: '234',
|
|
||||||
} as jest.Mocked<User>
|
|
||||||
|
|
||||||
regularSubscription = {
|
|
||||||
uuid: '1-2-3',
|
|
||||||
subscriptionType: UserSubscriptionType.Regular,
|
|
||||||
user: Promise.resolve(regularUser),
|
|
||||||
} as jest.Mocked<UserSubscription>
|
|
||||||
|
|
||||||
sharedSubscription = {
|
|
||||||
uuid: '2-3-4',
|
|
||||||
subscriptionType: UserSubscriptionType.Shared,
|
|
||||||
user: Promise.resolve(sharedUser),
|
|
||||||
} as jest.Mocked<UserSubscription>
|
|
||||||
|
|
||||||
userSubscriptionService = {} as jest.Mocked<UserSubscriptionServiceInterface>
|
|
||||||
userSubscriptionService.findRegularSubscriptionForUserUuid = jest
|
|
||||||
.fn()
|
|
||||||
.mockReturnValue({ regularSubscription, sharedSubscription: null })
|
|
||||||
|
|
||||||
subscriptionSettingService = {} as jest.Mocked<SubscriptionSettingServiceInterface>
|
|
||||||
subscriptionSettingService.findSubscriptionSettingWithDecryptedValue = jest.fn().mockReturnValue(null)
|
|
||||||
subscriptionSettingService.createOrReplace = jest.fn()
|
|
||||||
|
|
||||||
event = {} as jest.Mocked<FileRemovedEvent>
|
|
||||||
event.createdAt = new Date(1)
|
|
||||||
event.payload = {
|
|
||||||
userUuid: '1-2-3',
|
|
||||||
fileByteSize: 123,
|
|
||||||
filePath: '1-2-3/2-3-4',
|
|
||||||
fileName: '2-3-4',
|
|
||||||
regularSubscriptionUuid: '4-5-6',
|
|
||||||
}
|
|
||||||
|
|
||||||
logger = {} as jest.Mocked<Logger>
|
|
||||||
logger.warn = jest.fn()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should do nothing a bytes used setting does not exist', async () => {
|
|
||||||
await createHandler().handle(event)
|
|
||||||
|
|
||||||
expect(subscriptionSettingService.createOrReplace).not.toHaveBeenCalled()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should not do anything if a user subscription is not found', async () => {
|
|
||||||
subscriptionSettingService.findSubscriptionSettingWithDecryptedValue = jest.fn().mockReturnValue({
|
|
||||||
value: 345,
|
|
||||||
})
|
|
||||||
userSubscriptionService.findRegularSubscriptionForUserUuid = jest
|
|
||||||
.fn()
|
|
||||||
.mockReturnValue({ regularSubscription: null, sharedSubscription: null })
|
|
||||||
|
|
||||||
await createHandler().handle(event)
|
|
||||||
|
|
||||||
expect(subscriptionSettingService.createOrReplace).not.toHaveBeenCalled()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should update a bytes used setting', async () => {
|
|
||||||
subscriptionSettingService.findSubscriptionSettingWithDecryptedValue = jest.fn().mockReturnValue({
|
|
||||||
value: 345,
|
|
||||||
})
|
|
||||||
await createHandler().handle(event)
|
|
||||||
|
|
||||||
expect(subscriptionSettingService.createOrReplace).toHaveBeenCalledWith({
|
|
||||||
props: {
|
|
||||||
name: 'FILE_UPLOAD_BYTES_USED',
|
|
||||||
sensitive: false,
|
|
||||||
unencryptedValue: '222',
|
|
||||||
serverEncryptionVersion: 0,
|
|
||||||
},
|
|
||||||
user: regularUser,
|
|
||||||
userSubscription: {
|
|
||||||
uuid: '1-2-3',
|
|
||||||
subscriptionType: 'regular',
|
|
||||||
user: Promise.resolve(regularUser),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should update a bytes used setting on both shared and regular subscription', async () => {
|
|
||||||
userSubscriptionService.findRegularSubscriptionForUserUuid = jest
|
|
||||||
.fn()
|
|
||||||
.mockReturnValue({ regularSubscription, sharedSubscription })
|
|
||||||
|
|
||||||
subscriptionSettingService.findSubscriptionSettingWithDecryptedValue = jest.fn().mockReturnValue({
|
|
||||||
value: 345,
|
|
||||||
})
|
|
||||||
await createHandler().handle(event)
|
|
||||||
|
|
||||||
expect(subscriptionSettingService.createOrReplace).toHaveBeenNthCalledWith(1, {
|
|
||||||
props: {
|
|
||||||
name: 'FILE_UPLOAD_BYTES_USED',
|
|
||||||
sensitive: false,
|
|
||||||
unencryptedValue: '222',
|
|
||||||
serverEncryptionVersion: 0,
|
|
||||||
},
|
|
||||||
user: regularUser,
|
|
||||||
userSubscription: {
|
|
||||||
uuid: '1-2-3',
|
|
||||||
subscriptionType: 'regular',
|
|
||||||
user: Promise.resolve(regularUser),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
expect(subscriptionSettingService.createOrReplace).toHaveBeenNthCalledWith(2, {
|
|
||||||
props: {
|
|
||||||
name: 'FILE_UPLOAD_BYTES_USED',
|
|
||||||
sensitive: false,
|
|
||||||
unencryptedValue: '222',
|
|
||||||
serverEncryptionVersion: 0,
|
|
||||||
},
|
|
||||||
user: sharedUser,
|
|
||||||
userSubscription: {
|
|
||||||
uuid: '2-3-4',
|
|
||||||
subscriptionType: 'shared',
|
|
||||||
user: Promise.resolve(sharedUser),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,63 +1,19 @@
|
|||||||
import { DomainEventHandlerInterface, FileRemovedEvent } from '@standardnotes/domain-events'
|
import { DomainEventHandlerInterface, FileRemovedEvent } from '@standardnotes/domain-events'
|
||||||
import { SettingName } from '@standardnotes/settings'
|
|
||||||
import { inject, injectable } from 'inversify'
|
|
||||||
import { Logger } from 'winston'
|
import { Logger } from 'winston'
|
||||||
|
|
||||||
import TYPES from '../../Bootstrap/Types'
|
import { UpdateStorageQuotaUsedForUser } from '../UseCase/UpdateStorageQuotaUsedForUser/UpdateStorageQuotaUsedForUser'
|
||||||
import { EncryptionVersion } from '../Encryption/EncryptionVersion'
|
|
||||||
import { SubscriptionSettingServiceInterface } from '../Setting/SubscriptionSettingServiceInterface'
|
|
||||||
import { UserSubscription } from '../Subscription/UserSubscription'
|
|
||||||
import { UserSubscriptionServiceInterface } from '../Subscription/UserSubscriptionServiceInterface'
|
|
||||||
|
|
||||||
@injectable()
|
|
||||||
export class FileRemovedEventHandler implements DomainEventHandlerInterface {
|
export class FileRemovedEventHandler implements DomainEventHandlerInterface {
|
||||||
constructor(
|
constructor(private updateStorageQuotaUsedForUserUseCase: UpdateStorageQuotaUsedForUser, private logger: Logger) {}
|
||||||
@inject(TYPES.Auth_UserSubscriptionService) private userSubscriptionService: UserSubscriptionServiceInterface,
|
|
||||||
@inject(TYPES.Auth_SubscriptionSettingService)
|
|
||||||
private subscriptionSettingService: SubscriptionSettingServiceInterface,
|
|
||||||
@inject(TYPES.Auth_Logger) private logger: Logger,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
async handle(event: FileRemovedEvent): Promise<void> {
|
async handle(event: FileRemovedEvent): Promise<void> {
|
||||||
const { regularSubscription, sharedSubscription } =
|
const result = await this.updateStorageQuotaUsedForUserUseCase.execute({
|
||||||
await this.userSubscriptionService.findRegularSubscriptionForUserUuid(event.payload.userUuid)
|
userUuid: event.payload.userUuid,
|
||||||
if (regularSubscription === null) {
|
bytesUsed: -event.payload.fileByteSize,
|
||||||
this.logger.warn(`Could not find regular user subscription for user with uuid: ${event.payload.userUuid}`)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.updateUploadBytesUsedSetting(regularSubscription, event.payload.fileByteSize)
|
|
||||||
|
|
||||||
if (sharedSubscription !== null) {
|
|
||||||
await this.updateUploadBytesUsedSetting(sharedSubscription, event.payload.fileByteSize)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async updateUploadBytesUsedSetting(subscription: UserSubscription, byteSize: number): Promise<void> {
|
|
||||||
const user = await subscription.user
|
|
||||||
const bytesUsedSetting = await this.subscriptionSettingService.findSubscriptionSettingWithDecryptedValue({
|
|
||||||
userUuid: user.uuid,
|
|
||||||
userSubscriptionUuid: subscription.uuid,
|
|
||||||
subscriptionSettingName: SettingName.create(SettingName.NAMES.FileUploadBytesUsed).getValue(),
|
|
||||||
})
|
})
|
||||||
if (bytesUsedSetting === null) {
|
|
||||||
this.logger.warn(`Could not find bytes used setting for user with uuid: ${user.uuid}`)
|
|
||||||
|
|
||||||
return
|
if (result.isFailed()) {
|
||||||
|
this.logger.error(`Failed to update storage quota used for user: ${result.getError()}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const bytesUsed = bytesUsedSetting.value as string
|
|
||||||
|
|
||||||
await this.subscriptionSettingService.createOrReplace({
|
|
||||||
userSubscription: subscription,
|
|
||||||
user,
|
|
||||||
props: {
|
|
||||||
name: SettingName.NAMES.FileUploadBytesUsed,
|
|
||||||
unencryptedValue: (+bytesUsed - byteSize).toString(),
|
|
||||||
sensitive: false,
|
|
||||||
serverEncryptionVersion: EncryptionVersion.Unencrypted,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,73 +1,19 @@
|
|||||||
import { DomainEventHandlerInterface, FileUploadedEvent } from '@standardnotes/domain-events'
|
import { DomainEventHandlerInterface, FileUploadedEvent } from '@standardnotes/domain-events'
|
||||||
import { SettingName } from '@standardnotes/settings'
|
|
||||||
import { inject, injectable } from 'inversify'
|
|
||||||
import { Logger } from 'winston'
|
import { Logger } from 'winston'
|
||||||
|
|
||||||
import TYPES from '../../Bootstrap/Types'
|
import { UpdateStorageQuotaUsedForUser } from '../UseCase/UpdateStorageQuotaUsedForUser/UpdateStorageQuotaUsedForUser'
|
||||||
import { EncryptionVersion } from '../Encryption/EncryptionVersion'
|
|
||||||
import { SubscriptionSettingServiceInterface } from '../Setting/SubscriptionSettingServiceInterface'
|
|
||||||
import { UserSubscription } from '../Subscription/UserSubscription'
|
|
||||||
import { UserSubscriptionServiceInterface } from '../Subscription/UserSubscriptionServiceInterface'
|
|
||||||
import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
|
|
||||||
import { User } from '../User/User'
|
|
||||||
|
|
||||||
@injectable()
|
|
||||||
export class FileUploadedEventHandler implements DomainEventHandlerInterface {
|
export class FileUploadedEventHandler implements DomainEventHandlerInterface {
|
||||||
constructor(
|
constructor(private updateStorageQuotaUsedForUserUseCase: UpdateStorageQuotaUsedForUser, private logger: Logger) {}
|
||||||
@inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface,
|
|
||||||
@inject(TYPES.Auth_UserSubscriptionService) private userSubscriptionService: UserSubscriptionServiceInterface,
|
|
||||||
@inject(TYPES.Auth_SubscriptionSettingService)
|
|
||||||
private subscriptionSettingService: SubscriptionSettingServiceInterface,
|
|
||||||
@inject(TYPES.Auth_Logger) private logger: Logger,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
async handle(event: FileUploadedEvent): Promise<void> {
|
async handle(event: FileUploadedEvent): Promise<void> {
|
||||||
const user = await this.userRepository.findOneByUuid(event.payload.userUuid)
|
const result = await this.updateStorageQuotaUsedForUserUseCase.execute({
|
||||||
if (user === null) {
|
userUuid: event.payload.userUuid,
|
||||||
this.logger.warn(`Could not find user with uuid: ${event.payload.userUuid}`)
|
bytesUsed: event.payload.fileByteSize,
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const { regularSubscription, sharedSubscription } =
|
|
||||||
await this.userSubscriptionService.findRegularSubscriptionForUserUuid(event.payload.userUuid)
|
|
||||||
if (regularSubscription === null) {
|
|
||||||
this.logger.warn(`Could not find regular user subscription for user with uuid: ${event.payload.userUuid}`)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.updateUploadBytesUsedSetting(regularSubscription, user, event.payload.fileByteSize)
|
|
||||||
|
|
||||||
if (sharedSubscription !== null) {
|
|
||||||
await this.updateUploadBytesUsedSetting(sharedSubscription, user, event.payload.fileByteSize)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async updateUploadBytesUsedSetting(
|
|
||||||
subscription: UserSubscription,
|
|
||||||
user: User,
|
|
||||||
byteSize: number,
|
|
||||||
): Promise<void> {
|
|
||||||
let bytesUsed = '0'
|
|
||||||
const bytesUsedSetting = await this.subscriptionSettingService.findSubscriptionSettingWithDecryptedValue({
|
|
||||||
userUuid: (await subscription.user).uuid,
|
|
||||||
userSubscriptionUuid: subscription.uuid,
|
|
||||||
subscriptionSettingName: SettingName.create(SettingName.NAMES.FileUploadBytesUsed).getValue(),
|
|
||||||
})
|
})
|
||||||
if (bytesUsedSetting !== null) {
|
|
||||||
bytesUsed = bytesUsedSetting.value as string
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.subscriptionSettingService.createOrReplace({
|
if (result.isFailed()) {
|
||||||
userSubscription: subscription,
|
this.logger.error(`Failed to update storage quota used for user: ${result.getError()}`)
|
||||||
user,
|
}
|
||||||
props: {
|
|
||||||
name: SettingName.NAMES.FileUploadBytesUsed,
|
|
||||||
unencryptedValue: (+bytesUsed + byteSize).toString(),
|
|
||||||
sensitive: false,
|
|
||||||
serverEncryptionVersion: EncryptionVersion.Unencrypted,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import { Logger } from 'winston'
|
||||||
|
import { Result } from '@standardnotes/domain-core'
|
||||||
|
import { PaymentsAccountDeletedEvent } from '@standardnotes/domain-events'
|
||||||
|
|
||||||
|
import { DeleteAccount } from '../UseCase/DeleteAccount/DeleteAccount'
|
||||||
|
import { PaymentsAccountDeletedEventHandler } from './PaymentsAccountDeletedEventHandler'
|
||||||
|
|
||||||
|
describe('PaymentsAccountDeletedEventHandler', () => {
|
||||||
|
let deleteAccountUseCase: DeleteAccount
|
||||||
|
let logger: Logger
|
||||||
|
let event: PaymentsAccountDeletedEvent
|
||||||
|
|
||||||
|
const createHandler = () => new PaymentsAccountDeletedEventHandler(deleteAccountUseCase, logger)
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
deleteAccountUseCase = {} as jest.Mocked<DeleteAccount>
|
||||||
|
deleteAccountUseCase.execute = jest.fn().mockResolvedValue(Result.ok('success'))
|
||||||
|
|
||||||
|
logger = {} as jest.Mocked<Logger>
|
||||||
|
logger.error = jest.fn()
|
||||||
|
|
||||||
|
event = {
|
||||||
|
payload: {
|
||||||
|
username: 'username',
|
||||||
|
},
|
||||||
|
} as jest.Mocked<PaymentsAccountDeletedEvent>
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should delete account', async () => {
|
||||||
|
const handler = createHandler()
|
||||||
|
|
||||||
|
await handler.handle(event)
|
||||||
|
|
||||||
|
expect(deleteAccountUseCase.execute).toHaveBeenCalledWith({
|
||||||
|
username: 'username',
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should log error if delete account fails', async () => {
|
||||||
|
const handler = createHandler()
|
||||||
|
|
||||||
|
deleteAccountUseCase.execute = jest.fn().mockResolvedValue(Result.fail('error'))
|
||||||
|
|
||||||
|
await handler.handle(event)
|
||||||
|
|
||||||
|
expect(logger.error).toHaveBeenCalledWith('Failed to delete account for user username: error')
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { DomainEventHandlerInterface, PaymentsAccountDeletedEvent } from '@standardnotes/domain-events'
|
||||||
|
import { Logger } from 'winston'
|
||||||
|
|
||||||
|
import { DeleteAccount } from '../UseCase/DeleteAccount/DeleteAccount'
|
||||||
|
|
||||||
|
export class PaymentsAccountDeletedEventHandler implements DomainEventHandlerInterface {
|
||||||
|
constructor(private deleteAccountUseCase: DeleteAccount, private logger: Logger) {}
|
||||||
|
|
||||||
|
async handle(event: PaymentsAccountDeletedEvent): Promise<void> {
|
||||||
|
const result = await this.deleteAccountUseCase.execute({
|
||||||
|
username: event.payload.username,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (result.isFailed()) {
|
||||||
|
this.logger.error(`Failed to delete account for user ${event.payload.username}: ${result.getError()}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { DomainEventHandlerInterface, SharedVaultFileMovedEvent } from '@standardnotes/domain-events'
|
||||||
|
import { Logger } from 'winston'
|
||||||
|
|
||||||
|
import { UpdateStorageQuotaUsedForUser } from '../UseCase/UpdateStorageQuotaUsedForUser/UpdateStorageQuotaUsedForUser'
|
||||||
|
|
||||||
|
export class SharedVaultFileMovedEventHandler implements DomainEventHandlerInterface {
|
||||||
|
constructor(private updateStorageQuotaUsedForUserUseCase: UpdateStorageQuotaUsedForUser, private logger: Logger) {}
|
||||||
|
|
||||||
|
async handle(event: SharedVaultFileMovedEvent): Promise<void> {
|
||||||
|
const subtractResult = await this.updateStorageQuotaUsedForUserUseCase.execute({
|
||||||
|
userUuid: event.payload.from.ownerUuid,
|
||||||
|
bytesUsed: -event.payload.fileByteSize,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (subtractResult.isFailed()) {
|
||||||
|
this.logger.error(`Failed to update storage quota used for user: ${subtractResult.getError()}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const addResult = await this.updateStorageQuotaUsedForUserUseCase.execute({
|
||||||
|
userUuid: event.payload.to.ownerUuid,
|
||||||
|
bytesUsed: event.payload.fileByteSize,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (addResult.isFailed()) {
|
||||||
|
this.logger.error(`Failed to update storage quota used for user: ${addResult.getError()}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { DomainEventHandlerInterface, SharedVaultFileRemovedEvent } from '@standardnotes/domain-events'
|
||||||
|
import { Logger } from 'winston'
|
||||||
|
|
||||||
|
import { UpdateStorageQuotaUsedForUser } from '../UseCase/UpdateStorageQuotaUsedForUser/UpdateStorageQuotaUsedForUser'
|
||||||
|
|
||||||
|
export class SharedVaultFileRemovedEventHandler implements DomainEventHandlerInterface {
|
||||||
|
constructor(private updateStorageQuotaUsedForUserUseCase: UpdateStorageQuotaUsedForUser, private logger: Logger) {}
|
||||||
|
|
||||||
|
async handle(event: SharedVaultFileRemovedEvent): Promise<void> {
|
||||||
|
const result = await this.updateStorageQuotaUsedForUserUseCase.execute({
|
||||||
|
userUuid: event.payload.vaultOwnerUuid,
|
||||||
|
bytesUsed: -event.payload.fileByteSize,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (result.isFailed()) {
|
||||||
|
this.logger.error(`Failed to update storage quota used for user: ${result.getError()}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { DomainEventHandlerInterface, SharedVaultFileUploadedEvent } from '@standardnotes/domain-events'
|
||||||
|
import { Logger } from 'winston'
|
||||||
|
|
||||||
|
import { UpdateStorageQuotaUsedForUser } from '../UseCase/UpdateStorageQuotaUsedForUser/UpdateStorageQuotaUsedForUser'
|
||||||
|
|
||||||
|
export class SharedVaultFileUploadedEventHandler implements DomainEventHandlerInterface {
|
||||||
|
constructor(private updateStorageQuotaUsedForUserUseCase: UpdateStorageQuotaUsedForUser, private logger: Logger) {}
|
||||||
|
|
||||||
|
async handle(event: SharedVaultFileUploadedEvent): Promise<void> {
|
||||||
|
const result = await this.updateStorageQuotaUsedForUserUseCase.execute({
|
||||||
|
userUuid: event.payload.vaultOwnerUuid,
|
||||||
|
bytesUsed: event.payload.fileByteSize,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (result.isFailed()) {
|
||||||
|
this.logger.error(`Failed to update storage quota used for user: ${result.getError()}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -60,7 +60,7 @@ describe('SubscriptionExpiredEventHandler', () => {
|
|||||||
offlineUserSubscriptionRepository.updateEndsAt = jest.fn()
|
offlineUserSubscriptionRepository.updateEndsAt = jest.fn()
|
||||||
|
|
||||||
roleService = {} as jest.Mocked<RoleServiceInterface>
|
roleService = {} as jest.Mocked<RoleServiceInterface>
|
||||||
roleService.removeUserRole = jest.fn()
|
roleService.removeUserRoleBasedOnSubscription = jest.fn()
|
||||||
|
|
||||||
timestamp = dayjs.utc().valueOf()
|
timestamp = dayjs.utc().valueOf()
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ describe('SubscriptionExpiredEventHandler', () => {
|
|||||||
it('should update the user role', async () => {
|
it('should update the user role', async () => {
|
||||||
await createHandler().handle(event)
|
await createHandler().handle(event)
|
||||||
|
|
||||||
expect(roleService.removeUserRole).toHaveBeenCalledWith(user, SubscriptionName.PlusPlan)
|
expect(roleService.removeUserRoleBasedOnSubscription).toHaveBeenCalledWith(user, SubscriptionName.PlusPlan)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should update subscription ends at', async () => {
|
it('should update subscription ends at', async () => {
|
||||||
@@ -108,7 +108,7 @@ describe('SubscriptionExpiredEventHandler', () => {
|
|||||||
|
|
||||||
await createHandler().handle(event)
|
await createHandler().handle(event)
|
||||||
|
|
||||||
expect(roleService.removeUserRole).not.toHaveBeenCalled()
|
expect(roleService.removeUserRoleBasedOnSubscription).not.toHaveBeenCalled()
|
||||||
expect(userSubscriptionRepository.updateEndsAt).not.toHaveBeenCalled()
|
expect(userSubscriptionRepository.updateEndsAt).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ describe('SubscriptionExpiredEventHandler', () => {
|
|||||||
|
|
||||||
await createHandler().handle(event)
|
await createHandler().handle(event)
|
||||||
|
|
||||||
expect(roleService.removeUserRole).not.toHaveBeenCalled()
|
expect(roleService.removeUserRoleBasedOnSubscription).not.toHaveBeenCalled()
|
||||||
expect(userSubscriptionRepository.updateEndsAt).not.toHaveBeenCalled()
|
expect(userSubscriptionRepository.updateEndsAt).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export class SubscriptionExpiredEventHandler implements DomainEventHandlerInterf
|
|||||||
private async removeRoleFromSubscriptionUsers(subscriptionId: number, subscriptionName: string): Promise<void> {
|
private async removeRoleFromSubscriptionUsers(subscriptionId: number, subscriptionName: string): Promise<void> {
|
||||||
const userSubscriptions = await this.userSubscriptionRepository.findBySubscriptionId(subscriptionId)
|
const userSubscriptions = await this.userSubscriptionRepository.findBySubscriptionId(subscriptionId)
|
||||||
for (const userSubscription of userSubscriptions) {
|
for (const userSubscription of userSubscriptions) {
|
||||||
await this.roleService.removeUserRole(await userSubscription.user, subscriptionName)
|
await this.roleService.removeUserRoleBasedOnSubscription(await userSubscription.user, subscriptionName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ describe('SubscriptionPurchasedEventHandler', () => {
|
|||||||
offlineUserSubscriptionRepository.save = jest.fn().mockReturnValue(offlineUserSubscription)
|
offlineUserSubscriptionRepository.save = jest.fn().mockReturnValue(offlineUserSubscription)
|
||||||
|
|
||||||
roleService = {} as jest.Mocked<RoleServiceInterface>
|
roleService = {} as jest.Mocked<RoleServiceInterface>
|
||||||
roleService.addUserRole = jest.fn()
|
roleService.addUserRoleBasedOnSubscription = jest.fn()
|
||||||
roleService.setOfflineUserRole = jest.fn()
|
roleService.setOfflineUserRole = jest.fn()
|
||||||
|
|
||||||
subscriptionExpiresAt = timestamp + 365 * 1000
|
subscriptionExpiresAt = timestamp + 365 * 1000
|
||||||
@@ -106,7 +106,7 @@ describe('SubscriptionPurchasedEventHandler', () => {
|
|||||||
it('should update the user role', async () => {
|
it('should update the user role', async () => {
|
||||||
await createHandler().handle(event)
|
await createHandler().handle(event)
|
||||||
|
|
||||||
expect(roleService.addUserRole).toHaveBeenCalledWith(user, SubscriptionName.ProPlan)
|
expect(roleService.addUserRoleBasedOnSubscription).toHaveBeenCalledWith(user, SubscriptionName.ProPlan)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should update user default settings', async () => {
|
it('should update user default settings', async () => {
|
||||||
@@ -162,7 +162,7 @@ describe('SubscriptionPurchasedEventHandler', () => {
|
|||||||
|
|
||||||
await createHandler().handle(event)
|
await createHandler().handle(event)
|
||||||
|
|
||||||
expect(roleService.addUserRole).not.toHaveBeenCalled()
|
expect(roleService.addUserRoleBasedOnSubscription).not.toHaveBeenCalled()
|
||||||
expect(userSubscriptionRepository.save).not.toHaveBeenCalled()
|
expect(userSubscriptionRepository.save).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -171,7 +171,7 @@ describe('SubscriptionPurchasedEventHandler', () => {
|
|||||||
|
|
||||||
await createHandler().handle(event)
|
await createHandler().handle(event)
|
||||||
|
|
||||||
expect(roleService.addUserRole).not.toHaveBeenCalled()
|
expect(roleService.addUserRoleBasedOnSubscription).not.toHaveBeenCalled()
|
||||||
expect(userSubscriptionRepository.save).not.toHaveBeenCalled()
|
expect(userSubscriptionRepository.save).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ export class SubscriptionPurchasedEventHandler implements DomainEventHandlerInte
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async addUserRole(user: User, subscriptionName: string): Promise<void> {
|
private async addUserRole(user: User, subscriptionName: string): Promise<void> {
|
||||||
await this.roleService.addUserRole(user, subscriptionName)
|
await this.roleService.addUserRoleBasedOnSubscription(user, subscriptionName)
|
||||||
}
|
}
|
||||||
|
|
||||||
private async createSubscription(
|
private async createSubscription(
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ describe('SubscriptionReassignedEventHandler', () => {
|
|||||||
userSubscriptionRepository.save = jest.fn().mockReturnValue(subscription)
|
userSubscriptionRepository.save = jest.fn().mockReturnValue(subscription)
|
||||||
|
|
||||||
roleService = {} as jest.Mocked<RoleServiceInterface>
|
roleService = {} as jest.Mocked<RoleServiceInterface>
|
||||||
roleService.addUserRole = jest.fn()
|
roleService.addUserRoleBasedOnSubscription = jest.fn()
|
||||||
|
|
||||||
subscriptionExpiresAt = timestamp + 365 * 1000
|
subscriptionExpiresAt = timestamp + 365 * 1000
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ describe('SubscriptionReassignedEventHandler', () => {
|
|||||||
it('should update the user role', async () => {
|
it('should update the user role', async () => {
|
||||||
await createHandler().handle(event)
|
await createHandler().handle(event)
|
||||||
|
|
||||||
expect(roleService.addUserRole).toHaveBeenCalledWith(user, SubscriptionName.ProPlan)
|
expect(roleService.addUserRoleBasedOnSubscription).toHaveBeenCalledWith(user, SubscriptionName.ProPlan)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should create subscription', async () => {
|
it('should create subscription', async () => {
|
||||||
@@ -146,7 +146,7 @@ describe('SubscriptionReassignedEventHandler', () => {
|
|||||||
|
|
||||||
await createHandler().handle(event)
|
await createHandler().handle(event)
|
||||||
|
|
||||||
expect(roleService.addUserRole).not.toHaveBeenCalled()
|
expect(roleService.addUserRoleBasedOnSubscription).not.toHaveBeenCalled()
|
||||||
expect(userSubscriptionRepository.save).not.toHaveBeenCalled()
|
expect(userSubscriptionRepository.save).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -155,7 +155,7 @@ describe('SubscriptionReassignedEventHandler', () => {
|
|||||||
|
|
||||||
await createHandler().handle(event)
|
await createHandler().handle(event)
|
||||||
|
|
||||||
expect(roleService.addUserRole).not.toHaveBeenCalled()
|
expect(roleService.addUserRoleBasedOnSubscription).not.toHaveBeenCalled()
|
||||||
expect(userSubscriptionRepository.save).not.toHaveBeenCalled()
|
expect(userSubscriptionRepository.save).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ export class SubscriptionReassignedEventHandler implements DomainEventHandlerInt
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async addUserRole(user: User, subscriptionName: string): Promise<void> {
|
private async addUserRole(user: User, subscriptionName: string): Promise<void> {
|
||||||
await this.roleService.addUserRole(user, subscriptionName)
|
await this.roleService.addUserRoleBasedOnSubscription(user, subscriptionName)
|
||||||
}
|
}
|
||||||
|
|
||||||
private async createSubscription(
|
private async createSubscription(
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user