Compare commits

..

1 Commits

Author SHA1 Message Date
dependabot[bot]
0055edc3e4 chore(deps): bump actions/setup-node from 3 to 4
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3 to 4.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 06:55:37 +00:00
256 changed files with 3478 additions and 3782 deletions

2
.github/ci.env vendored
View File

@@ -26,5 +26,3 @@ MYSQL_ROOT_PASSWORD=changeme123
AUTH_JWT_SECRET=f95259c5e441f5a4646d76422cfb3df4c4488842901aa50b6c51b8be2e0040e9
AUTH_SERVER_ENCRYPTION_SERVER_KEY=1087415dfde3093797f9a7ca93a49e7d7aa1861735eb0d32aae9c303b8c3d060
VALET_TOKEN_SECRET=4b886819ebe1e908077c6cae96311b48a8416bd60cc91c03060e15bdf6b30d1f
SYNCING_SERVER_CONTENT_SIZE_TRANSFER_LIMIT=1000000

View File

@@ -61,6 +61,13 @@ updates:
allow:
- dependency-type: "direct"
- package-ecosystem: "npm"
directory: "/packages/event-store"
schedule:
interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm"
directory: "/packages/files"
schedule:

View File

@@ -42,7 +42,7 @@ jobs:
key: ${{ runner.os }}-${{ inputs.service_name }}-build-${{ github.sha }}
- name: Set up Node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
registry-url: 'https://registry.npmjs.org'
node-version-file: '.nvmrc'

View File

@@ -46,7 +46,7 @@ jobs:
- uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
registry-url: 'https://registry.npmjs.org'
node-version-file: '.nvmrc'
@@ -70,7 +70,6 @@ jobs:
echo "ACCESS_TOKEN_AGE=4" >> packages/home-server/.env
echo "REFRESH_TOKEN_AGE=10" >> packages/home-server/.env
echo "REVISIONS_FREQUENCY=2" >> packages/home-server/.env
echo "CONTENT_SIZE_TRANSFER_LIMIT=1000000" >> packages/home-server/.env
echo "DB_HOST=localhost" >> packages/home-server/.env
echo "DB_PORT=3306" >> packages/home-server/.env
echo "DB_DATABASE=standardnotes" >> packages/home-server/.env

View File

@@ -29,7 +29,7 @@ jobs:
- uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
registry-url: 'https://registry.npmjs.org'
node-version-file: '.nvmrc'

View File

@@ -20,7 +20,7 @@ jobs:
key: ${{ runner.os }}-build-${{ github.sha }}
- name: Set up Node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
registry-url: 'https://registry.npmjs.org'
node-version-file: '.nvmrc'
@@ -48,7 +48,7 @@ jobs:
key: ${{ runner.os }}-build-${{ github.sha }}
- name: Set up Node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
registry-url: 'https://registry.npmjs.org'
node-version-file: '.nvmrc'
@@ -80,7 +80,7 @@ jobs:
key: ${{ runner.os }}-build-${{ github.sha }}
- name: Set up Node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
registry-url: 'https://registry.npmjs.org'
node-version-file: '.nvmrc'

View File

@@ -20,7 +20,7 @@ jobs:
key: ${{ runner.os }}-build-${{ github.sha }}
- name: Set up Node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
registry-url: 'https://registry.npmjs.org'
node-version-file: '.nvmrc'
@@ -48,7 +48,7 @@ jobs:
key: ${{ runner.os }}-build-${{ github.sha }}
- name: Set up Node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
registry-url: 'https://registry.npmjs.org'
node-version-file: '.nvmrc'
@@ -80,7 +80,7 @@ jobs:
key: ${{ runner.os }}-build-${{ github.sha }}
- name: Set up Node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
registry-url: 'https://registry.npmjs.org'
node-version-file: '.nvmrc'
@@ -151,7 +151,7 @@ jobs:
git_commit_gpgsign: true
- name: Set up Node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
registry-url: 'https://registry.npmjs.org'
node-version-file: '.nvmrc'

