Compare commits

...

14 Commits

Author SHA1 Message Date
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
standardci
63af335877 chore(release): publish new version
- @standardnotes/auth-server@1.128.0
 - @standardnotes/home-server@1.13.25
 - @standardnotes/revisions-server@1.26.0
 - @standardnotes/syncing-server@1.75.0
2023-08-02 08:09:24 +00:00
Karol Sójko
8cd7a138ab feat: enable Write Ahead Log mode for SQLite (#681)
Co-authored-by: Karol Sójko <karolsojko@proton.me>
2023-08-02 09:47:37 +02:00
standardci
f69cdc7b03 chore(release): publish new version
- @standardnotes/home-server@1.13.24
 - @standardnotes/syncing-server@1.74.1
 - @standardnotes/websockets-server@1.10.10
2023-08-02 07:35:12 +00:00
Karol Sójko
2ca649cf31 fix(syncing-server): encapsulate delete queries into transactions 2023-08-02 08:35:19 +02:00
Mo
f2ada08201 chore: remove unused package (#680) 2023-08-02 07:46:10 +02:00
Mo
54ba1f69e5 chore: bump mocha timeout 2023-08-01 16:46:19 -05:00
standardci
f13a99f5fd chore(release): publish new version
- @standardnotes/home-server@1.13.23
 - @standardnotes/syncing-server@1.74.0
2023-08-01 16:32:29 +00:00
Karol Sójko
e9bba6fd3a feat(syncing-server): remove legacy privileges items (#679)
Co-authored-by: Karol Sójko <karolsojko@proton.me>
2023-08-01 18:15:16 +02:00
53 changed files with 502 additions and 103 deletions

View File

@@ -50,7 +50,7 @@ jobs:
run: docker/is-available.sh http://localhost:3123 $(pwd)/logs
- name: Run E2E Test Suite
run: yarn dlx mocha-headless-chrome --timeout 1200000 -f http://localhost:9001/mocha/test.html
run: yarn dlx mocha-headless-chrome --timeout 1800000 -f http://localhost:9001/mocha/test.html
- name: Show logs on failure
if: ${{ failure() }}
@@ -145,7 +145,7 @@ jobs:
run: for i in {1..30}; do curl -s http://localhost:3123/healthcheck && break || sleep 1; done
- name: Run E2E Test Suite
run: yarn dlx mocha-headless-chrome --timeout 1200000 -f http://localhost:9001/mocha/test.html
run: yarn dlx mocha-headless-chrome --timeout 1800000 -f http://localhost:9001/mocha/test.html
- name: Show logs on failure
if: ${{ failure() }}

1
.pnp.cjs generated
View File

@@ -5259,7 +5259,6 @@ const RAW_RUNTIME_STATE =
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@standardnotes/responses", "npm:1.13.27"],\
["@standardnotes/security", "workspace:packages/security"],\
["@standardnotes/utils", "npm:1.17.5"],\
["@types/cors", "npm:2.8.13"],\
["@types/express", "npm:4.17.17"],\
["@types/ioredis", "npm:5.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.
## [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,22 @@
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
* enable Write Ahead Log mode for SQLite ([#681](https://github.com/standardnotes/server/issues/681)) ([8cd7a13](https://github.com/standardnotes/server/commit/8cd7a138ab56f6a2b0d6c06ef6041ab9b85ae540))
## [1.127.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.127.1...@standardnotes/auth-server@1.127.2) (2023-08-01)
### Bug Fixes

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/auth-server",
"version": "1.127.2",
"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

@@ -114,6 +114,8 @@ export class AppDataSource {
...commonDataSourceOptions,
type: 'sqlite',
database: this.env.get('DB_SQLITE_DATABASE_PATH'),
enableWAL: true,
busyErrorRetry: 2000,
}
this._dataSource = new DataSource(sqliteDataSourceOptions)

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,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [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
## [1.13.24](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.23...@standardnotes/home-server@1.13.24) (2023-08-02)
**Note:** Version bump only for package @standardnotes/home-server
## [1.13.23](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.22...@standardnotes/home-server@1.13.23) (2023-08-01)
**Note:** Version bump only for package @standardnotes/home-server
## [1.13.22](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.13.21...@standardnotes/home-server@1.13.22) (2023-08-01)
**Note:** Version bump only for package @standardnotes/home-server

View File

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

View File

@@ -3,6 +3,20 @@
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
* enable Write Ahead Log mode for SQLite ([#681](https://github.com/standardnotes/server/issues/681)) ([8cd7a13](https://github.com/standardnotes/server/commit/8cd7a138ab56f6a2b0d6c06ef6041ab9b85ae540))
## [1.25.7](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.25.6...@standardnotes/revisions-server@1.25.7) (2023-08-01)
### Bug Fixes

View File

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

View File

@@ -80,6 +80,8 @@ export class AppDataSource {
...commonDataSourceOptions,
type: 'sqlite',
database: this.env.get('DB_SQLITE_DATABASE_PATH'),
enableWAL: true,
busyErrorRetry: 2000,
}
this.dataSource = new DataSource(sqliteDataSourceOptions)

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,38 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [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
* enable Write Ahead Log mode for SQLite ([#681](https://github.com/standardnotes/syncing-server-js/issues/681)) ([8cd7a13](https://github.com/standardnotes/syncing-server-js/commit/8cd7a138ab56f6a2b0d6c06ef6041ab9b85ae540))
## [1.74.1](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.74.0...@standardnotes/syncing-server@1.74.1) (2023-08-02)
### Bug Fixes
* **syncing-server:** encapsulate delete queries into transactions ([2ca649c](https://github.com/standardnotes/syncing-server-js/commit/2ca649cf314617f01107f8479928df1581c924db))
# [1.74.0](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.73.1...@standardnotes/syncing-server@1.74.0) (2023-08-01)
### Features
* **syncing-server:** remove legacy privileges items ([#679](https://github.com/standardnotes/syncing-server-js/issues/679)) ([e9bba6f](https://github.com/standardnotes/syncing-server-js/commit/e9bba6fd3acfde62c3063160ba3ec3aa83c45b31))
## [1.73.1](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.73.0...@standardnotes/syncing-server@1.73.1) (2023-08-01)
### Bug Fixes

View File

@@ -0,0 +1,23 @@
import { MigrationInterface, QueryRunner } from 'typeorm'
export class DeletePrivileges1690900526061 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
const itemsWithPrivilegesContentTypeQueryResult = await queryRunner.manager.query(
'SELECT COUNT(*) as count FROM items i WHERE i.content_type = "SN|Privileges"',
)
const itemsWithPrivilegesContentTypeCount = +itemsWithPrivilegesContentTypeQueryResult[0].count
const batchSize = 1_000
const batchCount = Math.ceil(itemsWithPrivilegesContentTypeCount / batchSize)
for (let batchIndex = 0; batchIndex < batchCount; batchIndex++) {
await queryRunner.startTransaction()
await queryRunner.manager.query(`DELETE FROM items WHERE content_type = "SN|Privileges" LIMIT ${batchSize}`)
await queryRunner.commitTransaction()
}
}
public async down(): Promise<void> {
return
}
}

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,23 @@
import { MigrationInterface, QueryRunner } from 'typeorm'
export class DeletePrivileges1690901030484 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
const itemsWithPrivilegesContentTypeQueryResult = await queryRunner.manager.query(
'SELECT COUNT(*) as count FROM items i WHERE i.content_type = "SN|Privileges"',
)
const itemsWithPrivilegesContentTypeCount = +itemsWithPrivilegesContentTypeQueryResult[0].count
const batchSize = 1_000
const batchCount = Math.ceil(itemsWithPrivilegesContentTypeCount / batchSize)
for (let batchIndex = 0; batchIndex < batchCount; batchIndex++) {
await queryRunner.startTransaction()
await queryRunner.manager.query(`DELETE FROM items WHERE content_type = "SN|Privileges" LIMIT ${batchSize}`)
await queryRunner.commitTransaction()
}
}
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.73.1",
"version": "1.75.3",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -98,6 +98,8 @@ export class AppDataSource {
...commonDataSourceOptions,
type: 'sqlite',
database: this.env.get('DB_SQLITE_DATABASE_PATH'),
enableWAL: true,
busyErrorRetry: 2000,
}
this._dataSource = new DataSource(sqliteDataSourceOptions)

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.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
## [1.10.9](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.10.8...@standardnotes/websockets-server@1.10.9) (2023-08-01)
### Bug Fixes

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/websockets-server",
"version": "1.10.9",
"version": "1.10.12",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
@@ -30,7 +30,6 @@
"@standardnotes/domain-events-infra": "workspace:^",
"@standardnotes/responses": "^1.13.27",
"@standardnotes/security": "workspace:^",
"@standardnotes/utils": "^1.17.5",
"axios": "^1.1.3",
"cors": "2.8.5",
"dotenv": "^16.0.1",

View File

@@ -4171,7 +4171,6 @@ __metadata:
"@standardnotes/domain-events-infra": "workspace:^"
"@standardnotes/responses": "npm:^1.13.27"
"@standardnotes/security": "workspace:^"
"@standardnotes/utils": "npm:^1.17.5"
"@types/cors": "npm:^2.8.9"
"@types/express": "npm:^4.17.14"
"@types/ioredis": "npm:^5.0.0"