mirror of
https://github.com/standardnotes/server
synced 2026-05-12 15:57:16 -04:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c99334889c | |||
| 7ce9aba517 | |||
| 46257a058b | |||
| 979dc35cfc | |||
| c99a447a04 | |||
| 6dd9fd5abd | |||
| 0d37cb293c | |||
| 27d04c95a1 | |||
| cd830cdf25 | |||
| 5b06ea94f9 | |||
| aba4f90485 | |||
| 350621ed52 | |||
| 69b4324c78 | |||
| b2be0a7c0b | |||
| cab0dfba39 | |||
| 296ca47d63 | |||
| 1cad18a681 | |||
| bdd052f90c | |||
| 32fe8d0a85 | |||
| 31338066ef | |||
| 07398169c8 | |||
| 1632c83217 | |||
| 0c29ff1ab4 |
@@ -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
|
||||||
|
|||||||
@@ -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: "/"
|
||||||
|
|||||||
@@ -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,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
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
|
||||||
|
|||||||
@@ -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,7 +102,6 @@ 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
|
||||||
@@ -111,4 +110,3 @@ jobs:
|
|||||||
# with:
|
# with:
|
||||||
# snjs_image_tag: 'latest'
|
# snjs_image_tag: 'latest'
|
||||||
# suite: 'vaults'
|
# suite: 'vaults'
|
||||||
# secrets: inherit
|
|
||||||
|
|||||||
@@ -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,7 +102,6 @@ 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
|
||||||
@@ -111,7 +110,6 @@ jobs:
|
|||||||
# 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 ]
|
||||||
@@ -126,7 +124,7 @@ jobs:
|
|||||||
|
|
||||||
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
|
||||||
|
|||||||
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
@@ -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,6 +3,30 @@
|
|||||||
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.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)
|
## [2.31.4](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.31.3...@standardnotes/analytics@2.31.4) (2023-10-12)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -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'
|
||||||
|
|||||||
@@ -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,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/analytics",
|
"name": "@standardnotes/analytics",
|
||||||
"version": "2.31.4",
|
"version": "2.32.1",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <21.0.0"
|
"node": ">=18.0.0 <21.0.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import {
|
|||||||
DomainEventHandlerInterface,
|
DomainEventHandlerInterface,
|
||||||
DomainEventMessageHandlerInterface,
|
DomainEventMessageHandlerInterface,
|
||||||
DomainEventPublisherInterface,
|
DomainEventPublisherInterface,
|
||||||
DomainEventSubscriberFactoryInterface,
|
DomainEventSubscriberInterface,
|
||||||
} from '@standardnotes/domain-events'
|
} from '@standardnotes/domain-events'
|
||||||
import { MapperInterface } from '@standardnotes/domain-core'
|
import { MapperInterface, ServiceIdentifier } from '@standardnotes/domain-core'
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const Mixpanel = require('mixpanel')
|
const Mixpanel = require('mixpanel')
|
||||||
|
|
||||||
@@ -17,8 +17,8 @@ import { AppDataSource } from './DataSource'
|
|||||||
import { DomainEventFactory } from '../Domain/Event/DomainEventFactory'
|
import { DomainEventFactory } from '../Domain/Event/DomainEventFactory'
|
||||||
import {
|
import {
|
||||||
SNSOpenTelemetryDomainEventPublisher,
|
SNSOpenTelemetryDomainEventPublisher,
|
||||||
SQSDomainEventSubscriberFactory,
|
|
||||||
SQSEventMessageHandler,
|
SQSEventMessageHandler,
|
||||||
|
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'
|
||||||
@@ -240,12 +240,14 @@ export class ContainerConfigLoader {
|
|||||||
.bind<DomainEventMessageHandlerInterface>(TYPES.DomainEventMessageHandler)
|
.bind<DomainEventMessageHandlerInterface>(TYPES.DomainEventMessageHandler)
|
||||||
.toConstantValue(new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Logger)))
|
.toConstantValue(new SQSEventMessageHandler(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),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -42,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'),
|
||||||
|
|||||||
@@ -3,6 +3,30 @@
|
|||||||
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.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)
|
## [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
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|||||||
@@ -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,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/api-gateway",
|
"name": "@standardnotes/api-gateway",
|
||||||
"version": "1.79.9",
|
"version": "1.79.14",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <21.0.0"
|
"node": ">=18.0.0 <21.0.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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'],
|
||||||
|
|||||||
@@ -3,6 +3,44 @@
|
|||||||
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.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)
|
## [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
|
### Bug Fixes
|
||||||
|
|||||||
@@ -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`)
|
||||||
|
|
||||||
|
|||||||
@@ -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'
|
||||||
|
|||||||
@@ -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'
|
||||||
|
|||||||
@@ -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'
|
||||||
|
|||||||
@@ -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, RoleName, TransitionStatus } from '@standardnotes/domain-core'
|
import { ServiceIdentifier, RoleName, TransitionStatus } from '@standardnotes/domain-core'
|
||||||
|
|
||||||
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.AuthScheduledTask)
|
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AuthScheduledTask })
|
||||||
sdk.start()
|
sdk.start()
|
||||||
|
|
||||||
import { Logger } from 'winston'
|
import { Logger } from 'winston'
|
||||||
@@ -35,78 +35,87 @@ const requestTransition = async (
|
|||||||
const startDate = new Date(startDateString)
|
const startDate = new Date(startDateString)
|
||||||
const endDate = new Date(endDateString)
|
const endDate = new Date(endDateString)
|
||||||
|
|
||||||
const users = await userRepository.findAllCreatedBetween(startDate, endDate)
|
const usersCount = await userRepository.countAllCreatedBetween(startDate, endDate)
|
||||||
|
|
||||||
const timestamp = timer.getTimestampInMicroseconds()
|
const timestamp = timer.getTimestampInMicroseconds()
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
`[TRANSITION ${timestamp}] Found ${users.length} users created between ${startDateString} and ${endDateString}`,
|
`[TRANSITION ${timestamp}] Found ${usersCount} users created between ${startDateString} and ${endDateString}`,
|
||||||
)
|
)
|
||||||
|
|
||||||
let usersTriggered = 0
|
let itemTransitionsTriggered = 0
|
||||||
|
let revisionTransitionsTriggered = 0
|
||||||
const forceRun = forceRunParam === 'true'
|
const forceRun = forceRunParam === 'true'
|
||||||
for (const user of users) {
|
|
||||||
const itemsTransitionStatus = await transitionStatusRepository.getStatus(user.uuid, 'items')
|
|
||||||
const revisionsTransitionStatus = await transitionStatusRepository.getStatus(user.uuid, 'revisions')
|
|
||||||
|
|
||||||
const userRoles = await user.roles
|
const pageLimit = 100
|
||||||
|
const totalPages = Math.ceil(usersCount / pageLimit)
|
||||||
|
for (let currentPage = 1; currentPage <= totalPages; currentPage++) {
|
||||||
|
const users = await userRepository.findAllCreatedBetween({
|
||||||
|
start: startDate,
|
||||||
|
end: endDate,
|
||||||
|
offset: (currentPage - 1) * pageLimit,
|
||||||
|
limit: pageLimit,
|
||||||
|
})
|
||||||
|
|
||||||
const userHasTransitionRole = userRoles.some((role) => role.name === RoleName.NAMES.TransitionUser)
|
for (const user of users) {
|
||||||
const bothTransitionStatusesAreVerified =
|
const itemsTransitionStatus = await transitionStatusRepository.getStatus(user.uuid, 'items')
|
||||||
itemsTransitionStatus?.value === TransitionStatus.STATUSES.Verified &&
|
const revisionsTransitionStatus = await transitionStatusRepository.getStatus(user.uuid, 'revisions')
|
||||||
revisionsTransitionStatus?.value === TransitionStatus.STATUSES.Verified
|
|
||||||
|
|
||||||
if (!userHasTransitionRole && bothTransitionStatusesAreVerified) {
|
const userRoles = await user.roles
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
let wasTransitionRequested = false
|
const userHasTransitionRole = userRoles.some((role) => role.name === RoleName.NAMES.TransitionUser)
|
||||||
|
const bothTransitionStatusesAreVerified =
|
||||||
|
itemsTransitionStatus?.value === TransitionStatus.STATUSES.Verified &&
|
||||||
|
revisionsTransitionStatus?.value === TransitionStatus.STATUSES.Verified
|
||||||
|
|
||||||
if (
|
if (!userHasTransitionRole && bothTransitionStatusesAreVerified) {
|
||||||
itemsTransitionStatus === null ||
|
continue
|
||||||
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(
|
logger.info(
|
||||||
`[TRANSITION ${timestamp}] Transition requested for user ${user.uuid} - items status: ${itemsTransitionStatus?.value}, revisions status: ${revisionsTransitionStatus?.value}, has transition role: ${userHasTransitionRole}`,
|
`[TRANSITION ${timestamp}] Transition status for user ${user.uuid} - items status: ${itemsTransitionStatus?.value}, revisions status: ${revisionsTransitionStatus?.value}, has transition role: ${userHasTransitionRole}`,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
itemsTransitionStatus === null ||
|
||||||
|
itemsTransitionStatus.value === TransitionStatus.STATUSES.Failed ||
|
||||||
|
(itemsTransitionStatus.value === TransitionStatus.STATUSES.InProgress && forceRun)
|
||||||
|
) {
|
||||||
|
await transitionStatusRepository.remove(user.uuid, 'items')
|
||||||
|
|
||||||
|
await domainEventPublisher.publish(
|
||||||
|
domainEventFactory.createTransitionRequestedEvent({
|
||||||
|
userUuid: user.uuid,
|
||||||
|
type: 'items',
|
||||||
|
timestamp,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
itemTransitionsTriggered++
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
revisionsTransitionStatus === null ||
|
||||||
|
revisionsTransitionStatus.value === TransitionStatus.STATUSES.Failed ||
|
||||||
|
(revisionsTransitionStatus.value === TransitionStatus.STATUSES.InProgress && forceRun)
|
||||||
|
) {
|
||||||
|
await transitionStatusRepository.remove(user.uuid, 'revisions')
|
||||||
|
|
||||||
|
await domainEventPublisher.publish(
|
||||||
|
domainEventFactory.createTransitionRequestedEvent({
|
||||||
|
userUuid: user.uuid,
|
||||||
|
type: 'revisions',
|
||||||
|
timestamp,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
revisionTransitionsTriggered++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
`[TRANSITION ${timestamp}] Triggered transition for ${usersTriggered} users created between ${startDateString} and ${endDateString}`,
|
`[TRANSITION ${timestamp}] Triggered ${itemTransitionsTriggered} item transitions and ${revisionTransitionsTriggered} revision transitions for users created between ${startDateString} and ${endDateString}`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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}`)
|
||||||
|
|||||||
@@ -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,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/auth-server",
|
"name": "@standardnotes/auth-server",
|
||||||
"version": "1.158.4",
|
"version": "1.159.2",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <21.0.0"
|
"node": ">=18.0.0 <21.0.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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'
|
||||||
@@ -90,8 +90,8 @@ import {
|
|||||||
DirectCallDomainEventPublisher,
|
DirectCallDomainEventPublisher,
|
||||||
DirectCallEventMessageHandler,
|
DirectCallEventMessageHandler,
|
||||||
SNSOpenTelemetryDomainEventPublisher,
|
SNSOpenTelemetryDomainEventPublisher,
|
||||||
SQSDomainEventSubscriberFactory,
|
|
||||||
SQSEventMessageHandler,
|
SQSEventMessageHandler,
|
||||||
|
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'
|
||||||
@@ -188,6 +188,7 @@ import {
|
|||||||
ControllerContainer,
|
ControllerContainer,
|
||||||
ControllerContainerInterface,
|
ControllerContainerInterface,
|
||||||
MapperInterface,
|
MapperInterface,
|
||||||
|
ServiceIdentifier,
|
||||||
SharedVaultUser,
|
SharedVaultUser,
|
||||||
} from '@standardnotes/domain-core'
|
} from '@standardnotes/domain-core'
|
||||||
import { SessionTracePersistenceMapper } from '../Mapping/SessionTracePersistenceMapper'
|
import { SessionTracePersistenceMapper } from '../Mapping/SessionTracePersistenceMapper'
|
||||||
@@ -273,6 +274,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') {}
|
||||||
@@ -306,6 +309,8 @@ export class ContainerConfigLoader {
|
|||||||
}
|
}
|
||||||
container.bind<winston.Logger>(TYPES.Auth_Logger).toConstantValue(logger)
|
container.bind<winston.Logger>(TYPES.Auth_Logger).toConstantValue(logger)
|
||||||
|
|
||||||
|
container.bind<CryptoNode>(TYPES.Auth_CryptoNode).toConstantValue(new CryptoNode())
|
||||||
|
|
||||||
const appDataSource = new AppDataSource({ env, runMigrations: this.mode === 'server' })
|
const appDataSource = new AppDataSource({ env, runMigrations: this.mode === 'server' })
|
||||||
await appDataSource.initialize()
|
await appDataSource.initialize()
|
||||||
|
|
||||||
@@ -367,6 +372,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)
|
||||||
@@ -547,7 +565,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
|
||||||
@@ -649,6 +666,9 @@ export class ContainerConfigLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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)
|
||||||
@@ -691,44 +711,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(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)
|
||||||
@@ -881,7 +918,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)
|
||||||
@@ -1227,12 +1263,14 @@ export class ContainerConfigLoader {
|
|||||||
.toConstantValue(new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Auth_Logger)))
|
.toConstantValue(new SQSEventMessageHandler(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),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1311,7 +1349,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),
|
||||||
|
|||||||
@@ -218,7 +218,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'),
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ 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 {
|
||||||
@@ -277,6 +278,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 +294,7 @@ export class DomainEventFactory implements DomainEventFactoryInterface {
|
|||||||
userUuid,
|
userUuid,
|
||||||
userHasEmailsMuted,
|
userHasEmailsMuted,
|
||||||
muteEmailsSettingUuid,
|
muteEmailsSettingUuid,
|
||||||
|
keyParams,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import {
|
|||||||
TransitionRequestedEvent,
|
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 +42,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
|
||||||
|
|||||||
@@ -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,24 +1,22 @@
|
|||||||
import { inject, injectable } from 'inversify'
|
import { KeyParamsData } from '@standardnotes/responses'
|
||||||
import TYPES from '../../../Bootstrap/Types'
|
import { Logger } from 'winston'
|
||||||
|
import { Username, Uuid } from '@standardnotes/domain-core'
|
||||||
|
|
||||||
import { KeyParamsFactoryInterface } from '../../User/KeyParamsFactoryInterface'
|
import { KeyParamsFactoryInterface } from '../../User/KeyParamsFactoryInterface'
|
||||||
import { UserRepositoryInterface } from '../../User/UserRepositoryInterface'
|
import { UserRepositoryInterface } from '../../User/UserRepositoryInterface'
|
||||||
import { GetUserKeyParamsDTO } from './GetUserKeyParamsDTO'
|
import { GetUserKeyParamsDTO } from './GetUserKeyParamsDTO'
|
||||||
import { GetUserKeyParamsResponse } from './GetUserKeyParamsResponse'
|
import { GetUserKeyParamsResponse } from './GetUserKeyParamsResponse'
|
||||||
import { UseCaseInterface } from '../UseCaseInterface'
|
import { UseCaseInterface } from '../UseCaseInterface'
|
||||||
import { Logger } from 'winston'
|
|
||||||
import { User } from '../../User/User'
|
import { User } from '../../User/User'
|
||||||
import { PKCERepositoryInterface } from '../../User/PKCERepositoryInterface'
|
import { PKCERepositoryInterface } from '../../User/PKCERepositoryInterface'
|
||||||
import { GetUserKeyParamsDTOV2Challenged } from './GetUserKeyParamsDTOV2Challenged'
|
import { GetUserKeyParamsDTOV2Challenged } from './GetUserKeyParamsDTOV2Challenged'
|
||||||
import { KeyParamsData } from '@standardnotes/responses'
|
|
||||||
import { Username, Uuid } from '@standardnotes/domain-core'
|
|
||||||
|
|
||||||
@injectable()
|
|
||||||
export class GetUserKeyParams implements UseCaseInterface {
|
export class GetUserKeyParams implements UseCaseInterface {
|
||||||
constructor(
|
constructor(
|
||||||
@inject(TYPES.Auth_KeyParamsFactory) private keyParamsFactory: KeyParamsFactoryInterface,
|
private keyParamsFactory: KeyParamsFactoryInterface,
|
||||||
@inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface,
|
private userRepository: UserRepositoryInterface,
|
||||||
@inject(TYPES.Auth_PKCERepository) private pkceRepository: PKCERepositoryInterface,
|
private pkceRepository: PKCERepositoryInterface,
|
||||||
@inject(TYPES.Auth_Logger) private logger: Logger,
|
private logger: Logger,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async execute(dto: GetUserKeyParamsDTO): Promise<GetUserKeyParamsResponse> {
|
async execute(dto: GetUserKeyParamsDTO): Promise<GetUserKeyParamsResponse> {
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ export interface UserRepositoryInterface {
|
|||||||
streamTeam(memberEmail?: Email): Promise<ReadStream>
|
streamTeam(memberEmail?: Email): Promise<ReadStream>
|
||||||
findOneByUuid(uuid: Uuid): Promise<User | null>
|
findOneByUuid(uuid: Uuid): Promise<User | null>
|
||||||
findOneByUsernameOrEmail(usernameOrEmail: Email | Username): Promise<User | null>
|
findOneByUsernameOrEmail(usernameOrEmail: Email | Username): Promise<User | null>
|
||||||
findAllCreatedBetween(start: Date, end: Date): Promise<User[]>
|
findAllCreatedBetween(dto: { start: Date; end: Date; offset: number; limit: number }): Promise<User[]>
|
||||||
|
countAllCreatedBetween(start: Date, end: Date): Promise<number>
|
||||||
save(user: User): Promise<User>
|
save(user: User): Promise<User>
|
||||||
remove(user: User): Promise<User>
|
remove(user: User): Promise<User>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import { Result, Username } from '@standardnotes/domain-core'
|
|||||||
import { DeleteAccount } from '../../Domain/UseCase/DeleteAccount/DeleteAccount'
|
import { DeleteAccount } from '../../Domain/UseCase/DeleteAccount/DeleteAccount'
|
||||||
import { ChangeCredentials } from '../../Domain/UseCase/ChangeCredentials/ChangeCredentials'
|
import { ChangeCredentials } from '../../Domain/UseCase/ChangeCredentials/ChangeCredentials'
|
||||||
import { ClearLoginAttempts } from '../../Domain/UseCase/ClearLoginAttempts'
|
import { ClearLoginAttempts } from '../../Domain/UseCase/ClearLoginAttempts'
|
||||||
import { GetUserKeyParams } from '../../Domain/UseCase/GetUserKeyParams/GetUserKeyParams'
|
|
||||||
import { GetUserSubscription } from '../../Domain/UseCase/GetUserSubscription/GetUserSubscription'
|
import { GetUserSubscription } from '../../Domain/UseCase/GetUserSubscription/GetUserSubscription'
|
||||||
import { IncreaseLoginAttempts } from '../../Domain/UseCase/IncreaseLoginAttempts'
|
import { IncreaseLoginAttempts } from '../../Domain/UseCase/IncreaseLoginAttempts'
|
||||||
import { InviteToSharedSubscription } from '../../Domain/UseCase/InviteToSharedSubscription/InviteToSharedSubscription'
|
import { InviteToSharedSubscription } from '../../Domain/UseCase/InviteToSharedSubscription/InviteToSharedSubscription'
|
||||||
@@ -18,7 +17,6 @@ import { User } from '../../Domain/User/User'
|
|||||||
describe('AnnotatedUsersController', () => {
|
describe('AnnotatedUsersController', () => {
|
||||||
let updateUser: UpdateUser
|
let updateUser: UpdateUser
|
||||||
let deleteAccount: DeleteAccount
|
let deleteAccount: DeleteAccount
|
||||||
let getUserKeyParams: GetUserKeyParams
|
|
||||||
let getUserSubscription: GetUserSubscription
|
let getUserSubscription: GetUserSubscription
|
||||||
let clearLoginAttempts: ClearLoginAttempts
|
let clearLoginAttempts: ClearLoginAttempts
|
||||||
let increaseLoginAttempts: IncreaseLoginAttempts
|
let increaseLoginAttempts: IncreaseLoginAttempts
|
||||||
@@ -32,7 +30,6 @@ describe('AnnotatedUsersController', () => {
|
|||||||
const createController = () =>
|
const createController = () =>
|
||||||
new AnnotatedUsersController(
|
new AnnotatedUsersController(
|
||||||
updateUser,
|
updateUser,
|
||||||
getUserKeyParams,
|
|
||||||
deleteAccount,
|
deleteAccount,
|
||||||
getUserSubscription,
|
getUserSubscription,
|
||||||
clearLoginAttempts,
|
clearLoginAttempts,
|
||||||
@@ -51,9 +48,6 @@ describe('AnnotatedUsersController', () => {
|
|||||||
user.uuid = '123'
|
user.uuid = '123'
|
||||||
user.email = 'test@test.te'
|
user.email = 'test@test.te'
|
||||||
|
|
||||||
getUserKeyParams = {} as jest.Mocked<GetUserKeyParams>
|
|
||||||
getUserKeyParams.execute = jest.fn()
|
|
||||||
|
|
||||||
getUserSubscription = {} as jest.Mocked<GetUserSubscription>
|
getUserSubscription = {} as jest.Mocked<GetUserSubscription>
|
||||||
getUserSubscription.execute = jest.fn()
|
getUserSubscription.execute = jest.fn()
|
||||||
|
|
||||||
@@ -213,60 +207,6 @@ describe('AnnotatedUsersController', () => {
|
|||||||
expect(result.statusCode).toEqual(401)
|
expect(result.statusCode).toEqual(401)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should get user key params', async () => {
|
|
||||||
request.query = {
|
|
||||||
email: 'test@test.te',
|
|
||||||
uuid: '1-2-3',
|
|
||||||
}
|
|
||||||
|
|
||||||
getUserKeyParams.execute = jest.fn().mockReturnValue({ foo: 'bar' })
|
|
||||||
|
|
||||||
const httpResponse = <results.JsonResult>await createController().keyParams(request)
|
|
||||||
const result = await httpResponse.executeAsync()
|
|
||||||
|
|
||||||
expect(getUserKeyParams.execute).toHaveBeenCalledWith({
|
|
||||||
email: 'test@test.te',
|
|
||||||
userUuid: '1-2-3',
|
|
||||||
authenticated: false,
|
|
||||||
})
|
|
||||||
|
|
||||||
expect(result.statusCode).toEqual(200)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should get authenticated user key params', async () => {
|
|
||||||
request.query = {
|
|
||||||
email: 'test@test.te',
|
|
||||||
uuid: '1-2-3',
|
|
||||||
authenticated: 'true',
|
|
||||||
}
|
|
||||||
|
|
||||||
getUserKeyParams.execute = jest.fn().mockReturnValue({ foo: 'bar' })
|
|
||||||
|
|
||||||
const httpResponse = <results.JsonResult>await createController().keyParams(request)
|
|
||||||
const result = await httpResponse.executeAsync()
|
|
||||||
|
|
||||||
expect(getUserKeyParams.execute).toHaveBeenCalledWith({
|
|
||||||
email: 'test@test.te',
|
|
||||||
userUuid: '1-2-3',
|
|
||||||
authenticated: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
expect(result.statusCode).toEqual(200)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should not get user key params if email and user uuid is missing', async () => {
|
|
||||||
request.query = {}
|
|
||||||
|
|
||||||
getUserKeyParams.execute = jest.fn().mockReturnValue({ foo: 'bar' })
|
|
||||||
|
|
||||||
const httpResponse = <results.JsonResult>await createController().keyParams(request)
|
|
||||||
const result = await httpResponse.executeAsync()
|
|
||||||
|
|
||||||
expect(getUserKeyParams.execute).not.toHaveBeenCalled()
|
|
||||||
|
|
||||||
expect(result.statusCode).toEqual(400)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should get user subscription', async () => {
|
it('should get user subscription', async () => {
|
||||||
request.params.userUuid = '1-2-3'
|
request.params.userUuid = '1-2-3'
|
||||||
response.locals.user = {
|
response.locals.user = {
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import {
|
|||||||
} from 'inversify-express-utils'
|
} from 'inversify-express-utils'
|
||||||
import TYPES from '../../Bootstrap/Types'
|
import TYPES from '../../Bootstrap/Types'
|
||||||
import { DeleteAccount } from '../../Domain/UseCase/DeleteAccount/DeleteAccount'
|
import { DeleteAccount } from '../../Domain/UseCase/DeleteAccount/DeleteAccount'
|
||||||
import { GetUserKeyParams } from '../../Domain/UseCase/GetUserKeyParams/GetUserKeyParams'
|
|
||||||
import { UpdateUser } from '../../Domain/UseCase/UpdateUser'
|
import { UpdateUser } from '../../Domain/UseCase/UpdateUser'
|
||||||
import { GetUserSubscription } from '../../Domain/UseCase/GetUserSubscription/GetUserSubscription'
|
import { GetUserSubscription } from '../../Domain/UseCase/GetUserSubscription/GetUserSubscription'
|
||||||
import { ClearLoginAttempts } from '../../Domain/UseCase/ClearLoginAttempts'
|
import { ClearLoginAttempts } from '../../Domain/UseCase/ClearLoginAttempts'
|
||||||
@@ -23,7 +22,6 @@ import { BaseUsersController } from './Base/BaseUsersController'
|
|||||||
export class AnnotatedUsersController extends BaseUsersController {
|
export class AnnotatedUsersController extends BaseUsersController {
|
||||||
constructor(
|
constructor(
|
||||||
@inject(TYPES.Auth_UpdateUser) override updateUser: UpdateUser,
|
@inject(TYPES.Auth_UpdateUser) override updateUser: UpdateUser,
|
||||||
@inject(TYPES.Auth_GetUserKeyParams) override getUserKeyParams: GetUserKeyParams,
|
|
||||||
@inject(TYPES.Auth_DeleteAccount) override doDeleteAccount: DeleteAccount,
|
@inject(TYPES.Auth_DeleteAccount) override doDeleteAccount: DeleteAccount,
|
||||||
@inject(TYPES.Auth_GetUserSubscription) override doGetUserSubscription: GetUserSubscription,
|
@inject(TYPES.Auth_GetUserSubscription) override doGetUserSubscription: GetUserSubscription,
|
||||||
@inject(TYPES.Auth_ClearLoginAttempts) override clearLoginAttempts: ClearLoginAttempts,
|
@inject(TYPES.Auth_ClearLoginAttempts) override clearLoginAttempts: ClearLoginAttempts,
|
||||||
@@ -32,7 +30,6 @@ export class AnnotatedUsersController extends BaseUsersController {
|
|||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
updateUser,
|
updateUser,
|
||||||
getUserKeyParams,
|
|
||||||
doDeleteAccount,
|
doDeleteAccount,
|
||||||
doGetUserSubscription,
|
doGetUserSubscription,
|
||||||
clearLoginAttempts,
|
clearLoginAttempts,
|
||||||
@@ -46,11 +43,6 @@ export class AnnotatedUsersController extends BaseUsersController {
|
|||||||
return super.update(request, response)
|
return super.update(request, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
@httpGet('/params')
|
|
||||||
override async keyParams(request: Request): Promise<results.JsonResult> {
|
|
||||||
return super.keyParams(request)
|
|
||||||
}
|
|
||||||
|
|
||||||
@httpDelete('/:userUuid', TYPES.Auth_RequiredCrossServiceTokenMiddleware)
|
@httpDelete('/:userUuid', TYPES.Auth_RequiredCrossServiceTokenMiddleware)
|
||||||
override async deleteAccount(request: Request, response: Response): Promise<results.JsonResult> {
|
override async deleteAccount(request: Request, response: Response): Promise<results.JsonResult> {
|
||||||
return super.deleteAccount(request, response)
|
return super.deleteAccount(request, response)
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { BaseHttpController, results } from 'inversify-express-utils'
|
|||||||
import { ChangeCredentials } from '../../../Domain/UseCase/ChangeCredentials/ChangeCredentials'
|
import { ChangeCredentials } from '../../../Domain/UseCase/ChangeCredentials/ChangeCredentials'
|
||||||
import { ClearLoginAttempts } from '../../../Domain/UseCase/ClearLoginAttempts'
|
import { ClearLoginAttempts } from '../../../Domain/UseCase/ClearLoginAttempts'
|
||||||
import { DeleteAccount } from '../../../Domain/UseCase/DeleteAccount/DeleteAccount'
|
import { DeleteAccount } from '../../../Domain/UseCase/DeleteAccount/DeleteAccount'
|
||||||
import { GetUserKeyParams } from '../../../Domain/UseCase/GetUserKeyParams/GetUserKeyParams'
|
|
||||||
import { GetUserSubscription } from '../../../Domain/UseCase/GetUserSubscription/GetUserSubscription'
|
import { GetUserSubscription } from '../../../Domain/UseCase/GetUserSubscription/GetUserSubscription'
|
||||||
import { IncreaseLoginAttempts } from '../../../Domain/UseCase/IncreaseLoginAttempts'
|
import { IncreaseLoginAttempts } from '../../../Domain/UseCase/IncreaseLoginAttempts'
|
||||||
import { UpdateUser } from '../../../Domain/UseCase/UpdateUser'
|
import { UpdateUser } from '../../../Domain/UseCase/UpdateUser'
|
||||||
@@ -14,7 +13,6 @@ import { ErrorTag } from '@standardnotes/responses'
|
|||||||
export class BaseUsersController extends BaseHttpController {
|
export class BaseUsersController extends BaseHttpController {
|
||||||
constructor(
|
constructor(
|
||||||
protected updateUser: UpdateUser,
|
protected updateUser: UpdateUser,
|
||||||
protected getUserKeyParams: GetUserKeyParams,
|
|
||||||
protected doDeleteAccount: DeleteAccount,
|
protected doDeleteAccount: DeleteAccount,
|
||||||
protected doGetUserSubscription: GetUserSubscription,
|
protected doGetUserSubscription: GetUserSubscription,
|
||||||
protected clearLoginAttempts: ClearLoginAttempts,
|
protected clearLoginAttempts: ClearLoginAttempts,
|
||||||
@@ -26,7 +24,6 @@ export class BaseUsersController extends BaseHttpController {
|
|||||||
|
|
||||||
if (this.controllerContainer !== undefined) {
|
if (this.controllerContainer !== undefined) {
|
||||||
this.controllerContainer.register('auth.users.update', this.update.bind(this))
|
this.controllerContainer.register('auth.users.update', this.update.bind(this))
|
||||||
this.controllerContainer.register('auth.users.getKeyParams', this.keyParams.bind(this))
|
|
||||||
this.controllerContainer.register('auth.users.getSubscription', this.getSubscription.bind(this))
|
this.controllerContainer.register('auth.users.getSubscription', this.getSubscription.bind(this))
|
||||||
this.controllerContainer.register('auth.users.updateCredentials', this.changeCredentials.bind(this))
|
this.controllerContainer.register('auth.users.updateCredentials', this.changeCredentials.bind(this))
|
||||||
this.controllerContainer.register('auth.users.delete', this.deleteAccount.bind(this))
|
this.controllerContainer.register('auth.users.delete', this.deleteAccount.bind(this))
|
||||||
@@ -79,30 +76,6 @@ export class BaseUsersController extends BaseHttpController {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async keyParams(request: Request): Promise<results.JsonResult> {
|
|
||||||
const email = 'email' in request.query ? <string>request.query.email : undefined
|
|
||||||
const userUuid = 'uuid' in request.query ? <string>request.query.uuid : undefined
|
|
||||||
|
|
||||||
if (!email && !userUuid) {
|
|
||||||
return this.json(
|
|
||||||
{
|
|
||||||
error: {
|
|
||||||
message: 'Missing mandatory request query parameters.',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
400,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = await this.getUserKeyParams.execute({
|
|
||||||
email,
|
|
||||||
userUuid,
|
|
||||||
authenticated: request.query.authenticated === 'true',
|
|
||||||
})
|
|
||||||
|
|
||||||
return this.json(result.keyParams)
|
|
||||||
}
|
|
||||||
|
|
||||||
async deleteAccount(request: Request, response: Response): Promise<results.JsonResult> {
|
async deleteAccount(request: Request, response: Response): Promise<results.JsonResult> {
|
||||||
if (request.params.userUuid !== response.locals.user.uuid) {
|
if (request.params.userUuid !== response.locals.user.uuid) {
|
||||||
return this.json(
|
return this.json(
|
||||||
|
|||||||
@@ -14,11 +14,21 @@ export class TypeORMUserRepository implements UserRepositoryInterface {
|
|||||||
private ormRepository: Repository<User>,
|
private ormRepository: Repository<User>,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async findAllCreatedBetween(start: Date, end: Date): Promise<User[]> {
|
async findAllCreatedBetween(dto: { start: Date; end: Date; offset: number; limit: number }): Promise<User[]> {
|
||||||
|
return this.ormRepository
|
||||||
|
.createQueryBuilder('user')
|
||||||
|
.where('user.created_at BETWEEN :start AND :end', { start: dto.start, end: dto.end })
|
||||||
|
.orderBy('user.created_at', 'ASC')
|
||||||
|
.take(dto.limit)
|
||||||
|
.skip(dto.offset)
|
||||||
|
.getMany()
|
||||||
|
}
|
||||||
|
|
||||||
|
async countAllCreatedBetween(start: Date, end: Date): Promise<number> {
|
||||||
return this.ormRepository
|
return this.ormRepository
|
||||||
.createQueryBuilder('user')
|
.createQueryBuilder('user')
|
||||||
.where('user.created_at BETWEEN :start AND :end', { start, end })
|
.where('user.created_at BETWEEN :start AND :end', { start, end })
|
||||||
.getMany()
|
.getCount()
|
||||||
}
|
}
|
||||||
|
|
||||||
async save(user: User): Promise<User> {
|
async save(user: User): Promise<User> {
|
||||||
|
|||||||
@@ -3,6 +3,34 @@
|
|||||||
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.20.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.20.0...@standardnotes/domain-events-infra@1.20.1) (2023-10-18)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* remove ip attributes in opentelemetry http instrumentation ([#874](https://github.com/standardnotes/server/issues/874)) ([7ce9aba](https://github.com/standardnotes/server/commit/7ce9aba517435034f491c9f080f671285fb91b91))
|
||||||
|
|
||||||
|
# [1.20.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.19.7...@standardnotes/domain-events-infra@1.20.0) (2023-10-17)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add wrapping sqs receive message with open telemetry ([aba4f90](https://github.com/standardnotes/server/commit/aba4f90485e1b40baac34561321a5381945aa27e))
|
||||||
|
|
||||||
|
## [1.19.7](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.19.6...@standardnotes/domain-events-infra@1.19.7) (2023-10-13)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* reduce the amount of metrics gathered in telemetery ([32fe8d0](https://github.com/standardnotes/server/commit/32fe8d0a8523d6e1875cd0814c0cbdf27d8df7b3))
|
||||||
|
|
||||||
|
## [1.19.6](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.19.5...@standardnotes/domain-events-infra@1.19.6) (2023-10-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/domain-events-infra
|
||||||
|
|
||||||
|
## [1.19.5](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.19.4...@standardnotes/domain-events-infra@1.19.5) (2023-10-12)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **domain-events-infra:** retrieve all message attributes from sqs ([0c29ff1](https://github.com/standardnotes/server/commit/0c29ff1ab4886a73eae8079e80d7ff779c0e3859))
|
||||||
|
|
||||||
## [1.19.4](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.19.3...@standardnotes/domain-events-infra@1.19.4) (2023-10-12)
|
## [1.19.4](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.19.3...@standardnotes/domain-events-infra@1.19.4) (2023-10-12)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/domain-events-infra",
|
"name": "@standardnotes/domain-events-infra",
|
||||||
"version": "1.19.4",
|
"version": "1.20.1",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <21.0.0"
|
"node": ">=18.0.0 <21.0.0"
|
||||||
},
|
},
|
||||||
@@ -27,23 +27,23 @@
|
|||||||
"@aws-sdk/client-sns": "^3.427.0",
|
"@aws-sdk/client-sns": "^3.427.0",
|
||||||
"@aws-sdk/client-sqs": "^3.427.0",
|
"@aws-sdk/client-sqs": "^3.427.0",
|
||||||
"@opentelemetry/api": "^1.6.0",
|
"@opentelemetry/api": "^1.6.0",
|
||||||
"@opentelemetry/exporter-metrics-otlp-proto": "^0.43.0",
|
"@opentelemetry/exporter-metrics-otlp-proto": "^0.44.0",
|
||||||
"@opentelemetry/exporter-trace-otlp-grpc": "^0.43.0",
|
"@opentelemetry/exporter-trace-otlp-grpc": "^0.44.0",
|
||||||
"@opentelemetry/id-generator-aws-xray": "^1.2.1",
|
"@opentelemetry/id-generator-aws-xray": "^1.2.1",
|
||||||
"@opentelemetry/instrumentation-aws-sdk": "^0.36.0",
|
"@opentelemetry/instrumentation-aws-sdk": "^0.36.1",
|
||||||
"@opentelemetry/instrumentation-express": "^0.33.1",
|
"@opentelemetry/instrumentation-express": "^0.33.2",
|
||||||
"@opentelemetry/instrumentation-http": "^0.43.0",
|
"@opentelemetry/instrumentation-http": "^0.44.0",
|
||||||
"@opentelemetry/instrumentation-ioredis": "^0.35.1",
|
"@opentelemetry/instrumentation-ioredis": "^0.35.2",
|
||||||
"@opentelemetry/instrumentation-winston": "^0.32.1",
|
"@opentelemetry/instrumentation-winston": "^0.32.2",
|
||||||
"@opentelemetry/propagator-aws-xray": "^1.3.1",
|
"@opentelemetry/propagator-aws-xray": "^1.3.1",
|
||||||
"@opentelemetry/resource-detector-aws": "^1.3.1",
|
"@opentelemetry/resource-detector-aws": "^1.3.2",
|
||||||
"@opentelemetry/sdk-node": "^0.43.0",
|
"@opentelemetry/sdk-node": "^0.44.0",
|
||||||
"@opentelemetry/semantic-conventions": "^1.17.0",
|
"@opentelemetry/semantic-conventions": "^1.17.1",
|
||||||
"@standardnotes/domain-events": "workspace:*",
|
"@standardnotes/domain-events": "workspace:*",
|
||||||
"ioredis": "^5.2.4",
|
"ioredis": "^5.2.4",
|
||||||
"opentelemetry-instrumentation-typeorm": "^0.39.1",
|
"opentelemetry-instrumentation-typeorm": "^0.39.1",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"sqs-consumer": "^7.3.0",
|
"sqs-consumer": "7.4.0-canary.0",
|
||||||
"winston": "^3.8.1"
|
"winston": "^3.8.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as OpenTelemetrySDKNode from '@opentelemetry/sdk-node'
|
import * as OpenTelemetrySDKNode from '@opentelemetry/sdk-node'
|
||||||
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'
|
import { SemanticAttributes, SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'
|
||||||
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc'
|
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc'
|
||||||
import { AWSXRayIdGenerator } from '@opentelemetry/id-generator-aws-xray'
|
import { AWSXRayIdGenerator } from '@opentelemetry/id-generator-aws-xray'
|
||||||
import * as AwsResourceDetectors from '@opentelemetry/resource-detector-aws'
|
import * as AwsResourceDetectors from '@opentelemetry/resource-detector-aws'
|
||||||
@@ -10,16 +10,21 @@ import { AwsInstrumentation } from '@opentelemetry/instrumentation-aws-sdk'
|
|||||||
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-proto'
|
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-proto'
|
||||||
import { WinstonInstrumentation } from '@opentelemetry/instrumentation-winston'
|
import { WinstonInstrumentation } from '@opentelemetry/instrumentation-winston'
|
||||||
import { IORedisInstrumentation } from '@opentelemetry/instrumentation-ioredis'
|
import { IORedisInstrumentation } from '@opentelemetry/instrumentation-ioredis'
|
||||||
|
import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express'
|
||||||
|
import { IncomingMessage } from 'http'
|
||||||
|
import { Attributes } from '@opentelemetry/api'
|
||||||
|
|
||||||
import { OpenTelemetrySDKInterface } from './OpenTelemetrySDKInterface'
|
import { OpenTelemetrySDKInterface } from './OpenTelemetrySDKInterface'
|
||||||
import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express'
|
|
||||||
|
|
||||||
export class OpenTelemetrySDK implements OpenTelemetrySDKInterface {
|
export class OpenTelemetrySDK implements OpenTelemetrySDKInterface {
|
||||||
private declare sdk: OpenTelemetrySDKNode.NodeSDK
|
private declare sdk: OpenTelemetrySDKNode.NodeSDK
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private serviceName: string,
|
private options: {
|
||||||
private spanRatio?: number,
|
serviceName: string
|
||||||
|
spanRatio?: number
|
||||||
|
metricExportIntervalMillis?: number
|
||||||
|
},
|
||||||
) {
|
) {
|
||||||
this.build()
|
this.build()
|
||||||
}
|
}
|
||||||
@@ -27,24 +32,28 @@ export class OpenTelemetrySDK implements OpenTelemetrySDKInterface {
|
|||||||
build(): void {
|
build(): void {
|
||||||
const otResource = OpenTelemetrySDKNode.resources.Resource.default().merge(
|
const otResource = OpenTelemetrySDKNode.resources.Resource.default().merge(
|
||||||
new OpenTelemetrySDKNode.resources.Resource({
|
new OpenTelemetrySDKNode.resources.Resource({
|
||||||
[SemanticResourceAttributes.SERVICE_NAME]: this.serviceName,
|
[SemanticResourceAttributes.SERVICE_NAME]: this.options.serviceName,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
const traceExporter = new OTLPTraceExporter()
|
const traceExporter = new OTLPTraceExporter()
|
||||||
|
|
||||||
const spanProcessor = new OpenTelemetrySDKNode.tracing.BatchSpanProcessor(traceExporter)
|
const spanProcessor = new OpenTelemetrySDKNode.tracing.BatchSpanProcessor(traceExporter)
|
||||||
|
|
||||||
|
const metricExportIntervalMillis = this.options.metricExportIntervalMillis ?? 300_000
|
||||||
const metricReader = new OpenTelemetrySDKNode.metrics.PeriodicExportingMetricReader({
|
const metricReader = new OpenTelemetrySDKNode.metrics.PeriodicExportingMetricReader({
|
||||||
exportIntervalMillis: 1_000,
|
exportIntervalMillis: metricExportIntervalMillis,
|
||||||
exporter: new OTLPMetricExporter(),
|
exporter: new OTLPMetricExporter(),
|
||||||
})
|
})
|
||||||
|
|
||||||
const serviceName = this.serviceName
|
const serviceName = this.options.serviceName
|
||||||
const winstonInstrumentation = new WinstonInstrumentation({
|
const winstonInstrumentation = new WinstonInstrumentation({
|
||||||
logHook: (_span, record) => {
|
logHook: (_span, record) => {
|
||||||
record['resource.service.name'] = serviceName
|
record['resource.service.name'] = serviceName
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const ratio = this.spanRatio ?? 0.01
|
const ratio = this.options.spanRatio ?? 0.01
|
||||||
|
|
||||||
this.sdk = new OpenTelemetrySDKNode.NodeSDK({
|
this.sdk = new OpenTelemetrySDKNode.NodeSDK({
|
||||||
sampler: new OpenTelemetrySDKNode.tracing.TraceIdRatioBasedSampler(ratio),
|
sampler: new OpenTelemetrySDKNode.tracing.TraceIdRatioBasedSampler(ratio),
|
||||||
@@ -56,6 +65,11 @@ export class OpenTelemetrySDK implements OpenTelemetrySDKInterface {
|
|||||||
|
|
||||||
return isHealthCheckUrl
|
return isHealthCheckUrl
|
||||||
},
|
},
|
||||||
|
startIncomingSpanHook: (_request: IncomingMessage): Attributes => {
|
||||||
|
return {
|
||||||
|
[SemanticAttributes.HTTP_CLIENT_IP]: undefined,
|
||||||
|
}
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
new ExpressInstrumentation(),
|
new ExpressInstrumentation(),
|
||||||
new AwsInstrumentation({
|
new AwsInstrumentation({
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export class SQSDomainEventSubscriberFactory implements DomainEventSubscriberFac
|
|||||||
create(): DomainEventSubscriberInterface {
|
create(): DomainEventSubscriberInterface {
|
||||||
const sqsConsumer = Consumer.create({
|
const sqsConsumer = Consumer.create({
|
||||||
attributeNames: ['All'],
|
attributeNames: ['All'],
|
||||||
messageAttributeNames: ['compression', 'event'],
|
messageAttributeNames: ['All'],
|
||||||
queueUrl: this.queueUrl,
|
queueUrl: this.queueUrl,
|
||||||
sqs: this.sqs,
|
sqs: this.sqs,
|
||||||
handleMessage:
|
handleMessage:
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import { Consumer } from 'sqs-consumer'
|
||||||
|
import * as OpenTelemetryApi from '@opentelemetry/api'
|
||||||
|
import { Message, SQSClient } from '@aws-sdk/client-sqs'
|
||||||
|
import { DomainEventSubscriberInterface, DomainEventMessageHandlerInterface } from '@standardnotes/domain-events'
|
||||||
|
import { Logger } from 'winston'
|
||||||
|
|
||||||
|
export class SQSOpenTelemetryDomainEventSubscriber implements DomainEventSubscriberInterface {
|
||||||
|
private currentSpan: OpenTelemetryApi.Span | undefined
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private serviceName: string,
|
||||||
|
private sqs: SQSClient,
|
||||||
|
private queueUrl: string,
|
||||||
|
private domainEventMessageHandler: DomainEventMessageHandlerInterface,
|
||||||
|
private logger: Logger,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
start(): void {
|
||||||
|
const sqsConsumer = Consumer.create({
|
||||||
|
attributeNames: ['All'],
|
||||||
|
messageAttributeNames: ['All'],
|
||||||
|
queueUrl: this.queueUrl,
|
||||||
|
sqs: this.sqs,
|
||||||
|
preReceiveMessageCallback: this.startParentSpan.bind(this),
|
||||||
|
handleMessage: this.handleMessage.bind(this),
|
||||||
|
})
|
||||||
|
|
||||||
|
sqsConsumer.on('error', this.handleError.bind(this))
|
||||||
|
sqsConsumer.on('processing_error', this.handleError.bind(this))
|
||||||
|
|
||||||
|
sqsConsumer.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
async startParentSpan(): Promise<void> {
|
||||||
|
const tracer = OpenTelemetryApi.trace.getTracer(`${this.serviceName}-domain-event-subscriber`)
|
||||||
|
|
||||||
|
this.currentSpan = tracer.startSpan(this.serviceName, { kind: OpenTelemetryApi.SpanKind.CONSUMER })
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleMessage(message: Message): Promise<void> {
|
||||||
|
await this.domainEventMessageHandler.handleMessage(<string>message.Body)
|
||||||
|
|
||||||
|
if (this.currentSpan) {
|
||||||
|
this.currentSpan.end()
|
||||||
|
this.currentSpan = undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleError(error: Error): void {
|
||||||
|
this.logger.error('Error occured while handling SQS message: %O', error)
|
||||||
|
|
||||||
|
if (this.currentSpan) {
|
||||||
|
this.currentSpan.recordException(error)
|
||||||
|
this.currentSpan.end()
|
||||||
|
this.currentSpan = undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
import { Logger } from 'winston'
|
|
||||||
import * as zlib from 'zlib'
|
|
||||||
import {
|
|
||||||
DomainEventHandlerInterface,
|
|
||||||
DomainEventInterface,
|
|
||||||
DomainEventMessageHandlerInterface,
|
|
||||||
} from '@standardnotes/domain-events'
|
|
||||||
import { OpenTelemetryTracer } from '../OpenTelemetry/OpenTelemetryTracer'
|
|
||||||
import { OpenTelemetryTracerInterface } from '../OpenTelemetry/OpenTelemetryTracerInterface'
|
|
||||||
|
|
||||||
export class SQSOpenTelemetryEventMessageHandler implements DomainEventMessageHandlerInterface {
|
|
||||||
private tracer: OpenTelemetryTracerInterface | undefined
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private serviceName: string,
|
|
||||||
private handlers: Map<string, DomainEventHandlerInterface>,
|
|
||||||
private logger: Logger,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
async handleMessage(message: string): Promise<void> {
|
|
||||||
const messageParsed = JSON.parse(message)
|
|
||||||
|
|
||||||
const domainEventJson = zlib.unzipSync(Buffer.from(messageParsed.Message, 'base64')).toString()
|
|
||||||
|
|
||||||
const domainEvent: DomainEventInterface = JSON.parse(domainEventJson)
|
|
||||||
|
|
||||||
domainEvent.createdAt = new Date(domainEvent.createdAt)
|
|
||||||
|
|
||||||
const handler = this.handlers.get(domainEvent.type)
|
|
||||||
if (!handler) {
|
|
||||||
this.logger.debug(`Event handler for event type ${domainEvent.type} does not exist`)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.debug(`Received event: ${domainEvent.type}`)
|
|
||||||
|
|
||||||
this.tracer = new OpenTelemetryTracer()
|
|
||||||
|
|
||||||
this.tracer.startSpan(this.serviceName, domainEvent.type)
|
|
||||||
|
|
||||||
try {
|
|
||||||
await handler.handle(domainEvent)
|
|
||||||
} catch (error) {
|
|
||||||
this.tracer.stopSpanWithError(error as Error)
|
|
||||||
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
|
|
||||||
this.tracer.stopSpan()
|
|
||||||
}
|
|
||||||
|
|
||||||
async handleError(error: Error): Promise<void> {
|
|
||||||
this.logger.error('Error occured while handling SQS message: %O', error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -17,4 +17,4 @@ export * from './SNS/SNSOpenTelemetryDomainEventPublisher'
|
|||||||
export * from './SQS/SQSBounceNotificiationHandler'
|
export * from './SQS/SQSBounceNotificiationHandler'
|
||||||
export * from './SQS/SQSDomainEventSubscriberFactory'
|
export * from './SQS/SQSDomainEventSubscriberFactory'
|
||||||
export * from './SQS/SQSEventMessageHandler'
|
export * from './SQS/SQSEventMessageHandler'
|
||||||
export * from './SQS/SQSOpenTelemetryEventMessageHandler'
|
export * from './SQS/SQSOpenTelemetryDomainEventSubscriber'
|
||||||
|
|||||||
@@ -3,6 +3,12 @@
|
|||||||
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.132.3](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.132.2...@standardnotes/domain-events@2.132.3) (2023-10-12)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* passing key params for backup requests ([#867](https://github.com/standardnotes/server/issues/867)) ([0739816](https://github.com/standardnotes/server/commit/07398169c80e7871cd04d889f471c3eef70e1aae))
|
||||||
|
|
||||||
## [2.132.2](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.132.1...@standardnotes/domain-events@2.132.2) (2023-10-12)
|
## [2.132.2](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.132.1...@standardnotes/domain-events@2.132.2) (2023-10-12)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/domain-events",
|
"name": "@standardnotes/domain-events",
|
||||||
"version": "2.132.2",
|
"version": "2.132.3",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <21.0.0"
|
"node": ">=18.0.0 <21.0.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,4 +2,5 @@ export interface EmailBackupRequestedEventPayload {
|
|||||||
userUuid: string
|
userUuid: string
|
||||||
userHasEmailsMuted: boolean
|
userHasEmailsMuted: boolean
|
||||||
muteEmailsSettingUuid: string
|
muteEmailsSettingUuid: string
|
||||||
|
keyParams: Record<string, unknown>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,26 @@
|
|||||||
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.13.14](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.13.13...@standardnotes/event-store@1.13.14) (2023-10-18)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/event-store
|
||||||
|
|
||||||
|
## [1.13.13](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.13.12...@standardnotes/event-store@1.13.13) (2023-10-17)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/event-store
|
||||||
|
|
||||||
|
## [1.13.12](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.13.11...@standardnotes/event-store@1.13.12) (2023-10-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/event-store
|
||||||
|
|
||||||
|
## [1.13.11](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.13.10...@standardnotes/event-store@1.13.11) (2023-10-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/event-store
|
||||||
|
|
||||||
|
## [1.13.10](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.13.9...@standardnotes/event-store@1.13.10) (2023-10-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/event-store
|
||||||
|
|
||||||
## [1.13.9](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.13.8...@standardnotes/event-store@1.13.9) (2023-10-12)
|
## [1.13.9](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.13.8...@standardnotes/event-store@1.13.9) (2023-10-12)
|
||||||
|
|
||||||
**Note:** Version bump only for package @standardnotes/event-store
|
**Note:** Version bump only for package @standardnotes/event-store
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/event-store",
|
"name": "@standardnotes/event-store",
|
||||||
"version": "1.13.9",
|
"version": "1.13.14",
|
||||||
"description": "Event Store Service",
|
"description": "Event Store Service",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "dist/src/index.js",
|
"main": "dist/src/index.js",
|
||||||
|
|||||||
@@ -3,6 +3,30 @@
|
|||||||
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.31.1](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.31.0...@standardnotes/files-server@1.31.1) (2023-10-18)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/files-server
|
||||||
|
|
||||||
|
# [1.31.0](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.30.7...@standardnotes/files-server@1.31.0) (2023-10-17)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add wrapping sqs receive message with open telemetry ([aba4f90](https://github.com/standardnotes/files/commit/aba4f90485e1b40baac34561321a5381945aa27e))
|
||||||
|
|
||||||
|
## [1.30.7](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.30.6...@standardnotes/files-server@1.30.7) (2023-10-13)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* reduce the amount of metrics gathered in telemetery ([32fe8d0](https://github.com/standardnotes/files/commit/32fe8d0a8523d6e1875cd0814c0cbdf27d8df7b3))
|
||||||
|
|
||||||
|
## [1.30.6](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.30.5...@standardnotes/files-server@1.30.6) (2023-10-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/files-server
|
||||||
|
|
||||||
|
## [1.30.5](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.30.4...@standardnotes/files-server@1.30.5) (2023-10-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/files-server
|
||||||
|
|
||||||
## [1.30.4](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.30.3...@standardnotes/files-server@1.30.4) (2023-10-12)
|
## [1.30.4](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.30.3...@standardnotes/files-server@1.30.4) (2023-10-12)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -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.Files)
|
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.Files })
|
||||||
sdk.start()
|
sdk.start()
|
||||||
|
|
||||||
import * as busboy from 'connect-busboy'
|
import * as busboy from 'connect-busboy'
|
||||||
|
|||||||
@@ -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.FilesWorker)
|
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.FilesWorker })
|
||||||
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.Files_DomainEventSubscriber)
|
||||||
TYPES.Files_DomainEventSubscriberFactory,
|
|
||||||
)
|
subscriber.start()
|
||||||
subscriberFactory.create().start()
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/files-server",
|
"name": "@standardnotes/files-server",
|
||||||
"version": "1.30.4",
|
"version": "1.31.1",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <21.0.0"
|
"node": ">=18.0.0 <21.0.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ import {
|
|||||||
DirectCallDomainEventPublisher,
|
DirectCallDomainEventPublisher,
|
||||||
DirectCallEventMessageHandler,
|
DirectCallEventMessageHandler,
|
||||||
SNSOpenTelemetryDomainEventPublisher,
|
SNSOpenTelemetryDomainEventPublisher,
|
||||||
SQSDomainEventSubscriberFactory,
|
|
||||||
SQSEventMessageHandler,
|
SQSEventMessageHandler,
|
||||||
|
SQSOpenTelemetryDomainEventSubscriber,
|
||||||
} from '@standardnotes/domain-events-infra'
|
} from '@standardnotes/domain-events-infra'
|
||||||
import { StreamDownloadFile } from '../Domain/UseCase/StreamDownloadFile/StreamDownloadFile'
|
import { StreamDownloadFile } from '../Domain/UseCase/StreamDownloadFile/StreamDownloadFile'
|
||||||
import { FileDownloaderInterface } from '../Domain/Services/FileDownloaderInterface'
|
import { FileDownloaderInterface } from '../Domain/Services/FileDownloaderInterface'
|
||||||
@@ -40,7 +40,7 @@ import {
|
|||||||
DomainEventHandlerInterface,
|
DomainEventHandlerInterface,
|
||||||
DomainEventMessageHandlerInterface,
|
DomainEventMessageHandlerInterface,
|
||||||
DomainEventPublisherInterface,
|
DomainEventPublisherInterface,
|
||||||
DomainEventSubscriberFactoryInterface,
|
DomainEventSubscriberInterface,
|
||||||
} from '@standardnotes/domain-events'
|
} from '@standardnotes/domain-events'
|
||||||
import { MarkFilesToBeRemoved } from '../Domain/UseCase/MarkFilesToBeRemoved/MarkFilesToBeRemoved'
|
import { MarkFilesToBeRemoved } from '../Domain/UseCase/MarkFilesToBeRemoved/MarkFilesToBeRemoved'
|
||||||
import { AccountDeletionRequestedEventHandler } from '../Domain/Handler/AccountDeletionRequestedEventHandler'
|
import { AccountDeletionRequestedEventHandler } from '../Domain/Handler/AccountDeletionRequestedEventHandler'
|
||||||
@@ -52,6 +52,7 @@ import { S3FileMover } from '../Infra/S3/S3FileMover'
|
|||||||
import { FSFileMover } from '../Infra/FS/FSFileMover'
|
import { FSFileMover } from '../Infra/FS/FSFileMover'
|
||||||
import { MoveFile } from '../Domain/UseCase/MoveFile/MoveFile'
|
import { MoveFile } from '../Domain/UseCase/MoveFile/MoveFile'
|
||||||
import { SharedVaultValetTokenAuthMiddleware } from '../Infra/InversifyExpress/Middleware/SharedVaultValetTokenAuthMiddleware'
|
import { SharedVaultValetTokenAuthMiddleware } from '../Infra/InversifyExpress/Middleware/SharedVaultValetTokenAuthMiddleware'
|
||||||
|
import { ServiceIdentifier } from '@standardnotes/domain-core'
|
||||||
|
|
||||||
export class ContainerConfigLoader {
|
export class ContainerConfigLoader {
|
||||||
async load(configuration?: {
|
async load(configuration?: {
|
||||||
@@ -298,12 +299,14 @@ export class ContainerConfigLoader {
|
|||||||
.bind<DomainEventMessageHandlerInterface>(TYPES.Files_DomainEventMessageHandler)
|
.bind<DomainEventMessageHandlerInterface>(TYPES.Files_DomainEventMessageHandler)
|
||||||
.toConstantValue(new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Files_Logger)))
|
.toConstantValue(new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Files_Logger)))
|
||||||
container
|
container
|
||||||
.bind<DomainEventSubscriberFactoryInterface>(TYPES.Files_DomainEventSubscriberFactory)
|
.bind<DomainEventSubscriberInterface>(TYPES.Files_DomainEventSubscriber)
|
||||||
.toConstantValue(
|
.toConstantValue(
|
||||||
new SQSDomainEventSubscriberFactory(
|
new SQSOpenTelemetryDomainEventSubscriber(
|
||||||
container.get(TYPES.Files_SQS),
|
ServiceIdentifier.NAMES.FilesWorker,
|
||||||
container.get(TYPES.Files_SQS_QUEUE_URL),
|
container.get<SQSClient>(TYPES.Files_SQS),
|
||||||
container.get(TYPES.Files_DomainEventMessageHandler),
|
container.get<string>(TYPES.Files_SQS_QUEUE_URL),
|
||||||
|
container.get<DomainEventMessageHandlerInterface>(TYPES.Files_DomainEventMessageHandler),
|
||||||
|
container.get<winston.Logger>(TYPES.Files_Logger),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ const TYPES = {
|
|||||||
|
|
||||||
// Handlers
|
// Handlers
|
||||||
Files_DomainEventMessageHandler: Symbol.for('Files_DomainEventMessageHandler'),
|
Files_DomainEventMessageHandler: Symbol.for('Files_DomainEventMessageHandler'),
|
||||||
Files_DomainEventSubscriberFactory: Symbol.for('Files_DomainEventSubscriberFactory'),
|
Files_DomainEventSubscriber: Symbol.for('Files_DomainEventSubscriber'),
|
||||||
Files_AccountDeletionRequestedEventHandler: Symbol.for('Files_AccountDeletionRequestedEventHandler'),
|
Files_AccountDeletionRequestedEventHandler: Symbol.for('Files_AccountDeletionRequestedEventHandler'),
|
||||||
Files_SharedSubscriptionInvitationCanceledEventHandler: Symbol.for(
|
Files_SharedSubscriptionInvitationCanceledEventHandler: Symbol.for(
|
||||||
'Files_SharedSubscriptionInvitationCanceledEventHandler',
|
'Files_SharedSubscriptionInvitationCanceledEventHandler',
|
||||||
|
|||||||
@@ -3,6 +3,34 @@
|
|||||||
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.17.17](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.17.16...@standardnotes/home-server@1.17.17) (2023-10-18)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/home-server
|
||||||
|
|
||||||
|
## [1.17.16](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.17.15...@standardnotes/home-server@1.17.16) (2023-10-17)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/home-server
|
||||||
|
|
||||||
|
## [1.17.15](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.17.14...@standardnotes/home-server@1.17.15) (2023-10-17)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/home-server
|
||||||
|
|
||||||
|
## [1.17.14](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.17.13...@standardnotes/home-server@1.17.14) (2023-10-16)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/home-server
|
||||||
|
|
||||||
|
## [1.17.13](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.17.12...@standardnotes/home-server@1.17.13) (2023-10-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/home-server
|
||||||
|
|
||||||
|
## [1.17.12](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.17.11...@standardnotes/home-server@1.17.12) (2023-10-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/home-server
|
||||||
|
|
||||||
|
## [1.17.11](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.17.10...@standardnotes/home-server@1.17.11) (2023-10-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/home-server
|
||||||
|
|
||||||
## [1.17.10](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.17.9...@standardnotes/home-server@1.17.10) (2023-10-12)
|
## [1.17.10](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.17.9...@standardnotes/home-server@1.17.10) (2023-10-12)
|
||||||
|
|
||||||
**Note:** Version bump only for package @standardnotes/home-server
|
**Note:** Version bump only for package @standardnotes/home-server
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/home-server",
|
"name": "@standardnotes/home-server",
|
||||||
"version": "1.17.10",
|
"version": "1.17.17",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <21.0.0"
|
"node": ">=18.0.0 <21.0.0"
|
||||||
},
|
},
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user