Compare commits

...

40 Commits

Author SHA1 Message Date
standardci 599a84e634 chore(release): publish new version
- @standardnotes/api-gateway@1.81.1
 - @standardnotes/home-server@1.18.4
2023-10-20 08:52:56 +00:00
Karol Sójko 1c3d19cca4 fix(api-gateway): logs severity on retry attempts 2023-10-20 10:21:10 +02:00
standardci 9986e8e7ce chore(release): publish new version
- @standardnotes/home-server@1.18.3
 - @standardnotes/revisions-server@1.47.1
 - @standardnotes/syncing-server@1.119.1
2023-10-20 08:12:46 +00:00
Karol Sójko e19f7a7b7f fix: merge mysql and mysql-legacy together (#883) 2023-10-20 09:42:10 +02:00
Karol Sójko d570146378 fix: publishing workflow 2023-10-20 09:40:54 +02:00
standardci 8a9e4370e5 chore(release): publish new version
- @standardnotes/api-gateway@1.81.0
 - @standardnotes/home-server@1.18.2
2023-10-20 07:40:07 +00:00
Karol Sójko ce357679e9 feat(api-gateway): add retry attempts on timedout requests (#885) 2023-10-20 09:24:01 +02:00
standardci acab402747 chore(release): publish new version
- @standardnotes/api-gateway@1.80.1
 - @standardnotes/home-server@1.18.1
2023-10-19 18:17:41 +00:00
Karol Sójko e385926046 fix(api-gateway): stringify error in service proxy 2023-10-19 20:01:18 +02:00
standardci e9b8d0ceb7 chore(release): publish new version
- @standardnotes/analytics@2.32.2
 - @standardnotes/api-gateway@1.80.0
 - @standardnotes/auth-server@1.160.0
 - @standardnotes/domain-core@1.38.0
 - @standardnotes/domain-events-infra@1.20.2
 - @standardnotes/domain-events@2.133.0
 - @standardnotes/event-store@1.13.15
 - @standardnotes/files-server@1.32.0
 - @standardnotes/home-server@1.18.0
 - @standardnotes/revisions-server@1.47.0
 - @standardnotes/scheduler-server@1.26.2
 - @standardnotes/security@1.16.0
 - @standardnotes/settings@1.21.46
 - @standardnotes/syncing-server@1.119.0
 - @standardnotes/websockets-server@1.17.2
2023-10-19 09:56:55 +00:00
Karol Sójko a2c1ebe675 feat: remove transition state (#882)
* fix: Dockerfile build deps

* feat: remove transition state
2023-10-19 11:38:16 +02:00
Karol Sójko 3ef8e9ea24 fix: re-enable vault tests (#875) 2023-10-18 11:14:24 +02:00
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
317 changed files with 2282 additions and 7035 deletions
-6
View File
@@ -23,12 +23,6 @@ MYSQL_USER=std_notes_user
MYSQL_PASSWORD=changeme123 MYSQL_PASSWORD=changeme123
MYSQL_ROOT_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_JWT_SECRET=f95259c5e441f5a4646d76422cfb3df4c4488842901aa50b6c51b8be2e0040e9
AUTH_SERVER_ENCRYPTION_SERVER_KEY=1087415dfde3093797f9a7ca93a49e7d7aa1861735eb0d32aae9c303b8c3d060 AUTH_SERVER_ENCRYPTION_SERVER_KEY=1087415dfde3093797f9a7ca93a49e7d7aa1861735eb0d32aae9c303b8c3d060
VALET_TOKEN_SECRET=4b886819ebe1e908077c6cae96311b48a8416bd60cc91c03060e15bdf6b30d1f VALET_TOKEN_SECRET=4b886819ebe1e908077c6cae96311b48a8416bd60cc91c03060e15bdf6b30d1f
+40
View File
@@ -9,101 +9,141 @@ updates:
directory: "/" directory: "/"
schedule: schedule:
interval: "daily" interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/packages/analytics" directory: "/packages/analytics"
schedule: schedule:
interval: "daily" interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/packages/api-gateway" directory: "/packages/api-gateway"
schedule: schedule:
interval: "daily" interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/packages/auth" directory: "/packages/auth"
schedule: schedule:
interval: "daily" interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/packages/common" directory: "/packages/common"
schedule: schedule:
interval: "daily" interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/packages/domain-core" directory: "/packages/domain-core"
schedule: schedule:
interval: "daily" interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/packages/domain-events" directory: "/packages/domain-events"
schedule: schedule:
interval: "daily" interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/packages/domain-events-infra" directory: "/packages/domain-events-infra"
schedule: schedule:
interval: "daily" interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/packages/event-store" directory: "/packages/event-store"
schedule: schedule:
interval: "daily" interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/packages/files" directory: "/packages/files"
schedule: schedule:
interval: "daily" interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/packages/home-server" directory: "/packages/home-server"
schedule: schedule:
interval: "daily" interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/packages/predicates" directory: "/packages/predicates"
schedule: schedule:
interval: "daily" interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/packages/revisions" directory: "/packages/revisions"
schedule: schedule:
interval: "daily" interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/packages/scheduler" directory: "/packages/scheduler"
schedule: schedule:
interval: "daily" interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/packages/security" directory: "/packages/security"
schedule: schedule:
interval: "daily" interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/packages/settings" directory: "/packages/settings"
schedule: schedule:
interval: "daily" interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/packages/sncrypto-node" directory: "/packages/sncrypto-node"
schedule: schedule:
interval: "daily" interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/packages/syncing-server" directory: "/packages/syncing-server"
schedule: schedule:
interval: "daily" interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/packages/time" directory: "/packages/time"
schedule: schedule:
interval: "daily" interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/packages/websockets" directory: "/packages/websockets"
schedule: schedule:
interval: "daily" interval: "daily"
allow:
- dependency-type: "direct"
- package-ecosystem: "github-actions" - package-ecosystem: "github-actions"
directory: "/" directory: "/"
+1 -1
View File
@@ -27,7 +27,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-python@v4 - uses: actions/setup-python@v4
with: with:
-11
View File
@@ -11,15 +11,6 @@ on:
type: string type: string
default: all default: all
description: The test suite to run 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: jobs:
e2e-self-hosted: e2e-self-hosted:
@@ -27,11 +18,9 @@ jobs:
with: with:
snjs_image_tag: ${{ inputs.snjs_image_tag }} snjs_image_tag: ${{ inputs.snjs_image_tag }}
suite: ${{ inputs.suite }} suite: ${{ inputs.suite }}
secrets: inherit
e2e-home-server: e2e-home-server:
uses: standardnotes/server/.github/workflows/e2e-home-server.yml@main uses: standardnotes/server/.github/workflows/e2e-home-server.yml@main
with: with:
snjs_image_tag: ${{ inputs.snjs_image_tag }} snjs_image_tag: ${{ inputs.snjs_image_tag }}
suite: ${{ inputs.suite }} suite: ${{ inputs.suite }}
secrets: inherit
+1 -1
View File
@@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Login to Docker Hub - name: Login to Docker Hub
uses: docker/login-action@v2 uses: docker/login-action@v2
+2 -26
View File
@@ -11,15 +11,6 @@ on:
type: string type: string
default: all default: all
description: The test suite to run 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: jobs:
e2e-home-server: e2e-home-server:
@@ -29,7 +20,6 @@ jobs:
matrix: matrix:
db_type: [mysql, sqlite] db_type: [mysql, sqlite]
cache_type: [redis, memory] cache_type: [redis, memory]
secondary_db_enabled: [true, false]
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -51,17 +41,9 @@ jobs:
MYSQL_DATABASE: standardnotes MYSQL_DATABASE: standardnotes
MYSQL_USER: standardnotes MYSQL_USER: standardnotes
MYSQL_PASSWORD: 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: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Set up Node - name: Set up Node
uses: actions/setup-node@v3 uses: actions/setup-node@v3
@@ -98,12 +80,6 @@ jobs:
echo "DB_DEBUG_LEVEL=all" >> packages/home-server/.env echo "DB_DEBUG_LEVEL=all" >> packages/home-server/.env
echo "REDIS_URL=redis://localhost:6379" >> 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 "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 "FILES_SERVER_URL=http://localhost:3123" >> packages/home-server/.env
echo "E2E_TESTING=true" >> packages/home-server/.env echo "E2E_TESTING=true" >> packages/home-server/.env
@@ -122,7 +98,7 @@ jobs:
if: ${{ failure() }} if: ${{ failure() }}
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: 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 retention-days: 5
path: | path: |
logs/output.log logs/output.log
+2 -14
View File
@@ -11,23 +11,12 @@ on:
type: string type: string
default: all default: all
description: The test suite to run 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: jobs:
e2e: e2e:
name: (Self Hosting) E2E Test Suite name: (Self Hosting) E2E Test Suite
strategy: strategy:
fail-fast: false fail-fast: false
matrix:
secondary_db_enabled: [true, false]
runs-on: ubuntu-latest runs-on: ubuntu-latest
services: services:
@@ -37,7 +26,7 @@ jobs:
- 9001:9001 - 9001:9001
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Set up Node - name: Set up Node
uses: actions/setup-node@v3 uses: actions/setup-node@v3
@@ -53,7 +42,6 @@ jobs:
env: env:
DB_TYPE: mysql DB_TYPE: mysql
CACHE_TYPE: redis CACHE_TYPE: redis
SECONDARY_DB_ENABLED: ${{ matrix.secondary_db_enabled }}
- name: Wait for server to start - name: Wait for server to start
run: docker/is-available.sh http://localhost:3123 $(pwd)/logs run: docker/is-available.sh http://localhost:3123 $(pwd)/logs
@@ -65,7 +53,7 @@ jobs:
if: ${{ failure() }} if: ${{ failure() }}
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: with:
name: self-hosted-failure-logs-${{ inputs.suite }}-${{ matrix.secondary_db_enabled }} name: self-hosted-failure-logs-${{ inputs.suite }}
retention-days: 5 retention-days: 5
path: | path: |
logs/*.err logs/*.err
-1
View File
@@ -31,4 +31,3 @@ jobs:
with: with:
snjs_image_tag: ${{ inputs.snjs_image_tag || 'latest' }} snjs_image_tag: ${{ inputs.snjs_image_tag || 'latest' }}
suite: ${{ inputs.suite || 'all' }} suite: ${{ inputs.suite || 'all' }}
secrets: inherit
+13 -15
View File
@@ -9,7 +9,7 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Cache build - name: Cache build
id: cache-build id: cache-build
@@ -26,7 +26,7 @@ jobs:
node-version-file: '.nvmrc' node-version-file: '.nvmrc'
- name: Install - name: Install
run: yarn install --immutable run: yarn install
- name: Build - name: Build
run: yarn build run: yarn build
@@ -37,7 +37,7 @@ jobs:
needs: build needs: build
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Cache build - name: Cache build
id: cache-build id: cache-build
@@ -54,7 +54,7 @@ jobs:
node-version-file: '.nvmrc' node-version-file: '.nvmrc'
- name: Install - name: Install
run: yarn install --immutable run: yarn install
- name: Build - name: Build
if: steps.cache-build.outputs.cache-hit != 'true' if: steps.cache-build.outputs.cache-hit != 'true'
@@ -69,7 +69,7 @@ jobs:
needs: build needs: build
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Cache build - name: Cache build
id: cache-build id: cache-build
@@ -86,7 +86,7 @@ jobs:
node-version-file: '.nvmrc' node-version-file: '.nvmrc'
- name: Install - name: Install
run: yarn install --immutable run: yarn install
- name: Build - name: Build
if: steps.cache-build.outputs.cache-hit != 'true' if: steps.cache-build.outputs.cache-hit != 'true'
@@ -102,13 +102,11 @@ jobs:
with: with:
snjs_image_tag: 'latest' snjs_image_tag: 'latest'
suite: 'base' suite: 'base'
secrets: inherit
# e2e-vaults: e2e-vaults:
# needs: build needs: build
# name: E2E Vaults Suite name: E2E Vaults Suite
# uses: standardnotes/server/.github/workflows/common-e2e.yml@main uses: standardnotes/server/.github/workflows/common-e2e.yml@main
# with: with:
# snjs_image_tag: 'latest' snjs_image_tag: 'latest'
# suite: 'vaults' suite: 'vaults'
# secrets: inherit
+13 -15
View File
@@ -9,7 +9,7 @@ jobs:
if: contains(github.event.head_commit.message, 'chore(release)') == false if: contains(github.event.head_commit.message, 'chore(release)') == false
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Cache build - name: Cache build
id: cache-build id: cache-build
@@ -37,7 +37,7 @@ jobs:
needs: build needs: build
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Cache build - name: Cache build
id: cache-build id: cache-build
@@ -69,7 +69,7 @@ jobs:
needs: build needs: build
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Cache build - name: Cache build
id: cache-build id: cache-build
@@ -102,31 +102,29 @@ jobs:
with: with:
snjs_image_tag: 'latest' snjs_image_tag: 'latest'
suite: 'base' suite: 'base'
secrets: inherit
# e2e-vaults: e2e-vaults:
# needs: build needs: build
# name: E2E Vaults Suite name: E2E Vaults Suite
# uses: standardnotes/server/.github/workflows/common-e2e.yml@main uses: standardnotes/server/.github/workflows/common-e2e.yml@main
# with: with:
# snjs_image_tag: 'latest' snjs_image_tag: 'latest'
# suite: 'vaults' suite: 'vaults'
# secrets: inherit
publish-self-hosting: publish-self-hosting:
needs: [ test, lint, e2e-base ] needs: [ test, lint, e2e-base, e2e-vaults ]
name: Publish Self Hosting Docker Image name: Publish Self Hosting Docker Image
uses: standardnotes/server/.github/workflows/common-self-hosting.yml@main uses: standardnotes/server/.github/workflows/common-self-hosting.yml@main
secrets: inherit secrets: inherit
publish-services: publish-services:
needs: [ test, lint, e2e-base ] needs: [ test, lint, e2e-base, e2e-vaults ]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v3 uses: actions/checkout@v4
with: with:
token: ${{ secrets.CI_PAT_TOKEN }} token: ${{ secrets.CI_PAT_TOKEN }}
fetch-depth: 0 fetch-depth: 0
Generated
+362 -537
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+2
View File
@@ -3,6 +3,8 @@ FROM node:20.6.1-alpine
ENV NODE_ENV production ENV NODE_ENV production
RUN apk add --update --no-cache \ RUN apk add --update --no-cache \
g++ \
make \
openssl \ openssl \
curl \ curl \
bash \ bash \
-16
View File
@@ -22,7 +22,6 @@ services:
environment: environment:
DB_TYPE: "${DB_TYPE}" DB_TYPE: "${DB_TYPE}"
CACHE_TYPE: "${CACHE_TYPE}" CACHE_TYPE: "${CACHE_TYPE}"
SECONDARY_DB_ENABLED: "${SECONDARY_DB_ENABLED}"
container_name: server-ci container_name: server-ci
ports: ports:
- 3123:3000 - 3123:3000
@@ -61,21 +60,6 @@ services:
networks: networks:
- standardnotes_self_hosted - 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: cache:
image: redis:6.0-alpine image: redis:6.0-alpine
container_name: cache-ci container_name: cache-ci
-3
View File
@@ -57,9 +57,6 @@ fi
if [ -z "$CACHE_TYPE" ]; then if [ -z "$CACHE_TYPE" ]; then
export CACHE_TYPE="redis" export CACHE_TYPE="redis"
fi fi
if [ -z "$SECONDARY_DB_ENABLED" ]; then
export SECONDARY_DB_ENABLED=false
fi
export DB_MIGRATIONS_PATH="dist/migrations/*.js" export DB_MIGRATIONS_PATH="dist/migrations/*.js"
######### #########
+35
View File
@@ -3,6 +3,41 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.32.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.32.1...@standardnotes/analytics@2.32.2) (2023-10-19)
**Note:** Version bump only for package @standardnotes/analytics
## [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) ## [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 **Note:** Version bump only for package @standardnotes/analytics
+1 -1
View File
@@ -3,7 +3,7 @@ import 'reflect-metadata'
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra' import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
import { EmailLevel, ServiceIdentifier } from '@standardnotes/domain-core' import { EmailLevel, ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.AnalyticsScheduledTask) const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AnalyticsScheduledTask })
sdk.start() sdk.start()
import { Logger } from 'winston' import { Logger } from 'winston'
+5 -4
View File
@@ -3,11 +3,11 @@ import 'reflect-metadata'
import { OpenTelemetrySDK } from '@standardnotes/domain-events-infra' import { OpenTelemetrySDK } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core' import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.AnalyticsWorker) const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AnalyticsWorker })
sdk.start() sdk.start()
import { Logger } from 'winston' import { Logger } from 'winston'
import { DomainEventSubscriberFactoryInterface } from '@standardnotes/domain-events' import { DomainEventSubscriberInterface } from '@standardnotes/domain-events'
import * as dayjs from 'dayjs' import * as dayjs from 'dayjs'
import * as utc from 'dayjs/plugin/utc' import * as utc from 'dayjs/plugin/utc'
@@ -26,6 +26,7 @@ void container.load().then((container) => {
logger.info('Starting worker...') logger.info('Starting worker...')
const subscriberFactory: DomainEventSubscriberFactoryInterface = container.get(TYPES.DomainEventSubscriberFactory) const subscriber = container.get<DomainEventSubscriberInterface>(TYPES.DomainEventSubscriber)
subscriberFactory.create().start()
subscriber.start()
}) })
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@standardnotes/analytics", "name": "@standardnotes/analytics",
"version": "2.31.3", "version": "2.32.2",
"engines": { "engines": {
"node": ">=18.0.0 <21.0.0" "node": ">=18.0.0 <21.0.0"
}, },
+12 -27
View File
@@ -5,7 +5,7 @@ import {
DomainEventHandlerInterface, DomainEventHandlerInterface,
DomainEventMessageHandlerInterface, DomainEventMessageHandlerInterface,
DomainEventPublisherInterface, DomainEventPublisherInterface,
DomainEventSubscriberFactoryInterface, DomainEventSubscriberInterface,
} from '@standardnotes/domain-events' } from '@standardnotes/domain-events'
import { MapperInterface, ServiceIdentifier } from '@standardnotes/domain-core' import { MapperInterface, ServiceIdentifier } from '@standardnotes/domain-core'
// eslint-disable-next-line @typescript-eslint/no-var-requires // eslint-disable-next-line @typescript-eslint/no-var-requires
@@ -16,11 +16,9 @@ import TYPES from './Types'
import { AppDataSource } from './DataSource' import { AppDataSource } from './DataSource'
import { DomainEventFactory } from '../Domain/Event/DomainEventFactory' import { DomainEventFactory } from '../Domain/Event/DomainEventFactory'
import { import {
OpenTelemetryPropagation,
OpenTelemetryPropagationInterface,
SNSOpenTelemetryDomainEventPublisher, SNSOpenTelemetryDomainEventPublisher,
SQSDomainEventSubscriberFactory, SQSEventMessageHandler,
SQSOpenTelemetryEventMessageHandler, SQSOpenTelemetryDomainEventSubscriber,
} from '@standardnotes/domain-events-infra' } from '@standardnotes/domain-events-infra'
import { Timer, TimerInterface } from '@standardnotes/time' import { Timer, TimerInterface } from '@standardnotes/time'
import { PeriodKeyGeneratorInterface } from '../Domain/Time/PeriodKeyGeneratorInterface' import { PeriodKeyGeneratorInterface } from '../Domain/Time/PeriodKeyGeneratorInterface'
@@ -89,10 +87,6 @@ export class ContainerConfigLoader {
}) })
container.bind<winston.Logger>(TYPES.Logger).toConstantValue(logger) container.bind<winston.Logger>(TYPES.Logger).toConstantValue(logger)
container
.bind<OpenTelemetryPropagationInterface>(TYPES.OTEL_PROPAGATOR)
.toConstantValue(new OpenTelemetryPropagation())
const snsConfig: SNSClientConfig = { const snsConfig: SNSClientConfig = {
apiVersion: 'latest', apiVersion: 'latest',
region: env.get('SNS_AWS_REGION', true), region: env.get('SNS_AWS_REGION', true),
@@ -146,11 +140,7 @@ export class ContainerConfigLoader {
container container
.bind<DomainEventPublisherInterface>(TYPES.DomainEventPublisher) .bind<DomainEventPublisherInterface>(TYPES.DomainEventPublisher)
.toConstantValue( .toConstantValue(
new SNSOpenTelemetryDomainEventPublisher( new SNSOpenTelemetryDomainEventPublisher(container.get(TYPES.SNS), container.get(TYPES.SNS_TOPIC_ARN)),
container.get<OpenTelemetryPropagationInterface>(TYPES.OTEL_PROPAGATOR),
container.get(TYPES.SNS),
container.get(TYPES.SNS_TOPIC_ARN),
),
) )
if (env.get('MIXPANEL_TOKEN', true)) { if (env.get('MIXPANEL_TOKEN', true)) {
container.bind<Mixpanel>(TYPES.MixpanelClient).toConstantValue(Mixpanel.init(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 container
.bind<DomainEventMessageHandlerInterface>(TYPES.DomainEventMessageHandler) .bind<DomainEventMessageHandlerInterface>(TYPES.DomainEventMessageHandler)
.toConstantValue( .toConstantValue(new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Logger)))
new SQSOpenTelemetryEventMessageHandler(
ServiceIdentifier.NAMES.AnalyticsWorker,
container.get<OpenTelemetryPropagationInterface>(TYPES.OTEL_PROPAGATOR),
eventHandlers,
container.get(TYPES.Logger),
),
)
container container
.bind<DomainEventSubscriberFactoryInterface>(TYPES.DomainEventSubscriberFactory) .bind<DomainEventSubscriberInterface>(TYPES.DomainEventSubscriber)
.toConstantValue( .toConstantValue(
new SQSDomainEventSubscriberFactory( new SQSOpenTelemetryDomainEventSubscriber(
container.get(TYPES.SQS), ServiceIdentifier.NAMES.AnalyticsWorker,
container.get(TYPES.SQS_QUEUE_URL), container.get<SQSClient>(TYPES.SQS),
container.get(TYPES.DomainEventMessageHandler), container.get<string>(TYPES.SQS_QUEUE_URL),
container.get<DomainEventMessageHandlerInterface>(TYPES.DomainEventMessageHandler),
container.get<winston.Logger>(TYPES.Logger),
), ),
) )
+1 -2
View File
@@ -3,7 +3,6 @@ const TYPES = {
Redis: Symbol.for('Redis'), Redis: Symbol.for('Redis'),
SNS: Symbol.for('SNS'), SNS: Symbol.for('SNS'),
SQS: Symbol.for('SQS'), SQS: Symbol.for('SQS'),
OTEL_PROPAGATOR: Symbol.for('OTEL_PROPAGATOR'),
// env vars // env vars
REDIS_URL: Symbol.for('REDIS_URL'), REDIS_URL: Symbol.for('REDIS_URL'),
SNS_TOPIC_ARN: Symbol.for('SNS_TOPIC_ARN'), SNS_TOPIC_ARN: Symbol.for('SNS_TOPIC_ARN'),
@@ -43,7 +42,7 @@ const TYPES = {
RevenueModificationMap: Symbol.for('RevenueModificationMap'), RevenueModificationMap: Symbol.for('RevenueModificationMap'),
// Services // Services
DomainEventPublisher: Symbol.for('DomainEventPublisher'), DomainEventPublisher: Symbol.for('DomainEventPublisher'),
DomainEventSubscriberFactory: Symbol.for('DomainEventSubscriberFactory'), DomainEventSubscriber: Symbol.for('DomainEventSubscriber'),
DomainEventFactory: Symbol.for('DomainEventFactory'), DomainEventFactory: Symbol.for('DomainEventFactory'),
DomainEventMessageHandler: Symbol.for('DomainEventMessageHandler'), DomainEventMessageHandler: Symbol.for('DomainEventMessageHandler'),
AnalyticsStore: Symbol.for('AnalyticsStore'), AnalyticsStore: Symbol.for('AnalyticsStore'),
+52
View File
@@ -3,6 +3,58 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.81.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.81.0...@standardnotes/api-gateway@1.81.1) (2023-10-20)
### Bug Fixes
* **api-gateway:** logs severity on retry attempts ([1c3d19c](https://github.com/standardnotes/api-gateway/commit/1c3d19cca43a7a3eba2b0d05c820de5112edf89e))
# [1.81.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.80.1...@standardnotes/api-gateway@1.81.0) (2023-10-20)
### Features
* **api-gateway:** add retry attempts on timedout requests ([#885](https://github.com/standardnotes/api-gateway/issues/885)) ([ce35767](https://github.com/standardnotes/api-gateway/commit/ce357679e9bc704ab562e9d6ca192f49a794a664))
## [1.80.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.80.0...@standardnotes/api-gateway@1.80.1) (2023-10-19)
### Bug Fixes
* **api-gateway:** stringify error in service proxy ([e385926](https://github.com/standardnotes/api-gateway/commit/e38592604644e0f52df0865ffae5b7e79d1d3d07))
# [1.80.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.79.14...@standardnotes/api-gateway@1.80.0) (2023-10-19)
### Features
* remove transition state ([#882](https://github.com/standardnotes/api-gateway/issues/882)) ([a2c1ebe](https://github.com/standardnotes/api-gateway/commit/a2c1ebe675cd5678c923715056a6966f465a15d6))
## [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) ## [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 **Note:** Version bump only for package @standardnotes/api-gateway
+1 -1
View File
@@ -3,7 +3,7 @@ import 'reflect-metadata'
import { OpenTelemetrySDK } from '@standardnotes/domain-events-infra' import { OpenTelemetrySDK } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core' import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.ApiGateway) const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.ApiGateway })
sdk.start() sdk.start()
import '../src/Controller/LegacyController' import '../src/Controller/LegacyController'
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@standardnotes/api-gateway", "name": "@standardnotes/api-gateway",
"version": "1.79.8", "version": "1.81.1",
"engines": { "engines": {
"node": ">=18.0.0 <21.0.0" "node": ">=18.0.0 <21.0.0"
}, },
@@ -103,6 +103,8 @@ export class ContainerConfigLoader {
.to(SubscriptionTokenAuthMiddleware) .to(SubscriptionTokenAuthMiddleware)
// Services // Services
container.bind<TimerInterface>(TYPES.ApiGateway_Timer).toConstantValue(new Timer())
if (isConfiguredForHomeServer) { if (isConfiguredForHomeServer) {
if (!configuration?.serviceContainer) { if (!configuration?.serviceContainer) {
throw new Error('Service container is required when configured for home server') throw new Error('Service container is required when configured for home server')
@@ -115,7 +117,6 @@ export class ContainerConfigLoader {
} else { } else {
container.bind<ServiceProxyInterface>(TYPES.ApiGateway_ServiceProxy).to(HttpServiceProxy) container.bind<ServiceProxyInterface>(TYPES.ApiGateway_ServiceProxy).to(HttpServiceProxy)
} }
container.bind<TimerInterface>(TYPES.ApiGateway_Timer).toConstantValue(new Timer())
if (isConfiguredForHomeServer) { if (isConfiguredForHomeServer) {
container container
@@ -39,7 +39,7 @@ export abstract class AuthMiddleware extends BaseMiddleware {
crossServiceToken = await this.crossServiceTokenCache.get(cacheKey) crossServiceToken = await this.crossServiceTokenCache.get(cacheKey)
} }
if (this.crossServiceTokenIsEmptyOrRequiresRevalidation(crossServiceToken)) { if (crossServiceToken === null) {
const authResponse = await this.serviceProxy.validateSession({ const authResponse = await this.serviceProxy.validateSession({
authorization: authHeaderValue, authorization: authHeaderValue,
sharedVaultOwnerContext: sharedVaultOwnerContextHeaderValue, sharedVaultOwnerContext: sharedVaultOwnerContextHeaderValue,
@@ -129,14 +129,4 @@ export abstract class AuthMiddleware extends BaseMiddleware {
return Math.min(crossServiceTokenDefaultCacheExpiration, sessionAccessExpiration, sessionRefreshExpiration) return Math.min(crossServiceTokenDefaultCacheExpiration, sessionAccessExpiration, sessionRefreshExpiration)
} }
private crossServiceTokenIsEmptyOrRequiresRevalidation(crossServiceToken: string | null) {
if (crossServiceToken === null) {
return true
}
const decodedToken = <CrossServiceTokenData>verify(crossServiceToken, this.jwtSecret, { algorithms: ['HS256'] })
return decodedToken.ongoing_transition === true
}
} }
@@ -34,16 +34,6 @@ export class ItemsController extends BaseHttpController {
) )
} }
@httpPost('/transition')
async transition(request: Request, response: Response): Promise<void> {
await this.serviceProxy.callSyncingServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'items/transition'),
request.body,
)
}
@httpGet('/:uuid') @httpGet('/:uuid')
async getItem(request: Request, response: Response): Promise<void> { async getItem(request: Request, response: Response): Promise<void> {
await this.serviceProxy.callSyncingServer( await this.serviceProxy.callSyncingServer(
@@ -1,6 +1,6 @@
import { Request, Response } from 'express' import { Request, Response } from 'express'
import { inject } from 'inversify' import { inject } from 'inversify'
import { BaseHttpController, controller, httpDelete, httpGet, httpPost } from 'inversify-express-utils' import { BaseHttpController, controller, httpDelete, httpGet } from 'inversify-express-utils'
import { TYPES } from '../../Bootstrap/Types' import { TYPES } from '../../Bootstrap/Types'
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface' import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
@@ -55,14 +55,4 @@ export class RevisionsControllerV2 extends BaseHttpController {
), ),
) )
} }
@httpPost('/revisions/transition')
async transition(request: Request, response: Response): Promise<void> {
await this.serviceProxy.callRevisionsServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'revisions/transition'),
request.body,
)
}
} }
@@ -7,6 +7,7 @@ import { Logger } from 'winston'
import { TYPES } from '../../Bootstrap/Types' import { TYPES } from '../../Bootstrap/Types'
import { CrossServiceTokenCacheInterface } from '../Cache/CrossServiceTokenCacheInterface' import { CrossServiceTokenCacheInterface } from '../Cache/CrossServiceTokenCacheInterface'
import { ServiceProxyInterface } from './ServiceProxyInterface' import { ServiceProxyInterface } from './ServiceProxyInterface'
import { TimerInterface } from '@standardnotes/time'
@injectable() @injectable()
export class HttpServiceProxy implements ServiceProxyInterface { export class HttpServiceProxy implements ServiceProxyInterface {
@@ -22,6 +23,7 @@ export class HttpServiceProxy implements ServiceProxyInterface {
@inject(TYPES.ApiGateway_HTTP_CALL_TIMEOUT) private httpCallTimeout: number, @inject(TYPES.ApiGateway_HTTP_CALL_TIMEOUT) private httpCallTimeout: number,
@inject(TYPES.ApiGateway_CrossServiceTokenCache) private crossServiceTokenCache: CrossServiceTokenCacheInterface, @inject(TYPES.ApiGateway_CrossServiceTokenCache) private crossServiceTokenCache: CrossServiceTokenCacheInterface,
@inject(TYPES.ApiGateway_Logger) private logger: Logger, @inject(TYPES.ApiGateway_Logger) private logger: Logger,
@inject(TYPES.ApiGateway_Timer) private timer: TimerInterface,
) {} ) {}
async validateSession(headers: { async validateSession(headers: {
@@ -169,6 +171,7 @@ export class HttpServiceProxy implements ServiceProxyInterface {
response: Response, response: Response,
endpointOrMethodIdentifier: string, endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string, payload?: Record<string, unknown> | string,
retryAttempt?: number,
): Promise<AxiosResponse | undefined> { ): Promise<AxiosResponse | undefined> {
try { try {
const headers: Record<string, string> = {} const headers: Record<string, string> = {}
@@ -211,14 +214,44 @@ export class HttpServiceProxy implements ServiceProxyInterface {
await this.crossServiceTokenCache.invalidate(userUuid) await this.crossServiceTokenCache.invalidate(userUuid)
} }
if (retryAttempt) {
this.logger.debug(
`Request to ${serverUrl}/${endpointOrMethodIdentifier} succeeded after ${retryAttempt} retries`,
)
}
return serviceResponse return serviceResponse
} catch (error) { } catch (error) {
const requestTimedOut =
'code' in (error as Record<string, unknown>) && (error as Record<string, unknown>).code === 'ETIMEDOUT'
const tooManyRetryAttempts = retryAttempt && retryAttempt > 2
if (!tooManyRetryAttempts && requestTimedOut) {
await this.timer.sleep(50)
const nextRetryAttempt = retryAttempt ? retryAttempt + 1 : 1
this.logger.debug(
`Retrying request to ${serverUrl}/${endpointOrMethodIdentifier} for the ${nextRetryAttempt} time`,
)
return this.getServerResponse(
serverUrl,
request,
response,
endpointOrMethodIdentifier,
payload,
nextRetryAttempt,
)
}
const errorMessage = (error as AxiosError).isAxiosError const errorMessage = (error as AxiosError).isAxiosError
? JSON.stringify((error as AxiosError).response?.data) ? JSON.stringify((error as AxiosError).response?.data)
: (error as Error).message : (error as Error).message
this.logger.error( this.logger.error(
`Could not pass the request to ${serverUrl}/${endpointOrMethodIdentifier} on underlying service: ${errorMessage}`, `Could not pass the request to ${serverUrl}/${endpointOrMethodIdentifier} on underlying service: ${JSON.stringify(
error,
)}`,
) )
this.logger.debug('Response error: %O', (error as AxiosError).response ?? error) this.logger.debug('Response error: %O', (error as AxiosError).response ?? error)
@@ -42,7 +42,6 @@ export class EndpointResolver implements EndpointResolverInterface {
// Users Controller // Users Controller
['[PATCH]:users/:userId', 'auth.users.update'], ['[PATCH]:users/:userId', 'auth.users.update'],
['[PUT]:users/:userUuid/attributes/credentials', 'auth.users.updateCredentials'], ['[PUT]:users/:userUuid/attributes/credentials', 'auth.users.updateCredentials'],
['[GET]:users/params', 'auth.users.getKeyParams'],
['[DELETE]:users/:userUuid', 'auth.users.delete'], ['[DELETE]:users/:userUuid', 'auth.users.delete'],
['[POST]:listed', 'auth.users.createListedAccount'], ['[POST]:listed', 'auth.users.createListedAccount'],
['[POST]:auth', 'auth.users.register'], ['[POST]:auth', 'auth.users.register'],
+51
View File
@@ -3,6 +3,57 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.160.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.159.2...@standardnotes/auth-server@1.160.0) (2023-10-19)
### Features
* remove transition state ([#882](https://github.com/standardnotes/server/issues/882)) ([a2c1ebe](https://github.com/standardnotes/server/commit/a2c1ebe675cd5678c923715056a6966f465a15d6))
## [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) ## [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 **Note:** Version bump only for package @standardnotes/auth-server
+13 -2
View File
@@ -3,7 +3,7 @@ import 'reflect-metadata'
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra' import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core' import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.AuthScheduledTask) const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AuthScheduledTask })
sdk.start() sdk.start()
import { Stream } from 'stream' import { Stream } from 'stream'
@@ -21,6 +21,7 @@ import { SettingRepositoryInterface } from '../src/Domain/Setting/SettingReposit
import { MuteFailedBackupsEmailsOption, SettingName } from '@standardnotes/settings' import { MuteFailedBackupsEmailsOption, SettingName } from '@standardnotes/settings'
import { RoleServiceInterface } from '../src/Domain/Role/RoleServiceInterface' import { RoleServiceInterface } from '../src/Domain/Role/RoleServiceInterface'
import { PermissionName } from '@standardnotes/features' import { PermissionName } from '@standardnotes/features'
import { GetUserKeyParams } from '../src/Domain/UseCase/GetUserKeyParams/GetUserKeyParams'
const inputArgs = process.argv.slice(2) const inputArgs = process.argv.slice(2)
const backupProvider = inputArgs[0] const backupProvider = inputArgs[0]
@@ -31,6 +32,7 @@ const requestBackups = async (
roleService: RoleServiceInterface, roleService: RoleServiceInterface,
domainEventFactory: DomainEventFactoryInterface, domainEventFactory: DomainEventFactoryInterface,
domainEventPublisher: DomainEventPublisherInterface, domainEventPublisher: DomainEventPublisherInterface,
getUserKeyParamsUseCase: GetUserKeyParams,
): Promise<void> => { ): Promise<void> => {
const settingName = SettingName.create(SettingName.NAMES.EmailBackupFrequency).getValue() const settingName = SettingName.create(SettingName.NAMES.EmailBackupFrequency).getValue()
const permissionName = PermissionName.DailyEmailBackup const permissionName = PermissionName.DailyEmailBackup
@@ -64,11 +66,17 @@ const requestBackups = async (
userHasEmailsMuted = emailsMutedSetting.value === muteEmailsSettingValue userHasEmailsMuted = emailsMutedSetting.value === muteEmailsSettingValue
} }
const keyParamsResponse = await getUserKeyParamsUseCase.execute({
userUuid: setting.setting_user_uuid,
authenticated: false,
})
await domainEventPublisher.publish( await domainEventPublisher.publish(
domainEventFactory.createEmailBackupRequestedEvent( domainEventFactory.createEmailBackupRequestedEvent(
setting.setting_user_uuid, setting.setting_user_uuid,
emailsMutedSetting?.uuid as string, emailsMutedSetting?.uuid as string,
userHasEmailsMuted, userHasEmailsMuted,
keyParamsResponse.keyParams,
), ),
) )
@@ -96,11 +104,14 @@ void container.load().then((container) => {
const roleService: RoleServiceInterface = container.get(TYPES.Auth_RoleService) const roleService: RoleServiceInterface = container.get(TYPES.Auth_RoleService)
const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.Auth_DomainEventFactory) const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.Auth_DomainEventFactory)
const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.Auth_DomainEventPublisher) const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.Auth_DomainEventPublisher)
const getUserKeyParamsUseCase: GetUserKeyParams = container.get(TYPES.Auth_GetUserKeyParams)
const tracer = new OpenTelemetryTracer() const tracer = new OpenTelemetryTracer()
tracer.startSpan(ServiceIdentifier.NAMES.AuthScheduledTask, 'backup') tracer.startSpan(ServiceIdentifier.NAMES.AuthScheduledTask, 'backup')
Promise.resolve(requestBackups(settingRepository, roleService, domainEventFactory, domainEventPublisher)) Promise.resolve(
requestBackups(settingRepository, roleService, domainEventFactory, domainEventPublisher, getUserKeyParamsUseCase),
)
.then(() => { .then(() => {
logger.info(`${backupFrequency} ${backupProvider} backup requesting complete`) logger.info(`${backupFrequency} ${backupProvider} backup requesting complete`)
+1 -1
View File
@@ -3,7 +3,7 @@ import 'reflect-metadata'
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra' import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core' import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.AuthScheduledTask) const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AuthScheduledTask })
sdk.start() sdk.start()
import { Logger } from 'winston' import { Logger } from 'winston'
+1 -1
View File
@@ -3,7 +3,7 @@ import 'reflect-metadata'
import { OpenTelemetrySDK } from '@standardnotes/domain-events-infra' import { OpenTelemetrySDK } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core' import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.Auth) const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.Auth })
sdk.start() sdk.start()
import '../src/Infra/InversifyExpressUtils/AnnotatedAuthController' import '../src/Infra/InversifyExpressUtils/AnnotatedAuthController'
+1 -1
View File
@@ -3,7 +3,7 @@ import 'reflect-metadata'
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra' import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core' import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.AuthScheduledTask) const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AuthScheduledTask })
sdk.start() sdk.start()
import { Logger } from 'winston' import { Logger } from 'winston'
-161
View File
@@ -1,161 +0,0 @@
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)
sdk.start()
import { Logger } from 'winston'
import * as dayjs from 'dayjs'
import * as utc from 'dayjs/plugin/utc'
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
import TYPES from '../src/Bootstrap/Types'
import { Env } from '../src/Bootstrap/Env'
import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
import { DomainEventFactoryInterface } from '../src/Domain/Event/DomainEventFactoryInterface'
import { UserRepositoryInterface } from '../src/Domain/User/UserRepositoryInterface'
import { TimerInterface } from '@standardnotes/time'
import { TransitionStatusRepositoryInterface } from '../src/Domain/Transition/TransitionStatusRepositoryInterface'
const inputArgs = process.argv.slice(2)
const startDateString = inputArgs[0]
const endDateString = inputArgs[1]
const forceRunParam = inputArgs[2]
const requestTransition = async (
transitionStatusRepository: TransitionStatusRepositoryInterface,
userRepository: UserRepositoryInterface,
logger: Logger,
domainEventFactory: DomainEventFactoryInterface,
domainEventPublisher: DomainEventPublisherInterface,
timer: TimerInterface,
): Promise<void> => {
const startDate = new Date(startDateString)
const endDate = new Date(endDateString)
const users = await userRepository.findAllCreatedBetween(startDate, endDate)
const timestamp = timer.getTimestampInMicroseconds()
logger.info(
`[TRANSITION ${timestamp}] Found ${users.length} users created between ${startDateString} and ${endDateString}`,
)
let usersTriggered = 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 userHasTransitionRole = userRoles.some((role) => role.name === RoleName.NAMES.TransitionUser)
const bothTransitionStatusesAreVerified =
itemsTransitionStatus?.value === TransitionStatus.STATUSES.Verified &&
revisionsTransitionStatus?.value === TransitionStatus.STATUSES.Verified
if (!userHasTransitionRole && bothTransitionStatusesAreVerified) {
continue
}
let wasTransitionRequested = false
if (
itemsTransitionStatus === null ||
itemsTransitionStatus.value === TransitionStatus.STATUSES.Failed ||
(itemsTransitionStatus.value === TransitionStatus.STATUSES.InProgress && forceRun)
) {
wasTransitionRequested = true
await transitionStatusRepository.remove(user.uuid, 'items')
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}`,
)
}
}
logger.info(
`[TRANSITION ${timestamp}] Triggered transition for ${usersTriggered} users created between ${startDateString} and ${endDateString}`,
)
}
const container = new ContainerConfigLoader('worker')
void container.load().then((container) => {
dayjs.extend(utc)
const env: Env = new Env()
env.load()
const logger: Logger = container.get(TYPES.Auth_Logger)
logger.info(`Starting transition request for users created between ${startDateString} and ${endDateString}`)
const userRepository: UserRepositoryInterface = container.get(TYPES.Auth_UserRepository)
const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.Auth_DomainEventFactory)
const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.Auth_DomainEventPublisher)
const timer = container.get<TimerInterface>(TYPES.Auth_Timer)
const transitionStatusRepository = container.get<TransitionStatusRepositoryInterface>(
TYPES.Auth_TransitionStatusRepository,
)
const tracer = new OpenTelemetryTracer()
tracer.startSpan(ServiceIdentifier.NAMES.AuthScheduledTask, 'transition')
Promise.resolve(
requestTransition(
transitionStatusRepository,
userRepository,
logger,
domainEventFactory,
domainEventPublisher,
timer,
),
)
.then(() => {
logger.info(`Finished transition request for users created between ${startDateString} and ${endDateString}`)
tracer.stopSpan()
process.exit(0)
})
.catch((error) => {
logger.error(
`Error while requesting transition for users created between ${startDateString} and ${endDateString}: ${error}`,
)
tracer.stopSpanWithError(error)
process.exit(1)
})
})
+18 -2
View File
@@ -3,7 +3,7 @@ import 'reflect-metadata'
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra' import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
import { Email, ServiceIdentifier } from '@standardnotes/domain-core' import { Email, ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.AuthScheduledTask) const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AuthScheduledTask })
sdk.start() sdk.start()
import { Logger } from 'winston' import { Logger } from 'winston'
@@ -20,6 +20,7 @@ import { MuteFailedBackupsEmailsOption, SettingName } from '@standardnotes/setti
import { RoleServiceInterface } from '../src/Domain/Role/RoleServiceInterface' import { RoleServiceInterface } from '../src/Domain/Role/RoleServiceInterface'
import { PermissionName } from '@standardnotes/features' import { PermissionName } from '@standardnotes/features'
import { UserRepositoryInterface } from '../src/Domain/User/UserRepositoryInterface' import { UserRepositoryInterface } from '../src/Domain/User/UserRepositoryInterface'
import { GetUserKeyParams } from '../src/Domain/UseCase/GetUserKeyParams/GetUserKeyParams'
const inputArgs = process.argv.slice(2) const inputArgs = process.argv.slice(2)
const backupEmail = inputArgs[0] const backupEmail = inputArgs[0]
@@ -30,6 +31,7 @@ const requestBackups = async (
roleService: RoleServiceInterface, roleService: RoleServiceInterface,
domainEventFactory: DomainEventFactoryInterface, domainEventFactory: DomainEventFactoryInterface,
domainEventPublisher: DomainEventPublisherInterface, domainEventPublisher: DomainEventPublisherInterface,
getUserKeyParamsUseCase: GetUserKeyParams,
): Promise<void> => { ): Promise<void> => {
const permissionName = PermissionName.DailyEmailBackup const permissionName = PermissionName.DailyEmailBackup
const muteEmailsSettingName = SettingName.NAMES.MuteFailedBackupsEmails const muteEmailsSettingName = SettingName.NAMES.MuteFailedBackupsEmails
@@ -57,11 +59,17 @@ const requestBackups = async (
userHasEmailsMuted = emailsMutedSetting.value === muteEmailsSettingValue userHasEmailsMuted = emailsMutedSetting.value === muteEmailsSettingValue
} }
const keyParamsResponse = await getUserKeyParamsUseCase.execute({
userUuid: user.uuid,
authenticated: false,
})
await domainEventPublisher.publish( await domainEventPublisher.publish(
domainEventFactory.createEmailBackupRequestedEvent( domainEventFactory.createEmailBackupRequestedEvent(
user.uuid, user.uuid,
emailsMutedSetting?.uuid as string, emailsMutedSetting?.uuid as string,
userHasEmailsMuted, userHasEmailsMuted,
keyParamsResponse.keyParams,
), ),
) )
@@ -84,12 +92,20 @@ void container.load().then((container) => {
const roleService: RoleServiceInterface = container.get(TYPES.Auth_RoleService) const roleService: RoleServiceInterface = container.get(TYPES.Auth_RoleService)
const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.Auth_DomainEventFactory) const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.Auth_DomainEventFactory)
const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.Auth_DomainEventPublisher) const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.Auth_DomainEventPublisher)
const getUserKeyParamsUseCase: GetUserKeyParams = container.get(TYPES.Auth_GetUserKeyParams)
const tracer = new OpenTelemetryTracer() const tracer = new OpenTelemetryTracer()
tracer.startSpan(ServiceIdentifier.NAMES.AuthScheduledTask, 'user_email_backup') tracer.startSpan(ServiceIdentifier.NAMES.AuthScheduledTask, 'user_email_backup')
Promise.resolve( Promise.resolve(
requestBackups(userRepository, settingRepository, roleService, domainEventFactory, domainEventPublisher), requestBackups(
userRepository,
settingRepository,
roleService,
domainEventFactory,
domainEventPublisher,
getUserKeyParamsUseCase,
),
) )
.then(() => { .then(() => {
logger.info(`Email backup requesting complete for ${backupEmail}`) logger.info(`Email backup requesting complete for ${backupEmail}`)
+5 -6
View File
@@ -3,7 +3,7 @@ import 'reflect-metadata'
import { OpenTelemetrySDK } from '@standardnotes/domain-events-infra' import { OpenTelemetrySDK } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core' import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.AuthWorker) const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AuthWorker })
sdk.start() sdk.start()
import { Logger } from 'winston' import { Logger } from 'winston'
@@ -11,7 +11,7 @@ import { Logger } from 'winston'
import { ContainerConfigLoader } from '../src/Bootstrap/Container' import { ContainerConfigLoader } from '../src/Bootstrap/Container'
import TYPES from '../src/Bootstrap/Types' import TYPES from '../src/Bootstrap/Types'
import { Env } from '../src/Bootstrap/Env' 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 dayjs from 'dayjs'
import * as utc from 'dayjs/plugin/utc' import * as utc from 'dayjs/plugin/utc'
@@ -26,8 +26,7 @@ void container.load().then((container) => {
logger.info('Starting worker...') logger.info('Starting worker...')
const subscriberFactory: DomainEventSubscriberFactoryInterface = container.get( const subscriber = container.get<DomainEventSubscriberInterface>(TYPES.Auth_DomainEventSubscriber)
TYPES.Auth_DomainEventSubscriberFactory,
) subscriber.start()
subscriberFactory.create().start()
}) })
@@ -1,11 +0,0 @@
'use strict'
const path = require('path')
const pnp = require(path.normalize(path.resolve(__dirname, '../../..', '.pnp.cjs'))).setup()
const index = require(path.normalize(path.resolve(__dirname, '../dist/bin/transition.js')))
Object.defineProperty(exports, '__esModule', { value: true })
exports.default = index
-7
View File
@@ -55,13 +55,6 @@ case "$COMMAND" in
node docker/entrypoint-backup.js one_drive daily node docker/entrypoint-backup.js one_drive daily
;; ;;
'transition' )
START_DATE=$1 && shift 1
END_DATE=$1 && shift 1
echo "[Docker] Starting Transition..."
node docker/entrypoint-transition.js $START_DATE $END_DATE
;;
* ) * )
echo "[Docker] Unknown command" echo "[Docker] Unknown command"
;; ;;
@@ -1,8 +1,8 @@
import { MigrationInterface, QueryRunner } from 'typeorm' import { MigrationInterface, QueryRunner } from 'typeorm'
export class UpdateUnknownContent1690975361562 implements MigrationInterface { export class RemoveTransitionRole1697704066569 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> { public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.manager.query('UPDATE items SET content_type = "Note" WHERE content_type = "Unknown"') await queryRunner.query('DELETE FROM `roles` WHERE name = "TRANSITION_USER"')
} }
public async down(): Promise<void> { public async down(): Promise<void> {
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@standardnotes/auth-server", "name": "@standardnotes/auth-server",
"version": "1.158.3", "version": "1.160.0",
"engines": { "engines": {
"node": ">=18.0.0 <21.0.0" "node": ">=18.0.0 <21.0.0"
}, },
+67 -77
View File
@@ -7,7 +7,7 @@ import {
DomainEventHandlerInterface, DomainEventHandlerInterface,
DomainEventMessageHandlerInterface, DomainEventMessageHandlerInterface,
DomainEventPublisherInterface, DomainEventPublisherInterface,
DomainEventSubscriberFactoryInterface, DomainEventSubscriberInterface,
} from '@standardnotes/domain-events' } from '@standardnotes/domain-events'
import { TimerInterface, Timer } from '@standardnotes/time' import { TimerInterface, Timer } from '@standardnotes/time'
import { UAParser } from 'ua-parser-js' import { UAParser } from 'ua-parser-js'
@@ -89,12 +89,9 @@ import { ExtensionKeyGrantedEventHandler } from '../Domain/Handler/ExtensionKeyG
import { import {
DirectCallDomainEventPublisher, DirectCallDomainEventPublisher,
DirectCallEventMessageHandler, DirectCallEventMessageHandler,
OpenTelemetryPropagation,
OpenTelemetryPropagationInterface,
SNSOpenTelemetryDomainEventPublisher, SNSOpenTelemetryDomainEventPublisher,
SQSDomainEventSubscriberFactory,
SQSEventMessageHandler, SQSEventMessageHandler,
SQSOpenTelemetryEventMessageHandler, SQSOpenTelemetryDomainEventSubscriber,
} from '@standardnotes/domain-events-infra' } from '@standardnotes/domain-events-infra'
import { GetUserSubscription } from '../Domain/UseCase/GetUserSubscription/GetUserSubscription' import { GetUserSubscription } from '../Domain/UseCase/GetUserSubscription/GetUserSubscription'
import { ChangeCredentials } from '../Domain/UseCase/ChangeCredentials/ChangeCredentials' import { ChangeCredentials } from '../Domain/UseCase/ChangeCredentials/ChangeCredentials'
@@ -261,11 +258,6 @@ import { UpdateStorageQuotaUsedForUser } from '../Domain/UseCase/UpdateStorageQu
import { SharedVaultFileUploadedEventHandler } from '../Domain/Handler/SharedVaultFileUploadedEventHandler' import { SharedVaultFileUploadedEventHandler } from '../Domain/Handler/SharedVaultFileUploadedEventHandler'
import { SharedVaultFileRemovedEventHandler } from '../Domain/Handler/SharedVaultFileRemovedEventHandler' import { SharedVaultFileRemovedEventHandler } from '../Domain/Handler/SharedVaultFileRemovedEventHandler'
import { SharedVaultFileMovedEventHandler } from '../Domain/Handler/SharedVaultFileMovedEventHandler' import { SharedVaultFileMovedEventHandler } from '../Domain/Handler/SharedVaultFileMovedEventHandler'
import { TransitionStatusRepositoryInterface } from '../Domain/Transition/TransitionStatusRepositoryInterface'
import { RedisTransitionStatusRepository } from '../Infra/Redis/RedisTransitionStatusRepository'
import { InMemoryTransitionStatusRepository } from '../Infra/InMemory/InMemoryTransitionStatusRepository'
import { TransitionStatusUpdatedEventHandler } from '../Domain/Handler/TransitionStatusUpdatedEventHandler'
import { UpdateTransitionStatus } from '../Domain/UseCase/UpdateTransitionStatus/UpdateTransitionStatus'
import { TypeORMSharedVaultUser } from '../Infra/TypeORM/TypeORMSharedVaultUser' import { TypeORMSharedVaultUser } from '../Infra/TypeORM/TypeORMSharedVaultUser'
import { SharedVaultUserPersistenceMapper } from '../Mapping/SharedVaultUserPersistenceMapper' import { SharedVaultUserPersistenceMapper } from '../Mapping/SharedVaultUserPersistenceMapper'
import { SharedVaultUserRepositoryInterface } from '../Domain/SharedVault/SharedVaultUserRepositoryInterface' import { SharedVaultUserRepositoryInterface } from '../Domain/SharedVault/SharedVaultUserRepositoryInterface'
@@ -277,6 +269,8 @@ import { UserRemovedFromSharedVaultEventHandler } from '../Domain/Handler/UserRe
import { DesignateSurvivor } from '../Domain/UseCase/DesignateSurvivor/DesignateSurvivor' import { DesignateSurvivor } from '../Domain/UseCase/DesignateSurvivor/DesignateSurvivor'
import { UserDesignatedAsSurvivorInSharedVaultEventHandler } from '../Domain/Handler/UserDesignatedAsSurvivorInSharedVaultEventHandler' import { UserDesignatedAsSurvivorInSharedVaultEventHandler } from '../Domain/Handler/UserDesignatedAsSurvivorInSharedVaultEventHandler'
import { DisableEmailSettingBasedOnEmailSubscription } from '../Domain/UseCase/DisableEmailSettingBasedOnEmailSubscription/DisableEmailSettingBasedOnEmailSubscription' import { DisableEmailSettingBasedOnEmailSubscription } from '../Domain/UseCase/DisableEmailSettingBasedOnEmailSubscription/DisableEmailSettingBasedOnEmailSubscription'
import { DomainEventFactoryInterface } from '../Domain/Event/DomainEventFactoryInterface'
import { KeyParamsFactoryInterface } from '../Domain/User/KeyParamsFactoryInterface'
export class ContainerConfigLoader { export class ContainerConfigLoader {
constructor(private mode: 'server' | 'worker' = 'server') {} constructor(private mode: 'server' | 'worker' = 'server') {}
@@ -310,9 +304,7 @@ export class ContainerConfigLoader {
} }
container.bind<winston.Logger>(TYPES.Auth_Logger).toConstantValue(logger) container.bind<winston.Logger>(TYPES.Auth_Logger).toConstantValue(logger)
container container.bind<CryptoNode>(TYPES.Auth_CryptoNode).toConstantValue(new CryptoNode())
.bind<OpenTelemetryPropagationInterface>(TYPES.Auth_OTEL_PROPAGATOR)
.toConstantValue(new OpenTelemetryPropagation())
const appDataSource = new AppDataSource({ env, runMigrations: this.mode === 'server' }) const appDataSource = new AppDataSource({ env, runMigrations: this.mode === 'server' })
await appDataSource.initialize() await appDataSource.initialize()
@@ -375,6 +367,19 @@ export class ContainerConfigLoader {
container.bind<SQSClient>(TYPES.Auth_SQS).toConstantValue(sqsClient) 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 // Mapping
container container
.bind<MapperInterface<SessionTrace, TypeORMSessionTrace>>(TYPES.Auth_SessionTracePersistenceMapper) .bind<MapperInterface<SessionTrace, TypeORMSessionTrace>>(TYPES.Auth_SessionTracePersistenceMapper)
@@ -555,7 +560,6 @@ export class ContainerConfigLoader {
container container
.bind(TYPES.Auth_DISABLE_USER_REGISTRATION) .bind(TYPES.Auth_DISABLE_USER_REGISTRATION)
.toConstantValue(env.get('DISABLE_USER_REGISTRATION', true) === 'true') .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_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.bind(TYPES.Auth_SQS_QUEUE_URL).toConstantValue(env.get('SQS_QUEUE_URL', true))
container container
@@ -636,9 +640,6 @@ export class ContainerConfigLoader {
container.get(TYPES.Auth_Timer), container.get(TYPES.Auth_Timer),
), ),
) )
container
.bind<TransitionStatusRepositoryInterface>(TYPES.Auth_TransitionStatusRepository)
.toConstantValue(new InMemoryTransitionStatusRepository())
} else { } else {
container.bind<PKCERepositoryInterface>(TYPES.Auth_PKCERepository).to(RedisPKCERepository) container.bind<PKCERepositoryInterface>(TYPES.Auth_PKCERepository).to(RedisPKCERepository)
container.bind<LockRepositoryInterface>(TYPES.Auth_LockRepository).to(LockRepository) container.bind<LockRepositoryInterface>(TYPES.Auth_LockRepository).to(LockRepository)
@@ -651,12 +652,12 @@ export class ContainerConfigLoader {
container container
.bind<SubscriptionTokenRepositoryInterface>(TYPES.Auth_SubscriptionTokenRepository) .bind<SubscriptionTokenRepositoryInterface>(TYPES.Auth_SubscriptionTokenRepository)
.to(RedisSubscriptionTokenRepository) .to(RedisSubscriptionTokenRepository)
container
.bind<TransitionStatusRepositoryInterface>(TYPES.Auth_TransitionStatusRepository)
.toConstantValue(new RedisTransitionStatusRepository(container.get<Redis>(TYPES.Auth_Redis)))
} }
// Services // Services
container
.bind<SelectorInterface<ProtocolVersion>>(TYPES.Auth_ProtocolVersionSelector)
.toConstantValue(new DeterministicSelector<ProtocolVersion>())
container.bind<UAParser>(TYPES.Auth_DeviceDetector).toConstantValue(new UAParser()) container.bind<UAParser>(TYPES.Auth_DeviceDetector).toConstantValue(new UAParser())
container.bind<SessionService>(TYPES.Auth_SessionService).to(SessionService) container.bind<SessionService>(TYPES.Auth_SessionService).to(SessionService)
container.bind<AuthResponseFactory20161215>(TYPES.Auth_AuthResponseFactory20161215).to(AuthResponseFactory20161215) container.bind<AuthResponseFactory20161215>(TYPES.Auth_AuthResponseFactory20161215).to(AuthResponseFactory20161215)
@@ -699,45 +700,61 @@ export class ContainerConfigLoader {
container.bind<DomainEventFactory>(TYPES.Auth_DomainEventFactory).to(DomainEventFactory) container.bind<DomainEventFactory>(TYPES.Auth_DomainEventFactory).to(DomainEventFactory)
container.bind<AxiosInstance>(TYPES.Auth_HTTPClient).toConstantValue(axios.create()) container.bind<AxiosInstance>(TYPES.Auth_HTTPClient).toConstantValue(axios.create())
container.bind<CrypterInterface>(TYPES.Auth_Crypter).to(CrypterNode) 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 container
.bind<SubscriptionSettingServiceInterface>(TYPES.Auth_SubscriptionSettingService) .bind<SubscriptionSettingServiceInterface>(TYPES.Auth_SubscriptionSettingService)
.to(SubscriptionSettingService) .to(SubscriptionSettingService)
container.bind<OfflineSettingServiceInterface>(TYPES.Auth_OfflineSettingService).to(OfflineSettingService) 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<ContentDecoderInterface>(TYPES.Auth_ContenDecoder).toConstantValue(new ContentDecoder())
container.bind<ClientServiceInterface>(TYPES.Auth_WebSocketsClientService).to(WebSocketsClientService) container.bind<ClientServiceInterface>(TYPES.Auth_WebSocketsClientService).to(WebSocketsClientService)
container.bind<RoleServiceInterface>(TYPES.Auth_RoleService).to(RoleService) container.bind<RoleServiceInterface>(TYPES.Auth_RoleService).to(RoleService)
container.bind<RoleToSubscriptionMapInterface>(TYPES.Auth_RoleToSubscriptionMap).to(RoleToSubscriptionMap) container.bind<RoleToSubscriptionMapInterface>(TYPES.Auth_RoleToSubscriptionMap).to(RoleToSubscriptionMap)
container
.bind<SettingsAssociationServiceInterface>(TYPES.Auth_SettingsAssociationService)
.to(SettingsAssociationService)
container container
.bind<SubscriptionSettingsAssociationServiceInterface>(TYPES.Auth_SubscriptionSettingsAssociationService) .bind<SubscriptionSettingsAssociationServiceInterface>(TYPES.Auth_SubscriptionSettingsAssociationService)
.to(SubscriptionSettingsAssociationService) .to(SubscriptionSettingsAssociationService)
container.bind<FeatureServiceInterface>(TYPES.Auth_FeatureService).to(FeatureService) 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 container
.bind<SelectorInterface<boolean>>(TYPES.Auth_BooleanSelector) .bind<SelectorInterface<boolean>>(TYPES.Auth_BooleanSelector)
.toConstantValue(new DeterministicSelector<boolean>()) .toConstantValue(new DeterministicSelector<boolean>())
container.bind<UserSubscriptionServiceInterface>(TYPES.Auth_UserSubscriptionService).to(UserSubscriptionService) 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 // Middleware
container.bind<SessionMiddleware>(TYPES.Auth_SessionMiddleware).to(SessionMiddleware) container.bind<SessionMiddleware>(TYPES.Auth_SessionMiddleware).to(SessionMiddleware)
container.bind<LockMiddleware>(TYPES.Auth_LockMiddleware).to(LockMiddleware) container.bind<LockMiddleware>(TYPES.Auth_LockMiddleware).to(LockMiddleware)
@@ -890,7 +907,6 @@ export class ContainerConfigLoader {
container.get(TYPES.Auth_SettingService), container.get(TYPES.Auth_SettingService),
), ),
) )
container.bind<GetUserKeyParams>(TYPES.Auth_GetUserKeyParams).to(GetUserKeyParams)
container.bind<UpdateUser>(TYPES.Auth_UpdateUser).to(UpdateUser) container.bind<UpdateUser>(TYPES.Auth_UpdateUser).to(UpdateUser)
container.bind<Register>(TYPES.Auth_Register).to(Register) container.bind<Register>(TYPES.Auth_Register).to(Register)
container.bind<GetActiveSessionsForUser>(TYPES.Auth_GetActiveSessionsForUser).to(GetActiveSessionsForUser) container.bind<GetActiveSessionsForUser>(TYPES.Auth_GetActiveSessionsForUser).to(GetActiveSessionsForUser)
@@ -958,15 +974,6 @@ export class ContainerConfigLoader {
container.get(TYPES.Auth_SubscriptionSettingService), container.get(TYPES.Auth_SubscriptionSettingService),
), ),
) )
container
.bind<UpdateTransitionStatus>(TYPES.Auth_UpdateTransitionStatus)
.toConstantValue(
new UpdateTransitionStatus(
container.get<TransitionStatusRepositoryInterface>(TYPES.Auth_TransitionStatusRepository),
container.get<RoleServiceInterface>(TYPES.Auth_RoleService),
container.get<winston.Logger>(TYPES.Auth_Logger),
),
)
container container
.bind<AddSharedVaultUser>(TYPES.Auth_AddSharedVaultUser) .bind<AddSharedVaultUser>(TYPES.Auth_AddSharedVaultUser)
.toConstantValue( .toConstantValue(
@@ -1147,14 +1154,6 @@ export class ContainerConfigLoader {
container.get(TYPES.Auth_Logger), container.get(TYPES.Auth_Logger),
), ),
) )
container
.bind<TransitionStatusUpdatedEventHandler>(TYPES.Auth_TransitionStatusUpdatedEventHandler)
.toConstantValue(
new TransitionStatusUpdatedEventHandler(
container.get<UpdateTransitionStatus>(TYPES.Auth_UpdateTransitionStatus),
container.get<winston.Logger>(TYPES.Auth_Logger),
),
)
container container
.bind<UserAddedToSharedVaultEventHandler>(TYPES.Auth_UserAddedToSharedVaultEventHandler) .bind<UserAddedToSharedVaultEventHandler>(TYPES.Auth_UserAddedToSharedVaultEventHandler)
.toConstantValue( .toConstantValue(
@@ -1212,7 +1211,6 @@ export class ContainerConfigLoader {
['PREDICATE_VERIFICATION_REQUESTED', container.get(TYPES.Auth_PredicateVerificationRequestedEventHandler)], ['PREDICATE_VERIFICATION_REQUESTED', container.get(TYPES.Auth_PredicateVerificationRequestedEventHandler)],
['EMAIL_SUBSCRIPTION_UNSUBSCRIBED', container.get(TYPES.Auth_EmailSubscriptionUnsubscribedEventHandler)], ['EMAIL_SUBSCRIPTION_UNSUBSCRIBED', container.get(TYPES.Auth_EmailSubscriptionUnsubscribedEventHandler)],
['PAYMENTS_ACCOUNT_DELETED', container.get(TYPES.Auth_PaymentsAccountDeletedEventHandler)], ['PAYMENTS_ACCOUNT_DELETED', container.get(TYPES.Auth_PaymentsAccountDeletedEventHandler)],
['TRANSITION_STATUS_UPDATED', container.get(TYPES.Auth_TransitionStatusUpdatedEventHandler)],
['USER_ADDED_TO_SHARED_VAULT', container.get(TYPES.Auth_UserAddedToSharedVaultEventHandler)], ['USER_ADDED_TO_SHARED_VAULT', container.get(TYPES.Auth_UserAddedToSharedVaultEventHandler)],
['USER_REMOVED_FROM_SHARED_VAULT', container.get(TYPES.Auth_UserRemovedFromSharedVaultEventHandler)], ['USER_REMOVED_FROM_SHARED_VAULT', container.get(TYPES.Auth_UserRemovedFromSharedVaultEventHandler)],
[ [
@@ -1233,24 +1231,17 @@ export class ContainerConfigLoader {
} else { } else {
container container
.bind<DomainEventMessageHandlerInterface>(TYPES.Auth_DomainEventMessageHandler) .bind<DomainEventMessageHandlerInterface>(TYPES.Auth_DomainEventMessageHandler)
.toConstantValue( .toConstantValue(new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Auth_Logger)))
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),
),
)
container container
.bind<DomainEventSubscriberFactoryInterface>(TYPES.Auth_DomainEventSubscriberFactory) .bind<DomainEventSubscriberInterface>(TYPES.Auth_DomainEventSubscriber)
.toConstantValue( .toConstantValue(
new SQSDomainEventSubscriberFactory( new SQSOpenTelemetryDomainEventSubscriber(
container.get(TYPES.Auth_SQS), ServiceIdentifier.NAMES.AuthWorker,
container.get(TYPES.Auth_SQS_QUEUE_URL), container.get<SQSClient>(TYPES.Auth_SQS),
container.get(TYPES.Auth_DomainEventMessageHandler), container.get<string>(TYPES.Auth_SQS_QUEUE_URL),
container.get<DomainEventMessageHandlerInterface>(TYPES.Auth_DomainEventMessageHandler),
container.get<winston.Logger>(TYPES.Auth_Logger),
), ),
) )
} }
@@ -1329,7 +1320,6 @@ export class ContainerConfigLoader {
.toConstantValue( .toConstantValue(
new BaseUsersController( new BaseUsersController(
container.get<UpdateUser>(TYPES.Auth_UpdateUser), container.get<UpdateUser>(TYPES.Auth_UpdateUser),
container.get<GetUserKeyParams>(TYPES.Auth_GetUserKeyParams),
container.get<DeleteAccount>(TYPES.Auth_DeleteAccount), container.get<DeleteAccount>(TYPES.Auth_DeleteAccount),
container.get<GetUserSubscription>(TYPES.Auth_GetUserSubscription), container.get<GetUserSubscription>(TYPES.Auth_GetUserSubscription),
container.get<ClearLoginAttempts>(TYPES.Auth_ClearLoginAttempts), container.get<ClearLoginAttempts>(TYPES.Auth_ClearLoginAttempts),
+1 -5
View File
@@ -3,7 +3,6 @@ const TYPES = {
Auth_Redis: Symbol.for('Auth_Redis'), Auth_Redis: Symbol.for('Auth_Redis'),
Auth_SNS: Symbol.for('Auth_SNS'), Auth_SNS: Symbol.for('Auth_SNS'),
Auth_SQS: Symbol.for('Auth_SQS'), Auth_SQS: Symbol.for('Auth_SQS'),
Auth_OTEL_PROPAGATOR: Symbol.for('Auth_OTEL_PROPAGATOR'),
// Mapping // Mapping
Auth_SessionTracePersistenceMapper: Symbol.for('Auth_SessionTracePersistenceMapper'), Auth_SessionTracePersistenceMapper: Symbol.for('Auth_SessionTracePersistenceMapper'),
Auth_AuthenticatorChallengePersistenceMapper: Symbol.for('Auth_AuthenticatorChallengePersistenceMapper'), Auth_AuthenticatorChallengePersistenceMapper: Symbol.for('Auth_AuthenticatorChallengePersistenceMapper'),
@@ -37,7 +36,6 @@ const TYPES = {
Auth_AuthenticatorRepository: Symbol.for('Auth_AuthenticatorRepository'), Auth_AuthenticatorRepository: Symbol.for('Auth_AuthenticatorRepository'),
Auth_AuthenticatorChallengeRepository: Symbol.for('Auth_AuthenticatorChallengeRepository'), Auth_AuthenticatorChallengeRepository: Symbol.for('Auth_AuthenticatorChallengeRepository'),
Auth_CacheEntryRepository: Symbol.for('Auth_CacheEntryRepository'), Auth_CacheEntryRepository: Symbol.for('Auth_CacheEntryRepository'),
Auth_TransitionStatusRepository: Symbol.for('Auth_TransitionStatusRepository'),
Auth_SharedVaultUserRepository: Symbol.for('Auth_SharedVaultUserRepository'), Auth_SharedVaultUserRepository: Symbol.for('Auth_SharedVaultUserRepository'),
// ORM // ORM
Auth_ORMOfflineSettingRepository: Symbol.for('Auth_ORMOfflineSettingRepository'), Auth_ORMOfflineSettingRepository: Symbol.for('Auth_ORMOfflineSettingRepository'),
@@ -158,7 +156,6 @@ const TYPES = {
Auth_SignInWithRecoveryCodes: Symbol.for('Auth_SignInWithRecoveryCodes'), Auth_SignInWithRecoveryCodes: Symbol.for('Auth_SignInWithRecoveryCodes'),
Auth_GetUserKeyParamsRecovery: Symbol.for('Auth_GetUserKeyParamsRecovery'), Auth_GetUserKeyParamsRecovery: Symbol.for('Auth_GetUserKeyParamsRecovery'),
Auth_UpdateStorageQuotaUsedForUser: Symbol.for('Auth_UpdateStorageQuotaUsedForUser'), Auth_UpdateStorageQuotaUsedForUser: Symbol.for('Auth_UpdateStorageQuotaUsedForUser'),
Auth_UpdateTransitionStatus: Symbol.for('Auth_UpdateTransitionStatus'),
Auth_AddSharedVaultUser: Symbol.for('Auth_AddSharedVaultUser'), Auth_AddSharedVaultUser: Symbol.for('Auth_AddSharedVaultUser'),
Auth_RemoveSharedVaultUser: Symbol.for('Auth_RemoveSharedVaultUser'), Auth_RemoveSharedVaultUser: Symbol.for('Auth_RemoveSharedVaultUser'),
Auth_DesignateSurvivor: Symbol.for('Auth_DesignateSurvivor'), Auth_DesignateSurvivor: Symbol.for('Auth_DesignateSurvivor'),
@@ -191,7 +188,6 @@ const TYPES = {
Auth_PredicateVerificationRequestedEventHandler: Symbol.for('Auth_PredicateVerificationRequestedEventHandler'), Auth_PredicateVerificationRequestedEventHandler: Symbol.for('Auth_PredicateVerificationRequestedEventHandler'),
Auth_EmailSubscriptionUnsubscribedEventHandler: Symbol.for('Auth_EmailSubscriptionUnsubscribedEventHandler'), Auth_EmailSubscriptionUnsubscribedEventHandler: Symbol.for('Auth_EmailSubscriptionUnsubscribedEventHandler'),
Auth_PaymentsAccountDeletedEventHandler: Symbol.for('Auth_PaymentsAccountDeletedEventHandler'), Auth_PaymentsAccountDeletedEventHandler: Symbol.for('Auth_PaymentsAccountDeletedEventHandler'),
Auth_TransitionStatusUpdatedEventHandler: Symbol.for('Auth_TransitionStatusUpdatedEventHandler'),
Auth_UserAddedToSharedVaultEventHandler: Symbol.for('Auth_UserAddedToSharedVaultEventHandler'), Auth_UserAddedToSharedVaultEventHandler: Symbol.for('Auth_UserAddedToSharedVaultEventHandler'),
Auth_UserRemovedFromSharedVaultEventHandler: Symbol.for('Auth_UserRemovedFromSharedVaultEventHandler'), Auth_UserRemovedFromSharedVaultEventHandler: Symbol.for('Auth_UserRemovedFromSharedVaultEventHandler'),
Auth_UserDesignatedAsSurvivorInSharedVaultEventHandler: Symbol.for( Auth_UserDesignatedAsSurvivorInSharedVaultEventHandler: Symbol.for(
@@ -219,7 +215,7 @@ const TYPES = {
Auth_WebSocketConnectionTokenDecoder: Symbol.for('Auth_WebSocketConnectionTokenDecoder'), Auth_WebSocketConnectionTokenDecoder: Symbol.for('Auth_WebSocketConnectionTokenDecoder'),
Auth_AuthenticationMethodResolver: Symbol.for('Auth_AuthenticationMethodResolver'), Auth_AuthenticationMethodResolver: Symbol.for('Auth_AuthenticationMethodResolver'),
Auth_DomainEventPublisher: Symbol.for('Auth_DomainEventPublisher'), 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_DomainEventFactory: Symbol.for('Auth_DomainEventFactory'),
Auth_DomainEventMessageHandler: Symbol.for('Auth_DomainEventMessageHandler'), Auth_DomainEventMessageHandler: Symbol.for('Auth_DomainEventMessageHandler'),
Auth_HTTPClient: Symbol.for('Auth_HTTPClient'), Auth_HTTPClient: Symbol.for('Auth_HTTPClient'),
@@ -20,7 +20,6 @@ import {
StatisticPersistenceRequestedEvent, StatisticPersistenceRequestedEvent,
SessionCreatedEvent, SessionCreatedEvent,
SessionRefreshedEvent, SessionRefreshedEvent,
TransitionRequestedEvent,
} from '@standardnotes/domain-events' } from '@standardnotes/domain-events'
import { Predicate, PredicateVerificationResult } from '@standardnotes/predicates' import { Predicate, PredicateVerificationResult } from '@standardnotes/predicates'
import { TimerInterface } from '@standardnotes/time' import { TimerInterface } from '@standardnotes/time'
@@ -28,30 +27,12 @@ import { inject, injectable } from 'inversify'
import TYPES from '../../Bootstrap/Types' import TYPES from '../../Bootstrap/Types'
import { InviteeIdentifierType } from '../SharedSubscription/InviteeIdentifierType' import { InviteeIdentifierType } from '../SharedSubscription/InviteeIdentifierType'
import { DomainEventFactoryInterface } from './DomainEventFactoryInterface' import { DomainEventFactoryInterface } from './DomainEventFactoryInterface'
import { KeyParamsData } from '@standardnotes/responses'
@injectable() @injectable()
export class DomainEventFactory implements DomainEventFactoryInterface { export class DomainEventFactory implements DomainEventFactoryInterface {
constructor(@inject(TYPES.Auth_Timer) private timer: TimerInterface) {} constructor(@inject(TYPES.Auth_Timer) private timer: TimerInterface) {}
createTransitionRequestedEvent(dto: {
userUuid: string
type: 'items' | 'revisions'
timestamp: number
}): TransitionRequestedEvent {
return {
type: 'TRANSITION_REQUESTED',
createdAt: this.timer.getUTCDate(),
meta: {
correlation: {
userIdentifier: dto.userUuid,
userIdentifierType: 'uuid',
},
origin: DomainEventService.Auth,
},
payload: dto,
}
}
createSessionCreatedEvent(dto: { userUuid: string }): SessionCreatedEvent { createSessionCreatedEvent(dto: { userUuid: string }): SessionCreatedEvent {
return { return {
type: 'SESSION_CREATED', type: 'SESSION_CREATED',
@@ -277,6 +258,7 @@ export class DomainEventFactory implements DomainEventFactoryInterface {
userUuid: string, userUuid: string,
muteEmailsSettingUuid: string, muteEmailsSettingUuid: string,
userHasEmailsMuted: boolean, userHasEmailsMuted: boolean,
keyParams: KeyParamsData,
): EmailBackupRequestedEvent { ): EmailBackupRequestedEvent {
return { return {
type: 'EMAIL_BACKUP_REQUESTED', type: 'EMAIL_BACKUP_REQUESTED',
@@ -292,6 +274,7 @@ export class DomainEventFactory implements DomainEventFactoryInterface {
userUuid, userUuid,
userHasEmailsMuted, userHasEmailsMuted,
muteEmailsSettingUuid, muteEmailsSettingUuid,
keyParams,
}, },
} }
} }
@@ -18,9 +18,9 @@ import {
StatisticPersistenceRequestedEvent, StatisticPersistenceRequestedEvent,
SessionCreatedEvent, SessionCreatedEvent,
SessionRefreshedEvent, SessionRefreshedEvent,
TransitionRequestedEvent,
} from '@standardnotes/domain-events' } from '@standardnotes/domain-events'
import { InviteeIdentifierType } from '../SharedSubscription/InviteeIdentifierType' import { InviteeIdentifierType } from '../SharedSubscription/InviteeIdentifierType'
import { KeyParamsData } from '@standardnotes/responses'
export interface DomainEventFactoryInterface { export interface DomainEventFactoryInterface {
createWebSocketMessageRequestedEvent(dto: { userUuid: string; message: JSONString }): WebSocketMessageRequestedEvent createWebSocketMessageRequestedEvent(dto: { userUuid: string; message: JSONString }): WebSocketMessageRequestedEvent
@@ -41,6 +41,7 @@ export interface DomainEventFactoryInterface {
userUuid: string, userUuid: string,
muteEmailsSettingUuid: string, muteEmailsSettingUuid: string,
userHasEmailsMuted: boolean, userHasEmailsMuted: boolean,
keyParams: KeyParamsData,
): EmailBackupRequestedEvent ): EmailBackupRequestedEvent
createAccountDeletionRequestedEvent(dto: { createAccountDeletionRequestedEvent(dto: {
userUuid: string userUuid: string
@@ -90,9 +91,4 @@ export interface DomainEventFactoryInterface {
}): StatisticPersistenceRequestedEvent }): StatisticPersistenceRequestedEvent
createSessionCreatedEvent(dto: { userUuid: string }): SessionCreatedEvent createSessionCreatedEvent(dto: { userUuid: string }): SessionCreatedEvent
createSessionRefreshedEvent(dto: { userUuid: string }): SessionRefreshedEvent createSessionRefreshedEvent(dto: { userUuid: string }): SessionRefreshedEvent
createTransitionRequestedEvent(dto: {
userUuid: string
type: 'items' | 'revisions'
timestamp: number
}): TransitionRequestedEvent
} }
@@ -1,23 +0,0 @@
import { DomainEventHandlerInterface, TransitionStatusUpdatedEvent } from '@standardnotes/domain-events'
import { UpdateTransitionStatus } from '../UseCase/UpdateTransitionStatus/UpdateTransitionStatus'
import { Logger } from 'winston'
export class TransitionStatusUpdatedEventHandler implements DomainEventHandlerInterface {
constructor(
private updateTransitionStatusUseCase: UpdateTransitionStatus,
private logger: Logger,
) {}
async handle(event: TransitionStatusUpdatedEvent): Promise<void> {
const result = await this.updateTransitionStatusUseCase.execute({
status: event.payload.status,
userUuid: event.payload.userUuid,
transitionType: event.payload.transitionType,
transitionTimestamp: event.payload.transitionTimestamp,
})
if (result.isFailed()) {
this.logger.error(`Failed to update transition status for user ${event.payload.userUuid}`)
}
}
}
@@ -19,6 +19,8 @@ import { SettingDecrypterInterface } from './SettingDecrypterInterface'
import { SettingInterpreter } from './SettingInterpreter' import { SettingInterpreter } from './SettingInterpreter'
import { SettingRepositoryInterface } from './SettingRepositoryInterface' import { SettingRepositoryInterface } from './SettingRepositoryInterface'
import { GetUserKeyParams } from '../UseCase/GetUserKeyParams/GetUserKeyParams'
import { KeyParamsData } from '@standardnotes/responses'
describe('SettingInterpreter', () => { describe('SettingInterpreter', () => {
let user: User let user: User
@@ -27,8 +29,10 @@ describe('SettingInterpreter', () => {
let settingRepository: SettingRepositoryInterface let settingRepository: SettingRepositoryInterface
let settingDecrypter: SettingDecrypterInterface let settingDecrypter: SettingDecrypterInterface
let logger: Logger let logger: Logger
let getUserKeyParams: GetUserKeyParams
const createInterpreter = () => new SettingInterpreter(domainEventPublisher, domainEventFactory, settingRepository) const createInterpreter = () =>
new SettingInterpreter(domainEventPublisher, domainEventFactory, settingRepository, getUserKeyParams)
beforeEach(() => { beforeEach(() => {
user = { user = {
@@ -61,6 +65,9 @@ describe('SettingInterpreter', () => {
logger.debug = jest.fn() logger.debug = jest.fn()
logger.warn = jest.fn() logger.warn = jest.fn()
logger.error = 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 () => { 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(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 () => { it('should trigger backup if email backup setting is created - emails muted', async () => {
@@ -102,7 +109,7 @@ describe('SettingInterpreter', () => {
) )
expect(domainEventPublisher.publish).toHaveBeenCalled() 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 () => { it('should not trigger backup if email backup setting is disabled', async () => {
@@ -6,15 +6,13 @@ import {
MuteFailedBackupsEmailsOption, MuteFailedBackupsEmailsOption,
SettingName, SettingName,
} from '@standardnotes/settings' } from '@standardnotes/settings'
import { inject, injectable } from 'inversify'
import TYPES from '../../Bootstrap/Types'
import { DomainEventFactoryInterface } from '../Event/DomainEventFactoryInterface' import { DomainEventFactoryInterface } from '../Event/DomainEventFactoryInterface'
import { User } from '../User/User' import { User } from '../User/User'
import { SettingInterpreterInterface } from './SettingInterpreterInterface' import { SettingInterpreterInterface } from './SettingInterpreterInterface'
import { SettingRepositoryInterface } from './SettingRepositoryInterface' import { SettingRepositoryInterface } from './SettingRepositoryInterface'
import { GetUserKeyParams } from '../UseCase/GetUserKeyParams/GetUserKeyParams'
@injectable()
export class SettingInterpreter implements SettingInterpreterInterface { export class SettingInterpreter implements SettingInterpreterInterface {
private readonly emailSettingToSubscriptionRejectionLevelMap: Map<string, string> = new Map([ private readonly emailSettingToSubscriptionRejectionLevelMap: Map<string, string> = new Map([
[SettingName.NAMES.MuteFailedBackupsEmails, EmailLevel.LEVELS.FailedEmailBackup], [SettingName.NAMES.MuteFailedBackupsEmails, EmailLevel.LEVELS.FailedEmailBackup],
@@ -24,9 +22,10 @@ export class SettingInterpreter implements SettingInterpreterInterface {
]) ])
constructor( constructor(
@inject(TYPES.Auth_DomainEventPublisher) private domainEventPublisher: DomainEventPublisherInterface, private domainEventPublisher: DomainEventPublisherInterface,
@inject(TYPES.Auth_DomainEventFactory) private domainEventFactory: DomainEventFactoryInterface, private domainEventFactory: DomainEventFactoryInterface,
@inject(TYPES.Auth_SettingRepository) private settingRepository: SettingRepositoryInterface, private settingRepository: SettingRepositoryInterface,
private getUserKeyParams: GetUserKeyParams,
) {} ) {}
async interpretSettingUpdated( async interpretSettingUpdated(
@@ -59,8 +58,18 @@ export class SettingInterpreter implements SettingInterpreterInterface {
muteEmailsSettingUuid = muteFailedEmailsBackupSetting.uuid muteEmailsSettingUuid = muteFailedEmailsBackupSetting.uuid
} }
const keyParamsResponse = await this.getUserKeyParams.execute({
authenticated: false,
userUuid,
})
await this.domainEventPublisher.publish( await this.domainEventPublisher.publish(
this.domainEventFactory.createEmailBackupRequestedEvent(userUuid, muteEmailsSettingUuid, userHasEmailsMuted), this.domainEventFactory.createEmailBackupRequestedEvent(
userUuid,
muteEmailsSettingUuid,
userHasEmailsMuted,
keyParamsResponse.keyParams,
),
) )
} }
@@ -1,7 +1,6 @@
import { SettingName } from '@standardnotes/settings' import { SettingName } from '@standardnotes/settings'
import { inject, injectable } from 'inversify'
import { Logger } from 'winston' import { Logger } from 'winston'
import TYPES from '../../Bootstrap/Types'
import { User } from '../User/User' import { User } from '../User/User'
import { CreateOrReplaceSettingDto } from './CreateOrReplaceSettingDto' import { CreateOrReplaceSettingDto } from './CreateOrReplaceSettingDto'
import { CreateOrReplaceSettingResponse } from './CreateOrReplaceSettingResponse' import { CreateOrReplaceSettingResponse } from './CreateOrReplaceSettingResponse'
@@ -14,16 +13,14 @@ import { SettingInterpreterInterface } from './SettingInterpreterInterface'
import { SettingDecrypterInterface } from './SettingDecrypterInterface' import { SettingDecrypterInterface } from './SettingDecrypterInterface'
import { SettingFactoryInterface } from './SettingFactoryInterface' import { SettingFactoryInterface } from './SettingFactoryInterface'
@injectable()
export class SettingService implements SettingServiceInterface { export class SettingService implements SettingServiceInterface {
constructor( constructor(
@inject(TYPES.Auth_SettingFactory) private factory: SettingFactoryInterface, private factory: SettingFactoryInterface,
@inject(TYPES.Auth_SettingRepository) private settingRepository: SettingRepositoryInterface, private settingRepository: SettingRepositoryInterface,
@inject(TYPES.Auth_SettingsAssociationService)
private settingsAssociationService: SettingsAssociationServiceInterface, private settingsAssociationService: SettingsAssociationServiceInterface,
@inject(TYPES.Auth_SettingInterpreter) private settingInterpreter: SettingInterpreterInterface, private settingInterpreter: SettingInterpreterInterface,
@inject(TYPES.Auth_SettingDecrypter) private settingDecrypter: SettingDecrypterInterface, private settingDecrypter: SettingDecrypterInterface,
@inject(TYPES.Auth_Logger) private logger: Logger, private logger: Logger,
) {} ) {}
async applyDefaultSettingsUponRegistration(user: User): Promise<void> { async applyDefaultSettingsUponRegistration(user: User): Promise<void> {
@@ -1,7 +0,0 @@
import { TransitionStatus } from '@standardnotes/domain-core'
export interface TransitionStatusRepositoryInterface {
updateStatus(userUuid: string, transitionType: 'items' | 'revisions', status: TransitionStatus): Promise<void>
getStatus(userUuid: string, transitionType: 'items' | 'revisions'): Promise<TransitionStatus | null>
remove(userUuid: string, transitionType: 'items' | 'revisions'): Promise<void>
}
@@ -9,15 +9,7 @@ import { UserRepositoryInterface } from '../../User/UserRepositoryInterface'
import { CreateCrossServiceToken } from './CreateCrossServiceToken' import { CreateCrossServiceToken } from './CreateCrossServiceToken'
import { GetSetting } from '../GetSetting/GetSetting' import { GetSetting } from '../GetSetting/GetSetting'
import { import { Result, SharedVaultUser, SharedVaultUserPermission, Timestamps, Uuid } from '@standardnotes/domain-core'
Result,
SharedVaultUser,
SharedVaultUserPermission,
Timestamps,
TransitionStatus,
Uuid,
} from '@standardnotes/domain-core'
import { TransitionStatusRepositoryInterface } from '../../Transition/TransitionStatusRepositoryInterface'
import { SharedVaultUserRepositoryInterface } from '../../SharedVault/SharedVaultUserRepositoryInterface' import { SharedVaultUserRepositoryInterface } from '../../SharedVault/SharedVaultUserRepositoryInterface'
describe('CreateCrossServiceToken', () => { describe('CreateCrossServiceToken', () => {
@@ -27,7 +19,6 @@ describe('CreateCrossServiceToken', () => {
let tokenEncoder: TokenEncoderInterface<CrossServiceTokenData> let tokenEncoder: TokenEncoderInterface<CrossServiceTokenData>
let userRepository: UserRepositoryInterface let userRepository: UserRepositoryInterface
let getSettingUseCase: GetSetting let getSettingUseCase: GetSetting
let transitionStatusRepository: TransitionStatusRepositoryInterface
let sharedVaultUserRepository: SharedVaultUserRepositoryInterface let sharedVaultUserRepository: SharedVaultUserRepositoryInterface
const jwtTTL = 60 const jwtTTL = 60
@@ -44,7 +35,6 @@ describe('CreateCrossServiceToken', () => {
userRepository, userRepository,
jwtTTL, jwtTTL,
getSettingUseCase, getSettingUseCase,
transitionStatusRepository,
sharedVaultUserRepository, sharedVaultUserRepository,
) )
@@ -78,11 +68,6 @@ describe('CreateCrossServiceToken', () => {
getSettingUseCase = {} as jest.Mocked<GetSetting> getSettingUseCase = {} as jest.Mocked<GetSetting>
getSettingUseCase.execute = jest.fn().mockReturnValue(Result.ok({ setting: { value: '100' } })) getSettingUseCase.execute = jest.fn().mockReturnValue(Result.ok({ setting: { value: '100' } }))
transitionStatusRepository = {} as jest.Mocked<TransitionStatusRepositoryInterface>
transitionStatusRepository.getStatus = jest
.fn()
.mockReturnValue(TransitionStatus.create(TransitionStatus.STATUSES.Verified).getValue())
sharedVaultUserRepository = {} as jest.Mocked<SharedVaultUserRepositoryInterface> sharedVaultUserRepository = {} as jest.Mocked<SharedVaultUserRepositoryInterface>
sharedVaultUserRepository.findByUserUuid = jest.fn().mockReturnValue([ sharedVaultUserRepository.findByUserUuid = jest.fn().mockReturnValue([
SharedVaultUser.create({ SharedVaultUser.create({
@@ -122,46 +107,6 @@ describe('CreateCrossServiceToken', () => {
email: 'test@test.te', email: 'test@test.te',
uuid: '00000000-0000-0000-0000-000000000000', uuid: '00000000-0000-0000-0000-000000000000',
}, },
ongoing_transition: false,
ongoing_revisions_transition: false,
},
60,
)
})
it('should create a cross service token for user that has an ongoing transaction', async () => {
transitionStatusRepository.getStatus = jest
.fn()
.mockReturnValue(TransitionStatus.create(TransitionStatus.STATUSES.InProgress).getValue())
await createUseCase().execute({
user,
session,
})
expect(tokenEncoder.encodeExpirableToken).toHaveBeenCalledWith(
{
roles: [
{
name: 'role1',
uuid: '1-3-4',
},
],
belongs_to_shared_vaults: [
{
shared_vault_uuid: '00000000-0000-0000-0000-000000000000',
permission: 'read',
},
],
session: {
test: 'test',
},
user: {
email: 'test@test.te',
uuid: '00000000-0000-0000-0000-000000000000',
},
ongoing_transition: true,
ongoing_revisions_transition: true,
}, },
60, 60,
) )
@@ -190,8 +135,6 @@ describe('CreateCrossServiceToken', () => {
email: 'test@test.te', email: 'test@test.te',
uuid: '00000000-0000-0000-0000-000000000000', uuid: '00000000-0000-0000-0000-000000000000',
}, },
ongoing_transition: false,
ongoing_revisions_transition: false,
}, },
60, 60,
) )
@@ -220,8 +163,6 @@ describe('CreateCrossServiceToken', () => {
email: 'test@test.te', email: 'test@test.te',
uuid: '00000000-0000-0000-0000-000000000000', uuid: '00000000-0000-0000-0000-000000000000',
}, },
ongoing_transition: false,
ongoing_revisions_transition: false,
}, },
60, 60,
) )
@@ -277,8 +218,6 @@ describe('CreateCrossServiceToken', () => {
email: 'test@test.te', email: 'test@test.te',
uuid: '00000000-0000-0000-0000-000000000000', uuid: '00000000-0000-0000-0000-000000000000',
}, },
ongoing_revisions_transition: false,
ongoing_transition: false,
}, },
60, 60,
) )
@@ -1,6 +1,6 @@
import { TokenEncoderInterface, CrossServiceTokenData } from '@standardnotes/security' import { TokenEncoderInterface, CrossServiceTokenData } from '@standardnotes/security'
import { inject, injectable } from 'inversify' import { inject, injectable } from 'inversify'
import { Result, TransitionStatus, UseCaseInterface, Uuid } from '@standardnotes/domain-core' import { Result, UseCaseInterface, Uuid } from '@standardnotes/domain-core'
import TYPES from '../../../Bootstrap/Types' import TYPES from '../../../Bootstrap/Types'
import { ProjectorInterface } from '../../../Projection/ProjectorInterface' import { ProjectorInterface } from '../../../Projection/ProjectorInterface'
@@ -12,7 +12,6 @@ import { UserRepositoryInterface } from '../../User/UserRepositoryInterface'
import { CreateCrossServiceTokenDTO } from './CreateCrossServiceTokenDTO' import { CreateCrossServiceTokenDTO } from './CreateCrossServiceTokenDTO'
import { GetSetting } from '../GetSetting/GetSetting' import { GetSetting } from '../GetSetting/GetSetting'
import { SettingName } from '@standardnotes/settings' import { SettingName } from '@standardnotes/settings'
import { TransitionStatusRepositoryInterface } from '../../Transition/TransitionStatusRepositoryInterface'
import { SharedVaultUserRepositoryInterface } from '../../SharedVault/SharedVaultUserRepositoryInterface' import { SharedVaultUserRepositoryInterface } from '../../SharedVault/SharedVaultUserRepositoryInterface'
@injectable() @injectable()
@@ -26,8 +25,6 @@ export class CreateCrossServiceToken implements UseCaseInterface<string> {
@inject(TYPES.Auth_AUTH_JWT_TTL) private jwtTTL: number, @inject(TYPES.Auth_AUTH_JWT_TTL) private jwtTTL: number,
@inject(TYPES.Auth_GetSetting) @inject(TYPES.Auth_GetSetting)
private getSettingUseCase: GetSetting, private getSettingUseCase: GetSetting,
@inject(TYPES.Auth_TransitionStatusRepository)
private transitionStatusRepository: TransitionStatusRepositoryInterface,
@inject(TYPES.Auth_SharedVaultUserRepository) private sharedVaultUserRepository: SharedVaultUserRepositoryInterface, @inject(TYPES.Auth_SharedVaultUserRepository) private sharedVaultUserRepository: SharedVaultUserRepositoryInterface,
) {} ) {}
@@ -47,9 +44,6 @@ export class CreateCrossServiceToken implements UseCaseInterface<string> {
return Result.fail(`Could not find user with uuid ${dto.userUuid}`) return Result.fail(`Could not find user with uuid ${dto.userUuid}`)
} }
const transitionStatus = await this.transitionStatusRepository.getStatus(user.uuid, 'items')
const revisionsTransitionStatus = await this.transitionStatusRepository.getStatus(user.uuid, 'revisions')
const roles = await user.roles const roles = await user.roles
const sharedVaultAssociations = await this.sharedVaultUserRepository.findByUserUuid( const sharedVaultAssociations = await this.sharedVaultUserRepository.findByUserUuid(
@@ -60,8 +54,6 @@ export class CreateCrossServiceToken implements UseCaseInterface<string> {
user: this.projectUser(user), user: this.projectUser(user),
roles: this.projectRoles(roles), roles: this.projectRoles(roles),
shared_vault_owner_context: undefined, shared_vault_owner_context: undefined,
ongoing_transition: transitionStatus?.value === TransitionStatus.STATUSES.InProgress,
ongoing_revisions_transition: revisionsTransitionStatus?.value === TransitionStatus.STATUSES.InProgress,
belongs_to_shared_vaults: sharedVaultAssociations.map((association) => ({ belongs_to_shared_vaults: sharedVaultAssociations.map((association) => ({
shared_vault_uuid: association.props.sharedVaultUuid.value, shared_vault_uuid: association.props.sharedVaultUuid.value,
permission: association.props.permission.value, permission: association.props.permission.value,
@@ -1,6 +1,5 @@
import 'reflect-metadata' import 'reflect-metadata'
import { TransitionStatus } from '@standardnotes/domain-core'
import { TimerInterface } from '@standardnotes/time' import { TimerInterface } from '@standardnotes/time'
import { TokenEncoderInterface, ValetTokenData, ValetTokenOperation } from '@standardnotes/security' import { TokenEncoderInterface, ValetTokenData, ValetTokenOperation } from '@standardnotes/security'
@@ -11,7 +10,6 @@ import { User } from '../../User/User'
import { UserSubscriptionType } from '../../Subscription/UserSubscriptionType' import { UserSubscriptionType } from '../../Subscription/UserSubscriptionType'
import { SubscriptionSettingsAssociationServiceInterface } from '../../Setting/SubscriptionSettingsAssociationServiceInterface' import { SubscriptionSettingsAssociationServiceInterface } from '../../Setting/SubscriptionSettingsAssociationServiceInterface'
import { UserSubscriptionServiceInterface } from '../../Subscription/UserSubscriptionServiceInterface' import { UserSubscriptionServiceInterface } from '../../Subscription/UserSubscriptionServiceInterface'
import { TransitionStatusRepositoryInterface } from '../../Transition/TransitionStatusRepositoryInterface'
describe('CreateValetToken', () => { describe('CreateValetToken', () => {
let tokenEncoder: TokenEncoderInterface<ValetTokenData> let tokenEncoder: TokenEncoderInterface<ValetTokenData>
@@ -23,7 +21,6 @@ describe('CreateValetToken', () => {
let regularSubscription: UserSubscription let regularSubscription: UserSubscription
let sharedSubscription: UserSubscription let sharedSubscription: UserSubscription
let user: User let user: User
let transitionStatusRepository: TransitionStatusRepositoryInterface
const createUseCase = () => const createUseCase = () =>
new CreateValetToken( new CreateValetToken(
@@ -33,7 +30,6 @@ describe('CreateValetToken', () => {
userSubscriptionService, userSubscriptionService,
timer, timer,
valetTokenTTL, valetTokenTTL,
transitionStatusRepository,
) )
beforeEach(() => { beforeEach(() => {
@@ -71,11 +67,6 @@ describe('CreateValetToken', () => {
timer = {} as jest.Mocked<TimerInterface> timer = {} as jest.Mocked<TimerInterface>
timer.getTimestampInMicroseconds = jest.fn().mockReturnValue(100) timer.getTimestampInMicroseconds = jest.fn().mockReturnValue(100)
transitionStatusRepository = {} as jest.Mocked<TransitionStatusRepositoryInterface>
transitionStatusRepository.getStatus = jest
.fn()
.mockReturnValue(TransitionStatus.create(TransitionStatus.STATUSES.Verified).getValue())
}) })
it('should create a read valet token', async () => { it('should create a read valet token', async () => {
@@ -176,7 +167,6 @@ describe('CreateValetToken', () => {
{ {
sharedSubscriptionUuid: undefined, sharedSubscriptionUuid: undefined,
regularSubscriptionUuid: '1-2-3', regularSubscriptionUuid: '1-2-3',
ongoingTransition: false,
permittedOperation: 'write', permittedOperation: 'write',
permittedResources: [ permittedResources: [
{ {
@@ -217,7 +207,6 @@ describe('CreateValetToken', () => {
{ {
sharedSubscriptionUuid: '2-3-4', sharedSubscriptionUuid: '2-3-4',
regularSubscriptionUuid: '1-2-3', regularSubscriptionUuid: '1-2-3',
ongoingTransition: false,
permittedOperation: 'write', permittedOperation: 'write',
permittedResources: [ permittedResources: [
{ {
@@ -278,7 +267,6 @@ describe('CreateValetToken', () => {
{ {
sharedSubscriptionUuid: undefined, sharedSubscriptionUuid: undefined,
regularSubscriptionUuid: '1-2-3', regularSubscriptionUuid: '1-2-3',
ongoingTransition: false,
permittedOperation: 'write', permittedOperation: 'write',
permittedResources: [ permittedResources: [
{ {

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