Compare commits

..

29 Commits

Author SHA1 Message Date
standardci
7e74261f62 chore(release): publish new version
- @standardnotes/analytics@2.12.17
 - @standardnotes/api-gateway@1.39.21
 - @standardnotes/auth-server@1.66.3
 - @standardnotes/domain-events-infra@1.9.51
 - @standardnotes/domain-events@2.102.0
 - @standardnotes/event-store@1.6.48
 - @standardnotes/files-server@1.8.47
 - @standardnotes/revisions-server@1.9.20
 - @standardnotes/scheduler-server@1.15.1
 - @standardnotes/syncing-server@1.24.0
 - @standardnotes/websockets-server@1.4.48
 - @standardnotes/workspace-server@1.17.47
2022-12-09 13:11:30 +00:00
Karol Sójko
32601f34f1 feat(syncing-server): replace email backup attachment created with email requested 2022-12-09 14:09:30 +01:00
standardci
aef69a1a96 chore(release): publish new version
- @standardnotes/analytics@2.12.16
 - @standardnotes/api-gateway@1.39.20
 - @standardnotes/auth-server@1.66.2
 - @standardnotes/domain-events-infra@1.9.50
 - @standardnotes/domain-events@2.101.0
 - @standardnotes/event-store@1.6.47
 - @standardnotes/files-server@1.8.46
 - @standardnotes/revisions-server@1.9.19
 - @standardnotes/scheduler-server@1.15.0
 - @standardnotes/syncing-server@1.23.0
 - @standardnotes/websockets-server@1.4.47
 - @standardnotes/workspace-server@1.17.46
2022-12-09 10:22:39 +00:00
Karol Sójko
130f90bdb6 feat(syncing-server): replace one drive backup failed event with email requested 2022-12-09 11:20:34 +01:00
standardci
851c7de87f chore(release): publish new version
- @standardnotes/syncing-server@1.22.0
2022-12-09 09:35:39 +00:00
Karol Sójko
118156c62d feat(syncing-serfver): remove dropbox backup failed event in favour of email requested 2022-12-09 10:33:40 +01:00
standardci
cdad3143c9 chore(release): publish new version
- @standardnotes/analytics@2.12.15
 - @standardnotes/api-gateway@1.39.19
 - @standardnotes/auth-server@1.66.1
 - @standardnotes/domain-events-infra@1.9.49
 - @standardnotes/domain-events@2.100.0
 - @standardnotes/event-store@1.6.46
 - @standardnotes/files-server@1.8.45
 - @standardnotes/revisions-server@1.9.18
 - @standardnotes/scheduler-server@1.14.10
 - @standardnotes/syncing-server@1.21.0
 - @standardnotes/websockets-server@1.4.46
 - @standardnotes/workspace-server@1.17.45
2022-12-09 09:28:27 +00:00
Karol Sójko
00fe32136e feat(syncing-server): remove google drive backup failed event in favour of email requested 2022-12-09 10:26:13 +01:00
standardci
52f56eeb68 chore(release): publish new version
- @standardnotes/auth-server@1.66.0
2022-12-09 09:17:28 +00:00
Karol Sójko
b595264e31 feat(email): replace offline subscription token created event in favour of email requested 2022-12-09 10:15:33 +01:00
standardci
bf04262170 chore(release): publish new version
- @standardnotes/analytics@2.12.14
 - @standardnotes/api-gateway@1.39.18
 - @standardnotes/auth-server@1.65.0
 - @standardnotes/domain-events-infra@1.9.48
 - @standardnotes/domain-events@2.99.0
 - @standardnotes/event-store@1.6.45
 - @standardnotes/files-server@1.8.44
 - @standardnotes/revisions-server@1.9.17
 - @standardnotes/scheduler-server@1.14.9
 - @standardnotes/syncing-server@1.20.17
 - @standardnotes/websockets-server@1.4.45
 - @standardnotes/workspace-server@1.17.44
2022-12-09 09:03:31 +00:00
Karol Sójko
fd589922bb feat(auth): remove offline subscription token created event in favour of email requested 2022-12-09 10:01:38 +01:00
standardci
fb7029f5c1 chore(release): publish new version
- @standardnotes/analytics@2.12.13
 - @standardnotes/api-gateway@1.39.17
 - @standardnotes/auth-server@1.64.7
 - @standardnotes/domain-events-infra@1.9.47
 - @standardnotes/domain-events@2.98.4
 - @standardnotes/event-store@1.6.44
 - @standardnotes/files-server@1.8.43
 - @standardnotes/revisions-server@1.9.16
 - @standardnotes/scheduler-server@1.14.8
 - @standardnotes/syncing-server@1.20.16
 - @standardnotes/websockets-server@1.4.44
 - @standardnotes/workspace-server@1.17.43
2022-12-09 07:54:49 +00:00
Karol Sójko
cc4b4f9bf8 fix(domain-events): remove unused event 2022-12-09 08:52:51 +01:00
standardci
b048d6d7e3 chore(release): publish new version
- @standardnotes/analytics@2.12.12
 - @standardnotes/api-gateway@1.39.16
 - @standardnotes/auth-server@1.64.6
 - @standardnotes/domain-events-infra@1.9.46
 - @standardnotes/domain-events@2.98.3
 - @standardnotes/event-store@1.6.43
 - @standardnotes/files-server@1.8.42
 - @standardnotes/revisions-server@1.9.15
 - @standardnotes/scheduler-server@1.14.7
 - @standardnotes/syncing-server@1.20.15
 - @standardnotes/websockets-server@1.4.43
 - @standardnotes/workspace-server@1.17.42
2022-12-08 14:03:38 +00:00
Karol Sójko
cffc1f442f fix(domain-events): remove unused event 2022-12-08 15:01:44 +01:00
standardci
91fe710741 chore(release): publish new version
- @standardnotes/analytics@2.12.11
 - @standardnotes/api-gateway@1.39.15
 - @standardnotes/auth-server@1.64.5
 - @standardnotes/domain-events-infra@1.9.45
 - @standardnotes/domain-events@2.98.2
 - @standardnotes/event-store@1.6.42
 - @standardnotes/files-server@1.8.41
 - @standardnotes/revisions-server@1.9.14
 - @standardnotes/scheduler-server@1.14.6
 - @standardnotes/syncing-server@1.20.14
 - @standardnotes/websockets-server@1.4.42
 - @standardnotes/workspace-server@1.17.41
2022-12-08 13:55:05 +00:00
Karol Sójko
5a1eb9fdac fix(domain-events): remove unused event 2022-12-08 14:53:07 +01:00
standardci
a64ef6e750 chore(release): publish new version
- @standardnotes/analytics@2.12.10
 - @standardnotes/api-gateway@1.39.14
 - @standardnotes/auth-server@1.64.4
 - @standardnotes/domain-events-infra@1.9.44
 - @standardnotes/domain-events@2.98.1
 - @standardnotes/event-store@1.6.41
 - @standardnotes/files-server@1.8.40
 - @standardnotes/revisions-server@1.9.13
 - @standardnotes/scheduler-server@1.14.5
 - @standardnotes/syncing-server@1.20.13
 - @standardnotes/websockets-server@1.4.41
 - @standardnotes/workspace-server@1.17.40
2022-12-08 13:49:54 +00:00
Karol Sójko
47d2012b3d fix(domain-events): remove unused event 2022-12-08 14:47:39 +01:00
standardci
2c99cd2e21 chore(release): publish new version
- @standardnotes/analytics@2.12.9
 - @standardnotes/api-gateway@1.39.13
 - @standardnotes/auth-server@1.64.3
 - @standardnotes/domain-events-infra@1.9.43
 - @standardnotes/domain-events@2.98.0
 - @standardnotes/event-store@1.6.40
 - @standardnotes/files-server@1.8.39
 - @standardnotes/revisions-server@1.9.12
 - @standardnotes/scheduler-server@1.14.4
 - @standardnotes/syncing-server@1.20.12
 - @standardnotes/websockets-server@1.4.40
 - @standardnotes/workspace-server@1.17.39
2022-12-08 10:01:57 +00:00
Karol Sójko
435cd2f66a feat(domain-events): remove unused events and add attachments option for sending emails 2022-12-08 11:00:02 +01:00
standardci
372b12dfc2 chore(release): publish new version
- @standardnotes/analytics@2.12.8
 - @standardnotes/api-gateway@1.39.12
 - @standardnotes/auth-server@1.64.2
 - @standardnotes/domain-events-infra@1.9.42
 - @standardnotes/domain-events@2.97.0
 - @standardnotes/event-store@1.6.39
 - @standardnotes/files-server@1.8.38
 - @standardnotes/revisions-server@1.9.11
 - @standardnotes/scheduler-server@1.14.3
 - @standardnotes/syncing-server@1.20.11
 - @standardnotes/websockets-server@1.4.39
 - @standardnotes/workspace-server@1.17.38
2022-12-08 09:13:34 +00:00
Karol Sójko
3a12f5c1c4 feat(domain-events): remove unused account reset requested event 2022-12-08 10:11:14 +01:00
standardci
781de224b6 chore(release): publish new version
- @standardnotes/event-store@1.6.38
2022-12-07 14:36:38 +00:00
Karol Sójko
eff09454c3 fix(event-store): add email requested subscription 2022-12-07 15:34:41 +01:00
Karol Sójko
473feba6a8 fix(event-store): reduce handlers 2022-12-07 15:34:41 +01:00
standardci
e9f0704fb0 chore(release): publish new version
- @standardnotes/auth-server@1.64.1
2022-12-07 14:00:14 +00:00
Mo
8c99469d88 refactor: future-proof code verifier check on sign in (#363) 2022-12-07 07:58:26 -06:00
89 changed files with 934 additions and 464 deletions

6
.prettierrc Normal file
View File

@@ -0,0 +1,6 @@
{
"singleQuote": true,
"trailingComma": "all",
"printWidth": 120,
"semi": false
}

View File

@@ -3,6 +3,46 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.12.17](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.16...@standardnotes/analytics@2.12.17) (2022-12-09)
**Note:** Version bump only for package @standardnotes/analytics
## [2.12.16](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.15...@standardnotes/analytics@2.12.16) (2022-12-09)
**Note:** Version bump only for package @standardnotes/analytics
## [2.12.15](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.14...@standardnotes/analytics@2.12.15) (2022-12-09)
**Note:** Version bump only for package @standardnotes/analytics
## [2.12.14](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.13...@standardnotes/analytics@2.12.14) (2022-12-09)
**Note:** Version bump only for package @standardnotes/analytics
## [2.12.13](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.12...@standardnotes/analytics@2.12.13) (2022-12-09)
**Note:** Version bump only for package @standardnotes/analytics
## [2.12.12](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.11...@standardnotes/analytics@2.12.12) (2022-12-08)
**Note:** Version bump only for package @standardnotes/analytics
## [2.12.11](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.10...@standardnotes/analytics@2.12.11) (2022-12-08)
**Note:** Version bump only for package @standardnotes/analytics
## [2.12.10](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.9...@standardnotes/analytics@2.12.10) (2022-12-08)
**Note:** Version bump only for package @standardnotes/analytics
## [2.12.9](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.8...@standardnotes/analytics@2.12.9) (2022-12-08)
**Note:** Version bump only for package @standardnotes/analytics
## [2.12.8](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.7...@standardnotes/analytics@2.12.8) (2022-12-08)
**Note:** Version bump only for package @standardnotes/analytics
## [2.12.7](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.6...@standardnotes/analytics@2.12.7) (2022-12-07)
**Note:** Version bump only for package @standardnotes/analytics

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/analytics",
"version": "2.12.7",
"version": "2.12.17",
"engines": {
"node": ">=18.0.0 <19.0.0"
},

View File

@@ -3,6 +3,46 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.39.21](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.39.20...@standardnotes/api-gateway@1.39.21) (2022-12-09)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.39.20](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.39.19...@standardnotes/api-gateway@1.39.20) (2022-12-09)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.39.19](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.39.18...@standardnotes/api-gateway@1.39.19) (2022-12-09)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.39.18](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.39.17...@standardnotes/api-gateway@1.39.18) (2022-12-09)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.39.17](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.39.16...@standardnotes/api-gateway@1.39.17) (2022-12-09)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.39.16](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.39.15...@standardnotes/api-gateway@1.39.16) (2022-12-08)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.39.15](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.39.14...@standardnotes/api-gateway@1.39.15) (2022-12-08)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.39.14](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.39.13...@standardnotes/api-gateway@1.39.14) (2022-12-08)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.39.13](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.39.12...@standardnotes/api-gateway@1.39.13) (2022-12-08)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.39.12](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.39.11...@standardnotes/api-gateway@1.39.12) (2022-12-08)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.39.11](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.39.10...@standardnotes/api-gateway@1.39.11) (2022-12-07)
**Note:** Version bump only for package @standardnotes/api-gateway

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/api-gateway",
"version": "1.39.11",
"version": "1.39.21",
"engines": {
"node": ">=18.0.0 <19.0.0"
},

