Compare commits

...

30 Commits

Author SHA1 Message Date
standardci
c99334889c chore(release): publish new version
- @standardnotes/analytics@2.32.1
 - @standardnotes/api-gateway@1.79.14
 - @standardnotes/auth-server@1.159.2
 - @standardnotes/domain-events-infra@1.20.1
 - @standardnotes/event-store@1.13.14
 - @standardnotes/files-server@1.31.1
 - @standardnotes/home-server@1.17.17
 - @standardnotes/revisions-server@1.46.1
 - @standardnotes/scheduler-server@1.26.1
 - @standardnotes/syncing-server@1.118.1
 - @standardnotes/websockets-server@1.17.1
2023-10-18 08:41:21 +00:00
Karol Sójko
7ce9aba517 fix: remove ip attributes in opentelemetry http instrumentation (#874) 2023-10-18 10:21:35 +02:00
Karol Sójko
46257a058b chore: allow only direct updates for dependabot: 2023-10-18 09:32:25 +02:00
dependabot[bot]
979dc35cfc chore(deps): bump actions/checkout from 3 to 4 (#817)
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-17 14:02:56 +02:00
standardci
c99a447a04 chore(release): publish new version
- @standardnotes/auth-server@1.159.1
 - @standardnotes/home-server@1.17.16
2023-10-17 11:58:49 +00:00
Karol Sójko
6dd9fd5abd fix: remove secrets from e2e test suites 2023-10-17 13:40:52 +02:00
Karol Sójko
0d37cb293c fix(auth): traversing through users in transition 2023-10-17 13:25:20 +02:00
standardci
27d04c95a1 chore(release): publish new version
- @standardnotes/analytics@2.32.0
 - @standardnotes/api-gateway@1.79.13
 - @standardnotes/auth-server@1.159.0
 - @standardnotes/domain-events-infra@1.20.0
 - @standardnotes/event-store@1.13.13
 - @standardnotes/files-server@1.31.0
 - @standardnotes/home-server@1.17.15
 - @standardnotes/revisions-server@1.46.0
 - @standardnotes/scheduler-server@1.26.0
 - @standardnotes/syncing-server@1.118.0
 - @standardnotes/websockets-server@1.17.0
2023-10-17 09:03:21 +00:00
Karol Sójko
cd830cdf25 fix: allow mutable yarn install on PR for dependabot purposes 2023-10-17 10:47:32 +02:00
Karol Sójko
5b06ea94f9 fix(syncing-server): binding 2023-10-17 10:41:55 +02:00
Karol Sójko
aba4f90485 feat: add wrapping sqs receive message with open telemetry 2023-10-17 10:14:26 +02:00
Karol Sójko
350621ed52 fix: remove secondary db from docker ci setup 2023-10-16 12:26:57 +02:00
Karol Sójko
69b4324c78 fix: remove unused variables in ci 2023-10-16 12:26:07 +02:00
Karol Sójko
b2be0a7c0b fix: remove secondary db from e2e test suites 2023-10-16 12:24:17 +02:00
Karol Sójko
cab0dfba39 fix: scheduled test suite to run only base tests 2023-10-16 12:04:34 +02:00
standardci
296ca47d63 chore(release): publish new version
- @standardnotes/auth-server@1.158.8
 - @standardnotes/home-server@1.17.14
2023-10-16 06:35:52 +00:00
Karol Sójko
1cad18a681 fix(auth): logs for triggering transition 2023-10-16 08:15:53 +02:00
standardci
bdd052f90c chore(release): publish new version
- @standardnotes/analytics@2.31.7
 - @standardnotes/api-gateway@1.79.12
 - @standardnotes/auth-server@1.158.7
 - @standardnotes/domain-events-infra@1.19.7
 - @standardnotes/event-store@1.13.12
 - @standardnotes/files-server@1.30.7
 - @standardnotes/home-server@1.17.13
 - @standardnotes/revisions-server@1.45.7
 - @standardnotes/scheduler-server@1.25.7
 - @standardnotes/syncing-server@1.117.7
 - @standardnotes/websockets-server@1.16.7
2023-10-13 08:38:45 +00:00
Karol Sójko
32fe8d0a85 fix: reduce the amount of metrics gathered in telemetery 2023-10-13 10:19:33 +02:00
standardci
31338066ef chore(release): publish new version
- @standardnotes/analytics@2.31.6
 - @standardnotes/api-gateway@1.79.11
 - @standardnotes/auth-server@1.158.6
 - @standardnotes/domain-events-infra@1.19.6
 - @standardnotes/domain-events@2.132.3
 - @standardnotes/event-store@1.13.11
 - @standardnotes/files-server@1.30.6
 - @standardnotes/home-server@1.17.12
 - @standardnotes/revisions-server@1.45.6
 - @standardnotes/scheduler-server@1.25.6
 - @standardnotes/syncing-server@1.117.6
 - @standardnotes/websockets-server@1.16.6
2023-10-12 13:57:28 +00:00
Karol Sójko
07398169c8 fix: passing key params for backup requests (#867) 2023-10-12 15:37:20 +02:00
standardci
1632c83217 chore(release): publish new version
- @standardnotes/analytics@2.31.5
 - @standardnotes/api-gateway@1.79.10
 - @standardnotes/auth-server@1.158.5
 - @standardnotes/domain-events-infra@1.19.5
 - @standardnotes/event-store@1.13.10
 - @standardnotes/files-server@1.30.5
 - @standardnotes/home-server@1.17.11
 - @standardnotes/revisions-server@1.45.5
 - @standardnotes/scheduler-server@1.25.5
 - @standardnotes/syncing-server@1.117.5
 - @standardnotes/websockets-server@1.16.5
2023-10-12 09:29:55 +00:00
Karol Sójko
0c29ff1ab4 fix(domain-events-infra): retrieve all message attributes from sqs 2023-10-12 11:09:43 +02:00
standardci
2a8029ba02 chore(release): publish new version
- @standardnotes/analytics@2.31.4
 - @standardnotes/api-gateway@1.79.9
 - @standardnotes/auth-server@1.158.4
 - @standardnotes/domain-events-infra@1.19.4
 - @standardnotes/domain-events@2.132.2
 - @standardnotes/event-store@1.13.9
 - @standardnotes/files-server@1.30.4
 - @standardnotes/home-server@1.17.10
 - @standardnotes/revisions-server@1.45.4
 - @standardnotes/scheduler-server@1.25.4
 - @standardnotes/syncing-server@1.117.4
 - @standardnotes/websockets-server@1.16.4
2023-10-12 08:34:51 +00:00
Karol Sójko
337eae73c6 fix: disable sqs open telemetry manual tracing in favour of automated instrumentation 2023-10-12 10:17:04 +02:00
Karol Sójko
0a90502658 fix: enable opentelemetry tracing on async workers via sqs/sns automation 2023-10-12 10:07:55 +02:00
Karol Sójko
1246af2551 fix(domain-events-infra): supress typeorm internal instrumentation 2023-10-12 09:54:41 +02:00
Karol Sójko
e0b19ef011 fix: disable opentelemetry tracing on async worker jobs 2023-10-12 09:41:20 +02:00
standardci
63201934a5 chore(release): publish new version
- @standardnotes/analytics@2.31.3
 - @standardnotes/api-gateway@1.79.8
 - @standardnotes/auth-server@1.158.3
 - @standardnotes/domain-events-infra@1.19.3
 - @standardnotes/domain-events@2.132.1
 - @standardnotes/event-store@1.13.8
 - @standardnotes/files-server@1.30.3
 - @standardnotes/home-server@1.17.9
 - @standardnotes/revisions-server@1.45.3
 - @standardnotes/scheduler-server@1.25.3
 - @standardnotes/syncing-server@1.117.3
 - @standardnotes/websockets-server@1.16.3
2023-10-12 06:11:53 +00:00
Karol Sójko
4a6f90b95b fix: injecting opentelemetry trace into sqs/sns coms 2023-10-12 07:50:18 +02:00
134 changed files with 1566 additions and 1274 deletions

6
.github/ci.env vendored
View File

@@ -23,12 +23,6 @@ MYSQL_USER=std_notes_user
MYSQL_PASSWORD=changeme123
MYSQL_ROOT_PASSWORD=changeme123
MONGO_HOST=secondary_db
MONGO_PORT=27017
MONGO_USERNAME=standardnotes
MONGO_PASSWORD=standardnotes
MONGO_DATABASE=standardnotes
AUTH_JWT_SECRET=f95259c5e441f5a4646d76422cfb3df4c4488842901aa50b6c51b8be2e0040e9
AUTH_SERVER_ENCRYPTION_SERVER_KEY=1087415dfde3093797f9a7ca93a49e7d7aa1861735eb0d32aae9c303b8c3d060
VALET_TOKEN_SECRET=4b886819ebe1e908077c6cae96311b48a8416bd60cc91c03060e15bdf6b30d1f

View File

@@ -9,101 +9,141 @@ updates:
directory: "/"
schedule:
interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm"
directory: "/packages/analytics"
schedule:
interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm"
directory: "/packages/api-gateway"
schedule:
interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm"
directory: "/packages/auth"
schedule:
interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm"
directory: "/packages/common"
schedule:
interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm"
directory: "/packages/domain-core"
schedule:
interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm"
directory: "/packages/domain-events"
schedule:
interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm"
directory: "/packages/domain-events-infra"
schedule:
interval: "daily"
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:
interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm"
directory: "/packages/home-server"
schedule:
interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm"
directory: "/packages/predicates"
schedule:
interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm"
directory: "/packages/revisions"
schedule:
interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm"
directory: "/packages/scheduler"
schedule:
interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm"
directory: "/packages/security"
schedule:
interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm"
directory: "/packages/settings"
schedule:
interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm"
directory: "/packages/sncrypto-node"
schedule:
interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm"
directory: "/packages/syncing-server"
schedule:
interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm"
directory: "/packages/time"
schedule:
interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm"
directory: "/packages/websockets"
schedule:
interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "github-actions"
directory: "/"

View File

@@ -27,7 +27,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:

View File

@@ -11,15 +11,6 @@ on:
type: string
default: all
description: The test suite to run
secrets:
DOCKER_USERNAME:
required: true
DOCKER_PASSWORD:
required: true
AWS_ACCESS_KEY_ID:
required: true
AWS_SECRET_ACCESS_KEY:
required: true
jobs:
e2e-self-hosted:
@@ -27,11 +18,9 @@ jobs:
with:
snjs_image_tag: ${{ inputs.snjs_image_tag }}
suite: ${{ inputs.suite }}
secrets: inherit
e2e-home-server:
uses: standardnotes/server/.github/workflows/e2e-home-server.yml@main
with:
snjs_image_tag: ${{ inputs.snjs_image_tag }}
suite: ${{ inputs.suite }}
secrets: inherit

View File

@@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Login to Docker Hub
uses: docker/login-action@v2

View File

@@ -11,15 +11,6 @@ on:
type: string
default: all
description: The test suite to run
secrets:
DOCKER_USERNAME:
required: true
DOCKER_PASSWORD:
required: true
AWS_ACCESS_KEY_ID:
required: true
AWS_SECRET_ACCESS_KEY:
required: true
jobs:
e2e-home-server:
@@ -29,7 +20,6 @@ jobs:
matrix:
db_type: [mysql, sqlite]
cache_type: [redis, memory]
secondary_db_enabled: [true, false]
runs-on: ubuntu-latest
@@ -51,17 +41,9 @@ jobs:
MYSQL_DATABASE: standardnotes
MYSQL_USER: standardnotes
MYSQL_PASSWORD: standardnotes
secondary_db:
image: mongo:5.0
ports:
- 27017:27017
env:
MONGO_INITDB_ROOT_USERNAME: standardnotes
MONGO_INITDB_ROOT_PASSWORD: standardnotes
MONGO_INITDB_DATABASE: standardnotes
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v3
@@ -98,12 +80,6 @@ jobs:
echo "DB_DEBUG_LEVEL=all" >> packages/home-server/.env
echo "REDIS_URL=redis://localhost:6379" >> packages/home-server/.env
echo "CACHE_TYPE=${{ matrix.cache_type }}" >> packages/home-server/.env
echo "SECONDARY_DB_ENABLED=${{ matrix.secondary_db_enabled }}" >> packages/home-server/.env
echo "MONGO_HOST=localhost" >> packages/home-server/.env
echo "MONGO_PORT=27017" >> packages/home-server/.env
echo "MONGO_DATABASE=standardnotes" >> packages/home-server/.env
echo "MONGO_USERNAME=standardnotes" >> packages/home-server/.env
echo "MONGO_PASSWORD=standardnotes" >> packages/home-server/.env
echo "FILES_SERVER_URL=http://localhost:3123" >> packages/home-server/.env
echo "E2E_TESTING=true" >> packages/home-server/.env
@@ -122,7 +98,7 @@ jobs:
if: ${{ failure() }}
uses: actions/upload-artifact@v3
with:
name: home-server-failure-logs-${{ inputs.suite }}-${{ matrix.db_type }}-${{ matrix.cache_type }}-${{ matrix.secondary_db_enabled }}
name: home-server-failure-logs-${{ inputs.suite }}-${{ matrix.db_type }}-${{ matrix.cache_type }}
retention-days: 5
path: |
logs/output.log

View File

@@ -11,23 +11,12 @@ on:
type: string
default: all
description: The test suite to run
secrets:
DOCKER_USERNAME:
required: true
DOCKER_PASSWORD:
required: true
AWS_ACCESS_KEY_ID:
required: true
AWS_SECRET_ACCESS_KEY:
required: true
jobs:
e2e:
name: (Self Hosting) E2E Test Suite
strategy:
fail-fast: false
matrix:
secondary_db_enabled: [true, false]
runs-on: ubuntu-latest
services:
@@ -37,7 +26,7 @@ jobs:
- 9001:9001
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v3
@@ -53,7 +42,6 @@ jobs:
env:
DB_TYPE: mysql
CACHE_TYPE: redis
SECONDARY_DB_ENABLED: ${{ matrix.secondary_db_enabled }}
- name: Wait for server to start
run: docker/is-available.sh http://localhost:3123 $(pwd)/logs
@@ -65,7 +53,7 @@ jobs:
if: ${{ failure() }}
uses: actions/upload-artifact@v3
with:
name: self-hosted-failure-logs-${{ inputs.suite }}-${{ matrix.secondary_db_enabled }}
name: self-hosted-failure-logs-${{ inputs.suite }}
retention-days: 5
path: |
logs/*.err

View File

@@ -31,4 +31,3 @@ jobs:
with:
snjs_image_tag: ${{ inputs.snjs_image_tag || 'latest' }}
suite: ${{ inputs.suite || 'all' }}
secrets: inherit

View File

@@ -9,7 +9,7 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Cache build
id: cache-build
@@ -26,7 +26,7 @@ jobs:
node-version-file: '.nvmrc'
- name: Install
run: yarn install --immutable
run: yarn install
- name: Build
run: yarn build
@@ -37,7 +37,7 @@ jobs:
needs: build
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Cache build
id: cache-build
@@ -54,7 +54,7 @@ jobs:
node-version-file: '.nvmrc'
- name: Install
run: yarn install --immutable
run: yarn install
- name: Build
if: steps.cache-build.outputs.cache-hit != 'true'
@@ -69,7 +69,7 @@ jobs:
needs: build
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Cache build
id: cache-build
@@ -86,7 +86,7 @@ jobs:
node-version-file: '.nvmrc'
- name: Install
run: yarn install --immutable
run: yarn install
- name: Build
if: steps.cache-build.outputs.cache-hit != 'true'
@@ -102,7 +102,6 @@ jobs:
with:
snjs_image_tag: 'latest'
suite: 'base'
secrets: inherit
# e2e-vaults:
# needs: build
@@ -111,4 +110,3 @@ jobs:
# with:
# snjs_image_tag: 'latest'
# suite: 'vaults'
# secrets: inherit

View File

@@ -9,7 +9,7 @@ jobs:
if: contains(github.event.head_commit.message, 'chore(release)') == false
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Cache build
id: cache-build
@@ -37,7 +37,7 @@ jobs:
needs: build
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Cache build
id: cache-build
@@ -69,7 +69,7 @@ jobs:
needs: build
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Cache build
id: cache-build
@@ -102,7 +102,6 @@ jobs:
with:
snjs_image_tag: 'latest'
suite: 'base'
secrets: inherit
# e2e-vaults:
# needs: build
@@ -111,7 +110,6 @@ jobs:
# with:
# snjs_image_tag: 'latest'
# suite: 'vaults'
# secrets: inherit
publish-self-hosting:
needs: [ test, lint, e2e-base ]
@@ -126,7 +124,7 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
token: ${{ secrets.CI_PAT_TOKEN }}
fetch-depth: 0

659
.pnp.cjs generated

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -22,7 +22,6 @@ services:
environment:
DB_TYPE: "${DB_TYPE}"
CACHE_TYPE: "${CACHE_TYPE}"
SECONDARY_DB_ENABLED: "${SECONDARY_DB_ENABLED}"
container_name: server-ci
ports:
- 3123:3000
@@ -61,21 +60,6 @@ services:
networks:
- standardnotes_self_hosted
secondary_db:
image: mongo:5.0
container_name: secondary_db-ci
ports:
- 27017
restart: unless-stopped
volumes:
- ./data/mongo:/data/db
environment:
MONGO_INITDB_ROOT_USERNAME: standardnotes
MONGO_INITDB_ROOT_PASSWORD: standardnotes
MONGO_INITDB_DATABASE: standardnotes
networks:
- standardnotes_self_hosted
cache:
image: redis:6.0-alpine
container_name: cache-ci

View File

@@ -3,6 +3,41 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.32.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.32.0...@standardnotes/analytics@2.32.1) (2023-10-18)
**Note:** Version bump only for package @standardnotes/analytics
# [2.32.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.31.7...@standardnotes/analytics@2.32.0) (2023-10-17)
### Features
* add wrapping sqs receive message with open telemetry ([aba4f90](https://github.com/standardnotes/server/commit/aba4f90485e1b40baac34561321a5381945aa27e))
## [2.31.7](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.31.6...@standardnotes/analytics@2.31.7) (2023-10-13)
### Bug Fixes
* reduce the amount of metrics gathered in telemetery ([32fe8d0](https://github.com/standardnotes/server/commit/32fe8d0a8523d6e1875cd0814c0cbdf27d8df7b3))
## [2.31.6](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.31.5...@standardnotes/analytics@2.31.6) (2023-10-12)
**Note:** Version bump only for package @standardnotes/analytics
## [2.31.5](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.31.4...@standardnotes/analytics@2.31.5) (2023-10-12)
**Note:** Version bump only for package @standardnotes/analytics
## [2.31.4](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.31.3...@standardnotes/analytics@2.31.4) (2023-10-12)
### Bug Fixes
* disable opentelemetry tracing on async worker jobs ([e0b19ef](https://github.com/standardnotes/server/commit/e0b19ef011197c854cb6e833dbaa982f661e8d17))
* disable sqs open telemetry manual tracing in favour of automated instrumentation ([337eae7](https://github.com/standardnotes/server/commit/337eae73c6cb18ae872527b06f6c23e1c48b6dff))
## [2.31.3](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.31.2...@standardnotes/analytics@2.31.3) (2023-10-12)
**Note:** Version bump only for package @standardnotes/analytics
## [2.31.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.31.1...@standardnotes/analytics@2.31.2) (2023-10-11)
**Note:** Version bump only for package @standardnotes/analytics

View File

@@ -3,7 +3,7 @@ import 'reflect-metadata'
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
import { EmailLevel, ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.AnalyticsScheduledTask)
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AnalyticsScheduledTask })
sdk.start()
import { Logger } from 'winston'

View File

@@ -3,11 +3,11 @@ import 'reflect-metadata'
import { OpenTelemetrySDK } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.AnalyticsWorker)
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AnalyticsWorker })
sdk.start()
import { Logger } from 'winston'
import { DomainEventSubscriberFactoryInterface } from '@standardnotes/domain-events'
import { DomainEventSubscriberInterface } from '@standardnotes/domain-events'
import * as dayjs from 'dayjs'
import * as utc from 'dayjs/plugin/utc'
@@ -26,6 +26,7 @@ void container.load().then((container) => {
logger.info('Starting worker...')
const subscriberFactory: DomainEventSubscriberFactoryInterface = container.get(TYPES.DomainEventSubscriberFactory)
subscriberFactory.create().start()
const subscriber = container.get<DomainEventSubscriberInterface>(TYPES.DomainEventSubscriber)
subscriber.start()
})

View File

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

View File

@@ -5,7 +5,7 @@ import {
DomainEventHandlerInterface,
DomainEventMessageHandlerInterface,
DomainEventPublisherInterface,
DomainEventSubscriberFactoryInterface,
DomainEventSubscriberInterface,
} from '@standardnotes/domain-events'
import { MapperInterface, ServiceIdentifier } from '@standardnotes/domain-core'
// eslint-disable-next-line @typescript-eslint/no-var-requires
@@ -16,11 +16,9 @@ import TYPES from './Types'
import { AppDataSource } from './DataSource'
import { DomainEventFactory } from '../Domain/Event/DomainEventFactory'
import {
OpenTelemetryPropagation,
OpenTelemetryPropagationInterface,
SNSOpenTelemetryDomainEventPublisher,
SQSDomainEventSubscriberFactory,
SQSOpenTelemetryEventMessageHandler,
SQSEventMessageHandler,
SQSOpenTelemetryDomainEventSubscriber,
} from '@standardnotes/domain-events-infra'
import { Timer, TimerInterface } from '@standardnotes/time'
import { PeriodKeyGeneratorInterface } from '../Domain/Time/PeriodKeyGeneratorInterface'
@@ -89,10 +87,6 @@ export class ContainerConfigLoader {
})
container.bind<winston.Logger>(TYPES.Logger).toConstantValue(logger)
container
.bind<OpenTelemetryPropagationInterface>(TYPES.OTEL_PROPAGATOR)
.toConstantValue(new OpenTelemetryPropagation())
const snsConfig: SNSClientConfig = {
apiVersion: 'latest',
region: env.get('SNS_AWS_REGION', true),
@@ -146,11 +140,7 @@ export class ContainerConfigLoader {
container
.bind<DomainEventPublisherInterface>(TYPES.DomainEventPublisher)
.toConstantValue(
new SNSOpenTelemetryDomainEventPublisher(
container.get<OpenTelemetryPropagationInterface>(TYPES.OTEL_PROPAGATOR),
container.get(TYPES.SNS),
container.get(TYPES.SNS_TOPIC_ARN),
),
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)))
@@ -248,21 +238,16 @@ export class ContainerConfigLoader {
container
.bind<DomainEventMessageHandlerInterface>(TYPES.DomainEventMessageHandler)
.toConstantValue(
new SQSOpenTelemetryEventMessageHandler(
ServiceIdentifier.NAMES.AnalyticsWorker,
container.get<OpenTelemetryPropagationInterface>(TYPES.OTEL_PROPAGATOR),
eventHandlers,
container.get(TYPES.Logger),
),
)
.toConstantValue(new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Logger)))
container
.bind<DomainEventSubscriberFactoryInterface>(TYPES.DomainEventSubscriberFactory)
.bind<DomainEventSubscriberInterface>(TYPES.DomainEventSubscriber)
.toConstantValue(
new SQSDomainEventSubscriberFactory(
container.get(TYPES.SQS),
container.get(TYPES.SQS_QUEUE_URL),
container.get(TYPES.DomainEventMessageHandler),
new SQSOpenTelemetryDomainEventSubscriber(
ServiceIdentifier.NAMES.AnalyticsWorker,
container.get<SQSClient>(TYPES.SQS),
container.get<string>(TYPES.SQS_QUEUE_URL),
container.get<DomainEventMessageHandlerInterface>(TYPES.DomainEventMessageHandler),
container.get<winston.Logger>(TYPES.Logger),
),
)

View File

@@ -3,7 +3,6 @@ const TYPES = {
Redis: Symbol.for('Redis'),
SNS: Symbol.for('SNS'),
SQS: Symbol.for('SQS'),
OTEL_PROPAGATOR: Symbol.for('OTEL_PROPAGATOR'),
// env vars
REDIS_URL: Symbol.for('REDIS_URL'),
SNS_TOPIC_ARN: Symbol.for('SNS_TOPIC_ARN'),
@@ -43,7 +42,7 @@ const TYPES = {
RevenueModificationMap: Symbol.for('RevenueModificationMap'),
// Services
DomainEventPublisher: Symbol.for('DomainEventPublisher'),
DomainEventSubscriberFactory: Symbol.for('DomainEventSubscriberFactory'),
DomainEventSubscriber: Symbol.for('DomainEventSubscriber'),
DomainEventFactory: Symbol.for('DomainEventFactory'),
DomainEventMessageHandler: Symbol.for('DomainEventMessageHandler'),
AnalyticsStore: Symbol.for('AnalyticsStore'),

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.79.14](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.79.13...@standardnotes/api-gateway@1.79.14) (2023-10-18)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.79.13](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.79.12...@standardnotes/api-gateway@1.79.13) (2023-10-17)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.79.12](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.79.11...@standardnotes/api-gateway@1.79.12) (2023-10-13)
### Bug Fixes
* reduce the amount of metrics gathered in telemetery ([32fe8d0](https://github.com/standardnotes/api-gateway/commit/32fe8d0a8523d6e1875cd0814c0cbdf27d8df7b3))
## [1.79.11](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.79.10...@standardnotes/api-gateway@1.79.11) (2023-10-12)
### Bug Fixes
* passing key params for backup requests ([#867](https://github.com/standardnotes/api-gateway/issues/867)) ([0739816](https://github.com/standardnotes/api-gateway/commit/07398169c80e7871cd04d889f471c3eef70e1aae))
## [1.79.10](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.79.9...@standardnotes/api-gateway@1.79.10) (2023-10-12)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.79.9](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.79.8...@standardnotes/api-gateway@1.79.9) (2023-10-12)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.79.8](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.79.7...@standardnotes/api-gateway@1.79.8) (2023-10-12)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.79.7](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.79.6...@standardnotes/api-gateway@1.79.7) (2023-10-11)
**Note:** Version bump only for package @standardnotes/api-gateway

View File

@@ -3,7 +3,7 @@ import 'reflect-metadata'
import { OpenTelemetrySDK } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.ApiGateway)
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.ApiGateway })
sdk.start()
import '../src/Controller/LegacyController'

View File

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

View File

@@ -42,7 +42,6 @@ export class EndpointResolver implements EndpointResolverInterface {
// Users Controller
['[PATCH]:users/:userId', 'auth.users.update'],
['[PUT]:users/:userUuid/attributes/credentials', 'auth.users.updateCredentials'],
['[GET]:users/params', 'auth.users.getKeyParams'],
['[DELETE]:users/:userUuid', 'auth.users.delete'],
['[POST]:listed', 'auth.users.createListedAccount'],
['[POST]:auth', 'auth.users.register'],

View File

@@ -3,6 +3,55 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.159.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.159.1...@standardnotes/auth-server@1.159.2) (2023-10-18)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.159.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.159.0...@standardnotes/auth-server@1.159.1) (2023-10-17)
### Bug Fixes
* **auth:** traversing through users in transition ([0d37cb2](https://github.com/standardnotes/server/commit/0d37cb293c3f8c1fa798a3c847a1f76c18a8c3aa))
# [1.159.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.158.8...@standardnotes/auth-server@1.159.0) (2023-10-17)
### Features
* add wrapping sqs receive message with open telemetry ([aba4f90](https://github.com/standardnotes/server/commit/aba4f90485e1b40baac34561321a5381945aa27e))
## [1.158.8](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.158.7...@standardnotes/auth-server@1.158.8) (2023-10-16)
### Bug Fixes
* **auth:** logs for triggering transition ([1cad18a](https://github.com/standardnotes/server/commit/1cad18a681d933c67244d43dd6f3c2ec405149be))
## [1.158.7](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.158.6...@standardnotes/auth-server@1.158.7) (2023-10-13)
### Bug Fixes
* reduce the amount of metrics gathered in telemetery ([32fe8d0](https://github.com/standardnotes/server/commit/32fe8d0a8523d6e1875cd0814c0cbdf27d8df7b3))
## [1.158.6](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.158.5...@standardnotes/auth-server@1.158.6) (2023-10-12)
### Bug Fixes
* passing key params for backup requests ([#867](https://github.com/standardnotes/server/issues/867)) ([0739816](https://github.com/standardnotes/server/commit/07398169c80e7871cd04d889f471c3eef70e1aae))
## [1.158.5](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.158.4...@standardnotes/auth-server@1.158.5) (2023-10-12)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.158.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.158.3...@standardnotes/auth-server@1.158.4) (2023-10-12)
### Bug Fixes
* disable opentelemetry tracing on async worker jobs ([e0b19ef](https://github.com/standardnotes/server/commit/e0b19ef011197c854cb6e833dbaa982f661e8d17))
* disable sqs open telemetry manual tracing in favour of automated instrumentation ([337eae7](https://github.com/standardnotes/server/commit/337eae73c6cb18ae872527b06f6c23e1c48b6dff))
## [1.158.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.158.2...@standardnotes/auth-server@1.158.3) (2023-10-12)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.158.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.158.1...@standardnotes/auth-server@1.158.2) (2023-10-11)
**Note:** Version bump only for package @standardnotes/auth-server

View File

@@ -3,7 +3,7 @@ import 'reflect-metadata'
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.AuthScheduledTask)
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AuthScheduledTask })
sdk.start()
import { Stream } from 'stream'
@@ -21,6 +21,7 @@ import { SettingRepositoryInterface } from '../src/Domain/Setting/SettingReposit
import { MuteFailedBackupsEmailsOption, SettingName } 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 backupProvider = inputArgs[0]
@@ -31,6 +32,7 @@ const requestBackups = async (
roleService: RoleServiceInterface,
domainEventFactory: DomainEventFactoryInterface,
domainEventPublisher: DomainEventPublisherInterface,
getUserKeyParamsUseCase: GetUserKeyParams,
): Promise<void> => {
const settingName = SettingName.create(SettingName.NAMES.EmailBackupFrequency).getValue()
const permissionName = PermissionName.DailyEmailBackup
@@ -64,11 +66,17 @@ const requestBackups = async (
userHasEmailsMuted = emailsMutedSetting.value === muteEmailsSettingValue
}
const keyParamsResponse = await getUserKeyParamsUseCase.execute({
userUuid: setting.setting_user_uuid,
authenticated: false,
})
await domainEventPublisher.publish(
domainEventFactory.createEmailBackupRequestedEvent(
setting.setting_user_uuid,
emailsMutedSetting?.uuid as string,
userHasEmailsMuted,
keyParamsResponse.keyParams,
),
)
@@ -96,11 +104,14 @@ void container.load().then((container) => {
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))
Promise.resolve(
requestBackups(settingRepository, roleService, domainEventFactory, domainEventPublisher, getUserKeyParamsUseCase),
)
.then(() => {
logger.info(`${backupFrequency} ${backupProvider} backup requesting complete`)

View File

@@ -3,7 +3,7 @@ import 'reflect-metadata'
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.AuthScheduledTask)
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AuthScheduledTask })
sdk.start()
import { Logger } from 'winston'

View File

@@ -3,7 +3,7 @@ import 'reflect-metadata'
import { OpenTelemetrySDK } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.Auth)
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.Auth })
sdk.start()
import '../src/Infra/InversifyExpressUtils/AnnotatedAuthController'

View File

@@ -3,7 +3,7 @@ import 'reflect-metadata'
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.AuthScheduledTask)
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AuthScheduledTask })
sdk.start()
import { Logger } from 'winston'

View File

@@ -3,7 +3,7 @@ import 'reflect-metadata'
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier, RoleName, TransitionStatus } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.AuthScheduledTask)
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AuthScheduledTask })
sdk.start()
import { Logger } from 'winston'
@@ -35,78 +35,87 @@ const requestTransition = async (
const startDate = new Date(startDateString)
const endDate = new Date(endDateString)
const users = await userRepository.findAllCreatedBetween(startDate, endDate)
const usersCount = await userRepository.countAllCreatedBetween(startDate, endDate)
const timestamp = timer.getTimestampInMicroseconds()
logger.info(
`[TRANSITION ${timestamp}] Found ${users.length} users created between ${startDateString} and ${endDateString}`,
`[TRANSITION ${timestamp}] Found ${usersCount} users created between ${startDateString} and ${endDateString}`,
)
let usersTriggered = 0
let itemTransitionsTriggered = 0
let revisionTransitionsTriggered = 0
const forceRun = forceRunParam === 'true'
for (const user of users) {
const itemsTransitionStatus = await transitionStatusRepository.getStatus(user.uuid, 'items')
const revisionsTransitionStatus = await transitionStatusRepository.getStatus(user.uuid, 'revisions')
const userRoles = await user.roles
const pageLimit = 100
const totalPages = Math.ceil(usersCount / pageLimit)
for (let currentPage = 1; currentPage <= totalPages; currentPage++) {
const users = await userRepository.findAllCreatedBetween({
start: startDate,
end: endDate,
offset: (currentPage - 1) * pageLimit,
limit: pageLimit,
})
const userHasTransitionRole = userRoles.some((role) => role.name === RoleName.NAMES.TransitionUser)
const bothTransitionStatusesAreVerified =
itemsTransitionStatus?.value === TransitionStatus.STATUSES.Verified &&
revisionsTransitionStatus?.value === TransitionStatus.STATUSES.Verified
for (const user of users) {
const itemsTransitionStatus = await transitionStatusRepository.getStatus(user.uuid, 'items')
const revisionsTransitionStatus = await transitionStatusRepository.getStatus(user.uuid, 'revisions')
if (!userHasTransitionRole && bothTransitionStatusesAreVerified) {
continue
}
const userRoles = await user.roles
let wasTransitionRequested = false
const userHasTransitionRole = userRoles.some((role) => role.name === RoleName.NAMES.TransitionUser)
const bothTransitionStatusesAreVerified =
itemsTransitionStatus?.value === TransitionStatus.STATUSES.Verified &&
revisionsTransitionStatus?.value === TransitionStatus.STATUSES.Verified
if (
itemsTransitionStatus === null ||
itemsTransitionStatus.value === TransitionStatus.STATUSES.Failed ||
(itemsTransitionStatus.value === TransitionStatus.STATUSES.InProgress && forceRun)
) {
wasTransitionRequested = true
await transitionStatusRepository.remove(user.uuid, 'items')
if (!userHasTransitionRole && bothTransitionStatusesAreVerified) {
continue
}
await domainEventPublisher.publish(
domainEventFactory.createTransitionRequestedEvent({
userUuid: user.uuid,
type: 'items',
timestamp,
}),
)
}
if (
revisionsTransitionStatus === null ||
revisionsTransitionStatus.value === TransitionStatus.STATUSES.Failed ||
(revisionsTransitionStatus.value === TransitionStatus.STATUSES.InProgress && forceRun)
) {
wasTransitionRequested = true
await transitionStatusRepository.remove(user.uuid, 'revisions')
await domainEventPublisher.publish(
domainEventFactory.createTransitionRequestedEvent({
userUuid: user.uuid,
type: 'revisions',
timestamp,
}),
)
}
usersTriggered += 1
if (wasTransitionRequested) {
logger.info(
`[TRANSITION ${timestamp}] Transition requested for user ${user.uuid} - items status: ${itemsTransitionStatus?.value}, revisions status: ${revisionsTransitionStatus?.value}, has transition role: ${userHasTransitionRole}`,
`[TRANSITION ${timestamp}] Transition status for user ${user.uuid} - items status: ${itemsTransitionStatus?.value}, revisions status: ${revisionsTransitionStatus?.value}, has transition role: ${userHasTransitionRole}`,
)
if (
itemsTransitionStatus === null ||
itemsTransitionStatus.value === TransitionStatus.STATUSES.Failed ||
(itemsTransitionStatus.value === TransitionStatus.STATUSES.InProgress && forceRun)
) {
await transitionStatusRepository.remove(user.uuid, 'items')
await domainEventPublisher.publish(
domainEventFactory.createTransitionRequestedEvent({
userUuid: user.uuid,
type: 'items',
timestamp,
}),
)
itemTransitionsTriggered++
}
if (
revisionsTransitionStatus === null ||
revisionsTransitionStatus.value === TransitionStatus.STATUSES.Failed ||
(revisionsTransitionStatus.value === TransitionStatus.STATUSES.InProgress && forceRun)
) {
await transitionStatusRepository.remove(user.uuid, 'revisions')
await domainEventPublisher.publish(
domainEventFactory.createTransitionRequestedEvent({
userUuid: user.uuid,
type: 'revisions',
timestamp,
}),
)
revisionTransitionsTriggered++
}
}
}
logger.info(
`[TRANSITION ${timestamp}] Triggered transition for ${usersTriggered} users created between ${startDateString} and ${endDateString}`,
`[TRANSITION ${timestamp}] Triggered ${itemTransitionsTriggered} item transitions and ${revisionTransitionsTriggered} revision transitions for users created between ${startDateString} and ${endDateString}`,
)
}

View File

@@ -3,7 +3,7 @@ import 'reflect-metadata'
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
import { Email, ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.AuthScheduledTask)
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AuthScheduledTask })
sdk.start()
import { Logger } from 'winston'
@@ -20,6 +20,7 @@ import { MuteFailedBackupsEmailsOption, SettingName } from '@standardnotes/setti
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'
const inputArgs = process.argv.slice(2)
const backupEmail = inputArgs[0]
@@ -30,6 +31,7 @@ const requestBackups = async (
roleService: RoleServiceInterface,
domainEventFactory: DomainEventFactoryInterface,
domainEventPublisher: DomainEventPublisherInterface,
getUserKeyParamsUseCase: GetUserKeyParams,
): Promise<void> => {
const permissionName = PermissionName.DailyEmailBackup
const muteEmailsSettingName = SettingName.NAMES.MuteFailedBackupsEmails
@@ -57,11 +59,17 @@ const requestBackups = async (
userHasEmailsMuted = emailsMutedSetting.value === muteEmailsSettingValue
}
const keyParamsResponse = await getUserKeyParamsUseCase.execute({
userUuid: user.uuid,
authenticated: false,
})
await domainEventPublisher.publish(
domainEventFactory.createEmailBackupRequestedEvent(
user.uuid,
emailsMutedSetting?.uuid as string,
userHasEmailsMuted,
keyParamsResponse.keyParams,
),
)
@@ -84,12 +92,20 @@ void container.load().then((container) => {
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, 'user_email_backup')
Promise.resolve(
requestBackups(userRepository, settingRepository, roleService, domainEventFactory, domainEventPublisher),
requestBackups(
userRepository,
settingRepository,
roleService,
domainEventFactory,
domainEventPublisher,
getUserKeyParamsUseCase,
),
)
.then(() => {
logger.info(`Email backup requesting complete for ${backupEmail}`)

View File

@@ -3,7 +3,7 @@ import 'reflect-metadata'
import { OpenTelemetrySDK } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.AuthWorker)
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AuthWorker })
sdk.start()
import { Logger } from 'winston'
@@ -11,7 +11,7 @@ import { Logger } from 'winston'
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
import TYPES from '../src/Bootstrap/Types'
import { Env } from '../src/Bootstrap/Env'
import { DomainEventSubscriberFactoryInterface } from '@standardnotes/domain-events'
import { DomainEventSubscriberInterface } from '@standardnotes/domain-events'
import * as dayjs from 'dayjs'
import * as utc from 'dayjs/plugin/utc'
@@ -26,8 +26,7 @@ void container.load().then((container) => {
logger.info('Starting worker...')
const subscriberFactory: DomainEventSubscriberFactoryInterface = container.get(
TYPES.Auth_DomainEventSubscriberFactory,
)
subscriberFactory.create().start()
const subscriber = container.get<DomainEventSubscriberInterface>(TYPES.Auth_DomainEventSubscriber)
subscriber.start()
})

View File

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

View File

@@ -7,7 +7,7 @@ import {
DomainEventHandlerInterface,
DomainEventMessageHandlerInterface,
DomainEventPublisherInterface,
DomainEventSubscriberFactoryInterface,
DomainEventSubscriberInterface,
} from '@standardnotes/domain-events'
import { TimerInterface, Timer } from '@standardnotes/time'
import { UAParser } from 'ua-parser-js'
@@ -89,12 +89,9 @@ import { ExtensionKeyGrantedEventHandler } from '../Domain/Handler/ExtensionKeyG
import {
DirectCallDomainEventPublisher,
DirectCallEventMessageHandler,
OpenTelemetryPropagation,
OpenTelemetryPropagationInterface,
SNSOpenTelemetryDomainEventPublisher,
SQSDomainEventSubscriberFactory,
SQSEventMessageHandler,
SQSOpenTelemetryEventMessageHandler,
SQSOpenTelemetryDomainEventSubscriber,
} from '@standardnotes/domain-events-infra'
import { GetUserSubscription } from '../Domain/UseCase/GetUserSubscription/GetUserSubscription'
import { ChangeCredentials } from '../Domain/UseCase/ChangeCredentials/ChangeCredentials'
@@ -277,6 +274,8 @@ import { UserRemovedFromSharedVaultEventHandler } from '../Domain/Handler/UserRe
import { DesignateSurvivor } from '../Domain/UseCase/DesignateSurvivor/DesignateSurvivor'
import { UserDesignatedAsSurvivorInSharedVaultEventHandler } from '../Domain/Handler/UserDesignatedAsSurvivorInSharedVaultEventHandler'
import { DisableEmailSettingBasedOnEmailSubscription } from '../Domain/UseCase/DisableEmailSettingBasedOnEmailSubscription/DisableEmailSettingBasedOnEmailSubscription'
import { DomainEventFactoryInterface } from '../Domain/Event/DomainEventFactoryInterface'
import { KeyParamsFactoryInterface } from '../Domain/User/KeyParamsFactoryInterface'
export class ContainerConfigLoader {
constructor(private mode: 'server' | 'worker' = 'server') {}
@@ -310,9 +309,7 @@ export class ContainerConfigLoader {
}
container.bind<winston.Logger>(TYPES.Auth_Logger).toConstantValue(logger)
container
.bind<OpenTelemetryPropagationInterface>(TYPES.Auth_OTEL_PROPAGATOR)
.toConstantValue(new OpenTelemetryPropagation())
container.bind<CryptoNode>(TYPES.Auth_CryptoNode).toConstantValue(new CryptoNode())
const appDataSource = new AppDataSource({ env, runMigrations: this.mode === 'server' })
await appDataSource.initialize()
@@ -375,6 +372,19 @@ export class ContainerConfigLoader {
container.bind<SQSClient>(TYPES.Auth_SQS).toConstantValue(sqsClient)
}
container.bind(TYPES.Auth_SNS_TOPIC_ARN).toConstantValue(env.get('SNS_TOPIC_ARN', true))
container
.bind<DomainEventPublisherInterface>(TYPES.Auth_DomainEventPublisher)
.toConstantValue(
isConfiguredForHomeServer
? directCallDomainEventPublisher
: new SNSOpenTelemetryDomainEventPublisher(
container.get(TYPES.Auth_SNS),
container.get(TYPES.Auth_SNS_TOPIC_ARN),
),
)
// Mapping
container
.bind<MapperInterface<SessionTrace, TypeORMSessionTrace>>(TYPES.Auth_SessionTracePersistenceMapper)
@@ -555,7 +565,6 @@ export class ContainerConfigLoader {
container
.bind(TYPES.Auth_DISABLE_USER_REGISTRATION)
.toConstantValue(env.get('DISABLE_USER_REGISTRATION', true) === 'true')
container.bind(TYPES.Auth_SNS_TOPIC_ARN).toConstantValue(env.get('SNS_TOPIC_ARN', true))
container.bind(TYPES.Auth_SNS_AWS_REGION).toConstantValue(env.get('SNS_AWS_REGION', true))
container.bind(TYPES.Auth_SQS_QUEUE_URL).toConstantValue(env.get('SQS_QUEUE_URL', true))
container
@@ -657,6 +666,9 @@ export class ContainerConfigLoader {
}
// Services
container
.bind<SelectorInterface<ProtocolVersion>>(TYPES.Auth_ProtocolVersionSelector)
.toConstantValue(new DeterministicSelector<ProtocolVersion>())
container.bind<UAParser>(TYPES.Auth_DeviceDetector).toConstantValue(new UAParser())
container.bind<SessionService>(TYPES.Auth_SessionService).to(SessionService)
container.bind<AuthResponseFactory20161215>(TYPES.Auth_AuthResponseFactory20161215).to(AuthResponseFactory20161215)
@@ -699,45 +711,61 @@ export class ContainerConfigLoader {
container.bind<DomainEventFactory>(TYPES.Auth_DomainEventFactory).to(DomainEventFactory)
container.bind<AxiosInstance>(TYPES.Auth_HTTPClient).toConstantValue(axios.create())
container.bind<CrypterInterface>(TYPES.Auth_Crypter).to(CrypterNode)
container.bind<SettingServiceInterface>(TYPES.Auth_SettingService).to(SettingService)
container
.bind<SettingsAssociationServiceInterface>(TYPES.Auth_SettingsAssociationService)
.to(SettingsAssociationService)
container.bind<SettingDecrypterInterface>(TYPES.Auth_SettingDecrypter).to(SettingDecrypter)
container
.bind<GetUserKeyParams>(TYPES.Auth_GetUserKeyParams)
.toConstantValue(
new GetUserKeyParams(
container.get<KeyParamsFactoryInterface>(TYPES.Auth_KeyParamsFactory),
container.get<UserRepositoryInterface>(TYPES.Auth_UserRepository),
container.get<PKCERepositoryInterface>(TYPES.Auth_PKCERepository),
container.get<winston.Logger>(TYPES.Auth_Logger),
),
)
container
.bind<SettingInterpreterInterface>(TYPES.Auth_SettingInterpreter)
.toConstantValue(
new SettingInterpreter(
container.get<DomainEventPublisherInterface>(TYPES.Auth_DomainEventPublisher),
container.get<DomainEventFactoryInterface>(TYPES.Auth_DomainEventFactory),
container.get<SettingRepositoryInterface>(TYPES.Auth_SettingRepository),
container.get<GetUserKeyParams>(TYPES.Auth_GetUserKeyParams),
),
)
container
.bind<SettingServiceInterface>(TYPES.Auth_SettingService)
.toConstantValue(
new SettingService(
container.get<SettingFactoryInterface>(TYPES.Auth_SettingFactory),
container.get<SettingRepositoryInterface>(TYPES.Auth_SettingRepository),
container.get<SettingsAssociationServiceInterface>(TYPES.Auth_SettingsAssociationService),
container.get<SettingInterpreterInterface>(TYPES.Auth_SettingInterpreter),
container.get<SettingDecrypterInterface>(TYPES.Auth_SettingDecrypter),
container.get<winston.Logger>(TYPES.Auth_Logger),
),
)
container
.bind<SubscriptionSettingServiceInterface>(TYPES.Auth_SubscriptionSettingService)
.to(SubscriptionSettingService)
container.bind<OfflineSettingServiceInterface>(TYPES.Auth_OfflineSettingService).to(OfflineSettingService)
container.bind<CryptoNode>(TYPES.Auth_CryptoNode).toConstantValue(new CryptoNode())
container.bind<ContentDecoderInterface>(TYPES.Auth_ContenDecoder).toConstantValue(new ContentDecoder())
container.bind<ClientServiceInterface>(TYPES.Auth_WebSocketsClientService).to(WebSocketsClientService)
container.bind<RoleServiceInterface>(TYPES.Auth_RoleService).to(RoleService)
container.bind<RoleToSubscriptionMapInterface>(TYPES.Auth_RoleToSubscriptionMap).to(RoleToSubscriptionMap)
container
.bind<SettingsAssociationServiceInterface>(TYPES.Auth_SettingsAssociationService)
.to(SettingsAssociationService)
container
.bind<SubscriptionSettingsAssociationServiceInterface>(TYPES.Auth_SubscriptionSettingsAssociationService)
.to(SubscriptionSettingsAssociationService)
container.bind<FeatureServiceInterface>(TYPES.Auth_FeatureService).to(FeatureService)
container.bind<SettingInterpreterInterface>(TYPES.Auth_SettingInterpreter).to(SettingInterpreter)
container.bind<SettingDecrypterInterface>(TYPES.Auth_SettingDecrypter).to(SettingDecrypter)
container
.bind<SelectorInterface<ProtocolVersion>>(TYPES.Auth_ProtocolVersionSelector)
.toConstantValue(new DeterministicSelector<ProtocolVersion>())
container
.bind<SelectorInterface<boolean>>(TYPES.Auth_BooleanSelector)
.toConstantValue(new DeterministicSelector<boolean>())
container.bind<UserSubscriptionServiceInterface>(TYPES.Auth_UserSubscriptionService).to(UserSubscriptionService)
container
.bind<DomainEventPublisherInterface>(TYPES.Auth_DomainEventPublisher)
.toConstantValue(
isConfiguredForHomeServer
? directCallDomainEventPublisher
: new SNSOpenTelemetryDomainEventPublisher(
container.get<OpenTelemetryPropagationInterface>(TYPES.Auth_OTEL_PROPAGATOR),
container.get(TYPES.Auth_SNS),
container.get(TYPES.Auth_SNS_TOPIC_ARN),
),
)
// Middleware
container.bind<SessionMiddleware>(TYPES.Auth_SessionMiddleware).to(SessionMiddleware)
container.bind<LockMiddleware>(TYPES.Auth_LockMiddleware).to(LockMiddleware)
@@ -890,7 +918,6 @@ export class ContainerConfigLoader {
container.get(TYPES.Auth_SettingService),
),
)
container.bind<GetUserKeyParams>(TYPES.Auth_GetUserKeyParams).to(GetUserKeyParams)
container.bind<UpdateUser>(TYPES.Auth_UpdateUser).to(UpdateUser)
container.bind<Register>(TYPES.Auth_Register).to(Register)
container.bind<GetActiveSessionsForUser>(TYPES.Auth_GetActiveSessionsForUser).to(GetActiveSessionsForUser)
@@ -1233,24 +1260,17 @@ export class ContainerConfigLoader {
} else {
container
.bind<DomainEventMessageHandlerInterface>(TYPES.Auth_DomainEventMessageHandler)
.toConstantValue(
isConfiguredForHomeServerOrSelfHosting
? new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Auth_Logger))
: new SQSOpenTelemetryEventMessageHandler(
ServiceIdentifier.NAMES.AuthWorker,
container.get<OpenTelemetryPropagationInterface>(TYPES.Auth_OTEL_PROPAGATOR),
eventHandlers,
container.get(TYPES.Auth_Logger),
),
)
.toConstantValue(new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Auth_Logger)))
container
.bind<DomainEventSubscriberFactoryInterface>(TYPES.Auth_DomainEventSubscriberFactory)
.bind<DomainEventSubscriberInterface>(TYPES.Auth_DomainEventSubscriber)
.toConstantValue(
new SQSDomainEventSubscriberFactory(
container.get(TYPES.Auth_SQS),
container.get(TYPES.Auth_SQS_QUEUE_URL),
container.get(TYPES.Auth_DomainEventMessageHandler),
new SQSOpenTelemetryDomainEventSubscriber(
ServiceIdentifier.NAMES.AuthWorker,
container.get<SQSClient>(TYPES.Auth_SQS),
container.get<string>(TYPES.Auth_SQS_QUEUE_URL),
container.get<DomainEventMessageHandlerInterface>(TYPES.Auth_DomainEventMessageHandler),
container.get<winston.Logger>(TYPES.Auth_Logger),
),
)
}
@@ -1329,7 +1349,6 @@ export class ContainerConfigLoader {
.toConstantValue(
new BaseUsersController(
container.get<UpdateUser>(TYPES.Auth_UpdateUser),
container.get<GetUserKeyParams>(TYPES.Auth_GetUserKeyParams),
container.get<DeleteAccount>(TYPES.Auth_DeleteAccount),
container.get<GetUserSubscription>(TYPES.Auth_GetUserSubscription),
container.get<ClearLoginAttempts>(TYPES.Auth_ClearLoginAttempts),

View File

@@ -3,7 +3,6 @@ const TYPES = {
Auth_Redis: Symbol.for('Auth_Redis'),
Auth_SNS: Symbol.for('Auth_SNS'),
Auth_SQS: Symbol.for('Auth_SQS'),
Auth_OTEL_PROPAGATOR: Symbol.for('Auth_OTEL_PROPAGATOR'),
// Mapping
Auth_SessionTracePersistenceMapper: Symbol.for('Auth_SessionTracePersistenceMapper'),
Auth_AuthenticatorChallengePersistenceMapper: Symbol.for('Auth_AuthenticatorChallengePersistenceMapper'),
@@ -219,7 +218,7 @@ const TYPES = {
Auth_WebSocketConnectionTokenDecoder: Symbol.for('Auth_WebSocketConnectionTokenDecoder'),
Auth_AuthenticationMethodResolver: Symbol.for('Auth_AuthenticationMethodResolver'),
Auth_DomainEventPublisher: Symbol.for('Auth_DomainEventPublisher'),
Auth_DomainEventSubscriberFactory: Symbol.for('Auth_DomainEventSubscriberFactory'),
Auth_DomainEventSubscriber: Symbol.for('Auth_DomainEventSubscriber'),
Auth_DomainEventFactory: Symbol.for('Auth_DomainEventFactory'),
Auth_DomainEventMessageHandler: Symbol.for('Auth_DomainEventMessageHandler'),
Auth_HTTPClient: Symbol.for('Auth_HTTPClient'),

View File

@@ -28,6 +28,7 @@ import { inject, injectable } from 'inversify'
import TYPES from '../../Bootstrap/Types'
import { InviteeIdentifierType } from '../SharedSubscription/InviteeIdentifierType'
import { DomainEventFactoryInterface } from './DomainEventFactoryInterface'
import { KeyParamsData } from '@standardnotes/responses'
@injectable()
export class DomainEventFactory implements DomainEventFactoryInterface {
@@ -277,6 +278,7 @@ export class DomainEventFactory implements DomainEventFactoryInterface {
userUuid: string,
muteEmailsSettingUuid: string,
userHasEmailsMuted: boolean,
keyParams: KeyParamsData,
): EmailBackupRequestedEvent {
return {
type: 'EMAIL_BACKUP_REQUESTED',
@@ -292,6 +294,7 @@ export class DomainEventFactory implements DomainEventFactoryInterface {
userUuid,
userHasEmailsMuted,
muteEmailsSettingUuid,
keyParams,
},
}
}

View File

@@ -21,6 +21,7 @@ import {
TransitionRequestedEvent,
} from '@standardnotes/domain-events'
import { InviteeIdentifierType } from '../SharedSubscription/InviteeIdentifierType'
import { KeyParamsData } from '@standardnotes/responses'
export interface DomainEventFactoryInterface {
createWebSocketMessageRequestedEvent(dto: { userUuid: string; message: JSONString }): WebSocketMessageRequestedEvent
@@ -41,6 +42,7 @@ export interface DomainEventFactoryInterface {
userUuid: string,
muteEmailsSettingUuid: string,
userHasEmailsMuted: boolean,
keyParams: KeyParamsData,
): EmailBackupRequestedEvent
createAccountDeletionRequestedEvent(dto: {
userUuid: string

View File

@@ -19,6 +19,8 @@ import { SettingDecrypterInterface } from './SettingDecrypterInterface'
import { SettingInterpreter } from './SettingInterpreter'
import { SettingRepositoryInterface } from './SettingRepositoryInterface'
import { GetUserKeyParams } from '../UseCase/GetUserKeyParams/GetUserKeyParams'
import { KeyParamsData } from '@standardnotes/responses'
describe('SettingInterpreter', () => {
let user: User
@@ -27,8 +29,10 @@ describe('SettingInterpreter', () => {
let settingRepository: SettingRepositoryInterface
let settingDecrypter: SettingDecrypterInterface
let logger: Logger
let getUserKeyParams: GetUserKeyParams
const createInterpreter = () => new SettingInterpreter(domainEventPublisher, domainEventFactory, settingRepository)
const createInterpreter = () =>
new SettingInterpreter(domainEventPublisher, domainEventFactory, settingRepository, getUserKeyParams)
beforeEach(() => {
user = {
@@ -61,6 +65,9 @@ describe('SettingInterpreter', () => {
logger.debug = jest.fn()
logger.warn = jest.fn()
logger.error = jest.fn()
getUserKeyParams = {} as jest.Mocked<GetUserKeyParams>
getUserKeyParams.execute = jest.fn().mockReturnValue({ keyParams: {} as jest.Mocked<KeyParamsData> })
})
it('should trigger session cleanup if user is disabling session user agent logging', async () => {
@@ -85,7 +92,7 @@ describe('SettingInterpreter', () => {
)
expect(domainEventPublisher.publish).toHaveBeenCalled()
expect(domainEventFactory.createEmailBackupRequestedEvent).toHaveBeenCalledWith('4-5-6', '', false)
expect(domainEventFactory.createEmailBackupRequestedEvent).toHaveBeenCalledWith('4-5-6', '', false, {})
})
it('should trigger backup if email backup setting is created - emails muted', async () => {
@@ -102,7 +109,7 @@ describe('SettingInterpreter', () => {
)
expect(domainEventPublisher.publish).toHaveBeenCalled()
expect(domainEventFactory.createEmailBackupRequestedEvent).toHaveBeenCalledWith('4-5-6', '6-7-8', true)
expect(domainEventFactory.createEmailBackupRequestedEvent).toHaveBeenCalledWith('4-5-6', '6-7-8', true, {})
})
it('should not trigger backup if email backup setting is disabled', async () => {

View File

@@ -6,15 +6,13 @@ import {
MuteFailedBackupsEmailsOption,
SettingName,
} from '@standardnotes/settings'
import { inject, injectable } from 'inversify'
import TYPES from '../../Bootstrap/Types'
import { DomainEventFactoryInterface } from '../Event/DomainEventFactoryInterface'
import { User } from '../User/User'
import { SettingInterpreterInterface } from './SettingInterpreterInterface'
import { SettingRepositoryInterface } from './SettingRepositoryInterface'
import { GetUserKeyParams } from '../UseCase/GetUserKeyParams/GetUserKeyParams'
@injectable()
export class SettingInterpreter implements SettingInterpreterInterface {
private readonly emailSettingToSubscriptionRejectionLevelMap: Map<string, string> = new Map([
[SettingName.NAMES.MuteFailedBackupsEmails, EmailLevel.LEVELS.FailedEmailBackup],
@@ -24,9 +22,10 @@ export class SettingInterpreter implements SettingInterpreterInterface {
])
constructor(
@inject(TYPES.Auth_DomainEventPublisher) private domainEventPublisher: DomainEventPublisherInterface,
@inject(TYPES.Auth_DomainEventFactory) private domainEventFactory: DomainEventFactoryInterface,
@inject(TYPES.Auth_SettingRepository) private settingRepository: SettingRepositoryInterface,
private domainEventPublisher: DomainEventPublisherInterface,
private domainEventFactory: DomainEventFactoryInterface,
private settingRepository: SettingRepositoryInterface,
private getUserKeyParams: GetUserKeyParams,
) {}
async interpretSettingUpdated(
@@ -59,8 +58,18 @@ export class SettingInterpreter implements SettingInterpreterInterface {
muteEmailsSettingUuid = muteFailedEmailsBackupSetting.uuid
}
const keyParamsResponse = await this.getUserKeyParams.execute({
authenticated: false,
userUuid,
})
await this.domainEventPublisher.publish(
this.domainEventFactory.createEmailBackupRequestedEvent(userUuid, muteEmailsSettingUuid, userHasEmailsMuted),
this.domainEventFactory.createEmailBackupRequestedEvent(
userUuid,
muteEmailsSettingUuid,
userHasEmailsMuted,
keyParamsResponse.keyParams,
),
)
}

View File

@@ -1,7 +1,6 @@
import { SettingName } from '@standardnotes/settings'
import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
import TYPES from '../../Bootstrap/Types'
import { User } from '../User/User'
import { CreateOrReplaceSettingDto } from './CreateOrReplaceSettingDto'
import { CreateOrReplaceSettingResponse } from './CreateOrReplaceSettingResponse'
@@ -14,16 +13,14 @@ import { SettingInterpreterInterface } from './SettingInterpreterInterface'
import { SettingDecrypterInterface } from './SettingDecrypterInterface'
import { SettingFactoryInterface } from './SettingFactoryInterface'
@injectable()
export class SettingService implements SettingServiceInterface {
constructor(
@inject(TYPES.Auth_SettingFactory) private factory: SettingFactoryInterface,
@inject(TYPES.Auth_SettingRepository) private settingRepository: SettingRepositoryInterface,
@inject(TYPES.Auth_SettingsAssociationService)
private factory: SettingFactoryInterface,
private settingRepository: SettingRepositoryInterface,
private settingsAssociationService: SettingsAssociationServiceInterface,
@inject(TYPES.Auth_SettingInterpreter) private settingInterpreter: SettingInterpreterInterface,
@inject(TYPES.Auth_SettingDecrypter) private settingDecrypter: SettingDecrypterInterface,
@inject(TYPES.Auth_Logger) private logger: Logger,
private settingInterpreter: SettingInterpreterInterface,
private settingDecrypter: SettingDecrypterInterface,
private logger: Logger,
) {}
async applyDefaultSettingsUponRegistration(user: User): Promise<void> {

View File

@@ -1,24 +1,22 @@
import { inject, injectable } from 'inversify'
import TYPES from '../../../Bootstrap/Types'
import { KeyParamsData } from '@standardnotes/responses'
import { Logger } from 'winston'
import { Username, Uuid } from '@standardnotes/domain-core'
import { KeyParamsFactoryInterface } from '../../User/KeyParamsFactoryInterface'
import { UserRepositoryInterface } from '../../User/UserRepositoryInterface'
import { GetUserKeyParamsDTO } from './GetUserKeyParamsDTO'
import { GetUserKeyParamsResponse } from './GetUserKeyParamsResponse'
import { UseCaseInterface } from '../UseCaseInterface'
import { Logger } from 'winston'
import { User } from '../../User/User'
import { PKCERepositoryInterface } from '../../User/PKCERepositoryInterface'
import { GetUserKeyParamsDTOV2Challenged } from './GetUserKeyParamsDTOV2Challenged'
import { KeyParamsData } from '@standardnotes/responses'
import { Username, Uuid } from '@standardnotes/domain-core'
@injectable()
export class GetUserKeyParams implements UseCaseInterface {
constructor(
@inject(TYPES.Auth_KeyParamsFactory) private keyParamsFactory: KeyParamsFactoryInterface,
@inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.Auth_PKCERepository) private pkceRepository: PKCERepositoryInterface,
@inject(TYPES.Auth_Logger) private logger: Logger,
private keyParamsFactory: KeyParamsFactoryInterface,
private userRepository: UserRepositoryInterface,
private pkceRepository: PKCERepositoryInterface,
private logger: Logger,
) {}
async execute(dto: GetUserKeyParamsDTO): Promise<GetUserKeyParamsResponse> {

View File

@@ -8,7 +8,8 @@ export interface UserRepositoryInterface {
streamTeam(memberEmail?: Email): Promise<ReadStream>
findOneByUuid(uuid: Uuid): Promise<User | null>
findOneByUsernameOrEmail(usernameOrEmail: Email | Username): Promise<User | null>
findAllCreatedBetween(start: Date, end: Date): Promise<User[]>
findAllCreatedBetween(dto: { start: Date; end: Date; offset: number; limit: number }): Promise<User[]>
countAllCreatedBetween(start: Date, end: Date): Promise<number>
save(user: User): Promise<User>
remove(user: User): Promise<User>
}

View File

@@ -8,7 +8,6 @@ import { Result, Username } 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'
@@ -18,7 +17,6 @@ import { User } from '../../Domain/User/User'
describe('AnnotatedUsersController', () => {
let updateUser: UpdateUser
let deleteAccount: DeleteAccount
let getUserKeyParams: GetUserKeyParams
let getUserSubscription: GetUserSubscription
let clearLoginAttempts: ClearLoginAttempts
let increaseLoginAttempts: IncreaseLoginAttempts
@@ -32,7 +30,6 @@ describe('AnnotatedUsersController', () => {
const createController = () =>
new AnnotatedUsersController(
updateUser,
getUserKeyParams,
deleteAccount,
getUserSubscription,
clearLoginAttempts,
@@ -51,9 +48,6 @@ describe('AnnotatedUsersController', () => {
user.uuid = '123'
user.email = 'test@test.te'
getUserKeyParams = {} as jest.Mocked<GetUserKeyParams>
getUserKeyParams.execute = jest.fn()
getUserSubscription = {} as jest.Mocked<GetUserSubscription>
getUserSubscription.execute = jest.fn()
@@ -213,60 +207,6 @@ describe('AnnotatedUsersController', () => {
expect(result.statusCode).toEqual(401)
})
it('should get user key params', async () => {
request.query = {
email: 'test@test.te',
uuid: '1-2-3',
}
getUserKeyParams.execute = jest.fn().mockReturnValue({ foo: 'bar' })
const httpResponse = <results.JsonResult>await createController().keyParams(request)
const result = await httpResponse.executeAsync()
expect(getUserKeyParams.execute).toHaveBeenCalledWith({
email: 'test@test.te',
userUuid: '1-2-3',
authenticated: false,
})
expect(result.statusCode).toEqual(200)
})
it('should get authenticated user key params', async () => {
request.query = {
email: 'test@test.te',
uuid: '1-2-3',
authenticated: 'true',
}
getUserKeyParams.execute = jest.fn().mockReturnValue({ foo: 'bar' })
const httpResponse = <results.JsonResult>await createController().keyParams(request)
const result = await httpResponse.executeAsync()
expect(getUserKeyParams.execute).toHaveBeenCalledWith({
email: 'test@test.te',
userUuid: '1-2-3',
authenticated: true,
})
expect(result.statusCode).toEqual(200)
})
it('should not get user key params if email and user uuid is missing', async () => {
request.query = {}
getUserKeyParams.execute = jest.fn().mockReturnValue({ foo: 'bar' })
const httpResponse = <results.JsonResult>await createController().keyParams(request)
const result = await httpResponse.executeAsync()
expect(getUserKeyParams.execute).not.toHaveBeenCalled()
expect(result.statusCode).toEqual(400)
})
it('should get user subscription', async () => {
request.params.userUuid = '1-2-3'
response.locals.user = {

View File

@@ -11,7 +11,6 @@ import {
} 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'
@@ -23,7 +22,6 @@ import { BaseUsersController } from './Base/BaseUsersController'
export class AnnotatedUsersController extends BaseUsersController {
constructor(
@inject(TYPES.Auth_UpdateUser) override updateUser: UpdateUser,
@inject(TYPES.Auth_GetUserKeyParams) override getUserKeyParams: GetUserKeyParams,
@inject(TYPES.Auth_DeleteAccount) override doDeleteAccount: DeleteAccount,
@inject(TYPES.Auth_GetUserSubscription) override doGetUserSubscription: GetUserSubscription,
@inject(TYPES.Auth_ClearLoginAttempts) override clearLoginAttempts: ClearLoginAttempts,
@@ -32,7 +30,6 @@ export class AnnotatedUsersController extends BaseUsersController {
) {
super(
updateUser,
getUserKeyParams,
doDeleteAccount,
doGetUserSubscription,
clearLoginAttempts,
@@ -46,11 +43,6 @@ export class AnnotatedUsersController extends BaseUsersController {
return super.update(request, response)
}
@httpGet('/params')
override async keyParams(request: Request): Promise<results.JsonResult> {
return super.keyParams(request)
}
@httpDelete('/:userUuid', TYPES.Auth_RequiredCrossServiceTokenMiddleware)
override async deleteAccount(request: Request, response: Response): Promise<results.JsonResult> {
return super.deleteAccount(request, response)

View File

@@ -5,7 +5,6 @@ import { BaseHttpController, results } from 'inversify-express-utils'
import { ChangeCredentials } from '../../../Domain/UseCase/ChangeCredentials/ChangeCredentials'
import { ClearLoginAttempts } from '../../../Domain/UseCase/ClearLoginAttempts'
import { DeleteAccount } from '../../../Domain/UseCase/DeleteAccount/DeleteAccount'
import { GetUserKeyParams } from '../../../Domain/UseCase/GetUserKeyParams/GetUserKeyParams'
import { GetUserSubscription } from '../../../Domain/UseCase/GetUserSubscription/GetUserSubscription'
import { IncreaseLoginAttempts } from '../../../Domain/UseCase/IncreaseLoginAttempts'
import { UpdateUser } from '../../../Domain/UseCase/UpdateUser'
@@ -14,7 +13,6 @@ import { ErrorTag } from '@standardnotes/responses'
export class BaseUsersController extends BaseHttpController {
constructor(
protected updateUser: UpdateUser,
protected getUserKeyParams: GetUserKeyParams,
protected doDeleteAccount: DeleteAccount,
protected doGetUserSubscription: GetUserSubscription,
protected clearLoginAttempts: ClearLoginAttempts,
@@ -26,7 +24,6 @@ export class BaseUsersController extends BaseHttpController {
if (this.controllerContainer !== undefined) {
this.controllerContainer.register('auth.users.update', this.update.bind(this))
this.controllerContainer.register('auth.users.getKeyParams', this.keyParams.bind(this))
this.controllerContainer.register('auth.users.getSubscription', this.getSubscription.bind(this))
this.controllerContainer.register('auth.users.updateCredentials', this.changeCredentials.bind(this))
this.controllerContainer.register('auth.users.delete', this.deleteAccount.bind(this))
@@ -79,30 +76,6 @@ export class BaseUsersController extends BaseHttpController {
)
}
async keyParams(request: Request): Promise<results.JsonResult> {
const email = 'email' in request.query ? <string>request.query.email : undefined
const userUuid = 'uuid' in request.query ? <string>request.query.uuid : undefined
if (!email && !userUuid) {
return this.json(
{
error: {
message: 'Missing mandatory request query parameters.',
},
},
400,
)
}
const result = await this.getUserKeyParams.execute({
email,
userUuid,
authenticated: request.query.authenticated === 'true',
})
return this.json(result.keyParams)
}
async deleteAccount(request: Request, response: Response): Promise<results.JsonResult> {
if (request.params.userUuid !== response.locals.user.uuid) {
return this.json(

View File

@@ -14,11 +14,21 @@ export class TypeORMUserRepository implements UserRepositoryInterface {
private ormRepository: Repository<User>,
) {}
async findAllCreatedBetween(start: Date, end: Date): Promise<User[]> {
async findAllCreatedBetween(dto: { start: Date; end: Date; offset: number; limit: number }): Promise<User[]> {
return this.ormRepository
.createQueryBuilder('user')
.where('user.created_at BETWEEN :start AND :end', { start: dto.start, end: dto.end })
.orderBy('user.created_at', 'ASC')
.take(dto.limit)
.skip(dto.offset)
.getMany()
}
async countAllCreatedBetween(start: Date, end: Date): Promise<number> {
return this.ormRepository
.createQueryBuilder('user')
.where('user.created_at BETWEEN :start AND :end', { start, end })
.getMany()
.getCount()
}
async save(user: User): Promise<User> {

View File

@@ -3,6 +3,48 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.20.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.20.0...@standardnotes/domain-events-infra@1.20.1) (2023-10-18)
### Bug Fixes
* remove ip attributes in opentelemetry http instrumentation ([#874](https://github.com/standardnotes/server/issues/874)) ([7ce9aba](https://github.com/standardnotes/server/commit/7ce9aba517435034f491c9f080f671285fb91b91))
# [1.20.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.19.7...@standardnotes/domain-events-infra@1.20.0) (2023-10-17)
### Features
* add wrapping sqs receive message with open telemetry ([aba4f90](https://github.com/standardnotes/server/commit/aba4f90485e1b40baac34561321a5381945aa27e))
## [1.19.7](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.19.6...@standardnotes/domain-events-infra@1.19.7) (2023-10-13)
### Bug Fixes
* reduce the amount of metrics gathered in telemetery ([32fe8d0](https://github.com/standardnotes/server/commit/32fe8d0a8523d6e1875cd0814c0cbdf27d8df7b3))
## [1.19.6](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.19.5...@standardnotes/domain-events-infra@1.19.6) (2023-10-12)
**Note:** Version bump only for package @standardnotes/domain-events-infra
## [1.19.5](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.19.4...@standardnotes/domain-events-infra@1.19.5) (2023-10-12)
### Bug Fixes
* **domain-events-infra:** retrieve all message attributes from sqs ([0c29ff1](https://github.com/standardnotes/server/commit/0c29ff1ab4886a73eae8079e80d7ff779c0e3859))
## [1.19.4](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.19.3...@standardnotes/domain-events-infra@1.19.4) (2023-10-12)
### Bug Fixes
* disable opentelemetry tracing on async worker jobs ([e0b19ef](https://github.com/standardnotes/server/commit/e0b19ef011197c854cb6e833dbaa982f661e8d17))
* **domain-events-infra:** supress typeorm internal instrumentation ([1246af2](https://github.com/standardnotes/server/commit/1246af2551ae3502734583fbc7dcebc91c16eb6b))
* enable opentelemetry tracing on async workers via sqs/sns automation ([0a90502](https://github.com/standardnotes/server/commit/0a90502658ce6f60f4a3100a518d522d6209a8fd))
## [1.19.3](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.19.2...@standardnotes/domain-events-infra@1.19.3) (2023-10-12)
### Bug Fixes
* injecting opentelemetry trace into sqs/sns coms ([4a6f90b](https://github.com/standardnotes/server/commit/4a6f90b95b39e7990b10dd4b96d549e1366383fe))
## [1.19.2](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.19.1...@standardnotes/domain-events-infra@1.19.2) (2023-10-11)
### Bug Fixes

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/domain-events-infra",
"version": "1.19.2",
"version": "1.20.1",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
@@ -27,23 +27,23 @@
"@aws-sdk/client-sns": "^3.427.0",
"@aws-sdk/client-sqs": "^3.427.0",
"@opentelemetry/api": "^1.6.0",
"@opentelemetry/exporter-metrics-otlp-proto": "^0.43.0",
"@opentelemetry/exporter-trace-otlp-grpc": "^0.43.0",
"@opentelemetry/exporter-metrics-otlp-proto": "^0.44.0",
"@opentelemetry/exporter-trace-otlp-grpc": "^0.44.0",
"@opentelemetry/id-generator-aws-xray": "^1.2.1",
"@opentelemetry/instrumentation-aws-sdk": "^0.36.0",
"@opentelemetry/instrumentation-express": "^0.33.1",
"@opentelemetry/instrumentation-http": "^0.43.0",
"@opentelemetry/instrumentation-ioredis": "^0.35.1",
"@opentelemetry/instrumentation-winston": "^0.32.1",
"@opentelemetry/instrumentation-aws-sdk": "^0.36.1",
"@opentelemetry/instrumentation-express": "^0.33.2",
"@opentelemetry/instrumentation-http": "^0.44.0",
"@opentelemetry/instrumentation-ioredis": "^0.35.2",
"@opentelemetry/instrumentation-winston": "^0.32.2",
"@opentelemetry/propagator-aws-xray": "^1.3.1",
"@opentelemetry/resource-detector-aws": "^1.3.1",
"@opentelemetry/sdk-node": "^0.43.0",
"@opentelemetry/semantic-conventions": "^1.17.0",
"@opentelemetry/resource-detector-aws": "^1.3.2",
"@opentelemetry/sdk-node": "^0.44.0",
"@opentelemetry/semantic-conventions": "^1.17.1",
"@standardnotes/domain-events": "workspace:*",
"ioredis": "^5.2.4",
"opentelemetry-instrumentation-typeorm": "^0.39.1",
"reflect-metadata": "^0.1.13",
"sqs-consumer": "^7.3.0",
"sqs-consumer": "7.4.0-canary.0",
"winston": "^3.8.1"
},
"devDependencies": {

View File

@@ -1,17 +0,0 @@
import * as OpenTelemetryApi from '@opentelemetry/api'
export class OpenTelemetryPropagation {
inject(): { traceparent?: string; tracestate?: string } {
const output = {}
OpenTelemetryApi.propagation.inject(OpenTelemetryApi.context.active(), output)
return output as { traceparent?: string; tracestate?: string }
}
extract(input: { traceparent?: string; tracestate?: string }): OpenTelemetryApi.Context {
const activeContext = OpenTelemetryApi.propagation.extract(OpenTelemetryApi.context.active(), input)
return activeContext
}
}

View File

@@ -1,6 +0,0 @@
import { Context } from '@opentelemetry/api'
export interface OpenTelemetryPropagationInterface {
inject(): { traceparent?: string; tracestate?: string }
extract(input: { traceparent?: string; tracestate?: string }): Context
}

View File

@@ -1,5 +1,5 @@
import * as OpenTelemetrySDKNode from '@opentelemetry/sdk-node'
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'
import { SemanticAttributes, SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc'
import { AWSXRayIdGenerator } from '@opentelemetry/id-generator-aws-xray'
import * as AwsResourceDetectors from '@opentelemetry/resource-detector-aws'
@@ -10,16 +10,21 @@ import { AwsInstrumentation } from '@opentelemetry/instrumentation-aws-sdk'
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-proto'
import { WinstonInstrumentation } from '@opentelemetry/instrumentation-winston'
import { IORedisInstrumentation } from '@opentelemetry/instrumentation-ioredis'
import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express'
import { IncomingMessage } from 'http'
import { Attributes } from '@opentelemetry/api'
import { OpenTelemetrySDKInterface } from './OpenTelemetrySDKInterface'
import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express'
export class OpenTelemetrySDK implements OpenTelemetrySDKInterface {
private declare sdk: OpenTelemetrySDKNode.NodeSDK
constructor(
private serviceName: string,
private spanRatio?: number,
private options: {
serviceName: string
spanRatio?: number
metricExportIntervalMillis?: number
},
) {
this.build()
}
@@ -27,24 +32,28 @@ export class OpenTelemetrySDK implements OpenTelemetrySDKInterface {
build(): void {
const otResource = OpenTelemetrySDKNode.resources.Resource.default().merge(
new OpenTelemetrySDKNode.resources.Resource({
[SemanticResourceAttributes.SERVICE_NAME]: this.serviceName,
[SemanticResourceAttributes.SERVICE_NAME]: this.options.serviceName,
}),
)
const traceExporter = new OTLPTraceExporter()
const spanProcessor = new OpenTelemetrySDKNode.tracing.BatchSpanProcessor(traceExporter)
const metricExportIntervalMillis = this.options.metricExportIntervalMillis ?? 300_000
const metricReader = new OpenTelemetrySDKNode.metrics.PeriodicExportingMetricReader({
exportIntervalMillis: 1_000,
exportIntervalMillis: metricExportIntervalMillis,
exporter: new OTLPMetricExporter(),
})
const serviceName = this.serviceName
const serviceName = this.options.serviceName
const winstonInstrumentation = new WinstonInstrumentation({
logHook: (_span, record) => {
record['resource.service.name'] = serviceName
},
})
const ratio = this.spanRatio ?? 0.01
const ratio = this.options.spanRatio ?? 0.01
this.sdk = new OpenTelemetrySDKNode.NodeSDK({
sampler: new OpenTelemetrySDKNode.tracing.TraceIdRatioBasedSampler(ratio),
@@ -56,12 +65,21 @@ export class OpenTelemetrySDK implements OpenTelemetrySDKInterface {
return isHealthCheckUrl
},
startIncomingSpanHook: (_request: IncomingMessage): Attributes => {
return {
[SemanticAttributes.HTTP_CLIENT_IP]: undefined,
}
},
}),
new ExpressInstrumentation(),
new AwsInstrumentation({
suppressInternalInstrumentation: true,
sqsExtractContextPropagationFromPayload: true,
}),
new TypeormInstrumentation({
collectParameters: false,
suppressInternalInstrumentation: true,
}),
new TypeormInstrumentation(),
winstonInstrumentation,
new IORedisInstrumentation(),
],

View File

@@ -6,11 +6,11 @@ export class OpenTelemetryTracer implements OpenTelemetryTracerInterface {
private parentSpan: OpenTelemetryApi.Span | undefined
private internalSpan: OpenTelemetryApi.Span | undefined
startSpan(parentSpanName: string, internalSpanName: string, activeContext?: OpenTelemetryApi.Context): void {
startSpan(parentSpanName: string, internalSpanName: string): void {
const tracer = OpenTelemetryApi.trace.getTracer(`${parentSpanName}-handler`)
this.parentSpan = tracer.startSpan(parentSpanName, { kind: OpenTelemetryApi.SpanKind.CONSUMER }, activeContext)
const ctx = OpenTelemetryApi.trace.setSpan(activeContext ?? OpenTelemetryApi.context.active(), this.parentSpan)
this.parentSpan = tracer.startSpan(parentSpanName, { kind: OpenTelemetryApi.SpanKind.CONSUMER })
const ctx = OpenTelemetryApi.trace.setSpan(OpenTelemetryApi.context.active(), this.parentSpan)
this.internalSpan = tracer.startSpan(internalSpanName, { kind: OpenTelemetryApi.SpanKind.INTERNAL }, ctx)
}

View File

@@ -1,7 +1,5 @@
import { Context } from '@opentelemetry/api'
export interface OpenTelemetryTracerInterface {
startSpan(parentSpanName: string, internalSpanName: string, activeContext?: Context): void
startSpan(parentSpanName: string, internalSpanName: string): void
stopSpan(): void
stopSpanWithError(error: Error): void
}

View File

@@ -2,19 +2,14 @@ import * as zlib from 'zlib'
import { MessageAttributeValue, PublishCommand, PublishCommandInput, SNSClient } from '@aws-sdk/client-sns'
import { DomainEventInterface, DomainEventPublisherInterface } from '@standardnotes/domain-events'
import { OpenTelemetryPropagationInterface } from '../OpenTelemetry/OpenTelemetryPropagationInterface'
export class SNSOpenTelemetryDomainEventPublisher implements DomainEventPublisherInterface {
constructor(
private propagator: OpenTelemetryPropagationInterface,
private snsClient: SNSClient,
private topicArn: string,
) {}
async publish(event: DomainEventInterface): Promise<void> {
const trace = this.propagator.inject()
event.meta.trace = trace
const message: PublishCommandInput = {
TopicArn: this.topicArn,
MessageAttributes: {

View File

@@ -16,7 +16,7 @@ export class SQSDomainEventSubscriberFactory implements DomainEventSubscriberFac
create(): DomainEventSubscriberInterface {
const sqsConsumer = Consumer.create({
attributeNames: ['All'],
messageAttributeNames: ['compression', 'event'],
messageAttributeNames: ['All'],
queueUrl: this.queueUrl,
sqs: this.sqs,
handleMessage:

View File

@@ -0,0 +1,58 @@
import { Consumer } from 'sqs-consumer'
import * as OpenTelemetryApi from '@opentelemetry/api'
import { Message, SQSClient } from '@aws-sdk/client-sqs'
import { DomainEventSubscriberInterface, DomainEventMessageHandlerInterface } from '@standardnotes/domain-events'
import { Logger } from 'winston'
export class SQSOpenTelemetryDomainEventSubscriber implements DomainEventSubscriberInterface {
private currentSpan: OpenTelemetryApi.Span | undefined
constructor(
private serviceName: string,
private sqs: SQSClient,
private queueUrl: string,
private domainEventMessageHandler: DomainEventMessageHandlerInterface,
private logger: Logger,
) {}
start(): void {
const sqsConsumer = Consumer.create({
attributeNames: ['All'],
messageAttributeNames: ['All'],
queueUrl: this.queueUrl,
sqs: this.sqs,
preReceiveMessageCallback: this.startParentSpan.bind(this),
handleMessage: this.handleMessage.bind(this),
})
sqsConsumer.on('error', this.handleError.bind(this))
sqsConsumer.on('processing_error', this.handleError.bind(this))
sqsConsumer.start()
}
async startParentSpan(): Promise<void> {
const tracer = OpenTelemetryApi.trace.getTracer(`${this.serviceName}-domain-event-subscriber`)
this.currentSpan = tracer.startSpan(this.serviceName, { kind: OpenTelemetryApi.SpanKind.CONSUMER })
}
async handleMessage(message: Message): Promise<void> {
await this.domainEventMessageHandler.handleMessage(<string>message.Body)
if (this.currentSpan) {
this.currentSpan.end()
this.currentSpan = undefined
}
}
handleError(error: Error): void {
this.logger.error('Error occured while handling SQS message: %O', error)
if (this.currentSpan) {
this.currentSpan.recordException(error)
this.currentSpan.end()
this.currentSpan = undefined
}
}
}

View File

@@ -1,65 +0,0 @@
import { Logger } from 'winston'
import * as zlib from 'zlib'
import {
DomainEventHandlerInterface,
DomainEventInterface,
DomainEventMessageHandlerInterface,
} from '@standardnotes/domain-events'
import { OpenTelemetryTracer } from '../OpenTelemetry/OpenTelemetryTracer'
import { OpenTelemetryTracerInterface } from '../OpenTelemetry/OpenTelemetryTracerInterface'
import { OpenTelemetryPropagationInterface } from '../OpenTelemetry/OpenTelemetryPropagationInterface'
export class SQSOpenTelemetryEventMessageHandler implements DomainEventMessageHandlerInterface {
private tracer: OpenTelemetryTracerInterface | undefined
constructor(
private serviceName: string,
private propagator: OpenTelemetryPropagationInterface,
private handlers: Map<string, DomainEventHandlerInterface>,
private logger: Logger,
) {}
async handleMessage(message: string): Promise<void> {
const messageParsed = JSON.parse(message)
const domainEventJson = zlib.unzipSync(Buffer.from(messageParsed.Message, 'base64')).toString()
const domainEvent: DomainEventInterface = JSON.parse(domainEventJson)
domainEvent.createdAt = new Date(domainEvent.createdAt)
const handler = this.handlers.get(domainEvent.type)
if (!handler) {
this.logger.debug(`Event handler for event type ${domainEvent.type} does not exist`)
return
}
this.logger.debug(`Received event: ${domainEvent.type}`)
this.tracer = new OpenTelemetryTracer()
let activeContext = undefined
if (domainEvent.meta.trace) {
this.logger.debug(`Event has trace: ${JSON.stringify(domainEvent.meta.trace)}`)
activeContext = this.propagator.extract(domainEvent.meta.trace)
}
this.tracer.startSpan(this.serviceName, domainEvent.type, activeContext)
try {
await handler.handle(domainEvent)
} catch (error) {
this.tracer.stopSpanWithError(error as Error)
throw error
}
this.tracer.stopSpan()
}
async handleError(error: Error): Promise<void> {
this.logger.error('Error occured while handling SQS message: %O', error)
}
}

View File

@@ -1,8 +1,6 @@
export * from './DirectCall/DirectCallDomainEventPublisher'
export * from './DirectCall/DirectCallEventMessageHandler'
export * from './OpenTelemetry/OpenTelemetryPropagation'
export * from './OpenTelemetry/OpenTelemetryPropagationInterface'
export * from './OpenTelemetry/OpenTelemetrySDK'
export * from './OpenTelemetry/OpenTelemetrySDKInterface'
export * from './OpenTelemetry/OpenTelemetryTracer'
@@ -19,4 +17,4 @@ export * from './SNS/SNSOpenTelemetryDomainEventPublisher'
export * from './SQS/SQSBounceNotificiationHandler'
export * from './SQS/SQSDomainEventSubscriberFactory'
export * from './SQS/SQSEventMessageHandler'
export * from './SQS/SQSOpenTelemetryEventMessageHandler'
export * from './SQS/SQSOpenTelemetryDomainEventSubscriber'

View File

@@ -3,6 +3,24 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.132.3](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.132.2...@standardnotes/domain-events@2.132.3) (2023-10-12)
### Bug Fixes
* passing key params for backup requests ([#867](https://github.com/standardnotes/server/issues/867)) ([0739816](https://github.com/standardnotes/server/commit/07398169c80e7871cd04d889f471c3eef70e1aae))
## [2.132.2](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.132.1...@standardnotes/domain-events@2.132.2) (2023-10-12)
### Bug Fixes
* disable opentelemetry tracing on async worker jobs ([e0b19ef](https://github.com/standardnotes/server/commit/e0b19ef011197c854cb6e833dbaa982f661e8d17))
## [2.132.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.132.0...@standardnotes/domain-events@2.132.1) (2023-10-12)
### Bug Fixes
* injecting opentelemetry trace into sqs/sns coms ([4a6f90b](https://github.com/standardnotes/server/commit/4a6f90b95b39e7990b10dd4b96d549e1366383fe))
# [2.132.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.131.1...@standardnotes/domain-events@2.132.0) (2023-10-11)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/domain-events",
"version": "2.132.0",
"version": "2.132.3",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -9,10 +9,6 @@ export interface DomainEventInterface {
userIdentifier: string
userIdentifierType: 'uuid' | 'email' | 'shared-vault-uuid'
}
trace?: {
traceparent?: string
tracestate?: string
}
origin: DomainEventService
target?: DomainEventService
}

View File

@@ -2,4 +2,5 @@ export interface EmailBackupRequestedEventPayload {
userUuid: string
userHasEmailsMuted: boolean
muteEmailsSettingUuid: string
keyParams: Record<string, unknown>
}

View File

@@ -3,6 +3,34 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.13.14](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.13.13...@standardnotes/event-store@1.13.14) (2023-10-18)
**Note:** Version bump only for package @standardnotes/event-store
## [1.13.13](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.13.12...@standardnotes/event-store@1.13.13) (2023-10-17)
**Note:** Version bump only for package @standardnotes/event-store
## [1.13.12](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.13.11...@standardnotes/event-store@1.13.12) (2023-10-13)
**Note:** Version bump only for package @standardnotes/event-store
## [1.13.11](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.13.10...@standardnotes/event-store@1.13.11) (2023-10-12)
**Note:** Version bump only for package @standardnotes/event-store
## [1.13.10](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.13.9...@standardnotes/event-store@1.13.10) (2023-10-12)
**Note:** Version bump only for package @standardnotes/event-store
## [1.13.9](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.13.8...@standardnotes/event-store@1.13.9) (2023-10-12)
**Note:** Version bump only for package @standardnotes/event-store
## [1.13.8](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.13.7...@standardnotes/event-store@1.13.8) (2023-10-12)
**Note:** Version bump only for package @standardnotes/event-store
## [1.13.7](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.13.6...@standardnotes/event-store@1.13.7) (2023-10-11)
**Note:** Version bump only for package @standardnotes/event-store

View File

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

View File

@@ -3,6 +3,41 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.31.1](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.31.0...@standardnotes/files-server@1.31.1) (2023-10-18)
**Note:** Version bump only for package @standardnotes/files-server
# [1.31.0](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.30.7...@standardnotes/files-server@1.31.0) (2023-10-17)
### Features
* add wrapping sqs receive message with open telemetry ([aba4f90](https://github.com/standardnotes/files/commit/aba4f90485e1b40baac34561321a5381945aa27e))
## [1.30.7](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.30.6...@standardnotes/files-server@1.30.7) (2023-10-13)
### Bug Fixes
* reduce the amount of metrics gathered in telemetery ([32fe8d0](https://github.com/standardnotes/files/commit/32fe8d0a8523d6e1875cd0814c0cbdf27d8df7b3))
## [1.30.6](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.30.5...@standardnotes/files-server@1.30.6) (2023-10-12)
**Note:** Version bump only for package @standardnotes/files-server
## [1.30.5](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.30.4...@standardnotes/files-server@1.30.5) (2023-10-12)
**Note:** Version bump only for package @standardnotes/files-server
## [1.30.4](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.30.3...@standardnotes/files-server@1.30.4) (2023-10-12)
### Bug Fixes
* disable opentelemetry tracing on async worker jobs ([e0b19ef](https://github.com/standardnotes/files/commit/e0b19ef011197c854cb6e833dbaa982f661e8d17))
* disable sqs open telemetry manual tracing in favour of automated instrumentation ([337eae7](https://github.com/standardnotes/files/commit/337eae73c6cb18ae872527b06f6c23e1c48b6dff))
## [1.30.3](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.30.2...@standardnotes/files-server@1.30.3) (2023-10-12)
**Note:** Version bump only for package @standardnotes/files-server
## [1.30.2](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.30.1...@standardnotes/files-server@1.30.2) (2023-10-11)
**Note:** Version bump only for package @standardnotes/files-server

View File

@@ -3,7 +3,7 @@ import 'reflect-metadata'
import { OpenTelemetrySDK } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.Files)
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.Files })
sdk.start()
import * as busboy from 'connect-busboy'

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