Compare commits

..

53 Commits

Author SHA1 Message Date
standardci e6d8e5c5f2 chore(release): publish new version
- @standardnotes/analytics@2.33.0
 - @standardnotes/api-gateway@1.82.0
 - @standardnotes/auth-server@1.168.0
 - @standardnotes/domain-events-infra@1.21.0
 - @standardnotes/domain-events@2.134.0
 - @standardnotes/event-store@1.14.0
 - @standardnotes/files-server@1.33.0
 - @standardnotes/home-server@1.19.0
 - @standardnotes/revisions-server@1.48.0
 - @standardnotes/scheduler-server@1.27.0
 - @standardnotes/syncing-server@1.121.0
 - @standardnotes/websockets-server@1.18.0
2023-11-10 11:46:24 +00:00
Karol Sójko c24353cc24 feat: add graceful shutdown procedures upon SIGTERM (#923) 2023-11-10 12:20:21 +01:00
standardci 4855e1d5f5 chore(release): publish new version
- @standardnotes/api-gateway@1.81.14
 - @standardnotes/home-server@1.18.32
2023-11-10 10:04:31 +00:00
Karol Sójko 5d3fb9a537 fix(api-gateway): add logs about calling web sockets with minimal format 2023-11-10 10:32:47 +01:00
standardci b55d80a7cd chore(release): publish new version
- @standardnotes/api-gateway@1.81.13
 - @standardnotes/home-server@1.18.31
2023-11-09 14:29:28 +00:00
Karol Sójko 16f92bdc99 fix(api-gateway): add possibility to configure keep-alive timeout (#920) 2023-11-09 15:02:32 +01:00
standardci 4c5738416a chore(release): publish new version
- @standardnotes/home-server@1.18.30
 - @standardnotes/syncing-server@1.120.5
 - @standardnotes/websockets-server@1.17.8
2023-11-09 13:26:30 +00:00
Karol Sójko 45d4920e0f fix: remove unused axios dep in subservices 2023-11-09 14:03:44 +01:00
standardci 94e738532a chore(release): publish new version
- @standardnotes/api-gateway@1.81.12
 - @standardnotes/home-server@1.18.29
 - @standardnotes/websockets-server@1.17.7
2023-11-09 11:18:35 +00:00
Karol Sójko c4ae12d53f fix: reduce websockets api communication data (#919) 2023-11-09 11:44:31 +01:00
standardci 4ff78452f9 chore(release): publish new version
- @standardnotes/auth-server@1.167.2
 - @standardnotes/home-server@1.18.28
 - @standardnotes/syncing-server@1.120.4
2023-11-08 15:38:47 +00:00
Karol Sójko 9465f2ecd8 fix: add logs about sending websocket events to clients 2023-11-08 16:10:44 +01:00
standardci 93c2f1f12f chore(release): publish new version
- @standardnotes/auth-server@1.167.1
 - @standardnotes/home-server@1.18.27
2023-11-08 12:15:35 +00:00
Karol Sójko ca8a3fc77d fix(auth): path to delete accounts script 2023-11-08 12:30:12 +01:00
standardci 00936e06bc chore(release): publish new version
- @standardnotes/auth-server@1.167.0
 - @standardnotes/home-server@1.18.26
2023-11-08 10:48:51 +00:00
Karol Sójko a6dea50d74 feat: script to mass delete accounts from CSV source (#913) 2023-11-08 11:21:00 +01:00
standardci 28b04e6a4a chore(release): publish new version
- @standardnotes/auth-server@1.166.0
 - @standardnotes/home-server@1.18.25
2023-11-07 14:49:54 +00:00
Karol Sójko d228a86f48 feat(auth): add triggering post setting update actions (#905)
* feat(auth): add triggering post setting update actions

* feat(auth): refactor email backups

* fix: add extra logs for backups

* fix: specs
2023-11-07 15:14:51 +01:00
standardci 0cb234aa47 chore(release): publish new version
- @standardnotes/api-gateway@1.81.11
 - @standardnotes/home-server@1.18.24
2023-11-07 11:28:36 +00:00
Karol Sójko 6b554c28b7 fix(api-gateway): remove calling both auth and payments on account deletion request 2023-11-07 12:02:40 +01:00
standardci 8a0accd8ea chore(release): publish new version
- @standardnotes/analytics@2.32.6
 - @standardnotes/api-gateway@1.81.10
 - @standardnotes/auth-server@1.165.4
 - @standardnotes/domain-events-infra@1.20.4
 - @standardnotes/domain-events@2.133.1
 - @standardnotes/event-store@1.13.19
 - @standardnotes/files-server@1.32.5
 - @standardnotes/home-server@1.18.23
 - @standardnotes/revisions-server@1.47.5
 - @standardnotes/scheduler-server@1.26.6
 - @standardnotes/syncing-server@1.120.3
 - @standardnotes/websockets-server@1.17.6
2023-11-07 11:00:09 +00:00
Karol Sójko d66ae62cf4 fix: account deletion event (#904)
* fix: account deletion event

* fix: feature service binding
2023-11-07 11:34:10 +01:00
standardci b01d1c659d chore(release): publish new version
- @standardnotes/analytics@2.32.5
 - @standardnotes/api-gateway@1.81.9
 - @standardnotes/auth-server@1.165.3
 - @standardnotes/domain-events-infra@1.20.3
 - @standardnotes/event-store@1.13.18
 - @standardnotes/files-server@1.32.4
 - @standardnotes/home-server@1.18.22
 - @standardnotes/revisions-server@1.47.4
 - @standardnotes/scheduler-server@1.26.5
 - @standardnotes/syncing-server@1.120.2
 - @standardnotes/websockets-server@1.17.5
2023-11-07 08:52:34 +00:00
Karol Sójko 751f3b2547 fix: remove open telemetry from code (#903) 2023-11-07 09:15:31 +01:00
standardci 11514e3836 chore(release): publish new version
- @standardnotes/home-server@1.18.21
 - @standardnotes/syncing-server@1.120.1
2023-11-06 15:00:46 +00:00
Karol Sójko 71689c1497 fix(syncing-server): return cursor token upon transfer limit breached (#902)
* fix(syncing-server): return cursor token upon transfer limit breached

* fix e2e env vars
2023-11-06 15:38:28 +01:00
standardci 2742075edc chore(release): publish new version
- @standardnotes/auth-server@1.165.2
 - @standardnotes/home-server@1.18.20
2023-11-03 17:04:35 +00:00
Karol Sójko 7f16232f8b fix(auth): change log severity on user authentication 2023-11-03 17:36:29 +01:00
standardci 0b0703e6d1 chore(release): publish new version
- @standardnotes/api-gateway@1.81.8
 - @standardnotes/auth-server@1.165.1
 - @standardnotes/home-server@1.18.19
2023-11-03 16:27:17 +00:00
Karol Sójko 3e376c44e3 fix: retry attempts on session validation and more verbose logs (#898) 2023-11-03 11:23:02 +01:00
standardci bfe2d4bb4a chore(release): publish new version
- @standardnotes/auth-server@1.165.0
 - @standardnotes/home-server@1.18.18
 - @standardnotes/syncing-server@1.120.0
2023-11-02 12:01:26 +00:00
Karol Sójko 7253a0a1d9 feat: add shared vault invitation email notifications (#897) 2023-11-02 12:35:01 +01:00
standardci f2c5810023 chore(release): publish new version
- @standardnotes/home-server@1.18.17
2023-11-02 07:13:07 +00:00
Karol Sójko 2e5b9105b8 fix(home-server): remove unused dep 2023-11-02 07:42:10 +01:00
Karol Sójko d14411d72e chore: upgrade deps 2023-11-02 07:40:27 +01:00
standardci 5226513b26 chore(release): publish new version
- @standardnotes/auth-server@1.164.2
 - @standardnotes/home-server@1.18.16
2023-11-01 14:18:52 +00:00
Mo 334449f8aa chore: update change email copy 2023-11-01 08:50:37 -05:00
dependabot[bot] 7f43d0c69d chore(deps): bump docker/login-action from 2 to 3 (#832)
Bumps [docker/login-action](https://github.com/docker/login-action) from 2 to 3.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/login-action
  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-11-01 13:33:03 +01:00
dependabot[bot] 6f18276e7a chore(deps): bump crazy-max/ghaction-import-gpg from 5 to 6 (#818)
Bumps [crazy-max/ghaction-import-gpg](https://github.com/crazy-max/ghaction-import-gpg) from 5 to 6.
- [Release notes](https://github.com/crazy-max/ghaction-import-gpg/releases)
- [Commits](https://github.com/crazy-max/ghaction-import-gpg/compare/v5...v6)

---
updated-dependencies:
- dependency-name: crazy-max/ghaction-import-gpg
  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-11-01 13:32:41 +01:00
dependabot[bot] 9ff18a18a5 chore(deps): bump aws-actions/amazon-ecr-login from 1 to 2 (#873)
Bumps [aws-actions/amazon-ecr-login](https://github.com/aws-actions/amazon-ecr-login) from 1 to 2.
- [Release notes](https://github.com/aws-actions/amazon-ecr-login/releases)
- [Changelog](https://github.com/aws-actions/amazon-ecr-login/blob/main/CHANGELOG.md)
- [Commits](https://github.com/aws-actions/amazon-ecr-login/compare/v1...v2)

---
updated-dependencies:
- dependency-name: aws-actions/amazon-ecr-login
  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-11-01 13:31:49 +01:00
dependabot[bot] 999e72fb1f chore(deps): bump ua-parser-js from 1.0.35 to 1.0.37 (#891)
Bumps [ua-parser-js](https://github.com/faisalman/ua-parser-js) from 1.0.35 to 1.0.37.
- [Release notes](https://github.com/faisalman/ua-parser-js/releases)
- [Changelog](https://github.com/faisalman/ua-parser-js/blob/1.0.37/changelog.md)
- [Commits](https://github.com/faisalman/ua-parser-js/compare/1.0.35...1.0.37)

---
updated-dependencies:
- dependency-name: ua-parser-js
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-01 13:31:11 +01:00
standardci 4733e663a3 chore(release): publish new version
- @standardnotes/auth-server@1.164.1
 - @standardnotes/home-server@1.18.15
2023-11-01 11:51:38 +00:00
Karol Sójko b48eeb16c3 fix(auth): creating valet tokens for shared subscription users (#895)
* fix(auth): creating valet tokens for shared subscription users

* fix(auth): updating storage quota
2023-11-01 12:18:44 +01:00
standardci 0aa2584e82 chore(release): publish new version
- @standardnotes/auth-server@1.164.0
 - @standardnotes/home-server@1.18.14
2023-11-01 08:55:15 +00:00
Karol Sójko eb8c704d84 feat(auth): add sending email to old email address when the address is changed (#894) 2023-11-01 09:28:00 +01:00
standardci e93fa14703 chore(release): publish new version
- @standardnotes/api-gateway@1.81.7
 - @standardnotes/files-server@1.32.3
 - @standardnotes/home-server@1.18.13
 - @standardnotes/syncing-server@1.119.4
2023-10-31 14:16:00 +00:00
Karol Sójko 16a6815b69 fix: add fallback methods for 404 requests (#893)
* fix: add fallback methods for 404 requests

* fix: remove fallback controllers exports

* fix: have only one fallback controller expored
2023-10-31 14:44:33 +01:00
standardci b08e9731b8 chore(release): publish new version
- @standardnotes/auth-server@1.163.2
 - @standardnotes/home-server@1.18.12
2023-10-30 12:23:43 +00:00
Karol Sójko 9bd4fb2d79 fix(auth): checking permissions to update setting only when directly performed by user (#892) 2023-10-30 12:51:31 +01:00
standardci 647aeda1de chore(release): publish new version
- @standardnotes/auth-server@1.163.1
 - @standardnotes/home-server@1.18.11
2023-10-30 11:20:27 +00:00
Karol Sójko 78ff748d91 fix(auth): add more information on the listed creation error 2023-10-30 11:52:26 +01:00
standardci 31f8cf1169 chore(release): publish new version
- @standardnotes/api-gateway@1.81.6
 - @standardnotes/home-server@1.18.10
2023-10-27 10:03:28 +00:00
Karol Sójko 14bcf7b6c9 fix(api-gateway): logs for errors reaching service 2023-10-27 11:36:52 +02:00
256 changed files with 4104 additions and 1768 deletions
+2
View File
@@ -26,3 +26,5 @@ MYSQL_ROOT_PASSWORD=changeme123
AUTH_JWT_SECRET=f95259c5e441f5a4646d76422cfb3df4c4488842901aa50b6c51b8be2e0040e9 AUTH_JWT_SECRET=f95259c5e441f5a4646d76422cfb3df4c4488842901aa50b6c51b8be2e0040e9
AUTH_SERVER_ENCRYPTION_SERVER_KEY=1087415dfde3093797f9a7ca93a49e7d7aa1861735eb0d32aae9c303b8c3d060 AUTH_SERVER_ENCRYPTION_SERVER_KEY=1087415dfde3093797f9a7ca93a49e7d7aa1861735eb0d32aae9c303b8c3d060
VALET_TOKEN_SECRET=4b886819ebe1e908077c6cae96311b48a8416bd60cc91c03060e15bdf6b30d1f VALET_TOKEN_SECRET=4b886819ebe1e908077c6cae96311b48a8416bd60cc91c03060e15bdf6b30d1f
SYNCING_SERVER_CONTENT_SIZE_TRANSFER_LIMIT=1000000
+2 -2
View File
@@ -55,7 +55,7 @@ jobs:
run: yarn build run: yarn build
- name: Login to Docker Hub - name: Login to Docker Hub
uses: docker/login-action@v2 uses: docker/login-action@v3
with: with:
username: ${{ secrets.DOCKER_USERNAME }} username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }} password: ${{ secrets.DOCKER_PASSWORD }}
@@ -69,7 +69,7 @@ jobs:
- name: Login to Amazon ECR - name: Login to Amazon ECR
id: login-ecr id: login-ecr
uses: aws-actions/amazon-ecr-login@v1 uses: aws-actions/amazon-ecr-login@v2
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@master uses: docker/setup-qemu-action@master
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Login to Docker Hub - name: Login to Docker Hub
uses: docker/login-action@v2 uses: docker/login-action@v3
with: with:
username: ${{ secrets.DOCKER_USERNAME }} username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }} password: ${{ secrets.DOCKER_PASSWORD }}
+1
View File
@@ -70,6 +70,7 @@ jobs:
echo "ACCESS_TOKEN_AGE=4" >> packages/home-server/.env echo "ACCESS_TOKEN_AGE=4" >> packages/home-server/.env
echo "REFRESH_TOKEN_AGE=10" >> packages/home-server/.env echo "REFRESH_TOKEN_AGE=10" >> packages/home-server/.env
echo "REVISIONS_FREQUENCY=2" >> packages/home-server/.env echo "REVISIONS_FREQUENCY=2" >> packages/home-server/.env
echo "CONTENT_SIZE_TRANSFER_LIMIT=1000000" >> packages/home-server/.env
echo "DB_HOST=localhost" >> packages/home-server/.env echo "DB_HOST=localhost" >> packages/home-server/.env
echo "DB_PORT=3306" >> packages/home-server/.env echo "DB_PORT=3306" >> packages/home-server/.env
echo "DB_DATABASE=standardnotes" >> packages/home-server/.env echo "DB_DATABASE=standardnotes" >> packages/home-server/.env
+1 -1
View File
@@ -143,7 +143,7 @@ jobs:
git config --global user.email "ci@standardnotes.com" git config --global user.email "ci@standardnotes.com"
- name: Import GPG key - name: Import GPG key
uses: crazy-max/ghaction-import-gpg@v5 uses: crazy-max/ghaction-import-gpg@v6
with: with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.PASSPHRASE }} passphrase: ${{ secrets.PASSPHRASE }}
Generated
+909 -9
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+16
View File
@@ -3,6 +3,22 @@
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.33.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.32.6...@standardnotes/analytics@2.33.0) (2023-11-10)
### Features
* add graceful shutdown procedures upon SIGTERM ([#923](https://github.com/standardnotes/server/issues/923)) ([c24353c](https://github.com/standardnotes/server/commit/c24353cc24ebf4b40ff9a2cec8e37cfdef109e37))
## [2.32.6](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.32.5...@standardnotes/analytics@2.32.6) (2023-11-07)
**Note:** Version bump only for package @standardnotes/analytics
## [2.32.5](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.32.4...@standardnotes/analytics@2.32.5) (2023-11-07)
### Bug Fixes
* remove open telemetry from code ([#903](https://github.com/standardnotes/server/issues/903)) ([751f3b2](https://github.com/standardnotes/server/commit/751f3b25476c5be3d663ad8540c43266acd39493))
## [2.32.4](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.32.3...@standardnotes/analytics@2.32.4) (2023-10-26) ## [2.32.4](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.32.3...@standardnotes/analytics@2.32.4) (2023-10-26)
**Note:** Version bump only for package @standardnotes/analytics **Note:** Version bump only for package @standardnotes/analytics
+1 -13
View File
@@ -1,11 +1,5 @@
import 'reflect-metadata' import 'reflect-metadata'
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
import { EmailLevel, ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AnalyticsScheduledTask })
sdk.start()
import { Logger } from 'winston' import { Logger } from 'winston'
import { DomainEventPublisherInterface } from '@standardnotes/domain-events' import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
@@ -22,6 +16,7 @@ import { CalculateMonthlyRecurringRevenue } from '../src/Domain/UseCase/Calculat
import { getBody, getSubject } from '../src/Domain/Email/DailyAnalyticsReport' import { getBody, getSubject } from '../src/Domain/Email/DailyAnalyticsReport'
import { TimerInterface } from '@standardnotes/time' import { TimerInterface } from '@standardnotes/time'
import { StatisticMeasureName } from '../src/Domain/Statistics/StatisticMeasureName' import { StatisticMeasureName } from '../src/Domain/Statistics/StatisticMeasureName'
import { EmailLevel } from '@standardnotes/domain-core'
const requestReport = async ( const requestReport = async (
analyticsStore: AnalyticsStoreInterface, analyticsStore: AnalyticsStoreInterface,
@@ -275,9 +270,6 @@ void container.load().then((container) => {
logger.info(`Sending report to following admins: ${adminEmails}`) logger.info(`Sending report to following admins: ${adminEmails}`)
const tracer = new OpenTelemetryTracer()
tracer.startSpan(ServiceIdentifier.NAMES.AnalyticsScheduledTask, 'report')
Promise.resolve( Promise.resolve(
requestReport( requestReport(
analyticsStore, analyticsStore,
@@ -293,15 +285,11 @@ void container.load().then((container) => {
.then(() => { .then(() => {
logger.info('Usage report generation complete') logger.info('Usage report generation complete')
tracer.stopSpan()
process.exit(0) process.exit(0)
}) })
.catch((error) => { .catch((error) => {
logger.error(`Could not finish usage report generation: ${error.message}`) logger.error(`Could not finish usage report generation: ${error.message}`)
tracer.stopSpanWithError(error)
process.exit(1) process.exit(1)
}) })
}) })
+6 -6
View File
@@ -1,11 +1,5 @@
import 'reflect-metadata' import 'reflect-metadata'
import { OpenTelemetrySDK } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AnalyticsWorker })
sdk.start()
import { Logger } from 'winston' import { Logger } from 'winston'
import { DomainEventSubscriberInterface } from '@standardnotes/domain-events' import { DomainEventSubscriberInterface } from '@standardnotes/domain-events'
import * as dayjs from 'dayjs' import * as dayjs from 'dayjs'
@@ -28,5 +22,11 @@ void container.load().then((container) => {
const subscriber = container.get<DomainEventSubscriberInterface>(TYPES.DomainEventSubscriber) const subscriber = container.get<DomainEventSubscriberInterface>(TYPES.DomainEventSubscriber)
process.on('SIGTERM', () => {
logger.info('SIGTERM received. Stopping worker...')
subscriber.stop()
logger.info('Worker stopped.')
})
subscriber.start() subscriber.start()
}) })
+2 -2
View File
@@ -6,12 +6,12 @@ COMMAND=$1 && shift 1
case "$COMMAND" in case "$COMMAND" in
'start-worker' ) 'start-worker' )
echo "[Docker] Starting Worker..." echo "[Docker] Starting Worker..."
node docker/entrypoint-worker.js exec node docker/entrypoint-worker.js
;; ;;
'report' ) 'report' )
echo "[Docker] Starting Usage Report Generation..." echo "[Docker] Starting Usage Report Generation..."
node docker/entrypoint-report.js exec node docker/entrypoint-report.js
;; ;;
* ) * )
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@standardnotes/analytics", "name": "@standardnotes/analytics",
"version": "2.32.4", "version": "2.33.0",
"engines": { "engines": {
"node": ">=18.0.0 <21.0.0" "node": ">=18.0.0 <21.0.0"
}, },
@@ -7,7 +7,7 @@ import {
DomainEventPublisherInterface, DomainEventPublisherInterface,
DomainEventSubscriberInterface, DomainEventSubscriberInterface,
} from '@standardnotes/domain-events' } from '@standardnotes/domain-events'
import { MapperInterface, ServiceIdentifier } from '@standardnotes/domain-core' import { MapperInterface } from '@standardnotes/domain-core'
// eslint-disable-next-line @typescript-eslint/no-var-requires // eslint-disable-next-line @typescript-eslint/no-var-requires
const Mixpanel = require('mixpanel') const Mixpanel = require('mixpanel')
@@ -16,9 +16,9 @@ import TYPES from './Types'
import { AppDataSource } from './DataSource' import { AppDataSource } from './DataSource'
import { DomainEventFactory } from '../Domain/Event/DomainEventFactory' import { DomainEventFactory } from '../Domain/Event/DomainEventFactory'
import { import {
SNSOpenTelemetryDomainEventPublisher, SNSDomainEventPublisher,
SQSDomainEventSubscriber,
SQSEventMessageHandler, SQSEventMessageHandler,
SQSOpenTelemetryDomainEventSubscriber,
} from '@standardnotes/domain-events-infra' } from '@standardnotes/domain-events-infra'
import { Timer, TimerInterface } from '@standardnotes/time' import { Timer, TimerInterface } from '@standardnotes/time'
import { PeriodKeyGeneratorInterface } from '../Domain/Time/PeriodKeyGeneratorInterface' import { PeriodKeyGeneratorInterface } from '../Domain/Time/PeriodKeyGeneratorInterface'
@@ -139,9 +139,7 @@ export class ContainerConfigLoader {
container container
.bind<DomainEventPublisherInterface>(TYPES.DomainEventPublisher) .bind<DomainEventPublisherInterface>(TYPES.DomainEventPublisher)
.toConstantValue( .toConstantValue(new SNSDomainEventPublisher(container.get(TYPES.SNS), container.get(TYPES.SNS_TOPIC_ARN)))
new SNSOpenTelemetryDomainEventPublisher(container.get(TYPES.SNS), container.get(TYPES.SNS_TOPIC_ARN)),
)
if (env.get('MIXPANEL_TOKEN', true)) { if (env.get('MIXPANEL_TOKEN', true)) {
container.bind<Mixpanel>(TYPES.MixpanelClient).toConstantValue(Mixpanel.init(env.get('MIXPANEL_TOKEN', true))) container.bind<Mixpanel>(TYPES.MixpanelClient).toConstantValue(Mixpanel.init(env.get('MIXPANEL_TOKEN', true)))
} }
@@ -242,8 +240,7 @@ export class ContainerConfigLoader {
container container
.bind<DomainEventSubscriberInterface>(TYPES.DomainEventSubscriber) .bind<DomainEventSubscriberInterface>(TYPES.DomainEventSubscriber)
.toConstantValue( .toConstantValue(
new SQSOpenTelemetryDomainEventSubscriber( new SQSDomainEventSubscriber(
ServiceIdentifier.NAMES.AnalyticsWorker,
container.get<SQSClient>(TYPES.SQS), container.get<SQSClient>(TYPES.SQS),
container.get<string>(TYPES.SQS_QUEUE_URL), container.get<string>(TYPES.SQS_QUEUE_URL),
container.get<DomainEventMessageHandlerInterface>(TYPES.DomainEventMessageHandler), container.get<DomainEventMessageHandlerInterface>(TYPES.DomainEventMessageHandler),
+58
View File
@@ -3,6 +3,64 @@
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.82.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.81.14...@standardnotes/api-gateway@1.82.0) (2023-11-10)
### Features
* add graceful shutdown procedures upon SIGTERM ([#923](https://github.com/standardnotes/api-gateway/issues/923)) ([c24353c](https://github.com/standardnotes/api-gateway/commit/c24353cc24ebf4b40ff9a2cec8e37cfdef109e37))
## [1.81.14](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.81.13...@standardnotes/api-gateway@1.81.14) (2023-11-10)
### Bug Fixes
* **api-gateway:** add logs about calling web sockets with minimal format ([5d3fb9a](https://github.com/standardnotes/api-gateway/commit/5d3fb9a537f6971cfe8ae3c5ea449806cc4de8a0))
## [1.81.13](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.81.12...@standardnotes/api-gateway@1.81.13) (2023-11-09)
### Bug Fixes
* **api-gateway:** add possibility to configure keep-alive timeout ([#920](https://github.com/standardnotes/api-gateway/issues/920)) ([16f92bd](https://github.com/standardnotes/api-gateway/commit/16f92bdc990ded5c3f1fe5af1e6e4a113a9954de))
## [1.81.12](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.81.11...@standardnotes/api-gateway@1.81.12) (2023-11-09)
### Bug Fixes
* reduce websockets api communication data ([#919](https://github.com/standardnotes/api-gateway/issues/919)) ([c4ae12d](https://github.com/standardnotes/api-gateway/commit/c4ae12d53fc166879f90a4c5dbad1ab1cb4797e2))
## [1.81.11](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.81.10...@standardnotes/api-gateway@1.81.11) (2023-11-07)
### Bug Fixes
* **api-gateway:** remove calling both auth and payments on account deletion request ([6b554c2](https://github.com/standardnotes/api-gateway/commit/6b554c28b731a9080d7ad2942d3fa05c01dcabf2))
## [1.81.10](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.81.9...@standardnotes/api-gateway@1.81.10) (2023-11-07)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.81.9](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.81.8...@standardnotes/api-gateway@1.81.9) (2023-11-07)
### Bug Fixes
* remove open telemetry from code ([#903](https://github.com/standardnotes/api-gateway/issues/903)) ([751f3b2](https://github.com/standardnotes/api-gateway/commit/751f3b25476c5be3d663ad8540c43266acd39493))
## [1.81.8](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.81.7...@standardnotes/api-gateway@1.81.8) (2023-11-03)
### Bug Fixes
* retry attempts on session validation and more verbose logs ([#898](https://github.com/standardnotes/api-gateway/issues/898)) ([3e376c4](https://github.com/standardnotes/api-gateway/commit/3e376c44e3a6c336dcff3d8ef5eb3ab040d9a561))
## [1.81.7](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.81.6...@standardnotes/api-gateway@1.81.7) (2023-10-31)
### Bug Fixes
* add fallback methods for 404 requests ([#893](https://github.com/standardnotes/api-gateway/issues/893)) ([16a6815](https://github.com/standardnotes/api-gateway/commit/16a6815b69e344573ae07682f3bac1d44d715d79))
## [1.81.6](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.81.5...@standardnotes/api-gateway@1.81.6) (2023-10-27)
### Bug Fixes
* **api-gateway:** logs for errors reaching service ([14bcf7b](https://github.com/standardnotes/api-gateway/commit/14bcf7b6c9403c3413e7579f58ea17168d14dce7))
## [1.81.5](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.81.4...@standardnotes/api-gateway@1.81.5) (2023-10-26) ## [1.81.5](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.81.4...@standardnotes/api-gateway@1.81.5) (2023-10-26)
**Note:** Version bump only for package @standardnotes/api-gateway **Note:** Version bump only for package @standardnotes/api-gateway
+11 -8
View File
@@ -1,11 +1,5 @@
import 'reflect-metadata' import 'reflect-metadata'
import { OpenTelemetrySDK } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.ApiGateway })
sdk.start()
import '../src/Controller/LegacyController' import '../src/Controller/LegacyController'
import '../src/Controller/HealthCheckController' import '../src/Controller/HealthCheckController'
@@ -108,9 +102,18 @@ void container.load().then((container) => {
}) })
}) })
const serverInstance = server.build() const serverInstance = server.build().listen(env.get('PORT'))
serverInstance.listen(env.get('PORT')) const keepAliveTimeout = env.get('KEEP_ALIVE_TIMEOUT', true) ? +env.get('KEEP_ALIVE_TIMEOUT', true) : 5000
serverInstance.keepAliveTimeout = keepAliveTimeout
process.on('SIGTERM', () => {
logger.info('SIGTERM signal received: closing HTTP server')
serverInstance.close(() => {
logger.info('HTTP server closed')
})
})
logger.info(`Server started on port ${process.env.PORT}`) logger.info(`Server started on port ${process.env.PORT}`)
}) })
+1 -1
View File
@@ -6,7 +6,7 @@ COMMAND=$1 && shift 1
case "$COMMAND" in case "$COMMAND" in
'start-web' ) 'start-web' )
echo "Starting Web..." echo "Starting Web..."
node docker/entrypoint-server.js exec node docker/entrypoint-server.js
;; ;;
* ) * )
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@standardnotes/api-gateway", "name": "@standardnotes/api-gateway",
"version": "1.81.5", "version": "1.82.0",
"engines": { "engines": {
"node": ">=18.0.0 <21.0.0" "node": ">=18.0.0 <21.0.0"
}, },
@@ -74,13 +74,16 @@ export abstract class AuthMiddleware extends BaseMiddleware {
response.locals.sharedVaultOwnerContext = decodedToken.shared_vault_owner_context response.locals.sharedVaultOwnerContext = decodedToken.shared_vault_owner_context
response.locals.belongsToSharedVaults = decodedToken.belongs_to_shared_vaults ?? [] response.locals.belongsToSharedVaults = decodedToken.belongs_to_shared_vaults ?? []
} catch (error) { } catch (error) {
const errorMessage = (error as AxiosError).isAxiosError let detailedErrorMessage = (error as Error).message
? JSON.stringify((error as AxiosError).response?.data) if (error instanceof AxiosError) {
: (error as Error).message detailedErrorMessage = `Status: ${error.status}, code: ${error.code}, message: ${error.message}`
}
this.logger.error(`Could not pass the request to sessions/validate on underlying service: ${errorMessage}`) this.logger.error(
`Could not pass the request to sessions/validate on underlying service: ${detailedErrorMessage}`,
)
this.logger.debug('Response error: %O', (error as AxiosError).response ?? error) this.logger.debug(`Response error: ${JSON.stringify(error)}`)
if ((error as AxiosError).response?.headers['content-type']) { if ((error as AxiosError).response?.headers['content-type']) {
response.setHeader('content-type', (error as AxiosError).response?.headers['content-type'] as string) response.setHeader('content-type', (error as AxiosError).response?.headers['content-type'] as string)
@@ -91,7 +94,14 @@ export abstract class AuthMiddleware extends BaseMiddleware {
? +((error as AxiosError).code as string) ? +((error as AxiosError).code as string)
: 500 : 500
response.status(errorCode).send(errorMessage) const responseErrorMessage = (error as AxiosError).response?.data
response
.status(errorCode)
.send(
responseErrorMessage ??
"Unfortunately, we couldn't handle your request. Please try again or contact our support if the error persists.",
)
return return
} }
@@ -0,0 +1,9 @@
import { BaseHttpController, all, controller, results } from 'inversify-express-utils'
@controller('')
export class FallbackController extends BaseHttpController {
@all('*')
public async fallback(): Promise<results.NotFoundResult> {
return this.notFound()
}
}
@@ -1,4 +1,5 @@
export * from './AuthMiddleware' export * from './AuthMiddleware'
export * from './FallbackController'
export * from './HealthCheckController' export * from './HealthCheckController'
export * from './SubscriptionTokenAuthMiddleware' export * from './SubscriptionTokenAuthMiddleware'
export * from './TokenAuthenticationMethod' export * from './TokenAuthenticationMethod'
@@ -23,7 +23,6 @@ export class UsersController extends BaseHttpController {
@inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface, @inject(TYPES.ApiGateway_ServiceProxy) private httpService: ServiceProxyInterface,
@inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface, @inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface,
@inject(TYPES.ApiGateway_Logger) private logger: Logger, @inject(TYPES.ApiGateway_Logger) private logger: Logger,
@inject(TYPES.ApiGateway_IS_CONFIGURED_FOR_HOME_SERVER) private isConfiguredForHomeServer: boolean,
) { ) {
super() super()
} }
@@ -238,10 +237,6 @@ export class UsersController extends BaseHttpController {
@httpDelete('/:userUuid', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware) @httpDelete('/:userUuid', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware)
async deleteUser(request: Request, response: Response): Promise<void> { async deleteUser(request: Request, response: Response): Promise<void> {
if (!this.isConfiguredForHomeServer) {
await this.httpService.callPaymentsServer(request, response, 'api/account', request.body, true)
}
await this.httpService.callAuthServer( await this.httpService.callAuthServer(
request, request,
response, response,
@@ -55,10 +55,9 @@ export class HttpServiceProxy implements ServiceProxyInterface {
}, },
} }
} catch (error) { } catch (error) {
const requestTimedOut = const requestDidNotMakeIt = this.requestTimedOutOrDidNotReachDestination(error as Record<string, unknown>)
'code' in (error as Record<string, unknown>) && (error as Record<string, unknown>).code === 'ETIMEDOUT'
const tooManyRetryAttempts = retryAttempt && retryAttempt > 2 const tooManyRetryAttempts = retryAttempt && retryAttempt > 2
if (!tooManyRetryAttempts && requestTimedOut) { if (!tooManyRetryAttempts && requestDidNotMakeIt) {
await this.timer.sleep(50) await this.timer.sleep(50)
const nextRetryAttempt = retryAttempt ? retryAttempt + 1 : 1 const nextRetryAttempt = retryAttempt ? retryAttempt + 1 : 1
@@ -144,7 +143,21 @@ export class HttpServiceProxy implements ServiceProxyInterface {
return return
} }
await this.callServer(this.webSocketServerUrl, request, response, endpointOrMethodIdentifier, payload) const isARequestComingFromApiGatewayAndShouldBeKeptInMinimalFormat = request.headers.connectionid !== undefined
this.logger.info(
`Calling websockets service: ${endpointOrMethodIdentifier}. Format is minimal: ${isARequestComingFromApiGatewayAndShouldBeKeptInMinimalFormat}`,
)
if (isARequestComingFromApiGatewayAndShouldBeKeptInMinimalFormat) {
await this.callServerWithLegacyFormat(
this.webSocketServerUrl,
request,
response,
endpointOrMethodIdentifier,
payload,
)
} else {
await this.callServer(this.webSocketServerUrl, request, response, endpointOrMethodIdentifier, payload)
}
} }
async callPaymentsServer( async callPaymentsServer(
@@ -152,7 +165,6 @@ export class HttpServiceProxy implements ServiceProxyInterface {
response: Response, response: Response,
endpointOrMethodIdentifier: string, endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string, payload?: Record<string, unknown> | string,
returnRawResponse?: boolean,
): Promise<void | Response<unknown, Record<string, unknown>>> { ): Promise<void | Response<unknown, Record<string, unknown>>> {
if (!this.paymentsServerUrl) { if (!this.paymentsServerUrl) {
this.logger.debug('Payments Server URL not defined. Skipped request to Payments API.') this.logger.debug('Payments Server URL not defined. Skipped request to Payments API.')
@@ -160,18 +172,13 @@ export class HttpServiceProxy implements ServiceProxyInterface {
return return
} }
const rawResponse = await this.callServerWithLegacyFormat( await this.callServerWithLegacyFormat(
this.paymentsServerUrl, this.paymentsServerUrl,
request, request,
response, response,
endpointOrMethodIdentifier, endpointOrMethodIdentifier,
payload, payload,
returnRawResponse,
) )
if (returnRawResponse) {
return rawResponse
}
} }
async callAuthServerWithLegacyFormat( async callAuthServerWithLegacyFormat(
@@ -261,14 +268,15 @@ export class HttpServiceProxy implements ServiceProxyInterface {
) )
} }
const errorMessage = (error as AxiosError).isAxiosError let detailedErrorMessage = (error as Error).message
? JSON.stringify((error as AxiosError).response?.data) if (error instanceof AxiosError) {
: (error as Error).message detailedErrorMessage = `Status: ${error.status}, code: ${error.code}, message: ${error.message}`
}
this.logger.error( this.logger.error(
tooManyRetryAttempts tooManyRetryAttempts
? `Request to ${serverUrl}/${endpointOrMethodIdentifier} timed out after ${retryAttempt} retries` ? `Request to ${serverUrl}/${endpointOrMethodIdentifier} timed out after ${retryAttempt} retries`
: `Could not pass the request to ${serverUrl}/${endpointOrMethodIdentifier} on underlying service: ${errorMessage}`, : `Could not pass the request to ${serverUrl}/${endpointOrMethodIdentifier} on underlying service: ${detailedErrorMessage}`,
) )
this.logger.debug(`Response error: ${JSON.stringify(error)}`) this.logger.debug(`Response error: ${JSON.stringify(error)}`)
@@ -282,7 +290,14 @@ export class HttpServiceProxy implements ServiceProxyInterface {
? +((error as AxiosError).code as string) ? +((error as AxiosError).code as string)
: 500 : 500
response.status(errorCode).send(errorMessage) const responseErrorMessage = (error as AxiosError).response?.data
response
.status(errorCode)
.send(
responseErrorMessage ??
"Unfortunately, we couldn't handle your request. Please try again or contact our support if the error persists.",
)
} }
return return
@@ -338,7 +353,6 @@ export class HttpServiceProxy implements ServiceProxyInterface {
response: Response, response: Response,
endpointOrMethodIdentifier: string, endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string, payload?: Record<string, unknown> | string,
returnRawResponse?: boolean,
): Promise<void | Response<unknown, Record<string, unknown>>> { ): Promise<void | Response<unknown, Record<string, unknown>>> {
const serviceResponse = await this.getServerResponse( const serviceResponse = await this.getServerResponse(
serverUrl, serverUrl,
@@ -357,18 +371,10 @@ export class HttpServiceProxy implements ServiceProxyInterface {
if (serviceResponse.request._redirectable._redirectCount > 0) { if (serviceResponse.request._redirectable._redirectCount > 0) {
response.status(302) response.status(302)
if (returnRawResponse) {
return response
}
response.redirect(serviceResponse.request.res.responseUrl) response.redirect(serviceResponse.request.res.responseUrl)
} else { } else {
response.status(serviceResponse.status) response.status(serviceResponse.status)
if (returnRawResponse) {
return response
}
response.send(serviceResponse.data) response.send(serviceResponse.data)
} }
} }
@@ -42,7 +42,6 @@ export interface ServiceProxyInterface {
response: Response, response: Response,
endpointOrMethodIdentifier: string, endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string, payload?: Record<string, unknown> | string,
returnRawResponse?: boolean,
): Promise<void | Response<unknown, Record<string, unknown>>> ): Promise<void | Response<unknown, Record<string, unknown>>>
callWebSocketServer( callWebSocketServer(
request: Request, request: Request,
@@ -50,7 +49,13 @@ export interface ServiceProxyInterface {
endpointOrMethodIdentifier: string, endpointOrMethodIdentifier: string,
payload?: Record<string, unknown> | string, payload?: Record<string, unknown> | string,
): Promise<void> ): Promise<void>
validateSession(headers: { authorization: string; sharedVaultOwnerContext?: string }): Promise<{ validateSession(
headers: {
authorization: string
sharedVaultOwnerContext?: string
},
retryAttempt?: number,
): Promise<{
status: number status: number
data: unknown data: unknown
headers: { headers: {
@@ -9,10 +9,13 @@ export class DirectCallServiceProxy implements ServiceProxyInterface {
private filesServerUrl: string, private filesServerUrl: string,
) {} ) {}
async validateSession(headers: { async validateSession(
authorization: string headers: {
sharedVaultOwnerContext?: string authorization: string
}): Promise<{ status: number; data: unknown; headers: { contentType: string } }> { sharedVaultOwnerContext?: string
},
_retryAttempt?: number,
): Promise<{ status: number; data: unknown; headers: { contentType: string } }> {
const authService = this.serviceContainer.get(ServiceIdentifier.create(ServiceIdentifier.NAMES.Auth).getValue()) const authService = this.serviceContainer.get(ServiceIdentifier.create(ServiceIdentifier.NAMES.Auth).getValue())
if (!authService) { if (!authService) {
throw new Error('Auth service not found') throw new Error('Auth service not found')
@@ -6,4 +6,4 @@ sh supervisor/wait-for.sh localhost $AUTH_SERVER_PORT
sh supervisor/wait-for.sh localhost $FILES_SERVER_PORT sh supervisor/wait-for.sh localhost $FILES_SERVER_PORT
sh supervisor/wait-for.sh localhost $REVISIONS_SERVER_PORT sh supervisor/wait-for.sh localhost $REVISIONS_SERVER_PORT
sh supervisor/wait-for.sh localhost $SYNCING_SERVER_PORT sh supervisor/wait-for.sh localhost $SYNCING_SERVER_PORT
node docker/entrypoint-server.js exec node docker/entrypoint-server.js
+88
View File
@@ -3,6 +3,94 @@
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.168.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.167.2...@standardnotes/auth-server@1.168.0) (2023-11-10)
### Features
* add graceful shutdown procedures upon SIGTERM ([#923](https://github.com/standardnotes/server/issues/923)) ([c24353c](https://github.com/standardnotes/server/commit/c24353cc24ebf4b40ff9a2cec8e37cfdef109e37))
## [1.167.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.167.1...@standardnotes/auth-server@1.167.2) (2023-11-08)
### Bug Fixes
* add logs about sending websocket events to clients ([9465f2e](https://github.com/standardnotes/server/commit/9465f2ecd8e8f0bf3ebeeb3976227b1b105aded0))
## [1.167.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.167.0...@standardnotes/auth-server@1.167.1) (2023-11-08)
### Bug Fixes
* **auth:** path to delete accounts script ([ca8a3fc](https://github.com/standardnotes/server/commit/ca8a3fc77d91410f0dee8c3ddef29c09947c9cf5))
# [1.167.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.166.0...@standardnotes/auth-server@1.167.0) (2023-11-08)
### Features
* script to mass delete accounts from CSV source ([#913](https://github.com/standardnotes/server/issues/913)) ([a6dea50](https://github.com/standardnotes/server/commit/a6dea50d745ff6f051fd9ede168aef27036159c3))
# [1.166.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.165.4...@standardnotes/auth-server@1.166.0) (2023-11-07)
### Features
* **auth:** add triggering post setting update actions ([#905](https://github.com/standardnotes/server/issues/905)) ([d228a86](https://github.com/standardnotes/server/commit/d228a86f48c9ff62b7810244c347abf7770e2b9f))
## [1.165.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.165.3...@standardnotes/auth-server@1.165.4) (2023-11-07)
### Bug Fixes
* account deletion event ([#904](https://github.com/standardnotes/server/issues/904)) ([d66ae62](https://github.com/standardnotes/server/commit/d66ae62cf4f413cac5f6f4eac45dc0f1ddbc9e32))
## [1.165.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.165.2...@standardnotes/auth-server@1.165.3) (2023-11-07)
### Bug Fixes
* remove open telemetry from code ([#903](https://github.com/standardnotes/server/issues/903)) ([751f3b2](https://github.com/standardnotes/server/commit/751f3b25476c5be3d663ad8540c43266acd39493))
## [1.165.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.165.1...@standardnotes/auth-server@1.165.2) (2023-11-03)
### Bug Fixes
* **auth:** change log severity on user authentication ([7f16232](https://github.com/standardnotes/server/commit/7f16232f8b13e3736801b6dc0af799e0559a3cfa))
## [1.165.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.165.0...@standardnotes/auth-server@1.165.1) (2023-11-03)
### Bug Fixes
* retry attempts on session validation and more verbose logs ([#898](https://github.com/standardnotes/server/issues/898)) ([3e376c4](https://github.com/standardnotes/server/commit/3e376c44e3a6c336dcff3d8ef5eb3ab040d9a561))
# [1.165.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.164.2...@standardnotes/auth-server@1.165.0) (2023-11-02)
### Features
* add shared vault invitation email notifications ([#897](https://github.com/standardnotes/server/issues/897)) ([7253a0a](https://github.com/standardnotes/server/commit/7253a0a1d92099df844c9baf6541b440bbcb0a68))
## [1.164.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.164.1...@standardnotes/auth-server@1.164.2) (2023-11-01)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.164.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.164.0...@standardnotes/auth-server@1.164.1) (2023-11-01)
### Bug Fixes
* **auth:** creating valet tokens for shared subscription users ([#895](https://github.com/standardnotes/server/issues/895)) ([b48eeb1](https://github.com/standardnotes/server/commit/b48eeb16c32031e73e9757e34c4b50ca0a3a773d))
# [1.164.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.163.2...@standardnotes/auth-server@1.164.0) (2023-11-01)
### Features
* **auth:** add sending email to old email address when the address is changed ([#894](https://github.com/standardnotes/server/issues/894)) ([eb8c704](https://github.com/standardnotes/server/commit/eb8c704d84277130dc0dc51c1fe475a7220612cd))
## [1.163.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.163.1...@standardnotes/auth-server@1.163.2) (2023-10-30)
### Bug Fixes
* **auth:** checking permissions to update setting only when directly performed by user ([#892](https://github.com/standardnotes/server/issues/892)) ([9bd4fb2](https://github.com/standardnotes/server/commit/9bd4fb2d794dae032286c68f23d3896b68735bdd))
## [1.163.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.163.0...@standardnotes/auth-server@1.163.1) (2023-10-30)
### Bug Fixes
* **auth:** add more information on the listed creation error ([78ff748](https://github.com/standardnotes/server/commit/78ff748d911a5a4063903847ef761822bbb8f4e2))
# [1.163.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.162.0...@standardnotes/auth-server@1.163.0) (2023-10-26) # [1.163.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.162.0...@standardnotes/auth-server@1.163.0) (2023-10-26)
### Features ### Features
+11 -95
View File
@@ -1,13 +1,5 @@
import 'reflect-metadata' import 'reflect-metadata'
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier, SettingName } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AuthScheduledTask })
sdk.start()
import { Stream } from 'stream'
import { Logger } from 'winston' import { Logger } from 'winston'
import * as dayjs from 'dayjs' import * as dayjs from 'dayjs'
import * as utc from 'dayjs/plugin/utc' import * as utc from 'dayjs/plugin/utc'
@@ -15,78 +7,13 @@ import * as utc from 'dayjs/plugin/utc'
import { ContainerConfigLoader } from '../src/Bootstrap/Container' import { ContainerConfigLoader } from '../src/Bootstrap/Container'
import TYPES from '../src/Bootstrap/Types' import TYPES from '../src/Bootstrap/Types'
import { Env } from '../src/Bootstrap/Env' import { Env } from '../src/Bootstrap/Env'
import { DomainEventPublisherInterface } from '@standardnotes/domain-events' import { TriggerEmailBackupForAllUsers } from '../src/Domain/UseCase/TriggerEmailBackupForAllUsers/TriggerEmailBackupForAllUsers'
import { DomainEventFactoryInterface } from '../src/Domain/Event/DomainEventFactoryInterface'
import { SettingRepositoryInterface } from '../src/Domain/Setting/SettingRepositoryInterface'
import { MuteFailedBackupsEmailsOption } from '@standardnotes/settings'
import { RoleServiceInterface } from '../src/Domain/Role/RoleServiceInterface'
import { PermissionName } from '@standardnotes/features'
import { GetUserKeyParams } from '../src/Domain/UseCase/GetUserKeyParams/GetUserKeyParams'
const inputArgs = process.argv.slice(2) const inputArgs = process.argv.slice(2)
const backupProvider = inputArgs[0] const backupFrequency = inputArgs[0]
const backupFrequency = inputArgs[1]
const requestBackups = async ( const requestBackups = async (triggerEmailBackupForAllUsers: TriggerEmailBackupForAllUsers): Promise<void> => {
settingRepository: SettingRepositoryInterface, await triggerEmailBackupForAllUsers.execute({ backupFrequency })
roleService: RoleServiceInterface,
domainEventFactory: DomainEventFactoryInterface,
domainEventPublisher: DomainEventPublisherInterface,
getUserKeyParamsUseCase: GetUserKeyParams,
): Promise<void> => {
const settingName = SettingName.create(SettingName.NAMES.EmailBackupFrequency).getValue()
const permissionName = PermissionName.DailyEmailBackup
const muteEmailsSettingName = SettingName.NAMES.MuteFailedBackupsEmails
const muteEmailsSettingValue = MuteFailedBackupsEmailsOption.Muted
const stream = await settingRepository.streamAllByNameAndValue(settingName, backupFrequency)
return new Promise((resolve, reject) => {
stream
.pipe(
new Stream.Transform({
objectMode: true,
transform: async (setting, _encoding, callback) => {
const userIsPermittedForEmailBackups = await roleService.userHasPermission(
setting.setting_user_uuid,
permissionName,
)
if (!userIsPermittedForEmailBackups) {
callback()
return
}
let userHasEmailsMuted = false
const emailsMutedSetting = await settingRepository.findOneByNameAndUserUuid(
muteEmailsSettingName,
setting.setting_user_uuid,
)
if (emailsMutedSetting !== null && emailsMutedSetting.props.value !== null) {
userHasEmailsMuted = emailsMutedSetting.props.value === muteEmailsSettingValue
}
const keyParamsResponse = await getUserKeyParamsUseCase.execute({
userUuid: setting.setting_user_uuid,
authenticated: false,
})
await domainEventPublisher.publish(
domainEventFactory.createEmailBackupRequestedEvent(
setting.setting_user_uuid,
emailsMutedSetting?.id.toString() as string,
userHasEmailsMuted,
keyParamsResponse.keyParams,
),
)
callback()
},
}),
)
.on('finish', resolve)
.on('error', reject)
})
} }
const container = new ContainerConfigLoader('worker') const container = new ContainerConfigLoader('worker')
@@ -98,31 +25,20 @@ void container.load().then((container) => {
const logger: Logger = container.get(TYPES.Auth_Logger) const logger: Logger = container.get(TYPES.Auth_Logger)
logger.info(`Starting ${backupFrequency} ${backupProvider} backup requesting...`) logger.info(`Starting ${backupFrequency} email backup requesting...`)
const settingRepository: SettingRepositoryInterface = container.get(TYPES.Auth_SettingRepository) const triggerEmailBackupForAllUsers: TriggerEmailBackupForAllUsers = container.get(
const roleService: RoleServiceInterface = container.get(TYPES.Auth_RoleService) TYPES.Auth_TriggerEmailBackupForAllUsers,
const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.Auth_DomainEventFactory)
const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.Auth_DomainEventPublisher)
const getUserKeyParamsUseCase: GetUserKeyParams = container.get(TYPES.Auth_GetUserKeyParams)
const tracer = new OpenTelemetryTracer()
tracer.startSpan(ServiceIdentifier.NAMES.AuthScheduledTask, 'backup')
Promise.resolve(
requestBackups(settingRepository, roleService, domainEventFactory, domainEventPublisher, getUserKeyParamsUseCase),
) )
.then(() => {
logger.info(`${backupFrequency} ${backupProvider} backup requesting complete`)
tracer.stopSpan() Promise.resolve(requestBackups(triggerEmailBackupForAllUsers))
.then(() => {
logger.info(`${backupFrequency} email backup requesting complete`)
process.exit(0) process.exit(0)
}) })
.catch((error) => { .catch((error) => {
logger.error(`Could not finish ${backupFrequency} ${backupProvider} backup requesting: ${error.message}`) logger.error(`Could not finish ${backupFrequency} email backup requesting: ${error.message}`)
tracer.stopSpanWithError(error)
process.exit(1) process.exit(1)
}) })
-13
View File
@@ -1,11 +1,5 @@
import 'reflect-metadata' import 'reflect-metadata'
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AuthScheduledTask })
sdk.start()
import { Logger } from 'winston' import { Logger } from 'winston'
import { ContainerConfigLoader } from '../src/Bootstrap/Container' import { ContainerConfigLoader } from '../src/Bootstrap/Container'
@@ -36,22 +30,15 @@ void container.load().then((container) => {
const cleanupSessionTraces: CleanupSessionTraces = container.get(TYPES.Auth_CleanupSessionTraces) const cleanupSessionTraces: CleanupSessionTraces = container.get(TYPES.Auth_CleanupSessionTraces)
const cleanupExpiredSessions: CleanupExpiredSessions = container.get(TYPES.Auth_CleanupExpiredSessions) const cleanupExpiredSessions: CleanupExpiredSessions = container.get(TYPES.Auth_CleanupExpiredSessions)
const tracer = new OpenTelemetryTracer()
tracer.startSpan(ServiceIdentifier.NAMES.AuthScheduledTask, 'cleanup')
Promise.resolve(cleanup(cleanupSessionTraces, cleanupExpiredSessions)) Promise.resolve(cleanup(cleanupSessionTraces, cleanupExpiredSessions))
.then(() => { .then(() => {
logger.info('Expired sessions and session traces cleaned.') logger.info('Expired sessions and session traces cleaned.')
tracer.stopSpan()
process.exit(0) process.exit(0)
}) })
.catch((error) => { .catch((error) => {
logger.error(`Could not clean sessions and session traces: ${error.message}`) logger.error(`Could not clean sessions and session traces: ${error.message}`)
tracer.stopSpanWithError(error)
process.exit(1) process.exit(1)
}) })
}) })
+43
View File
@@ -0,0 +1,43 @@
import 'reflect-metadata'
import { Logger } from 'winston'
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
import TYPES from '../src/Bootstrap/Types'
import { Env } from '../src/Bootstrap/Env'
import { DeleteAccountsFromCSVFile } from '../src/Domain/UseCase/DeleteAccountsFromCSVFile/DeleteAccountsFromCSVFile'
const inputArgs = process.argv.slice(2)
const fileName = inputArgs[0]
const mode = inputArgs[1]
const deleteAccounts = async (deleteAccountsFromCSVFile: DeleteAccountsFromCSVFile): Promise<void> => {
await deleteAccountsFromCSVFile.execute({
fileName,
dryRun: mode !== 'delete',
})
}
const container = new ContainerConfigLoader('worker')
void container.load().then((container) => {
const env: Env = new Env()
env.load()
const logger: Logger = container.get(TYPES.Auth_Logger)
logger.info('Starting mass accounts deletion from CSV file')
const deleteAccountsFromCSVFile = container.get<DeleteAccountsFromCSVFile>(TYPES.Auth_DeleteAccountsFromCSVFile)
Promise.resolve(deleteAccounts(deleteAccountsFromCSVFile))
.then(() => {
logger.info('Accounts deleted.')
process.exit(0)
})
.catch((error) => {
logger.error(`Could not delete accounts: ${error.message}`)
process.exit(1)
})
})
+7 -8
View File
@@ -1,11 +1,5 @@
import 'reflect-metadata' import 'reflect-metadata'
import { OpenTelemetrySDK } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.Auth })
sdk.start()
import '../src/Infra/InversifyExpressUtils/AnnotatedAuthController' import '../src/Infra/InversifyExpressUtils/AnnotatedAuthController'
import '../src/Infra/InversifyExpressUtils/AnnotatedAuthenticatorsController' import '../src/Infra/InversifyExpressUtils/AnnotatedAuthenticatorsController'
import '../src/Infra/InversifyExpressUtils/AnnotatedSessionsController' import '../src/Infra/InversifyExpressUtils/AnnotatedSessionsController'
@@ -70,9 +64,14 @@ void container.load().then((container) => {
}) })
}) })
const serverInstance = server.build() const serverInstance = server.build().listen(env.get('PORT'))
serverInstance.listen(env.get('PORT')) process.on('SIGTERM', () => {
logger.info('SIGTERM signal received: closing HTTP server')
serverInstance.close(() => {
logger.info('HTTP server closed')
})
})
logger.info(`Server started on port ${process.env.PORT}`) logger.info(`Server started on port ${process.env.PORT}`)
}) })
-13
View File
@@ -1,11 +1,5 @@
import 'reflect-metadata' import 'reflect-metadata'
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AuthScheduledTask })
sdk.start()
import { Logger } from 'winston' import { Logger } from 'winston'
import { TimerInterface } from '@standardnotes/time' import { TimerInterface } from '@standardnotes/time'
@@ -26,9 +20,6 @@ void container.load().then((container) => {
const persistStats: PersistStatistics = container.get(TYPES.Auth_PersistStatistics) const persistStats: PersistStatistics = container.get(TYPES.Auth_PersistStatistics)
const timer: TimerInterface = container.get(TYPES.Auth_Timer) const timer: TimerInterface = container.get(TYPES.Auth_Timer)
const tracer = new OpenTelemetryTracer()
tracer.startSpan(ServiceIdentifier.NAMES.AuthScheduledTask, 'stats')
Promise.resolve( Promise.resolve(
persistStats.execute({ persistStats.execute({
sessionsInADay: timer.getUTCDateNDaysAgo(1), sessionsInADay: timer.getUTCDateNDaysAgo(1),
@@ -37,15 +28,11 @@ void container.load().then((container) => {
.then(() => { .then(() => {
logger.info('Stats persisted.') logger.info('Stats persisted.')
tracer.stopSpan()
process.exit(0) process.exit(0)
}) })
.catch((error) => { .catch((error) => {
logger.error(`Could not persist stats: ${error.message}`) logger.error(`Could not persist stats: ${error.message}`)
tracer.stopSpanWithError(error)
process.exit(1) process.exit(1)
}) })
}) })
+1 -13
View File
@@ -1,11 +1,5 @@
import 'reflect-metadata' import 'reflect-metadata'
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
import { Email, ServiceIdentifier, SettingName } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AuthScheduledTask })
sdk.start()
import { Logger } from 'winston' import { Logger } from 'winston'
import * as dayjs from 'dayjs' import * as dayjs from 'dayjs'
import * as utc from 'dayjs/plugin/utc' import * as utc from 'dayjs/plugin/utc'
@@ -21,6 +15,7 @@ import { RoleServiceInterface } from '../src/Domain/Role/RoleServiceInterface'
import { PermissionName } from '@standardnotes/features' import { PermissionName } from '@standardnotes/features'
import { UserRepositoryInterface } from '../src/Domain/User/UserRepositoryInterface' import { UserRepositoryInterface } from '../src/Domain/User/UserRepositoryInterface'
import { GetUserKeyParams } from '../src/Domain/UseCase/GetUserKeyParams/GetUserKeyParams' import { GetUserKeyParams } from '../src/Domain/UseCase/GetUserKeyParams/GetUserKeyParams'
import { Email, SettingName } from '@standardnotes/domain-core'
const inputArgs = process.argv.slice(2) const inputArgs = process.argv.slice(2)
const backupEmail = inputArgs[0] const backupEmail = inputArgs[0]
@@ -94,9 +89,6 @@ void container.load().then((container) => {
const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.Auth_DomainEventPublisher) const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.Auth_DomainEventPublisher)
const getUserKeyParamsUseCase: GetUserKeyParams = container.get(TYPES.Auth_GetUserKeyParams) const getUserKeyParamsUseCase: GetUserKeyParams = container.get(TYPES.Auth_GetUserKeyParams)
const tracer = new OpenTelemetryTracer()
tracer.startSpan(ServiceIdentifier.NAMES.AuthScheduledTask, 'user_email_backup')
Promise.resolve( Promise.resolve(
requestBackups( requestBackups(
userRepository, userRepository,
@@ -110,15 +102,11 @@ void container.load().then((container) => {
.then(() => { .then(() => {
logger.info(`Email backup requesting complete for ${backupEmail}`) logger.info(`Email backup requesting complete for ${backupEmail}`)
tracer.stopSpan()
process.exit(0) process.exit(0)
}) })
.catch((error) => { .catch((error) => {
logger.error(`Could not finish email backup requesting for ${backupEmail}: ${error.message}`) logger.error(`Could not finish email backup requesting for ${backupEmail}: ${error.message}`)
tracer.stopSpanWithError(error)
process.exit(1) process.exit(1)
}) })
}) })
+6 -6
View File
@@ -1,11 +1,5 @@
import 'reflect-metadata' import 'reflect-metadata'
import { OpenTelemetrySDK } from '@standardnotes/domain-events-infra'
import { ServiceIdentifier } from '@standardnotes/domain-core'
const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.AuthWorker })
sdk.start()
import { Logger } from 'winston' import { Logger } from 'winston'
import { ContainerConfigLoader } from '../src/Bootstrap/Container' import { ContainerConfigLoader } from '../src/Bootstrap/Container'
@@ -28,5 +22,11 @@ void container.load().then((container) => {
const subscriber = container.get<DomainEventSubscriberInterface>(TYPES.Auth_DomainEventSubscriber) const subscriber = container.get<DomainEventSubscriberInterface>(TYPES.Auth_DomainEventSubscriber)
process.on('SIGTERM', () => {
logger.info('SIGTERM received. Stopping worker...')
subscriber.stop()
logger.info('Worker stopped.')
})
subscriber.start() subscriber.start()
}) })

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