mirror of
https://github.com/standardnotes/server
synced 2026-01-27 17:01:07 -05:00
Compare commits
37 Commits
@standardn
...
@standardn
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9183b4c62 | ||
|
|
c7d575a0ff | ||
|
|
a575e62519 | ||
|
|
3761d60f41 | ||
|
|
fd629d43ba | ||
|
|
76b1cb0f5a | ||
|
|
2f94abc9f7 | ||
|
|
c70040fe5d | ||
|
|
4b8a9e448a | ||
|
|
1e4c7d0f31 | ||
|
|
ec75795a02 | ||
|
|
ad26b64b28 | ||
|
|
9e4715ebbd | ||
|
|
cc612296d0 | ||
|
|
1148b3948c | ||
|
|
c7e605fd60 | ||
|
|
4ab32c670e | ||
|
|
2d810568a8 | ||
|
|
b8353aa817 | ||
|
|
7924f63e28 | ||
|
|
b3b617ea0b | ||
|
|
18a5071618 | ||
|
|
fea58029b9 | ||
|
|
e748723209 | ||
|
|
8a47d81936 | ||
|
|
7ae9f5694d | ||
|
|
9031379469 | ||
|
|
dc71e6777f | ||
|
|
89eb798fa8 | ||
|
|
4304e068b9 | ||
|
|
126bc6de6a | ||
|
|
c2b9107f13 | ||
|
|
1471f4a839 | ||
|
|
b0b3c6671d | ||
|
|
6ddb8fb6c2 | ||
|
|
66da49b0df | ||
|
|
750cd26c36 |
@@ -15,6 +15,7 @@ DB_TYPE=mysql
|
||||
|
||||
REDIS_PORT=6379
|
||||
REDIS_HOST=cache
|
||||
CACHE_TYPE=redis
|
||||
|
||||
########
|
||||
# KEYS #
|
||||
|
||||
64
.github/workflows/common-e2e.yml
vendored
64
.github/workflows/common-e2e.yml
vendored
@@ -19,15 +19,7 @@ on:
|
||||
|
||||
jobs:
|
||||
e2e:
|
||||
strategy:
|
||||
matrix:
|
||||
database: [ "mysql", "sqlite" ]
|
||||
include:
|
||||
- cache: "redis"
|
||||
database: "mysql"
|
||||
- cache: "memory"
|
||||
database: "sqlite"
|
||||
|
||||
name: (Docker) E2E Test Suite
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
services:
|
||||
@@ -48,11 +40,61 @@ jobs:
|
||||
- name: Run Server
|
||||
run: docker compose -f docker-compose.ci.yml up -d
|
||||
env:
|
||||
DB_TYPE: ${{ matrix.database }}
|
||||
CACHE_TYPE: ${{ matrix.cache }}
|
||||
DB_TYPE: mysql
|
||||
CACHE_TYPE: redis
|
||||
|
||||
- name: Wait for server to start
|
||||
run: docker/is-available.sh http://localhost:3123 $(pwd)/logs
|
||||
|
||||
- name: Run E2E Test Suite
|
||||
run: yarn dlx mocha-headless-chrome --timeout 1200000 -f http://localhost:9001/mocha/test.html
|
||||
|
||||
e2e-home-server:
|
||||
name: (Home Server) E2E Test Suite
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
services:
|
||||
snjs:
|
||||
image: standardnotes/snjs:${{ inputs.snjs_image_tag }}
|
||||
ports:
|
||||
- 9001:9001
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
node-version-file: '.nvmrc'
|
||||
|
||||
- name: Install Dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Build
|
||||
run: yarn build
|
||||
|
||||
- name: Copy dotenv file
|
||||
run: cp packages/home-server/.env.sample packages/home-server/.env
|
||||
|
||||
- name: Fill in env variables
|
||||
run: |
|
||||
sed -i "s/JWT_SECRET=/JWT_SECRET=$(openssl rand -hex 32)/g" packages/home-server/.env
|
||||
sed -i "s/AUTH_JWT_SECRET=/AUTH_JWT_SECRET=$(openssl rand -hex 32)/g" packages/home-server/.env
|
||||
sed -i "s/ENCRYPTION_SERVER_KEY=/ENCRYPTION_SERVER_KEY=$(openssl rand -hex 32)/g" packages/home-server/.env
|
||||
sed -i "s/PSEUDO_KEY_PARAMS_KEY=/PSEUDO_KEY_PARAMS_KEY=$(openssl rand -hex 32)/g" packages/home-server/.env
|
||||
sed -i "s/VALET_TOKEN_SECRET=/VALET_TOKEN_SECRET=$(openssl rand -hex 32)/g" packages/home-server/.env
|
||||
echo "ACCESS_TOKEN_AGE=4" >> packages/home-server/.env
|
||||
echo "REFRESH_TOKEN_AGE=7" >> packages/home-server/.env
|
||||
echo "REVISIONS_FREQUENCY=5" >> packages/home-server/.env
|
||||
|
||||
- name: Run Server
|
||||
run: nohup yarn workspace @standardnotes/home-server start &
|
||||
env:
|
||||
PORT: 3123
|
||||
|
||||
- name: Wait for server to start
|
||||
run: for i in {1..30}; do curl -s http://localhost:3123/healthcheck && break || sleep 1; done
|
||||
|
||||
- name: Run E2E Test Suite
|
||||
run: yarn dlx mocha-headless-chrome --timeout 1200000 -f http://localhost:9001/mocha/test.html?skip_paid_features=true
|
||||
|
||||
BIN
.yarn/cache/@aws-sdk-abort-controller-npm-3.329.0-330df022b1-86f90b191d.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-abort-controller-npm-3.329.0-330df022b1-86f90b191d.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-config-resolver-npm-3.329.0-ad937b6b5a-96a66188db.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-config-resolver-npm-3.329.0-ad937b6b5a-96a66188db.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-credential-provider-env-npm-3.329.0-a157793370-f55a57adfb.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-credential-provider-env-npm-3.329.0-a157793370-f55a57adfb.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-credential-provider-imds-npm-3.329.0-04ff9ca00d-6ec90ae7e4.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-credential-provider-imds-npm-3.329.0-04ff9ca00d-6ec90ae7e4.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-credential-provider-process-npm-3.329.0-a4e22c58e7-ad125b9c5e.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-credential-provider-process-npm-3.329.0-a4e22c58e7-ad125b9c5e.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-credential-provider-web-identity-npm-3.329.0-64a1517f92-cfdf8074d2.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-credential-provider-web-identity-npm-3.329.0-64a1517f92-cfdf8074d2.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-fetch-http-handler-npm-3.329.0-2d5e8249a0-d0961fb2ed.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-fetch-http-handler-npm-3.329.0-2d5e8249a0-d0961fb2ed.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-hash-node-npm-3.329.0-a7c67f51ba-7eaa0387ec.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-hash-node-npm-3.329.0-a7c67f51ba-7eaa0387ec.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-invalid-dependency-npm-3.329.0-09565fa8f1-d81664bb97.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-invalid-dependency-npm-3.329.0-09565fa8f1-d81664bb97.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-md5-js-npm-3.329.0-62455ff652-3157a9019d.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-md5-js-npm-3.329.0-62455ff652-3157a9019d.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-middleware-content-length-npm-3.329.0-572714587f-b6e8b7d79a.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-middleware-content-length-npm-3.329.0-572714587f-b6e8b7d79a.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-middleware-endpoint-npm-3.329.0-0500d0a5da-407dd4e705.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-middleware-endpoint-npm-3.329.0-0500d0a5da-407dd4e705.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-middleware-host-header-npm-3.329.0-e3a2c4eb17-f0470b64e8.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-middleware-host-header-npm-3.329.0-e3a2c4eb17-f0470b64e8.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-middleware-logger-npm-3.329.0-a83672165b-b8b4732902.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-middleware-logger-npm-3.329.0-a83672165b-b8b4732902.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-middleware-recursion-detection-npm-3.329.0-9530d1707a-7dff5457a7.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-middleware-recursion-detection-npm-3.329.0-9530d1707a-7dff5457a7.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-middleware-retry-npm-3.329.0-f85eca00a2-9d66667c56.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-middleware-retry-npm-3.329.0-f85eca00a2-9d66667c56.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-middleware-sdk-sqs-npm-3.329.0-53e6711cf6-9d1e875bfb.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-middleware-sdk-sqs-npm-3.329.0-53e6711cf6-9d1e875bfb.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-middleware-sdk-sts-npm-3.329.0-b8e0612c39-845b3f43bb.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-middleware-sdk-sts-npm-3.329.0-b8e0612c39-845b3f43bb.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-middleware-serde-npm-3.329.0-70b1cb397b-d200e91340.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-middleware-serde-npm-3.329.0-70b1cb397b-d200e91340.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-middleware-signing-npm-3.329.0-fafebbac45-06103d8a7d.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-middleware-signing-npm-3.329.0-fafebbac45-06103d8a7d.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-middleware-stack-npm-3.329.0-deb18647d9-80f34d8ff6.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-middleware-stack-npm-3.329.0-deb18647d9-80f34d8ff6.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-middleware-user-agent-npm-3.332.0-477b2b503f-75bfe862c1.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-middleware-user-agent-npm-3.332.0-477b2b503f-75bfe862c1.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-node-config-provider-npm-3.329.0-bea365bcec-2af283e3f5.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-node-config-provider-npm-3.329.0-bea365bcec-2af283e3f5.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-property-provider-npm-3.329.0-8f019ecd0f-e11809cea3.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-property-provider-npm-3.329.0-8f019ecd0f-e11809cea3.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-protocol-http-npm-3.329.0-9599f077f6-459a46d8c0.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-protocol-http-npm-3.329.0-9599f077f6-459a46d8c0.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-querystring-builder-npm-3.329.0-2df4fb67f1-681efb98ac.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-querystring-builder-npm-3.329.0-2df4fb67f1-681efb98ac.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-querystring-parser-npm-3.329.0-4b1a1e0fb5-9ed54dc61d.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-querystring-parser-npm-3.329.0-4b1a1e0fb5-9ed54dc61d.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-service-error-classification-npm-3.329.0-c85b83bd81-215b61f2cc.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-service-error-classification-npm-3.329.0-c85b83bd81-215b61f2cc.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-shared-ini-file-loader-npm-3.329.0-b4fe16c15a-4dda8a5a79.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-shared-ini-file-loader-npm-3.329.0-b4fe16c15a-4dda8a5a79.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-signature-v4-npm-3.329.0-0702b2b15c-aba37d7f61.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-signature-v4-npm-3.329.0-0702b2b15c-aba37d7f61.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-smithy-client-npm-3.329.0-7cced1d303-45f87ed846.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-smithy-client-npm-3.329.0-7cced1d303-45f87ed846.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-types-npm-3.329.0-06a5c61fa9-28aff60622.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-types-npm-3.329.0-06a5c61fa9-28aff60622.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-url-parser-npm-3.329.0-70076d0522-9ca336e5bb.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-url-parser-npm-3.329.0-70076d0522-9ca336e5bb.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-util-defaults-mode-browser-npm-3.329.0-c5d6a57d9a-ccff18607b.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-util-defaults-mode-browser-npm-3.329.0-c5d6a57d9a-ccff18607b.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-util-defaults-mode-node-npm-3.329.0-fd81099dd9-f927efbc3d.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-util-defaults-mode-node-npm-3.329.0-fd81099dd9-f927efbc3d.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-util-endpoints-npm-3.332.0-8713e2eaa5-1974420c77.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-util-endpoints-npm-3.332.0-8713e2eaa5-1974420c77.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-util-middleware-npm-3.329.0-659548e387-0493c049ae.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-util-middleware-npm-3.329.0-659548e387-0493c049ae.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-util-retry-npm-3.329.0-39c3180797-3612d19ae4.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-util-retry-npm-3.329.0-39c3180797-3612d19ae4.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-util-user-agent-browser-npm-3.329.0-14a80d95c5-04f10b65e7.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-util-user-agent-browser-npm-3.329.0-14a80d95c5-04f10b65e7.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@aws-sdk-util-user-agent-node-npm-3.329.0-178e22c724-cebebd6e4d.zip
vendored
Normal file
BIN
.yarn/cache/@aws-sdk-util-user-agent-node-npm-3.329.0-178e22c724-cebebd6e4d.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.22.5](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.22.4...@standardnotes/analytics@2.22.5) (2023-05-29)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.22.4](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.22.3...@standardnotes/analytics@2.22.4) (2023-05-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.22.3](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.22.2...@standardnotes/analytics@2.22.3) (2023-05-16)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.22.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.22.1...@standardnotes/analytics@2.22.2) (2023-05-15)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.22.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.22.0...@standardnotes/analytics@2.22.1) (2023-05-09)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/analytics",
|
||||
"version": "2.22.1",
|
||||
"version": "2.22.5",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
@@ -40,8 +40,8 @@
|
||||
"typescript": "^5.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-sns": "^3.328.0",
|
||||
"@aws-sdk/client-sqs": "^3.328.0",
|
||||
"@aws-sdk/client-sns": "^3.332.0",
|
||||
"@aws-sdk/client-sqs": "^3.332.0",
|
||||
"@newrelic/winston-enricher": "^4.0.1",
|
||||
"@standardnotes/common": "workspace:*",
|
||||
"@standardnotes/domain-core": "workspace:^",
|
||||
|
||||
@@ -3,6 +3,63 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.59.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.58.0...@standardnotes/api-gateway@1.59.0) (2023-05-29)
|
||||
|
||||
### Features
|
||||
|
||||
* add files server as a service to home-server ([#614](https://github.com/standardnotes/api-gateway/issues/614)) ([c7d575a](https://github.com/standardnotes/api-gateway/commit/c7d575a0ffc7eb3e8799c3835da5727584f4f67b))
|
||||
|
||||
# [1.58.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.57.0...@standardnotes/api-gateway@1.58.0) (2023-05-25)
|
||||
|
||||
### Features
|
||||
|
||||
* add revisions service to home server ([#613](https://github.com/standardnotes/api-gateway/issues/613)) ([c70040f](https://github.com/standardnotes/api-gateway/commit/c70040fe5dfd35663b9811fbbaa9370bd0298482))
|
||||
|
||||
# [1.57.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.56.2...@standardnotes/api-gateway@1.57.0) (2023-05-25)
|
||||
|
||||
### Features
|
||||
|
||||
* refactor auth middleware to handle required and optional cross service token scenarios ([#612](https://github.com/standardnotes/api-gateway/issues/612)) ([1e4c7d0](https://github.com/standardnotes/api-gateway/commit/1e4c7d0f317d5c2d98065da12ffeb950b10ee5dc))
|
||||
|
||||
## [1.56.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.56.1...@standardnotes/api-gateway@1.56.2) (2023-05-18)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **api-gateway:** decorating responses for direct call proxy ([4ab32c6](https://github.com/standardnotes/api-gateway/commit/4ab32c670eedcfc64611a191bc25566d43372b23))
|
||||
* **api-gateway:** pkce endpoints resolution for direct code calls ([c7e605f](https://github.com/standardnotes/api-gateway/commit/c7e605fd6046e8476c493658c6feaed365e82e5d))
|
||||
|
||||
## [1.56.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.56.0...@standardnotes/api-gateway@1.56.1) (2023-05-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
# [1.56.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.55.0...@standardnotes/api-gateway@1.56.0) (2023-05-17)
|
||||
|
||||
### Features
|
||||
|
||||
* bundle syncing server into home server setup ([#611](https://github.com/standardnotes/api-gateway/issues/611)) ([b3b617e](https://github.com/standardnotes/api-gateway/commit/b3b617ea0b4f4574f6aa7cfae0e9fa8f868f1f4c))
|
||||
|
||||
# [1.55.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.54.0...@standardnotes/api-gateway@1.55.0) (2023-05-17)
|
||||
|
||||
### Features
|
||||
|
||||
* add direct event handling for home server ([#608](https://github.com/standardnotes/api-gateway/issues/608)) ([8a47d81](https://github.com/standardnotes/api-gateway/commit/8a47d81936acd765224e74fd083810579a83c9a7))
|
||||
|
||||
# [1.54.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.53.1...@standardnotes/api-gateway@1.54.0) (2023-05-16)
|
||||
|
||||
### Features
|
||||
|
||||
* home-server package initial setup with Api Gateway and Auth services ([#605](https://github.com/standardnotes/api-gateway/issues/605)) ([dc71e67](https://github.com/standardnotes/api-gateway/commit/dc71e6777fc4c51234b79f6fb409f9f3111cc6a5))
|
||||
|
||||
## [1.53.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.53.0...@standardnotes/api-gateway@1.53.1) (2023-05-15)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
# [1.53.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.52.1...@standardnotes/api-gateway@1.53.0) (2023-05-09)
|
||||
|
||||
### Features
|
||||
|
||||
* **home-server:** add boilerplate ([#601](https://github.com/standardnotes/api-gateway/issues/601)) ([750cd26](https://github.com/standardnotes/api-gateway/commit/750cd26c369e7d93fa3da29dbe41823059252639))
|
||||
|
||||
## [1.52.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.52.0...@standardnotes/api-gateway@1.52.1) (2023-05-09)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -32,7 +32,7 @@ const robots = require('express-robots-txt')
|
||||
|
||||
import { InversifyExpressServer } from 'inversify-express-utils'
|
||||
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
|
||||
import TYPES from '../src/Bootstrap/Types'
|
||||
import { TYPES } from '../src/Bootstrap/Types'
|
||||
import { Env } from '../src/Bootstrap/Env'
|
||||
|
||||
const container = new ContainerConfigLoader()
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
{
|
||||
"name": "@standardnotes/api-gateway",
|
||||
"version": "1.52.1",
|
||||
"version": "1.59.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
"private": true,
|
||||
"description": "API Gateway For Standard Notes Services",
|
||||
"main": "dist/src/index.js",
|
||||
"typings": "dist/src/index.d.ts",
|
||||
"types": "dist/src/index.d.ts",
|
||||
"files": [
|
||||
"dist/src/**/*.js",
|
||||
"dist/src/**/*.d.ts"
|
||||
],
|
||||
"repository": "git@github.com:standardnotes/api-gateway.git",
|
||||
"author": "Karol Sójko <karolsojko@standardnotes.com>",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
|
||||
@@ -7,21 +7,26 @@ import { Container } from 'inversify'
|
||||
import { Timer, TimerInterface } from '@standardnotes/time'
|
||||
|
||||
import { Env } from './Env'
|
||||
import TYPES from './Types'
|
||||
import { AuthMiddleware } from '../Controller/AuthMiddleware'
|
||||
import { HttpServiceInterface } from '../Service/Http/HttpServiceInterface'
|
||||
import { HttpService } from '../Service/Http/HttpService'
|
||||
import { TYPES } from './Types'
|
||||
import { ServiceProxyInterface } from '../Service/Http/ServiceProxyInterface'
|
||||
import { HttpServiceProxy } from '../Service/Http/HttpServiceProxy'
|
||||
import { SubscriptionTokenAuthMiddleware } from '../Controller/SubscriptionTokenAuthMiddleware'
|
||||
import { CrossServiceTokenCacheInterface } from '../Service/Cache/CrossServiceTokenCacheInterface'
|
||||
import { RedisCrossServiceTokenCache } from '../Infra/Redis/RedisCrossServiceTokenCache'
|
||||
import { WebSocketAuthMiddleware } from '../Controller/WebSocketAuthMiddleware'
|
||||
import { InMemoryCrossServiceTokenCache } from '../Infra/InMemory/InMemoryCrossServiceTokenCache'
|
||||
import { DirectCallServiceProxy } from '../Service/Proxy/DirectCallServiceProxy'
|
||||
import { ServiceContainerInterface } from '@standardnotes/domain-core'
|
||||
import { EndpointResolverInterface } from '../Service/Resolver/EndpointResolverInterface'
|
||||
import { EndpointResolver } from '../Service/Resolver/EndpointResolver'
|
||||
import { RequiredCrossServiceTokenMiddleware } from '../Controller/RequiredCrossServiceTokenMiddleware'
|
||||
import { OptionalCrossServiceTokenMiddleware } from '../Controller/OptionalCrossServiceTokenMiddleware'
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const newrelicFormatter = require('@newrelic/winston-enricher')
|
||||
|
||||
export class ContainerConfigLoader {
|
||||
async load(): Promise<Container> {
|
||||
async load(serviceContainer?: ServiceContainerInterface): Promise<Container> {
|
||||
const env: Env = new Env()
|
||||
env.load()
|
||||
|
||||
@@ -39,30 +44,33 @@ export class ContainerConfigLoader {
|
||||
level: env.get('LOG_LEVEL') || 'info',
|
||||
format: winston.format.combine(...winstonFormatters),
|
||||
transports: [new winston.transports.Console({ level: env.get('LOG_LEVEL') || 'info' })],
|
||||
defaultMeta: { service: 'api-gateway' },
|
||||
})
|
||||
container.bind<winston.Logger>(TYPES.Logger).toConstantValue(logger)
|
||||
|
||||
const redisUrl = env.get('REDIS_URL')
|
||||
const isRedisInClusterMode = redisUrl.indexOf(',') > 0
|
||||
let redis
|
||||
if (isRedisInClusterMode) {
|
||||
redis = new Redis.Cluster(redisUrl.split(','))
|
||||
} else {
|
||||
redis = new Redis(redisUrl)
|
||||
if (!isConfiguredForHomeServer) {
|
||||
const redisUrl = env.get('REDIS_URL')
|
||||
const isRedisInClusterMode = redisUrl.indexOf(',') > 0
|
||||
let redis
|
||||
if (isRedisInClusterMode) {
|
||||
redis = new Redis.Cluster(redisUrl.split(','))
|
||||
} else {
|
||||
redis = new Redis(redisUrl)
|
||||
}
|
||||
container.bind(TYPES.Redis).toConstantValue(redis)
|
||||
}
|
||||
container.bind(TYPES.Redis).toConstantValue(redis)
|
||||
|
||||
container.bind<AxiosInstance>(TYPES.HTTPClient).toConstantValue(axios.create())
|
||||
|
||||
// env vars
|
||||
container.bind(TYPES.SYNCING_SERVER_JS_URL).toConstantValue(env.get('SYNCING_SERVER_JS_URL'))
|
||||
container.bind(TYPES.AUTH_SERVER_URL).toConstantValue(env.get('AUTH_SERVER_URL'))
|
||||
container.bind(TYPES.SYNCING_SERVER_JS_URL).toConstantValue(env.get('SYNCING_SERVER_JS_URL', true))
|
||||
container.bind(TYPES.AUTH_SERVER_URL).toConstantValue(env.get('AUTH_SERVER_URL', true))
|
||||
container.bind(TYPES.REVISIONS_SERVER_URL).toConstantValue(env.get('REVISIONS_SERVER_URL', true))
|
||||
container.bind(TYPES.EMAIL_SERVER_URL).toConstantValue(env.get('EMAIL_SERVER_URL', true))
|
||||
container.bind(TYPES.PAYMENTS_SERVER_URL).toConstantValue(env.get('PAYMENTS_SERVER_URL', true))
|
||||
container.bind(TYPES.FILES_SERVER_URL).toConstantValue(env.get('FILES_SERVER_URL', true))
|
||||
container.bind(TYPES.AUTH_JWT_SECRET).toConstantValue(env.get('AUTH_JWT_SECRET'))
|
||||
container.bind(TYPES.WEB_SOCKET_SERVER_URL).toConstantValue(env.get('WEB_SOCKET_SERVER_URL', true))
|
||||
container.bind(TYPES.AUTH_JWT_SECRET).toConstantValue(env.get('AUTH_JWT_SECRET'))
|
||||
container
|
||||
.bind(TYPES.HTTP_CALL_TIMEOUT)
|
||||
.toConstantValue(env.get('HTTP_CALL_TIMEOUT', true) ? +env.get('HTTP_CALL_TIMEOUT', true) : 60_000)
|
||||
@@ -70,14 +78,28 @@ export class ContainerConfigLoader {
|
||||
container.bind(TYPES.CROSS_SERVICE_TOKEN_CACHE_TTL).toConstantValue(+env.get('CROSS_SERVICE_TOKEN_CACHE_TTL', true))
|
||||
|
||||
// Middleware
|
||||
container.bind<AuthMiddleware>(TYPES.AuthMiddleware).to(AuthMiddleware)
|
||||
container
|
||||
.bind<RequiredCrossServiceTokenMiddleware>(TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
.to(RequiredCrossServiceTokenMiddleware)
|
||||
container
|
||||
.bind<OptionalCrossServiceTokenMiddleware>(TYPES.OptionalCrossServiceTokenMiddleware)
|
||||
.to(OptionalCrossServiceTokenMiddleware)
|
||||
container.bind<WebSocketAuthMiddleware>(TYPES.WebSocketAuthMiddleware).to(WebSocketAuthMiddleware)
|
||||
container
|
||||
.bind<SubscriptionTokenAuthMiddleware>(TYPES.SubscriptionTokenAuthMiddleware)
|
||||
.to(SubscriptionTokenAuthMiddleware)
|
||||
|
||||
// Services
|
||||
container.bind<HttpServiceInterface>(TYPES.HTTPService).to(HttpService)
|
||||
if (isConfiguredForHomeServer) {
|
||||
if (!serviceContainer) {
|
||||
throw new Error('Service container is required when configured for home server')
|
||||
}
|
||||
container
|
||||
.bind<ServiceProxyInterface>(TYPES.ServiceProxy)
|
||||
.toConstantValue(new DirectCallServiceProxy(serviceContainer, container.get(TYPES.FILES_SERVER_URL)))
|
||||
} else {
|
||||
container.bind<ServiceProxyInterface>(TYPES.ServiceProxy).to(HttpServiceProxy)
|
||||
}
|
||||
container.bind<TimerInterface>(TYPES.Timer).toConstantValue(new Timer())
|
||||
|
||||
if (isConfiguredForHomeServer) {
|
||||
@@ -87,6 +109,9 @@ export class ContainerConfigLoader {
|
||||
} else {
|
||||
container.bind<CrossServiceTokenCacheInterface>(TYPES.CrossServiceTokenCache).to(RedisCrossServiceTokenCache)
|
||||
}
|
||||
container
|
||||
.bind<EndpointResolverInterface>(TYPES.EndpointResolver)
|
||||
.toConstantValue(new EndpointResolver(isConfiguredForHomeServer))
|
||||
|
||||
return container
|
||||
}
|
||||
|
||||
23
packages/api-gateway/src/Bootstrap/Service.ts
Normal file
23
packages/api-gateway/src/Bootstrap/Service.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { ServiceContainerInterface, ServiceIdentifier, ServiceInterface } from '@standardnotes/domain-core'
|
||||
|
||||
import { ContainerConfigLoader } from './Container'
|
||||
|
||||
export class Service implements ServiceInterface {
|
||||
constructor(private serviceContainer: ServiceContainerInterface) {
|
||||
this.serviceContainer.register(this.getId(), this)
|
||||
}
|
||||
|
||||
async handleRequest(_request: never, _response: never, _endpointOrMethodIdentifier: string): Promise<unknown> {
|
||||
throw new Error('Requests are handled via inversify-express at ApiGateway level')
|
||||
}
|
||||
|
||||
async getContainer(): Promise<unknown> {
|
||||
const config = new ContainerConfigLoader()
|
||||
|
||||
return config.load(this.serviceContainer)
|
||||
}
|
||||
|
||||
getId(): ServiceIdentifier {
|
||||
return ServiceIdentifier.create(ServiceIdentifier.NAMES.Auth).getValue()
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
const TYPES = {
|
||||
export const TYPES = {
|
||||
Logger: Symbol.for('Logger'),
|
||||
Redis: Symbol.for('Redis'),
|
||||
HTTPClient: Symbol.for('HTTPClient'),
|
||||
@@ -15,13 +15,15 @@ const TYPES = {
|
||||
VERSION: Symbol.for('VERSION'),
|
||||
CROSS_SERVICE_TOKEN_CACHE_TTL: Symbol.for('CROSS_SERVICE_TOKEN_CACHE_TTL'),
|
||||
// Middleware
|
||||
AuthMiddleware: Symbol.for('AuthMiddleware'),
|
||||
RequiredCrossServiceTokenMiddleware: Symbol.for('RequiredCrossServiceTokenMiddleware'),
|
||||
OptionalCrossServiceTokenMiddleware: Symbol.for('OptionalCrossServiceTokenMiddleware'),
|
||||
WebSocketAuthMiddleware: Symbol.for('WebSocketAuthMiddleware'),
|
||||
SubscriptionTokenAuthMiddleware: Symbol.for('SubscriptionTokenAuthMiddleware'),
|
||||
// Services
|
||||
HTTPService: Symbol.for('HTTPService'),
|
||||
ServiceProxy: Symbol.for('ServiceProxy'),
|
||||
CrossServiceTokenCache: Symbol.for('CrossServiceTokenCache'),
|
||||
Timer: Symbol.for('Timer'),
|
||||
EndpointResolver: Symbol.for('EndpointResolver'),
|
||||
}
|
||||
|
||||
export default TYPES
|
||||
// export default TYPES
|
||||
|
||||
2
packages/api-gateway/src/Bootstrap/index.ts
Normal file
2
packages/api-gateway/src/Bootstrap/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './Service'
|
||||
export * from './Types'
|
||||
@@ -2,43 +2,33 @@ import { CrossServiceTokenData } from '@standardnotes/security'
|
||||
import { RoleName } from '@standardnotes/domain-core'
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
import { NextFunction, Request, Response } from 'express'
|
||||
import { inject, injectable } from 'inversify'
|
||||
import { BaseMiddleware } from 'inversify-express-utils'
|
||||
import { verify } from 'jsonwebtoken'
|
||||
import { AxiosError, AxiosInstance } from 'axios'
|
||||
import { AxiosError } from 'axios'
|
||||
import { Logger } from 'winston'
|
||||
|
||||
import TYPES from '../Bootstrap/Types'
|
||||
import { CrossServiceTokenCacheInterface } from '../Service/Cache/CrossServiceTokenCacheInterface'
|
||||
import { ServiceProxyInterface } from '../Service/Http/ServiceProxyInterface'
|
||||
|
||||
@injectable()
|
||||
export class AuthMiddleware extends BaseMiddleware {
|
||||
export abstract class AuthMiddleware extends BaseMiddleware {
|
||||
constructor(
|
||||
@inject(TYPES.HTTPClient) private httpClient: AxiosInstance,
|
||||
@inject(TYPES.AUTH_SERVER_URL) private authServerUrl: string,
|
||||
@inject(TYPES.AUTH_JWT_SECRET) private jwtSecret: string,
|
||||
@inject(TYPES.CROSS_SERVICE_TOKEN_CACHE_TTL) private crossServiceTokenCacheTTL: number,
|
||||
@inject(TYPES.CrossServiceTokenCache) private crossServiceTokenCache: CrossServiceTokenCacheInterface,
|
||||
@inject(TYPES.Timer) private timer: TimerInterface,
|
||||
@inject(TYPES.Logger) private logger: Logger,
|
||||
private serviceProxy: ServiceProxyInterface,
|
||||
private jwtSecret: string,
|
||||
private crossServiceTokenCacheTTL: number,
|
||||
private crossServiceTokenCache: CrossServiceTokenCacheInterface,
|
||||
private timer: TimerInterface,
|
||||
private logger: Logger,
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
async handler(request: Request, response: Response, next: NextFunction): Promise<void> {
|
||||
const authHeaderValue = request.headers.authorization as string
|
||||
|
||||
if (!authHeaderValue) {
|
||||
response.status(401).send({
|
||||
error: {
|
||||
tag: 'invalid-auth',
|
||||
message: 'Invalid login credentials.',
|
||||
},
|
||||
})
|
||||
|
||||
if (!this.handleMissingAuthHeader(request.headers.authorization, response, next)) {
|
||||
return
|
||||
}
|
||||
|
||||
const authHeaderValue = request.headers.authorization as string
|
||||
|
||||
try {
|
||||
let crossServiceTokenFetchedFromCache = true
|
||||
let crossServiceToken = null
|
||||
@@ -47,26 +37,13 @@ export class AuthMiddleware extends BaseMiddleware {
|
||||
}
|
||||
|
||||
if (crossServiceToken === null) {
|
||||
const authResponse = await this.httpClient.request({
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: authHeaderValue,
|
||||
Accept: 'application/json',
|
||||
},
|
||||
validateStatus: (status: number) => {
|
||||
return status >= 200 && status < 500
|
||||
},
|
||||
url: `${this.authServerUrl}/sessions/validate`,
|
||||
})
|
||||
|
||||
if (authResponse.status > 200) {
|
||||
response.setHeader('content-type', authResponse.headers['content-type'] as string)
|
||||
response.status(authResponse.status).send(authResponse.data)
|
||||
const authResponse = await this.serviceProxy.validateSession(authHeaderValue)
|
||||
|
||||
if (!this.handleSessionValidationResponse(authResponse, response, next)) {
|
||||
return
|
||||
}
|
||||
|
||||
crossServiceToken = authResponse.data.authToken
|
||||
crossServiceToken = (authResponse.data as { authToken: string }).authToken
|
||||
crossServiceTokenFetchedFromCache = false
|
||||
}
|
||||
|
||||
@@ -87,16 +64,15 @@ export class AuthMiddleware extends BaseMiddleware {
|
||||
})
|
||||
}
|
||||
|
||||
response.locals.userUuid = decodedToken.user.uuid
|
||||
response.locals.user = decodedToken.user
|
||||
response.locals.session = decodedToken.session
|
||||
response.locals.roles = decodedToken.roles
|
||||
} catch (error) {
|
||||
const errorMessage = (error as AxiosError).isAxiosError
|
||||
? JSON.stringify((error as AxiosError).response?.data)
|
||||
: (error as Error).message
|
||||
|
||||
this.logger.error(
|
||||
`Could not pass the request to ${this.authServerUrl}/sessions/validate on underlying service: ${errorMessage}`,
|
||||
)
|
||||
this.logger.error(`Could not pass the request to sessions/validate on underlying service: ${errorMessage}`)
|
||||
|
||||
this.logger.debug('Response error: %O', (error as AxiosError).response ?? error)
|
||||
|
||||
@@ -117,6 +93,24 @@ export class AuthMiddleware extends BaseMiddleware {
|
||||
return next()
|
||||
}
|
||||
|
||||
protected abstract handleSessionValidationResponse(
|
||||
authResponse: {
|
||||
status: number
|
||||
data: unknown
|
||||
headers: {
|
||||
contentType: string
|
||||
}
|
||||
},
|
||||
response: Response,
|
||||
next: NextFunction,
|
||||
): boolean
|
||||
|
||||
protected abstract handleMissingAuthHeader(
|
||||
authHeaderValue: string | undefined,
|
||||
response: Response,
|
||||
next: NextFunction,
|
||||
): boolean
|
||||
|
||||
private getCrossServiceTokenCacheExpireTimestamp(token: CrossServiceTokenData): number {
|
||||
const crossServiceTokenDefaultCacheExpiration = this.timer.getTimestampInSeconds() + this.crossServiceTokenCacheTTL
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import { Request, Response } from 'express'
|
||||
import { inject } from 'inversify'
|
||||
import { controller, all, BaseHttpController, httpPost, httpGet, results, httpDelete } from 'inversify-express-utils'
|
||||
import TYPES from '../Bootstrap/Types'
|
||||
import { HttpServiceInterface } from '../Service/Http/HttpServiceInterface'
|
||||
import { TYPES } from '../Bootstrap/Types'
|
||||
import { ServiceProxyInterface } from '../Service/Http/ServiceProxyInterface'
|
||||
|
||||
@controller('')
|
||||
export class LegacyController extends BaseHttpController {
|
||||
private AUTH_ROUTES: Map<string, string>
|
||||
private PARAMETRIZED_AUTH_ROUTES: Map<string, string>
|
||||
|
||||
constructor(@inject(TYPES.HTTPService) private httpService: HttpServiceInterface) {
|
||||
constructor(@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface) {
|
||||
super()
|
||||
|
||||
this.AUTH_ROUTES = new Map([
|
||||
@@ -29,17 +29,17 @@ export class LegacyController extends BaseHttpController {
|
||||
])
|
||||
}
|
||||
|
||||
@httpPost('/items/sync', TYPES.AuthMiddleware)
|
||||
@httpPost('/items/sync', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async legacyItemsSync(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callLegacySyncingServer(request, response, request.path.substring(1), request.body)
|
||||
}
|
||||
|
||||
@httpGet('/items/:item_id/revisions', TYPES.AuthMiddleware)
|
||||
@httpGet('/items/:item_id/revisions', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async legacyGetRevisions(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callLegacySyncingServer(request, response, request.path.substring(1), request.body)
|
||||
}
|
||||
|
||||
@httpGet('/items/:item_id/revisions/:id', TYPES.AuthMiddleware)
|
||||
@httpGet('/items/:item_id/revisions/:id', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async legacyGetRevision(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callLegacySyncingServer(request, response, request.path.substring(1), request.body)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
import { NextFunction, Response } from 'express'
|
||||
import { inject, injectable } from 'inversify'
|
||||
import { Logger } from 'winston'
|
||||
|
||||
import { TYPES } from '../Bootstrap/Types'
|
||||
import { CrossServiceTokenCacheInterface } from '../Service/Cache/CrossServiceTokenCacheInterface'
|
||||
import { ServiceProxyInterface } from '../Service/Http/ServiceProxyInterface'
|
||||
import { AuthMiddleware } from './AuthMiddleware'
|
||||
|
||||
@injectable()
|
||||
export class OptionalCrossServiceTokenMiddleware extends AuthMiddleware {
|
||||
constructor(
|
||||
@inject(TYPES.ServiceProxy) serviceProxy: ServiceProxyInterface,
|
||||
@inject(TYPES.AUTH_JWT_SECRET) jwtSecret: string,
|
||||
@inject(TYPES.CROSS_SERVICE_TOKEN_CACHE_TTL) crossServiceTokenCacheTTL: number,
|
||||
@inject(TYPES.CrossServiceTokenCache) crossServiceTokenCache: CrossServiceTokenCacheInterface,
|
||||
@inject(TYPES.Timer) timer: TimerInterface,
|
||||
@inject(TYPES.Logger) logger: Logger,
|
||||
) {
|
||||
super(serviceProxy, jwtSecret, crossServiceTokenCacheTTL, crossServiceTokenCache, timer, logger)
|
||||
}
|
||||
|
||||
protected override handleSessionValidationResponse(
|
||||
authResponse: { status: number; data: unknown; headers: { contentType: string } },
|
||||
_response: Response,
|
||||
next: NextFunction,
|
||||
): boolean {
|
||||
if (authResponse.status > 200) {
|
||||
next()
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
protected override handleMissingAuthHeader(
|
||||
authHeaderValue: string | undefined,
|
||||
_response: Response,
|
||||
next: NextFunction,
|
||||
): boolean {
|
||||
if (!authHeaderValue) {
|
||||
next()
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
import { NextFunction, Response } from 'express'
|
||||
import { inject, injectable } from 'inversify'
|
||||
import { Logger } from 'winston'
|
||||
|
||||
import { TYPES } from '../Bootstrap/Types'
|
||||
import { CrossServiceTokenCacheInterface } from '../Service/Cache/CrossServiceTokenCacheInterface'
|
||||
import { ServiceProxyInterface } from '../Service/Http/ServiceProxyInterface'
|
||||
import { AuthMiddleware } from './AuthMiddleware'
|
||||
|
||||
@injectable()
|
||||
export class RequiredCrossServiceTokenMiddleware extends AuthMiddleware {
|
||||
constructor(
|
||||
@inject(TYPES.ServiceProxy) serviceProxy: ServiceProxyInterface,
|
||||
@inject(TYPES.AUTH_JWT_SECRET) jwtSecret: string,
|
||||
@inject(TYPES.CROSS_SERVICE_TOKEN_CACHE_TTL) crossServiceTokenCacheTTL: number,
|
||||
@inject(TYPES.CrossServiceTokenCache) crossServiceTokenCache: CrossServiceTokenCacheInterface,
|
||||
@inject(TYPES.Timer) timer: TimerInterface,
|
||||
@inject(TYPES.Logger) logger: Logger,
|
||||
) {
|
||||
super(serviceProxy, jwtSecret, crossServiceTokenCacheTTL, crossServiceTokenCache, timer, logger)
|
||||
}
|
||||
|
||||
protected override handleSessionValidationResponse(
|
||||
authResponse: { status: number; data: unknown; headers: { contentType: string } },
|
||||
response: Response,
|
||||
_next: NextFunction,
|
||||
): boolean {
|
||||
if (authResponse.status > 200) {
|
||||
response.setHeader('content-type', authResponse.headers.contentType)
|
||||
response.status(authResponse.status).send(authResponse.data)
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
protected override handleMissingAuthHeader(
|
||||
authHeaderValue: string | undefined,
|
||||
response: Response,
|
||||
_next: NextFunction,
|
||||
): boolean {
|
||||
if (!authHeaderValue) {
|
||||
response.status(401).send({
|
||||
error: {
|
||||
tag: 'invalid-auth',
|
||||
message: 'Invalid login credentials.',
|
||||
},
|
||||
})
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import { BaseMiddleware } from 'inversify-express-utils'
|
||||
import { verify } from 'jsonwebtoken'
|
||||
import { AxiosError, AxiosInstance, AxiosResponse } from 'axios'
|
||||
import { Logger } from 'winston'
|
||||
import TYPES from '../Bootstrap/Types'
|
||||
import { TYPES } from '../Bootstrap/Types'
|
||||
import { TokenAuthenticationMethod } from './TokenAuthenticationMethod'
|
||||
|
||||
@injectable()
|
||||
@@ -118,7 +118,7 @@ export class SubscriptionTokenAuthMiddleware extends BaseMiddleware {
|
||||
verify(authResponse.data.authToken, this.jwtSecret, { algorithms: ['HS256'] })
|
||||
)
|
||||
|
||||
response.locals.userUuid = decodedToken.user.uuid
|
||||
response.locals.user = decodedToken.user
|
||||
response.locals.roles = decodedToken.roles
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import { verify } from 'jsonwebtoken'
|
||||
import { AxiosError, AxiosInstance } from 'axios'
|
||||
import { Logger } from 'winston'
|
||||
|
||||
import TYPES from '../Bootstrap/Types'
|
||||
import { TYPES } from '../Bootstrap/Types'
|
||||
|
||||
@injectable()
|
||||
export class WebSocketAuthMiddleware extends BaseMiddleware {
|
||||
@@ -63,7 +63,7 @@ export class WebSocketAuthMiddleware extends BaseMiddleware {
|
||||
response.locals.freeUser =
|
||||
decodedToken.roles.length === 1 &&
|
||||
decodedToken.roles.find((role) => role.name === RoleName.NAMES.CoreUser) !== undefined
|
||||
response.locals.userUuid = decodedToken.user.uuid
|
||||
response.locals.user = decodedToken.user
|
||||
response.locals.roles = decodedToken.roles
|
||||
} catch (error) {
|
||||
const errorMessage = (error as AxiosError).isAxiosError
|
||||
|
||||
21
packages/api-gateway/src/Controller/index.ts
Normal file
21
packages/api-gateway/src/Controller/index.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
export * from './AuthMiddleware'
|
||||
export * from './HealthCheckController'
|
||||
export * from './SubscriptionTokenAuthMiddleware'
|
||||
export * from './TokenAuthenticationMethod'
|
||||
export * from './WebSocketAuthMiddleware'
|
||||
export * from './v1/ActionsController'
|
||||
export * from './v1/AuthenticatorsController'
|
||||
export * from './v1/FilesController'
|
||||
export * from './v1/InvoicesController'
|
||||
export * from './v1/ItemsController'
|
||||
export * from './v1/OfflineController'
|
||||
export * from './v1/PaymentsController'
|
||||
export * from './v1/RevisionsController'
|
||||
export * from './v1/SessionsController'
|
||||
export * from './v1/SubscriptionInvitesController'
|
||||
export * from './v1/TokensController'
|
||||
export * from './v1/UsersController'
|
||||
export * from './v1/WebSocketsController'
|
||||
export * from './v2/ActionsControllerV2'
|
||||
export * from './v2/PaymentsControllerV2'
|
||||
export * from './v2/RevisionsControllerV2'
|
||||
@@ -1,38 +1,52 @@
|
||||
import { Request, Response } from 'express'
|
||||
import { inject } from 'inversify'
|
||||
import { BaseHttpController, controller, httpGet, httpPost } from 'inversify-express-utils'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { HttpServiceInterface } from '../../Service/Http/HttpServiceInterface'
|
||||
import { TYPES } from '../../Bootstrap/Types'
|
||||
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
|
||||
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
|
||||
|
||||
@controller('/v1')
|
||||
export class ActionsController extends BaseHttpController {
|
||||
constructor(@inject(TYPES.HTTPService) private httpService: HttpServiceInterface) {
|
||||
constructor(
|
||||
@inject(TYPES.ServiceProxy) private serviceProxy: ServiceProxyInterface,
|
||||
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
@httpPost('/login')
|
||||
async login(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, 'auth/sign_in', request.body)
|
||||
await this.serviceProxy.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'auth/sign_in'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/login-params')
|
||||
@httpGet('/login-params', TYPES.OptionalCrossServiceTokenMiddleware)
|
||||
async loginParams(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, 'auth/params', request.body)
|
||||
await this.serviceProxy.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'auth/params'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpPost('/logout')
|
||||
@httpPost('/logout', TYPES.OptionalCrossServiceTokenMiddleware)
|
||||
async logout(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, 'auth/sign_out', request.body)
|
||||
}
|
||||
|
||||
@httpGet('/auth/methods')
|
||||
async methods(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, 'auth/methods', request.body)
|
||||
await this.serviceProxy.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'auth/sign_out'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/unsubscribe/:token')
|
||||
async emailUnsubscribe(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callEmailServer(
|
||||
await this.serviceProxy.callEmailServer(
|
||||
request,
|
||||
response,
|
||||
`subscriptions/actions/unsubscribe/${request.params.token}`,
|
||||
@@ -40,18 +54,33 @@ export class ActionsController extends BaseHttpController {
|
||||
)
|
||||
}
|
||||
|
||||
@httpPost('/recovery/codes', TYPES.AuthMiddleware)
|
||||
@httpPost('/recovery/codes', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async recoveryCodes(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, 'auth/recovery/codes', request.body)
|
||||
await this.serviceProxy.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'auth/recovery/codes'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpPost('/recovery/login')
|
||||
async recoveryLogin(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, 'auth/recovery/login', request.body)
|
||||
await this.serviceProxy.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'auth/recovery/login'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpPost('/recovery/login-params')
|
||||
async recoveryParams(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, 'auth/recovery/params', request.body)
|
||||
await this.serviceProxy.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'auth/recovery/params'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,36 +2,49 @@ import { inject } from 'inversify'
|
||||
import { Request, Response } from 'express'
|
||||
import { controller, BaseHttpController, httpPost, httpGet, httpDelete } from 'inversify-express-utils'
|
||||
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { HttpServiceInterface } from '../../Service/Http/HttpServiceInterface'
|
||||
import { TYPES } from '../../Bootstrap/Types'
|
||||
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
|
||||
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
|
||||
|
||||
@controller('/v1/authenticators')
|
||||
export class AuthenticatorsController extends BaseHttpController {
|
||||
constructor(@inject(TYPES.HTTPService) private httpService: HttpServiceInterface) {
|
||||
constructor(
|
||||
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface,
|
||||
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
@httpDelete('/:authenticatorId', TYPES.AuthMiddleware)
|
||||
@httpDelete('/:authenticatorId', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async delete(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
`authenticators/${request.params.authenticatorId}`,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'DELETE',
|
||||
'authenticators/:authenticatorId',
|
||||
request.params.authenticatorId,
|
||||
),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/', TYPES.AuthMiddleware)
|
||||
@httpGet('/', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async list(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, 'authenticators/', request.body)
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'authenticators/'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/generate-registration-options', TYPES.AuthMiddleware)
|
||||
@httpGet('/generate-registration-options', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async generateRegistrationOptions(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
'authenticators/generate-registration-options',
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'authenticators/generate-registration-options'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
@@ -41,13 +54,18 @@ export class AuthenticatorsController extends BaseHttpController {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
'authenticators/generate-authentication-options',
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'authenticators/generate-authentication-options'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpPost('/verify-registration', TYPES.AuthMiddleware)
|
||||
@httpPost('/verify-registration', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async verifyRegistration(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, 'authenticators/verify-registration', request.body)
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'authenticators/verify-registration'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,17 +2,26 @@ import { Request, Response } from 'express'
|
||||
import { inject } from 'inversify'
|
||||
import { BaseHttpController, controller, httpPost } from 'inversify-express-utils'
|
||||
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { HttpServiceInterface } from '../../Service/Http/HttpServiceInterface'
|
||||
import { TYPES } from '../../Bootstrap/Types'
|
||||
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
|
||||
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
|
||||
|
||||
@controller('/v1/files')
|
||||
export class FilesController extends BaseHttpController {
|
||||
constructor(@inject(TYPES.HTTPService) private httpService: HttpServiceInterface) {
|
||||
constructor(
|
||||
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface,
|
||||
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
@httpPost('/valet-tokens', TYPES.AuthMiddleware)
|
||||
@httpPost('/valet-tokens', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async createToken(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, 'valet-tokens', request.body)
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'valet-tokens'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Request, Response } from 'express'
|
||||
import { BaseHttpController, controller, httpPost } from 'inversify-express-utils'
|
||||
import { inject } from 'inversify'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { HttpServiceInterface } from '../../Service/Http/HttpServiceInterface'
|
||||
import { TYPES } from '../../Bootstrap/Types'
|
||||
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
|
||||
|
||||
@controller('/v1')
|
||||
export class InvoicesController extends BaseHttpController {
|
||||
constructor(@inject(TYPES.HTTPService) private httpService: HttpServiceInterface) {
|
||||
constructor(@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface) {
|
||||
super()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,27 +1,46 @@
|
||||
import { Request, Response } from 'express'
|
||||
import { inject } from 'inversify'
|
||||
import { BaseHttpController, controller, httpGet, httpPost } from 'inversify-express-utils'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { HttpServiceInterface } from '../../Service/Http/HttpServiceInterface'
|
||||
import { TYPES } from '../../Bootstrap/Types'
|
||||
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
|
||||
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
|
||||
|
||||
@controller('/v1/items', TYPES.AuthMiddleware)
|
||||
@controller('/v1/items', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
export class ItemsController extends BaseHttpController {
|
||||
constructor(@inject(TYPES.HTTPService) private httpService: HttpServiceInterface) {
|
||||
constructor(
|
||||
@inject(TYPES.ServiceProxy) private serviceProxy: ServiceProxyInterface,
|
||||
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
@httpPost('/')
|
||||
async sync(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(request, response, 'items/sync', request.body)
|
||||
await this.serviceProxy.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'items/sync'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpPost('/check-integrity')
|
||||
async checkIntegrity(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(request, response, 'items/check-integrity', request.body)
|
||||
await this.serviceProxy.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'items/check-integrity'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/:uuid')
|
||||
async getItem(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(request, response, `items/${request.params.uuid}`, request.body)
|
||||
await this.serviceProxy.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'items/:uuid', request.params.uuid),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,23 +2,37 @@ import { Request, Response } from 'express'
|
||||
import { inject } from 'inversify'
|
||||
import { BaseHttpController, controller, httpGet, httpPost } from 'inversify-express-utils'
|
||||
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { HttpServiceInterface } from '../../Service/Http/HttpServiceInterface'
|
||||
import { TYPES } from '../../Bootstrap/Types'
|
||||
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
|
||||
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
|
||||
|
||||
@controller('/v1/offline')
|
||||
export class OfflineController extends BaseHttpController {
|
||||
constructor(@inject(TYPES.HTTPService) private httpService: HttpServiceInterface) {
|
||||
constructor(
|
||||
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface,
|
||||
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
@httpGet('/features')
|
||||
async getOfflineFeatures(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, 'offline/features', request.body)
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'offline/features'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpPost('/subscription-tokens')
|
||||
async createOfflineSubscriptionToken(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, 'offline/subscription-tokens', request.body)
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'offline/subscription-tokens'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpPost('/payments/stripe-setup-intent')
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Request, Response } from 'express'
|
||||
import { inject } from 'inversify'
|
||||
import { all, BaseHttpController, controller, httpDelete, httpGet, httpPost } from 'inversify-express-utils'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { HttpServiceInterface } from '../../Service/Http/HttpServiceInterface'
|
||||
import { TYPES } from '../../Bootstrap/Types'
|
||||
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
|
||||
|
||||
@controller('/v1')
|
||||
export class PaymentsController extends BaseHttpController {
|
||||
constructor(@inject(TYPES.HTTPService) private httpService: HttpServiceInterface) {
|
||||
constructor(@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface) {
|
||||
super()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
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.AuthMiddleware)
|
||||
@controller('/v1/items/:item_id/revisions', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
export class RevisionsController extends BaseHttpController {
|
||||
@httpGet('/')
|
||||
async getRevisions(): Promise<results.JsonResult> {
|
||||
|
||||
@@ -1,34 +1,56 @@
|
||||
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 { HttpServiceInterface } from '../../Service/Http/HttpServiceInterface'
|
||||
import { TYPES } from '../../Bootstrap/Types'
|
||||
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
|
||||
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
|
||||
|
||||
@controller('/v1/sessions')
|
||||
export class SessionsController extends BaseHttpController {
|
||||
constructor(@inject(TYPES.HTTPService) private httpService: HttpServiceInterface) {
|
||||
constructor(
|
||||
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface,
|
||||
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
@httpGet('/', TYPES.AuthMiddleware)
|
||||
@httpGet('/', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async getSessions(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, 'sessions')
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'sessions'),
|
||||
)
|
||||
}
|
||||
|
||||
@httpDelete('/:uuid', TYPES.AuthMiddleware)
|
||||
@httpDelete('/:uuid', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async deleteSession(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, 'session', {
|
||||
uuid: request.params.uuid,
|
||||
})
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('DELETE', 'session'),
|
||||
{
|
||||
uuid: request.params.uuid,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@httpDelete('/', TYPES.AuthMiddleware)
|
||||
@httpDelete('/', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async deleteSessions(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, 'session/all')
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('DELETE', 'session/all'),
|
||||
)
|
||||
}
|
||||
|
||||
@httpPost('/refresh')
|
||||
async refreshSession(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, 'session/refresh', request.body)
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'session/refresh'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,32 +2,62 @@ 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 { HttpServiceInterface } from '../../Service/Http/HttpServiceInterface'
|
||||
import { TYPES } from '../../Bootstrap/Types'
|
||||
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
|
||||
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
|
||||
|
||||
@controller('/v1/subscription-invites')
|
||||
export class SubscriptionInvitesController extends BaseHttpController {
|
||||
constructor(@inject(TYPES.HTTPService) private httpService: HttpServiceInterface) {
|
||||
constructor(
|
||||
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface,
|
||||
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
@httpPost('/', TYPES.AuthMiddleware)
|
||||
@httpPost('/', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async inviteToSubscriptionSharing(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, 'subscription-invites', request.body)
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'subscription-invites'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/', TYPES.AuthMiddleware)
|
||||
@httpGet('/', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async listInvites(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, 'subscription-invites', request.body)
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'subscription-invites'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpDelete('/:inviteUuid', TYPES.AuthMiddleware)
|
||||
@httpDelete('/:inviteUuid', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async cancelSubscriptionSharing(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, `subscription-invites/${request.params.inviteUuid}`)
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'DELETE',
|
||||
'subscription-invites/:inviteUuid',
|
||||
request.params.inviteUuid,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@httpPost('/:inviteUuid/accept', TYPES.AuthMiddleware)
|
||||
@httpPost('/:inviteUuid/accept', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async acceptInvite(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, `subscription-invites/${request.params.inviteUuid}/accept`)
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'POST',
|
||||
'subscription-invites/:inviteUuid/accept',
|
||||
request.params.inviteUuid,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,17 +2,26 @@ import { Request, Response } from 'express'
|
||||
import { inject } from 'inversify'
|
||||
import { BaseHttpController, controller, httpPost } from 'inversify-express-utils'
|
||||
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { HttpServiceInterface } from '../../Service/Http/HttpServiceInterface'
|
||||
import { TYPES } from '../../Bootstrap/Types'
|
||||
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
|
||||
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
|
||||
|
||||
@controller('/v1/subscription-tokens')
|
||||
export class TokensController extends BaseHttpController {
|
||||
constructor(@inject(TYPES.HTTPService) private httpService: HttpServiceInterface) {
|
||||
constructor(
|
||||
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface,
|
||||
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
@httpPost('/', TYPES.AuthMiddleware)
|
||||
@httpPost('/', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async createToken(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, 'subscription-tokens', request.body)
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'subscription-tokens'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,14 +12,16 @@ import {
|
||||
results,
|
||||
} from 'inversify-express-utils'
|
||||
import { Logger } from 'winston'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { HttpServiceInterface } from '../../Service/Http/HttpServiceInterface'
|
||||
import { TYPES } from '../../Bootstrap/Types'
|
||||
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
|
||||
import { TokenAuthenticationMethod } from '../TokenAuthenticationMethod'
|
||||
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
|
||||
|
||||
@controller('/v1/users')
|
||||
export class UsersController extends BaseHttpController {
|
||||
constructor(
|
||||
@inject(TYPES.HTTPService) private httpService: HttpServiceInterface,
|
||||
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface,
|
||||
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
|
||||
@inject(TYPES.Logger) private logger: Logger,
|
||||
) {
|
||||
super()
|
||||
@@ -35,12 +37,17 @@ export class UsersController extends BaseHttpController {
|
||||
await this.httpService.callPaymentsServer(request, response, 'api/pro_users/send-activation-code', request.body)
|
||||
}
|
||||
|
||||
@httpPatch('/:userId', TYPES.AuthMiddleware)
|
||||
@httpPatch('/:userId', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async updateUser(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, `users/${request.params.userId}`, request.body)
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('PATCH', 'users/:userId', request.params.userId),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpPut('/:userUuid/password', TYPES.AuthMiddleware)
|
||||
@httpPut('/:userUuid/password', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async changePassword(request: Request, response: Response): Promise<void> {
|
||||
this.logger.debug(
|
||||
'[DEPRECATED] use endpoint /v1/users/:userUuid/attributes/credentials instead of /v1/users/:userUuid/password',
|
||||
@@ -49,107 +56,198 @@ export class UsersController extends BaseHttpController {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
`users/${request.params.userUuid}/attributes/credentials`,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'PUT',
|
||||
'users/:userUuid/attributes/credentials',
|
||||
request.params.userUuid,
|
||||
),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpPut('/:userUuid/attributes/credentials', TYPES.AuthMiddleware)
|
||||
@httpPut('/:userUuid/attributes/credentials', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async changeCredentials(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
`users/${request.params.userUuid}/attributes/credentials`,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'PUT',
|
||||
'users/:userUuid/attributes/credentials',
|
||||
request.params.userUuid,
|
||||
),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/:userId/params', TYPES.AuthMiddleware)
|
||||
@httpGet('/:userId/params', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async getKeyParams(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, 'auth/params')
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'auth/params'),
|
||||
)
|
||||
}
|
||||
|
||||
@all('/:userId/mfa', TYPES.AuthMiddleware)
|
||||
@all('/:userId/mfa', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async blockMFA(): Promise<results.StatusCodeResult> {
|
||||
return this.statusCode(401)
|
||||
}
|
||||
|
||||
@httpPost('/:userUuid/integrations/listed', TYPES.AuthMiddleware)
|
||||
@httpPost('/:userUuid/integrations/listed', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async createListedAccount(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, 'listed', request.body)
|
||||
}
|
||||
|
||||
@httpPost('/')
|
||||
async register(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, 'auth', request.body)
|
||||
}
|
||||
|
||||
@httpGet('/:userUuid/settings', TYPES.AuthMiddleware)
|
||||
async listSettings(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, `users/${request.params.userUuid}/settings`)
|
||||
}
|
||||
|
||||
@httpPut('/:userUuid/settings', TYPES.AuthMiddleware)
|
||||
async putSetting(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, `users/${request.params.userUuid}/settings`, request.body)
|
||||
}
|
||||
|
||||
@httpGet('/:userUuid/settings/:settingName', TYPES.AuthMiddleware)
|
||||
async getSetting(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
`users/${request.params.userUuid}/settings/${request.params.settingName}`,
|
||||
)
|
||||
}
|
||||
|
||||
@httpDelete('/:userUuid/settings/:settingName', TYPES.AuthMiddleware)
|
||||
async deleteSetting(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
`users/${request.params.userUuid}/settings/${request.params.settingName}`,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'listed'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/:userUuid/subscription-settings/:subscriptionSettingName', TYPES.AuthMiddleware)
|
||||
@httpPost('/')
|
||||
async register(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'auth'),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/:userUuid/settings', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async listSettings(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'GET',
|
||||
'users/:userUuid/settings',
|
||||
request.params.userUuid,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@httpPut('/:userUuid/settings', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async putSetting(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'PUT',
|
||||
'users/:userUuid/settings',
|
||||
request.params.userUuid,
|
||||
),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/:userUuid/settings/:settingName', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async getSetting(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'GET',
|
||||
'users/:userUuid/settings/:settingName',
|
||||
request.params.userUuid,
|
||||
request.params.settingName,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@httpDelete('/:userUuid/settings/:settingName', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async deleteSetting(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'DELETE',
|
||||
'users/:userUuid/settings/:settingName',
|
||||
request.params.userUuid,
|
||||
request.params.settingName,
|
||||
),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/:userUuid/subscription-settings/:subscriptionSettingName', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async getSubscriptionSetting(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
`users/${request.params.userUuid}/subscription-settings/${request.params.subscriptionSettingName}`,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'GET',
|
||||
'users/:userUuid/subscription-settings/:subscriptionSettingName',
|
||||
request.params.userUuid,
|
||||
request.params.subscriptionSettingName,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/:userUuid/features', TYPES.AuthMiddleware)
|
||||
@httpGet('/:userUuid/features', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async getFeatures(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, `users/${request.params.userUuid}/features`)
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'GET',
|
||||
'users/:userUuid/features',
|
||||
request.params.userUuid,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/:userUuid/subscription', TYPES.AuthMiddleware)
|
||||
@httpGet('/:userUuid/subscription', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async getSubscription(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, `users/${request.params.userUuid}/subscription`)
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'GET',
|
||||
'users/:userUuid/subscription',
|
||||
request.params.userUuid,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@httpGet('/subscription', TYPES.SubscriptionTokenAuthMiddleware)
|
||||
async getSubscriptionBySubscriptionToken(request: Request, response: Response): Promise<void> {
|
||||
if (response.locals.tokenAuthenticationMethod === TokenAuthenticationMethod.OfflineSubscriptionToken) {
|
||||
await this.httpService.callAuthServer(request, response, 'offline/users/subscription')
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'offline/users/subscription'),
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
await this.httpService.callAuthServer(request, response, `users/${response.locals.userUuid}/subscription`)
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'GET',
|
||||
'users/:userUuid/subscription',
|
||||
response.locals.user.uuid,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@httpDelete('/:userUuid', TYPES.AuthMiddleware)
|
||||
@httpDelete('/:userUuid', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async deleteUser(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callPaymentsServer(request, response, 'api/account', request.body)
|
||||
}
|
||||
|
||||
@httpPost('/:userUuid/requests', TYPES.AuthMiddleware)
|
||||
@httpPost('/:userUuid/requests', TYPES.RequiredCrossServiceTokenMiddleware)
|
||||
async submitRequest(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callAuthServer(request, response, `users/${request.params.userUuid}/requests`, request.body)
|
||||
await this.httpService.callAuthServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'POST',
|
||||
'users/:userUuid/requests',
|
||||
request.params.userUuid,
|
||||
),
|
||||
request.body,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user