View File

@@ -3,6 +3,58 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.66.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.66.2...@standardnotes/auth-server@1.66.3) (2022-12-09)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.66.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.66.1...@standardnotes/auth-server@1.66.2) (2022-12-09)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.66.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.66.0...@standardnotes/auth-server@1.66.1) (2022-12-09)
**Note:** Version bump only for package @standardnotes/auth-server
# [1.66.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.65.0...@standardnotes/auth-server@1.66.0) (2022-12-09)
### Features
* **email:** replace offline subscription token created event in favour of email requested ([b595264](https://github.com/standardnotes/server/commit/b595264e313ac5ae5404f6a4a05b90b8c11f7f02))
# [1.65.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.64.7...@standardnotes/auth-server@1.65.0) (2022-12-09)
### Features
* **auth:** remove offline subscription token created event in favour of email requested ([fd58992](https://github.com/standardnotes/server/commit/fd589922bba29595a0dfd154a42fe158024fad28))
## [1.64.7](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.64.6...@standardnotes/auth-server@1.64.7) (2022-12-09)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.64.6](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.64.5...@standardnotes/auth-server@1.64.6) (2022-12-08)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.64.5](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.64.4...@standardnotes/auth-server@1.64.5) (2022-12-08)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.64.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.64.3...@standardnotes/auth-server@1.64.4) (2022-12-08)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.64.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.64.2...@standardnotes/auth-server@1.64.3) (2022-12-08)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.64.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.64.1...@standardnotes/auth-server@1.64.2) (2022-12-08)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.64.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.64.0...@standardnotes/auth-server@1.64.1) (2022-12-07)
**Note:** Version bump only for package @standardnotes/auth-server
# [1.64.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.63.2...@standardnotes/auth-server@1.64.0) (2022-12-07)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/auth-server",
"version": "1.64.0",
"version": "1.66.3",
"engines": {
"node": ">=18.0.0 <19.0.0"
},

View File

@@ -0,0 +1,9 @@
import { html } from './offline-subscription-token-created.html'
export function getSubject(): string {
return 'Access to your Standard Notes Subscription Dashboard'
}
export function getBody(email: string, offlineSubscriptionDashboardUrl: string): string {
return html(email, offlineSubscriptionDashboardUrl)
}

View File

@@ -0,0 +1,9 @@
import { html } from './shared-subscription-invitation-created.html'
export function getSubject(): string {
return 'You have been invited to a Standard Notes subscription'
}
export function getBody(inviterIdentifier: string, inviteUuid: string): string {
return html(inviterIdentifier, inviteUuid)
}

View File

@@ -5,11 +5,5 @@ export function getSubject(email: string): string {
}
export function getBody(email: string, device: string, browser: string, date: Date): string {
const body = html
return body
.replace('%%EMAIL%%', email)
.replace('%%DEVICE%%', device)
.replace('%%BROWSER%%', browser)
.replace('%%TIME_AND_DATE%%', date.toLocaleString())
return html(email, device, browser, date.toLocaleString())
}

View File

@@ -0,0 +1,24 @@
export const html = (userEmail: string, offlineSubscriptionDashboardUrl: string) => `<div class="sn-component">
<div class="sk-panel static">
<div class="sk-panel-content">
<div class="sk-panel-section">
<h1 class="h1 title sk-panel-row">
<div class="sk-panel-column">
Access your Standard Notes Subscription Dashboard,
</div>
</h1>
<div class="faded sk-panel-row small">Registered as ${userEmail}</div>
</div>
<div class="sk-panel-section">
<div class="title">Link to your subscription dashboard: <a
href="${offlineSubscriptionDashboardUrl}">${offlineSubscriptionDashboardUrl}</a></div>
</div>
<div class="sk-panel-section">
<p>
Get help any time by visiting our <a href="https://standardnotes.com/help">Help page</a>
or by replying directly to this email.
</p>
</div>
</div>
</div>
</div>`

View File

@@ -0,0 +1,5 @@
export const html = (inviterIdentifier: string, inviteUuid: string) => `<p>Hello,</p>
<p>You've been invited to join a Standard Notes premium subscription at no cost. ${inviterIdentifier} has invited you to share the benefits of their subscription plan.</p>
<p>
<a href='https://app.standardnotes.com/?accept-subscription-invite=${inviteUuid}'>Accept Invite</a>
</p>`

View File

@@ -1,15 +1,15 @@
export const html = `
export const html = (email: string, device: string, browser: string, timeAndDate: string) => `
<div>
<p>Hello,</p>
<p>We've detected a new sign-in to your account %%EMAIL%%.</p>
<p>We've detected a new sign-in to your account ${email}</p>
<p>
<b>Device type</b>: %%DEVICE%%
<b>Device type</b>: ${device}
</p>
<p>
<b>Browser type</b>: %%BROWSER%%
<b>Browser type</b>: ${browser}
</p>
<p>
<strong>Time and date</strong>: <span>%%TIME_AND_DATE%%</span>
<strong>Time and date</strong>: <span>${timeAndDate}</span>
</p>
<p>
If this was you, please disregard this email. If it wasn't you, we recommend signing into your account and

View File

@@ -6,7 +6,6 @@ import {
UserEmailChangedEvent,
UserRegisteredEvent,
UserRolesChangedEvent,
OfflineSubscriptionTokenCreatedEvent,
EmailBackupRequestedEvent,
CloudBackupRequestedEvent,
ListedAccountRequestedEvent,
@@ -290,24 +289,6 @@ export class DomainEventFactory implements DomainEventFactoryInterface {
}
}
createOfflineSubscriptionTokenCreatedEvent(token: string, email: string): OfflineSubscriptionTokenCreatedEvent {
return {
type: 'OFFLINE_SUBSCRIPTION_TOKEN_CREATED',
createdAt: this.timer.getUTCDate(),
meta: {
correlation: {
userIdentifier: email,
userIdentifierType: 'email',
},
origin: DomainEventService.Auth,
},
payload: {
token,
email,
},
}
}
createUserRegisteredEvent(dto: {
userUuid: string
email: string

View File

@@ -6,7 +6,6 @@ import {
UserRegisteredEvent,
UserRolesChangedEvent,
UserEmailChangedEvent,
OfflineSubscriptionTokenCreatedEvent,
EmailBackupRequestedEvent,
ListedAccountRequestedEvent,
UserDisabledSessionUserAgentLoggingEvent,
@@ -56,7 +55,6 @@ export interface DomainEventFactoryInterface {
}): AccountDeletionRequestedEvent
createUserRolesChangedEvent(userUuid: string, email: string, currentRoles: RoleName[]): UserRolesChangedEvent
createUserEmailChangedEvent(userUuid: string, fromEmail: string, toEmail: string): UserEmailChangedEvent
createOfflineSubscriptionTokenCreatedEvent(token: string, email: string): OfflineSubscriptionTokenCreatedEvent
createUserDisabledSessionUserAgentLoggingEvent(dto: {
userUuid: Uuid
email: string

View File

@@ -5,7 +5,7 @@ import { TimerInterface } from '@standardnotes/time'
import { OfflineSubscriptionTokenRepositoryInterface } from '../../Auth/OfflineSubscriptionTokenRepositoryInterface'
import { CreateOfflineSubscriptionToken } from './CreateOfflineSubscriptionToken'
import { DomainEventPublisherInterface, OfflineSubscriptionTokenCreatedEvent } from '@standardnotes/domain-events'
import { DomainEventPublisherInterface, EmailRequestedEvent } from '@standardnotes/domain-events'
import { DomainEventFactoryInterface } from '../../Event/DomainEventFactoryInterface'
import { OfflineUserSubscriptionRepositoryInterface } from '../../Subscription/OfflineUserSubscriptionRepositoryInterface'
import { OfflineUserSubscription } from '../../Subscription/OfflineUserSubscription'
@@ -47,9 +47,9 @@ describe('CreateOfflineSubscriptionToken', () => {
domainEventPublisher.publish = jest.fn()
domainEventFactory = {} as jest.Mocked<DomainEventFactoryInterface>
domainEventFactory.createOfflineSubscriptionTokenCreatedEvent = jest
domainEventFactory.createEmailRequestedEvent = jest
.fn()
.mockReturnValue({} as jest.Mocked<OfflineSubscriptionTokenCreatedEvent>)
.mockReturnValue({} as jest.Mocked<EmailRequestedEvent>)
timer = {} as jest.Mocked<TimerInterface>
timer.convertStringDateToMicroseconds = jest.fn().mockReturnValue(1)
@@ -71,10 +71,7 @@ describe('CreateOfflineSubscriptionToken', () => {
expiresAt: 1,
})
expect(domainEventFactory.createOfflineSubscriptionTokenCreatedEvent).toHaveBeenCalledWith(
'random-string',
'test@test.com',
)
expect(domainEventFactory.createEmailRequestedEvent).toHaveBeenCalled()
expect(domainEventPublisher.publish).toHaveBeenCalled()
})
@@ -91,7 +88,7 @@ describe('CreateOfflineSubscriptionToken', () => {
})
expect(offlineSubscriptionTokenRepository.save).not.toHaveBeenCalled()
expect(domainEventFactory.createOfflineSubscriptionTokenCreatedEvent).not.toHaveBeenCalled()
expect(domainEventFactory.createEmailRequestedEvent).not.toHaveBeenCalled()
expect(domainEventPublisher.publish).not.toHaveBeenCalled()
})
@@ -110,7 +107,7 @@ describe('CreateOfflineSubscriptionToken', () => {
})
expect(offlineSubscriptionTokenRepository.save).not.toHaveBeenCalled()
expect(domainEventFactory.createOfflineSubscriptionTokenCreatedEvent).not.toHaveBeenCalled()
expect(domainEventFactory.createEmailRequestedEvent).not.toHaveBeenCalled()
expect(domainEventPublisher.publish).not.toHaveBeenCalled()
})
@@ -129,7 +126,7 @@ describe('CreateOfflineSubscriptionToken', () => {
})
expect(offlineSubscriptionTokenRepository.save).not.toHaveBeenCalled()
expect(domainEventFactory.createOfflineSubscriptionTokenCreatedEvent).not.toHaveBeenCalled()
expect(domainEventFactory.createEmailRequestedEvent).not.toHaveBeenCalled()
expect(domainEventPublisher.publish).not.toHaveBeenCalled()
})
})

View File

