mirror of
https://github.com/standardnotes/server
synced 2026-02-01 14:01:19 -05:00
Compare commits
8 Commits
@standardn
...
@standardn
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d810568a8 | ||
|
|
b8353aa817 | ||
|
|
7924f63e28 | ||
|
|
b3b617ea0b | ||
|
|
18a5071618 | ||
|
|
fea58029b9 | ||
|
|
e748723209 | ||
|
|
8a47d81936 |
24
.pnp.cjs
generated
24
.pnp.cjs
generated
@@ -4625,6 +4625,8 @@ const RAW_RUNTIME_STATE =
|
||||
["@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/syncing-server", "workspace:packages/syncing-server"],\
|
||||
["@types/cors", "npm:2.8.13"],\
|
||||
["@types/express", "npm:4.17.17"],\
|
||||
["@types/prettyjson", "npm:0.0.30"],\
|
||||
@@ -4712,7 +4714,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"],\
|
||||
@@ -4732,7 +4733,7 @@ const RAW_RUNTIME_STATE =
|
||||
["reflect-metadata", "npm:0.1.13"],\
|
||||
["sqlite3", "virtual:31b5a94a105c89c9294c3d524a7f8929fe63ee5a2efadf21951ca4c0cfd2ecf02e8f4ef5a066bbda091f1e3a56e57c6749069a080618c96b22e51131a330fc4a#npm:5.1.6"],\
|
||||
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.0"],\
|
||||
["typeorm", "virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:0.3.15"],\
|
||||
["typeorm", "virtual:67ad3a1ca34e24ce4821cc48979e98af0c3e5dd7aabc7ad0b5d22d1d977d6f943f81c9f141a420105ebdc61ef777e508a96c7946081decd98f8c30543d468b33#npm:0.3.15"],\
|
||||
["typescript", "patch:typescript@npm%3A5.0.4#optional!builtin<compat/typescript>::version=5.0.4&hash=b5f058"],\
|
||||
["winston", "npm:3.8.2"]\
|
||||
],\
|
||||
@@ -4896,7 +4897,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"],\
|
||||
@@ -4925,7 +4925,7 @@ const RAW_RUNTIME_STATE =
|
||||
["reflect-metadata", "npm:0.1.13"],\
|
||||
["sqlite3", "virtual:31b5a94a105c89c9294c3d524a7f8929fe63ee5a2efadf21951ca4c0cfd2ecf02e8f4ef5a066bbda091f1e3a56e57c6749069a080618c96b22e51131a330fc4a#npm:5.1.6"],\
|
||||
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.0"],\
|
||||
["typeorm", "virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:0.3.15"],\
|
||||
["typeorm", "virtual:67ad3a1ca34e24ce4821cc48979e98af0c3e5dd7aabc7ad0b5d22d1d977d6f943f81c9f141a420105ebdc61ef777e508a96c7946081decd98f8c30543d468b33#npm:0.3.15"],\
|
||||
["typescript", "patch:typescript@npm%3A5.0.4#optional!builtin<compat/typescript>::version=5.0.4&hash=b5f058"],\
|
||||
["ua-parser-js", "npm:1.0.35"],\
|
||||
["uuid", "npm:9.0.0"],\
|
||||
@@ -5298,16 +5298,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/",\
|
||||
@@ -15176,10 +15166,10 @@ const RAW_RUNTIME_STATE =
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}],\
|
||||
["virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:0.3.15", {\
|
||||
"packageLocation": "./.yarn/__virtual__/typeorm-virtual-7fe891193c/0/cache/typeorm-npm-0.3.15-20a6c4f754-db890f14cb.zip/node_modules/typeorm/",\
|
||||
["virtual:67ad3a1ca34e24ce4821cc48979e98af0c3e5dd7aabc7ad0b5d22d1d977d6f943f81c9f141a420105ebdc61ef777e508a96c7946081decd98f8c30543d468b33#npm:0.3.15", {\
|
||||
"packageLocation": "./.yarn/__virtual__/typeorm-virtual-91f15b21d5/0/cache/typeorm-npm-0.3.15-20a6c4f754-db890f14cb.zip/node_modules/typeorm/",\
|
||||
"packageDependencies": [\
|
||||
["typeorm", "virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:0.3.15"],\
|
||||
["typeorm", "virtual:67ad3a1ca34e24ce4821cc48979e98af0c3e5dd7aabc7ad0b5d22d1d977d6f943f81c9f141a420105ebdc61ef777e508a96c7946081decd98f8c30543d468b33#npm:0.3.15"],\
|
||||
["@google-cloud/spanner", null],\
|
||||
["@sap/hana-client", null],\
|
||||
["@sqltools/formatter", "npm:1.2.5"],\
|
||||
|
||||
Binary file not shown.
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/analytics",
|
||||
"version": "2.22.3",
|
||||
"version": "2.22.4",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/api-gateway",
|
||||
"version": "1.54.0",
|
||||
"version": "1.56.1",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -43,6 +43,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)
|
||||
|
||||
|
||||
@@ -1,28 +1,14 @@
|
||||
import {
|
||||
ControllerContainerInterface,
|
||||
ServiceContainerInterface,
|
||||
ServiceIdentifier,
|
||||
ServiceInterface,
|
||||
} from '@standardnotes/domain-core'
|
||||
import { ServiceContainerInterface, ServiceIdentifier, ServiceInterface } from '@standardnotes/domain-core'
|
||||
|
||||
import { ContainerConfigLoader } from './Container'
|
||||
|
||||
export class Service implements ServiceInterface {
|
||||
constructor(
|
||||
private serviceContainer: ServiceContainerInterface,
|
||||
private controllerContainer: ControllerContainerInterface,
|
||||
) {
|
||||
this.serviceContainer.register(ServiceIdentifier.create(ServiceIdentifier.NAMES.ApiGateway).getValue(), this)
|
||||
constructor(private serviceContainer: ServiceContainerInterface) {
|
||||
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 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> {
|
||||
|
||||
@@ -5,17 +5,17 @@ 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 {
|
||||
constructor(
|
||||
@inject(TYPES.HTTPClient) private httpClient: AxiosInstance,
|
||||
@inject(TYPES.AUTH_SERVER_URL) private authServerUrl: string,
|
||||
@inject(TYPES.ServiceProxy) private serviceProxy: ServiceProxyInterface,
|
||||
@inject(TYPES.AUTH_JWT_SECRET) private jwtSecret: string,
|
||||
@inject(TYPES.CROSS_SERVICE_TOKEN_CACHE_TTL) private crossServiceTokenCacheTTL: number,
|
||||
@inject(TYPES.CrossServiceTokenCache) private crossServiceTokenCache: CrossServiceTokenCacheInterface,
|
||||
@@ -47,26 +47,16 @@ 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`,
|
||||
})
|
||||
const authResponse = await this.serviceProxy.validateSession(authHeaderValue)
|
||||
|
||||
if (authResponse.status > 200) {
|
||||
response.setHeader('content-type', authResponse.headers['content-type'] as string)
|
||||
response.setHeader('content-type', authResponse.headers.contentType)
|
||||
response.status(authResponse.status).send(authResponse.data)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
crossServiceToken = authResponse.data.authToken
|
||||
crossServiceToken = (authResponse.data as { authToken: string }).authToken
|
||||
crossServiceTokenFetchedFromCache = false
|
||||
}
|
||||
|
||||
@@ -87,16 +77,14 @@ export class AuthMiddleware extends BaseMiddleware {
|
||||
})
|
||||
}
|
||||
|
||||
response.locals.userUuid = decodedToken.user.uuid
|
||||
response.locals.user = decodedToken.user
|
||||
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)
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -8,7 +8,7 @@ import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolv
|
||||
@controller('/v1/items', TYPES.AuthMiddleware)
|
||||
export class ItemsController extends BaseHttpController {
|
||||
constructor(
|
||||
@inject(TYPES.ServiceProxy) private httpService: ServiceProxyInterface,
|
||||
@inject(TYPES.ServiceProxy) private serviceProxy: ServiceProxyInterface,
|
||||
@inject(TYPES.EndpointResolver) private endpointResolver: EndpointResolverInterface,
|
||||
) {
|
||||
super()
|
||||
@@ -16,7 +16,7 @@ export class ItemsController extends BaseHttpController {
|
||||
|
||||
@httpPost('/')
|
||||
async sync(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(
|
||||
await this.serviceProxy.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'items/sync'),
|
||||
@@ -26,7 +26,7 @@ export class ItemsController extends BaseHttpController {
|
||||
|
||||
@httpPost('/check-integrity')
|
||||
async checkIntegrity(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(
|
||||
await this.serviceProxy.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'items/check-integrity'),
|
||||
@@ -36,7 +36,7 @@ export class ItemsController extends BaseHttpController {
|
||||
|
||||
@httpGet('/:uuid')
|
||||
async getItem(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callSyncingServer(
|
||||
await this.serviceProxy.callSyncingServer(
|
||||
request,
|
||||
response,
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'items/:uuid', request.params.uuid),
|
||||
|
||||
@@ -227,7 +227,7 @@ export class UsersController extends BaseHttpController {
|
||||
this.endpointResolver.resolveEndpointOrMethodIdentifier(
|
||||
'GET',
|
||||
'users/:userUuid/subscription',
|
||||
response.locals.userUuid,
|
||||
response.locals.user.uuid,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -24,6 +24,30 @@ export class HttpServiceProxy implements ServiceProxyInterface {
|
||||
@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,
|
||||
@@ -238,7 +262,7 @@ export class HttpServiceProxy implements ServiceProxyInterface {
|
||||
response.status(serviceResponse.status).send({
|
||||
meta: {
|
||||
auth: {
|
||||
userUuid: response.locals.userUuid,
|
||||
userUuid: response.locals.user?.uuid,
|
||||
roles: response.locals.roles,
|
||||
},
|
||||
server: {
|
||||
|
||||
@@ -49,4 +49,11 @@ export interface ServiceProxyInterface {
|
||||
endpointOrMethodIdentifier: string,
|
||||
payload?: Record<string, unknown> | string,
|
||||
): Promise<void>
|
||||
validateSession(authorizationHeaderValue: string): Promise<{
|
||||
status: number
|
||||
data: unknown
|
||||
headers: {
|
||||
contentType: string
|
||||
}
|
||||
}>
|
||||
}
|
||||
|
||||
@@ -6,6 +6,34 @@ import { ServiceContainerInterface, ServiceIdentifier } from '@standardnotes/dom
|
||||
export class DirectCallServiceProxy implements ServiceProxyInterface {
|
||||
constructor(private serviceContainer: ServiceContainerInterface) {}
|
||||
|
||||
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.')
|
||||
}
|
||||
@@ -49,7 +77,12 @@ export class DirectCallServiceProxy implements ServiceProxyInterface {
|
||||
throw new Error('Syncing service not found')
|
||||
}
|
||||
|
||||
await service.handleRequest(request, response, endpointOrMethodIdentifier)
|
||||
const serviceResponse = (await service.handleRequest(request, response, endpointOrMethodIdentifier)) as {
|
||||
statusCode: number
|
||||
json: Record<string, unknown>
|
||||
}
|
||||
|
||||
void (response as Response).status(serviceResponse.statusCode).send(serviceResponse.json)
|
||||
}
|
||||
|
||||
async callLegacySyncingServer(
|
||||
|
||||
@@ -4,6 +4,8 @@ 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'],
|
||||
@@ -49,6 +51,10 @@ export class EndpointResolver implements EndpointResolverInterface {
|
||||
['[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'],
|
||||
])
|
||||
|
||||
resolveEndpointOrMethodIdentifier(method: string, endpoint: string, ...params: string[]): string {
|
||||
|
||||
@@ -3,6 +3,28 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [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
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/auth-server",
|
||||
"version": "1.106.0",
|
||||
"version": "1.109.1",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -6,6 +6,7 @@ import { Container } from 'inversify'
|
||||
import {
|
||||
DomainEventHandlerInterface,
|
||||
DomainEventMessageHandlerInterface,
|
||||
DomainEventPublisherInterface,
|
||||
DomainEventSubscriberFactoryInterface,
|
||||
} from '@standardnotes/domain-events'
|
||||
import { TimerInterface, Timer } from '@standardnotes/time'
|
||||
@@ -13,7 +14,6 @@ import { UAParser } from 'ua-parser-js'
|
||||
|
||||
import { Env } from './Env'
|
||||
import TYPES from './Types'
|
||||
import { AuthMiddleware } from '../Controller/AuthMiddleware'
|
||||
import { AuthenticateUser } from '../Domain/UseCase/AuthenticateUser'
|
||||
import { Repository } from 'typeorm'
|
||||
import { AppDataSource } from './DataSource'
|
||||
@@ -23,7 +23,6 @@ import { SessionService } from '../Domain/Session/SessionService'
|
||||
import { TypeORMSessionRepository } from '../Infra/TypeORM/TypeORMSessionRepository'
|
||||
import { TypeORMUserRepository } from '../Infra/TypeORM/TypeORMUserRepository'
|
||||
import { SessionProjector } from '../Projection/SessionProjector'
|
||||
import { SessionMiddleware } from '../Controller/SessionMiddleware'
|
||||
import { RefreshSessionToken } from '../Domain/UseCase/RefreshSessionToken'
|
||||
import { KeyParamsFactory } from '../Domain/User/KeyParamsFactory'
|
||||
import { SignIn } from '../Domain/UseCase/SignIn'
|
||||
@@ -35,8 +34,6 @@ import { AuthResponseFactory20200115 } from '../Domain/Auth/AuthResponseFactory2
|
||||
import { AuthResponseFactoryResolver } from '../Domain/Auth/AuthResponseFactoryResolver'
|
||||
import { ClearLoginAttempts } from '../Domain/UseCase/ClearLoginAttempts'
|
||||
import { IncreaseLoginAttempts } from '../Domain/UseCase/IncreaseLoginAttempts'
|
||||
import { LockMiddleware } from '../Controller/LockMiddleware'
|
||||
import { AuthMiddlewareWithoutResponse } from '../Controller/AuthMiddlewareWithoutResponse'
|
||||
import { GetUserKeyParams } from '../Domain/UseCase/GetUserKeyParams/GetUserKeyParams'
|
||||
import { UpdateUser } from '../Domain/UseCase/UpdateUser'
|
||||
import { RedisEphemeralSessionRepository } from '../Infra/Redis/RedisEphemeralSessionRepository'
|
||||
@@ -90,6 +87,8 @@ import { FeatureService } from '../Domain/Feature/FeatureService'
|
||||
import { SettingServiceInterface } from '../Domain/Setting/SettingServiceInterface'
|
||||
import { ExtensionKeyGrantedEventHandler } from '../Domain/Handler/ExtensionKeyGrantedEventHandler'
|
||||
import {
|
||||
DirectCallDomainEventPublisher,
|
||||
DirectCallEventMessageHandler,
|
||||
SNSDomainEventPublisher,
|
||||
SQSDomainEventSubscriberFactory,
|
||||
SQSEventMessageHandler,
|
||||
@@ -100,7 +99,6 @@ import { ChangeCredentials } from '../Domain/UseCase/ChangeCredentials/ChangeCre
|
||||
import { SubscriptionReassignedEventHandler } from '../Domain/Handler/SubscriptionReassignedEventHandler'
|
||||
import { UserSubscriptionRepositoryInterface } from '../Domain/Subscription/UserSubscriptionRepositoryInterface'
|
||||
import { CreateSubscriptionToken } from '../Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken'
|
||||
import { ApiGatewayAuthMiddleware } from '../Controller/ApiGatewayAuthMiddleware'
|
||||
import { SubscriptionTokenRepositoryInterface } from '../Domain/Subscription/SubscriptionTokenRepositoryInterface'
|
||||
import { RedisSubscriptionTokenRepository } from '../Infra/Redis/RedisSubscriptionTokenRepository'
|
||||
import { AuthenticateSubscriptionToken } from '../Domain/UseCase/AuthenticateSubscriptionToken/AuthenticateSubscriptionToken'
|
||||
@@ -113,7 +111,6 @@ import { TypeORMOfflineSettingRepository } from '../Infra/TypeORM/TypeORMOffline
|
||||
import { OfflineUserSubscription } from '../Domain/Subscription/OfflineUserSubscription'
|
||||
import { OfflineUserSubscriptionRepositoryInterface } from '../Domain/Subscription/OfflineUserSubscriptionRepositoryInterface'
|
||||
import { TypeORMOfflineUserSubscriptionRepository } from '../Infra/TypeORM/TypeORMOfflineUserSubscriptionRepository'
|
||||
import { OfflineUserAuthMiddleware } from '../Controller/OfflineUserAuthMiddleware'
|
||||
import { OfflineSubscriptionTokenRepositoryInterface } from '../Domain/Auth/OfflineSubscriptionTokenRepositoryInterface'
|
||||
import { RedisOfflineSubscriptionTokenRepository } from '../Infra/Redis/RedisOfflineSubscriptionTokenRepository'
|
||||
import { CreateOfflineSubscriptionToken } from '../Domain/UseCase/CreateOfflineSubscriptionToken/CreateOfflineSubscriptionToken'
|
||||
@@ -121,7 +118,6 @@ import { AuthenticateOfflineSubscriptionToken } from '../Domain/UseCase/Authenti
|
||||
import { SubscriptionCancelledEventHandler } from '../Domain/Handler/SubscriptionCancelledEventHandler'
|
||||
import { ContentDecoder, ContentDecoderInterface, ProtocolVersion } from '@standardnotes/common'
|
||||
import { GetUserOfflineSubscription } from '../Domain/UseCase/GetUserOfflineSubscription/GetUserOfflineSubscription'
|
||||
import { ApiGatewayOfflineAuthMiddleware } from '../Controller/ApiGatewayOfflineAuthMiddleware'
|
||||
import { UserEmailChangedEventHandler } from '../Domain/Handler/UserEmailChangedEventHandler'
|
||||
import { SettingsAssociationServiceInterface } from '../Domain/Setting/SettingsAssociationServiceInterface'
|
||||
import { SettingsAssociationService } from '../Domain/Setting/SettingsAssociationService'
|
||||
@@ -237,12 +233,37 @@ import { InversifyExpressAuthenticatorsController } from '../Infra/InversifyExpr
|
||||
import { InversifyExpressSubscriptionInvitesController } from '../Infra/InversifyExpressUtils/InversifyExpressSubscriptionInvitesController'
|
||||
import { InversifyExpressUserRequestsController } from '../Infra/InversifyExpressUtils/InversifyExpressUserRequestsController'
|
||||
import { InversifyExpressWebSocketsController } from '../Infra/InversifyExpressUtils/InversifyExpressWebSocketsController'
|
||||
import { InversifyExpressSessionsController } from '../Infra/InversifyExpressUtils/InversifyExpressSessionsController'
|
||||
import { InversifyExpressValetTokenController } from '../Infra/InversifyExpressUtils/InversifyExpressValetTokenController'
|
||||
import { InversifyExpressUsersController } from '../Infra/InversifyExpressUtils/InversifyExpressUsersController'
|
||||
import { InversifyExpressAdminController } from '../Infra/InversifyExpressUtils/InversifyExpressAdminController'
|
||||
import { InversifyExpressSubscriptionTokensController } from '../Infra/InversifyExpressUtils/InversifyExpressSubscriptionTokensController'
|
||||
import { InversifyExpressSubscriptionSettingsController } from '../Infra/InversifyExpressUtils/InversifyExpressSubscriptionSettingsController'
|
||||
import { InversifyExpressSettingsController } from '../Infra/InversifyExpressUtils/InversifyExpressSettingsController'
|
||||
import { SessionMiddleware } from '../Infra/InversifyExpressUtils/Middleware/SessionMiddleware'
|
||||
import { ApiGatewayAuthMiddleware } from '../Infra/InversifyExpressUtils/Middleware/ApiGatewayAuthMiddleware'
|
||||
import { ApiGatewayOfflineAuthMiddleware } from '../Infra/InversifyExpressUtils/Middleware/ApiGatewayOfflineAuthMiddleware'
|
||||
import { AuthMiddleware } from '../Infra/InversifyExpressUtils/Middleware/AuthMiddleware'
|
||||
import { OfflineUserAuthMiddleware } from '../Infra/InversifyExpressUtils/Middleware/OfflineUserAuthMiddleware'
|
||||
import { AuthMiddlewareWithoutResponse } from '../Infra/InversifyExpressUtils/Middleware/AuthMiddlewareWithoutResponse'
|
||||
import { LockMiddleware } from '../Infra/InversifyExpressUtils/Middleware/LockMiddleware'
|
||||
import { InversifyExpressSessionController } from '../Infra/InversifyExpressUtils/InversifyExpressSessionController'
|
||||
import { InversifyExpressOfflineController } from '../Infra/InversifyExpressUtils/InversifyExpressOfflineController'
|
||||
import { InversifyExpressListedController } from '../Infra/InversifyExpressUtils/InversifyExpressListedController'
|
||||
import { InversifyExpressInternalController } from '../Infra/InversifyExpressUtils/InversifyExpressInternalController'
|
||||
import { InversifyExpressFeaturesController } from '../Infra/InversifyExpressUtils/InversifyExpressFeaturesController'
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const newrelicFormatter = require('@newrelic/winston-enricher')
|
||||
|
||||
export class ContainerConfigLoader {
|
||||
async load(controllerConatiner?: ControllerContainerInterface): Promise<Container> {
|
||||
async load(configuration?: {
|
||||
controllerConatiner?: ControllerContainerInterface
|
||||
directCallDomainEventPublisher?: DirectCallDomainEventPublisher
|
||||
}): Promise<Container> {
|
||||
const directCallDomainEventPublisher =
|
||||
configuration?.directCallDomainEventPublisher ?? new DirectCallDomainEventPublisher()
|
||||
|
||||
const env: Env = new Env()
|
||||
env.load()
|
||||
|
||||
@@ -275,38 +296,41 @@ 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: 'auth' },
|
||||
})
|
||||
container.bind<winston.Logger>(TYPES.Auth_Logger).toConstantValue(logger)
|
||||
|
||||
container.bind<TimerInterface>(TYPES.Auth_Timer).toConstantValue(new Timer())
|
||||
|
||||
const snsConfig: SNSClientConfig = {
|
||||
region: env.get('SNS_AWS_REGION', true),
|
||||
}
|
||||
if (env.get('SNS_ENDPOINT', true)) {
|
||||
snsConfig.endpoint = env.get('SNS_ENDPOINT', true)
|
||||
}
|
||||
if (env.get('SNS_ACCESS_KEY_ID', true) && env.get('SNS_SECRET_ACCESS_KEY', true)) {
|
||||
snsConfig.credentials = {
|
||||
accessKeyId: env.get('SNS_ACCESS_KEY_ID', true),
|
||||
secretAccessKey: env.get('SNS_SECRET_ACCESS_KEY', true),
|
||||
if (!isConfiguredForHomeServer) {
|
||||
const snsConfig: SNSClientConfig = {
|
||||
region: env.get('SNS_AWS_REGION', true),
|
||||
}
|
||||
}
|
||||
container.bind<SNSClient>(TYPES.Auth_SNS).toConstantValue(new SNSClient(snsConfig))
|
||||
if (env.get('SNS_ENDPOINT', true)) {
|
||||
snsConfig.endpoint = env.get('SNS_ENDPOINT', true)
|
||||
}
|
||||
if (env.get('SNS_ACCESS_KEY_ID', true) && env.get('SNS_SECRET_ACCESS_KEY', true)) {
|
||||
snsConfig.credentials = {
|
||||
accessKeyId: env.get('SNS_ACCESS_KEY_ID', true),
|
||||
secretAccessKey: env.get('SNS_SECRET_ACCESS_KEY', true),
|
||||
}
|
||||
}
|
||||
container.bind<SNSClient>(TYPES.Auth_SNS).toConstantValue(new SNSClient(snsConfig))
|
||||
|
||||
const sqsConfig: SQSClientConfig = {
|
||||
region: env.get('SQS_AWS_REGION', true),
|
||||
}
|
||||
if (env.get('SQS_ENDPOINT', true)) {
|
||||
sqsConfig.endpoint = env.get('SQS_ENDPOINT', true)
|
||||
}
|
||||
if (env.get('SQS_ACCESS_KEY_ID', true) && env.get('SQS_SECRET_ACCESS_KEY', true)) {
|
||||
sqsConfig.credentials = {
|
||||
accessKeyId: env.get('SQS_ACCESS_KEY_ID', true),
|
||||
secretAccessKey: env.get('SQS_SECRET_ACCESS_KEY', true),
|
||||
const sqsConfig: SQSClientConfig = {
|
||||
region: env.get('SQS_AWS_REGION', true),
|
||||
}
|
||||
if (env.get('SQS_ENDPOINT', true)) {
|
||||
sqsConfig.endpoint = env.get('SQS_ENDPOINT', true)
|
||||
}
|
||||
if (env.get('SQS_ACCESS_KEY_ID', true) && env.get('SQS_SECRET_ACCESS_KEY', true)) {
|
||||
sqsConfig.credentials = {
|
||||
accessKeyId: env.get('SQS_ACCESS_KEY_ID', true),
|
||||
secretAccessKey: env.get('SQS_SECRET_ACCESS_KEY', true),
|
||||
}
|
||||
}
|
||||
container.bind<SQSClient>(TYPES.Auth_SQS).toConstantValue(new SQSClient(sqsConfig))
|
||||
}
|
||||
container.bind<SQSClient>(TYPES.Auth_SQS).toConstantValue(new SQSClient(sqsConfig))
|
||||
|
||||
// Mapping
|
||||
container
|
||||
@@ -494,7 +518,7 @@ export class ContainerConfigLoader {
|
||||
.toConstantValue(env.get('USER_SERVER_CHANGE_EMAIL_URL', true))
|
||||
container.bind(TYPES.Auth_NEW_RELIC_ENABLED).toConstantValue(env.get('NEW_RELIC_ENABLED', true))
|
||||
container.bind(TYPES.Auth_SYNCING_SERVER_URL).toConstantValue(env.get('SYNCING_SERVER_URL', true))
|
||||
container.bind(TYPES.Auth_VERSION).toConstantValue(env.get('VERSION'))
|
||||
container.bind(TYPES.Auth_VERSION).toConstantValue(env.get('VERSION', true) ?? 'development')
|
||||
container.bind(TYPES.Auth_PAYMENTS_SERVER_URL).toConstantValue(env.get('PAYMENTS_SERVER_URL', true))
|
||||
container
|
||||
.bind(TYPES.Auth_SESSION_TRACE_DAYS_TTL)
|
||||
@@ -649,9 +673,11 @@ export class ContainerConfigLoader {
|
||||
container.bind<UserSubscriptionServiceInterface>(TYPES.Auth_UserSubscriptionService).to(UserSubscriptionService)
|
||||
|
||||
container
|
||||
.bind<SNSDomainEventPublisher>(TYPES.Auth_DomainEventPublisher)
|
||||
.bind<DomainEventPublisherInterface>(TYPES.Auth_DomainEventPublisher)
|
||||
.toConstantValue(
|
||||
new SNSDomainEventPublisher(container.get(TYPES.Auth_SNS), container.get(TYPES.Auth_SNS_TOPIC_ARN)),
|
||||
isConfiguredForHomeServer
|
||||
? directCallDomainEventPublisher
|
||||
: new SNSDomainEventPublisher(container.get(TYPES.Auth_SNS), container.get(TYPES.Auth_SNS_TOPIC_ARN)),
|
||||
)
|
||||
|
||||
// use cases
|
||||
@@ -836,7 +862,7 @@ export class ContainerConfigLoader {
|
||||
// Controller
|
||||
container
|
||||
.bind<ControllerContainerInterface>(TYPES.Auth_ControllerContainer)
|
||||
.toConstantValue(controllerConatiner ?? new ControllerContainer())
|
||||
.toConstantValue(configuration?.controllerConatiner ?? new ControllerContainer())
|
||||
container
|
||||
.bind<AuthController>(TYPES.Auth_AuthController)
|
||||
.toConstantValue(
|
||||
@@ -956,22 +982,34 @@ export class ContainerConfigLoader {
|
||||
['EMAIL_SUBSCRIPTION_UNSUBSCRIBED', container.get(TYPES.Auth_EmailSubscriptionUnsubscribedEventHandler)],
|
||||
])
|
||||
|
||||
container
|
||||
.bind<DomainEventMessageHandlerInterface>(TYPES.Auth_DomainEventMessageHandler)
|
||||
.toConstantValue(
|
||||
env.get('NEW_RELIC_ENABLED', true) === 'true'
|
||||
? new SQSNewRelicEventMessageHandler(eventHandlers, container.get(TYPES.Auth_Logger))
|
||||
: new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Auth_Logger)),
|
||||
)
|
||||
container
|
||||
.bind<DomainEventSubscriberFactoryInterface>(TYPES.Auth_DomainEventSubscriberFactory)
|
||||
.toConstantValue(
|
||||
new SQSDomainEventSubscriberFactory(
|
||||
container.get(TYPES.Auth_SQS),
|
||||
container.get(TYPES.Auth_SQS_QUEUE_URL),
|
||||
container.get(TYPES.Auth_DomainEventMessageHandler),
|
||||
),
|
||||
if (isConfiguredForHomeServer) {
|
||||
const directCallEventMessageHandler = new DirectCallEventMessageHandler(
|
||||
eventHandlers,
|
||||
container.get(TYPES.Auth_Logger),
|
||||
)
|
||||
directCallDomainEventPublisher.register(directCallEventMessageHandler)
|
||||
container
|
||||
.bind<DomainEventMessageHandlerInterface>(TYPES.Auth_DomainEventMessageHandler)
|
||||
.toConstantValue(directCallEventMessageHandler)
|
||||
} else {
|
||||
container
|
||||
.bind<DomainEventMessageHandlerInterface>(TYPES.Auth_DomainEventMessageHandler)
|
||||
.toConstantValue(
|
||||
env.get('NEW_RELIC_ENABLED', true) === 'true'
|
||||
? new SQSNewRelicEventMessageHandler(eventHandlers, container.get(TYPES.Auth_Logger))
|
||||
: new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Auth_Logger)),
|
||||
)
|
||||
|
||||
container
|
||||
.bind<DomainEventSubscriberFactoryInterface>(TYPES.Auth_DomainEventSubscriberFactory)
|
||||
.toConstantValue(
|
||||
new SQSDomainEventSubscriberFactory(
|
||||
container.get(TYPES.Auth_SQS),
|
||||
container.get(TYPES.Auth_SQS_QUEUE_URL),
|
||||
container.get(TYPES.Auth_DomainEventMessageHandler),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
container
|
||||
.bind<InversifyExpressAuthController>(TYPES.Auth_InversifyExpressAuthController)
|
||||
@@ -987,39 +1025,168 @@ export class ContainerConfigLoader {
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressAuthenticatorsController>(TYPES.Auth_InversifyExpressAuthenticatorsController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressAuthenticatorsController(
|
||||
container.get(TYPES.Auth_AuthenticatorsController),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressSubscriptionInvitesController>(TYPES.Auth_InversifyExpressSubscriptionInvitesController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressSubscriptionInvitesController(
|
||||
container.get(TYPES.Auth_SubscriptionInvitesController),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressUserRequestsController>(TYPES.Auth_InversifyExpressUserRequestsController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressUserRequestsController(
|
||||
container.get(TYPES.Auth_UserRequestsController),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressWebSocketsController>(TYPES.Auth_InversifyExpressWebSocketsController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressWebSocketsController(
|
||||
container.get(TYPES.Auth_CreateCrossServiceToken),
|
||||
container.get(TYPES.Auth_WebSocketConnectionTokenDecoder),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
|
||||
// Inversify Controllers
|
||||
if (isConfiguredForHomeServer) {
|
||||
container
|
||||
.bind<InversifyExpressAuthenticatorsController>(TYPES.Auth_InversifyExpressAuthenticatorsController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressAuthenticatorsController(
|
||||
container.get(TYPES.Auth_AuthenticatorsController),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressSubscriptionInvitesController>(TYPES.Auth_InversifyExpressSubscriptionInvitesController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressSubscriptionInvitesController(
|
||||
container.get(TYPES.Auth_SubscriptionInvitesController),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressUserRequestsController>(TYPES.Auth_InversifyExpressUserRequestsController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressUserRequestsController(
|
||||
container.get(TYPES.Auth_UserRequestsController),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressWebSocketsController>(TYPES.Auth_InversifyExpressWebSocketsController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressWebSocketsController(
|
||||
container.get(TYPES.Auth_CreateCrossServiceToken),
|
||||
container.get(TYPES.Auth_WebSocketConnectionTokenDecoder),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressSessionsController>(TYPES.Auth_SessionsController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressSessionsController(
|
||||
container.get(TYPES.Auth_GetActiveSessionsForUser),
|
||||
container.get(TYPES.Auth_AuthenticateRequest),
|
||||
container.get(TYPES.Auth_SessionProjector),
|
||||
container.get(TYPES.Auth_CreateCrossServiceToken),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressValetTokenController>(TYPES.Auth_InversifyExpressValetTokenController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressValetTokenController(
|
||||
container.get(TYPES.Auth_CreateValetToken),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressUsersController>(TYPES.Auth_InversifyExpressUsersController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressUsersController(
|
||||
container.get(TYPES.Auth_UpdateUser),
|
||||
container.get(TYPES.Auth_GetUserKeyParams),
|
||||
container.get(TYPES.Auth_DeleteAccount),
|
||||
container.get(TYPES.Auth_GetUserSubscription),
|
||||
container.get(TYPES.Auth_ClearLoginAttempts),
|
||||
container.get(TYPES.Auth_IncreaseLoginAttempts),
|
||||
container.get(TYPES.Auth_ChangeCredentials),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressAdminController>(TYPES.Auth_InversifyExpressAdminController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressAdminController(
|
||||
container.get(TYPES.Auth_DeleteSetting),
|
||||
container.get(TYPES.Auth_UserRepository),
|
||||
container.get(TYPES.Auth_CreateSubscriptionToken),
|
||||
container.get(TYPES.Auth_CreateOfflineSubscriptionToken),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressSubscriptionTokensController>(TYPES.Auth_InversifyExpressSubscriptionTokensController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressSubscriptionTokensController(
|
||||
container.get(TYPES.Auth_CreateSubscriptionToken),
|
||||
container.get(TYPES.Auth_AuthenticateSubscriptionToken),
|
||||
container.get(TYPES.Auth_SettingService),
|
||||
container.get(TYPES.Auth_UserProjector),
|
||||
container.get(TYPES.Auth_RoleProjector),
|
||||
container.get(TYPES.Auth_CrossServiceTokenEncoder),
|
||||
container.get(TYPES.Auth_AUTH_JWT_TTL),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressSubscriptionSettingsController>(TYPES.Auth_InversifyExpressSubscriptionSettingsController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressSubscriptionSettingsController(
|
||||
container.get(TYPES.Auth_GetSetting),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressSettingsController>(TYPES.Auth_InversifyExpressSettingsController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressSettingsController(
|
||||
container.get(TYPES.Auth_GetSettings),
|
||||
container.get(TYPES.Auth_GetSetting),
|
||||
container.get(TYPES.Auth_UpdateSetting),
|
||||
container.get(TYPES.Auth_DeleteSetting),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressSessionController>(TYPES.Auth_InversifyExpressSessionController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressSessionController(
|
||||
container.get(TYPES.Auth_DeleteSessionForUser),
|
||||
container.get(TYPES.Auth_DeletePreviousSessionsForUser),
|
||||
container.get(TYPES.Auth_RefreshSessionToken),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressOfflineController>(TYPES.Auth_InversifyExpressOfflineController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressOfflineController(
|
||||
container.get(TYPES.Auth_GetUserFeatures),
|
||||
container.get(TYPES.Auth_GetUserOfflineSubscription),
|
||||
container.get(TYPES.Auth_CreateOfflineSubscriptionToken),
|
||||
container.get(TYPES.Auth_AuthenticateOfflineSubscriptionToken),
|
||||
container.get(TYPES.Auth_OfflineUserTokenEncoder),
|
||||
container.get(TYPES.Auth_AUTH_JWT_TTL),
|
||||
container.get(TYPES.Auth_Logger),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressListedController>(TYPES.Auth_InversifyExpressListedController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressListedController(
|
||||
container.get(TYPES.Auth_CreateListedAccount),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressInternalController>(TYPES.Auth_InversifyExpressInternalController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressInternalController(
|
||||
container.get(TYPES.Auth_GetUserFeatures),
|
||||
container.get(TYPES.Auth_GetSetting),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<InversifyExpressFeaturesController>(TYPES.Auth_InversifyExpressFeaturesController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressFeaturesController(
|
||||
container.get(TYPES.Auth_GetUserFeatures),
|
||||
container.get(TYPES.Auth_ControllerContainer),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
return container
|
||||
}
|
||||
|
||||
@@ -6,13 +6,15 @@ import {
|
||||
} 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(ServiceIdentifier.create(ServiceIdentifier.NAMES.Auth).getValue(), this)
|
||||
this.serviceContainer.register(this.getId(), this)
|
||||
}
|
||||
|
||||
async handleRequest(request: never, response: never, endpointOrMethodIdentifier: string): Promise<unknown> {
|
||||
@@ -28,7 +30,10 @@ export class Service implements ServiceInterface {
|
||||
async getContainer(): Promise<unknown> {
|
||||
const config = new ContainerConfigLoader()
|
||||
|
||||
return config.load(this.controllerContainer)
|
||||
return config.load({
|
||||
controllerConatiner: this.controllerContainer,
|
||||
directCallDomainEventPublisher: this.directCallDomainEventPublisher,
|
||||
})
|
||||
}
|
||||
|
||||
getId(): ServiceIdentifier {
|
||||
|
||||
@@ -222,6 +222,20 @@ const TYPES = {
|
||||
Auth_InversifyExpressSubscriptionInvitesController: Symbol.for('Auth_InversifyExpressSubscriptionInvitesController'),
|
||||
Auth_InversifyExpressUserRequestsController: Symbol.for('Auth_InversifyExpressUserRequestsController'),
|
||||
Auth_InversifyExpressWebSocketsController: Symbol.for('Auth_InversifyExpressWebSocketsController'),
|
||||
Auth_SessionsController: Symbol.for('Auth_SessionsController'),
|
||||
Auth_InversifyExpressValetTokenController: Symbol.for('Auth_InversifyExpressValetTokenController'),
|
||||
Auth_InversifyExpressUsersController: Symbol.for('Auth_InversifyExpressUsersController'),
|
||||
Auth_InversifyExpressAdminController: Symbol.for('Auth_InversifyExpressAdminController'),
|
||||
Auth_InversifyExpressSubscriptionTokensController: Symbol.for('Auth_InversifyExpressSubscriptionTokensController'),
|
||||
Auth_InversifyExpressSubscriptionSettingsController: Symbol.for(
|
||||
'Auth_InversifyExpressSubscriptionSettingsController',
|
||||
),
|
||||
Auth_InversifyExpressSettingsController: Symbol.for('Auth_InversifyExpressSettingsController'),
|
||||
Auth_InversifyExpressSessionController: Symbol.for('Auth_InversifyExpressSessionController'),
|
||||
Auth_InversifyExpressOfflineController: Symbol.for('Auth_InversifyExpressOfflineController'),
|
||||
Auth_InversifyExpressListedController: Symbol.for('Auth_InversifyExpressListedController'),
|
||||
Auth_InversifyExpressInternalController: Symbol.for('Auth_InversifyExpressInternalController'),
|
||||
Auth_InversifyExpressFeaturesController: Symbol.for('Auth_InversifyExpressFeaturesController'),
|
||||
}
|
||||
|
||||
export default TYPES
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { AdminController } from './AdminController'
|
||||
import { InversifyExpressAdminController } from './InversifyExpressAdminController'
|
||||
import { results } from 'inversify-express-utils'
|
||||
import { User } from '../Domain/User/User'
|
||||
import { UserRepositoryInterface } from '../Domain/User/UserRepositoryInterface'
|
||||
import { User } from '../../Domain/User/User'
|
||||
import { UserRepositoryInterface } from '../../Domain/User/UserRepositoryInterface'
|
||||
import * as express from 'express'
|
||||
import { DeleteSetting } from '../Domain/UseCase/DeleteSetting/DeleteSetting'
|
||||
import { CreateSubscriptionToken } from '../Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken'
|
||||
import { CreateOfflineSubscriptionToken } from '../Domain/UseCase/CreateOfflineSubscriptionToken/CreateOfflineSubscriptionToken'
|
||||
import { DeleteSetting } from '../../Domain/UseCase/DeleteSetting/DeleteSetting'
|
||||
import { CreateSubscriptionToken } from '../../Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken'
|
||||
import { CreateOfflineSubscriptionToken } from '../../Domain/UseCase/CreateOfflineSubscriptionToken/CreateOfflineSubscriptionToken'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
|
||||
describe('AdminController', () => {
|
||||
describe('InversifyExpressAdminController', () => {
|
||||
let deleteSetting: DeleteSetting
|
||||
let userRepository: UserRepositoryInterface
|
||||
let createSubscriptionToken: CreateSubscriptionToken
|
||||
@@ -20,7 +20,7 @@ describe('AdminController', () => {
|
||||
let controllerContainer: ControllerContainerInterface
|
||||
|
||||
const createController = () =>
|
||||
new AdminController(
|
||||
new InversifyExpressAdminController(
|
||||
deleteSetting,
|
||||
userRepository,
|
||||
createSubscriptionToken,
|
||||
@@ -11,14 +11,14 @@ import {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
results,
|
||||
} from 'inversify-express-utils'
|
||||
import TYPES from '../Bootstrap/Types'
|
||||
import { CreateOfflineSubscriptionToken } from '../Domain/UseCase/CreateOfflineSubscriptionToken/CreateOfflineSubscriptionToken'
|
||||
import { CreateSubscriptionToken } from '../Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken'
|
||||
import { DeleteSetting } from '../Domain/UseCase/DeleteSetting/DeleteSetting'
|
||||
import { UserRepositoryInterface } from '../Domain/User/UserRepositoryInterface'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { CreateOfflineSubscriptionToken } from '../../Domain/UseCase/CreateOfflineSubscriptionToken/CreateOfflineSubscriptionToken'
|
||||
import { CreateSubscriptionToken } from '../../Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken'
|
||||
import { DeleteSetting } from '../../Domain/UseCase/DeleteSetting/DeleteSetting'
|
||||
import { UserRepositoryInterface } from '../../Domain/User/UserRepositoryInterface'
|
||||
|
||||
@controller('/admin')
|
||||
export class AdminController extends BaseHttpController {
|
||||
export class InversifyExpressAdminController extends BaseHttpController {
|
||||
constructor(
|
||||
@inject(TYPES.Auth_DeleteSetting) private doDeleteSetting: DeleteSetting,
|
||||
@inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface,
|
||||
@@ -2,13 +2,13 @@ import 'reflect-metadata'
|
||||
|
||||
import * as express from 'express'
|
||||
|
||||
import { FeaturesController } from './FeaturesController'
|
||||
import { InversifyExpressFeaturesController } from './InversifyExpressFeaturesController'
|
||||
import { results } from 'inversify-express-utils'
|
||||
import { User } from '../Domain/User/User'
|
||||
import { GetUserFeatures } from '../Domain/UseCase/GetUserFeatures/GetUserFeatures'
|
||||
import { User } from '../../Domain/User/User'
|
||||
import { GetUserFeatures } from '../../Domain/UseCase/GetUserFeatures/GetUserFeatures'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
|
||||
describe('FeaturesController', () => {
|
||||
describe('InversifyExpressFeaturesController', () => {
|
||||
let getUserFeatures: GetUserFeatures
|
||||
|
||||
let request: express.Request
|
||||
@@ -16,7 +16,7 @@ describe('FeaturesController', () => {
|
||||
let user: User
|
||||
let controllerContainer: ControllerContainerInterface
|
||||
|
||||
const createController = () => new FeaturesController(getUserFeatures, controllerContainer)
|
||||
const createController = () => new InversifyExpressFeaturesController(getUserFeatures, controllerContainer)
|
||||
|
||||
beforeEach(() => {
|
||||
controllerContainer = {} as jest.Mocked<ControllerContainerInterface>
|
||||
@@ -7,12 +7,12 @@ import {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
results,
|
||||
} from 'inversify-express-utils'
|
||||
import TYPES from '../Bootstrap/Types'
|
||||
import { GetUserFeatures } from '../Domain/UseCase/GetUserFeatures/GetUserFeatures'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { GetUserFeatures } from '../../Domain/UseCase/GetUserFeatures/GetUserFeatures'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
|
||||
@controller('/users/:userUuid/features')
|
||||
export class FeaturesController extends BaseHttpController {
|
||||
export class InversifyExpressFeaturesController extends BaseHttpController {
|
||||
constructor(
|
||||
@inject(TYPES.Auth_GetUserFeatures) private doGetUserFeatures: GetUserFeatures,
|
||||
@inject(TYPES.Auth_ControllerContainer) private controllerContainer: ControllerContainerInterface,
|
||||
@@ -1,7 +1,7 @@
|
||||
import { controller, httpGet } from 'inversify-express-utils'
|
||||
|
||||
@controller('/healthcheck')
|
||||
export class HealthCheckController {
|
||||
export class InversifyExpressHealthCheckController {
|
||||
@httpGet('/')
|
||||
public async get(): Promise<string> {
|
||||
return 'OK'
|
||||
@@ -2,13 +2,13 @@ import 'reflect-metadata'
|
||||
|
||||
import * as express from 'express'
|
||||
|
||||
import { InternalController } from './InternalController'
|
||||
import { InversifyExpressInternalController } from './InversifyExpressInternalController'
|
||||
import { results } from 'inversify-express-utils'
|
||||
import { User } from '../Domain/User/User'
|
||||
import { GetUserFeatures } from '../Domain/UseCase/GetUserFeatures/GetUserFeatures'
|
||||
import { GetSetting } from '../Domain/UseCase/GetSetting/GetSetting'
|
||||
import { User } from '../../Domain/User/User'
|
||||
import { GetUserFeatures } from '../../Domain/UseCase/GetUserFeatures/GetUserFeatures'
|
||||
import { GetSetting } from '../../Domain/UseCase/GetSetting/GetSetting'
|
||||
|
||||
describe('InternalController', () => {
|
||||
describe('InversifyExpressInternalController', () => {
|
||||
let getUserFeatures: GetUserFeatures
|
||||
let getSetting: GetSetting
|
||||
|
||||
@@ -16,7 +16,7 @@ describe('InternalController', () => {
|
||||
let response: express.Response
|
||||
let user: User
|
||||
|
||||
const createController = () => new InternalController(getUserFeatures, getSetting)
|
||||
const createController = () => new InversifyExpressInternalController(getUserFeatures, getSetting)
|
||||
|
||||
beforeEach(() => {
|
||||
user = {} as jest.Mocked<User>
|
||||
@@ -7,12 +7,12 @@ import {
|
||||
// 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'
|
||||
import { GetUserFeatures } from '../Domain/UseCase/GetUserFeatures/GetUserFeatures'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { GetSetting } from '../../Domain/UseCase/GetSetting/GetSetting'
|
||||
import { GetUserFeatures } from '../../Domain/UseCase/GetUserFeatures/GetUserFeatures'
|
||||
|
||||
@controller('/internal')
|
||||
export class InternalController extends BaseHttpController {
|
||||
export class InversifyExpressInternalController extends BaseHttpController {
|
||||
constructor(
|
||||
@inject(TYPES.Auth_GetUserFeatures) private doGetUserFeatures: GetUserFeatures,
|
||||
@inject(TYPES.Auth_GetSetting) private doGetSetting: GetSetting,
|
||||
@@ -3,12 +3,12 @@ import 'reflect-metadata'
|
||||
import * as express from 'express'
|
||||
import { results } from 'inversify-express-utils'
|
||||
|
||||
import { ListedController } from './ListedController'
|
||||
import { User } from '../Domain/User/User'
|
||||
import { CreateListedAccount } from '../Domain/UseCase/CreateListedAccount/CreateListedAccount'
|
||||
import { InversifyExpressListedController } from './InversifyExpressListedController'
|
||||
import { User } from '../../Domain/User/User'
|
||||
import { CreateListedAccount } from '../../Domain/UseCase/CreateListedAccount/CreateListedAccount'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
|
||||
describe('ListedController', () => {
|
||||
describe('InversifyExpressListedController', () => {
|
||||
let createListedAccount: CreateListedAccount
|
||||
|
||||
let request: express.Request
|
||||
@@ -16,7 +16,7 @@ describe('ListedController', () => {
|
||||
let user: User
|
||||
let controllerContainer: ControllerContainerInterface
|
||||
|
||||
const createController = () => new ListedController(createListedAccount, controllerContainer)
|
||||
const createController = () => new InversifyExpressListedController(createListedAccount, controllerContainer)
|
||||
|
||||
beforeEach(() => {
|
||||
controllerContainer = {} as jest.Mocked<ControllerContainerInterface>
|
||||
@@ -2,13 +2,13 @@ import { inject } from 'inversify'
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
import { BaseHttpController, controller, httpPost, results } from 'inversify-express-utils'
|
||||
import { Request, Response } from 'express'
|
||||
import TYPES from '../Bootstrap/Types'
|
||||
import { CreateListedAccount } from '../Domain/UseCase/CreateListedAccount/CreateListedAccount'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { CreateListedAccount } from '../../Domain/UseCase/CreateListedAccount/CreateListedAccount'
|
||||
import { ErrorTag } from '@standardnotes/responses'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
|
||||
@controller('/listed')
|
||||
export class ListedController extends BaseHttpController {
|
||||
export class InversifyExpressListedController extends BaseHttpController {
|
||||
constructor(
|
||||
@inject(TYPES.Auth_CreateListedAccount) private doCreateListedAccount: CreateListedAccount,
|
||||
@inject(TYPES.Auth_ControllerContainer) private controllerContainer: ControllerContainerInterface,
|
||||
@@ -2,21 +2,21 @@ import 'reflect-metadata'
|
||||
|
||||
import * as express from 'express'
|
||||
|
||||
import { OfflineController } from './OfflineController'
|
||||
import { InversifyExpressOfflineController } from './InversifyExpressOfflineController'
|
||||
import { results } from 'inversify-express-utils'
|
||||
import { User } from '../Domain/User/User'
|
||||
import { GetUserFeatures } from '../Domain/UseCase/GetUserFeatures/GetUserFeatures'
|
||||
import { CreateOfflineSubscriptionToken } from '../Domain/UseCase/CreateOfflineSubscriptionToken/CreateOfflineSubscriptionToken'
|
||||
import { CreateOfflineSubscriptionTokenResponse } from '../Domain/UseCase/CreateOfflineSubscriptionToken/CreateOfflineSubscriptionTokenResponse'
|
||||
import { AuthenticateOfflineSubscriptionToken } from '../Domain/UseCase/AuthenticateOfflineSubscriptionToken/AuthenticateOfflineSubscriptionToken'
|
||||
import { OfflineUserSubscription } from '../Domain/Subscription/OfflineUserSubscription'
|
||||
import { GetUserOfflineSubscription } from '../Domain/UseCase/GetUserOfflineSubscription/GetUserOfflineSubscription'
|
||||
import { User } from '../../Domain/User/User'
|
||||
import { GetUserFeatures } from '../../Domain/UseCase/GetUserFeatures/GetUserFeatures'
|
||||
import { CreateOfflineSubscriptionToken } from '../../Domain/UseCase/CreateOfflineSubscriptionToken/CreateOfflineSubscriptionToken'
|
||||
import { CreateOfflineSubscriptionTokenResponse } from '../../Domain/UseCase/CreateOfflineSubscriptionToken/CreateOfflineSubscriptionTokenResponse'
|
||||
import { AuthenticateOfflineSubscriptionToken } from '../../Domain/UseCase/AuthenticateOfflineSubscriptionToken/AuthenticateOfflineSubscriptionToken'
|
||||
import { OfflineUserSubscription } from '../../Domain/Subscription/OfflineUserSubscription'
|
||||
import { GetUserOfflineSubscription } from '../../Domain/UseCase/GetUserOfflineSubscription/GetUserOfflineSubscription'
|
||||
import { OfflineUserTokenData, TokenEncoderInterface } from '@standardnotes/security'
|
||||
import { SubscriptionName } from '@standardnotes/common'
|
||||
import { Logger } from 'winston'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
|
||||
describe('OfflineController', () => {
|
||||
describe('InversifyExpressOfflineController', () => {
|
||||
let getUserFeatures: GetUserFeatures
|
||||
let getUserOfflineSubscription: GetUserOfflineSubscription
|
||||
let createOfflineSubscriptionToken: CreateOfflineSubscriptionToken
|
||||
@@ -32,7 +32,7 @@ describe('OfflineController', () => {
|
||||
let controllerContainer: ControllerContainerInterface
|
||||
|
||||
const createController = () =>
|
||||
new OfflineController(
|
||||
new InversifyExpressOfflineController(
|
||||
getUserFeatures,
|
||||
getUserOfflineSubscription,
|
||||
createOfflineSubscriptionToken,
|
||||
@@ -8,17 +8,17 @@ import {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
results,
|
||||
} from 'inversify-express-utils'
|
||||
import TYPES from '../Bootstrap/Types'
|
||||
import { GetUserFeatures } from '../Domain/UseCase/GetUserFeatures/GetUserFeatures'
|
||||
import { AuthenticateOfflineSubscriptionToken } from '../Domain/UseCase/AuthenticateOfflineSubscriptionToken/AuthenticateOfflineSubscriptionToken'
|
||||
import { CreateOfflineSubscriptionToken } from '../Domain/UseCase/CreateOfflineSubscriptionToken/CreateOfflineSubscriptionToken'
|
||||
import { GetUserOfflineSubscription } from '../Domain/UseCase/GetUserOfflineSubscription/GetUserOfflineSubscription'
|
||||
import { Logger } from 'winston'
|
||||
import { OfflineUserTokenData, TokenEncoderInterface } from '@standardnotes/security'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { AuthenticateOfflineSubscriptionToken } from '../../Domain/UseCase/AuthenticateOfflineSubscriptionToken/AuthenticateOfflineSubscriptionToken'
|
||||
import { CreateOfflineSubscriptionToken } from '../../Domain/UseCase/CreateOfflineSubscriptionToken/CreateOfflineSubscriptionToken'
|
||||
import { GetUserFeatures } from '../../Domain/UseCase/GetUserFeatures/GetUserFeatures'
|
||||
import { GetUserOfflineSubscription } from '../../Domain/UseCase/GetUserOfflineSubscription/GetUserOfflineSubscription'
|
||||
|
||||
@controller('/offline')
|
||||
export class OfflineController extends BaseHttpController {
|
||||
export class InversifyExpressOfflineController extends BaseHttpController {
|
||||
constructor(
|
||||
@inject(TYPES.Auth_GetUserFeatures) private doGetUserFeatures: GetUserFeatures,
|
||||
@inject(TYPES.Auth_GetUserOfflineSubscription) private getUserOfflineSubscription: GetUserOfflineSubscription,
|
||||
@@ -2,14 +2,14 @@ import 'reflect-metadata'
|
||||
|
||||
import * as express from 'express'
|
||||
|
||||
import { SessionController } from './SessionController'
|
||||
import { InversifyExpressSessionController } from './InversifyExpressSessionController'
|
||||
import { results } from 'inversify-express-utils'
|
||||
import { RefreshSessionToken } from '../Domain/UseCase/RefreshSessionToken'
|
||||
import { DeletePreviousSessionsForUser } from '../Domain/UseCase/DeletePreviousSessionsForUser'
|
||||
import { DeleteSessionForUser } from '../Domain/UseCase/DeleteSessionForUser'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { DeletePreviousSessionsForUser } from '../../Domain/UseCase/DeletePreviousSessionsForUser'
|
||||
import { DeleteSessionForUser } from '../../Domain/UseCase/DeleteSessionForUser'
|
||||
import { RefreshSessionToken } from '../../Domain/UseCase/RefreshSessionToken'
|
||||
|
||||
describe('SessionController', () => {
|
||||
describe('InversifyExpressSessionController', () => {
|
||||
let deleteSessionForUser: DeleteSessionForUser
|
||||
let deletePreviousSessionsForUser: DeletePreviousSessionsForUser
|
||||
let refreshSessionToken: RefreshSessionToken
|
||||
@@ -18,7 +18,12 @@ describe('SessionController', () => {
|
||||
let controllerContainer: ControllerContainerInterface
|
||||
|
||||
const createController = () =>
|
||||
new SessionController(deleteSessionForUser, deletePreviousSessionsForUser, refreshSessionToken, controllerContainer)
|
||||
new InversifyExpressSessionController(
|
||||
deleteSessionForUser,
|
||||
deletePreviousSessionsForUser,
|
||||
refreshSessionToken,
|
||||
controllerContainer,
|
||||
)
|
||||
|
||||
beforeEach(() => {
|
||||
controllerContainer = {} as jest.Mocked<ControllerContainerInterface>
|
||||
@@ -9,14 +9,14 @@ import {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
results,
|
||||
} from 'inversify-express-utils'
|
||||
import TYPES from '../Bootstrap/Types'
|
||||
import { DeletePreviousSessionsForUser } from '../Domain/UseCase/DeletePreviousSessionsForUser'
|
||||
import { DeleteSessionForUser } from '../Domain/UseCase/DeleteSessionForUser'
|
||||
import { RefreshSessionToken } from '../Domain/UseCase/RefreshSessionToken'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { DeletePreviousSessionsForUser } from '../../Domain/UseCase/DeletePreviousSessionsForUser'
|
||||
import { DeleteSessionForUser } from '../../Domain/UseCase/DeleteSessionForUser'
|
||||
import { RefreshSessionToken } from '../../Domain/UseCase/RefreshSessionToken'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
|
||||
@controller('/session')
|
||||
export class SessionController extends BaseHttpController {
|
||||
export class InversifyExpressSessionController extends BaseHttpController {
|
||||
constructor(
|
||||
@inject(TYPES.Auth_DeleteSessionForUser) private deleteSessionForUser: DeleteSessionForUser,
|
||||
@inject(TYPES.Auth_DeletePreviousSessionsForUser)
|
||||
@@ -2,17 +2,18 @@ import 'reflect-metadata'
|
||||
|
||||
import * as express from 'express'
|
||||
|
||||
import { SessionsController } from './SessionsController'
|
||||
import { InversifyExpressSessionsController } from './InversifyExpressSessionsController'
|
||||
import { results } from 'inversify-express-utils'
|
||||
import { Session } from '../Domain/Session/Session'
|
||||
import { ProjectorInterface } from '../Projection/ProjectorInterface'
|
||||
import { GetActiveSessionsForUser } from '../Domain/UseCase/GetActiveSessionsForUser'
|
||||
import { AuthenticateRequest } from '../Domain/UseCase/AuthenticateRequest'
|
||||
import { User } from '../Domain/User/User'
|
||||
import { CreateCrossServiceToken } from '../Domain/UseCase/CreateCrossServiceToken/CreateCrossServiceToken'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { User } from '@standardnotes/responses'
|
||||
|
||||
describe('SessionsController', () => {
|
||||
import { AuthenticateRequest } from '../../Domain/UseCase/AuthenticateRequest'
|
||||
import { CreateCrossServiceToken } from '../../Domain/UseCase/CreateCrossServiceToken/CreateCrossServiceToken'
|
||||
import { GetActiveSessionsForUser } from '../../Domain/UseCase/GetActiveSessionsForUser'
|
||||
import { ProjectorInterface } from '../../Projection/ProjectorInterface'
|
||||
import { Session } from '../../Domain/Session/Session'
|
||||
|
||||
describe('InversifyExpressSessionsController', () => {
|
||||
let getActiveSessionsForUser: GetActiveSessionsForUser
|
||||
let authenticateRequest: AuthenticateRequest
|
||||
let sessionProjector: ProjectorInterface<Session>
|
||||
@@ -24,7 +25,7 @@ describe('SessionsController', () => {
|
||||
let controllerContainer: ControllerContainerInterface
|
||||
|
||||
const createController = () =>
|
||||
new SessionsController(
|
||||
new InversifyExpressSessionsController(
|
||||
getActiveSessionsForUser,
|
||||
authenticateRequest,
|
||||
sessionProjector,
|
||||
@@ -8,18 +8,19 @@ import {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
results,
|
||||
} from 'inversify-express-utils'
|
||||
import TYPES from '../Bootstrap/Types'
|
||||
import { Session } from '../Domain/Session/Session'
|
||||
import { AuthenticateRequest } from '../Domain/UseCase/AuthenticateRequest'
|
||||
import { GetActiveSessionsForUser } from '../Domain/UseCase/GetActiveSessionsForUser'
|
||||
import { User } from '../Domain/User/User'
|
||||
import { ProjectorInterface } from '../Projection/ProjectorInterface'
|
||||
import { SessionProjector } from '../Projection/SessionProjector'
|
||||
import { CreateCrossServiceToken } from '../Domain/UseCase/CreateCrossServiceToken/CreateCrossServiceToken'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { AuthenticateRequest } from '../../Domain/UseCase/AuthenticateRequest'
|
||||
import { CreateCrossServiceToken } from '../../Domain/UseCase/CreateCrossServiceToken/CreateCrossServiceToken'
|
||||
import { GetActiveSessionsForUser } from '../../Domain/UseCase/GetActiveSessionsForUser'
|
||||
import { ProjectorInterface } from '../../Projection/ProjectorInterface'
|
||||
import { SessionProjector } from '../../Projection/SessionProjector'
|
||||
import { User } from '../../Domain/User/User'
|
||||
import { Session } from '../../Domain/Session/Session'
|
||||
|
||||
@controller('/sessions')
|
||||
export class SessionsController extends BaseHttpController {
|
||||
export class InversifyExpressSessionsController extends BaseHttpController {
|
||||
constructor(
|
||||
@inject(TYPES.Auth_GetActiveSessionsForUser) private getActiveSessionsForUser: GetActiveSessionsForUser,
|
||||
@inject(TYPES.Auth_AuthenticateRequest) private authenticateRequest: AuthenticateRequest,
|
||||
@@ -30,6 +31,7 @@ export class SessionsController extends BaseHttpController {
|
||||
super()
|
||||
|
||||
this.controllerContainer.register('auth.sessions.list', this.getSessions.bind(this))
|
||||
this.controllerContainer.register('auth.sessions.validate', this.validate.bind(this))
|
||||
}
|
||||
|
||||
@httpPost('/validate')
|
||||
@@ -2,17 +2,17 @@ import 'reflect-metadata'
|
||||
|
||||
import * as express from 'express'
|
||||
|
||||
import { SettingsController } from './SettingsController'
|
||||
import { InversifyExpressSettingsController } from './InversifyExpressSettingsController'
|
||||
import { results } from 'inversify-express-utils'
|
||||
import { User } from '../Domain/User/User'
|
||||
import { GetSettings } from '../Domain/UseCase/GetSettings/GetSettings'
|
||||
import { GetSetting } from '../Domain/UseCase/GetSetting/GetSetting'
|
||||
import { UpdateSetting } from '../Domain/UseCase/UpdateSetting/UpdateSetting'
|
||||
import { DeleteSetting } from '../Domain/UseCase/DeleteSetting/DeleteSetting'
|
||||
import { EncryptionVersion } from '../Domain/Encryption/EncryptionVersion'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { EncryptionVersion } from '../../Domain/Encryption/EncryptionVersion'
|
||||
import { DeleteSetting } from '../../Domain/UseCase/DeleteSetting/DeleteSetting'
|
||||
import { GetSetting } from '../../Domain/UseCase/GetSetting/GetSetting'
|
||||
import { GetSettings } from '../../Domain/UseCase/GetSettings/GetSettings'
|
||||
import { UpdateSetting } from '../../Domain/UseCase/UpdateSetting/UpdateSetting'
|
||||
import { User } from '../../Domain/User/User'
|
||||
|
||||
describe('SettingsController', () => {
|
||||
describe('InversifyExpressSettingsController', () => {
|
||||
let deleteSetting: DeleteSetting
|
||||
let getSettings: GetSettings
|
||||
let getSetting: GetSetting
|
||||
@@ -24,7 +24,7 @@ describe('SettingsController', () => {
|
||||
let controllerContainer: ControllerContainerInterface
|
||||
|
||||
const createController = () =>
|
||||
new SettingsController(getSettings, getSetting, updateSetting, deleteSetting, controllerContainer)
|
||||
new InversifyExpressSettingsController(getSettings, getSetting, updateSetting, deleteSetting, controllerContainer)
|
||||
|
||||
beforeEach(() => {
|
||||
controllerContainer = {} as jest.Mocked<ControllerContainerInterface>
|
||||
@@ -10,16 +10,16 @@ import {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
results,
|
||||
} from 'inversify-express-utils'
|
||||
import TYPES from '../Bootstrap/Types'
|
||||
import { EncryptionVersion } from '../Domain/Encryption/EncryptionVersion'
|
||||
import { DeleteSetting } from '../Domain/UseCase/DeleteSetting/DeleteSetting'
|
||||
import { GetSetting } from '../Domain/UseCase/GetSetting/GetSetting'
|
||||
import { GetSettings } from '../Domain/UseCase/GetSettings/GetSettings'
|
||||
import { UpdateSetting } from '../Domain/UseCase/UpdateSetting/UpdateSetting'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { EncryptionVersion } from '../../Domain/Encryption/EncryptionVersion'
|
||||
import { DeleteSetting } from '../../Domain/UseCase/DeleteSetting/DeleteSetting'
|
||||
import { GetSetting } from '../../Domain/UseCase/GetSetting/GetSetting'
|
||||
import { GetSettings } from '../../Domain/UseCase/GetSettings/GetSettings'
|
||||
import { UpdateSetting } from '../../Domain/UseCase/UpdateSetting/UpdateSetting'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
|
||||
@controller('/users/:userUuid')
|
||||
export class SettingsController extends BaseHttpController {
|
||||
export class InversifyExpressSettingsController extends BaseHttpController {
|
||||
constructor(
|
||||
@inject(TYPES.Auth_GetSettings) private doGetSettings: GetSettings,
|
||||
@inject(TYPES.Auth_GetSetting) private doGetSetting: GetSetting,
|
||||
@@ -3,12 +3,12 @@ import 'reflect-metadata'
|
||||
import * as express from 'express'
|
||||
|
||||
import { results } from 'inversify-express-utils'
|
||||
import { User } from '../Domain/User/User'
|
||||
import { SubscriptionSettingsController } from './SubscriptionSettingsController'
|
||||
import { GetSetting } from '../Domain/UseCase/GetSetting/GetSetting'
|
||||
import { InversifyExpressSubscriptionSettingsController } from './InversifyExpressSubscriptionSettingsController'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { User } from '../../Domain/User/User'
|
||||
import { GetSetting } from '../../Domain/UseCase/GetSetting/GetSetting'
|
||||
|
||||
describe('SubscriptionSettingsController', () => {
|
||||
describe('InversifyExpressSubscriptionSettingsController', () => {
|
||||
let getSetting: GetSetting
|
||||
|
||||
let request: express.Request
|
||||
@@ -16,7 +16,7 @@ describe('SubscriptionSettingsController', () => {
|
||||
let user: User
|
||||
let controllerContainer: ControllerContainerInterface
|
||||
|
||||
const createController = () => new SubscriptionSettingsController(getSetting, controllerContainer)
|
||||
const createController = () => new InversifyExpressSubscriptionSettingsController(getSetting, controllerContainer)
|
||||
|
||||
beforeEach(() => {
|
||||
controllerContainer = {} as jest.Mocked<ControllerContainerInterface>
|
||||
@@ -7,12 +7,12 @@ import {
|
||||
// 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'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { GetSetting } from '../../Domain/UseCase/GetSetting/GetSetting'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
|
||||
@controller('/users/:userUuid')
|
||||
export class SubscriptionSettingsController extends BaseHttpController {
|
||||
export class InversifyExpressSubscriptionSettingsController extends BaseHttpController {
|
||||
constructor(
|
||||
@inject(TYPES.Auth_GetSetting) private doGetSetting: GetSetting,
|
||||
@inject(TYPES.Auth_ControllerContainer) private controllerContainer: ControllerContainerInterface,
|
||||
@@ -3,19 +3,19 @@ import 'reflect-metadata'
|
||||
import * as express from 'express'
|
||||
import { results } from 'inversify-express-utils'
|
||||
|
||||
import { SubscriptionTokensController } from './SubscriptionTokensController'
|
||||
import { User } from '../Domain/User/User'
|
||||
import { CreateSubscriptionToken } from '../Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken'
|
||||
import { CreateSubscriptionTokenResponse } from '../Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionTokenResponse'
|
||||
import { AuthenticateSubscriptionToken } from '../Domain/UseCase/AuthenticateSubscriptionToken/AuthenticateSubscriptionToken'
|
||||
import { ProjectorInterface } from '../Projection/ProjectorInterface'
|
||||
import { Role } from '../Domain/Role/Role'
|
||||
import { SettingServiceInterface } from '../Domain/Setting/SettingServiceInterface'
|
||||
import { Setting } from '../Domain/Setting/Setting'
|
||||
import { InversifyExpressSubscriptionTokensController } from './InversifyExpressSubscriptionTokensController'
|
||||
import { CrossServiceTokenData, TokenEncoderInterface } from '@standardnotes/security'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { Setting } from '../../Domain/Setting/Setting'
|
||||
import { SettingServiceInterface } from '../../Domain/Setting/SettingServiceInterface'
|
||||
import { AuthenticateSubscriptionToken } from '../../Domain/UseCase/AuthenticateSubscriptionToken/AuthenticateSubscriptionToken'
|
||||
import { CreateSubscriptionToken } from '../../Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken'
|
||||
import { CreateSubscriptionTokenResponse } from '../../Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionTokenResponse'
|
||||
import { ProjectorInterface } from '../../Projection/ProjectorInterface'
|
||||
import { User } from '../../Domain/User/User'
|
||||
import { Role } from '../../Domain/Role/Role'
|
||||
|
||||
describe('SubscriptionTokensController', () => {
|
||||
describe('InversifyExpressSubscriptionTokensController', () => {
|
||||
let createSubscriptionToken: CreateSubscriptionToken
|
||||
let authenticateToken: AuthenticateSubscriptionToken
|
||||
const jwtTTL = 60
|
||||
@@ -33,7 +33,7 @@ describe('SubscriptionTokensController', () => {
|
||||
let controllerContainer: ControllerContainerInterface
|
||||
|
||||
const createController = () =>
|
||||
new SubscriptionTokensController(
|
||||
new InversifyExpressSubscriptionTokensController(
|
||||
createSubscriptionToken,
|
||||
authenticateToken,
|
||||
settingService,
|
||||
@@ -11,17 +11,17 @@ import {
|
||||
results,
|
||||
} from 'inversify-express-utils'
|
||||
|
||||
import TYPES from '../Bootstrap/Types'
|
||||
import { Role } from '../Domain/Role/Role'
|
||||
import { SettingServiceInterface } from '../Domain/Setting/SettingServiceInterface'
|
||||
import { AuthenticateSubscriptionToken } from '../Domain/UseCase/AuthenticateSubscriptionToken/AuthenticateSubscriptionToken'
|
||||
import { CreateSubscriptionToken } from '../Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken'
|
||||
import { User } from '../Domain/User/User'
|
||||
import { ProjectorInterface } from '../Projection/ProjectorInterface'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { Role } from '../../Domain/Role/Role'
|
||||
import { SettingServiceInterface } from '../../Domain/Setting/SettingServiceInterface'
|
||||
import { AuthenticateSubscriptionToken } from '../../Domain/UseCase/AuthenticateSubscriptionToken/AuthenticateSubscriptionToken'
|
||||
import { CreateSubscriptionToken } from '../../Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken'
|
||||
import { User } from '../../Domain/User/User'
|
||||
import { ProjectorInterface } from '../../Projection/ProjectorInterface'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
|
||||
@controller('/subscription-tokens')
|
||||
export class SubscriptionTokensController extends BaseHttpController {
|
||||
export class InversifyExpressSubscriptionTokensController extends BaseHttpController {
|
||||
constructor(
|
||||
@inject(TYPES.Auth_CreateSubscriptionToken) private createSubscriptionToken: CreateSubscriptionToken,
|
||||
@inject(TYPES.Auth_AuthenticateSubscriptionToken) private authenticateToken: AuthenticateSubscriptionToken,
|
||||
@@ -2,20 +2,20 @@ import 'reflect-metadata'
|
||||
|
||||
import * as express from 'express'
|
||||
|
||||
import { UsersController } from './UsersController'
|
||||
import { InversifyExpressUsersController } from './InversifyExpressUsersController'
|
||||
import { results } from 'inversify-express-utils'
|
||||
import { User } from '../Domain/User/User'
|
||||
import { UpdateUser } from '../Domain/UseCase/UpdateUser'
|
||||
import { GetUserKeyParams } from '../Domain/UseCase/GetUserKeyParams/GetUserKeyParams'
|
||||
import { DeleteAccount } from '../Domain/UseCase/DeleteAccount/DeleteAccount'
|
||||
import { GetUserSubscription } from '../Domain/UseCase/GetUserSubscription/GetUserSubscription'
|
||||
import { ClearLoginAttempts } from '../Domain/UseCase/ClearLoginAttempts'
|
||||
import { IncreaseLoginAttempts } from '../Domain/UseCase/IncreaseLoginAttempts'
|
||||
import { ChangeCredentials } from '../Domain/UseCase/ChangeCredentials/ChangeCredentials'
|
||||
import { InviteToSharedSubscription } from '../Domain/UseCase/InviteToSharedSubscription/InviteToSharedSubscription'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { DeleteAccount } from '../../Domain/UseCase/DeleteAccount/DeleteAccount'
|
||||
import { ChangeCredentials } from '../../Domain/UseCase/ChangeCredentials/ChangeCredentials'
|
||||
import { ClearLoginAttempts } from '../../Domain/UseCase/ClearLoginAttempts'
|
||||
import { GetUserKeyParams } from '../../Domain/UseCase/GetUserKeyParams/GetUserKeyParams'
|
||||
import { GetUserSubscription } from '../../Domain/UseCase/GetUserSubscription/GetUserSubscription'
|
||||
import { IncreaseLoginAttempts } from '../../Domain/UseCase/IncreaseLoginAttempts'
|
||||
import { InviteToSharedSubscription } from '../../Domain/UseCase/InviteToSharedSubscription/InviteToSharedSubscription'
|
||||
import { UpdateUser } from '../../Domain/UseCase/UpdateUser'
|
||||
import { User } from '../../Domain/User/User'
|
||||
|
||||
describe('UsersController', () => {
|
||||
describe('InversifyExpressUsersController', () => {
|
||||
let updateUser: UpdateUser
|
||||
let deleteAccount: DeleteAccount
|
||||
let getUserKeyParams: GetUserKeyParams
|
||||
@@ -31,7 +31,7 @@ describe('UsersController', () => {
|
||||
let controllerContainer: ControllerContainerInterface
|
||||
|
||||
const createController = () =>
|
||||
new UsersController(
|
||||
new InversifyExpressUsersController(
|
||||
updateUser,
|
||||
getUserKeyParams,
|
||||
deleteAccount,
|
||||
@@ -11,18 +11,18 @@ import {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
results,
|
||||
} from 'inversify-express-utils'
|
||||
import TYPES from '../Bootstrap/Types'
|
||||
import { DeleteAccount } from '../Domain/UseCase/DeleteAccount/DeleteAccount'
|
||||
import { GetUserKeyParams } from '../Domain/UseCase/GetUserKeyParams/GetUserKeyParams'
|
||||
import { UpdateUser } from '../Domain/UseCase/UpdateUser'
|
||||
import { GetUserSubscription } from '../Domain/UseCase/GetUserSubscription/GetUserSubscription'
|
||||
import { ClearLoginAttempts } from '../Domain/UseCase/ClearLoginAttempts'
|
||||
import { IncreaseLoginAttempts } from '../Domain/UseCase/IncreaseLoginAttempts'
|
||||
import { ChangeCredentials } from '../Domain/UseCase/ChangeCredentials/ChangeCredentials'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { DeleteAccount } from '../../Domain/UseCase/DeleteAccount/DeleteAccount'
|
||||
import { GetUserKeyParams } from '../../Domain/UseCase/GetUserKeyParams/GetUserKeyParams'
|
||||
import { UpdateUser } from '../../Domain/UseCase/UpdateUser'
|
||||
import { GetUserSubscription } from '../../Domain/UseCase/GetUserSubscription/GetUserSubscription'
|
||||
import { ClearLoginAttempts } from '../../Domain/UseCase/ClearLoginAttempts'
|
||||
import { IncreaseLoginAttempts } from '../../Domain/UseCase/IncreaseLoginAttempts'
|
||||
import { ChangeCredentials } from '../../Domain/UseCase/ChangeCredentials/ChangeCredentials'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
|
||||
@controller('/users')
|
||||
export class UsersController extends BaseHttpController {
|
||||
export class InversifyExpressUsersController extends BaseHttpController {
|
||||
constructor(
|
||||
@inject(TYPES.Auth_UpdateUser) private updateUser: UpdateUser,
|
||||
@inject(TYPES.Auth_GetUserKeyParams) private getUserKeyParams: GetUserKeyParams,
|
||||
@@ -2,17 +2,17 @@ import 'reflect-metadata'
|
||||
|
||||
import { Request, Response } from 'express'
|
||||
import { results } from 'inversify-express-utils'
|
||||
import { ValetTokenController } from './ValetTokenController'
|
||||
import { CreateValetToken } from '../Domain/UseCase/CreateValetToken/CreateValetToken'
|
||||
import { InversifyExpressValetTokenController } from './InversifyExpressValetTokenController'
|
||||
import { CreateValetToken } from '../../Domain/UseCase/CreateValetToken/CreateValetToken'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
|
||||
describe('ValetTokenController', () => {
|
||||
describe('InversifyExpressValetTokenController', () => {
|
||||
let createValetToken: CreateValetToken
|
||||
let request: Request
|
||||
let response: Response
|
||||
let controllerContainer: ControllerContainerInterface
|
||||
|
||||
const createController = () => new ValetTokenController(createValetToken, controllerContainer)
|
||||
const createController = () => new InversifyExpressValetTokenController(createValetToken, controllerContainer)
|
||||
|
||||
beforeEach(() => {
|
||||
controllerContainer = {} as jest.Mocked<ControllerContainerInterface>
|
||||
@@ -10,12 +10,11 @@ import {
|
||||
import { CreateValetTokenPayload, ErrorTag } from '@standardnotes/responses'
|
||||
import { ValetTokenOperation } from '@standardnotes/security'
|
||||
import { ControllerContainerInterface, Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
import TYPES from '../Bootstrap/Types'
|
||||
import { CreateValetToken } from '../Domain/UseCase/CreateValetToken/CreateValetToken'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { CreateValetToken } from '../../Domain/UseCase/CreateValetToken/CreateValetToken'
|
||||
|
||||
@controller('/valet-tokens', TYPES.Auth_ApiGatewayAuthMiddleware)
|
||||
export class ValetTokenController extends BaseHttpController {
|
||||
export class InversifyExpressValetTokenController extends BaseHttpController {
|
||||
constructor(
|
||||
@inject(TYPES.Auth_CreateValetToken) private createValetKey: CreateValetToken,
|
||||
@inject(TYPES.Auth_ControllerContainer) private controllerContainer: ControllerContainerInterface,
|
||||
@@ -3,7 +3,7 @@ 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 TYPES from '../../../Bootstrap/Types'
|
||||
|
||||
@injectable()
|
||||
export class ApiGatewayAuthMiddleware extends BaseMiddleware {
|
||||
@@ -3,7 +3,7 @@ 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 TYPES from '../../../Bootstrap/Types'
|
||||
|
||||
@injectable()
|
||||
export class ApiGatewayOfflineAuthMiddleware extends BaseMiddleware {
|
||||
@@ -2,9 +2,9 @@ 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 { User } from '../../../Domain/User/User'
|
||||
import { AuthenticateRequest } from '../../../Domain/UseCase/AuthenticateRequest'
|
||||
import { Session } from '../../../Domain/Session/Session'
|
||||
import { Logger } from 'winston'
|
||||
|
||||
describe('AuthMiddleware', () => {
|
||||
@@ -2,8 +2,8 @@ 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'
|
||||
import TYPES from '../../../Bootstrap/Types'
|
||||
import { AuthenticateRequest } from '../../../Domain/UseCase/AuthenticateRequest'
|
||||
|
||||
@injectable()
|
||||
export class AuthMiddleware extends BaseMiddleware {
|
||||
@@ -2,9 +2,9 @@ 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'
|
||||
import { User } from '../../../Domain/User/User'
|
||||
import { AuthenticateRequest } from '../../../Domain/UseCase/AuthenticateRequest'
|
||||
import { Session } from '../../../Domain/Session/Session'
|
||||
|
||||
describe('AuthMiddlewareWithoutResponse', () => {
|
||||
let authenticateRequest: AuthenticateRequest
|
||||
@@ -1,8 +1,8 @@
|
||||
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'
|
||||
import TYPES from '../../../Bootstrap/Types'
|
||||
import { AuthenticateRequest } from '../../../Domain/UseCase/AuthenticateRequest'
|
||||
|
||||
@injectable()
|
||||
export class AuthMiddlewareWithoutResponse extends BaseMiddleware {
|
||||
@@ -2,9 +2,9 @@ import 'reflect-metadata'
|
||||
|
||||
import { LockMiddleware } from './LockMiddleware'
|
||||
import { NextFunction, Request, Response } from 'express'
|
||||
import { User } from '../Domain/User/User'
|
||||
import { UserRepositoryInterface } from '../Domain/User/UserRepositoryInterface'
|
||||
import { LockRepositoryInterface } from '../Domain/User/LockRepositoryInterface'
|
||||
import { User } from '../../../Domain/User/User'
|
||||
import { UserRepositoryInterface } from '../../../Domain/User/UserRepositoryInterface'
|
||||
import { LockRepositoryInterface } from '../../../Domain/User/LockRepositoryInterface'
|
||||
|
||||
describe('LockMiddleware', () => {
|
||||
let userRepository: UserRepositoryInterface
|
||||
@@ -2,10 +2,10 @@ import { Username } from '@standardnotes/domain-core'
|
||||
import { NextFunction, Request, Response } from 'express'
|
||||
import { inject, injectable } from 'inversify'
|
||||
import { BaseMiddleware } from 'inversify-express-utils'
|
||||
import TYPES from '../Bootstrap/Types'
|
||||
import { LockRepositoryInterface } from '../Domain/User/LockRepositoryInterface'
|
||||
import TYPES from '../../../Bootstrap/Types'
|
||||
import { LockRepositoryInterface } from '../../../Domain/User/LockRepositoryInterface'
|
||||
|
||||
import { UserRepositoryInterface } from '../Domain/User/UserRepositoryInterface'
|
||||
import { UserRepositoryInterface } from '../../../Domain/User/UserRepositoryInterface'
|
||||
|
||||
@injectable()
|
||||
export class LockMiddleware extends BaseMiddleware {
|
||||
@@ -3,8 +3,8 @@ import 'reflect-metadata'
|
||||
import { OfflineUserAuthMiddleware } from './OfflineUserAuthMiddleware'
|
||||
import { NextFunction, Request, Response } from 'express'
|
||||
import { Logger } from 'winston'
|
||||
import { OfflineSettingRepositoryInterface } from '../Domain/Setting/OfflineSettingRepositoryInterface'
|
||||
import { OfflineSetting } from '../Domain/Setting/OfflineSetting'
|
||||
import { OfflineSettingRepositoryInterface } from '../../../Domain/Setting/OfflineSettingRepositoryInterface'
|
||||
import { OfflineSetting } from '../../../Domain/Setting/OfflineSetting'
|
||||
|
||||
describe('OfflineUserAuthMiddleware', () => {
|
||||
let offlineSettingRepository: OfflineSettingRepositoryInterface
|
||||
@@ -2,9 +2,9 @@ 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 { OfflineSettingName } from '../Domain/Setting/OfflineSettingName'
|
||||
import { OfflineSettingRepositoryInterface } from '../Domain/Setting/OfflineSettingRepositoryInterface'
|
||||
import TYPES from '../../../Bootstrap/Types'
|
||||
import { OfflineSettingName } from '../../../Domain/Setting/OfflineSettingName'
|
||||
import { OfflineSettingRepositoryInterface } from '../../../Domain/Setting/OfflineSettingRepositoryInterface'
|
||||
|
||||
@injectable()
|
||||
export class OfflineUserAuthMiddleware extends BaseMiddleware {
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.12.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.11.2...@standardnotes/domain-events-infra@1.12.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.11.2](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.11.1...@standardnotes/domain-events-infra@1.11.2) (2023-05-15)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/domain-events-infra
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/domain-events-infra",
|
||||
"version": "1.11.2",
|
||||
"version": "1.12.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import {
|
||||
DomainEventInterface,
|
||||
DomainEventMessageHandlerInterface,
|
||||
DomainEventPublisherInterface,
|
||||
} from '@standardnotes/domain-events'
|
||||
|
||||
export class DirectCallDomainEventPublisher implements DomainEventPublisherInterface {
|
||||
private handlers: Array<DomainEventMessageHandlerInterface> = []
|
||||
|
||||
register(domainEventMessageHandler: DomainEventMessageHandlerInterface): void {
|
||||
this.handlers.push(domainEventMessageHandler)
|
||||
}
|
||||
|
||||
async publish(event: DomainEventInterface): Promise<void> {
|
||||
await Promise.all(this.handlers.map((handler) => handler.handleMessage(event)))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { Logger } from 'winston'
|
||||
|
||||
import {
|
||||
DomainEventHandlerInterface,
|
||||
DomainEventInterface,
|
||||
DomainEventMessageHandlerInterface,
|
||||
} from '@standardnotes/domain-events'
|
||||
|
||||
export class DirectCallEventMessageHandler implements DomainEventMessageHandlerInterface {
|
||||
constructor(private handlers: Map<string, DomainEventHandlerInterface>, private logger: Logger) {}
|
||||
|
||||
async handleMessage(messageOrEvent: string | DomainEventInterface): Promise<void> {
|
||||
if (typeof messageOrEvent === 'string') {
|
||||
throw new Error('DirectCallEventMessageHandler does not support string messages')
|
||||
}
|
||||
|
||||
const handler = this.handlers.get(messageOrEvent.type)
|
||||
if (!handler) {
|
||||
this.logger.debug(`Event handler for event type ${messageOrEvent.type} does not exist`)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
this.logger.debug(`Received event: ${messageOrEvent.type}`)
|
||||
|
||||
await handler.handle(messageOrEvent)
|
||||
}
|
||||
|
||||
async handleError(error: Error): Promise<void> {
|
||||
this.logger.error('Error occured while handling SQS message: %O', error)
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
export * from './DirectCall/DirectCallDomainEventPublisher'
|
||||
export * from './DirectCall/DirectCallEventMessageHandler'
|
||||
|
||||
export * from './Redis/RedisDomainEventPublisher'
|
||||
export * from './Redis/RedisDomainEventSubscriber'
|
||||
export * from './Redis/RedisDomainEventSubscriberFactory'
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [2.111.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.110.2...@standardnotes/domain-events@2.111.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))
|
||||
|
||||
## [2.110.2](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.110.1...@standardnotes/domain-events@2.110.2) (2023-05-09)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/domain-events",
|
||||
"version": "2.110.2",
|
||||
"version": "2.111.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { DomainEventInterface } from '../Event/DomainEventInterface'
|
||||
|
||||
export interface DomainEventMessageHandlerInterface {
|
||||
handleMessage(message: string): Promise<void>
|
||||
handleMessage(messageOrEvent: string | DomainEventInterface): Promise<void>
|
||||
handleError(error: Error): Promise<void>
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.8.3](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.8.2...@standardnotes/event-store@1.8.3) (2023-05-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
## [1.8.2](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.8.1...@standardnotes/event-store@1.8.2) (2023-05-15)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/event-store",
|
||||
"version": "1.8.2",
|
||||
"version": "1.8.3",
|
||||
"description": "Event Store Service",
|
||||
"private": true,
|
||||
"main": "dist/src/index.js",
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.12.5](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.12.4...@standardnotes/files-server@1.12.5) (2023-05-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
## [1.12.4](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.12.3...@standardnotes/files-server@1.12.4) (2023-05-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
## [1.12.3](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.12.2...@standardnotes/files-server@1.12.3) (2023-05-16)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/files-server",
|
||||
"version": "1.12.3",
|
||||
"version": "1.12.5",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -211,6 +211,7 @@ export class ContainerConfigLoader {
|
||||
level: env.get('LOG_LEVEL') || 'info',
|
||||
format: winston.format.combine(winston.format.splat(), winston.format.json()),
|
||||
transports: [new winston.transports.Console({ level: env.get('LOG_LEVEL') || 'info' })],
|
||||
defaultMeta: { service: 'files' },
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,26 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.4.1](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.4.0...@standardnotes/home-server@1.4.1) (2023-05-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/home-server
|
||||
|
||||
# [1.4.0](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.3.1...@standardnotes/home-server@1.4.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.3.1](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.3.0...@standardnotes/home-server@1.3.1) (2023-05-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/home-server
|
||||
|
||||
# [1.3.0](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.2.0...@standardnotes/home-server@1.3.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.2.0](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.1.1...@standardnotes/home-server@1.2.0) (2023-05-16)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -2,7 +2,9 @@ import 'reflect-metadata'
|
||||
|
||||
import { ControllerContainer, ServiceContainer } from '@standardnotes/domain-core'
|
||||
import { Service as ApiGatewayService, TYPES as ApiGatewayTYPES } from '@standardnotes/api-gateway'
|
||||
import { DirectCallDomainEventPublisher } from '@standardnotes/domain-events-infra'
|
||||
import { Service as AuthService } from '@standardnotes/auth-server'
|
||||
import { Service as SyncingService } from '@standardnotes/syncing-server'
|
||||
import { Container } from 'inversify'
|
||||
import { InversifyExpressServer } from 'inversify-express-utils'
|
||||
import helmet from 'helmet'
|
||||
@@ -17,13 +19,16 @@ import { Env } from '../src/Bootstrap/Env'
|
||||
const startServer = async (): Promise<void> => {
|
||||
const controllerContainer = new ControllerContainer()
|
||||
const serviceContainer = new ServiceContainer()
|
||||
const directCallDomainEventPublisher = new DirectCallDomainEventPublisher()
|
||||
|
||||
const apiGatewayService = new ApiGatewayService(serviceContainer, controllerContainer)
|
||||
const authService = new AuthService(serviceContainer, controllerContainer)
|
||||
const apiGatewayService = new ApiGatewayService(serviceContainer)
|
||||
const authService = new AuthService(serviceContainer, controllerContainer, directCallDomainEventPublisher)
|
||||
const syncingService = new SyncingService(serviceContainer, controllerContainer, directCallDomainEventPublisher)
|
||||
|
||||
const container = Container.merge(
|
||||
(await apiGatewayService.getContainer()) as Container,
|
||||
(await authService.getContainer()) as Container,
|
||||
(await syncingService.getContainer()) as Container,
|
||||
)
|
||||
|
||||
const env: Env = new Env()
|
||||
@@ -91,12 +96,7 @@ const startServer = async (): Promise<void> => {
|
||||
logger.info(`Server started on port ${process.env.PORT}`)
|
||||
}
|
||||
|
||||
Promise.resolve(startServer())
|
||||
.then(() => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Server started')
|
||||
})
|
||||
.catch((error) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Could not start server: ${error.message}`)
|
||||
})
|
||||
Promise.resolve(startServer()).catch((error) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Could not start server: ${error.message}`)
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/home-server",
|
||||
"version": "1.2.0",
|
||||
"version": "1.4.1",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
@@ -21,6 +21,8 @@
|
||||
"@standardnotes/api-gateway": "workspace:^",
|
||||
"@standardnotes/auth-server": "workspace:^",
|
||||
"@standardnotes/domain-core": "workspace:^",
|
||||
"@standardnotes/domain-events-infra": "workspace:^",
|
||||
"@standardnotes/syncing-server": "workspace:^",
|
||||
"cors": "2.8.5",
|
||||
"dotenv": "^16.0.1",
|
||||
"express": "^4.18.2",
|
||||
|
||||
@@ -3,6 +3,20 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.15.1](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.15.0...@standardnotes/revisions-server@1.15.1) (2023-05-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/revisions-server
|
||||
|
||||
# [1.15.0](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.14.4...@standardnotes/revisions-server@1.15.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.14.4](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.14.3...@standardnotes/revisions-server@1.14.4) (2023-05-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/revisions-server
|
||||
|
||||
## [1.14.3](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.14.2...@standardnotes/revisions-server@1.14.3) (2023-05-16)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/revisions-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/revisions-server",
|
||||
"version": "1.14.3",
|
||||
"version": "1.15.1",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
@@ -50,7 +50,6 @@
|
||||
"@types/cors": "^2.8.9",
|
||||
"@types/dotenv": "^8.2.0",
|
||||
"@types/express": "^4.17.14",
|
||||
"@types/inversify-express-utils": "^2.0.0",
|
||||
"@types/jest": "^29.5.1",
|
||||
"@types/newrelic": "^9.13.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.2",
|
||||
|
||||
@@ -43,6 +43,7 @@ export class CommonContainerConfigLoader {
|
||||
level: env.get('LOG_LEVEL') || 'info',
|
||||
format: winston.format.combine(...winstonFormatters),
|
||||
transports: [new winston.transports.Console({ level: env.get('LOG_LEVEL') || 'info' })],
|
||||
defaultMeta: { service: 'revisions' },
|
||||
})
|
||||
|
||||
return logger
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.18.4](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.18.3...@standardnotes/scheduler-server@1.18.4) (2023-05-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
## [1.18.3](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.18.2...@standardnotes/scheduler-server@1.18.3) (2023-05-16)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/scheduler-server",
|
||||
"version": "1.18.3",
|
||||
"version": "1.18.4",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,26 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.37.1](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.37.0...@standardnotes/syncing-server@1.37.1) (2023-05-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/syncing-server
|
||||
|
||||
# [1.37.0](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.36.0...@standardnotes/syncing-server@1.37.0) (2023-05-17)
|
||||
|
||||
### Features
|
||||
|
||||
* bundle syncing server into home server setup ([#611](https://github.com/standardnotes/syncing-server-js/issues/611)) ([b3b617e](https://github.com/standardnotes/syncing-server-js/commit/b3b617ea0b4f4574f6aa7cfae0e9fa8f868f1f4c))
|
||||
|
||||
# [1.36.0](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.35.4...@standardnotes/syncing-server@1.36.0) (2023-05-17)
|
||||
|
||||
### Features
|
||||
|
||||
* **auth:** move inversify express controllers to different structure ([#610](https://github.com/standardnotes/syncing-server-js/issues/610)) ([fea5802](https://github.com/standardnotes/syncing-server-js/commit/fea58029b90804dba31faa3c26dcd7dabe541648))
|
||||
|
||||
## [1.35.4](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.35.3...@standardnotes/syncing-server@1.35.4) (2023-05-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/syncing-server
|
||||
|
||||
## [1.35.3](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.35.2...@standardnotes/syncing-server@1.35.3) (2023-05-16)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/syncing-server
|
||||
|
||||
@@ -2,8 +2,8 @@ import 'reflect-metadata'
|
||||
|
||||
import 'newrelic'
|
||||
|
||||
import '../src/Controller/HealthCheckController'
|
||||
import '../src/Controller/ItemsController'
|
||||
import '../src/Infra/InversifyExpressUtils/InversifyExpressHealthCheckController'
|
||||
import '../src/Infra/InversifyExpressUtils/InversifyExpressItemsController'
|
||||
|
||||
import helmet from 'helmet'
|
||||
import * as cors from 'cors'
|
||||
@@ -13,9 +13,9 @@ import * as winston from 'winston'
|
||||
import { InversifyExpressServer } from 'inversify-express-utils'
|
||||
import TYPES from '../src/Bootstrap/Types'
|
||||
import { Env } from '../src/Bootstrap/Env'
|
||||
import { ServerContainerConfigLoader } from '../src/Bootstrap/ServerContainerConfigLoader'
|
||||
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
|
||||
|
||||
const container = new ServerContainerConfigLoader()
|
||||
const container = new ContainerConfigLoader()
|
||||
void container.load().then((container) => {
|
||||
const env: Env = new Env()
|
||||
env.load()
|
||||
@@ -24,7 +24,7 @@ void container.load().then((container) => {
|
||||
|
||||
server.setConfig((app) => {
|
||||
app.use((_request: Request, response: Response, next: NextFunction) => {
|
||||
response.setHeader('X-SSJS-Version', container.get(TYPES.VERSION))
|
||||
response.setHeader('X-SSJS-Version', container.get(TYPES.Sync_VERSION))
|
||||
next()
|
||||
})
|
||||
/* eslint-disable */
|
||||
@@ -54,7 +54,7 @@ void container.load().then((container) => {
|
||||
app.use(cors())
|
||||
})
|
||||
|
||||
const logger: winston.Logger = container.get(TYPES.Logger)
|
||||
const logger: winston.Logger = container.get(TYPES.Sync_Logger)
|
||||
|
||||
server.setErrorConfig((app) => {
|
||||
app.use((error: Record<string, unknown>, _request: Request, response: Response, _next: NextFunction) => {
|
||||
|
||||
@@ -7,18 +7,20 @@ import { Logger } from 'winston'
|
||||
import TYPES from '../src/Bootstrap/Types'
|
||||
import { Env } from '../src/Bootstrap/Env'
|
||||
import { DomainEventSubscriberFactoryInterface } from '@standardnotes/domain-events'
|
||||
import { WorkerContainerConfigLoader } from '../src/Bootstrap/WorkerContainerConfigLoader'
|
||||
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
|
||||
|
||||
const container = new WorkerContainerConfigLoader()
|
||||
const container = new ContainerConfigLoader()
|
||||
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.Sync_Logger)
|
||||
|
||||
logger.info('Starting worker...')
|
||||
|
||||
const subscriberFactory: DomainEventSubscriberFactoryInterface = container.get(TYPES.DomainEventSubscriberFactory)
|
||||
const subscriberFactory: DomainEventSubscriberFactoryInterface = container.get(
|
||||
TYPES.Sync_DomainEventSubscriberFactory,
|
||||
)
|
||||
subscriberFactory.create().start()
|
||||
|
||||
setInterval(() => logger.info('Alive and kicking!'), 20 * 60 * 1000)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/syncing-server",
|
||||
"version": "1.35.3",
|
||||
"version": "1.37.1",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
@@ -61,7 +61,6 @@
|
||||
"@types/cors": "^2.8.9",
|
||||
"@types/dotenv": "^8.2.0",
|
||||
"@types/express": "^4.17.14",
|
||||
"@types/inversify-express-utils": "^2.0.0",
|
||||
"@types/jest": "^29.5.1",
|
||||
"@types/jsonwebtoken": "^9.0.1",
|
||||
"@types/newrelic": "^9.13.0",
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
import * as winston from 'winston'
|
||||
import { Container, interfaces } from 'inversify'
|
||||
|
||||
import { Env } from './Env'
|
||||
import TYPES from './Types'
|
||||
import { AppDataSource } from './DataSource'
|
||||
import { SNSClient, SNSClientConfig } from '@aws-sdk/client-sns'
|
||||
import { ItemRepositoryInterface } from '../Domain/Item/ItemRepositoryInterface'
|
||||
import { TypeORMItemRepository } from '../Infra/TypeORM/TypeORMItemRepository'
|
||||
import { Repository } from 'typeorm'
|
||||
import { Item } from '../Domain/Item/Item'
|
||||
import { ItemProjection } from '../Projection/ItemProjection'
|
||||
import { ProjectorInterface } from '../Projection/ProjectorInterface'
|
||||
import { ItemProjector } from '../Projection/ItemProjector'
|
||||
import { SNSDomainEventPublisher } from '@standardnotes/domain-events-infra'
|
||||
import { DomainEventFactoryInterface } from '../Domain/Event/DomainEventFactoryInterface'
|
||||
import { DomainEventFactory } from '../Domain/Event/DomainEventFactory'
|
||||
import { Timer, TimerInterface } from '@standardnotes/time'
|
||||
import { ItemTransferCalculatorInterface } from '../Domain/Item/ItemTransferCalculatorInterface'
|
||||
import { ItemTransferCalculator } from '../Domain/Item/ItemTransferCalculator'
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const newrelicFormatter = require('@newrelic/winston-enricher')
|
||||
|
||||
export class CommonContainerConfigLoader {
|
||||
async load(): Promise<Container> {
|
||||
const env: Env = new Env()
|
||||
env.load()
|
||||
|
||||
const container = new Container({
|
||||
defaultScope: 'Singleton',
|
||||
})
|
||||
|
||||
await AppDataSource.initialize()
|
||||
|
||||
container.bind<Env>(TYPES.Env).toConstantValue(env)
|
||||
|
||||
container.bind<winston.Logger>(TYPES.Logger).toDynamicValue((context: interfaces.Context) => {
|
||||
const env: Env = context.container.get(TYPES.Env)
|
||||
|
||||
const newrelicWinstonFormatter = newrelicFormatter(winston)
|
||||
const winstonFormatters = [winston.format.splat(), winston.format.json()]
|
||||
if (env.get('NEW_RELIC_ENABLED', true) === 'true') {
|
||||
winstonFormatters.push(newrelicWinstonFormatter())
|
||||
}
|
||||
|
||||
const logger = winston.createLogger({
|
||||
level: env.get('LOG_LEVEL') || 'info',
|
||||
format: winston.format.combine(...winstonFormatters),
|
||||
transports: [new winston.transports.Console({ level: env.get('LOG_LEVEL') || 'info' })],
|
||||
})
|
||||
|
||||
return logger
|
||||
})
|
||||
|
||||
container.bind<SNSClient>(TYPES.SNS).toDynamicValue((context: interfaces.Context) => {
|
||||
const env: Env = context.container.get(TYPES.Env)
|
||||
|
||||
const snsConfig: SNSClientConfig = {
|
||||
apiVersion: 'latest',
|
||||
region: env.get('SNS_AWS_REGION', true),
|
||||
}
|
||||
if (env.get('SNS_ENDPOINT', true)) {
|
||||
snsConfig.endpoint = env.get('SNS_ENDPOINT', true)
|
||||
}
|
||||
if (env.get('SNS_ACCESS_KEY_ID', true) && env.get('SNS_SECRET_ACCESS_KEY', true)) {
|
||||
snsConfig.credentials = {
|
||||
accessKeyId: env.get('SNS_ACCESS_KEY_ID', true),
|
||||
secretAccessKey: env.get('SNS_SECRET_ACCESS_KEY', true),
|
||||
}
|
||||
}
|
||||
|
||||
return new SNSClient(snsConfig)
|
||||
})
|
||||
|
||||
// Repositories
|
||||
container.bind<ItemRepositoryInterface>(TYPES.ItemRepository).toDynamicValue((context: interfaces.Context) => {
|
||||
return new TypeORMItemRepository(context.container.get(TYPES.ORMItemRepository))
|
||||
})
|
||||
|
||||
// ORM
|
||||
container.bind<Repository<Item>>(TYPES.ORMItemRepository).toDynamicValue(() => AppDataSource.getRepository(Item))
|
||||
|
||||
// Projectors
|
||||
container
|
||||
.bind<ProjectorInterface<Item, ItemProjection>>(TYPES.ItemProjector)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new ItemProjector(context.container.get(TYPES.Timer))
|
||||
})
|
||||
|
||||
// env vars
|
||||
container.bind(TYPES.SNS_TOPIC_ARN).toConstantValue(env.get('SNS_TOPIC_ARN'))
|
||||
container.bind(TYPES.SNS_AWS_REGION).toConstantValue(env.get('SNS_AWS_REGION', true))
|
||||
|
||||
container.bind<TimerInterface>(TYPES.Timer).toDynamicValue(() => new Timer())
|
||||
|
||||
container
|
||||
.bind<SNSDomainEventPublisher>(TYPES.DomainEventPublisher)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new SNSDomainEventPublisher(context.container.get(TYPES.SNS), context.container.get(TYPES.SNS_TOPIC_ARN))
|
||||
})
|
||||
|
||||
container
|
||||
.bind<DomainEventFactoryInterface>(TYPES.DomainEventFactory)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new DomainEventFactory(context.container.get(TYPES.Timer))
|
||||
})
|
||||
|
||||
container
|
||||
.bind<ItemTransferCalculatorInterface>(TYPES.ItemTransferCalculator)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new ItemTransferCalculator(
|
||||
context.container.get(TYPES.ItemRepository),
|
||||
context.container.get(TYPES.Logger),
|
||||
)
|
||||
})
|
||||
|
||||
return container
|
||||
}
|
||||
}
|
||||
517
packages/syncing-server/src/Bootstrap/Container.ts
Normal file
517
packages/syncing-server/src/Bootstrap/Container.ts
Normal file
@@ -0,0 +1,517 @@
|
||||
import * as winston from 'winston'
|
||||
import { Container, interfaces } from 'inversify'
|
||||
|
||||
import { Env } from './Env'
|
||||
import TYPES from './Types'
|
||||
import { AppDataSource } from './DataSource'
|
||||
import { SNSClient, SNSClientConfig } from '@aws-sdk/client-sns'
|
||||
import { ItemRepositoryInterface } from '../Domain/Item/ItemRepositoryInterface'
|
||||
import { TypeORMItemRepository } from '../Infra/TypeORM/TypeORMItemRepository'
|
||||
import { Repository } from 'typeorm'
|
||||
import { Item } from '../Domain/Item/Item'
|
||||
import { ItemProjection } from '../Projection/ItemProjection'
|
||||
import { ProjectorInterface } from '../Projection/ProjectorInterface'
|
||||
import { ItemProjector } from '../Projection/ItemProjector'
|
||||
import {
|
||||
DirectCallDomainEventPublisher,
|
||||
DirectCallEventMessageHandler,
|
||||
SNSDomainEventPublisher,
|
||||
SQSDomainEventSubscriberFactory,
|
||||
SQSEventMessageHandler,
|
||||
SQSNewRelicEventMessageHandler,
|
||||
} from '@standardnotes/domain-events-infra'
|
||||
import { DomainEventFactoryInterface } from '../Domain/Event/DomainEventFactoryInterface'
|
||||
import { DomainEventFactory } from '../Domain/Event/DomainEventFactory'
|
||||
import { Timer, TimerInterface } from '@standardnotes/time'
|
||||
import { ItemTransferCalculatorInterface } from '../Domain/Item/ItemTransferCalculatorInterface'
|
||||
import { ItemTransferCalculator } from '../Domain/Item/ItemTransferCalculator'
|
||||
import { ItemConflict } from '../Domain/Item/ItemConflict'
|
||||
import { ItemFactory } from '../Domain/Item/ItemFactory'
|
||||
import { ItemFactoryInterface } from '../Domain/Item/ItemFactoryInterface'
|
||||
import { ItemService } from '../Domain/Item/ItemService'
|
||||
import { ItemServiceInterface } from '../Domain/Item/ItemServiceInterface'
|
||||
import { ContentFilter } from '../Domain/Item/SaveRule/ContentFilter'
|
||||
import { ContentTypeFilter } from '../Domain/Item/SaveRule/ContentTypeFilter'
|
||||
import { OwnershipFilter } from '../Domain/Item/SaveRule/OwnershipFilter'
|
||||
import { TimeDifferenceFilter } from '../Domain/Item/SaveRule/TimeDifferenceFilter'
|
||||
import { UuidFilter } from '../Domain/Item/SaveRule/UuidFilter'
|
||||
import { ItemSaveValidator } from '../Domain/Item/SaveValidator/ItemSaveValidator'
|
||||
import { ItemSaveValidatorInterface } from '../Domain/Item/SaveValidator/ItemSaveValidatorInterface'
|
||||
import { SyncResponseFactory20161215 } from '../Domain/Item/SyncResponse/SyncResponseFactory20161215'
|
||||
import { SyncResponseFactory20200115 } from '../Domain/Item/SyncResponse/SyncResponseFactory20200115'
|
||||
import { SyncResponseFactoryResolver } from '../Domain/Item/SyncResponse/SyncResponseFactoryResolver'
|
||||
import { SyncResponseFactoryResolverInterface } from '../Domain/Item/SyncResponse/SyncResponseFactoryResolverInterface'
|
||||
import { CheckIntegrity } from '../Domain/UseCase/CheckIntegrity/CheckIntegrity'
|
||||
import { GetItem } from '../Domain/UseCase/GetItem/GetItem'
|
||||
import { SyncItems } from '../Domain/UseCase/SyncItems'
|
||||
import { InversifyExpressAuthMiddleware } from '../Infra/InversifyExpressUtils/Middleware/InversifyExpressAuthMiddleware'
|
||||
import { ItemConflictProjection } from '../Projection/ItemConflictProjection'
|
||||
import { ItemConflictProjector } from '../Projection/ItemConflictProjector'
|
||||
import { SavedItemProjection } from '../Projection/SavedItemProjection'
|
||||
import { SavedItemProjector } from '../Projection/SavedItemProjector'
|
||||
import { S3Client } from '@aws-sdk/client-s3'
|
||||
import { SQSClient, SQSClientConfig } from '@aws-sdk/client-sqs'
|
||||
import { ContentDecoder } from '@standardnotes/common'
|
||||
import {
|
||||
DomainEventMessageHandlerInterface,
|
||||
DomainEventHandlerInterface,
|
||||
DomainEventSubscriberFactoryInterface,
|
||||
DomainEventPublisherInterface,
|
||||
} from '@standardnotes/domain-events'
|
||||
import axios, { AxiosInstance } from 'axios'
|
||||
import { AuthHttpServiceInterface } from '../Domain/Auth/AuthHttpServiceInterface'
|
||||
import { ExtensionsHttpService } from '../Domain/Extension/ExtensionsHttpService'
|
||||
import { ExtensionsHttpServiceInterface } from '../Domain/Extension/ExtensionsHttpServiceInterface'
|
||||
import { AccountDeletionRequestedEventHandler } from '../Domain/Handler/AccountDeletionRequestedEventHandler'
|
||||
import { DuplicateItemSyncedEventHandler } from '../Domain/Handler/DuplicateItemSyncedEventHandler'
|
||||
import { EmailBackupRequestedEventHandler } from '../Domain/Handler/EmailBackupRequestedEventHandler'
|
||||
import { ItemRevisionCreationRequestedEventHandler } from '../Domain/Handler/ItemRevisionCreationRequestedEventHandler'
|
||||
import { ItemBackupServiceInterface } from '../Domain/Item/ItemBackupServiceInterface'
|
||||
import { FSItemBackupService } from '../Infra/FS/FSItemBackupService'
|
||||
import { AuthHttpService } from '../Infra/HTTP/AuthHttpService'
|
||||
import { S3ItemBackupService } from '../Infra/S3/S3ItemBackupService'
|
||||
import { ControllerContainer, ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { InversifyExpressItemsController } from '../Infra/InversifyExpressUtils/InversifyExpressItemsController'
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const newrelicFormatter = require('@newrelic/winston-enricher')
|
||||
|
||||
export class ContainerConfigLoader {
|
||||
private readonly DEFAULT_CONTENT_SIZE_TRANSFER_LIMIT = 10_000_000
|
||||
private readonly DEFAULT_MAX_ITEMS_LIMIT = 300
|
||||
private readonly DEFAULT_FILE_UPLOAD_PATH = `${__dirname}/../../uploads`
|
||||
|
||||
async load(configuration?: {
|
||||
controllerConatiner?: ControllerContainerInterface
|
||||
directCallDomainEventPublisher?: DirectCallDomainEventPublisher
|
||||
}): Promise<Container> {
|
||||
const directCallDomainEventPublisher =
|
||||
configuration?.directCallDomainEventPublisher ?? new DirectCallDomainEventPublisher()
|
||||
|
||||
const env: Env = new Env()
|
||||
env.load()
|
||||
|
||||
const container = new Container({
|
||||
defaultScope: 'Singleton',
|
||||
})
|
||||
|
||||
await AppDataSource.initialize()
|
||||
|
||||
const isConfiguredForHomeServer = env.get('DB_TYPE') === 'sqlite'
|
||||
|
||||
container.bind<Env>(TYPES.Sync_Env).toConstantValue(env)
|
||||
|
||||
container.bind<winston.Logger>(TYPES.Sync_Logger).toDynamicValue((context: interfaces.Context) => {
|
||||
const env: Env = context.container.get(TYPES.Sync_Env)
|
||||
|
||||
const newrelicWinstonFormatter = newrelicFormatter(winston)
|
||||
const winstonFormatters = [winston.format.splat(), winston.format.json()]
|
||||
if (env.get('NEW_RELIC_ENABLED', true) === 'true') {
|
||||
winstonFormatters.push(newrelicWinstonFormatter())
|
||||
}
|
||||
|
||||
const logger = winston.createLogger({
|
||||
level: env.get('LOG_LEVEL') || 'info',
|
||||
format: winston.format.combine(...winstonFormatters),
|
||||
transports: [new winston.transports.Console({ level: env.get('LOG_LEVEL') || 'info' })],
|
||||
defaultMeta: { service: 'syncing-server' },
|
||||
})
|
||||
|
||||
return logger
|
||||
})
|
||||
|
||||
if (isConfiguredForHomeServer) {
|
||||
container
|
||||
.bind<DomainEventPublisherInterface>(TYPES.Sync_DomainEventPublisher)
|
||||
.toConstantValue(directCallDomainEventPublisher)
|
||||
} else {
|
||||
container.bind(TYPES.Sync_SNS_TOPIC_ARN).toConstantValue(env.get('SNS_TOPIC_ARN'))
|
||||
container.bind(TYPES.Sync_SNS_AWS_REGION).toConstantValue(env.get('SNS_AWS_REGION', true))
|
||||
container.bind(TYPES.Sync_SQS_QUEUE_URL).toConstantValue(env.get('SQS_QUEUE_URL'))
|
||||
container.bind(TYPES.Sync_S3_AWS_REGION).toConstantValue(env.get('S3_AWS_REGION', true))
|
||||
container.bind(TYPES.Sync_S3_BACKUP_BUCKET_NAME).toConstantValue(env.get('S3_BACKUP_BUCKET_NAME', true))
|
||||
container.bind(TYPES.Sync_EXTENSIONS_SERVER_URL).toConstantValue(env.get('EXTENSIONS_SERVER_URL', true))
|
||||
|
||||
container.bind<SNSClient>(TYPES.Sync_SNS).toDynamicValue((context: interfaces.Context) => {
|
||||
const env: Env = context.container.get(TYPES.Sync_Env)
|
||||
|
||||
const snsConfig: SNSClientConfig = {
|
||||
apiVersion: 'latest',
|
||||
region: env.get('SNS_AWS_REGION', true),
|
||||
}
|
||||
if (env.get('SNS_ENDPOINT', true)) {
|
||||
snsConfig.endpoint = env.get('SNS_ENDPOINT', true)
|
||||
}
|
||||
if (env.get('SNS_ACCESS_KEY_ID', true) && env.get('SNS_SECRET_ACCESS_KEY', true)) {
|
||||
snsConfig.credentials = {
|
||||
accessKeyId: env.get('SNS_ACCESS_KEY_ID', true),
|
||||
secretAccessKey: env.get('SNS_SECRET_ACCESS_KEY', true),
|
||||
}
|
||||
}
|
||||
|
||||
return new SNSClient(snsConfig)
|
||||
})
|
||||
|
||||
container
|
||||
.bind<DomainEventPublisherInterface>(TYPES.Sync_DomainEventPublisher)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new SNSDomainEventPublisher(
|
||||
context.container.get(TYPES.Sync_SNS),
|
||||
context.container.get(TYPES.Sync_SNS_TOPIC_ARN),
|
||||
)
|
||||
})
|
||||
|
||||
container.bind<SQSClient>(TYPES.Sync_SQS).toDynamicValue((context: interfaces.Context) => {
|
||||
const env: Env = context.container.get(TYPES.Sync_Env)
|
||||
|
||||
const sqsConfig: SQSClientConfig = {
|
||||
region: env.get('SQS_AWS_REGION'),
|
||||
}
|
||||
if (env.get('SQS_ENDPOINT', true)) {
|
||||
sqsConfig.endpoint = env.get('SQS_ENDPOINT', true)
|
||||
}
|
||||
if (env.get('SQS_ACCESS_KEY_ID', true) && env.get('SQS_SECRET_ACCESS_KEY', true)) {
|
||||
sqsConfig.credentials = {
|
||||
accessKeyId: env.get('SQS_ACCESS_KEY_ID', true),
|
||||
secretAccessKey: env.get('SQS_SECRET_ACCESS_KEY', true),
|
||||
}
|
||||
}
|
||||
|
||||
return new SQSClient(sqsConfig)
|
||||
})
|
||||
|
||||
container.bind<S3Client | undefined>(TYPES.Sync_S3).toDynamicValue((context: interfaces.Context) => {
|
||||
const env: Env = context.container.get(TYPES.Sync_Env)
|
||||
|
||||
let s3Client = undefined
|
||||
if (env.get('S3_AWS_REGION', true)) {
|
||||
s3Client = new S3Client({
|
||||
apiVersion: 'latest',
|
||||
region: env.get('S3_AWS_REGION', true),
|
||||
})
|
||||
}
|
||||
|
||||
return s3Client
|
||||
})
|
||||
}
|
||||
|
||||
// Repositories
|
||||
container.bind<ItemRepositoryInterface>(TYPES.Sync_ItemRepository).toDynamicValue((context: interfaces.Context) => {
|
||||
return new TypeORMItemRepository(context.container.get(TYPES.Sync_ORMItemRepository))
|
||||
})
|
||||
|
||||
// ORM
|
||||
container
|
||||
.bind<Repository<Item>>(TYPES.Sync_ORMItemRepository)
|
||||
.toDynamicValue(() => AppDataSource.getRepository(Item))
|
||||
|
||||
// Projectors
|
||||
container
|
||||
.bind<ProjectorInterface<Item, ItemProjection>>(TYPES.Sync_ItemProjector)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new ItemProjector(context.container.get(TYPES.Sync_Timer))
|
||||
})
|
||||
|
||||
container.bind<TimerInterface>(TYPES.Sync_Timer).toDynamicValue(() => new Timer())
|
||||
|
||||
container
|
||||
.bind<DomainEventFactoryInterface>(TYPES.Sync_DomainEventFactory)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new DomainEventFactory(context.container.get(TYPES.Sync_Timer))
|
||||
})
|
||||
|
||||
container
|
||||
.bind<ItemTransferCalculatorInterface>(TYPES.Sync_ItemTransferCalculator)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new ItemTransferCalculator(
|
||||
context.container.get(TYPES.Sync_ItemRepository),
|
||||
context.container.get(TYPES.Sync_Logger),
|
||||
)
|
||||
})
|
||||
|
||||
// Middleware
|
||||
container
|
||||
.bind<InversifyExpressAuthMiddleware>(TYPES.Sync_AuthMiddleware)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new InversifyExpressAuthMiddleware(
|
||||
context.container.get(TYPES.Sync_AUTH_JWT_SECRET),
|
||||
context.container.get(TYPES.Sync_Logger),
|
||||
)
|
||||
})
|
||||
|
||||
// Projectors
|
||||
container
|
||||
.bind<ProjectorInterface<Item, SavedItemProjection>>(TYPES.Sync_SavedItemProjector)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new SavedItemProjector(context.container.get(TYPES.Sync_Timer))
|
||||
})
|
||||
container
|
||||
.bind<ProjectorInterface<ItemConflict, ItemConflictProjection>>(TYPES.Sync_ItemConflictProjector)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new ItemConflictProjector(context.container.get(TYPES.Sync_ItemProjector))
|
||||
})
|
||||
|
||||
// env vars
|
||||
container.bind(TYPES.Sync_AUTH_JWT_SECRET).toConstantValue(env.get('AUTH_JWT_SECRET'))
|
||||
container
|
||||
.bind(TYPES.Sync_REVISIONS_FREQUENCY)
|
||||
.toConstantValue(env.get('REVISIONS_FREQUENCY', true) ? +env.get('REVISIONS_FREQUENCY', true) : 300)
|
||||
container.bind(TYPES.Sync_NEW_RELIC_ENABLED).toConstantValue(env.get('NEW_RELIC_ENABLED', true))
|
||||
container.bind(TYPES.Sync_VERSION).toConstantValue(env.get('VERSION', true) ?? 'development')
|
||||
container
|
||||
.bind(TYPES.Sync_CONTENT_SIZE_TRANSFER_LIMIT)
|
||||
.toConstantValue(
|
||||
env.get('CONTENT_SIZE_TRANSFER_LIMIT', true)
|
||||
? +env.get('CONTENT_SIZE_TRANSFER_LIMIT', true)
|
||||
: this.DEFAULT_CONTENT_SIZE_TRANSFER_LIMIT,
|
||||
)
|
||||
container
|
||||
.bind(TYPES.Sync_MAX_ITEMS_LIMIT)
|
||||
.toConstantValue(
|
||||
env.get('MAX_ITEMS_LIMIT', true) ? +env.get('MAX_ITEMS_LIMIT', true) : this.DEFAULT_MAX_ITEMS_LIMIT,
|
||||
)
|
||||
|
||||
// use cases
|
||||
container.bind<SyncItems>(TYPES.Sync_SyncItems).toDynamicValue((context: interfaces.Context) => {
|
||||
return new SyncItems(context.container.get(TYPES.Sync_ItemService))
|
||||
})
|
||||
container.bind<CheckIntegrity>(TYPES.Sync_CheckIntegrity).toDynamicValue((context: interfaces.Context) => {
|
||||
return new CheckIntegrity(context.container.get(TYPES.Sync_ItemRepository))
|
||||
})
|
||||
container.bind<GetItem>(TYPES.Sync_GetItem).toDynamicValue((context: interfaces.Context) => {
|
||||
return new GetItem(context.container.get(TYPES.Sync_ItemRepository))
|
||||
})
|
||||
|
||||
// Services
|
||||
container.bind<ItemServiceInterface>(TYPES.Sync_ItemService).toDynamicValue((context: interfaces.Context) => {
|
||||
return new ItemService(
|
||||
context.container.get(TYPES.Sync_ItemSaveValidator),
|
||||
context.container.get(TYPES.Sync_ItemFactory),
|
||||
context.container.get(TYPES.Sync_ItemRepository),
|
||||
context.container.get(TYPES.Sync_DomainEventPublisher),
|
||||
context.container.get(TYPES.Sync_DomainEventFactory),
|
||||
context.container.get(TYPES.Sync_REVISIONS_FREQUENCY),
|
||||
context.container.get(TYPES.Sync_CONTENT_SIZE_TRANSFER_LIMIT),
|
||||
context.container.get(TYPES.Sync_ItemTransferCalculator),
|
||||
context.container.get(TYPES.Sync_Timer),
|
||||
context.container.get(TYPES.Sync_ItemProjector),
|
||||
context.container.get(TYPES.Sync_MAX_ITEMS_LIMIT),
|
||||
context.container.get(TYPES.Sync_Logger),
|
||||
)
|
||||
})
|
||||
container
|
||||
.bind<SyncResponseFactory20161215>(TYPES.Sync_SyncResponseFactory20161215)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new SyncResponseFactory20161215(context.container.get(TYPES.Sync_ItemProjector))
|
||||
})
|
||||
container
|
||||
.bind<SyncResponseFactory20200115>(TYPES.Sync_SyncResponseFactory20200115)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new SyncResponseFactory20200115(
|
||||
context.container.get(TYPES.Sync_ItemProjector),
|
||||
context.container.get(TYPES.Sync_ItemConflictProjector),
|
||||
context.container.get(TYPES.Sync_SavedItemProjector),
|
||||
)
|
||||
})
|
||||
container
|
||||
.bind<SyncResponseFactoryResolverInterface>(TYPES.Sync_SyncResponseFactoryResolver)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new SyncResponseFactoryResolver(
|
||||
context.container.get(TYPES.Sync_SyncResponseFactory20161215),
|
||||
context.container.get(TYPES.Sync_SyncResponseFactory20200115),
|
||||
)
|
||||
})
|
||||
|
||||
container.bind<ItemFactoryInterface>(TYPES.Sync_ItemFactory).toDynamicValue((context: interfaces.Context) => {
|
||||
return new ItemFactory(context.container.get(TYPES.Sync_Timer), context.container.get(TYPES.Sync_ItemProjector))
|
||||
})
|
||||
|
||||
container.bind<OwnershipFilter>(TYPES.Sync_OwnershipFilter).toDynamicValue(() => new OwnershipFilter())
|
||||
container
|
||||
.bind<TimeDifferenceFilter>(TYPES.Sync_TimeDifferenceFilter)
|
||||
.toDynamicValue(
|
||||
(context: interfaces.Context) => new TimeDifferenceFilter(context.container.get(TYPES.Sync_Timer)),
|
||||
)
|
||||
container.bind<UuidFilter>(TYPES.Sync_UuidFilter).toDynamicValue(() => new UuidFilter())
|
||||
container.bind<ContentTypeFilter>(TYPES.Sync_ContentTypeFilter).toDynamicValue(() => new ContentTypeFilter())
|
||||
container.bind<ContentFilter>(TYPES.Sync_ContentFilter).toDynamicValue(() => new ContentFilter())
|
||||
|
||||
container
|
||||
.bind<ItemSaveValidatorInterface>(TYPES.Sync_ItemSaveValidator)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new ItemSaveValidator([
|
||||
context.container.get(TYPES.Sync_OwnershipFilter),
|
||||
context.container.get(TYPES.Sync_TimeDifferenceFilter),
|
||||
context.container.get(TYPES.Sync_UuidFilter),
|
||||
context.container.get(TYPES.Sync_ContentTypeFilter),
|
||||
context.container.get(TYPES.Sync_ContentFilter),
|
||||
])
|
||||
})
|
||||
|
||||
// env vars
|
||||
container
|
||||
.bind(TYPES.Sync_EMAIL_ATTACHMENT_MAX_BYTE_SIZE)
|
||||
.toConstantValue(
|
||||
env.get('EMAIL_ATTACHMENT_MAX_BYTE_SIZE', true) ? +env.get('EMAIL_ATTACHMENT_MAX_BYTE_SIZE', true) : 10485760,
|
||||
)
|
||||
container.bind(TYPES.Sync_NEW_RELIC_ENABLED).toConstantValue(env.get('NEW_RELIC_ENABLED', true))
|
||||
container
|
||||
.bind(TYPES.Sync_FILE_UPLOAD_PATH)
|
||||
.toConstantValue(
|
||||
env.get('FILE_UPLOAD_PATH', true) ? env.get('FILE_UPLOAD_PATH', true) : this.DEFAULT_FILE_UPLOAD_PATH,
|
||||
)
|
||||
|
||||
// Handlers
|
||||
container
|
||||
.bind<DuplicateItemSyncedEventHandler>(TYPES.Sync_DuplicateItemSyncedEventHandler)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new DuplicateItemSyncedEventHandler(
|
||||
context.container.get(TYPES.Sync_ItemRepository),
|
||||
context.container.get(TYPES.Sync_DomainEventFactory),
|
||||
context.container.get(TYPES.Sync_DomainEventPublisher),
|
||||
context.container.get(TYPES.Sync_Logger),
|
||||
)
|
||||
})
|
||||
container
|
||||
.bind<AccountDeletionRequestedEventHandler>(TYPES.Sync_AccountDeletionRequestedEventHandler)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new AccountDeletionRequestedEventHandler(
|
||||
context.container.get(TYPES.Sync_ItemRepository),
|
||||
context.container.get(TYPES.Sync_Logger),
|
||||
)
|
||||
})
|
||||
container
|
||||
.bind<ItemRevisionCreationRequestedEventHandler>(TYPES.Sync_ItemRevisionCreationRequestedEventHandler)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new ItemRevisionCreationRequestedEventHandler(
|
||||
context.container.get(TYPES.Sync_ItemRepository),
|
||||
context.container.get(TYPES.Sync_ItemBackupService),
|
||||
context.container.get(TYPES.Sync_DomainEventFactory),
|
||||
context.container.get(TYPES.Sync_DomainEventPublisher),
|
||||
)
|
||||
})
|
||||
|
||||
// Services
|
||||
container.bind<ContentDecoder>(TYPES.Sync_ContentDecoder).toDynamicValue(() => new ContentDecoder())
|
||||
container.bind<AxiosInstance>(TYPES.Sync_HTTPClient).toDynamicValue(() => axios.create())
|
||||
container
|
||||
.bind<ExtensionsHttpServiceInterface>(TYPES.Sync_ExtensionsHttpService)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new ExtensionsHttpService(
|
||||
context.container.get(TYPES.Sync_HTTPClient),
|
||||
context.container.get(TYPES.Sync_ItemRepository),
|
||||
context.container.get(TYPES.Sync_ContentDecoder),
|
||||
context.container.get(TYPES.Sync_DomainEventPublisher),
|
||||
context.container.get(TYPES.Sync_DomainEventFactory),
|
||||
context.container.get(TYPES.Sync_Logger),
|
||||
)
|
||||
})
|
||||
|
||||
container
|
||||
.bind<ItemBackupServiceInterface>(TYPES.Sync_ItemBackupService)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
const env: Env = context.container.get(TYPES.Sync_Env)
|
||||
|
||||
if (env.get('S3_AWS_REGION', true)) {
|
||||
return new S3ItemBackupService(
|
||||
context.container.get(TYPES.Sync_S3_BACKUP_BUCKET_NAME),
|
||||
context.container.get(TYPES.Sync_ItemProjector),
|
||||
context.container.get(TYPES.Sync_Logger),
|
||||
context.container.get(TYPES.Sync_S3),
|
||||
)
|
||||
} else {
|
||||
return new FSItemBackupService(
|
||||
context.container.get(TYPES.Sync_FILE_UPLOAD_PATH),
|
||||
context.container.get(TYPES.Sync_ItemProjector),
|
||||
context.container.get(TYPES.Sync_Logger),
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
const eventHandlers: Map<string, DomainEventHandlerInterface> = new Map([
|
||||
['DUPLICATE_ITEM_SYNCED', container.get(TYPES.Sync_DuplicateItemSyncedEventHandler)],
|
||||
['ACCOUNT_DELETION_REQUESTED', container.get(TYPES.Sync_AccountDeletionRequestedEventHandler)],
|
||||
['ITEM_REVISION_CREATION_REQUESTED', container.get(TYPES.Sync_ItemRevisionCreationRequestedEventHandler)],
|
||||
])
|
||||
if (!isConfiguredForHomeServer) {
|
||||
container.bind(TYPES.Sync_AUTH_SERVER_URL).toConstantValue(env.get('AUTH_SERVER_URL'))
|
||||
|
||||
container
|
||||
.bind<AuthHttpServiceInterface>(TYPES.Sync_AuthHttpService)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new AuthHttpService(
|
||||
context.container.get(TYPES.Sync_HTTPClient),
|
||||
context.container.get(TYPES.Sync_AUTH_SERVER_URL),
|
||||
)
|
||||
})
|
||||
|
||||
container
|
||||
.bind<EmailBackupRequestedEventHandler>(TYPES.Sync_EmailBackupRequestedEventHandler)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new EmailBackupRequestedEventHandler(
|
||||
context.container.get(TYPES.Sync_ItemRepository),
|
||||
context.container.get(TYPES.Sync_AuthHttpService),
|
||||
context.container.get(TYPES.Sync_ItemBackupService),
|
||||
context.container.get(TYPES.Sync_DomainEventPublisher),
|
||||
context.container.get(TYPES.Sync_DomainEventFactory),
|
||||
context.container.get(TYPES.Sync_EMAIL_ATTACHMENT_MAX_BYTE_SIZE),
|
||||
context.container.get(TYPES.Sync_ItemTransferCalculator),
|
||||
context.container.get(TYPES.Sync_S3_BACKUP_BUCKET_NAME),
|
||||
context.container.get(TYPES.Sync_Logger),
|
||||
)
|
||||
})
|
||||
|
||||
eventHandlers.set('EMAIL_BACKUP_REQUESTED', container.get(TYPES.Sync_EmailBackupRequestedEventHandler))
|
||||
}
|
||||
|
||||
if (isConfiguredForHomeServer) {
|
||||
const directCallEventMessageHandler = new DirectCallEventMessageHandler(
|
||||
eventHandlers,
|
||||
container.get(TYPES.Sync_Logger),
|
||||
)
|
||||
directCallDomainEventPublisher.register(directCallEventMessageHandler)
|
||||
|
||||
container
|
||||
.bind<DomainEventMessageHandlerInterface>(TYPES.Sync_DomainEventMessageHandler)
|
||||
.toConstantValue(directCallEventMessageHandler)
|
||||
} else {
|
||||
container
|
||||
.bind<DomainEventMessageHandlerInterface>(TYPES.Sync_DomainEventMessageHandler)
|
||||
.toConstantValue(
|
||||
env.get('NEW_RELIC_ENABLED', true) === 'true'
|
||||
? new SQSNewRelicEventMessageHandler(eventHandlers, container.get(TYPES.Sync_Logger))
|
||||
: new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Sync_Logger)),
|
||||
)
|
||||
}
|
||||
|
||||
container
|
||||
.bind<DomainEventSubscriberFactoryInterface>(TYPES.Sync_DomainEventSubscriberFactory)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new SQSDomainEventSubscriberFactory(
|
||||
context.container.get(TYPES.Sync_SQS),
|
||||
context.container.get(TYPES.Sync_SQS_QUEUE_URL),
|
||||
context.container.get(TYPES.Sync_DomainEventMessageHandler),
|
||||
)
|
||||
})
|
||||
|
||||
container
|
||||
.bind<ControllerContainerInterface>(TYPES.Sync_ControllerContainer)
|
||||
.toConstantValue(configuration?.controllerConatiner ?? new ControllerContainer())
|
||||
|
||||
if (isConfiguredForHomeServer) {
|
||||
container
|
||||
.bind<InversifyExpressItemsController>(TYPES.Sync_InversifyExpressItemsController)
|
||||
.toConstantValue(
|
||||
new InversifyExpressItemsController(
|
||||
container.get(TYPES.Sync_SyncItems),
|
||||
container.get(TYPES.Sync_CheckIntegrity),
|
||||
container.get(TYPES.Sync_GetItem),
|
||||
container.get(TYPES.Sync_ItemProjector),
|
||||
container.get(TYPES.Sync_SyncResponseFactoryResolver),
|
||||
container.get(TYPES.Sync_ControllerContainer),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
return container
|
||||
}
|
||||
}
|
||||
@@ -13,55 +13,62 @@ 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 commonDataSourceOptions = {
|
||||
maxQueryExecutionTime,
|
||||
entities: [Item],
|
||||
migrations: [`${__dirname}/../../migrations/${isConfiguredForMySQL ? 'mysql' : 'sqlite'}/*.js`],
|
||||
migrationsRun: true,
|
||||
logging: <LoggerOptions>env.get('DB_DEBUG_LEVEL', true) ?? 'info',
|
||||
}
|
||||
|
||||
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),
|
||||
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'),
|
||||
},
|
||||
],
|
||||
removeNodeErrorCount: 10,
|
||||
restoreNodeTimeout: 5,
|
||||
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 commonDataSourceOptions = {
|
||||
maxQueryExecutionTime,
|
||||
entities: [Item],
|
||||
migrations: [`dist/migrations/${isConfiguredForMySQL ? 'mysql' : 'sqlite'}/*.js`],
|
||||
migrationsRun: true,
|
||||
logging: <LoggerOptions>env.get('DB_DEBUG_LEVEL'),
|
||||
}
|
||||
|
||||
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'),
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
import { Container, interfaces } from 'inversify'
|
||||
|
||||
import { Env } from './Env'
|
||||
import TYPES from './Types'
|
||||
import { AuthMiddleware } from '../Controller/AuthMiddleware'
|
||||
import { Item } from '../Domain/Item/Item'
|
||||
import { SyncResponseFactory20161215 } from '../Domain/Item/SyncResponse/SyncResponseFactory20161215'
|
||||
import { SyncResponseFactory20200115 } from '../Domain/Item/SyncResponse/SyncResponseFactory20200115'
|
||||
import { SyncResponseFactoryResolverInterface } from '../Domain/Item/SyncResponse/SyncResponseFactoryResolverInterface'
|
||||
import { SyncResponseFactoryResolver } from '../Domain/Item/SyncResponse/SyncResponseFactoryResolver'
|
||||
import { ItemServiceInterface } from '../Domain/Item/ItemServiceInterface'
|
||||
import { ItemService } from '../Domain/Item/ItemService'
|
||||
import { SyncItems } from '../Domain/UseCase/SyncItems'
|
||||
import { ItemConflictProjector } from '../Projection/ItemConflictProjector'
|
||||
import { ItemSaveValidatorInterface } from '../Domain/Item/SaveValidator/ItemSaveValidatorInterface'
|
||||
import { ItemSaveValidator } from '../Domain/Item/SaveValidator/ItemSaveValidator'
|
||||
import { OwnershipFilter } from '../Domain/Item/SaveRule/OwnershipFilter'
|
||||
import { TimeDifferenceFilter } from '../Domain/Item/SaveRule/TimeDifferenceFilter'
|
||||
import { ItemFactoryInterface } from '../Domain/Item/ItemFactoryInterface'
|
||||
import { ItemFactory } from '../Domain/Item/ItemFactory'
|
||||
import { UuidFilter } from '../Domain/Item/SaveRule/UuidFilter'
|
||||
import { ContentTypeFilter } from '../Domain/Item/SaveRule/ContentTypeFilter'
|
||||
import { ContentFilter } from '../Domain/Item/SaveRule/ContentFilter'
|
||||
import { CheckIntegrity } from '../Domain/UseCase/CheckIntegrity/CheckIntegrity'
|
||||
import { GetItem } from '../Domain/UseCase/GetItem/GetItem'
|
||||
import { ProjectorInterface } from '../Projection/ProjectorInterface'
|
||||
import { SavedItemProjection } from '../Projection/SavedItemProjection'
|
||||
import { SavedItemProjector } from '../Projection/SavedItemProjector'
|
||||
import { ItemConflict } from '../Domain/Item/ItemConflict'
|
||||
import { ItemConflictProjection } from '../Projection/ItemConflictProjection'
|
||||
import { CommonContainerConfigLoader } from './CommonContainerConfigLoader'
|
||||
|
||||
export class ServerContainerConfigLoader extends CommonContainerConfigLoader {
|
||||
private readonly DEFAULT_CONTENT_SIZE_TRANSFER_LIMIT = 10_000_000
|
||||
private readonly DEFAULT_MAX_ITEMS_LIMIT = 300
|
||||
|
||||
override async load(): Promise<Container> {
|
||||
const container = await super.load()
|
||||
|
||||
const env: Env = container.get(TYPES.Env)
|
||||
|
||||
// Middleware
|
||||
container.bind<AuthMiddleware>(TYPES.AuthMiddleware).toDynamicValue((context: interfaces.Context) => {
|
||||
return new AuthMiddleware(context.container.get(TYPES.AUTH_JWT_SECRET), context.container.get(TYPES.Logger))
|
||||
})
|
||||
|
||||
// Projectors
|
||||
container
|
||||
.bind<ProjectorInterface<Item, SavedItemProjection>>(TYPES.SavedItemProjector)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new SavedItemProjector(context.container.get(TYPES.Timer))
|
||||
})
|
||||
container
|
||||
.bind<ProjectorInterface<ItemConflict, ItemConflictProjection>>(TYPES.ItemConflictProjector)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new ItemConflictProjector(context.container.get(TYPES.ItemProjector))
|
||||
})
|
||||
|
||||
// env vars
|
||||
container.bind(TYPES.AUTH_JWT_SECRET).toConstantValue(env.get('AUTH_JWT_SECRET'))
|
||||
container.bind(TYPES.REVISIONS_FREQUENCY).toConstantValue(env.get('REVISIONS_FREQUENCY'))
|
||||
container.bind(TYPES.NEW_RELIC_ENABLED).toConstantValue(env.get('NEW_RELIC_ENABLED', true))
|
||||
container.bind(TYPES.VERSION).toConstantValue(env.get('VERSION'))
|
||||
container
|
||||
.bind(TYPES.CONTENT_SIZE_TRANSFER_LIMIT)
|
||||
.toConstantValue(
|
||||
env.get('CONTENT_SIZE_TRANSFER_LIMIT', true)
|
||||
? +env.get('CONTENT_SIZE_TRANSFER_LIMIT', true)
|
||||
: this.DEFAULT_CONTENT_SIZE_TRANSFER_LIMIT,
|
||||
)
|
||||
container
|
||||
.bind(TYPES.MAX_ITEMS_LIMIT)
|
||||
.toConstantValue(
|
||||
env.get('MAX_ITEMS_LIMIT', true) ? +env.get('MAX_ITEMS_LIMIT', true) : this.DEFAULT_MAX_ITEMS_LIMIT,
|
||||
)
|
||||
|
||||
// use cases
|
||||
container.bind<SyncItems>(TYPES.SyncItems).toDynamicValue((context: interfaces.Context) => {
|
||||
return new SyncItems(context.container.get(TYPES.ItemService))
|
||||
})
|
||||
container.bind<CheckIntegrity>(TYPES.CheckIntegrity).toDynamicValue((context: interfaces.Context) => {
|
||||
return new CheckIntegrity(context.container.get(TYPES.ItemRepository))
|
||||
})
|
||||
container.bind<GetItem>(TYPES.GetItem).toDynamicValue((context: interfaces.Context) => {
|
||||
return new GetItem(context.container.get(TYPES.ItemRepository))
|
||||
})
|
||||
|
||||
// Services
|
||||
container.bind<ItemServiceInterface>(TYPES.ItemService).toDynamicValue((context: interfaces.Context) => {
|
||||
return new ItemService(
|
||||
context.container.get(TYPES.ItemSaveValidator),
|
||||
context.container.get(TYPES.ItemFactory),
|
||||
context.container.get(TYPES.ItemRepository),
|
||||
context.container.get(TYPES.DomainEventPublisher),
|
||||
context.container.get(TYPES.DomainEventFactory),
|
||||
context.container.get(TYPES.REVISIONS_FREQUENCY),
|
||||
context.container.get(TYPES.CONTENT_SIZE_TRANSFER_LIMIT),
|
||||
context.container.get(TYPES.ItemTransferCalculator),
|
||||
context.container.get(TYPES.Timer),
|
||||
context.container.get(TYPES.ItemProjector),
|
||||
context.container.get(TYPES.MAX_ITEMS_LIMIT),
|
||||
context.container.get(TYPES.Logger),
|
||||
)
|
||||
})
|
||||
container
|
||||
.bind<SyncResponseFactory20161215>(TYPES.SyncResponseFactory20161215)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new SyncResponseFactory20161215(context.container.get(TYPES.ItemProjector))
|
||||
})
|
||||
container
|
||||
.bind<SyncResponseFactory20200115>(TYPES.SyncResponseFactory20200115)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new SyncResponseFactory20200115(
|
||||
context.container.get(TYPES.ItemProjector),
|
||||
context.container.get(TYPES.ItemConflictProjector),
|
||||
context.container.get(TYPES.SavedItemProjector),
|
||||
)
|
||||
})
|
||||
container
|
||||
.bind<SyncResponseFactoryResolverInterface>(TYPES.SyncResponseFactoryResolver)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new SyncResponseFactoryResolver(
|
||||
context.container.get(TYPES.SyncResponseFactory20161215),
|
||||
context.container.get(TYPES.SyncResponseFactory20200115),
|
||||
)
|
||||
})
|
||||
|
||||
container.bind<ItemFactoryInterface>(TYPES.ItemFactory).toDynamicValue((context: interfaces.Context) => {
|
||||
return new ItemFactory(context.container.get(TYPES.Timer), context.container.get(TYPES.ItemProjector))
|
||||
})
|
||||
|
||||
container.bind<OwnershipFilter>(TYPES.OwnershipFilter).toDynamicValue(() => new OwnershipFilter())
|
||||
container
|
||||
.bind<TimeDifferenceFilter>(TYPES.TimeDifferenceFilter)
|
||||
.toDynamicValue((context: interfaces.Context) => new TimeDifferenceFilter(context.container.get(TYPES.Timer)))
|
||||
container.bind<UuidFilter>(TYPES.UuidFilter).toDynamicValue(() => new UuidFilter())
|
||||
container.bind<ContentTypeFilter>(TYPES.ContentTypeFilter).toDynamicValue(() => new ContentTypeFilter())
|
||||
container.bind<ContentFilter>(TYPES.ContentFilter).toDynamicValue(() => new ContentFilter())
|
||||
|
||||
container
|
||||
.bind<ItemSaveValidatorInterface>(TYPES.ItemSaveValidator)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new ItemSaveValidator([
|
||||
context.container.get(TYPES.OwnershipFilter),
|
||||
context.container.get(TYPES.TimeDifferenceFilter),
|
||||
context.container.get(TYPES.UuidFilter),
|
||||
context.container.get(TYPES.ContentTypeFilter),
|
||||
context.container.get(TYPES.ContentFilter),
|
||||
])
|
||||
})
|
||||
|
||||
return container
|
||||
}
|
||||
}
|
||||
42
packages/syncing-server/src/Bootstrap/Service.ts
Normal file
42
packages/syncing-server/src/Bootstrap/Service.ts
Normal 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.SyncingServer).getValue()
|
||||
}
|
||||
}
|
||||
@@ -1,71 +1,73 @@
|
||||
const TYPES = {
|
||||
DBConnection: Symbol.for('DBConnection'),
|
||||
Logger: Symbol.for('Logger'),
|
||||
Redis: Symbol.for('Redis'),
|
||||
SNS: Symbol.for('SNS'),
|
||||
SQS: Symbol.for('SQS'),
|
||||
S3: Symbol.for('S3'),
|
||||
Env: Symbol.for('Env'),
|
||||
Sync_DBConnection: Symbol.for('Sync_DBConnection'),
|
||||
Sync_Logger: Symbol.for('Sync_Logger'),
|
||||
Sync_Redis: Symbol.for('Sync_Redis'),
|
||||
Sync_SNS: Symbol.for('Sync_SNS'),
|
||||
Sync_SQS: Symbol.for('Sync_SQS'),
|
||||
Sync_S3: Symbol.for('Sync_S3'),
|
||||
Sync_Env: Symbol.for('Sync_Env'),
|
||||
// Repositories
|
||||
ItemRepository: Symbol.for('ItemRepository'),
|
||||
Sync_ItemRepository: Symbol.for('Sync_ItemRepository'),
|
||||
// ORM
|
||||
ORMItemRepository: Symbol.for('ORMItemRepository'),
|
||||
Sync_ORMItemRepository: Symbol.for('Sync_ORMItemRepository'),
|
||||
// Middleware
|
||||
AuthMiddleware: Symbol.for('AuthMiddleware'),
|
||||
Sync_AuthMiddleware: Symbol.for('Sync_AuthMiddleware'),
|
||||
// Projectors
|
||||
ItemProjector: Symbol.for('ItemProjector'),
|
||||
SavedItemProjector: Symbol.for('SavedItemProjector'),
|
||||
ItemConflictProjector: Symbol.for('ItemConflictProjector'),
|
||||
Sync_ItemProjector: Symbol.for('Sync_ItemProjector'),
|
||||
Sync_SavedItemProjector: Symbol.for('Sync_SavedItemProjector'),
|
||||
Sync_ItemConflictProjector: Symbol.for('Sync_ItemConflictProjector'),
|
||||
// env vars
|
||||
REDIS_URL: Symbol.for('REDIS_URL'),
|
||||
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'),
|
||||
AUTH_JWT_SECRET: Symbol.for('AUTH_JWT_SECRET'),
|
||||
EXTENSIONS_SERVER_URL: Symbol.for('EXTENSIONS_SERVER_URL'),
|
||||
AUTH_SERVER_URL: Symbol.for('AUTH_SERVER_URL'),
|
||||
S3_AWS_REGION: Symbol.for('S3_AWS_REGION'),
|
||||
S3_BACKUP_BUCKET_NAME: Symbol.for('S3_BACKUP_BUCKET_NAME'),
|
||||
EMAIL_ATTACHMENT_MAX_BYTE_SIZE: Symbol.for('EMAIL_ATTACHMENT_MAX_BYTE_SIZE'),
|
||||
REVISIONS_FREQUENCY: Symbol.for('REVISIONS_FREQUENCY'),
|
||||
NEW_RELIC_ENABLED: Symbol.for('NEW_RELIC_ENABLED'),
|
||||
VERSION: Symbol.for('VERSION'),
|
||||
CONTENT_SIZE_TRANSFER_LIMIT: Symbol.for('CONTENT_SIZE_TRANSFER_LIMIT'),
|
||||
MAX_ITEMS_LIMIT: Symbol.for('MAX_ITEMS_LIMIT'),
|
||||
FILE_UPLOAD_PATH: Symbol.for('FILE_UPLOAD_PATH'),
|
||||
Sync_REDIS_URL: Symbol.for('Sync_REDIS_URL'),
|
||||
Sync_SNS_TOPIC_ARN: Symbol.for('Sync_SNS_TOPIC_ARN'),
|
||||
Sync_SNS_AWS_REGION: Symbol.for('Sync_SNS_AWS_REGION'),
|
||||
Sync_SQS_QUEUE_URL: Symbol.for('Sync_SQS_QUEUE_URL'),
|
||||
Sync_SQS_AWS_REGION: Symbol.for('Sync_SQS_AWS_REGION'),
|
||||
Sync_AUTH_JWT_SECRET: Symbol.for('Sync_AUTH_JWT_SECRET'),
|
||||
Sync_EXTENSIONS_SERVER_URL: Symbol.for('Sync_EXTENSIONS_SERVER_URL'),
|
||||
Sync_AUTH_SERVER_URL: Symbol.for('Sync_AUTH_SERVER_URL'),
|
||||
Sync_S3_AWS_REGION: Symbol.for('Sync_S3_AWS_REGION'),
|
||||
Sync_S3_BACKUP_BUCKET_NAME: Symbol.for('Sync_S3_BACKUP_BUCKET_NAME'),
|
||||
Sync_EMAIL_ATTACHMENT_MAX_BYTE_SIZE: Symbol.for('Sync_EMAIL_ATTACHMENT_MAX_BYTE_SIZE'),
|
||||
Sync_REVISIONS_FREQUENCY: Symbol.for('Sync_REVISIONS_FREQUENCY'),
|
||||
Sync_NEW_RELIC_ENABLED: Symbol.for('Sync_NEW_RELIC_ENABLED'),
|
||||
Sync_VERSION: Symbol.for('Sync_VERSION'),
|
||||
Sync_CONTENT_SIZE_TRANSFER_LIMIT: Symbol.for('Sync_CONTENT_SIZE_TRANSFER_LIMIT'),
|
||||
Sync_MAX_ITEMS_LIMIT: Symbol.for('Sync_MAX_ITEMS_LIMIT'),
|
||||
Sync_FILE_UPLOAD_PATH: Symbol.for('Sync_FILE_UPLOAD_PATH'),
|
||||
// use cases
|
||||
SyncItems: Symbol.for('SyncItems'),
|
||||
CheckIntegrity: Symbol.for('CheckIntegrity'),
|
||||
GetItem: Symbol.for('GetItem'),
|
||||
Sync_SyncItems: Symbol.for('Sync_SyncItems'),
|
||||
Sync_CheckIntegrity: Symbol.for('Sync_CheckIntegrity'),
|
||||
Sync_GetItem: Symbol.for('Sync_GetItem'),
|
||||
// Handlers
|
||||
AccountDeletionRequestedEventHandler: Symbol.for('AccountDeletionRequestedEventHandler'),
|
||||
DuplicateItemSyncedEventHandler: Symbol.for('DuplicateItemSyncedEventHandler'),
|
||||
EmailBackupRequestedEventHandler: Symbol.for('EmailBackupRequestedEventHandler'),
|
||||
ItemRevisionCreationRequestedEventHandler: Symbol.for('ItemRevisionCreationRequestedEventHandler'),
|
||||
Sync_AccountDeletionRequestedEventHandler: Symbol.for('Sync_AccountDeletionRequestedEventHandler'),
|
||||
Sync_DuplicateItemSyncedEventHandler: Symbol.for('Sync_DuplicateItemSyncedEventHandler'),
|
||||
Sync_EmailBackupRequestedEventHandler: Symbol.for('Sync_EmailBackupRequestedEventHandler'),
|
||||
Sync_ItemRevisionCreationRequestedEventHandler: Symbol.for('Sync_ItemRevisionCreationRequestedEventHandler'),
|
||||
// Services
|
||||
ContentDecoder: Symbol.for('ContentDecoder'),
|
||||
DomainEventPublisher: Symbol.for('DomainEventPublisher'),
|
||||
DomainEventSubscriberFactory: Symbol.for('DomainEventSubscriberFactory'),
|
||||
DomainEventFactory: Symbol.for('DomainEventFactory'),
|
||||
DomainEventMessageHandler: Symbol.for('DomainEventMessageHandler'),
|
||||
HTTPClient: Symbol.for('HTTPClient'),
|
||||
ItemService: Symbol.for('ItemService'),
|
||||
Timer: Symbol.for('Timer'),
|
||||
SyncResponseFactory20161215: Symbol.for('SyncResponseFactory20161215'),
|
||||
SyncResponseFactory20200115: Symbol.for('SyncResponseFactory20200115'),
|
||||
SyncResponseFactoryResolver: Symbol.for('SyncResponseFactoryResolver'),
|
||||
AuthHttpService: Symbol.for('AuthHttpService'),
|
||||
ExtensionsHttpService: Symbol.for('ExtensionsHttpService'),
|
||||
ItemBackupService: Symbol.for('ItemBackupService'),
|
||||
ItemSaveValidator: Symbol.for('ItemSaveValidator'),
|
||||
OwnershipFilter: Symbol.for('OwnershipFilter'),
|
||||
TimeDifferenceFilter: Symbol.for('TimeDifferenceFilter'),
|
||||
UuidFilter: Symbol.for('UuidFilter'),
|
||||
ContentTypeFilter: Symbol.for('ContentTypeFilter'),
|
||||
ContentFilter: Symbol.for('ContentFilter'),
|
||||
ItemFactory: Symbol.for('ItemFactory'),
|
||||
ItemTransferCalculator: Symbol.for('ItemTransferCalculator'),
|
||||
Sync_ContentDecoder: Symbol.for('Sync_ContentDecoder'),
|
||||
Sync_DomainEventPublisher: Symbol.for('Sync_DomainEventPublisher'),
|
||||
Sync_DomainEventSubscriberFactory: Symbol.for('Sync_DomainEventSubscriberFactory'),
|
||||
Sync_DomainEventFactory: Symbol.for('Sync_DomainEventFactory'),
|
||||
Sync_DomainEventMessageHandler: Symbol.for('Sync_DomainEventMessageHandler'),
|
||||
Sync_HTTPClient: Symbol.for('Sync_HTTPClient'),
|
||||
Sync_ItemService: Symbol.for('Sync_ItemService'),
|
||||
Sync_Timer: Symbol.for('Sync_Timer'),
|
||||
Sync_SyncResponseFactory20161215: Symbol.for('Sync_SyncResponseFactory20161215'),
|
||||
Sync_SyncResponseFactory20200115: Symbol.for('Sync_SyncResponseFactory20200115'),
|
||||
Sync_SyncResponseFactoryResolver: Symbol.for('Sync_SyncResponseFactoryResolver'),
|
||||
Sync_AuthHttpService: Symbol.for('Sync_AuthHttpService'),
|
||||
Sync_ExtensionsHttpService: Symbol.for('Sync_ExtensionsHttpService'),
|
||||
Sync_ItemBackupService: Symbol.for('Sync_ItemBackupService'),
|
||||
Sync_ItemSaveValidator: Symbol.for('Sync_ItemSaveValidator'),
|
||||
Sync_OwnershipFilter: Symbol.for('Sync_OwnershipFilter'),
|
||||
Sync_TimeDifferenceFilter: Symbol.for('Sync_TimeDifferenceFilter'),
|
||||
Sync_UuidFilter: Symbol.for('Sync_UuidFilter'),
|
||||
Sync_ContentTypeFilter: Symbol.for('Sync_ContentTypeFilter'),
|
||||
Sync_ContentFilter: Symbol.for('Sync_ContentFilter'),
|
||||
Sync_ItemFactory: Symbol.for('Sync_ItemFactory'),
|
||||
Sync_ItemTransferCalculator: Symbol.for('Sync_ItemTransferCalculator'),
|
||||
Sync_ControllerContainer: Symbol.for('Sync_ControllerContainer'),
|
||||
Sync_InversifyExpressItemsController: Symbol.for('Sync_InversifyExpressItemsController'),
|
||||
}
|
||||
|
||||
export default TYPES
|
||||
|
||||
@@ -1,207 +0,0 @@
|
||||
import { SQSClient, SQSClientConfig } from '@aws-sdk/client-sqs'
|
||||
import { S3Client } from '@aws-sdk/client-s3'
|
||||
import { Container, interfaces } from 'inversify'
|
||||
import {
|
||||
DomainEventHandlerInterface,
|
||||
DomainEventMessageHandlerInterface,
|
||||
DomainEventSubscriberFactoryInterface,
|
||||
} from '@standardnotes/domain-events'
|
||||
|
||||
import { Env } from './Env'
|
||||
import TYPES from './Types'
|
||||
import { ContentDecoder } from '../Domain/Item/ContentDecoder'
|
||||
import { AuthHttpServiceInterface } from '../Domain/Auth/AuthHttpServiceInterface'
|
||||
import { AuthHttpService } from '../Infra/HTTP/AuthHttpService'
|
||||
import { ExtensionsHttpServiceInterface } from '../Domain/Extension/ExtensionsHttpServiceInterface'
|
||||
import { ExtensionsHttpService } from '../Domain/Extension/ExtensionsHttpService'
|
||||
import { ItemBackupServiceInterface } from '../Domain/Item/ItemBackupServiceInterface'
|
||||
import { S3ItemBackupService } from '../Infra/S3/S3ItemBackupService'
|
||||
import { DuplicateItemSyncedEventHandler } from '../Domain/Handler/DuplicateItemSyncedEventHandler'
|
||||
import { AccountDeletionRequestedEventHandler } from '../Domain/Handler/AccountDeletionRequestedEventHandler'
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const axios = require('axios')
|
||||
import { AxiosInstance } from 'axios'
|
||||
import {
|
||||
SQSDomainEventSubscriberFactory,
|
||||
SQSEventMessageHandler,
|
||||
SQSNewRelicEventMessageHandler,
|
||||
} from '@standardnotes/domain-events-infra'
|
||||
import { EmailBackupRequestedEventHandler } from '../Domain/Handler/EmailBackupRequestedEventHandler'
|
||||
import { ItemRevisionCreationRequestedEventHandler } from '../Domain/Handler/ItemRevisionCreationRequestedEventHandler'
|
||||
import { FSItemBackupService } from '../Infra/FS/FSItemBackupService'
|
||||
import { CommonContainerConfigLoader } from './CommonContainerConfigLoader'
|
||||
|
||||
export class WorkerContainerConfigLoader extends CommonContainerConfigLoader {
|
||||
private readonly DEFAULT_FILE_UPLOAD_PATH = `${__dirname}/../../uploads`
|
||||
|
||||
override async load(): Promise<Container> {
|
||||
const container = await super.load()
|
||||
|
||||
const env: Env = container.get(TYPES.Env)
|
||||
|
||||
container.bind<SQSClient>(TYPES.SQS).toDynamicValue((context: interfaces.Context) => {
|
||||
const env: Env = context.container.get(TYPES.Env)
|
||||
|
||||
const sqsConfig: SQSClientConfig = {
|
||||
region: env.get('SQS_AWS_REGION'),
|
||||
}
|
||||
if (env.get('SQS_ENDPOINT', true)) {
|
||||
sqsConfig.endpoint = env.get('SQS_ENDPOINT', true)
|
||||
}
|
||||
if (env.get('SQS_ACCESS_KEY_ID', true) && env.get('SQS_SECRET_ACCESS_KEY', true)) {
|
||||
sqsConfig.credentials = {
|
||||
accessKeyId: env.get('SQS_ACCESS_KEY_ID', true),
|
||||
secretAccessKey: env.get('SQS_SECRET_ACCESS_KEY', true),
|
||||
}
|
||||
}
|
||||
|
||||
return new SQSClient(sqsConfig)
|
||||
})
|
||||
|
||||
container.bind<S3Client | undefined>(TYPES.S3).toDynamicValue((context: interfaces.Context) => {
|
||||
const env: Env = context.container.get(TYPES.Env)
|
||||
|
||||
let s3Client = undefined
|
||||
if (env.get('S3_AWS_REGION', true)) {
|
||||
s3Client = new S3Client({
|
||||
apiVersion: 'latest',
|
||||
region: env.get('S3_AWS_REGION', true),
|
||||
})
|
||||
}
|
||||
|
||||
return s3Client
|
||||
})
|
||||
|
||||
// env vars
|
||||
container.bind(TYPES.SQS_QUEUE_URL).toConstantValue(env.get('SQS_QUEUE_URL'))
|
||||
container.bind(TYPES.EXTENSIONS_SERVER_URL).toConstantValue(env.get('EXTENSIONS_SERVER_URL', true))
|
||||
container.bind(TYPES.AUTH_SERVER_URL).toConstantValue(env.get('AUTH_SERVER_URL'))
|
||||
container.bind(TYPES.S3_AWS_REGION).toConstantValue(env.get('S3_AWS_REGION', true))
|
||||
container.bind(TYPES.S3_BACKUP_BUCKET_NAME).toConstantValue(env.get('S3_BACKUP_BUCKET_NAME', true))
|
||||
container.bind(TYPES.EMAIL_ATTACHMENT_MAX_BYTE_SIZE).toConstantValue(env.get('EMAIL_ATTACHMENT_MAX_BYTE_SIZE'))
|
||||
container.bind(TYPES.NEW_RELIC_ENABLED).toConstantValue(env.get('NEW_RELIC_ENABLED', true))
|
||||
container.bind(TYPES.VERSION).toConstantValue(env.get('VERSION'))
|
||||
container
|
||||
.bind(TYPES.FILE_UPLOAD_PATH)
|
||||
.toConstantValue(
|
||||
env.get('FILE_UPLOAD_PATH', true) ? env.get('FILE_UPLOAD_PATH', true) : this.DEFAULT_FILE_UPLOAD_PATH,
|
||||
)
|
||||
|
||||
// Handlers
|
||||
container
|
||||
.bind<DuplicateItemSyncedEventHandler>(TYPES.DuplicateItemSyncedEventHandler)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new DuplicateItemSyncedEventHandler(
|
||||
context.container.get(TYPES.ItemRepository),
|
||||
context.container.get(TYPES.DomainEventFactory),
|
||||
context.container.get(TYPES.DomainEventPublisher),
|
||||
context.container.get(TYPES.Logger),
|
||||
)
|
||||
})
|
||||
container
|
||||
.bind<AccountDeletionRequestedEventHandler>(TYPES.AccountDeletionRequestedEventHandler)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new AccountDeletionRequestedEventHandler(
|
||||
context.container.get(TYPES.ItemRepository),
|
||||
context.container.get(TYPES.Logger),
|
||||
)
|
||||
})
|
||||
container
|
||||
.bind<EmailBackupRequestedEventHandler>(TYPES.EmailBackupRequestedEventHandler)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new EmailBackupRequestedEventHandler(
|
||||
context.container.get(TYPES.ItemRepository),
|
||||
context.container.get(TYPES.AuthHttpService),
|
||||
context.container.get(TYPES.ItemBackupService),
|
||||
context.container.get(TYPES.DomainEventPublisher),
|
||||
context.container.get(TYPES.DomainEventFactory),
|
||||
context.container.get(TYPES.EMAIL_ATTACHMENT_MAX_BYTE_SIZE),
|
||||
context.container.get(TYPES.ItemTransferCalculator),
|
||||
context.container.get(TYPES.S3_BACKUP_BUCKET_NAME),
|
||||
context.container.get(TYPES.Logger),
|
||||
)
|
||||
})
|
||||
container
|
||||
.bind<ItemRevisionCreationRequestedEventHandler>(TYPES.ItemRevisionCreationRequestedEventHandler)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new ItemRevisionCreationRequestedEventHandler(
|
||||
context.container.get(TYPES.ItemRepository),
|
||||
context.container.get(TYPES.ItemBackupService),
|
||||
context.container.get(TYPES.DomainEventFactory),
|
||||
context.container.get(TYPES.DomainEventPublisher),
|
||||
)
|
||||
})
|
||||
|
||||
// Services
|
||||
container.bind<ContentDecoder>(TYPES.ContentDecoder).toDynamicValue(() => new ContentDecoder())
|
||||
container.bind<AxiosInstance>(TYPES.HTTPClient).toDynamicValue(() => axios.create())
|
||||
container.bind<AuthHttpServiceInterface>(TYPES.AuthHttpService).toDynamicValue((context: interfaces.Context) => {
|
||||
return new AuthHttpService(context.container.get(TYPES.HTTPClient), context.container.get(TYPES.AUTH_SERVER_URL))
|
||||
})
|
||||
container
|
||||
.bind<ExtensionsHttpServiceInterface>(TYPES.ExtensionsHttpService)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new ExtensionsHttpService(
|
||||
context.container.get(TYPES.HTTPClient),
|
||||
context.container.get(TYPES.ItemRepository),
|
||||
context.container.get(TYPES.ContentDecoder),
|
||||
context.container.get(TYPES.DomainEventPublisher),
|
||||
context.container.get(TYPES.DomainEventFactory),
|
||||
context.container.get(TYPES.Logger),
|
||||
)
|
||||
})
|
||||
|
||||
container
|
||||
.bind<ItemBackupServiceInterface>(TYPES.ItemBackupService)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
const env: Env = context.container.get(TYPES.Env)
|
||||
|
||||
if (env.get('S3_AWS_REGION', true)) {
|
||||
return new S3ItemBackupService(
|
||||
context.container.get(TYPES.S3_BACKUP_BUCKET_NAME),
|
||||
context.container.get(TYPES.ItemProjector),
|
||||
context.container.get(TYPES.Logger),
|
||||
context.container.get(TYPES.S3),
|
||||
)
|
||||
} else {
|
||||
return new FSItemBackupService(
|
||||
context.container.get(TYPES.FILE_UPLOAD_PATH),
|
||||
context.container.get(TYPES.ItemProjector),
|
||||
context.container.get(TYPES.Logger),
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
container
|
||||
.bind<DomainEventMessageHandlerInterface>(TYPES.DomainEventMessageHandler)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
const env: Env = context.container.get(TYPES.Env)
|
||||
|
||||
const eventHandlers: Map<string, DomainEventHandlerInterface> = new Map([
|
||||
['DUPLICATE_ITEM_SYNCED', context.container.get(TYPES.DuplicateItemSyncedEventHandler)],
|
||||
['ACCOUNT_DELETION_REQUESTED', context.container.get(TYPES.AccountDeletionRequestedEventHandler)],
|
||||
['EMAIL_BACKUP_REQUESTED', context.container.get(TYPES.EmailBackupRequestedEventHandler)],
|
||||
['ITEM_REVISION_CREATION_REQUESTED', context.container.get(TYPES.ItemRevisionCreationRequestedEventHandler)],
|
||||
])
|
||||
|
||||
const handler =
|
||||
env.get('NEW_RELIC_ENABLED', true) === 'true'
|
||||
? new SQSNewRelicEventMessageHandler(eventHandlers, context.container.get(TYPES.Logger))
|
||||
: new SQSEventMessageHandler(eventHandlers, context.container.get(TYPES.Logger))
|
||||
|
||||
return handler
|
||||
})
|
||||
|
||||
container
|
||||
.bind<DomainEventSubscriberFactoryInterface>(TYPES.DomainEventSubscriberFactory)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new SQSDomainEventSubscriberFactory(
|
||||
context.container.get(TYPES.SQS),
|
||||
context.container.get(TYPES.SQS_QUEUE_URL),
|
||||
context.container.get(TYPES.DomainEventMessageHandler),
|
||||
)
|
||||
})
|
||||
|
||||
return container
|
||||
}
|
||||
}
|
||||
1
packages/syncing-server/src/Bootstrap/index.ts
Normal file
1
packages/syncing-server/src/Bootstrap/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './Service'
|
||||
@@ -1,7 +1,7 @@
|
||||
import { controller, httpGet } from 'inversify-express-utils'
|
||||
|
||||
@controller('/healthcheck')
|
||||
export class HealthCheckController {
|
||||
export class InversifyExpressHealthCheckController {
|
||||
@httpGet('/')
|
||||
public async get(): Promise<string> {
|
||||
return 'OK'
|
||||
@@ -3,20 +3,21 @@ import 'reflect-metadata'
|
||||
import * as express from 'express'
|
||||
import { ContentType } from '@standardnotes/common'
|
||||
|
||||
import { ItemsController } from './ItemsController'
|
||||
import { InversifyExpressItemsController } from './InversifyExpressItemsController'
|
||||
import { results } from 'inversify-express-utils'
|
||||
import { SyncItems } from '../Domain/UseCase/SyncItems'
|
||||
import { ApiVersion } from '../Domain/Api/ApiVersion'
|
||||
import { SyncResponseFactoryResolverInterface } from '../Domain/Item/SyncResponse/SyncResponseFactoryResolverInterface'
|
||||
import { SyncResponseFactoryInterface } from '../Domain/Item/SyncResponse/SyncResponseFactoryInterface'
|
||||
import { SyncResponse20200115 } from '../Domain/Item/SyncResponse/SyncResponse20200115'
|
||||
import { CheckIntegrity } from '../Domain/UseCase/CheckIntegrity/CheckIntegrity'
|
||||
import { GetItem } from '../Domain/UseCase/GetItem/GetItem'
|
||||
import { Item } from '../Domain/Item/Item'
|
||||
import { ProjectorInterface } from '../Projection/ProjectorInterface'
|
||||
import { ItemProjection } from '../Projection/ItemProjection'
|
||||
import { Item } from '../../Domain/Item/Item'
|
||||
import { ItemProjection } from '../../Projection/ItemProjection'
|
||||
import { ProjectorInterface } from '../../Projection/ProjectorInterface'
|
||||
import { ApiVersion } from '../../Domain/Api/ApiVersion'
|
||||
import { SyncResponse20200115 } from '../../Domain/Item/SyncResponse/SyncResponse20200115'
|
||||
import { SyncResponseFactoryInterface } from '../../Domain/Item/SyncResponse/SyncResponseFactoryInterface'
|
||||
import { SyncResponseFactoryResolverInterface } from '../../Domain/Item/SyncResponse/SyncResponseFactoryResolverInterface'
|
||||
import { CheckIntegrity } from '../../Domain/UseCase/CheckIntegrity/CheckIntegrity'
|
||||
import { GetItem } from '../../Domain/UseCase/GetItem/GetItem'
|
||||
import { SyncItems } from '../../Domain/UseCase/SyncItems'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
|
||||
describe('ItemsController', () => {
|
||||
describe('InversifyExpressItemsController', () => {
|
||||
let syncItems: SyncItems
|
||||
let checkIntegrity: CheckIntegrity
|
||||
let getItem: GetItem
|
||||
@@ -26,11 +27,22 @@ describe('ItemsController', () => {
|
||||
let syncResponceFactoryResolver: SyncResponseFactoryResolverInterface
|
||||
let syncResponseFactory: SyncResponseFactoryInterface
|
||||
let syncResponse: SyncResponse20200115
|
||||
let controllerContainer: ControllerContainerInterface
|
||||
|
||||
const createController = () =>
|
||||
new ItemsController(syncItems, checkIntegrity, getItem, itemProjector, syncResponceFactoryResolver)
|
||||
new InversifyExpressItemsController(
|
||||
syncItems,
|
||||
checkIntegrity,
|
||||
getItem,
|
||||
itemProjector,
|
||||
syncResponceFactoryResolver,
|
||||
controllerContainer,
|
||||
)
|
||||
|
||||
beforeEach(() => {
|
||||
controllerContainer = {} as jest.Mocked<ControllerContainerInterface>
|
||||
controllerContainer.register = jest.fn()
|
||||
|
||||
itemProjector = {} as jest.Mocked<ProjectorInterface<Item, ItemProjection>>
|
||||
itemProjector.projectFull = jest.fn().mockReturnValue({ foo: 'bar' })
|
||||
|
||||
@@ -1,27 +1,34 @@
|
||||
import { Request, Response } from 'express'
|
||||
import { inject } from 'inversify'
|
||||
import { BaseHttpController, controller, httpGet, httpPost, results } from 'inversify-express-utils'
|
||||
import TYPES from '../Bootstrap/Types'
|
||||
import { ApiVersion } from '../Domain/Api/ApiVersion'
|
||||
import { Item } from '../Domain/Item/Item'
|
||||
import { SyncResponseFactoryResolverInterface } from '../Domain/Item/SyncResponse/SyncResponseFactoryResolverInterface'
|
||||
import { CheckIntegrity } from '../Domain/UseCase/CheckIntegrity/CheckIntegrity'
|
||||
import { GetItem } from '../Domain/UseCase/GetItem/GetItem'
|
||||
import { SyncItems } from '../Domain/UseCase/SyncItems'
|
||||
import { ItemProjection } from '../Projection/ItemProjection'
|
||||
import { ProjectorInterface } from '../Projection/ProjectorInterface'
|
||||
|
||||
@controller('/items', TYPES.AuthMiddleware)
|
||||
export class ItemsController extends BaseHttpController {
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { Item } from '../../Domain/Item/Item'
|
||||
import { SyncResponseFactoryResolverInterface } from '../../Domain/Item/SyncResponse/SyncResponseFactoryResolverInterface'
|
||||
import { CheckIntegrity } from '../../Domain/UseCase/CheckIntegrity/CheckIntegrity'
|
||||
import { GetItem } from '../../Domain/UseCase/GetItem/GetItem'
|
||||
import { SyncItems } from '../../Domain/UseCase/SyncItems'
|
||||
import { ItemProjection } from '../../Projection/ItemProjection'
|
||||
import { ProjectorInterface } from '../../Projection/ProjectorInterface'
|
||||
import { ApiVersion } from '../../Domain/Api/ApiVersion'
|
||||
import { ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
|
||||
@controller('/items', TYPES.Sync_AuthMiddleware)
|
||||
export class InversifyExpressItemsController extends BaseHttpController {
|
||||
constructor(
|
||||
@inject(TYPES.SyncItems) private syncItems: SyncItems,
|
||||
@inject(TYPES.CheckIntegrity) private checkIntegrity: CheckIntegrity,
|
||||
@inject(TYPES.GetItem) private getItem: GetItem,
|
||||
@inject(TYPES.ItemProjector) private itemProjector: ProjectorInterface<Item, ItemProjection>,
|
||||
@inject(TYPES.SyncResponseFactoryResolver)
|
||||
@inject(TYPES.Sync_SyncItems) private syncItems: SyncItems,
|
||||
@inject(TYPES.Sync_CheckIntegrity) private checkIntegrity: CheckIntegrity,
|
||||
@inject(TYPES.Sync_GetItem) private getItem: GetItem,
|
||||
@inject(TYPES.Sync_ItemProjector) private itemProjector: ProjectorInterface<Item, ItemProjection>,
|
||||
@inject(TYPES.Sync_SyncResponseFactoryResolver)
|
||||
private syncResponseFactoryResolver: SyncResponseFactoryResolverInterface,
|
||||
@inject(TYPES.Sync_ControllerContainer) private controllerContainer: ControllerContainerInterface,
|
||||
) {
|
||||
super()
|
||||
|
||||
this.controllerContainer.register('sync.items.sync', this.sync.bind(this))
|
||||
this.controllerContainer.register('sync.items.check_integrity', this.checkItemsIntegrity.bind(this))
|
||||
this.controllerContainer.register('sync.items.get_item', this.getSingleItem.bind(this))
|
||||
}
|
||||
|
||||
@httpPost('/sync')
|
||||
@@ -2,19 +2,19 @@ import 'reflect-metadata'
|
||||
|
||||
import * as winston from 'winston'
|
||||
|
||||
import { AuthMiddleware } from './AuthMiddleware'
|
||||
import { InversifyExpressAuthMiddleware } from './InversifyExpressAuthMiddleware'
|
||||
import { NextFunction, Request, Response } from 'express'
|
||||
import { sign } from 'jsonwebtoken'
|
||||
import { RoleName } from '@standardnotes/domain-core'
|
||||
|
||||
describe('AuthMiddleware', () => {
|
||||
describe('InversifyExpressAuthMiddleware', () => {
|
||||
let logger: winston.Logger
|
||||
const jwtSecret = 'auth_jwt_secret'
|
||||
let request: Request
|
||||
let response: Response
|
||||
let next: NextFunction
|
||||
|
||||
const createMiddleware = () => new AuthMiddleware(jwtSecret, logger)
|
||||
const createMiddleware = () => new InversifyExpressAuthMiddleware(jwtSecret, logger)
|
||||
|
||||
beforeEach(() => {
|
||||
logger = {} as jest.Mocked<winston.Logger>
|
||||
@@ -5,7 +5,7 @@ import { CrossServiceTokenData } from '@standardnotes/security'
|
||||
import * as winston from 'winston'
|
||||
import { RoleName } from '@standardnotes/domain-core'
|
||||
|
||||
export class AuthMiddleware extends BaseMiddleware {
|
||||
export class InversifyExpressAuthMiddleware extends BaseMiddleware {
|
||||
constructor(private authJWTSecret: string, private logger: winston.Logger) {
|
||||
super()
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user