Compare commits

...

33 Commits

Author SHA1 Message Date
standardci
f9183b4c62 chore(release): publish new version
- @standardnotes/analytics@2.22.5
 - @standardnotes/api-gateway@1.59.0
 - @standardnotes/auth-server@1.112.0
 - @standardnotes/domain-core@1.16.0
 - @standardnotes/files-server@1.13.0
 - @standardnotes/home-server@1.6.0
 - @standardnotes/revisions-server@1.17.0
 - @standardnotes/scheduler-server@1.18.5
 - @standardnotes/settings@1.21.5
 - @standardnotes/syncing-server@1.38.0
 - @standardnotes/websockets-server@1.7.5
2023-05-29 12:59:40 +00:00
Karol Sójko
c7d575a0ff feat: add files server as a service to home-server (#614)
* wip: add files server as a service to home-server

* wip: introduce home-server controllers without inversify-express-utils decorators. Move in progress

* fix(auth): move remaining home server controllers

* fix(syncing-server): home server controllers

* fix(revisions): home server controllers

* fix: specs

* fix: import for legacy controller

* fix: remove router debug
2023-05-29 14:45:49 +02:00
Karol Sójko
a575e62519 fix: waiting for home server to start in ci 2023-05-29 14:05:15 +02:00
Karol Sójko
3761d60f41 fix: add VALET_TOKEN_SECRET env var to ci e2e test suite 2023-05-29 13:29:07 +02:00
standardci
fd629d43ba chore(release): publish new version
- @standardnotes/home-server@1.5.1
 - @standardnotes/revisions-server@1.16.1
2023-05-25 11:44:41 +00:00
Karol Sójko
76b1cb0f5a fix(revisions): container bindings 2023-05-25 13:17:53 +02:00
standardci
2f94abc9f7 chore(release): publish new version
- @standardnotes/api-gateway@1.58.0
 - @standardnotes/auth-server@1.111.0
 - @standardnotes/home-server@1.5.0
 - @standardnotes/revisions-server@1.16.0
2023-05-25 11:11:19 +00:00
Karol Sójko
c70040fe5d feat: add revisions service to home server (#613)
* feat: add revisions service to home server

* fix: make e2e test suite on home server non-optional

* fix(auth): specs
2023-05-25 12:57:05 +02:00
standardci
4b8a9e448a chore(release): publish new version
- @standardnotes/api-gateway@1.57.0
 - @standardnotes/auth-server@1.110.0
 - @standardnotes/home-server@1.4.4
2023-05-25 07:56:05 +00:00
Karol Sójko
1e4c7d0f31 feat: refactor auth middleware to handle required and optional cross service token scenarios (#612)
* wip: fix variable name

* wip: remove redundant middleware in auth

* fix: auth middleware refactor

* fix(auth): fetching user for key params

* fix(auth): specs

* fix(auth): registering session controller endpoints
2023-05-25 09:43:00 +02:00
Karol Sójko
ec75795a02 fix: session tokens ttl on home-server e2e suite 2023-05-24 13:56:09 +02:00
standardci
ad26b64b28 chore(release): publish new version
- @standardnotes/auth-server@1.109.2
 - @standardnotes/home-server@1.4.3
2023-05-18 10:55:29 +00:00
Karol Sójko
9e4715ebbd fix: skip paid features on the home server e2e test suite 2023-05-18 12:42:20 +02:00
Karol Sójko
cc612296d0 fix(auth): changing user credentials to work both on http proxy and direct code call 2023-05-18 12:42:20 +02:00
standardci
1148b3948c chore(release): publish new version
- @standardnotes/api-gateway@1.56.2
 - @standardnotes/home-server@1.4.2
2023-05-18 09:19:56 +00:00
Karol Sójko
c7e605fd60 fix(api-gateway): pkce endpoints resolution for direct code calls 2023-05-18 11:03:13 +02:00
Karol Sójko
4ab32c670e fix(api-gateway): decorating responses for direct call proxy 2023-05-18 11:03:12 +02:00
standardci
2d810568a8 chore(release): publish new version
- @standardnotes/api-gateway@1.56.1
 - @standardnotes/auth-server@1.109.1
 - @standardnotes/files-server@1.12.5
 - @standardnotes/home-server@1.4.1
 - @standardnotes/revisions-server@1.15.1
 - @standardnotes/syncing-server@1.37.1
2023-05-18 06:07:38 +00:00
Karol Sójko
b8353aa817 chore: add metadata to winston loggers 2023-05-18 07:54:36 +02:00
standardci
7924f63e28 chore(release): publish new version
- @standardnotes/api-gateway@1.56.0
 - @standardnotes/auth-server@1.109.0
 - @standardnotes/home-server@1.4.0
 - @standardnotes/syncing-server@1.37.0
2023-05-17 13:50:56 +00:00
Karol Sójko
b3b617ea0b feat: bundle syncing server into home server setup (#611)
* feat(syncing-server): move inversify express controllers to new structure

* wip: syncing server service binding for home server

* fix(syncing-server): container bindings

* fix(api-gateway): rename https service to service proxy

* fix: proxying requests to syncing server

* fix: responses and version binding
2023-05-17 15:38:12 +02:00
standardci
18a5071618 chore(release): publish new version
- @standardnotes/auth-server@1.108.0
 - @standardnotes/home-server@1.3.1
 - @standardnotes/revisions-server@1.15.0
 - @standardnotes/syncing-server@1.36.0
2023-05-17 10:07:01 +00:00
Karol Sójko
fea58029b9 feat(auth): move inversify express controllers to different structure (#610)
* wip: move valet token controller

* wip: move users controller

* wip: move admin controller

* wip: move subscription tokens controller

* wip: move subscription settings controller

* wip: move settings controller

* wip: move middleware

* wip: move session controller

* wip: move offline controller

* wip: move listed controller

* wip: move internal controller

* wip: move healthcheck controller

* wip: move features controller

* fix: bind inversify express controllers only for home server

* fix: inversify deps
2023-05-17 11:54:18 +02:00
standardci
e748723209 chore(release): publish new version
- @standardnotes/analytics@2.22.4
 - @standardnotes/api-gateway@1.55.0
 - @standardnotes/auth-server@1.107.0
 - @standardnotes/domain-events-infra@1.12.0
 - @standardnotes/domain-events@2.111.0
 - @standardnotes/event-store@1.8.3
 - @standardnotes/files-server@1.12.4
 - @standardnotes/home-server@1.3.0
 - @standardnotes/revisions-server@1.14.4
 - @standardnotes/scheduler-server@1.18.4
 - @standardnotes/syncing-server@1.35.4
 - @standardnotes/websockets-server@1.7.4
2023-05-17 07:39:38 +00:00
Karol Sójko
8a47d81936 feat: add direct event handling for home server (#608)
* feat(domain-events-infra): add direct call event message handler

* feat: add direct publishing of events into handlers

* fix: validating sessions with direct calls
2023-05-17 09:23:48 +02:00
standardci
7ae9f5694d chore(release): publish new version
- @standardnotes/analytics@2.22.3
 - @standardnotes/api-gateway@1.54.0
 - @standardnotes/auth-server@1.106.0
 - @standardnotes/domain-core@1.15.0
 - @standardnotes/files-server@1.12.3
 - @standardnotes/home-server@1.2.0
 - @standardnotes/revisions-server@1.14.3
 - @standardnotes/scheduler-server@1.18.3
 - @standardnotes/settings@1.21.4
 - @standardnotes/syncing-server@1.35.3
 - @standardnotes/websockets-server@1.7.3
2023-05-16 09:59:30 +00:00
Karol Sójko
9031379469 chore: fix test suite names 2023-05-16 11:44:43 +02:00
Karol Sójko
dc71e6777f feat: home-server package initial setup with Api Gateway and Auth services (#605)
* fix(api-gateway): reduce exports

* wip controllers

* fix: imports of controllers

* fix(api-gateway): rename http service interface to proxy interface

* wip: self-registering services and controllers

* wip: add registering controller method bindings and services in container

* feat: merge two services together

* wip: resolving endpoints to direct code calls

* wip: bind controller container to a singleton

* fix: controller binding to instantiate and self-register on controller container

* fix: move signout endpoint to auth controller

* wip: define inversify controllers in the controller container

* fix(auth): bind inversify controllers to controller container

* fix(auth): linter issues

* fix(auth): specs

* fix(auth): inversify controllers bindings

* wip: endpoint resolving

* wip: add endpoint for more auth controllers

* wip: add sessions controller endpoint resolvings

* wip: add subscription invites endpoint resolvings

* wip: add subscription tokens endpoint resolvings

* wip: add all binding for auth server controllers

* wip: fix migrations path

* fix: configure default env vars and ci setup
2023-05-16 11:38:56 +02:00
Karol Sójko
89eb798fa8 chore: fix nohup execution 2023-05-16 11:23:01 +02:00
Karol Sójko
4304e068b9 chore: run home server in the background with nohup 2023-05-16 11:22:09 +02:00
Karol Sójko
126bc6de6a chore: fix home server e2e suite with non installed driver 2023-05-16 11:13:13 +02:00
Karol Sójko
c2b9107f13 chore: add running home server e2e test suite without docker 2023-05-16 11:07:37 +02:00
Karol Sójko
1471f4a839 chore: disable running e2e for home server with docker 2023-05-16 11:06:10 +02:00
321 changed files with 6302 additions and 3927 deletions

View File

@@ -15,6 +15,7 @@ DB_TYPE=mysql
REDIS_PORT=6379
REDIS_HOST=cache
CACHE_TYPE=redis
########
# KEYS #

View File

@@ -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

20
.pnp.cjs generated
View File

@@ -4623,8 +4623,15 @@ const RAW_RUNTIME_STATE =
"packageDependencies": [\
["@standardnotes/home-server", "workspace:packages/home-server"],\
["@standardnotes/api-gateway", "workspace:packages/api-gateway"],\
["@standardnotes/auth-server", "workspace:packages/auth"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@standardnotes/files-server", "workspace:packages/files"],\
["@standardnotes/revisions-server", "workspace:packages/revisions"],\
["@standardnotes/syncing-server", "workspace:packages/syncing-server"],\
["@types/cors", "npm:2.8.13"],\
["@types/express", "npm:4.17.17"],\
["@types/prettyjson", "npm:0.0.30"],\
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.59.2"],\
["@typescript-eslint/parser", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.59.2"],\
["cors", "npm:2.8.5"],\
@@ -4637,6 +4644,7 @@ const RAW_RUNTIME_STATE =
["inversify", "npm:6.0.1"],\
["inversify-express-utils", "npm:6.4.3"],\
["prettier", "npm:2.8.8"],\
["prettyjson", "npm:1.2.5"],\
["reflect-metadata", "npm:0.1.13"],\
["typescript", "patch:typescript@npm%3A5.0.4#optional!builtin<compat/typescript>::version=5.0.4&hash=b5f058"],\
["winston", "npm:3.8.2"]\
@@ -4708,7 +4716,6 @@ const RAW_RUNTIME_STATE =
["@types/cors", "npm:2.8.13"],\
["@types/dotenv", "npm:8.2.0"],\
["@types/express", "npm:4.17.17"],\
["@types/inversify-express-utils", "npm:2.0.0"],\
["@types/jest", "npm:29.5.1"],\
["@types/newrelic", "npm:9.13.0"],\
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.59.2"],\
@@ -4892,7 +4899,6 @@ const RAW_RUNTIME_STATE =
["@types/cors", "npm:2.8.13"],\
["@types/dotenv", "npm:8.2.0"],\
["@types/express", "npm:4.17.17"],\
["@types/inversify-express-utils", "npm:2.0.0"],\
["@types/jest", "npm:29.5.1"],\
["@types/jsonwebtoken", "npm:9.0.2"],\
["@types/newrelic", "npm:9.13.0"],\
@@ -5294,16 +5300,6 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["@types/inversify-express-utils", [\
["npm:2.0.0", {\
"packageLocation": "./.yarn/cache/@types-inversify-express-utils-npm-2.0.0-e78182955d-9841bfddff.zip/node_modules/@types/inversify-express-utils/",\
"packageDependencies": [\
["@types/inversify-express-utils", "npm:2.0.0"],\
["inversify-express-utils", "npm:6.4.3"]\
],\
"linkType": "HARD"\
}]\
]],\
["@types/ioredis", [\
["npm:5.0.0", {\
"packageLocation": "./.yarn/cache/@types-ioredis-npm-5.0.0-6efa70abfa-439770c9da.zip/node_modules/@types/ioredis/",\

View File

@@ -3,6 +3,18 @@
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

View File

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

View File

@@ -3,6 +3,53 @@
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

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/api-gateway",
"version": "1.53.1",
"version": "1.59.0",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -8,20 +8,25 @@ 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 { 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,6 +44,7 @@ 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)
@@ -57,14 +63,14 @@ export class ContainerConfigLoader {
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)
@@ -72,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) {
@@ -89,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
}

View 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()
}
}

View File

@@ -15,13 +15,15 @@ export 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

View File

@@ -1,3 +1,2 @@
export * from './Container'
export * from './Env'
export * from './Service'
export * from './Types'

View File

@@ -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

View File

@@ -2,14 +2,14 @@ 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 { 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)
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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

View File

@@ -1,6 +1,5 @@
export * from './AuthMiddleware'
export * from './HealthCheckController'
export * from './LegacyController'
export * from './SubscriptionTokenAuthMiddleware'
export * from './TokenAuthenticationMethod'
export * from './WebSocketAuthMiddleware'

View File

@@ -2,37 +2,51 @@ 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 { 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,
)
}
}

View File

@@ -3,35 +3,48 @@ 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 { 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,
)
}
}

View File

@@ -3,16 +3,25 @@ import { inject } from 'inversify'
import { BaseHttpController, controller, httpPost } from 'inversify-express-utils'
import { TYPES } from '../../Bootstrap/Types'
import { HttpServiceInterface } from '../../Service/Http/HttpServiceInterface'
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,
)
}
}

View File

@@ -2,11 +2,11 @@ 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 { 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()
}

View File

@@ -2,26 +2,45 @@ 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 { 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,
)
}
}

View File

@@ -3,22 +3,36 @@ 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 { 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')

View File

@@ -2,11 +2,11 @@ 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 { 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()
}

View File

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

View File

@@ -2,33 +2,55 @@ 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 { 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,
)
}
}

View File

@@ -3,31 +3,61 @@ 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 { 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,
),
)
}
}

View File

@@ -3,16 +3,25 @@ import { inject } from 'inversify'
import { BaseHttpController, controller, httpPost } from 'inversify-express-utils'
import { TYPES } from '../../Bootstrap/Types'
import { HttpServiceInterface } from '../../Service/Http/HttpServiceInterface'
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,
)
}
}

View File

@@ -13,13 +13,15 @@ import {
} from 'inversify-express-utils'
import { Logger } from 'winston'
import { TYPES } from '../../Bootstrap/Types'
import { HttpServiceInterface } from '../../Service/Http/HttpServiceInterface'
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,
)
}
}

View File

@@ -4,20 +4,27 @@ import { BaseHttpController, controller, httpDelete, httpPost } from 'inversify-
import { Logger } from 'winston'
import { TYPES } from '../../Bootstrap/Types'
import { HttpServiceInterface } from '../../Service/Http/HttpServiceInterface'
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
@controller('/v1/sockets')
export class WebSocketsController 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()
}
@httpPost('/tokens', TYPES.AuthMiddleware)
@httpPost('/tokens', TYPES.RequiredCrossServiceTokenMiddleware)
async createWebSocketConnectionToken(request: Request, response: Response): Promise<void> {
await this.httpService.callWebSocketServer(request, response, 'sockets/tokens', request.body)
await this.httpService.callWebSocketServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'sockets/tokens'),
request.body,
)
}
@httpPost('/connections', TYPES.WebSocketAuthMiddleware)
@@ -33,7 +40,11 @@ export class WebSocketsController extends BaseHttpController {
await this.httpService.callWebSocketServer(
request,
response,
`sockets/connections/${request.headers.connectionid}`,
this.endpointResolver.resolveEndpointOrMethodIdentifier(
'POST',
'sockets/connections/:connectionId',
request.headers.connectionid as string,
),
request.body,
)
}
@@ -51,7 +62,11 @@ export class WebSocketsController extends BaseHttpController {
await this.httpService.callWebSocketServer(
request,
response,
`sockets/connections/${request.headers.connectionid}`,
this.endpointResolver.resolveEndpointOrMethodIdentifier(
'DELETE',
'sockets/connections/:connectionId',
request.headers.connectionid as string,
),
request.body,
)
}

View File

@@ -3,21 +3,35 @@ import { inject } from 'inversify'
import { BaseHttpController, controller, httpPost } from 'inversify-express-utils'
import { TYPES } from '../../Bootstrap/Types'
import { HttpServiceInterface } from '../../Service/Http/HttpServiceInterface'
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
@controller('/v2')
export class ActionsControllerV2 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/pkce_sign_in', request.body)
await this.serviceProxy.callAuthServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'auth/pkce_sign_in'),
request.body,
)
}
@httpPost('/login-params')
@httpPost('/login-params', TYPES.OptionalCrossServiceTokenMiddleware)
async loginParams(request: Request, response: Response): Promise<void> {
await this.httpService.callAuthServer(request, response, 'auth/pkce_params', request.body)
await this.serviceProxy.callAuthServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'auth/pkce_params'),
request.body,
)
}
}

View File

