Compare commits

..

21 Commits

Author SHA1 Message Date
standardci
f6cdb7916c chore(release): publish new version
- @standardnotes/auth-server@1.152.1
 - @standardnotes/home-server@1.16.33
 - @standardnotes/revisions-server@1.40.1
 - @standardnotes/syncing-server@1.112.1
2023-10-06 13:34:07 +00:00
Karol Sójko
eafb064d79 fix(syncing-server): increase axios timeout on calling auth 2023-10-06 15:18:26 +02:00
Karol Sójko
ba050681f7 fix(syncing-server): logs on request backup handler 2023-10-06 15:16:38 +02:00
Karol Sójko
4780629549 fix(revisions): casting creation date from MongoDB 2023-10-06 15:14:11 +02:00
Karol Sójko
79a44aa51f fix(auth): checking for transition role when triggering transition 2023-10-06 14:56:45 +02:00
standardci
dd72769841 chore(release): publish new version
- @standardnotes/auth-server@1.152.0
 - @standardnotes/home-server@1.16.32
 - @standardnotes/revisions-server@1.40.0
 - @standardnotes/syncing-server@1.112.0
2023-10-06 11:22:47 +00:00
Karol Sójko
d8f1c66fd5 fix: enable TransitionRequestedEventHandler 2023-10-06 13:02:37 +02:00
Karol Sójko
afe9967d26 fix(auth): strip user from transition role after migration 2023-10-06 12:59:18 +02:00
Karol Sójko
27bea444cc feat: switch transition direction 2023-10-06 12:48:08 +02:00
standardci
7a571dec0a chore(release): publish new version
- @standardnotes/home-server@1.16.31
 - @standardnotes/syncing-server@1.111.5
2023-10-06 08:48:31 +00:00
Karol Sójko
8c57f505be fix(syncing-server): add more logs on successfull email backups requested 2023-10-06 10:28:50 +02:00
standardci
973612bf4f chore(release): publish new version
- @standardnotes/analytics@2.28.1
 - @standardnotes/auth-server@1.151.2
 - @standardnotes/home-server@1.16.30
 - @standardnotes/scheduler-server@1.22.1
 - @standardnotes/syncing-server@1.111.4
2023-10-06 08:01:50 +00:00
Karol Sójko
702a1286eb fix(syncing-server): error log on email backup request handler 2023-10-06 09:40:27 +02:00
Karol Sójko
a45b5b69b5 fix: add xray-sdk to background processors 2023-10-06 09:33:15 +02:00
standardci
321353f26c chore(release): publish new version
- @standardnotes/analytics@2.28.0
 - @standardnotes/api-gateway@1.77.1
 - @standardnotes/auth-server@1.151.1
 - @standardnotes/domain-core@1.35.0
 - @standardnotes/domain-events-infra@1.14.8
 - @standardnotes/event-store@1.12.11
 - @standardnotes/files-server@1.26.3
 - @standardnotes/home-server@1.16.29
 - @standardnotes/revisions-server@1.39.5
 - @standardnotes/scheduler-server@1.22.0
 - @standardnotes/settings@1.21.43
 - @standardnotes/syncing-server@1.111.3
 - @standardnotes/websockets-server@1.12.0
2023-10-06 05:44:00 +00:00
Karol Sójko
db4607d4aa chore: upgrade sqs-consumer 2023-10-06 07:26:59 +02:00
Karol Sójko
f0531d68cb feat: add xray to analytics scheduler and websockets 2023-10-06 07:23:06 +02:00
Karol Sójko
8a00d159a6 Revert "fix: naming of segments for sqs handlers"
This reverts commit d244cc0d5f.
2023-10-06 06:50:14 +02:00
Karol Sójko
d244cc0d5f fix: naming of segments for sqs handlers 2023-10-05 18:06:17 +02:00
standardci
6a2aa4b148 chore(release): publish new version
- @standardnotes/api-gateway@1.77.0
 - @standardnotes/auth-server@1.151.0
 - @standardnotes/home-server@1.16.28
2023-10-05 14:42:25 +00:00
Karol Sójko
3ee49416f8 feat: setting xray segment user on api-gateway level 2023-10-05 16:25:09 +02:00
119 changed files with 1293 additions and 472 deletions

17
.pnp.cjs generated
View File

