Compare commits

..

9 Commits

Author SHA1 Message Date
standardci
1ae7cca394 chore(release): publish new version
- @standardnotes/home-server@1.13.47
 - @standardnotes/syncing-server@1.78.10
2023-08-11 09:00:00 +00:00
Karol Sójko
bc1c7a8ae1 tmp: disable decorating items completely 2023-08-11 10:54:12 +02:00
standardci
c22c5e4584 chore(release): publish new version
- @standardnotes/home-server@1.13.46
 - @standardnotes/syncing-server@1.78.9
2023-08-11 08:46:28 +00:00
Karol Sójko
ac3646836c tmp: disable decorating with associations on revisions 2023-08-11 10:40:03 +02:00
standardci
7a31ab75d6 chore(release): publish new version
- @standardnotes/home-server@1.13.45
 - @standardnotes/syncing-server@1.78.8
2023-08-11 08:23:28 +00:00
Karol Sójko
c49dc35ab5 tmp: disable shared vaults 2023-08-11 10:15:55 +02:00
Karol Sójko
06cedd11d8 tmp: ci 2023-08-11 10:15:55 +02:00
standardci
f496376fb3 chore(release): publish new version
- @standardnotes/scheduler-server@1.20.22
2023-08-11 08:14:41 +00:00
Karol Sójko
091e2a57e8 fix(scheduler): adjust email backups encouraging email schedule (#695) 2023-08-11 09:35:51 +02:00
20 changed files with 93 additions and 58 deletions

View File

@@ -95,20 +95,20 @@ jobs:
- name: Test
run: yarn test
e2e:
needs: build
name: E2E
uses: standardnotes/server/.github/workflows/common-e2e.yml@main
secrets: inherit
# e2e:
# needs: build
# name: E2E
# uses: standardnotes/server/.github/workflows/common-e2e.yml@main
# secrets: inherit
publish-self-hosting:
needs: [ test, lint, e2e ]
needs: [ test, lint ]
name: Publish Self Hosting Docker Image
uses: standardnotes/server/.github/workflows/common-self-hosting.yml@main
secrets: inherit
publish-services:
needs: [ test, lint, e2e ]
needs: [ test, lint ]
runs-on: ubuntu-latest

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.13.47](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.46...@standardnotes/home-server@1.13.47) (2023-08-11)
**Note:** Version bump only for package @standardnotes/home-server
## [1.13.46](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.45...@standardnotes/home-server@1.13.46) (2023-08-11)
**Note:** Version bump only for package @standardnotes/home-server
## [1.13.45](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.44...@standardnotes/home-server@1.13.45) (2023-08-11)
**Note:** Version bump only for package @standardnotes/home-server
## [1.13.44](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.43...@standardnotes/home-server@1.13.44) (2023-08-11)
**Note:** Version bump only for package @standardnotes/home-server

View File

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

View File