@@ -1,4 +1,5 @@
import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
import { EmailLevel } from '@standardnotes/domain-core'
import { CryptoNode } from '@standardnotes/sncrypto-node'
import { TimerInterface } from '@standardnotes/time'
import { inject, injectable } from 'inversify'
@@ -6,6 +7,7 @@ import { Logger } from 'winston'
import TYPES from '../../../Bootstrap/Types'
import { OfflineSubscriptionTokenRepositoryInterface } from '../../Auth/OfflineSubscriptionTokenRepositoryInterface'
import { getBody, getSubject } from '../../Email/OfflineSubscriptionTokenCreated'
import { DomainEventFactoryInterface } from '../../Event/DomainEventFactoryInterface'
import { OfflineUserSubscriptionRepositoryInterface } from '../../Subscription/OfflineUserSubscriptionRepositoryInterface'
import { UseCaseInterface } from '../UseCaseInterface'
@@ -62,7 +64,13 @@ export class CreateOfflineSubscriptionToken implements UseCaseInterface {
await this.offlineSubscriptionTokenRepository.save(offlineSubscriptionToken)
await this.domainEventPublisher.publish(
this.domainEventFactory.createOfflineSubscriptionTokenCreatedEvent(token, dto.userEmail),
this.domainEventFactory.createEmailRequestedEvent({
body: getBody(dto.userEmail, `https://standardnotes.com/dashboard/offline?subscription_token=${token}`),
level: EmailLevel.LEVELS.System,
subject: getSubject(),
messageIdentifier: 'OFFLINE_SUBSCRIPTION_ACCESS',
userEmail: dto.userEmail,
}),
)
return {

View File

@@ -1,6 +1,10 @@
import 'reflect-metadata'
import { DomainEventPublisherInterface, SharedSubscriptionInvitationCreatedEvent } from '@standardnotes/domain-events'
import {
DomainEventPublisherInterface,
SharedSubscriptionInvitationCreatedEvent,
EmailRequestedEvent,
} from '@standardnotes/domain-events'
import { TimerInterface } from '@standardnotes/time'
import { DomainEventFactoryInterface } from '../../Event/DomainEventFactoryInterface'
import { SharedSubscriptionInvitationRepositoryInterface } from '../../SharedSubscription/SharedSubscriptionInvitationRepositoryInterface'
@@ -51,6 +55,7 @@ describe('InviteToSharedSubscription', () => {
domainEventFactory.createSharedSubscriptionInvitationCreatedEvent = jest
.fn()
.mockReturnValue({} as jest.Mocked<SharedSubscriptionInvitationCreatedEvent>)
domainEventFactory.createEmailRequestedEvent = jest.fn().mockReturnValue({} as jest.Mocked<EmailRequestedEvent>)
})
it('should not create an inivitation for sharing the subscription if inviter has no subscription', async () => {

View File

@@ -1,9 +1,11 @@
import { RoleName } from '@standardnotes/common'
import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
import { EmailLevel } from '@standardnotes/domain-core'
import { TimerInterface } from '@standardnotes/time'
import { inject, injectable } from 'inversify'
import TYPES from '../../../Bootstrap/Types'
import { getBody, getSubject } from '../../Email/SharedSubscriptionInvitationCreated'
import { DomainEventFactoryInterface } from '../../Event/DomainEventFactoryInterface'
import { InvitationStatus } from '../../SharedSubscription/InvitationStatus'
import { InviteeIdentifierType } from '../../SharedSubscription/InviteeIdentifierType'
@@ -89,6 +91,16 @@ export class InviteToSharedSubscription implements UseCaseInterface {
}),
)
await this.domainEventPublisher.publish(
this.domainEventFactory.createEmailRequestedEvent({
userEmail: dto.inviteeIdentifier,
level: EmailLevel.LEVELS.System,
body: getBody(dto.inviterEmail, savedInvitation.uuid),
messageIdentifier: 'SHARED_SUBSCRIPTION_INVITATION',
subject: getSubject(),
}),
)
return {
success: true,
sharedSubscriptionInvitationUuid: savedInvitation.uuid,

View File

@@ -98,7 +98,29 @@ describe('SignIn', () => {
expect(domainEventPublisher.publish).toHaveBeenCalled()
})
it('should not sign in a user without code verifier', async () => {
it('should not sign in 004 user without code verifier', async () => {
expect(
await createUseCase().execute({
email: 'test@test.te',
password: 'qweqwe123123',
userAgent: 'Google Chrome',
apiVersion: '20190520',
ephemeralSession: false,
}),
).toEqual({
success: false,
errorCode: 410,
errorMessage: 'Please update your client application.',
})
})
it('should not sign in 005 user without code verifier', async () => {
user = {
uuid: '1-2-3',
email: 'test@test.com',
version: '005',
} as jest.Mocked<User>
expect(
await createUseCase().execute({
email: 'test@test.te',

View File

@@ -15,7 +15,7 @@ import { UseCaseInterface } from './UseCaseInterface'
import { PKCERepositoryInterface } from '../User/PKCERepositoryInterface'
import { CrypterInterface } from '../Encryption/CrypterInterface'
import { SignInDTOV2Challenged } from './SignInDTOV2Challenged'
import { ProtocolVersion } from '@standardnotes/common'
import { leftVersionGreaterThanOrEqualToRight, ProtocolVersion } from '@standardnotes/common'
import { HttpStatusCode } from '@standardnotes/api'
import { EmailLevel } from '@standardnotes/domain-core'
import { getBody, getSubject } from '../Email/UserSignedIn'
@@ -59,7 +59,12 @@ export class SignIn implements UseCaseInterface {
}
}
if (user.version === ProtocolVersion.V004 && !performingCodeChallengedSignIn) {
const userVersionIs004OrGreater = leftVersionGreaterThanOrEqualToRight(
user.version as ProtocolVersion,
ProtocolVersion.V004,
)
if (userVersionIs004OrGreater && !performingCodeChallengedSignIn) {
return {
success: false,
errorMessage: 'Please update your client application.',

View File

@@ -3,6 +3,46 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.9.51](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.9.50...@standardnotes/domain-events-infra@1.9.51) (2022-12-09)
**Note:** Version bump only for package @standardnotes/domain-events-infra
## [1.9.50](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.9.49...@standardnotes/domain-events-infra@1.9.50) (2022-12-09)
**Note:** Version bump only for package @standardnotes/domain-events-infra
## [1.9.49](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.9.48...@standardnotes/domain-events-infra@1.9.49) (2022-12-09)
**Note:** Version bump only for package @standardnotes/domain-events-infra
## [1.9.48](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.9.47...@standardnotes/domain-events-infra@1.9.48) (2022-12-09)
**Note:** Version bump only for package @standardnotes/domain-events-infra
## [1.9.47](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.9.46...@standardnotes/domain-events-infra@1.9.47) (2022-12-09)
**Note:** Version bump only for package @standardnotes/domain-events-infra
## [1.9.46](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.9.45...@standardnotes/domain-events-infra@1.9.46) (2022-12-08)
**Note:** Version bump only for package @standardnotes/domain-events-infra
## [1.9.45](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.9.44...@standardnotes/domain-events-infra@1.9.45) (2022-12-08)
**Note:** Version bump only for package @standardnotes/domain-events-infra
## [1.9.44](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.9.43...@standardnotes/domain-events-infra@1.9.44) (2022-12-08)
**Note:** Version bump only for package @standardnotes/domain-events-infra
## [1.9.43](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.9.42...@standardnotes/domain-events-infra@1.9.43) (2022-12-08)
**Note:** Version bump only for package @standardnotes/domain-events-infra
## [1.9.42](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.9.41...@standardnotes/domain-events-infra@1.9.42) (2022-12-08)
**Note:** Version bump only for package @standardnotes/domain-events-infra
## [1.9.41](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.9.40...@standardnotes/domain-events-infra@1.9.41) (2022-12-07)
**Note:** Version bump only for package @standardnotes/domain-events-infra

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/domain-events-infra",
"version": "1.9.41",
"version": "1.9.51",
"engines": {
"node": ">=18.0.0 <19.0.0"
},

View File

@@ -3,6 +3,66 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [2.102.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.101.0...@standardnotes/domain-events@2.102.0) (2022-12-09)
### Features
* **syncing-server:** replace email backup attachment created with email requested ([32601f3](https://github.com/standardnotes/server/commit/32601f34f181b29b7c62cd2926111a0887d97fbf))
# [2.101.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.100.0...@standardnotes/domain-events@2.101.0) (2022-12-09)
### Features
* **syncing-server:** replace one drive backup failed event with email requested ([130f90b](https://github.com/standardnotes/server/commit/130f90bdb6cc88e073b9380e8aed5eebe8c49c1e))
# [2.100.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.99.0...@standardnotes/domain-events@2.100.0) (2022-12-09)
### Features
* **syncing-server:** remove google drive backup failed event in favour of email requested ([00fe321](https://github.com/standardnotes/server/commit/00fe32136e7add627e58e8ea223f7f484f1d3718))
# [2.99.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.98.4...@standardnotes/domain-events@2.99.0) (2022-12-09)
### Features
* **auth:** remove offline subscription token created event in favour of email requested ([fd58992](https://github.com/standardnotes/server/commit/fd589922bba29595a0dfd154a42fe158024fad28))
## [2.98.4](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.98.3...@standardnotes/domain-events@2.98.4) (2022-12-09)
### Bug Fixes
* **domain-events:** remove unused event ([cc4b4f9](https://github.com/standardnotes/server/commit/cc4b4f9bf831b9aabec7d506d977ee1df50d5222))
## [2.98.3](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.98.2...@standardnotes/domain-events@2.98.3) (2022-12-08)
### Bug Fixes
* **domain-events:** remove unused event ([cffc1f4](https://github.com/standardnotes/server/commit/cffc1f442f3c6f781c4468ac96245e13f57115d5))
## [2.98.2](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.98.1...@standardnotes/domain-events@2.98.2) (2022-12-08)
### Bug Fixes
* **domain-events:** remove unused event ([5a1eb9f](https://github.com/standardnotes/server/commit/5a1eb9fdacb8cfe8fde06df9e83fef1753b1a619))
## [2.98.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.98.0...@standardnotes/domain-events@2.98.1) (2022-12-08)
### Bug Fixes
* **domain-events:** remove unused event ([47d2012](https://github.com/standardnotes/server/commit/47d2012b3d96eddf5f6304f158659dc764f9b1c4))
# [2.98.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.97.0...@standardnotes/domain-events@2.98.0) (2022-12-08)
### Features
* **domain-events:** remove unused events and add attachments option for sending emails ([435cd2f](https://github.com/standardnotes/server/commit/435cd2f66a1332a294001e87eed3ece1b8b991ae))
# [2.97.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.96.0...@standardnotes/domain-events@2.97.0) (2022-12-08)
### Features
* **domain-events:** remove unused account reset requested event ([3a12f5c](https://github.com/standardnotes/server/commit/3a12f5c1c40ab6cb236b963bad2a987bacef55e4))
# [2.96.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.95.0...@standardnotes/domain-events@2.96.0) (2022-12-07)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/domain-events",
"version": "2.96.0",
"version": "2.102.0",
"engines": {
"node": ">=18.0.0 <19.0.0"
},

View File

@@ -1,7 +0,0 @@
import { DomainEventInterface } from './DomainEventInterface'
import { AccountClaimRequestedEventPayload } from './AccountClaimRequestedEventPayload'
export interface AccountClaimRequestedEvent extends DomainEventInterface {
type: 'ACCOUNT_CLAIM_REQUESTED'
payload: AccountClaimRequestedEventPayload
}

View File

@@ -1,4 +0,0 @@
export interface AccountClaimRequestedEventPayload {
email: string
token: string
}

View File

@@ -1,8 +0,0 @@
import { DomainEventInterface } from './DomainEventInterface'
import { AccountResetRequestedEventPayload } from './AccountResetRequestedEventPayload'
export interface AccountResetRequestedEvent extends DomainEventInterface {
type: 'ACCOUNT_RESET_REQUESTED'
payload: AccountResetRequestedEventPayload
}

View File

@@ -1,4 +0,0 @@
export interface AccountResetRequestedEventPayload {
resetRequestToken: string
userEmail: string
}

View File

@@ -1,7 +0,0 @@
import { DomainEventInterface } from './DomainEventInterface'
import { ActivationCodeRequestedEventPayload } from './ActivationCodeRequestedEventPayload'
export interface ActivationCodeRequestedEvent extends DomainEventInterface {
type: 'ACTIVATION_CODE_REQUESTED'
payload: ActivationCodeRequestedEventPayload
}

View File

@@ -1,4 +0,0 @@
export interface ActivationCodeRequestedEventPayload {
userEmail: string
offlineFeaturesToken: string
}

View File

@@ -1,8 +0,0 @@
import { DomainEventInterface } from './DomainEventInterface'
import { DiscountAppliedEventPayload } from './DiscountAppliedEventPayload'
export interface DiscountAppliedEvent extends DomainEventInterface {
type: 'DISCOUNT_APPLIED'
payload: DiscountAppliedEventPayload
}

View File

@@ -1,4 +0,0 @@
export interface DiscountAppliedEventPayload {
userEmail: string
discountRate: number
}

View File

@@ -1,8 +0,0 @@
import { DomainEventInterface } from './DomainEventInterface'
import { DropboxBackupFailedEventPayload } from './DropboxBackupFailedEventPayload'
export interface DropboxBackupFailedEvent extends DomainEventInterface {
type: 'DROPBOX_BACKUP_FAILED'
payload: DropboxBackupFailedEventPayload
}

View File

@@ -1,5 +0,0 @@
export interface DropboxBackupFailedEventPayload {
muteCloudEmailsSettingUuid: string
extensionSettingUuid?: string
email: string
}

View File

@@ -1,7 +0,0 @@
import { DomainEventInterface } from './DomainEventInterface'
import { EmailBackupAttachmentCreatedEventPayload } from './EmailBackupAttachmentCreatedEventPayload'
export interface EmailBackupAttachmentCreatedEvent extends DomainEventInterface {
type: 'EMAIL_BACKUP_ATTACHMENT_CREATED'
payload: EmailBackupAttachmentCreatedEventPayload
}

View File

@@ -1,6 +0,0 @@
export interface EmailBackupAttachmentCreatedEventPayload {
backupFileName: string
backupFileIndex: number
backupFilesTotal: number
email: string
}

View File

@@ -4,4 +4,11 @@ export interface EmailRequestedEventPayload {
level: string
subject: string
body: string
sender?: string
attachments?: Array<{
filePath: string
fileName: string
attachmentFileName: string
attachmentContentType: string
}>
}

View File

@@ -1,8 +0,0 @@
import { DomainEventInterface } from './DomainEventInterface'
import { GoogleDriveBackupFailedEventPayload } from './GoogleDriveBackupFailedEventPayload'
export interface GoogleDriveBackupFailedEvent extends DomainEventInterface {
type: 'GOOGLE_DRIVE_BACKUP_FAILED'
payload: GoogleDriveBackupFailedEventPayload
}

View File

@@ -1,5 +0,0 @@
export interface GoogleDriveBackupFailedEventPayload {
muteCloudEmailsSettingUuid: string
extensionSettingUuid?: string
email: string
}

View File

@@ -1,8 +0,0 @@
import { DomainEventInterface } from './DomainEventInterface'
import { InvoiceGeneratedEventPayload } from './InvoiceGeneratedEventPayload'
export interface InvoiceGeneratedEvent extends DomainEventInterface {
type: 'INVOICE_GENERATED'
payload: InvoiceGeneratedEventPayload
}

View File

@@ -1,7 +0,0 @@
export interface InvoiceGeneratedEventPayload {
userEmail: string
invoiceNumber: string
paymentDateFormatted: string
s3BucketName: string
s3InvoiceObjectKey: string
}

View File

@@ -1,8 +0,0 @@
import { DomainEventInterface } from './DomainEventInterface'
import { OfflineSubscriptionTokenCreatedEventPayload } from './OfflineSubscriptionTokenCreatedEventPayload'
export interface OfflineSubscriptionTokenCreatedEvent extends DomainEventInterface {
type: 'OFFLINE_SUBSCRIPTION_TOKEN_CREATED'
payload: OfflineSubscriptionTokenCreatedEventPayload
}

View File

@@ -1,4 +0,0 @@
export interface OfflineSubscriptionTokenCreatedEventPayload {
token: string
email: string
}

View File

@@ -1,8 +0,0 @@
import { DomainEventInterface } from './DomainEventInterface'
import { OneDriveBackupFailedEventPayload } from './OneDriveBackupFailedEventPayload'
export interface OneDriveBackupFailedEvent extends DomainEventInterface {
type: 'ONE_DRIVE_BACKUP_FAILED'
payload: OneDriveBackupFailedEventPayload
}

View File

@@ -1,5 +0,0 @@
export interface OneDriveBackupFailedEventPayload {
muteCloudEmailsSettingUuid: string
extensionSettingUuid?: string
email: string
}

View File

@@ -1,8 +0,0 @@
import { DomainEventInterface } from './DomainEventInterface'
import { RefundRequestedEventPayload } from './RefundRequestedEventPayload'
export interface RefundRequestedEvent extends DomainEventInterface {
type: 'REFUND_REQUESTED'
payload: RefundRequestedEventPayload
}

View File

@@ -1,4 +0,0 @@
export interface RefundRequestedEventPayload {
userEmail: string
refundProcessingLink: string
}

View File

@@ -1,8 +0,0 @@
import { DomainEventInterface } from './DomainEventInterface'
import { StudentDiscountApprovedEventPayload } from './StudentDiscountApprovedEventPayload'
export interface StudentDiscountApprovedEvent extends DomainEventInterface {
type: 'STUDENT_DISCOUNT_APPROVED'
payload: StudentDiscountApprovedEventPayload
}

View File

@@ -1,3 +0,0 @@
export interface StudentDiscountApprovedEventPayload {
userEmail: string
}

View File

@@ -1,8 +0,0 @@
import { DomainEventInterface } from './DomainEventInterface'
import { StudentDiscountRequestedEventPayload } from './StudentDiscountRequestedEventPayload'
export interface StudentDiscountRequestedEvent extends DomainEventInterface {
type: 'STUDENT_DISCOUNT_REQUESTED'
payload: StudentDiscountRequestedEventPayload
}

View File

@@ -1,5 +0,0 @@
export interface StudentDiscountRequestedEventPayload {
studentEmail: string
userEmail: string
adminApprovalLink: string
}

View File

@@ -1,8 +0,0 @@
import { DomainEventInterface } from './DomainEventInterface'
import { SubscriptionRateAdjustedEventPayload } from './SubscriptionRateAdjustedEventPayload'
export interface SubscriptionRateAdjustedEvent extends DomainEventInterface {
type: 'SUBSCRIPTION_RATE_ADJUSTED'
payload: SubscriptionRateAdjustedEventPayload
}

View File

@@ -1,5 +0,0 @@
export interface SubscriptionRateAdjustedEventPayload {
userEmail: string
newRateFormatted: string
refundAmountInDollarsFormatted: string
}

View File

@@ -1,31 +1,19 @@
export * from './Event/AccountClaimRequestedEvent'
export * from './Event/AccountClaimRequestedEventPayload'
export * from './Event/AccountDeletionRequestedEvent'
export * from './Event/AccountDeletionRequestedEventPayload'
export * from './Event/AccountResetRequestedEvent'
export * from './Event/AccountResetRequestedEventPayload'
export * from './Event/ActivationCodeRequestedEvent'
export * from './Event/ActivationCodeRequestedEventPayload'
export * from './Event/CloudBackupRequestedEvent'
export * from './Event/CloudBackupRequestedEventPayload'
export * from './Event/DailyAnalyticsReportGeneratedEvent'
export * from './Event/DailyAnalyticsReportGeneratedEventPayload'
export * from './Event/DiscountAppliedEvent'
export * from './Event/DiscountAppliedEventPayload'
export * from './Event/DiscountApplyRequestedEvent'
export * from './Event/DiscountApplyRequestedEventPayload'
export * from './Event/DiscountWithdrawRequestedEvent'
export * from './Event/DiscountWithdrawRequestedEventPayload'
export * from './Event/DomainEventInterface'
export * from './Event/DomainEventService'
export * from './Event/DropboxBackupFailedEvent'
export * from './Event/DropboxBackupFailedEventPayload'
export * from './Event/DuplicateItemSyncedEvent'
export * from './Event/DuplicateItemSyncedEventPayload'
export * from './Event/EmailArchiveExtensionSyncedEvent'
export * from './Event/EmailArchiveExtensionSyncedEventPayload'
export * from './Event/EmailBackupAttachmentCreatedEvent'
export * from './Event/EmailBackupAttachmentCreatedEventPayload'
export * from './Event/EmailBackupRequestedEvent'
export * from './Event/EmailBackupRequestedEventPayload'
export * from './Event/EmailRequestedEvent'
@@ -42,10 +30,6 @@ export * from './Event/FileRemovedEvent'
export * from './Event/FileRemovedEventPayload'
export * from './Event/FileUploadedEvent'
export * from './Event/FileUploadedEventPayload'
export * from './Event/GoogleDriveBackupFailedEvent'
export * from './Event/GoogleDriveBackupFailedEventPayload'
export * from './Event/InvoiceGeneratedEvent'
export * from './Event/InvoiceGeneratedEventPayload'
export * from './Event/ItemDumpedEvent'
export * from './Event/ItemDumpedEventPayload'
export * from './Event/ItemRevisionCreationRequestedEvent'
@@ -60,10 +44,6 @@ export * from './Event/ListedAccountRequestedEvent'
export * from './Event/ListedAccountRequestedEventPayload'
export * from './Event/MuteEmailsSettingChangedEvent'
export * from './Event/MuteEmailsSettingChangedEventPayload'
export * from './Event/OfflineSubscriptionTokenCreatedEvent'
export * from './Event/OfflineSubscriptionTokenCreatedEventPayload'
export * from './Event/OneDriveBackupFailedEvent'
export * from './Event/OneDriveBackupFailedEventPayload'
export * from './Event/PaymentFailedEvent'
export * from './Event/PaymentFailedEventPayload'
export * from './Event/PaymentSuccessEvent'
@@ -72,8 +52,6 @@ export * from './Event/PredicateVerificationRequestedEvent'
export * from './Event/PredicateVerificationRequestedEventPayload'
export * from './Event/PredicateVerifiedEvent'
export * from './Event/PredicateVerifiedEventPayload'
export * from './Event/RefundRequestedEvent'
export * from './Event/RefundRequestedEventPayload'
export * from './Event/RefundProcessedEvent'
export * from './Event/RefundProcessedEventPayload'
export * from './Event/RevisionsCopyRequestedEvent'
@@ -84,16 +62,10 @@ export * from './Event/SharedSubscriptionInvitationCanceledEvent'
export * from './Event/SharedSubscriptionInvitationCanceledEventPayload'
export * from './Event/SharedSubscriptionInvitationCreatedEvent'
export * from './Event/SharedSubscriptionInvitationCreatedEventPayload'
export * from './Event/StudentDiscountApprovedEvent'
export * from './Event/StudentDiscountApprovedEventPayload'
export * from './Event/StudentDiscountRequestedEvent'
export * from './Event/StudentDiscountRequestedEventPayload'
export * from './Event/SubscriptionCancelledEvent'
export * from './Event/SubscriptionCancelledEventPayload'
export * from './Event/SubscriptionPurchasedEvent'
export * from './Event/SubscriptionPurchasedEventPayload'
export * from './Event/SubscriptionRateAdjustedEvent'
export * from './Event/SubscriptionRateAdjustedEventPayload'
export * from './Event/SubscriptionReactivatedEvent'
export * from './Event/SubscriptionReactivatedEventPayload'
export * from './Event/SubscriptionReassignedEvent'

View File

@@ -3,6 +3,53 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.6.48](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.6.47...@standardnotes/event-store@1.6.48) (2022-12-09)
**Note:** Version bump only for package @standardnotes/event-store
## [1.6.47](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.6.46...@standardnotes/event-store@1.6.47) (2022-12-09)
**Note:** Version bump only for package @standardnotes/event-store
## [1.6.46](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.6.45...@standardnotes/event-store@1.6.46) (2022-12-09)
**Note:** Version bump only for package @standardnotes/event-store
## [1.6.45](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.6.44...@standardnotes/event-store@1.6.45) (2022-12-09)
**Note:** Version bump only for package @standardnotes/event-store
## [1.6.44](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.6.43...@standardnotes/event-store@1.6.44) (2022-12-09)
**Note:** Version bump only for package @standardnotes/event-store
## [1.6.43](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.6.42...@standardnotes/event-store@1.6.43) (2022-12-08)
**Note:** Version bump only for package @standardnotes/event-store
## [1.6.42](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.6.41...@standardnotes/event-store@1.6.42) (2022-12-08)
**Note:** Version bump only for package @standardnotes/event-store
## [1.6.41](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.6.40...@standardnotes/event-store@1.6.41) (2022-12-08)
**Note:** Version bump only for package @standardnotes/event-store
## [1.6.40](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.6.39...@standardnotes/event-store@1.6.40) (2022-12-08)
**Note:** Version bump only for package @standardnotes/event-store
## [1.6.39](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.6.38...@standardnotes/event-store@1.6.39) (2022-12-08)
**Note:** Version bump only for package @standardnotes/event-store
## [1.6.38](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.6.37...@standardnotes/event-store@1.6.38) (2022-12-07)
### Bug Fixes
* **event-store:** add email requested subscription ([eff0945](https://github.com/standardnotes/server/commit/eff09454c3a28b0124b74c2850fed19313b9e2b2))
* **event-store:** reduce handlers ([473feba](https://github.com/standardnotes/server/commit/473feba6a8f008c9d73238be82e1d197082464c0))
## [1.6.37](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.6.36...@standardnotes/event-store@1.6.37) (2022-12-07)
**Note:** Version bump only for package @standardnotes/event-store

View File

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

View File

@@ -78,7 +78,7 @@ export class ContainerConfigLoader {
['LISTED_ACCOUNT_REQUESTED', container.get(TYPES.EventHandler)],
['LISTED_ACCOUNT_CREATED', container.get(TYPES.EventHandler)],
['LISTED_ACCOUNT_DELETED', container.get(TYPES.EventHandler)],
['USER_SIGNED_IN', container.get(TYPES.EventHandler)],
['EMAIL_REQUESTED', container.get(TYPES.EventHandler)],
['SHARED_SUBSCRIPTION_INVITATION_CREATED', container.get(TYPES.EventHandler)],
['EMAIL_BACKUP_ATTACHMENT_CREATED', container.get(TYPES.EventHandler)],
['EMAIL_BACKUP_REQUESTED', container.get(TYPES.EventHandler)],

View File

@@ -3,6 +3,46 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.8.47](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.8.46...@standardnotes/files-server@1.8.47) (2022-12-09)
**Note:** Version bump only for package @standardnotes/files-server
## [1.8.46](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.8.45...@standardnotes/files-server@1.8.46) (2022-12-09)
**Note:** Version bump only for package @standardnotes/files-server
## [1.8.45](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.8.44...@standardnotes/files-server@1.8.45) (2022-12-09)
**Note:** Version bump only for package @standardnotes/files-server
## [1.8.44](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.8.43...@standardnotes/files-server@1.8.44) (2022-12-09)
**Note:** Version bump only for package @standardnotes/files-server
## [1.8.43](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.8.42...@standardnotes/files-server@1.8.43) (2022-12-09)
**Note:** Version bump only for package @standardnotes/files-server
## [1.8.42](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.8.41...@standardnotes/files-server@1.8.42) (2022-12-08)
**Note:** Version bump only for package @standardnotes/files-server
## [1.8.41](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.8.40...@standardnotes/files-server@1.8.41) (2022-12-08)
**Note:** Version bump only for package @standardnotes/files-server
## [1.8.40](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.8.39...@standardnotes/files-server@1.8.40) (2022-12-08)
**Note:** Version bump only for package @standardnotes/files-server
## [1.8.39](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.8.38...@standardnotes/files-server@1.8.39) (2022-12-08)
**Note:** Version bump only for package @standardnotes/files-server
## [1.8.38](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.8.37...@standardnotes/files-server@1.8.38) (2022-12-08)
**Note:** Version bump only for package @standardnotes/files-server
## [1.8.37](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.8.36...@standardnotes/files-server@1.8.37) (2022-12-07)
**Note:** Version bump only for package @standardnotes/files-server

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/files-server",
"version": "1.8.37",
"version": "1.8.47",
"engines": {
"node": ">=18.0.0 <19.0.0"
},

View File

@@ -3,6 +3,46 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.9.20](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.9.19...@standardnotes/revisions-server@1.9.20) (2022-12-09)
**Note:** Version bump only for package @standardnotes/revisions-server
## [1.9.19](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.9.18...@standardnotes/revisions-server@1.9.19) (2022-12-09)
**Note:** Version bump only for package @standardnotes/revisions-server
## [1.9.18](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.9.17...@standardnotes/revisions-server@1.9.18) (2022-12-09)
**Note:** Version bump only for package @standardnotes/revisions-server
## [1.9.17](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.9.16...@standardnotes/revisions-server@1.9.17) (2022-12-09)
**Note:** Version bump only for package @standardnotes/revisions-server
## [1.9.16](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.9.15...@standardnotes/revisions-server@1.9.16) (2022-12-09)
**Note:** Version bump only for package @standardnotes/revisions-server
## [1.9.15](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.9.14...@standardnotes/revisions-server@1.9.15) (2022-12-08)
**Note:** Version bump only for package @standardnotes/revisions-server
## [1.9.14](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.9.13...@standardnotes/revisions-server@1.9.14) (2022-12-08)
**Note:** Version bump only for package @standardnotes/revisions-server
## [1.9.13](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.9.12...@standardnotes/revisions-server@1.9.13) (2022-12-08)
**Note:** Version bump only for package @standardnotes/revisions-server
## [1.9.12](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.9.11...@standardnotes/revisions-server@1.9.12) (2022-12-08)
**Note:** Version bump only for package @standardnotes/revisions-server
## [1.9.11](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.9.10...@standardnotes/revisions-server@1.9.11) (2022-12-08)
**Note:** Version bump only for package @standardnotes/revisions-server
## [1.9.10](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.9.9...@standardnotes/revisions-server@1.9.10) (2022-12-07)
**Note:** Version bump only for package @standardnotes/revisions-server

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/revisions-server",
"version": "1.9.10",
"version": "1.9.20",
"engines": {
"node": ">=18.0.0 <19.0.0"
},

View File

@@ -3,6 +3,48 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.15.1](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.15.0...@standardnotes/scheduler-server@1.15.1) (2022-12-09)
**Note:** Version bump only for package @standardnotes/scheduler-server
# [1.15.0](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.14.10...@standardnotes/scheduler-server@1.15.0) (2022-12-09)
### Features
* **syncing-server:** replace one drive backup failed event with email requested ([130f90b](https://github.com/standardnotes/server/commit/130f90bdb6cc88e073b9380e8aed5eebe8c49c1e))
## [1.14.10](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.14.9...@standardnotes/scheduler-server@1.14.10) (2022-12-09)
**Note:** Version bump only for package @standardnotes/scheduler-server
## [1.14.9](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.14.8...@standardnotes/scheduler-server@1.14.9) (2022-12-09)
**Note:** Version bump only for package @standardnotes/scheduler-server
## [1.14.8](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.14.7...@standardnotes/scheduler-server@1.14.8) (2022-12-09)
**Note:** Version bump only for package @standardnotes/scheduler-server
## [1.14.7](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.14.6...@standardnotes/scheduler-server@1.14.7) (2022-12-08)
**Note:** Version bump only for package @standardnotes/scheduler-server
## [1.14.6](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.14.5...@standardnotes/scheduler-server@1.14.6) (2022-12-08)
**Note:** Version bump only for package @standardnotes/scheduler-server
## [1.14.5](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.14.4...@standardnotes/scheduler-server@1.14.5) (2022-12-08)
**Note:** Version bump only for package @standardnotes/scheduler-server
## [1.14.4](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.14.3...@standardnotes/scheduler-server@1.14.4) (2022-12-08)
**Note:** Version bump only for package @standardnotes/scheduler-server
## [1.14.3](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.14.2...@standardnotes/scheduler-server@1.14.3) (2022-12-08)
**Note:** Version bump only for package @standardnotes/scheduler-server
## [1.14.2](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.14.1...@standardnotes/scheduler-server@1.14.2) (2022-12-07)
**Note:** Version bump only for package @standardnotes/scheduler-server

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/scheduler-server",
"version": "1.14.2",
"version": "1.15.1",
"engines": {
"node": ">=18.0.0 <19.0.0"
},

View File

@@ -2,7 +2,7 @@ import {
DiscountApplyRequestedEvent,
DiscountWithdrawRequestedEvent,
DomainEventPublisherInterface,
EmailMessageRequestedEvent,
EmailRequestedEvent,
ExitDiscountWithdrawRequestedEvent,
} from '@standardnotes/domain-events'
import { PredicateName } from '@standardnotes/predicates'
@@ -45,9 +45,7 @@ describe('JobDoneInterpreter', () => {
predicateRepository.findByJobUuid = jest.fn().mockReturnValue([])
domainEventFactory = {} as jest.Mocked<DomainEventFactoryInterface>
domainEventFactory.createEmailRequestedEvent = jest
.fn()
.mockReturnValue({} as jest.Mocked<EmailMessageRequestedEvent>)
domainEventFactory.createEmailRequestedEvent = jest.fn().mockReturnValue({} as jest.Mocked<EmailRequestedEvent>)
domainEventFactory.createDiscountApplyRequestedEvent = jest
.fn()
.mockReturnValue({} as jest.Mocked<DiscountApplyRequestedEvent>)

View File

@@ -3,6 +3,58 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.24.0](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.23.0...@standardnotes/syncing-server@1.24.0) (2022-12-09)
### Features
* **syncing-server:** replace email backup attachment created with email requested ([32601f3](https://github.com/standardnotes/syncing-server-js/commit/32601f34f181b29b7c62cd2926111a0887d97fbf))
# [1.23.0](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.22.0...@standardnotes/syncing-server@1.23.0) (2022-12-09)
### Features
* **syncing-server:** replace one drive backup failed event with email requested ([130f90b](https://github.com/standardnotes/syncing-server-js/commit/130f90bdb6cc88e073b9380e8aed5eebe8c49c1e))
# [1.22.0](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.21.0...@standardnotes/syncing-server@1.22.0) (2022-12-09)
### Features
* **syncing-serfver:** remove dropbox backup failed event in favour of email requested ([118156c](https://github.com/standardnotes/syncing-server-js/commit/118156c62de70eca8fd89414f6e409abd0363e62))
# [1.21.0](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.20.17...@standardnotes/syncing-server@1.21.0) (2022-12-09)
### Features
* **syncing-server:** remove google drive backup failed event in favour of email requested ([00fe321](https://github.com/standardnotes/syncing-server-js/commit/00fe32136e7add627e58e8ea223f7f484f1d3718))
## [1.20.17](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.20.16...@standardnotes/syncing-server@1.20.17) (2022-12-09)
**Note:** Version bump only for package @standardnotes/syncing-server
## [1.20.16](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.20.15...@standardnotes/syncing-server@1.20.16) (2022-12-09)
**Note:** Version bump only for package @standardnotes/syncing-server
## [1.20.15](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.20.14...@standardnotes/syncing-server@1.20.15) (2022-12-08)
**Note:** Version bump only for package @standardnotes/syncing-server
## [1.20.14](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.20.13...@standardnotes/syncing-server@1.20.14) (2022-12-08)
**Note:** Version bump only for package @standardnotes/syncing-server
## [1.20.13](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.20.12...@standardnotes/syncing-server@1.20.13) (2022-12-08)
**Note:** Version bump only for package @standardnotes/syncing-server
## [1.20.12](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.20.11...@standardnotes/syncing-server@1.20.12) (2022-12-08)
**Note:** Version bump only for package @standardnotes/syncing-server
## [1.20.11](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.20.10...@standardnotes/syncing-server@1.20.11) (2022-12-08)
**Note:** Version bump only for package @standardnotes/syncing-server
## [1.20.10](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.20.9...@standardnotes/syncing-server@1.20.10) (2022-12-07)
**Note:** Version bump only for package @standardnotes/syncing-server

View File

@@ -7,6 +7,6 @@ module.exports = {
transform: {
...tsjPreset.transform,
},
coveragePathIgnorePatterns: ['/Bootstrap/', 'HealthCheckController', '/Infra/'],
coveragePathIgnorePatterns: ['/Bootstrap/', 'HealthCheckController', '/Infra/', '/Domain/Email/'],
setupFilesAfterEnv: ['./test-setup.ts'],
}

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/syncing-server",
"version": "1.20.10",
"version": "1.24.0",
"engines": {
"node": ">=18.0.0 <19.0.0"
},

View File

@@ -0,0 +1,9 @@
import { html } from './dropbox-backup-failed.html'
export function getSubject(): string {
return 'Failed Daily Backup to Dropbox'
}
export function getBody(): string {
return html
}

View File

@@ -0,0 +1,14 @@
import { html } from './email-backup-attachment-created.html'
export function getSubject(fileIndex: number, numberOfFiles: number, date: string): string {
let subject = `Data Backup for ${date}`
if (numberOfFiles > 1) {
subject = `Data Backup for ${date} - Part ${fileIndex} Of ${numberOfFiles}`
}
return subject
}
export function getBody(email: string): string {
return html(email)
}

View File

@@ -0,0 +1,9 @@
import { html } from './google-drive-backup-failed.html'
export function getSubject(): string {
return 'Failed Daily Backup to Google Drive Sync'
}
export function getBody(): string {
return html
}

View File

@@ -0,0 +1,9 @@
import { html } from './one-drive-backup-failed.html'
export function getSubject(): string {
return 'Failed Daily Backup to OneDrive Sync'
}
export function getBody(): string {
return html
}

View File

@@ -0,0 +1,17 @@
export const html = `<p>Hello,</p>
<p>We recently tried backing up your data to <strong>Dropbox</strong>, but an issue prevented us from doing so.</p>
<p>
The usual cause is an expired or revoked token from your sync provider. Please follow
<a href='https://standardnotes.com/help/27/how-do-i-enable-dropbox-google-drive-or-onedrive-backups'>these
instructions</a>
to use CloudLink on the web or desktop Standard Notes application to uninstall then reinstall this sync provider.
</p>
<p>
We apologize for any inconvenience this may cause.
If you have any questions, please feel free to reply directly to this email.
</p>
<p>
Thanks,
<br>SN</br>
</p>
<a href='https://app.standardnotes.com/?settings=backups'>Mute these emails</a>`

View File

@@ -0,0 +1,33 @@
export const html = (email: string) => `
<p>
Your encrypted data backup is attached for ${email}. You can import this file using
the Standard Notes web or desktop app, or by using the offline decryption script available at
<a style="text-decoration:none !important; text-decoration:none;">standardnotes.org/offline</a>.
</p>
<p>
<strong>Please note:</strong>
<ol>
<li>
We will never send anything other than a <code>txt</code> file
as part of your daily backups. To protect yourself against phishing attacks, never open
any other kind of file, and always open the <code>txt</code> file with a text editor to
verify its contents before decrypting.
</li>
<li>
We will never include clickable links in this email. Instead, manually verify
and copy/paste the offline link above in your browser.
</li>
</ol>
</p>
<hr />
<p>
<i>
Want to disable daily backups? Uninstall 'Daily Email Backups' from your Extensions
menu in Standard Notes to immediately disable backups.
Otherwise, reply to this email with "Stop". Note that it may
take up to 72 hours or more to perform manual removal via the "Stop" method.
</i>
</p>
`

View File

@@ -0,0 +1,19 @@
export const html = `<p>Hello,</p>
<p>We recently tried backing up your data to <strong>Google Drive Sync</strong>, but an issue prevented us from
doing
so.</p>
<p>
The usual cause is an expired or revoked token from your sync provider. Please follow
<a href='https://standardnotes.com/help/27/how-do-i-enable-dropbox-google-drive-or-onedrive-backups'>these
instructions</a>
to use CloudLink on the web or desktop Standard Notes application to uninstall then reinstall this sync provider.
</p>
<p>
We apologize for any inconvenience this may cause.
If you have any questions, please feel free to reply directly to this email.
</p>
<p>
Thanks,
<br>SN</br>
</p>
<a href='https://app.standardnotes.com/?settings=backups'>Mute these emails</a>`

View File

@@ -0,0 +1,18 @@
export const html = `<p>Hello,</p>
<p>We recently tried backing up your data to <strong>OneDrive Sync</strong>, but an issue prevented us from doing
so.</p>
<p>
The usual cause is an expired or revoked token from your sync provider. Please follow
<a href='https://standardnotes.com/help/27/how-do-i-enable-dropbox-google-drive-or-onedrive-backups'>these
instructions</a>
to use CloudLink on the web or desktop Standard Notes application to uninstall then reinstall this sync provider.
</p>
<p>
We apologize for any inconvenience this may cause.
If you have any questions, please feel free to reply directly to this email.
</p>
<p>
Thanks,
<br>SN</br>
</p>
<a href='https://app.standardnotes.com/?settings=backups'>Mute these emails</a>`

View File

@@ -1,15 +1,12 @@
/* istanbul ignore file */
import {
DomainEventService,
DropboxBackupFailedEvent,
DuplicateItemSyncedEvent,
EmailArchiveExtensionSyncedEvent,
EmailBackupAttachmentCreatedEvent,
GoogleDriveBackupFailedEvent,
EmailRequestedEvent,
ItemDumpedEvent,
ItemRevisionCreationRequestedEvent,
ItemsSyncedEvent,
OneDriveBackupFailedEvent,
RevisionsCopyRequestedEvent,
RevisionsOwnershipUpdateRequestedEvent,
UserContentSizeRecalculationRequestedEvent,
@@ -131,57 +128,31 @@ export class DomainEventFactory implements DomainEventFactoryInterface {
}
}
createDropboxBackupFailedEvent(muteCloudEmailsSettingUuid: string, email: string): DropboxBackupFailedEvent {
createEmailRequestedEvent(dto: {
userEmail: string
messageIdentifier: string
level: string
body: string
subject: string
sender?: string
attachments?: Array<{
filePath: string
fileName: string
attachmentFileName: string
attachmentContentType: string
}>
}): EmailRequestedEvent {
return {
type: 'DROPBOX_BACKUP_FAILED',
type: 'EMAIL_REQUESTED',
createdAt: this.timer.getUTCDate(),
meta: {
correlation: {
userIdentifier: email,
userIdentifier: dto.userEmail,
userIdentifierType: 'email',
},
origin: DomainEventService.SyncingServer,
},
payload: {
muteCloudEmailsSettingUuid,
email,
},
}
}
createGoogleDriveBackupFailedEvent(muteCloudEmailsSettingUuid: string, email: string): GoogleDriveBackupFailedEvent {
return {
type: 'GOOGLE_DRIVE_BACKUP_FAILED',
createdAt: this.timer.getUTCDate(),
meta: {
correlation: {
userIdentifier: email,
userIdentifierType: 'email',
},
origin: DomainEventService.SyncingServer,
},
payload: {
muteCloudEmailsSettingUuid,
email,
},
}
}
createOneDriveBackupFailedEvent(muteCloudEmailsSettingUuid: string, email: string): OneDriveBackupFailedEvent {
return {
type: 'ONE_DRIVE_BACKUP_FAILED',
createdAt: this.timer.getUTCDate(),
meta: {
correlation: {
userIdentifier: email,
userIdentifierType: 'email',
},
origin: DomainEventService.SyncingServer,
},
payload: {
muteCloudEmailsSettingUuid,
email,
},
payload: dto,
}
}
@@ -225,24 +196,4 @@ export class DomainEventFactory implements DomainEventFactoryInterface {
},
}
}
createEmailBackupAttachmentCreatedEvent(dto: {
backupFileName: string
backupFileIndex: number
backupFilesTotal: number
email: string
}): EmailBackupAttachmentCreatedEvent {
return {
type: 'EMAIL_BACKUP_ATTACHMENT_CREATED',
createdAt: this.timer.getUTCDate(),
meta: {
correlation: {
userIdentifier: dto.email,
userIdentifierType: 'email',
},
origin: DomainEventService.SyncingServer,
},
payload: dto,
}
}
}

View File

@@ -1,13 +1,10 @@
import {
DropboxBackupFailedEvent,
DuplicateItemSyncedEvent,
EmailArchiveExtensionSyncedEvent,
EmailBackupAttachmentCreatedEvent,
GoogleDriveBackupFailedEvent,
EmailRequestedEvent,
ItemDumpedEvent,
ItemRevisionCreationRequestedEvent,
ItemsSyncedEvent,
OneDriveBackupFailedEvent,
RevisionsCopyRequestedEvent,
RevisionsOwnershipUpdateRequestedEvent,
UserContentSizeRecalculationRequestedEvent,
@@ -15,9 +12,20 @@ import {
export interface DomainEventFactoryInterface {
createUserContentSizeRecalculationRequestedEvent(userUuid: string): UserContentSizeRecalculationRequestedEvent
createDropboxBackupFailedEvent(muteCloudEmailsSettingUuid: string, email: string): DropboxBackupFailedEvent
createGoogleDriveBackupFailedEvent(muteCloudEmailsSettingUuid: string, email: string): GoogleDriveBackupFailedEvent
createOneDriveBackupFailedEvent(muteCloudEmailsSettingUuid: string, email: string): OneDriveBackupFailedEvent
createEmailRequestedEvent(dto: {
userEmail: string
messageIdentifier: string
level: string
body: string
subject: string
sender?: string
attachments?: Array<{
filePath: string
fileName: string
attachmentFileName: string
attachmentContentType: string
}>
}): EmailRequestedEvent
createItemsSyncedEvent(dto: {
userUuid: string
extensionUrl: string
@@ -28,12 +36,6 @@ export interface DomainEventFactoryInterface {
source: 'account-deletion' | 'realtime-extensions-sync'
}): ItemsSyncedEvent
createEmailArchiveExtensionSyncedEvent(userUuid: string, extensionId: string): EmailArchiveExtensionSyncedEvent
createEmailBackupAttachmentCreatedEvent(dto: {
backupFileName: string
backupFileIndex: number
backupFilesTotal: number
email: string
}): EmailBackupAttachmentCreatedEvent
createDuplicateItemSyncedEvent(itemUuid: string, userUuid: string): DuplicateItemSyncedEvent
createItemRevisionCreationRequested(itemUuid: string, userUuid: string): ItemRevisionCreationRequestedEvent
createItemDumpedEvent(fileDumpPath: string, userUuid: string): ItemDumpedEvent

View File

@@ -50,9 +50,7 @@ describe('ExtensionsHttpService', () => {
domainEventPublisher.publish = jest.fn()
domainEventFactory = {} as jest.Mocked<DomainEventFactoryInterface>
domainEventFactory.createDropboxBackupFailedEvent = jest.fn()
domainEventFactory.createGoogleDriveBackupFailedEvent = jest.fn()
domainEventFactory.createOneDriveBackupFailedEvent = jest.fn()
domainEventFactory.createEmailRequestedEvent = jest.fn()
contentDecoder = {} as jest.Mocked<ContentDecoderInterface>
contentDecoder.decode = jest.fn().mockReturnValue({ name: 'Dropbox' })
@@ -65,7 +63,6 @@ describe('ExtensionsHttpService', () => {
forceMute: false,
backupFilename: 'test',
authParams,
muteEmailsSettingUuid: '3-4-5',
cloudProvider: 'DROPBOX',
})
@@ -73,7 +70,6 @@ describe('ExtensionsHttpService', () => {
data: {
auth_params: authParams,
backup_filename: 'test',
settings_id: '3-4-5',
silent: false,
user_uuid: '1-2-3',
},
@@ -99,12 +95,11 @@ describe('ExtensionsHttpService', () => {
forceMute: false,
backupFilename: 'test',
authParams,
muteEmailsSettingUuid: '3-4-5',
cloudProvider: 'DROPBOX',
})
expect(domainEventPublisher.publish).toHaveBeenCalled()
expect(domainEventFactory.createDropboxBackupFailedEvent).toHaveBeenCalled()
expect(domainEventFactory.createEmailRequestedEvent).toHaveBeenCalled()
})
it('should send items to extensions server', async () => {
@@ -116,7 +111,6 @@ describe('ExtensionsHttpService', () => {
items: [item],
backupFilename: '',
authParams,
muteEmailsSettingUuid: '3-4-5',
})
expect(httpClient.request).toHaveBeenCalledWith({
@@ -124,7 +118,6 @@ describe('ExtensionsHttpService', () => {
auth_params: authParams,
backup_filename: '',
items: [item],
settings_id: '3-4-5',
silent: false,
user_uuid: '1-2-3',
},
@@ -145,14 +138,12 @@ describe('ExtensionsHttpService', () => {
forceMute: false,
backupFilename: 'backup-file',
authParams,
muteEmailsSettingUuid: '3-4-5',
})
expect(httpClient.request).toHaveBeenCalledWith({
data: {
auth_params: authParams,
backup_filename: 'backup-file',
settings_id: '3-4-5',
silent: false,
user_uuid: '1-2-3',
},
@@ -180,11 +171,10 @@ describe('ExtensionsHttpService', () => {
items: [item],
backupFilename: 'backup-file',
authParams,
muteEmailsSettingUuid: '3-4-5',
})
expect(domainEventPublisher.publish).toHaveBeenCalled()
expect(domainEventFactory.createDropboxBackupFailedEvent).toHaveBeenCalled()
expect(domainEventFactory.createEmailRequestedEvent).toHaveBeenCalled()
})
it('should publish a failed Dropbox backup event if request was sent and extensions server responded not ok', async () => {
@@ -200,11 +190,10 @@ describe('ExtensionsHttpService', () => {
items: [item],
backupFilename: 'backup-file',
authParams,
muteEmailsSettingUuid: '3-4-5',
})
expect(domainEventPublisher.publish).toHaveBeenCalled()
expect(domainEventFactory.createDropboxBackupFailedEvent).toHaveBeenCalled()
expect(domainEventFactory.createEmailRequestedEvent).toHaveBeenCalled()
})
it('should publish a failed Google Drive backup event if request was not sent successfully', async () => {
@@ -222,11 +211,10 @@ describe('ExtensionsHttpService', () => {
items: [item],
backupFilename: 'backup-file',
authParams,
muteEmailsSettingUuid: '3-4-5',
})
expect(domainEventPublisher.publish).toHaveBeenCalled()
expect(domainEventFactory.createGoogleDriveBackupFailedEvent).toHaveBeenCalled()
expect(domainEventFactory.createEmailRequestedEvent).toHaveBeenCalled()
})
it('should publish a failed One Drive backup event if request was not sent successfully', async () => {
@@ -244,11 +232,10 @@ describe('ExtensionsHttpService', () => {
items: [item],
backupFilename: 'backup-file',
authParams,
muteEmailsSettingUuid: '3-4-5',
})
expect(domainEventPublisher.publish).toHaveBeenCalled()
expect(domainEventFactory.createOneDriveBackupFailedEvent).toHaveBeenCalled()
expect(domainEventFactory.createEmailRequestedEvent).toHaveBeenCalled()
})
it('should not publish a failed backup event if emailes are force muted', async () => {
@@ -266,7 +253,6 @@ describe('ExtensionsHttpService', () => {
items: [item],
backupFilename: 'backup-file',
authParams,
muteEmailsSettingUuid: '3-4-5',
})
expect(domainEventPublisher.publish).not.toHaveBeenCalled()
@@ -289,7 +275,6 @@ describe('ExtensionsHttpService', () => {
items: [item],
backupFilename: 'backup-file',
authParams,
muteEmailsSettingUuid: '3-4-5',
})
} catch (e) {
error = e
@@ -316,7 +301,6 @@ describe('ExtensionsHttpService', () => {
items: [item],
backupFilename: 'backup-file',
authParams,
muteEmailsSettingUuid: '3-4-5',
})
} catch (e) {
error = e
@@ -340,11 +324,10 @@ describe('ExtensionsHttpService', () => {
items: [item],
backupFilename: 'backup-file',
authParams,
muteEmailsSettingUuid: '3-4-5',
})
expect(domainEventPublisher.publish).toHaveBeenCalled()
expect(domainEventFactory.createDropboxBackupFailedEvent).toHaveBeenCalled()
expect(domainEventFactory.createEmailRequestedEvent).toHaveBeenCalled()
})
it('should publish a failed Google Drive backup event judging by extension url if request was not sent successfully', async () => {
@@ -362,11 +345,10 @@ describe('ExtensionsHttpService', () => {
items: [item],
backupFilename: 'backup-file',
authParams,
muteEmailsSettingUuid: '3-4-5',
})
expect(domainEventPublisher.publish).toHaveBeenCalled()
expect(domainEventFactory.createGoogleDriveBackupFailedEvent).toHaveBeenCalled()
expect(domainEventFactory.createEmailRequestedEvent).toHaveBeenCalled()
})
it('should publish a failed One Drive backup event judging by extension url if request was not sent successfully', async () => {
@@ -384,11 +366,10 @@ describe('ExtensionsHttpService', () => {
items: [item],
backupFilename: 'backup-file',
authParams,
muteEmailsSettingUuid: '3-4-5',
})
expect(domainEventPublisher.publish).toHaveBeenCalled()
expect(domainEventFactory.createOneDriveBackupFailedEvent).toHaveBeenCalled()
expect(domainEventFactory.createEmailRequestedEvent).toHaveBeenCalled()
})
it('should throw an error if cannot deduce extension by judging from the url', async () => {
@@ -408,7 +389,6 @@ describe('ExtensionsHttpService', () => {
items: [item],
backupFilename: 'backup-file',
authParams,
muteEmailsSettingUuid: '3-4-5',
})
} catch (e) {
error = e
@@ -434,7 +414,6 @@ describe('ExtensionsHttpService', () => {
items: [item],
backupFilename: 'backup-file',
authParams,
muteEmailsSettingUuid: '3-4-5',
})
} catch (e) {
error = e

View File

@@ -1,5 +1,6 @@
import { KeyParamsData } from '@standardnotes/responses'
import { DomainEventInterface, DomainEventPublisherInterface } from '@standardnotes/domain-events'
import { EmailLevel } from '@standardnotes/domain-core'
import { AxiosInstance } from 'axios'
import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
@@ -10,6 +11,9 @@ import { ItemRepositoryInterface } from '../Item/ItemRepositoryInterface'
import { ExtensionName } from './ExtensionName'
import { ExtensionsHttpServiceInterface } from './ExtensionsHttpServiceInterface'
import { SendItemsToExtensionsServerDTO } from './SendItemsToExtensionsServerDTO'
import { getBody as googleDriveBody, getSubject as googleDriveSubject } from '../Email/GoogleDriveBackupFailed'
import { getBody as dropboxBody, getSubject as dropboxSubject } from '../Email/DropboxBackupFailed'
import { getBody as oneDriveBody, getSubject as oneDriveSubject } from '../Email/OneDriveBackupFailed'
@injectable()
export class ExtensionsHttpService implements ExtensionsHttpServiceInterface {
@@ -29,7 +33,6 @@ export class ExtensionsHttpService implements ExtensionsHttpServiceInterface {
authParams: KeyParamsData
forceMute: boolean
userUuid: string
muteEmailsSettingUuid: string
}): Promise<void> {
let sent = false
try {
@@ -38,7 +41,6 @@ export class ExtensionsHttpService implements ExtensionsHttpServiceInterface {
auth_params: dto.authParams,
silent: dto.forceMute,
user_uuid: dto.userUuid,
settings_id: dto.muteEmailsSettingUuid,
}
const response = await this.httpClient.request({
@@ -58,13 +60,9 @@ export class ExtensionsHttpService implements ExtensionsHttpServiceInterface {
this.logger.error(`[${dto.userUuid}] Failed to send a request to extensions server: ${(error as Error).message}`)
}
if (!sent && !dto.forceMute && dto.muteEmailsSettingUuid !== undefined) {
if (!sent && !dto.forceMute) {
await this.domainEventPublisher.publish(
this.createCloudBackupFailedEventBasedOnProvider(
dto.cloudProvider,
dto.authParams.identifier as string,
dto.muteEmailsSettingUuid,
),
this.createCloudBackupFailedEventBasedOnProvider(dto.cloudProvider, dto.authParams.identifier as string),
)
}
}
@@ -77,7 +75,6 @@ export class ExtensionsHttpService implements ExtensionsHttpServiceInterface {
auth_params: dto.authParams,
silent: dto.forceMute,
user_uuid: dto.userUuid,
settings_id: dto.muteEmailsSettingUuid,
}
if (dto.items !== undefined) {
payload.items = dto.items
@@ -100,14 +97,9 @@ export class ExtensionsHttpService implements ExtensionsHttpServiceInterface {
this.logger.error(`[${dto.userUuid}] Failed to send a request to extensions server: ${(error as Error).message}`)
}
if (!sent && !dto.forceMute && dto.muteEmailsSettingUuid !== undefined) {
if (!sent && !dto.forceMute) {
await this.domainEventPublisher.publish(
await this.getBackupFailedEvent(
dto.muteEmailsSettingUuid,
dto.extensionId,
dto.userUuid,
dto.authParams.identifier as string,
),
await this.getBackupFailedEvent(dto.extensionId, dto.userUuid, dto.authParams.identifier as string),
)
}
}
@@ -115,20 +107,36 @@ export class ExtensionsHttpService implements ExtensionsHttpServiceInterface {
private createCloudBackupFailedEventBasedOnProvider(
cloudProvider: 'DROPBOX' | 'GOOGLE_DRIVE' | 'ONE_DRIVE',
email: string,
muteCloudEmailsSettingUuid: string,
): DomainEventInterface {
switch (cloudProvider) {
case 'DROPBOX':
return this.domainEventFactory.createDropboxBackupFailedEvent(muteCloudEmailsSettingUuid, email)
return this.domainEventFactory.createEmailRequestedEvent({
userEmail: email,
level: EmailLevel.LEVELS.FailedCloudBackup,
body: dropboxBody(),
messageIdentifier: 'FAILED_DROPBOX_BACKUP',
subject: dropboxSubject(),
})
case 'GOOGLE_DRIVE':
return this.domainEventFactory.createGoogleDriveBackupFailedEvent(muteCloudEmailsSettingUuid, email)
return this.domainEventFactory.createEmailRequestedEvent({
userEmail: email,
level: EmailLevel.LEVELS.FailedCloudBackup,
body: googleDriveBody(),
messageIdentifier: 'FAILED_GOOGLE_DRIVE_BACKUP',
subject: googleDriveSubject(),
})
case 'ONE_DRIVE':
return this.domainEventFactory.createOneDriveBackupFailedEvent(muteCloudEmailsSettingUuid, email)
return this.domainEventFactory.createEmailRequestedEvent({
userEmail: email,
level: EmailLevel.LEVELS.FailedCloudBackup,
body: oneDriveBody(),
messageIdentifier: 'FAILED_ONE_DRIVE_BACKUP',
subject: oneDriveSubject(),
})
}
}
private async getBackupFailedEvent(
muteCloudEmailsSettingUuid: string,
extensionId: string,
userUuid: string,
email: string,
@@ -141,11 +149,11 @@ export class ExtensionsHttpService implements ExtensionsHttpServiceInterface {
const content = this.contentDecoder.decode(extension.content)
switch (this.getExtensionName(content)) {
case ExtensionName.Dropbox:
return this.createCloudBackupFailedEventBasedOnProvider('DROPBOX', muteCloudEmailsSettingUuid, email)
return this.createCloudBackupFailedEventBasedOnProvider('DROPBOX', email)
case ExtensionName.GoogleDrive:
return this.createCloudBackupFailedEventBasedOnProvider('GOOGLE_DRIVE', muteCloudEmailsSettingUuid, email)
return this.createCloudBackupFailedEventBasedOnProvider('GOOGLE_DRIVE', email)
case ExtensionName.OneDrive:
return this.createCloudBackupFailedEventBasedOnProvider('ONE_DRIVE', muteCloudEmailsSettingUuid, email)
return this.createCloudBackupFailedEventBasedOnProvider('ONE_DRIVE', email)
}
}

View File

@@ -1,4 +1,5 @@
import { KeyParamsData } from '@standardnotes/responses'
import { Item } from '../Item/Item'
export type SendItemsToExtensionsServerDTO = {
@@ -8,6 +9,5 @@ export type SendItemsToExtensionsServerDTO = {
authParams: KeyParamsData
forceMute: boolean
userUuid: string
muteEmailsSettingUuid?: string
items?: Array<Item>
}

View File

@@ -3,7 +3,7 @@ import 'reflect-metadata'
import {
DomainEventPublisherInterface,
EmailArchiveExtensionSyncedEvent,
EmailBackupAttachmentCreatedEvent,
EmailRequestedEvent,
} from '@standardnotes/domain-events'
import { Logger } from 'winston'
import { AuthHttpServiceInterface } from '../Auth/AuthHttpServiceInterface'
@@ -35,6 +35,7 @@ describe('EmailArchiveExtensionSyncedEventHandler', () => {
domainEventFactory,
emailAttachmentMaxByteSize,
itemTransferCalculator,
's3-backup-bucket-name',
logger,
)
@@ -62,9 +63,7 @@ describe('EmailArchiveExtensionSyncedEventHandler', () => {
domainEventPublisher.publish = jest.fn()
domainEventFactory = {} as jest.Mocked<DomainEventFactoryInterface>
domainEventFactory.createEmailBackupAttachmentCreatedEvent = jest
.fn()
.mockReturnValue({} as jest.Mocked<EmailBackupAttachmentCreatedEvent>)
domainEventFactory.createEmailRequestedEvent = jest.fn().mockReturnValue({} as jest.Mocked<EmailRequestedEvent>)
itemTransferCalculator = {} as jest.Mocked<ItemTransferCalculatorInterface>
itemTransferCalculator.computeItemUuidBundlesToFetch = jest.fn().mockReturnValue([['1-2-3']])
@@ -78,12 +77,7 @@ describe('EmailArchiveExtensionSyncedEventHandler', () => {
await createHandler().handle(event)
expect(domainEventPublisher.publish).toHaveBeenCalledTimes(1)
expect(domainEventFactory.createEmailBackupAttachmentCreatedEvent).toHaveBeenCalledWith({
backupFileIndex: 1,
backupFileName: 'backup-file-name',
backupFilesTotal: 1,
email: 'test@test.com',
})
expect(domainEventFactory.createEmailRequestedEvent).toHaveBeenCalled()
})
it('should inform that multipart backup attachment for email was created', async () => {
@@ -96,18 +90,7 @@ describe('EmailArchiveExtensionSyncedEventHandler', () => {
await createHandler().handle(event)
expect(domainEventPublisher.publish).toHaveBeenCalledTimes(2)
expect(domainEventFactory.createEmailBackupAttachmentCreatedEvent).toHaveBeenNthCalledWith(1, {
backupFileIndex: 1,
backupFileName: 'backup-file-name-1',
backupFilesTotal: 2,
email: 'test@test.com',
})
expect(domainEventFactory.createEmailBackupAttachmentCreatedEvent).toHaveBeenNthCalledWith(2, {
backupFileIndex: 2,
backupFileName: 'backup-file-name-2',
backupFilesTotal: 2,
email: 'test@test.com',
})
expect(domainEventFactory.createEmailRequestedEvent).toHaveBeenCalledTimes(2)
})
it('should not inform that backup attachment for email was created if user key params cannot be obtained', async () => {
@@ -118,7 +101,7 @@ describe('EmailArchiveExtensionSyncedEventHandler', () => {
await createHandler().handle(event)
expect(domainEventPublisher.publish).not.toHaveBeenCalled()
expect(domainEventFactory.createEmailBackupAttachmentCreatedEvent).not.toHaveBeenCalled()
expect(domainEventFactory.createEmailRequestedEvent).not.toHaveBeenCalled()
})
it('should not inform that backup attachment for email was created if backup file name is empty', async () => {
@@ -127,6 +110,6 @@ describe('EmailArchiveExtensionSyncedEventHandler', () => {
await createHandler().handle(event)
expect(domainEventPublisher.publish).not.toHaveBeenCalled()
expect(domainEventFactory.createEmailBackupAttachmentCreatedEvent).not.toHaveBeenCalled()
expect(domainEventFactory.createEmailRequestedEvent).not.toHaveBeenCalled()
})
})

View File

@@ -4,6 +4,7 @@ import {
DomainEventPublisherInterface,
EmailArchiveExtensionSyncedEvent,
} from '@standardnotes/domain-events'
import { EmailLevel } from '@standardnotes/domain-core'
import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
import TYPES from '../../Bootstrap/Types'
@@ -13,6 +14,7 @@ import { ItemBackupServiceInterface } from '../Item/ItemBackupServiceInterface'
import { ItemRepositoryInterface } from '../Item/ItemRepositoryInterface'
import { ItemQuery } from '../Item/ItemQuery'
import { ItemTransferCalculatorInterface } from '../Item/ItemTransferCalculatorInterface'
import { getBody, getSubject } from '../Email/EmailBackupAttachmentCreated'
@injectable()
export class EmailArchiveExtensionSyncedEventHandler implements DomainEventHandlerInterface {
@@ -24,6 +26,7 @@ export class EmailArchiveExtensionSyncedEventHandler implements DomainEventHandl
@inject(TYPES.DomainEventFactory) private domainEventFactory: DomainEventFactoryInterface,
@inject(TYPES.EMAIL_ATTACHMENT_MAX_BYTE_SIZE) private emailAttachmentMaxByteSize: number,
@inject(TYPES.ItemTransferCalculator) private itemTransferCalculator: ItemTransferCalculatorInterface,
@inject(TYPES.S3_BACKUP_BUCKET_NAME) private s3BackupBucketName: string,
@inject(TYPES.Logger) private logger: Logger,
) {}
@@ -64,14 +67,24 @@ export class EmailArchiveExtensionSyncedEventHandler implements DomainEventHandl
this.logger.debug(`Data backed up into: ${backupFileName}`)
if (backupFileName.length !== 0) {
this.logger.debug('Publishing EMAIL_BACKUP_ATTACHMENT_CREATED event')
const dateOnly = new Date().toISOString().substring(0, 10)
await this.domainEventPublisher.publish(
this.domainEventFactory.createEmailBackupAttachmentCreatedEvent({
backupFileName,
backupFileIndex: bundleIndex++,
backupFilesTotal: itemUuidBundles.length,
email: authParams.identifier as string,
this.domainEventFactory.createEmailRequestedEvent({
body: getBody(authParams.identifier as string),
level: EmailLevel.LEVELS.System,
messageIdentifier: 'DATA_BACKUP',
subject: getSubject(bundleIndex++, itemUuidBundles.length, dateOnly),
userEmail: authParams.identifier as string,
sender: 'backups@standardnotes.org',
attachments: [
{
fileName: backupFileName,
filePath: this.s3BackupBucketName,
attachmentFileName: `SN-Data-${dateOnly}.txt`,
attachmentContentType: 'application/json',
},
],
}),
)
}

View File

@@ -3,7 +3,7 @@ import 'reflect-metadata'
import {
DomainEventPublisherInterface,
EmailBackupRequestedEvent,
EmailBackupAttachmentCreatedEvent,
EmailRequestedEvent,
} from '@standardnotes/domain-events'
import { Logger } from 'winston'
import { AuthHttpServiceInterface } from '../Auth/AuthHttpServiceInterface'
@@ -35,6 +35,7 @@ describe('EmailBackupRequestedEventHandler', () => {
domainEventFactory,
emailAttachmentMaxByteSize,
itemTransferCalculator,
's3-backup-bucket-name',
logger,
)
@@ -62,9 +63,7 @@ describe('EmailBackupRequestedEventHandler', () => {
domainEventPublisher.publish = jest.fn()
domainEventFactory = {} as jest.Mocked<DomainEventFactoryInterface>
domainEventFactory.createEmailBackupAttachmentCreatedEvent = jest
.fn()
.mockReturnValue({} as jest.Mocked<EmailBackupAttachmentCreatedEvent>)
domainEventFactory.createEmailRequestedEvent = jest.fn().mockReturnValue({} as jest.Mocked<EmailRequestedEvent>)
itemTransferCalculator = {} as jest.Mocked<ItemTransferCalculatorInterface>
itemTransferCalculator.computeItemUuidBundlesToFetch = jest.fn().mockReturnValue([['1-2-3']])
@@ -79,12 +78,7 @@ describe('EmailBackupRequestedEventHandler', () => {
await createHandler().handle(event)
expect(domainEventPublisher.publish).toHaveBeenCalledTimes(1)
expect(domainEventFactory.createEmailBackupAttachmentCreatedEvent).toHaveBeenCalledWith({
backupFileIndex: 1,
backupFileName: 'backup-file-name',
backupFilesTotal: 1,
email: 'test@test.com',
})
expect(domainEventFactory.createEmailRequestedEvent).toHaveBeenCalled()
})
it('should inform that multipart backup attachment for email was created', async () => {
@@ -97,18 +91,7 @@ describe('EmailBackupRequestedEventHandler', () => {
await createHandler().handle(event)
expect(domainEventPublisher.publish).toHaveBeenCalledTimes(2)
expect(domainEventFactory.createEmailBackupAttachmentCreatedEvent).toHaveBeenNthCalledWith(1, {
backupFileIndex: 1,
backupFileName: 'backup-file-name-1',
backupFilesTotal: 2,
email: 'test@test.com',
})
expect(domainEventFactory.createEmailBackupAttachmentCreatedEvent).toHaveBeenNthCalledWith(2, {
backupFileIndex: 2,
backupFileName: 'backup-file-name-2',
backupFilesTotal: 2,
email: 'test@test.com',
})
expect(domainEventFactory.createEmailRequestedEvent).toHaveBeenCalledTimes(2)
})
it('should not inform that backup attachment for email was created if user key params cannot be obtained', async () => {
@@ -119,7 +102,7 @@ describe('EmailBackupRequestedEventHandler', () => {
await createHandler().handle(event)
expect(domainEventPublisher.publish).not.toHaveBeenCalled()
expect(domainEventFactory.createEmailBackupAttachmentCreatedEvent).not.toHaveBeenCalled()
expect(domainEventFactory.createEmailRequestedEvent).not.toHaveBeenCalled()
})
it('should not inform that backup attachment for email was created if backup file name is empty', async () => {
@@ -128,6 +111,6 @@ describe('EmailBackupRequestedEventHandler', () => {
await createHandler().handle(event)
expect(domainEventPublisher.publish).not.toHaveBeenCalled()
expect(domainEventFactory.createEmailBackupAttachmentCreatedEvent).not.toHaveBeenCalled()
expect(domainEventFactory.createEmailRequestedEvent).not.toHaveBeenCalled()
})
})

View File

@@ -4,6 +4,7 @@ import {
DomainEventPublisherInterface,
EmailBackupRequestedEvent,
} from '@standardnotes/domain-events'
import { EmailLevel } from '@standardnotes/domain-core'
import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
import TYPES from '../../Bootstrap/Types'
@@ -13,6 +14,7 @@ import { ItemBackupServiceInterface } from '../Item/ItemBackupServiceInterface'
import { ItemRepositoryInterface } from '../Item/ItemRepositoryInterface'
import { ItemTransferCalculatorInterface } from '../Item/ItemTransferCalculatorInterface'
import { ItemQuery } from '../Item/ItemQuery'
import { getBody, getSubject } from '../Email/EmailBackupAttachmentCreated'
@injectable()
export class EmailBackupRequestedEventHandler implements DomainEventHandlerInterface {
@@ -24,6 +26,7 @@ export class EmailBackupRequestedEventHandler implements DomainEventHandlerInter
@inject(TYPES.DomainEventFactory) private domainEventFactory: DomainEventFactoryInterface,
@inject(TYPES.EMAIL_ATTACHMENT_MAX_BYTE_SIZE) private emailAttachmentMaxByteSize: number,
@inject(TYPES.ItemTransferCalculator) private itemTransferCalculator: ItemTransferCalculatorInterface,
@inject(TYPES.S3_BACKUP_BUCKET_NAME) private s3BackupBucketName: string,
@inject(TYPES.Logger) private logger: Logger,
) {}
@@ -68,15 +71,24 @@ export class EmailBackupRequestedEventHandler implements DomainEventHandlerInter
return
}
this.logger.debug('Publishing EMAIL_BACKUP_ATTACHMENT_CREATED event')
const dateOnly = new Date().toISOString().substring(0, 10)
await this.domainEventPublisher.publish(
this.domainEventFactory.createEmailBackupAttachmentCreatedEvent({
backupFileName,
backupFileIndex: bundleIndex++,
backupFilesTotal: itemUuidBundles.length,
email: authParams.identifier as string,
this.domainEventFactory.createEmailRequestedEvent({
body: getBody(authParams.identifier as string),
level: EmailLevel.LEVELS.System,
messageIdentifier: 'DATA_BACKUP',
subject: getSubject(bundleIndex++, itemUuidBundles.length, dateOnly),
userEmail: authParams.identifier as string,
sender: 'backups@standardnotes.org',
attachments: [
{
fileName: backupFileName,
filePath: this.s3BackupBucketName,
attachmentFileName: `SN-Data-${dateOnly}.txt`,
attachmentContentType: 'application/json',
},
],
}),
)
}

View File

@@ -3,6 +3,46 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.4.48](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.4.47...@standardnotes/websockets-server@1.4.48) (2022-12-09)
**Note:** Version bump only for package @standardnotes/websockets-server
## [1.4.47](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.4.46...@standardnotes/websockets-server@1.4.47) (2022-12-09)
**Note:** Version bump only for package @standardnotes/websockets-server
## [1.4.46](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.4.45...@standardnotes/websockets-server@1.4.46) (2022-12-09)
**Note:** Version bump only for package @standardnotes/websockets-server
## [1.4.45](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.4.44...@standardnotes/websockets-server@1.4.45) (2022-12-09)
**Note:** Version bump only for package @standardnotes/websockets-server
## [1.4.44](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.4.43...@standardnotes/websockets-server@1.4.44) (2022-12-09)
**Note:** Version bump only for package @standardnotes/websockets-server
## [1.4.43](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.4.42...@standardnotes/websockets-server@1.4.43) (2022-12-08)
**Note:** Version bump only for package @standardnotes/websockets-server
## [1.4.42](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.4.41...@standardnotes/websockets-server@1.4.42) (2022-12-08)
**Note:** Version bump only for package @standardnotes/websockets-server
## [1.4.41](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.4.40...@standardnotes/websockets-server@1.4.41) (2022-12-08)
**Note:** Version bump only for package @standardnotes/websockets-server
## [1.4.40](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.4.39...@standardnotes/websockets-server@1.4.40) (2022-12-08)
**Note:** Version bump only for package @standardnotes/websockets-server
## [1.4.39](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.4.38...@standardnotes/websockets-server@1.4.39) (2022-12-08)
**Note:** Version bump only for package @standardnotes/websockets-server
## [1.4.38](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.4.37...@standardnotes/websockets-server@1.4.38) (2022-12-07)
**Note:** Version bump only for package @standardnotes/websockets-server

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/websockets-server",
"version": "1.4.38",
"version": "1.4.48",
"engines": {
"node": ">=18.0.0 <19.0.0"
},

View File

@@ -3,6 +3,46 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.17.47](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.46...@standardnotes/workspace-server@1.17.47) (2022-12-09)
**Note:** Version bump only for package @standardnotes/workspace-server
## [1.17.46](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.45...@standardnotes/workspace-server@1.17.46) (2022-12-09)
**Note:** Version bump only for package @standardnotes/workspace-server
## [1.17.45](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.44...@standardnotes/workspace-server@1.17.45) (2022-12-09)
**Note:** Version bump only for package @standardnotes/workspace-server
## [1.17.44](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.43...@standardnotes/workspace-server@1.17.44) (2022-12-09)
**Note:** Version bump only for package @standardnotes/workspace-server
## [1.17.43](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.42...@standardnotes/workspace-server@1.17.43) (2022-12-09)
**Note:** Version bump only for package @standardnotes/workspace-server
## [1.17.42](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.41...@standardnotes/workspace-server@1.17.42) (2022-12-08)
**Note:** Version bump only for package @standardnotes/workspace-server
## [1.17.41](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.40...@standardnotes/workspace-server@1.17.41) (2022-12-08)
**Note:** Version bump only for package @standardnotes/workspace-server
## [1.17.40](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.39...@standardnotes/workspace-server@1.17.40) (2022-12-08)
**Note:** Version bump only for package @standardnotes/workspace-server
## [1.17.39](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.38...@standardnotes/workspace-server@1.17.39) (2022-12-08)
**Note:** Version bump only for package @standardnotes/workspace-server
## [1.17.38](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.37...@standardnotes/workspace-server@1.17.38) (2022-12-08)
**Note:** Version bump only for package @standardnotes/workspace-server
## [1.17.37](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.36...@standardnotes/workspace-server@1.17.37) (2022-12-07)
**Note:** Version bump only for package @standardnotes/workspace-server

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/workspace-server",
"version": "1.17.37",
"version": "1.17.47",
"engines": {
"node": ">=18.0.0 <19.0.0"
},