Compare commits

..

8 Commits

Author SHA1 Message Date
standardci
5cf84e31b0 chore(release): publish new version
- @standardnotes/analytics@2.26.18
 - @standardnotes/api-gateway@1.74.16
 - @standardnotes/auth-server@1.143.8
 - @standardnotes/domain-core@1.31.0
 - @standardnotes/event-store@1.11.46
 - @standardnotes/files-server@1.22.25
 - @standardnotes/home-server@1.15.69
 - @standardnotes/revisions-server@1.35.8
 - @standardnotes/scheduler-server@1.20.50
 - @standardnotes/settings@1.21.35
 - @standardnotes/syncing-server@1.99.0
 - @standardnotes/websockets-server@1.10.47
2023-09-20 09:04:29 +00:00
Karol Sójko
31e7aaf253 feat(syncing-server): add notification for user upon declined shared vault invitation (#837) 2023-09-20 10:47:19 +02:00
standardci
8ec3d37c18 chore(release): publish new version
- @standardnotes/analytics@2.26.17
 - @standardnotes/api-gateway@1.74.15
 - @standardnotes/auth-server@1.143.7
 - @standardnotes/domain-core@1.30.1
 - @standardnotes/event-store@1.11.45
 - @standardnotes/files-server@1.22.24
 - @standardnotes/home-server@1.15.68
 - @standardnotes/revisions-server@1.35.7
 - @standardnotes/scheduler-server@1.20.49
 - @standardnotes/settings@1.21.34
 - @standardnotes/syncing-server@1.98.6
 - @standardnotes/websockets-server@1.10.46
2023-09-19 13:25:30 +00:00
Karol Sójko
857c6af946 fix: skip removing already existing content in secondary to pick up where the transition left of 2023-09-19 14:55:40 +02:00
Karol Sójko
de081fe786 fix(domain-core): allow any version and variant of the UUID format 2023-09-19 14:42:19 +02:00
standardci
0aeeb2d1cf chore(release): publish new version
- @standardnotes/home-server@1.15.67
 - @standardnotes/revisions-server@1.35.6
 - @standardnotes/syncing-server@1.98.5
2023-09-19 11:23:30 +00:00
Karol Sójko
e589029722 fix: logs verbosity during transitions 2023-09-19 13:04:43 +02:00
Karol Sójko
b265a39b63 fix: increase timeout for secondary database to catch up for indexes to be rebuilt 2023-09-19 13:04:43 +02:00
32 changed files with 297 additions and 76 deletions

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.26.18](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.17...@standardnotes/analytics@2.26.18) (2023-09-20)
**Note:** Version bump only for package @standardnotes/analytics
## [2.26.17](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.16...@standardnotes/analytics@2.26.17) (2023-09-19)
**Note:** Version bump only for package @standardnotes/analytics
## [2.26.16](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.15...@standardnotes/analytics@2.26.16) (2023-09-18)
**Note:** Version bump only for package @standardnotes/analytics

View File

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

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.74.16](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.74.15...@standardnotes/api-gateway@1.74.16) (2023-09-20)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.74.15](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.74.14...@standardnotes/api-gateway@1.74.15) (2023-09-19)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.74.14](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.74.13...@standardnotes/api-gateway@1.74.14) (2023-09-18)
**Note:** Version bump only for package @standardnotes/api-gateway

View File

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

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.143.8](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.143.7...@standardnotes/auth-server@1.143.8) (2023-09-20)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.143.7](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.143.6...@standardnotes/auth-server@1.143.7) (2023-09-19)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.143.6](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.143.4...@standardnotes/auth-server@1.143.6) (2023-09-19)
### Bug Fixes

View File

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

View File