@@ -5740,6 +5740,7 @@ const RAW_RUNTIME_STATE =
["@types/node", "npm:20.5.7"],\
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\
["@typescript-eslint/parser", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\
["aws-xray-sdk", "npm:3.5.2"],\
["dayjs", "npm:1.11.7"],\
["dotenv", "npm:16.1.3"],\
["eslint", "npm:8.41.0"],\
@@ -5972,7 +5973,7 @@ const RAW_RUNTIME_STATE =
["newrelic", "npm:11.0.0"],\
["prettier", "npm:3.0.3"],\
["reflect-metadata", "npm:0.1.13"],\
["sqs-consumer", "virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:6.2.1"],\
["sqs-consumer", "virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:7.3.0"],\
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.0"],\
["typescript", "patch:typescript@npm%3A5.0.4#optional!builtin<compat/typescript>::version=5.0.4&hash=b5f058"],\
["winston", "npm:3.9.0"]\
@@ -6235,6 +6236,7 @@ const RAW_RUNTIME_STATE =
["@types/node", "npm:20.5.7"],\
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\
["@typescript-eslint/parser", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\
["aws-xray-sdk", "npm:3.5.2"],\
["dayjs", "npm:1.11.7"],\
["dotenv", "npm:16.1.3"],\
["eslint", "npm:8.41.0"],\
@@ -6472,6 +6474,7 @@ const RAW_RUNTIME_STATE =
["@types/newrelic", "npm:9.14.0"],\
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\
["@typescript-eslint/parser", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\
["aws-xray-sdk", "npm:3.5.2"],\
["axios", "npm:1.4.0"],\
["cors", "npm:2.8.5"],\
["dotenv", "npm:16.1.3"],\
@@ -16074,17 +16077,17 @@ const RAW_RUNTIME_STATE =
}]\
]],\
["sqs-consumer", [\
["npm:6.2.1", {\
"packageLocation": "./.yarn/cache/sqs-consumer-npm-6.2.1-857abd3d30-a903daa836.zip/node_modules/sqs-consumer/",\
["npm:7.3.0", {\
"packageLocation": "./.yarn/cache/sqs-consumer-npm-7.3.0-a47c08ef71-367ea2a6f3.zip/node_modules/sqs-consumer/",\
"packageDependencies": [\
["sqs-consumer", "npm:6.2.1"]\
["sqs-consumer", "npm:7.3.0"]\
],\
"linkType": "SOFT"\
}],\
["virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:6.2.1", {\
"packageLocation": "./.yarn/__virtual__/sqs-consumer-virtual-603a7c5831/0/cache/sqs-consumer-npm-6.2.1-857abd3d30-a903daa836.zip/node_modules/sqs-consumer/",\
["virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:7.3.0", {\
"packageLocation": "./.yarn/__virtual__/sqs-consumer-virtual-bf07118bf0/0/cache/sqs-consumer-npm-7.3.0-a47c08ef71-367ea2a6f3.zip/node_modules/sqs-consumer/",\
"packageDependencies": [\
["sqs-consumer", "virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:6.2.1"],\
["sqs-consumer", "virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:7.3.0"],\
["@aws-sdk/client-sqs", "npm:3.342.0"],\
["@types/aws-sdk__client-sqs", null],\
["debug", "virtual:ac3d8e680759ce54399273724d44e041d6c9b73454d191d411a8c44bb27e22f02aaf6ed9d3ad0ac1c298eac4833cff369c9c7b84c573016112c4f84be2cd8543#npm:4.3.4"]\

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.28.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.28.0...@standardnotes/analytics@2.28.1) (2023-10-06)
### Bug Fixes
* add xray-sdk to background processors ([a45b5b6](https://github.com/standardnotes/server/commit/a45b5b69b5d68c2e696c30f0ba5ad22d313321e6))
# [2.28.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.27.10...@standardnotes/analytics@2.28.0) (2023-10-06)
### Features
* add xray to analytics scheduler and websockets ([f0531d6](https://github.com/standardnotes/server/commit/f0531d68cb77036222f2a34602819f11e6a2697d))
## [2.27.10](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.27.9...@standardnotes/analytics@2.27.10) (2023-10-05)
**Note:** Version bump only for package @standardnotes/analytics

View File

@@ -1,6 +1,7 @@
import 'reflect-metadata'
import { Logger } from 'winston'
import * as AWSXRay from 'aws-xray-sdk'
import { EmailLevel } from '@standardnotes/domain-core'
import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
@@ -253,6 +254,14 @@ void container.load().then((container) => {
const env: Env = new Env()
env.load()
const isConfiguredForAWSProduction =
env.get('MODE', true) !== 'home-server' && env.get('MODE', true) !== 'self-hosted'
if (isConfiguredForAWSProduction) {
AWSXRay.enableManualMode()
AWSXRay.config([AWSXRay.plugins.ECSPlugin])
}
const logger: Logger = container.get(TYPES.Logger)
logger.info('Starting usage report generation...')

View File

@@ -1,6 +1,7 @@
import 'reflect-metadata'
import { Logger } from 'winston'
import * as AWSXRay from 'aws-xray-sdk'
import { DomainEventSubscriberFactoryInterface } from '@standardnotes/domain-events'
import * as dayjs from 'dayjs'
import * as utc from 'dayjs/plugin/utc'
@@ -16,6 +17,14 @@ void container.load().then((container) => {
const env: Env = new Env()
env.load()
const isConfiguredForAWSProduction =
env.get('MODE', true) !== 'home-server' && env.get('MODE', true) !== 'self-hosted'
if (isConfiguredForAWSProduction) {
AWSXRay.enableManualMode()
AWSXRay.config([AWSXRay.plugins.ECSPlugin])
}
const logger: Logger = container.get(TYPES.Logger)
logger.info('Starting worker...')

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/analytics",
"version": "2.27.10",
"version": "2.28.1",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
@@ -46,6 +46,7 @@
"@standardnotes/domain-events": "workspace:*",
"@standardnotes/domain-events-infra": "workspace:*",
"@standardnotes/time": "workspace:*",
"aws-xray-sdk": "^3.5.2",
"dayjs": "^1.11.6",
"dotenv": "^16.0.1",
"inversify": "^6.0.1",

View File

@@ -6,7 +6,7 @@ import {
DomainEventMessageHandlerInterface,
DomainEventSubscriberFactoryInterface,
} 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')
@@ -18,7 +18,7 @@ import {
SNSDomainEventPublisher,
SQSDomainEventSubscriberFactory,
SQSEventMessageHandler,
SQSNewRelicEventMessageHandler,
SQSXRayEventMessageHandler,
} from '@standardnotes/domain-events-infra'
import { Timer, TimerInterface } from '@standardnotes/time'
import { PeriodKeyGeneratorInterface } from '../Domain/Time/PeriodKeyGeneratorInterface'
@@ -57,6 +57,7 @@ import { SNSClient, SNSClientConfig } from '@aws-sdk/client-sns'
import { SQSClient, SQSClientConfig } from '@aws-sdk/client-sqs'
import { SessionCreatedEventHandler } from '../Domain/Handler/SessionCreatedEventHandler'
import { SessionRefreshedEventHandler } from '../Domain/Handler/SessionRefreshedEventHandler'
import { captureAWSv3Client } from 'aws-xray-sdk'
export class ContainerConfigLoader {
async load(): Promise<Container> {
@@ -107,7 +108,7 @@ export class ContainerConfigLoader {
secretAccessKey: env.get('SNS_SECRET_ACCESS_KEY', true),
}
}
container.bind<SNSClient>(TYPES.SNS).toConstantValue(new SNSClient(snsConfig))
container.bind<SNSClient>(TYPES.SNS).toConstantValue(captureAWSv3Client(new SNSClient(snsConfig)))
if (env.get('SQS_QUEUE_URL', true)) {
const sqsConfig: SQSClientConfig = {
@@ -122,7 +123,7 @@ export class ContainerConfigLoader {
secretAccessKey: env.get('SQS_SECRET_ACCESS_KEY', true),
}
}
container.bind<SQSClient>(TYPES.SQS).toConstantValue(new SQSClient(sqsConfig))
container.bind<SQSClient>(TYPES.SQS).toConstantValue(captureAWSv3Client(new SQSClient(sqsConfig)))
}
// env vars
@@ -246,7 +247,11 @@ export class ContainerConfigLoader {
.bind<DomainEventMessageHandlerInterface>(TYPES.DomainEventMessageHandler)
.toConstantValue(
env.get('NEW_RELIC_ENABLED', true) === 'true'
? new SQSNewRelicEventMessageHandler(eventHandlers, container.get(TYPES.Logger))
? new SQSXRayEventMessageHandler(
ServiceIdentifier.NAMES.AnalyticsWorker,
eventHandlers,
container.get(TYPES.Logger),
)
: new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Logger)),
)
container

View File

@@ -3,6 +3,16 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.77.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.77.0...@standardnotes/api-gateway@1.77.1) (2023-10-06)
**Note:** Version bump only for package @standardnotes/api-gateway
# [1.77.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.76.2...@standardnotes/api-gateway@1.77.0) (2023-10-05)
### Features
* setting xray segment user on api-gateway level ([3ee4941](https://github.com/standardnotes/api-gateway/commit/3ee49416f8e19207540141d98baa7f68880929bd))
## [1.76.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.76.1...@standardnotes/api-gateway@1.76.2) (2023-10-05)
**Note:** Version bump only for package @standardnotes/api-gateway

View File

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

View File

@@ -35,6 +35,8 @@ export class ContainerConfigLoader {
const container = new Container()
const isConfiguredForHomeServer = env.get('MODE', true) === 'home-server'
const isConfiguredForSelfHosting = env.get('MODE', true) === 'self-hosted'
const isConfiguredForAWSProduction = !isConfiguredForHomeServer && !isConfiguredForSelfHosting
const isConfiguredForInMemoryCache = env.get('CACHE_TYPE', true) === 'memory'
const winstonFormatters = [winston.format.splat(), winston.format.json()]
@@ -90,6 +92,9 @@ export class ContainerConfigLoader {
.bind(TYPES.ApiGateway_CROSS_SERVICE_TOKEN_CACHE_TTL)
.toConstantValue(+env.get('CROSS_SERVICE_TOKEN_CACHE_TTL', true))
container.bind(TYPES.ApiGateway_IS_CONFIGURED_FOR_HOME_SERVER).toConstantValue(isConfiguredForHomeServer)
container
.bind<boolean>(TYPES.ApiGateway_IS_CONFIGURED_FOR_AWS_PRODUCTION)
.toConstantValue(isConfiguredForAWSProduction)
// Middleware
container

View File

@@ -15,6 +15,7 @@ export const TYPES = {
ApiGateway_VERSION: Symbol.for('ApiGateway_VERSION'),
ApiGateway_CROSS_SERVICE_TOKEN_CACHE_TTL: Symbol.for('ApiGateway_CROSS_SERVICE_TOKEN_CACHE_TTL'),
ApiGateway_IS_CONFIGURED_FOR_HOME_SERVER: Symbol.for('ApiGateway_IS_CONFIGURED_FOR_HOME_SERVER'),
ApiGateway_IS_CONFIGURED_FOR_AWS_PRODUCTION: Symbol.for('ApiGateway_IS_CONFIGURED_FOR_AWS_PRODUCTION'),
// Middleware
ApiGateway_RequiredCrossServiceTokenMiddleware: Symbol.for('ApiGateway_RequiredCrossServiceTokenMiddleware'),
ApiGateway_OptionalCrossServiceTokenMiddleware: Symbol.for('ApiGateway_OptionalCrossServiceTokenMiddleware'),

View File

@@ -8,6 +8,7 @@ import { Logger } from 'winston'
import { CrossServiceTokenCacheInterface } from '../Service/Cache/CrossServiceTokenCacheInterface'
import { ServiceProxyInterface } from '../Service/Http/ServiceProxyInterface'
import { Segment, getSegment } from 'aws-xray-sdk'
export abstract class AuthMiddleware extends BaseMiddleware {
constructor(
@@ -16,6 +17,7 @@ export abstract class AuthMiddleware extends BaseMiddleware {
private crossServiceTokenCacheTTL: number,
private crossServiceTokenCache: CrossServiceTokenCacheInterface,
private timer: TimerInterface,
private isConfiguredForAWSProduction: boolean,
protected logger: Logger,
) {
super()
@@ -73,6 +75,13 @@ export abstract class AuthMiddleware extends BaseMiddleware {
response.locals.roles = decodedToken.roles
response.locals.sharedVaultOwnerContext = decodedToken.shared_vault_owner_context
response.locals.belongsToSharedVaults = decodedToken.belongs_to_shared_vaults ?? []
if (this.isConfiguredForAWSProduction) {
const segment = getSegment()
if (segment instanceof Segment) {
segment.setUser(decodedToken.user.uuid)
}
}
} catch (error) {
const errorMessage = (error as AxiosError).isAxiosError
? JSON.stringify((error as AxiosError).response?.data)

View File

@@ -16,9 +16,18 @@ export class OptionalCrossServiceTokenMiddleware extends AuthMiddleware {
@inject(TYPES.ApiGateway_CROSS_SERVICE_TOKEN_CACHE_TTL) crossServiceTokenCacheTTL: number,
@inject(TYPES.ApiGateway_CrossServiceTokenCache) crossServiceTokenCache: CrossServiceTokenCacheInterface,
@inject(TYPES.ApiGateway_Timer) timer: TimerInterface,
@inject(TYPES.ApiGateway_IS_CONFIGURED_FOR_AWS_PRODUCTION) isConfiguredForAWSProduction: boolean,
@inject(TYPES.ApiGateway_Logger) logger: Logger,
) {
super(serviceProxy, jwtSecret, crossServiceTokenCacheTTL, crossServiceTokenCache, timer, logger)
super(
serviceProxy,
jwtSecret,
crossServiceTokenCacheTTL,
crossServiceTokenCache,
timer,
isConfiguredForAWSProduction,
logger,
)
}
protected override handleSessionValidationResponse(

View File

@@ -16,9 +16,18 @@ export class RequiredCrossServiceTokenMiddleware extends AuthMiddleware {
@inject(TYPES.ApiGateway_CROSS_SERVICE_TOKEN_CACHE_TTL) crossServiceTokenCacheTTL: number,
@inject(TYPES.ApiGateway_CrossServiceTokenCache) crossServiceTokenCache: CrossServiceTokenCacheInterface,
@inject(TYPES.ApiGateway_Timer) timer: TimerInterface,
@inject(TYPES.ApiGateway_IS_CONFIGURED_FOR_AWS_PRODUCTION) isConfiguredForAWSProduction: boolean,
@inject(TYPES.ApiGateway_Logger) logger: Logger,
) {
super(serviceProxy, jwtSecret, crossServiceTokenCacheTTL, crossServiceTokenCache, timer, logger)
super(
serviceProxy,
jwtSecret,
crossServiceTokenCacheTTL,
crossServiceTokenCache,
timer,
isConfiguredForAWSProduction,
logger,
)
}
protected override handleSessionValidationResponse(

View File

@@ -3,6 +3,38 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.152.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.152.0...@standardnotes/auth-server@1.152.1) (2023-10-06)
### Bug Fixes
* **auth:** checking for transition role when triggering transition ([79a44aa](https://github.com/standardnotes/server/commit/79a44aa51f15311fcaf76c39f93d1934ec1d135d))
# [1.152.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.151.2...@standardnotes/auth-server@1.152.0) (2023-10-06)
### Bug Fixes
* **auth:** strip user from transition role after migration ([afe9967](https://github.com/standardnotes/server/commit/afe9967d26b5be02d1dc76a740df614d81a6984e))
### Features
* switch transition direction ([27bea44](https://github.com/standardnotes/server/commit/27bea444cce4964feda04bad64e5f12a07415e0c))
## [1.151.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.151.1...@standardnotes/auth-server@1.151.2) (2023-10-06)
### Bug Fixes
* add xray-sdk to background processors ([a45b5b6](https://github.com/standardnotes/server/commit/a45b5b69b5d68c2e696c30f0ba5ad22d313321e6))
## [1.151.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.151.0...@standardnotes/auth-server@1.151.1) (2023-10-06)
**Note:** Version bump only for package @standardnotes/auth-server
# [1.151.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.150.9...@standardnotes/auth-server@1.151.0) (2023-10-05)
### Features
* setting xray segment user on api-gateway level ([3ee4941](https://github.com/standardnotes/server/commit/3ee49416f8e19207540141d98baa7f68880929bd))
## [1.150.9](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.150.8...@standardnotes/auth-server@1.150.9) (2023-10-05)
**Note:** Version bump only for package @standardnotes/auth-server

View File

@@ -5,6 +5,7 @@ import { Stream } from 'stream'
import { Logger } from 'winston'
import * as dayjs from 'dayjs'
import * as utc from 'dayjs/plugin/utc'
import * as AWSXRay from 'aws-xray-sdk'
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
import TYPES from '../src/Bootstrap/Types'
@@ -82,6 +83,14 @@ void container.load().then((container) => {
const env: Env = new Env()
env.load()
const isConfiguredForAWSProduction =
env.get('MODE', true) !== 'home-server' && env.get('MODE', true) !== 'self-hosted'
if (isConfiguredForAWSProduction) {
AWSXRay.enableManualMode()
AWSXRay.config([AWSXRay.plugins.ECSPlugin])
}
const logger: Logger = container.get(TYPES.Auth_Logger)
logger.info(`Starting ${backupFrequency} ${backupProvider} backup requesting...`)

View File

@@ -1,6 +1,7 @@
import 'reflect-metadata'
import { Logger } from 'winston'
import * as AWSXRay from 'aws-xray-sdk'
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
import TYPES from '../src/Bootstrap/Types'
@@ -23,6 +24,14 @@ void container.load().then((container) => {
const env: Env = new Env()
env.load()
const isConfiguredForAWSProduction =
env.get('MODE', true) !== 'home-server' && env.get('MODE', true) !== 'self-hosted'
if (isConfiguredForAWSProduction) {
AWSXRay.enableManualMode()
AWSXRay.config([AWSXRay.plugins.ECSPlugin])
}
const logger: Logger = container.get(TYPES.Auth_Logger)
logger.info('Starting sessions and session traces cleanup')

View File

@@ -2,6 +2,7 @@ import 'reflect-metadata'
import { Logger } from 'winston'
import { TimerInterface } from '@standardnotes/time'
import * as AWSXRay from 'aws-xray-sdk'
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
import TYPES from '../src/Bootstrap/Types'
@@ -13,6 +14,14 @@ void container.load().then((container) => {
const env: Env = new Env()
env.load()
const isConfiguredForAWSProduction =
env.get('MODE', true) !== 'home-server' && env.get('MODE', true) !== 'self-hosted'
if (isConfiguredForAWSProduction) {
AWSXRay.enableManualMode()
AWSXRay.config([AWSXRay.plugins.ECSPlugin])
}
const logger: Logger = container.get(TYPES.Auth_Logger)
logger.info('Starting session traces cleanup')

View File

@@ -3,6 +3,7 @@ import 'reflect-metadata'
import { Logger } from 'winston'
import * as dayjs from 'dayjs'
import * as utc from 'dayjs/plugin/utc'
import * as AWSXRay from 'aws-xray-sdk'
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
import TYPES from '../src/Bootstrap/Types'
@@ -49,7 +50,7 @@ const requestTransition = async (
itemsTransitionStatus?.value === TransitionStatus.STATUSES.Verified &&
revisionsTransitionStatus?.value === TransitionStatus.STATUSES.Verified
if (userHasTransitionRole && bothTransitionStatusesAreVerified) {
if (!userHasTransitionRole && bothTransitionStatusesAreVerified) {
continue
}
@@ -102,6 +103,14 @@ void container.load().then((container) => {
const env: Env = new Env()
env.load()
const isConfiguredForAWSProduction =
env.get('MODE', true) !== 'home-server' && env.get('MODE', true) !== 'self-hosted'
if (isConfiguredForAWSProduction) {
AWSXRay.enableManualMode()
AWSXRay.config([AWSXRay.plugins.ECSPlugin])
}
const logger: Logger = container.get(TYPES.Auth_Logger)
logger.info(`Starting transition request for users created between ${startDateString} and ${endDateString}`)

View File

@@ -3,6 +3,7 @@ import 'reflect-metadata'
import { Logger } from 'winston'
import * as dayjs from 'dayjs'
import * as utc from 'dayjs/plugin/utc'
import * as AWSXRay from 'aws-xray-sdk'
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
import TYPES from '../src/Bootstrap/Types'
@@ -70,6 +71,14 @@ void container.load().then((container) => {
const env: Env = new Env()
env.load()
const isConfiguredForAWSProduction =
env.get('MODE', true) !== 'home-server' && env.get('MODE', true) !== 'self-hosted'
if (isConfiguredForAWSProduction) {
AWSXRay.enableManualMode()
AWSXRay.config([AWSXRay.plugins.ECSPlugin])
}
const logger: Logger = container.get(TYPES.Auth_Logger)
logger.info(`Starting email backup requesting for ${backupEmail} ...`)

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/auth-server",
"version": "1.150.9",
"version": "1.152.1",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -747,7 +747,6 @@ export class ContainerConfigLoader {
.toConstantValue(
new RequiredCrossServiceTokenMiddleware(
container.get<TokenDecoderInterface<CrossServiceTokenData>>(TYPES.Auth_CrossServiceTokenDecoder),
isConfiguredForAWSProduction && this.mode === 'server',
container.get<winston.Logger>(TYPES.Auth_Logger),
),
)
@@ -756,7 +755,6 @@ export class ContainerConfigLoader {
.toConstantValue(
new OptionalCrossServiceTokenMiddleware(
container.get<TokenDecoderInterface<CrossServiceTokenData>>(TYPES.Auth_CrossServiceTokenDecoder),
isConfiguredForAWSProduction && this.mode === 'server',
container.get<winston.Logger>(TYPES.Auth_Logger),
),
)

View File

@@ -118,6 +118,40 @@ describe('RoleService', () => {
})
})
describe('removing roles', () => {
beforeEach(() => {
user = {
uuid: '123',
email: 'test@test.com',
roles: Promise.resolve([basicRole]),
} as jest.Mocked<User>
userRepository.findOneByUuid = jest.fn().mockReturnValue(user)
userRepository.save = jest.fn().mockReturnValue(user)
})
it('should remove a role from a user', async () => {
await createService().removeRoleFromUser(
Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
RoleName.create(RoleName.NAMES.CoreUser).getValue(),
)
user.roles = Promise.resolve([])
expect(userRepository.save).toHaveBeenCalledWith(user)
})
it('should not remove a role from a user if the user could not be found', async () => {
userRepository.findOneByUuid = jest.fn().mockReturnValue(null)
await createService().removeRoleFromUser(
Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
RoleName.create(RoleName.NAMES.CoreUser).getValue(),
)
expect(userRepository.save).not.toHaveBeenCalled()
})
})
describe('adding roles based on subscription', () => {
beforeEach(() => {
user = {

View File

@@ -65,6 +65,17 @@ export class RoleService implements RoleServiceInterface {
await this.addToExistingRoles(user, roleName.value)
}
async removeRoleFromUser(userUuid: Uuid, roleName: RoleName): Promise<void> {
const user = await this.userRepository.findOneByUuid(userUuid)
if (user === null) {
this.logger.error(`Could not find user with uuid ${userUuid.value} to remove role ${roleName.value}`)
return
}
await this.removeUserRole(user, roleName.value)
}
async addUserRoleBasedOnSubscription(user: User, subscriptionName: SubscriptionName): Promise<void> {
const roleName = this.roleToSubscriptionMap.getRoleNameForSubscriptionName(subscriptionName)
@@ -108,9 +119,15 @@ export class RoleService implements RoleServiceInterface {
return
}
await this.removeUserRole(user, roleName)
}
private async removeUserRole(user: User, roleName: string): Promise<void> {
const currentRoles = await user.roles
user.roles = Promise.resolve(currentRoles.filter((role) => role.name !== roleName))
await this.userRepository.save(user)
await this.webSocketsClientService.sendUserRolesChangedEvent(user)
}

View File

@@ -5,6 +5,7 @@ import { User } from '../User/User'
export interface RoleServiceInterface {
addRoleToUser(userUuid: Uuid, roleName: RoleName): Promise<void>
removeRoleFromUser(userUuid: Uuid, roleName: RoleName): Promise<void>
addUserRoleBasedOnSubscription(user: User, subscriptionName: string): Promise<void>
setOfflineUserRole(offlineUserSubscription: OfflineUserSubscription): Promise<void>
removeUserRoleBasedOnSubscription(user: User, subscriptionName: string): Promise<void>

View File

@@ -21,7 +21,7 @@ describe('UpdateTransitionStatus', () => {
transitionStatusRepository.getStatus = jest.fn().mockResolvedValue(null)
roleService = {} as jest.Mocked<RoleServiceInterface>
roleService.addRoleToUser = jest.fn()
roleService.removeRoleFromUser = jest.fn()
})
it('should add TRANSITION_USER role', async () => {
@@ -35,7 +35,7 @@ describe('UpdateTransitionStatus', () => {
})
expect(result.isFailed()).toBeFalsy()
expect(roleService.addRoleToUser).toHaveBeenCalledWith(
expect(roleService.removeRoleFromUser).toHaveBeenCalledWith(
Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
RoleName.create(RoleName.NAMES.TransitionUser).getValue(),
)

View File

@@ -32,7 +32,7 @@ export class UpdateTransitionStatus implements UseCaseInterface<void> {
await this.transitionStatusRepository.updateStatus(dto.userUuid, dto.transitionType, transitionStatus)
if (dto.transitionType === 'items' && transitionStatus.value === TransitionStatus.STATUSES.Verified) {
await this.roleService.addRoleToUser(userUuid, RoleName.create(RoleName.NAMES.TransitionUser).getValue())
await this.roleService.removeRoleFromUser(userUuid, RoleName.create(RoleName.NAMES.TransitionUser).getValue())
}
return Result.ok()

View File

@@ -2,12 +2,10 @@ import { CrossServiceTokenData, TokenDecoderInterface } from '@standardnotes/sec
import { NextFunction, Request, Response } from 'express'
import { BaseMiddleware } from 'inversify-express-utils'
import { Logger } from 'winston'
import { Segment, getSegment } from 'aws-xray-sdk'
export abstract class ApiGatewayAuthMiddleware extends BaseMiddleware {
constructor(
private tokenDecoder: TokenDecoderInterface<CrossServiceTokenData>,
private isConfiguredForAWSProduction: boolean,
private logger: Logger,
) {
super()
@@ -41,13 +39,6 @@ export abstract class ApiGatewayAuthMiddleware extends BaseMiddleware {
response.locals.session = token.session
response.locals.readOnlyAccess = token.session?.readonly_access ?? false
if (this.isConfiguredForAWSProduction) {
const segment = getSegment()
if (segment instanceof Segment) {
segment.setUser(token.user.uuid)
}
}
return next()
} catch (error) {
return next(error)

View File

@@ -5,12 +5,8 @@ import { Logger } from 'winston'
import { ApiGatewayAuthMiddleware } from './ApiGatewayAuthMiddleware'
export class OptionalCrossServiceTokenMiddleware extends ApiGatewayAuthMiddleware {
constructor(
tokenDecoder: TokenDecoderInterface<CrossServiceTokenData>,
isConfiguredForAWSProduction: boolean,
logger: Logger,
) {
super(tokenDecoder, isConfiguredForAWSProduction, logger)
constructor(tokenDecoder: TokenDecoderInterface<CrossServiceTokenData>, logger: Logger) {
super(tokenDecoder, logger)
}
protected override handleMissingToken(request: Request, _response: Response, next: NextFunction): boolean {

View File

@@ -5,12 +5,8 @@ import { Logger } from 'winston'
import { ApiGatewayAuthMiddleware } from './ApiGatewayAuthMiddleware'
export class RequiredCrossServiceTokenMiddleware extends ApiGatewayAuthMiddleware {
constructor(
tokenDecoder: TokenDecoderInterface<CrossServiceTokenData>,
isConfiguredForAWSProduction: boolean,
logger: Logger,
) {
super(tokenDecoder, isConfiguredForAWSProduction, logger)
constructor(tokenDecoder: TokenDecoderInterface<CrossServiceTokenData>, logger: Logger) {
super(tokenDecoder, logger)
}
protected override handleMissingToken(request: Request, response: Response, _next: NextFunction): boolean {

View File

@@ -4,7 +4,7 @@ import { TransitionStatusRepositoryInterface } from '../../Domain/Transition/Tra
import { TransitionStatus } from '@standardnotes/domain-core'
export class RedisTransitionStatusRepository implements TransitionStatusRepositoryInterface {
private readonly PREFIX = 'transition'
private readonly PREFIX = 'transition-back'
constructor(private redisClient: IORedis.Redis) {}

View File

@@ -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.35.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.34.2...@standardnotes/domain-core@1.35.0) (2023-10-06)
### Features
* add xray to analytics scheduler and websockets ([f0531d6](https://github.com/standardnotes/server/commit/f0531d68cb77036222f2a34602819f11e6a2697d))
## [1.34.2](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.34.1...@standardnotes/domain-core@1.34.2) (2023-10-04)
### Bug Fixes

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/domain-core",
"version": "1.34.2",
"version": "1.35.0",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -4,6 +4,7 @@ import { ServiceIdentifierProps } from './ServiceIdentifierProps'
export class ServiceIdentifier extends ValueObject<ServiceIdentifierProps> {
static readonly NAMES = {
AnalyticsWorker: 'AnalyticsWorker',
ApiGateway: 'ApiGateway',
Auth: 'Auth',
AuthWorker: 'AuthWorker',
@@ -13,6 +14,11 @@ export class ServiceIdentifier extends ValueObject<ServiceIdentifierProps> {
RevisionsWorker: 'RevisionsWorker',
Files: 'Files',
FilesWorker: 'FilesWorker',
SchedulerWorker: 'SchedulerWorker',
Email: 'Email',
EmailWorker: 'EmailWorker',
Websockets: 'Websockets',
WebsocketsWorker: 'WebsocketsWorker',
}
get value(): string {

View File

@@ -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.14.8](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.14.7...@standardnotes/domain-events-infra@1.14.8) (2023-10-06)
**Note:** Version bump only for package @standardnotes/domain-events-infra
## [1.14.7](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.14.6...@standardnotes/domain-events-infra@1.14.7) (2023-10-05)
### Reverts

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/domain-events-infra",
"version": "1.14.7",
"version": "1.14.8",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
@@ -30,7 +30,7 @@
"aws-xray-sdk": "^3.5.2",
"ioredis": "^5.2.4",
"reflect-metadata": "^0.1.13",
"sqs-consumer": "^6.2.1",
"sqs-consumer": "^7.3.0",
"winston": "^3.8.1"
},
"devDependencies": {

View File

@@ -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.12.11](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.12.10...@standardnotes/event-store@1.12.11) (2023-10-06)
**Note:** Version bump only for package @standardnotes/event-store
## [1.12.10](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.12.9...@standardnotes/event-store@1.12.10) (2023-10-05)
**Note:** Version bump only for package @standardnotes/event-store

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/event-store",
"version": "1.12.10",
"version": "1.12.11",
"description": "Event Store Service",
"private": true,
"main": "dist/src/index.js",

View File

@@ -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.26.3](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.26.2...@standardnotes/files-server@1.26.3) (2023-10-06)
**Note:** Version bump only for package @standardnotes/files-server
## [1.26.2](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.26.1...@standardnotes/files-server@1.26.2) (2023-10-05)
**Note:** Version bump only for package @standardnotes/files-server

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/files-server",
"version": "1.26.2",
"version": "1.26.3",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.16.33](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.16.32...@standardnotes/home-server@1.16.33) (2023-10-06)
**Note:** Version bump only for package @standardnotes/home-server
## [1.16.32](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.16.31...@standardnotes/home-server@1.16.32) (2023-10-06)
**Note:** Version bump only for package @standardnotes/home-server
## [1.16.31](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.16.30...@standardnotes/home-server@1.16.31) (2023-10-06)
**Note:** Version bump only for package @standardnotes/home-server
## [1.16.30](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.16.29...@standardnotes/home-server@1.16.30) (2023-10-06)
**Note:** Version bump only for package @standardnotes/home-server
## [1.16.29](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.16.28...@standardnotes/home-server@1.16.29) (2023-10-06)
**Note:** Version bump only for package @standardnotes/home-server
## [1.16.28](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.16.27...@standardnotes/home-server@1.16.28) (2023-10-05)
**Note:** Version bump only for package @standardnotes/home-server
## [1.16.27](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.16.26...@standardnotes/home-server@1.16.27) (2023-10-05)
**Note:** Version bump only for package @standardnotes/home-server

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/home-server",
"version": "1.16.27",
"version": "1.16.33",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -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.40.1](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.40.0...@standardnotes/revisions-server@1.40.1) (2023-10-06)
### Bug Fixes
* **revisions:** casting creation date from MongoDB ([4780629](https://github.com/standardnotes/server/commit/47806295491867ca5fd53e39757f057a0722ae28))
# [1.40.0](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.39.5...@standardnotes/revisions-server@1.40.0) (2023-10-06)
### Bug Fixes
* enable TransitionRequestedEventHandler ([d8f1c66](https://github.com/standardnotes/server/commit/d8f1c66fd5e59285ccaa1be36da2ee9796b81ccb))
### Features
* switch transition direction ([27bea44](https://github.com/standardnotes/server/commit/27bea444cce4964feda04bad64e5f12a07415e0c))
## [1.39.5](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.39.4...@standardnotes/revisions-server@1.39.5) (2023-10-06)
**Note:** Version bump only for package @standardnotes/revisions-server
## [1.39.4](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.39.3...@standardnotes/revisions-server@1.39.4) (2023-10-05)
### Bug Fixes

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/revisions-server",
"version": "1.39.4",
"version": "1.40.1",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -268,7 +268,7 @@ export class ContainerConfigLoader {
.toConstantValue(new MongoDBRevisionMetadataPersistenceMapper())
container
.bind<MapperInterface<Revision, MongoDBRevision>>(TYPES.Revisions_MongoDBRevisionPersistenceMapper)
.toConstantValue(new MongoDBRevisionPersistenceMapper())
.toConstantValue(new MongoDBRevisionPersistenceMapper(container.get<TimerInterface>(TYPES.Revisions_Timer)))
// ORM
container
@@ -491,7 +491,7 @@ export class ContainerConfigLoader {
.bind<TransitionRequestedEventHandler>(TYPES.Revisions_TransitionRequestedEventHandler)
.toConstantValue(
new TransitionRequestedEventHandler(
true,
false,
container.get<TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser>(
TYPES.Revisions_TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser,
),

View File

@@ -61,7 +61,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
this.logger.info(`[${dto.userUuid}] Revisions migrated`)
await this.allowForSecondaryDatabaseToCatchUp()
await this.allowForPrimaryDatabaseToCatchUp()
this.logger.info(`[${dto.userUuid}] Checking integrity between primary and secondary database`)
@@ -75,11 +75,16 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
return Result.fail(integrityCheckResult.getError())
}
const cleanupResult = await this.deleteRevisionsForUser(userUuid, this.primaryRevisionsRepository)
const cleanupResult = await this.deleteRevisionsForUser(
userUuid,
this.secondRevisionsRepository as RevisionRepositoryInterface,
)
if (cleanupResult.isFailed()) {
await this.updateTransitionStatus(userUuid, TransitionStatus.STATUSES.Failed, dto.timestamp)
this.logger.error(`[${dto.userUuid}] Failed to clean up primary database revisions: ${cleanupResult.getError()}`)
this.logger.error(
`[${dto.userUuid}] Failed to clean up secondary database revisions: ${cleanupResult.getError()}`,
)
}
const migrationTimeEnd = this.timer.getTimestampInMicroseconds()
@@ -104,7 +109,9 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
this.logger.info(`[${userUuid.value}] Migrating from page ${initialPage}`)
const totalRevisionsCountForUser = await this.primaryRevisionsRepository.countByUserUuid(userUuid)
const totalRevisionsCountForUser = await (
this.secondRevisionsRepository as RevisionRepositoryInterface
).countByUserUuid(userUuid)
const totalPages = Math.ceil(totalRevisionsCountForUser / this.pageSize)
for (let currentPage = initialPage; currentPage <= totalPages; currentPage++) {
const isPageInEvery10Percent = currentPage % Math.ceil(totalPages / 10) === 0
@@ -128,47 +135,49 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
limit: this.pageSize,
}
const revisions = await this.primaryRevisionsRepository.findByUserUuid(query)
const revisions = await (this.secondRevisionsRepository as RevisionRepositoryInterface).findByUserUuid(query)
for (const revision of revisions) {
try {
const revisionInSecondary = await (
this.secondRevisionsRepository as RevisionRepositoryInterface
).findOneByUuid(Uuid.create(revision.id.toString()).getValue(), revision.props.userUuid as Uuid, [])
const revisionInPrimary = await this.primaryRevisionsRepository.findOneByUuid(
Uuid.create(revision.id.toString()).getValue(),
revision.props.userUuid as Uuid,
[],
)
if (revisionInSecondary !== null) {
if (revisionInSecondary.isIdenticalTo(revision)) {
continue
}
if (revisionInSecondary.props.dates.updatedAt > revision.props.dates.updatedAt) {
if (revisionInPrimary !== null) {
if (revisionInPrimary.props.dates.updatedAt > revision.props.dates.updatedAt) {
this.logger.info(
`[${userUuid.value}] Revision ${revision.id.toString()} is older than revision in secondary database`,
`[${
userUuid.value
}] Revision ${revision.id.toString()} is older in secondary than revision in primary database`,
)
continue
}
if (revisionInPrimary.isIdenticalTo(revision)) {
continue
}
this.logger.info(
`[${
userUuid.value
}] Removing revision ${revision.id.toString()} in secondary database as it is not identical to revision in primary database`,
}] Removing revision ${revision.id.toString()} in primary database as it is not identical to revision in secondary database`,
)
await (this.secondRevisionsRepository as RevisionRepositoryInterface).removeOneByUuid(
Uuid.create(revisionInSecondary.id.toString()).getValue(),
revisionInSecondary.props.userUuid as Uuid,
await this.primaryRevisionsRepository.removeOneByUuid(
Uuid.create(revisionInPrimary.id.toString()).getValue(),
revisionInPrimary.props.userUuid as Uuid,
)
await this.allowForSecondaryDatabaseToCatchUp()
await this.allowForPrimaryDatabaseToCatchUp()
}
const didSave = await (this.secondRevisionsRepository as RevisionRepositoryInterface).insert(revision)
const didSave = await this.primaryRevisionsRepository.insert(revision)
if (!didSave) {
this.logger.error(`Failed to save revision ${revision.id.toString()} to secondary database`)
this.logger.error(`Failed to save revision ${revision.id.toString()} to primary database`)
}
} catch (error) {
this.logger.error(
`Errored when saving revision ${revision.id.toString()} to secondary database: ${
(error as Error).message
}`,
`Errored when saving revision ${revision.id.toString()} to primary database: ${(error as Error).message}`,
)
}
}
@@ -185,7 +194,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
revisionRepository: RevisionRepositoryInterface,
): Promise<Result<void>> {
try {
this.logger.info(`[${userUuid.value}] Deleting all revisions from primary database`)
this.logger.info(`[${userUuid.value}] Deleting all revisions from secondary database`)
await revisionRepository.removeByUserUuid(userUuid)
@@ -195,7 +204,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
}
}
private async allowForSecondaryDatabaseToCatchUp(): Promise<void> {
private async allowForPrimaryDatabaseToCatchUp(): Promise<void> {
const twoSecondsInMilliseconds = 2_000
await this.timer.sleep(twoSecondsInMilliseconds)
}
@@ -208,12 +217,12 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
this.logger.info(`[${userUuid.value}] Checking integrity from page ${initialPage}`)
const totalRevisionsCountForUserInPrimary = await this.primaryRevisionsRepository.countByUserUuid(userUuid)
const totalRevisionsCountForUserInSecondary = await (
this.secondRevisionsRepository as RevisionRepositoryInterface
).countByUserUuid(userUuid)
const totalRevisionsCountForUserInPrimary = await this.primaryRevisionsRepository.countByUserUuid(userUuid)
if (totalRevisionsCountForUserInPrimary > totalRevisionsCountForUserInSecondary) {
if (totalRevisionsCountForUserInPrimary < totalRevisionsCountForUserInSecondary) {
return Result.fail(
`Total revisions count for user ${userUuid.value} in primary database (${totalRevisionsCountForUserInPrimary}) does not match total revisions count in secondary database (${totalRevisionsCountForUserInSecondary})`,
)
@@ -232,7 +241,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
limit: this.pageSize,
}
const revisions = await this.primaryRevisionsRepository.findByUserUuid(query)
const revisions = await (this.secondRevisionsRepository as RevisionRepositoryInterface).findByUserUuid(query)
for (const revision of revisions) {
const revisionUuidOrError = Uuid.create(revision.id.toString())
@@ -242,31 +251,29 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
}
const revisionUuid = revisionUuidOrError.getValue()
const revisionInSecondary = await (
this.secondRevisionsRepository as RevisionRepositoryInterface
).findOneByUuid(revisionUuid, userUuid, [])
if (!revisionInSecondary) {
return Result.fail(`Revision ${revision.id.toString()} not found in secondary database`)
const revisionInPrimary = await this.primaryRevisionsRepository.findOneByUuid(revisionUuid, userUuid, [])
if (!revisionInPrimary) {
return Result.fail(`Revision ${revision.id.toString()} not found in primary database`)
}
if (revision.isIdenticalTo(revisionInSecondary)) {
continue
}
if (revisionInSecondary.props.dates.updatedAt > revision.props.dates.updatedAt) {
if (revisionInPrimary.props.dates.updatedAt > revision.props.dates.updatedAt) {
this.logger.info(
`[${
userUuid.value
}] Integrity check of revision ${revision.id.toString()} - is older than revision in secondary database`,
}] Integrity check of revision ${revision.id.toString()} - is older in secondary than revision in primary database`,
)
continue
}
if (revision.isIdenticalTo(revisionInPrimary)) {
continue
}
return Result.fail(
`Revision ${revision.id.toString()} is not identical in primary and secondary database. Revision in primary database: ${JSON.stringify(
revision,
)}, revision in secondary database: ${JSON.stringify(revisionInSecondary)}`,
revisionInPrimary,
)}, revision in secondary database: ${JSON.stringify(revision)}`,
)
}
}
@@ -291,14 +298,16 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
}
private async isAlreadyMigrated(userUuid: Uuid): Promise<boolean> {
const totalRevisionsCountForUserInPrimary = await this.primaryRevisionsRepository.countByUserUuid(userUuid)
const totalRevisionsCountForUserInSecondary = await (
this.secondRevisionsRepository as RevisionRepositoryInterface
).countByUserUuid(userUuid)
if (totalRevisionsCountForUserInPrimary > 0) {
if (totalRevisionsCountForUserInSecondary > 0) {
this.logger.info(
`[${userUuid.value}] User has ${totalRevisionsCountForUserInPrimary} revisions in primary database.`,
`[${userUuid.value}] User has ${totalRevisionsCountForUserInSecondary} revisions in secondary database.`,
)
}
return totalRevisionsCountForUserInPrimary === 0
return totalRevisionsCountForUserInSecondary === 0
}
}

View File

@@ -5,8 +5,11 @@ import { MongoDBRevision } from '../../../Infra/TypeORM/MongoDB/MongoDBRevision'
import { Revision } from '../../../Domain/Revision/Revision'
import { SharedVaultAssociation } from '../../../Domain/SharedVault/SharedVaultAssociation'
import { KeySystemAssociation } from '../../../Domain/KeySystem/KeySystemAssociation'
import { TimerInterface } from '@standardnotes/time'
export class MongoDBRevisionPersistenceMapper implements MapperInterface<Revision, MongoDBRevision> {
constructor(private timer: TimerInterface) {}
toDomain(projection: MongoDBRevision): Revision {
const contentTypeOrError = ContentType.create(projection.contentType)
if (contentTypeOrError.isFailed()) {
@@ -73,7 +76,7 @@ export class MongoDBRevisionPersistenceMapper implements MapperInterface<Revisio
authHash: projection.authHash,
content: projection.content,
contentType,
creationDate: projection.creationDate,
creationDate: new Date(this.timer.convertDateToFormattedString(projection.creationDate, 'YYYY-MM-DD')),
encItemKey: projection.encItemKey,
itemsKeyId: projection.itemsKeyId,
itemUuid,
@@ -99,7 +102,9 @@ export class MongoDBRevisionPersistenceMapper implements MapperInterface<Revisio
mongoDBRevision.contentType = domain.props.contentType.value
mongoDBRevision.createdAt = domain.props.dates.createdAt
mongoDBRevision.updatedAt = domain.props.dates.updatedAt
mongoDBRevision.creationDate = domain.props.creationDate
mongoDBRevision.creationDate = new Date(
this.timer.convertDateToFormattedString(domain.props.creationDate, 'YYYY-MM-DD'),
)
mongoDBRevision.encItemKey = domain.props.encItemKey
mongoDBRevision.itemUuid = domain.props.itemUuid.value
mongoDBRevision.itemsKeyId = domain.props.itemsKeyId

View File

@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.22.1](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.22.0...@standardnotes/scheduler-server@1.22.1) (2023-10-06)
### Bug Fixes
* add xray-sdk to background processors ([a45b5b6](https://github.com/standardnotes/server/commit/a45b5b69b5d68c2e696c30f0ba5ad22d313321e6))
# [1.22.0](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.21.10...@standardnotes/scheduler-server@1.22.0) (2023-10-06)
### Features
* add xray to analytics scheduler and websockets ([f0531d6](https://github.com/standardnotes/server/commit/f0531d68cb77036222f2a34602819f11e6a2697d))
## [1.21.10](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.21.9...@standardnotes/scheduler-server@1.21.10) (2023-10-05)
**Note:** Version bump only for package @standardnotes/scheduler-server

View File

@@ -3,6 +3,7 @@ import 'reflect-metadata'
import { Logger } from 'winston'
import * as dayjs from 'dayjs'
import * as utc from 'dayjs/plugin/utc'
import * as AWSXRay from 'aws-xray-sdk'
import { TimerInterface } from '@standardnotes/time'
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
@@ -21,6 +22,14 @@ void container.load().then((container) => {
const env: Env = new Env()
env.load()
const isConfiguredForAWSProduction =
env.get('MODE', true) !== 'home-server' && env.get('MODE', true) !== 'self-hosted'
if (isConfiguredForAWSProduction) {
AWSXRay.enableManualMode()
AWSXRay.config([AWSXRay.plugins.ECSPlugin])
}
const logger: Logger = container.get(TYPES.Logger)
const timer: TimerInterface = container.get(TYPES.Timer)
const now = timer.getTimestampInMicroseconds()

View File

@@ -1,6 +1,7 @@
import 'reflect-metadata'
import { Logger } from 'winston'
import * as AWSXRay from 'aws-xray-sdk'
import { DomainEventSubscriberFactoryInterface } from '@standardnotes/domain-events'
import * as dayjs from 'dayjs'
import * as utc from 'dayjs/plugin/utc'
@@ -16,6 +17,14 @@ void container.load().then((container) => {
const env: Env = new Env()
env.load()
const isConfiguredForAWSProduction =
env.get('MODE', true) !== 'home-server' && env.get('MODE', true) !== 'self-hosted'
if (isConfiguredForAWSProduction) {
AWSXRay.enableManualMode()
AWSXRay.config([AWSXRay.plugins.ECSPlugin])
}
const logger: Logger = container.get(TYPES.Logger)
logger.info('Starting worker...')

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