@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.20.22](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.20.21...@standardnotes/scheduler-server@1.20.22) (2023-08-11)
### Bug Fixes
* **scheduler:** adjust email backups encouraging email schedule ([#695](https://github.com/standardnotes/server/issues/695)) ([091e2a5](https://github.com/standardnotes/server/commit/091e2a57e81bb335286807bba4b0fcfc04a086bb))
## [1.20.21](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.20.20...@standardnotes/scheduler-server@1.20.21) (2023-08-09)
**Note:** Version bump only for package @standardnotes/scheduler-server

View File

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

View File

@@ -33,7 +33,7 @@ export class UserRegisteredEventHandler implements DomainEventHandlerInterface {
private async scheduleEncourageEmailBackupsJob(event: UserRegisteredEvent): Promise<void> {
const job = new Job()
job.name = JobName.ENCOURAGE_EMAIL_BACKUPS
job.scheduledAt = this.timer.convertDateToMicroseconds(this.timer.getUTCDateNDaysAhead(7))
job.scheduledAt = this.timer.convertDateToMicroseconds(this.timer.getUTCDateNDaysAhead(2))
job.createdAt = this.timer.getTimestampInMicroseconds()
job.status = JobStatus.Pending
job.userIdentifier = event.payload.email

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.78.10](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.78.9...@standardnotes/syncing-server@1.78.10) (2023-08-11)
**Note:** Version bump only for package @standardnotes/syncing-server
## [1.78.9](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.78.8...@standardnotes/syncing-server@1.78.9) (2023-08-11)
**Note:** Version bump only for package @standardnotes/syncing-server
## [1.78.8](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.78.7...@standardnotes/syncing-server@1.78.8) (2023-08-11)
**Note:** Version bump only for package @standardnotes/syncing-server
## [1.78.7](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.78.6...@standardnotes/syncing-server@1.78.7) (2023-08-11)
**Note:** Version bump only for package @standardnotes/syncing-server

View File

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

View File

@@ -541,7 +541,6 @@ export class ContainerConfigLoader {
.toConstantValue(
new GetItems(
container.get(TYPES.Sync_ItemRepository),
container.get(TYPES.Sync_SharedVaultUserRepository),
container.get(TYPES.Sync_CONTENT_SIZE_TRANSFER_LIMIT),
container.get(TYPES.Sync_ItemTransferCalculator),
container.get(TYPES.Sync_Timer),

View File

@@ -139,7 +139,7 @@ export class ExtensionsHttpService implements ExtensionsHttpServiceInterface {
userUuid: string,
email: string,
): Promise<DomainEventInterface> {
const extension = await this.itemRepository.findByUuidAndUserUuid(extensionId, userUuid)
const extension = await this.itemRepository.findByUuidAndUserUuid(extensionId, userUuid, true)
if (extension === null || !extension.props.content) {
throw Error(`Could not find extensions with id ${extensionId}`)
}

View File

@@ -16,7 +16,7 @@ export class DuplicateItemSyncedEventHandler implements DomainEventHandlerInterf
) {}
async handle(event: DuplicateItemSyncedEvent): Promise<void> {
const item = await this.itemRepository.findByUuidAndUserUuid(event.payload.itemUuid, event.payload.userUuid)
const item = await this.itemRepository.findByUuidAndUserUuid(event.payload.itemUuid, event.payload.userUuid, true)
if (item === null) {
this.logger.warn(`Could not find item with uuid ${event.payload.itemUuid}`)
@@ -33,6 +33,7 @@ export class DuplicateItemSyncedEventHandler implements DomainEventHandlerInterf
const existingOriginalItem = await this.itemRepository.findByUuidAndUserUuid(
item.props.duplicateOf.value,
event.payload.userUuid,
true,
)
if (existingOriginalItem !== null) {

View File

@@ -53,11 +53,14 @@ export class EmailBackupRequestedEventHandler implements DomainEventHandlerInter
const backupFileNames: string[] = []
for (const itemUuidBundle of itemUuidBundles) {
const items = await this.itemRepository.findAll({
uuids: itemUuidBundle,
sortBy: 'updated_at_timestamp',
sortOrder: 'ASC',
})
const items = await this.itemRepository.findAll(
{
uuids: itemUuidBundle,
sortBy: 'updated_at_timestamp',
sortOrder: 'ASC',
},
true,
)
const bundleBackupFileNames = await this.itemBackupService.backup(
items,

View File

@@ -24,7 +24,7 @@ export class ItemRevisionCreationRequestedEventHandler implements DomainEventHan
}
const itemUuid = itemUuidOrError.getValue()
const item = await this.itemRepository.findByUuid(itemUuid)
const item = await this.itemRepository.findByUuid(itemUuid, true)
if (item === null) {
return
}

View File

@@ -7,7 +7,7 @@ import { ExtendedIntegrityPayload } from './ExtendedIntegrityPayload'
export interface ItemRepositoryInterface {
deleteByUserUuid(userUuid: string): Promise<void>
findAll(query: ItemQuery): Promise<Item[]>
findAll(query: ItemQuery, noAssociations: boolean): Promise<Item[]>
findAllRaw<T>(query: ItemQuery): Promise<T[]>
streamAll(query: ItemQuery): Promise<ReadStream>
countAll(query: ItemQuery): Promise<number>
@@ -16,8 +16,8 @@ export interface ItemRepositoryInterface {
): Promise<Array<{ uuid: string; contentSize: number | null }>>
findDatesForComputingIntegrityHash(userUuid: string): Promise<Array<{ updated_at_timestamp: number }>>
findItemsForComputingIntegrityPayloads(userUuid: string): Promise<ExtendedIntegrityPayload[]>
findByUuidAndUserUuid(uuid: string, userUuid: string): Promise<Item | null>
findByUuid(uuid: Uuid): Promise<Item | null>
findByUuidAndUserUuid(uuid: string, userUuid: string, noAssociations: boolean): Promise<Item | null>
findByUuid(uuid: Uuid, noAssociations: boolean): Promise<Item | null>
remove(item: Item): Promise<void>
save(item: Item): Promise<void>
markItemsAsDeleted(itemUuids: Array<string>, updatedAtTimestamp: number): Promise<void>

View File

@@ -8,7 +8,7 @@ export class GetItem implements UseCaseInterface<Item> {
constructor(private itemRepository: ItemRepositoryInterface) {}
async execute(dto: GetItemDTO): Promise<Result<Item>> {
const item = await this.itemRepository.findByUuidAndUserUuid(dto.itemUuid, dto.userUuid)
const item = await this.itemRepository.findByUuidAndUserUuid(dto.itemUuid, dto.userUuid, true)
if (item === null) {
return Result.fail(`Could not find item with uuid ${dto.itemUuid}`)

View File

@@ -16,14 +16,7 @@ describe('GetItems', () => {
let sharedVaultUserRepository: SharedVaultUserRepositoryInterface
const createUseCase = () =>
new GetItems(
itemRepository,
sharedVaultUserRepository,
contentSizeTransferLimit,
itemTransferCalculator,
timer,
maxItemsSyncLimit,
)
new GetItems(itemRepository, contentSizeTransferLimit, itemTransferCalculator, timer, maxItemsSyncLimit)
beforeEach(() => {
item = Item.create({

View File

@@ -7,7 +7,6 @@ import { ItemQuery } from '../../../Item/ItemQuery'
import { ItemRepositoryInterface } from '../../../Item/ItemRepositoryInterface'
import { ItemTransferCalculatorInterface } from '../../../Item/ItemTransferCalculatorInterface'
import { GetItemsDTO } from './GetItemsDTO'
import { SharedVaultUserRepositoryInterface } from '../../../SharedVault/User/SharedVaultUserRepositoryInterface'
export class GetItems implements UseCaseInterface<GetItemsResult> {
private readonly DEFAULT_ITEMS_LIMIT = 150
@@ -15,7 +14,6 @@ export class GetItems implements UseCaseInterface<GetItemsResult> {
constructor(
private itemRepository: ItemRepositoryInterface,
private sharedVaultUserRepository: SharedVaultUserRepositoryInterface,
private contentSizeTransferLimit: number,
private itemTransferCalculator: ItemTransferCalculatorInterface,
private timer: TimerInterface,
@@ -39,13 +37,6 @@ export class GetItems implements UseCaseInterface<GetItemsResult> {
const limit = dto.limit === undefined || dto.limit < 1 ? this.DEFAULT_ITEMS_LIMIT : dto.limit
const upperBoundLimit = limit < this.maxItemsSyncLimit ? limit : this.maxItemsSyncLimit
const sharedVaultUsers = await this.sharedVaultUserRepository.findByUserUuid(userUuid)
const userSharedVaultUuids = sharedVaultUsers.map((sharedVaultUser) => sharedVaultUser.props.sharedVaultUuid.value)
const exclusiveSharedVaultUuids = dto.sharedVaultUuids
? dto.sharedVaultUuids.filter((sharedVaultUuid) => userSharedVaultUuids.includes(sharedVaultUuid))
: undefined
const itemQuery: ItemQuery = {
userUuid: userUuid.value,
lastSyncTime: lastSyncTime ?? undefined,
@@ -55,8 +46,8 @@ export class GetItems implements UseCaseInterface<GetItemsResult> {
sortBy: 'updated_at_timestamp',
sortOrder: 'ASC',
limit: upperBoundLimit,
includeSharedVaultUuids: !dto.sharedVaultUuids ? userSharedVaultUuids : undefined,
exclusiveSharedVaultUuids,
includeSharedVaultUuids: undefined,
exclusiveSharedVaultUuids: undefined,
}
const itemUuidsToFetch = await this.itemTransferCalculator.computeItemUuidsToFetch(
@@ -65,11 +56,14 @@ export class GetItems implements UseCaseInterface<GetItemsResult> {
)
let items: Array<Item> = []
if (itemUuidsToFetch.length > 0) {
items = await this.itemRepository.findAll({
uuids: itemUuidsToFetch,
sortBy: 'updated_at_timestamp',
sortOrder: 'ASC',
})
items = await this.itemRepository.findAll(
{
uuids: itemUuidsToFetch,
sortBy: 'updated_at_timestamp',
sortOrder: 'ASC',
},
true,
)
}
const totalItemsCount = await this.itemRepository.countAll(itemQuery)

View File

@@ -42,7 +42,7 @@ export class SaveItems implements UseCaseInterface<SaveItemsResult> {
}
const itemUuid = itemUuidOrError.getValue()
const existingItem = await this.itemRepository.findByUuid(itemUuid)
const existingItem = await this.itemRepository.findByUuid(itemUuid, true)
if (dto.readOnlyAccess) {
conflicts.push({

View File

@@ -126,12 +126,15 @@ export class SyncItems implements UseCaseInterface<SyncItemsResponse> {
}
private async frontLoadKeysItemsToTop(userUuid: string, retrievedItems: Array<Item>): Promise<Array<Item>> {
const itemsKeys = await this.itemRepository.findAll({
userUuid,
contentType: ContentType.TYPES.ItemsKey,
sortBy: 'updated_at_timestamp',
sortOrder: 'ASC',
})
const itemsKeys = await this.itemRepository.findAll(
{
userUuid,
contentType: ContentType.TYPES.ItemsKey,
sortBy: 'updated_at_timestamp',
sortOrder: 'ASC',
},
true,
)
const retrievedItemsIds: Array<string> = retrievedItems.map((item: Item) => item.id.toString())

View File

@@ -77,7 +77,7 @@ export class TypeORMItemRepository implements ItemRepositoryInterface {
.execute()
}
async findByUuid(uuid: Uuid): Promise<Item | null> {
async findByUuid(uuid: Uuid, noAssociations: boolean): Promise<Item | null> {
const persistence = await this.ormRepository
.createQueryBuilder('item')
.where('item.uuid = :uuid', {
@@ -92,6 +92,10 @@ export class TypeORMItemRepository implements ItemRepositoryInterface {
try {
const item = this.mapper.toDomain(persistence)
if (noAssociations) {
return item
}
await this.decorateItemWithAssociations(item)
return item
@@ -126,7 +130,7 @@ export class TypeORMItemRepository implements ItemRepositoryInterface {
return items.sort((itemA, itemB) => itemB.updated_at_timestamp - itemA.updated_at_timestamp)
}
async findByUuidAndUserUuid(uuid: string, userUuid: string): Promise<Item | null> {
async findByUuidAndUserUuid(uuid: string, userUuid: string, noAssociations: boolean): Promise<Item | null> {
const persistence = await this.ormRepository
.createQueryBuilder('item')
.where('item.uuid = :uuid AND item.user_uuid = :userUuid', {
@@ -142,6 +146,10 @@ export class TypeORMItemRepository implements ItemRepositoryInterface {
try {
const item = this.mapper.toDomain(persistence)
if (noAssociations) {
return item
}
await this.decorateItemWithAssociations(item)
return item
@@ -152,7 +160,7 @@ export class TypeORMItemRepository implements ItemRepositoryInterface {
}
}
async findAll(query: ItemQuery): Promise<Item[]> {
async findAll(query: ItemQuery, noAssociations: boolean): Promise<Item[]> {
const persistence = await this.createFindAllQueryBuilder(query).getMany()
const domainItems: Item[] = []
@@ -164,6 +172,10 @@ export class TypeORMItemRepository implements ItemRepositoryInterface {
}
}
if (noAssociations) {
return domainItems
}
await Promise.all(domainItems.map((item) => this.decorateItemWithAssociations(item)))
return domainItems