Compare commits

..

17 Commits

Author SHA1 Message Date
standardci
76e34131fb chore(release): publish new version
- @standardnotes/api-gateway@1.24.4
 - @standardnotes/auth-server@1.36.4
 - @standardnotes/common@1.34.0
 - @standardnotes/domain-events-infra@1.8.15
 - @standardnotes/domain-events@2.61.1
 - @standardnotes/event-store@1.3.20
 - @standardnotes/files-server@1.6.6
 - @standardnotes/predicates@1.4.3
 - @standardnotes/scheduler-server@1.10.34
 - @standardnotes/security@1.4.1
 - @standardnotes/syncing-server@1.8.18
2022-10-04 12:17:15 +00:00
Karol Sójko
3c40ee4b4a feat(common): add subscription billing frequency 2022-10-04 14:15:45 +02:00
standardci
5abd7ae32c chore(release): publish new version
- @standardnotes/analytics@1.34.0
 - @standardnotes/api-gateway@1.24.3
 - @standardnotes/auth-server@1.36.3
 - @standardnotes/syncing-server@1.8.17
2022-10-04 11:26:29 +00:00
Karol Sójko
09b3f9a0d7 fix(auth): turn down severity of logs for predicate verification 2022-10-04 13:24:58 +02:00
Karol Sójko
19455ba6a7 feat(analytics): add new statistics measures for income 2022-10-04 13:24:58 +02:00
standardci
7d042689f0 chore(release): publish new version
- @standardnotes/api-gateway@1.24.2
2022-10-03 12:49:37 +00:00
Karol Sójko
f43fbf1584 fix(api-gateway): report churn values for empty months 2022-10-03 14:47:45 +02:00
standardci
24c0cb8366 chore(release): publish new version
- @standardnotes/api-gateway@1.24.1
2022-10-03 12:15:56 +00:00
Karol Sójko
2236cc3828 fix: add debug logs for churn calculation 2022-10-03 14:14:27 +02:00
standardci
039d44718a chore(release): publish new version
- @standardnotes/analytics@1.33.0
 - @standardnotes/api-gateway@1.24.0
 - @standardnotes/auth-server@1.36.2
 - @standardnotes/domain-events-infra@1.8.14
 - @standardnotes/domain-events@2.61.0
 - @standardnotes/event-store@1.3.19
 - @standardnotes/files-server@1.6.5
 - @standardnotes/scheduler-server@1.10.33
 - @standardnotes/syncing-server@1.8.16
2022-10-03 11:22:13 +00:00
Karol Sójko
f075cd8c4d feat: add calculating monthly churn rate 2022-10-03 13:19:53 +02:00
standardci
ea0f3e8999 chore(release): publish new version
- @standardnotes/auth-server@1.36.1
2022-10-03 08:40:15 +00:00
Karol Sójko
e7736bba25 fix(auth): counting active subscriptions 2022-10-03 10:38:31 +02:00
standardci
fdf8809e13 chore(release): publish new version
- @standardnotes/auth-server@1.36.0
2022-10-03 08:33:51 +00:00
Karol Sójko
6a9d479f71 feat(auth): disallow v1 sign in for users with 004 protocol version 2022-10-03 10:31:58 +02:00
standardci
82c9637f37 chore(release): publish new version
- @standardnotes/api-gateway@1.23.0
2022-09-30 12:02:50 +00:00
Karol Sójko
dfab849f48 feat(api-gateway): add churn metrics to the report 2022-09-30 14:01:15 +02:00
55 changed files with 590 additions and 117 deletions

61
.pnp.cjs generated
View File