978
.pnp.cjs generated

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@@ -3,26 +3,6 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.33.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.33.0...@standardnotes/analytics@2.33.1) (2023-11-13)
**Note:** Version bump only for package @standardnotes/analytics
# [2.33.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.32.6...@standardnotes/analytics@2.33.0) (2023-11-10)
### Features
* add graceful shutdown procedures upon SIGTERM ([#923](https://github.com/standardnotes/server/issues/923)) ([c24353c](https://github.com/standardnotes/server/commit/c24353cc24ebf4b40ff9a2cec8e37cfdef109e37))
## [2.32.6](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.32.5...@standardnotes/analytics@2.32.6) (2023-11-07)
**Note:** Version bump only for package @standardnotes/analytics
## [2.32.5](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.32.4...@standardnotes/analytics@2.32.5) (2023-11-07)
### Bug Fixes
* remove open telemetry from code ([#903](https://github.com/standardnotes/server/issues/903)) ([751f3b2](https://github.com/standardnotes/server/commit/751f3b25476c5be3d663ad8540c43266acd39493))
## [2.32.4](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.32.3...@standardnotes/analytics@2.32.4) (2023-10-26)
**Note:** Version bump only for package @standardnotes/analytics

View File

@@ -1,5 +1,11 @@
import 'reflect-metadata'
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
import { EmailLevel, ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AnalyticsScheduledTask })
sdk.start()
import { Logger } from 'winston'
import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
@@ -16,7 +22,6 @@ import { CalculateMonthlyRecurringRevenue } from '../src/Domain/UseCase/Calculat
import { getBody, getSubject } from '../src/Domain/Email/DailyAnalyticsReport'
import { TimerInterface } from '@standardnotes/time'
import { StatisticMeasureName } from '../src/Domain/Statistics/StatisticMeasureName'
import { EmailLevel } from '@standardnotes/domain-core'
const requestReport = async (
analyticsStore: AnalyticsStoreInterface,
@@ -270,6 +275,9 @@ void container.load().then((container) => {
logger.info(`Sending report to following admins: ${adminEmails}`)
const tracer = new OpenTelemetryTracer()
tracer.startSpan(ServiceIdentifier.NAMES.AnalyticsScheduledTask, 'report')
Promise.resolve(
requestReport(
analyticsStore,
@@ -285,11 +293,15 @@ void container.load().then((container) => {
.then(() => {
logger.info('Usage report generation complete')
tracer.stopSpan()
process.exit(0)
})
.catch((error) => {
logger.error(`Could not finish usage report generation: ${error.message}`)
tracer.stopSpanWithError(error)
process.exit(1)
})
})

View File

@@ -1,5 +1,11 @@
import 'reflect-metadata'
import { OpenTelemetrySDK } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AnalyticsWorker })
sdk.start()
import { Logger } from 'winston'
import { DomainEventSubscriberInterface } from '@standardnotes/domain-events'
import * as dayjs from 'dayjs'
@@ -22,11 +28,5 @@ void container.load().then((container) => {
const subscriber = container.get<DomainEventSubscriberInterface>(TYPES.DomainEventSubscriber)
process.on('SIGTERM', () => {
logger.info('SIGTERM received. Stopping worker...')
subscriber.stop()
logger.info('Worker stopped.')
})
subscriber.start()
})

View File

@@ -6,12 +6,12 @@ COMMAND=$1 && shift 1
case "$COMMAND" in
'start-worker' )
echo "[Docker] Starting Worker..."
exec node docker/entrypoint-worker.js
node docker/entrypoint-worker.js
;;
'report' )
echo "[Docker] Starting Usage Report Generation..."
exec node docker/entrypoint-report.js
node docker/entrypoint-report.js
;;
* )

View File

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

View File

@@ -7,7 +7,7 @@ import {
DomainEventPublisherInterface,
DomainEventSubscriberInterface,
} from '@standardnotes/domain-events'
import { MapperInterface } from '@standardnotes/domain-core'
import { MapperInterface, ServiceIdentifier } from '@standardnotes/domain-core'
// eslint-disable-next-line @typescript-eslint/no-var-requires
const Mixpanel = require('mixpanel')
@@ -16,9 +16,9 @@ import TYPES from './Types'
import { AppDataSource } from './DataSource'
import { DomainEventFactory } from '../Domain/Event/DomainEventFactory'
import {
SNSDomainEventPublisher,
SQSDomainEventSubscriber,
SNSOpenTelemetryDomainEventPublisher,
SQSEventMessageHandler,
SQSOpenTelemetryDomainEventSubscriber,
} from '@standardnotes/domain-events-infra'
import { Timer, TimerInterface } from '@standardnotes/time'
import { PeriodKeyGeneratorInterface } from '../Domain/Time/PeriodKeyGeneratorInterface'
@@ -139,7 +139,9 @@ export class ContainerConfigLoader {
container
.bind<DomainEventPublisherInterface>(TYPES.DomainEventPublisher)
.toConstantValue(new SNSDomainEventPublisher(container.get(TYPES.SNS), container.get(TYPES.SNS_TOPIC_ARN)))
.toConstantValue(
new SNSOpenTelemetryDomainEventPublisher(container.get(TYPES.SNS), container.get(TYPES.SNS_TOPIC_ARN)),
)
if (env.get('MIXPANEL_TOKEN', true)) {
container.bind<Mixpanel>(TYPES.MixpanelClient).toConstantValue(Mixpanel.init(env.get('MIXPANEL_TOKEN', true)))
}
@@ -240,7 +242,8 @@ export class ContainerConfigLoader {
container
.bind<DomainEventSubscriberInterface>(TYPES.DomainEventSubscriber)
.toConstantValue(
new SQSDomainEventSubscriber(
new SQSOpenTelemetryDomainEventSubscriber(
ServiceIdentifier.NAMES.AnalyticsWorker,
container.get<SQSClient>(TYPES.SQS),
container.get<string>(TYPES.SQS_QUEUE_URL),
container.get<DomainEventMessageHandlerInterface>(TYPES.DomainEventMessageHandler),

View File

@@ -3,74 +3,6 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.83.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.83.1...@standardnotes/api-gateway@1.83.2) (2023-11-13)
### Bug Fixes
* **api-gateway:** debug log on error thrown body representation ([c8bf4ab](https://github.com/standardnotes/api-gateway/commit/c8bf4ab3a0ab757092077fc594e3ca7e090116b4))
## [1.83.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.83.0...@standardnotes/api-gateway@1.83.1) (2023-11-13)
### Bug Fixes
* **api-gateway:** add debug logs for errors on parsing ([60686dc](https://github.com/standardnotes/api-gateway/commit/60686dcdbd59c0d99cd1857a82ad62baed088b25))
# [1.83.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.82.1...@standardnotes/api-gateway@1.83.0) (2023-11-10)
### Bug Fixes
* **api-gateway:** add more info on error logs ([f997501](https://github.com/standardnotes/api-gateway/commit/f99750169f4d24cdc7530184af2230c687f3e166))
### Features
* add keep-alive connections to subservices ([#924](https://github.com/standardnotes/api-gateway/issues/924)) ([daad76d](https://github.com/standardnotes/api-gateway/commit/daad76d0ddae34c59dce45eedc4a055c4a11456d))
## [1.82.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.82.0...@standardnotes/api-gateway@1.82.1) (2023-11-10)
### Bug Fixes
* **api-gateway:** websockets calls logs severity ([a9b1543](https://github.com/standardnotes/api-gateway/commit/a9b1543e204afeab1fa2e008327c39cf306a247c))
# [1.82.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.81.14...@standardnotes/api-gateway@1.82.0) (2023-11-10)
### Features
* add graceful shutdown procedures upon SIGTERM ([#923](https://github.com/standardnotes/api-gateway/issues/923)) ([c24353c](https://github.com/standardnotes/api-gateway/commit/c24353cc24ebf4b40ff9a2cec8e37cfdef109e37))
## [1.81.14](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.81.13...@standardnotes/api-gateway@1.81.14) (2023-11-10)
### Bug Fixes
* **api-gateway:** add logs about calling web sockets with minimal format ([5d3fb9a](https://github.com/standardnotes/api-gateway/commit/5d3fb9a537f6971cfe8ae3c5ea449806cc4de8a0))
## [1.81.13](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.81.12...@standardnotes/api-gateway@1.81.13) (2023-11-09)
### Bug Fixes
* **api-gateway:** add possibility to configure keep-alive timeout ([#920](https://github.com/standardnotes/api-gateway/issues/920)) ([16f92bd](https://github.com/standardnotes/api-gateway/commit/16f92bdc990ded5c3f1fe5af1e6e4a113a9954de))
## [1.81.12](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.81.11...@standardnotes/api-gateway@1.81.12) (2023-11-09)
### Bug Fixes
* reduce websockets api communication data ([#919](https://github.com/standardnotes/api-gateway/issues/919)) ([c4ae12d](https://github.com/standardnotes/api-gateway/commit/c4ae12d53fc166879f90a4c5dbad1ab1cb4797e2))
## [1.81.11](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.81.10...@standardnotes/api-gateway@1.81.11) (2023-11-07)
### Bug Fixes
* **api-gateway:** remove calling both auth and payments on account deletion request ([6b554c2](https://github.com/standardnotes/api-gateway/commit/6b554c28b731a9080d7ad2942d3fa05c01dcabf2))
## [1.81.10](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.81.9...@standardnotes/api-gateway@1.81.10) (2023-11-07)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.81.9](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.81.8...@standardnotes/api-gateway@1.81.9) (2023-11-07)
### Bug Fixes
* remove open telemetry from code ([#903](https://github.com/standardnotes/api-gateway/issues/903)) ([751f3b2](https://github.com/standardnotes/api-gateway/commit/751f3b25476c5be3d663ad8540c43266acd39493))
## [1.81.8](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.81.7...@standardnotes/api-gateway@1.81.8) (2023-11-03)
### Bug Fixes

View File

@@ -1,5 +1,11 @@
import 'reflect-metadata'
import { OpenTelemetrySDK } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.ApiGateway })
sdk.start()
import '../src/Controller/LegacyController'
import '../src/Controller/HealthCheckController'
@@ -90,13 +96,8 @@ void container.load().then((container) => {
const logger: winston.Logger = container.get(TYPES.ApiGateway_Logger)
server.setErrorConfig((app) => {
app.use((error: Record<string, unknown>, request: Request, response: Response, _next: NextFunction) => {
logger.error(`[URL: ${request.url}][SNJS: ${request.headers['x-snjs-version']}] Error thrown: ${error.stack}`)
logger.debug(
`[URL: ${request.url}][SNJS: ${request.headers['x-snjs-version']}] Request body: ${JSON.stringify(
request.body,
)}`,
)
app.use((error: Record<string, unknown>, _request: Request, response: Response, _next: NextFunction) => {
logger.error(error.stack)
response.status(500).send({
error: {
@@ -107,18 +108,9 @@ void container.load().then((container) => {
})
})
const serverInstance = server.build().listen(env.get('PORT'))
const serverInstance = server.build()
const keepAliveTimeout = env.get('KEEP_ALIVE_TIMEOUT', true) ? +env.get('KEEP_ALIVE_TIMEOUT', true) : 5000
serverInstance.keepAliveTimeout = keepAliveTimeout
process.on('SIGTERM', () => {
logger.info('SIGTERM signal received: closing HTTP server')
serverInstance.close(() => {
logger.info('HTTP server closed')
})
})
serverInstance.listen(env.get('PORT'))
logger.info(`Server started on port ${process.env.PORT}`)
})

View File

@@ -6,7 +6,7 @@ COMMAND=$1 && shift 1
case "$COMMAND" in
'start-web' )
echo "Starting Web..."
exec node docker/entrypoint-server.js
node docker/entrypoint-server.js
;;
* )

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/api-gateway",
"version": "1.83.2",
"version": "1.81.8",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
@@ -31,8 +31,7 @@
"@standardnotes/domain-events-infra": "workspace:*",
"@standardnotes/security": "workspace:*",
"@standardnotes/time": "workspace:*",
"agentkeepalive": "^4.5.0",
"axios": "^1.6.1",
"axios": "^1.1.3",
"cors": "2.8.5",
"dotenv": "^16.0.1",
"express": "^4.18.2",

View File

@@ -1,6 +1,7 @@
import * as winston from 'winston'
import * as AgentKeepAlive from 'agentkeepalive'
import axios, { AxiosInstance } from 'axios'
// eslint-disable-next-line @typescript-eslint/no-var-requires
const axios = require('axios')
import { AxiosInstance } from 'axios'
import Redis from 'ioredis'
import { Container } from 'inversify'
import { Timer, TimerInterface } from '@standardnotes/time'
@@ -69,17 +70,7 @@ export class ContainerConfigLoader {
container.bind(TYPES.ApiGateway_Redis).toConstantValue(redis)
}
container.bind<AxiosInstance>(TYPES.ApiGateway_HTTPClient).toConstantValue(
axios.create({
httpAgent: new AgentKeepAlive({
keepAlive: true,
timeout: env.get('AGENT_KEEP_ALIVE_TIMEOUT', true) ? +env.get('AGENT_KEEP_ALIVE_TIMEOUT', true) : 8_000,
freeSocketTimeout: env.get('AGENT_KEEP_ALIVE_FREE_SOCKET_TIMEOUT', true)
? +env.get('AGENT_KEEP_ALIVE_FREE_SOCKET_TIMEOUT', true)
: 4_000,
}),
}),
)
container.bind<AxiosInstance>(TYPES.ApiGateway_HTTPClient).toConstantValue(axios.create())
// env vars
container.bind(TYPES.ApiGateway_SYNCING_SERVER_JS_URL).toConstantValue(env.get('SYNCING_SERVER_JS_URL', true))

View File

@@ -23,6 +23,7 @@ export class UsersController extends BaseHttpController {
@inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
@inject(TYPES.ApiGateway_Logger) private logger: Logger,
@inject(TYPES.ApiGateway_IS_CONFIGURED_FOR_HOME_SERVER) private isConfiguredForHomeServer: boolean,
) {
super()
}
@@ -237,6 +238,10 @@ export class UsersController extends BaseHttpController {
@httpDelete('/:userUuid', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async deleteUser(request: Request, response: Response): Promise<void> {
if (!this.isConfiguredForHomeServer) {
await this.httpService.callPaymentsServer(request, response, 'api/account', request.body, true)
}
await this.httpService.callAuthServer(
request,
response,

View File

@@ -143,21 +143,7 @@ export class HttpServiceProxy implements ServiceProxyInterface {
return
}
const isARequestComingFromApiGatewayAndShouldBeKeptInMinimalFormat = request.headers.connectionid !== undefined
this.logger.debug(
`Calling websockets service: ${endpointOrMethodIdentifier}. Format is minimal: ${isARequestComingFromApiGatewayAndShouldBeKeptInMinimalFormat}`,
)
if (isARequestComingFromApiGatewayAndShouldBeKeptInMinimalFormat) {
await this.callServerWithLegacyFormat(
this.webSocketServerUrl,
request,
response,
endpointOrMethodIdentifier,
payload,
)
} else {
await this.callServer(this.webSocketServerUrl, request, response, endpointOrMethodIdentifier, payload)
}
await this.callServer(this.webSocketServerUrl, request, response, endpointOrMethodIdentifier, payload)
}
async callPaymentsServer(
@@ -165,6 +151,7 @@ export class HttpServiceProxy implements ServiceProxyInterface {
response: Response,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
returnRawResponse?: boolean,
): Promise<void | Response<unknown, Record<string, unknown>>> {
if (!this.paymentsServerUrl) {
this.logger.debug('Payments Server URL not defined. Skipped request to Payments API.')
@@ -172,13 +159,18 @@ export class HttpServiceProxy implements ServiceProxyInterface {
return
}
await this.callServerWithLegacyFormat(
const rawResponse = await this.callServerWithLegacyFormat(
this.paymentsServerUrl,
request,
response,
endpointOrMethodIdentifier,
payload,
returnRawResponse,
)
if (returnRawResponse) {
return rawResponse
}
}
async callAuthServerWithLegacyFormat(
@@ -353,6 +345,7 @@ export class HttpServiceProxy implements ServiceProxyInterface {
response: Response,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
returnRawResponse?: boolean,
): Promise<void | Response<unknown, Record<string, unknown>>> {
const serviceResponse = await this.getServerResponse(
serverUrl,
@@ -371,10 +364,18 @@ export class HttpServiceProxy implements ServiceProxyInterface {
if (serviceResponse.request._redirectable._redirectCount > 0) {
response.status(302)
if (returnRawResponse) {
return response
}
response.redirect(serviceResponse.request.res.responseUrl)
} else {
response.status(serviceResponse.status)
if (returnRawResponse) {
return response
}
response.send(serviceResponse.data)
}
}

View File

@@ -42,6 +42,7 @@ export interface ServiceProxyInterface {
response: Response,
endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string,
returnRawResponse?: boolean,
): Promise<void | Response<unknown, Record<string, unknown>>>
callWebSocketServer(
request: Request,

View File

@@ -6,4 +6,4 @@ sh supervisor/wait-for.sh localhost $AUTH_SERVER_PORT
sh supervisor/wait-for.sh localhost $FILES_SERVER_PORT
sh supervisor/wait-for.sh localhost $REVISIONS_SERVER_PORT
sh supervisor/wait-for.sh localhost $SYNCING_SERVER_PORT
exec node docker/entrypoint-server.js
node docker/entrypoint-server.js

View File

@@ -3,58 +3,6 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.169.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.169.0...@standardnotes/auth-server@1.169.1) (2023-11-13)
**Note:** Version bump only for package @standardnotes/auth-server
# [1.169.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.168.0...@standardnotes/auth-server@1.169.0) (2023-11-10)
### Features
* add keep-alive connections to subservices ([#924](https://github.com/standardnotes/server/issues/924)) ([daad76d](https://github.com/standardnotes/server/commit/daad76d0ddae34c59dce45eedc4a055c4a11456d))
# [1.168.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.167.2...@standardnotes/auth-server@1.168.0) (2023-11-10)
### Features
* add graceful shutdown procedures upon SIGTERM ([#923](https://github.com/standardnotes/server/issues/923)) ([c24353c](https://github.com/standardnotes/server/commit/c24353cc24ebf4b40ff9a2cec8e37cfdef109e37))
## [1.167.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.167.1...@standardnotes/auth-server@1.167.2) (2023-11-08)
### Bug Fixes
* add logs about sending websocket events to clients ([9465f2e](https://github.com/standardnotes/server/commit/9465f2ecd8e8f0bf3ebeeb3976227b1b105aded0))
## [1.167.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.167.0...@standardnotes/auth-server@1.167.1) (2023-11-08)
### Bug Fixes
* **auth:** path to delete accounts script ([ca8a3fc](https://github.com/standardnotes/server/commit/ca8a3fc77d91410f0dee8c3ddef29c09947c9cf5))
# [1.167.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.166.0...@standardnotes/auth-server@1.167.0) (2023-11-08)
### Features
* script to mass delete accounts from CSV source ([#913](https://github.com/standardnotes/server/issues/913)) ([a6dea50](https://github.com/standardnotes/server/commit/a6dea50d745ff6f051fd9ede168aef27036159c3))
# [1.166.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.165.4...@standardnotes/auth-server@1.166.0) (2023-11-07)
### Features
* **auth:** add triggering post setting update actions ([#905](https://github.com/standardnotes/server/issues/905)) ([d228a86](https://github.com/standardnotes/server/commit/d228a86f48c9ff62b7810244c347abf7770e2b9f))
## [1.165.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.165.3...@standardnotes/auth-server@1.165.4) (2023-11-07)
### Bug Fixes
* account deletion event ([#904](https://github.com/standardnotes/server/issues/904)) ([d66ae62](https://github.com/standardnotes/server/commit/d66ae62cf4f413cac5f6f4eac45dc0f1ddbc9e32))
## [1.165.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.165.2...@standardnotes/auth-server@1.165.3) (2023-11-07)
### Bug Fixes
* remove open telemetry from code ([#903](https://github.com/standardnotes/server/issues/903)) ([751f3b2](https://github.com/standardnotes/server/commit/751f3b25476c5be3d663ad8540c43266acd39493))
## [1.165.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.165.1...@standardnotes/auth-server@1.165.2) (2023-11-03)
### Bug Fixes

View File

@@ -1,5 +1,13 @@
import 'reflect-metadata'
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier, SettingName } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AuthScheduledTask })
sdk.start()
import { Stream } from 'stream'
import { Logger } from 'winston'
import * as dayjs from 'dayjs'
import * as utc from 'dayjs/plugin/utc'
@@ -7,13 +15,78 @@ import * as utc from 'dayjs/plugin/utc'
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
import TYPES from '../src/Bootstrap/Types'
import { Env } from '../src/Bootstrap/Env'
import { TriggerEmailBackupForAllUsers } from '../src/Domain/UseCase/TriggerEmailBackupForAllUsers/TriggerEmailBackupForAllUsers'
import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
import { DomainEventFactoryInterface } from '../src/Domain/Event/DomainEventFactoryInterface'
import { SettingRepositoryInterface } from '../src/Domain/Setting/SettingRepositoryInterface'
import { MuteFailedBackupsEmailsOption } from '@standardnotes/settings'
import { RoleServiceInterface } from '../src/Domain/Role/RoleServiceInterface'
import { PermissionName } from '@standardnotes/features'
import { GetUserKeyParams } from '../src/Domain/UseCase/GetUserKeyParams/GetUserKeyParams'
const inputArgs = process.argv.slice(2)
const backupFrequency = inputArgs[0]
const backupProvider = inputArgs[0]
const backupFrequency = inputArgs[1]
const requestBackups = async (triggerEmailBackupForAllUsers: TriggerEmailBackupForAllUsers): Promise<void> => {
await triggerEmailBackupForAllUsers.execute({ backupFrequency })
const requestBackups = async (
settingRepository: SettingRepositoryInterface,
roleService: RoleServiceInterface,
domainEventFactory: DomainEventFactoryInterface,
domainEventPublisher: DomainEventPublisherInterface,
getUserKeyParamsUseCase: GetUserKeyParams,
): Promise<void> => {
const settingName = SettingName.create(SettingName.NAMES.EmailBackupFrequency).getValue()
const permissionName = PermissionName.DailyEmailBackup
const muteEmailsSettingName = SettingName.NAMES.MuteFailedBackupsEmails
const muteEmailsSettingValue = MuteFailedBackupsEmailsOption.Muted
const stream = await settingRepository.streamAllByNameAndValue(settingName, backupFrequency)
return new Promise((resolve, reject) => {
stream
.pipe(
new Stream.Transform({
objectMode: true,
transform: async (setting, _encoding, callback) => {
const userIsPermittedForEmailBackups = await roleService.userHasPermission(
setting.setting_user_uuid,
permissionName,
)
if (!userIsPermittedForEmailBackups) {
callback()
return
}
let userHasEmailsMuted = false
const emailsMutedSetting = await settingRepository.findOneByNameAndUserUuid(
muteEmailsSettingName,
setting.setting_user_uuid,
)
if (emailsMutedSetting !== null && emailsMutedSetting.props.value !== null) {
userHasEmailsMuted = emailsMutedSetting.props.value === muteEmailsSettingValue
}
const keyParamsResponse = await getUserKeyParamsUseCase.execute({
userUuid: setting.setting_user_uuid,
authenticated: false,
})
await domainEventPublisher.publish(
domainEventFactory.createEmailBackupRequestedEvent(
setting.setting_user_uuid,
emailsMutedSetting?.id.toString() as string,
userHasEmailsMuted,
keyParamsResponse.keyParams,
),
)
callback()
},
}),
)
.on('finish', resolve)
.on('error', reject)
})
}
const container = new ContainerConfigLoader('worker')
@@ -25,20 +98,31 @@ void container.load().then((container) => {
const logger: Logger = container.get(TYPES.Auth_Logger)
logger.info(`Starting ${backupFrequency} email backup requesting...`)
logger.info(`Starting ${backupFrequency} ${backupProvider} backup requesting...`)
const triggerEmailBackupForAllUsers: TriggerEmailBackupForAllUsers = container.get(
TYPES.Auth_TriggerEmailBackupForAllUsers,
const settingRepository: SettingRepositoryInterface = container.get(TYPES.Auth_SettingRepository)
const roleService: RoleServiceInterface = container.get(TYPES.Auth_RoleService)
const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.Auth_DomainEventFactory)
const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.Auth_DomainEventPublisher)
const getUserKeyParamsUseCase: GetUserKeyParams = container.get(TYPES.Auth_GetUserKeyParams)
const tracer = new OpenTelemetryTracer()
tracer.startSpan(ServiceIdentifier.NAMES.AuthScheduledTask, 'backup')
Promise.resolve(
requestBackups(settingRepository, roleService, domainEventFactory, domainEventPublisher, getUserKeyParamsUseCase),
)
Promise.resolve(requestBackups(triggerEmailBackupForAllUsers))
.then(() => {
logger.info(`${backupFrequency} email backup requesting complete`)
logger.info(`${backupFrequency} ${backupProvider} backup requesting complete`)
tracer.stopSpan()
process.exit(0)
})
.catch((error) => {
logger.error(`Could not finish ${backupFrequency} email backup requesting: ${error.message}`)
logger.error(`Could not finish ${backupFrequency} ${backupProvider} backup requesting: ${error.message}`)
tracer.stopSpanWithError(error)
process.exit(1)
})

View File

@@ -1,5 +1,11 @@
import 'reflect-metadata'
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AuthScheduledTask })
sdk.start()
import { Logger } from 'winston'
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
@@ -30,15 +36,22 @@ void container.load().then((container) => {
const cleanupSessionTraces: CleanupSessionTraces = container.get(TYPES.Auth_CleanupSessionTraces)
const cleanupExpiredSessions: CleanupExpiredSessions = container.get(TYPES.Auth_CleanupExpiredSessions)
const tracer = new OpenTelemetryTracer()
tracer.startSpan(ServiceIdentifier.NAMES.AuthScheduledTask, 'cleanup')
Promise.resolve(cleanup(cleanupSessionTraces, cleanupExpiredSessions))
.then(() => {
logger.info('Expired sessions and session traces cleaned.')
tracer.stopSpan()
process.exit(0)
})
.catch((error) => {
logger.error(`Could not clean sessions and session traces: ${error.message}`)
tracer.stopSpanWithError(error)
process.exit(1)
})
})

View File

@@ -1,43 +0,0 @@
import 'reflect-metadata'
import { Logger } from 'winston'
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
import TYPES from '../src/Bootstrap/Types'
import { Env } from '../src/Bootstrap/Env'
import { DeleteAccountsFromCSVFile } from '../src/Domain/UseCase/DeleteAccountsFromCSVFile/DeleteAccountsFromCSVFile'
const inputArgs = process.argv.slice(2)
const fileName = inputArgs[0]
const mode = inputArgs[1]
const deleteAccounts = async (deleteAccountsFromCSVFile: DeleteAccountsFromCSVFile): Promise<void> => {
await deleteAccountsFromCSVFile.execute({
fileName,
dryRun: mode !== 'delete',
})
}
const container = new ContainerConfigLoader('worker')
void container.load().then((container) => {
const env: Env = new Env()
env.load()
const logger: Logger = container.get(TYPES.Auth_Logger)
logger.info('Starting mass accounts deletion from CSV file')
const deleteAccountsFromCSVFile = container.get<DeleteAccountsFromCSVFile>(TYPES.Auth_DeleteAccountsFromCSVFile)
Promise.resolve(deleteAccounts(deleteAccountsFromCSVFile))
.then(() => {
logger.info('Accounts deleted.')
process.exit(0)
})
.catch((error) => {
logger.error(`Could not delete accounts: ${error.message}`)
process.exit(1)
})
})

View File

@@ -1,5 +1,11 @@
import 'reflect-metadata'
import { OpenTelemetrySDK } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.Auth })
sdk.start()
import '../src/Infra/InversifyExpressUtils/AnnotatedAuthController'
import '../src/Infra/InversifyExpressUtils/AnnotatedAuthenticatorsController'
import '../src/Infra/InversifyExpressUtils/AnnotatedSessionsController'
@@ -64,18 +70,9 @@ void container.load().then((container) => {
})
})
const serverInstance = server.build().listen(env.get('PORT'))
const serverInstance = server.build()
const keepAliveTimeout = env.get('KEEP_ALIVE_TIMEOUT', true) ? +env.get('KEEP_ALIVE_TIMEOUT', true) : 5000
serverInstance.keepAliveTimeout = keepAliveTimeout
process.on('SIGTERM', () => {
logger.info('SIGTERM signal received: closing HTTP server')
serverInstance.close(() => {
logger.info('HTTP server closed')
})
})
serverInstance.listen(env.get('PORT'))
logger.info(`Server started on port ${process.env.PORT}`)
})

View File

@@ -1,5 +1,11 @@
import 'reflect-metadata'
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AuthScheduledTask })
sdk.start()
import { Logger } from 'winston'
import { TimerInterface } from '@standardnotes/time'
@@ -20,6 +26,9 @@ void container.load().then((container) => {
const persistStats: PersistStatistics = container.get(TYPES.Auth_PersistStatistics)
const timer: TimerInterface = container.get(TYPES.Auth_Timer)
const tracer = new OpenTelemetryTracer()
tracer.startSpan(ServiceIdentifier.NAMES.AuthScheduledTask, 'stats')
Promise.resolve(
persistStats.execute({
sessionsInADay: timer.getUTCDateNDaysAgo(1),
@@ -28,11 +37,15 @@ void container.load().then((container) => {
.then(() => {
logger.info('Stats persisted.')
tracer.stopSpan()
process.exit(0)
})
.catch((error) => {
logger.error(`Could not persist stats: ${error.message}`)
tracer.stopSpanWithError(error)
process.exit(1)
})
})

View File

@@ -1,5 +1,11 @@
import 'reflect-metadata'
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
import { Email, ServiceIdentifier, SettingName } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AuthScheduledTask })
sdk.start()
import { Logger } from 'winston'
import * as dayjs from 'dayjs'
import * as utc from 'dayjs/plugin/utc'
@@ -15,7 +21,6 @@ import { RoleServiceInterface } from '../src/Domain/Role/RoleServiceInterface'
import { PermissionName } from '@standardnotes/features'
import { UserRepositoryInterface } from '../src/Domain/User/UserRepositoryInterface'
import { GetUserKeyParams } from '../src/Domain/UseCase/GetUserKeyParams/GetUserKeyParams'
import { Email, SettingName } from '@standardnotes/domain-core'
const inputArgs = process.argv.slice(2)
const backupEmail = inputArgs[0]
@@ -89,6 +94,9 @@ void container.load().then((container) => {
const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.Auth_DomainEventPublisher)
const getUserKeyParamsUseCase: GetUserKeyParams = container.get(TYPES.Auth_GetUserKeyParams)
const tracer = new OpenTelemetryTracer()
tracer.startSpan(ServiceIdentifier.NAMES.AuthScheduledTask, 'user_email_backup')
Promise.resolve(
requestBackups(
userRepository,
@@ -102,11 +110,15 @@ void container.load().then((container) => {
.then(() => {
logger.info(`Email backup requesting complete for ${backupEmail}`)
tracer.stopSpan()
process.exit(0)
})
.catch((error) => {
logger.error(`Could not finish email backup requesting for ${backupEmail}: ${error.message}`)
tracer.stopSpanWithError(error)
process.exit(1)
})
})

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