Compare commits

..

22 Commits

Author SHA1 Message Date
standardci
e9b8d0ceb7 chore(release): publish new version
- @standardnotes/analytics@2.32.2
 - @standardnotes/api-gateway@1.80.0
 - @standardnotes/auth-server@1.160.0
 - @standardnotes/domain-core@1.38.0
 - @standardnotes/domain-events-infra@1.20.2
 - @standardnotes/domain-events@2.133.0
 - @standardnotes/event-store@1.13.15
 - @standardnotes/files-server@1.32.0
 - @standardnotes/home-server@1.18.0
 - @standardnotes/revisions-server@1.47.0
 - @standardnotes/scheduler-server@1.26.2
 - @standardnotes/security@1.16.0
 - @standardnotes/settings@1.21.46
 - @standardnotes/syncing-server@1.119.0
 - @standardnotes/websockets-server@1.17.2
2023-10-19 09:56:55 +00:00
Karol Sójko
a2c1ebe675 feat: remove transition state (#882)
* fix: Dockerfile build deps

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-17 14:02:56 +02:00
standardci
c99a447a04 chore(release): publish new version
- @standardnotes/auth-server@1.159.1
 - @standardnotes/home-server@1.17.16
2023-10-17 11:58:49 +00:00
Karol Sójko
6dd9fd5abd fix: remove secrets from e2e test suites 2023-10-17 13:40:52 +02:00
Karol Sójko
0d37cb293c fix(auth): traversing through users in transition 2023-10-17 13:25:20 +02:00
standardci
27d04c95a1 chore(release): publish new version
- @standardnotes/analytics@2.32.0
 - @standardnotes/api-gateway@1.79.13
 - @standardnotes/auth-server@1.159.0
 - @standardnotes/domain-events-infra@1.20.0
 - @standardnotes/event-store@1.13.13
 - @standardnotes/files-server@1.31.0
 - @standardnotes/home-server@1.17.15
 - @standardnotes/revisions-server@1.46.0
 - @standardnotes/scheduler-server@1.26.0
 - @standardnotes/syncing-server@1.118.0
 - @standardnotes/websockets-server@1.17.0
2023-10-17 09:03:21 +00:00
Karol Sójko
cd830cdf25 fix: allow mutable yarn install on PR for dependabot purposes 2023-10-17 10:47:32 +02:00
Karol Sójko
5b06ea94f9 fix(syncing-server): binding 2023-10-17 10:41:55 +02:00
Karol Sójko
aba4f90485 feat: add wrapping sqs receive message with open telemetry 2023-10-17 10:14:26 +02:00
Karol Sójko
350621ed52 fix: remove secondary db from docker ci setup 2023-10-16 12:26:57 +02:00
Karol Sójko
69b4324c78 fix: remove unused variables in ci 2023-10-16 12:26:07 +02:00
Karol Sójko
b2be0a7c0b fix: remove secondary db from e2e test suites 2023-10-16 12:24:17 +02:00
Karol Sójko
cab0dfba39 fix: scheduled test suite to run only base tests 2023-10-16 12:04:34 +02:00
standardci
296ca47d63 chore(release): publish new version
- @standardnotes/auth-server@1.158.8
 - @standardnotes/home-server@1.17.14
2023-10-16 06:35:52 +00:00
Karol Sójko
1cad18a681 fix(auth): logs for triggering transition 2023-10-16 08:15:53 +02:00
standardci
bdd052f90c chore(release): publish new version
- @standardnotes/analytics@2.31.7
 - @standardnotes/api-gateway@1.79.12
 - @standardnotes/auth-server@1.158.7
 - @standardnotes/domain-events-infra@1.19.7
 - @standardnotes/event-store@1.13.12
 - @standardnotes/files-server@1.30.7
 - @standardnotes/home-server@1.17.13
 - @standardnotes/revisions-server@1.45.7
 - @standardnotes/scheduler-server@1.25.7
 - @standardnotes/syncing-server@1.117.7
 - @standardnotes/websockets-server@1.16.7
2023-10-13 08:38:45 +00:00
Karol Sójko
32fe8d0a85 fix: reduce the amount of metrics gathered in telemetery 2023-10-13 10:19:33 +02:00
253 changed files with 1378 additions and 5061 deletions

6
.github/ci.env vendored
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -9,7 +9,7 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Cache build
id: cache-build
@@ -26,7 +26,7 @@ jobs:
node-version-file: '.nvmrc'
- name: Install
run: yarn install --immutable
run: yarn install
- name: Build
run: yarn build
@@ -37,7 +37,7 @@ jobs:
needs: build
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Cache build
id: cache-build
@@ -54,7 +54,7 @@ jobs:
node-version-file: '.nvmrc'
- name: Install
run: yarn install --immutable
run: yarn install
- name: Build
if: steps.cache-build.outputs.cache-hit != 'true'
@@ -69,7 +69,7 @@ jobs:
needs: build
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Cache build
id: cache-build
@@ -86,7 +86,7 @@ jobs:
node-version-file: '.nvmrc'
- name: Install
run: yarn install --immutable
run: yarn install
- name: Build
if: steps.cache-build.outputs.cache-hit != 'true'
@@ -102,13 +102,11 @@ jobs:
with:
snjs_image_tag: 'latest'
suite: 'base'
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
e2e-vaults:
needs: build
name: E2E Vaults Suite
uses: standardnotes/server/.github/workflows/common-e2e.yml@main
with:
snjs_image_tag: 'latest'
suite: 'vaults'

View File

@@ -9,7 +9,7 @@ jobs:
if: contains(github.event.head_commit.message, 'chore(release)') == false
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Cache build
id: cache-build
@@ -37,7 +37,7 @@ jobs:
needs: build
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Cache build
id: cache-build
@@ -69,7 +69,7 @@ jobs:
needs: build
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Cache build
id: cache-build
@@ -102,16 +102,14 @@ jobs:
with:
snjs_image_tag: 'latest'
suite: 'base'
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
e2e-vaults:
needs: build
name: E2E Vaults Suite
uses: standardnotes/server/.github/workflows/common-e2e.yml@main
with:
snjs_image_tag: 'latest'
suite: 'vaults'
publish-self-hosting:
needs: [ test, lint, e2e-base ]
@@ -126,7 +124,7 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
token: ${{ secrets.CI_PAT_TOKEN }}
fetch-depth: 0

899
.pnp.cjs generated

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -3,6 +3,8 @@ FROM node:20.6.1-alpine
ENV NODE_ENV production
RUN apk add --update --no-cache \
g++ \
make \
openssl \
curl \
bash \

View File

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

View File

@@ -57,9 +57,6 @@ fi
if [ -z "$CACHE_TYPE" ]; then
export CACHE_TYPE="redis"
fi
if [ -z "$SECONDARY_DB_ENABLED" ]; then
export SECONDARY_DB_ENABLED=false
fi
export DB_MIGRATIONS_PATH="dist/migrations/*.js"
#########

View File

@@ -3,6 +3,26 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.32.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.32.1...@standardnotes/analytics@2.32.2) (2023-10-19)
**Note:** Version bump only for package @standardnotes/analytics
## [2.32.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.32.0...@standardnotes/analytics@2.32.1) (2023-10-18)
**Note:** Version bump only for package @standardnotes/analytics
# [2.32.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.31.7...@standardnotes/analytics@2.32.0) (2023-10-17)
### Features
* add wrapping sqs receive message with open telemetry ([aba4f90](https://github.com/standardnotes/server/commit/aba4f90485e1b40baac34561321a5381945aa27e))
## [2.31.7](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.31.6...@standardnotes/analytics@2.31.7) (2023-10-13)
### Bug Fixes
* reduce the amount of metrics gathered in telemetery ([32fe8d0](https://github.com/standardnotes/server/commit/32fe8d0a8523d6e1875cd0814c0cbdf27d8df7b3))
## [2.31.6](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.31.5...@standardnotes/analytics@2.31.6) (2023-10-12)
**Note:** Version bump only for package @standardnotes/analytics

View File

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

View File

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

View File

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

View File

@@ -5,9 +5,9 @@ import {
DomainEventHandlerInterface,
DomainEventMessageHandlerInterface,
DomainEventPublisherInterface,
DomainEventSubscriberFactoryInterface,
DomainEventSubscriberInterface,
} from '@standardnotes/domain-events'
import { MapperInterface } from '@standardnotes/domain-core'
import { MapperInterface, ServiceIdentifier } from '@standardnotes/domain-core'
// eslint-disable-next-line @typescript-eslint/no-var-requires
const Mixpanel = require('mixpanel')
@@ -17,8 +17,8 @@ import { AppDataSource } from './DataSource'
import { DomainEventFactory } from '../Domain/Event/DomainEventFactory'
import {
SNSOpenTelemetryDomainEventPublisher,
SQSDomainEventSubscriberFactory,
SQSEventMessageHandler,
SQSOpenTelemetryDomainEventSubscriber,
} from '@standardnotes/domain-events-infra'
import { Timer, TimerInterface } from '@standardnotes/time'
import { PeriodKeyGeneratorInterface } from '../Domain/Time/PeriodKeyGeneratorInterface'
@@ -240,12 +240,14 @@ export class ContainerConfigLoader {
.bind<DomainEventMessageHandlerInterface>(TYPES.DomainEventMessageHandler)
.toConstantValue(new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Logger)))
container
.bind<DomainEventSubscriberFactoryInterface>(TYPES.DomainEventSubscriberFactory)
.bind<DomainEventSubscriberInterface>(TYPES.DomainEventSubscriber)
.toConstantValue(
new SQSDomainEventSubscriberFactory(
container.get(TYPES.SQS),
container.get(TYPES.SQS_QUEUE_URL),
container.get(TYPES.DomainEventMessageHandler),
new SQSOpenTelemetryDomainEventSubscriber(
ServiceIdentifier.NAMES.AnalyticsWorker,
container.get<SQSClient>(TYPES.SQS),
container.get<string>(TYPES.SQS_QUEUE_URL),
container.get<DomainEventMessageHandlerInterface>(TYPES.DomainEventMessageHandler),
container.get<winston.Logger>(TYPES.Logger),
),
)

View File

@@ -42,7 +42,7 @@ const TYPES = {
RevenueModificationMap: Symbol.for('RevenueModificationMap'),
// Services
DomainEventPublisher: Symbol.for('DomainEventPublisher'),
DomainEventSubscriberFactory: Symbol.for('DomainEventSubscriberFactory'),
DomainEventSubscriber: Symbol.for('DomainEventSubscriber'),
DomainEventFactory: Symbol.for('DomainEventFactory'),
DomainEventMessageHandler: Symbol.for('DomainEventMessageHandler'),
AnalyticsStore: Symbol.for('AnalyticsStore'),

View File

@@ -3,6 +3,26 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.80.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.79.14...@standardnotes/api-gateway@1.80.0) (2023-10-19)
### Features
* remove transition state ([#882](https://github.com/standardnotes/api-gateway/issues/882)) ([a2c1ebe](https://github.com/standardnotes/api-gateway/commit/a2c1ebe675cd5678c923715056a6966f465a15d6))
## [1.79.14](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.79.13...@standardnotes/api-gateway@1.79.14) (2023-10-18)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.79.13](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.79.12...@standardnotes/api-gateway@1.79.13) (2023-10-17)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.79.12](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.79.11...@standardnotes/api-gateway@1.79.12) (2023-10-13)
### Bug Fixes
* reduce the amount of metrics gathered in telemetery ([32fe8d0](https://github.com/standardnotes/api-gateway/commit/32fe8d0a8523d6e1875cd0814c0cbdf27d8df7b3))
## [1.79.11](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.79.10...@standardnotes/api-gateway@1.79.11) (2023-10-12)
### Bug Fixes

View File

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

View File

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

View File

@@ -39,7 +39,7 @@ export abstract class AuthMiddleware extends BaseMiddleware {
crossServiceToken = await this.crossServiceTokenCache.get(cacheKey)
}
if (this.crossServiceTokenIsEmptyOrRequiresRevalidation(crossServiceToken)) {
if (crossServiceToken === null) {
const authResponse = await this.serviceProxy.validateSession({
authorization: authHeaderValue,
sharedVaultOwnerContext: sharedVaultOwnerContextHeaderValue,
@@ -129,14 +129,4 @@ export abstract class AuthMiddleware extends BaseMiddleware {
return Math.min(crossServiceTokenDefaultCacheExpiration, sessionAccessExpiration, sessionRefreshExpiration)
}
private crossServiceTokenIsEmptyOrRequiresRevalidation(crossServiceToken: string | null) {
if (crossServiceToken === null) {
return true
}
const decodedToken = <CrossServiceTokenData>verify(crossServiceToken, this.jwtSecret, { algorithms: ['HS256'] })
return decodedToken.ongoing_transition === true
}
}

View File

@@ -34,16 +34,6 @@ export class ItemsController extends BaseHttpController {
)
}
@httpPost('/transition')
async transition(request: Request, response: Response): Promise<void> {
await this.serviceProxy.callSyncingServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'items/transition'),
request.body,
)
}
@httpGet('/:uuid')
async getItem(request: Request, response: Response): Promise<void> {
await this.serviceProxy.callSyncingServer(

View File

@@ -1,6 +1,6 @@
import { Request, Response } from 'express'
import { inject } from 'inversify'
import { BaseHttpController, controller, httpDelete, httpGet, httpPost } from 'inversify-express-utils'
import { BaseHttpController, controller, httpDelete, httpGet } from 'inversify-express-utils'
import { TYPES } from '../../Bootstrap/Types'
import { ServiceProxyInterface } from '../../Service/Http/ServiceProxyInterface'
@@ -55,14 +55,4 @@ export class RevisionsControllerV2 extends BaseHttpController {
),
)
}
@httpPost('/revisions/transition')
async transition(request: Request, response: Response): Promise<void> {
await this.serviceProxy.callRevisionsServer(
request,
response,
this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'revisions/transition'),
request.body,
)
}
}

View File

@@ -3,6 +3,40 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.160.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.159.2...@standardnotes/auth-server@1.160.0) (2023-10-19)
### Features
* remove transition state ([#882](https://github.com/standardnotes/server/issues/882)) ([a2c1ebe](https://github.com/standardnotes/server/commit/a2c1ebe675cd5678c923715056a6966f465a15d6))
## [1.159.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.159.1...@standardnotes/auth-server@1.159.2) (2023-10-18)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.159.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.159.0...@standardnotes/auth-server@1.159.1) (2023-10-17)
### Bug Fixes
* **auth:** traversing through users in transition ([0d37cb2](https://github.com/standardnotes/server/commit/0d37cb293c3f8c1fa798a3c847a1f76c18a8c3aa))
# [1.159.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.158.8...@standardnotes/auth-server@1.159.0) (2023-10-17)
### Features
* add wrapping sqs receive message with open telemetry ([aba4f90](https://github.com/standardnotes/server/commit/aba4f90485e1b40baac34561321a5381945aa27e))
## [1.158.8](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.158.7...@standardnotes/auth-server@1.158.8) (2023-10-16)
### Bug Fixes
* **auth:** logs for triggering transition ([1cad18a](https://github.com/standardnotes/server/commit/1cad18a681d933c67244d43dd6f3c2ec405149be))
## [1.158.7](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.158.6...@standardnotes/auth-server@1.158.7) (2023-10-13)
### Bug Fixes
* reduce the amount of metrics gathered in telemetery ([32fe8d0](https://github.com/standardnotes/server/commit/32fe8d0a8523d6e1875cd0814c0cbdf27d8df7b3))
## [1.158.6](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.158.5...@standardnotes/auth-server@1.158.6) (2023-10-12)
### Bug Fixes

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,161 +0,0 @@
import 'reflect-metadata'
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier, RoleName, TransitionStatus } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.AuthScheduledTask)
sdk.start()
import { Logger } from 'winston'
import * as dayjs from 'dayjs'
import * as utc from 'dayjs/plugin/utc'
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
import TYPES from '../src/Bootstrap/Types'
import { Env } from '../src/Bootstrap/Env'
import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
import { DomainEventFactoryInterface } from '../src/Domain/Event/DomainEventFactoryInterface'
import { UserRepositoryInterface } from '../src/Domain/User/UserRepositoryInterface'
import { TimerInterface } from '@standardnotes/time'
import { TransitionStatusRepositoryInterface } from '../src/Domain/Transition/TransitionStatusRepositoryInterface'
const inputArgs = process.argv.slice(2)
const startDateString = inputArgs[0]
const endDateString = inputArgs[1]
const forceRunParam = inputArgs[2]
const requestTransition = async (
transitionStatusRepository: TransitionStatusRepositoryInterface,
userRepository: UserRepositoryInterface,
logger: Logger,
domainEventFactory: DomainEventFactoryInterface,
domainEventPublisher: DomainEventPublisherInterface,
timer: TimerInterface,
): Promise<void> => {
const startDate = new Date(startDateString)
const endDate = new Date(endDateString)
const users = await userRepository.findAllCreatedBetween(startDate, endDate)
const timestamp = timer.getTimestampInMicroseconds()
logger.info(
`[TRANSITION ${timestamp}] Found ${users.length} users created between ${startDateString} and ${endDateString}`,
)
let usersTriggered = 0
const forceRun = forceRunParam === 'true'
for (const user of users) {
const itemsTransitionStatus = await transitionStatusRepository.getStatus(user.uuid, 'items')
const revisionsTransitionStatus = await transitionStatusRepository.getStatus(user.uuid, 'revisions')
const userRoles = await user.roles
const userHasTransitionRole = userRoles.some((role) => role.name === RoleName.NAMES.TransitionUser)
const bothTransitionStatusesAreVerified =
itemsTransitionStatus?.value === TransitionStatus.STATUSES.Verified &&
revisionsTransitionStatus?.value === TransitionStatus.STATUSES.Verified
if (!userHasTransitionRole && bothTransitionStatusesAreVerified) {
continue
}
let wasTransitionRequested = false
if (
itemsTransitionStatus === null ||
itemsTransitionStatus.value === TransitionStatus.STATUSES.Failed ||
(itemsTransitionStatus.value === TransitionStatus.STATUSES.InProgress && forceRun)
) {
wasTransitionRequested = true
await transitionStatusRepository.remove(user.uuid, 'items')
await domainEventPublisher.publish(
domainEventFactory.createTransitionRequestedEvent({
userUuid: user.uuid,
type: 'items',
timestamp,
}),
)
}
if (
revisionsTransitionStatus === null ||
revisionsTransitionStatus.value === TransitionStatus.STATUSES.Failed ||
(revisionsTransitionStatus.value === TransitionStatus.STATUSES.InProgress && forceRun)
) {
wasTransitionRequested = true
await transitionStatusRepository.remove(user.uuid, 'revisions')
await domainEventPublisher.publish(
domainEventFactory.createTransitionRequestedEvent({
userUuid: user.uuid,
type: 'revisions',
timestamp,
}),
)
}
usersTriggered += 1
if (wasTransitionRequested) {
logger.info(
`[TRANSITION ${timestamp}] Transition requested for user ${user.uuid} - items status: ${itemsTransitionStatus?.value}, revisions status: ${revisionsTransitionStatus?.value}, has transition role: ${userHasTransitionRole}`,
)
}
}
logger.info(
`[TRANSITION ${timestamp}] Triggered transition for ${usersTriggered} users created between ${startDateString} and ${endDateString}`,
)
}
const container = new ContainerConfigLoader('worker')
void container.load().then((container) => {
dayjs.extend(utc)
const env: Env = new Env()
env.load()
const logger: Logger = container.get(TYPES.Auth_Logger)
logger.info(`Starting transition request for users created between ${startDateString} and ${endDateString}`)
const userRepository: UserRepositoryInterface = container.get(TYPES.Auth_UserRepository)
const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.Auth_DomainEventFactory)
const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.Auth_DomainEventPublisher)
const timer = container.get<TimerInterface>(TYPES.Auth_Timer)
const transitionStatusRepository = container.get<TransitionStatusRepositoryInterface>(
TYPES.Auth_TransitionStatusRepository,
)
const tracer = new OpenTelemetryTracer()
tracer.startSpan(ServiceIdentifier.NAMES.AuthScheduledTask, 'transition')
Promise.resolve(
requestTransition(
transitionStatusRepository,
userRepository,
logger,
domainEventFactory,
domainEventPublisher,
timer,
),
)
.then(() => {
logger.info(`Finished transition request for users created between ${startDateString} and ${endDateString}`)
tracer.stopSpan()
process.exit(0)
})
.catch((error) => {
logger.error(
`Error while requesting transition for users created between ${startDateString} and ${endDateString}: ${error}`,
)
tracer.stopSpanWithError(error)
process.exit(1)
})
})

View File

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

View File

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

View File

@@ -1,11 +0,0 @@
'use strict'
const path = require('path')
const pnp = require(path.normalize(path.resolve(__dirname, '../../..', '.pnp.cjs'))).setup()
const index = require(path.normalize(path.resolve(__dirname, '../dist/bin/transition.js')))
Object.defineProperty(exports, '__esModule', { value: true })
exports.default = index

View File

@@ -55,13 +55,6 @@ case "$COMMAND" in
node docker/entrypoint-backup.js one_drive daily
;;
'transition' )
START_DATE=$1 && shift 1
END_DATE=$1 && shift 1
echo "[Docker] Starting Transition..."
node docker/entrypoint-transition.js $START_DATE $END_DATE
;;
* )
echo "[Docker] Unknown command"
;;

View File

@@ -0,0 +1,11 @@
import { MigrationInterface, QueryRunner } from 'typeorm'
export class RemoveTransitionRole1697704066569 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query('DELETE FROM `roles` WHERE name = "TRANSITION_USER"')
}
public async down(): Promise<void> {
return
}
}

View File

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

View File

@@ -7,7 +7,7 @@ import {
DomainEventHandlerInterface,
DomainEventMessageHandlerInterface,
DomainEventPublisherInterface,
DomainEventSubscriberFactoryInterface,
DomainEventSubscriberInterface,
} from '@standardnotes/domain-events'
import { TimerInterface, Timer } from '@standardnotes/time'
import { UAParser } from 'ua-parser-js'
@@ -90,8 +90,8 @@ import {
DirectCallDomainEventPublisher,
DirectCallEventMessageHandler,
SNSOpenTelemetryDomainEventPublisher,
SQSDomainEventSubscriberFactory,
SQSEventMessageHandler,
SQSOpenTelemetryDomainEventSubscriber,
} from '@standardnotes/domain-events-infra'
import { GetUserSubscription } from '../Domain/UseCase/GetUserSubscription/GetUserSubscription'
import { ChangeCredentials } from '../Domain/UseCase/ChangeCredentials/ChangeCredentials'
@@ -188,6 +188,7 @@ import {
ControllerContainer,
ControllerContainerInterface,
MapperInterface,
ServiceIdentifier,
SharedVaultUser,
} from '@standardnotes/domain-core'
import { SessionTracePersistenceMapper } from '../Mapping/SessionTracePersistenceMapper'
@@ -257,11 +258,6 @@ import { UpdateStorageQuotaUsedForUser } from '../Domain/UseCase/UpdateStorageQu
import { SharedVaultFileUploadedEventHandler } from '../Domain/Handler/SharedVaultFileUploadedEventHandler'
import { SharedVaultFileRemovedEventHandler } from '../Domain/Handler/SharedVaultFileRemovedEventHandler'
import { SharedVaultFileMovedEventHandler } from '../Domain/Handler/SharedVaultFileMovedEventHandler'
import { TransitionStatusRepositoryInterface } from '../Domain/Transition/TransitionStatusRepositoryInterface'
import { RedisTransitionStatusRepository } from '../Infra/Redis/RedisTransitionStatusRepository'
import { InMemoryTransitionStatusRepository } from '../Infra/InMemory/InMemoryTransitionStatusRepository'
import { TransitionStatusUpdatedEventHandler } from '../Domain/Handler/TransitionStatusUpdatedEventHandler'
import { UpdateTransitionStatus } from '../Domain/UseCase/UpdateTransitionStatus/UpdateTransitionStatus'
import { TypeORMSharedVaultUser } from '../Infra/TypeORM/TypeORMSharedVaultUser'
import { SharedVaultUserPersistenceMapper } from '../Mapping/SharedVaultUserPersistenceMapper'
import { SharedVaultUserRepositoryInterface } from '../Domain/SharedVault/SharedVaultUserRepositoryInterface'
@@ -644,9 +640,6 @@ export class ContainerConfigLoader {
container.get(TYPES.Auth_Timer),
),
)
container
.bind<TransitionStatusRepositoryInterface>(TYPES.Auth_TransitionStatusRepository)
.toConstantValue(new InMemoryTransitionStatusRepository())
} else {
container.bind<PKCERepositoryInterface>(TYPES.Auth_PKCERepository).to(RedisPKCERepository)
container.bind<LockRepositoryInterface>(TYPES.Auth_LockRepository).to(LockRepository)
@@ -659,9 +652,6 @@ export class ContainerConfigLoader {
container
.bind<SubscriptionTokenRepositoryInterface>(TYPES.Auth_SubscriptionTokenRepository)
.to(RedisSubscriptionTokenRepository)
container
.bind<TransitionStatusRepositoryInterface>(TYPES.Auth_TransitionStatusRepository)
.toConstantValue(new RedisTransitionStatusRepository(container.get<Redis>(TYPES.Auth_Redis)))
}
// Services
@@ -984,15 +974,6 @@ export class ContainerConfigLoader {
container.get(TYPES.Auth_SubscriptionSettingService),
),
)
container
.bind<UpdateTransitionStatus>(TYPES.Auth_UpdateTransitionStatus)
.toConstantValue(
new UpdateTransitionStatus(
container.get<TransitionStatusRepositoryInterface>(TYPES.Auth_TransitionStatusRepository),
container.get<RoleServiceInterface>(TYPES.Auth_RoleService),
container.get<winston.Logger>(TYPES.Auth_Logger),
),
)
container
.bind<AddSharedVaultUser>(TYPES.Auth_AddSharedVaultUser)
.toConstantValue(
@@ -1173,14 +1154,6 @@ export class ContainerConfigLoader {
container.get(TYPES.Auth_Logger),
),
)
container
.bind<TransitionStatusUpdatedEventHandler>(TYPES.Auth_TransitionStatusUpdatedEventHandler)
.toConstantValue(
new TransitionStatusUpdatedEventHandler(
container.get<UpdateTransitionStatus>(TYPES.Auth_UpdateTransitionStatus),
container.get<winston.Logger>(TYPES.Auth_Logger),
),
)
container
.bind<UserAddedToSharedVaultEventHandler>(TYPES.Auth_UserAddedToSharedVaultEventHandler)
.toConstantValue(
@@ -1238,7 +1211,6 @@ export class ContainerConfigLoader {
['PREDICATE_VERIFICATION_REQUESTED', container.get(TYPES.Auth_PredicateVerificationRequestedEventHandler)],
['EMAIL_SUBSCRIPTION_UNSUBSCRIBED', container.get(TYPES.Auth_EmailSubscriptionUnsubscribedEventHandler)],
['PAYMENTS_ACCOUNT_DELETED', container.get(TYPES.Auth_PaymentsAccountDeletedEventHandler)],
['TRANSITION_STATUS_UPDATED', container.get(TYPES.Auth_TransitionStatusUpdatedEventHandler)],
['USER_ADDED_TO_SHARED_VAULT', container.get(TYPES.Auth_UserAddedToSharedVaultEventHandler)],
['USER_REMOVED_FROM_SHARED_VAULT', container.get(TYPES.Auth_UserRemovedFromSharedVaultEventHandler)],
[
@@ -1262,12 +1234,14 @@ export class ContainerConfigLoader {
.toConstantValue(new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Auth_Logger)))
container
.bind<DomainEventSubscriberFactoryInterface>(TYPES.Auth_DomainEventSubscriberFactory)
.bind<DomainEventSubscriberInterface>(TYPES.Auth_DomainEventSubscriber)
.toConstantValue(
new SQSDomainEventSubscriberFactory(
container.get(TYPES.Auth_SQS),
container.get(TYPES.Auth_SQS_QUEUE_URL),
container.get(TYPES.Auth_DomainEventMessageHandler),
new SQSOpenTelemetryDomainEventSubscriber(
ServiceIdentifier.NAMES.AuthWorker,
container.get<SQSClient>(TYPES.Auth_SQS),
container.get<string>(TYPES.Auth_SQS_QUEUE_URL),
container.get<DomainEventMessageHandlerInterface>(TYPES.Auth_DomainEventMessageHandler),
container.get<winston.Logger>(TYPES.Auth_Logger),
),
)
}

View File

@@ -36,7 +36,6 @@ const TYPES = {
Auth_AuthenticatorRepository: Symbol.for('Auth_AuthenticatorRepository'),
Auth_AuthenticatorChallengeRepository: Symbol.for('Auth_AuthenticatorChallengeRepository'),
Auth_CacheEntryRepository: Symbol.for('Auth_CacheEntryRepository'),
Auth_TransitionStatusRepository: Symbol.for('Auth_TransitionStatusRepository'),
Auth_SharedVaultUserRepository: Symbol.for('Auth_SharedVaultUserRepository'),
// ORM
Auth_ORMOfflineSettingRepository: Symbol.for('Auth_ORMOfflineSettingRepository'),
@@ -157,7 +156,6 @@ const TYPES = {
Auth_SignInWithRecoveryCodes: Symbol.for('Auth_SignInWithRecoveryCodes'),
Auth_GetUserKeyParamsRecovery: Symbol.for('Auth_GetUserKeyParamsRecovery'),
Auth_UpdateStorageQuotaUsedForUser: Symbol.for('Auth_UpdateStorageQuotaUsedForUser'),
Auth_UpdateTransitionStatus: Symbol.for('Auth_UpdateTransitionStatus'),
Auth_AddSharedVaultUser: Symbol.for('Auth_AddSharedVaultUser'),
Auth_RemoveSharedVaultUser: Symbol.for('Auth_RemoveSharedVaultUser'),
Auth_DesignateSurvivor: Symbol.for('Auth_DesignateSurvivor'),
@@ -190,7 +188,6 @@ const TYPES = {
Auth_PredicateVerificationRequestedEventHandler: Symbol.for('Auth_PredicateVerificationRequestedEventHandler'),
Auth_EmailSubscriptionUnsubscribedEventHandler: Symbol.for('Auth_EmailSubscriptionUnsubscribedEventHandler'),
Auth_PaymentsAccountDeletedEventHandler: Symbol.for('Auth_PaymentsAccountDeletedEventHandler'),
Auth_TransitionStatusUpdatedEventHandler: Symbol.for('Auth_TransitionStatusUpdatedEventHandler'),
Auth_UserAddedToSharedVaultEventHandler: Symbol.for('Auth_UserAddedToSharedVaultEventHandler'),
Auth_UserRemovedFromSharedVaultEventHandler: Symbol.for('Auth_UserRemovedFromSharedVaultEventHandler'),
Auth_UserDesignatedAsSurvivorInSharedVaultEventHandler: Symbol.for(
@@ -218,7 +215,7 @@ const TYPES = {
Auth_WebSocketConnectionTokenDecoder: Symbol.for('Auth_WebSocketConnectionTokenDecoder'),
Auth_AuthenticationMethodResolver: Symbol.for('Auth_AuthenticationMethodResolver'),
Auth_DomainEventPublisher: Symbol.for('Auth_DomainEventPublisher'),
Auth_DomainEventSubscriberFactory: Symbol.for('Auth_DomainEventSubscriberFactory'),
Auth_DomainEventSubscriber: Symbol.for('Auth_DomainEventSubscriber'),
Auth_DomainEventFactory: Symbol.for('Auth_DomainEventFactory'),
Auth_DomainEventMessageHandler: Symbol.for('Auth_DomainEventMessageHandler'),
Auth_HTTPClient: Symbol.for('Auth_HTTPClient'),

View File

@@ -20,7 +20,6 @@ import {
StatisticPersistenceRequestedEvent,
SessionCreatedEvent,
SessionRefreshedEvent,
TransitionRequestedEvent,
} from '@standardnotes/domain-events'
import { Predicate, PredicateVerificationResult } from '@standardnotes/predicates'
import { TimerInterface } from '@standardnotes/time'
@@ -34,25 +33,6 @@ import { KeyParamsData } from '@standardnotes/responses'
export class DomainEventFactory implements DomainEventFactoryInterface {
constructor(@inject(TYPES.Auth_Timer) private timer: TimerInterface) {}
createTransitionRequestedEvent(dto: {
userUuid: string
type: 'items' | 'revisions'
timestamp: number
}): TransitionRequestedEvent {
return {
type: 'TRANSITION_REQUESTED',
createdAt: this.timer.getUTCDate(),
meta: {
correlation: {
userIdentifier: dto.userUuid,
userIdentifierType: 'uuid',
},
origin: DomainEventService.Auth,
},
payload: dto,
}
}
createSessionCreatedEvent(dto: { userUuid: string }): SessionCreatedEvent {
return {
type: 'SESSION_CREATED',

View File

@@ -18,7 +18,6 @@ import {
StatisticPersistenceRequestedEvent,
SessionCreatedEvent,
SessionRefreshedEvent,
TransitionRequestedEvent,
} from '@standardnotes/domain-events'
import { InviteeIdentifierType } from '../SharedSubscription/InviteeIdentifierType'
import { KeyParamsData } from '@standardnotes/responses'
@@ -92,9 +91,4 @@ export interface DomainEventFactoryInterface {
}): StatisticPersistenceRequestedEvent
createSessionCreatedEvent(dto: { userUuid: string }): SessionCreatedEvent
createSessionRefreshedEvent(dto: { userUuid: string }): SessionRefreshedEvent
createTransitionRequestedEvent(dto: {
userUuid: string
type: 'items' | 'revisions'
timestamp: number
}): TransitionRequestedEvent
}

View File

@@ -1,23 +0,0 @@
import { DomainEventHandlerInterface, TransitionStatusUpdatedEvent } from '@standardnotes/domain-events'
import { UpdateTransitionStatus } from '../UseCase/UpdateTransitionStatus/UpdateTransitionStatus'
import { Logger } from 'winston'
export class TransitionStatusUpdatedEventHandler implements DomainEventHandlerInterface {
constructor(
private updateTransitionStatusUseCase: UpdateTransitionStatus,
private logger: Logger,
) {}
async handle(event: TransitionStatusUpdatedEvent): Promise<void> {
const result = await this.updateTransitionStatusUseCase.execute({
status: event.payload.status,
userUuid: event.payload.userUuid,
transitionType: event.payload.transitionType,
transitionTimestamp: event.payload.transitionTimestamp,
})
if (result.isFailed()) {
this.logger.error(`Failed to update transition status for user ${event.payload.userUuid}`)
}
}
}

View File

@@ -1,7 +0,0 @@
import { TransitionStatus } from '@standardnotes/domain-core'
export interface TransitionStatusRepositoryInterface {
updateStatus(userUuid: string, transitionType: 'items' | 'revisions', status: TransitionStatus): Promise<void>
getStatus(userUuid: string, transitionType: 'items' | 'revisions'): Promise<TransitionStatus | null>
remove(userUuid: string, transitionType: 'items' | 'revisions'): Promise<void>
}

View File

@@ -9,15 +9,7 @@ import { UserRepositoryInterface } from '../../User/UserRepositoryInterface'
import { CreateCrossServiceToken } from './CreateCrossServiceToken'
import { GetSetting } from '../GetSetting/GetSetting'
import {
Result,
SharedVaultUser,
SharedVaultUserPermission,
Timestamps,
TransitionStatus,
Uuid,
} from '@standardnotes/domain-core'
import { TransitionStatusRepositoryInterface } from '../../Transition/TransitionStatusRepositoryInterface'
import { Result, SharedVaultUser, SharedVaultUserPermission, Timestamps, Uuid } from '@standardnotes/domain-core'
import { SharedVaultUserRepositoryInterface } from '../../SharedVault/SharedVaultUserRepositoryInterface'
describe('CreateCrossServiceToken', () => {
@@ -27,7 +19,6 @@ describe('CreateCrossServiceToken', () => {
let tokenEncoder: TokenEncoderInterface<CrossServiceTokenData>
let userRepository: UserRepositoryInterface
let getSettingUseCase: GetSetting
let transitionStatusRepository: TransitionStatusRepositoryInterface
let sharedVaultUserRepository: SharedVaultUserRepositoryInterface
const jwtTTL = 60
@@ -44,7 +35,6 @@ describe('CreateCrossServiceToken', () => {
userRepository,
jwtTTL,
getSettingUseCase,
transitionStatusRepository,
sharedVaultUserRepository,
)
@@ -78,11 +68,6 @@ describe('CreateCrossServiceToken', () => {
getSettingUseCase = {} as jest.Mocked<GetSetting>
getSettingUseCase.execute = jest.fn().mockReturnValue(Result.ok({ setting: { value: '100' } }))
transitionStatusRepository = {} as jest.Mocked<TransitionStatusRepositoryInterface>
transitionStatusRepository.getStatus = jest
.fn()
.mockReturnValue(TransitionStatus.create(TransitionStatus.STATUSES.Verified).getValue())
sharedVaultUserRepository = {} as jest.Mocked<SharedVaultUserRepositoryInterface>
sharedVaultUserRepository.findByUserUuid = jest.fn().mockReturnValue([
SharedVaultUser.create({
@@ -122,46 +107,6 @@ describe('CreateCrossServiceToken', () => {
email: 'test@test.te',
uuid: '00000000-0000-0000-0000-000000000000',
},
ongoing_transition: false,
ongoing_revisions_transition: false,
},
60,
)
})
it('should create a cross service token for user that has an ongoing transaction', async () => {
transitionStatusRepository.getStatus = jest
.fn()
.mockReturnValue(TransitionStatus.create(TransitionStatus.STATUSES.InProgress).getValue())
await createUseCase().execute({
user,
session,
})
expect(tokenEncoder.encodeExpirableToken).toHaveBeenCalledWith(
{
roles: [
{
name: 'role1',
uuid: '1-3-4',
},
],
belongs_to_shared_vaults: [
{
shared_vault_uuid: '00000000-0000-0000-0000-000000000000',
permission: 'read',
},
],
session: {
test: 'test',
},
user: {
email: 'test@test.te',
uuid: '00000000-0000-0000-0000-000000000000',
},
ongoing_transition: true,
ongoing_revisions_transition: true,
},
60,
)
@@ -190,8 +135,6 @@ describe('CreateCrossServiceToken', () => {
email: 'test@test.te',
uuid: '00000000-0000-0000-0000-000000000000',
},
ongoing_transition: false,
ongoing_revisions_transition: false,
},
60,
)
@@ -220,8 +163,6 @@ describe('CreateCrossServiceToken', () => {
email: 'test@test.te',
uuid: '00000000-0000-0000-0000-000000000000',
},
ongoing_transition: false,
ongoing_revisions_transition: false,
},
60,
)
@@ -277,8 +218,6 @@ describe('CreateCrossServiceToken', () => {
email: 'test@test.te',
uuid: '00000000-0000-0000-0000-000000000000',
},
ongoing_revisions_transition: false,
ongoing_transition: false,
},
60,
)

View File

@@ -1,6 +1,6 @@
import { TokenEncoderInterface, CrossServiceTokenData } from '@standardnotes/security'
import { inject, injectable } from 'inversify'
import { Result, TransitionStatus, UseCaseInterface, Uuid } from '@standardnotes/domain-core'
import { Result, UseCaseInterface, Uuid } from '@standardnotes/domain-core'
import TYPES from '../../../Bootstrap/Types'
import { ProjectorInterface } from '../../../Projection/ProjectorInterface'
@@ -12,7 +12,6 @@ import { UserRepositoryInterface } from '../../User/UserRepositoryInterface'
import { CreateCrossServiceTokenDTO } from './CreateCrossServiceTokenDTO'
import { GetSetting } from '../GetSetting/GetSetting'
import { SettingName } from '@standardnotes/settings'
import { TransitionStatusRepositoryInterface } from '../../Transition/TransitionStatusRepositoryInterface'
import { SharedVaultUserRepositoryInterface } from '../../SharedVault/SharedVaultUserRepositoryInterface'
@injectable()
@@ -26,8 +25,6 @@ export class CreateCrossServiceToken implements UseCaseInterface<string> {
@inject(TYPES.Auth_AUTH_JWT_TTL) private jwtTTL: number,
@inject(TYPES.Auth_GetSetting)
private getSettingUseCase: GetSetting,
@inject(TYPES.Auth_TransitionStatusRepository)
private transitionStatusRepository: TransitionStatusRepositoryInterface,
@inject(TYPES.Auth_SharedVaultUserRepository) private sharedVaultUserRepository: SharedVaultUserRepositoryInterface,
) {}
@@ -47,9 +44,6 @@ export class CreateCrossServiceToken implements UseCaseInterface<string> {
return Result.fail(`Could not find user with uuid ${dto.userUuid}`)
}
const transitionStatus = await this.transitionStatusRepository.getStatus(user.uuid, 'items')
const revisionsTransitionStatus = await this.transitionStatusRepository.getStatus(user.uuid, 'revisions')
const roles = await user.roles
const sharedVaultAssociations = await this.sharedVaultUserRepository.findByUserUuid(
@@ -60,8 +54,6 @@ export class CreateCrossServiceToken implements UseCaseInterface<string> {
user: this.projectUser(user),
roles: this.projectRoles(roles),
shared_vault_owner_context: undefined,
ongoing_transition: transitionStatus?.value === TransitionStatus.STATUSES.InProgress,
ongoing_revisions_transition: revisionsTransitionStatus?.value === TransitionStatus.STATUSES.InProgress,
belongs_to_shared_vaults: sharedVaultAssociations.map((association) => ({
shared_vault_uuid: association.props.sharedVaultUuid.value,
permission: association.props.permission.value,

View File

@@ -1,6 +1,5 @@
import 'reflect-metadata'
import { TransitionStatus } from '@standardnotes/domain-core'
import { TimerInterface } from '@standardnotes/time'
import { TokenEncoderInterface, ValetTokenData, ValetTokenOperation } from '@standardnotes/security'
@@ -11,7 +10,6 @@ import { User } from '../../User/User'
import { UserSubscriptionType } from '../../Subscription/UserSubscriptionType'
import { SubscriptionSettingsAssociationServiceInterface } from '../../Setting/SubscriptionSettingsAssociationServiceInterface'
import { UserSubscriptionServiceInterface } from '../../Subscription/UserSubscriptionServiceInterface'
import { TransitionStatusRepositoryInterface } from '../../Transition/TransitionStatusRepositoryInterface'
describe('CreateValetToken', () => {
let tokenEncoder: TokenEncoderInterface<ValetTokenData>
@@ -23,7 +21,6 @@ describe('CreateValetToken', () => {
let regularSubscription: UserSubscription
let sharedSubscription: UserSubscription
let user: User
let transitionStatusRepository: TransitionStatusRepositoryInterface
const createUseCase = () =>
new CreateValetToken(
@@ -33,7 +30,6 @@ describe('CreateValetToken', () => {
userSubscriptionService,
timer,
valetTokenTTL,
transitionStatusRepository,
)
beforeEach(() => {
@@ -71,11 +67,6 @@ describe('CreateValetToken', () => {
timer = {} as jest.Mocked<TimerInterface>
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 () => {
@@ -176,7 +167,6 @@ describe('CreateValetToken', () => {
{
sharedSubscriptionUuid: undefined,
regularSubscriptionUuid: '1-2-3',
ongoingTransition: false,
permittedOperation: 'write',
permittedResources: [
{
@@ -217,7 +207,6 @@ describe('CreateValetToken', () => {
{
sharedSubscriptionUuid: '2-3-4',
regularSubscriptionUuid: '1-2-3',
ongoingTransition: false,
permittedOperation: 'write',
permittedResources: [
{
@@ -278,7 +267,6 @@ describe('CreateValetToken', () => {
{
sharedSubscriptionUuid: undefined,
regularSubscriptionUuid: '1-2-3',
ongoingTransition: false,
permittedOperation: 'write',
permittedResources: [
{

View File

@@ -13,8 +13,6 @@ import { CreateValetTokenDTO } from './CreateValetTokenDTO'
import { SubscriptionSettingsAssociationServiceInterface } from '../../Setting/SubscriptionSettingsAssociationServiceInterface'
import { UserSubscriptionServiceInterface } from '../../Subscription/UserSubscriptionServiceInterface'
import { CreateValetTokenPayload } from '../../ValetToken/CreateValetTokenPayload'
import { TransitionStatusRepositoryInterface } from '../../Transition/TransitionStatusRepositoryInterface'
import { TransitionStatus } from '@standardnotes/domain-core'
@injectable()
export class CreateValetToken implements UseCaseInterface {
@@ -27,8 +25,6 @@ export class CreateValetToken implements UseCaseInterface {
@inject(TYPES.Auth_UserSubscriptionService) private userSubscriptionService: UserSubscriptionServiceInterface,
@inject(TYPES.Auth_Timer) private timer: TimerInterface,
@inject(TYPES.Auth_VALET_TOKEN_TTL) private valetTokenTTL: number,
@inject(TYPES.Auth_TransitionStatusRepository)
private transitionStatusRepository: TransitionStatusRepositoryInterface,
) {}
async execute(dto: CreateValetTokenDTO): Promise<CreateValetTokenResponseData> {
@@ -87,8 +83,6 @@ export class CreateValetToken implements UseCaseInterface {
sharedSubscriptionUuid = sharedSubscription.uuid
}
const transitionStatus = await this.transitionStatusRepository.getStatus(userUuid, 'items')
const tokenData: ValetTokenData = {
userUuid: dto.userUuid,
permittedOperation: dto.operation,
@@ -97,7 +91,6 @@ export class CreateValetToken implements UseCaseInterface {
uploadBytesLimit,
sharedSubscriptionUuid,
regularSubscriptionUuid: regularSubscription.uuid,
ongoingTransition: transitionStatus?.value === TransitionStatus.STATUSES.InProgress,
}
const valetToken = this.tokenEncoder.encodeExpirableToken(tokenData, this.valetTokenTTL)

View File

@@ -1,107 +0,0 @@
import { RoleName, TransitionStatus, Uuid } from '@standardnotes/domain-core'
import { RoleServiceInterface } from '../../Role/RoleServiceInterface'
import { TransitionStatusRepositoryInterface } from '../../Transition/TransitionStatusRepositoryInterface'
import { UpdateTransitionStatus } from './UpdateTransitionStatus'
import { Logger } from 'winston'
describe('UpdateTransitionStatus', () => {
let transitionStatusRepository: TransitionStatusRepositoryInterface
let roleService: RoleServiceInterface
let logger: Logger
const createUseCase = () => new UpdateTransitionStatus(transitionStatusRepository, roleService, logger)
beforeEach(() => {
logger = {} as jest.Mocked<Logger>
logger.info = jest.fn()
transitionStatusRepository = {} as jest.Mocked<TransitionStatusRepositoryInterface>
transitionStatusRepository.updateStatus = jest.fn()
transitionStatusRepository.getStatus = jest.fn().mockResolvedValue(null)
roleService = {} as jest.Mocked<RoleServiceInterface>
roleService.removeRoleFromUser = jest.fn()
})
it('should add TRANSITION_USER role', async () => {
const useCase = createUseCase()
const result = await useCase.execute({
userUuid: '00000000-0000-0000-0000-000000000000',
status: 'VERIFIED',
transitionType: 'items',
transitionTimestamp: 123,
})
expect(result.isFailed()).toBeFalsy()
expect(roleService.removeRoleFromUser).toHaveBeenCalledWith(
Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
RoleName.create(RoleName.NAMES.TransitionUser).getValue(),
)
})
it('should update transition status', async () => {
const useCase = createUseCase()
const result = await useCase.execute({
userUuid: '00000000-0000-0000-0000-000000000000',
status: TransitionStatus.STATUSES.InProgress,
transitionType: 'items',
transitionTimestamp: 123,
})
expect(result.isFailed()).toBeFalsy()
expect(transitionStatusRepository.updateStatus).toHaveBeenCalled()
})
it('should return error when user uuid is invalid', async () => {
const useCase = createUseCase()
const result = await useCase.execute({
userUuid: 'invalid',
status: 'STARTED',
transitionType: 'items',
transitionTimestamp: 123,
})
expect(result.isFailed()).toBeTruthy()
expect(result.getError()).toEqual('Given value is not a valid uuid: invalid')
})
it('should not update status if transition is already verified', async () => {
transitionStatusRepository.getStatus = jest
.fn()
.mockResolvedValue(TransitionStatus.create(TransitionStatus.STATUSES.Verified).getValue())
const useCase = createUseCase()
const result = await useCase.execute({
userUuid: '00000000-0000-0000-0000-000000000000',
status: TransitionStatus.STATUSES.InProgress,
transitionType: 'items',
transitionTimestamp: 123,
})
expect(result.isFailed()).toBeFalsy()
expect(transitionStatusRepository.updateStatus).not.toHaveBeenCalled()
})
it('should not update status if transition is already failed', async () => {
transitionStatusRepository.getStatus = jest
.fn()
.mockResolvedValue(TransitionStatus.create(TransitionStatus.STATUSES.Failed).getValue())
const useCase = createUseCase()
const result = await useCase.execute({
userUuid: '00000000-0000-0000-0000-000000000000',
status: TransitionStatus.STATUSES.InProgress,
transitionType: 'items',
transitionTimestamp: 123,
})
expect(result.isFailed()).toBeFalsy()
expect(transitionStatusRepository.updateStatus).not.toHaveBeenCalled()
})
})

View File

@@ -1,40 +0,0 @@
import { Result, RoleName, TransitionStatus, UseCaseInterface, Uuid } from '@standardnotes/domain-core'
import { TransitionStatusRepositoryInterface } from '../../Transition/TransitionStatusRepositoryInterface'
import { UpdateTransitionStatusDTO } from './UpdateTransitionStatusDTO'
import { RoleServiceInterface } from '../../Role/RoleServiceInterface'
import { Logger } from 'winston'
export class UpdateTransitionStatus implements UseCaseInterface<void> {
constructor(
private transitionStatusRepository: TransitionStatusRepositoryInterface,
private roleService: RoleServiceInterface,
private logger: Logger,
) {}
async execute(dto: UpdateTransitionStatusDTO): Promise<Result<void>> {
const userUuidOrError = Uuid.create(dto.userUuid)
if (userUuidOrError.isFailed()) {
return Result.fail(userUuidOrError.getError())
}
const userUuid = userUuidOrError.getValue()
const currentStatus = await this.transitionStatusRepository.getStatus(dto.userUuid, dto.transitionType)
if (
[TransitionStatus.STATUSES.Verified, TransitionStatus.STATUSES.Failed].includes(currentStatus?.value as string)
) {
this.logger.info(`User ${dto.userUuid} transition already finished.`)
return Result.ok()
}
const transitionStatus = TransitionStatus.create(dto.status).getValue()
await this.transitionStatusRepository.updateStatus(dto.userUuid, dto.transitionType, transitionStatus)
if (dto.transitionType === 'items' && transitionStatus.value === TransitionStatus.STATUSES.Verified) {
await this.roleService.removeRoleFromUser(userUuid, RoleName.create(RoleName.NAMES.TransitionUser).getValue())
}
return Result.ok()
}
}

View File

@@ -1,6 +0,0 @@
export interface UpdateTransitionStatusDTO {
userUuid: string
transitionType: 'items' | 'revisions'
transitionTimestamp: number
status: string
}

View File

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

View File

@@ -1,39 +0,0 @@
import { TransitionStatus } from '@standardnotes/domain-core'
import { TransitionStatusRepositoryInterface } from '../../Domain/Transition/TransitionStatusRepositoryInterface'
export class InMemoryTransitionStatusRepository implements TransitionStatusRepositoryInterface {
private itemStatuses: Map<string, string> = new Map()
private revisionStatuses: Map<string, string> = new Map()
async updateStatus(userUuid: string, transitionType: 'items' | 'revisions', status: TransitionStatus): Promise<void> {
if (transitionType === 'items') {
this.itemStatuses.set(userUuid, status.value)
} else {
this.revisionStatuses.set(userUuid, status.value)
}
}
async remove(userUuid: string, transitionType: 'items' | 'revisions'): Promise<void> {
if (transitionType === 'items') {
this.itemStatuses.delete(userUuid)
} else {
this.revisionStatuses.delete(userUuid)
}
}
async getStatus(userUuid: string, transitionType: 'items' | 'revisions'): Promise<TransitionStatus | null> {
let status: string | null
if (transitionType === 'items') {
status = this.itemStatuses.get(userUuid) ?? null
} else {
status = this.revisionStatuses.get(userUuid) ?? null
}
if (status === null) {
return null
}
return TransitionStatus.create(status).getValue()
}
}

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