Compare commits

..

8 Commits

Author SHA1 Message Date
standardci
8e47491e3c chore(release): publish new version
- @standardnotes/home-server@1.13.29
 - @standardnotes/syncing-server@1.75.4
2023-08-03 13:38:37 +00:00
Karol Sójko
0036d527bd fix(syncing-server): skip retrieval of items with invalid uuids (#683) 2023-08-03 15:05:59 +02:00
standardci
f565f1d950 chore(release): publish new version
- @standardnotes/analytics@2.25.8
 - @standardnotes/api-gateway@1.69.3
 - @standardnotes/auth-server@1.129.0
 - @standardnotes/domain-events-infra@1.12.10
 - @standardnotes/domain-events@2.114.0
 - @standardnotes/event-store@1.11.15
 - @standardnotes/files-server@1.19.18
 - @standardnotes/home-server@1.13.28
 - @standardnotes/revisions-server@1.26.2
 - @standardnotes/scheduler-server@1.20.17
 - @standardnotes/syncing-server@1.75.3
 - @standardnotes/websockets-server@1.10.12
2023-08-03 10:34:26 +00:00
Karol Sójko
8e35dfa4b7 feat(auth): add handling payments account deleted events STA-1769 (#682)
* feat(auth): add handling payments account deleted events

* fix(auth): result type for accounts already deleted

---------

Co-authored-by: Karol Sójko <karolsojko@proton.me>
2023-08-03 12:01:42 +02:00
standardci
f911473be9 chore(release): publish new version
- @standardnotes/analytics@2.25.7
 - @standardnotes/api-gateway@1.69.2
 - @standardnotes/auth-server@1.128.1
 - @standardnotes/domain-core@1.24.2
 - @standardnotes/event-store@1.11.14
 - @standardnotes/files-server@1.19.17
 - @standardnotes/home-server@1.13.27
 - @standardnotes/revisions-server@1.26.1
 - @standardnotes/scheduler-server@1.20.16
 - @standardnotes/settings@1.21.21
 - @standardnotes/syncing-server@1.75.2
 - @standardnotes/websockets-server@1.10.11
2023-08-02 15:51:56 +00:00
Karol Sójko
71624f1897 fix(domain-core): remove unused content types 2023-08-02 17:34:40 +02:00
standardci
17de6ea7e1 chore(release): publish new version
- @standardnotes/home-server@1.13.26
 - @standardnotes/syncing-server@1.75.1
2023-08-02 11:41:20 +00:00
Karol Sójko
6aad7cd207 fix(syncing-server): update unknown content type on items migration 2023-08-02 13:24:14 +02:00
48 changed files with 448 additions and 106 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.25.8](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.7...@standardnotes/analytics@2.25.8) (2023-08-03)
**Note:** Version bump only for package @standardnotes/analytics
## [2.25.7](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.6...@standardnotes/analytics@2.25.7) (2023-08-02)
**Note:** Version bump only for package @standardnotes/analytics
## [2.25.6](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.25.5...@standardnotes/analytics@2.25.6) (2023-07-27)
**Note:** Version bump only for package @standardnotes/analytics

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/analytics",
"version": "2.25.6",
"version": "2.25.8",
"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.69.3](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.69.2...@standardnotes/api-gateway@1.69.3) (2023-08-03)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.69.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.69.1...@standardnotes/api-gateway@1.69.2) (2023-08-02)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.69.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.69.0...@standardnotes/api-gateway@1.69.1) (2023-07-31)
### Bug Fixes

View File

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

View File

@@ -3,6 +3,16 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.129.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.128.1...@standardnotes/auth-server@1.129.0) (2023-08-03)
### Features
* **auth:** add handling payments account deleted events STA-1769 ([#682](https://github.com/standardnotes/server/issues/682)) ([8e35dfa](https://github.com/standardnotes/server/commit/8e35dfa4b77256f4c0a3294b296a5526fd1020ad))
## [1.128.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.128.0...@standardnotes/auth-server@1.128.1) (2023-08-02)
**Note:** Version bump only for package @standardnotes/auth-server
# [1.128.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.127.2...@standardnotes/auth-server@1.128.0) (2023-08-02)
### Features

View File

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

View File

@@ -252,6 +252,7 @@ import { BaseWebSocketsController } from '../Infra/InversifyExpressUtils/Base/Ba
import { BaseSessionsController } from '../Infra/InversifyExpressUtils/Base/BaseSessionsController'
import { Transform } from 'stream'
import { ActivatePremiumFeatures } from '../Domain/UseCase/ActivatePremiumFeatures/ActivatePremiumFeatures'
import { PaymentsAccountDeletedEventHandler } from '../Domain/Handler/PaymentsAccountDeletedEventHandler'
export class ContainerConfigLoader {
async load(configuration?: {
@@ -978,6 +979,14 @@ export class ContainerConfigLoader {
container.get(TYPES.Auth_SettingService),
),
)
container
.bind<PaymentsAccountDeletedEventHandler>(TYPES.Auth_PaymentsAccountDeletedEventHandler)
.toConstantValue(
new PaymentsAccountDeletedEventHandler(
container.get(TYPES.Auth_DeleteAccount),
container.get(TYPES.Auth_Logger),
),
)
const eventHandlers: Map<string, DomainEventHandlerInterface> = new Map([
['USER_REGISTERED', container.get(TYPES.Auth_UserRegisteredEventHandler)],
@@ -1005,6 +1014,7 @@ export class ContainerConfigLoader {
],
['PREDICATE_VERIFICATION_REQUESTED', container.get(TYPES.Auth_PredicateVerificationRequestedEventHandler)],
['EMAIL_SUBSCRIPTION_UNSUBSCRIBED', container.get(TYPES.Auth_EmailSubscriptionUnsubscribedEventHandler)],
['PAYMENTS_ACCOUNT_DELETED', container.get(TYPES.Auth_PaymentsAccountDeletedEventHandler)],
])
if (isConfiguredForHomeServer) {

View File

@@ -176,6 +176,7 @@ const TYPES = {
),
Auth_PredicateVerificationRequestedEventHandler: Symbol.for('Auth_PredicateVerificationRequestedEventHandler'),
Auth_EmailSubscriptionUnsubscribedEventHandler: Symbol.for('Auth_EmailSubscriptionUnsubscribedEventHandler'),
Auth_PaymentsAccountDeletedEventHandler: Symbol.for('Auth_PaymentsAccountDeletedEventHandler'),
// Services
Auth_DeviceDetector: Symbol.for('Auth_DeviceDetector'),
Auth_SessionService: Symbol.for('Auth_SessionService'),

View File

@@ -0,0 +1,48 @@
import { Logger } from 'winston'
import { Result } from '@standardnotes/domain-core'
import { PaymentsAccountDeletedEvent } from '@standardnotes/domain-events'
import { DeleteAccount } from '../UseCase/DeleteAccount/DeleteAccount'
import { PaymentsAccountDeletedEventHandler } from './PaymentsAccountDeletedEventHandler'
describe('PaymentsAccountDeletedEventHandler', () => {
let deleteAccountUseCase: DeleteAccount
let logger: Logger
let event: PaymentsAccountDeletedEvent
const createHandler = () => new PaymentsAccountDeletedEventHandler(deleteAccountUseCase, logger)
beforeEach(() => {
deleteAccountUseCase = {} as jest.Mocked<DeleteAccount>
deleteAccountUseCase.execute = jest.fn().mockResolvedValue(Result.ok('success'))
logger = {} as jest.Mocked<Logger>
logger.error = jest.fn()
event = {
payload: {
username: 'username',
},
} as jest.Mocked<PaymentsAccountDeletedEvent>
})
it('should delete account', async () => {
const handler = createHandler()
await handler.handle(event)
expect(deleteAccountUseCase.execute).toHaveBeenCalledWith({
username: 'username',
})
})
it('should log error if delete account fails', async () => {
const handler = createHandler()
deleteAccountUseCase.execute = jest.fn().mockResolvedValue(Result.fail('error'))
await handler.handle(event)
expect(logger.error).toHaveBeenCalledWith('Failed to delete account for user username: error')
})
})

View File

@@ -0,0 +1,18 @@
import { DomainEventHandlerInterface, PaymentsAccountDeletedEvent } from '@standardnotes/domain-events'
import { Logger } from 'winston'
import { DeleteAccount } from '../UseCase/DeleteAccount/DeleteAccount'
export class PaymentsAccountDeletedEventHandler implements DomainEventHandlerInterface {
constructor(private deleteAccountUseCase: DeleteAccount, private logger: Logger) {}
async handle(event: PaymentsAccountDeletedEvent): Promise<void> {
const result = await this.deleteAccountUseCase.execute({
username: event.payload.username,
})
if (result.isFailed()) {
this.logger.error(`Failed to delete account for user ${event.payload.username}: ${result.getError()}`)
}
}
}

View File

@@ -35,6 +35,7 @@ describe('DeleteAccount', () => {
userRepository = {} as jest.Mocked<UserRepositoryInterface>
userRepository.findOneByUuid = jest.fn().mockReturnValue(user)
userRepository.findOneByUsernameOrEmail = jest.fn().mockReturnValue(user)
userSubscriptionService = {} as jest.Mocked<UserSubscriptionServiceInterface>
userSubscriptionService.findRegularSubscriptionForUserUuid = jest
@@ -53,65 +54,124 @@ describe('DeleteAccount', () => {
timer.convertDateToMicroseconds = jest.fn().mockReturnValue(1)
})
it('should trigger account deletion - no subscription', async () => {
userSubscriptionService.findRegularSubscriptionForUserUuid = jest
.fn()
.mockReturnValue({ regularSubscription: null, sharedSubscription: null })
describe('when user uuid is provided', () => {
it('should trigger account deletion - no subscription', async () => {
userSubscriptionService.findRegularSubscriptionForUserUuid = jest
.fn()
.mockReturnValue({ regularSubscription: null, sharedSubscription: null })
expect(await createUseCase().execute({ userUuid: '00000000-0000-0000-0000-000000000000' })).toEqual({
message: 'Successfully deleted user',
responseCode: 200,
success: true,
const result = await createUseCase().execute({ userUuid: '00000000-0000-0000-0000-000000000000' })
expect(result.isFailed()).toBeFalsy()
expect(domainEventPublisher.publish).toHaveBeenCalledTimes(1)
expect(domainEventFactory.createAccountDeletionRequestedEvent).toHaveBeenLastCalledWith({
userUuid: '1-2-3',
userCreatedAtTimestamp: 1,
regularSubscriptionUuid: undefined,
})
})
expect(domainEventPublisher.publish).toHaveBeenCalledTimes(1)
expect(domainEventFactory.createAccountDeletionRequestedEvent).toHaveBeenLastCalledWith({
userUuid: '1-2-3',
userCreatedAtTimestamp: 1,
regularSubscriptionUuid: undefined,
it('should trigger account deletion - subscription present', async () => {
userSubscriptionService.findRegularSubscriptionForUserUuid = jest
.fn()
.mockReturnValue({ regularSubscription, sharedSubscription: null })
const result = await createUseCase().execute({ userUuid: '00000000-0000-0000-0000-000000000000' })
expect(result.isFailed()).toBeFalsy()
expect(domainEventPublisher.publish).toHaveBeenCalledTimes(1)
expect(domainEventFactory.createAccountDeletionRequestedEvent).toHaveBeenLastCalledWith({
userUuid: '1-2-3',
userCreatedAtTimestamp: 1,
regularSubscriptionUuid: '1-2-3',
})
})
it('should not trigger account deletion if user is not found', async () => {
userRepository.findOneByUuid = jest.fn().mockReturnValue(null)
const result = await createUseCase().execute({ userUuid: '00000000-0000-0000-0000-000000000000' })
expect(result.isFailed()).toBeFalsy()
expect(domainEventPublisher.publish).not.toHaveBeenCalled()
expect(domainEventFactory.createAccountDeletionRequestedEvent).not.toHaveBeenCalled()
})
it('should not trigger account deletion if user uuid is invalid', async () => {
const result = await createUseCase().execute({ userUuid: 'invalid' })
expect(result.isFailed()).toBeTruthy()
expect(domainEventPublisher.publish).not.toHaveBeenCalled()
expect(domainEventFactory.createAccountDeletionRequestedEvent).not.toHaveBeenCalled()
})
})
it('should trigger account deletion - subscription present', async () => {
userSubscriptionService.findRegularSubscriptionForUserUuid = jest
.fn()
.mockReturnValue({ regularSubscription, sharedSubscription: null })
describe('when username is provided', () => {
it('should trigger account deletion - no subscription', async () => {
userSubscriptionService.findRegularSubscriptionForUserUuid = jest
.fn()
.mockReturnValue({ regularSubscription: null, sharedSubscription: null })
expect(await createUseCase().execute({ userUuid: '00000000-0000-0000-0000-000000000000' })).toEqual({
message: 'Successfully deleted user',
responseCode: 200,
success: true,
const result = await createUseCase().execute({ username: 'test@test.te' })
expect(result.isFailed()).toBeFalsy()
expect(domainEventPublisher.publish).toHaveBeenCalledTimes(1)
expect(domainEventFactory.createAccountDeletionRequestedEvent).toHaveBeenLastCalledWith({
userUuid: '1-2-3',
userCreatedAtTimestamp: 1,
regularSubscriptionUuid: undefined,
})
})
expect(domainEventPublisher.publish).toHaveBeenCalledTimes(1)
expect(domainEventFactory.createAccountDeletionRequestedEvent).toHaveBeenLastCalledWith({
userUuid: '1-2-3',
userCreatedAtTimestamp: 1,
regularSubscriptionUuid: '1-2-3',
it('should trigger account deletion - subscription present', async () => {
userSubscriptionService.findRegularSubscriptionForUserUuid = jest
.fn()
.mockReturnValue({ regularSubscription, sharedSubscription: null })
const result = await createUseCase().execute({ username: 'test@test.te' })
expect(result.isFailed()).toBeFalsy()
expect(domainEventPublisher.publish).toHaveBeenCalledTimes(1)
expect(domainEventFactory.createAccountDeletionRequestedEvent).toHaveBeenLastCalledWith({
userUuid: '1-2-3',
userCreatedAtTimestamp: 1,
regularSubscriptionUuid: '1-2-3',
})
})
it('should not trigger account deletion if user is not found', async () => {
userRepository.findOneByUsernameOrEmail = jest.fn().mockReturnValue(null)
const result = await createUseCase().execute({ username: 'test@test.te' })
expect(result.isFailed()).toBeFalsy()
expect(domainEventPublisher.publish).not.toHaveBeenCalled()
expect(domainEventFactory.createAccountDeletionRequestedEvent).not.toHaveBeenCalled()
})
it('should not trigger account deletion if username is invalid', async () => {
const result = await createUseCase().execute({ username: '' })
expect(result.isFailed()).toBeTruthy()
expect(domainEventPublisher.publish).not.toHaveBeenCalled()
expect(domainEventFactory.createAccountDeletionRequestedEvent).not.toHaveBeenCalled()
})
})
it('should not trigger account deletion if user is not found', async () => {
userRepository.findOneByUuid = jest.fn().mockReturnValue(null)
describe('when neither user uuid nor username is provided', () => {
it('should not trigger account deletion', async () => {
const result = await createUseCase().execute({})
expect(await createUseCase().execute({ userUuid: '00000000-0000-0000-0000-000000000000' })).toEqual({
message: 'User not found',
responseCode: 404,
success: false,
expect(result.isFailed()).toBeTruthy()
expect(domainEventPublisher.publish).not.toHaveBeenCalled()
expect(domainEventFactory.createAccountDeletionRequestedEvent).not.toHaveBeenCalled()
})
expect(domainEventPublisher.publish).not.toHaveBeenCalled()
expect(domainEventFactory.createAccountDeletionRequestedEvent).not.toHaveBeenCalled()
})
it('should not trigger account deletion if user uuid is invalid', async () => {
expect(await createUseCase().execute({ userUuid: '' })).toEqual({
message: 'Given value is not a valid uuid: ',
responseCode: 400,
success: false,
})
expect(domainEventPublisher.publish).not.toHaveBeenCalled()
expect(domainEventFactory.createAccountDeletionRequestedEvent).not.toHaveBeenCalled()
})
})

View File

@@ -1,4 +1,4 @@
import { Uuid } from '@standardnotes/domain-core'
import { Result, UseCaseInterface, Username, Uuid } from '@standardnotes/domain-core'
import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
import { TimerInterface } from '@standardnotes/time'
import { inject, injectable } from 'inversify'
@@ -7,13 +7,12 @@ import TYPES from '../../../Bootstrap/Types'
import { DomainEventFactoryInterface } from '../../Event/DomainEventFactoryInterface'
import { UserSubscriptionServiceInterface } from '../../Subscription/UserSubscriptionServiceInterface'
import { UserRepositoryInterface } from '../../User/UserRepositoryInterface'
import { UseCaseInterface } from '../UseCaseInterface'
import { DeleteAccountDTO } from './DeleteAccountDTO'
import { DeleteAccountResponse } from './DeleteAccountResponse'
import { User } from '../../User/User'
@injectable()
export class DeleteAccount implements UseCaseInterface {
export class DeleteAccount implements UseCaseInterface<string> {
constructor(
@inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.Auth_UserSubscriptionService) private userSubscriptionService: UserSubscriptionServiceInterface,
@@ -22,25 +21,30 @@ export class DeleteAccount implements UseCaseInterface {
@inject(TYPES.Auth_Timer) private timer: TimerInterface,
) {}
async execute(dto: DeleteAccountDTO): Promise<DeleteAccountResponse> {
const uuidOrError = Uuid.create(dto.userUuid)
if (uuidOrError.isFailed()) {
return {
success: false,
responseCode: 400,
message: uuidOrError.getError(),
async execute(dto: DeleteAccountDTO): Promise<Result<string>> {
let user: User | null = null
if (dto.userUuid !== undefined) {
const uuidOrError = Uuid.create(dto.userUuid)
if (uuidOrError.isFailed()) {
return Result.fail(uuidOrError.getError())
}
}
const uuid = uuidOrError.getValue()
const uuid = uuidOrError.getValue()
const user = await this.userRepository.findOneByUuid(uuid)
user = await this.userRepository.findOneByUuid(uuid)
} else if (dto.username !== undefined) {
const usernameOrError = Username.create(dto.username)
if (usernameOrError.isFailed()) {
return Result.fail(usernameOrError.getError())
}
const username = usernameOrError.getValue()
user = await this.userRepository.findOneByUsernameOrEmail(username)
} else {
return Result.fail('Either userUuid or username must be provided.')
}
if (user === null) {
return {
success: false,
responseCode: 404,
message: 'User not found',
}
return Result.ok('User already deleted.')
}
let regularSubscriptionUuid = undefined
@@ -57,10 +61,6 @@ export class DeleteAccount implements UseCaseInterface {
}),
)
return {
success: true,
message: 'Successfully deleted user',
responseCode: 200,
}
return Result.ok('Successfully deleted account.')
}
}

View File

@@ -1,3 +1,4 @@
export type DeleteAccountDTO = {
userUuid: string
userUuid?: string
username?: string
}

View File

@@ -1,5 +0,0 @@
export type DeleteAccountResponse = {
success: boolean
responseCode: number
message: string
}

View File

@@ -4,7 +4,7 @@ import * as express from 'express'
import { AnnotatedUsersController } from './AnnotatedUsersController'
import { results } from 'inversify-express-utils'
import { Username } from '@standardnotes/domain-core'
import { Result, Username } from '@standardnotes/domain-core'
import { DeleteAccount } from '../../Domain/UseCase/DeleteAccount/DeleteAccount'
import { ChangeCredentials } from '../../Domain/UseCase/ChangeCredentials/ChangeCredentials'
import { ClearLoginAttempts } from '../../Domain/UseCase/ClearLoginAttempts'
@@ -45,7 +45,7 @@ describe('AnnotatedUsersController', () => {
updateUser.execute = jest.fn()
deleteAccount = {} as jest.Mocked<DeleteAccount>
deleteAccount.execute = jest.fn().mockReturnValue({ success: true, message: 'A OK', responseCode: 200 })
deleteAccount.execute = jest.fn().mockReturnValue(Result.ok('success'))
user = {} as jest.Mocked<User>
user.uuid = '123'
@@ -181,7 +181,22 @@ describe('AnnotatedUsersController', () => {
expect(deleteAccount.execute).toHaveBeenCalledWith({ userUuid: '1-2-3' })
expect(result.statusCode).toEqual(200)
expect(await result.content.readAsStringAsync()).toEqual('{"message":"A OK"}')
})
it('should indicate failure when deleting user', async () => {
request.params.userUuid = '1-2-3'
response.locals.user = {
uuid: '1-2-3',
}
deleteAccount.execute = jest.fn().mockReturnValue(Result.fail('Something bad happened'))
const httpResponse = <results.JsonResult>await createController().deleteAccount(request, response)
const result = await httpResponse.executeAsync()
expect(deleteAccount.execute).toHaveBeenCalledWith({ userUuid: '1-2-3' })
expect(result.statusCode).toEqual(400)
})
it('should not delete user if user uuid is different than the one in the session', async () => {

View File

@@ -119,7 +119,18 @@ export class BaseUsersController extends BaseHttpController {
userUuid: request.params.userUuid,
})
return this.json({ message: result.message }, result.responseCode)
if (result.isFailed()) {
return this.json(
{
error: {
message: result.getError(),
},
},
400,
)
}
return this.json({ message: result.getValue() }, 200)
}
async getSubscription(request: Request, response: Response): Promise<results.JsonResult> {

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.24.2](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.24.1...@standardnotes/domain-core@1.24.2) (2023-08-02)
### Bug Fixes
* **domain-core:** remove unused content types ([71624f1](https://github.com/standardnotes/server/commit/71624f18979ed9254fafeeced733e598cd66cbeb))
## [1.24.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.24.0...@standardnotes/domain-core@1.24.1) (2023-07-27)
### Bug Fixes

View File

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

View File

@@ -31,9 +31,9 @@ describe('ContentType', () => {
})
it('should fallback to the value if the display name is not found', () => {
const valueOrError = ContentType.create(ContentType.TYPES.Unknown)
const valueOrError = ContentType.create(ContentType.TYPES.EncryptedStorage)
expect(valueOrError.isFailed()).toBeFalsy()
expect(valueOrError.getValue().getDisplayName()).toEqual('Unknown')
expect(valueOrError.getValue().getDisplayName()).toEqual('SN|EncryptedStorage')
})
})

View File

@@ -14,7 +14,6 @@ export class ContentType extends ValueObject<ContentTypeProps> {
RootKey: 'SN|RootKey|NoSync',
ItemsKey: 'SN|ItemsKey',
EncryptedStorage: 'SN|EncryptedStorage',
Privileges: 'SN|Privileges',
Note: 'Note',
Tag: 'Tag',
SmartView: 'SN|SmartTag',
@@ -29,7 +28,6 @@ export class ContentType extends ValueObject<ContentTypeProps> {
FilesafeFileMetadata: 'SN|FileSafe|FileMetadata',
FilesafeIntegration: 'SN|FileSafe|Integration',
ExtensionRepo: 'SN|ExtensionRepo',
Unknown: 'Unknown',
}
private readonly displayNamesMap: Partial<Record<string, string>> = {

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.12.10](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.12.9...@standardnotes/domain-events-infra@1.12.10) (2023-08-03)
**Note:** Version bump only for package @standardnotes/domain-events-infra
## [1.12.9](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.12.8...@standardnotes/domain-events-infra@1.12.9) (2023-07-07)
**Note:** Version bump only for package @standardnotes/domain-events-infra

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/domain-events-infra",
"version": "1.12.9",
"version": "1.12.10",
"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.
# [2.114.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.113.1...@standardnotes/domain-events@2.114.0) (2023-08-03)
### Features
* **auth:** add handling payments account deleted events STA-1769 ([#682](https://github.com/standardnotes/server/issues/682)) ([8e35dfa](https://github.com/standardnotes/server/commit/8e35dfa4b77256f4c0a3294b296a5526fd1020ad))
## [2.113.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.113.0...@standardnotes/domain-events@2.113.1) (2023-07-07)
### Bug Fixes

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/domain-events",
"version": "2.113.1",
"version": "2.114.0",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -0,0 +1,8 @@
import { DomainEventInterface } from './DomainEventInterface'
import { PaymentsAccountDeletedEventPayload } from './PaymentsAccountDeletedEventPayload'
export interface PaymentsAccountDeletedEvent extends DomainEventInterface {
type: 'PAYMENTS_ACCOUNT_DELETED'
payload: PaymentsAccountDeletedEventPayload
}

View File

@@ -0,0 +1,3 @@
export interface PaymentsAccountDeletedEventPayload {
username: string
}

View File

@@ -44,6 +44,8 @@ export * from './Event/MuteEmailsSettingChangedEvent'
export * from './Event/MuteEmailsSettingChangedEventPayload'
export * from './Event/PaymentFailedEvent'
export * from './Event/PaymentFailedEventPayload'
export * from './Event/PaymentsAccountDeletedEvent'
export * from './Event/PaymentsAccountDeletedEventPayload'
export * from './Event/PaymentSuccessEvent'
export * from './Event/PaymentSuccessEventPayload'
export * from './Event/PredicateVerificationRequestedEvent'

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.15](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.11.14...@standardnotes/event-store@1.11.15) (2023-08-03)
**Note:** Version bump only for package @standardnotes/event-store
## [1.11.14](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.11.13...@standardnotes/event-store@1.11.14) (2023-08-02)
**Note:** Version bump only for package @standardnotes/event-store
## [1.11.13](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.11.12...@standardnotes/event-store@1.11.13) (2023-07-27)
**Note:** Version bump only for package @standardnotes/event-store

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/event-store",
"version": "1.11.13",
"version": "1.11.15",
"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.19.18](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.19.17...@standardnotes/files-server@1.19.18) (2023-08-03)
**Note:** Version bump only for package @standardnotes/files-server
## [1.19.17](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.19.16...@standardnotes/files-server@1.19.17) (2023-08-02)
**Note:** Version bump only for package @standardnotes/files-server
## [1.19.16](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.19.15...@standardnotes/files-server@1.19.16) (2023-08-01)
### Bug Fixes

View File

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

View File

@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.13.29](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.28...@standardnotes/home-server@1.13.29) (2023-08-03)
**Note:** Version bump only for package @standardnotes/home-server
## [1.13.28](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.27...@standardnotes/home-server@1.13.28) (2023-08-03)
**Note:** Version bump only for package @standardnotes/home-server
## [1.13.27](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.26...@standardnotes/home-server@1.13.27) (2023-08-02)
**Note:** Version bump only for package @standardnotes/home-server
## [1.13.26](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.25...@standardnotes/home-server@1.13.26) (2023-08-02)
**Note:** Version bump only for package @standardnotes/home-server
## [1.13.25](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.24...@standardnotes/home-server@1.13.25) (2023-08-02)
**Note:** Version bump only for package @standardnotes/home-server

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/home-server",
"version": "1.13.25",
"version": "1.13.29",
"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.26.2](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.26.1...@standardnotes/revisions-server@1.26.2) (2023-08-03)
**Note:** Version bump only for package @standardnotes/revisions-server
## [1.26.1](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.26.0...@standardnotes/revisions-server@1.26.1) (2023-08-02)
**Note:** Version bump only for package @standardnotes/revisions-server
# [1.26.0](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.25.7...@standardnotes/revisions-server@1.26.0) (2023-08-02)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/revisions-server",
"version": "1.26.0",
"version": "1.26.2",
"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.20.17](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.20.16...@standardnotes/scheduler-server@1.20.17) (2023-08-03)
**Note:** Version bump only for package @standardnotes/scheduler-server
## [1.20.16](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.20.15...@standardnotes/scheduler-server@1.20.16) (2023-08-02)
**Note:** Version bump only for package @standardnotes/scheduler-server
## [1.20.15](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.20.14...@standardnotes/scheduler-server@1.20.15) (2023-07-27)
**Note:** Version bump only for package @standardnotes/scheduler-server

View File

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

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.21.21](https://github.com/standardnotes/server/compare/@standardnotes/settings@1.21.20...@standardnotes/settings@1.21.21) (2023-08-02)
**Note:** Version bump only for package @standardnotes/settings
## [1.21.20](https://github.com/standardnotes/server/compare/@standardnotes/settings@1.21.19...@standardnotes/settings@1.21.20) (2023-07-27)
**Note:** Version bump only for package @standardnotes/settings

View File

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

View File

@@ -3,6 +3,26 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.75.4](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.75.3...@standardnotes/syncing-server@1.75.4) (2023-08-03)
### Bug Fixes
* **syncing-server:** skip retrieval of items with invalid uuids ([#683](https://github.com/standardnotes/syncing-server-js/issues/683)) ([0036d52](https://github.com/standardnotes/syncing-server-js/commit/0036d527bd31cd81eda59e918b5f897f24cfa340))
## [1.75.3](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.75.2...@standardnotes/syncing-server@1.75.3) (2023-08-03)
**Note:** Version bump only for package @standardnotes/syncing-server
## [1.75.2](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.75.1...@standardnotes/syncing-server@1.75.2) (2023-08-02)
**Note:** Version bump only for package @standardnotes/syncing-server
## [1.75.1](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.75.0...@standardnotes/syncing-server@1.75.1) (2023-08-02)
### Bug Fixes
* **syncing-server:** update unknown content type on items migration ([6aad7cd](https://github.com/standardnotes/syncing-server-js/commit/6aad7cd207dcacd4ee372e7a6e6ebc60a75cea2a))
# [1.75.0](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.74.1...@standardnotes/syncing-server@1.75.0) (2023-08-02)
### Features

View File

@@ -0,0 +1,11 @@
import { MigrationInterface, QueryRunner } from 'typeorm'
export class UpdateUnknownContent1690975361562 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.manager.query('UPDATE items SET content_type = "Note" WHERE content_type = "Unknown"')
}
public async down(): Promise<void> {
return
}
}

View File

@@ -0,0 +1,11 @@
import { MigrationInterface, QueryRunner } from 'typeorm'
export class UpdateUnknownContent1690975207883 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.manager.query('UPDATE items SET content_type = "Note" WHERE content_type = "Unknown"')
}
public async down(): Promise<void> {
return
}
}

View File

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

View File

@@ -402,6 +402,7 @@ export class ContainerConfigLoader {
container.get(TYPES.Sync_ItemPersistenceMapper),
container.get(TYPES.Sync_KeySystemAssociationRepository),
container.get(TYPES.Sync_SharedVaultAssociationRepository),
container.get(TYPES.Sync_Logger),
),
)
container

View File

@@ -1,6 +1,7 @@
import { ReadStream } from 'fs'
import { Repository, SelectQueryBuilder, Brackets } from 'typeorm'
import { Change, MapperInterface, Uuid } from '@standardnotes/domain-core'
import { Logger } from 'winston'
import { Item } from '../../Domain/Item/Item'
import { ItemQuery } from '../../Domain/Item/ItemQuery'
@@ -19,6 +20,7 @@ export class TypeORMItemRepository implements ItemRepositoryInterface {
private mapper: MapperInterface<Item, TypeORMItem>,
private keySystemAssociationRepository: KeySystemAssociationRepositoryInterface,
private sharedVaultAssociationRepository: SharedVaultAssociationRepositoryInterface,
private logger: Logger,
) {}
async save(item: Item): Promise<void> {
@@ -87,11 +89,17 @@ export class TypeORMItemRepository implements ItemRepositoryInterface {
return null
}
const item = this.mapper.toDomain(persistence)
try {
const item = this.mapper.toDomain(persistence)
await this.decorateItemWithAssociations(item)
await this.decorateItemWithAssociations(item)
return item
return item
} catch (error) {
this.logger.error(`Failed to find item ${uuid.value} by uuid: ${(error as Error).message}`)
return null
}
}
async findDatesForComputingIntegrityHash(userUuid: string): Promise<Array<{ updated_at_timestamp: number }>> {
@@ -131,17 +139,30 @@ export class TypeORMItemRepository implements ItemRepositoryInterface {
return null
}
const item = this.mapper.toDomain(persistence)
try {
const item = this.mapper.toDomain(persistence)
await this.decorateItemWithAssociations(item)
await this.decorateItemWithAssociations(item)
return item
return item
} catch (error) {
this.logger.error(`Failed to find item ${uuid} by uuid and userUuid: ${(error as Error).message}`)
return null
}
}
async findAll(query: ItemQuery): Promise<Item[]> {
const persistence = await this.createFindAllQueryBuilder(query).getMany()
const domainItems = persistence.map((p) => this.mapper.toDomain(p))
const domainItems: Item[] = []
for (const persistencItem of persistence) {
try {
domainItems.push(this.mapper.toDomain(persistencItem))
} catch (error) {
this.logger.error(`Failed to map item ${persistencItem.uuid} to domain: ${(error as Error).message}`)
}
}
await Promise.all(domainItems.map((item) => this.decorateItemWithAssociations(item)))

View File

@@ -6,6 +6,12 @@ import { TypeORMItem } from '../../Infra/TypeORM/TypeORMItem'
export class ItemPersistenceMapper implements MapperInterface<Item, TypeORMItem> {
toDomain(projection: TypeORMItem): Item {
const uuidOrError = Uuid.create(projection.uuid)
if (uuidOrError.isFailed()) {
throw new Error(`Failed to create item from projection: ${uuidOrError.getError()}`)
}
const uuid = uuidOrError.getValue()
let duplicateOf = null
if (projection.duplicateOf) {
const duplicateOfOrError = Uuid.create(projection.duplicateOf)
@@ -63,7 +69,7 @@ export class ItemPersistenceMapper implements MapperInterface<Item, TypeORMItem>
timestamps,
updatedWithSession,
},
new UniqueEntityId(projection.uuid),
new UniqueEntityId(uuid.value),
)
if (itemOrError.isFailed()) {
throw new Error(`Failed to create item from projection: ${itemOrError.getError()}`)

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.12](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.10.11...@standardnotes/websockets-server@1.10.12) (2023-08-03)
**Note:** Version bump only for package @standardnotes/websockets-server
## [1.10.11](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.10.10...@standardnotes/websockets-server@1.10.11) (2023-08-02)
**Note:** Version bump only for package @standardnotes/websockets-server
## [1.10.10](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.10.9...@standardnotes/websockets-server@1.10.10) (2023-08-02)
**Note:** Version bump only for package @standardnotes/websockets-server

View File

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