mirror of
https://github.com/standardnotes/server
synced 2026-04-26 21:01:31 -04:00
Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7f9e6e2f44 | |||
| d3c6c0d48e | |||
| 6c83476fd2 | |||
| 9cdf7e2c51 | |||
| 599119e14e | |||
| a2c484e0f3 | |||
| 97ff4d5ac2 | |||
| 5255cfbb25 | |||
| 780358368b | |||
| cf0b918913 | |||
| 4ea690204e | |||
| 14eb775749 | |||
| bf4a3be6d9 | |||
| b9e1e47871 | |||
| ff532ecb22 | |||
| eb21872db1 | |||
| 8e3df184dc | |||
| b34bbcac8b | |||
| 226965a1d7 | |||
| 17b2ea126c | |||
| 59fc4a089c | |||
| ef26dc8cbb | |||
| 8a0fbb28b0 | |||
| 618d8d5b1a | |||
| 3a936dc9c1 | |||
| 031fcd75ee | |||
| c8cd23cb32 | |||
| a3049938a3 | |||
| b23488e862 | |||
| c8203cf04c | |||
| 4f2616ef0a | |||
| 04ffc69e00 | |||
| 5b4bb6e7a7 | |||
| 2e953ba998 | |||
| ed5a4eb960 | |||
| 31b2c05084 | |||
| 6e1662038c | |||
| df78d88f79 | |||
| addedb3091 | |||
| 2ea17b2dea | |||
| 85d2f42f47 | |||
| cdb655c1bd | |||
| 3064d03aa9 | |||
| 6af6417ca2 | |||
| a35271fbb3 |
@@ -190,9 +190,9 @@ jobs:
|
|||||||
uses: convictional/trigger-workflow-and-wait@master
|
uses: convictional/trigger-workflow-and-wait@master
|
||||||
with:
|
with:
|
||||||
owner: standardnotes
|
owner: standardnotes
|
||||||
repo: e2e
|
repo: self-hosted
|
||||||
github_token: ${{ secrets.CI_PAT_TOKEN }}
|
github_token: ${{ secrets.CI_PAT_TOKEN }}
|
||||||
workflow_file_name: testing-with-stable-client.yml
|
workflow_file_name: testing-with-updating-client-and-server.yml
|
||||||
wait_interval: 30
|
wait_interval: 30
|
||||||
client_payload: '{"${{ inputs.e2e_tag_parameter_name }}": "${{ github.sha }}"}'
|
client_payload: '{"${{ inputs.e2e_tag_parameter_name }}": "${{ github.sha }}"}'
|
||||||
propagate_failure: true
|
propagate_failure: true
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ const RAW_RUNTIME_STATE =
|
|||||||
["@lerna-lite/cli", "npm:1.6.0"],\
|
["@lerna-lite/cli", "npm:1.6.0"],\
|
||||||
["@lerna-lite/list", "npm:1.6.0"],\
|
["@lerna-lite/list", "npm:1.6.0"],\
|
||||||
["@lerna-lite/run", "npm:1.6.0"],\
|
["@lerna-lite/run", "npm:1.6.0"],\
|
||||||
["@sentry/node", "npm:7.27.0"],\
|
["@sentry/node", "npm:7.28.1"],\
|
||||||
["@types/jest", "npm:29.1.1"],\
|
["@types/jest", "npm:29.1.1"],\
|
||||||
["@types/newrelic", "npm:7.0.4"],\
|
["@types/newrelic", "npm:7.0.4"],\
|
||||||
["@types/node", "npm:18.11.9"],\
|
["@types/node", "npm:18.11.9"],\
|
||||||
@@ -2447,6 +2447,16 @@ const RAW_RUNTIME_STATE =
|
|||||||
["tslib", "npm:1.14.1"]\
|
["tslib", "npm:1.14.1"]\
|
||||||
],\
|
],\
|
||||||
"linkType": "HARD"\
|
"linkType": "HARD"\
|
||||||
|
}],\
|
||||||
|
["npm:7.28.1", {\
|
||||||
|
"packageLocation": "./.yarn/cache/@sentry-core-npm-7.28.1-a468033ea8-f29d747d3e.zip/node_modules/@sentry/core/",\
|
||||||
|
"packageDependencies": [\
|
||||||
|
["@sentry/core", "npm:7.28.1"],\
|
||||||
|
["@sentry/types", "npm:7.28.1"],\
|
||||||
|
["@sentry/utils", "npm:7.28.1"],\
|
||||||
|
["tslib", "npm:1.14.1"]\
|
||||||
|
],\
|
||||||
|
"linkType": "HARD"\
|
||||||
}]\
|
}]\
|
||||||
]],\
|
]],\
|
||||||
["@sentry/hub", [\
|
["@sentry/hub", [\
|
||||||
@@ -2476,6 +2486,20 @@ const RAW_RUNTIME_STATE =
|
|||||||
["tslib", "npm:1.14.1"]\
|
["tslib", "npm:1.14.1"]\
|
||||||
],\
|
],\
|
||||||
"linkType": "HARD"\
|
"linkType": "HARD"\
|
||||||
|
}],\
|
||||||
|
["npm:7.28.1", {\
|
||||||
|
"packageLocation": "./.yarn/cache/@sentry-node-npm-7.28.1-b0e124fdfc-b4922d1f0a.zip/node_modules/@sentry/node/",\
|
||||||
|
"packageDependencies": [\
|
||||||
|
["@sentry/node", "npm:7.28.1"],\
|
||||||
|
["@sentry/core", "npm:7.28.1"],\
|
||||||
|
["@sentry/types", "npm:7.28.1"],\
|
||||||
|
["@sentry/utils", "npm:7.28.1"],\
|
||||||
|
["cookie", "npm:0.4.2"],\
|
||||||
|
["https-proxy-agent", "npm:5.0.1"],\
|
||||||
|
["lru_map", "npm:0.3.3"],\
|
||||||
|
["tslib", "npm:1.14.1"]\
|
||||||
|
],\
|
||||||
|
"linkType": "HARD"\
|
||||||
}]\
|
}]\
|
||||||
]],\
|
]],\
|
||||||
["@sentry/profiling-node", [\
|
["@sentry/profiling-node", [\
|
||||||
@@ -2506,6 +2530,17 @@ const RAW_RUNTIME_STATE =
|
|||||||
["tslib", "npm:1.14.1"]\
|
["tslib", "npm:1.14.1"]\
|
||||||
],\
|
],\
|
||||||
"linkType": "HARD"\
|
"linkType": "HARD"\
|
||||||
|
}],\
|
||||||
|
["npm:7.28.1", {\
|
||||||
|
"packageLocation": "./.yarn/cache/@sentry-tracing-npm-7.28.1-e15d453d8e-be501ca9d7.zip/node_modules/@sentry/tracing/",\
|
||||||
|
"packageDependencies": [\
|
||||||
|
["@sentry/tracing", "npm:7.28.1"],\
|
||||||
|
["@sentry/core", "npm:7.28.1"],\
|
||||||
|
["@sentry/types", "npm:7.28.1"],\
|
||||||
|
["@sentry/utils", "npm:7.28.1"],\
|
||||||
|
["tslib", "npm:1.14.1"]\
|
||||||
|
],\
|
||||||
|
"linkType": "HARD"\
|
||||||
}]\
|
}]\
|
||||||
]],\
|
]],\
|
||||||
["@sentry/types", [\
|
["@sentry/types", [\
|
||||||
@@ -2515,6 +2550,13 @@ const RAW_RUNTIME_STATE =
|
|||||||
["@sentry/types", "npm:7.27.0"]\
|
["@sentry/types", "npm:7.27.0"]\
|
||||||
],\
|
],\
|
||||||
"linkType": "HARD"\
|
"linkType": "HARD"\
|
||||||
|
}],\
|
||||||
|
["npm:7.28.1", {\
|
||||||
|
"packageLocation": "./.yarn/cache/@sentry-types-npm-7.28.1-42d9a8574c-7dc6639cb7.zip/node_modules/@sentry/types/",\
|
||||||
|
"packageDependencies": [\
|
||||||
|
["@sentry/types", "npm:7.28.1"]\
|
||||||
|
],\
|
||||||
|
"linkType": "HARD"\
|
||||||
}]\
|
}]\
|
||||||
]],\
|
]],\
|
||||||
["@sentry/utils", [\
|
["@sentry/utils", [\
|
||||||
@@ -2526,6 +2568,15 @@ const RAW_RUNTIME_STATE =
|
|||||||
["tslib", "npm:1.14.1"]\
|
["tslib", "npm:1.14.1"]\
|
||||||
],\
|
],\
|
||||||
"linkType": "HARD"\
|
"linkType": "HARD"\
|
||||||
|
}],\
|
||||||
|
["npm:7.28.1", {\
|
||||||
|
"packageLocation": "./.yarn/cache/@sentry-utils-npm-7.28.1-71eaeb767f-a4b5f73db0.zip/node_modules/@sentry/utils/",\
|
||||||
|
"packageDependencies": [\
|
||||||
|
["@sentry/utils", "npm:7.28.1"],\
|
||||||
|
["@sentry/types", "npm:7.28.1"],\
|
||||||
|
["tslib", "npm:1.14.1"]\
|
||||||
|
],\
|
||||||
|
"linkType": "HARD"\
|
||||||
}]\
|
}]\
|
||||||
]],\
|
]],\
|
||||||
["@sinclair/typebox", [\
|
["@sinclair/typebox", [\
|
||||||
@@ -2581,7 +2632,7 @@ const RAW_RUNTIME_STATE =
|
|||||||
"packageDependencies": [\
|
"packageDependencies": [\
|
||||||
["@standardnotes/analytics", "workspace:packages/analytics"],\
|
["@standardnotes/analytics", "workspace:packages/analytics"],\
|
||||||
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
|
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
|
||||||
["@sentry/node", "npm:7.27.0"],\
|
["@sentry/node", "npm:7.28.1"],\
|
||||||
["@standardnotes/common", "workspace:packages/common"],\
|
["@standardnotes/common", "workspace:packages/common"],\
|
||||||
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
|
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
|
||||||
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
|
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
|
||||||
@@ -2633,7 +2684,7 @@ const RAW_RUNTIME_STATE =
|
|||||||
"packageDependencies": [\
|
"packageDependencies": [\
|
||||||
["@standardnotes/api-gateway", "workspace:packages/api-gateway"],\
|
["@standardnotes/api-gateway", "workspace:packages/api-gateway"],\
|
||||||
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
|
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
|
||||||
["@sentry/node", "npm:7.27.0"],\
|
["@sentry/node", "npm:7.28.1"],\
|
||||||
["@standardnotes/common", "workspace:packages/common"],\
|
["@standardnotes/common", "workspace:packages/common"],\
|
||||||
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
|
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
|
||||||
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
|
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
|
||||||
@@ -2689,9 +2740,9 @@ const RAW_RUNTIME_STATE =
|
|||||||
"packageDependencies": [\
|
"packageDependencies": [\
|
||||||
["@standardnotes/auth-server", "workspace:packages/auth"],\
|
["@standardnotes/auth-server", "workspace:packages/auth"],\
|
||||||
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
|
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
|
||||||
["@sentry/node", "npm:7.27.0"],\
|
["@sentry/node", "npm:7.28.1"],\
|
||||||
["@sentry/profiling-node", "npm:0.0.12"],\
|
["@sentry/profiling-node", "npm:0.0.12"],\
|
||||||
["@sentry/tracing", "npm:7.27.0"],\
|
["@sentry/tracing", "npm:7.28.1"],\
|
||||||
["@standardnotes/api", "npm:1.19.0"],\
|
["@standardnotes/api", "npm:1.19.0"],\
|
||||||
["@standardnotes/common", "workspace:packages/common"],\
|
["@standardnotes/common", "workspace:packages/common"],\
|
||||||
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
|
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
|
||||||
@@ -2915,7 +2966,7 @@ const RAW_RUNTIME_STATE =
|
|||||||
"packageLocation": "./packages/files/",\
|
"packageLocation": "./packages/files/",\
|
||||||
"packageDependencies": [\
|
"packageDependencies": [\
|
||||||
["@standardnotes/files-server", "workspace:packages/files"],\
|
["@standardnotes/files-server", "workspace:packages/files"],\
|
||||||
["@sentry/node", "npm:7.27.0"],\
|
["@sentry/node", "npm:7.28.1"],\
|
||||||
["@standardnotes/common", "workspace:packages/common"],\
|
["@standardnotes/common", "workspace:packages/common"],\
|
||||||
["@standardnotes/config", "npm:2.4.3"],\
|
["@standardnotes/config", "npm:2.4.3"],\
|
||||||
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
|
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
|
||||||
@@ -3050,7 +3101,7 @@ const RAW_RUNTIME_STATE =
|
|||||||
"packageDependencies": [\
|
"packageDependencies": [\
|
||||||
["@standardnotes/revisions-server", "workspace:packages/revisions"],\
|
["@standardnotes/revisions-server", "workspace:packages/revisions"],\
|
||||||
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
|
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
|
||||||
["@sentry/node", "npm:7.27.0"],\
|
["@sentry/node", "npm:7.28.1"],\
|
||||||
["@standardnotes/api", "npm:1.19.0"],\
|
["@standardnotes/api", "npm:1.19.0"],\
|
||||||
["@standardnotes/common", "workspace:packages/common"],\
|
["@standardnotes/common", "workspace:packages/common"],\
|
||||||
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
|
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
|
||||||
@@ -3095,7 +3146,7 @@ const RAW_RUNTIME_STATE =
|
|||||||
"packageDependencies": [\
|
"packageDependencies": [\
|
||||||
["@standardnotes/scheduler-server", "workspace:packages/scheduler"],\
|
["@standardnotes/scheduler-server", "workspace:packages/scheduler"],\
|
||||||
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
|
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
|
||||||
["@sentry/node", "npm:7.27.0"],\
|
["@sentry/node", "npm:7.28.1"],\
|
||||||
["@standardnotes/common", "workspace:packages/common"],\
|
["@standardnotes/common", "workspace:packages/common"],\
|
||||||
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
|
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
|
||||||
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
|
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
|
||||||
@@ -3156,7 +3207,7 @@ const RAW_RUNTIME_STATE =
|
|||||||
["@lerna-lite/cli", "npm:1.6.0"],\
|
["@lerna-lite/cli", "npm:1.6.0"],\
|
||||||
["@lerna-lite/list", "npm:1.6.0"],\
|
["@lerna-lite/list", "npm:1.6.0"],\
|
||||||
["@lerna-lite/run", "npm:1.6.0"],\
|
["@lerna-lite/run", "npm:1.6.0"],\
|
||||||
["@sentry/node", "npm:7.27.0"],\
|
["@sentry/node", "npm:7.28.1"],\
|
||||||
["@types/jest", "npm:29.1.1"],\
|
["@types/jest", "npm:29.1.1"],\
|
||||||
["@types/newrelic", "npm:7.0.4"],\
|
["@types/newrelic", "npm:7.0.4"],\
|
||||||
["@types/node", "npm:18.11.9"],\
|
["@types/node", "npm:18.11.9"],\
|
||||||
@@ -3222,9 +3273,9 @@ const RAW_RUNTIME_STATE =
|
|||||||
"packageDependencies": [\
|
"packageDependencies": [\
|
||||||
["@standardnotes/syncing-server", "workspace:packages/syncing-server"],\
|
["@standardnotes/syncing-server", "workspace:packages/syncing-server"],\
|
||||||
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
|
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
|
||||||
["@sentry/node", "npm:7.27.0"],\
|
["@sentry/node", "npm:7.28.1"],\
|
||||||
["@sentry/profiling-node", "npm:0.0.12"],\
|
["@sentry/profiling-node", "npm:0.0.12"],\
|
||||||
["@sentry/tracing", "npm:7.27.0"],\
|
["@sentry/tracing", "npm:7.28.1"],\
|
||||||
["@standardnotes/common", "workspace:packages/common"],\
|
["@standardnotes/common", "workspace:packages/common"],\
|
||||||
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
|
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
|
||||||
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
|
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
|
||||||
@@ -3324,7 +3375,7 @@ const RAW_RUNTIME_STATE =
|
|||||||
"packageDependencies": [\
|
"packageDependencies": [\
|
||||||
["@standardnotes/websockets-server", "workspace:packages/websockets"],\
|
["@standardnotes/websockets-server", "workspace:packages/websockets"],\
|
||||||
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
|
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
|
||||||
["@sentry/node", "npm:7.27.0"],\
|
["@sentry/node", "npm:7.28.1"],\
|
||||||
["@standardnotes/api", "npm:1.19.0"],\
|
["@standardnotes/api", "npm:1.19.0"],\
|
||||||
["@standardnotes/common", "workspace:packages/common"],\
|
["@standardnotes/common", "workspace:packages/common"],\
|
||||||
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
|
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
|
||||||
@@ -3364,7 +3415,7 @@ const RAW_RUNTIME_STATE =
|
|||||||
"packageDependencies": [\
|
"packageDependencies": [\
|
||||||
["@standardnotes/workspace-server", "workspace:packages/workspace"],\
|
["@standardnotes/workspace-server", "workspace:packages/workspace"],\
|
||||||
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
|
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
|
||||||
["@sentry/node", "npm:7.27.0"],\
|
["@sentry/node", "npm:7.28.1"],\
|
||||||
["@standardnotes/api", "npm:1.19.0"],\
|
["@standardnotes/api", "npm:1.19.0"],\
|
||||||
["@standardnotes/common", "workspace:packages/common"],\
|
["@standardnotes/common", "workspace:packages/common"],\
|
||||||
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
|
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1
-1
@@ -61,7 +61,7 @@
|
|||||||
},
|
},
|
||||||
"packageManager": "yarn@4.0.0-rc.25",
|
"packageManager": "yarn@4.0.0-rc.25",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sentry/node": "^7.27.0",
|
"@sentry/node": "^7.28.1",
|
||||||
"newrelic": "^9.6.0"
|
"newrelic": "^9.6.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,75 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [2.17.8](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.17.7...@standardnotes/analytics@2.17.8) (2022-12-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.17.7](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.17.6...@standardnotes/analytics@2.17.7) (2022-12-20)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **analytics:** monthly numbers of active users ([b34bbca](https://github.com/standardnotes/server/commit/b34bbcac8b9604283b3a5959ab3218c468ce8a00))
|
||||||
|
|
||||||
|
## [2.17.6](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.17.5...@standardnotes/analytics@2.17.6) (2022-12-20)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **analytics:** filtered counts for user activity check ([17b2ea1](https://github.com/standardnotes/server/commit/17b2ea126c5ad2d7cf07657def63f9977f239a3c))
|
||||||
|
|
||||||
|
## [2.17.5](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.17.4...@standardnotes/analytics@2.17.5) (2022-12-20)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **analytics:** accessing analytics in report ([ef26dc8](https://github.com/standardnotes/server/commit/ef26dc8cbb967e088ae7387ff6dbec1e60dc3ee4))
|
||||||
|
|
||||||
|
## [2.17.4](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.17.3...@standardnotes/analytics@2.17.4) (2022-12-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/analytics
|
||||||
|
|
||||||
|
## [2.17.3](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.17.2...@standardnotes/analytics@2.17.3) (2022-12-20)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **analytics:** add debug logs for the report ([031fcd7](https://github.com/standardnotes/server/commit/031fcd75eecdcf4c2f17257754a0ba3f24ba6d6e))
|
||||||
|
|
||||||
|
## [2.17.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.17.1...@standardnotes/analytics@2.17.2) (2022-12-20)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **analytics:** calculating active users ([a304993](https://github.com/standardnotes/server/commit/a3049938a31e21a5867a314ac62bee6aa4990d57))
|
||||||
|
|
||||||
|
## [2.17.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.17.0...@standardnotes/analytics@2.17.1) (2022-12-20)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **analytics:** container binding ([04ffc69](https://github.com/standardnotes/server/commit/04ffc69e000803107d8834c286de97b3d213a842))
|
||||||
|
* **auth:** replace date object with number timestamp ([5b4bb6e](https://github.com/standardnotes/server/commit/5b4bb6e7a78a1b0f4e663bb990619f65f6a5c757))
|
||||||
|
|
||||||
|
# [2.17.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.16.0...@standardnotes/analytics@2.17.0) (2022-12-20)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **analytics:** add users activit to the report email ([ed5a4eb](https://github.com/standardnotes/server/commit/ed5a4eb960a6c8fe9d0c77331f29dc3c7ffb9100))
|
||||||
|
|
||||||
|
# [2.16.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.15.1...@standardnotes/analytics@2.16.0) (2022-12-20)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **analytics:** add active users stats to report ([6e16620](https://github.com/standardnotes/server/commit/6e1662038c3340fb60939464616789bab7639160))
|
||||||
|
|
||||||
|
## [2.15.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.15.0...@standardnotes/analytics@2.15.1) (2022-12-20)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **auth:** add persisting statistics for all subscription plans ([addedb3](https://github.com/standardnotes/server/commit/addedb3091ddae81618d56663e18f2ae76a43c4e))
|
||||||
|
|
||||||
|
# [2.15.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.14.0...@standardnotes/analytics@2.15.0) (2022-12-19)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **auth:** add requesting persisting statistics ([a35271f](https://github.com/standardnotes/server/commit/a35271fbb399b68a3ac7021395d8063707fba222))
|
||||||
|
|
||||||
# [2.14.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.13.0...@standardnotes/analytics@2.14.0) (2022-12-19)
|
# [2.14.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.13.0...@standardnotes/analytics@2.14.0) (2022-12-19)
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|||||||
@@ -121,6 +121,10 @@ const requestReport = async (
|
|||||||
StatisticMeasureName.NAMES.FiveYearPlansMRR,
|
StatisticMeasureName.NAMES.FiveYearPlansMRR,
|
||||||
StatisticMeasureName.NAMES.PlusPlansMRR,
|
StatisticMeasureName.NAMES.PlusPlansMRR,
|
||||||
StatisticMeasureName.NAMES.ProPlansMRR,
|
StatisticMeasureName.NAMES.ProPlansMRR,
|
||||||
|
StatisticMeasureName.NAMES.ActiveUsers,
|
||||||
|
StatisticMeasureName.NAMES.ActiveFreeUsers,
|
||||||
|
StatisticMeasureName.NAMES.ActivePlusUsers,
|
||||||
|
StatisticMeasureName.NAMES.ActiveProUsers,
|
||||||
]
|
]
|
||||||
for (const statisticName of thirtyDaysStatisticsNames) {
|
for (const statisticName of thirtyDaysStatisticsNames) {
|
||||||
statisticsOverTime.push({
|
statisticsOverTime.push({
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/analytics",
|
"name": "@standardnotes/analytics",
|
||||||
"version": "2.14.0",
|
"version": "2.17.8",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <19.0.0"
|
"node": ">=18.0.0 <19.0.0"
|
||||||
},
|
},
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@newrelic/winston-enricher": "^4.0.0",
|
"@newrelic/winston-enricher": "^4.0.0",
|
||||||
"@sentry/node": "^7.27.0",
|
"@sentry/node": "^7.28.1",
|
||||||
"@standardnotes/common": "workspace:*",
|
"@standardnotes/common": "workspace:*",
|
||||||
"@standardnotes/domain-core": "workspace:^",
|
"@standardnotes/domain-core": "workspace:^",
|
||||||
"@standardnotes/domain-events": "workspace:*",
|
"@standardnotes/domain-events": "workspace:*",
|
||||||
|
|||||||
@@ -218,6 +218,7 @@ export class ContainerConfigLoader {
|
|||||||
.toConstantValue(
|
.toConstantValue(
|
||||||
new StatisticPersistenceRequestedEventHandler(
|
new StatisticPersistenceRequestedEventHandler(
|
||||||
container.get(TYPES.PersistStatistic),
|
container.get(TYPES.PersistStatistic),
|
||||||
|
container.get(TYPES.Timer),
|
||||||
container.get(TYPES.Logger),
|
container.get(TYPES.Logger),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,6 +5,38 @@ import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
|
|||||||
import { StatisticMeasureName } from '../Statistics/StatisticMeasureName'
|
import { StatisticMeasureName } from '../Statistics/StatisticMeasureName'
|
||||||
import { Period } from '../Time/Period'
|
import { Period } from '../Time/Period'
|
||||||
|
|
||||||
|
const countActiveUsers = (measureName: string, data: any): { yesterday: number; last30Days: number } => {
|
||||||
|
const totalActiveUsersLast30DaysIncludingToday = data.statisticsOverTime.find(
|
||||||
|
(a: { name: string; period: number }) => a.name === measureName && a.period === 27,
|
||||||
|
)
|
||||||
|
|
||||||
|
const totalActiveUsersYesterday =
|
||||||
|
totalActiveUsersLast30DaysIncludingToday.counts[totalActiveUsersLast30DaysIncludingToday.counts.length - 2]
|
||||||
|
.totalCount
|
||||||
|
|
||||||
|
const filteredCounts = totalActiveUsersLast30DaysIncludingToday.counts.filter(
|
||||||
|
(count: { totalCount: number }) => count.totalCount !== 0,
|
||||||
|
)
|
||||||
|
if (filteredCounts.length === 0) {
|
||||||
|
return {
|
||||||
|
yesterday: 0,
|
||||||
|
last30Days: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const last30DaysNumbers = filteredCounts.map((count: { totalCount: number }) => count.totalCount)
|
||||||
|
const last30DaysCount = last30DaysNumbers.reduce((previousValue: number, currentValue: number) => {
|
||||||
|
return previousValue + currentValue
|
||||||
|
})
|
||||||
|
|
||||||
|
const averageActiveUsersLast30Days = Math.floor(last30DaysCount / last30DaysNumbers.length)
|
||||||
|
|
||||||
|
return {
|
||||||
|
yesterday: totalActiveUsersYesterday,
|
||||||
|
last30Days: averageActiveUsersLast30Days,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const getChartUrls = (
|
const getChartUrls = (
|
||||||
data: any,
|
data: any,
|
||||||
): {
|
): {
|
||||||
@@ -12,7 +44,6 @@ const getChartUrls = (
|
|||||||
users: string
|
users: string
|
||||||
quarterlyPerformance: string
|
quarterlyPerformance: string
|
||||||
churn: string
|
churn: string
|
||||||
mrr: string
|
|
||||||
mrrMonthly: string
|
mrrMonthly: string
|
||||||
} => {
|
} => {
|
||||||
const subscriptionPurchasingOverTime = data.activityStatisticsOverTime.find(
|
const subscriptionPurchasingOverTime = data.activityStatisticsOverTime.find(
|
||||||
@@ -237,82 +268,6 @@ const getChartUrls = (
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const mrrOverTime = data.statisticsOverTime.find(
|
|
||||||
(a: { name: string; period: number }) => a.name === 'mrr' && a.period === 27,
|
|
||||||
)
|
|
||||||
const monthlyPlansMrrOverTime = data.statisticsOverTime.find(
|
|
||||||
(a: { name: string; period: number }) => a.name === 'monthly-plans-mrr' && a.period === 27,
|
|
||||||
)
|
|
||||||
const annualPlansMrrOverTime = data.statisticsOverTime.find(
|
|
||||||
(a: { name: string; period: number }) => a.name === 'annual-plans-mrr' && a.period === 27,
|
|
||||||
)
|
|
||||||
const fiveYearPlansMrrOverTime = data.statisticsOverTime.find(
|
|
||||||
(a: { name: string; period: number }) => a.name === 'five-year-plans-mrr' && a.period === 27,
|
|
||||||
)
|
|
||||||
const proPlansMrrOverTime = data.statisticsOverTime.find(
|
|
||||||
(a: { name: string; period: number }) => a.name === 'pro-plans-mrr' && a.period === 27,
|
|
||||||
)
|
|
||||||
const plusPlansMrrOverTime = data.statisticsOverTime.find(
|
|
||||||
(a: { name: string; period: number }) => a.name === 'plus-plans-mrr' && a.period === 27,
|
|
||||||
)
|
|
||||||
|
|
||||||
const mrrOverTimeConfig = {
|
|
||||||
type: 'line',
|
|
||||||
data: {
|
|
||||||
labels: mrrOverTime?.counts.map((count: { periodKey: any }) => count.periodKey),
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
label: 'MRR',
|
|
||||||
backgroundColor: 'rgb(25, 255, 140)',
|
|
||||||
borderColor: 'rgb(25, 255, 140)',
|
|
||||||
data: mrrOverTime?.counts.map((count: { totalCount: any }) => count.totalCount),
|
|
||||||
fill: false,
|
|
||||||
pointRadius: 2,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'MRR - Monthly Plans',
|
|
||||||
backgroundColor: 'rgb(54, 162, 235)',
|
|
||||||
borderColor: 'rgb(54, 162, 235)',
|
|
||||||
data: monthlyPlansMrrOverTime?.counts.map((count: { totalCount: any }) => count.totalCount),
|
|
||||||
fill: false,
|
|
||||||
pointRadius: 2,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'MRR - Annual Plans',
|
|
||||||
backgroundColor: 'rgb(255, 221, 51)',
|
|
||||||
borderColor: 'rgb(255, 221, 51)',
|
|
||||||
data: annualPlansMrrOverTime?.counts.map((count: { totalCount: any }) => count.totalCount),
|
|
||||||
fill: false,
|
|
||||||
pointRadius: 2,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'MRR - Five Year Plans',
|
|
||||||
backgroundColor: 'rgb(255, 120, 120)',
|
|
||||||
borderColor: 'rgb(255, 120, 120)',
|
|
||||||
data: fiveYearPlansMrrOverTime?.counts.map((count: { totalCount: any }) => count.totalCount),
|
|
||||||
fill: false,
|
|
||||||
pointRadius: 2,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'MRR - PRO Plans',
|
|
||||||
backgroundColor: 'rgb(255, 99, 132)',
|
|
||||||
borderColor: 'rgb(255, 99, 132)',
|
|
||||||
data: proPlansMrrOverTime?.counts.map((count: { totalCount: any }) => count.totalCount),
|
|
||||||
fill: false,
|
|
||||||
pointRadius: 2,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'MRR - PLUS Plans',
|
|
||||||
backgroundColor: 'rgb(221, 51, 255)',
|
|
||||||
borderColor: 'rgb(221, 51, 255)',
|
|
||||||
data: plusPlansMrrOverTime?.counts.map((count: { totalCount: any }) => count.totalCount),
|
|
||||||
fill: false,
|
|
||||||
pointRadius: 2,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
const mrrMonthlyOverTime = data.statisticsOverTime
|
const mrrMonthlyOverTime = data.statisticsOverTime
|
||||||
.find((a: { name: string; period: Period }) => a.name === 'mrr' && a.period === Period.ThisYear)
|
.find((a: { name: string; period: Period }) => a.name === 'mrr' && a.period === Period.ThisYear)
|
||||||
?.counts.map((count: { totalCount: number }) => +count.totalCount.toFixed(2))
|
?.counts.map((count: { totalCount: number }) => +count.totalCount.toFixed(2))
|
||||||
@@ -371,7 +326,6 @@ const getChartUrls = (
|
|||||||
JSON.stringify(quarterlyConfig),
|
JSON.stringify(quarterlyConfig),
|
||||||
)}`,
|
)}`,
|
||||||
churn: `https://quickchart.io/chart?width=800&c=${encodeURIComponent(JSON.stringify(churnConfig))}`,
|
churn: `https://quickchart.io/chart?width=800&c=${encodeURIComponent(JSON.stringify(churnConfig))}`,
|
||||||
mrr: `https://quickchart.io/chart?width=800&c=${encodeURIComponent(JSON.stringify(mrrOverTimeConfig))}`,
|
|
||||||
mrrMonthly: `https://quickchart.io/chart?width=800&c=${encodeURIComponent(JSON.stringify(mrrMonthlyConfig))}`,
|
mrrMonthly: `https://quickchart.io/chart?width=800&c=${encodeURIComponent(JSON.stringify(mrrMonthlyConfig))}`,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -608,12 +562,39 @@ export const html = (data: any, timer: TimerInterface) => {
|
|||||||
(value: { periodKey: string }) => value.periodKey === thisMonthPeriodKey,
|
(value: { periodKey: string }) => value.periodKey === thisMonthPeriodKey,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const totalActiveUsers = countActiveUsers(StatisticMeasureName.NAMES.ActiveUsers, data)
|
||||||
|
const totalActiveFreeUsers = countActiveUsers(StatisticMeasureName.NAMES.ActiveFreeUsers, data)
|
||||||
|
const totalActivePlusUsers = countActiveUsers(StatisticMeasureName.NAMES.ActivePlusUsers, data)
|
||||||
|
const totalActiveProUsers = countActiveUsers(StatisticMeasureName.NAMES.ActiveProUsers, data)
|
||||||
|
|
||||||
return ` <div>
|
return ` <div>
|
||||||
<p>Hello,</p>
|
<p>Hello,</p>
|
||||||
<p>
|
<p>
|
||||||
<strong>Here are some statistics from yesterday:</strong>
|
<strong>Here are some statistics from yesterday:</strong>
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
|
<li>
|
||||||
|
<b>Active Users</b>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<b>Total:</b> ${totalActiveUsers.yesterday.toLocaleString('en-US')}
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>By Subscription Type:</b>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<b>FREE:</b> ${totalActiveFreeUsers.yesterday.toLocaleString('en-US')}
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>PLUS:</b> ${totalActivePlusUsers.yesterday.toLocaleString('en-US')}
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>PRO:</b> ${totalActiveProUsers.yesterday.toLocaleString('en-US')}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<b>Payments</b>
|
<b>Payments</b>
|
||||||
<ul>
|
<ul>
|
||||||
@@ -812,6 +793,28 @@ export const html = (data: any, timer: TimerInterface) => {
|
|||||||
<strong>Here are some statistics from last 30 days:</strong>
|
<strong>Here are some statistics from last 30 days:</strong>
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
|
<li>
|
||||||
|
<b>Active Users (Average)</b>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<b>Total:</b> ${totalActiveUsers.last30Days.toLocaleString('en-US')}
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>By Subscription Type:</b>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<b>FREE:</b> ${totalActiveFreeUsers.last30Days.toLocaleString('en-US')}
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>PLUS:</b> ${totalActivePlusUsers.last30Days.toLocaleString('en-US')}
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>PRO:</b> ${totalActiveProUsers.last30Days.toLocaleString('en-US')}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<b>Payments (This Month)</b>
|
<b>Payments (This Month)</b>
|
||||||
<ul>
|
<ul>
|
||||||
@@ -944,10 +947,6 @@ export const html = (data: any, timer: TimerInterface) => {
|
|||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>
|
|
||||||
<strong>Here is the MRR chart over 30 days:</strong>
|
|
||||||
</p>
|
|
||||||
<img src=${chartUrls.mrr}></img>
|
|
||||||
<p>
|
<p>
|
||||||
<strong>Here is the MRR Monthly chart this year:</strong>
|
<strong>Here is the MRR Monthly chart this year:</strong>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import { DomainEventHandlerInterface, StatisticPersistenceRequestedEvent } from '@standardnotes/domain-events'
|
import { DomainEventHandlerInterface, StatisticPersistenceRequestedEvent } from '@standardnotes/domain-events'
|
||||||
|
import { TimerInterface } from '@standardnotes/time'
|
||||||
import { Logger } from 'winston'
|
import { Logger } from 'winston'
|
||||||
import { PersistStatistic } from '../UseCase/PersistStatistic/PersistStatistic'
|
import { PersistStatistic } from '../UseCase/PersistStatistic/PersistStatistic'
|
||||||
|
|
||||||
export class StatisticPersistenceRequestedEventHandler implements DomainEventHandlerInterface {
|
export class StatisticPersistenceRequestedEventHandler implements DomainEventHandlerInterface {
|
||||||
constructor(private persistStatistic: PersistStatistic, private logger: Logger) {}
|
constructor(private persistStatistic: PersistStatistic, private timer: TimerInterface, private logger: Logger) {}
|
||||||
|
|
||||||
async handle(event: StatisticPersistenceRequestedEvent): Promise<void> {
|
async handle(event: StatisticPersistenceRequestedEvent): Promise<void> {
|
||||||
const result = await this.persistStatistic.execute({
|
const result = await this.persistStatistic.execute({
|
||||||
date: event.payload.date,
|
date: this.timer.convertMicrosecondsToDate(event.payload.date),
|
||||||
statisticMeasureName: event.payload.statisticMeasureName,
|
statisticMeasureName: event.payload.statisticMeasureName,
|
||||||
value: event.payload.value,
|
value: event.payload.value,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -26,6 +26,10 @@ export class StatisticMeasureName extends ValueObject<StatisticMeasureNameProps>
|
|||||||
FiveYearPlansMRR: 'five-year-plans-mrr',
|
FiveYearPlansMRR: 'five-year-plans-mrr',
|
||||||
ProPlansMRR: 'pro-plans-mrr',
|
ProPlansMRR: 'pro-plans-mrr',
|
||||||
PlusPlansMRR: 'plus-plans-mrr',
|
PlusPlansMRR: 'plus-plans-mrr',
|
||||||
|
ActiveUsers: 'active-users',
|
||||||
|
ActiveProUsers: 'active-pro-users',
|
||||||
|
ActivePlusUsers: 'active-plus-users',
|
||||||
|
ActiveFreeUsers: 'active-free-users',
|
||||||
}
|
}
|
||||||
|
|
||||||
get value(): string {
|
get value(): string {
|
||||||
|
|||||||
@@ -3,6 +3,14 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.41.3](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.41.2...@standardnotes/api-gateway@1.41.3) (2022-12-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
|
## [1.41.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.41.1...@standardnotes/api-gateway@1.41.2) (2022-12-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|
||||||
## [1.41.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.41.0...@standardnotes/api-gateway@1.41.1) (2022-12-19)
|
## [1.41.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.41.0...@standardnotes/api-gateway@1.41.1) (2022-12-19)
|
||||||
|
|
||||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/api-gateway",
|
"name": "@standardnotes/api-gateway",
|
||||||
"version": "1.41.1",
|
"version": "1.41.3",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <19.0.0"
|
"node": ">=18.0.0 <19.0.0"
|
||||||
},
|
},
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@newrelic/winston-enricher": "^4.0.0",
|
"@newrelic/winston-enricher": "^4.0.0",
|
||||||
"@sentry/node": "^7.27.0",
|
"@sentry/node": "^7.28.1",
|
||||||
"@standardnotes/common": "workspace:^",
|
"@standardnotes/common": "workspace:^",
|
||||||
"@standardnotes/domain-events": "workspace:*",
|
"@standardnotes/domain-events": "workspace:*",
|
||||||
"@standardnotes/domain-events-infra": "workspace:*",
|
"@standardnotes/domain-events-infra": "workspace:*",
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ ENCRYPTION_SERVER_KEY=change-me-!
|
|||||||
|
|
||||||
PORT=3000
|
PORT=3000
|
||||||
|
|
||||||
DB_HOST=localhost
|
DB_HOST=127.0.0.1
|
||||||
DB_REPLICA_HOST=localhost
|
DB_REPLICA_HOST=127.0.0.1
|
||||||
DB_PORT=3306
|
DB_PORT=3306
|
||||||
DB_USERNAME=auth
|
DB_USERNAME=auth
|
||||||
DB_PASSWORD=changeme123
|
DB_PASSWORD=changeme123
|
||||||
|
|||||||
@@ -3,6 +3,64 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.70.9](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.70.8...@standardnotes/auth-server@1.70.9) (2022-12-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/auth-server
|
||||||
|
|
||||||
|
## [1.70.8](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.70.7...@standardnotes/auth-server@1.70.8) (2022-12-20)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **auth:** move tracing sessions to session creation instead of cross service token creation ([5255cfb](https://github.com/standardnotes/server/commit/5255cfbb257cc9e6ac437fe0c5b28d938e3e599b))
|
||||||
|
|
||||||
|
## [1.70.7](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.70.6...@standardnotes/auth-server@1.70.7) (2022-12-20)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **auth:** change severity on tracing session errors - most probably hazardous reads ([cf0b918](https://github.com/standardnotes/server/commit/cf0b91891370e1c1799ad80c10ee9f6b98087a94))
|
||||||
|
|
||||||
|
## [1.70.6](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.70.5...@standardnotes/auth-server@1.70.6) (2022-12-20)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **auth:** query for session traces ([14eb775](https://github.com/standardnotes/server/commit/14eb775749bfa9972dc3c07049505f3d15f0b556))
|
||||||
|
|
||||||
|
## [1.70.5](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.70.4...@standardnotes/auth-server@1.70.5) (2022-12-20)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **auth:** add session traces index ([b9e1e47](https://github.com/standardnotes/server/commit/b9e1e4787129f00fab8f98cb721141f2e7d75600))
|
||||||
|
|
||||||
|
## [1.70.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.70.3...@standardnotes/auth-server@1.70.4) (2022-12-20)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **auth:** replace date object with number timestamp ([5b4bb6e](https://github.com/standardnotes/server/commit/5b4bb6e7a78a1b0f4e663bb990619f65f6a5c757))
|
||||||
|
|
||||||
|
## [1.70.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.70.2...@standardnotes/auth-server@1.70.3) (2022-12-20)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **auth:** add persisting statistics for all subscription plans ([addedb3](https://github.com/standardnotes/server/commit/addedb3091ddae81618d56663e18f2ae76a43c4e))
|
||||||
|
|
||||||
|
## [1.70.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.70.1...@standardnotes/auth-server@1.70.2) (2022-12-20)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **auth:** docker command ([85d2f42](https://github.com/standardnotes/server/commit/85d2f42f473110e8dfca975bfecc7a56823bdef4))
|
||||||
|
|
||||||
|
## [1.70.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.70.0...@standardnotes/auth-server@1.70.1) (2022-12-20)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **auth:** saving subscription plan name in session traces ([3064d03](https://github.com/standardnotes/server/commit/3064d03aa9a2ac9ca3acfff30480ea8629faeb14))
|
||||||
|
|
||||||
|
# [1.70.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.69.1...@standardnotes/auth-server@1.70.0) (2022-12-19)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **auth:** add requesting persisting statistics ([a35271f](https://github.com/standardnotes/server/commit/a35271fbb399b68a3ac7021395d8063707fba222))
|
||||||
|
|
||||||
## [1.69.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.69.0...@standardnotes/auth-server@1.69.1) (2022-12-19)
|
## [1.69.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.69.0...@standardnotes/auth-server@1.69.1) (2022-12-19)
|
||||||
|
|
||||||
**Note:** Version bump only for package @standardnotes/auth-server
|
**Note:** Version bump only for package @standardnotes/auth-server
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import 'reflect-metadata'
|
||||||
|
|
||||||
|
import 'newrelic'
|
||||||
|
|
||||||
|
import { Logger } from 'winston'
|
||||||
|
import { TimerInterface } from '@standardnotes/time'
|
||||||
|
|
||||||
|
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
|
||||||
|
import TYPES from '../src/Bootstrap/Types'
|
||||||
|
import { Env } from '../src/Bootstrap/Env'
|
||||||
|
import { PersistStatistics } from '../src/Domain/UseCase/PersistStatistics/PersistStatistics'
|
||||||
|
|
||||||
|
const container = new ContainerConfigLoader()
|
||||||
|
void container.load().then((container) => {
|
||||||
|
const env: Env = new Env()
|
||||||
|
env.load()
|
||||||
|
|
||||||
|
const logger: Logger = container.get(TYPES.Logger)
|
||||||
|
|
||||||
|
logger.info('Starting session traces cleanup')
|
||||||
|
|
||||||
|
const persistStats: PersistStatistics = container.get(TYPES.PersistStatistics)
|
||||||
|
const timer: TimerInterface = container.get(TYPES.Timer)
|
||||||
|
|
||||||
|
Promise.resolve(
|
||||||
|
persistStats.execute({
|
||||||
|
sessionsInADay: timer.getUTCDateNDaysAgo(1),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.then(() => {
|
||||||
|
logger.info('Stats persisted.')
|
||||||
|
|
||||||
|
process.exit(0)
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
logger.error(`Could not persist stats: ${error.message}`)
|
||||||
|
|
||||||
|
process.exit(1)
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -24,6 +24,11 @@ case "$COMMAND" in
|
|||||||
yarn workspace @standardnotes/auth-server cleanup
|
yarn workspace @standardnotes/auth-server cleanup
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
'stats' )
|
||||||
|
echo "[Docker] Starting Persisting Stats..."
|
||||||
|
yarn workspace @standardnotes/auth-server stats
|
||||||
|
;;
|
||||||
|
|
||||||
'email-daily-backup' )
|
'email-daily-backup' )
|
||||||
echo "[Docker] Starting Email Daily Backup..."
|
echo "[Docker] Starting Email Daily Backup..."
|
||||||
yarn workspace @standardnotes/auth-server daily-backup:email
|
yarn workspace @standardnotes/auth-server daily-backup:email
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||||
|
|
||||||
|
export class addSessionTracesCompoundIndex1671561748264 implements MigrationInterface {
|
||||||
|
name = 'addSessionTracesCompoundIndex1671561748264'
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
'CREATE UNIQUE INDEX `user_uuid_and_creation_date` ON `session_traces` (`user_uuid`, `creation_date`)',
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query('DROP INDEX `user_uuid_and_creation_date` ON `session_traces`')
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/auth-server",
|
"name": "@standardnotes/auth-server",
|
||||||
"version": "1.69.1",
|
"version": "1.70.9",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <19.0.0"
|
"node": ">=18.0.0 <19.0.0"
|
||||||
},
|
},
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
"start": "yarn node dist/bin/server.js",
|
"start": "yarn node dist/bin/server.js",
|
||||||
"worker": "yarn node dist/bin/worker.js",
|
"worker": "yarn node dist/bin/worker.js",
|
||||||
"cleanup": "yarn node dist/bin/cleanup.js",
|
"cleanup": "yarn node dist/bin/cleanup.js",
|
||||||
|
"stats": "yarn node dist/bin/stats.js",
|
||||||
"daily-backup:email": "yarn node dist/bin/backup.js email daily",
|
"daily-backup:email": "yarn node dist/bin/backup.js email daily",
|
||||||
"user-email-backup": "yarn node dist/bin/user_email_backup.js",
|
"user-email-backup": "yarn node dist/bin/user_email_backup.js",
|
||||||
"daily-backup:dropbox": "yarn node dist/bin/backup.js dropbox daily",
|
"daily-backup:dropbox": "yarn node dist/bin/backup.js dropbox daily",
|
||||||
@@ -32,9 +33,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@newrelic/winston-enricher": "^4.0.0",
|
"@newrelic/winston-enricher": "^4.0.0",
|
||||||
"@sentry/node": "^7.27.0",
|
"@sentry/node": "^7.28.1",
|
||||||
"@sentry/profiling-node": "^0.0.12",
|
"@sentry/profiling-node": "^0.0.12",
|
||||||
"@sentry/tracing": "^7.27.0",
|
"@sentry/tracing": "^7.28.1",
|
||||||
"@standardnotes/api": "^1.19.0",
|
"@standardnotes/api": "^1.19.0",
|
||||||
"@standardnotes/common": "workspace:*",
|
"@standardnotes/common": "workspace:*",
|
||||||
"@standardnotes/domain-core": "workspace:^",
|
"@standardnotes/domain-core": "workspace:^",
|
||||||
|
|||||||
@@ -202,6 +202,7 @@ import { SessionTrace } from '../Domain/Session/SessionTrace'
|
|||||||
import { TypeORMSessionTrace } from '../Infra/TypeORM/TypeORMSessionTrace'
|
import { TypeORMSessionTrace } from '../Infra/TypeORM/TypeORMSessionTrace'
|
||||||
import { TraceSession } from '../Domain/UseCase/TraceSession/TraceSession'
|
import { TraceSession } from '../Domain/UseCase/TraceSession/TraceSession'
|
||||||
import { CleanupSessionTraces } from '../Domain/UseCase/CleanupSessionTraces/CleanupSessionTraces'
|
import { CleanupSessionTraces } from '../Domain/UseCase/CleanupSessionTraces/CleanupSessionTraces'
|
||||||
|
import { PersistStatistics } from '../Domain/UseCase/PersistStatistics/PersistStatistics'
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const newrelicFormatter = require('@newrelic/winston-enricher')
|
const newrelicFormatter = require('@newrelic/winston-enricher')
|
||||||
@@ -500,6 +501,16 @@ export class ContainerConfigLoader {
|
|||||||
container.get(TYPES.SESSION_TRACE_DAYS_TTL),
|
container.get(TYPES.SESSION_TRACE_DAYS_TTL),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
container
|
||||||
|
.bind<PersistStatistics>(TYPES.PersistStatistics)
|
||||||
|
.toConstantValue(
|
||||||
|
new PersistStatistics(
|
||||||
|
container.get(TYPES.SessionTraceRepository),
|
||||||
|
container.get(TYPES.DomainEventPublisher),
|
||||||
|
container.get(TYPES.DomainEventFactory),
|
||||||
|
container.get(TYPES.Timer),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
container
|
container
|
||||||
.bind<CleanupSessionTraces>(TYPES.CleanupSessionTraces)
|
.bind<CleanupSessionTraces>(TYPES.CleanupSessionTraces)
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ const TYPES = {
|
|||||||
ProcessUserRequest: Symbol.for('ProcessUserRequest'),
|
ProcessUserRequest: Symbol.for('ProcessUserRequest'),
|
||||||
TraceSession: Symbol.for('TraceSession'),
|
TraceSession: Symbol.for('TraceSession'),
|
||||||
CleanupSessionTraces: Symbol.for('CleanupSessionTraces'),
|
CleanupSessionTraces: Symbol.for('CleanupSessionTraces'),
|
||||||
|
PersistStatistics: Symbol.for('PersistStatistics'),
|
||||||
// Handlers
|
// Handlers
|
||||||
UserRegisteredEventHandler: Symbol.for('UserRegisteredEventHandler'),
|
UserRegisteredEventHandler: Symbol.for('UserRegisteredEventHandler'),
|
||||||
AccountDeletionRequestedEventHandler: Symbol.for('AccountDeletionRequestedEventHandler'),
|
AccountDeletionRequestedEventHandler: Symbol.for('AccountDeletionRequestedEventHandler'),
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
UserContentSizeRecalculationRequestedEvent,
|
UserContentSizeRecalculationRequestedEvent,
|
||||||
MuteEmailsSettingChangedEvent,
|
MuteEmailsSettingChangedEvent,
|
||||||
EmailRequestedEvent,
|
EmailRequestedEvent,
|
||||||
|
StatisticPersistenceRequestedEvent,
|
||||||
} from '@standardnotes/domain-events'
|
} from '@standardnotes/domain-events'
|
||||||
import { Predicate, PredicateVerificationResult } from '@standardnotes/predicates'
|
import { Predicate, PredicateVerificationResult } from '@standardnotes/predicates'
|
||||||
import { TimerInterface } from '@standardnotes/time'
|
import { TimerInterface } from '@standardnotes/time'
|
||||||
@@ -31,6 +32,25 @@ import { DomainEventFactoryInterface } from './DomainEventFactoryInterface'
|
|||||||
export class DomainEventFactory implements DomainEventFactoryInterface {
|
export class DomainEventFactory implements DomainEventFactoryInterface {
|
||||||
constructor(@inject(TYPES.Timer) private timer: TimerInterface) {}
|
constructor(@inject(TYPES.Timer) private timer: TimerInterface) {}
|
||||||
|
|
||||||
|
createStatisticPersistenceRequestedEvent(dto: {
|
||||||
|
statisticMeasureName: string
|
||||||
|
value: number
|
||||||
|
date: number
|
||||||
|
}): StatisticPersistenceRequestedEvent {
|
||||||
|
return {
|
||||||
|
type: 'STATISTIC_PERSISTENCE_REQUESTED',
|
||||||
|
createdAt: this.timer.getUTCDate(),
|
||||||
|
meta: {
|
||||||
|
correlation: {
|
||||||
|
userIdentifier: '-',
|
||||||
|
userIdentifierType: 'email',
|
||||||
|
},
|
||||||
|
origin: DomainEventService.Auth,
|
||||||
|
},
|
||||||
|
payload: dto,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
createMuteEmailsSettingChangedEvent(dto: {
|
createMuteEmailsSettingChangedEvent(dto: {
|
||||||
username: string
|
username: string
|
||||||
mute: boolean
|
mute: boolean
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
UserContentSizeRecalculationRequestedEvent,
|
UserContentSizeRecalculationRequestedEvent,
|
||||||
MuteEmailsSettingChangedEvent,
|
MuteEmailsSettingChangedEvent,
|
||||||
EmailRequestedEvent,
|
EmailRequestedEvent,
|
||||||
|
StatisticPersistenceRequestedEvent,
|
||||||
} from '@standardnotes/domain-events'
|
} from '@standardnotes/domain-events'
|
||||||
import { InviteeIdentifierType } from '../SharedSubscription/InviteeIdentifierType'
|
import { InviteeIdentifierType } from '../SharedSubscription/InviteeIdentifierType'
|
||||||
|
|
||||||
@@ -88,4 +89,9 @@ export interface DomainEventFactoryInterface {
|
|||||||
mute: boolean
|
mute: boolean
|
||||||
emailSubscriptionRejectionLevel: string
|
emailSubscriptionRejectionLevel: string
|
||||||
}): MuteEmailsSettingChangedEvent
|
}): MuteEmailsSettingChangedEvent
|
||||||
|
createStatisticPersistenceRequestedEvent(dto: {
|
||||||
|
statisticMeasureName: string
|
||||||
|
value: number
|
||||||
|
date: number
|
||||||
|
}): StatisticPersistenceRequestedEvent
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,4 +41,23 @@ describe('RoleToSubscriptionMap', () => {
|
|||||||
},
|
},
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should filter our subscription roles from an array of roles', () => {
|
||||||
|
const roles = [
|
||||||
|
{
|
||||||
|
name: RoleName.CoreUser,
|
||||||
|
} as jest.Mocked<Role>,
|
||||||
|
{
|
||||||
|
name: RoleName.FilesBetaUser,
|
||||||
|
} as jest.Mocked<Role>,
|
||||||
|
{
|
||||||
|
name: RoleName.PlusUser,
|
||||||
|
} as jest.Mocked<Role>,
|
||||||
|
]
|
||||||
|
expect(createMap().filterSubscriptionRoles(roles)).toEqual([
|
||||||
|
{
|
||||||
|
name: RoleName.PlusUser,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ export class RoleToSubscriptionMap implements RoleToSubscriptionMapInterface {
|
|||||||
return roles.filter((role) => this.nonSubscriptionRoles.includes(role.name as RoleName))
|
return roles.filter((role) => this.nonSubscriptionRoles.includes(role.name as RoleName))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filterSubscriptionRoles(roles: Role[]): Array<Role> {
|
||||||
|
return roles.filter((role) => !this.nonSubscriptionRoles.includes(role.name as RoleName))
|
||||||
|
}
|
||||||
|
|
||||||
getSubscriptionNameForRoleName(roleName: RoleName): SubscriptionName | undefined {
|
getSubscriptionNameForRoleName(roleName: RoleName): SubscriptionName | undefined {
|
||||||
return this.roleNameToSubscriptionNameMap.get(roleName)
|
return this.roleNameToSubscriptionNameMap.get(roleName)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { Role } from './Role'
|
|||||||
|
|
||||||
export interface RoleToSubscriptionMapInterface {
|
export interface RoleToSubscriptionMapInterface {
|
||||||
filterNonSubscriptionRoles(roles: Role[]): Array<Role>
|
filterNonSubscriptionRoles(roles: Role[]): Array<Role>
|
||||||
|
filterSubscriptionRoles(roles: Role[]): Array<Role>
|
||||||
getSubscriptionNameForRoleName(roleName: RoleName): SubscriptionName | undefined
|
getSubscriptionNameForRoleName(roleName: RoleName): SubscriptionName | undefined
|
||||||
getRoleNameForSubscriptionName(subscriptionName: SubscriptionName): RoleName | undefined
|
getRoleNameForSubscriptionName(subscriptionName: SubscriptionName): RoleName | undefined
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ import { SettingServiceInterface } from '../Setting/SettingServiceInterface'
|
|||||||
import { LogSessionUserAgentOption } from '@standardnotes/settings'
|
import { LogSessionUserAgentOption } from '@standardnotes/settings'
|
||||||
import { Setting } from '../Setting/Setting'
|
import { Setting } from '../Setting/Setting'
|
||||||
import { CryptoNode } from '@standardnotes/sncrypto-node'
|
import { CryptoNode } from '@standardnotes/sncrypto-node'
|
||||||
|
import { UserSubscriptionRepositoryInterface } from '../Subscription/UserSubscriptionRepositoryInterface'
|
||||||
|
import { TraceSession } from '../UseCase/TraceSession/TraceSession'
|
||||||
|
import { UserSubscription } from '../Subscription/UserSubscription'
|
||||||
|
import { Result } from '@standardnotes/domain-core'
|
||||||
|
|
||||||
describe('SessionService', () => {
|
describe('SessionService', () => {
|
||||||
let sessionRepository: SessionRepositoryInterface
|
let sessionRepository: SessionRepositoryInterface
|
||||||
@@ -28,6 +32,8 @@ describe('SessionService', () => {
|
|||||||
let timer: TimerInterface
|
let timer: TimerInterface
|
||||||
let logger: winston.Logger
|
let logger: winston.Logger
|
||||||
let cryptoNode: CryptoNode
|
let cryptoNode: CryptoNode
|
||||||
|
let traceSession: TraceSession
|
||||||
|
let userSubscriptionRepository: UserSubscriptionRepositoryInterface
|
||||||
|
|
||||||
const createService = () =>
|
const createService = () =>
|
||||||
new SessionService(
|
new SessionService(
|
||||||
@@ -41,6 +47,8 @@ describe('SessionService', () => {
|
|||||||
234,
|
234,
|
||||||
settingService,
|
settingService,
|
||||||
cryptoNode,
|
cryptoNode,
|
||||||
|
traceSession,
|
||||||
|
userSubscriptionRepository,
|
||||||
)
|
)
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -106,6 +114,14 @@ describe('SessionService', () => {
|
|||||||
cryptoNode = {} as jest.Mocked<CryptoNode>
|
cryptoNode = {} as jest.Mocked<CryptoNode>
|
||||||
cryptoNode.generateRandomKey = jest.fn().mockReturnValue('foo bar')
|
cryptoNode.generateRandomKey = jest.fn().mockReturnValue('foo bar')
|
||||||
cryptoNode.base64URLEncode = jest.fn().mockReturnValue('foobar')
|
cryptoNode.base64URLEncode = jest.fn().mockReturnValue('foobar')
|
||||||
|
|
||||||
|
traceSession = {} as jest.Mocked<TraceSession>
|
||||||
|
traceSession.execute = jest.fn()
|
||||||
|
|
||||||
|
userSubscriptionRepository = {} as jest.Mocked<UserSubscriptionRepositoryInterface>
|
||||||
|
userSubscriptionRepository.findOneByUserUuid = jest.fn().mockReturnValue({
|
||||||
|
planName: 'PRO_PLAN',
|
||||||
|
} as jest.Mocked<UserSubscription>)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should mark a revoked session as received', async () => {
|
it('should mark a revoked session as received', async () => {
|
||||||
@@ -204,6 +220,129 @@ describe('SessionService', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should trace a session', async () => {
|
||||||
|
const user = {} as jest.Mocked<User>
|
||||||
|
user.uuid = '123'
|
||||||
|
user.email = 'test@test.te'
|
||||||
|
|
||||||
|
await createService().createNewSessionForUser({
|
||||||
|
user,
|
||||||
|
apiVersion: '003',
|
||||||
|
userAgent: 'Google Chrome',
|
||||||
|
readonlyAccess: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(traceSession.execute).toHaveBeenCalledWith({
|
||||||
|
userUuid: '123',
|
||||||
|
username: 'test@test.te',
|
||||||
|
subscriptionPlanName: 'PRO_PLAN',
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should trace a session without a subscription', async () => {
|
||||||
|
userSubscriptionRepository.findOneByUserUuid = jest.fn().mockReturnValue(null)
|
||||||
|
const user = {} as jest.Mocked<User>
|
||||||
|
user.uuid = '123'
|
||||||
|
user.email = 'test@test.te'
|
||||||
|
|
||||||
|
await createService().createNewSessionForUser({
|
||||||
|
user,
|
||||||
|
apiVersion: '003',
|
||||||
|
userAgent: 'Google Chrome',
|
||||||
|
readonlyAccess: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(traceSession.execute).toHaveBeenCalledWith({
|
||||||
|
userUuid: '123',
|
||||||
|
username: 'test@test.te',
|
||||||
|
subscriptionPlanName: null,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should create a session if tracing session throws an error', async () => {
|
||||||
|
traceSession.execute = jest.fn().mockRejectedValue(new Error('foo bar'))
|
||||||
|
userSubscriptionRepository.findOneByUserUuid = jest.fn().mockReturnValue(null)
|
||||||
|
const user = {} as jest.Mocked<User>
|
||||||
|
user.uuid = '123'
|
||||||
|
user.email = 'test@test.te'
|
||||||
|
|
||||||
|
const sessionPayload = await createService().createNewSessionForUser({
|
||||||
|
user,
|
||||||
|
apiVersion: '003',
|
||||||
|
userAgent: 'Google Chrome',
|
||||||
|
readonlyAccess: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(traceSession.execute).toHaveBeenCalledWith({
|
||||||
|
userUuid: '123',
|
||||||
|
username: 'test@test.te',
|
||||||
|
subscriptionPlanName: null,
|
||||||
|
})
|
||||||
|
expect(sessionPayload).toEqual({
|
||||||
|
access_expiration: 123,
|
||||||
|
access_token: expect.any(String),
|
||||||
|
refresh_expiration: 123,
|
||||||
|
refresh_token: expect.any(String),
|
||||||
|
readonly_access: false,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should create a session if tracing session throws an error', async () => {
|
||||||
|
traceSession.execute = jest.fn().mockRejectedValue(new Error('foo bar'))
|
||||||
|
userSubscriptionRepository.findOneByUserUuid = jest.fn().mockReturnValue(null)
|
||||||
|
const user = {} as jest.Mocked<User>
|
||||||
|
user.uuid = '123'
|
||||||
|
user.email = 'test@test.te'
|
||||||
|
|
||||||
|
const sessionPayload = await createService().createNewSessionForUser({
|
||||||
|
user,
|
||||||
|
apiVersion: '003',
|
||||||
|
userAgent: 'Google Chrome',
|
||||||
|
readonlyAccess: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(traceSession.execute).toHaveBeenCalledWith({
|
||||||
|
userUuid: '123',
|
||||||
|
username: 'test@test.te',
|
||||||
|
subscriptionPlanName: null,
|
||||||
|
})
|
||||||
|
expect(sessionPayload).toEqual({
|
||||||
|
access_expiration: 123,
|
||||||
|
access_token: expect.any(String),
|
||||||
|
refresh_expiration: 123,
|
||||||
|
refresh_token: expect.any(String),
|
||||||
|
readonly_access: false,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should create a session if tracing session fails', async () => {
|
||||||
|
traceSession.execute = jest.fn().mockReturnValue(Result.fail('Oops'))
|
||||||
|
userSubscriptionRepository.findOneByUserUuid = jest.fn().mockReturnValue(null)
|
||||||
|
const user = {} as jest.Mocked<User>
|
||||||
|
user.uuid = '123'
|
||||||
|
user.email = 'test@test.te'
|
||||||
|
|
||||||
|
const sessionPayload = await createService().createNewSessionForUser({
|
||||||
|
user,
|
||||||
|
apiVersion: '003',
|
||||||
|
userAgent: 'Google Chrome',
|
||||||
|
readonlyAccess: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(traceSession.execute).toHaveBeenCalledWith({
|
||||||
|
userUuid: '123',
|
||||||
|
username: 'test@test.te',
|
||||||
|
subscriptionPlanName: null,
|
||||||
|
})
|
||||||
|
expect(sessionPayload).toEqual({
|
||||||
|
access_expiration: 123,
|
||||||
|
access_token: expect.any(String),
|
||||||
|
refresh_expiration: 123,
|
||||||
|
refresh_token: expect.any(String),
|
||||||
|
readonly_access: false,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
it('should create new ephemeral session for a user', async () => {
|
it('should create new ephemeral session for a user', async () => {
|
||||||
const user = {} as jest.Mocked<User>
|
const user = {} as jest.Mocked<User>
|
||||||
user.uuid = '123'
|
user.uuid = '123'
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
import * as crypto from 'crypto'
|
import * as crypto from 'crypto'
|
||||||
import * as winston from 'winston'
|
|
||||||
import * as dayjs from 'dayjs'
|
import * as dayjs from 'dayjs'
|
||||||
import { UAParser } from 'ua-parser-js'
|
import { UAParser } from 'ua-parser-js'
|
||||||
import { inject, injectable } from 'inversify'
|
import { inject, injectable } from 'inversify'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
import { TimerInterface } from '@standardnotes/time'
|
import { TimerInterface } from '@standardnotes/time'
|
||||||
|
import { Logger } from 'winston'
|
||||||
|
import { LogSessionUserAgentOption, SettingName } from '@standardnotes/settings'
|
||||||
|
import { SessionBody } from '@standardnotes/responses'
|
||||||
|
import { Uuid } from '@standardnotes/common'
|
||||||
|
import { CryptoNode } from '@standardnotes/sncrypto-node'
|
||||||
|
|
||||||
import TYPES from '../../Bootstrap/Types'
|
import TYPES from '../../Bootstrap/Types'
|
||||||
import { Session } from './Session'
|
import { Session } from './Session'
|
||||||
@@ -16,10 +20,8 @@ import { EphemeralSession } from './EphemeralSession'
|
|||||||
import { RevokedSession } from './RevokedSession'
|
import { RevokedSession } from './RevokedSession'
|
||||||
import { RevokedSessionRepositoryInterface } from './RevokedSessionRepositoryInterface'
|
import { RevokedSessionRepositoryInterface } from './RevokedSessionRepositoryInterface'
|
||||||
import { SettingServiceInterface } from '../Setting/SettingServiceInterface'
|
import { SettingServiceInterface } from '../Setting/SettingServiceInterface'
|
||||||
import { LogSessionUserAgentOption, SettingName } from '@standardnotes/settings'
|
import { TraceSession } from '../UseCase/TraceSession/TraceSession'
|
||||||
import { SessionBody } from '@standardnotes/responses'
|
import { UserSubscriptionRepositoryInterface } from '../Subscription/UserSubscriptionRepositoryInterface'
|
||||||
import { Uuid } from '@standardnotes/common'
|
|
||||||
import { CryptoNode } from '@standardnotes/sncrypto-node'
|
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class SessionService implements SessionServiceInterface {
|
export class SessionService implements SessionServiceInterface {
|
||||||
@@ -31,11 +33,13 @@ export class SessionService implements SessionServiceInterface {
|
|||||||
@inject(TYPES.RevokedSessionRepository) private revokedSessionRepository: RevokedSessionRepositoryInterface,
|
@inject(TYPES.RevokedSessionRepository) private revokedSessionRepository: RevokedSessionRepositoryInterface,
|
||||||
@inject(TYPES.DeviceDetector) private deviceDetector: UAParser,
|
@inject(TYPES.DeviceDetector) private deviceDetector: UAParser,
|
||||||
@inject(TYPES.Timer) private timer: TimerInterface,
|
@inject(TYPES.Timer) private timer: TimerInterface,
|
||||||
@inject(TYPES.Logger) private logger: winston.Logger,
|
@inject(TYPES.Logger) private logger: Logger,
|
||||||
@inject(TYPES.ACCESS_TOKEN_AGE) private accessTokenAge: number,
|
@inject(TYPES.ACCESS_TOKEN_AGE) private accessTokenAge: number,
|
||||||
@inject(TYPES.REFRESH_TOKEN_AGE) private refreshTokenAge: number,
|
@inject(TYPES.REFRESH_TOKEN_AGE) private refreshTokenAge: number,
|
||||||
@inject(TYPES.SettingService) private settingService: SettingServiceInterface,
|
@inject(TYPES.SettingService) private settingService: SettingServiceInterface,
|
||||||
@inject(TYPES.CryptoNode) private cryptoNode: CryptoNode,
|
@inject(TYPES.CryptoNode) private cryptoNode: CryptoNode,
|
||||||
|
@inject(TYPES.TraceSession) private traceSession: TraceSession,
|
||||||
|
@inject(TYPES.UserSubscriptionRepository) private userSubscriptionRepository: UserSubscriptionRepositoryInterface,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async createNewSessionForUser(dto: {
|
async createNewSessionForUser(dto: {
|
||||||
@@ -53,6 +57,20 @@ export class SessionService implements SessionServiceInterface {
|
|||||||
|
|
||||||
await this.sessionRepository.save(session)
|
await this.sessionRepository.save(session)
|
||||||
|
|
||||||
|
try {
|
||||||
|
const userSubscription = await this.userSubscriptionRepository.findOneByUserUuid(dto.user.uuid)
|
||||||
|
const traceSessionResult = await this.traceSession.execute({
|
||||||
|
userUuid: dto.user.uuid,
|
||||||
|
username: dto.user.email,
|
||||||
|
subscriptionPlanName: userSubscription ? userSubscription.planName : null,
|
||||||
|
})
|
||||||
|
if (traceSessionResult.isFailed()) {
|
||||||
|
this.logger.error(traceSessionResult.getError())
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(`Could not trace session while creating cross service token.: ${(error as Error).message}`)
|
||||||
|
}
|
||||||
|
|
||||||
return sessionPayload
|
return sessionPayload
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Uuid } from '@standardnotes/domain-core'
|
import { SubscriptionPlanName, Uuid } from '@standardnotes/domain-core'
|
||||||
|
|
||||||
import { SessionTrace } from './SessionTrace'
|
import { SessionTrace } from './SessionTrace'
|
||||||
|
|
||||||
@@ -6,4 +6,6 @@ export interface SessionTraceRepositoryInterface {
|
|||||||
save(sessionTrace: SessionTrace): Promise<void>
|
save(sessionTrace: SessionTrace): Promise<void>
|
||||||
removeExpiredBefore(date: Date): Promise<void>
|
removeExpiredBefore(date: Date): Promise<void>
|
||||||
findOneByUserUuidAndDate(userUuid: Uuid, date: Date): Promise<SessionTrace | null>
|
findOneByUserUuidAndDate(userUuid: Uuid, date: Date): Promise<SessionTrace | null>
|
||||||
|
countByDate(date: Date): Promise<number>
|
||||||
|
countByDateAndSubscriptionPlanName(date: Date, subscriptionPlanName: SubscriptionPlanName): Promise<number>
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-157
@@ -8,10 +8,6 @@ import { Role } from '../../Role/Role'
|
|||||||
import { UserRepositoryInterface } from '../../User/UserRepositoryInterface'
|
import { UserRepositoryInterface } from '../../User/UserRepositoryInterface'
|
||||||
|
|
||||||
import { CreateCrossServiceToken } from './CreateCrossServiceToken'
|
import { CreateCrossServiceToken } from './CreateCrossServiceToken'
|
||||||
import { RoleToSubscriptionMapInterface } from '../../Role/RoleToSubscriptionMapInterface'
|
|
||||||
import { TraceSession } from '../TraceSession/TraceSession'
|
|
||||||
import { Logger } from 'winston'
|
|
||||||
import { Result, RoleName, SubscriptionPlanName } from '@standardnotes/domain-core'
|
|
||||||
|
|
||||||
describe('CreateCrossServiceToken', () => {
|
describe('CreateCrossServiceToken', () => {
|
||||||
let userProjector: ProjectorInterface<User>
|
let userProjector: ProjectorInterface<User>
|
||||||
@@ -19,9 +15,6 @@ describe('CreateCrossServiceToken', () => {
|
|||||||
let roleProjector: ProjectorInterface<Role>
|
let roleProjector: ProjectorInterface<Role>
|
||||||
let tokenEncoder: TokenEncoderInterface<CrossServiceTokenData>
|
let tokenEncoder: TokenEncoderInterface<CrossServiceTokenData>
|
||||||
let userRepository: UserRepositoryInterface
|
let userRepository: UserRepositoryInterface
|
||||||
let roleToSubscriptionMap: RoleToSubscriptionMapInterface
|
|
||||||
let traceSession: TraceSession
|
|
||||||
let logger: Logger
|
|
||||||
const jwtTTL = 60
|
const jwtTTL = 60
|
||||||
|
|
||||||
let session: Session
|
let session: Session
|
||||||
@@ -29,17 +22,7 @@ describe('CreateCrossServiceToken', () => {
|
|||||||
let role: Role
|
let role: Role
|
||||||
|
|
||||||
const createUseCase = () =>
|
const createUseCase = () =>
|
||||||
new CreateCrossServiceToken(
|
new CreateCrossServiceToken(userProjector, sessionProjector, roleProjector, tokenEncoder, userRepository, jwtTTL)
|
||||||
userProjector,
|
|
||||||
sessionProjector,
|
|
||||||
roleProjector,
|
|
||||||
tokenEncoder,
|
|
||||||
userRepository,
|
|
||||||
jwtTTL,
|
|
||||||
roleToSubscriptionMap,
|
|
||||||
traceSession,
|
|
||||||
logger,
|
|
||||||
)
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
session = {} as jest.Mocked<Session>
|
session = {} as jest.Mocked<Session>
|
||||||
@@ -65,18 +48,6 @@ describe('CreateCrossServiceToken', () => {
|
|||||||
|
|
||||||
userRepository = {} as jest.Mocked<UserRepositoryInterface>
|
userRepository = {} as jest.Mocked<UserRepositoryInterface>
|
||||||
userRepository.findOneByUuid = jest.fn().mockReturnValue(user)
|
userRepository.findOneByUuid = jest.fn().mockReturnValue(user)
|
||||||
|
|
||||||
roleToSubscriptionMap = {} as jest.Mocked<RoleToSubscriptionMapInterface>
|
|
||||||
roleToSubscriptionMap.filterNonSubscriptionRoles = jest.fn().mockReturnValue([RoleName.NAMES.PlusUser])
|
|
||||||
roleToSubscriptionMap.getSubscriptionNameForRoleName = jest
|
|
||||||
.fn()
|
|
||||||
.mockReturnValue(SubscriptionPlanName.NAMES.PlusPlan)
|
|
||||||
|
|
||||||
traceSession = {} as jest.Mocked<TraceSession>
|
|
||||||
traceSession.execute = jest.fn()
|
|
||||||
|
|
||||||
logger = {} as jest.Mocked<Logger>
|
|
||||||
logger.error = jest.fn()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should create a cross service token for user', async () => {
|
it('should create a cross service token for user', async () => {
|
||||||
@@ -85,11 +56,6 @@ describe('CreateCrossServiceToken', () => {
|
|||||||
session,
|
session,
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(traceSession.execute).toHaveBeenCalledWith({
|
|
||||||
userUuid: '1-2-3',
|
|
||||||
username: 'test@test.te',
|
|
||||||
subscriptionPlanName: 'PLUS_PLAN',
|
|
||||||
})
|
|
||||||
expect(tokenEncoder.encodeExpirableToken).toHaveBeenCalledWith(
|
expect(tokenEncoder.encodeExpirableToken).toHaveBeenCalledWith(
|
||||||
{
|
{
|
||||||
roles: [
|
roles: [
|
||||||
@@ -168,126 +134,4 @@ describe('CreateCrossServiceToken', () => {
|
|||||||
|
|
||||||
expect(caughtError).not.toBeNull()
|
expect(caughtError).not.toBeNull()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should trace session without a subscription role', async () => {
|
|
||||||
roleToSubscriptionMap.filterNonSubscriptionRoles = jest.fn().mockReturnValue([])
|
|
||||||
|
|
||||||
await createUseCase().execute({
|
|
||||||
user,
|
|
||||||
session,
|
|
||||||
})
|
|
||||||
|
|
||||||
expect(traceSession.execute).toHaveBeenCalledWith({
|
|
||||||
userUuid: '1-2-3',
|
|
||||||
username: 'test@test.te',
|
|
||||||
subscriptionPlanName: null,
|
|
||||||
})
|
|
||||||
expect(tokenEncoder.encodeExpirableToken).toHaveBeenCalledWith(
|
|
||||||
{
|
|
||||||
roles: [
|
|
||||||
{
|
|
||||||
name: 'role1',
|
|
||||||
uuid: '1-3-4',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
session: {
|
|
||||||
test: 'test',
|
|
||||||
},
|
|
||||||
user: {
|
|
||||||
email: 'test@test.te',
|
|
||||||
uuid: '1-2-3',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
60,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should trace session without a subscription', async () => {
|
|
||||||
roleToSubscriptionMap.getSubscriptionNameForRoleName = jest.fn().mockReturnValue(undefined)
|
|
||||||
|
|
||||||
await createUseCase().execute({
|
|
||||||
user,
|
|
||||||
session,
|
|
||||||
})
|
|
||||||
|
|
||||||
expect(traceSession.execute).toHaveBeenCalledWith({
|
|
||||||
userUuid: '1-2-3',
|
|
||||||
username: 'test@test.te',
|
|
||||||
subscriptionPlanName: null,
|
|
||||||
})
|
|
||||||
expect(tokenEncoder.encodeExpirableToken).toHaveBeenCalledWith(
|
|
||||||
{
|
|
||||||
roles: [
|
|
||||||
{
|
|
||||||
name: 'role1',
|
|
||||||
uuid: '1-3-4',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
session: {
|
|
||||||
test: 'test',
|
|
||||||
},
|
|
||||||
user: {
|
|
||||||
email: 'test@test.te',
|
|
||||||
uuid: '1-2-3',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
60,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should create token if tracing session throws an error', async () => {
|
|
||||||
traceSession.execute = jest.fn().mockRejectedValue(new Error('test'))
|
|
||||||
|
|
||||||
await createUseCase().execute({
|
|
||||||
user,
|
|
||||||
session,
|
|
||||||
})
|
|
||||||
|
|
||||||
expect(tokenEncoder.encodeExpirableToken).toHaveBeenCalledWith(
|
|
||||||
{
|
|
||||||
roles: [
|
|
||||||
{
|
|
||||||
name: 'role1',
|
|
||||||
uuid: '1-3-4',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
session: {
|
|
||||||
test: 'test',
|
|
||||||
},
|
|
||||||
user: {
|
|
||||||
email: 'test@test.te',
|
|
||||||
uuid: '1-2-3',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
60,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should create token if tracing session fails', async () => {
|
|
||||||
traceSession.execute = jest.fn().mockReturnValue(Result.fail('Ooops'))
|
|
||||||
|
|
||||||
await createUseCase().execute({
|
|
||||||
user,
|
|
||||||
session,
|
|
||||||
})
|
|
||||||
|
|
||||||
expect(tokenEncoder.encodeExpirableToken).toHaveBeenCalledWith(
|
|
||||||
{
|
|
||||||
roles: [
|
|
||||||
{
|
|
||||||
name: 'role1',
|
|
||||||
uuid: '1-3-4',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
session: {
|
|
||||||
test: 'test',
|
|
||||||
},
|
|
||||||
user: {
|
|
||||||
email: 'test@test.te',
|
|
||||||
uuid: '1-2-3',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
60,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
import { RoleName } from '@standardnotes/common'
|
import { RoleName } from '@standardnotes/common'
|
||||||
import { TokenEncoderInterface, CrossServiceTokenData } from '@standardnotes/security'
|
import { TokenEncoderInterface, CrossServiceTokenData } from '@standardnotes/security'
|
||||||
import { inject, injectable } from 'inversify'
|
import { inject, injectable } from 'inversify'
|
||||||
import { Logger } from 'winston'
|
|
||||||
|
|
||||||
import TYPES from '../../../Bootstrap/Types'
|
import TYPES from '../../../Bootstrap/Types'
|
||||||
import { ProjectorInterface } from '../../../Projection/ProjectorInterface'
|
import { ProjectorInterface } from '../../../Projection/ProjectorInterface'
|
||||||
import { Role } from '../../Role/Role'
|
import { Role } from '../../Role/Role'
|
||||||
import { RoleToSubscriptionMapInterface } from '../../Role/RoleToSubscriptionMapInterface'
|
|
||||||
import { Session } from '../../Session/Session'
|
import { Session } from '../../Session/Session'
|
||||||
import { User } from '../../User/User'
|
import { User } from '../../User/User'
|
||||||
import { UserRepositoryInterface } from '../../User/UserRepositoryInterface'
|
import { UserRepositoryInterface } from '../../User/UserRepositoryInterface'
|
||||||
import { TraceSession } from '../TraceSession/TraceSession'
|
|
||||||
import { UseCaseInterface } from '../UseCaseInterface'
|
import { UseCaseInterface } from '../UseCaseInterface'
|
||||||
|
|
||||||
import { CreateCrossServiceTokenDTO } from './CreateCrossServiceTokenDTO'
|
import { CreateCrossServiceTokenDTO } from './CreateCrossServiceTokenDTO'
|
||||||
@@ -25,9 +22,6 @@ export class CreateCrossServiceToken implements UseCaseInterface {
|
|||||||
@inject(TYPES.CrossServiceTokenEncoder) private tokenEncoder: TokenEncoderInterface<CrossServiceTokenData>,
|
@inject(TYPES.CrossServiceTokenEncoder) private tokenEncoder: TokenEncoderInterface<CrossServiceTokenData>,
|
||||||
@inject(TYPES.UserRepository) private userRepository: UserRepositoryInterface,
|
@inject(TYPES.UserRepository) private userRepository: UserRepositoryInterface,
|
||||||
@inject(TYPES.AUTH_JWT_TTL) private jwtTTL: number,
|
@inject(TYPES.AUTH_JWT_TTL) private jwtTTL: number,
|
||||||
@inject(TYPES.RoleToSubscriptionMap) private roleToSubscriptionMap: RoleToSubscriptionMapInterface,
|
|
||||||
@inject(TYPES.TraceSession) private traceSession: TraceSession,
|
|
||||||
@inject(TYPES.Logger) private logger: Logger,
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async execute(dto: CreateCrossServiceTokenDTO): Promise<CreateCrossServiceTokenResponse> {
|
async execute(dto: CreateCrossServiceTokenDTO): Promise<CreateCrossServiceTokenResponse> {
|
||||||
@@ -51,19 +45,6 @@ export class CreateCrossServiceToken implements UseCaseInterface {
|
|||||||
authTokenData.session = this.projectSession(dto.session)
|
authTokenData.session = this.projectSession(dto.session)
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
const traceSessionResult = await this.traceSession.execute({
|
|
||||||
userUuid: user.uuid,
|
|
||||||
username: user.email,
|
|
||||||
subscriptionPlanName: this.getSubscriptionNameFromRoles(roles),
|
|
||||||
})
|
|
||||||
if (traceSessionResult.isFailed()) {
|
|
||||||
this.logger.error(traceSessionResult.getError())
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
this.logger.error(`Could not trace session while creating cross service token: ${(error as Error).message}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
token: this.tokenEncoder.encodeExpirableToken(authTokenData, this.jwtTTL),
|
token: this.tokenEncoder.encodeExpirableToken(authTokenData, this.jwtTTL),
|
||||||
}
|
}
|
||||||
@@ -100,17 +81,4 @@ export class CreateCrossServiceToken implements UseCaseInterface {
|
|||||||
private projectRoles(roles: Array<Role>): Array<{ uuid: string; name: RoleName }> {
|
private projectRoles(roles: Array<Role>): Array<{ uuid: string; name: RoleName }> {
|
||||||
return roles.map((role) => <{ uuid: string; name: RoleName }>this.roleProjector.projectSimple(role))
|
return roles.map((role) => <{ uuid: string; name: RoleName }>this.roleProjector.projectSimple(role))
|
||||||
}
|
}
|
||||||
|
|
||||||
private getSubscriptionNameFromRoles(roles: Array<Role>): string | null {
|
|
||||||
const nonSubscriptionRoles = this.roleToSubscriptionMap.filterNonSubscriptionRoles(roles)
|
|
||||||
if (nonSubscriptionRoles.length === 0) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
const subscriptionName = this.roleToSubscriptionMap.getSubscriptionNameForRoleName(
|
|
||||||
nonSubscriptionRoles[0].name as RoleName,
|
|
||||||
)
|
|
||||||
|
|
||||||
return subscriptionName === undefined ? null : subscriptionName
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import { DomainEventPublisherInterface, StatisticPersistenceRequestedEvent } from '@standardnotes/domain-events'
|
||||||
|
import { TimerInterface } from '@standardnotes/time'
|
||||||
|
|
||||||
|
import { DomainEventFactoryInterface } from '../../Event/DomainEventFactoryInterface'
|
||||||
|
import { SessionTraceRepositoryInterface } from '../../Session/SessionTraceRepositoryInterface'
|
||||||
|
|
||||||
|
import { PersistStatistics } from './PersistStatistics'
|
||||||
|
|
||||||
|
describe('PersistStatistics', () => {
|
||||||
|
let sessionTracesRepository: SessionTraceRepositoryInterface
|
||||||
|
let domainEventPublisher: DomainEventPublisherInterface
|
||||||
|
let domainEventFactory: DomainEventFactoryInterface
|
||||||
|
let timer: TimerInterface
|
||||||
|
|
||||||
|
const createUseCase = () =>
|
||||||
|
new PersistStatistics(sessionTracesRepository, domainEventPublisher, domainEventFactory, timer)
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
sessionTracesRepository = {} as jest.Mocked<SessionTraceRepositoryInterface>
|
||||||
|
sessionTracesRepository.countByDate = jest.fn().mockReturnValue(1)
|
||||||
|
sessionTracesRepository.countByDateAndSubscriptionPlanName = jest.fn().mockReturnValue(2)
|
||||||
|
|
||||||
|
domainEventFactory = {} as jest.Mocked<DomainEventFactoryInterface>
|
||||||
|
domainEventFactory.createStatisticPersistenceRequestedEvent = jest
|
||||||
|
.fn()
|
||||||
|
.mockReturnValue({} as jest.Mocked<StatisticPersistenceRequestedEvent>)
|
||||||
|
|
||||||
|
domainEventPublisher = {} as jest.Mocked<DomainEventPublisherInterface>
|
||||||
|
domainEventPublisher.publish = jest.fn()
|
||||||
|
|
||||||
|
timer = {} as jest.Mocked<TimerInterface>
|
||||||
|
timer.convertDateToMicroseconds = jest.fn().mockReturnValue(3)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should request statistic persistence', async () => {
|
||||||
|
await createUseCase().execute({ sessionsInADay: new Date() })
|
||||||
|
|
||||||
|
expect(domainEventPublisher.publish).toHaveBeenCalledTimes(4)
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
import { Result, SubscriptionPlanName, UseCaseInterface } from '@standardnotes/domain-core'
|
||||||
|
import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
|
||||||
|
import { TimerInterface } from '@standardnotes/time'
|
||||||
|
|
||||||
|
import { DomainEventFactoryInterface } from '../../Event/DomainEventFactoryInterface'
|
||||||
|
import { SessionTraceRepositoryInterface } from '../../Session/SessionTraceRepositoryInterface'
|
||||||
|
import { PersistStatisticsDTO } from './PersistStatisticsDTO'
|
||||||
|
|
||||||
|
export class PersistStatistics implements UseCaseInterface<string> {
|
||||||
|
constructor(
|
||||||
|
private sessionTracesRepository: SessionTraceRepositoryInterface,
|
||||||
|
private domainEventPublisher: DomainEventPublisherInterface,
|
||||||
|
private domainEventFactory: DomainEventFactoryInterface,
|
||||||
|
private timer: TimerInterface,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async execute(dto: PersistStatisticsDTO): Promise<Result<string>> {
|
||||||
|
const countSessionsInADay = await this.sessionTracesRepository.countByDate(dto.sessionsInADay)
|
||||||
|
await this.domainEventPublisher.publish(
|
||||||
|
this.domainEventFactory.createStatisticPersistenceRequestedEvent({
|
||||||
|
statisticMeasureName: 'active-users',
|
||||||
|
value: countSessionsInADay,
|
||||||
|
date: this.timer.convertDateToMicroseconds(dto.sessionsInADay),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
const proSubscriptionPlanName = SubscriptionPlanName.create(SubscriptionPlanName.NAMES.ProPlan).getValue()
|
||||||
|
const countProSessionsInADay = await this.sessionTracesRepository.countByDateAndSubscriptionPlanName(
|
||||||
|
dto.sessionsInADay,
|
||||||
|
proSubscriptionPlanName,
|
||||||
|
)
|
||||||
|
await this.domainEventPublisher.publish(
|
||||||
|
this.domainEventFactory.createStatisticPersistenceRequestedEvent({
|
||||||
|
statisticMeasureName: 'active-pro-users',
|
||||||
|
value: countProSessionsInADay,
|
||||||
|
date: this.timer.convertDateToMicroseconds(dto.sessionsInADay),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
const plusSubscriptionPlanName = SubscriptionPlanName.create(SubscriptionPlanName.NAMES.PlusPlan).getValue()
|
||||||
|
const countPlusSessionsInADay = await this.sessionTracesRepository.countByDateAndSubscriptionPlanName(
|
||||||
|
dto.sessionsInADay,
|
||||||
|
plusSubscriptionPlanName,
|
||||||
|
)
|
||||||
|
await this.domainEventPublisher.publish(
|
||||||
|
this.domainEventFactory.createStatisticPersistenceRequestedEvent({
|
||||||
|
statisticMeasureName: 'active-plus-users',
|
||||||
|
value: countPlusSessionsInADay,
|
||||||
|
date: this.timer.convertDateToMicroseconds(dto.sessionsInADay),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
const countFreeSessionsInADay = countSessionsInADay - countProSessionsInADay - countPlusSessionsInADay
|
||||||
|
await this.domainEventPublisher.publish(
|
||||||
|
this.domainEventFactory.createStatisticPersistenceRequestedEvent({
|
||||||
|
statisticMeasureName: 'active-free-users',
|
||||||
|
value: countFreeSessionsInADay,
|
||||||
|
date: this.timer.convertDateToMicroseconds(dto.sessionsInADay),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
return Result.ok('Statistics persisted.')
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export interface PersistStatisticsDTO {
|
||||||
|
sessionsInADay: Date
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MapperInterface, Uuid } from '@standardnotes/domain-core'
|
import { MapperInterface, SubscriptionPlanName, Uuid } from '@standardnotes/domain-core'
|
||||||
import { Repository } from 'typeorm'
|
import { Repository } from 'typeorm'
|
||||||
import { SessionTrace } from '../../Domain/Session/SessionTrace'
|
import { SessionTrace } from '../../Domain/Session/SessionTrace'
|
||||||
import { SessionTraceRepositoryInterface } from '../../Domain/Session/SessionTraceRepositoryInterface'
|
import { SessionTraceRepositoryInterface } from '../../Domain/Session/SessionTraceRepositoryInterface'
|
||||||
@@ -10,6 +10,27 @@ export class MySQLSessionTraceRepository implements SessionTraceRepositoryInterf
|
|||||||
private mapper: MapperInterface<SessionTrace, TypeORMSessionTrace>,
|
private mapper: MapperInterface<SessionTrace, TypeORMSessionTrace>,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
async countByDateAndSubscriptionPlanName(date: Date, subscriptionPlanName: SubscriptionPlanName): Promise<number> {
|
||||||
|
return this.ormRepository
|
||||||
|
.createQueryBuilder('trace')
|
||||||
|
.where('trace.creation_date = :creationDate', {
|
||||||
|
creationDate: `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`,
|
||||||
|
})
|
||||||
|
.andWhere('trace.subscription_plan_name = :subscriptionPlanName', {
|
||||||
|
subscriptionPlanName: subscriptionPlanName.value,
|
||||||
|
})
|
||||||
|
.getCount()
|
||||||
|
}
|
||||||
|
|
||||||
|
async countByDate(date: Date): Promise<number> {
|
||||||
|
return this.ormRepository
|
||||||
|
.createQueryBuilder('trace')
|
||||||
|
.where('trace.creation_date = :creationDate', {
|
||||||
|
creationDate: `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`,
|
||||||
|
})
|
||||||
|
.getCount()
|
||||||
|
}
|
||||||
|
|
||||||
async removeExpiredBefore(date: Date): Promise<void> {
|
async removeExpiredBefore(date: Date): Promise<void> {
|
||||||
await this.ormRepository
|
await this.ormRepository
|
||||||
.createQueryBuilder()
|
.createQueryBuilder()
|
||||||
@@ -23,7 +44,7 @@ export class MySQLSessionTraceRepository implements SessionTraceRepositoryInterf
|
|||||||
.createQueryBuilder('trace')
|
.createQueryBuilder('trace')
|
||||||
.where('trace.user_uuid = :userUuid AND trace.creation_date = :creationDate', {
|
.where('trace.user_uuid = :userUuid AND trace.creation_date = :creationDate', {
|
||||||
userUuid: userUuid.value,
|
userUuid: userUuid.value,
|
||||||
creationDate: new Date(date.getFullYear(), date.getMonth(), date.getDate()),
|
creationDate: `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`,
|
||||||
})
|
})
|
||||||
.getOne()
|
.getOne()
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm'
|
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm'
|
||||||
|
|
||||||
@Entity({ name: 'session_traces' })
|
@Entity({ name: 'session_traces' })
|
||||||
|
@Index('user_uuid_and_creation_date', ['userUuid', 'creationDate'], { unique: true })
|
||||||
export class TypeORMSessionTrace {
|
export class TypeORMSessionTrace {
|
||||||
@PrimaryGeneratedColumn('uuid')
|
@PrimaryGeneratedColumn('uuid')
|
||||||
declare uuid: string
|
declare uuid: string
|
||||||
|
|||||||
@@ -3,6 +3,10 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.9.59](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.9.58...@standardnotes/domain-events-infra@1.9.59) (2022-12-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/domain-events-infra
|
||||||
|
|
||||||
## [1.9.58](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.9.57...@standardnotes/domain-events-infra@1.9.58) (2022-12-19)
|
## [1.9.58](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.9.57...@standardnotes/domain-events-infra@1.9.58) (2022-12-19)
|
||||||
|
|
||||||
**Note:** Version bump only for package @standardnotes/domain-events-infra
|
**Note:** Version bump only for package @standardnotes/domain-events-infra
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/domain-events-infra",
|
"name": "@standardnotes/domain-events-infra",
|
||||||
"version": "1.9.58",
|
"version": "1.9.59",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <19.0.0"
|
"node": ">=18.0.0 <19.0.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,6 +3,12 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [2.105.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.105.0...@standardnotes/domain-events@2.105.1) (2022-12-20)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **auth:** replace date object with number timestamp ([5b4bb6e](https://github.com/standardnotes/server/commit/5b4bb6e7a78a1b0f4e663bb990619f65f6a5c757))
|
||||||
|
|
||||||
# [2.105.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.104.2...@standardnotes/domain-events@2.105.0) (2022-12-19)
|
# [2.105.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.104.2...@standardnotes/domain-events@2.105.0) (2022-12-19)
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/domain-events",
|
"name": "@standardnotes/domain-events",
|
||||||
"version": "2.105.0",
|
"version": "2.105.1",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <19.0.0"
|
"node": ">=18.0.0 <19.0.0"
|
||||||
},
|
},
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
export interface StatisticPersistenceRequestedEventPayload {
|
export interface StatisticPersistenceRequestedEventPayload {
|
||||||
statisticMeasureName: string
|
statisticMeasureName: string
|
||||||
value: number
|
value: number
|
||||||
date: Date
|
date: number
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,10 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.6.56](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.6.55...@standardnotes/event-store@1.6.56) (2022-12-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/event-store
|
||||||
|
|
||||||
## [1.6.55](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.6.54...@standardnotes/event-store@1.6.55) (2022-12-19)
|
## [1.6.55](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.6.54...@standardnotes/event-store@1.6.55) (2022-12-19)
|
||||||
|
|
||||||
**Note:** Version bump only for package @standardnotes/event-store
|
**Note:** Version bump only for package @standardnotes/event-store
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/event-store",
|
"name": "@standardnotes/event-store",
|
||||||
"version": "1.6.55",
|
"version": "1.6.56",
|
||||||
"description": "Event Store Service",
|
"description": "Event Store Service",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "dist/src/index.js",
|
"main": "dist/src/index.js",
|
||||||
|
|||||||
@@ -3,6 +3,14 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.9.3](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.9.2...@standardnotes/files-server@1.9.3) (2022-12-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/files-server
|
||||||
|
|
||||||
|
## [1.9.2](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.9.1...@standardnotes/files-server@1.9.2) (2022-12-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/files-server
|
||||||
|
|
||||||
## [1.9.1](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.9.0...@standardnotes/files-server@1.9.1) (2022-12-19)
|
## [1.9.1](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.9.0...@standardnotes/files-server@1.9.1) (2022-12-19)
|
||||||
|
|
||||||
**Note:** Version bump only for package @standardnotes/files-server
|
**Note:** Version bump only for package @standardnotes/files-server
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/files-server",
|
"name": "@standardnotes/files-server",
|
||||||
"version": "1.9.1",
|
"version": "1.9.3",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <19.0.0"
|
"node": ">=18.0.0 <19.0.0"
|
||||||
},
|
},
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
"upgrade:snjs": "yarn ncu -u '@standardnotes/*'"
|
"upgrade:snjs": "yarn ncu -u '@standardnotes/*'"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sentry/node": "^7.27.0",
|
"@sentry/node": "^7.28.1",
|
||||||
"@standardnotes/common": "workspace:*",
|
"@standardnotes/common": "workspace:*",
|
||||||
"@standardnotes/domain-events": "workspace:*",
|
"@standardnotes/domain-events": "workspace:*",
|
||||||
"@standardnotes/domain-events-infra": "workspace:*",
|
"@standardnotes/domain-events-infra": "workspace:*",
|
||||||
|
|||||||
@@ -3,6 +3,14 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.10.3](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.10.2...@standardnotes/revisions-server@1.10.3) (2022-12-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/revisions-server
|
||||||
|
|
||||||
|
## [1.10.2](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.10.1...@standardnotes/revisions-server@1.10.2) (2022-12-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/revisions-server
|
||||||
|
|
||||||
## [1.10.1](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.10.0...@standardnotes/revisions-server@1.10.1) (2022-12-19)
|
## [1.10.1](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.10.0...@standardnotes/revisions-server@1.10.1) (2022-12-19)
|
||||||
|
|
||||||
**Note:** Version bump only for package @standardnotes/revisions-server
|
**Note:** Version bump only for package @standardnotes/revisions-server
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/revisions-server",
|
"name": "@standardnotes/revisions-server",
|
||||||
"version": "1.10.1",
|
"version": "1.10.3",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <19.0.0"
|
"node": ">=18.0.0 <19.0.0"
|
||||||
},
|
},
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@newrelic/winston-enricher": "^4.0.0",
|
"@newrelic/winston-enricher": "^4.0.0",
|
||||||
"@sentry/node": "^7.27.0",
|
"@sentry/node": "^7.28.1",
|
||||||
"@standardnotes/api": "^1.19.0",
|
"@standardnotes/api": "^1.19.0",
|
||||||
"@standardnotes/common": "workspace:^",
|
"@standardnotes/common": "workspace:^",
|
||||||
"@standardnotes/domain-core": "workspace:^",
|
"@standardnotes/domain-core": "workspace:^",
|
||||||
|
|||||||
@@ -3,6 +3,20 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.16.4](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.16.3...@standardnotes/scheduler-server@1.16.4) (2022-12-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||||
|
|
||||||
|
## [1.16.3](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.16.2...@standardnotes/scheduler-server@1.16.3) (2022-12-20)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **scheduler:** new pricing for subscription encouragement email ([eb21872](https://github.com/standardnotes/server/commit/eb21872db1726c4f8a55b5d16de712650c5e946b))
|
||||||
|
|
||||||
|
## [1.16.2](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.16.1...@standardnotes/scheduler-server@1.16.2) (2022-12-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||||
|
|
||||||
## [1.16.1](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.16.0...@standardnotes/scheduler-server@1.16.1) (2022-12-19)
|
## [1.16.1](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.16.0...@standardnotes/scheduler-server@1.16.1) (2022-12-19)
|
||||||
|
|
||||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/scheduler-server",
|
"name": "@standardnotes/scheduler-server",
|
||||||
"version": "1.16.1",
|
"version": "1.16.4",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <19.0.0"
|
"node": ">=18.0.0 <19.0.0"
|
||||||
},
|
},
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@newrelic/winston-enricher": "^4.0.0",
|
"@newrelic/winston-enricher": "^4.0.0",
|
||||||
"@sentry/node": "^7.27.0",
|
"@sentry/node": "^7.28.1",
|
||||||
"@standardnotes/common": "workspace:*",
|
"@standardnotes/common": "workspace:*",
|
||||||
"@standardnotes/domain-core": "workspace:^",
|
"@standardnotes/domain-core": "workspace:^",
|
||||||
"@standardnotes/domain-events": "workspace:*",
|
"@standardnotes/domain-events": "workspace:*",
|
||||||
|
|||||||
@@ -5,7 +5,5 @@ export function getSubject(): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getBody(registrationDate: string): string {
|
export function getBody(registrationDate: string): string {
|
||||||
const body = html
|
return html(registrationDate, 90, 120)
|
||||||
|
|
||||||
return body.replace('%%REGISTRATION_DATE%%', registrationDate)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export const html = `<div>
|
export const html = (registrationDate: string, annualPlusPrice: number, annualProPrice: number) => `<div>
|
||||||
<p>Hi there,</p>
|
<p>Hi there,</p>
|
||||||
<p>
|
<p>
|
||||||
We hope you've been finding great use out of Standard Notes. We built Standard Notes to be a secure place for
|
We hope you've been finding great use out of Standard Notes. We built Standard Notes to be a secure place for
|
||||||
@@ -7,7 +7,7 @@ export const html = `<div>
|
|||||||
<p>
|
<p>
|
||||||
As a reminder,
|
As a reminder,
|
||||||
<strong>
|
<strong>
|
||||||
<em>you signed up for the Standard Notes free plan on %%REGISTRATION_DATE%%</em>
|
<em>you signed up for the Standard Notes free plan on ${registrationDate}</em>
|
||||||
</strong>
|
</strong>
|
||||||
Your free account comes with standard features like end-to-end encryption, multiple-device sync, and
|
Your free account comes with standard features like end-to-end encryption, multiple-device sync, and
|
||||||
two-factor authentication.
|
two-factor authentication.
|
||||||
@@ -19,13 +19,13 @@ export const html = `<div>
|
|||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<p>
|
<p>
|
||||||
<strong>Productivity</strong> <strong>($59/year)</strong> powers up your editing experience with unique
|
<strong>Productivity</strong> <strong>($${annualPlusPrice}/year)</strong> powers up your editing experience with unique
|
||||||
and special-built note-types for markdown, rich text, spreadsheets, todo, and more.
|
and special-built note-types for markdown, rich text, spreadsheets, todo, and more.
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<p>
|
<p>
|
||||||
<strong>Professional</strong> <strong>($99/year)</strong> gives you all the power of Productivity plus
|
<strong>Professional</strong> <strong>($${annualProPrice}/year)</strong> gives you all the power of Productivity plus
|
||||||
100GB of end-to-end encrypted file storage for your private photos, videos, and documents, plus family
|
100GB of end-to-end encrypted file storage for your private photos, videos, and documents, plus family
|
||||||
subscription sharing with up to 5 people.
|
subscription sharing with up to 5 people.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -3,6 +3,14 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.28.3](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.28.2...@standardnotes/syncing-server@1.28.3) (2022-12-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/syncing-server
|
||||||
|
|
||||||
|
## [1.28.2](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.28.1...@standardnotes/syncing-server@1.28.2) (2022-12-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/syncing-server
|
||||||
|
|
||||||
## [1.28.1](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.28.0...@standardnotes/syncing-server@1.28.1) (2022-12-19)
|
## [1.28.1](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.28.0...@standardnotes/syncing-server@1.28.1) (2022-12-19)
|
||||||
|
|
||||||
**Note:** Version bump only for package @standardnotes/syncing-server
|
**Note:** Version bump only for package @standardnotes/syncing-server
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/syncing-server",
|
"name": "@standardnotes/syncing-server",
|
||||||
"version": "1.28.1",
|
"version": "1.28.3",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <19.0.0"
|
"node": ">=18.0.0 <19.0.0"
|
||||||
},
|
},
|
||||||
@@ -27,9 +27,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@newrelic/winston-enricher": "^4.0.0",
|
"@newrelic/winston-enricher": "^4.0.0",
|
||||||
"@sentry/node": "^7.27.0",
|
"@sentry/node": "^7.28.1",
|
||||||
"@sentry/profiling-node": "^0.0.12",
|
"@sentry/profiling-node": "^0.0.12",
|
||||||
"@sentry/tracing": "^7.27.0",
|
"@sentry/tracing": "^7.28.1",
|
||||||
"@standardnotes/common": "workspace:*",
|
"@standardnotes/common": "workspace:*",
|
||||||
"@standardnotes/domain-core": "workspace:^",
|
"@standardnotes/domain-core": "workspace:^",
|
||||||
"@standardnotes/domain-events": "workspace:*",
|
"@standardnotes/domain-events": "workspace:*",
|
||||||
|
|||||||
@@ -3,6 +3,14 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.5.3](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.5.2...@standardnotes/websockets-server@1.5.3) (2022-12-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/websockets-server
|
||||||
|
|
||||||
|
## [1.5.2](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.5.1...@standardnotes/websockets-server@1.5.2) (2022-12-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/websockets-server
|
||||||
|
|
||||||
## [1.5.1](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.5.0...@standardnotes/websockets-server@1.5.1) (2022-12-19)
|
## [1.5.1](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.5.0...@standardnotes/websockets-server@1.5.1) (2022-12-19)
|
||||||
|
|
||||||
**Note:** Version bump only for package @standardnotes/websockets-server
|
**Note:** Version bump only for package @standardnotes/websockets-server
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/websockets-server",
|
"name": "@standardnotes/websockets-server",
|
||||||
"version": "1.5.1",
|
"version": "1.5.3",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <19.0.0"
|
"node": ">=18.0.0 <19.0.0"
|
||||||
},
|
},
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@newrelic/winston-enricher": "^4.0.0",
|
"@newrelic/winston-enricher": "^4.0.0",
|
||||||
"@sentry/node": "^7.27.0",
|
"@sentry/node": "^7.28.1",
|
||||||
"@standardnotes/api": "^1.19.0",
|
"@standardnotes/api": "^1.19.0",
|
||||||
"@standardnotes/common": "workspace:^",
|
"@standardnotes/common": "workspace:^",
|
||||||
"@standardnotes/domain-events": "workspace:^",
|
"@standardnotes/domain-events": "workspace:^",
|
||||||
|
|||||||
@@ -3,6 +3,20 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.19.4](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.3...@standardnotes/workspace-server@1.19.4) (2022-12-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/workspace-server
|
||||||
|
|
||||||
|
## [1.19.3](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.2...@standardnotes/workspace-server@1.19.3) (2022-12-20)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **workspace:** specs ([c8203cf](https://github.com/standardnotes/server/commit/c8203cf04cb93cc65d30b69f10fb275f5e6be449))
|
||||||
|
|
||||||
|
## [1.19.2](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.1...@standardnotes/workspace-server@1.19.2) (2022-12-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @standardnotes/workspace-server
|
||||||
|
|
||||||
## [1.19.1](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.0...@standardnotes/workspace-server@1.19.1) (2022-12-19)
|
## [1.19.1](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.0...@standardnotes/workspace-server@1.19.1) (2022-12-19)
|
||||||
|
|
||||||
**Note:** Version bump only for package @standardnotes/workspace-server
|
**Note:** Version bump only for package @standardnotes/workspace-server
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@standardnotes/workspace-server",
|
"name": "@standardnotes/workspace-server",
|
||||||
"version": "1.19.1",
|
"version": "1.19.4",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0 <19.0.0"
|
"node": ">=18.0.0 <19.0.0"
|
||||||
},
|
},
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@newrelic/winston-enricher": "^4.0.0",
|
"@newrelic/winston-enricher": "^4.0.0",
|
||||||
"@sentry/node": "^7.27.0",
|
"@sentry/node": "^7.28.1",
|
||||||
"@standardnotes/api": "^1.19.0",
|
"@standardnotes/api": "^1.19.0",
|
||||||
"@standardnotes/common": "workspace:*",
|
"@standardnotes/common": "workspace:*",
|
||||||
"@standardnotes/domain-core": "workspace:^",
|
"@standardnotes/domain-core": "workspace:^",
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { WorkspaceInviteRepositoryInterface } from '../../Invite/WorkspaceInvite
|
|||||||
|
|
||||||
import { InviteToWorkspace } from './InviteToWorkspace'
|
import { InviteToWorkspace } from './InviteToWorkspace'
|
||||||
import { DomainEventFactoryInterface } from '../../Event/DomainEventFactoryInterface'
|
import { DomainEventFactoryInterface } from '../../Event/DomainEventFactoryInterface'
|
||||||
import { DomainEventPublisherInterface, WorkspaceInviteCreatedEvent } from '@standardnotes/domain-events'
|
import { DomainEventPublisherInterface, EmailRequestedEvent } from '@standardnotes/domain-events'
|
||||||
import { WorkspaceAccessLevel } from '@standardnotes/common'
|
import { WorkspaceAccessLevel } from '@standardnotes/common'
|
||||||
|
|
||||||
describe('InviteToWorkspace', () => {
|
describe('InviteToWorkspace', () => {
|
||||||
@@ -33,9 +33,7 @@ describe('InviteToWorkspace', () => {
|
|||||||
domainEventPublisher.publish = jest.fn()
|
domainEventPublisher.publish = jest.fn()
|
||||||
|
|
||||||
domainEventFactory = {} as jest.Mocked<DomainEventFactoryInterface>
|
domainEventFactory = {} as jest.Mocked<DomainEventFactoryInterface>
|
||||||
domainEventFactory.createWorkspaceInviteCreatedEvent = jest
|
domainEventFactory.createEmailRequestedEvent = jest.fn().mockReturnValue({} as jest.Mocked<EmailRequestedEvent>)
|
||||||
.fn()
|
|
||||||
.mockReturnValue({} as jest.Mocked<WorkspaceInviteCreatedEvent>)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should create an invite', async () => {
|
it('should create an invite', async () => {
|
||||||
|
|||||||
@@ -1717,6 +1717,17 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@sentry/core@npm:7.28.1":
|
||||||
|
version: 7.28.1
|
||||||
|
resolution: "@sentry/core@npm:7.28.1"
|
||||||
|
dependencies:
|
||||||
|
"@sentry/types": "npm:7.28.1"
|
||||||
|
"@sentry/utils": "npm:7.28.1"
|
||||||
|
tslib: "npm:^1.9.3"
|
||||||
|
checksum: f29d747d3e15000d8010fe3c192260a78927f37d30a3bb82cd533f3a5beca0c7fd81353ec57420c4295daea5384a045bde70ff6d3af1468ec1201b1d84131d6d
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@sentry/hub@npm:^7.16.0":
|
"@sentry/hub@npm:^7.16.0":
|
||||||
version: 7.27.0
|
version: 7.27.0
|
||||||
resolution: "@sentry/hub@npm:7.27.0"
|
resolution: "@sentry/hub@npm:7.27.0"
|
||||||
@@ -1729,7 +1740,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@sentry/node@npm:^7.16.0, @sentry/node@npm:^7.27.0":
|
"@sentry/node@npm:^7.16.0":
|
||||||
version: 7.27.0
|
version: 7.27.0
|
||||||
resolution: "@sentry/node@npm:7.27.0"
|
resolution: "@sentry/node@npm:7.27.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -1744,6 +1755,21 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@sentry/node@npm:^7.28.1":
|
||||||
|
version: 7.28.1
|
||||||
|
resolution: "@sentry/node@npm:7.28.1"
|
||||||
|
dependencies:
|
||||||
|
"@sentry/core": "npm:7.28.1"
|
||||||
|
"@sentry/types": "npm:7.28.1"
|
||||||
|
"@sentry/utils": "npm:7.28.1"
|
||||||
|
cookie: "npm:^0.4.1"
|
||||||
|
https-proxy-agent: "npm:^5.0.0"
|
||||||
|
lru_map: "npm:^0.3.3"
|
||||||
|
tslib: "npm:^1.9.3"
|
||||||
|
checksum: b4922d1f0a1b1e96cd73e5381871d0a2d20c4a05dd09f1cb9def6795c5fbe099b2e2b97025262cac595d19a42ebc82a34a8f9e59f87c0176e5206ae1f6377532
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@sentry/profiling-node@npm:^0.0.12":
|
"@sentry/profiling-node@npm:^0.0.12":
|
||||||
version: 0.0.12
|
version: 0.0.12
|
||||||
resolution: "@sentry/profiling-node@npm:0.0.12"
|
resolution: "@sentry/profiling-node@npm:0.0.12"
|
||||||
@@ -1760,7 +1786,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@sentry/tracing@npm:^7.16.0, @sentry/tracing@npm:^7.27.0":
|
"@sentry/tracing@npm:^7.16.0":
|
||||||
version: 7.27.0
|
version: 7.27.0
|
||||||
resolution: "@sentry/tracing@npm:7.27.0"
|
resolution: "@sentry/tracing@npm:7.27.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -1772,6 +1798,18 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@sentry/tracing@npm:^7.28.1":
|
||||||
|
version: 7.28.1
|
||||||
|
resolution: "@sentry/tracing@npm:7.28.1"
|
||||||
|
dependencies:
|
||||||
|
"@sentry/core": "npm:7.28.1"
|
||||||
|
"@sentry/types": "npm:7.28.1"
|
||||||
|
"@sentry/utils": "npm:7.28.1"
|
||||||
|
tslib: "npm:^1.9.3"
|
||||||
|
checksum: be501ca9d727f4893121c208f80fa82589964970c5a01155ba1d24cfd7ebdb2a1d6e325ea5556f0747d16519631013315781ad1c178f8721e5eab77de2446b63
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@sentry/types@npm:7.27.0, @sentry/types@npm:^7.16.0":
|
"@sentry/types@npm:7.27.0, @sentry/types@npm:^7.16.0":
|
||||||
version: 7.27.0
|
version: 7.27.0
|
||||||
resolution: "@sentry/types@npm:7.27.0"
|
resolution: "@sentry/types@npm:7.27.0"
|
||||||
@@ -1779,6 +1817,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@sentry/types@npm:7.28.1":
|
||||||
|
version: 7.28.1
|
||||||
|
resolution: "@sentry/types@npm:7.28.1"
|
||||||
|
checksum: 7dc6639cb7645c37bd8f759b60dbf2a149573b8a24dfb06baf7d7978f785e4635a65b3fb9e007f0eea56d33b543043fcfa1c1a376a83aa9824bb2d25be1a56dc
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@sentry/utils@npm:7.27.0, @sentry/utils@npm:^7.16.0":
|
"@sentry/utils@npm:7.27.0, @sentry/utils@npm:^7.16.0":
|
||||||
version: 7.27.0
|
version: 7.27.0
|
||||||
resolution: "@sentry/utils@npm:7.27.0"
|
resolution: "@sentry/utils@npm:7.27.0"
|
||||||
@@ -1789,6 +1834,16 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@sentry/utils@npm:7.28.1":
|
||||||
|
version: 7.28.1
|
||||||
|
resolution: "@sentry/utils@npm:7.28.1"
|
||||||
|
dependencies:
|
||||||
|
"@sentry/types": "npm:7.28.1"
|
||||||
|
tslib: "npm:^1.9.3"
|
||||||
|
checksum: a4b5f73db0e287e49b2eab5da80d6bbf1f6c7e11e1cc06ae06f49a9477d2b45de98310b143198207f3ae1fdd25ef76c90984eb99553a8308f6516e12c0c9c98c
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@sinclair/typebox@npm:^0.24.1":
|
"@sinclair/typebox@npm:^0.24.1":
|
||||||
version: 0.24.44
|
version: 0.24.44
|
||||||
resolution: "@sinclair/typebox@npm:0.24.44"
|
resolution: "@sinclair/typebox@npm:0.24.44"
|
||||||
@@ -1833,7 +1888,7 @@ __metadata:
|
|||||||
resolution: "@standardnotes/analytics@workspace:packages/analytics"
|
resolution: "@standardnotes/analytics@workspace:packages/analytics"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@newrelic/winston-enricher": "npm:^4.0.0"
|
"@newrelic/winston-enricher": "npm:^4.0.0"
|
||||||
"@sentry/node": "npm:^7.27.0"
|
"@sentry/node": "npm:^7.28.1"
|
||||||
"@standardnotes/common": "workspace:*"
|
"@standardnotes/common": "workspace:*"
|
||||||
"@standardnotes/domain-core": "workspace:^"
|
"@standardnotes/domain-core": "workspace:^"
|
||||||
"@standardnotes/domain-events": "workspace:*"
|
"@standardnotes/domain-events": "workspace:*"
|
||||||
@@ -1867,7 +1922,7 @@ __metadata:
|
|||||||
resolution: "@standardnotes/api-gateway@workspace:packages/api-gateway"
|
resolution: "@standardnotes/api-gateway@workspace:packages/api-gateway"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@newrelic/winston-enricher": "npm:^4.0.0"
|
"@newrelic/winston-enricher": "npm:^4.0.0"
|
||||||
"@sentry/node": "npm:^7.27.0"
|
"@sentry/node": "npm:^7.28.1"
|
||||||
"@standardnotes/common": "workspace:^"
|
"@standardnotes/common": "workspace:^"
|
||||||
"@standardnotes/domain-events": "workspace:*"
|
"@standardnotes/domain-events": "workspace:*"
|
||||||
"@standardnotes/domain-events-infra": "workspace:*"
|
"@standardnotes/domain-events-infra": "workspace:*"
|
||||||
@@ -1925,9 +1980,9 @@ __metadata:
|
|||||||
resolution: "@standardnotes/auth-server@workspace:packages/auth"
|
resolution: "@standardnotes/auth-server@workspace:packages/auth"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@newrelic/winston-enricher": "npm:^4.0.0"
|
"@newrelic/winston-enricher": "npm:^4.0.0"
|
||||||
"@sentry/node": "npm:^7.27.0"
|
"@sentry/node": "npm:^7.28.1"
|
||||||
"@sentry/profiling-node": "npm:^0.0.12"
|
"@sentry/profiling-node": "npm:^0.0.12"
|
||||||
"@sentry/tracing": "npm:^7.27.0"
|
"@sentry/tracing": "npm:^7.28.1"
|
||||||
"@standardnotes/api": "npm:^1.19.0"
|
"@standardnotes/api": "npm:^1.19.0"
|
||||||
"@standardnotes/common": "workspace:*"
|
"@standardnotes/common": "workspace:*"
|
||||||
"@standardnotes/domain-core": "workspace:^"
|
"@standardnotes/domain-core": "workspace:^"
|
||||||
@@ -2147,7 +2202,7 @@ __metadata:
|
|||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@standardnotes/files-server@workspace:packages/files"
|
resolution: "@standardnotes/files-server@workspace:packages/files"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@sentry/node": "npm:^7.27.0"
|
"@sentry/node": "npm:^7.28.1"
|
||||||
"@standardnotes/common": "workspace:*"
|
"@standardnotes/common": "workspace:*"
|
||||||
"@standardnotes/config": "npm:2.4.3"
|
"@standardnotes/config": "npm:2.4.3"
|
||||||
"@standardnotes/domain-events": "workspace:*"
|
"@standardnotes/domain-events": "workspace:*"
|
||||||
@@ -2277,7 +2332,7 @@ __metadata:
|
|||||||
resolution: "@standardnotes/revisions-server@workspace:packages/revisions"
|
resolution: "@standardnotes/revisions-server@workspace:packages/revisions"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@newrelic/winston-enricher": "npm:^4.0.0"
|
"@newrelic/winston-enricher": "npm:^4.0.0"
|
||||||
"@sentry/node": "npm:^7.27.0"
|
"@sentry/node": "npm:^7.28.1"
|
||||||
"@standardnotes/api": "npm:^1.19.0"
|
"@standardnotes/api": "npm:^1.19.0"
|
||||||
"@standardnotes/common": "workspace:^"
|
"@standardnotes/common": "workspace:^"
|
||||||
"@standardnotes/domain-core": "workspace:^"
|
"@standardnotes/domain-core": "workspace:^"
|
||||||
@@ -2320,7 +2375,7 @@ __metadata:
|
|||||||
resolution: "@standardnotes/scheduler-server@workspace:packages/scheduler"
|
resolution: "@standardnotes/scheduler-server@workspace:packages/scheduler"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@newrelic/winston-enricher": "npm:^4.0.0"
|
"@newrelic/winston-enricher": "npm:^4.0.0"
|
||||||
"@sentry/node": "npm:^7.27.0"
|
"@sentry/node": "npm:^7.28.1"
|
||||||
"@standardnotes/common": "workspace:*"
|
"@standardnotes/common": "workspace:*"
|
||||||
"@standardnotes/domain-core": "workspace:^"
|
"@standardnotes/domain-core": "workspace:^"
|
||||||
"@standardnotes/domain-events": "workspace:*"
|
"@standardnotes/domain-events": "workspace:*"
|
||||||
@@ -2377,7 +2432,7 @@ __metadata:
|
|||||||
"@lerna-lite/cli": "npm:^1.5.1"
|
"@lerna-lite/cli": "npm:^1.5.1"
|
||||||
"@lerna-lite/list": "npm:^1.5.1"
|
"@lerna-lite/list": "npm:^1.5.1"
|
||||||
"@lerna-lite/run": "npm:^1.5.1"
|
"@lerna-lite/run": "npm:^1.5.1"
|
||||||
"@sentry/node": "npm:^7.27.0"
|
"@sentry/node": "npm:^7.28.1"
|
||||||
"@types/jest": "npm:^29.1.1"
|
"@types/jest": "npm:^29.1.1"
|
||||||
"@types/newrelic": "npm:^7.0.4"
|
"@types/newrelic": "npm:^7.0.4"
|
||||||
"@types/node": "npm:^18.11.9"
|
"@types/node": "npm:^18.11.9"
|
||||||
@@ -2436,9 +2491,9 @@ __metadata:
|
|||||||
resolution: "@standardnotes/syncing-server@workspace:packages/syncing-server"
|
resolution: "@standardnotes/syncing-server@workspace:packages/syncing-server"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@newrelic/winston-enricher": "npm:^4.0.0"
|
"@newrelic/winston-enricher": "npm:^4.0.0"
|
||||||
"@sentry/node": "npm:^7.27.0"
|
"@sentry/node": "npm:^7.28.1"
|
||||||
"@sentry/profiling-node": "npm:^0.0.12"
|
"@sentry/profiling-node": "npm:^0.0.12"
|
||||||
"@sentry/tracing": "npm:^7.27.0"
|
"@sentry/tracing": "npm:^7.28.1"
|
||||||
"@standardnotes/common": "workspace:*"
|
"@standardnotes/common": "workspace:*"
|
||||||
"@standardnotes/domain-core": "workspace:^"
|
"@standardnotes/domain-core": "workspace:^"
|
||||||
"@standardnotes/domain-events": "workspace:*"
|
"@standardnotes/domain-events": "workspace:*"
|
||||||
@@ -2534,7 +2589,7 @@ __metadata:
|
|||||||
resolution: "@standardnotes/websockets-server@workspace:packages/websockets"
|
resolution: "@standardnotes/websockets-server@workspace:packages/websockets"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@newrelic/winston-enricher": "npm:^4.0.0"
|
"@newrelic/winston-enricher": "npm:^4.0.0"
|
||||||
"@sentry/node": "npm:^7.27.0"
|
"@sentry/node": "npm:^7.28.1"
|
||||||
"@standardnotes/api": "npm:^1.19.0"
|
"@standardnotes/api": "npm:^1.19.0"
|
||||||
"@standardnotes/common": "workspace:^"
|
"@standardnotes/common": "workspace:^"
|
||||||
"@standardnotes/domain-events": "workspace:^"
|
"@standardnotes/domain-events": "workspace:^"
|
||||||
@@ -2572,7 +2627,7 @@ __metadata:
|
|||||||
resolution: "@standardnotes/workspace-server@workspace:packages/workspace"
|
resolution: "@standardnotes/workspace-server@workspace:packages/workspace"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@newrelic/winston-enricher": "npm:^4.0.0"
|
"@newrelic/winston-enricher": "npm:^4.0.0"
|
||||||
"@sentry/node": "npm:^7.27.0"
|
"@sentry/node": "npm:^7.28.1"
|
||||||
"@standardnotes/api": "npm:^1.19.0"
|
"@standardnotes/api": "npm:^1.19.0"
|
||||||
"@standardnotes/common": "workspace:*"
|
"@standardnotes/common": "workspace:*"
|
||||||
"@standardnotes/domain-core": "workspace:^"
|
"@standardnotes/domain-core": "workspace:^"
|
||||||
|
|||||||
Reference in New Issue
Block a user