@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.31.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.30.1...@standardnotes/domain-core@1.31.0) (2023-09-20)
### Features
* **syncing-server:** add notification for user upon declined shared vault invitation ([#837](https://github.com/standardnotes/server/issues/837)) ([31e7aaf](https://github.com/standardnotes/server/commit/31e7aaf253029a951d8b943d6cffd655cd5ca765))
## [1.30.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.30.0...@standardnotes/domain-core@1.30.1) (2023-09-19)
### Bug Fixes
* **domain-core:** allow any version and variant of the UUID format ([de081fe](https://github.com/standardnotes/server/commit/de081fe78658bdd36c8c5d86b70a16a2880aa3d1))
# [1.30.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.29.0...@standardnotes/domain-core@1.30.0) (2023-09-18)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/domain-core",
"version": "1.30.0",
"version": "1.31.0",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -5,6 +5,7 @@ describe('Validator', () => {
'2221101c-1da9-4d2b-9b32-b8be2a8d1c82',
'c08f2f29-a74b-42b4-aefd-98af9832391c',
'b453fa64-1493-443b-b5bb-bca7b9c696c7',
'fa7350b3-77cf-8c0c-40b2-6046b13254fe',
]
const invalidUuids = [

View File

@@ -1,12 +1,13 @@
import { Result } from './Result'
export class Validator {
private static readonly UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i
private static readonly UUID_ANY_VERSION_AND_VARIANT_REGEX =
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
private static readonly EMAIL_REGEX =
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
static isValidUuid(value: string): Result<string> {
const matchesUuidRegex = String(value).toLowerCase().match(Validator.UUID_REGEX) !== null
const matchesUuidRegex = String(value).toLowerCase().match(Validator.UUID_ANY_VERSION_AND_VARIANT_REGEX) !== null
if (matchesUuidRegex) {
return Result.ok()
}

View File

@@ -7,6 +7,7 @@ export class NotificationType extends ValueObject<NotificationTypeProps> {
SharedVaultItemRemoved: 'shared_vault_item_removed',
RemovedFromSharedVault: 'removed_from_shared_vault',
UserAddedToSharedVault: 'user_added_to_shared_vault',
SharedVaultInviteDeclined: 'shared_vault_invite_declined',
SharedVaultFileUploaded: 'shared_vault_file_uploaded',
SharedVaultFileRemoved: 'shared_vault_file_removed',
}

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.11.46](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.11.45...@standardnotes/event-store@1.11.46) (2023-09-20)
**Note:** Version bump only for package @standardnotes/event-store
## [1.11.45](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.11.44...@standardnotes/event-store@1.11.45) (2023-09-19)
**Note:** Version bump only for package @standardnotes/event-store
## [1.11.44](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.11.43...@standardnotes/event-store@1.11.44) (2023-09-18)
**Note:** Version bump only for package @standardnotes/event-store

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/event-store",
"version": "1.11.44",
"version": "1.11.46",
"description": "Event Store Service",
"private": true,
"main": "dist/src/index.js",

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.22.25](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.22.24...@standardnotes/files-server@1.22.25) (2023-09-20)
**Note:** Version bump only for package @standardnotes/files-server
## [1.22.24](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.22.23...@standardnotes/files-server@1.22.24) (2023-09-19)
**Note:** Version bump only for package @standardnotes/files-server
## [1.22.23](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.22.22...@standardnotes/files-server@1.22.23) (2023-09-18)
**Note:** Version bump only for package @standardnotes/files-server

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/files-server",
"version": "1.22.23",
"version": "1.22.25",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.15.69](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.15.68...@standardnotes/home-server@1.15.69) (2023-09-20)
**Note:** Version bump only for package @standardnotes/home-server
## [1.15.68](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.15.67...@standardnotes/home-server@1.15.68) (2023-09-19)
**Note:** Version bump only for package @standardnotes/home-server
## [1.15.67](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.15.66...@standardnotes/home-server@1.15.67) (2023-09-19)
**Note:** Version bump only for package @standardnotes/home-server
## [1.15.66](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.15.65...@standardnotes/home-server@1.15.66) (2023-09-19)
**Note:** Version bump only for package @standardnotes/home-server

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/home-server",
"version": "1.15.66",
"version": "1.15.69",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -3,6 +3,23 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.35.8](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.35.7...@standardnotes/revisions-server@1.35.8) (2023-09-20)
**Note:** Version bump only for package @standardnotes/revisions-server
## [1.35.7](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.35.6...@standardnotes/revisions-server@1.35.7) (2023-09-19)
### Bug Fixes
* skip removing already existing content in secondary to pick up where the transition left of ([857c6af](https://github.com/standardnotes/server/commit/857c6af9468ec829ff4dce9a96ba7bf9c14d55a5))
## [1.35.6](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.35.5...@standardnotes/revisions-server@1.35.6) (2023-09-19)
### Bug Fixes
* increase timeout for secondary database to catch up for indexes to be rebuilt ([b265a39](https://github.com/standardnotes/server/commit/b265a39b635373c36ee8c3d8e09f0631159b3574))
* logs verbosity during transitions ([e589029](https://github.com/standardnotes/server/commit/e589029722ab9f4debc8aa6cc78913f877eda2e3))
## [1.35.5](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.35.4...@standardnotes/revisions-server@1.35.5) (2023-09-19)
### Bug Fixes

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/revisions-server",
"version": "1.35.5",
"version": "1.35.8",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -31,19 +31,16 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
let newRevisionsInSecondaryCount = 0
let updatedRevisionsInSecondary: string[] = []
let alreadyIdenticalInSecondaryAndPrimary: string[] = []
if (await this.hasAlreadyDataInSecondaryDatabase(userUuid)) {
const { alreadyExistingInPrimary, newRevisionsInSecondary, updatedInSecondary } =
const { alreadyExistingInSecondaryAndPrimary, newRevisionsInSecondary, updatedInSecondary } =
await this.getNewRevisionsCreatedInSecondaryDatabase(userUuid)
this.logger.info(
`[${dto.userUuid}] Removing ${alreadyExistingInPrimary.length} already existing revisions from secondary database`,
`[${dto.userUuid}] ${alreadyExistingInSecondaryAndPrimary.length} already existing identical revisions in primary and secondary.`,
)
for (const existingRevisionUuid of alreadyExistingInPrimary) {
await (this.secondRevisionsRepository as RevisionRepositoryInterface).removeOneByUuid(
Uuid.create(existingRevisionUuid).getValue(),
userUuid,
)
}
alreadyIdenticalInSecondaryAndPrimary = alreadyExistingInSecondaryAndPrimary
if (newRevisionsInSecondary.length > 0) {
this.logger.info(
@@ -66,9 +63,13 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
const migrationTimeStart = this.timer.getTimestampInMicroseconds()
this.logger.debug(`[${dto.userUuid}] Transitioning revisions`)
this.logger.info(`[${dto.userUuid}] Migrating revisions`)
const migrationResult = await this.migrateRevisionsForUser(userUuid, updatedRevisionsInSecondary)
const migrationResult = await this.migrateRevisionsForUser(
userUuid,
updatedRevisionsInSecondary,
alreadyIdenticalInSecondaryAndPrimary,
)
if (migrationResult.isFailed()) {
if (newRevisionsInSecondaryCount === 0 && updatedRevisionsInSecondaryCount === 0) {
const cleanupResult = await this.deleteRevisionsForUser(userUuid, this.secondRevisionsRepository)
@@ -88,6 +89,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
userUuid,
newRevisionsInSecondaryCount,
updatedRevisionsInSecondary,
alreadyIdenticalInSecondaryAndPrimary,
)
if (integrityCheckResult.isFailed()) {
if (newRevisionsInSecondaryCount === 0 && updatedRevisionsInSecondaryCount === 0) {
@@ -119,10 +121,13 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
return Result.ok()
}
private async migrateRevisionsForUser(userUuid: Uuid, updatedRevisionsInSecondary: string[]): Promise<Result<void>> {
private async migrateRevisionsForUser(
userUuid: Uuid,
updatedRevisionsInSecondary: string[],
alreadyExistingInSecondaryAndPrimary: string[],
): Promise<Result<void>> {
try {
const totalRevisionsCountForUser = await this.primaryRevisionsRepository.countByUserUuid(userUuid)
let totalRevisionsCountTransitionedToSecondary = 0
const totalPages = Math.ceil(totalRevisionsCountForUser / this.pageSize)
for (let currentPage = 1; currentPage <= totalPages; currentPage++) {
const query = {
@@ -147,17 +152,18 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
continue
}
this.logger.debug(
`[${userUuid.value}]Transitioning revision #${
totalRevisionsCountTransitionedToSecondary + 1
}: ${revision.id.toString()} to secondary database`,
)
if (
alreadyExistingInSecondaryAndPrimary.find(
(alreadyExistingRevisionUuid) => alreadyExistingRevisionUuid === revision.id.toString(),
)
) {
continue
}
const didSave = await (this.secondRevisionsRepository as RevisionRepositoryInterface).insert(revision)
if (!didSave) {
return Result.fail(`Failed to save revision ${revision.id.toString()} to secondary database`)
}
totalRevisionsCountTransitionedToSecondary++
} catch (error) {
return Result.fail(
`Errored when saving revision ${revision.id.toString()} to secondary database: ${
@@ -168,10 +174,6 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
}
}
this.logger.debug(
`[${userUuid.value}] Transitioned ${totalRevisionsCountTransitionedToSecondary} revisions to secondary database`,
)
return Result.ok()
} catch (error) {
return Result.fail(`Errored when migrating revisions for user ${userUuid.value}: ${(error as Error).message}`)
@@ -192,8 +194,8 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
}
private async allowForSecondaryDatabaseToCatchUp(): Promise<void> {
const twoSecondsInMilliseconds = 2_000
await this.timer.sleep(twoSecondsInMilliseconds)
const tenSecondsInMillisecondsToRebuildIndexes = 10_000
await this.timer.sleep(tenSecondsInMillisecondsToRebuildIndexes)
}
private async hasAlreadyDataInSecondaryDatabase(userUuid: Uuid): Promise<boolean> {
@@ -212,7 +214,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
}
private async getNewRevisionsCreatedInSecondaryDatabase(userUuid: Uuid): Promise<{
alreadyExistingInPrimary: string[]
alreadyExistingInSecondaryAndPrimary: string[]
newRevisionsInSecondary: string[]
updatedInSecondary: string[]
}> {
@@ -223,7 +225,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
).countByUserUuid(userUuid)
const totalPages = Math.ceil(totalRevisionsCountForUser / this.pageSize)
const alreadyExistingInPrimary: string[] = []
const alreadyExistingInSecondaryAndPrimary: string[] = []
const newRevisionsInSecondary: string[] = []
const updatedInSecondary: string[] = []
@@ -236,17 +238,17 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
const revisions = await (this.secondRevisionsRepository as RevisionRepositoryInterface).findByUserUuid(query)
for (const revision of revisions) {
const { revisionInPrimary, newerRevisionInSecondary } =
const { identicalRevisionInPrimary, newerRevisionInSecondary } =
await this.checkIfRevisionExistsInPrimaryDatabase(revision)
if (revisionInPrimary !== null) {
alreadyExistingInPrimary.push(revision.id.toString())
if (identicalRevisionInPrimary !== null) {
alreadyExistingInSecondaryAndPrimary.push(revision.id.toString())
continue
}
if (newerRevisionInSecondary !== null) {
updatedInSecondary.push(newerRevisionInSecondary.id.toString())
continue
}
if (revisionInPrimary === null && newerRevisionInSecondary === null) {
if (identicalRevisionInPrimary === null && newerRevisionInSecondary === null) {
newRevisionsInSecondary.push(revision.id.toString())
continue
}
@@ -254,7 +256,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
}
return {
alreadyExistingInPrimary,
alreadyExistingInSecondaryAndPrimary,
newRevisionsInSecondary,
updatedInSecondary,
}
@@ -262,7 +264,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
private async checkIfRevisionExistsInPrimaryDatabase(
revision: Revision,
): Promise<{ revisionInPrimary: Revision | null; newerRevisionInSecondary: Revision | null }> {
): Promise<{ identicalRevisionInPrimary: Revision | null; newerRevisionInSecondary: Revision | null }> {
const revisionInPrimary = await this.primaryRevisionsRepository.findOneByUuid(
Uuid.create(revision.id.toString()).getValue(),
revision.props.userUuid as Uuid,
@@ -271,7 +273,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
if (revisionInPrimary === null) {
return {
revisionInPrimary: null,
identicalRevisionInPrimary: null,
newerRevisionInSecondary: null,
}
}
@@ -285,14 +287,14 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
)
return {
revisionInPrimary: null,
identicalRevisionInPrimary: null,
newerRevisionInSecondary:
revision.props.dates.updatedAt > revisionInPrimary.props.dates.updatedAt ? revision : null,
}
}
return {
revisionInPrimary: revisionInPrimary,
identicalRevisionInPrimary: revisionInPrimary,
newerRevisionInSecondary: null,
}
}
@@ -301,6 +303,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
userUuid: Uuid,
newRevisionsInSecondaryCount: number,
updatedRevisionsInSecondary: string[],
alreadyExistingInSecondaryAndPrimary: string[],
): Promise<Result<boolean>> {
try {
const totalRevisionsCountForUserInPrimary = await this.primaryRevisionsRepository.countByUserUuid(userUuid)
@@ -341,6 +344,14 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
continue
}
if (
alreadyExistingInSecondaryAndPrimary.find(
(alreadyExistingRevisionUuid) => alreadyExistingRevisionUuid === revision.id.toString(),
)
) {
continue
}
if (!revision.isIdenticalTo(revisionInSecondary)) {
return Result.fail(
`Revision ${revision.id.toString()} is not identical in primary and secondary database. Revision in primary database: ${JSON.stringify(

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.20.50](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.20.49...@standardnotes/scheduler-server@1.20.50) (2023-09-20)
**Note:** Version bump only for package @standardnotes/scheduler-server
## [1.20.49](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.20.48...@standardnotes/scheduler-server@1.20.49) (2023-09-19)
**Note:** Version bump only for package @standardnotes/scheduler-server
## [1.20.48](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.20.47...@standardnotes/scheduler-server@1.20.48) (2023-09-18)
**Note:** Version bump only for package @standardnotes/scheduler-server

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/scheduler-server",
"version": "1.20.48",
"version": "1.20.50",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.21.35](https://github.com/standardnotes/server/compare/@standardnotes/settings@1.21.34...@standardnotes/settings@1.21.35) (2023-09-20)
**Note:** Version bump only for package @standardnotes/settings
## [1.21.34](https://github.com/standardnotes/server/compare/@standardnotes/settings@1.21.33...@standardnotes/settings@1.21.34) (2023-09-19)
**Note:** Version bump only for package @standardnotes/settings
## [1.21.33](https://github.com/standardnotes/server/compare/@standardnotes/settings@1.21.32...@standardnotes/settings@1.21.33) (2023-09-18)
**Note:** Version bump only for package @standardnotes/settings

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/settings",
"version": "1.21.33",
"version": "1.21.35",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -3,6 +3,25 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.99.0](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.98.6...@standardnotes/syncing-server@1.99.0) (2023-09-20)
### Features
* **syncing-server:** add notification for user upon declined shared vault invitation ([#837](https://github.com/standardnotes/syncing-server-js/issues/837)) ([31e7aaf](https://github.com/standardnotes/syncing-server-js/commit/31e7aaf253029a951d8b943d6cffd655cd5ca765))
## [1.98.6](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.98.5...@standardnotes/syncing-server@1.98.6) (2023-09-19)
### Bug Fixes
* skip removing already existing content in secondary to pick up where the transition left of ([857c6af](https://github.com/standardnotes/syncing-server-js/commit/857c6af9468ec829ff4dce9a96ba7bf9c14d55a5))
## [1.98.5](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.98.4...@standardnotes/syncing-server@1.98.5) (2023-09-19)
### Bug Fixes
* increase timeout for secondary database to catch up for indexes to be rebuilt ([b265a39](https://github.com/standardnotes/syncing-server-js/commit/b265a39b635373c36ee8c3d8e09f0631159b3574))
* logs verbosity during transitions ([e589029](https://github.com/standardnotes/syncing-server-js/commit/e589029722ab9f4debc8aa6cc78913f877eda2e3))
## [1.98.4](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.98.3...@standardnotes/syncing-server@1.98.4) (2023-09-19)
### Bug Fixes

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/syncing-server",
"version": "1.98.4",
"version": "1.99.0",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -723,7 +723,12 @@ export class ContainerConfigLoader {
)
container
.bind<DeclineInviteToSharedVault>(TYPES.Sync_DeclineInviteToSharedVault)
.toConstantValue(new DeclineInviteToSharedVault(container.get(TYPES.Sync_SharedVaultInviteRepository)))
.toConstantValue(
new DeclineInviteToSharedVault(
container.get<SharedVaultInviteRepositoryInterface>(TYPES.Sync_SharedVaultInviteRepository),
container.get<AddNotificationForUser>(TYPES.Sync_AddNotificationForUser),
),
)
container
.bind<DeleteSharedVaultInvitesToUser>(TYPES.Sync_DeleteSharedVaultInvitesToUser)
.toConstantValue(

View File

@@ -1,13 +1,15 @@
import { SharedVaultUserPermission, Timestamps, Uuid } from '@standardnotes/domain-core'
import { NotificationPayload, Result, SharedVaultUserPermission, Timestamps, Uuid } from '@standardnotes/domain-core'
import { SharedVaultInviteRepositoryInterface } from '../../../SharedVault/User/Invite/SharedVaultInviteRepositoryInterface'
import { DeclineInviteToSharedVault } from './DeclineInviteToSharedVault'
import { SharedVaultInvite } from '../../../SharedVault/User/Invite/SharedVaultInvite'
import { AddNotificationForUser } from '../../Messaging/AddNotificationForUser/AddNotificationForUser'
describe('DeclineInviteToSharedVault', () => {
let sharedVaultInviteRepository: SharedVaultInviteRepositoryInterface
let invite: SharedVaultInvite
let addNotificationForUser: AddNotificationForUser
const createUseCase = () => new DeclineInviteToSharedVault(sharedVaultInviteRepository)
const createUseCase = () => new DeclineInviteToSharedVault(sharedVaultInviteRepository, addNotificationForUser)
beforeEach(() => {
invite = SharedVaultInvite.create({
@@ -22,6 +24,9 @@ describe('DeclineInviteToSharedVault', () => {
sharedVaultInviteRepository = {} as jest.Mocked<SharedVaultInviteRepositoryInterface>
sharedVaultInviteRepository.findByUuid = jest.fn().mockResolvedValue(invite)
sharedVaultInviteRepository.remove = jest.fn()
addNotificationForUser = {} as jest.Mocked<AddNotificationForUser>
addNotificationForUser.execute = jest.fn().mockReturnValue(Result.ok())
})
it('should fail if invite uuid is invalid', async () => {
@@ -36,6 +41,37 @@ describe('DeclineInviteToSharedVault', () => {
expect(result.getError()).toBe('Given value is not a valid uuid: invalid')
})
it('should fail if adding a notification for user fails', async () => {
addNotificationForUser.execute = jest.fn().mockReturnValue(Result.fail('Error'))
const useCase = createUseCase()
const result = await useCase.execute({
inviteUuid: '00000000-0000-0000-0000-000000000000',
userUuid: '00000000-0000-0000-0000-000000000000',
})
expect(result.isFailed()).toBe(true)
expect(result.getError()).toBe('Error')
})
it('should return error if notification payload could not be created', async () => {
const mock = jest.spyOn(NotificationPayload, 'create')
mock.mockReturnValue(Result.fail('Oops'))
const useCase = createUseCase()
const result = await useCase.execute({
inviteUuid: '00000000-0000-0000-0000-000000000000',
userUuid: '00000000-0000-0000-0000-000000000000',
})
expect(result.isFailed()).toBe(true)
expect(result.getError()).toBe('Oops')
mock.mockRestore()
})
it('should fail if originator uuid is invalid', async () => {
const useCase = createUseCase()

View File

@@ -1,9 +1,14 @@
import { Result, UseCaseInterface, Uuid } from '@standardnotes/domain-core'
import { NotificationPayload, NotificationType, Result, UseCaseInterface, Uuid } from '@standardnotes/domain-core'
import { DeclineInviteToSharedVaultDTO } from './DeclineInviteToSharedVaultDTO'
import { SharedVaultInviteRepositoryInterface } from '../../../SharedVault/User/Invite/SharedVaultInviteRepositoryInterface'
import { AddNotificationForUser } from '../../Messaging/AddNotificationForUser/AddNotificationForUser'
export class DeclineInviteToSharedVault implements UseCaseInterface<void> {
constructor(private sharedVaultInviteRepository: SharedVaultInviteRepositoryInterface) {}
constructor(
private sharedVaultInviteRepository: SharedVaultInviteRepositoryInterface,
private addNotificationForUser: AddNotificationForUser,
) {}
async execute(dto: DeclineInviteToSharedVaultDTO): Promise<Result<void>> {
const inviteUuidOrError = Uuid.create(dto.inviteUuid)
@@ -29,6 +34,26 @@ export class DeclineInviteToSharedVault implements UseCaseInterface<void> {
await this.sharedVaultInviteRepository.remove(invite)
const notificationPayloadOrError = NotificationPayload.create({
sharedVaultUuid: invite.props.sharedVaultUuid,
type: NotificationType.create(NotificationType.TYPES.SharedVaultInviteDeclined).getValue(),
version: '1.0',
})
if (notificationPayloadOrError.isFailed()) {
return Result.fail(notificationPayloadOrError.getError())
}
const notificationPayload = notificationPayloadOrError.getValue()
const result = await this.addNotificationForUser.execute({
userUuid: invite.props.userUuid.value,
type: NotificationType.TYPES.SharedVaultInviteDeclined,
payload: notificationPayload,
version: '1.0',
})
if (result.isFailed()) {
return Result.fail(result.getError())
}
return Result.ok()
}
}

View File

@@ -32,19 +32,16 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
let newItemsInSecondaryCount = 0
let updatedItemsInSecondary: string[] = []
let alreadyIdenticalInSecondaryAndPrimary: string[] = []
if (await this.hasAlreadyDataInSecondaryDatabase(userUuid)) {
const { alreadyExistingInPrimary, newItemsInSecondary, updatedInSecondary } =
const { alreadyExistingInSecondaryAndPrimary, newItemsInSecondary, updatedInSecondary } =
await this.getNewItemsCreatedInSecondaryDatabase(userUuid)
this.logger.info(
`[${dto.userUuid}] Removing ${alreadyExistingInPrimary.length} already existing items from secondary database.`,
`[${dto.userUuid}] ${alreadyExistingInSecondaryAndPrimary.length} already existing identical items in primary and secondary.`,
)
for (const existingItemUuid of alreadyExistingInPrimary) {
await (this.secondaryItemRepository as ItemRepositoryInterface).removeByUuid(
Uuid.create(existingItemUuid).getValue(),
)
}
alreadyIdenticalInSecondaryAndPrimary = alreadyExistingInSecondaryAndPrimary
if (newItemsInSecondary.length > 0) {
this.logger.info(`[${dto.userUuid}] Found ${newItemsInSecondary.length} new items in secondary database.`)
@@ -64,7 +61,13 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
const migrationTimeStart = this.timer.getTimestampInMicroseconds()
const migrationResult = await this.migrateItemsForUser(userUuid, updatedItemsInSecondary)
this.logger.info(`[${dto.userUuid}] Migrating items`)
const migrationResult = await this.migrateItemsForUser(
userUuid,
updatedItemsInSecondary,
alreadyIdenticalInSecondaryAndPrimary,
)
if (migrationResult.isFailed()) {
if (newItemsInSecondaryCount === 0 && updatedItemsInSecondaryCount === 0) {
const cleanupResult = await this.deleteItemsForUser(userUuid, this.secondaryItemRepository)
@@ -84,6 +87,7 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
userUuid,
newItemsInSecondaryCount,
updatedItemsInSecondary,
alreadyIdenticalInSecondaryAndPrimary,
)
if (integrityCheckResult.isFailed()) {
if (newItemsInSecondaryCount === 0 && updatedItemsInSecondaryCount === 0) {
@@ -129,18 +133,18 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
}
private async allowForSecondaryDatabaseToCatchUp(): Promise<void> {
const twoSecondsInMilliseconds = 2_000
await this.timer.sleep(twoSecondsInMilliseconds)
const tenSecondsInMillisecondsToRebuildIndexes = 10_000
await this.timer.sleep(tenSecondsInMillisecondsToRebuildIndexes)
}
private async getNewItemsCreatedInSecondaryDatabase(userUuid: Uuid): Promise<{
alreadyExistingInPrimary: string[]
alreadyExistingInSecondaryAndPrimary: string[]
newItemsInSecondary: string[]
updatedInSecondary: string[]
}> {
this.logger.info(`[${userUuid.value}] Checking for new items in secondary database`)
const alreadyExistingInPrimary: string[] = []
const alreadyExistingInSecondaryAndPrimary: string[] = []
const updatedInSecondary: string[] = []
const newItemsInSecondary: string[] = []
@@ -159,16 +163,16 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
const items = await (this.secondaryItemRepository as ItemRepositoryInterface).findAll(query)
for (const item of items) {
const { itemInPrimary, newerItemInSecondary } = await this.checkIfItemExistsInPrimaryDatabase(item)
if (itemInPrimary !== null) {
alreadyExistingInPrimary.push(item.id.toString())
const { identicalItemInPrimary, newerItemInSecondary } = await this.checkIfItemExistsInPrimaryDatabase(item)
if (identicalItemInPrimary !== null) {
alreadyExistingInSecondaryAndPrimary.push(item.id.toString())
continue
}
if (newerItemInSecondary !== null) {
updatedInSecondary.push(newerItemInSecondary.id.toString())
continue
}
if (itemInPrimary === null && newerItemInSecondary === null) {
if (identicalItemInPrimary === null && newerItemInSecondary === null) {
newItemsInSecondary.push(item.id.toString())
continue
}
@@ -176,7 +180,7 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
}
return {
alreadyExistingInPrimary,
alreadyExistingInSecondaryAndPrimary,
newItemsInSecondary,
updatedInSecondary,
}
@@ -184,11 +188,11 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
private async checkIfItemExistsInPrimaryDatabase(
item: Item,
): Promise<{ itemInPrimary: Item | null; newerItemInSecondary: Item | null }> {
): Promise<{ identicalItemInPrimary: Item | null; newerItemInSecondary: Item | null }> {
const itemInPrimary = await this.primaryItemRepository.findByUuid(item.uuid)
if (itemInPrimary === null) {
return { itemInPrimary: null, newerItemInSecondary: null }
return { identicalItemInPrimary: null, newerItemInSecondary: null }
}
if (!item.isIdenticalTo(itemInPrimary)) {
@@ -201,15 +205,19 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
)
return {
itemInPrimary: null,
identicalItemInPrimary: null,
newerItemInSecondary: item.props.timestamps.updatedAt > itemInPrimary.props.timestamps.updatedAt ? item : null,
}
}
return { itemInPrimary: itemInPrimary, newerItemInSecondary: null }
return { identicalItemInPrimary: itemInPrimary, newerItemInSecondary: null }
}
private async migrateItemsForUser(userUuid: Uuid, updatedItemsInSecondary: string[]): Promise<Result<void>> {
private async migrateItemsForUser(
userUuid: Uuid,
updatedItemsInSecondary: string[],
alreadyExistingInSecondaryAndPrimary: string[],
): Promise<Result<void>> {
try {
const totalItemsCountForUser = await this.primaryItemRepository.countAll({ userUuid: userUuid.value })
const totalPages = Math.ceil(totalItemsCountForUser / this.pageSize)
@@ -232,6 +240,10 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
continue
}
if (alreadyExistingInSecondaryAndPrimary.find((itemUuid) => item.uuid.value === itemUuid)) {
continue
}
await (this.secondaryItemRepository as ItemRepositoryInterface).save(item)
}
}
@@ -256,6 +268,7 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
userUuid: Uuid,
newItemsInSecondaryCount: number,
updatedItemsInSecondary: string[],
alreadyExistingInSecondaryAndPrimary: string[],
): Promise<Result<boolean>> {
try {
const totalItemsCountForUserInPrimary = await this.primaryItemRepository.countAll({ userUuid: userUuid.value })
@@ -296,6 +309,10 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
continue
}
if (alreadyExistingInSecondaryAndPrimary.find((itemUuid) => item.uuid.value === itemUuid)) {
continue
}
if (!item.isIdenticalTo(itemInSecondary)) {
return Result.fail(
`Item ${

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.10.47](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.10.46...@standardnotes/websockets-server@1.10.47) (2023-09-20)
**Note:** Version bump only for package @standardnotes/websockets-server
## [1.10.46](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.10.45...@standardnotes/websockets-server@1.10.46) (2023-09-19)
**Note:** Version bump only for package @standardnotes/websockets-server
## [1.10.45](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.10.44...@standardnotes/websockets-server@1.10.45) (2023-09-18)
**Note:** Version bump only for package @standardnotes/websockets-server

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/websockets-server",
"version": "1.10.45",
"version": "1.10.47",
"engines": {
"node": ">=18.0.0 <21.0.0"
},