@@ -2484,14 +2484,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
}]\
]],\
["@standardnotes/api", [\
["npm:1.8.1", {\
"packageLocation": "./.yarn/cache/@standardnotes-api-npm-1.8.1-15c2e051d4-76c5d1a2d2.zip/node_modules/@standardnotes/api/",\
["npm:1.9.0", {\
"packageLocation": "./.yarn/cache/@standardnotes-api-npm-1.9.0-507434ff00-cc3feac393.zip/node_modules/@standardnotes/api/",\
"packageDependencies": [\
["@standardnotes/api", "npm:1.8.1"],\
["@standardnotes/api", "npm:1.9.0"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/encryption", "npm:1.15.3"],\
["@standardnotes/models", "npm:1.18.3"],\
["@standardnotes/responses", "npm:1.10.2"],\
["@standardnotes/encryption", "npm:1.15.9"],\
["@standardnotes/models", "npm:1.22.0"],\
["@standardnotes/responses", "npm:1.10.3"],\
["@standardnotes/security", "workspace:packages/security"],\
["@standardnotes/utils", "npm:1.9.0"],\
["reflect-metadata", "npm:0.1.13"]\
@@ -2563,7 +2563,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["@newrelic/winston-enricher", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:4.0.0"],\
["@sentry/node", "npm:7.5.0"],\
["@standardnotes/analytics", "workspace:packages/analytics"],\
["@standardnotes/api", "npm:1.8.1"],\
["@standardnotes/api", "npm:1.9.0"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
@@ -2688,14 +2688,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
}]\
]],\
["@standardnotes/encryption", [\
["npm:1.15.3", {\
"packageLocation": "./.yarn/cache/@standardnotes-encryption-npm-1.15.3-3580c52c1f-1a7863299f.zip/node_modules/@standardnotes/encryption/",\
["npm:1.15.9", {\
"packageLocation": "./.yarn/cache/@standardnotes-encryption-npm-1.15.9-00c7fac9f6-7595ac08ce.zip/node_modules/@standardnotes/encryption/",\
"packageDependencies": [\
["@standardnotes/encryption", "npm:1.15.3"],\
["@standardnotes/encryption", "npm:1.15.9"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/models", "npm:1.18.3"],\
["@standardnotes/responses", "npm:1.10.2"],\
["@standardnotes/sncrypto-common", "npm:1.11.1"],\
["@standardnotes/models", "npm:1.22.0"],\
["@standardnotes/responses", "npm:1.10.3"],\
["@standardnotes/sncrypto-common", "npm:1.12.0"],\
["@standardnotes/utils", "npm:1.9.0"],\
["reflect-metadata", "npm:0.1.13"]\
],\
@@ -2743,17 +2743,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
],\
"linkType": "HARD"\
}],\
["npm:1.52.0", {\
"packageLocation": "./.yarn/cache/@standardnotes-features-npm-1.52.0-8c1adf7881-3e6014272f.zip/node_modules/@standardnotes/features/",\
"packageDependencies": [\
["@standardnotes/features", "npm:1.52.0"],\
["@standardnotes/auth", "npm:3.19.4"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/security", "workspace:packages/security"],\
["reflect-metadata", "npm:0.1.13"]\
],\
"linkType": "HARD"\
}],\
["npm:1.52.1", {\
"packageLocation": "./.yarn/cache/@standardnotes-features-npm-1.52.1-1fee85cf4e-ff3684399e.zip/node_modules/@standardnotes/features/",\
"packageDependencies": [\
@@ -2819,13 +2808,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
}]\
]],\
["@standardnotes/models", [\
["npm:1.18.3", {\
"packageLocation": "./.yarn/cache/@standardnotes-models-npm-1.18.3-6c65a62f30-21830c805f.zip/node_modules/@standardnotes/models/",\
["npm:1.22.0", {\
"packageLocation": "./.yarn/cache/@standardnotes-models-npm-1.22.0-2cc72f987b-9928246368.zip/node_modules/@standardnotes/models/",\
"packageDependencies": [\
["@standardnotes/models", "npm:1.18.3"],\
["@standardnotes/models", "npm:1.22.0"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/features", "npm:1.52.0"],\
["@standardnotes/responses", "npm:1.10.2"],\
["@standardnotes/features", "npm:1.52.1"],\
["@standardnotes/responses", "npm:1.10.3"],\
["@standardnotes/utils", "npm:1.9.0"],\
["lodash", "npm:4.17.21"],\
["reflect-metadata", "npm:0.1.13"]\
@@ -2862,12 +2851,12 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
}]\
]],\
["@standardnotes/responses", [\
["npm:1.10.2", {\
"packageLocation": "./.yarn/cache/@standardnotes-responses-npm-1.10.2-39d2d1f9b5-364724b5c7.zip/node_modules/@standardnotes/responses/",\
["npm:1.10.3", {\
"packageLocation": "./.yarn/cache/@standardnotes-responses-npm-1.10.3-7cdb15f83a-4a1e31eb89.zip/node_modules/@standardnotes/responses/",\
"packageDependencies": [\
["@standardnotes/responses", "npm:1.10.2"],\
["@standardnotes/responses", "npm:1.10.3"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/features", "npm:1.52.0"],\
["@standardnotes/features", "npm:1.52.1"],\
["@standardnotes/security", "workspace:packages/security"],\
["reflect-metadata", "npm:0.1.13"]\
],\
@@ -2978,10 +2967,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
}]\
]],\
["@standardnotes/sncrypto-common", [\
["npm:1.11.1", {\
"packageLocation": "./.yarn/cache/@standardnotes-sncrypto-common-npm-1.11.1-58d12d6912-69d698abb7.zip/node_modules/@standardnotes/sncrypto-common/",\
["npm:1.12.0", {\
"packageLocation": "./.yarn/cache/@standardnotes-sncrypto-common-npm-1.12.0-1a093ff006-b89a14bd23.zip/node_modules/@standardnotes/sncrypto-common/",\
"packageDependencies": [\
["@standardnotes/sncrypto-common", "npm:1.11.1"],\
["@standardnotes/sncrypto-common", "npm:1.12.0"],\
["reflect-metadata", "npm:0.1.13"]\
],\
"linkType": "HARD"\

View File

@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.34.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@1.33.0...@standardnotes/analytics@1.34.0) (2022-10-04)
### Features
* **analytics:** add new statistics measures for income ([19455ba](https://github.com/standardnotes/server/commit/19455ba6a7d84a389830c728c3dfea550b156985))
# [1.33.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@1.32.0...@standardnotes/analytics@1.33.0) (2022-10-03)
### Features
* add calculating monthly churn rate ([f075cd8](https://github.com/standardnotes/server/commit/f075cd8c4dfc411ba513dfec21bb84c03b238254))
# [1.32.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@1.31.1...@standardnotes/analytics@1.32.0) (2022-09-30)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/analytics",
"version": "1.32.0",
"version": "1.34.0",
"engines": {
"node": ">=14.0.0 <17.0.0"
},

View File

@@ -12,7 +12,7 @@ export interface AnalyticsStoreInterface {
secondActivity: AnalyticsActivity
secondActivityPeriodKey: string
}): Promise<number>
calculateActivityTotalCount(activity: AnalyticsActivity, period: Period): Promise<number>
calculateActivityTotalCount(activity: AnalyticsActivity, periodOrPeriodKey: Period | string): Promise<number>
calculateActivityChangesTotalCount(
activity: AnalyticsActivity,
period: Period,

View File

@@ -1,5 +1,13 @@
export enum StatisticsMeasure {
Income = 'income',
PlusSubscriptionInitialMonthlyPaymentsIncome = 'plus-subscription-initial-monthly-payments-income',
ProSubscriptionInitialMonthlyPaymentsIncome = 'pro-subscription-initial-monthly-payments-income',
PlusSubscriptionInitialAnnualPaymentsIncome = 'plus-subscription-initial-annual-payments-income',
ProSubscriptionInitialAnnualPaymentsIncome = 'pro-subscription-initial-annual-payments-income',
PlusSubscriptionRenewingMonthlyPaymentsIncome = 'plus-subscription-renewing-monthly-payments-income',
ProSubscriptionRenewingMonthlyPaymentsIncome = 'pro-subscription-renewing-monthly-payments-income',
PlusSubscriptionRenewingAnnualPaymentsIncome = 'plus-subscription-renewing-annual-payments-income',
ProSubscriptionRenewingAnnualPaymentsIncome = 'pro-subscription-renewing-annual-payments-income',
SubscriptionLength = 'subscription-length',
RegistrationLength = 'registration-length',
RegistrationToSubscriptionTime = 'registration-to-subscription-time',

View File

@@ -11,5 +11,5 @@ export interface StatisticsStoreInterface {
incrementMeasure(measure: StatisticsMeasure, value: number, periods: Period[]): Promise<void>
setMeasure(measure: StatisticsMeasure, value: number, periods: Period[]): Promise<void>
getMeasureAverage(measure: StatisticsMeasure, period: Period): Promise<number>
getMeasureTotal(measure: StatisticsMeasure, period: Period): Promise<number>
getMeasureTotal(measure: StatisticsMeasure, periodOrPeriodKey: Period | string): Promise<number>
}

View File

@@ -14,4 +14,16 @@ export enum Period {
Q2ThisYear,
Q3ThisYear,
Q4ThisYear,
JanuaryThisYear,
FebruaryThisYear,
MarchThisYear,
AprilThisYear,
MayThisYear,
JuneThisYear,
JulyThisYear,
AugustThisYear,
SeptemberThisYear,
OctoberThisYear,
NovemberThisYear,
DecemberThisYear,
}

View File

@@ -3,6 +3,20 @@ import { PeriodKeyGenerator } from './PeriodKeyGenerator'
describe('PeriodKeyGenerator', () => {
const createGenerator = () => new PeriodKeyGenerator()
const months = [
Period.JanuaryThisYear,
Period.FebruaryThisYear,
Period.MarchThisYear,
Period.AprilThisYear,
Period.MayThisYear,
Period.JuneThisYear,
Period.JulyThisYear,
Period.AugustThisYear,
Period.SeptemberThisYear,
Period.OctoberThisYear,
Period.NovemberThisYear,
Period.DecemberThisYear,
]
beforeEach(() => {
jest.useFakeTimers()
@@ -48,6 +62,23 @@ describe('PeriodKeyGenerator', () => {
])
})
it('should generate period keys for this year', () => {
expect(createGenerator().getDiscretePeriodKeys(Period.ThisYear)).toEqual([
'2022-1',
'2022-2',
'2022-3',
'2022-4',
'2022-5',
'2022-6',
'2022-7',
'2022-8',
'2022-9',
'2022-10',
'2022-11',
'2022-12',
])
})
it('should generate period keys for last 7 days', () => {
expect(createGenerator().getDiscretePeriodKeys(Period.Last7Days)).toEqual([
'2022-5-17',
@@ -60,6 +91,81 @@ describe('PeriodKeyGenerator', () => {
])
})
it('should generate period keys for this month', () => {
expect(createGenerator().getDiscretePeriodKeys(Period.ThisMonth)).toEqual([
'2022-5-1',
'2022-5-2',
'2022-5-3',
'2022-5-4',
'2022-5-5',
'2022-5-6',
'2022-5-7',
'2022-5-8',
'2022-5-9',
'2022-5-10',
'2022-5-11',
'2022-5-12',
'2022-5-13',
'2022-5-14',
'2022-5-15',
'2022-5-16',
'2022-5-17',
'2022-5-18',
'2022-5-19',
'2022-5-20',
'2022-5-21',
'2022-5-22',
'2022-5-23',
'2022-5-24',
'2022-5-25',
'2022-5-26',
'2022-5-27',
'2022-5-28',
'2022-5-29',
'2022-5-30',
'2022-5-31',
])
})
it('should generate period keys for specific month', () => {
expect(createGenerator().getDiscretePeriodKeys(Period.FebruaryThisYear)).toEqual([
'2022-2-1',
'2022-2-2',
'2022-2-3',
'2022-2-4',
'2022-2-5',
'2022-2-6',
'2022-2-7',
'2022-2-8',
'2022-2-9',
'2022-2-10',
'2022-2-11',
'2022-2-12',
'2022-2-13',
'2022-2-14',
'2022-2-15',
'2022-2-16',
'2022-2-17',
'2022-2-18',
'2022-2-19',
'2022-2-20',
'2022-2-21',
'2022-2-22',
'2022-2-23',
'2022-2-24',
'2022-2-25',
'2022-2-26',
'2022-2-27',
'2022-2-28',
])
})
it('should generate period keys for specific months', () => {
for (const month of months) {
expect(createGenerator().getDiscretePeriodKeys(month).length >= 28).toBeTruthy()
}
})
it('should generate period keys for Q1', () => {
expect(createGenerator().getDiscretePeriodKeys(Period.Q1ThisYear)).toEqual(['2022-1', '2022-2', '2022-3'])
})
@@ -76,6 +182,10 @@ describe('PeriodKeyGenerator', () => {
expect(createGenerator().getDiscretePeriodKeys(Period.Q4ThisYear)).toEqual(['2022-10', '2022-11', '2022-12'])
})
it('should generate a period key for this year', () => {
expect(createGenerator().getPeriodKey(Period.ThisYear)).toEqual('2022')
})
it('should generate a period key for today', () => {
expect(createGenerator().getPeriodKey(Period.Today)).toEqual('2022-5-24')
})
@@ -104,6 +214,12 @@ describe('PeriodKeyGenerator', () => {
expect(createGenerator().getPeriodKey(Period.ThisMonth)).toEqual('2022-5')
})
it('should generate a period key for each month', () => {
for (let i = 0; i < months.length; i++) {
expect(createGenerator().getPeriodKey(months[i])).toEqual(`2022-${i + 1}`)
}
})
it('should generate a period key for last month', () => {
expect(createGenerator().getPeriodKey(Period.LastMonth)).toEqual('2022-4')
})
@@ -129,4 +245,19 @@ describe('PeriodKeyGenerator', () => {
expect(error).not.toBeNull()
})
it('should convert period key to period', () => {
expect(createGenerator().convertPeriodKeyToPeriod('2022-1')).toEqual(Period.JanuaryThisYear)
expect(createGenerator().convertPeriodKeyToPeriod('2022-2')).toEqual(Period.FebruaryThisYear)
expect(createGenerator().convertPeriodKeyToPeriod('2022-3')).toEqual(Period.MarchThisYear)
expect(createGenerator().convertPeriodKeyToPeriod('2022-4')).toEqual(Period.AprilThisYear)
expect(createGenerator().convertPeriodKeyToPeriod('2022-5')).toEqual(Period.MayThisYear)
expect(createGenerator().convertPeriodKeyToPeriod('2022-6')).toEqual(Period.JuneThisYear)
expect(createGenerator().convertPeriodKeyToPeriod('2022-7')).toEqual(Period.JulyThisYear)
expect(createGenerator().convertPeriodKeyToPeriod('2022-8')).toEqual(Period.AugustThisYear)
expect(createGenerator().convertPeriodKeyToPeriod('2022-9')).toEqual(Period.SeptemberThisYear)
expect(createGenerator().convertPeriodKeyToPeriod('2022-10')).toEqual(Period.OctoberThisYear)
expect(createGenerator().convertPeriodKeyToPeriod('2022-11')).toEqual(Period.NovemberThisYear)
expect(createGenerator().convertPeriodKeyToPeriod('2022-12')).toEqual(Period.DecemberThisYear)
})
})

View File

@@ -2,6 +2,28 @@ import { Period } from './Period'
import { PeriodKeyGeneratorInterface } from './PeriodKeyGeneratorInterface'
export class PeriodKeyGenerator implements PeriodKeyGeneratorInterface {
private readonly MONTHS = [
Period.JanuaryThisYear,
Period.FebruaryThisYear,
Period.MarchThisYear,
Period.AprilThisYear,
Period.MayThisYear,
Period.JuneThisYear,
Period.JulyThisYear,
Period.AugustThisYear,
Period.SeptemberThisYear,
Period.OctoberThisYear,
Period.NovemberThisYear,
Period.DecemberThisYear,
]
convertPeriodKeyToPeriod(periodKey: string): Period {
const date = new Date(periodKey)
const month = this.getMonth(date)
return this.MONTHS[+month - 1]
}
getDiscretePeriodKeys(period: Period): string[] {
const periodKeys = []
@@ -26,6 +48,23 @@ export class PeriodKeyGenerator implements PeriodKeyGeneratorInterface {
return this.generateMonthlyKeysRange(6, 9)
case Period.Q4ThisYear:
return this.generateMonthlyKeysRange(9, 12)
case Period.ThisYear:
return this.generateMonthlyKeysRange(0, 12)
case Period.ThisMonth:
return this.generateDailyKeysRange()
case Period.JanuaryThisYear:
case Period.FebruaryThisYear:
case Period.MarchThisYear:
case Period.AprilThisYear:
case Period.MayThisYear:
case Period.JuneThisYear:
case Period.JulyThisYear:
case Period.AugustThisYear:
case Period.SeptemberThisYear:
case Period.OctoberThisYear:
case Period.NovemberThisYear:
case Period.DecemberThisYear:
return this.generateDailyKeysRange(period - 15)
default:
throw new Error(`Unsuporrted period: ${period}`)
}
@@ -51,6 +90,30 @@ export class PeriodKeyGenerator implements PeriodKeyGeneratorInterface {
return this.getMonthlyKey(this.getLastMonthDate())
case Period.ThisYear:
return this.getYearlyKey()
case Period.JanuaryThisYear:
return this.generateMonthlyKeysRange(0, 1)[0]
case Period.FebruaryThisYear:
return this.generateMonthlyKeysRange(1, 2)[0]
case Period.MarchThisYear:
return this.generateMonthlyKeysRange(2, 3)[0]
case Period.AprilThisYear:
return this.generateMonthlyKeysRange(3, 4)[0]
case Period.MayThisYear:
return this.generateMonthlyKeysRange(4, 5)[0]
case Period.JuneThisYear:
return this.generateMonthlyKeysRange(5, 6)[0]
case Period.JulyThisYear:
return this.generateMonthlyKeysRange(6, 7)[0]
case Period.AugustThisYear:
return this.generateMonthlyKeysRange(7, 8)[0]
case Period.SeptemberThisYear:
return this.generateMonthlyKeysRange(8, 9)[0]
case Period.OctoberThisYear:
return this.generateMonthlyKeysRange(9, 10)[0]
case Period.NovemberThisYear:
return this.generateMonthlyKeysRange(10, 11)[0]
case Period.DecemberThisYear:
return this.generateMonthlyKeysRange(11, 12)[0]
default:
throw new Error(`Unsuporrted period: ${period}`)
}
@@ -149,4 +212,22 @@ export class PeriodKeyGenerator implements PeriodKeyGeneratorInterface {
return keys
}
private generateDailyKeysRange(month?: number): string[] {
const today = new Date()
if (month) {
today.setMonth(month)
}
const numberOfDays = new Date(today.getFullYear(), today.getMonth() + 1, 0).getDate()
const keys = []
for (let i = 1; i <= numberOfDays; i++) {
const date = new Date()
date.setMonth(today.getMonth())
date.setDate(i)
keys.push(this.getDailyKey(date))
}
return keys
}
}

View File

@@ -2,5 +2,6 @@ import { Period } from './Period'
export interface PeriodKeyGeneratorInterface {
getPeriodKey(period: Period): string
convertPeriodKeyToPeriod(periodKey: string): Period
getDiscretePeriodKeys(period: Period): string[]
}

View File

@@ -102,7 +102,7 @@ describe('RedisAnalyticsStore', () => {
expect(caughtError).not.toBeNull()
})
it('should calculate total count of activities', async () => {
it('should calculate total count of activities by period', async () => {
redisClient.bitcount = jest.fn().mockReturnValue(70)
expect(await createStore().calculateActivityTotalCount(AnalyticsActivity.EditingItems, Period.Yesterday)).toEqual(
@@ -112,6 +112,14 @@ describe('RedisAnalyticsStore', () => {
expect(redisClient.bitcount).toHaveBeenCalledWith('bitmap:action:editing-items:timespan:period-key')
})
it('should calculate total count of activities by period key', async () => {
redisClient.bitcount = jest.fn().mockReturnValue(70)
expect(await createStore().calculateActivityTotalCount(AnalyticsActivity.EditingItems, '2022-10-03')).toEqual(70)
expect(redisClient.bitcount).toHaveBeenCalledWith('bitmap:action:editing-items:timespan:2022-10-03')
})
it('should calculate activity retention', async () => {
redisClient.bitcount = jest.fn().mockReturnValueOnce(7).mockReturnValueOnce(10)

View File

@@ -134,9 +134,12 @@ export class RedisAnalyticsStore implements AnalyticsStoreInterface {
})
}
async calculateActivityTotalCount(activity: AnalyticsActivity, period: Period): Promise<number> {
return this.redisClient.bitcount(
`bitmap:action:${activity}:timespan:${this.periodKeyGenerator.getPeriodKey(period)}`,
)
async calculateActivityTotalCount(activity: AnalyticsActivity, periodOrPeriodKey: Period | string): Promise<number> {
let periodKey = periodOrPeriodKey
if (!isNaN(+periodOrPeriodKey)) {
periodKey = this.periodKeyGenerator.getPeriodKey(periodOrPeriodKey as Period)
}
return this.redisClient.bitcount(`bitmap:action:${activity}:timespan:${periodKey}`)
}
}

View File

@@ -125,4 +125,20 @@ describe('RedisStatisticsStore', () => {
expect(await createStore().getMeasureAverage(StatisticsMeasure.Income, Period.Today)).toEqual(0)
})
it('should retrieve a measurement total for period', async () => {
redisClient.get = jest.fn().mockReturnValueOnce(5)
expect(await createStore().getMeasureTotal(StatisticsMeasure.Income, Period.Today)).toEqual(5)
expect(redisClient.get).toHaveBeenCalledWith('count:measure:income:timespan:period-key')
})
it('should retrieve a measurement total for period key', async () => {
redisClient.get = jest.fn().mockReturnValueOnce(5)
expect(await createStore().getMeasureTotal(StatisticsMeasure.Income, '2022-10-03')).toEqual(5)
expect(redisClient.get).toHaveBeenCalledWith('count:measure:income:timespan:2022-10-03')
})
})

View File

@@ -18,10 +18,13 @@ export class RedisStatisticsStore implements StatisticsStoreInterface {
await pipeline.exec()
}
async getMeasureTotal(measure: StatisticsMeasure, period: Period): Promise<number> {
const totalValue = await this.redisClient.get(
`count:measure:${measure}:timespan:${this.periodKeyGenerator.getPeriodKey(period)}`,
)
async getMeasureTotal(measure: StatisticsMeasure, periodOrPeriodKey: Period | string): Promise<number> {
let periodKey = periodOrPeriodKey
if (!isNaN(+periodOrPeriodKey)) {
periodKey = this.periodKeyGenerator.getPeriodKey(periodOrPeriodKey as Period)
}
const totalValue = await this.redisClient.get(`count:measure:${measure}:timespan:${periodKey}`)
if (totalValue === null) {
return 0

View File

@@ -3,6 +3,38 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.24.4](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.24.3...@standardnotes/api-gateway@1.24.4) (2022-10-04)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.24.3](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.24.2...@standardnotes/api-gateway@1.24.3) (2022-10-04)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.24.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.24.1...@standardnotes/api-gateway@1.24.2) (2022-10-03)
### Bug Fixes
* **api-gateway:** report churn values for empty months ([f43fbf1](https://github.com/standardnotes/api-gateway/commit/f43fbf15844be05add905134dfb3e8ca90f78458))
## [1.24.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.24.0...@standardnotes/api-gateway@1.24.1) (2022-10-03)
### Bug Fixes
* add debug logs for churn calculation ([2236cc3](https://github.com/standardnotes/api-gateway/commit/2236cc3828167e4b94defbde2691bba38458bd1c))
# [1.24.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.23.0...@standardnotes/api-gateway@1.24.0) (2022-10-03)
### Features
* add calculating monthly churn rate ([f075cd8](https://github.com/standardnotes/api-gateway/commit/f075cd8c4dfc411ba513dfec21bb84c03b238254))
# [1.23.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.22.6...@standardnotes/api-gateway@1.23.0) (2022-09-30)
### Features
* **api-gateway:** add churn metrics to the report ([dfab849](https://github.com/standardnotes/api-gateway/commit/dfab849f48ab782c3cd2e97f52fdb72b7143002f))
## [1.22.6](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.22.5...@standardnotes/api-gateway@1.22.6) (2022-09-30)
**Note:** Version bump only for package @standardnotes/api-gateway

View File

@@ -38,6 +38,8 @@ const requestReport = async (
AnalyticsActivity.DeleteAccount,
AnalyticsActivity.SubscriptionCancelled,
AnalyticsActivity.SubscriptionRefunded,
AnalyticsActivity.ExistingCustomersChurn,
AnalyticsActivity.NewCustomersChurn,
]
for (const analyticsName of thirtyDaysAnalyticsNames) {
@@ -74,6 +76,8 @@ const requestReport = async (
AnalyticsActivity.GeneralActivityPaidUsers,
AnalyticsActivity.PaymentFailed,
AnalyticsActivity.PaymentSuccess,
AnalyticsActivity.NewCustomersChurn,
AnalyticsActivity.ExistingCustomersChurn,
]
for (const activityName of yesterdayActivityNames) {
@@ -98,6 +102,8 @@ const requestReport = async (
StatisticsMeasure.NotesCountFreeUsers,
StatisticsMeasure.NotesCountPaidUsers,
StatisticsMeasure.FilesCount,
StatisticsMeasure.NewCustomers,
StatisticsMeasure.TotalCustomers,
]
const statisticMeasures = []
for (const statisticMeasureName of statisticMeasureNames) {
@@ -130,6 +136,39 @@ const requestReport = async (
}
}
const monthlyPeriodKeys = periodKeyGenerator.getDiscretePeriodKeys(Period.ThisYear)
const churnRates = []
for (const monthPeriodKey of monthlyPeriodKeys) {
const monthPeriod = periodKeyGenerator.convertPeriodKeyToPeriod(monthPeriodKey)
const dailyPeriodKeys = periodKeyGenerator.getDiscretePeriodKeys(monthPeriod)
const totalCustomerCounts: Array<number> = []
for (const dailyPeriodKey of dailyPeriodKeys) {
const customersCount = await statisticsStore.getMeasureTotal(StatisticsMeasure.TotalCustomers, dailyPeriodKey)
totalCustomerCounts.push(customersCount)
}
const filteredTotalCustomerCounts = totalCustomerCounts.filter((count) => !!count)
const averageCustomersCount = filteredTotalCustomerCounts.length
? filteredTotalCustomerCounts.reduce((total, current) => total + current, 0) / filteredTotalCustomerCounts.length
: 0
const existingCustomersChurn = await analyticsStore.calculateActivityTotalCount(
AnalyticsActivity.ExistingCustomersChurn,
monthPeriodKey,
)
const newCustomersChurn = await analyticsStore.calculateActivityTotalCount(
AnalyticsActivity.NewCustomersChurn,
monthPeriodKey,
)
const totalChurn = existingCustomersChurn + newCustomersChurn
churnRates.push({
periodKey: monthPeriodKey,
rate: averageCustomersCount ? (totalChurn / averageCustomersCount) * 100 : 0,
})
}
const event: DailyAnalyticsReportGeneratedEvent = {
type: 'DAILY_ANALYTICS_REPORT_GENERATED',
createdAt: new Date(),
@@ -157,6 +196,10 @@ const requestReport = async (
},
},
],
churn: {
periodKeys: monthlyPeriodKeys,
values: churnRates,
},
},
}

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/api-gateway",
"version": "1.22.6",
"version": "1.24.4",
"engines": {
"node": ">=16.0.0 <17.0.0"
},

View File

@@ -3,6 +3,32 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.36.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.36.3...@standardnotes/auth-server@1.36.4) (2022-10-04)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.36.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.36.2...@standardnotes/auth-server@1.36.3) (2022-10-04)
### Bug Fixes
* **auth:** turn down severity of logs for predicate verification ([09b3f9a](https://github.com/standardnotes/server/commit/09b3f9a0d787d2a329f84e2d625ec8a63b4bd847))
## [1.36.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.36.1...@standardnotes/auth-server@1.36.2) (2022-10-03)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.36.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.36.0...@standardnotes/auth-server@1.36.1) (2022-10-03)
### Bug Fixes
* **auth:** counting active subscriptions ([e7736bb](https://github.com/standardnotes/server/commit/e7736bba250782a3967fd08c82dbf32884b5b892))
# [1.36.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.35.0...@standardnotes/auth-server@1.36.0) (2022-10-03)
### Features
* **auth:** disallow v1 sign in for users with 004 protocol version ([6a9d479](https://github.com/standardnotes/server/commit/6a9d479f7173268bc0c79b1c7583021989be783a))
# [1.35.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.34.1...@standardnotes/auth-server@1.35.0) (2022-09-30)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/auth-server",
"version": "1.35.0",
"version": "1.36.4",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -34,7 +34,7 @@
"@newrelic/winston-enricher": "^4.0.0",
"@sentry/node": "^7.3.0",
"@standardnotes/analytics": "workspace:*",
"@standardnotes/api": "^1.8.1",
"@standardnotes/api": "^1.9.0",
"@standardnotes/common": "workspace:*",
"@standardnotes/domain-events": "workspace:*",
"@standardnotes/domain-events-infra": "workspace:*",

View File

@@ -54,6 +54,7 @@ describe('PredicateVerificationRequestedEventHandler', () => {
logger = {} as jest.Mocked<Logger>
logger.warn = jest.fn()
logger.info = jest.fn()
logger.debug = jest.fn()
event = {} as jest.Mocked<PredicateVerificationRequestedEvent>
event.meta = {

View File

@@ -23,7 +23,7 @@ export class PredicateVerificationRequestedEventHandler implements DomainEventHa
) {}
async handle(event: PredicateVerificationRequestedEvent): Promise<void> {
this.logger.info(`Received verification request of predicate: ${event.payload.predicate.name}`)
this.logger.debug(`Received verification request of predicate: ${event.payload.predicate.name}`)
let userUuid = event.meta.correlation.userIdentifier
if (event.meta.correlation.userIdentifierType === 'email') {
@@ -55,7 +55,7 @@ export class PredicateVerificationRequestedEventHandler implements DomainEventHa
}),
)
this.logger.info(
this.logger.debug(
`Published predicate verification (${predicateVerificationResult}) result for: ${event.payload.predicate.name}`,
)
}

View File

@@ -16,6 +16,7 @@ import { Setting } from '../Setting/Setting'
import { MuteSignInEmailsOption } from '@standardnotes/settings'
import { PKCERepositoryInterface } from '../User/PKCERepositoryInterface'
import { CrypterInterface } from '../Encryption/CrypterInterface'
import { ProtocolVersion } from '@standardnotes/common'
describe('SignIn', () => {
let user: User
@@ -50,6 +51,7 @@ describe('SignIn', () => {
user = {
uuid: '1-2-3',
email: 'test@test.com',
version: ProtocolVersion.V004,
} as jest.Mocked<User>
user.encryptedPassword = '$2a$11$K3g6XoTau8VmLJcai1bB0eD9/YvBSBRtBhMprJOaVZ0U3SgasZH3a'
@@ -99,7 +101,10 @@ describe('SignIn', () => {
logger.error = jest.fn()
})
it('should sign in a user', async () => {
it('should sign in a legacy user without code verifier', async () => {
user.version = ProtocolVersion.V003
userRepository.findOneByEmail = jest.fn().mockReturnValue(user)
expect(
await createUseCase().execute({
email: 'test@test.te',
@@ -124,6 +129,22 @@ describe('SignIn', () => {
expect(domainEventPublisher.publish).toHaveBeenCalled()
})
it('should not sign in a 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 sign in a user with valid code verifier', async () => {
expect(
await createUseCase().execute({
@@ -165,6 +186,7 @@ describe('SignIn', () => {
userAgent: 'Google Chrome',
apiVersion: '20190520',
ephemeralSession: false,
codeVerifier: 'test',
}),
).toEqual({
success: true,
@@ -192,6 +214,7 @@ describe('SignIn', () => {
userAgent: 'Google Chrome',
apiVersion: '20190520',
ephemeralSession: false,
codeVerifier: 'test',
}),
).toEqual({
success: true,
@@ -218,6 +241,7 @@ describe('SignIn', () => {
email: 'test@test.com',
encryptedPassword: '$2a$11$K3g6XoTau8VmLJcai1bB0eD9/YvBSBRtBhMprJOaVZ0U3SgasZH3a',
uuid: '1-2-3',
version: '004',
},
})
})
@@ -234,6 +258,7 @@ describe('SignIn', () => {
userAgent: 'Google Chrome',
apiVersion: '20190520',
ephemeralSession: false,
codeVerifier: 'test',
}),
).toEqual({
success: true,
@@ -249,6 +274,7 @@ describe('SignIn', () => {
userAgent: 'Google Chrome',
apiVersion: '20190520',
ephemeralSession: false,
codeVerifier: 'test',
}),
).toEqual({
success: false,
@@ -284,6 +310,7 @@ describe('SignIn', () => {
userAgent: 'Google Chrome',
apiVersion: '20190520',
ephemeralSession: false,
codeVerifier: 'test',
}),
).toEqual({
success: false,

View File

@@ -21,6 +21,8 @@ import { UseCaseInterface } from './UseCaseInterface'
import { PKCERepositoryInterface } from '../User/PKCERepositoryInterface'
import { CrypterInterface } from '../Encryption/CrypterInterface'
import { SignInDTOV2Challenged } from './SignInDTOV2Challenged'
import { ProtocolVersion } from '@standardnotes/common'
import { HttpStatusCode } from '@standardnotes/api'
@injectable()
export class SignIn implements UseCaseInterface {
@@ -39,7 +41,8 @@ export class SignIn implements UseCaseInterface {
) {}
async execute(dto: SignInDTO): Promise<SignInResponse> {
if (this.isCodeChallengedVersion(dto)) {
const performingCodeChallengedSignIn = this.isCodeChallengedVersion(dto)
if (performingCodeChallengedSignIn) {
const validCodeVerifier = await this.validateCodeVerifier(dto.codeVerifier)
if (!validCodeVerifier) {
this.logger.debug('Code verifier does not match')
@@ -62,6 +65,14 @@ export class SignIn implements UseCaseInterface {
}
}
if (user.version === ProtocolVersion.V004 && !performingCodeChallengedSignIn) {
return {
success: false,
errorMessage: 'Please update your client application.',
errorCode: HttpStatusCode.Gone,
}
}
const passwordMatches = await bcrypt.compare(dto.password, user.encryptedPassword)
if (!passwordMatches) {
this.logger.debug('Password does not match')

View File

@@ -1,3 +1,5 @@
import { HttpStatusCode } from '@standardnotes/api'
import { AuthResponse20161215 } from '../Auth/AuthResponse20161215'
import { AuthResponse20200115 } from '../Auth/AuthResponse20200115'
@@ -5,4 +7,5 @@ export type SignInResponse = {
success: boolean
authResponse?: AuthResponse20161215 | AuthResponse20200115
errorMessage?: string
errorCode?: HttpStatusCode
}

View File

@@ -137,7 +137,7 @@ export class InversifyExpressAuthController extends BaseHttpController {
message: signInResult.errorMessage,
},
},
401,
signInResult.errorCode ?? 401,
)
}

View File

@@ -66,18 +66,16 @@ describe('MySQLUserSubscriptionRepository', () => {
it('should count all active subscriptions', async () => {
ormRepository.createQueryBuilder = jest.fn().mockImplementation(() => selectQueryBuilder)
selectQueryBuilder.select = jest.fn().mockReturnThis()
selectQueryBuilder.distinct = jest.fn().mockReturnThis()
selectQueryBuilder.groupBy = jest.fn().mockReturnThis()
selectQueryBuilder.where = jest.fn().mockReturnThis()
selectQueryBuilder.getCount = jest.fn().mockReturnValue(2)
const result = await createRepository().countActiveSubscriptions()
expect(selectQueryBuilder.select).toHaveBeenCalledWith('user_uuid')
expect(selectQueryBuilder.distinct).toHaveBeenCalled()
expect(selectQueryBuilder.where).toHaveBeenCalledWith('ends_at > :timestamp', {
timestamp: 123,
})
expect(selectQueryBuilder.groupBy).toHaveBeenCalledWith('user_uuid')
expect(selectQueryBuilder.getCount).toHaveBeenCalled()
expect(result).toEqual(2)
})

View File

@@ -19,9 +19,8 @@ export class MySQLUserSubscriptionRepository implements UserSubscriptionReposito
async countActiveSubscriptions(): Promise<number> {
return await this.ormRepository
.createQueryBuilder()
.select('user_uuid')
.distinct()
.where('ends_at > :timestamp', { timestamp: this.timer.getTimestampInMicroseconds() })
.groupBy('user_uuid')
.getCount()
}

View File

@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.34.0](https://github.com/standardnotes/server/compare/@standardnotes/common@1.33.0...@standardnotes/common@1.34.0) (2022-10-04)
### Features
* **common:** add subscription billing frequency ([3c40ee4](https://github.com/standardnotes/server/commit/3c40ee4b4a33dffc35da148a0fa1582c08619733))
# [1.33.0](https://github.com/standardnotes/server/compare/@standardnotes/common@1.32.0...@standardnotes/common@1.33.0) (2022-09-19)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/common",
"version": "1.33.0",
"version": "1.34.0",
"engines": {
"node": ">=16.0.0 <17.0.0"
},

View File

@@ -0,0 +1,5 @@
/* istanbul ignore file */
export enum SubscriptionBillingFrequency {
Monthly = 1,
Annual = 12,
}

View File

@@ -17,6 +17,7 @@ export * from './KeyParams/KeyParamsOrigination'
export * from './Protocol/ProtocolVersion'
export * from './Role/PaidRoles'
export * from './Role/RoleName'
export * from './Subscription/SubscriptionBillingFrequency'
export * from './Subscription/SubscriptionName'
export * from './Type/Either'
export * from './Type/Only'

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.8.15](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.8.14...@standardnotes/domain-events-infra@1.8.15) (2022-10-04)
**Note:** Version bump only for package @standardnotes/domain-events-infra
## [1.8.14](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.8.13...@standardnotes/domain-events-infra@1.8.14) (2022-10-03)
**Note:** Version bump only for package @standardnotes/domain-events-infra
## [1.8.13](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.8.12...@standardnotes/domain-events-infra@1.8.13) (2022-09-28)
**Note:** Version bump only for package @standardnotes/domain-events-infra

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/domain-events-infra",
"version": "1.8.13",
"version": "1.8.15",
"engines": {
"node": ">=16.0.0 <17.0.0"
},

View File

@@ -3,6 +3,16 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.61.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.61.0...@standardnotes/domain-events@2.61.1) (2022-10-04)
**Note:** Version bump only for package @standardnotes/domain-events
# [2.61.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.60.7...@standardnotes/domain-events@2.61.0) (2022-10-03)
### Features
* add calculating monthly churn rate ([f075cd8](https://github.com/standardnotes/server/commit/f075cd8c4dfc411ba513dfec21bb84c03b238254))
## [2.60.7](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.60.6...@standardnotes/domain-events@2.60.7) (2022-09-28)
**Note:** Version bump only for package @standardnotes/domain-events

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/domain-events",
"version": "2.60.7",
"version": "2.61.1",
"engines": {
"node": ">=16.0.0 <17.0.0"
},

View File

@@ -40,4 +40,11 @@ export interface DailyAnalyticsReportGeneratedEventPayload {
}>
}
}>
churn: {
periodKeys: Array<string>
values: Array<{
rate: number
periodKey: string
}>
}
}

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.3.20](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.3.19...@standardnotes/event-store@1.3.20) (2022-10-04)
**Note:** Version bump only for package @standardnotes/event-store
## [1.3.19](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.3.18...@standardnotes/event-store@1.3.19) (2022-10-03)
**Note:** Version bump only for package @standardnotes/event-store
## [1.3.18](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.3.17...@standardnotes/event-store@1.3.18) (2022-09-28)
**Note:** Version bump only for package @standardnotes/event-store

View File

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

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.6.6](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.6.5...@standardnotes/files-server@1.6.6) (2022-10-04)
**Note:** Version bump only for package @standardnotes/files-server
## [1.6.5](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.6.4...@standardnotes/files-server@1.6.5) (2022-10-03)
**Note:** Version bump only for package @standardnotes/files-server
## [1.6.4](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.6.3...@standardnotes/files-server@1.6.4) (2022-09-28)
**Note:** Version bump only for package @standardnotes/files-server

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/files-server",
"version": "1.6.4",
"version": "1.6.6",
"engines": {
"node": ">=16.0.0 <17.0.0"
},

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.4.3](https://github.com/standardnotes/server/compare/@standardnotes/predicates@1.4.2...@standardnotes/predicates@1.4.3) (2022-10-04)
**Note:** Version bump only for package @standardnotes/predicates
## [1.4.2](https://github.com/standardnotes/server/compare/@standardnotes/predicates@1.4.1...@standardnotes/predicates@1.4.2) (2022-09-19)
**Note:** Version bump only for package @standardnotes/predicates

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/predicates",
"version": "1.4.2",
"version": "1.4.3",
"engines": {
"node": ">=16.0.0 <17.0.0"
},

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.10.34](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.10.33...@standardnotes/scheduler-server@1.10.34) (2022-10-04)
**Note:** Version bump only for package @standardnotes/scheduler-server
## [1.10.33](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.10.32...@standardnotes/scheduler-server@1.10.33) (2022-10-03)
**Note:** Version bump only for package @standardnotes/scheduler-server
## [1.10.32](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.10.31...@standardnotes/scheduler-server@1.10.32) (2022-09-28)
**Note:** Version bump only for package @standardnotes/scheduler-server

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/scheduler-server",
"version": "1.10.32",
"version": "1.10.34",
"engines": {
"node": ">=16.0.0 <17.0.0"
},

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.4.1](https://github.com/standardnotes/server/compare/@standardnotes/security@1.4.0...@standardnotes/security@1.4.1) (2022-10-04)
**Note:** Version bump only for package @standardnotes/security
# [1.4.0](https://github.com/standardnotes/server/compare/@standardnotes/security@1.3.3...@standardnotes/security@1.4.0) (2022-09-21)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/security",
"version": "1.4.0",
"version": "1.4.1",
"engines": {
"node": ">=16.0.0 <17.0.0"
},

View File

@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.8.18](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.8.17...@standardnotes/syncing-server@1.8.18) (2022-10-04)
**Note:** Version bump only for package @standardnotes/syncing-server
## [1.8.17](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.8.16...@standardnotes/syncing-server@1.8.17) (2022-10-04)
**Note:** Version bump only for package @standardnotes/syncing-server
## [1.8.16](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.8.15...@standardnotes/syncing-server@1.8.16) (2022-10-03)
**Note:** Version bump only for package @standardnotes/syncing-server
## [1.8.15](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.8.14...@standardnotes/syncing-server@1.8.15) (2022-09-30)
**Note:** Version bump only for package @standardnotes/syncing-server

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/syncing-server",
"version": "1.8.15",
"version": "1.8.18",
"engines": {
"node": ">=16.0.0 <17.0.0"
},

View File

@@ -1803,18 +1803,18 @@ __metadata:
languageName: unknown
linkType: soft
"@standardnotes/api@npm:^1.8.1":
version: 1.8.1
resolution: "@standardnotes/api@npm:1.8.1"
"@standardnotes/api@npm:^1.9.0":
version: 1.9.0
resolution: "@standardnotes/api@npm:1.9.0"
dependencies:
"@standardnotes/common": ^1.32.0
"@standardnotes/encryption": 1.15.3
"@standardnotes/models": 1.18.3
"@standardnotes/responses": 1.10.2
"@standardnotes/encryption": 1.15.9
"@standardnotes/models": 1.22.0
"@standardnotes/responses": 1.10.3
"@standardnotes/security": ^1.1.0
"@standardnotes/utils": 1.9.0
reflect-metadata: ^0.1.13
checksum: 76c5d1a2d29cf7f407813246febf54fe02c5d7cacedcfd1bf5f6ee6630d847f58cae0b5827fbba1c5c5d5a30e56095833c9eff8b413111f8aae9cc17802ffa63
checksum: cc3feac3935a382e0ce1fcaf233206a547b6c998cb99ab362d5c7030b3f4e7cbbd3a083eab40bdecbcdc9497dcd283e4513e29dbf200e815ffa46b192ed61b01
languageName: node
linkType: hard
@@ -1825,7 +1825,7 @@ __metadata:
"@newrelic/winston-enricher": ^4.0.0
"@sentry/node": ^7.3.0
"@standardnotes/analytics": "workspace:*"
"@standardnotes/api": ^1.8.1
"@standardnotes/api": ^1.9.0
"@standardnotes/common": "workspace:*"
"@standardnotes/domain-events": "workspace:*"
"@standardnotes/domain-events-infra": "workspace:*"
@@ -1951,17 +1951,17 @@ __metadata:
languageName: unknown
linkType: soft
"@standardnotes/encryption@npm:1.15.3":
version: 1.15.3
resolution: "@standardnotes/encryption@npm:1.15.3"
"@standardnotes/encryption@npm:1.15.9":
version: 1.15.9
resolution: "@standardnotes/encryption@npm:1.15.9"
dependencies:
"@standardnotes/common": ^1.32.0
"@standardnotes/models": 1.18.3
"@standardnotes/responses": 1.10.2
"@standardnotes/sncrypto-common": 1.11.1
"@standardnotes/models": 1.22.0
"@standardnotes/responses": 1.10.3
"@standardnotes/sncrypto-common": 1.12.0
"@standardnotes/utils": 1.9.0
reflect-metadata: ^0.1.13
checksum: 1a7863299f86ee28de1640b93277f8b3e206bec2b34a205eb6e6fd6c6899a4908623acd9f2452d71a83c542b1f181408e7743386e5e1079239c6c0fa384242c9
checksum: 7595ac08cea6e54e1456cbff3958969318d90ae237aff166bc4429da5bcf6167c5eb03aa8658a1747486a0639b80b523dae46106ab253c75d24579643cf3e948
languageName: node
linkType: hard
@@ -1993,15 +1993,15 @@ __metadata:
languageName: unknown
linkType: soft
"@standardnotes/features@npm:1.52.0":
version: 1.52.0
resolution: "@standardnotes/features@npm:1.52.0"
"@standardnotes/features@npm:1.52.1, @standardnotes/features@npm:^1.52.1":
version: 1.52.1
resolution: "@standardnotes/features@npm:1.52.1"
dependencies:
"@standardnotes/auth": ^3.19.4
"@standardnotes/common": ^1.32.0
"@standardnotes/security": ^1.2.0
reflect-metadata: ^0.1.13
checksum: 3e6014272f72ed33bc7de3cefb33a63a02866c01bfd4a54bc95426e2719f4997940de382cfd83982eaeafdbdf9afac558aecb9139117facfe9c7479089e2952d
checksum: ff3684399e0e0c0e799f11e69dddea2e1f65f315e5a5dd3ca5640e24e836ee85faf1f5ee15fc804411bf083004527fcef08411d5c2d0b5894491bf2f28ceca68
languageName: node
linkType: hard
@@ -2016,18 +2016,6 @@ __metadata:
languageName: node
linkType: hard
"@standardnotes/features@npm:^1.52.1":
version: 1.52.1
resolution: "@standardnotes/features@npm:1.52.1"
dependencies:
"@standardnotes/auth": ^3.19.4
"@standardnotes/common": ^1.32.0
"@standardnotes/security": ^1.2.0
reflect-metadata: ^0.1.13
checksum: ff3684399e0e0c0e799f11e69dddea2e1f65f315e5a5dd3ca5640e24e836ee85faf1f5ee15fc804411bf083004527fcef08411d5c2d0b5894491bf2f28ceca68
languageName: node
linkType: hard
"@standardnotes/files-server@workspace:packages/files":
version: 0.0.0-use.local
resolution: "@standardnotes/files-server@workspace:packages/files"
@@ -2078,17 +2066,17 @@ __metadata:
languageName: unknown
linkType: soft
"@standardnotes/models@npm:1.18.3":
version: 1.18.3
resolution: "@standardnotes/models@npm:1.18.3"
"@standardnotes/models@npm:1.22.0":
version: 1.22.0
resolution: "@standardnotes/models@npm:1.22.0"
dependencies:
"@standardnotes/common": ^1.32.0
"@standardnotes/features": 1.52.0
"@standardnotes/responses": 1.10.2
"@standardnotes/features": 1.52.1
"@standardnotes/responses": 1.10.3
"@standardnotes/utils": 1.9.0
lodash: ^4.17.21
reflect-metadata: ^0.1.13
checksum: 21830c805ffa1ac2184c64903f88915b7b439eb4eb80ac0686c4920a9a4c86cc6c71a3daeb1ede8f3fe6cf0ce106f7ba396f994165306c1c59c05902a7ec075a
checksum: 9928246368b7de7062314374219065507642ed3b6764c27f14ed8d42f0c5a9370fab8731a43a57885a000e461ea60694ba4caa7d9940350839d487cedb7079b5
languageName: node
linkType: hard
@@ -2117,15 +2105,15 @@ __metadata:
languageName: unknown
linkType: soft
"@standardnotes/responses@npm:1.10.2":
version: 1.10.2
resolution: "@standardnotes/responses@npm:1.10.2"
"@standardnotes/responses@npm:1.10.3":
version: 1.10.3
resolution: "@standardnotes/responses@npm:1.10.3"
dependencies:
"@standardnotes/common": ^1.32.0
"@standardnotes/features": 1.52.0
"@standardnotes/features": 1.52.1
"@standardnotes/security": ^1.1.0
reflect-metadata: ^0.1.13
checksum: 364724b5c7efa06948a240da82320817bce58049d6ea226cc2e828e86144ba4d19e5ae6fa437311438008b16aff7bd8cbe7e3f7475a2e9c89cf47650e1e1e9b0
checksum: 4a1e31eb89342461488f00c65884839d7d935d47d4e217da83967c7cbe181fd0341ee58b744fe607def30d06cd1a8069c3b54f40b3933765303db35ee63f6a0d
languageName: node
linkType: hard
@@ -2225,12 +2213,12 @@ __metadata:
languageName: unknown
linkType: soft
"@standardnotes/sncrypto-common@npm:1.11.1":
version: 1.11.1
resolution: "@standardnotes/sncrypto-common@npm:1.11.1"
"@standardnotes/sncrypto-common@npm:1.12.0":
version: 1.12.0
resolution: "@standardnotes/sncrypto-common@npm:1.12.0"
dependencies:
reflect-metadata: ^0.1.13
checksum: 69d698abb7ffc2aecfffd9ccf3e023adca73e5b27cfa1106dfdf10a13d6455b9581c9bf854b333f00255317ec62c384c516b218f40a55ee84fd4f659b8aef16b
checksum: b89a14bd233cb781213b2e25dd8d7bfe911820d341903f2987647c168745c3afb710ad94fa42e50aaafb644ee4a7b5fd64ec137f622cfc082951fd584af0d230
languageName: node
linkType: hard