mirror of
https://github.com/standardnotes/server
synced 2026-05-10 09:57:17 -04:00
Compare commits
99 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0057a5d6ff | |||
| b736dab3c1 | |||
| 951d965304 | |||
| 29e8de3238 | |||
| eeeacabaa8 | |||
| 51ca8229b8 | |||
| a6a19a391e | |||
| f6cdb7916c | |||
| eafb064d79 | |||
| ba050681f7 | |||
| 4780629549 | |||
| 79a44aa51f | |||
| dd72769841 | |||
| d8f1c66fd5 | |||
| afe9967d26 | |||
| 27bea444cc | |||
| 7a571dec0a | |||
| 8c57f505be | |||
| 973612bf4f | |||
| 702a1286eb | |||
| a45b5b69b5 | |||
| 321353f26c | |||
| db4607d4aa | |||
| f0531d68cb | |||
| 8a00d159a6 | |||
| d244cc0d5f | |||
| 6a2aa4b148 | |||
| 3ee49416f8 | |||
| ae1e86e19f | |||
| 9f76e389e2 | |||
| 6e2240e60c | |||
| cd37c951bb | |||
| c4c3dfb823 | |||
| c4b6f17ebc | |||
| 71ce938cb1 | |||
| dc76113915 | |||
| 6583ff6cd9 | |||
| 69ea947857 | |||
| eab78b3a95 | |||
| 3097f7f063 | |||
| 126989df82 | |||
| a25eb178c5 | |||
| 18dae26b8e | |||
| 5bc8157d4d | |||
| f29826e917 | |||
| ba7cbb989b | |||
| d4579ce21e | |||
| ed14d2dfb7 | |||
| 64f1fe59c2 | |||
| 207ef9f3e5 | |||
| 3ea0435459 | |||
| 7668713dd6 | |||
| f6bc1c3084 | |||
| 4203ff9a0c | |||
| 0281724196 | |||
| 94bd319279 | |||
| 373cfad1f7 | |||
| 59107f8553 | |||
| e066b6a126 | |||
| a0e4926135 | |||
| b1b244a2cf | |||
| b4a38d9dcc | |||
| 71e2a4187e | |||
| c94f9c1a60 | |||
| b9907924be | |||
| d4c188c096 | |||
| 2ccaf490df | |||
| cd893b41d7 | |||
| 3838358081 | |||
| 1a388f00c3 | |||
| bd71422fab | |||
| 3e1697f47f | |||
| 032cde7723 | |||
| 34b956b482 | |||
| 681e0378ae | |||
| 609e85f926 | |||
| e4ca310707 | |||
| d606493356 | |||
| 5ef6c5c14a | |||
| 0188f290f9 | |||
| 676cf36f8d | |||
| f8aef6c8ef | |||
| 5bf8cf49c1 | |||
| 51cd0a4dad | |||
| 1d06ffe9d5 | |||
| dbf532f55e | |||
| ca6dbc0053 | |||
| 1bb5980b45 | |||
| a02a28774b | |||
| 2d9b3578b6 | |||
| 3d5e747590 | |||
| 94467747ac | |||
| cebab59a02 | |||
| 09e1a892ca | |||
| 7b1eec21e5 | |||
| a58262d584 | |||
| a8f03e157b | |||
| a401962bcd | |||
| 9759814f63 |
@@ -38,6 +38,10 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
jq '(.containerDefinitions[] | select(.name=="${{ inputs.service_name }}-prod") | .environment[] | select(.name=="VERSION")).value = "${{ github.sha }}"' task-definition.json > tmp.json && mv tmp.json task-definition.json
|
jq '(.containerDefinitions[] | select(.name=="${{ inputs.service_name }}-prod") | .environment[] | select(.name=="VERSION")).value = "${{ github.sha }}"' task-definition.json > tmp.json && mv tmp.json task-definition.json
|
||||||
|
|
||||||
|
- name: Fill in the new package version in the Amazon ECS task definition
|
||||||
|
run: |
|
||||||
|
jq '(.containerDefinitions[] | select(.name=="${{ inputs.service_name }}-prod") | .environment[] | select(.name=="npm_package_version")).value = "${{ github.sha }}"' task-definition.json > tmp.json && mv tmp.json task-definition.json
|
||||||
|
|
||||||
- name: Fill in the new image ID in the Amazon ECS task definition
|
- name: Fill in the new image ID in the Amazon ECS task definition
|
||||||
id: task-def-prod
|
id: task-def-prod
|
||||||
uses: aws-actions/amazon-ecs-render-task-definition@v1
|
uses: aws-actions/amazon-ecs-render-task-definition@v1
|
||||||
|
|||||||
@@ -7,6 +7,10 @@ on:
|
|||||||
type: string
|
type: string
|
||||||
default: latest
|
default: latest
|
||||||
description: The Docker image tag used for SNJS container
|
description: The Docker image tag used for SNJS container
|
||||||
|
suite:
|
||||||
|
type: string
|
||||||
|
default: all
|
||||||
|
description: The test suite to run
|
||||||
secrets:
|
secrets:
|
||||||
DOCKER_USERNAME:
|
DOCKER_USERNAME:
|
||||||
required: true
|
required: true
|
||||||
@@ -18,149 +22,16 @@ on:
|
|||||||
required: true
|
required: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
e2e:
|
e2e-self-hosted:
|
||||||
name: (Self Hosting) E2E Test Suite
|
uses: standardnotes/server/.github/workflows/e2e-self-hosted.yml@main
|
||||||
strategy:
|
with:
|
||||||
fail-fast: false
|
snjs_image_tag: ${{ inputs.snjs_image_tag }}
|
||||||
matrix:
|
suite: ${{ inputs.suite }}
|
||||||
secondary_db_enabled: [true, false]
|
secrets: inherit
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
services:
|
|
||||||
snjs:
|
|
||||||
image: standardnotes/snjs:${{ inputs.snjs_image_tag }}
|
|
||||||
ports:
|
|
||||||
- 9001:9001
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Set up Node
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
registry-url: 'https://registry.npmjs.org'
|
|
||||||
node-version-file: '.nvmrc'
|
|
||||||
|
|
||||||
- name: Install
|
|
||||||
run: yarn install --immutable
|
|
||||||
|
|
||||||
- name: Run Server
|
|
||||||
run: docker compose -f docker-compose.ci.yml up -d
|
|
||||||
env:
|
|
||||||
DB_TYPE: mysql
|
|
||||||
CACHE_TYPE: redis
|
|
||||||
SECONDARY_DB_ENABLED: ${{ matrix.secondary_db_enabled }}
|
|
||||||
|
|
||||||
- name: Wait for server to start
|
|
||||||
run: docker/is-available.sh http://localhost:3123 $(pwd)/logs
|
|
||||||
|
|
||||||
- name: Run E2E Test Suite
|
|
||||||
run: yarn dlx mocha-headless-chrome --timeout 3600000 -f http://localhost:9001/mocha/test.html
|
|
||||||
|
|
||||||
- name: Show logs on failure
|
|
||||||
if: ${{ failure() }}
|
|
||||||
run: |
|
|
||||||
echo "# Errors:"
|
|
||||||
tail -n 100 logs/*.err
|
|
||||||
echo "# Logs:"
|
|
||||||
tail -n 100 logs/*.log
|
|
||||||
|
|
||||||
e2e-home-server:
|
e2e-home-server:
|
||||||
name: (Home Server) E2E Test Suite
|
uses: standardnotes/server/.github/workflows/e2e-home-server.yml@main
|
||||||
strategy:
|
with:
|
||||||
fail-fast: false
|
snjs_image_tag: ${{ inputs.snjs_image_tag }}
|
||||||
matrix:
|
suite: ${{ inputs.suite }}
|
||||||
db_type: [mysql, sqlite]
|
secrets: inherit
|
||||||
cache_type: [redis, memory]
|
|
||||||
secondary_db_enabled: [true, false]
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
services:
|
|
||||||
snjs:
|
|
||||||
image: standardnotes/snjs:${{ inputs.snjs_image_tag }}
|
|
||||||
ports:
|
|
||||||
- 9001:9001
|
|
||||||
cache:
|
|
||||||
image: redis
|
|
||||||
ports:
|
|
||||||
- 6379:6379
|
|
||||||
db:
|
|
||||||
image: mysql
|
|
||||||
ports:
|
|
||||||
- 3306:3306
|
|
||||||
env:
|
|
||||||
MYSQL_ROOT_PASSWORD: root
|
|
||||||
MYSQL_DATABASE: standardnotes
|
|
||||||
MYSQL_USER: standardnotes
|
|
||||||
MYSQL_PASSWORD: standardnotes
|
|
||||||
secondary_db:
|
|
||||||
image: mongo:5.0
|
|
||||||
ports:
|
|
||||||
- 27017:27017
|
|
||||||
env:
|
|
||||||
MONGO_INITDB_ROOT_USERNAME: standardnotes
|
|
||||||
MONGO_INITDB_ROOT_PASSWORD: standardnotes
|
|
||||||
MONGO_INITDB_DATABASE: standardnotes
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Set up Node
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
registry-url: 'https://registry.npmjs.org'
|
|
||||||
node-version-file: '.nvmrc'
|
|
||||||
|
|
||||||
- name: Install Dependencies
|
|
||||||
run: yarn install --immutable
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: yarn build
|
|
||||||
|
|
||||||
- name: Copy dotenv file
|
|
||||||
run: cp packages/home-server/.env.sample packages/home-server/.env
|
|
||||||
|
|
||||||
- name: Fill in env variables
|
|
||||||
run: |
|
|
||||||
sed -i "s/JWT_SECRET=/JWT_SECRET=$(openssl rand -hex 32)/g" packages/home-server/.env
|
|
||||||
sed -i "s/AUTH_JWT_SECRET=/AUTH_JWT_SECRET=$(openssl rand -hex 32)/g" packages/home-server/.env
|
|
||||||
sed -i "s/ENCRYPTION_SERVER_KEY=/ENCRYPTION_SERVER_KEY=$(openssl rand -hex 32)/g" packages/home-server/.env
|
|
||||||
sed -i "s/PSEUDO_KEY_PARAMS_KEY=/PSEUDO_KEY_PARAMS_KEY=$(openssl rand -hex 32)/g" packages/home-server/.env
|
|
||||||
sed -i "s/VALET_TOKEN_SECRET=/VALET_TOKEN_SECRET=$(openssl rand -hex 32)/g" packages/home-server/.env
|
|
||||||
echo "ACCESS_TOKEN_AGE=4" >> packages/home-server/.env
|
|
||||||
echo "REFRESH_TOKEN_AGE=10" >> packages/home-server/.env
|
|
||||||
echo "REVISIONS_FREQUENCY=2" >> packages/home-server/.env
|
|
||||||
echo "DB_HOST=localhost" >> packages/home-server/.env
|
|
||||||
echo "DB_PORT=3306" >> packages/home-server/.env
|
|
||||||
echo "DB_DATABASE=standardnotes" >> packages/home-server/.env
|
|
||||||
echo "DB_SQLITE_DATABASE_PATH=homeserver.db" >> packages/home-server/.env
|
|
||||||
echo "DB_USERNAME=standardnotes" >> packages/home-server/.env
|
|
||||||
echo "DB_PASSWORD=standardnotes" >> packages/home-server/.env
|
|
||||||
echo "DB_TYPE=${{ matrix.db_type }}" >> packages/home-server/.env
|
|
||||||
echo "DB_DEBUG_LEVEL=all" >> packages/home-server/.env
|
|
||||||
echo "REDIS_URL=redis://localhost:6379" >> packages/home-server/.env
|
|
||||||
echo "CACHE_TYPE=${{ matrix.cache_type }}" >> packages/home-server/.env
|
|
||||||
echo "SECONDARY_DB_ENABLED=${{ matrix.secondary_db_enabled }}" >> packages/home-server/.env
|
|
||||||
echo "MONGO_HOST=localhost" >> packages/home-server/.env
|
|
||||||
echo "MONGO_PORT=27017" >> packages/home-server/.env
|
|
||||||
echo "MONGO_DATABASE=standardnotes" >> packages/home-server/.env
|
|
||||||
echo "MONGO_USERNAME=standardnotes" >> packages/home-server/.env
|
|
||||||
echo "MONGO_PASSWORD=standardnotes" >> packages/home-server/.env
|
|
||||||
echo "FILES_SERVER_URL=http://localhost:3123" >> packages/home-server/.env
|
|
||||||
echo "E2E_TESTING=true" >> packages/home-server/.env
|
|
||||||
|
|
||||||
- name: Run Server
|
|
||||||
run: nohup yarn workspace @standardnotes/home-server start > logs/output.log 2>&1 &
|
|
||||||
env:
|
|
||||||
PORT: 3123
|
|
||||||
|
|
||||||
- name: Wait for server to start
|
|
||||||
run: for i in {1..30}; do curl -s http://localhost:3123/healthcheck && break || sleep 1; done
|
|
||||||
|
|
||||||
- name: Run E2E Test Suite
|
|
||||||
run: yarn dlx mocha-headless-chrome --timeout 3600000 -f http://localhost:9001/mocha/test.html
|
|
||||||
|
|
||||||
- name: Show logs on failure
|
|
||||||
if: ${{ failure() }}
|
|
||||||
run: tail -n 500 logs/output.log
|
|
||||||
|
|||||||
@@ -0,0 +1,128 @@
|
|||||||
|
name: E2E Home Server Test Suite
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
snjs_image_tag:
|
||||||
|
type: string
|
||||||
|
default: latest
|
||||||
|
description: The Docker image tag used for SNJS container
|
||||||
|
suite:
|
||||||
|
type: string
|
||||||
|
default: all
|
||||||
|
description: The test suite to run
|
||||||
|
secrets:
|
||||||
|
DOCKER_USERNAME:
|
||||||
|
required: true
|
||||||
|
DOCKER_PASSWORD:
|
||||||
|
required: true
|
||||||
|
AWS_ACCESS_KEY_ID:
|
||||||
|
required: true
|
||||||
|
AWS_SECRET_ACCESS_KEY:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
e2e-home-server:
|
||||||
|
name: (Home Server) E2E Test Suite
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
db_type: [mysql, sqlite]
|
||||||
|
cache_type: [redis, memory]
|
||||||
|
secondary_db_enabled: [true, false]
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
services:
|
||||||
|
snjs:
|
||||||
|
image: standardnotes/snjs:${{ inputs.snjs_image_tag }}
|
||||||
|
ports:
|
||||||
|
- 9001:9001
|
||||||
|
cache:
|
||||||
|
image: redis
|
||||||
|
ports:
|
||||||
|
- 6379:6379
|
||||||
|
db:
|
||||||
|
image: mysql
|
||||||
|
ports:
|
||||||
|
- 3306:3306
|
||||||
|
env:
|
||||||
|
MYSQL_ROOT_PASSWORD: root
|
||||||
|
MYSQL_DATABASE: standardnotes
|
||||||
|
MYSQL_USER: standardnotes
|
||||||
|
MYSQL_PASSWORD: standardnotes
|
||||||
|
secondary_db:
|
||||||
|
image: mongo:5.0
|
||||||
|
ports:
|
||||||
|
- 27017:27017
|
||||||
|
env:
|
||||||
|
MONGO_INITDB_ROOT_USERNAME: standardnotes
|
||||||
|
MONGO_INITDB_ROOT_PASSWORD: standardnotes
|
||||||
|
MONGO_INITDB_DATABASE: standardnotes
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up Node
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
registry-url: 'https://registry.npmjs.org'
|
||||||
|
node-version-file: '.nvmrc'
|
||||||
|
|
||||||
|
- name: Install Dependencies
|
||||||
|
run: yarn install --immutable
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: yarn build
|
||||||
|
|
||||||
|
- name: Copy dotenv file
|
||||||
|
run: cp packages/home-server/.env.sample packages/home-server/.env
|
||||||
|
|
||||||
|
- name: Fill in env variables
|
||||||
|
run: |
|
||||||
|
sed -i "s/JWT_SECRET=/JWT_SECRET=$(openssl rand -hex 32)/g" packages/home-server/.env
|
||||||
|
sed -i "s/AUTH_JWT_SECRET=/AUTH_JWT_SECRET=$(openssl rand -hex 32)/g" packages/home-server/.env
|
||||||
|
sed -i "s/ENCRYPTION_SERVER_KEY=/ENCRYPTION_SERVER_KEY=$(openssl rand -hex 32)/g" packages/home-server/.env
|
||||||
|
sed -i "s/PSEUDO_KEY_PARAMS_KEY=/PSEUDO_KEY_PARAMS_KEY=$(openssl rand -hex 32)/g" packages/home-server/.env
|
||||||
|
sed -i "s/VALET_TOKEN_SECRET=/VALET_TOKEN_SECRET=$(openssl rand -hex 32)/g" packages/home-server/.env
|
||||||
|
echo "ACCESS_TOKEN_AGE=4" >> packages/home-server/.env
|
||||||
|
echo "REFRESH_TOKEN_AGE=10" >> packages/home-server/.env
|
||||||
|
echo "REVISIONS_FREQUENCY=2" >> packages/home-server/.env
|
||||||
|
echo "DB_HOST=localhost" >> packages/home-server/.env
|
||||||
|
echo "DB_PORT=3306" >> packages/home-server/.env
|
||||||
|
echo "DB_DATABASE=standardnotes" >> packages/home-server/.env
|
||||||
|
echo "DB_SQLITE_DATABASE_PATH=homeserver.db" >> packages/home-server/.env
|
||||||
|
echo "DB_USERNAME=standardnotes" >> packages/home-server/.env
|
||||||
|
echo "DB_PASSWORD=standardnotes" >> packages/home-server/.env
|
||||||
|
echo "DB_TYPE=${{ matrix.db_type }}" >> packages/home-server/.env
|
||||||
|
echo "DB_DEBUG_LEVEL=all" >> packages/home-server/.env
|
||||||
|
echo "REDIS_URL=redis://localhost:6379" >> packages/home-server/.env
|
||||||
|
echo "CACHE_TYPE=${{ matrix.cache_type }}" >> packages/home-server/.env
|
||||||
|
echo "SECONDARY_DB_ENABLED=${{ matrix.secondary_db_enabled }}" >> packages/home-server/.env
|
||||||
|
echo "MONGO_HOST=localhost" >> packages/home-server/.env
|
||||||
|
echo "MONGO_PORT=27017" >> packages/home-server/.env
|
||||||
|
echo "MONGO_DATABASE=standardnotes" >> packages/home-server/.env
|
||||||
|
echo "MONGO_USERNAME=standardnotes" >> packages/home-server/.env
|
||||||
|
echo "MONGO_PASSWORD=standardnotes" >> packages/home-server/.env
|
||||||
|
echo "FILES_SERVER_URL=http://localhost:3123" >> packages/home-server/.env
|
||||||
|
echo "E2E_TESTING=true" >> packages/home-server/.env
|
||||||
|
|
||||||
|
- name: Run Server
|
||||||
|
run: nohup yarn workspace @standardnotes/home-server start > logs/output.log 2>&1 &
|
||||||
|
env:
|
||||||
|
PORT: 3123
|
||||||
|
|
||||||
|
- name: Wait for server to start
|
||||||
|
run: for i in {1..30}; do curl -s http://localhost:3123/healthcheck && break || sleep 1; done
|
||||||
|
|
||||||
|
- name: Run E2E Test Suite
|
||||||
|
run: yarn dlx mocha-headless-chrome --timeout 3600000 -f http://localhost:9001/mocha/test.html?suite=${{ inputs.suite }}
|
||||||
|
|
||||||
|
- name: Archive failed run logs
|
||||||
|
if: ${{ failure() }}
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: home-server-failure-logs-${{ inputs.suite }}-${{ matrix.db_type }}-${{ matrix.cache_type }}-${{ matrix.secondary_db_enabled }}
|
||||||
|
retention-days: 5
|
||||||
|
path: |
|
||||||
|
logs/output.log
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
name: E2E Self Hosted Test Suite
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
snjs_image_tag:
|
||||||
|
type: string
|
||||||
|
default: latest
|
||||||
|
description: The Docker image tag used for SNJS container
|
||||||
|
suite:
|
||||||
|
type: string
|
||||||
|
default: all
|
||||||
|
description: The test suite to run
|
||||||
|
secrets:
|
||||||
|
DOCKER_USERNAME:
|
||||||
|
required: true
|
||||||
|
DOCKER_PASSWORD:
|
||||||
|
required: true
|
||||||
|
AWS_ACCESS_KEY_ID:
|
||||||
|
required: true
|
||||||
|
AWS_SECRET_ACCESS_KEY:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
e2e:
|
||||||
|
name: (Self Hosting) E2E Test Suite
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
secondary_db_enabled: [true, false]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
services:
|
||||||
|
snjs:
|
||||||
|
image: standardnotes/snjs:${{ inputs.snjs_image_tag }}
|
||||||
|
ports:
|
||||||
|
- 9001:9001
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up Node
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
registry-url: 'https://registry.npmjs.org'
|
||||||
|
node-version-file: '.nvmrc'
|
||||||
|
|
||||||
|
- name: Install
|
||||||
|
run: yarn install --immutable
|
||||||
|
|
||||||
|
- name: Run Server
|
||||||
|
run: docker compose -f docker-compose.ci.yml up -d
|
||||||
|
env:
|
||||||
|
DB_TYPE: mysql
|
||||||
|
CACHE_TYPE: redis
|
||||||
|
SECONDARY_DB_ENABLED: ${{ matrix.secondary_db_enabled }}
|
||||||
|
|
||||||
|
- name: Wait for server to start
|
||||||
|
run: docker/is-available.sh http://localhost:3123 $(pwd)/logs
|
||||||
|
|
||||||
|
- name: Run E2E Test Suite
|
||||||
|
run: yarn dlx mocha-headless-chrome --timeout 3600000 -f http://localhost:9001/mocha/test.html?suite=${{ inputs.suite }}
|
||||||
|
|
||||||
|
- name: Archive failed run logs
|
||||||
|
if: ${{ failure() }}
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: self-hosted-failure-logs-${{ inputs.suite }}-${{ matrix.secondary_db_enabled }}
|
||||||
|
retention-days: 5
|
||||||
|
path: |
|
||||||
|
logs/*.err
|
||||||
|
logs/*.log
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
name: E2E Test Suite On Self Hosted Server
|
name: E2E Test Suite
|
||||||
|
|
||||||
run-name: E2E Test Suite against ${{ inputs.ref_name }} by ${{ inputs.author }}
|
run-name: E2E ${{ inputs.suite }} Test Suite against ${{ inputs.ref_name }} by ${{ inputs.author }}
|
||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
@@ -11,6 +11,10 @@ on:
|
|||||||
type: string
|
type: string
|
||||||
default: latest
|
default: latest
|
||||||
description: The Docker image tag used for SNJS container
|
description: The Docker image tag used for SNJS container
|
||||||
|
suite:
|
||||||
|
type: string
|
||||||
|
default: all
|
||||||
|
description: The test suite to run
|
||||||
author:
|
author:
|
||||||
type: string
|
type: string
|
||||||
default: unknown
|
default: unknown
|
||||||
@@ -26,4 +30,5 @@ jobs:
|
|||||||
uses: standardnotes/server/.github/workflows/common-e2e.yml@main
|
uses: standardnotes/server/.github/workflows/common-e2e.yml@main
|
||||||
with:
|
with:
|
||||||
snjs_image_tag: ${{ inputs.snjs_image_tag || 'latest' }}
|
snjs_image_tag: ${{ inputs.snjs_image_tag || 'latest' }}
|
||||||
|
suite: ${{ inputs.suite || 'all' }}
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|||||||
@@ -95,9 +95,20 @@ jobs:
|
|||||||
- name: Test
|
- name: Test
|
||||||
run: yarn test
|
run: yarn test
|
||||||
|
|
||||||
e2e:
|
e2e-base:
|
||||||
needs: build
|
needs: build
|
||||||
|
name: E2E Base Suite
|
||||||
name: E2E
|
|
||||||
uses: standardnotes/server/.github/workflows/common-e2e.yml@main
|
uses: standardnotes/server/.github/workflows/common-e2e.yml@main
|
||||||
|
with:
|
||||||
|
snjs_image_tag: 'latest'
|
||||||
|
suite: 'base'
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
|
# e2e-vaults:
|
||||||
|
# needs: build
|
||||||
|
# name: E2E Vaults Suite
|
||||||
|
# uses: standardnotes/server/.github/workflows/common-e2e.yml@main
|
||||||
|
# with:
|
||||||
|
# snjs_image_tag: 'latest'
|
||||||
|
# suite: 'vaults'
|
||||||
|
# secrets: inherit
|
||||||
|
|||||||
@@ -95,20 +95,32 @@ jobs:
|
|||||||
- name: Test
|
- name: Test
|
||||||
run: yarn test
|
run: yarn test
|
||||||
|
|
||||||
e2e:
|
e2e-base:
|
||||||
needs: build
|
needs: build
|
||||||
name: E2E
|
name: E2E Base Suite
|
||||||
uses: standardnotes/server/.github/workflows/common-e2e.yml@main
|
uses: standardnotes/server/.github/workflows/common-e2e.yml@main
|
||||||
|
with:
|
||||||
|
snjs_image_tag: 'latest'
|
||||||
|
suite: 'base'
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
|
# e2e-vaults:
|
||||||
|
# needs: build
|
||||||
|
# name: E2E Vaults Suite
|
||||||
|
# uses: standardnotes/server/.github/workflows/common-e2e.yml@main
|
||||||
|
# with:
|
||||||
|
# snjs_image_tag: 'latest'
|
||||||
|
# suite: 'vaults'
|
||||||
|
# secrets: inherit
|
||||||
|
|
||||||
publish-self-hosting:
|
publish-self-hosting:
|
||||||
needs: [ test, lint, e2e ]
|
needs: [ test, lint, e2e-base ]
|
||||||
name: Publish Self Hosting Docker Image
|
name: Publish Self Hosting Docker Image
|
||||||
uses: standardnotes/server/.github/workflows/common-self-hosting.yml@main
|
uses: standardnotes/server/.github/workflows/common-self-hosting.yml@main
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
publish-services:
|
publish-services:
|
||||||
needs: [ test, lint, e2e ]
|
needs: [ test, lint, e2e-base ]
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
|||||||
@@ -5945,7 +5945,7 @@ const RAW_RUNTIME_STATE =
|
|||||||
["newrelic", "npm:11.0.0"],\
|
["newrelic", "npm:11.0.0"],\
|
||||||
["prettier", "npm:3.0.3"],\
|
["prettier", "npm:3.0.3"],\
|
||||||
["reflect-metadata", "npm:0.1.13"],\
|
["reflect-metadata", "npm:0.1.13"],\
|
||||||
["sqs-consumer", "virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:6.2.1"],\
|
["sqs-consumer", "virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:7.3.0"],\
|
||||||
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.0"],\
|
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.0"],\
|
||||||
["typescript", "patch:typescript@npm%3A5.0.4#optional!builtin<compat/typescript>::version=5.0.4&hash=b5f058"],\
|
["typescript", "patch:typescript@npm%3A5.0.4#optional!builtin<compat/typescript>::version=5.0.4&hash=b5f058"],\
|
||||||
["winston", "npm:3.9.0"]\
|
["winston", "npm:3.9.0"]\
|
||||||
@@ -6156,6 +6156,7 @@ const RAW_RUNTIME_STATE =
|
|||||||
["@types/cors", "npm:2.8.13"],\
|
["@types/cors", "npm:2.8.13"],\
|
||||||
["@types/dotenv", "npm:8.2.0"],\
|
["@types/dotenv", "npm:8.2.0"],\
|
||||||
["@types/express", "npm:4.17.17"],\
|
["@types/express", "npm:4.17.17"],\
|
||||||
|
["@types/ioredis", "npm:5.0.0"],\
|
||||||
["@types/jest", "npm:29.5.2"],\
|
["@types/jest", "npm:29.5.2"],\
|
||||||
["@types/newrelic", "npm:9.14.0"],\
|
["@types/newrelic", "npm:9.14.0"],\
|
||||||
["@types/node", "npm:20.5.7"],\
|
["@types/node", "npm:20.5.7"],\
|
||||||
@@ -6168,6 +6169,7 @@ const RAW_RUNTIME_STATE =
|
|||||||
["express", "npm:4.18.2"],\
|
["express", "npm:4.18.2"],\
|
||||||
["inversify", "npm:6.0.1"],\
|
["inversify", "npm:6.0.1"],\
|
||||||
["inversify-express-utils", "npm:6.4.3"],\
|
["inversify-express-utils", "npm:6.4.3"],\
|
||||||
|
["ioredis", "npm:5.3.2"],\
|
||||||
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.5.0"],\
|
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.5.0"],\
|
||||||
["mongodb", "virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:6.0.0"],\
|
["mongodb", "virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:6.0.0"],\
|
||||||
["mysql2", "npm:3.3.3"],\
|
["mysql2", "npm:3.3.3"],\
|
||||||
@@ -6340,6 +6342,7 @@ const RAW_RUNTIME_STATE =
|
|||||||
["@types/cors", "npm:2.8.13"],\
|
["@types/cors", "npm:2.8.13"],\
|
||||||
["@types/dotenv", "npm:8.2.0"],\
|
["@types/dotenv", "npm:8.2.0"],\
|
||||||
["@types/express", "npm:4.17.17"],\
|
["@types/express", "npm:4.17.17"],\
|
||||||
|
["@types/ioredis", "npm:5.0.0"],\
|
||||||
["@types/jest", "npm:29.5.2"],\
|
["@types/jest", "npm:29.5.2"],\
|
||||||
["@types/jsonwebtoken", "npm:9.0.2"],\
|
["@types/jsonwebtoken", "npm:9.0.2"],\
|
||||||
["@types/newrelic", "npm:9.14.0"],\
|
["@types/newrelic", "npm:9.14.0"],\
|
||||||
@@ -6359,6 +6362,7 @@ const RAW_RUNTIME_STATE =
|
|||||||
["helmet", "npm:7.0.0"],\
|
["helmet", "npm:7.0.0"],\
|
||||||
["inversify", "npm:6.0.1"],\
|
["inversify", "npm:6.0.1"],\
|
||||||
["inversify-express-utils", "npm:6.4.3"],\
|
["inversify-express-utils", "npm:6.4.3"],\
|
||||||
|
["ioredis", "npm:5.3.2"],\
|
||||||
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.5.0"],\
|
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.5.0"],\
|
||||||
["jsonwebtoken", "npm:9.0.0"],\
|
["jsonwebtoken", "npm:9.0.0"],\
|
||||||
["mongodb", "virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:6.0.0"],\
|
["mongodb", "virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:6.0.0"],\
|
||||||
@@ -15713,17 +15717,17 @@ const RAW_RUNTIME_STATE =
|
|||||||
}]\
|
}]\
|
||||||
]],\
|
]],\
|
||||||
["sqs-consumer", [\
|
["sqs-consumer", [\
|
||||||
["npm:6.2.1", {\
|
["npm:7.3.0", {\
|
||||||
"packageLocation": "./.yarn/cache/sqs-consumer-npm-6.2.1-857abd3d30-a903daa836.zip/node_modules/sqs-consumer/",\
|
"packageLocation": "./.yarn/cache/sqs-consumer-npm-7.3.0-a47c08ef71-367ea2a6f3.zip/node_modules/sqs-consumer/",\
|
||||||
"packageDependencies": [\
|
"packageDependencies": [\
|
||||||
["sqs-consumer", "npm:6.2.1"]\
|
["sqs-consumer", "npm:7.3.0"]\
|
||||||
],\
|
],\
|
||||||
"linkType": "SOFT"\
|
"linkType": "SOFT"\
|
||||||
}],\
|
}],\
|
||||||
["virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:6.2.1", {\
|
["virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:7.3.0", {\
|
||||||
"packageLocation": "./.yarn/__virtual__/sqs-consumer-virtual-603a7c5831/0/cache/sqs-consumer-npm-6.2.1-857abd3d30-a903daa836.zip/node_modules/sqs-consumer/",\
|
"packageLocation": "./.yarn/__virtual__/sqs-consumer-virtual-bf07118bf0/0/cache/sqs-consumer-npm-7.3.0-a47c08ef71-367ea2a6f3.zip/node_modules/sqs-consumer/",\
|
||||||
"packageDependencies": [\
|
"packageDependencies": [\
|
||||||
["sqs-consumer", "virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:6.2.1"],\
|
["sqs-consumer", "virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:7.3.0"],\
|
||||||
["@aws-sdk/client-sqs", "npm:3.342.0"],\
|
["@aws-sdk/client-sqs", "npm:3.342.0"],\
|
||||||
["@types/aws-sdk__client-sqs", null],\
|
["@types/aws-sdk__client-sqs", null],\
|
||||||
["debug", "virtual:ac3d8e680759ce54399273724d44e041d6c9b73454d191d411a8c44bb27e22f02aaf6ed9d3ad0ac1c298eac4833cff369c9c7b84c573016112c4f84be2cd8543#npm:4.3.4"]\
|
["debug", "virtual:ac3d8e680759ce54399273724d44e041d6c9b73454d191d411a8c44bb27e22f02aaf6ed9d3ad0ac1c298eac4833cff369c9c7b84c573016112c4f84be2cd8543#npm:4.3.4"]\
|
||||||
@@ -16772,7 +16776,7 @@ const RAW_RUNTIME_STATE =
|
|||||||
["@types/better-sqlite3", null],\
|
["@types/better-sqlite3", null],\
|
||||||
["@types/google-cloud__spanner", null],\
|
["@types/google-cloud__spanner", null],\
|
||||||
["@types/hdb-pool", null],\
|
["@types/hdb-pool", null],\
|
||||||
["@types/ioredis", null],\
|
["@types/ioredis", "npm:5.0.0"],\
|
||||||
["@types/mongodb", null],\
|
["@types/mongodb", null],\
|
||||||
["@types/mssql", null],\
|
["@types/mssql", null],\
|
||||||
["@types/mysql2", null],\
|
["@types/mysql2", null],\
|
||||||
@@ -16796,7 +16800,7 @@ const RAW_RUNTIME_STATE =
|
|||||||
["dotenv", "npm:16.1.3"],\
|
["dotenv", "npm:16.1.3"],\
|
||||||
["glob", "npm:8.1.0"],\
|
["glob", "npm:8.1.0"],\
|
||||||
["hdb-pool", null],\
|
["hdb-pool", null],\
|
||||||
["ioredis", null],\
|
["ioredis", "npm:5.3.2"],\
|
||||||
["mkdirp", "npm:2.1.6"],\
|
["mkdirp", "npm:2.1.6"],\
|
||||||
["mongodb", "virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:6.0.0"],\
|
["mongodb", "virtual:365b8c88cdf194291829ee28b79556e2328175d26a621363e703848100bea0042e9500db2a1206c9bbc3a4a76a1d169639ef774b2ea3a1a98584a9936b58c6be#npm:6.0.0"],\
|
||||||
["mssql", null],\
|
["mssql", null],\
|
||||||
|
|||||||
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.
Vendored
BIN
Binary file not shown.
BIN
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.
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.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
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.
Binary file not shown.
Binary file not shown.
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.
Binary file not shown.
Binary file not shown.
@@ -139,6 +139,11 @@ LINKING_RESULT=$(link_queue_and_topic $AUTH_TOPIC_ARN $FILES_QUEUE_ARN)
|
|||||||
echo "linking done:"
|
echo "linking done:"
|
||||||
echo "$LINKING_RESULT"
|
echo "$LINKING_RESULT"
|
||||||
|
|
||||||
|
echo "linking topic $SYNCING_SERVER_TOPIC_ARN to queue $FILES_QUEUE_ARN"
|
||||||
|
LINKING_RESULT=$(link_queue_and_topic $SYNCING_SERVER_TOPIC_ARN $FILES_QUEUE_ARN)
|
||||||
|
echo "linking done:"
|
||||||
|
echo "$LINKING_RESULT"
|
||||||
|
|
||||||
QUEUE_NAME="syncing-server-local-queue"
|
QUEUE_NAME="syncing-server-local-queue"
|
||||||
|
|
||||||
echo "creating queue $QUEUE_NAME"
|
echo "creating queue $QUEUE_NAME"
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ module.exports = {
|
|||||||
testEnvironment: 'node',
|
testEnvironment: 'node',
|
||||||
testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.ts$',
|
testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.ts$',
|
||||||
testTimeout: 20000,
|
testTimeout: 20000,
|
||||||
coverageReporters: ['text'],
|
|
||||||
reporters: ['summary'],
|
|
||||||
coverageThreshold: {
|
coverageThreshold: {
|
||||||
global: {
|
global: {
|
||||||
branches: 100,
|
branches: 100,
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@
|
|||||||
"release": "lerna version --conventional-graduate --conventional-commits --yes -m \"chore(release): publish new version\"",
|
"release": "lerna version --conventional-graduate --conventional-commits --yes -m \"chore(release): publish new version\"",
|
||||||
"publish": "lerna publish from-git --yes --no-verify-access --loglevel verbose",
|
"publish": "lerna publish from-git --yes --no-verify-access --loglevel verbose",
|
||||||
"postversion": "./scripts/push-tags-one-by-one.sh",
|
"postversion": "./scripts/push-tags-one-by-one.sh",
|
||||||
"e2e": "yarn workspace @standardnotes/home-server run build && PORT=3123 yarn workspace @standardnotes/home-server start",
|
"e2e": "yarn build && PORT=3123 yarn workspace @standardnotes/home-server start",
|
||||||
"start": "yarn workspace @standardnotes/home-server run build && yarn workspace @standardnotes/home-server start"
|
"start": "yarn workspace @standardnotes/home-server run build && yarn workspace @standardnotes/home-server start"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -3,6 +3,82 @@
|
|||||||
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.28.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.28.1...@standardnotes/analytics@2.28.2) (2023-10-09)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* remove xray sdk in favor of opentelemetry ([b736dab](https://github.com/standardnotes/server/commit/b736dab3c1f76c9e03c4bc7bbf153dcb3309b7cb))
|
||||||
|
|
||||||
|
## [2.28.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.28.0...@standardnotes/analytics@2.28.1) (2023-10-06)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* add xray-sdk to background processors ([a45b5b6](https://github.com/standardnotes/server/commit/a45b5b69b5d68c2e696c30f0ba5ad22d313321e6))
|
||||||
|
|
||||||
|
# [2.28.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.27.10...@standardnotes/analytics@2.28.0) (2023-10-06)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add xray to analytics scheduler and websockets ([f0531d6](https://github.com/standardnotes/server/commit/f0531d68cb77036222f2a34602819f11e6a2697d))
|
||||||
|
|
||||||
|
## [2.27.10](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.27.9...@standardnotes/analytics@2.27.10) (2023-10-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.27.9](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.27.8...@standardnotes/analytics@2.27.9) (2023-10-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.27.8](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.27.7...@standardnotes/analytics@2.27.8) (2023-10-04)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.27.7](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.27.6...@standardnotes/analytics@2.27.7) (2023-10-04)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.27.6](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.27.5...@standardnotes/analytics@2.27.6) (2023-10-04)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.27.5](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.27.4...@standardnotes/analytics@2.27.5) (2023-10-04)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.27.4](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.27.3...@standardnotes/analytics@2.27.4) (2023-10-03)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.27.3](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.27.2...@standardnotes/analytics@2.27.3) (2023-10-03)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.27.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.27.1...@standardnotes/analytics@2.27.2) (2023-09-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.27.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.27.0...@standardnotes/analytics@2.27.1) (2023-09-27)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
# [2.27.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.24...@standardnotes/analytics@2.27.0) (2023-09-26)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* refactor handling revision creation from dump ([#854](https://github.com/standardnotes/server/issues/854)) ([ca6dbc0](https://github.com/standardnotes/server/commit/ca6dbc00537bb20f508f9310b1a838421f53a643))
|
||||||
|
|
||||||
|
## [2.26.24](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.23...@standardnotes/analytics@2.26.24) (2023-09-25)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.26.23](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.22...@standardnotes/analytics@2.26.23) (2023-09-25)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.26.22](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.21...@standardnotes/analytics@2.26.22) (2023-09-25)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
## [2.26.21](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.20...@standardnotes/analytics@2.26.21) (2023-09-25)
|
## [2.26.21](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.20...@standardnotes/analytics@2.26.21) (2023-09-25)
|
||||||
|
|
||||||
**Note:** Version bump only for package @standardnotes/analytics
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/analytics",
|
"name": "@standardnotes/analytics",
|
||||||
"version": "2.26.21",
|
"version": "2.28.2",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <21.0.0"
|
"node": ">=18.0.0 <21.0.0"
|
||||||
},
|
},
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
"build": "tsc --build",
|
"build": "tsc --build",
|
||||||
"lint": "eslint . --ext .ts",
|
"lint": "eslint . --ext .ts",
|
||||||
"lint:fix": "eslint . --ext .ts --fix",
|
"lint:fix": "eslint . --ext .ts --fix",
|
||||||
"test": "jest --coverage --config=./jest.config.js --maxWorkers=50%",
|
"test": "jest --coverage --no-cache --config=./jest.config.js --maxWorkers=50%",
|
||||||
"worker": "yarn node dist/bin/worker.js",
|
"worker": "yarn node dist/bin/worker.js",
|
||||||
"report": "yarn node dist/bin/report.js",
|
"report": "yarn node dist/bin/report.js",
|
||||||
"setup:env": "cp .env.sample .env",
|
"setup:env": "cp .env.sample .env",
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import {
|
|||||||
SNSDomainEventPublisher,
|
SNSDomainEventPublisher,
|
||||||
SQSDomainEventSubscriberFactory,
|
SQSDomainEventSubscriberFactory,
|
||||||
SQSEventMessageHandler,
|
SQSEventMessageHandler,
|
||||||
SQSNewRelicEventMessageHandler,
|
|
||||||
} 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'
|
||||||
@@ -244,11 +243,7 @@ export class ContainerConfigLoader {
|
|||||||
|
|
||||||
container
|
container
|
||||||
.bind<DomainEventMessageHandlerInterface>(TYPES.DomainEventMessageHandler)
|
.bind<DomainEventMessageHandlerInterface>(TYPES.DomainEventMessageHandler)
|
||||||
.toConstantValue(
|
.toConstantValue(new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Logger)))
|
||||||
env.get('NEW_RELIC_ENABLED', true) === 'true'
|
|
||||||
? new SQSNewRelicEventMessageHandler(eventHandlers, container.get(TYPES.Logger))
|
|
||||||
: new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Logger)),
|
|
||||||
)
|
|
||||||
container
|
container
|
||||||
.bind<DomainEventSubscriberFactoryInterface>(TYPES.DomainEventSubscriberFactory)
|
.bind<DomainEventSubscriberFactoryInterface>(TYPES.DomainEventSubscriberFactory)
|
||||||
.toConstantValue(
|
.toConstantValue(
|
||||||
|
|||||||
@@ -3,6 +3,84 @@
|
|||||||
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.77.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.77.1...@standardnotes/api-gateway@1.77.2) (2023-10-09)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* remove xray sdk in favor of opentelemetry ([b736dab](https://github.com/standardnotes/api-gateway/commit/b736dab3c1f76c9e03c4bc7bbf153dcb3309b7cb))
|
||||||
|
|
||||||
|
## [1.77.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.77.0...@standardnotes/api-gateway@1.77.1) (2023-10-06)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
# [1.77.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.76.2...@standardnotes/api-gateway@1.77.0) (2023-10-05)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* setting xray segment user on api-gateway level ([3ee4941](https://github.com/standardnotes/api-gateway/commit/3ee49416f8e19207540141d98baa7f68880929bd))
|
||||||
|
|
||||||
|
## [1.76.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.76.1...@standardnotes/api-gateway@1.76.2) (2023-10-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
## [1.76.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.76.0...@standardnotes/api-gateway@1.76.1) (2023-10-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
# [1.76.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.13...@standardnotes/api-gateway@1.76.0) (2023-10-04)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **api-gateaway:** configure aws-xray-sdk ([dc76113](https://github.com/standardnotes/api-gateway/commit/dc7611391515dd49a8e9b7ce8ac5e128cd7af0a8))
|
||||||
|
|
||||||
|
## [1.75.13](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.12...@standardnotes/api-gateway@1.75.13) (2023-10-04)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
## [1.75.12](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.11...@standardnotes/api-gateway@1.75.12) (2023-10-04)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
## [1.75.11](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.10...@standardnotes/api-gateway@1.75.11) (2023-10-04)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
## [1.75.10](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.9...@standardnotes/api-gateway@1.75.10) (2023-10-04)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
## [1.75.9](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.8...@standardnotes/api-gateway@1.75.9) (2023-10-03)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
## [1.75.8](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.7...@standardnotes/api-gateway@1.75.8) (2023-10-03)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
## [1.75.7](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.6...@standardnotes/api-gateway@1.75.7) (2023-09-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
## [1.75.6](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.5...@standardnotes/api-gateway@1.75.6) (2023-09-27)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
## [1.75.5](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.4...@standardnotes/api-gateway@1.75.5) (2023-09-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
## [1.75.4](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.3...@standardnotes/api-gateway@1.75.4) (2023-09-25)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
## [1.75.3](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.2...@standardnotes/api-gateway@1.75.3) (2023-09-25)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
## [1.75.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.1...@standardnotes/api-gateway@1.75.2) (2023-09-25)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
## [1.75.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.0...@standardnotes/api-gateway@1.75.1) (2023-09-25)
|
## [1.75.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.75.0...@standardnotes/api-gateway@1.75.1) (2023-09-25)
|
||||||
|
|
||||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/api-gateway",
|
"name": "@standardnotes/api-gateway",
|
||||||
"version": "1.75.1",
|
"version": "1.77.2",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <21.0.0"
|
"node": ">=18.0.0 <21.0.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,6 +3,151 @@
|
|||||||
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.152.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.152.1...@standardnotes/auth-server@1.152.2) (2023-10-09)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* remove xray sdk in favor of opentelemetry ([b736dab](https://github.com/standardnotes/server/commit/b736dab3c1f76c9e03c4bc7bbf153dcb3309b7cb))
|
||||||
|
|
||||||
|
## [1.152.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.152.0...@standardnotes/auth-server@1.152.1) (2023-10-06)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **auth:** checking for transition role when triggering transition ([79a44aa](https://github.com/standardnotes/server/commit/79a44aa51f15311fcaf76c39f93d1934ec1d135d))
|
||||||
|
|
||||||
|
# [1.152.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.151.2...@standardnotes/auth-server@1.152.0) (2023-10-06)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **auth:** strip user from transition role after migration ([afe9967](https://github.com/standardnotes/server/commit/afe9967d26b5be02d1dc76a740df614d81a6984e))
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* switch transition direction ([27bea44](https://github.com/standardnotes/server/commit/27bea444cce4964feda04bad64e5f12a07415e0c))
|
||||||
|
|
||||||
|
## [1.151.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.151.1...@standardnotes/auth-server@1.151.2) (2023-10-06)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* add xray-sdk to background processors ([a45b5b6](https://github.com/standardnotes/server/commit/a45b5b69b5d68c2e696c30f0ba5ad22d313321e6))
|
||||||
|
|
||||||
|
## [1.151.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.151.0...@standardnotes/auth-server@1.151.1) (2023-10-06)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/auth-server
|
||||||
|
|
||||||
|
# [1.151.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.150.9...@standardnotes/auth-server@1.151.0) (2023-10-05)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* setting xray segment user on api-gateway level ([3ee4941](https://github.com/standardnotes/server/commit/3ee49416f8e19207540141d98baa7f68880929bd))
|
||||||
|
|
||||||
|
## [1.150.9](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.150.8...@standardnotes/auth-server@1.150.9) (2023-10-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/auth-server
|
||||||
|
|
||||||
|
## [1.150.8](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.150.7...@standardnotes/auth-server@1.150.8) (2023-10-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/auth-server
|
||||||
|
|
||||||
|
## [1.150.7](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.150.6...@standardnotes/auth-server@1.150.7) (2023-10-04)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* identifying services in workers ([eab78b3](https://github.com/standardnotes/server/commit/eab78b3a95ec82cb779d069d172169bfa92368c9))
|
||||||
|
|
||||||
|
## [1.150.6](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.150.5...@standardnotes/auth-server@1.150.6) (2023-10-04)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **auth:** disable users from registering to MongoDB ([d4579ce](https://github.com/standardnotes/server/commit/d4579ce21ed34ba433deb1fe2ff25c073fbe9622))
|
||||||
|
|
||||||
|
## [1.150.5](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.150.4...@standardnotes/auth-server@1.150.5) (2023-10-04)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/auth-server
|
||||||
|
|
||||||
|
## [1.150.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.150.3...@standardnotes/auth-server@1.150.4) (2023-10-04)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/auth-server
|
||||||
|
|
||||||
|
## [1.150.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.150.2...@standardnotes/auth-server@1.150.3) (2023-10-04)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **auth:** remove ec2 plugin from worker ([0281724](https://github.com/standardnotes/server/commit/02817241965db06cc02e9cca1d068446db0dee4e))
|
||||||
|
|
||||||
|
## [1.150.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.150.1...@standardnotes/auth-server@1.150.2) (2023-10-04)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **auth:** remove ec2 plugin ([373cfad](https://github.com/standardnotes/server/commit/373cfad1f7c26d3a0ec2a69e720bbce535170359))
|
||||||
|
|
||||||
|
## [1.150.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.150.0...@standardnotes/auth-server@1.150.1) (2023-10-03)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/auth-server
|
||||||
|
|
||||||
|
# [1.150.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.149.1...@standardnotes/auth-server@1.150.0) (2023-10-03)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add xray segment tracing on auth-worker ([b1b244a](https://github.com/standardnotes/server/commit/b1b244a2cf1e17ddf67fc9b238b4b25a1bc5a190))
|
||||||
|
|
||||||
|
## [1.149.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.149.0...@standardnotes/auth-server@1.149.1) (2023-10-02)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **auth:** enable xray only for server ([71e2a41](https://github.com/standardnotes/server/commit/71e2a4187e8f79b2a3055f502310ed0b6a6d82ea))
|
||||||
|
|
||||||
|
# [1.149.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.148.2...@standardnotes/auth-server@1.149.0) (2023-10-02)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **auth:** add aws xray ecs and ec2 plugins ([3838358](https://github.com/standardnotes/server/commit/383835808165aba58d15e79f03b5ba4e1c899f4c))
|
||||||
|
* **auth:** prevent from loop disabling of email settings ([#858](https://github.com/standardnotes/server/issues/858)) ([bd71422](https://github.com/standardnotes/server/commit/bd71422fabc4b5b47cca6dd071e3332943adc81d))
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **auth:** introduce AWS X-Ray SDK ([#859](https://github.com/standardnotes/server/issues/859)) ([1a388f0](https://github.com/standardnotes/server/commit/1a388f00c3897d1ebb1411793cfb23c3d305ac2e))
|
||||||
|
|
||||||
|
## [1.148.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.148.1...@standardnotes/auth-server@1.148.2) (2023-09-29)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **auth:** increase ttl for in progress duration of transitions ([681e037](https://github.com/standardnotes/server/commit/681e0378ae6b97c838b0b34ccc630194b304b81a))
|
||||||
|
|
||||||
|
## [1.148.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.148.0...@standardnotes/auth-server@1.148.1) (2023-09-29)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **auth:** disable transitions retriggering if they are in progress ([5ef6c5c](https://github.com/standardnotes/server/commit/5ef6c5c14a9f7a558de7ac9ff0ab99a5f831c127))
|
||||||
|
|
||||||
|
# [1.148.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.147.1...@standardnotes/auth-server@1.148.0) (2023-09-28)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* block file operations during transition ([#856](https://github.com/standardnotes/server/issues/856)) ([676cf36](https://github.com/standardnotes/server/commit/676cf36f8d769aa433880b2800f0457d06fbbf14))
|
||||||
|
|
||||||
|
## [1.147.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.147.0...@standardnotes/auth-server@1.147.1) (2023-09-27)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/auth-server
|
||||||
|
|
||||||
|
# [1.147.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.146.4...@standardnotes/auth-server@1.147.0) (2023-09-26)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* refactor handling revision creation from dump ([#854](https://github.com/standardnotes/server/issues/854)) ([ca6dbc0](https://github.com/standardnotes/server/commit/ca6dbc00537bb20f508f9310b1a838421f53a643))
|
||||||
|
|
||||||
|
## [1.146.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.146.3...@standardnotes/auth-server@1.146.4) (2023-09-25)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/auth-server
|
||||||
|
|
||||||
|
## [1.146.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.146.2...@standardnotes/auth-server@1.146.3) (2023-09-25)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/auth-server
|
||||||
|
|
||||||
|
## [1.146.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.146.1...@standardnotes/auth-server@1.146.2) (2023-09-25)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/auth-server
|
||||||
|
|
||||||
## [1.146.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.146.0...@standardnotes/auth-server@1.146.1) (2023-09-25)
|
## [1.146.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.146.0...@standardnotes/auth-server@1.146.1) (2023-09-25)
|
||||||
|
|
||||||
**Note:** Version bump only for package @standardnotes/auth-server
|
**Note:** Version bump only for package @standardnotes/auth-server
|
||||||
|
|||||||
@@ -49,13 +49,13 @@ const requestTransition = async (
|
|||||||
itemsTransitionStatus?.value === TransitionStatus.STATUSES.Verified &&
|
itemsTransitionStatus?.value === TransitionStatus.STATUSES.Verified &&
|
||||||
revisionsTransitionStatus?.value === TransitionStatus.STATUSES.Verified
|
revisionsTransitionStatus?.value === TransitionStatus.STATUSES.Verified
|
||||||
|
|
||||||
if (userHasTransitionRole && bothTransitionStatusesAreVerified) {
|
if (!userHasTransitionRole && bothTransitionStatusesAreVerified) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
let wasTransitionRequested = false
|
let wasTransitionRequested = false
|
||||||
|
|
||||||
if (itemsTransitionStatus?.value !== TransitionStatus.STATUSES.Verified) {
|
if (itemsTransitionStatus === null || itemsTransitionStatus.value === TransitionStatus.STATUSES.Failed) {
|
||||||
wasTransitionRequested = true
|
wasTransitionRequested = true
|
||||||
await transitionStatusRepository.remove(user.uuid, 'items')
|
await transitionStatusRepository.remove(user.uuid, 'items')
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ const requestTransition = async (
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (revisionsTransitionStatus?.value !== TransitionStatus.STATUSES.Verified) {
|
if (revisionsTransitionStatus === null || revisionsTransitionStatus.value === TransitionStatus.STATUSES.Failed) {
|
||||||
wasTransitionRequested = true
|
wasTransitionRequested = true
|
||||||
await transitionStatusRepository.remove(user.uuid, 'revisions')
|
await transitionStatusRepository.remove(user.uuid, 'revisions')
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/auth-server",
|
"name": "@standardnotes/auth-server",
|
||||||
"version": "1.146.1",
|
"version": "1.152.2",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <21.0.0"
|
"node": ">=18.0.0 <21.0.0"
|
||||||
},
|
},
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
"lint": "eslint . --ext .ts",
|
"lint": "eslint . --ext .ts",
|
||||||
"lint:fix": "eslint . --fix --ext .ts",
|
"lint:fix": "eslint . --fix --ext .ts",
|
||||||
"pretest": "yarn lint && yarn build",
|
"pretest": "yarn lint && yarn build",
|
||||||
"test": "jest --coverage --config=./jest.config.js --maxWorkers=50%",
|
"test": "jest --coverage --no-cache --config=./jest.config.js --maxWorkers=50%",
|
||||||
"start": "yarn node dist/bin/server.js",
|
"start": "yarn node dist/bin/server.js",
|
||||||
"worker": "yarn node dist/bin/worker.js",
|
"worker": "yarn node dist/bin/worker.js",
|
||||||
"cleanup": "yarn node dist/bin/cleanup.js",
|
"cleanup": "yarn node dist/bin/cleanup.js",
|
||||||
|
|||||||
@@ -92,7 +92,6 @@ import {
|
|||||||
SNSDomainEventPublisher,
|
SNSDomainEventPublisher,
|
||||||
SQSDomainEventSubscriberFactory,
|
SQSDomainEventSubscriberFactory,
|
||||||
SQSEventMessageHandler,
|
SQSEventMessageHandler,
|
||||||
SQSNewRelicEventMessageHandler,
|
|
||||||
} 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'
|
||||||
@@ -273,6 +272,7 @@ import { UserAddedToSharedVaultEventHandler } from '../Domain/Handler/UserAddedT
|
|||||||
import { UserRemovedFromSharedVaultEventHandler } from '../Domain/Handler/UserRemovedFromSharedVaultEventHandler'
|
import { UserRemovedFromSharedVaultEventHandler } from '../Domain/Handler/UserRemovedFromSharedVaultEventHandler'
|
||||||
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'
|
||||||
|
|
||||||
export class ContainerConfigLoader {
|
export class ContainerConfigLoader {
|
||||||
constructor(private mode: 'server' | 'worker' = 'server') {}
|
constructor(private mode: 'server' | 'worker' = 'server') {}
|
||||||
@@ -349,7 +349,8 @@ export class ContainerConfigLoader {
|
|||||||
secretAccessKey: env.get('SNS_SECRET_ACCESS_KEY', true),
|
secretAccessKey: env.get('SNS_SECRET_ACCESS_KEY', true),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
container.bind<SNSClient>(TYPES.Auth_SNS).toConstantValue(new SNSClient(snsConfig))
|
const snsClient = new SNSClient(snsConfig)
|
||||||
|
container.bind<SNSClient>(TYPES.Auth_SNS).toConstantValue(snsClient)
|
||||||
|
|
||||||
const sqsConfig: SQSClientConfig = {
|
const sqsConfig: SQSClientConfig = {
|
||||||
region: env.get('SQS_AWS_REGION', true),
|
region: env.get('SQS_AWS_REGION', true),
|
||||||
@@ -363,13 +364,14 @@ export class ContainerConfigLoader {
|
|||||||
secretAccessKey: env.get('SQS_SECRET_ACCESS_KEY', true),
|
secretAccessKey: env.get('SQS_SECRET_ACCESS_KEY', true),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
container.bind<SQSClient>(TYPES.Auth_SQS).toConstantValue(new SQSClient(sqsConfig))
|
const sqsClient = new SQSClient(sqsConfig)
|
||||||
|
container.bind<SQSClient>(TYPES.Auth_SQS).toConstantValue(sqsClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mapping
|
// Mapping
|
||||||
container
|
container
|
||||||
.bind<MapperInterface<SessionTrace, TypeORMSessionTrace>>(TYPES.Auth_SessionTracePersistenceMapper)
|
.bind<MapperInterface<SessionTrace, TypeORMSessionTrace>>(TYPES.Auth_SessionTracePersistenceMapper)
|
||||||
.toConstantValue(new SessionTracePersistenceMapper())
|
.toConstantValue(new SessionTracePersistenceMapper(container.get<TimerInterface>(TYPES.Auth_Timer)))
|
||||||
container
|
container
|
||||||
.bind<MapperInterface<Authenticator, TypeORMAuthenticator>>(TYPES.Auth_AuthenticatorPersistenceMapper)
|
.bind<MapperInterface<Authenticator, TypeORMAuthenticator>>(TYPES.Auth_AuthenticatorPersistenceMapper)
|
||||||
.toConstantValue(new AuthenticatorPersistenceMapper())
|
.toConstantValue(new AuthenticatorPersistenceMapper())
|
||||||
@@ -458,8 +460,9 @@ export class ContainerConfigLoader {
|
|||||||
.bind<SessionTraceRepositoryInterface>(TYPES.Auth_SessionTraceRepository)
|
.bind<SessionTraceRepositoryInterface>(TYPES.Auth_SessionTraceRepository)
|
||||||
.toConstantValue(
|
.toConstantValue(
|
||||||
new TypeORMSessionTraceRepository(
|
new TypeORMSessionTraceRepository(
|
||||||
container.get(TYPES.Auth_ORMSessionTraceRepository),
|
container.get<Repository<TypeORMSessionTrace>>(TYPES.Auth_ORMSessionTraceRepository),
|
||||||
container.get(TYPES.Auth_SessionTracePersistenceMapper),
|
container.get<MapperInterface<SessionTrace, TypeORMSessionTrace>>(TYPES.Auth_SessionTracePersistenceMapper),
|
||||||
|
container.get<TimerInterface>(TYPES.Auth_Timer),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
container
|
container
|
||||||
@@ -497,20 +500,6 @@ export class ContainerConfigLoader {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
// Middleware
|
|
||||||
container.bind<SessionMiddleware>(TYPES.Auth_SessionMiddleware).to(SessionMiddleware)
|
|
||||||
container.bind<LockMiddleware>(TYPES.Auth_LockMiddleware).to(LockMiddleware)
|
|
||||||
container
|
|
||||||
.bind<RequiredCrossServiceTokenMiddleware>(TYPES.Auth_RequiredCrossServiceTokenMiddleware)
|
|
||||||
.to(RequiredCrossServiceTokenMiddleware)
|
|
||||||
container
|
|
||||||
.bind<OptionalCrossServiceTokenMiddleware>(TYPES.Auth_OptionalCrossServiceTokenMiddleware)
|
|
||||||
.to(OptionalCrossServiceTokenMiddleware)
|
|
||||||
container
|
|
||||||
.bind<ApiGatewayOfflineAuthMiddleware>(TYPES.Auth_ApiGatewayOfflineAuthMiddleware)
|
|
||||||
.to(ApiGatewayOfflineAuthMiddleware)
|
|
||||||
container.bind<OfflineUserAuthMiddleware>(TYPES.Auth_OfflineUserAuthMiddleware).to(OfflineUserAuthMiddleware)
|
|
||||||
|
|
||||||
// Projectors
|
// Projectors
|
||||||
container.bind<SessionProjector>(TYPES.Auth_SessionProjector).to(SessionProjector)
|
container.bind<SessionProjector>(TYPES.Auth_SessionProjector).to(SessionProjector)
|
||||||
container.bind<UserProjector>(TYPES.Auth_UserProjector).to(UserProjector)
|
container.bind<UserProjector>(TYPES.Auth_UserProjector).to(UserProjector)
|
||||||
@@ -739,6 +728,30 @@ export class ContainerConfigLoader {
|
|||||||
: new SNSDomainEventPublisher(container.get(TYPES.Auth_SNS), container.get(TYPES.Auth_SNS_TOPIC_ARN)),
|
: new SNSDomainEventPublisher(container.get(TYPES.Auth_SNS), container.get(TYPES.Auth_SNS_TOPIC_ARN)),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Middleware
|
||||||
|
container.bind<SessionMiddleware>(TYPES.Auth_SessionMiddleware).to(SessionMiddleware)
|
||||||
|
container.bind<LockMiddleware>(TYPES.Auth_LockMiddleware).to(LockMiddleware)
|
||||||
|
container
|
||||||
|
.bind<RequiredCrossServiceTokenMiddleware>(TYPES.Auth_RequiredCrossServiceTokenMiddleware)
|
||||||
|
.toConstantValue(
|
||||||
|
new RequiredCrossServiceTokenMiddleware(
|
||||||
|
container.get<TokenDecoderInterface<CrossServiceTokenData>>(TYPES.Auth_CrossServiceTokenDecoder),
|
||||||
|
container.get<winston.Logger>(TYPES.Auth_Logger),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
container
|
||||||
|
.bind<OptionalCrossServiceTokenMiddleware>(TYPES.Auth_OptionalCrossServiceTokenMiddleware)
|
||||||
|
.toConstantValue(
|
||||||
|
new OptionalCrossServiceTokenMiddleware(
|
||||||
|
container.get<TokenDecoderInterface<CrossServiceTokenData>>(TYPES.Auth_CrossServiceTokenDecoder),
|
||||||
|
container.get<winston.Logger>(TYPES.Auth_Logger),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
container
|
||||||
|
.bind<ApiGatewayOfflineAuthMiddleware>(TYPES.Auth_ApiGatewayOfflineAuthMiddleware)
|
||||||
|
.to(ApiGatewayOfflineAuthMiddleware)
|
||||||
|
container.bind<OfflineUserAuthMiddleware>(TYPES.Auth_OfflineUserAuthMiddleware).to(OfflineUserAuthMiddleware)
|
||||||
|
|
||||||
// use cases
|
// use cases
|
||||||
container
|
container
|
||||||
.bind<TraceSession>(TYPES.Auth_TraceSession)
|
.bind<TraceSession>(TYPES.Auth_TraceSession)
|
||||||
@@ -964,6 +977,15 @@ export class ContainerConfigLoader {
|
|||||||
container.get<TimerInterface>(TYPES.Auth_Timer),
|
container.get<TimerInterface>(TYPES.Auth_Timer),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
container
|
||||||
|
.bind<DisableEmailSettingBasedOnEmailSubscription>(TYPES.Auth_DisableEmailSettingBasedOnEmailSubscription)
|
||||||
|
.toConstantValue(
|
||||||
|
new DisableEmailSettingBasedOnEmailSubscription(
|
||||||
|
container.get<UserRepositoryInterface>(TYPES.Auth_UserRepository),
|
||||||
|
container.get<SettingRepositoryInterface>(TYPES.Auth_SettingRepository),
|
||||||
|
container.get<SettingFactoryInterface>(TYPES.Auth_SettingFactory),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
// Controller
|
// Controller
|
||||||
container
|
container
|
||||||
@@ -1011,7 +1033,6 @@ export class ContainerConfigLoader {
|
|||||||
container.get<SessionRepositoryInterface>(TYPES.Auth_SessionRepository),
|
container.get<SessionRepositoryInterface>(TYPES.Auth_SessionRepository),
|
||||||
container.get<EphemeralSessionRepositoryInterface>(TYPES.Auth_EphemeralSessionRepository),
|
container.get<EphemeralSessionRepositoryInterface>(TYPES.Auth_EphemeralSessionRepository),
|
||||||
container.get<RevokedSessionRepositoryInterface>(TYPES.Auth_RevokedSessionRepository),
|
container.get<RevokedSessionRepositoryInterface>(TYPES.Auth_RevokedSessionRepository),
|
||||||
container.get<RemoveSharedVaultUser>(TYPES.Auth_RemoveSharedVaultUser),
|
|
||||||
container.get<winston.Logger>(TYPES.Auth_Logger),
|
container.get<winston.Logger>(TYPES.Auth_Logger),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -1102,8 +1123,10 @@ export class ContainerConfigLoader {
|
|||||||
.bind<EmailSubscriptionUnsubscribedEventHandler>(TYPES.Auth_EmailSubscriptionUnsubscribedEventHandler)
|
.bind<EmailSubscriptionUnsubscribedEventHandler>(TYPES.Auth_EmailSubscriptionUnsubscribedEventHandler)
|
||||||
.toConstantValue(
|
.toConstantValue(
|
||||||
new EmailSubscriptionUnsubscribedEventHandler(
|
new EmailSubscriptionUnsubscribedEventHandler(
|
||||||
container.get(TYPES.Auth_UserRepository),
|
container.get<DisableEmailSettingBasedOnEmailSubscription>(
|
||||||
container.get(TYPES.Auth_SettingService),
|
TYPES.Auth_DisableEmailSettingBasedOnEmailSubscription,
|
||||||
|
),
|
||||||
|
container.get<winston.Logger>(TYPES.Auth_Logger),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
container
|
container
|
||||||
@@ -1200,11 +1223,7 @@ export class ContainerConfigLoader {
|
|||||||
} else {
|
} else {
|
||||||
container
|
container
|
||||||
.bind<DomainEventMessageHandlerInterface>(TYPES.Auth_DomainEventMessageHandler)
|
.bind<DomainEventMessageHandlerInterface>(TYPES.Auth_DomainEventMessageHandler)
|
||||||
.toConstantValue(
|
.toConstantValue(new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Auth_Logger)))
|
||||||
env.get('NEW_RELIC_ENABLED', true) === 'true'
|
|
||||||
? new SQSNewRelicEventMessageHandler(eventHandlers, container.get(TYPES.Auth_Logger))
|
|
||||||
: new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Auth_Logger)),
|
|
||||||
)
|
|
||||||
|
|
||||||
container
|
container
|
||||||
.bind<DomainEventSubscriberFactoryInterface>(TYPES.Auth_DomainEventSubscriberFactory)
|
.bind<DomainEventSubscriberFactoryInterface>(TYPES.Auth_DomainEventSubscriberFactory)
|
||||||
|
|||||||
@@ -161,6 +161,7 @@ const TYPES = {
|
|||||||
Auth_AddSharedVaultUser: Symbol.for('Auth_AddSharedVaultUser'),
|
Auth_AddSharedVaultUser: Symbol.for('Auth_AddSharedVaultUser'),
|
||||||
Auth_RemoveSharedVaultUser: Symbol.for('Auth_RemoveSharedVaultUser'),
|
Auth_RemoveSharedVaultUser: Symbol.for('Auth_RemoveSharedVaultUser'),
|
||||||
Auth_DesignateSurvivor: Symbol.for('Auth_DesignateSurvivor'),
|
Auth_DesignateSurvivor: Symbol.for('Auth_DesignateSurvivor'),
|
||||||
|
Auth_DisableEmailSettingBasedOnEmailSubscription: Symbol.for('Auth_DisableEmailSettingBasedOnEmailSubscription'),
|
||||||
// Handlers
|
// Handlers
|
||||||
Auth_UserRegisteredEventHandler: Symbol.for('Auth_UserRegisteredEventHandler'),
|
Auth_UserRegisteredEventHandler: Symbol.for('Auth_UserRegisteredEventHandler'),
|
||||||
Auth_AccountDeletionRequestedEventHandler: Symbol.for('Auth_AccountDeletionRequestedEventHandler'),
|
Auth_AccountDeletionRequestedEventHandler: Symbol.for('Auth_AccountDeletionRequestedEventHandler'),
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { EphemeralSessionRepositoryInterface } from '../Session/EphemeralSession
|
|||||||
import { RevokedSessionRepositoryInterface } from '../Session/RevokedSessionRepositoryInterface'
|
import { RevokedSessionRepositoryInterface } from '../Session/RevokedSessionRepositoryInterface'
|
||||||
import { SessionRepositoryInterface } from '../Session/SessionRepositoryInterface'
|
import { SessionRepositoryInterface } from '../Session/SessionRepositoryInterface'
|
||||||
import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
|
import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
|
||||||
import { RemoveSharedVaultUser } from '../UseCase/RemoveSharedVaultUser/RemoveSharedVaultUser'
|
|
||||||
|
|
||||||
export class AccountDeletionRequestedEventHandler implements DomainEventHandlerInterface {
|
export class AccountDeletionRequestedEventHandler implements DomainEventHandlerInterface {
|
||||||
constructor(
|
constructor(
|
||||||
@@ -14,7 +13,6 @@ export class AccountDeletionRequestedEventHandler implements DomainEventHandlerI
|
|||||||
private sessionRepository: SessionRepositoryInterface,
|
private sessionRepository: SessionRepositoryInterface,
|
||||||
private ephemeralSessionRepository: EphemeralSessionRepositoryInterface,
|
private ephemeralSessionRepository: EphemeralSessionRepositoryInterface,
|
||||||
private revokedSessionRepository: RevokedSessionRepositoryInterface,
|
private revokedSessionRepository: RevokedSessionRepositoryInterface,
|
||||||
private removeSharedVaultUser: RemoveSharedVaultUser,
|
|
||||||
private logger: Logger,
|
private logger: Logger,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@@ -37,13 +35,6 @@ export class AccountDeletionRequestedEventHandler implements DomainEventHandlerI
|
|||||||
|
|
||||||
await this.removeSessions(userUuid.value)
|
await this.removeSessions(userUuid.value)
|
||||||
|
|
||||||
const result = await this.removeSharedVaultUser.execute({
|
|
||||||
userUuid: userUuid.value,
|
|
||||||
})
|
|
||||||
if (result.isFailed()) {
|
|
||||||
this.logger.error(`Could not remove shared vault user: ${result.getError()}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.userRepository.remove(user)
|
await this.userRepository.remove(user)
|
||||||
|
|
||||||
this.logger.info(`Finished account cleanup for user: ${userUuid.value}`)
|
this.logger.info(`Finished account cleanup for user: ${userUuid.value}`)
|
||||||
|
|||||||
@@ -1,117 +0,0 @@
|
|||||||
import { EmailLevel } from '@standardnotes/domain-core'
|
|
||||||
import { EmailSubscriptionUnsubscribedEvent } from '@standardnotes/domain-events'
|
|
||||||
|
|
||||||
import { SettingServiceInterface } from '../Setting/SettingServiceInterface'
|
|
||||||
import { User } from '../User/User'
|
|
||||||
import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
|
|
||||||
import { EmailSubscriptionUnsubscribedEventHandler } from './EmailSubscriptionUnsubscribedEventHandler'
|
|
||||||
|
|
||||||
describe('EmailSubscriptionUnsubscribedEventHandler', () => {
|
|
||||||
let userRepository: UserRepositoryInterface
|
|
||||||
let settingsService: SettingServiceInterface
|
|
||||||
let event: EmailSubscriptionUnsubscribedEvent
|
|
||||||
|
|
||||||
const createHandler = () => new EmailSubscriptionUnsubscribedEventHandler(userRepository, settingsService)
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
userRepository = {} as jest.Mocked<UserRepositoryInterface>
|
|
||||||
userRepository.findOneByUsernameOrEmail = jest.fn().mockReturnValue({} as jest.Mocked<User>)
|
|
||||||
|
|
||||||
settingsService = {} as jest.Mocked<SettingServiceInterface>
|
|
||||||
settingsService.createOrReplace = jest.fn()
|
|
||||||
|
|
||||||
event = {
|
|
||||||
payload: {
|
|
||||||
userEmail: 'test@test.te',
|
|
||||||
level: EmailLevel.LEVELS.Marketing,
|
|
||||||
},
|
|
||||||
} as jest.Mocked<EmailSubscriptionUnsubscribedEvent>
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should not do anything if username is invalid', async () => {
|
|
||||||
event.payload.userEmail = ''
|
|
||||||
|
|
||||||
await createHandler().handle(event)
|
|
||||||
|
|
||||||
expect(settingsService.createOrReplace).not.toHaveBeenCalled()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should not do anything if user is not found', async () => {
|
|
||||||
userRepository.findOneByUsernameOrEmail = jest.fn().mockReturnValue(null)
|
|
||||||
|
|
||||||
await createHandler().handle(event)
|
|
||||||
|
|
||||||
expect(settingsService.createOrReplace).not.toHaveBeenCalled()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should update user marketing email settings', async () => {
|
|
||||||
await createHandler().handle(event)
|
|
||||||
|
|
||||||
expect(settingsService.createOrReplace).toHaveBeenCalledWith({
|
|
||||||
user: {},
|
|
||||||
props: {
|
|
||||||
name: 'MUTE_MARKETING_EMAILS',
|
|
||||||
unencryptedValue: 'muted',
|
|
||||||
sensitive: false,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should update user sign in email settings', async () => {
|
|
||||||
event.payload.level = EmailLevel.LEVELS.SignIn
|
|
||||||
|
|
||||||
await createHandler().handle(event)
|
|
||||||
|
|
||||||
expect(settingsService.createOrReplace).toHaveBeenCalledWith({
|
|
||||||
user: {},
|
|
||||||
props: {
|
|
||||||
name: 'MUTE_SIGN_IN_EMAILS',
|
|
||||||
unencryptedValue: 'muted',
|
|
||||||
sensitive: false,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should update user email backup email settings', async () => {
|
|
||||||
event.payload.level = EmailLevel.LEVELS.FailedEmailBackup
|
|
||||||
|
|
||||||
await createHandler().handle(event)
|
|
||||||
|
|
||||||
expect(settingsService.createOrReplace).toHaveBeenCalledWith({
|
|
||||||
user: {},
|
|
||||||
props: {
|
|
||||||
name: 'MUTE_FAILED_BACKUPS_EMAILS',
|
|
||||||
unencryptedValue: 'muted',
|
|
||||||
sensitive: false,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should update user email backup email settings', async () => {
|
|
||||||
event.payload.level = EmailLevel.LEVELS.FailedCloudBackup
|
|
||||||
|
|
||||||
await createHandler().handle(event)
|
|
||||||
|
|
||||||
expect(settingsService.createOrReplace).toHaveBeenCalledWith({
|
|
||||||
user: {},
|
|
||||||
props: {
|
|
||||||
name: 'MUTE_FAILED_CLOUD_BACKUPS_EMAILS',
|
|
||||||
unencryptedValue: 'muted',
|
|
||||||
sensitive: false,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should throw error for unrecognized level', async () => {
|
|
||||||
event.payload.level = 'foobar'
|
|
||||||
|
|
||||||
let caughtError = null
|
|
||||||
try {
|
|
||||||
await createHandler().handle(event)
|
|
||||||
} catch (error) {
|
|
||||||
caughtError = error
|
|
||||||
}
|
|
||||||
|
|
||||||
expect(caughtError).not.toBeNull()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,50 +1,21 @@
|
|||||||
import { EmailLevel, Username } from '@standardnotes/domain-core'
|
|
||||||
import { DomainEventHandlerInterface, EmailSubscriptionUnsubscribedEvent } from '@standardnotes/domain-events'
|
import { DomainEventHandlerInterface, EmailSubscriptionUnsubscribedEvent } from '@standardnotes/domain-events'
|
||||||
import { SettingName } from '@standardnotes/settings'
|
import { Logger } from 'winston'
|
||||||
|
import { DisableEmailSettingBasedOnEmailSubscription } from '../UseCase/DisableEmailSettingBasedOnEmailSubscription/DisableEmailSettingBasedOnEmailSubscription'
|
||||||
import { SettingServiceInterface } from '../Setting/SettingServiceInterface'
|
|
||||||
import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
|
|
||||||
|
|
||||||
export class EmailSubscriptionUnsubscribedEventHandler implements DomainEventHandlerInterface {
|
export class EmailSubscriptionUnsubscribedEventHandler implements DomainEventHandlerInterface {
|
||||||
constructor(
|
constructor(
|
||||||
private userRepository: UserRepositoryInterface,
|
private disableEmailSettingBasedOnEmailSubscription: DisableEmailSettingBasedOnEmailSubscription,
|
||||||
private settingsService: SettingServiceInterface,
|
private logger: Logger,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async handle(event: EmailSubscriptionUnsubscribedEvent): Promise<void> {
|
async handle(event: EmailSubscriptionUnsubscribedEvent): Promise<void> {
|
||||||
const usernameOrError = Username.create(event.payload.userEmail)
|
const result = await this.disableEmailSettingBasedOnEmailSubscription.execute({
|
||||||
if (usernameOrError.isFailed()) {
|
userEmail: event.payload.userEmail,
|
||||||
return
|
level: event.payload.level,
|
||||||
}
|
|
||||||
const username = usernameOrError.getValue()
|
|
||||||
|
|
||||||
const user = await this.userRepository.findOneByUsernameOrEmail(username)
|
|
||||||
if (user === null) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.settingsService.createOrReplace({
|
|
||||||
user,
|
|
||||||
props: {
|
|
||||||
name: this.getSettingNameFromLevel(event.payload.level),
|
|
||||||
unencryptedValue: 'muted',
|
|
||||||
sensitive: false,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
private getSettingNameFromLevel(level: string): string {
|
if (result.isFailed()) {
|
||||||
switch (level) {
|
this.logger.error(`Failed to disable email setting for user ${event.payload.userEmail}: ${result.getError()}`)
|
||||||
case EmailLevel.LEVELS.FailedCloudBackup:
|
|
||||||
return SettingName.NAMES.MuteFailedCloudBackupsEmails
|
|
||||||
case EmailLevel.LEVELS.FailedEmailBackup:
|
|
||||||
return SettingName.NAMES.MuteFailedBackupsEmails
|
|
||||||
case EmailLevel.LEVELS.Marketing:
|
|
||||||
return SettingName.NAMES.MuteMarketingEmails
|
|
||||||
case EmailLevel.LEVELS.SignIn:
|
|
||||||
return SettingName.NAMES.MuteSignInEmails
|
|
||||||
default:
|
|
||||||
throw new Error(`Unknown level: ${level}`)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,6 +118,40 @@ describe('RoleService', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('removing roles', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
user = {
|
||||||
|
uuid: '123',
|
||||||
|
email: 'test@test.com',
|
||||||
|
roles: Promise.resolve([basicRole]),
|
||||||
|
} as jest.Mocked<User>
|
||||||
|
|
||||||
|
userRepository.findOneByUuid = jest.fn().mockReturnValue(user)
|
||||||
|
userRepository.save = jest.fn().mockReturnValue(user)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should remove a role from a user', async () => {
|
||||||
|
await createService().removeRoleFromUser(
|
||||||
|
Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
|
||||||
|
RoleName.create(RoleName.NAMES.CoreUser).getValue(),
|
||||||
|
)
|
||||||
|
|
||||||
|
user.roles = Promise.resolve([])
|
||||||
|
expect(userRepository.save).toHaveBeenCalledWith(user)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should not remove a role from a user if the user could not be found', async () => {
|
||||||
|
userRepository.findOneByUuid = jest.fn().mockReturnValue(null)
|
||||||
|
|
||||||
|
await createService().removeRoleFromUser(
|
||||||
|
Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
|
||||||
|
RoleName.create(RoleName.NAMES.CoreUser).getValue(),
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(userRepository.save).not.toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('adding roles based on subscription', () => {
|
describe('adding roles based on subscription', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
user = {
|
user = {
|
||||||
|
|||||||
@@ -65,6 +65,17 @@ export class RoleService implements RoleServiceInterface {
|
|||||||
await this.addToExistingRoles(user, roleName.value)
|
await this.addToExistingRoles(user, roleName.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async removeRoleFromUser(userUuid: Uuid, roleName: RoleName): Promise<void> {
|
||||||
|
const user = await this.userRepository.findOneByUuid(userUuid)
|
||||||
|
if (user === null) {
|
||||||
|
this.logger.error(`Could not find user with uuid ${userUuid.value} to remove role ${roleName.value}`)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.removeUserRole(user, roleName.value)
|
||||||
|
}
|
||||||
|
|
||||||
async addUserRoleBasedOnSubscription(user: User, subscriptionName: SubscriptionName): Promise<void> {
|
async addUserRoleBasedOnSubscription(user: User, subscriptionName: SubscriptionName): Promise<void> {
|
||||||
const roleName = this.roleToSubscriptionMap.getRoleNameForSubscriptionName(subscriptionName)
|
const roleName = this.roleToSubscriptionMap.getRoleNameForSubscriptionName(subscriptionName)
|
||||||
|
|
||||||
@@ -108,9 +119,15 @@ export class RoleService implements RoleServiceInterface {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await this.removeUserRole(user, roleName)
|
||||||
|
}
|
||||||
|
|
||||||
|
private async removeUserRole(user: User, roleName: string): Promise<void> {
|
||||||
const currentRoles = await user.roles
|
const currentRoles = await user.roles
|
||||||
user.roles = Promise.resolve(currentRoles.filter((role) => role.name !== roleName))
|
user.roles = Promise.resolve(currentRoles.filter((role) => role.name !== roleName))
|
||||||
|
|
||||||
await this.userRepository.save(user)
|
await this.userRepository.save(user)
|
||||||
|
|
||||||
await this.webSocketsClientService.sendUserRolesChangedEvent(user)
|
await this.webSocketsClientService.sendUserRolesChangedEvent(user)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { User } from '../User/User'
|
|||||||
|
|
||||||
export interface RoleServiceInterface {
|
export interface RoleServiceInterface {
|
||||||
addRoleToUser(userUuid: Uuid, roleName: RoleName): Promise<void>
|
addRoleToUser(userUuid: Uuid, roleName: RoleName): Promise<void>
|
||||||
|
removeRoleFromUser(userUuid: Uuid, roleName: RoleName): Promise<void>
|
||||||
addUserRoleBasedOnSubscription(user: User, subscriptionName: string): Promise<void>
|
addUserRoleBasedOnSubscription(user: User, subscriptionName: string): Promise<void>
|
||||||
setOfflineUserRole(offlineUserSubscription: OfflineUserSubscription): Promise<void>
|
setOfflineUserRole(offlineUserSubscription: OfflineUserSubscription): Promise<void>
|
||||||
removeUserRoleBasedOnSubscription(user: User, subscriptionName: string): Promise<void>
|
removeUserRoleBasedOnSubscription(user: User, subscriptionName: string): Promise<void>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { SubscriptionPlanName, Uuid } from '@standardnotes/domain-core'
|
|||||||
import { SessionTrace } from './SessionTrace'
|
import { SessionTrace } from './SessionTrace'
|
||||||
|
|
||||||
export interface SessionTraceRepositoryInterface {
|
export interface SessionTraceRepositoryInterface {
|
||||||
save(sessionTrace: SessionTrace): Promise<void>
|
insert(sessionTrace: SessionTrace): Promise<void>
|
||||||
removeExpiredBefore(date: Date): Promise<void>
|
removeExpiredBefore(date: Date): Promise<void>
|
||||||
findOneByUserUuidAndDate(userUuid: Uuid, date: Date): Promise<SessionTrace | null>
|
findOneByUserUuidAndDate(userUuid: Uuid, date: Date): Promise<SessionTrace | null>
|
||||||
countByDate(date: Date): Promise<number>
|
countByDate(date: Date): Promise<number>
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
import 'reflect-metadata'
|
import 'reflect-metadata'
|
||||||
|
|
||||||
import { TokenEncoderInterface, ValetTokenData, ValetTokenOperation } from '@standardnotes/security'
|
import { TransitionStatus } from '@standardnotes/domain-core'
|
||||||
import { CreateValetToken } from './CreateValetToken'
|
|
||||||
import { TimerInterface } from '@standardnotes/time'
|
import { TimerInterface } from '@standardnotes/time'
|
||||||
|
import { TokenEncoderInterface, ValetTokenData, ValetTokenOperation } from '@standardnotes/security'
|
||||||
|
|
||||||
|
import { CreateValetToken } from './CreateValetToken'
|
||||||
import { UserSubscription } from '../../Subscription/UserSubscription'
|
import { UserSubscription } from '../../Subscription/UserSubscription'
|
||||||
import { SubscriptionSettingServiceInterface } from '../../Setting/SubscriptionSettingServiceInterface'
|
import { SubscriptionSettingServiceInterface } from '../../Setting/SubscriptionSettingServiceInterface'
|
||||||
import { User } from '../../User/User'
|
import { User } from '../../User/User'
|
||||||
import { UserSubscriptionType } from '../../Subscription/UserSubscriptionType'
|
import { UserSubscriptionType } from '../../Subscription/UserSubscriptionType'
|
||||||
import { SubscriptionSettingsAssociationServiceInterface } from '../../Setting/SubscriptionSettingsAssociationServiceInterface'
|
import { SubscriptionSettingsAssociationServiceInterface } from '../../Setting/SubscriptionSettingsAssociationServiceInterface'
|
||||||
import { UserSubscriptionServiceInterface } from '../../Subscription/UserSubscriptionServiceInterface'
|
import { UserSubscriptionServiceInterface } from '../../Subscription/UserSubscriptionServiceInterface'
|
||||||
|
import { TransitionStatusRepositoryInterface } from '../../Transition/TransitionStatusRepositoryInterface'
|
||||||
|
|
||||||
describe('CreateValetToken', () => {
|
describe('CreateValetToken', () => {
|
||||||
let tokenEncoder: TokenEncoderInterface<ValetTokenData>
|
let tokenEncoder: TokenEncoderInterface<ValetTokenData>
|
||||||
@@ -20,6 +23,7 @@ describe('CreateValetToken', () => {
|
|||||||
let regularSubscription: UserSubscription
|
let regularSubscription: UserSubscription
|
||||||
let sharedSubscription: UserSubscription
|
let sharedSubscription: UserSubscription
|
||||||
let user: User
|
let user: User
|
||||||
|
let transitionStatusRepository: TransitionStatusRepositoryInterface
|
||||||
|
|
||||||
const createUseCase = () =>
|
const createUseCase = () =>
|
||||||
new CreateValetToken(
|
new CreateValetToken(
|
||||||
@@ -29,6 +33,7 @@ describe('CreateValetToken', () => {
|
|||||||
userSubscriptionService,
|
userSubscriptionService,
|
||||||
timer,
|
timer,
|
||||||
valetTokenTTL,
|
valetTokenTTL,
|
||||||
|
transitionStatusRepository,
|
||||||
)
|
)
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -66,6 +71,11 @@ describe('CreateValetToken', () => {
|
|||||||
|
|
||||||
timer = {} as jest.Mocked<TimerInterface>
|
timer = {} as jest.Mocked<TimerInterface>
|
||||||
timer.getTimestampInMicroseconds = jest.fn().mockReturnValue(100)
|
timer.getTimestampInMicroseconds = jest.fn().mockReturnValue(100)
|
||||||
|
|
||||||
|
transitionStatusRepository = {} as jest.Mocked<TransitionStatusRepositoryInterface>
|
||||||
|
transitionStatusRepository.getStatus = jest
|
||||||
|
.fn()
|
||||||
|
.mockReturnValue(TransitionStatus.create(TransitionStatus.STATUSES.Verified).getValue())
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should create a read valet token', async () => {
|
it('should create a read valet token', async () => {
|
||||||
@@ -166,6 +176,7 @@ describe('CreateValetToken', () => {
|
|||||||
{
|
{
|
||||||
sharedSubscriptionUuid: undefined,
|
sharedSubscriptionUuid: undefined,
|
||||||
regularSubscriptionUuid: '1-2-3',
|
regularSubscriptionUuid: '1-2-3',
|
||||||
|
ongoingTransition: false,
|
||||||
permittedOperation: 'write',
|
permittedOperation: 'write',
|
||||||
permittedResources: [
|
permittedResources: [
|
||||||
{
|
{
|
||||||
@@ -206,6 +217,7 @@ describe('CreateValetToken', () => {
|
|||||||
{
|
{
|
||||||
sharedSubscriptionUuid: '2-3-4',
|
sharedSubscriptionUuid: '2-3-4',
|
||||||
regularSubscriptionUuid: '1-2-3',
|
regularSubscriptionUuid: '1-2-3',
|
||||||
|
ongoingTransition: false,
|
||||||
permittedOperation: 'write',
|
permittedOperation: 'write',
|
||||||
permittedResources: [
|
permittedResources: [
|
||||||
{
|
{
|
||||||
@@ -266,6 +278,7 @@ describe('CreateValetToken', () => {
|
|||||||
{
|
{
|
||||||
sharedSubscriptionUuid: undefined,
|
sharedSubscriptionUuid: undefined,
|
||||||
regularSubscriptionUuid: '1-2-3',
|
regularSubscriptionUuid: '1-2-3',
|
||||||
|
ongoingTransition: false,
|
||||||
permittedOperation: 'write',
|
permittedOperation: 'write',
|
||||||
permittedResources: [
|
permittedResources: [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import { CreateValetTokenDTO } from './CreateValetTokenDTO'
|
|||||||
import { SubscriptionSettingsAssociationServiceInterface } from '../../Setting/SubscriptionSettingsAssociationServiceInterface'
|
import { SubscriptionSettingsAssociationServiceInterface } from '../../Setting/SubscriptionSettingsAssociationServiceInterface'
|
||||||
import { UserSubscriptionServiceInterface } from '../../Subscription/UserSubscriptionServiceInterface'
|
import { UserSubscriptionServiceInterface } from '../../Subscription/UserSubscriptionServiceInterface'
|
||||||
import { CreateValetTokenPayload } from '../../ValetToken/CreateValetTokenPayload'
|
import { CreateValetTokenPayload } from '../../ValetToken/CreateValetTokenPayload'
|
||||||
|
import { TransitionStatusRepositoryInterface } from '../../Transition/TransitionStatusRepositoryInterface'
|
||||||
|
import { TransitionStatus } from '@standardnotes/domain-core'
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class CreateValetToken implements UseCaseInterface {
|
export class CreateValetToken implements UseCaseInterface {
|
||||||
@@ -25,6 +27,8 @@ export class CreateValetToken implements UseCaseInterface {
|
|||||||
@inject(TYPES.Auth_UserSubscriptionService) private userSubscriptionService: UserSubscriptionServiceInterface,
|
@inject(TYPES.Auth_UserSubscriptionService) private userSubscriptionService: UserSubscriptionServiceInterface,
|
||||||
@inject(TYPES.Auth_Timer) private timer: TimerInterface,
|
@inject(TYPES.Auth_Timer) private timer: TimerInterface,
|
||||||
@inject(TYPES.Auth_VALET_TOKEN_TTL) private valetTokenTTL: number,
|
@inject(TYPES.Auth_VALET_TOKEN_TTL) private valetTokenTTL: number,
|
||||||
|
@inject(TYPES.Auth_TransitionStatusRepository)
|
||||||
|
private transitionStatusRepository: TransitionStatusRepositoryInterface,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async execute(dto: CreateValetTokenDTO): Promise<CreateValetTokenResponseData> {
|
async execute(dto: CreateValetTokenDTO): Promise<CreateValetTokenResponseData> {
|
||||||
@@ -83,6 +87,8 @@ export class CreateValetToken implements UseCaseInterface {
|
|||||||
sharedSubscriptionUuid = sharedSubscription.uuid
|
sharedSubscriptionUuid = sharedSubscription.uuid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const transitionStatus = await this.transitionStatusRepository.getStatus(userUuid, 'items')
|
||||||
|
|
||||||
const tokenData: ValetTokenData = {
|
const tokenData: ValetTokenData = {
|
||||||
userUuid: dto.userUuid,
|
userUuid: dto.userUuid,
|
||||||
permittedOperation: dto.operation,
|
permittedOperation: dto.operation,
|
||||||
@@ -91,6 +97,7 @@ export class CreateValetToken implements UseCaseInterface {
|
|||||||
uploadBytesLimit,
|
uploadBytesLimit,
|
||||||
sharedSubscriptionUuid,
|
sharedSubscriptionUuid,
|
||||||
regularSubscriptionUuid: regularSubscription.uuid,
|
regularSubscriptionUuid: regularSubscription.uuid,
|
||||||
|
ongoingTransition: transitionStatus?.value === TransitionStatus.STATUSES.InProgress,
|
||||||
}
|
}
|
||||||
|
|
||||||
const valetToken = this.tokenEncoder.encodeExpirableToken(tokenData, this.valetTokenTTL)
|
const valetToken = this.tokenEncoder.encodeExpirableToken(tokenData, this.valetTokenTTL)
|
||||||
|
|||||||
+96
@@ -0,0 +1,96 @@
|
|||||||
|
import { EmailLevel } from '@standardnotes/domain-core'
|
||||||
|
import { Setting } from '../../Setting/Setting'
|
||||||
|
import { SettingFactoryInterface } from '../../Setting/SettingFactoryInterface'
|
||||||
|
import { SettingRepositoryInterface } from '../../Setting/SettingRepositoryInterface'
|
||||||
|
import { User } from '../../User/User'
|
||||||
|
import { UserRepositoryInterface } from '../../User/UserRepositoryInterface'
|
||||||
|
import { DisableEmailSettingBasedOnEmailSubscription } from './DisableEmailSettingBasedOnEmailSubscription'
|
||||||
|
|
||||||
|
describe('DisableEmailSettingBasedOnEmailSubscription', () => {
|
||||||
|
let userRepository: UserRepositoryInterface
|
||||||
|
let settingRepository: SettingRepositoryInterface
|
||||||
|
let factory: SettingFactoryInterface
|
||||||
|
let user: User
|
||||||
|
|
||||||
|
const createUseCase = () =>
|
||||||
|
new DisableEmailSettingBasedOnEmailSubscription(userRepository, settingRepository, factory)
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
user = {} as jest.Mocked<User>
|
||||||
|
user.uuid = 'userUuid'
|
||||||
|
|
||||||
|
userRepository = {} as jest.Mocked<UserRepositoryInterface>
|
||||||
|
userRepository.findOneByUsernameOrEmail = jest.fn().mockResolvedValue(user)
|
||||||
|
|
||||||
|
settingRepository = {} as jest.Mocked<SettingRepositoryInterface>
|
||||||
|
settingRepository.findLastByNameAndUserUuid = jest.fn().mockResolvedValue({} as jest.Mocked<Setting>)
|
||||||
|
settingRepository.save = jest.fn()
|
||||||
|
|
||||||
|
factory = {} as jest.Mocked<SettingFactoryInterface>
|
||||||
|
factory.create = jest.fn().mockResolvedValue({} as jest.Mocked<Setting>)
|
||||||
|
factory.createReplacement = jest.fn().mockResolvedValue({} as jest.Mocked<Setting>)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should fail if the username is empty', async () => {
|
||||||
|
const useCase = createUseCase()
|
||||||
|
|
||||||
|
const result = await useCase.execute({
|
||||||
|
userEmail: '',
|
||||||
|
level: EmailLevel.LEVELS.Marketing,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(result.isFailed()).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should fail if the user is not found', async () => {
|
||||||
|
userRepository.findOneByUsernameOrEmail = jest.fn().mockResolvedValue(null)
|
||||||
|
|
||||||
|
const useCase = createUseCase()
|
||||||
|
|
||||||
|
const result = await useCase.execute({
|
||||||
|
userEmail: 'test@test.te',
|
||||||
|
level: EmailLevel.LEVELS.Marketing,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(result.isFailed()).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should fail if the setting name cannot be determined', async () => {
|
||||||
|
const useCase = createUseCase()
|
||||||
|
|
||||||
|
const result = await useCase.execute({
|
||||||
|
userEmail: 'test@test.te',
|
||||||
|
level: 'invalid',
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(result.isFailed()).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should create a new setting if it does not exist', async () => {
|
||||||
|
settingRepository.findLastByNameAndUserUuid = jest.fn().mockResolvedValue(null)
|
||||||
|
|
||||||
|
const useCase = createUseCase()
|
||||||
|
|
||||||
|
const result = await useCase.execute({
|
||||||
|
userEmail: 'test@test.te',
|
||||||
|
level: EmailLevel.LEVELS.Marketing,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(result.isFailed()).toBeFalsy()
|
||||||
|
expect(factory.create).toHaveBeenCalled()
|
||||||
|
expect(factory.createReplacement).not.toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should replace the setting if it exists', async () => {
|
||||||
|
const useCase = createUseCase()
|
||||||
|
|
||||||
|
const result = await useCase.execute({
|
||||||
|
userEmail: 'test@test.te',
|
||||||
|
level: EmailLevel.LEVELS.Marketing,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(result.isFailed()).toBeFalsy()
|
||||||
|
expect(factory.create).not.toHaveBeenCalled()
|
||||||
|
expect(factory.createReplacement).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
})
|
||||||
+72
@@ -0,0 +1,72 @@
|
|||||||
|
import { EmailLevel, Result, UseCaseInterface, Username } from '@standardnotes/domain-core'
|
||||||
|
import { SettingName } from '@standardnotes/settings'
|
||||||
|
|
||||||
|
import { DisableEmailSettingBasedOnEmailSubscriptionDTO } from './DisableEmailSettingBasedOnEmailSubscriptionDTO'
|
||||||
|
import { UserRepositoryInterface } from '../../User/UserRepositoryInterface'
|
||||||
|
import { SettingRepositoryInterface } from '../../Setting/SettingRepositoryInterface'
|
||||||
|
import { SettingFactoryInterface } from '../../Setting/SettingFactoryInterface'
|
||||||
|
|
||||||
|
export class DisableEmailSettingBasedOnEmailSubscription implements UseCaseInterface<void> {
|
||||||
|
constructor(
|
||||||
|
private userRepository: UserRepositoryInterface,
|
||||||
|
private settingRepository: SettingRepositoryInterface,
|
||||||
|
private factory: SettingFactoryInterface,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async execute(dto: DisableEmailSettingBasedOnEmailSubscriptionDTO): Promise<Result<void>> {
|
||||||
|
const usernameOrError = Username.create(dto.userEmail)
|
||||||
|
if (usernameOrError.isFailed()) {
|
||||||
|
return Result.fail(usernameOrError.getError())
|
||||||
|
}
|
||||||
|
const username = usernameOrError.getValue()
|
||||||
|
|
||||||
|
const user = await this.userRepository.findOneByUsernameOrEmail(username)
|
||||||
|
if (user === null) {
|
||||||
|
return Result.fail(`User not found for email ${dto.userEmail}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const settingNameOrError = this.getSettingNameFromLevel(dto.level)
|
||||||
|
if (settingNameOrError.isFailed()) {
|
||||||
|
return Result.fail(settingNameOrError.getError())
|
||||||
|
}
|
||||||
|
const settingName = settingNameOrError.getValue()
|
||||||
|
|
||||||
|
let setting = await this.settingRepository.findLastByNameAndUserUuid(settingName, user.uuid)
|
||||||
|
if (!setting) {
|
||||||
|
setting = await this.factory.create(
|
||||||
|
{
|
||||||
|
name: settingName,
|
||||||
|
unencryptedValue: 'muted',
|
||||||
|
sensitive: false,
|
||||||
|
},
|
||||||
|
user,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
setting = await this.factory.createReplacement(setting, {
|
||||||
|
name: settingName,
|
||||||
|
unencryptedValue: 'muted',
|
||||||
|
sensitive: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.settingRepository.save(setting)
|
||||||
|
|
||||||
|
return Result.ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
private getSettingNameFromLevel(level: string): Result<string> {
|
||||||
|
/* istanbul ignore next */
|
||||||
|
switch (level) {
|
||||||
|
case EmailLevel.LEVELS.FailedCloudBackup:
|
||||||
|
return Result.ok(SettingName.NAMES.MuteFailedCloudBackupsEmails)
|
||||||
|
case EmailLevel.LEVELS.FailedEmailBackup:
|
||||||
|
return Result.ok(SettingName.NAMES.MuteFailedBackupsEmails)
|
||||||
|
case EmailLevel.LEVELS.Marketing:
|
||||||
|
return Result.ok(SettingName.NAMES.MuteMarketingEmails)
|
||||||
|
case EmailLevel.LEVELS.SignIn:
|
||||||
|
return Result.ok(SettingName.NAMES.MuteSignInEmails)
|
||||||
|
default:
|
||||||
|
return Result.fail(`Unknown level: ${level}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
export interface DisableEmailSettingBasedOnEmailSubscriptionDTO {
|
||||||
|
userEmail: string
|
||||||
|
level: string
|
||||||
|
}
|
||||||
@@ -84,14 +84,11 @@ describe('Register', () => {
|
|||||||
expect(settingService.applyDefaultSettingsUponRegistration).toHaveBeenCalled()
|
expect(settingService.applyDefaultSettingsUponRegistration).toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should register a new user with default role and transition role', async () => {
|
it('should register a new user with default set of roles', async () => {
|
||||||
const role = new Role()
|
const role = new Role()
|
||||||
role.name = RoleName.NAMES.CoreUser
|
role.name = RoleName.NAMES.CoreUser
|
||||||
|
|
||||||
const transitionRole = new Role()
|
roleRepository.findOneByName = jest.fn().mockReturnValueOnce(role)
|
||||||
transitionRole.name = RoleName.NAMES.TransitionUser
|
|
||||||
|
|
||||||
roleRepository.findOneByName = jest.fn().mockReturnValueOnce(role).mockReturnValueOnce(transitionRole)
|
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
await createUseCase().execute({
|
await createUseCase().execute({
|
||||||
@@ -120,7 +117,7 @@ describe('Register', () => {
|
|||||||
version: '004',
|
version: '004',
|
||||||
createdAt: new Date(1),
|
createdAt: new Date(1),
|
||||||
updatedAt: new Date(1),
|
updatedAt: new Date(1),
|
||||||
roles: Promise.resolve([role, transitionRole]),
|
roles: Promise.resolve([role]),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -77,10 +77,6 @@ export class Register implements UseCaseInterface {
|
|||||||
if (defaultRole) {
|
if (defaultRole) {
|
||||||
roles.push(defaultRole)
|
roles.push(defaultRole)
|
||||||
}
|
}
|
||||||
const transitionRole = await this.roleRepository.findOneByName(RoleName.NAMES.TransitionUser)
|
|
||||||
if (transitionRole) {
|
|
||||||
roles.push(transitionRole)
|
|
||||||
}
|
|
||||||
user.roles = Promise.resolve(roles)
|
user.roles = Promise.resolve(roles)
|
||||||
|
|
||||||
Object.assign(user, registrationFields)
|
Object.assign(user, registrationFields)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ describe('TraceSession', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
sessionTraceRepository = {} as jest.Mocked<SessionTraceRepositoryInterface>
|
sessionTraceRepository = {} as jest.Mocked<SessionTraceRepositoryInterface>
|
||||||
sessionTraceRepository.findOneByUserUuidAndDate = jest.fn().mockReturnValue(null)
|
sessionTraceRepository.findOneByUserUuidAndDate = jest.fn().mockReturnValue(null)
|
||||||
sessionTraceRepository.save = jest.fn()
|
sessionTraceRepository.insert = jest.fn()
|
||||||
|
|
||||||
timer = {} as jest.Mocked<TimerInterface>
|
timer = {} as jest.Mocked<TimerInterface>
|
||||||
timer.getUTCDateNDaysAhead = jest.fn().mockReturnValue(new Date())
|
timer.getUTCDateNDaysAhead = jest.fn().mockReturnValue(new Date())
|
||||||
@@ -30,7 +30,7 @@ describe('TraceSession', () => {
|
|||||||
|
|
||||||
expect(result.isFailed()).toBe(false)
|
expect(result.isFailed()).toBe(false)
|
||||||
expect(result.getValue().props.userUuid.value).toEqual('0702b137-4f5c-438a-915e-8f8b46572ce5')
|
expect(result.getValue().props.userUuid.value).toEqual('0702b137-4f5c-438a-915e-8f8b46572ce5')
|
||||||
expect(sessionTraceRepository.save).toHaveBeenCalledTimes(1)
|
expect(sessionTraceRepository.insert).toHaveBeenCalledTimes(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not save a session trace if one already exists for the same user and date', async () => {
|
it('should not save a session trace if one already exists for the same user and date', async () => {
|
||||||
@@ -43,7 +43,7 @@ describe('TraceSession', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
expect(result.isFailed()).toBe(false)
|
expect(result.isFailed()).toBe(false)
|
||||||
expect(sessionTraceRepository.save).not.toHaveBeenCalled()
|
expect(sessionTraceRepository.insert).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return an error if userUuid is invalid', async () => {
|
it('should return an error if userUuid is invalid', async () => {
|
||||||
@@ -54,7 +54,7 @@ describe('TraceSession', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
expect(result.isFailed()).toBe(true)
|
expect(result.isFailed()).toBe(true)
|
||||||
expect(sessionTraceRepository.save).not.toHaveBeenCalled()
|
expect(sessionTraceRepository.insert).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return an error if username is invalid', async () => {
|
it('should return an error if username is invalid', async () => {
|
||||||
@@ -65,7 +65,7 @@ describe('TraceSession', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
expect(result.isFailed()).toBe(true)
|
expect(result.isFailed()).toBe(true)
|
||||||
expect(sessionTraceRepository.save).not.toHaveBeenCalled()
|
expect(sessionTraceRepository.insert).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return an error if subscriptionPlanName is invalid', async () => {
|
it('should return an error if subscriptionPlanName is invalid', async () => {
|
||||||
@@ -76,7 +76,7 @@ describe('TraceSession', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
expect(result.isFailed()).toBe(true)
|
expect(result.isFailed()).toBe(true)
|
||||||
expect(sessionTraceRepository.save).not.toHaveBeenCalled()
|
expect(sessionTraceRepository.insert).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not save a session trace if creating of the session trace fails', async () => {
|
it('should not save a session trace if creating of the session trace fails', async () => {
|
||||||
@@ -90,7 +90,7 @@ describe('TraceSession', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
expect(result.isFailed()).toBe(true)
|
expect(result.isFailed()).toBe(true)
|
||||||
expect(sessionTraceRepository.save).not.toHaveBeenCalled()
|
expect(sessionTraceRepository.insert).not.toHaveBeenCalled()
|
||||||
|
|
||||||
mock.mockRestore()
|
mock.mockRestore()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export class TraceSession implements UseCaseInterface<SessionTrace> {
|
|||||||
}
|
}
|
||||||
const sessionTrace = sessionTraceOrError.getValue()
|
const sessionTrace = sessionTraceOrError.getValue()
|
||||||
|
|
||||||
await this.sessionTraceRepository.save(sessionTrace)
|
await this.sessionTraceRepository.insert(sessionTrace)
|
||||||
|
|
||||||
return Result.ok<SessionTrace>(sessionTrace)
|
return Result.ok<SessionTrace>(sessionTrace)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -21,7 +21,7 @@ describe('UpdateTransitionStatus', () => {
|
|||||||
transitionStatusRepository.getStatus = jest.fn().mockResolvedValue(null)
|
transitionStatusRepository.getStatus = jest.fn().mockResolvedValue(null)
|
||||||
|
|
||||||
roleService = {} as jest.Mocked<RoleServiceInterface>
|
roleService = {} as jest.Mocked<RoleServiceInterface>
|
||||||
roleService.addRoleToUser = jest.fn()
|
roleService.removeRoleFromUser = jest.fn()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should add TRANSITION_USER role', async () => {
|
it('should add TRANSITION_USER role', async () => {
|
||||||
@@ -35,7 +35,7 @@ describe('UpdateTransitionStatus', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
expect(result.isFailed()).toBeFalsy()
|
expect(result.isFailed()).toBeFalsy()
|
||||||
expect(roleService.addRoleToUser).toHaveBeenCalledWith(
|
expect(roleService.removeRoleFromUser).toHaveBeenCalledWith(
|
||||||
Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
|
Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
|
||||||
RoleName.create(RoleName.NAMES.TransitionUser).getValue(),
|
RoleName.create(RoleName.NAMES.TransitionUser).getValue(),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export class UpdateTransitionStatus implements UseCaseInterface<void> {
|
|||||||
await this.transitionStatusRepository.updateStatus(dto.userUuid, dto.transitionType, transitionStatus)
|
await this.transitionStatusRepository.updateStatus(dto.userUuid, dto.transitionType, transitionStatus)
|
||||||
|
|
||||||
if (dto.transitionType === 'items' && transitionStatus.value === TransitionStatus.STATUSES.Verified) {
|
if (dto.transitionType === 'items' && transitionStatus.value === TransitionStatus.STATUSES.Verified) {
|
||||||
await this.roleService.addRoleToUser(userUuid, RoleName.create(RoleName.NAMES.TransitionUser).getValue())
|
await this.roleService.removeRoleFromUser(userUuid, RoleName.create(RoleName.NAMES.TransitionUser).getValue())
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result.ok()
|
return Result.ok()
|
||||||
|
|||||||
+1
-7
@@ -1,17 +1,11 @@
|
|||||||
import { CrossServiceTokenData, TokenDecoderInterface } from '@standardnotes/security'
|
import { CrossServiceTokenData, TokenDecoderInterface } from '@standardnotes/security'
|
||||||
import { NextFunction, Request, Response } from 'express'
|
import { NextFunction, Request, Response } from 'express'
|
||||||
import { inject, injectable } from 'inversify'
|
|
||||||
import { Logger } from 'winston'
|
import { Logger } from 'winston'
|
||||||
|
|
||||||
import TYPES from '../../../Bootstrap/Types'
|
|
||||||
import { ApiGatewayAuthMiddleware } from './ApiGatewayAuthMiddleware'
|
import { ApiGatewayAuthMiddleware } from './ApiGatewayAuthMiddleware'
|
||||||
|
|
||||||
@injectable()
|
|
||||||
export class OptionalCrossServiceTokenMiddleware extends ApiGatewayAuthMiddleware {
|
export class OptionalCrossServiceTokenMiddleware extends ApiGatewayAuthMiddleware {
|
||||||
constructor(
|
constructor(tokenDecoder: TokenDecoderInterface<CrossServiceTokenData>, logger: Logger) {
|
||||||
@inject(TYPES.Auth_CrossServiceTokenDecoder) tokenDecoder: TokenDecoderInterface<CrossServiceTokenData>,
|
|
||||||
@inject(TYPES.Auth_Logger) logger: Logger,
|
|
||||||
) {
|
|
||||||
super(tokenDecoder, logger)
|
super(tokenDecoder, logger)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-7
@@ -1,17 +1,11 @@
|
|||||||
import { CrossServiceTokenData, TokenDecoderInterface } from '@standardnotes/security'
|
import { CrossServiceTokenData, TokenDecoderInterface } from '@standardnotes/security'
|
||||||
import { NextFunction, Request, Response } from 'express'
|
import { NextFunction, Request, Response } from 'express'
|
||||||
import { inject, injectable } from 'inversify'
|
|
||||||
import { Logger } from 'winston'
|
import { Logger } from 'winston'
|
||||||
|
|
||||||
import TYPES from '../../../Bootstrap/Types'
|
|
||||||
import { ApiGatewayAuthMiddleware } from './ApiGatewayAuthMiddleware'
|
import { ApiGatewayAuthMiddleware } from './ApiGatewayAuthMiddleware'
|
||||||
|
|
||||||
@injectable()
|
|
||||||
export class RequiredCrossServiceTokenMiddleware extends ApiGatewayAuthMiddleware {
|
export class RequiredCrossServiceTokenMiddleware extends ApiGatewayAuthMiddleware {
|
||||||
constructor(
|
constructor(tokenDecoder: TokenDecoderInterface<CrossServiceTokenData>, logger: Logger) {
|
||||||
@inject(TYPES.Auth_CrossServiceTokenDecoder) tokenDecoder: TokenDecoderInterface<CrossServiceTokenData>,
|
|
||||||
@inject(TYPES.Auth_Logger) logger: Logger,
|
|
||||||
) {
|
|
||||||
super(tokenDecoder, logger)
|
super(tokenDecoder, logger)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { TransitionStatusRepositoryInterface } from '../../Domain/Transition/Tra
|
|||||||
import { TransitionStatus } from '@standardnotes/domain-core'
|
import { TransitionStatus } from '@standardnotes/domain-core'
|
||||||
|
|
||||||
export class RedisTransitionStatusRepository implements TransitionStatusRepositoryInterface {
|
export class RedisTransitionStatusRepository implements TransitionStatusRepositoryInterface {
|
||||||
private readonly PREFIX = 'transition'
|
private readonly PREFIX = 'transition-back'
|
||||||
|
|
||||||
constructor(private redisClient: IORedis.Redis) {}
|
constructor(private redisClient: IORedis.Redis) {}
|
||||||
|
|
||||||
@@ -19,8 +19,8 @@ export class RedisTransitionStatusRepository implements TransitionStatusReposito
|
|||||||
await this.redisClient.set(`${this.PREFIX}:${transitionType}:${userUuid}`, status.value)
|
await this.redisClient.set(`${this.PREFIX}:${transitionType}:${userUuid}`, status.value)
|
||||||
break
|
break
|
||||||
case TransitionStatus.STATUSES.InProgress: {
|
case TransitionStatus.STATUSES.InProgress: {
|
||||||
const ttl2Hourse = 7_200
|
const ttl24Hours = 86_400
|
||||||
await this.redisClient.setex(`${this.PREFIX}:${transitionType}:${userUuid}`, ttl2Hourse, status.value)
|
await this.redisClient.setex(`${this.PREFIX}:${transitionType}:${userUuid}`, ttl24Hours, status.value)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import { MapperInterface, SubscriptionPlanName, Uuid } from '@standardnotes/domain-core'
|
import { MapperInterface, SubscriptionPlanName, Uuid } from '@standardnotes/domain-core'
|
||||||
|
import { TimerInterface } from '@standardnotes/time'
|
||||||
import { Repository } from 'typeorm'
|
import { Repository } from 'typeorm'
|
||||||
|
|
||||||
import { SessionTrace } from '../../Domain/Session/SessionTrace'
|
import { SessionTrace } from '../../Domain/Session/SessionTrace'
|
||||||
import { SessionTraceRepositoryInterface } from '../../Domain/Session/SessionTraceRepositoryInterface'
|
import { SessionTraceRepositoryInterface } from '../../Domain/Session/SessionTraceRepositoryInterface'
|
||||||
import { TypeORMSessionTrace } from './TypeORMSessionTrace'
|
import { TypeORMSessionTrace } from './TypeORMSessionTrace'
|
||||||
@@ -8,13 +10,14 @@ export class TypeORMSessionTraceRepository implements SessionTraceRepositoryInte
|
|||||||
constructor(
|
constructor(
|
||||||
private ormRepository: Repository<TypeORMSessionTrace>,
|
private ormRepository: Repository<TypeORMSessionTrace>,
|
||||||
private mapper: MapperInterface<SessionTrace, TypeORMSessionTrace>,
|
private mapper: MapperInterface<SessionTrace, TypeORMSessionTrace>,
|
||||||
|
private timer: TimerInterface,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async countByDateAndSubscriptionPlanName(date: Date, subscriptionPlanName: SubscriptionPlanName): Promise<number> {
|
async countByDateAndSubscriptionPlanName(date: Date, subscriptionPlanName: SubscriptionPlanName): Promise<number> {
|
||||||
return this.ormRepository
|
return this.ormRepository
|
||||||
.createQueryBuilder('trace')
|
.createQueryBuilder('trace')
|
||||||
.where('trace.creation_date = :creationDate', {
|
.where('trace.creation_date = :creationDate', {
|
||||||
creationDate: `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`,
|
creationDate: this.timer.convertDateToFormattedString(date, 'YYYY-MM-DD'),
|
||||||
})
|
})
|
||||||
.andWhere('trace.subscription_plan_name = :subscriptionPlanName', {
|
.andWhere('trace.subscription_plan_name = :subscriptionPlanName', {
|
||||||
subscriptionPlanName: subscriptionPlanName.value,
|
subscriptionPlanName: subscriptionPlanName.value,
|
||||||
@@ -26,7 +29,7 @@ export class TypeORMSessionTraceRepository implements SessionTraceRepositoryInte
|
|||||||
return this.ormRepository
|
return this.ormRepository
|
||||||
.createQueryBuilder('trace')
|
.createQueryBuilder('trace')
|
||||||
.where('trace.creation_date = :creationDate', {
|
.where('trace.creation_date = :creationDate', {
|
||||||
creationDate: `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`,
|
creationDate: this.timer.convertDateToFormattedString(date, 'YYYY-MM-DD'),
|
||||||
})
|
})
|
||||||
.getCount()
|
.getCount()
|
||||||
}
|
}
|
||||||
@@ -44,7 +47,7 @@ export class TypeORMSessionTraceRepository implements SessionTraceRepositoryInte
|
|||||||
.createQueryBuilder('trace')
|
.createQueryBuilder('trace')
|
||||||
.where('trace.user_uuid = :userUuid AND trace.creation_date = :creationDate', {
|
.where('trace.user_uuid = :userUuid AND trace.creation_date = :creationDate', {
|
||||||
userUuid: userUuid.value,
|
userUuid: userUuid.value,
|
||||||
creationDate: `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`,
|
creationDate: this.timer.convertDateToFormattedString(date, 'YYYY-MM-DD'),
|
||||||
})
|
})
|
||||||
.getOne()
|
.getOne()
|
||||||
|
|
||||||
@@ -55,9 +58,9 @@ export class TypeORMSessionTraceRepository implements SessionTraceRepositoryInte
|
|||||||
return this.mapper.toDomain(typeOrm)
|
return this.mapper.toDomain(typeOrm)
|
||||||
}
|
}
|
||||||
|
|
||||||
async save(sessionTrace: SessionTrace): Promise<void> {
|
async insert(sessionTrace: SessionTrace): Promise<void> {
|
||||||
const persistence = this.mapper.toProjection(sessionTrace)
|
const persistence = this.mapper.toProjection(sessionTrace)
|
||||||
|
|
||||||
await this.ormRepository.save(persistence)
|
await this.ormRepository.insert(persistence)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
import { MapperInterface, SubscriptionPlanName, UniqueEntityId, Username, Uuid } from '@standardnotes/domain-core'
|
import { MapperInterface, SubscriptionPlanName, UniqueEntityId, Username, Uuid } from '@standardnotes/domain-core'
|
||||||
import { SessionTrace } from '../Domain/Session/SessionTrace'
|
import { SessionTrace } from '../Domain/Session/SessionTrace'
|
||||||
import { TypeORMSessionTrace } from '../Infra/TypeORM/TypeORMSessionTrace'
|
import { TypeORMSessionTrace } from '../Infra/TypeORM/TypeORMSessionTrace'
|
||||||
|
import { TimerInterface } from '@standardnotes/time'
|
||||||
|
|
||||||
export class SessionTracePersistenceMapper implements MapperInterface<SessionTrace, TypeORMSessionTrace> {
|
export class SessionTracePersistenceMapper implements MapperInterface<SessionTrace, TypeORMSessionTrace> {
|
||||||
|
constructor(private timer: TimerInterface) {}
|
||||||
|
|
||||||
toDomain(projection: TypeORMSessionTrace): SessionTrace {
|
toDomain(projection: TypeORMSessionTrace): SessionTrace {
|
||||||
const userUuidOrError = Uuid.create(projection.userUuid)
|
const userUuidOrError = Uuid.create(projection.userUuid)
|
||||||
if (userUuidOrError.isFailed()) {
|
if (userUuidOrError.isFailed()) {
|
||||||
@@ -50,11 +53,7 @@ export class SessionTracePersistenceMapper implements MapperInterface<SessionTra
|
|||||||
typeOrm.username = domain.props.username.value
|
typeOrm.username = domain.props.username.value
|
||||||
typeOrm.subscriptionPlanName = domain.props.subscriptionPlanName ? domain.props.subscriptionPlanName.value : null
|
typeOrm.subscriptionPlanName = domain.props.subscriptionPlanName ? domain.props.subscriptionPlanName.value : null
|
||||||
typeOrm.createdAt = domain.props.createdAt
|
typeOrm.createdAt = domain.props.createdAt
|
||||||
typeOrm.creationDate = new Date(
|
typeOrm.creationDate = new Date(this.timer.convertDateToFormattedString(domain.props.createdAt, 'YYYY-MM-DD'))
|
||||||
domain.props.createdAt.getFullYear(),
|
|
||||||
domain.props.createdAt.getMonth(),
|
|
||||||
domain.props.createdAt.getDate(),
|
|
||||||
)
|
|
||||||
typeOrm.expiresAt = domain.props.expiresAt
|
typeOrm.expiresAt = domain.props.expiresAt
|
||||||
|
|
||||||
return typeOrm
|
return typeOrm
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|
||||||
|
# [1.51.0](https://github.com/standardnotes/server/compare/@standardnotes/common@1.50.4...@standardnotes/common@1.51.0) (2023-09-26)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* refactor handling revision creation from dump ([#854](https://github.com/standardnotes/server/issues/854)) ([ca6dbc0](https://github.com/standardnotes/server/commit/ca6dbc00537bb20f508f9310b1a838421f53a643))
|
||||||
|
|
||||||
## [1.50.4](https://github.com/standardnotes/server/compare/@standardnotes/common@1.50.3...@standardnotes/common@1.50.4) (2023-09-04)
|
## [1.50.4](https://github.com/standardnotes/server/compare/@standardnotes/common@1.50.3...@standardnotes/common@1.50.4) (2023-09-04)
|
||||||
|
|
||||||
**Note:** Version bump only for package @standardnotes/common
|
**Note:** Version bump only for package @standardnotes/common
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/common",
|
"name": "@standardnotes/common",
|
||||||
"version": "1.50.4",
|
"version": "1.51.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <21.0.0"
|
"node": ">=18.0.0 <21.0.0"
|
||||||
},
|
},
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
"clean": "rm -fr dist",
|
"clean": "rm -fr dist",
|
||||||
"build": "tsc --build",
|
"build": "tsc --build",
|
||||||
"lint": "eslint . --ext .ts",
|
"lint": "eslint . --ext .ts",
|
||||||
"test": "jest spec --coverage"
|
"test": "jest --coverage --no-cache"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^29.5.1",
|
"@types/jest": "^29.5.1",
|
||||||
|
|||||||
@@ -3,6 +3,42 @@
|
|||||||
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.35.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.34.2...@standardnotes/domain-core@1.35.0) (2023-10-06)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add xray to analytics scheduler and websockets ([f0531d6](https://github.com/standardnotes/server/commit/f0531d68cb77036222f2a34602819f11e6a2697d))
|
||||||
|
|
||||||
|
## [1.34.2](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.34.1...@standardnotes/domain-core@1.34.2) (2023-10-04)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* identifying services in workers ([eab78b3](https://github.com/standardnotes/server/commit/eab78b3a95ec82cb779d069d172169bfa92368c9))
|
||||||
|
|
||||||
|
## [1.34.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.34.0...@standardnotes/domain-core@1.34.1) (2023-09-27)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* removing items in a vault and notifying about designated survivor ([#855](https://github.com/standardnotes/server/issues/855)) ([1d06ffe](https://github.com/standardnotes/server/commit/1d06ffe9d51722ada7baa040e1d5ed351fc28f39))
|
||||||
|
|
||||||
|
# [1.34.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.33.2...@standardnotes/domain-core@1.34.0) (2023-09-26)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* refactor handling revision creation from dump ([#854](https://github.com/standardnotes/server/issues/854)) ([ca6dbc0](https://github.com/standardnotes/server/commit/ca6dbc00537bb20f508f9310b1a838421f53a643))
|
||||||
|
|
||||||
|
## [1.33.2](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.33.1...@standardnotes/domain-core@1.33.2) (2023-09-25)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **domain-core:** notification paylod to string casting ([a02a287](https://github.com/standardnotes/server/commit/a02a28774b6d500200043faefb9ebac3719e7661))
|
||||||
|
|
||||||
|
## [1.33.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.33.0...@standardnotes/domain-core@1.33.1) (2023-09-25)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* refactor the structure of notifications ([#853](https://github.com/standardnotes/server/issues/853)) ([cebab59](https://github.com/standardnotes/server/commit/cebab59a026c6868886e0945787a8ddb0442fbc3))
|
||||||
|
|
||||||
# [1.33.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.32.0...@standardnotes/domain-core@1.33.0) (2023-09-21)
|
# [1.33.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.32.0...@standardnotes/domain-core@1.33.0) (2023-09-21)
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/domain-core",
|
"name": "@standardnotes/domain-core",
|
||||||
"version": "1.33.0",
|
"version": "1.35.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <21.0.0"
|
"node": ">=18.0.0 <21.0.0"
|
||||||
},
|
},
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
"build": "tsc --build",
|
"build": "tsc --build",
|
||||||
"lint": "eslint . --ext .ts",
|
"lint": "eslint . --ext .ts",
|
||||||
"lint:fix": "eslint . --ext .ts --fix",
|
"lint:fix": "eslint . --ext .ts --fix",
|
||||||
"test": "jest spec --coverage --passWithNoTests"
|
"test": "jest --coverage --no-cache --passWithNoTests"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"uuid": "^9.0.0"
|
"uuid": "^9.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