@@ -2,11 +2,11 @@ import { Request, Response } from 'express'
import { BaseHttpController, controller, httpDelete, httpGet, httpPatch, httpPost } from 'inversify-express-utils'
import { inject } from 'inversify'
import { TYPES } from '../../Bootstrap/Types'
import { HttpServiceInterface } from '../../Service/Http/HttpServiceInterface'
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
@controller('/v2')
export class PaymentsControllerV2 extends BaseHttpController {
constructor(@inject(TYPES.HTTPService) private httpService: HttpServiceInterface) {
constructor(@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface) {
super()
}

View File

@@ -3,34 +3,56 @@ import { inject } from 'inversify'
import { BaseHttpController, controller, httpDelete, httpGet } from 'inversify-express-utils'
import { TYPES } from '../../Bootstrap/Types'
import { HttpServiceInterface } from '../../Service/Http/HttpServiceInterface'
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface'
@controller('/v2/items/:itemUuid/revisions', TYPES.AuthMiddleware)
@controller('/v2/items/:itemUuid/revisions', TYPES.RequiredCrossServiceTokenMiddleware)
export class RevisionsControllerV2 extends BaseHttpController {
constructor(@inject(TYPES.HTTPService) private httpService: HttpServiceInterface) {
constructor(
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
) {
super()
}
@httpGet('/')
async getRevisions(request: Request, response: Response): Promise<void> {
await this.httpService.callRevisionsServer(request, response, `items/${request.params.itemUuid}/revisions`)
await this.httpService.callRevisionsServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier(
'GET',
'items/:itemUuid/revisions',
request.params.itemUuid,
),
)
}
@httpGet('/:id')
@httpGet('/:uuid')
async getRevision(request: Request, response: Response): Promise<void> {
await this.httpService.callRevisionsServer(
request,
response,
`items/${request.params.itemUuid}/revisions/${request.params.id}`,
this.endpointResolver.resolveEndpointOrMethodIdentifier(
'GET',
'items/:itemUuid/revisions/:id',
request.params.itemUuid,
request.params.uuid,
),
)
}
@httpDelete('/:id')
@httpDelete('/:uuid')
async deleteRevision(request: Request, response: Response): Promise<void> {
await this.httpService.callRevisionsServer(
request,
response,
`items/${request.params.itemUuid}/revisions/${request.params.id}`,
this.endpointResolver.resolveEndpointOrMethodIdentifier(
'DELETE',
'items/:itemUuid/revisions/:id',
request.params.itemUuid,
request.params.uuid,
),
)
}
}

View File

@@ -1,2 +0,0 @@
export * from './InMemory/InMemoryCrossServiceTokenCache'
export * from './Redis/RedisCrossServiceTokenCache'

View File

@@ -6,10 +6,10 @@ import { Logger } from 'winston'
import { TYPES } from '../../Bootstrap/Types'
import { CrossServiceTokenCacheInterface } from '../Cache/CrossServiceTokenCacheInterface'
import { HttpServiceInterface } from './HttpServiceInterface'
import { ServiceProxyInterface } from './ServiceProxyInterface'
@injectable()
export class HttpService implements HttpServiceInterface {
export class HttpServiceProxy implements ServiceProxyInterface {
constructor(
@inject(TYPES.HTTPClient) private httpClient: AxiosInstance,
@inject(TYPES.AUTH_SERVER_URL) private authServerUrl: string,
@@ -24,19 +24,43 @@ export class HttpService implements HttpServiceInterface {
@inject(TYPES.Logger) private logger: Logger,
) {}
async validateSession(
authorizationHeaderValue: string,
): Promise<{ status: number; data: unknown; headers: { contentType: string } }> {
const authResponse = await this.httpClient.request({
method: 'POST',
headers: {
Authorization: authorizationHeaderValue,
Accept: 'application/json',
},
validateStatus: (status: number) => {
return status >= 200 && status < 500
},
url: `${this.authServerUrl}/sessions/validate`,
})
return {
status: authResponse.status,
data: authResponse.data,
headers: {
contentType: authResponse.headers['content-type'] as string,
},
}
}
async callSyncingServer(
request: Request,
response: Response,
endpoint: string,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
): Promise<void> {
await this.callServer(this.syncingServerJsUrl, request, response, endpoint, payload)
await this.callServer(this.syncingServerJsUrl, request, response, endpointOrMethodIdentifier, payload)
}
async callRevisionsServer(
request: Request,
response: Response,
endpoint: string,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
): Promise<void> {
if (!this.revisionsServerUrl) {
@@ -44,31 +68,37 @@ export class HttpService implements HttpServiceInterface {
return
}
await this.callServer(this.revisionsServerUrl, request, response, endpoint, payload)
await this.callServer(this.revisionsServerUrl, request, response, endpointOrMethodIdentifier, payload)
}
async callLegacySyncingServer(
request: Request,
response: Response,
endpoint: string,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
): Promise<void> {
await this.callServerWithLegacyFormat(this.syncingServerJsUrl, request, response, endpoint, payload)
await this.callServerWithLegacyFormat(
this.syncingServerJsUrl,
request,
response,
endpointOrMethodIdentifier,
payload,
)
}
async callAuthServer(
request: Request,
response: Response,
endpoint: string,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
): Promise<void> {
await this.callServer(this.authServerUrl, request, response, endpoint, payload)
await this.callServer(this.authServerUrl, request, response, endpointOrMethodIdentifier, payload)
}
async callEmailServer(
request: Request,
response: Response,
endpoint: string,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
): Promise<void> {
if (!this.emailServerUrl) {
@@ -77,13 +107,13 @@ export class HttpService implements HttpServiceInterface {
return
}
await this.callServer(this.emailServerUrl, request, response, endpoint, payload)
await this.callServer(this.emailServerUrl, request, response, endpointOrMethodIdentifier, payload)
}
async callWebSocketServer(
request: Request,
response: Response,
endpoint: string,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
): Promise<void> {
if (!this.webSocketServerUrl) {
@@ -92,13 +122,13 @@ export class HttpService implements HttpServiceInterface {
return
}
await this.callServer(this.webSocketServerUrl, request, response, endpoint, payload)
await this.callServer(this.webSocketServerUrl, request, response, endpointOrMethodIdentifier, payload)
}
async callPaymentsServer(
request: Request,
response: Response,
endpoint: string,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
): Promise<void> {
if (!this.paymentsServerUrl) {
@@ -106,23 +136,29 @@ export class HttpService implements HttpServiceInterface {
return
}
await this.callServerWithLegacyFormat(this.paymentsServerUrl, request, response, endpoint, payload)
await this.callServerWithLegacyFormat(
this.paymentsServerUrl,
request,
response,
endpointOrMethodIdentifier,
payload,
)
}
async callAuthServerWithLegacyFormat(
request: Request,
response: Response,
endpoint: string,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
): Promise<void> {
await this.callServerWithLegacyFormat(this.authServerUrl, request, response, endpoint, payload)
await this.callServerWithLegacyFormat(this.authServerUrl, request, response, endpointOrMethodIdentifier, payload)
}
private async getServerResponse(
serverUrl: string,
request: Request,
response: Response,
endpoint: string,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
): Promise<AxiosResponse | undefined> {
try {
@@ -142,7 +178,7 @@ export class HttpService implements HttpServiceInterface {
headers['X-Auth-Offline-Token'] = response.locals.offlineAuthToken
}
this.logger.debug(`Calling [${request.method}] ${serverUrl}/${endpoint},
this.logger.debug(`Calling [${request.method}] ${serverUrl}/${endpointOrMethodIdentifier},
headers: ${JSON.stringify(headers)},
query: ${JSON.stringify(request.query)},
payload: ${JSON.stringify(payload)}`)
@@ -150,7 +186,7 @@ export class HttpService implements HttpServiceInterface {
const serviceResponse = await this.httpClient.request({
method: request.method as Method,
headers,
url: `${serverUrl}/${endpoint}`,
url: `${serverUrl}/${endpointOrMethodIdentifier}`,
data: this.getRequestData(payload),
maxContentLength: Infinity,
maxBodyLength: Infinity,
@@ -172,7 +208,9 @@ export class HttpService implements HttpServiceInterface {
? JSON.stringify((error as AxiosError).response?.data)
: (error as Error).message
this.logger.error(`Could not pass the request to ${serverUrl}/${endpoint} on underlying service: ${errorMessage}`)
this.logger.error(
`Could not pass the request to ${serverUrl}/${endpointOrMethodIdentifier} on underlying service: ${errorMessage}`,
)
this.logger.debug('Response error: %O', (error as AxiosError).response ?? error)
@@ -195,10 +233,16 @@ export class HttpService implements HttpServiceInterface {
serverUrl: string,
request: Request,
response: Response,
endpoint: string,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
): Promise<void> {
const serviceResponse = await this.getServerResponse(serverUrl, request, response, endpoint, payload)
const serviceResponse = await this.getServerResponse(
serverUrl,
request,
response,
endpointOrMethodIdentifier,
payload,
)
this.logger.debug(`Response from underlying server: ${JSON.stringify(serviceResponse?.data)},
headers: ${JSON.stringify(serviceResponse?.headers)}`)
@@ -218,7 +262,7 @@ export class HttpService implements HttpServiceInterface {
response.status(serviceResponse.status).send({
meta: {
auth: {
userUuid: response.locals.userUuid,
userUuid: response.locals.user?.uuid,
roles: response.locals.roles,
},
server: {
@@ -233,10 +277,16 @@ export class HttpService implements HttpServiceInterface {
serverUrl: string,
request: Request,
response: Response,
endpoint: string,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
): Promise<void> {
const serviceResponse = await this.getServerResponse(serverUrl, request, response, endpoint, payload)
const serviceResponse = await this.getServerResponse(
serverUrl,
request,
response,
endpointOrMethodIdentifier,
payload,
)
if (!serviceResponse) {
return

View File

@@ -1,52 +1,59 @@
import { Request, Response } from 'express'
export interface HttpServiceInterface {
export interface ServiceProxyInterface {
callEmailServer(
request: Request,
response: Response,
endpoint: string,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
): Promise<void>
callAuthServer(
request: Request,
response: Response,
endpoint: string,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
): Promise<void>
callAuthServerWithLegacyFormat(
request: Request,
response: Response,
endpoint: string,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
): Promise<void>
callRevisionsServer(
request: Request,
response: Response,
endpoint: string,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
): Promise<void>
callSyncingServer(
request: Request,
response: Response,
endpoint: string,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
): Promise<void>
callLegacySyncingServer(
request: Request,
response: Response,
endpoint: string,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
): Promise<void>
callPaymentsServer(
request: Request,
response: Response,
endpoint: string,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
): Promise<void>
callWebSocketServer(
request: Request,
response: Response,
endpoint: string,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
): Promise<void>
validateSession(authorizationHeaderValue: string): Promise<{
status: number
data: unknown
headers: {
contentType: string
}
}>
}

View File

@@ -0,0 +1,130 @@
import { Request, Response } from 'express'
import { ServiceProxyInterface } from '../Http/ServiceProxyInterface'
import { ServiceContainerInterface, ServiceIdentifier } from '@standardnotes/domain-core'
export class DirectCallServiceProxy implements ServiceProxyInterface {
constructor(private serviceContainer: ServiceContainerInterface, private filesServerUrl: string) {}
async validateSession(
authorizationHeaderValue: string,
): Promise<{ status: number; data: unknown; headers: { contentType: string } }> {
const authService = this.serviceContainer.get(ServiceIdentifier.create(ServiceIdentifier.NAMES.Auth).getValue())
if (!authService) {
throw new Error('Auth service not found')
}
const serviceResponse = (await authService.handleRequest(
{
headers: {
authorization: authorizationHeaderValue,
},
} as never,
{} as never,
'auth.sessions.validate',
)) as {
statusCode: number
json: Record<string, unknown>
}
return {
status: serviceResponse.statusCode,
data: serviceResponse.json,
headers: { contentType: 'application/json' },
}
}
async callEmailServer(_request: Request, _response: Response, _endpointOrMethodIdentifier: string): Promise<void> {
throw new Error('Email server is not available.')
}
async callAuthServer(request: never, response: never, endpointOrMethodIdentifier: string): Promise<void> {
const authService = this.serviceContainer.get(ServiceIdentifier.create(ServiceIdentifier.NAMES.Auth).getValue())
if (!authService) {
throw new Error('Auth service not found')
}
const serviceResponse = (await authService.handleRequest(request, response, endpointOrMethodIdentifier)) as {
statusCode: number
json: Record<string, unknown>
}
this.sendDecoratedResponse(response, serviceResponse)
}
async callAuthServerWithLegacyFormat(
_request: Request,
_response: Response,
_endpointOrMethodIdentifier: string,
): Promise<void> {
throw new Error('Legacy auth endpoints are no longer available.')
}
async callRevisionsServer(request: never, response: never, endpointOrMethodIdentifier: string): Promise<void> {
const service = this.serviceContainer.get(ServiceIdentifier.create(ServiceIdentifier.NAMES.Revisions).getValue())
if (!service) {
throw new Error('Revisions service not found')
}
const serviceResponse = (await service.handleRequest(request, response, endpointOrMethodIdentifier)) as {
statusCode: number
json: Record<string, unknown>
}
this.sendDecoratedResponse(response, serviceResponse)
}
async callSyncingServer(request: never, response: never, endpointOrMethodIdentifier: string): Promise<void> {
const service = this.serviceContainer.get(
ServiceIdentifier.create(ServiceIdentifier.NAMES.SyncingServer).getValue(),
)
if (!service) {
throw new Error('Syncing service not found')
}
const serviceResponse = (await service.handleRequest(request, response, endpointOrMethodIdentifier)) as {
statusCode: number
json: Record<string, unknown>
}
this.sendDecoratedResponse(response, serviceResponse)
}
async callLegacySyncingServer(
_request: Request,
_response: Response,
_endpointOrMethodIdentifier: string,
): Promise<void> {
throw new Error('Legacy syncing server endpoints are no longer available.')
}
async callPaymentsServer(_request: Request, _response: Response, _endpointOrMethodIdentifier: string): Promise<void> {
throw new Error('Payments server is not available.')
}
async callWebSocketServer(
_request: Request,
_response: Response,
_endpointOrMethodIdentifier: string,
): Promise<void> {
throw new Error('Websockets server is not available.')
}
private sendDecoratedResponse(
response: Response,
serviceResponse: { statusCode: number; json: Record<string, unknown> },
): void {
void response.status(serviceResponse.statusCode).send({
meta: {
auth: {
userUuid: response.locals.user?.uuid,
roles: response.locals.roles,
},
server: {
filesServerUrl: this.filesServerUrl,
},
},
data: serviceResponse.json,
})
}
}

View File

@@ -0,0 +1,83 @@
import { EndpointResolverInterface } from './EndpointResolverInterface'
export class EndpointResolver implements EndpointResolverInterface {
constructor(private isConfiguredForHomeServer: boolean) {}
private readonly endpointToIdentifierMap: Map<string, string> = new Map([
// Auth Middleware
['[POST]:sessions/validate', 'auth.sessions.validate'],
// Actions Controller
['[POST]:auth/sign_in', 'auth.signIn'],
['[GET]:auth/params', 'auth.params'],
['[POST]:auth/sign_out', 'auth.signOut'],
['[POST]:auth/recovery/codes', 'auth.generateRecoveryCodes'],
['[POST]:auth/recovery/login', 'auth.signInWithRecoveryCodes'],
['[POST]:auth/recovery/params', 'auth.recoveryKeyParams'],
// v2 Actions Controller
['[POST]:auth/pkce_sign_in', 'auth.pkceSignIn'],
['[POST]:auth/pkce_params', 'auth.pkceParams'],
// Authenticators Controller
['[DELETE]:authenticators/:authenticatorId', 'auth.authenticators.delete'],
['[GET]:authenticators/', 'auth.authenticators.list'],
['[GET]:authenticators/generate-registration-options', 'auth.authenticators.generateRegistrationOptions'],
['[POST]:authenticators/generate-authentication-options', 'auth.authenticators.generateAuthenticationOptions'],
['[POST]:authenticators/verify-registration', 'auth.authenticators.verifyRegistrationResponse'],
// Files Controller
['[POST]:valet-tokens', 'auth.valet-tokens.create'],
// Offline Controller
['[GET]:offline/features', 'auth.offline.features'],
['[POST]:offline/subscription-tokens', 'auth.offline.subscriptionTokens.create'],
// Sessions Controller
['[GET]:sessions', 'auth.sessions.list'],
['[DELETE]:session', 'auth.sessions.delete'],
['[DELETE]:session/all', 'auth.sessions.deleteAll'],
['[POST]:session/refresh', 'auth.sessions.refresh'],
// Subscription Invites Controller
['[POST]:subscription-invites', 'auth.subscriptionInvites.create'],
['[GET]:subscription-invites', 'auth.subscriptionInvites.list'],
['[DELETE]:subscription-invites/:inviteUuid', 'auth.subscriptionInvites.delete'],
['[POST]:subscription-invites/:inviteUuid/accept', 'auth.subscriptionInvites.accept'],
// Tokens Controller
['[POST]:subscription-tokens', 'auth.subscription-tokens.create'],
// Users Controller
['[PATCH]:users/:userId', 'auth.users.update'],
['[PUT]:users/:userUuid/attributes/credentials', 'auth.users.updateCredentials'],
['[PUT]:auth/params', 'auth.users.getKeyParams'],
['[POST]:listed', 'auth.users.createListedAccount'],
['[POST]:auth', 'auth.users.register'],
['[GET]:users/:userUuid/settings', 'auth.users.getSettings'],
['[PUT]:users/:userUuid/settings', 'auth.users.updateSetting'],
['[GET]:users/:userUuid/settings/:settingName', 'auth.users.getSetting'],
['[DELETE]:users/:userUuid/settings/:settingName', 'auth.users.deleteSetting'],
['[GET]:users/:userUuid/subscription-settings/:subscriptionSettingName', 'auth.users.getSubscriptionSetting'],
['[GET]:users/:userUuid/features', 'auth.users.getFeatures'],
['[GET]:users/:userUuid/subscription', 'auth.users.getSubscription'],
['[GET]:offline/users/subscription', 'auth.users.getOfflineSubscriptionByToken'],
['[POST]:users/:userUuid/requests', 'auth.users.createRequest'],
// Syncing Server
['[POST]:items/sync', 'sync.items.sync'],
['[POST]:items/check-integrity', 'sync.items.check_integrity'],
['[GET]:items/:uuid', 'sync.items.get_item'],
// Revisions Controller V2
['[GET]:items/:itemUuid/revisions', 'revisions.revisions.getRevisions'],
['[GET]:items/:itemUuid/revisions/:id', 'revisions.revisions.getRevision'],
['[DELETE]:items/:itemUuid/revisions/:id', 'revisions.revisions.deleteRevision'],
])
resolveEndpointOrMethodIdentifier(method: string, endpoint: string, ...params: string[]): string {
if (!this.isConfiguredForHomeServer) {
if (params.length > 0) {
return params.reduce((acc, param) => acc.replace(/:[a-zA-Z0-9]+/, param), endpoint)
}
return endpoint
}
const identifier = this.endpointToIdentifierMap.get(`[${method}]:${endpoint}`)
if (!identifier) {
throw new Error(`Endpoint ${endpoint} not found`)
}
return identifier
}
}

View File

@@ -0,0 +1,3 @@
export interface EndpointResolverInterface {
resolveEndpointOrMethodIdentifier(method: string, endpoint: string, ...params: string[]): string
}

View File

@@ -1,3 +0,0 @@
export * from './Cache/CrossServiceTokenCacheInterface'
export * from './Http/HttpService'
export * from './Http/HttpServiceInterface'

View File

@@ -1,4 +1,2 @@
export * from './Bootstrap'
export * from './Controller'
export * from './Infra'
export * from './Service'

View File

@@ -3,6 +3,58 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.112.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.111.0...@standardnotes/auth-server@1.112.0) (2023-05-29)
### Features
* add files server as a service to home-server ([#614](https://github.com/standardnotes/server/issues/614)) ([c7d575a](https://github.com/standardnotes/server/commit/c7d575a0ffc7eb3e8799c3835da5727584f4f67b))
# [1.111.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.110.0...@standardnotes/auth-server@1.111.0) (2023-05-25)
### Features
* add revisions service to home server ([#613](https://github.com/standardnotes/server/issues/613)) ([c70040f](https://github.com/standardnotes/server/commit/c70040fe5dfd35663b9811fbbaa9370bd0298482))
# [1.110.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.109.2...@standardnotes/auth-server@1.110.0) (2023-05-25)
### Features
* refactor auth middleware to handle required and optional cross service token scenarios ([#612](https://github.com/standardnotes/server/issues/612)) ([1e4c7d0](https://github.com/standardnotes/server/commit/1e4c7d0f317d5c2d98065da12ffeb950b10ee5dc))
## [1.109.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.109.1...@standardnotes/auth-server@1.109.2) (2023-05-18)
### Bug Fixes
* **auth:** changing user credentials to work both on http proxy and direct code call ([cc61229](https://github.com/standardnotes/server/commit/cc612296d0fbfa7e95556fda45eb9706845e4f58))
## [1.109.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.109.0...@standardnotes/auth-server@1.109.1) (2023-05-18)
**Note:** Version bump only for package @standardnotes/auth-server
# [1.109.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.108.0...@standardnotes/auth-server@1.109.0) (2023-05-17)
### Features
* bundle syncing server into home server setup ([#611](https://github.com/standardnotes/server/issues/611)) ([b3b617e](https://github.com/standardnotes/server/commit/b3b617ea0b4f4574f6aa7cfae0e9fa8f868f1f4c))
# [1.108.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.107.0...@standardnotes/auth-server@1.108.0) (2023-05-17)
### Features
* **auth:** move inversify express controllers to different structure ([#610](https://github.com/standardnotes/server/issues/610)) ([fea5802](https://github.com/standardnotes/server/commit/fea58029b90804dba31faa3c26dcd7dabe541648))
# [1.107.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.106.0...@standardnotes/auth-server@1.107.0) (2023-05-17)
### Features
* add direct event handling for home server ([#608](https://github.com/standardnotes/server/issues/608)) ([8a47d81](https://github.com/standardnotes/server/commit/8a47d81936acd765224e74fd083810579a83c9a7))
# [1.106.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.105.2...@standardnotes/auth-server@1.106.0) (2023-05-16)
### Features
* home-server package initial setup with Api Gateway and Auth services ([#605](https://github.com/standardnotes/server/issues/605)) ([dc71e67](https://github.com/standardnotes/server/commit/dc71e6777fc4c51234b79f6fb409f9f3111cc6a5))
## [1.105.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.105.1...@standardnotes/auth-server@1.105.2) (2023-05-15)
**Note:** Version bump only for package @standardnotes/auth-server

View File

@@ -84,14 +84,14 @@ void container.load().then((container) => {
const env: Env = new Env()
env.load()
const logger: Logger = container.get(TYPES.Logger)
const logger: Logger = container.get(TYPES.Auth_Logger)
logger.info(`Starting ${backupFrequency} ${backupProvider} backup requesting...`)
const settingRepository: SettingRepositoryInterface = container.get(TYPES.SettingRepository)
const roleService: RoleServiceInterface = container.get(TYPES.RoleService)
const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.DomainEventFactory)
const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.DomainEventPublisher)
const settingRepository: SettingRepositoryInterface = container.get(TYPES.Auth_SettingRepository)
const roleService: RoleServiceInterface = container.get(TYPES.Auth_RoleService)
const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.Auth_DomainEventFactory)
const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.Auth_DomainEventPublisher)
Promise.resolve(requestBackups(settingRepository, roleService, domainEventFactory, domainEventPublisher))
.then(() => {

View File

@@ -25,12 +25,12 @@ void container.load().then((container) => {
const env: Env = new Env()
env.load()
const logger: Logger = container.get(TYPES.Logger)
const logger: Logger = container.get(TYPES.Auth_Logger)
logger.info('Starting sessions and session traces cleanup')
const cleanupSessionTraces: CleanupSessionTraces = container.get(TYPES.CleanupSessionTraces)
const cleanupExpiredSessions: CleanupExpiredSessions = container.get(TYPES.CleanupExpiredSessions)
const cleanupSessionTraces: CleanupSessionTraces = container.get(TYPES.Auth_CleanupSessionTraces)
const cleanupExpiredSessions: CleanupExpiredSessions = container.get(TYPES.Auth_CleanupExpiredSessions)
Promise.resolve(cleanup(cleanupSessionTraces, cleanupExpiredSessions))
.then(() => {

View File

@@ -2,25 +2,24 @@ import 'reflect-metadata'
import 'newrelic'
import '../src/Controller/HealthCheckController'
import '../src/Controller/SessionController'
import '../src/Controller/SessionsController'
import '../src/Controller/UsersController'
import '../src/Controller/SettingsController'
import '../src/Controller/FeaturesController'
import '../src/Controller/AdminController'
import '../src/Controller/InternalController'
import '../src/Controller/SubscriptionTokensController'
import '../src/Controller/OfflineController'
import '../src/Controller/ValetTokenController'
import '../src/Controller/ListedController'
import '../src/Controller/SubscriptionSettingsController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressAuthController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressAuthenticatorsController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressSessionsController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressSubscriptionInvitesController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressUserRequestsController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressWebSocketsController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressUsersController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressValetTokenController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressAdminController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressSubscriptionTokensController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressSubscriptionSettingsController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressSettingsController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressSessionController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressOfflineController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressListedController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressInternalController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressHealthCheckController'
import '../src/Infra/InversifyExpressUtils/InversifyExpressFeaturesController'
import * as cors from 'cors'
import { urlencoded, json, Request, Response, NextFunction } from 'express'
@@ -44,7 +43,7 @@ void container.load().then((container) => {
server.setConfig((app) => {
app.use((_request: Request, response: Response, next: NextFunction) => {
response.setHeader('X-Auth-Version', container.get(TYPES.VERSION))
response.setHeader('X-Auth-Version', container.get(TYPES.Auth_VERSION))
next()
})
app.use(json())
@@ -52,7 +51,7 @@ void container.load().then((container) => {
app.use(cors())
})
const logger: winston.Logger = container.get(TYPES.Logger)
const logger: winston.Logger = container.get(TYPES.Auth_Logger)
server.setErrorConfig((app) => {
app.use((error: Record<string, unknown>, _request: Request, response: Response, _next: NextFunction) => {

View File

@@ -15,12 +15,12 @@ void container.load().then((container) => {
const env: Env = new Env()
env.load()
const logger: Logger = container.get(TYPES.Logger)
const logger: Logger = container.get(TYPES.Auth_Logger)
logger.info('Starting session traces cleanup')
const persistStats: PersistStatistics = container.get(TYPES.PersistStatistics)
const timer: TimerInterface = container.get(TYPES.Timer)
const persistStats: PersistStatistics = container.get(TYPES.Auth_PersistStatistics)
const timer: TimerInterface = container.get(TYPES.Auth_Timer)
Promise.resolve(
persistStats.execute({

View File

@@ -72,15 +72,15 @@ void container.load().then((container) => {
const env: Env = new Env()
env.load()
const logger: Logger = container.get(TYPES.Logger)
const logger: Logger = container.get(TYPES.Auth_Logger)
logger.info(`Starting email backup requesting for ${backupEmail} ...`)
const settingRepository: SettingRepositoryInterface = container.get(TYPES.SettingRepository)
const userRepository: UserRepositoryInterface = container.get(TYPES.UserRepository)
const roleService: RoleServiceInterface = container.get(TYPES.RoleService)
const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.DomainEventFactory)
const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.DomainEventPublisher)
const settingRepository: SettingRepositoryInterface = container.get(TYPES.Auth_SettingRepository)
const userRepository: UserRepositoryInterface = container.get(TYPES.Auth_UserRepository)
const roleService: RoleServiceInterface = container.get(TYPES.Auth_RoleService)
const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.Auth_DomainEventFactory)
const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.Auth_DomainEventPublisher)
Promise.resolve(
requestBackups(userRepository, settingRepository, roleService, domainEventFactory, domainEventPublisher),

View File

@@ -18,11 +18,13 @@ void container.load().then((container) => {
const env: Env = new Env()
env.load()
const logger: Logger = container.get(TYPES.Logger)
const logger: Logger = container.get(TYPES.Auth_Logger)
logger.info('Starting worker...')
const subscriberFactory: DomainEventSubscriberFactoryInterface = container.get(TYPES.DomainEventSubscriberFactory)
const subscriberFactory: DomainEventSubscriberFactoryInterface = container.get(
TYPES.Auth_DomainEventSubscriberFactory,
)
subscriberFactory.create().start()
setInterval(() => logger.info('Alive and kicking!'), 20 * 60 * 1000)

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/auth-server",
"version": "1.105.2",
"version": "1.112.0",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
@@ -15,6 +15,7 @@
"setup:env": "cp .env.sample .env",
"build": "tsc --build",
"lint": "eslint . --ext .ts",
"lint:fix": "eslint . --fix --ext .ts",
"pretest": "yarn lint && yarn build",
"test": "jest --coverage --config=./jest.config.js --maxWorkers=50%",
"start": "yarn node dist/bin/server.js",

File diff suppressed because it is too large Load Diff

View File

@@ -28,29 +28,6 @@ const maxQueryExecutionTime = env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
? +env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
: 45_000
const inReplicaMode = env.get('DB_REPLICA_HOST', true) ? true : false
const replicationConfig = {
master: {
host: env.get('DB_HOST'),
port: parseInt(env.get('DB_PORT')),
username: env.get('DB_USERNAME'),
password: env.get('DB_PASSWORD'),
database: env.get('DB_DATABASE'),
},
slaves: [
{
host: env.get('DB_REPLICA_HOST', true),
port: parseInt(env.get('DB_PORT')),
username: env.get('DB_USERNAME'),
password: env.get('DB_PASSWORD'),
database: env.get('DB_DATABASE'),
},
],
removeNodeErrorCount: 10,
restoreNodeTimeout: 5,
}
const commonDataSourceOptions = {
maxQueryExecutionTime,
entities: [
@@ -71,29 +48,59 @@ const commonDataSourceOptions = {
TypeORMEmergencyAccessInvitation,
TypeORMCacheEntry,
],
migrations: [`dist/migrations/${isConfiguredForMySQL ? 'mysql' : 'sqlite'}/*.js`],
migrations: [`${__dirname}/../../migrations/${isConfiguredForMySQL ? 'mysql' : 'sqlite'}/*.js`],
migrationsRun: true,
logging: <LoggerOptions>env.get('DB_DEBUG_LEVEL'),
logging: <LoggerOptions>env.get('DB_DEBUG_LEVEL', true) ?? 'info',
}
const mySQLDataSourceOptions: MysqlConnectionOptions = {
...commonDataSourceOptions,
type: 'mysql',
charset: 'utf8mb4',
supportBigNumbers: true,
bigNumberStrings: false,
replication: inReplicaMode ? replicationConfig : undefined,
host: inReplicaMode ? undefined : env.get('DB_HOST'),
port: inReplicaMode ? undefined : parseInt(env.get('DB_PORT')),
username: inReplicaMode ? undefined : env.get('DB_USERNAME'),
password: inReplicaMode ? undefined : env.get('DB_PASSWORD'),
database: inReplicaMode ? undefined : env.get('DB_DATABASE'),
let dataSource: DataSource
if (isConfiguredForMySQL) {
const inReplicaMode = env.get('DB_REPLICA_HOST', true) ? true : false
const replicationConfig = {
master: {
host: env.get('DB_HOST'),
port: parseInt(env.get('DB_PORT')),
username: env.get('DB_USERNAME'),
password: env.get('DB_PASSWORD'),
database: env.get('DB_DATABASE'),
},
slaves: [
{
host: env.get('DB_REPLICA_HOST', true),
port: parseInt(env.get('DB_PORT')),
username: env.get('DB_USERNAME'),
password: env.get('DB_PASSWORD'),
database: env.get('DB_DATABASE'),
},
],
removeNodeErrorCount: 10,
restoreNodeTimeout: 5,
}
const mySQLDataSourceOptions: MysqlConnectionOptions = {
...commonDataSourceOptions,
type: 'mysql',
charset: 'utf8mb4',
supportBigNumbers: true,
bigNumberStrings: false,
replication: inReplicaMode ? replicationConfig : undefined,
host: inReplicaMode ? undefined : env.get('DB_HOST'),
port: inReplicaMode ? undefined : parseInt(env.get('DB_PORT')),
username: inReplicaMode ? undefined : env.get('DB_USERNAME'),
password: inReplicaMode ? undefined : env.get('DB_PASSWORD'),
database: inReplicaMode ? undefined : env.get('DB_DATABASE'),
}
dataSource = new DataSource(mySQLDataSourceOptions)
} else {
const sqliteDataSourceOptions: SqliteConnectionOptions = {
...commonDataSourceOptions,
type: 'sqlite',
database: `data/${env.get('DB_DATABASE')}.sqlite`,
}
dataSource = new DataSource(sqliteDataSourceOptions)
}
const sqliteDataSourceOptions: SqliteConnectionOptions = {
...commonDataSourceOptions,
type: 'sqlite',
database: `data/${env.get('DB_DATABASE')}.sqlite`,
}
export const AppDataSource = new DataSource(isConfiguredForMySQL ? mySQLDataSourceOptions : sqliteDataSourceOptions)
export const AppDataSource = dataSource

View File

@@ -0,0 +1,42 @@
import {
ControllerContainerInterface,
ServiceContainerInterface,
ServiceIdentifier,
ServiceInterface,
} from '@standardnotes/domain-core'
import { ContainerConfigLoader } from './Container'
import { DirectCallDomainEventPublisher } from '@standardnotes/domain-events-infra'
export class Service implements ServiceInterface {
constructor(
private serviceContainer: ServiceContainerInterface,
private controllerContainer: ControllerContainerInterface,
private directCallDomainEventPublisher: DirectCallDomainEventPublisher,
) {
this.serviceContainer.register(this.getId(), this)
}
async handleRequest(request: never, response: never, endpointOrMethodIdentifier: string): Promise<unknown> {
const method = this.controllerContainer.get(endpointOrMethodIdentifier)
if (!method) {
throw new Error(`Method ${endpointOrMethodIdentifier} not found`)
}
return method(request, response)
}
async getContainer(): Promise<unknown> {
const config = new ContainerConfigLoader()
return config.load({
controllerConatiner: this.controllerContainer,
directCallDomainEventPublisher: this.directCallDomainEventPublisher,
})
}
getId(): ServiceIdentifier {
return ServiceIdentifier.create(ServiceIdentifier.NAMES.Auth).getValue()
}
}

View File

@@ -1,217 +1,237 @@
const TYPES = {
Logger: Symbol.for('Logger'),
Redis: Symbol.for('Redis'),
SNS: Symbol.for('SNS'),
SQS: Symbol.for('SQS'),
Auth_Logger: Symbol.for('Auth_Logger'),
Auth_Redis: Symbol.for('Auth_Redis'),
Auth_SNS: Symbol.for('Auth_SNS'),
Auth_SQS: Symbol.for('Auth_SQS'),
// Mapping
SessionTracePersistenceMapper: Symbol.for('SessionTracePersistenceMapper'),
AuthenticatorChallengePersistenceMapper: Symbol.for('AuthenticatorChallengePersistenceMapper'),
AuthenticatorPersistenceMapper: Symbol.for('AuthenticatorPersistenceMapper'),
AuthenticatorHttpMapper: Symbol.for('AuthenticatorHttpMapper'),
CacheEntryPersistenceMapper: Symbol.for('CacheEntryPersistenceMapper'),
Auth_SessionTracePersistenceMapper: Symbol.for('Auth_SessionTracePersistenceMapper'),
Auth_AuthenticatorChallengePersistenceMapper: Symbol.for('Auth_AuthenticatorChallengePersistenceMapper'),
Auth_AuthenticatorPersistenceMapper: Symbol.for('Auth_AuthenticatorPersistenceMapper'),
Auth_AuthenticatorHttpMapper: Symbol.for('Auth_AuthenticatorHttpMapper'),
Auth_CacheEntryPersistenceMapper: Symbol.for('Auth_CacheEntryPersistenceMapper'),
// Controller
AuthController: Symbol.for('AuthController'),
AuthenticatorsController: Symbol.for('AuthenticatorsController'),
SubscriptionInvitesController: Symbol.for('SubscriptionInvitesController'),
UserRequestsController: Symbol.for('UserRequestsController'),
Auth_ControllerContainer: Symbol.for('Auth_ControllerContainer'),
Auth_AuthController: Symbol.for('Auth_AuthController'),
Auth_AuthenticatorsController: Symbol.for('Auth_AuthenticatorsController'),
Auth_SubscriptionInvitesController: Symbol.for('Auth_SubscriptionInvitesController'),
Auth_UserRequestsController: Symbol.for('Auth_UserRequestsController'),
// Repositories
UserRepository: Symbol.for('UserRepository'),
SessionRepository: Symbol.for('SessionRepository'),
EphemeralSessionRepository: Symbol.for('EphemeralSessionRepository'),
RevokedSessionRepository: Symbol.for('RevokedSessionRepository'),
SettingRepository: Symbol.for('SettingRepository'),
SubscriptionSettingRepository: Symbol.for('SubscriptionSettingRepository'),
OfflineSettingRepository: Symbol.for('OfflineSettingRepository'),
LockRepository: Symbol.for('LockRepository'),
RoleRepository: Symbol.for('RoleRepository'),
UserSubscriptionRepository: Symbol.for('UserSubscriptionRepository'),
OfflineUserSubscriptionRepository: Symbol.for('OfflineUserSubscriptionRepository'),
SubscriptionTokenRepository: Symbol.for('SubscriptionTokenRepository'),
OfflineSubscriptionTokenRepository: Symbol.for('OfflineSubscriptionTokenRepository'),
SharedSubscriptionInvitationRepository: Symbol.for('SharedSubscriptionInvitationRepository'),
PKCERepository: Symbol.for('PKCERepository'),
SessionTraceRepository: Symbol.for('SessionTraceRepository'),
AuthenticatorRepository: Symbol.for('AuthenticatorRepository'),
AuthenticatorChallengeRepository: Symbol.for('AuthenticatorChallengeRepository'),
CacheEntryRepository: Symbol.for('CacheEntryRepository'),
Auth_UserRepository: Symbol.for('Auth_UserRepository'),
Auth_SessionRepository: Symbol.for('Auth_SessionRepository'),
Auth_EphemeralSessionRepository: Symbol.for('Auth_EphemeralSessionRepository'),
Auth_RevokedSessionRepository: Symbol.for('Auth_RevokedSessionRepository'),
Auth_SettingRepository: Symbol.for('Auth_SettingRepository'),
Auth_SubscriptionSettingRepository: Symbol.for('Auth_SubscriptionSettingRepository'),
Auth_OfflineSettingRepository: Symbol.for('Auth_OfflineSettingRepository'),
Auth_LockRepository: Symbol.for('Auth_LockRepository'),
Auth_RoleRepository: Symbol.for('Auth_RoleRepository'),
Auth_UserSubscriptionRepository: Symbol.for('Auth_UserSubscriptionRepository'),
Auth_OfflineUserSubscriptionRepository: Symbol.for('Auth_OfflineUserSubscriptionRepository'),
Auth_SubscriptionTokenRepository: Symbol.for('Auth_SubscriptionTokenRepository'),
Auth_OfflineSubscriptionTokenRepository: Symbol.for('Auth_OfflineSubscriptionTokenRepository'),
Auth_SharedSubscriptionInvitationRepository: Symbol.for('Auth_SharedSubscriptionInvitationRepository'),
Auth_PKCERepository: Symbol.for('Auth_PKCERepository'),
Auth_SessionTraceRepository: Symbol.for('Auth_SessionTraceRepository'),
Auth_AuthenticatorRepository: Symbol.for('Auth_AuthenticatorRepository'),
Auth_AuthenticatorChallengeRepository: Symbol.for('Auth_AuthenticatorChallengeRepository'),
Auth_CacheEntryRepository: Symbol.for('Auth_CacheEntryRepository'),
// ORM
ORMOfflineSettingRepository: Symbol.for('ORMOfflineSettingRepository'),
ORMOfflineUserSubscriptionRepository: Symbol.for('ORMOfflineUserSubscriptionRepository'),
ORMRevokedSessionRepository: Symbol.for('ORMRevokedSessionRepository'),
ORMRoleRepository: Symbol.for('ORMRoleRepository'),
ORMSessionRepository: Symbol.for('ORMSessionRepository'),
ORMSettingRepository: Symbol.for('ORMSettingRepository'),
ORMSharedSubscriptionInvitationRepository: Symbol.for('ORMSharedSubscriptionInvitationRepository'),
ORMSubscriptionSettingRepository: Symbol.for('ORMSubscriptionSettingRepository'),
ORMUserRepository: Symbol.for('ORMUserRepository'),
ORMUserSubscriptionRepository: Symbol.for('ORMUserSubscriptionRepository'),
ORMSessionTraceRepository: Symbol.for('ORMSessionTraceRepository'),
ORMAuthenticatorRepository: Symbol.for('ORMAuthenticatorRepository'),
ORMAuthenticatorChallengeRepository: Symbol.for('ORMAuthenticatorChallengeRepository'),
ORMCacheEntryRepository: Symbol.for('ORMCacheEntryRepository'),
Auth_ORMOfflineSettingRepository: Symbol.for('Auth_ORMOfflineSettingRepository'),
Auth_ORMOfflineUserSubscriptionRepository: Symbol.for('Auth_ORMOfflineUserSubscriptionRepository'),
Auth_ORMRevokedSessionRepository: Symbol.for('Auth_ORMRevokedSessionRepository'),
Auth_ORMRoleRepository: Symbol.for('Auth_ORMRoleRepository'),
Auth_ORMSessionRepository: Symbol.for('Auth_ORMSessionRepository'),
Auth_ORMSettingRepository: Symbol.for('Auth_ORMSettingRepository'),
Auth_ORMSharedSubscriptionInvitationRepository: Symbol.for('Auth_ORMSharedSubscriptionInvitationRepository'),
Auth_ORMSubscriptionSettingRepository: Symbol.for('Auth_ORMSubscriptionSettingRepository'),
Auth_ORMUserRepository: Symbol.for('Auth_ORMUserRepository'),
Auth_ORMUserSubscriptionRepository: Symbol.for('Auth_ORMUserSubscriptionRepository'),
Auth_ORMSessionTraceRepository: Symbol.for('Auth_ORMSessionTraceRepository'),
Auth_ORMAuthenticatorRepository: Symbol.for('Auth_ORMAuthenticatorRepository'),
Auth_ORMAuthenticatorChallengeRepository: Symbol.for('Auth_ORMAuthenticatorChallengeRepository'),
Auth_ORMCacheEntryRepository: Symbol.for('Auth_ORMCacheEntryRepository'),
// Middleware
AuthMiddleware: Symbol.for('AuthMiddleware'),
ApiGatewayAuthMiddleware: Symbol.for('ApiGatewayAuthMiddleware'),
ApiGatewayOfflineAuthMiddleware: Symbol.for('ApiGatewayOfflineAuthMiddleware'),
OfflineUserAuthMiddleware: Symbol.for('OfflineUserAuthMiddleware'),
AuthMiddlewareWithoutResponse: Symbol.for('AuthMiddlewareWithoutResponse'),
LockMiddleware: Symbol.for('LockMiddleware'),
SessionMiddleware: Symbol.for('SessionMiddleware'),
Auth_RequiredCrossServiceTokenMiddleware: Symbol.for('Auth_RequiredCrossServiceTokenMiddleware'),
Auth_OptionalCrossServiceTokenMiddleware: Symbol.for('Auth_OptionalCrossServiceTokenMiddleware'),
Auth_ApiGatewayOfflineAuthMiddleware: Symbol.for('Auth_ApiGatewayOfflineAuthMiddleware'),
Auth_OfflineUserAuthMiddleware: Symbol.for('Auth_OfflineUserAuthMiddleware'),
Auth_LockMiddleware: Symbol.for('Auth_LockMiddleware'),
Auth_SessionMiddleware: Symbol.for('Auth_SessionMiddleware'),
// Projectors
SessionProjector: Symbol.for('SessionProjector'),
UserProjector: Symbol.for('UserProjector'),
RoleProjector: Symbol.for('RoleProjector'),
PermissionProjector: Symbol.for('PermissionProjector'),
SettingProjector: Symbol.for('SettingProjector'),
SubscriptionSettingProjector: Symbol.for('SubscriptionSettingProjector'),
Auth_SessionProjector: Symbol.for('Auth_SessionProjector'),
Auth_UserProjector: Symbol.for('Auth_UserProjector'),
Auth_RoleProjector: Symbol.for('Auth_RoleProjector'),
Auth_PermissionProjector: Symbol.for('Auth_PermissionProjector'),
Auth_SettingProjector: Symbol.for('Auth_SettingProjector'),
Auth_SubscriptionSettingProjector: Symbol.for('Auth_SubscriptionSettingProjector'),
// Factories
SettingFactory: Symbol.for('SettingFactory'),
Auth_SettingFactory: Symbol.for('Auth_SettingFactory'),
// env vars
JWT_SECRET: Symbol.for('JWT_SECRET'),
LEGACY_JWT_SECRET: Symbol.for('LEGACY_JWT_SECRET'),
AUTH_JWT_SECRET: Symbol.for('AUTH_JWT_SECRET'),
AUTH_JWT_TTL: Symbol.for('AUTH_JWT_TTL'),
VALET_TOKEN_SECRET: Symbol.for('VALET_TOKEN_SECRET'),
VALET_TOKEN_TTL: Symbol.for('VALET_TOKEN_TTL'),
WEB_SOCKET_CONNECTION_TOKEN_SECRET: Symbol.for('WEB_SOCKET_CONNECTION_TOKEN_SECRET'),
WEB_SOCKET_CONNECTION_TOKEN_TTL: Symbol.for('WEB_SOCKET_CONNECTION_TOKEN_TTL'),
ENCRYPTION_SERVER_KEY: Symbol.for('ENCRYPTION_SERVER_KEY'),
ACCESS_TOKEN_AGE: Symbol.for('ACCESS_TOKEN_AGE'),
REFRESH_TOKEN_AGE: Symbol.for('REFRESH_TOKEN_AGE'),
EPHEMERAL_SESSION_AGE: Symbol.for('EPHEMERAL_SESSION_AGE'),
MAX_LOGIN_ATTEMPTS: Symbol.for('MAX_LOGIN_ATTEMPTS'),
FAILED_LOGIN_LOCKOUT: Symbol.for('FAILED_LOGIN_LOCKOUT'),
PSEUDO_KEY_PARAMS_KEY: Symbol.for('PSEUDO_KEY_PARAMS_KEY'),
REDIS_URL: Symbol.for('REDIS_URL'),
DISABLE_USER_REGISTRATION: Symbol.for('DISABLE_USER_REGISTRATION'),
SNS_TOPIC_ARN: Symbol.for('SNS_TOPIC_ARN'),
SNS_AWS_REGION: Symbol.for('SNS_AWS_REGION'),
SQS_QUEUE_URL: Symbol.for('SQS_QUEUE_URL'),
SQS_AWS_REGION: Symbol.for('SQS_AWS_REGION'),
USER_SERVER_REGISTRATION_URL: Symbol.for('USER_SERVER_REGISTRATION_URL'),
USER_SERVER_AUTH_KEY: Symbol.for('USER_SERVER_AUTH_KEY'),
USER_SERVER_CHANGE_EMAIL_URL: Symbol.for('USER_SERVER_CHANGE_EMAIL_URL'),
NEW_RELIC_ENABLED: Symbol.for('NEW_RELIC_ENABLED'),
SYNCING_SERVER_URL: Symbol.for('SYNCING_SERVER_URL'),
VERSION: Symbol.for('VERSION'),
PAYMENTS_SERVER_URL: Symbol.for('PAYMENTS_SERVER_URL'),
SESSION_TRACE_DAYS_TTL: Symbol.for('SESSION_TRACE_DAYS_TTL'),
U2F_RELYING_PARTY_ID: Symbol.for('U2F_RELYING_PARTY_ID'),
U2F_RELYING_PARTY_NAME: Symbol.for('U2F_RELYING_PARTY_NAME'),
U2F_EXPECTED_ORIGIN: Symbol.for('U2F_EXPECTED_ORIGIN'),
U2F_REQUIRE_USER_VERIFICATION: Symbol.for('U2F_REQUIRE_USER_VERIFICATION'),
READONLY_USERS: Symbol.for('READONLY_USERS'),
Auth_JWT_SECRET: Symbol.for('Auth_JWT_SECRET'),
Auth_LEGACY_JWT_SECRET: Symbol.for('Auth_LEGACY_JWT_SECRET'),
Auth_AUTH_JWT_SECRET: Symbol.for('Auth_AUTH_JWT_SECRET'),
Auth_AUTH_JWT_TTL: Symbol.for('Auth_AUTH_JWT_TTL'),
Auth_VALET_TOKEN_SECRET: Symbol.for('Auth_VALET_TOKEN_SECRET'),
Auth_VALET_TOKEN_TTL: Symbol.for('Auth_VALET_TOKEN_TTL'),
Auth_WEB_SOCKET_CONNECTION_TOKEN_SECRET: Symbol.for('Auth_WEB_SOCKET_CONNECTION_TOKEN_SECRET'),
Auth_WEB_SOCKET_CONNECTION_TOKEN_TTL: Symbol.for('Auth_WEB_SOCKET_CONNECTION_TOKEN_TTL'),
Auth_ENCRYPTION_SERVER_KEY: Symbol.for('Auth_ENCRYPTION_SERVER_KEY'),
Auth_ACCESS_TOKEN_AGE: Symbol.for('Auth_ACCESS_TOKEN_AGE'),
Auth_REFRESH_TOKEN_AGE: Symbol.for('Auth_REFRESH_TOKEN_AGE'),
Auth_EPHEMERAL_SESSION_AGE: Symbol.for('Auth_EPHEMERAL_SESSION_AGE'),
Auth_MAX_LOGIN_ATTEMPTS: Symbol.for('Auth_MAX_LOGIN_ATTEMPTS'),
Auth_FAILED_LOGIN_LOCKOUT: Symbol.for('Auth_FAILED_LOGIN_LOCKOUT'),
Auth_PSEUDO_KEY_PARAMS_KEY: Symbol.for('Auth_PSEUDO_KEY_PARAMS_KEY'),
Auth_REDIS_URL: Symbol.for('Auth_REDIS_URL'),
Auth_DISABLE_USER_REGISTRATION: Symbol.for('Auth_DISABLE_USER_REGISTRATION'),
Auth_SNS_TOPIC_ARN: Symbol.for('Auth_SNS_TOPIC_ARN'),
Auth_SNS_AWS_REGION: Symbol.for('Auth_SNS_AWS_REGION'),
Auth_SQS_QUEUE_URL: Symbol.for('Auth_SQS_QUEUE_URL'),
Auth_SQS_AWS_REGION: Symbol.for('Auth_SQS_AWS_REGION'),
Auth_USER_SERVER_REGISTRATION_URL: Symbol.for('Auth_USER_SERVER_REGISTRATION_URL'),
Auth_USER_SERVER_AUTH_KEY: Symbol.for('Auth_USER_SERVER_AUTH_KEY'),
Auth_USER_SERVER_CHANGE_EMAIL_URL: Symbol.for('Auth_USER_SERVER_CHANGE_EMAIL_URL'),
Auth_NEW_RELIC_ENABLED: Symbol.for('Auth_NEW_RELIC_ENABLED'),
Auth_SYNCING_SERVER_URL: Symbol.for('Auth_SYNCING_SERVER_URL'),
Auth_VERSION: Symbol.for('Auth_VERSION'),
Auth_PAYMENTS_SERVER_URL: Symbol.for('Auth_PAYMENTS_SERVER_URL'),
Auth_SESSION_TRACE_DAYS_TTL: Symbol.for('Auth_SESSION_TRACE_DAYS_TTL'),
Auth_U2F_RELYING_PARTY_ID: Symbol.for('Auth_U2F_RELYING_PARTY_ID'),
Auth_U2F_RELYING_PARTY_NAME: Symbol.for('Auth_U2F_RELYING_PARTY_NAME'),
Auth_U2F_EXPECTED_ORIGIN: Symbol.for('Auth_U2F_EXPECTED_ORIGIN'),
Auth_U2F_REQUIRE_USER_VERIFICATION: Symbol.for('Auth_U2F_REQUIRE_USER_VERIFICATION'),
Auth_READONLY_USERS: Symbol.for('Auth_READONLY_USERS'),
// use cases
AuthenticateUser: Symbol.for('AuthenticateUser'),
AuthenticateRequest: Symbol.for('AuthenticateRequest'),
RefreshSessionToken: Symbol.for('RefreshSessionToken'),
VerifyMFA: Symbol.for('VerifyMFA'),
SignIn: Symbol.for('SignIn'),
ClearLoginAttempts: Symbol.for('ClearLoginAttempts'),
IncreaseLoginAttempts: Symbol.for('IncreaseLoginAttempts'),
GetUserKeyParams: Symbol.for('GetUserKeyParams'),
UpdateUser: Symbol.for('UpdateUser'),
Register: Symbol.for('Register'),
GetActiveSessionsForUser: Symbol.for('GetActiveSessionsForUser'),
DeletePreviousSessionsForUser: Symbol.for('DeletePreviousSessionsForUser'),
DeleteSessionForUser: Symbol.for('DeleteSessionForUser'),
ChangeCredentials: Symbol.for('ChangePassword'),
GetSettings: Symbol.for('GetSettings'),
GetSetting: Symbol.for('GetSetting'),
GetUserFeatures: Symbol.for('GetUserFeatures'),
UpdateSetting: Symbol.for('UpdateSetting'),
DeleteSetting: Symbol.for('DeleteSetting'),
DeleteAccount: Symbol.for('DeleteAccount'),
GetUserSubscription: Symbol.for('GetUserSubscription'),
GetUserOfflineSubscription: Symbol.for('GetUserOfflineSubscription'),
CreateSubscriptionToken: Symbol.for('CreateSubscriptionToken'),
AuthenticateSubscriptionToken: Symbol.for('AuthenticateSubscriptionToken'),
CreateOfflineSubscriptionToken: Symbol.for('CreateOfflineSubscriptionToken'),
AuthenticateOfflineSubscriptionToken: Symbol.for('AuthenticateOfflineSubscriptionToken'),
CreateValetToken: Symbol.for('CreateValetToken'),
CreateListedAccount: Symbol.for('CreateListedAccount'),
InviteToSharedSubscription: Symbol.for('InviteToSharedSubscription'),
AcceptSharedSubscriptionInvitation: Symbol.for('AcceptSharedSubscriptionInvitation'),
DeclineSharedSubscriptionInvitation: Symbol.for('DeclineSharedSubscriptionInvitation'),
CancelSharedSubscriptionInvitation: Symbol.for('CancelSharedSubscriptionInvitation'),
ListSharedSubscriptionInvitations: Symbol.for('ListSharedSubscriptionInvitations'),
VerifyPredicate: Symbol.for('VerifyPredicate'),
CreateCrossServiceToken: Symbol.for('CreateCrossServiceToken'),
ProcessUserRequest: Symbol.for('ProcessUserRequest'),
TraceSession: Symbol.for('TraceSession'),
CleanupSessionTraces: Symbol.for('CleanupSessionTraces'),
CleanupExpiredSessions: Symbol.for('CleanupExpiredSessions'),
PersistStatistics: Symbol.for('PersistStatistics'),
GenerateAuthenticatorRegistrationOptions: Symbol.for('GenerateAuthenticatorRegistrationOptions'),
VerifyAuthenticatorRegistrationResponse: Symbol.for('VerifyAuthenticatorRegistrationResponse'),
GenerateAuthenticatorAuthenticationOptions: Symbol.for('GenerateAuthenticatorAuthenticationOptions'),
VerifyAuthenticatorAuthenticationResponse: Symbol.for('VerifyAuthenticatorAuthenticationResponse'),
ListAuthenticators: Symbol.for('ListAuthenticators'),
DeleteAuthenticator: Symbol.for('DeleteAuthenticator'),
GenerateRecoveryCodes: Symbol.for('GenerateRecoveryCodes'),
SignInWithRecoveryCodes: Symbol.for('SignInWithRecoveryCodes'),
GetUserKeyParamsRecovery: Symbol.for('GetUserKeyParamsRecovery'),
Auth_AuthenticateUser: Symbol.for('Auth_AuthenticateUser'),
Auth_AuthenticateRequest: Symbol.for('Auth_AuthenticateRequest'),
Auth_RefreshSessionToken: Symbol.for('Auth_RefreshSessionToken'),
Auth_VerifyMFA: Symbol.for('Auth_VerifyMFA'),
Auth_SignIn: Symbol.for('Auth_SignIn'),
Auth_ClearLoginAttempts: Symbol.for('Auth_ClearLoginAttempts'),
Auth_IncreaseLoginAttempts: Symbol.for('Auth_IncreaseLoginAttempts'),
Auth_GetUserKeyParams: Symbol.for('Auth_GetUserKeyParams'),
Auth_UpdateUser: Symbol.for('Auth_UpdateUser'),
Auth_Register: Symbol.for('Auth_Register'),
Auth_GetActiveSessionsForUser: Symbol.for('Auth_GetActiveSessionsForUser'),
Auth_DeletePreviousSessionsForUser: Symbol.for('Auth_DeletePreviousSessionsForUser'),
Auth_DeleteSessionForUser: Symbol.for('Auth_DeleteSessionForUser'),
Auth_ChangeCredentials: Symbol.for('Auth_ChangePassword'),
Auth_GetSettings: Symbol.for('Auth_GetSettings'),
Auth_GetSetting: Symbol.for('Auth_GetSetting'),
Auth_GetUserFeatures: Symbol.for('Auth_GetUserFeatures'),
Auth_UpdateSetting: Symbol.for('Auth_UpdateSetting'),
Auth_DeleteSetting: Symbol.for('Auth_DeleteSetting'),
Auth_DeleteAccount: Symbol.for('Auth_DeleteAccount'),
Auth_GetUserSubscription: Symbol.for('Auth_GetUserSubscription'),
Auth_GetUserOfflineSubscription: Symbol.for('Auth_GetUserOfflineSubscription'),
Auth_CreateSubscriptionToken: Symbol.for('Auth_CreateSubscriptionToken'),
Auth_AuthenticateSubscriptionToken: Symbol.for('Auth_AuthenticateSubscriptionToken'),
Auth_CreateOfflineSubscriptionToken: Symbol.for('Auth_CreateOfflineSubscriptionToken'),
Auth_AuthenticateOfflineSubscriptionToken: Symbol.for('Auth_AuthenticateOfflineSubscriptionToken'),
Auth_CreateValetToken: Symbol.for('Auth_CreateValetToken'),
Auth_CreateListedAccount: Symbol.for('Auth_CreateListedAccount'),
Auth_InviteToSharedSubscription: Symbol.for('Auth_InviteToSharedSubscription'),
Auth_AcceptSharedSubscriptionInvitation: Symbol.for('Auth_AcceptSharedSubscriptionInvitation'),
Auth_DeclineSharedSubscriptionInvitation: Symbol.for('Auth_DeclineSharedSubscriptionInvitation'),
Auth_CancelSharedSubscriptionInvitation: Symbol.for('Auth_CancelSharedSubscriptionInvitation'),
Auth_ListSharedSubscriptionInvitations: Symbol.for('Auth_ListSharedSubscriptionInvitations'),
Auth_VerifyPredicate: Symbol.for('Auth_VerifyPredicate'),
Auth_CreateCrossServiceToken: Symbol.for('Auth_CreateCrossServiceToken'),
Auth_ProcessUserRequest: Symbol.for('Auth_ProcessUserRequest'),
Auth_TraceSession: Symbol.for('Auth_TraceSession'),
Auth_CleanupSessionTraces: Symbol.for('Auth_CleanupSessionTraces'),
Auth_CleanupExpiredSessions: Symbol.for('Auth_CleanupExpiredSessions'),
Auth_PersistStatistics: Symbol.for('Auth_PersistStatistics'),
Auth_GenerateAuthenticatorRegistrationOptions: Symbol.for('Auth_GenerateAuthenticatorRegistrationOptions'),
Auth_VerifyAuthenticatorRegistrationResponse: Symbol.for('Auth_VerifyAuthenticatorRegistrationResponse'),
Auth_GenerateAuthenticatorAuthenticationOptions: Symbol.for('Auth_GenerateAuthenticatorAuthenticationOptions'),
Auth_VerifyAuthenticatorAuthenticationResponse: Symbol.for('Auth_VerifyAuthenticatorAuthenticationResponse'),
Auth_ListAuthenticators: Symbol.for('Auth_ListAuthenticators'),
Auth_DeleteAuthenticator: Symbol.for('Auth_DeleteAuthenticator'),
Auth_GenerateRecoveryCodes: Symbol.for('Auth_GenerateRecoveryCodes'),
Auth_SignInWithRecoveryCodes: Symbol.for('Auth_SignInWithRecoveryCodes'),
Auth_GetUserKeyParamsRecovery: Symbol.for('Auth_GetUserKeyParamsRecovery'),
// Handlers
UserRegisteredEventHandler: Symbol.for('UserRegisteredEventHandler'),
AccountDeletionRequestedEventHandler: Symbol.for('AccountDeletionRequestedEventHandler'),
SubscriptionPurchasedEventHandler: Symbol.for('SubscriptionPurchasedEventHandler'),
SubscriptionCancelledEventHandler: Symbol.for('SubscriptionCancelledEventHandler'),
SubscriptionReassignedEventHandler: Symbol.for('SubscriptionReassignedEventHandler'),
SubscriptionRenewedEventHandler: Symbol.for('SubscriptionRenewedEventHandler'),
SubscriptionRefundedEventHandler: Symbol.for('SubscriptionRefundedEventHandler'),
SubscriptionExpiredEventHandler: Symbol.for('SubscriptionExpiredEventHandler'),
SubscriptionSyncRequestedEventHandler: Symbol.for('SubscriptionSyncRequestedEventHandler'),
ExtensionKeyGrantedEventHandler: Symbol.for('ExtensionKeyGrantedEventHandler'),
UserEmailChangedEventHandler: Symbol.for('UserEmailChangedEventHandler'),
FileUploadedEventHandler: Symbol.for('FileUploadedEventHandler'),
FileRemovedEventHandler: Symbol.for('FileRemovedEventHandler'),
ListedAccountCreatedEventHandler: Symbol.for('ListedAccountCreatedEventHandler'),
ListedAccountDeletedEventHandler: Symbol.for('ListedAccountDeletedEventHandler'),
UserDisabledSessionUserAgentLoggingEventHandler: Symbol.for('UserDisabledSessionUserAgentLoggingEventHandler'),
SharedSubscriptionInvitationCreatedEventHandler: Symbol.for('SharedSubscriptionInvitationCreatedEventHandler'),
PredicateVerificationRequestedEventHandler: Symbol.for('PredicateVerificationRequestedEventHandler'),
EmailSubscriptionUnsubscribedEventHandler: Symbol.for('EmailSubscriptionUnsubscribedEventHandler'),
Auth_UserRegisteredEventHandler: Symbol.for('Auth_UserRegisteredEventHandler'),
Auth_AccountDeletionRequestedEventHandler: Symbol.for('Auth_AccountDeletionRequestedEventHandler'),
Auth_SubscriptionPurchasedEventHandler: Symbol.for('Auth_SubscriptionPurchasedEventHandler'),
Auth_SubscriptionCancelledEventHandler: Symbol.for('Auth_SubscriptionCancelledEventHandler'),
Auth_SubscriptionReassignedEventHandler: Symbol.for('Auth_SubscriptionReassignedEventHandler'),
Auth_SubscriptionRenewedEventHandler: Symbol.for('Auth_SubscriptionRenewedEventHandler'),
Auth_SubscriptionRefundedEventHandler: Symbol.for('Auth_SubscriptionRefundedEventHandler'),
Auth_SubscriptionExpiredEventHandler: Symbol.for('Auth_SubscriptionExpiredEventHandler'),
Auth_SubscriptionSyncRequestedEventHandler: Symbol.for('Auth_SubscriptionSyncRequestedEventHandler'),
Auth_ExtensionKeyGrantedEventHandler: Symbol.for('Auth_ExtensionKeyGrantedEventHandler'),
Auth_UserEmailChangedEventHandler: Symbol.for('Auth_UserEmailChangedEventHandler'),
Auth_FileUploadedEventHandler: Symbol.for('Auth_FileUploadedEventHandler'),
Auth_FileRemovedEventHandler: Symbol.for('Auth_FileRemovedEventHandler'),
Auth_ListedAccountCreatedEventHandler: Symbol.for('Auth_ListedAccountCreatedEventHandler'),
Auth_ListedAccountDeletedEventHandler: Symbol.for('Auth_ListedAccountDeletedEventHandler'),
Auth_UserDisabledSessionUserAgentLoggingEventHandler: Symbol.for(
'Auth_UserDisabledSessionUserAgentLoggingEventHandler',
),
Auth_SharedSubscriptionInvitationCreatedEventHandler: Symbol.for(
'Auth_SharedSubscriptionInvitationCreatedEventHandler',
),
Auth_PredicateVerificationRequestedEventHandler: Symbol.for('Auth_PredicateVerificationRequestedEventHandler'),
Auth_EmailSubscriptionUnsubscribedEventHandler: Symbol.for('Auth_EmailSubscriptionUnsubscribedEventHandler'),
// Services
DeviceDetector: Symbol.for('DeviceDetector'),
SessionService: Symbol.for('SessionService'),
SettingService: Symbol.for('SettingService'),
SubscriptionSettingService: Symbol.for('SubscriptionSettingService'),
OfflineSettingService: Symbol.for('OfflineSettingService'),
AuthResponseFactory20161215: Symbol.for('AuthResponseFactory20161215'),
AuthResponseFactory20190520: Symbol.for('AuthResponseFactory20190520'),
AuthResponseFactory20200115: Symbol.for('AuthResponseFactory20200115'),
AuthResponseFactoryResolver: Symbol.for('AuthResponseFactoryResolver'),
KeyParamsFactory: Symbol.for('KeyParamsFactory'),
SessionTokenDecoder: Symbol.for('SessionTokenDecoder'),
FallbackSessionTokenDecoder: Symbol.for('FallbackSessionTokenDecoder'),
CrossServiceTokenDecoder: Symbol.for('CrossServiceTokenDecoder'),
OfflineUserTokenDecoder: Symbol.for('OfflineUserTokenDecoder'),
OfflineUserTokenEncoder: Symbol.for('OfflineUserTokenEncoder'),
CrossServiceTokenEncoder: Symbol.for('CrossServiceTokenEncoder'),
SessionTokenEncoder: Symbol.for('SessionTokenEncoder'),
ValetTokenEncoder: Symbol.for('ValetTokenEncoder'),
WebSocketConnectionTokenDecoder: Symbol.for('WebSocketConnectionTokenDecoder'),
AuthenticationMethodResolver: Symbol.for('AuthenticationMethodResolver'),
DomainEventPublisher: Symbol.for('DomainEventPublisher'),
DomainEventSubscriberFactory: Symbol.for('DomainEventSubscriberFactory'),
DomainEventFactory: Symbol.for('DomainEventFactory'),
DomainEventMessageHandler: Symbol.for('DomainEventMessageHandler'),
HTTPClient: Symbol.for('HTTPClient'),
Crypter: Symbol.for('Crypter'),
CryptoNode: Symbol.for('CryptoNode'),
Timer: Symbol.for('Timer'),
ContenDecoder: Symbol.for('ContenDecoder'),
WebSocketsClientService: Symbol.for('WebSocketClientService'),
RoleService: Symbol.for('RoleService'),
RoleToSubscriptionMap: Symbol.for('RoleToSubscriptionMap'),
SettingsAssociationService: Symbol.for('SettingsAssociationService'),
SubscriptionSettingsAssociationService: Symbol.for('SubscriptionSettingsAssociationService'),
FeatureService: Symbol.for('FeatureService'),
SettingDecrypter: Symbol.for('SettingDecrypter'),
SettingInterpreter: Symbol.for('SettingInterpreter'),
ProtocolVersionSelector: Symbol.for('ProtocolVersionSelector'),
BooleanSelector: Symbol.for('BooleanSelector'),
UserSubscriptionService: Symbol.for('UserSubscriptionService'),
Auth_DeviceDetector: Symbol.for('Auth_DeviceDetector'),
Auth_SessionService: Symbol.for('Auth_SessionService'),
Auth_SettingService: Symbol.for('Auth_SettingService'),
Auth_SubscriptionSettingService: Symbol.for('Auth_SubscriptionSettingService'),
Auth_OfflineSettingService: Symbol.for('Auth_OfflineSettingService'),
Auth_AuthResponseFactory20161215: Symbol.for('Auth_AuthResponseFactory20161215'),
Auth_AuthResponseFactory20190520: Symbol.for('Auth_AuthResponseFactory20190520'),
Auth_AuthResponseFactory20200115: Symbol.for('Auth_AuthResponseFactory20200115'),
Auth_AuthResponseFactoryResolver: Symbol.for('Auth_AuthResponseFactoryResolver'),
Auth_KeyParamsFactory: Symbol.for('Auth_KeyParamsFactory'),
Auth_SessionTokenDecoder: Symbol.for('Auth_SessionTokenDecoder'),
Auth_FallbackSessionTokenDecoder: Symbol.for('Auth_FallbackSessionTokenDecoder'),
Auth_CrossServiceTokenDecoder: Symbol.for('Auth_CrossServiceTokenDecoder'),
Auth_OfflineUserTokenDecoder: Symbol.for('Auth_OfflineUserTokenDecoder'),
Auth_OfflineUserTokenEncoder: Symbol.for('Auth_OfflineUserTokenEncoder'),
Auth_CrossServiceTokenEncoder: Symbol.for('Auth_CrossServiceTokenEncoder'),
Auth_SessionTokenEncoder: Symbol.for('Auth_SessionTokenEncoder'),
Auth_ValetTokenEncoder: Symbol.for('Auth_ValetTokenEncoder'),
Auth_WebSocketConnectionTokenDecoder: Symbol.for('Auth_WebSocketConnectionTokenDecoder'),
Auth_AuthenticationMethodResolver: Symbol.for('Auth_AuthenticationMethodResolver'),
Auth_DomainEventPublisher: Symbol.for('Auth_DomainEventPublisher'),
Auth_DomainEventSubscriberFactory: Symbol.for('Auth_DomainEventSubscriberFactory'),
Auth_DomainEventFactory: Symbol.for('Auth_DomainEventFactory'),
Auth_DomainEventMessageHandler: Symbol.for('Auth_DomainEventMessageHandler'),
Auth_HTTPClient: Symbol.for('Auth_HTTPClient'),
Auth_Crypter: Symbol.for('Auth_Crypter'),
Auth_CryptoNode: Symbol.for('Auth_CryptoNode'),
Auth_Timer: Symbol.for('Auth_Timer'),
Auth_ContenDecoder: Symbol.for('Auth_ContenDecoder'),
Auth_WebSocketsClientService: Symbol.for('Auth_WebSocketClientService'),
Auth_RoleService: Symbol.for('Auth_RoleService'),
Auth_RoleToSubscriptionMap: Symbol.for('Auth_RoleToSubscriptionMap'),
Auth_SettingsAssociationService: Symbol.for('Auth_SettingsAssociationService'),
Auth_SubscriptionSettingsAssociationService: Symbol.for('Auth_SubscriptionSettingsAssociationService'),
Auth_FeatureService: Symbol.for('Auth_FeatureService'),
Auth_SettingDecrypter: Symbol.for('Auth_SettingDecrypter'),
Auth_SettingInterpreter: Symbol.for('Auth_SettingInterpreter'),
Auth_ProtocolVersionSelector: Symbol.for('Auth_ProtocolVersionSelector'),
Auth_BooleanSelector: Symbol.for('Auth_BooleanSelector'),
Auth_UserSubscriptionService: Symbol.for('Auth_UserSubscriptionService'),
Auth_HomeServerAuthController: Symbol.for('Auth_HomeServerAuthController'),
Auth_HomeServerAuthenticatorsController: Symbol.for('Auth_HomeServerAuthenticatorsController'),
Auth_HomeServerSubscriptionInvitesController: Symbol.for('Auth_HomeServerSubscriptionInvitesController'),
Auth_HomeServerUserRequestsController: Symbol.for('Auth_HomeServerUserRequestsController'),
Auth_HomeServerWebSocketsController: Symbol.for('Auth_HomeServerWebSocketsController'),
Auth_HomeServerSessionsController: Symbol.for('Auth_HomeServerSessionsController'),
Auth_HomeServerValetTokenController: Symbol.for('Auth_HomeServerValetTokenController'),
Auth_HomeServerUsersController: Symbol.for('Auth_HomeServerUsersController'),
Auth_HomeServerAdminController: Symbol.for('Auth_HomeServerAdminController'),
Auth_HomeServerSubscriptionTokensController: Symbol.for('Auth_HomeServerSubscriptionTokensController'),
Auth_HomeServerSubscriptionSettingsController: Symbol.for('Auth_HomeServerSubscriptionSettingsController'),
Auth_HomeServerSettingsController: Symbol.for('Auth_HomeServerSettingsController'),
Auth_HomeServerSessionController: Symbol.for('Auth_HomeServerSessionController'),
Auth_HomeServerOfflineController: Symbol.for('Auth_HomeServerOfflineController'),
Auth_HomeServerListedController: Symbol.for('Auth_HomeServerListedController'),
Auth_HomeServerFeaturesController: Symbol.for('Auth_HomeServerFeaturesController'),
}
export default TYPES

View File

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

View File

@@ -1,99 +0,0 @@
import 'reflect-metadata'
import { ApiGatewayAuthMiddleware } from './ApiGatewayAuthMiddleware'
import { NextFunction, Request, Response } from 'express'
import { Logger } from 'winston'
import { CrossServiceTokenData, TokenDecoderInterface } from '@standardnotes/security'
import { RoleName } from '@standardnotes/domain-core'
describe('ApiGatewayAuthMiddleware', () => {
let tokenDecoder: TokenDecoderInterface<CrossServiceTokenData>
let request: Request
let response: Response
let next: NextFunction
const logger = {
debug: jest.fn(),
} as unknown as jest.Mocked<Logger>
const createMiddleware = () => new ApiGatewayAuthMiddleware(tokenDecoder, logger)
beforeEach(() => {
tokenDecoder = {} as jest.Mocked<TokenDecoderInterface<CrossServiceTokenData>>
tokenDecoder.decodeToken = jest.fn().mockReturnValue({
user: {
uuid: '1-2-3',
email: 'test@test.te',
},
roles: [
{
uuid: 'a-b-c',
name: RoleName.NAMES.CoreUser,
},
],
})
request = {
headers: {},
} as jest.Mocked<Request>
response = {
locals: {},
} as jest.Mocked<Response>
response.status = jest.fn().mockReturnThis()
response.send = jest.fn()
next = jest.fn()
})
it('should authorize user', async () => {
request.headers['x-auth-token'] = 'auth-jwt-token'
await createMiddleware().handler(request, response, next)
expect(response.locals.user).toEqual({
uuid: '1-2-3',
email: 'test@test.te',
})
expect(response.locals.roles).toEqual([
{
uuid: 'a-b-c',
name: RoleName.NAMES.CoreUser,
},
])
expect(next).toHaveBeenCalled()
})
it('should not authorize if request is missing auth jwt token in headers', async () => {
await createMiddleware().handler(request, response, next)
expect(response.status).toHaveBeenCalledWith(401)
expect(next).not.toHaveBeenCalled()
})
it('should not authorize if auth jwt token is malformed', async () => {
request.headers['x-auth-token'] = 'auth-jwt-token'
tokenDecoder.decodeToken = jest.fn().mockReturnValue(undefined)
await createMiddleware().handler(request, response, next)
expect(response.status).toHaveBeenCalledWith(401)
expect(next).not.toHaveBeenCalled()
})
it('should pass the error to next middleware if one occurres', async () => {
request.headers['x-auth-token'] = 'auth-jwt-token'
const error = new Error('Ooops')
tokenDecoder.decodeToken = jest.fn().mockImplementation(() => {
throw error
})
await createMiddleware().handler(request, response, next)
expect(response.status).not.toHaveBeenCalled()
expect(next).toHaveBeenCalledWith(error)
})
})

View File

@@ -13,6 +13,7 @@ import { SignInWithRecoveryCodes } from '../Domain/UseCase/SignInWithRecoveryCod
import { GetUserKeyParamsRecovery } from '../Domain/UseCase/GetUserKeyParamsRecovery/GetUserKeyParamsRecovery'
import { GenerateRecoveryCodes } from '../Domain/UseCase/GenerateRecoveryCodes/GenerateRecoveryCodes'
import { Logger } from 'winston'
import { SessionServiceInterface } from '../Domain/Session/SessionServiceInterface'
describe('AuthController', () => {
let clearLoginAttempts: ClearLoginAttempts
@@ -25,6 +26,7 @@ describe('AuthController', () => {
let getUserKeyParamsRecovery: GetUserKeyParamsRecovery
let doGenerateRecoveryCodes: GenerateRecoveryCodes
let logger: Logger
let sessionService: SessionServiceInterface
const createController = () =>
new AuthController(
@@ -36,6 +38,7 @@ describe('AuthController', () => {
getUserKeyParamsRecovery,
doGenerateRecoveryCodes,
logger,
sessionService,
)
beforeEach(() => {
@@ -58,6 +61,9 @@ describe('AuthController', () => {
logger = {} as jest.Mocked<Logger>
logger.debug = jest.fn()
sessionService = {} as jest.Mocked<SessionServiceInterface>
sessionService.deleteSessionByToken = jest.fn().mockReturnValue('1-2-3')
})
it('should register a user', async () => {

View File

@@ -1,4 +1,3 @@
import { inject, injectable } from 'inversify'
import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
import {
ApiVersion,
@@ -7,10 +6,9 @@ import {
UserDeletionResponseBody,
UserRegistrationResponseBody,
} from '@standardnotes/api'
import { HttpResponse, HttpStatusCode } from '@standardnotes/responses'
import { ErrorTag, HttpResponse, HttpStatusCode } from '@standardnotes/responses'
import { ProtocolVersion } from '@standardnotes/common'
import TYPES from '../Bootstrap/Types'
import { ClearLoginAttempts } from '../Domain/UseCase/ClearLoginAttempts'
import { Register } from '../Domain/UseCase/Register'
import { DomainEventFactoryInterface } from '../Domain/Event/DomainEventFactoryInterface'
@@ -24,18 +22,19 @@ import { GenerateRecoveryCodesResponseBody } from '../Infra/Http/Response/Genera
import { GenerateRecoveryCodes } from '../Domain/UseCase/GenerateRecoveryCodes/GenerateRecoveryCodes'
import { GenerateRecoveryCodesRequestParams } from '../Infra/Http/Request/GenerateRecoveryCodesRequestParams'
import { Logger } from 'winston'
import { SessionServiceInterface } from '../Domain/Session/SessionServiceInterface'
@injectable()
export class AuthController implements UserServerInterface {
constructor(
@inject(TYPES.ClearLoginAttempts) private clearLoginAttempts: ClearLoginAttempts,
@inject(TYPES.Register) private registerUser: Register,
@inject(TYPES.DomainEventPublisher) private domainEventPublisher: DomainEventPublisherInterface,
@inject(TYPES.DomainEventFactory) private domainEventFactory: DomainEventFactoryInterface,
@inject(TYPES.SignInWithRecoveryCodes) private doSignInWithRecoveryCodes: SignInWithRecoveryCodes,
@inject(TYPES.GetUserKeyParamsRecovery) private getUserKeyParamsRecovery: GetUserKeyParamsRecovery,
@inject(TYPES.GenerateRecoveryCodes) private doGenerateRecoveryCodes: GenerateRecoveryCodes,
@inject(TYPES.Logger) private logger: Logger,
private clearLoginAttempts: ClearLoginAttempts,
private registerUser: Register,
private domainEventPublisher: DomainEventPublisherInterface,
private domainEventFactory: DomainEventFactoryInterface,
private doSignInWithRecoveryCodes: SignInWithRecoveryCodes,
private getUserKeyParamsRecovery: GetUserKeyParamsRecovery,
private doGenerateRecoveryCodes: GenerateRecoveryCodes,
private logger: Logger,
private sessionService: SessionServiceInterface,
) {}
async deleteAccount(_params: never): Promise<HttpResponse<UserDeletionResponseBody>> {
@@ -200,4 +199,33 @@ export class AuthController implements UserServerInterface {
},
}
}
async signOut(params: Record<string, unknown>): Promise<HttpResponse> {
if (params.readOnlyAccess) {
return {
status: HttpStatusCode.Unauthorized,
data: {
error: {
tag: ErrorTag.ReadOnlyAccess,
message: 'Session has read-only access.',
},
},
}
}
const userUuid = await this.sessionService.deleteSessionByToken(
(params.authorizationHeader as string).replace('Bearer ', ''),
)
let headers = undefined
if (userUuid !== null) {
headers = new Map([['x-invalidate-cache', userUuid]])
}
return {
status: HttpStatusCode.NoContent,
data: {},
headers,
}
}
}

View File

@@ -1,79 +0,0 @@
import 'reflect-metadata'
import { AuthMiddleware } from './AuthMiddleware'
import { NextFunction, Request, Response } from 'express'
import { User } from '../Domain/User/User'
import { AuthenticateRequest } from '../Domain/UseCase/AuthenticateRequest'
import { Session } from '../Domain/Session/Session'
import { Logger } from 'winston'
describe('AuthMiddleware', () => {
let authenticateRequest: AuthenticateRequest
let request: Request
let response: Response
let next: NextFunction
const logger = {
debug: jest.fn(),
} as unknown as jest.Mocked<Logger>
const createMiddleware = () => new AuthMiddleware(authenticateRequest, logger)
beforeEach(() => {
authenticateRequest = {} as jest.Mocked<AuthenticateRequest>
authenticateRequest.execute = jest.fn()
request = {
headers: {},
} as jest.Mocked<Request>
response = {
locals: {},
} as jest.Mocked<Response>
response.status = jest.fn().mockReturnThis()
response.send = jest.fn()
next = jest.fn()
})
it('should authorize user', async () => {
const user = {} as jest.Mocked<User>
const session = {} as jest.Mocked<Session>
authenticateRequest.execute = jest.fn().mockReturnValue({
success: true,
user,
session,
})
await createMiddleware().handler(request, response, next)
expect(response.locals.user).toEqual(user)
expect(response.locals.session).toEqual(session)
expect(next).toHaveBeenCalled()
})
it('should not authorize if request authentication fails', async () => {
authenticateRequest.execute = jest.fn().mockReturnValue({
success: false,
responseCode: 401,
})
await createMiddleware().handler(request, response, next)
expect(response.status).toHaveBeenCalledWith(401)
expect(next).not.toHaveBeenCalled()
})
it('should pass the error to next middleware if one occurres', async () => {
const error = new Error('Ooops')
authenticateRequest.execute = jest.fn().mockImplementation(() => {
throw error
})
await createMiddleware().handler(request, response, next)
expect(response.status).not.toHaveBeenCalled()
expect(next).toHaveBeenCalledWith(error)
})
})

View File

@@ -1,45 +0,0 @@
import { NextFunction, Request, Response } from 'express'
import { inject, injectable } from 'inversify'
import { BaseMiddleware } from 'inversify-express-utils'
import { Logger } from 'winston'
import TYPES from '../Bootstrap/Types'
import { AuthenticateRequest } from '../Domain/UseCase/AuthenticateRequest'
@injectable()
export class AuthMiddleware extends BaseMiddleware {
constructor(
@inject(TYPES.AuthenticateRequest) private authenticateRequest: AuthenticateRequest,
@inject(TYPES.Logger) private logger: Logger,
) {
super()
}
async handler(request: Request, response: Response, next: NextFunction): Promise<void> {
try {
const authenticateRequestResponse = await this.authenticateRequest.execute({
authorizationHeader: request.headers.authorization,
})
if (!authenticateRequestResponse.success) {
this.logger.debug('AuthMiddleware authentication failure.')
response.status(authenticateRequestResponse.responseCode).send({
error: {
tag: authenticateRequestResponse.errorTag,
message: authenticateRequestResponse.errorMessage,
},
})
return
}
response.locals.user = authenticateRequestResponse.user
response.locals.session = authenticateRequestResponse.session
response.locals.readOnlyAccess = authenticateRequestResponse.session?.readonlyAccess ?? false
return next()
} catch (error) {
return next(error)
}
}
}

View File

@@ -1,68 +0,0 @@
import 'reflect-metadata'
import { AuthMiddlewareWithoutResponse } from './AuthMiddlewareWithoutResponse'
import { NextFunction, Request, Response } from 'express'
import { User } from '../Domain/User/User'
import { AuthenticateRequest } from '../Domain/UseCase/AuthenticateRequest'
import { Session } from '../Domain/Session/Session'
describe('AuthMiddlewareWithoutResponse', () => {
let authenticateRequest: AuthenticateRequest
let request: Request
let response: Response
let next: NextFunction
const createMiddleware = () => new AuthMiddlewareWithoutResponse(authenticateRequest)
beforeEach(() => {
authenticateRequest = {} as jest.Mocked<AuthenticateRequest>
authenticateRequest.execute = jest.fn()
request = {
headers: {},
} as jest.Mocked<Request>
response = {
locals: {},
} as jest.Mocked<Response>
response.status = jest.fn().mockReturnThis()
response.send = jest.fn()
next = jest.fn()
})
it('should authorize user', async () => {
const user = {} as jest.Mocked<User>
const session = {} as jest.Mocked<Session>
authenticateRequest.execute = jest.fn().mockReturnValue({
success: true,
user,
session,
})
await createMiddleware().handler(request, response, next)
expect(response.locals.user).toEqual(user)
expect(response.locals.session).toEqual(session)
expect(next).toHaveBeenCalled()
})
it('should skip middleware if authentication fails', async () => {
authenticateRequest.execute = jest.fn().mockReturnValue({
success: false,
})
await createMiddleware().handler(request, response, next)
expect(next).toHaveBeenCalled()
})
it('should skip middleware if authentication errors', async () => {
authenticateRequest.execute = jest.fn().mockImplementation(() => {
throw new Error('Ooops')
})
await createMiddleware().handler(request, response, next)
expect(next).toHaveBeenCalled()
})
})

View File

@@ -1,32 +0,0 @@
import { NextFunction, Request, Response } from 'express'
import { inject, injectable } from 'inversify'
import { BaseMiddleware } from 'inversify-express-utils'
import TYPES from '../Bootstrap/Types'
import { AuthenticateRequest } from '../Domain/UseCase/AuthenticateRequest'
@injectable()
export class AuthMiddlewareWithoutResponse extends BaseMiddleware {
constructor(@inject(TYPES.AuthenticateRequest) private authenticateRequest: AuthenticateRequest) {
super()
}
async handler(request: Request, response: Response, next: NextFunction): Promise<void> {
try {
const authenticateRequestResponse = await this.authenticateRequest.execute({
authorizationHeader: request.headers.authorization,
})
if (!authenticateRequestResponse.success) {
return next()
}
response.locals.user = authenticateRequestResponse.user
response.locals.session = authenticateRequestResponse.session
response.locals.readOnlyAccess = authenticateRequestResponse.session?.readonlyAccess ?? false
return next()
} catch (error) {
return next()
}
}
}

View File

@@ -26,14 +26,14 @@ import { ListSharedSubscriptionInvitations } from '../Domain/UseCase/ListSharedS
@injectable()
export class SubscriptionInvitesController implements SubscriptionServerInterface {
constructor(
@inject(TYPES.InviteToSharedSubscription) private inviteToSharedSubscription: InviteToSharedSubscription,
@inject(TYPES.AcceptSharedSubscriptionInvitation)
@inject(TYPES.Auth_InviteToSharedSubscription) private inviteToSharedSubscription: InviteToSharedSubscription,
@inject(TYPES.Auth_AcceptSharedSubscriptionInvitation)
private acceptSharedSubscriptionInvitation: AcceptSharedSubscriptionInvitation,
@inject(TYPES.DeclineSharedSubscriptionInvitation)
@inject(TYPES.Auth_DeclineSharedSubscriptionInvitation)
private declineSharedSubscriptionInvitation: DeclineSharedSubscriptionInvitation,
@inject(TYPES.CancelSharedSubscriptionInvitation)
@inject(TYPES.Auth_CancelSharedSubscriptionInvitation)
private cancelSharedSubscriptionInvitation: CancelSharedSubscriptionInvitation,
@inject(TYPES.ListSharedSubscriptionInvitations)
@inject(TYPES.Auth_ListSharedSubscriptionInvitations)
private listSharedSubscriptionInvitations: ListSharedSubscriptionInvitations,
) {}

View File

@@ -1,32 +0,0 @@
import { Request, Response } from 'express'
import { inject } from 'inversify'
import {
BaseHttpController,
controller,
httpGet,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
results,
} from 'inversify-express-utils'
import TYPES from '../Bootstrap/Types'
import { GetSetting } from '../Domain/UseCase/GetSetting/GetSetting'
@controller('/users/:userUuid')
export class SubscriptionSettingsController extends BaseHttpController {
constructor(@inject(TYPES.GetSetting) private doGetSetting: GetSetting) {
super()
}
@httpGet('/subscription-settings/:subscriptionSettingName', TYPES.ApiGatewayAuthMiddleware)
async getSubscriptionSetting(request: Request, response: Response): Promise<results.JsonResult> {
const result = await this.doGetSetting.execute({
userUuid: response.locals.user.uuid,
settingName: request.params.subscriptionSettingName.toUpperCase(),
})
if (result.success) {
return this.json(result)
}
return this.json(result, 400)
}
}

View File

@@ -6,7 +6,7 @@ import { ProcessUserRequest } from '../Domain/UseCase/ProcessUserRequest/Process
@injectable()
export class UserRequestsController implements UserRequestServerInterface {
constructor(@inject(TYPES.ProcessUserRequest) private processUserRequest: ProcessUserRequest) {}
constructor(@inject(TYPES.Auth_ProcessUserRequest) private processUserRequest: ProcessUserRequest) {}
async submitUserRequest(params: UserRequestRequestParams): Promise<HttpResponse<UserRequestResponseBody>> {
const result = await this.processUserRequest.execute({

View File

@@ -15,9 +15,9 @@ import { AuthResponseFactoryInterface } from './AuthResponseFactoryInterface'
@injectable()
export class AuthResponseFactory20161215 implements AuthResponseFactoryInterface {
constructor(
@inject(TYPES.UserProjector) protected userProjector: ProjectorInterface<User>,
@inject(TYPES.SessionTokenEncoder) protected tokenEncoder: TokenEncoderInterface<SessionTokenData>,
@inject(TYPES.Logger) protected logger: Logger,
@inject(TYPES.Auth_UserProjector) protected userProjector: ProjectorInterface<User>,
@inject(TYPES.Auth_SessionTokenEncoder) protected tokenEncoder: TokenEncoderInterface<SessionTokenData>,
@inject(TYPES.Auth_Logger) protected logger: Logger,
) {}
async createResponse(dto: {

View File

@@ -23,13 +23,13 @@ import { AuthResponse20200115 } from './AuthResponse20200115'
@injectable()
export class AuthResponseFactory20200115 extends AuthResponseFactory20190520 {
constructor(
@inject(TYPES.SessionService) private sessionService: SessionServiceInterface,
@inject(TYPES.KeyParamsFactory) private keyParamsFactory: KeyParamsFactoryInterface,
@inject(TYPES.UserProjector) userProjector: ProjectorInterface<User>,
@inject(TYPES.SessionTokenEncoder) protected override tokenEncoder: TokenEncoderInterface<SessionTokenData>,
@inject(TYPES.DomainEventFactory) private domainEventFactory: DomainEventFactoryInterface,
@inject(TYPES.DomainEventPublisher) private domainEventPublisher: DomainEventPublisherInterface,
@inject(TYPES.Logger) logger: Logger,
@inject(TYPES.Auth_SessionService) private sessionService: SessionServiceInterface,
@inject(TYPES.Auth_KeyParamsFactory) private keyParamsFactory: KeyParamsFactoryInterface,
@inject(TYPES.Auth_UserProjector) userProjector: ProjectorInterface<User>,
@inject(TYPES.Auth_SessionTokenEncoder) protected override tokenEncoder: TokenEncoderInterface<SessionTokenData>,
@inject(TYPES.Auth_DomainEventFactory) private domainEventFactory: DomainEventFactoryInterface,
@inject(TYPES.Auth_DomainEventPublisher) private domainEventPublisher: DomainEventPublisherInterface,
@inject(TYPES.Auth_Logger) logger: Logger,
) {
super(userProjector, tokenEncoder, logger)
}

View File

@@ -11,10 +11,10 @@ import { AuthResponseFactoryResolverInterface } from './AuthResponseFactoryResol
@injectable()
export class AuthResponseFactoryResolver implements AuthResponseFactoryResolverInterface {
constructor(
@inject(TYPES.AuthResponseFactory20161215) private authResponseFactory20161215: AuthResponseFactory20161215,
@inject(TYPES.AuthResponseFactory20190520) private authResponseFactory20190520: AuthResponseFactory20190520,
@inject(TYPES.AuthResponseFactory20200115) private authResponseFactory20200115: AuthResponseFactory20200115,
@inject(TYPES.Logger) private logger: Logger,
@inject(TYPES.Auth_AuthResponseFactory20161215) private authResponseFactory20161215: AuthResponseFactory20161215,
@inject(TYPES.Auth_AuthResponseFactory20190520) private authResponseFactory20190520: AuthResponseFactory20190520,
@inject(TYPES.Auth_AuthResponseFactory20200115) private authResponseFactory20200115: AuthResponseFactory20200115,
@inject(TYPES.Auth_Logger) private logger: Logger,
) {}
resolveAuthResponseFactoryVersion(apiVersion: string): AuthResponseFactoryInterface {

View File

@@ -9,10 +9,10 @@ import { AuthenticationMethodResolverInterface } from './AuthenticationMethodRes
@injectable()
export class AuthenticationMethodResolver implements AuthenticationMethodResolverInterface {
constructor(
@inject(TYPES.UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.SessionService) private sessionService: SessionServiceInterface,
@inject(TYPES.SessionTokenDecoder) private sessionTokenDecoder: TokenDecoderInterface<SessionTokenData>,
@inject(TYPES.FallbackSessionTokenDecoder)
@inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.Auth_SessionService) private sessionService: SessionServiceInterface,
@inject(TYPES.Auth_SessionTokenDecoder) private sessionTokenDecoder: TokenDecoderInterface<SessionTokenData>,
@inject(TYPES.Auth_FallbackSessionTokenDecoder)
private fallbackSessionTokenDecoder: TokenDecoderInterface<SessionTokenData>,
) {}

View File

@@ -9,9 +9,9 @@ import { CrypterInterface } from './CrypterInterface'
@injectable()
export class CrypterNode implements CrypterInterface {
constructor(
@inject(TYPES.ENCRYPTION_SERVER_KEY) private encryptionServerKey: string,
@inject(TYPES.CryptoNode) private cryptoNode: CryptoNode,
@inject(TYPES.Logger) private logger: Logger,
@inject(TYPES.Auth_ENCRYPTION_SERVER_KEY) private encryptionServerKey: string,
@inject(TYPES.Auth_CryptoNode) private cryptoNode: CryptoNode,
@inject(TYPES.Auth_Logger) private logger: Logger,
) {
const keyBuffer = Buffer.from(encryptionServerKey, 'hex')
const { byteLength } = keyBuffer

View File

@@ -30,7 +30,7 @@ import { DomainEventFactoryInterface } from './DomainEventFactoryInterface'
@injectable()
export class DomainEventFactory implements DomainEventFactoryInterface {
constructor(@inject(TYPES.Timer) private timer: TimerInterface) {}
constructor(@inject(TYPES.Auth_Timer) private timer: TimerInterface) {}
createSessionCreatedEvent(dto: { userUuid: string }): SessionCreatedEvent {
return {

View File

@@ -15,10 +15,10 @@ import { TimerInterface } from '@standardnotes/time'
@injectable()
export class FeatureService implements FeatureServiceInterface {
constructor(
@inject(TYPES.RoleToSubscriptionMap) private roleToSubscriptionMap: RoleToSubscriptionMapInterface,
@inject(TYPES.OfflineUserSubscriptionRepository)
@inject(TYPES.Auth_RoleToSubscriptionMap) private roleToSubscriptionMap: RoleToSubscriptionMapInterface,
@inject(TYPES.Auth_OfflineUserSubscriptionRepository)
private offlineUserSubscriptionRepository: OfflineUserSubscriptionRepositoryInterface,
@inject(TYPES.Timer) private timer: TimerInterface,
@inject(TYPES.Auth_Timer) private timer: TimerInterface,
) {}
async userIsEntitledToFeature(user: User, featureIdentifier: string): Promise<boolean> {

View File

@@ -10,11 +10,12 @@ import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
@injectable()
export class AccountDeletionRequestedEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.SessionRepository) private sessionRepository: SessionRepositoryInterface,
@inject(TYPES.EphemeralSessionRepository) private ephemeralSessionRepository: EphemeralSessionRepositoryInterface,
@inject(TYPES.RevokedSessionRepository) private revokedSessionRepository: RevokedSessionRepositoryInterface,
@inject(TYPES.Logger) private logger: Logger,
@inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.Auth_SessionRepository) private sessionRepository: SessionRepositoryInterface,
@inject(TYPES.Auth_EphemeralSessionRepository)
private ephemeralSessionRepository: EphemeralSessionRepositoryInterface,
@inject(TYPES.Auth_RevokedSessionRepository) private revokedSessionRepository: RevokedSessionRepositoryInterface,
@inject(TYPES.Auth_Logger) private logger: Logger,
) {}
async handle(event: AccountDeletionRequestedEvent): Promise<void> {

View File

@@ -16,11 +16,11 @@ import { Username } from '@standardnotes/domain-core'
@injectable()
export class ExtensionKeyGrantedEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.SettingService) private settingService: SettingServiceInterface,
@inject(TYPES.OfflineSettingService) private offlineSettingService: OfflineSettingServiceInterface,
@inject(TYPES.ContenDecoder) private contentDecoder: ContentDecoderInterface,
@inject(TYPES.Logger) private logger: Logger,
@inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.Auth_SettingService) private settingService: SettingServiceInterface,
@inject(TYPES.Auth_OfflineSettingService) private offlineSettingService: OfflineSettingServiceInterface,
@inject(TYPES.Auth_ContenDecoder) private contentDecoder: ContentDecoderInterface,
@inject(TYPES.Auth_Logger) private logger: Logger,
) {}
async handle(event: ExtensionKeyGrantedEvent): Promise<void> {

View File

@@ -12,9 +12,10 @@ import { UserSubscriptionServiceInterface } from '../Subscription/UserSubscripti
@injectable()
export class FileRemovedEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.UserSubscriptionService) private userSubscriptionService: UserSubscriptionServiceInterface,
@inject(TYPES.SubscriptionSettingService) private subscriptionSettingService: SubscriptionSettingServiceInterface,
@inject(TYPES.Logger) 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> {

View File

@@ -13,10 +13,11 @@ import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
@injectable()
export class FileUploadedEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.UserSubscriptionService) private userSubscriptionService: UserSubscriptionServiceInterface,
@inject(TYPES.SubscriptionSettingService) private subscriptionSettingService: SubscriptionSettingServiceInterface,
@inject(TYPES.Logger) 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> {

View File

@@ -11,9 +11,9 @@ import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
@injectable()
export class ListedAccountCreatedEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.SettingService) private settingService: SettingServiceInterface,
@inject(TYPES.Logger) private logger: Logger,
@inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.Auth_SettingService) private settingService: SettingServiceInterface,
@inject(TYPES.Auth_Logger) private logger: Logger,
) {}
async handle(event: ListedAccountCreatedEvent): Promise<void> {

View File

@@ -11,9 +11,9 @@ import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
@injectable()
export class ListedAccountDeletedEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.SettingService) private settingService: SettingServiceInterface,
@inject(TYPES.Logger) private logger: Logger,
@inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.Auth_SettingService) private settingService: SettingServiceInterface,
@inject(TYPES.Auth_Logger) private logger: Logger,
) {}
async handle(event: ListedAccountDeletedEvent): Promise<void> {

View File

@@ -16,11 +16,11 @@ import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
@injectable()
export class PredicateVerificationRequestedEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.VerifyPredicate) private verifyPredicate: VerifyPredicate,
@inject(TYPES.UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.DomainEventFactory) private domainEventFactory: DomainEventFactoryInterface,
@inject(TYPES.DomainEventPublisher) private domainEventPublisher: DomainEventPublisherInterface,
@inject(TYPES.Logger) private logger: Logger,
@inject(TYPES.Auth_VerifyPredicate) private verifyPredicate: VerifyPredicate,
@inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.Auth_DomainEventFactory) private domainEventFactory: DomainEventFactoryInterface,
@inject(TYPES.Auth_DomainEventPublisher) private domainEventPublisher: DomainEventPublisherInterface,
@inject(TYPES.Auth_Logger) private logger: Logger,
) {}
async handle(event: PredicateVerificationRequestedEvent): Promise<void> {

View File

@@ -8,7 +8,7 @@ import { AcceptSharedSubscriptionInvitation } from '../UseCase/AcceptSharedSubsc
@injectable()
export class SharedSubscriptionInvitationCreatedEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.AcceptSharedSubscriptionInvitation)
@inject(TYPES.Auth_AcceptSharedSubscriptionInvitation)
private acceptSharedSubscriptionInvitation: AcceptSharedSubscriptionInvitation,
) {}

View File

@@ -8,8 +8,9 @@ import { OfflineUserSubscriptionRepositoryInterface } from '../Subscription/Offl
@injectable()
export class SubscriptionCancelledEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.UserSubscriptionRepository) private userSubscriptionRepository: UserSubscriptionRepositoryInterface,
@inject(TYPES.OfflineUserSubscriptionRepository)
@inject(TYPES.Auth_UserSubscriptionRepository)
private userSubscriptionRepository: UserSubscriptionRepositoryInterface,
@inject(TYPES.Auth_OfflineUserSubscriptionRepository)
private offlineUserSubscriptionRepository: OfflineUserSubscriptionRepositoryInterface,
) {}

View File

@@ -12,12 +12,13 @@ import { Username } from '@standardnotes/domain-core'
@injectable()
export class SubscriptionExpiredEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.UserSubscriptionRepository) private userSubscriptionRepository: UserSubscriptionRepositoryInterface,
@inject(TYPES.OfflineUserSubscriptionRepository)
@inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.Auth_UserSubscriptionRepository)
private userSubscriptionRepository: UserSubscriptionRepositoryInterface,
@inject(TYPES.Auth_OfflineUserSubscriptionRepository)
private offlineUserSubscriptionRepository: OfflineUserSubscriptionRepositoryInterface,
@inject(TYPES.RoleService) private roleService: RoleServiceInterface,
@inject(TYPES.Logger) private logger: Logger,
@inject(TYPES.Auth_RoleService) private roleService: RoleServiceInterface,
@inject(TYPES.Auth_Logger) private logger: Logger,
) {}
async handle(event: SubscriptionExpiredEvent): Promise<void> {

View File

@@ -17,13 +17,15 @@ import { Username } from '@standardnotes/domain-core'
@injectable()
export class SubscriptionPurchasedEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.UserSubscriptionRepository) private userSubscriptionRepository: UserSubscriptionRepositoryInterface,
@inject(TYPES.OfflineUserSubscriptionRepository)
@inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.Auth_UserSubscriptionRepository)
private userSubscriptionRepository: UserSubscriptionRepositoryInterface,
@inject(TYPES.Auth_OfflineUserSubscriptionRepository)
private offlineUserSubscriptionRepository: OfflineUserSubscriptionRepositoryInterface,
@inject(TYPES.RoleService) private roleService: RoleServiceInterface,
@inject(TYPES.SubscriptionSettingService) private subscriptionSettingService: SubscriptionSettingServiceInterface,
@inject(TYPES.Logger) private logger: Logger,
@inject(TYPES.Auth_RoleService) private roleService: RoleServiceInterface,
@inject(TYPES.Auth_SubscriptionSettingService)
private subscriptionSettingService: SubscriptionSettingServiceInterface,
@inject(TYPES.Auth_Logger) private logger: Logger,
) {}
async handle(event: SubscriptionPurchasedEvent): Promise<void> {

View File

@@ -18,12 +18,14 @@ import { Username } from '@standardnotes/domain-core'
@injectable()
export class SubscriptionReassignedEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.UserSubscriptionRepository) private userSubscriptionRepository: UserSubscriptionRepositoryInterface,
@inject(TYPES.RoleService) private roleService: RoleServiceInterface,
@inject(TYPES.SettingService) private settingService: SettingServiceInterface,
@inject(TYPES.SubscriptionSettingService) private subscriptionSettingService: SubscriptionSettingServiceInterface,
@inject(TYPES.Logger) private logger: Logger,
@inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.Auth_UserSubscriptionRepository)
private userSubscriptionRepository: UserSubscriptionRepositoryInterface,
@inject(TYPES.Auth_RoleService) private roleService: RoleServiceInterface,
@inject(TYPES.Auth_SettingService) private settingService: SettingServiceInterface,
@inject(TYPES.Auth_SubscriptionSettingService)
private subscriptionSettingService: SubscriptionSettingServiceInterface,
@inject(TYPES.Auth_Logger) private logger: Logger,
) {}
async handle(event: SubscriptionReassignedEvent): Promise<void> {

View File

@@ -12,12 +12,13 @@ import { Username } from '@standardnotes/domain-core'
@injectable()
export class SubscriptionRefundedEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.UserSubscriptionRepository) private userSubscriptionRepository: UserSubscriptionRepositoryInterface,
@inject(TYPES.OfflineUserSubscriptionRepository)
@inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.Auth_UserSubscriptionRepository)
private userSubscriptionRepository: UserSubscriptionRepositoryInterface,
@inject(TYPES.Auth_OfflineUserSubscriptionRepository)
private offlineUserSubscriptionRepository: OfflineUserSubscriptionRepositoryInterface,
@inject(TYPES.RoleService) private roleService: RoleServiceInterface,
@inject(TYPES.Logger) private logger: Logger,
@inject(TYPES.Auth_RoleService) private roleService: RoleServiceInterface,
@inject(TYPES.Auth_Logger) private logger: Logger,
) {}
async handle(event: SubscriptionRefundedEvent): Promise<void> {

View File

@@ -13,12 +13,13 @@ import { Username } from '@standardnotes/domain-core'
@injectable()
export class SubscriptionRenewedEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.UserSubscriptionRepository) private userSubscriptionRepository: UserSubscriptionRepositoryInterface,
@inject(TYPES.OfflineUserSubscriptionRepository)
@inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.Auth_UserSubscriptionRepository)
private userSubscriptionRepository: UserSubscriptionRepositoryInterface,
@inject(TYPES.Auth_OfflineUserSubscriptionRepository)
private offlineUserSubscriptionRepository: OfflineUserSubscriptionRepositoryInterface,
@inject(TYPES.RoleService) private roleService: RoleServiceInterface,
@inject(TYPES.Logger) private logger: Logger,
@inject(TYPES.Auth_RoleService) private roleService: RoleServiceInterface,
@inject(TYPES.Auth_Logger) private logger: Logger,
) {}
async handle(event: SubscriptionRenewedEvent): Promise<void> {

View File

@@ -24,16 +24,18 @@ import { Username } from '@standardnotes/domain-core'
@injectable()
export class SubscriptionSyncRequestedEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.UserSubscriptionRepository) private userSubscriptionRepository: UserSubscriptionRepositoryInterface,
@inject(TYPES.OfflineUserSubscriptionRepository)
@inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.Auth_UserSubscriptionRepository)
private userSubscriptionRepository: UserSubscriptionRepositoryInterface,
@inject(TYPES.Auth_OfflineUserSubscriptionRepository)
private offlineUserSubscriptionRepository: OfflineUserSubscriptionRepositoryInterface,
@inject(TYPES.RoleService) private roleService: RoleServiceInterface,
@inject(TYPES.SettingService) private settingService: SettingServiceInterface,
@inject(TYPES.SubscriptionSettingService) private subscriptionSettingService: SubscriptionSettingServiceInterface,
@inject(TYPES.OfflineSettingService) private offlineSettingService: OfflineSettingServiceInterface,
@inject(TYPES.ContenDecoder) private contentDecoder: ContentDecoderInterface,
@inject(TYPES.Logger) private logger: Logger,
@inject(TYPES.Auth_RoleService) private roleService: RoleServiceInterface,
@inject(TYPES.Auth_SettingService) private settingService: SettingServiceInterface,
@inject(TYPES.Auth_SubscriptionSettingService)
private subscriptionSettingService: SubscriptionSettingServiceInterface,
@inject(TYPES.Auth_OfflineSettingService) private offlineSettingService: OfflineSettingServiceInterface,
@inject(TYPES.Auth_ContenDecoder) private contentDecoder: ContentDecoderInterface,
@inject(TYPES.Auth_Logger) private logger: Logger,
) {}
async handle(event: SubscriptionSyncRequestedEvent): Promise<void> {

View File

@@ -8,8 +8,8 @@ import { SessionRepositoryInterface } from '../Session/SessionRepositoryInterfac
@injectable()
export class UserDisabledSessionUserAgentLoggingEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.SessionRepository) private sessionRepository: SessionRepositoryInterface,
@inject(TYPES.SessionRepository) private revokedSessionRepository: RevokedSessionRepositoryInterface,
@inject(TYPES.Auth_SessionRepository) private sessionRepository: SessionRepositoryInterface,
@inject(TYPES.Auth_SessionRepository) private revokedSessionRepository: RevokedSessionRepositoryInterface,
) {}
async handle(event: UserDisabledSessionUserAgentLoggingEvent): Promise<void> {

View File

@@ -8,10 +8,10 @@ import TYPES from '../../Bootstrap/Types'
@injectable()
export class UserEmailChangedEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.HTTPClient) private httpClient: AxiosInstance,
@inject(TYPES.USER_SERVER_CHANGE_EMAIL_URL) private userServerChangeEmailUrl: string,
@inject(TYPES.USER_SERVER_AUTH_KEY) private userServerAuthKey: string,
@inject(TYPES.Logger) private logger: Logger,
@inject(TYPES.Auth_HTTPClient) private httpClient: AxiosInstance,
@inject(TYPES.Auth_USER_SERVER_CHANGE_EMAIL_URL) private userServerChangeEmailUrl: string,
@inject(TYPES.Auth_USER_SERVER_AUTH_KEY) private userServerAuthKey: string,
@inject(TYPES.Auth_Logger) private logger: Logger,
) {}
async handle(event: UserEmailChangedEvent): Promise<void> {

View File

@@ -8,10 +8,10 @@ import TYPES from '../../Bootstrap/Types'
@injectable()
export class UserRegisteredEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.HTTPClient) private httpClient: AxiosInstance,
@inject(TYPES.USER_SERVER_REGISTRATION_URL) private userServerRegistrationUrl: string,
@inject(TYPES.USER_SERVER_AUTH_KEY) private userServerAuthKey: string,
@inject(TYPES.Logger) private logger: Logger,
@inject(TYPES.Auth_HTTPClient) private httpClient: AxiosInstance,
@inject(TYPES.Auth_USER_SERVER_REGISTRATION_URL) private userServerRegistrationUrl: string,
@inject(TYPES.Auth_USER_SERVER_AUTH_KEY) private userServerAuthKey: string,
@inject(TYPES.Auth_Logger) private logger: Logger,
) {}
async handle(event: UserRegisteredEvent): Promise<void> {

View File

@@ -17,13 +17,13 @@ import { OfflineUserSubscription } from '../Subscription/OfflineUserSubscription
@injectable()
export class RoleService implements RoleServiceInterface {
constructor(
@inject(TYPES.UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.RoleRepository) private roleRepository: RoleRepositoryInterface,
@inject(TYPES.OfflineUserSubscriptionRepository)
@inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.Auth_RoleRepository) private roleRepository: RoleRepositoryInterface,
@inject(TYPES.Auth_OfflineUserSubscriptionRepository)
private offlineUserSubscriptionRepository: OfflineUserSubscriptionRepositoryInterface,
@inject(TYPES.WebSocketsClientService) private webSocketsClientService: ClientServiceInterface,
@inject(TYPES.RoleToSubscriptionMap) private roleToSubscriptionMap: RoleToSubscriptionMapInterface,
@inject(TYPES.Logger) private logger: Logger,
@inject(TYPES.Auth_WebSocketsClientService) private webSocketsClientService: ClientServiceInterface,
@inject(TYPES.Auth_RoleToSubscriptionMap) private roleToSubscriptionMap: RoleToSubscriptionMapInterface,
@inject(TYPES.Auth_Logger) private logger: Logger,
) {}
async userHasPermission(userUuid: string, permissionName: PermissionName): Promise<boolean> {

View File

@@ -27,19 +27,21 @@ export class SessionService implements SessionServiceInterface {
static readonly SESSION_TOKEN_VERSION = 1
constructor(
@inject(TYPES.SessionRepository) private sessionRepository: SessionRepositoryInterface,
@inject(TYPES.EphemeralSessionRepository) private ephemeralSessionRepository: EphemeralSessionRepositoryInterface,
@inject(TYPES.RevokedSessionRepository) private revokedSessionRepository: RevokedSessionRepositoryInterface,
@inject(TYPES.DeviceDetector) private deviceDetector: UAParser,
@inject(TYPES.Timer) private timer: TimerInterface,
@inject(TYPES.Logger) private logger: Logger,
@inject(TYPES.ACCESS_TOKEN_AGE) private accessTokenAge: number,
@inject(TYPES.REFRESH_TOKEN_AGE) private refreshTokenAge: number,
@inject(TYPES.SettingService) private settingService: SettingServiceInterface,
@inject(TYPES.CryptoNode) private cryptoNode: CryptoNode,
@inject(TYPES.TraceSession) private traceSession: TraceSession,
@inject(TYPES.UserSubscriptionRepository) private userSubscriptionRepository: UserSubscriptionRepositoryInterface,
@inject(TYPES.READONLY_USERS) private readonlyUsers: string[],
@inject(TYPES.Auth_SessionRepository) private sessionRepository: SessionRepositoryInterface,
@inject(TYPES.Auth_EphemeralSessionRepository)
private ephemeralSessionRepository: EphemeralSessionRepositoryInterface,
@inject(TYPES.Auth_RevokedSessionRepository) private revokedSessionRepository: RevokedSessionRepositoryInterface,
@inject(TYPES.Auth_DeviceDetector) private deviceDetector: UAParser,
@inject(TYPES.Auth_Timer) private timer: TimerInterface,
@inject(TYPES.Auth_Logger) private logger: Logger,
@inject(TYPES.Auth_ACCESS_TOKEN_AGE) private accessTokenAge: number,
@inject(TYPES.Auth_REFRESH_TOKEN_AGE) private refreshTokenAge: number,
@inject(TYPES.Auth_SettingService) private settingService: SettingServiceInterface,
@inject(TYPES.Auth_CryptoNode) private cryptoNode: CryptoNode,
@inject(TYPES.Auth_TraceSession) private traceSession: TraceSession,
@inject(TYPES.Auth_UserSubscriptionRepository)
private userSubscriptionRepository: UserSubscriptionRepositoryInterface,
@inject(TYPES.Auth_READONLY_USERS) private readonlyUsers: string[],
) {}
async createNewSessionForUser(dto: {

View File

@@ -12,8 +12,8 @@ import { OfflineSettingServiceInterface } from './OfflineSettingServiceInterface
@injectable()
export class OfflineSettingService implements OfflineSettingServiceInterface {
constructor(
@inject(TYPES.OfflineSettingRepository) private offlineSettingRepository: OfflineSettingRepositoryInterface,
@inject(TYPES.Timer) private timer: TimerInterface,
@inject(TYPES.Auth_OfflineSettingRepository) private offlineSettingRepository: OfflineSettingRepositoryInterface,
@inject(TYPES.Auth_Timer) private timer: TimerInterface,
) {}
async createOrUpdate(dto: {

View File

@@ -10,8 +10,8 @@ import { SubscriptionSetting } from './SubscriptionSetting'
@injectable()
export class SettingDecrypter implements SettingDecrypterInterface {
constructor(
@inject(TYPES.UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.Crypter) private crypter: CrypterInterface,
@inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.Auth_Crypter) private crypter: CrypterInterface,
) {}
async decryptSettingValue(setting: Setting | SubscriptionSetting, userUuid: string): Promise<string | null> {

View File

@@ -15,8 +15,8 @@ import { SubscriptionSettingProps } from './SubscriptionSettingProps'
@injectable()
export class SettingFactory implements SettingFactoryInterface {
constructor(
@inject(TYPES.Crypter) private crypter: CrypterInterface,
@inject(TYPES.Timer) private timer: TimerInterface,
@inject(TYPES.Auth_Crypter) private crypter: CrypterInterface,
@inject(TYPES.Auth_Timer) private timer: TimerInterface,
) {}
async createSubscriptionSetting(

View File

@@ -24,9 +24,9 @@ export class SettingInterpreter implements SettingInterpreterInterface {
])
constructor(
@inject(TYPES.DomainEventPublisher) private domainEventPublisher: DomainEventPublisherInterface,
@inject(TYPES.DomainEventFactory) private domainEventFactory: DomainEventFactoryInterface,
@inject(TYPES.SettingRepository) private settingRepository: SettingRepositoryInterface,
@inject(TYPES.Auth_DomainEventPublisher) private domainEventPublisher: DomainEventPublisherInterface,
@inject(TYPES.Auth_DomainEventFactory) private domainEventFactory: DomainEventFactoryInterface,
@inject(TYPES.Auth_SettingRepository) private settingRepository: SettingRepositoryInterface,
) {}
async interpretSettingUpdated(

View File

@@ -17,12 +17,13 @@ import { SettingFactoryInterface } from './SettingFactoryInterface'
@injectable()
export class SettingService implements SettingServiceInterface {
constructor(
@inject(TYPES.SettingFactory) private factory: SettingFactoryInterface,
@inject(TYPES.SettingRepository) private settingRepository: SettingRepositoryInterface,
@inject(TYPES.SettingsAssociationService) private settingsAssociationService: SettingsAssociationServiceInterface,
@inject(TYPES.SettingInterpreter) private settingInterpreter: SettingInterpreterInterface,
@inject(TYPES.SettingDecrypter) private settingDecrypter: SettingDecrypterInterface,
@inject(TYPES.Logger) private logger: Logger,
@inject(TYPES.Auth_SettingFactory) private factory: SettingFactoryInterface,
@inject(TYPES.Auth_SettingRepository) private settingRepository: SettingRepositoryInterface,
@inject(TYPES.Auth_SettingsAssociationService)
private settingsAssociationService: SettingsAssociationServiceInterface,
@inject(TYPES.Auth_SettingInterpreter) private settingInterpreter: SettingInterpreterInterface,
@inject(TYPES.Auth_SettingDecrypter) private settingDecrypter: SettingDecrypterInterface,
@inject(TYPES.Auth_Logger) private logger: Logger,
) {}
async applyDefaultSettingsUponRegistration(user: User): Promise<void> {

View File

@@ -22,15 +22,16 @@ import { SettingInterpreterInterface } from './SettingInterpreterInterface'
@injectable()
export class SubscriptionSettingService implements SubscriptionSettingServiceInterface {
constructor(
@inject(TYPES.SettingFactory) private factory: SettingFactoryInterface,
@inject(TYPES.SubscriptionSettingRepository)
@inject(TYPES.Auth_SettingFactory) private factory: SettingFactoryInterface,
@inject(TYPES.Auth_SubscriptionSettingRepository)
private subscriptionSettingRepository: SubscriptionSettingRepositoryInterface,
@inject(TYPES.SubscriptionSettingsAssociationService)
@inject(TYPES.Auth_SubscriptionSettingsAssociationService)
private subscriptionSettingAssociationService: SubscriptionSettingsAssociationServiceInterface,
@inject(TYPES.SettingInterpreter) private settingInterpreter: SettingInterpreterInterface,
@inject(TYPES.SettingDecrypter) private settingDecrypter: SettingDecrypterInterface,
@inject(TYPES.UserSubscriptionRepository) private userSubscriptionRepository: UserSubscriptionRepositoryInterface,
@inject(TYPES.Logger) private logger: Logger,
@inject(TYPES.Auth_SettingInterpreter) private settingInterpreter: SettingInterpreterInterface,
@inject(TYPES.Auth_SettingDecrypter) private settingDecrypter: SettingDecrypterInterface,
@inject(TYPES.Auth_UserSubscriptionRepository)
private userSubscriptionRepository: UserSubscriptionRepositoryInterface,
@inject(TYPES.Auth_Logger) private logger: Logger,
) {}
async applyDefaultSubscriptionSettingsForSubscription(

View File

@@ -15,8 +15,8 @@ import { SubscriptionSettingsAssociationServiceInterface } from './SubscriptionS
@injectable()
export class SubscriptionSettingsAssociationService implements SubscriptionSettingsAssociationServiceInterface {
constructor(
@inject(TYPES.RoleToSubscriptionMap) private roleToSubscriptionMap: RoleToSubscriptionMapInterface,
@inject(TYPES.RoleRepository) private roleRepository: RoleRepositoryInterface,
@inject(TYPES.Auth_RoleToSubscriptionMap) private roleToSubscriptionMap: RoleToSubscriptionMapInterface,
@inject(TYPES.Auth_RoleRepository) private roleRepository: RoleRepositoryInterface,
) {}
private readonly settingsToSubscriptionNameMap = new Map<SubscriptionName, Map<string, SettingDescription>>([

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