mirror of
https://github.com/standardnotes/server
synced 2026-01-28 11:02:23 -05:00
Compare commits
42 Commits
@standardn
...
@standardn
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78ab4dc94d | ||
|
|
6a5904cfaa | ||
|
|
a6061ec2a9 | ||
|
|
51c777304b | ||
|
|
fbd535f2c5 | ||
|
|
7d456671c2 | ||
|
|
dd4924c925 | ||
|
|
f73129cd7e | ||
|
|
4983c8741e | ||
|
|
c5798640ff | ||
|
|
5803a8018a | ||
|
|
e2aae8ac8a | ||
|
|
2917aeeb32 | ||
|
|
9377c03c3f | ||
|
|
9b926fbad6 | ||
|
|
8db19c3e2b | ||
|
|
ca970781c7 | ||
|
|
e7beee2788 | ||
|
|
d266eada88 | ||
|
|
11b8b078b4 | ||
|
|
37912fa29a | ||
|
|
b97dafe6f3 | ||
|
|
2a29151395 | ||
|
|
8b988d89c0 | ||
|
|
c0908f1b58 | ||
|
|
bb46044f7c | ||
|
|
60b3dd6138 | ||
|
|
22c1f936c3 | ||
|
|
e899874b04 | ||
|
|
04c6888cf6 | ||
|
|
29c56c6919 | ||
|
|
c98ed9cc85 | ||
|
|
88f7530c13 | ||
|
|
bb820437af | ||
|
|
d1a4bd38e0 | ||
|
|
d18f6ccd32 | ||
|
|
aa317c964e | ||
|
|
7ae8845ae9 | ||
|
|
123a6dbe0c | ||
|
|
dda8d79526 | ||
|
|
de5293955a | ||
|
|
96669bff5b |
9
.github/workflows/analytics.yml
vendored
9
.github/workflows/analytics.yml
vendored
@@ -11,19 +11,18 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
call_server_application_workflow:
|
||||
name: Server Application
|
||||
uses: standardnotes/server/.github/workflows/common-server-application.yml@main
|
||||
call_server_utility_workflow:
|
||||
name: Server Utility
|
||||
uses: standardnotes/server/.github/workflows/common-server-utility.yml@main
|
||||
with:
|
||||
service_name: analytics
|
||||
workspace_name: "@standardnotes/analytics"
|
||||
e2e_tag_parameter_name: analytics_image_tag
|
||||
deploy_web: false
|
||||
package_path: packages/analytics
|
||||
secrets: inherit
|
||||
|
||||
newrelic:
|
||||
needs: call_server_application_workflow
|
||||
needs: call_server_utility_workflow
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
|
||||
164
.github/workflows/common-server-utility.yml
vendored
Normal file
164
.github/workflows/common-server-utility.yml
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
name: Reusable Server Utility Workflow
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
service_name:
|
||||
required: true
|
||||
type: string
|
||||
workspace_name:
|
||||
required: true
|
||||
type: string
|
||||
deploy_web:
|
||||
required: false
|
||||
default: true
|
||||
type: boolean
|
||||
deploy_worker:
|
||||
required: false
|
||||
default: true
|
||||
type: boolean
|
||||
package_path:
|
||||
required: true
|
||||
type: string
|
||||
secrets:
|
||||
DOCKER_USERNAME:
|
||||
required: true
|
||||
DOCKER_PASSWORD:
|
||||
required: true
|
||||
CI_PAT_TOKEN:
|
||||
required: true
|
||||
AWS_ACCESS_KEY_ID:
|
||||
required: true
|
||||
AWS_SECRET_ACCESS_KEY:
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
outputs:
|
||||
temp_dir: ${{ steps.bundle-dir.outputs.temp_dir }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Create Bundle Dir
|
||||
id: bundle-dir
|
||||
run: echo "temp_dir=$(mktemp -d -t ${{ inputs.service_name }}-${{ github.sha }}-XXXXXXX)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Cache build
|
||||
id: cache-build
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
packages/**/dist
|
||||
${{ steps.bundle-dir.outputs.temp_dir }}
|
||||
key: ${{ runner.os }}-${{ inputs.service_name }}-build-${{ github.sha }}
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
node-version-file: '.nvmrc'
|
||||
|
||||
- name: Build
|
||||
run: yarn build ${{ inputs.package_path }}
|
||||
|
||||
- name: Bundle
|
||||
run: yarn workspace ${{ inputs.workspace_name }} bundle --no-compress --output-directory ${{ steps.bundle-dir.outputs.temp_dir }}
|
||||
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
needs: build
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Cache build
|
||||
id: cache-build
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
packages/**/dist
|
||||
${{ needs.build.outputs.temp_dir }}
|
||||
key: ${{ runner.os }}-${{ inputs.service_name }}-build-${{ github.sha }}
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
node-version-file: '.nvmrc'
|
||||
|
||||
- name: Build
|
||||
if: steps.cache-build.outputs.cache-hit != 'true'
|
||||
run: yarn build ${{ inputs.package_path }}
|
||||
|
||||
- name: Lint
|
||||
run: yarn lint:${{ inputs.service_name }}
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
needs: build
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Cache build
|
||||
id: cache-build
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
packages/**/dist
|
||||
${{ needs.build.outputs.temp_dir }}
|
||||
key: ${{ runner.os }}-${{ inputs.service_name }}-build-${{ github.sha }}
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
node-version-file: '.nvmrc'
|
||||
|
||||
- name: Build
|
||||
if: steps.cache-build.outputs.cache-hit != 'true'
|
||||
run: yarn build ${{ inputs.package_path }}
|
||||
|
||||
- name: Test
|
||||
run: yarn test ${{ inputs.package_path }}
|
||||
|
||||
publish:
|
||||
needs: [ build, test, lint ]
|
||||
|
||||
name: Publish Docker Image
|
||||
uses: standardnotes/server/.github/workflows/common-docker-image.yml@main
|
||||
with:
|
||||
service_name: ${{ inputs.service_name }}
|
||||
bundle_dir: ${{ needs.build.outputs.temp_dir }}
|
||||
package_path: ${{ inputs.package_path }}
|
||||
workspace_name: ${{ inputs.workspace_name }}
|
||||
secrets: inherit
|
||||
|
||||
deploy-web:
|
||||
if: ${{ inputs.deploy_web }}
|
||||
|
||||
needs: publish
|
||||
|
||||
name: Deploy Web
|
||||
uses: standardnotes/server/.github/workflows/common-deploy.yml@main
|
||||
with:
|
||||
service_name: ${{ inputs.service_name }}
|
||||
docker_image: ${{ inputs.service_name }}:${{ github.sha }}
|
||||
secrets: inherit
|
||||
|
||||
deploy-worker:
|
||||
if: ${{ inputs.deploy_worker }}
|
||||
|
||||
needs: publish
|
||||
|
||||
name: Deploy Worker
|
||||
uses: standardnotes/server/.github/workflows/common-deploy.yml@main
|
||||
with:
|
||||
service_name: ${{ inputs.service_name }}-worker
|
||||
docker_image: ${{ inputs.service_name }}:${{ github.sha }}
|
||||
secrets: inherit
|
||||
9
.github/workflows/event-store.yml
vendored
9
.github/workflows/event-store.yml
vendored
@@ -11,19 +11,18 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
call_server_application_workflow:
|
||||
name: Server Application
|
||||
uses: standardnotes/server/.github/workflows/common-server-application.yml@main
|
||||
call_server_utility_workflow:
|
||||
name: Server Utility
|
||||
uses: standardnotes/server/.github/workflows/common-server-utility.yml@main
|
||||
with:
|
||||
service_name: event-store
|
||||
workspace_name: "@standardnotes/event-store"
|
||||
e2e_tag_parameter_name: event_store_image_tag
|
||||
deploy_web: false
|
||||
package_path: packages/event-store
|
||||
secrets: inherit
|
||||
|
||||
newrelic:
|
||||
needs: call_server_application_workflow
|
||||
needs: call_server_utility_workflow
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
|
||||
9
.github/workflows/scheduler.yml
vendored
9
.github/workflows/scheduler.yml
vendored
@@ -11,19 +11,18 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
call_server_application_workflow:
|
||||
name: Server Application
|
||||
uses: standardnotes/server/.github/workflows/common-server-application.yml@main
|
||||
call_server_utility_workflow:
|
||||
name: Server Utility
|
||||
uses: standardnotes/server/.github/workflows/common-server-utility.yml@main
|
||||
with:
|
||||
service_name: scheduler
|
||||
workspace_name: "@standardnotes/scheduler-server"
|
||||
e2e_tag_parameter_name: scheduler_image_tag
|
||||
deploy_web: false
|
||||
package_path: packages/scheduler
|
||||
secrets: inherit
|
||||
|
||||
newrelic:
|
||||
needs: call_server_application_workflow
|
||||
needs: call_server_utility_workflow
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
|
||||
9
.github/workflows/websockets.yml
vendored
9
.github/workflows/websockets.yml
vendored
@@ -11,18 +11,17 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
call_server_application_workflow:
|
||||
name: Server Application
|
||||
uses: standardnotes/server/.github/workflows/common-server-application.yml@main
|
||||
call_server_utility_workflow:
|
||||
name: Server Utility
|
||||
uses: standardnotes/server/.github/workflows/common-server-utility.yml@main
|
||||
with:
|
||||
service_name: websockets
|
||||
workspace_name: "@standardnotes/websockets-server"
|
||||
e2e_tag_parameter_name: websockets_image_tag
|
||||
package_path: packages/websockets
|
||||
secrets: inherit
|
||||
|
||||
newrelic:
|
||||
needs: call_server_application_workflow
|
||||
needs: call_server_utility_workflow
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
9
.github/workflows/workspace.yml
vendored
9
.github/workflows/workspace.yml
vendored
@@ -11,18 +11,17 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
call_server_application_workflow:
|
||||
name: Server Application
|
||||
uses: standardnotes/server/.github/workflows/common-server-application.yml@main
|
||||
call_server_utility_workflow:
|
||||
name: Server Utility
|
||||
uses: standardnotes/server/.github/workflows/common-server-utility.yml@main
|
||||
with:
|
||||
service_name: workspace
|
||||
workspace_name: "@standardnotes/workspace-server"
|
||||
e2e_tag_parameter_name: workspace_image_tag
|
||||
package_path: packages/workspace
|
||||
secrets: inherit
|
||||
|
||||
newrelic:
|
||||
needs: call_server_application_workflow
|
||||
needs: call_server_utility_workflow
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
142
.pnp.cjs
generated
142
.pnp.cjs
generated
@@ -2647,7 +2647,7 @@ const RAW_RUNTIME_STATE =
|
||||
["ioredis", "npm:5.2.4"],\
|
||||
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
|
||||
["mixpanel", "npm:0.17.0"],\
|
||||
["mysql2", "npm:2.3.3"],\
|
||||
["mysql2", "npm:3.0.1"],\
|
||||
["newrelic", "npm:9.6.0"],\
|
||||
["reflect-metadata", "npm:0.1.13"],\
|
||||
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\
|
||||
@@ -2690,7 +2690,7 @@ const RAW_RUNTIME_STATE =
|
||||
["@types/express", "npm:4.17.14"],\
|
||||
["@types/ioredis", "npm:5.0.0"],\
|
||||
["@types/jest", "npm:29.1.1"],\
|
||||
["@types/jsonwebtoken", "npm:8.5.9"],\
|
||||
["@types/jsonwebtoken", "npm:9.0.1"],\
|
||||
["@types/newrelic", "npm:7.0.4"],\
|
||||
["@types/prettyjson", "npm:0.0.30"],\
|
||||
["@typescript-eslint/eslint-plugin", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:5.40.1"],\
|
||||
@@ -2701,12 +2701,13 @@ const RAW_RUNTIME_STATE =
|
||||
["eslint", "npm:8.25.0"],\
|
||||
["eslint-plugin-prettier", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.2.1"],\
|
||||
["express", "npm:4.18.2"],\
|
||||
["express-robots-txt", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:1.0.0"],\
|
||||
["helmet", "npm:6.0.0"],\
|
||||
["inversify", "npm:6.0.1"],\
|
||||
["inversify-express-utils", "npm:6.4.3"],\
|
||||
["ioredis", "npm:5.2.4"],\
|
||||
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
|
||||
["jsonwebtoken", "npm:8.5.1"],\
|
||||
["jsonwebtoken", "npm:9.0.0"],\
|
||||
["newrelic", "npm:9.6.0"],\
|
||||
["nodemon", "npm:2.0.20"],\
|
||||
["npm-check-updates", "npm:16.0.1"],\
|
||||
@@ -2777,7 +2778,7 @@ const RAW_RUNTIME_STATE =
|
||||
["inversify-express-utils", "npm:6.4.3"],\
|
||||
["ioredis", "npm:5.2.4"],\
|
||||
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
|
||||
["mysql2", "npm:2.3.3"],\
|
||||
["mysql2", "npm:3.0.1"],\
|
||||
["newrelic", "npm:9.6.0"],\
|
||||
["nodemon", "npm:2.0.20"],\
|
||||
["npm-check-updates", "npm:16.0.1"],\
|
||||
@@ -2923,7 +2924,7 @@ const RAW_RUNTIME_STATE =
|
||||
["inversify", "npm:6.0.1"],\
|
||||
["ioredis", "npm:5.2.4"],\
|
||||
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
|
||||
["mysql2", "npm:2.3.3"],\
|
||||
["mysql2", "npm:3.0.1"],\
|
||||
["newrelic", "npm:9.6.0"],\
|
||||
["reflect-metadata", "npm:0.1.13"],\
|
||||
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\
|
||||
@@ -2977,7 +2978,7 @@ const RAW_RUNTIME_STATE =
|
||||
["@types/express", "npm:4.17.14"],\
|
||||
["@types/ioredis", "npm:5.0.0"],\
|
||||
["@types/jest", "npm:29.1.1"],\
|
||||
["@types/jsonwebtoken", "npm:8.5.9"],\
|
||||
["@types/jsonwebtoken", "npm:9.0.1"],\
|
||||
["@types/newrelic", "npm:7.0.4"],\
|
||||
["@types/prettyjson", "npm:0.0.30"],\
|
||||
["@types/uuid", "npm:8.3.4"],\
|
||||
@@ -2990,13 +2991,14 @@ const RAW_RUNTIME_STATE =
|
||||
["eslint", "npm:8.25.0"],\
|
||||
["eslint-plugin-prettier", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.2.1"],\
|
||||
["express", "npm:4.18.2"],\
|
||||
["express-robots-txt", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:1.0.0"],\
|
||||
["express-winston", "virtual:b442cf0427cc365d1c137f7340f9b81f9b204561afe791a8564ae9590c3a7fc4b5f793aaf8817b946f75a3cb64d03ef8790eb847f8b576b41e700da7b00c240c#npm:4.2.0"],\
|
||||
["helmet", "npm:6.0.0"],\
|
||||
["inversify", "npm:6.0.1"],\
|
||||
["inversify-express-utils", "npm:6.4.3"],\
|
||||
["ioredis", "npm:5.2.4"],\
|
||||
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
|
||||
["jsonwebtoken", "npm:8.5.1"],\
|
||||
["jsonwebtoken", "npm:9.0.0"],\
|
||||
["newrelic", "npm:9.6.0"],\
|
||||
["nodemon", "npm:2.0.20"],\
|
||||
["npm-check-updates", "npm:16.0.1"],\
|
||||
@@ -3125,7 +3127,7 @@ const RAW_RUNTIME_STATE =
|
||||
["inversify-express-utils", "npm:6.4.3"],\
|
||||
["ioredis", "npm:5.2.4"],\
|
||||
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
|
||||
["mysql2", "npm:2.3.3"],\
|
||||
["mysql2", "npm:3.0.1"],\
|
||||
["newrelic", "npm:9.6.0"],\
|
||||
["npm-check-updates", "npm:16.0.1"],\
|
||||
["reflect-metadata", "npm:0.1.13"],\
|
||||
@@ -3163,7 +3165,7 @@ const RAW_RUNTIME_STATE =
|
||||
["inversify", "npm:6.0.1"],\
|
||||
["ioredis", "npm:5.2.4"],\
|
||||
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
|
||||
["mysql2", "npm:2.3.3"],\
|
||||
["mysql2", "npm:3.0.1"],\
|
||||
["newrelic", "npm:9.6.0"],\
|
||||
["npm-check-updates", "npm:16.0.1"],\
|
||||
["reflect-metadata", "npm:0.1.13"],\
|
||||
@@ -3182,11 +3184,11 @@ const RAW_RUNTIME_STATE =
|
||||
["@standardnotes/security", "workspace:packages/security"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["@types/jest", "npm:29.1.1"],\
|
||||
["@types/jsonwebtoken", "npm:8.5.9"],\
|
||||
["@types/jsonwebtoken", "npm:9.0.1"],\
|
||||
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.30.5"],\
|
||||
["eslint-plugin-prettier", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:4.2.1"],\
|
||||
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
|
||||
["jsonwebtoken", "npm:8.5.1"],\
|
||||
["jsonwebtoken", "npm:9.0.0"],\
|
||||
["reflect-metadata", "npm:0.1.13"],\
|
||||
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\
|
||||
["typescript", "patch:typescript@npm%3A4.8.4#optional!builtin<compat/typescript>::version=4.8.4&hash=701156"]\
|
||||
@@ -3287,7 +3289,7 @@ const RAW_RUNTIME_STATE =
|
||||
["@types/inversify-express-utils", "npm:2.0.0"],\
|
||||
["@types/ioredis", "npm:5.0.0"],\
|
||||
["@types/jest", "npm:29.1.1"],\
|
||||
["@types/jsonwebtoken", "npm:8.5.9"],\
|
||||
["@types/jsonwebtoken", "npm:9.0.1"],\
|
||||
["@types/newrelic", "npm:7.0.4"],\
|
||||
["@types/prettyjson", "npm:0.0.30"],\
|
||||
["@types/ua-parser-js", "npm:0.7.36"],\
|
||||
@@ -3305,8 +3307,8 @@ const RAW_RUNTIME_STATE =
|
||||
["inversify-express-utils", "npm:6.4.3"],\
|
||||
["ioredis", "npm:5.2.4"],\
|
||||
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
|
||||
["jsonwebtoken", "npm:8.5.1"],\
|
||||
["mysql2", "npm:2.3.3"],\
|
||||
["jsonwebtoken", "npm:9.0.0"],\
|
||||
["mysql2", "npm:3.0.1"],\
|
||||
["newrelic", "npm:9.6.0"],\
|
||||
["nodemon", "npm:2.0.20"],\
|
||||
["npm-check-updates", "npm:16.0.1"],\
|
||||
@@ -3394,7 +3396,7 @@ const RAW_RUNTIME_STATE =
|
||||
["inversify-express-utils", "npm:6.4.3"],\
|
||||
["ioredis", "npm:5.2.4"],\
|
||||
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
|
||||
["mysql2", "npm:2.3.3"],\
|
||||
["mysql2", "npm:3.0.1"],\
|
||||
["newrelic", "npm:9.6.0"],\
|
||||
["reflect-metadata", "npm:0.1.13"],\
|
||||
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\
|
||||
@@ -3436,7 +3438,7 @@ const RAW_RUNTIME_STATE =
|
||||
["inversify-express-utils", "npm:6.4.3"],\
|
||||
["ioredis", "npm:5.2.4"],\
|
||||
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
|
||||
["mysql2", "npm:2.3.3"],\
|
||||
["mysql2", "npm:3.0.1"],\
|
||||
["newrelic", "npm:9.6.0"],\
|
||||
["reflect-metadata", "npm:0.1.13"],\
|
||||
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\
|
||||
@@ -3754,10 +3756,10 @@ const RAW_RUNTIME_STATE =
|
||||
}]\
|
||||
]],\
|
||||
["@types/jsonwebtoken", [\
|
||||
["npm:8.5.9", {\
|
||||
"packageLocation": "./.yarn/cache/@types-jsonwebtoken-npm-8.5.9-79c2843a81-3f15a76cd5.zip/node_modules/@types/jsonwebtoken/",\
|
||||
["npm:9.0.1", {\
|
||||
"packageLocation": "./.yarn/cache/@types-jsonwebtoken-npm-9.0.1-5f660fdf38-44d3fccc6b.zip/node_modules/@types/jsonwebtoken/",\
|
||||
"packageDependencies": [\
|
||||
["@types/jsonwebtoken", "npm:8.5.9"],\
|
||||
["@types/jsonwebtoken", "npm:9.0.1"],\
|
||||
["@types/node", "npm:18.0.3"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
@@ -7316,6 +7318,28 @@ const RAW_RUNTIME_STATE =
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["express-robots-txt", [\
|
||||
["npm:1.0.0", {\
|
||||
"packageLocation": "./.yarn/cache/express-robots-txt-npm-1.0.0-dcc8bd8f0a-54f066f6c3.zip/node_modules/express-robots-txt/",\
|
||||
"packageDependencies": [\
|
||||
["express-robots-txt", "npm:1.0.0"]\
|
||||
],\
|
||||
"linkType": "SOFT"\
|
||||
}],\
|
||||
["virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:1.0.0", {\
|
||||
"packageLocation": "./.yarn/__virtual__/express-robots-txt-virtual-0a3eb9f2f5/0/cache/express-robots-txt-npm-1.0.0-dcc8bd8f0a-54f066f6c3.zip/node_modules/express-robots-txt/",\
|
||||
"packageDependencies": [\
|
||||
["express-robots-txt", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:1.0.0"],\
|
||||
["@types/express", "npm:4.17.14"],\
|
||||
["express", "npm:4.18.2"]\
|
||||
],\
|
||||
"packagePeers": [\
|
||||
"@types/express",\
|
||||
"express"\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["express-winston", [\
|
||||
["npm:4.2.0", {\
|
||||
"packageLocation": "./.yarn/cache/express-winston-npm-4.2.0-e4cfb26486-2d4b37671d.zip/node_modules/express-winston/",\
|
||||
@@ -9783,6 +9807,17 @@ const RAW_RUNTIME_STATE =
|
||||
["semver", "npm:5.7.1"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}],\
|
||||
["npm:9.0.0", {\
|
||||
"packageLocation": "./.yarn/cache/jsonwebtoken-npm-9.0.0-36fd1594c0-7ccbd0b7bf.zip/node_modules/jsonwebtoken/",\
|
||||
"packageDependencies": [\
|
||||
["jsonwebtoken", "npm:9.0.0"],\
|
||||
["jws", "npm:3.2.2"],\
|
||||
["lodash", "npm:4.17.21"],\
|
||||
["ms", "npm:2.1.3"],\
|
||||
["semver", "npm:7.3.8"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["jsrsasign", [\
|
||||
@@ -10149,6 +10184,13 @@ const RAW_RUNTIME_STATE =
|
||||
["long", "npm:4.0.0"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}],\
|
||||
["npm:5.2.1", {\
|
||||
"packageLocation": "./.yarn/cache/long-npm-5.2.1-3a12730171-f81b18ff29.zip/node_modules/long/",\
|
||||
"packageDependencies": [\
|
||||
["long", "npm:5.2.1"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["lowercase-keys", [\
|
||||
@@ -10168,15 +10210,6 @@ const RAW_RUNTIME_STATE =
|
||||
}]\
|
||||
]],\
|
||||
["lru-cache", [\
|
||||
["npm:4.1.5", {\
|
||||
"packageLocation": "./.yarn/cache/lru-cache-npm-4.1.5-ede304cc43-796f26ad92.zip/node_modules/lru-cache/",\
|
||||
"packageDependencies": [\
|
||||
["lru-cache", "npm:4.1.5"],\
|
||||
["pseudomap", "npm:1.0.2"],\
|
||||
["yallist", "npm:2.1.2"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}],\
|
||||
["npm:6.0.0", {\
|
||||
"packageLocation": "./.yarn/cache/lru-cache-npm-6.0.0-b4c8668fe1-b2d72088dd.zip/node_modules/lru-cache/",\
|
||||
"packageDependencies": [\
|
||||
@@ -10191,6 +10224,13 @@ const RAW_RUNTIME_STATE =
|
||||
["lru-cache", "npm:7.12.0"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}],\
|
||||
["npm:7.14.1", {\
|
||||
"packageLocation": "./.yarn/cache/lru-cache-npm-7.14.1-d3ba9407b6-e4c8c073d9.zip/node_modules/lru-cache/",\
|
||||
"packageDependencies": [\
|
||||
["lru-cache", "npm:7.14.1"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["lru_map", [\
|
||||
@@ -10648,16 +10688,16 @@ const RAW_RUNTIME_STATE =
|
||||
}]\
|
||||
]],\
|
||||
["mysql2", [\
|
||||
["npm:2.3.3", {\
|
||||
"packageLocation": "./.yarn/cache/mysql2-npm-2.3.3-fa543fff43-dda663a631.zip/node_modules/mysql2/",\
|
||||
["npm:3.0.1", {\
|
||||
"packageLocation": "./.yarn/cache/mysql2-npm-3.0.1-ceda50bb4d-6bbee1ee05.zip/node_modules/mysql2/",\
|
||||
"packageDependencies": [\
|
||||
["mysql2", "npm:2.3.3"],\
|
||||
["mysql2", "npm:3.0.1"],\
|
||||
["denque", "npm:2.1.0"],\
|
||||
["generate-function", "npm:2.3.1"],\
|
||||
["iconv-lite", "npm:0.6.3"],\
|
||||
["long", "npm:4.0.0"],\
|
||||
["lru-cache", "npm:6.0.0"],\
|
||||
["named-placeholders", "npm:1.1.2"],\
|
||||
["long", "npm:5.2.1"],\
|
||||
["lru-cache", "npm:7.14.1"],\
|
||||
["named-placeholders", "npm:1.1.3"],\
|
||||
["seq-queue", "npm:0.0.5"],\
|
||||
["sqlstring", "npm:2.3.3"]\
|
||||
],\
|
||||
@@ -10677,11 +10717,11 @@ const RAW_RUNTIME_STATE =
|
||||
}]\
|
||||
]],\
|
||||
["named-placeholders", [\
|
||||
["npm:1.1.2", {\
|
||||
"packageLocation": "./.yarn/cache/named-placeholders-npm-1.1.2-5d4cbc92b0-24477df960.zip/node_modules/named-placeholders/",\
|
||||
["npm:1.1.3", {\
|
||||
"packageLocation": "./.yarn/cache/named-placeholders-npm-1.1.3-1b385febe5-1cd77eb10c.zip/node_modules/named-placeholders/",\
|
||||
"packageDependencies": [\
|
||||
["named-placeholders", "npm:1.1.2"],\
|
||||
["lru-cache", "npm:4.1.5"]\
|
||||
["named-placeholders", "npm:1.1.3"],\
|
||||
["lru-cache", "npm:7.14.1"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
@@ -11845,15 +11885,6 @@ const RAW_RUNTIME_STATE =
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["pseudomap", [\
|
||||
["npm:1.0.2", {\
|
||||
"packageLocation": "./.yarn/cache/pseudomap-npm-1.0.2-0d0e40fee0-33cfbb99ac.zip/node_modules/pseudomap/",\
|
||||
"packageDependencies": [\
|
||||
["pseudomap", "npm:1.0.2"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["pstree.remy", [\
|
||||
["npm:1.1.8", {\
|
||||
"packageLocation": "./.yarn/cache/pstree.remy-npm-1.1.8-2dd5d55de2-f144e436fd.zip/node_modules/pstree.remy/",\
|
||||
@@ -12497,6 +12528,14 @@ const RAW_RUNTIME_STATE =
|
||||
["lru-cache", "npm:6.0.0"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}],\
|
||||
["npm:7.3.8", {\
|
||||
"packageLocation": "./.yarn/cache/semver-npm-7.3.8-25a996cb4f-94ad80ee14.zip/node_modules/semver/",\
|
||||
"packageDependencies": [\
|
||||
["semver", "npm:7.3.8"],\
|
||||
["lru-cache", "npm:6.0.0"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["semver-diff", [\
|
||||
@@ -13803,7 +13842,7 @@ const RAW_RUNTIME_STATE =
|
||||
["mkdirp", "npm:1.0.4"],\
|
||||
["mongodb", null],\
|
||||
["mssql", null],\
|
||||
["mysql2", "npm:2.3.3"],\
|
||||
["mysql2", "npm:3.0.1"],\
|
||||
["oracledb", null],\
|
||||
["pg", null],\
|
||||
["pg-native", null],\
|
||||
@@ -14504,13 +14543,6 @@ const RAW_RUNTIME_STATE =
|
||||
}]\
|
||||
]],\
|
||||
["yallist", [\
|
||||
["npm:2.1.2", {\
|
||||
"packageLocation": "./.yarn/cache/yallist-npm-2.1.2-2e38c366a3-f3ace13bed.zip/node_modules/yallist/",\
|
||||
"packageDependencies": [\
|
||||
["yallist", "npm:2.1.2"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}],\
|
||||
["npm:4.0.0", {\
|
||||
"packageLocation": "./.yarn/cache/yallist-npm-4.0.0-b493d9e907-cd7fe32508.zip/node_modules/yallist/",\
|
||||
"packageDependencies": [\
|
||||
|
||||
Binary file not shown.
BIN
.yarn/cache/@types-jsonwebtoken-npm-9.0.1-5f660fdf38-44d3fccc6b.zip
vendored
Normal file
BIN
.yarn/cache/@types-jsonwebtoken-npm-9.0.1-5f660fdf38-44d3fccc6b.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/express-robots-txt-npm-1.0.0-dcc8bd8f0a-54f066f6c3.zip
vendored
Normal file
BIN
.yarn/cache/express-robots-txt-npm-1.0.0-dcc8bd8f0a-54f066f6c3.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/jsonwebtoken-npm-9.0.0-36fd1594c0-7ccbd0b7bf.zip
vendored
Normal file
BIN
.yarn/cache/jsonwebtoken-npm-9.0.0-36fd1594c0-7ccbd0b7bf.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/long-npm-5.2.1-3a12730171-f81b18ff29.zip
vendored
Normal file
BIN
.yarn/cache/long-npm-5.2.1-3a12730171-f81b18ff29.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/lru-cache-npm-7.14.1-d3ba9407b6-e4c8c073d9.zip
vendored
Normal file
BIN
.yarn/cache/lru-cache-npm-7.14.1-d3ba9407b6-e4c8c073d9.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/mysql2-npm-3.0.1-ceda50bb4d-6bbee1ee05.zip
vendored
Normal file
BIN
.yarn/cache/mysql2-npm-3.0.1-ceda50bb4d-6bbee1ee05.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/named-placeholders-npm-1.1.3-1b385febe5-1cd77eb10c.zip
vendored
Normal file
BIN
.yarn/cache/named-placeholders-npm-1.1.3-1b385febe5-1cd77eb10c.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/semver-npm-7.3.8-25a996cb4f-94ad80ee14.zip
vendored
Normal file
BIN
.yarn/cache/semver-npm-7.3.8-25a996cb4f-94ad80ee14.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
@@ -3,6 +3,24 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.19.5](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.19.4...@standardnotes/analytics@2.19.5) (2023-01-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.19.4](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.19.3...@standardnotes/analytics@2.19.4) (2023-01-17)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* allow to run typeorm in non-replica mode ([f73129c](https://github.com/standardnotes/server/commit/f73129cd7e7d6a9b8a63e5c80284467597557982))
|
||||
|
||||
## [2.19.3](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.19.2...@standardnotes/analytics@2.19.3) (2023-01-16)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.19.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.19.1...@standardnotes/analytics@2.19.2) (2023-01-13)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.19.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.19.0...@standardnotes/analytics@2.19.1) (2022-12-30)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/analytics",
|
||||
"version": "2.19.1",
|
||||
"version": "2.19.5",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
@@ -51,7 +51,7 @@
|
||||
"inversify": "^6.0.1",
|
||||
"ioredis": "^5.2.4",
|
||||
"mixpanel": "^0.17.0",
|
||||
"mysql2": "^2.3.3",
|
||||
"mysql2": "^3.0.1",
|
||||
"newrelic": "^9.6.0",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"typeorm": "^0.3.10",
|
||||
|
||||
@@ -12,31 +12,41 @@ const maxQueryExecutionTime = env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
|
||||
? +env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
|
||||
: 45_000
|
||||
|
||||
const inReplicaMode = env.get('DB_REPLICA_HOST', true) ? true : false
|
||||
|
||||
const replicationConfig = {
|
||||
master: {
|
||||
host: env.get('DB_HOST'),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
slaves: [
|
||||
{
|
||||
host: env.get('DB_REPLICA_HOST', true),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
],
|
||||
removeNodeErrorCount: 10,
|
||||
restoreNodeTimeout: 5,
|
||||
}
|
||||
|
||||
export const AppDataSource = new DataSource({
|
||||
type: 'mysql',
|
||||
charset: 'utf8mb4',
|
||||
supportBigNumbers: true,
|
||||
bigNumberStrings: false,
|
||||
maxQueryExecutionTime,
|
||||
replication: {
|
||||
master: {
|
||||
host: env.get('DB_HOST'),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
slaves: [
|
||||
{
|
||||
host: env.get('DB_REPLICA_HOST'),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
],
|
||||
removeNodeErrorCount: 10,
|
||||
},
|
||||
replication: inReplicaMode ? replicationConfig : undefined,
|
||||
host: inReplicaMode ? undefined : env.get('DB_HOST'),
|
||||
port: inReplicaMode ? undefined : parseInt(env.get('DB_PORT')),
|
||||
username: inReplicaMode ? undefined : env.get('DB_USERNAME'),
|
||||
password: inReplicaMode ? undefined : env.get('DB_PASSWORD'),
|
||||
database: inReplicaMode ? undefined : env.get('DB_DATABASE'),
|
||||
entities: [AnalyticsEntity, TypeORMRevenueModification],
|
||||
migrations: [env.get('DB_MIGRATIONS_PATH', true) ?? 'dist/migrations/*.js'],
|
||||
migrationsRun: true,
|
||||
|
||||
@@ -3,6 +3,29 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.46.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.45.3...@standardnotes/api-gateway@1.46.0) (2023-01-16)
|
||||
|
||||
### Features
|
||||
|
||||
* **api-gateway:** add all revisions endpoints on v2 ([60b3dd6](https://github.com/standardnotes/api-gateway/commit/60b3dd6138ef9b8e9a717873548afc2d3924a0d7))
|
||||
* **api-gateway:** switch to fetching revisions from reivsions server ([22c1f93](https://github.com/standardnotes/api-gateway/commit/22c1f936c3a770a82dc1a1e6aa136e183d308aa6))
|
||||
|
||||
## [1.45.3](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.45.2...@standardnotes/api-gateway@1.45.3) (2023-01-16)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **api-gateway:** add noindex robots meta tag to api gateway homepage ([04c6888](https://github.com/standardnotes/api-gateway/commit/04c6888cf65f9f1315fc2fb8af069d26bfbc31b1))
|
||||
|
||||
## [1.45.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.45.1...@standardnotes/api-gateway@1.45.2) (2023-01-13)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
## [1.45.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.45.0...@standardnotes/api-gateway@1.45.1) (2023-01-13)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add robots.txt setup for api-gateway and files server to disallow indexing ([bb82043](https://github.com/standardnotes/api-gateway/commit/bb820437af2b9644d7597de045b5840037b81db3))
|
||||
|
||||
# [1.45.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.44.0...@standardnotes/api-gateway@1.45.0) (2023-01-05)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -31,6 +31,8 @@ import helmet from 'helmet'
|
||||
import * as cors from 'cors'
|
||||
import { text, json, Request, Response, NextFunction, RequestHandler, ErrorRequestHandler } from 'express'
|
||||
import * as winston from 'winston'
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const robots = require('express-robots-txt')
|
||||
|
||||
import { InversifyExpressServer } from 'inversify-express-utils'
|
||||
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
|
||||
@@ -78,6 +80,12 @@ void container.load().then((container) => {
|
||||
}),
|
||||
)
|
||||
app.use(cors())
|
||||
app.use(
|
||||
robots({
|
||||
UserAgent: '*',
|
||||
Disallow: '/',
|
||||
}),
|
||||
)
|
||||
|
||||
if (env.get('SENTRY_DSN', true)) {
|
||||
Sentry.init({
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/api-gateway",
|
||||
"version": "1.45.0",
|
||||
"version": "1.46.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
@@ -32,11 +32,12 @@
|
||||
"cors": "2.8.5",
|
||||
"dotenv": "^16.0.1",
|
||||
"express": "^4.18.2",
|
||||
"express-robots-txt": "^1.0.0",
|
||||
"helmet": "^6.0.0",
|
||||
"inversify": "^6.0.1",
|
||||
"inversify-express-utils": "^6.4.3",
|
||||
"ioredis": "^5.2.4",
|
||||
"jsonwebtoken": "8.5.1",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"newrelic": "^9.6.0",
|
||||
"prettyjson": "^1.2.5",
|
||||
"reflect-metadata": "0.1.13",
|
||||
@@ -47,7 +48,7 @@
|
||||
"@types/express": "^4.17.14",
|
||||
"@types/ioredis": "^5.0.0",
|
||||
"@types/jest": "^29.1.1",
|
||||
"@types/jsonwebtoken": "^8.5.0",
|
||||
"@types/jsonwebtoken": "^9.0.1",
|
||||
"@types/newrelic": "^7.0.4",
|
||||
"@types/prettyjson": "^0.0.30",
|
||||
"@typescript-eslint/eslint-plugin": "^5.29.0",
|
||||
|
||||
@@ -57,7 +57,9 @@ export class LegacyController extends BaseHttpController {
|
||||
@all('*')
|
||||
async legacyProxyToSyncingServer(request: Request, response: Response): Promise<void> {
|
||||
if (request.path === '/') {
|
||||
response.send('Welcome to the Standard Notes server infrastructure. Learn more at https://docs.standardnotes.com')
|
||||
response.send(
|
||||
'<!DOCTYPE html><html lang="en"><head><meta name="robots" content="noindex"></head><body>Welcome to the Standard Notes server infrastructure. Learn more at https://docs.standardnotes.com</body></html>',
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { Request, Response } from 'express'
|
||||
import { inject } from 'inversify'
|
||||
import { BaseHttpController, controller, httpGet } from 'inversify-express-utils'
|
||||
import { BaseHttpController, controller, httpDelete, httpGet } from 'inversify-express-utils'
|
||||
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { HttpServiceInterface } from '../../Service/Http/HttpServiceInterface'
|
||||
|
||||
@controller('/v2/items/:item_id/revisions', TYPES.AuthMiddleware)
|
||||
@controller('/v2/items/:itemUuid/revisions', TYPES.AuthMiddleware)
|
||||
export class RevisionsControllerV2 extends BaseHttpController {
|
||||
constructor(@inject(TYPES.HTTPService) private httpService: HttpServiceInterface) {
|
||||
super()
|
||||
@@ -12,6 +13,24 @@ export class RevisionsControllerV2 extends BaseHttpController {
|
||||
|
||||
@httpGet('/')
|
||||
async getRevisions(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callRevisionsServer(request, response, `items/${request.params.item_id}/revisions`)
|
||||
await this.httpService.callRevisionsServer(request, response, `items/${request.params.itemUuid}/revisions`)
|
||||
}
|
||||
|
||||
@httpGet('/:id')
|
||||
async getRevision(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callRevisionsServer(
|
||||
request,
|
||||
response,
|
||||
`items/${request.params.itemUuid}/revisions/${request.params.id}`,
|
||||
)
|
||||
}
|
||||
|
||||
@httpDelete('/:id')
|
||||
async deleteRevision(request: Request, response: Response): Promise<void> {
|
||||
await this.httpService.callRevisionsServer(
|
||||
request,
|
||||
response,
|
||||
`items/${request.params.itemUuid}/revisions/${request.params.id}`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,3 +67,7 @@ VALET_TOKEN_SECRET=
|
||||
VALET_TOKEN_TTL=
|
||||
|
||||
WEB_SOCKET_CONNECTION_TOKEN_SECRET=
|
||||
|
||||
# (Optional) U2F Setup
|
||||
U2F_RELYING_PARTY_ID=
|
||||
U2F_RELYING_PARTY_NAME=
|
||||
|
||||
@@ -3,6 +3,54 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.82.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.82.0...@standardnotes/auth-server@1.82.1) (2023-01-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/auth-server
|
||||
|
||||
# [1.82.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.81.11...@standardnotes/auth-server@1.82.0) (2023-01-17)
|
||||
|
||||
### Features
|
||||
|
||||
* super editor permissions migration ([#414](https://github.com/standardnotes/server/issues/414)) ([7d45667](https://github.com/standardnotes/server/commit/7d456671c2b234f6570261b84d67fc3468cbc654))
|
||||
|
||||
## [1.81.11](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.81.10...@standardnotes/auth-server@1.81.11) (2023-01-17)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* allow to run typeorm in non-replica mode ([f73129c](https://github.com/standardnotes/server/commit/f73129cd7e7d6a9b8a63e5c80284467597557982))
|
||||
|
||||
## [1.81.10](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.81.9...@standardnotes/auth-server@1.81.10) (2023-01-16)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/auth-server
|
||||
|
||||
## [1.81.9](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.81.8...@standardnotes/auth-server@1.81.9) (2023-01-13)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/auth-server
|
||||
|
||||
## [1.81.8](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.81.7...@standardnotes/auth-server@1.81.8) (2023-01-11)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** add relying party configuration options ([d18f6cc](https://github.com/standardnotes/server/commit/d18f6ccd32fa97c927781c17659cf7a8e662ee07))
|
||||
|
||||
## [1.81.7](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.81.6...@standardnotes/auth-server@1.81.7) (2023-01-09)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** failure messages for debug logs upon signing in with recovery codes ([7ae8845](https://github.com/standardnotes/server/commit/7ae8845ae9ff9c208d192aea48e5517a16c8338f))
|
||||
|
||||
## [1.81.6](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.81.5...@standardnotes/auth-server@1.81.6) (2023-01-09)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** request parameters names ([dda8d79](https://github.com/standardnotes/server/commit/dda8d795262d6629493377ae5a6143263a792378))
|
||||
|
||||
## [1.81.5](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.81.4...@standardnotes/auth-server@1.81.5) (2023-01-09)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** debuggin recovery sign in ([96669bf](https://github.com/standardnotes/server/commit/96669bff5bc0903f28c51628e9289626622e674c))
|
||||
|
||||
## [1.81.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.81.3...@standardnotes/auth-server@1.81.4) (2023-01-09)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
23
packages/auth/migrations/1673951291148-add_super_editor.ts
Normal file
23
packages/auth/migrations/1673951291148-add_super_editor.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||
|
||||
export class addSuperEditor1673951291148 implements MigrationInterface {
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
'INSERT INTO `permissions` (uuid, name) VALUES ("717ae814-a7f3-433c-a302-ea8736df3546", "editor:super-editor")',
|
||||
)
|
||||
|
||||
// Pro User Permissions
|
||||
await queryRunner.query(
|
||||
'INSERT INTO `role_permissions` (role_uuid, permission_uuid) VALUES ("8047edbb-a10a-4ff8-8d53-c2cae600a8e8", "717ae814-a7f3-433c-a302-ea8736df3546")',
|
||||
)
|
||||
|
||||
// Plus User Permissions
|
||||
await queryRunner.query(
|
||||
'INSERT INTO `role_permissions` (role_uuid, permission_uuid) VALUES ("dee6e144-724b-4450-86d1-cc784770b2e2", "717ae814-a7f3-433c-a302-ea8736df3546")',
|
||||
)
|
||||
}
|
||||
|
||||
public async down(): Promise<void> {
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/auth-server",
|
||||
"version": "1.81.4",
|
||||
"version": "1.82.1",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
@@ -60,7 +60,7 @@
|
||||
"inversify": "^6.0.1",
|
||||
"inversify-express-utils": "^6.4.3",
|
||||
"ioredis": "^5.2.4",
|
||||
"mysql2": "^2.3.3",
|
||||
"mysql2": "^3.0.1",
|
||||
"newrelic": "^9.6.0",
|
||||
"otplib": "12.0.1",
|
||||
"prettyjson": "^1.2.5",
|
||||
|
||||
@@ -463,7 +463,12 @@ export class ContainerConfigLoader {
|
||||
container
|
||||
.bind(TYPES.SESSION_TRACE_DAYS_TTL)
|
||||
.toConstantValue(env.get('SESSION_TRACE_DAYS_TTL', true) ? +env.get('SESSION_TRACE_DAYS_TTL', true) : 90)
|
||||
|
||||
container
|
||||
.bind(TYPES.U2F_RELYING_PARTY_NAME)
|
||||
.toConstantValue(env.get('U2F_RELYING_PARTY_NAME', true) ?? 'Standard Notes')
|
||||
container
|
||||
.bind(TYPES.U2F_RELYING_PARTY_ID)
|
||||
.toConstantValue(env.get('U2F_RELYING_PARTY_ID', true) ?? 'standardnotes.com')
|
||||
// Services
|
||||
container.bind<UAParser>(TYPES.DeviceDetector).toConstantValue(new UAParser())
|
||||
container.bind<SessionService>(TYPES.SessionService).to(SessionService)
|
||||
@@ -567,6 +572,8 @@ export class ContainerConfigLoader {
|
||||
new GenerateAuthenticatorRegistrationOptions(
|
||||
container.get(TYPES.AuthenticatorRepository),
|
||||
container.get(TYPES.AuthenticatorChallengeRepository),
|
||||
container.get(TYPES.U2F_RELYING_PARTY_NAME),
|
||||
container.get(TYPES.U2F_RELYING_PARTY_ID),
|
||||
),
|
||||
)
|
||||
container
|
||||
@@ -575,6 +582,7 @@ export class ContainerConfigLoader {
|
||||
new VerifyAuthenticatorRegistrationResponse(
|
||||
container.get(TYPES.AuthenticatorRepository),
|
||||
container.get(TYPES.AuthenticatorChallengeRepository),
|
||||
container.get(TYPES.U2F_RELYING_PARTY_ID),
|
||||
),
|
||||
)
|
||||
container
|
||||
@@ -591,6 +599,7 @@ export class ContainerConfigLoader {
|
||||
new VerifyAuthenticatorAuthenticationResponse(
|
||||
container.get(TYPES.AuthenticatorRepository),
|
||||
container.get(TYPES.AuthenticatorChallengeRepository),
|
||||
container.get(TYPES.U2F_RELYING_PARTY_ID),
|
||||
),
|
||||
)
|
||||
container
|
||||
|
||||
@@ -22,31 +22,41 @@ const maxQueryExecutionTime = env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
|
||||
? +env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
|
||||
: 45_000
|
||||
|
||||
const inReplicaMode = env.get('DB_REPLICA_HOST', true) ? true : false
|
||||
|
||||
const replicationConfig = {
|
||||
master: {
|
||||
host: env.get('DB_HOST'),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
slaves: [
|
||||
{
|
||||
host: env.get('DB_REPLICA_HOST', true),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
],
|
||||
removeNodeErrorCount: 10,
|
||||
restoreNodeTimeout: 5,
|
||||
}
|
||||
|
||||
export const AppDataSource = new DataSource({
|
||||
type: 'mysql',
|
||||
charset: 'utf8mb4',
|
||||
supportBigNumbers: true,
|
||||
bigNumberStrings: false,
|
||||
maxQueryExecutionTime,
|
||||
replication: {
|
||||
master: {
|
||||
host: env.get('DB_HOST'),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
slaves: [
|
||||
{
|
||||
host: env.get('DB_REPLICA_HOST'),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
],
|
||||
removeNodeErrorCount: 10,
|
||||
},
|
||||
replication: inReplicaMode ? replicationConfig : undefined,
|
||||
host: inReplicaMode ? undefined : env.get('DB_HOST'),
|
||||
port: inReplicaMode ? undefined : parseInt(env.get('DB_PORT')),
|
||||
username: inReplicaMode ? undefined : env.get('DB_USERNAME'),
|
||||
password: inReplicaMode ? undefined : env.get('DB_PASSWORD'),
|
||||
database: inReplicaMode ? undefined : env.get('DB_DATABASE'),
|
||||
entities: [
|
||||
User,
|
||||
UserSubscription,
|
||||
|
||||
@@ -94,6 +94,8 @@ const TYPES = {
|
||||
VERSION: Symbol.for('VERSION'),
|
||||
PAYMENTS_SERVER_URL: Symbol.for('PAYMENTS_SERVER_URL'),
|
||||
SESSION_TRACE_DAYS_TTL: Symbol.for('SESSION_TRACE_DAYS_TTL'),
|
||||
U2F_RELYING_PARTY_ID: Symbol.for('U2F_RELYING_PARTY_ID'),
|
||||
U2F_RELYING_PARTY_NAME: Symbol.for('U2F_RELYING_PARTY_NAME'),
|
||||
// use cases
|
||||
AuthenticateUser: Symbol.for('AuthenticateUser'),
|
||||
AuthenticateRequest: Symbol.for('AuthenticateRequest'),
|
||||
|
||||
@@ -12,6 +12,7 @@ import { ApiVersion } from '@standardnotes/api'
|
||||
import { SignInWithRecoveryCodes } from '../Domain/UseCase/SignInWithRecoveryCodes/SignInWithRecoveryCodes'
|
||||
import { GetUserKeyParamsRecovery } from '../Domain/UseCase/GetUserKeyParamsRecovery/GetUserKeyParamsRecovery'
|
||||
import { GenerateRecoveryCodes } from '../Domain/UseCase/GenerateRecoveryCodes/GenerateRecoveryCodes'
|
||||
import { Logger } from 'winston'
|
||||
|
||||
describe('AuthController', () => {
|
||||
let clearLoginAttempts: ClearLoginAttempts
|
||||
@@ -23,6 +24,7 @@ describe('AuthController', () => {
|
||||
let doSignInWithRecoveryCodes: SignInWithRecoveryCodes
|
||||
let getUserKeyParamsRecovery: GetUserKeyParamsRecovery
|
||||
let doGenerateRecoveryCodes: GenerateRecoveryCodes
|
||||
let logger: Logger
|
||||
|
||||
const createController = () =>
|
||||
new AuthController(
|
||||
@@ -33,6 +35,7 @@ describe('AuthController', () => {
|
||||
doSignInWithRecoveryCodes,
|
||||
getUserKeyParamsRecovery,
|
||||
doGenerateRecoveryCodes,
|
||||
logger,
|
||||
)
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -52,6 +55,9 @@ describe('AuthController', () => {
|
||||
|
||||
domainEventFactory = {} as jest.Mocked<DomainEventFactoryInterface>
|
||||
domainEventFactory.createUserRegisteredEvent = jest.fn().mockReturnValue(event)
|
||||
|
||||
logger = {} as jest.Mocked<Logger>
|
||||
logger.debug = jest.fn()
|
||||
})
|
||||
|
||||
it('should register a user', async () => {
|
||||
|
||||
@@ -23,6 +23,7 @@ import { RecoveryKeyParamsResponse } from '../Infra/Http/Response/RecoveryKeyPar
|
||||
import { GenerateRecoveryCodes } from '../Domain/UseCase/GenerateRecoveryCodes/GenerateRecoveryCodes'
|
||||
import { GenerateRecoveryCodesRequestParams } from '../Infra/Http/Request/GenerateRecoveryCodesRequestParams'
|
||||
import { GenerateRecoveryCodesResponse } from '../Infra/Http/Response/GenerateRecoveryCodesResponse'
|
||||
import { Logger } from 'winston'
|
||||
|
||||
@injectable()
|
||||
export class AuthController implements UserServerInterface {
|
||||
@@ -34,6 +35,7 @@ export class AuthController implements UserServerInterface {
|
||||
@inject(TYPES.SignInWithRecoveryCodes) private doSignInWithRecoveryCodes: SignInWithRecoveryCodes,
|
||||
@inject(TYPES.GetUserKeyParamsRecovery) private getUserKeyParamsRecovery: GetUserKeyParamsRecovery,
|
||||
@inject(TYPES.GenerateRecoveryCodes) private doGenerateRecoveryCodes: GenerateRecoveryCodes,
|
||||
@inject(TYPES.Logger) private logger: Logger,
|
||||
) {}
|
||||
|
||||
async deleteAccount(_params: never): Promise<UserDeletionResponse> {
|
||||
@@ -138,11 +140,13 @@ export class AuthController implements UserServerInterface {
|
||||
})
|
||||
|
||||
if (result.isFailed()) {
|
||||
this.logger.debug(`Failed to sign in with recovery codes: ${result.getError()}`)
|
||||
|
||||
return {
|
||||
status: HttpStatusCode.Unauthorized,
|
||||
data: {
|
||||
error: {
|
||||
message: result.getError(),
|
||||
message: 'Invalid login credentials.',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -173,11 +177,13 @@ export class AuthController implements UserServerInterface {
|
||||
})
|
||||
|
||||
if (result.isFailed()) {
|
||||
this.logger.debug(`Failed to get recovery key params: ${result.getError()}`)
|
||||
|
||||
return {
|
||||
status: HttpStatusCode.Unauthorized,
|
||||
data: {
|
||||
error: {
|
||||
message: result.getError(),
|
||||
message: 'Invalid login credentials.',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
export enum RelyingParty {
|
||||
RP_NAME = 'Standard Notes',
|
||||
RP_ID = 'standardnotes.com',
|
||||
}
|
||||
@@ -11,7 +11,12 @@ describe('GenerateAuthenticatorRegistrationOptions', () => {
|
||||
let authenticatorChallengeRepository: AuthenticatorChallengeRepositoryInterface
|
||||
|
||||
const createUseCase = () =>
|
||||
new GenerateAuthenticatorRegistrationOptions(authenticatorRepository, authenticatorChallengeRepository)
|
||||
new GenerateAuthenticatorRegistrationOptions(
|
||||
authenticatorRepository,
|
||||
authenticatorChallengeRepository,
|
||||
'Standard Notes',
|
||||
'standardnotes.com',
|
||||
)
|
||||
|
||||
beforeEach(() => {
|
||||
const authenticator = Authenticator.create({
|
||||
|
||||
@@ -5,12 +5,13 @@ import { GenerateAuthenticatorRegistrationOptionsDTO } from './GenerateAuthentic
|
||||
import { AuthenticatorRepositoryInterface } from '../../Authenticator/AuthenticatorRepositoryInterface'
|
||||
import { AuthenticatorChallengeRepositoryInterface } from '../../Authenticator/AuthenticatorChallengeRepositoryInterface'
|
||||
import { AuthenticatorChallenge } from '../../Authenticator/AuthenticatorChallenge'
|
||||
import { RelyingParty } from '../../Authenticator/RelyingParty'
|
||||
|
||||
export class GenerateAuthenticatorRegistrationOptions implements UseCaseInterface<Record<string, unknown>> {
|
||||
constructor(
|
||||
private authenticatorRepository: AuthenticatorRepositoryInterface,
|
||||
private authenticatorChallengeRepository: AuthenticatorChallengeRepositoryInterface,
|
||||
private relyingPartyName: string,
|
||||
private relyingPartyId: string,
|
||||
) {}
|
||||
|
||||
async execute(dto: GenerateAuthenticatorRegistrationOptionsDTO): Promise<Result<Record<string, unknown>>> {
|
||||
@@ -28,8 +29,8 @@ export class GenerateAuthenticatorRegistrationOptions implements UseCaseInterfac
|
||||
|
||||
const authenticators = await this.authenticatorRepository.findByUserUuid(userUuid)
|
||||
const options = generateRegistrationOptions({
|
||||
rpID: RelyingParty.RP_ID,
|
||||
rpName: RelyingParty.RP_NAME,
|
||||
rpID: this.relyingPartyId,
|
||||
rpName: this.relyingPartyName,
|
||||
userID: userUuid.value,
|
||||
userName: username.value,
|
||||
attestationType: 'none',
|
||||
|
||||
@@ -81,7 +81,7 @@ describe('SignInWithRecoveryCodes', () => {
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe('Invalid email or password')
|
||||
expect(result.getError()).toBe('Empty password')
|
||||
})
|
||||
|
||||
it('should return error if username is not provided', async () => {
|
||||
@@ -107,7 +107,7 @@ describe('SignInWithRecoveryCodes', () => {
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe('Invalid email or password')
|
||||
expect(result.getError()).toBe('Invalid code verifier')
|
||||
})
|
||||
|
||||
it('should return error if recovery codes are not provided', async () => {
|
||||
@@ -120,7 +120,7 @@ describe('SignInWithRecoveryCodes', () => {
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe('Invalid recovery codes')
|
||||
expect(result.getError()).toBe('Empty recovery codes')
|
||||
})
|
||||
|
||||
it('should return error if code verifier is invalid', async () => {
|
||||
@@ -135,7 +135,7 @@ describe('SignInWithRecoveryCodes', () => {
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe('Invalid email or password')
|
||||
expect(result.getError()).toBe('Invalid code verifier')
|
||||
})
|
||||
|
||||
it('should return error if user is not found', async () => {
|
||||
@@ -150,7 +150,7 @@ describe('SignInWithRecoveryCodes', () => {
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe('Invalid email or password')
|
||||
expect(result.getError()).toBe('Could not find user')
|
||||
})
|
||||
|
||||
it('should return error if recovery codes are invalid', async () => {
|
||||
@@ -176,7 +176,7 @@ describe('SignInWithRecoveryCodes', () => {
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe('Invalid email or password')
|
||||
expect(result.getError()).toBe('Invalid password')
|
||||
})
|
||||
|
||||
it('should return error if recovery codes are not generated for user', async () => {
|
||||
|
||||
@@ -40,21 +40,21 @@ export class SignInWithRecoveryCodes implements UseCaseInterface<AuthResponse202
|
||||
if (!validCodeVerifier) {
|
||||
await this.increaseLoginAttempts.execute({ email: username.value })
|
||||
|
||||
return Result.fail('Invalid email or password')
|
||||
return Result.fail('Invalid code verifier')
|
||||
}
|
||||
|
||||
const passwordValidationResult = Validator.isNotEmpty(dto.password)
|
||||
if (passwordValidationResult.isFailed()) {
|
||||
await this.increaseLoginAttempts.execute({ email: username.value })
|
||||
|
||||
return Result.fail('Invalid email or password')
|
||||
return Result.fail('Empty password')
|
||||
}
|
||||
|
||||
const recoveryCodesValidationResult = Validator.isNotEmpty(dto.recoveryCodes)
|
||||
if (recoveryCodesValidationResult.isFailed()) {
|
||||
await this.increaseLoginAttempts.execute({ email: username.value })
|
||||
|
||||
return Result.fail('Invalid recovery codes')
|
||||
return Result.fail('Empty recovery codes')
|
||||
}
|
||||
|
||||
const user = await this.userRepository.findOneByEmail(username.value)
|
||||
@@ -62,14 +62,14 @@ export class SignInWithRecoveryCodes implements UseCaseInterface<AuthResponse202
|
||||
if (!user) {
|
||||
await this.increaseLoginAttempts.execute({ email: username.value })
|
||||
|
||||
return Result.fail('Invalid email or password')
|
||||
return Result.fail('Could not find user')
|
||||
}
|
||||
|
||||
const passwordMatches = await bcrypt.compare(dto.password, user.encryptedPassword)
|
||||
if (!passwordMatches) {
|
||||
await this.increaseLoginAttempts.execute({ email: username.value })
|
||||
|
||||
return Result.fail('Invalid email or password')
|
||||
return Result.fail('Invalid password')
|
||||
}
|
||||
|
||||
const recoveryCodesSetting = await this.settingService.findSettingWithDecryptedValue({
|
||||
|
||||
@@ -13,7 +13,11 @@ describe('VerifyAuthenticatorAuthenticationResponse', () => {
|
||||
let authenticatorChallengeRepository: AuthenticatorChallengeRepositoryInterface
|
||||
|
||||
const createUseCase = () =>
|
||||
new VerifyAuthenticatorAuthenticationResponse(authenticatorRepository, authenticatorChallengeRepository)
|
||||
new VerifyAuthenticatorAuthenticationResponse(
|
||||
authenticatorRepository,
|
||||
authenticatorChallengeRepository,
|
||||
'standardnotes.com',
|
||||
)
|
||||
|
||||
beforeEach(() => {
|
||||
const authenticator = Authenticator.create({
|
||||
|
||||
@@ -5,12 +5,12 @@ import { AuthenticatorDevice } from '@simplewebauthn/typescript-types'
|
||||
import { AuthenticatorChallengeRepositoryInterface } from '../../Authenticator/AuthenticatorChallengeRepositoryInterface'
|
||||
import { AuthenticatorRepositoryInterface } from '../../Authenticator/AuthenticatorRepositoryInterface'
|
||||
import { VerifyAuthenticatorAuthenticationResponseDTO } from './VerifyAuthenticatorAuthenticationResponseDTO'
|
||||
import { RelyingParty } from '../../Authenticator/RelyingParty'
|
||||
|
||||
export class VerifyAuthenticatorAuthenticationResponse implements UseCaseInterface<boolean> {
|
||||
constructor(
|
||||
private authenticatorRepository: AuthenticatorRepositoryInterface,
|
||||
private authenticatorChallengeRepository: AuthenticatorChallengeRepositoryInterface,
|
||||
private relyingPartyId: string,
|
||||
) {}
|
||||
|
||||
async execute(dto: VerifyAuthenticatorAuthenticationResponseDTO): Promise<Result<boolean>> {
|
||||
@@ -40,8 +40,8 @@ export class VerifyAuthenticatorAuthenticationResponse implements UseCaseInterfa
|
||||
verification = await verifyAuthenticationResponse({
|
||||
credential: dto.authenticationCredential,
|
||||
expectedChallenge: authenticatorChallenge.props.challenge.toString(),
|
||||
expectedOrigin: `https://${RelyingParty.RP_ID}`,
|
||||
expectedRPID: RelyingParty.RP_ID,
|
||||
expectedOrigin: `https://${this.relyingPartyId}`,
|
||||
expectedRPID: this.relyingPartyId,
|
||||
authenticator: {
|
||||
counter: authenticator.props.counter,
|
||||
credentialID: authenticator.props.credentialId,
|
||||
|
||||
@@ -13,7 +13,11 @@ describe('VerifyAuthenticatorRegistrationResponse', () => {
|
||||
let authenticatorChallengeRepository: AuthenticatorChallengeRepositoryInterface
|
||||
|
||||
const createUseCase = () =>
|
||||
new VerifyAuthenticatorRegistrationResponse(authenticatorRepository, authenticatorChallengeRepository)
|
||||
new VerifyAuthenticatorRegistrationResponse(
|
||||
authenticatorRepository,
|
||||
authenticatorChallengeRepository,
|
||||
'standardnotes.com',
|
||||
)
|
||||
|
||||
beforeEach(() => {
|
||||
authenticatorRepository = {} as jest.Mocked<AuthenticatorRepositoryInterface>
|
||||
|
||||
@@ -2,7 +2,6 @@ import { Dates, Result, UseCaseInterface, Uuid, Validator } from '@standardnotes
|
||||
import { VerifiedRegistrationResponse, verifyRegistrationResponse } from '@simplewebauthn/server'
|
||||
|
||||
import { AuthenticatorChallengeRepositoryInterface } from '../../Authenticator/AuthenticatorChallengeRepositoryInterface'
|
||||
import { RelyingParty } from '../../Authenticator/RelyingParty'
|
||||
import { AuthenticatorRepositoryInterface } from '../../Authenticator/AuthenticatorRepositoryInterface'
|
||||
import { Authenticator } from '../../Authenticator/Authenticator'
|
||||
import { VerifyAuthenticatorRegistrationResponseDTO } from './VerifyAuthenticatorRegistrationResponseDTO'
|
||||
@@ -11,6 +10,7 @@ export class VerifyAuthenticatorRegistrationResponse implements UseCaseInterface
|
||||
constructor(
|
||||
private authenticatorRepository: AuthenticatorRepositoryInterface,
|
||||
private authenticatorChallengeRepository: AuthenticatorChallengeRepositoryInterface,
|
||||
private relyingPartyId: string,
|
||||
) {}
|
||||
|
||||
async execute(dto: VerifyAuthenticatorRegistrationResponseDTO): Promise<Result<boolean>> {
|
||||
@@ -35,8 +35,8 @@ export class VerifyAuthenticatorRegistrationResponse implements UseCaseInterface
|
||||
verification = await verifyRegistrationResponse({
|
||||
credential: dto.registrationCredential,
|
||||
expectedChallenge: authenticatorChallenge.props.challenge.toString(),
|
||||
expectedOrigin: `https://${RelyingParty.RP_ID}`,
|
||||
expectedRPID: RelyingParty.RP_ID,
|
||||
expectedOrigin: `https://${this.relyingPartyId}`,
|
||||
expectedRPID: this.relyingPartyId,
|
||||
})
|
||||
|
||||
if (!verification.verified) {
|
||||
|
||||
@@ -264,10 +264,10 @@ export class InversifyExpressAuthController extends BaseHttpController {
|
||||
@httpPost('/recovery/login', TYPES.LockMiddleware)
|
||||
async recoveryLogin(request: Request): Promise<results.JsonResult> {
|
||||
const result = await this.authController.signInWithRecoveryCodes({
|
||||
apiVersion: request.body.api,
|
||||
apiVersion: request.body.api_version,
|
||||
userAgent: <string>request.headers['user-agent'],
|
||||
codeVerifier: request.body.code_verifier,
|
||||
username: request.body.email,
|
||||
username: request.body.username,
|
||||
recoveryCodes: request.body.recovery_codes,
|
||||
password: request.body.password,
|
||||
})
|
||||
@@ -278,8 +278,8 @@ export class InversifyExpressAuthController extends BaseHttpController {
|
||||
@httpPost('/recovery/params')
|
||||
async recoveryParams(request: Request): Promise<results.JsonResult> {
|
||||
const result = await this.authController.recoveryKeyParams({
|
||||
apiVersion: request.body.api,
|
||||
username: request.body.email,
|
||||
apiVersion: request.body.api_version,
|
||||
username: request.body.username,
|
||||
codeChallenge: request.body.code_challenge,
|
||||
recoveryCodes: request.body.recovery_codes,
|
||||
})
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.11.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.11.0...@standardnotes/domain-core@1.11.1) (2023-01-16)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **revisions:** add required role to revisions list response ([e7beee2](https://github.com/standardnotes/server/commit/e7beee278871d2939b058d842404fd6980d7f48a))
|
||||
|
||||
# [1.11.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.10.0...@standardnotes/domain-core@1.11.0) (2022-12-15)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/domain-core",
|
||||
"version": "1.11.0",
|
||||
"version": "1.11.1",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import { Result } from '../Core/Result'
|
||||
|
||||
export interface SyncUseCaseInterface<T> {
|
||||
execute(...args: any[]): Result<T>
|
||||
}
|
||||
@@ -35,4 +35,5 @@ export * from './Mapping/MapperInterface'
|
||||
export * from './Subscription/SubscriptionPlanName'
|
||||
export * from './Subscription/SubscriptionPlanNameProps'
|
||||
|
||||
export * from './UseCase/SyncUseCaseInterface'
|
||||
export * from './UseCase/UseCaseInterface'
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.9.60](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.9.59...@standardnotes/domain-events-infra@1.9.60) (2023-01-13)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/domain-events-infra
|
||||
|
||||
## [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,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/domain-events-infra",
|
||||
"version": "1.9.59",
|
||||
"version": "1.9.60",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.105.2](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.105.1...@standardnotes/domain-events@2.105.2) (2023-01-13)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/domain-events
|
||||
|
||||
## [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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/domain-events",
|
||||
"version": "2.105.1",
|
||||
"version": "2.105.2",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,20 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.6.59](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.6.58...@standardnotes/event-store@1.6.59) (2023-01-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
## [1.6.58](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.6.57...@standardnotes/event-store@1.6.58) (2023-01-17)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* allow to run typeorm in non-replica mode ([f73129c](https://github.com/standardnotes/server/commit/f73129cd7e7d6a9b8a63e5c80284467597557982))
|
||||
|
||||
## [1.6.57](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.6.56...@standardnotes/event-store@1.6.57) (2023-01-13)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
## [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 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/event-store",
|
||||
"version": "1.6.56",
|
||||
"version": "1.6.59",
|
||||
"description": "Event Store Service",
|
||||
"private": true,
|
||||
"main": "dist/src/index.js",
|
||||
@@ -38,7 +38,7 @@
|
||||
"dotenv": "^16.0.1",
|
||||
"inversify": "^6.0.1",
|
||||
"ioredis": "^5.2.4",
|
||||
"mysql2": "^2.3.3",
|
||||
"mysql2": "^3.0.1",
|
||||
"newrelic": "^9.6.0",
|
||||
"reflect-metadata": "0.1.13",
|
||||
"typeorm": "^0.3.10",
|
||||
|
||||
@@ -9,31 +9,41 @@ const maxQueryExecutionTime = env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
|
||||
? +env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
|
||||
: 45_000
|
||||
|
||||
const inReplicaMode = env.get('DB_REPLICA_HOST', true) ? true : false
|
||||
|
||||
const replicationConfig = {
|
||||
master: {
|
||||
host: env.get('DB_HOST'),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
slaves: [
|
||||
{
|
||||
host: env.get('DB_REPLICA_HOST', true),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
],
|
||||
removeNodeErrorCount: 10,
|
||||
restoreNodeTimeout: 5,
|
||||
}
|
||||
|
||||
export const AppDataSource = new DataSource({
|
||||
type: 'mysql',
|
||||
charset: 'utf8mb4',
|
||||
supportBigNumbers: true,
|
||||
bigNumberStrings: false,
|
||||
maxQueryExecutionTime,
|
||||
replication: {
|
||||
master: {
|
||||
host: env.get('DB_HOST'),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
slaves: [
|
||||
{
|
||||
host: env.get('DB_REPLICA_HOST'),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
],
|
||||
removeNodeErrorCount: 10,
|
||||
},
|
||||
replication: inReplicaMode ? replicationConfig : undefined,
|
||||
host: inReplicaMode ? undefined : env.get('DB_HOST'),
|
||||
port: inReplicaMode ? undefined : parseInt(env.get('DB_PORT')),
|
||||
username: inReplicaMode ? undefined : env.get('DB_USERNAME'),
|
||||
password: inReplicaMode ? undefined : env.get('DB_PASSWORD'),
|
||||
database: inReplicaMode ? undefined : env.get('DB_DATABASE'),
|
||||
entities: [Event],
|
||||
migrations: [env.get('DB_MIGRATIONS_PATH', true) ?? 'dist/migrations/*.js'],
|
||||
migrationsRun: true,
|
||||
|
||||
@@ -3,6 +3,16 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.9.5](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.9.4...@standardnotes/files-server@1.9.5) (2023-01-13)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
## [1.9.4](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.9.3...@standardnotes/files-server@1.9.4) (2023-01-13)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add robots.txt setup for api-gateway and files server to disallow indexing ([bb82043](https://github.com/standardnotes/files/commit/bb820437af2b9644d7597de045b5840037b81db3))
|
||||
|
||||
## [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
|
||||
|
||||
@@ -12,6 +12,8 @@ import helmet from 'helmet'
|
||||
import * as cors from 'cors'
|
||||
import { urlencoded, json, raw, Request, Response, NextFunction, RequestHandler, ErrorRequestHandler } from 'express'
|
||||
import * as winston from 'winston'
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const robots = require('express-robots-txt')
|
||||
|
||||
import { InversifyExpressServer } from 'inversify-express-utils'
|
||||
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
|
||||
@@ -65,6 +67,12 @@ void container.load().then((container) => {
|
||||
exposedHeaders: ['Content-Range', 'Accept-Ranges'],
|
||||
}),
|
||||
)
|
||||
app.use(
|
||||
robots({
|
||||
UserAgent: '*',
|
||||
Disallow: '/',
|
||||
}),
|
||||
)
|
||||
|
||||
if (env.get('SENTRY_DSN', true)) {
|
||||
Sentry.init({
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/files-server",
|
||||
"version": "1.9.3",
|
||||
"version": "1.9.5",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
@@ -39,12 +39,13 @@
|
||||
"dayjs": "^1.11.6",
|
||||
"dotenv": "^16.0.1",
|
||||
"express": "^4.18.2",
|
||||
"express-robots-txt": "^1.0.0",
|
||||
"express-winston": "^4.0.5",
|
||||
"helmet": "^6.0.0",
|
||||
"inversify": "^6.0.1",
|
||||
"inversify-express-utils": "^6.4.3",
|
||||
"ioredis": "^5.2.4",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"newrelic": "^9.6.0",
|
||||
"nodemon": "^2.0.19",
|
||||
"prettyjson": "^1.2.5",
|
||||
@@ -59,7 +60,7 @@
|
||||
"@types/express": "^4.17.14",
|
||||
"@types/ioredis": "^5.0.0",
|
||||
"@types/jest": "^29.1.1",
|
||||
"@types/jsonwebtoken": "^8.5.0",
|
||||
"@types/jsonwebtoken": "^9.0.1",
|
||||
"@types/newrelic": "^7.0.4",
|
||||
"@types/prettyjson": "^0.0.30",
|
||||
"@types/uuid": "^8.3.0",
|
||||
|
||||
@@ -3,6 +3,62 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.10.13](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.10.12...@standardnotes/revisions-server@1.10.13) (2023-01-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/revisions-server
|
||||
|
||||
## [1.10.12](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.10.11...@standardnotes/revisions-server@1.10.12) (2023-01-17)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **revisions:** fetching revisions metadata ([51c7773](https://github.com/standardnotes/server/commit/51c777304be96d317f95e9787b51e8489f9998b4))
|
||||
|
||||
## [1.10.11](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.10.10...@standardnotes/revisions-server@1.10.11) (2023-01-17)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* allow to run typeorm in non-replica mode ([f73129c](https://github.com/standardnotes/server/commit/f73129cd7e7d6a9b8a63e5c80284467597557982))
|
||||
|
||||
## [1.10.10](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.10.9...@standardnotes/revisions-server@1.10.10) (2023-01-17)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **revisions:** add debug logs for retrieving revisions metadata from mysql ([c579864](https://github.com/standardnotes/server/commit/c5798640fffbbf29f30db11dcc10b8cd3f11839e))
|
||||
|
||||
## [1.10.9](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.10.8...@standardnotes/revisions-server@1.10.9) (2023-01-17)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **revisions:** response structure ([e2aae8a](https://github.com/standardnotes/server/commit/e2aae8ac8a98dff9f618709c33f7b80479747ec9))
|
||||
|
||||
## [1.10.8](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.10.7...@standardnotes/revisions-server@1.10.8) (2023-01-16)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **revisions:** add required role to revisions list response ([e7beee2](https://github.com/standardnotes/server/commit/e7beee278871d2939b058d842404fd6980d7f48a))
|
||||
|
||||
## [1.10.7](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.10.6...@standardnotes/revisions-server@1.10.7) (2023-01-16)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **revisions:** remove redundant specs ([11b8b07](https://github.com/standardnotes/server/commit/11b8b078b4c72f393fd4e555501242ffe22cc06f))
|
||||
|
||||
## [1.10.6](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.10.5...@standardnotes/revisions-server@1.10.6) (2023-01-16)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **revisions:** mapping to snake case ([b97dafe](https://github.com/standardnotes/server/commit/b97dafe6f35ad0f9e42a228f354c4bceb1a2874d))
|
||||
|
||||
## [1.10.5](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.10.4...@standardnotes/revisions-server@1.10.5) (2023-01-16)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **revisions:** response structure ([8b988d8](https://github.com/standardnotes/server/commit/8b988d89c09ee3d9df52d9922550f688bf16a9f4))
|
||||
|
||||
## [1.10.4](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.10.3...@standardnotes/revisions-server@1.10.4) (2023-01-13)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/revisions-server
|
||||
|
||||
## [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
|
||||
|
||||
@@ -7,5 +7,5 @@ module.exports = {
|
||||
transform: {
|
||||
...tsjPreset.transform,
|
||||
},
|
||||
coveragePathIgnorePatterns: ['/Bootstrap/', 'HealthCheckController', '/Infra/', '/Mapping/'],
|
||||
coveragePathIgnorePatterns: ['/Bootstrap/', '/Controller/', 'HealthCheckController', '/Infra/', '/Mapping/'],
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/revisions-server",
|
||||
"version": "1.10.3",
|
||||
"version": "1.10.13",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
@@ -40,7 +40,7 @@
|
||||
"inversify": "^6.0.1",
|
||||
"inversify-express-utils": "^6.4.3",
|
||||
"ioredis": "^5.2.4",
|
||||
"mysql2": "^2.3.3",
|
||||
"mysql2": "^3.0.1",
|
||||
"newrelic": "^9.6.0",
|
||||
"reflect-metadata": "0.1.13",
|
||||
"typeorm": "^0.3.10",
|
||||
|
||||
@@ -42,6 +42,10 @@ import { AccountDeletionRequestedEventHandler } from '../Domain/Handler/AccountD
|
||||
import { RevisionsCopyRequestedEventHandler } from '../Domain/Handler/RevisionsCopyRequestedEventHandler'
|
||||
import { CopyRevisions } from '../Domain/UseCase/CopyRevisions/CopyRevisions'
|
||||
import { RevisionsOwnershipUpdateRequestedEventHandler } from '../Domain/Handler/RevisionsOwnershipUpdateRequestedEventHandler'
|
||||
import { RevisionHttpMapper } from '../Mapping/RevisionHttpMapper'
|
||||
import { RevisionMetadataHttpMapper } from '../Mapping/RevisionMetadataHttpMapper'
|
||||
import { GetRequiredRoleToViewRevision } from '../Domain/UseCase/GetRequiredRoleToViewRevision/GetRequiredRoleToViewRevision'
|
||||
import { Timer, TimerInterface } from '@standardnotes/time'
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const newrelicFormatter = require('@newrelic/winston-enricher')
|
||||
@@ -102,6 +106,12 @@ export class ContainerConfigLoader {
|
||||
}
|
||||
container.bind<AWS.S3 | undefined>(TYPES.S3).toConstantValue(s3Client)
|
||||
|
||||
container.bind<TimerInterface>(TYPES.Timer).toConstantValue(new Timer())
|
||||
|
||||
container
|
||||
.bind<GetRequiredRoleToViewRevision>(TYPES.GetRequiredRoleToViewRevision)
|
||||
.toConstantValue(new GetRequiredRoleToViewRevision(container.get(TYPES.Timer)))
|
||||
|
||||
// Map
|
||||
container
|
||||
.bind<MapperInterface<RevisionMetadata, TypeORMRevision>>(TYPES.RevisionMetadataPersistenceMapper)
|
||||
@@ -112,6 +122,37 @@ export class ContainerConfigLoader {
|
||||
container
|
||||
.bind<MapperInterface<Revision, string>>(TYPES.RevisionItemStringMapper)
|
||||
.toConstantValue(new RevisionItemStringMapper())
|
||||
container
|
||||
.bind<
|
||||
MapperInterface<
|
||||
Revision,
|
||||
{
|
||||
uuid: string
|
||||
item_uuid: string
|
||||
content: string | null
|
||||
content_type: string
|
||||
items_key_id: string | null
|
||||
enc_item_key: string | null
|
||||
auth_hash: string | null
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
>
|
||||
>(TYPES.RevisionHttpMapper)
|
||||
.toConstantValue(new RevisionHttpMapper())
|
||||
container
|
||||
.bind<
|
||||
MapperInterface<
|
||||
RevisionMetadata,
|
||||
{
|
||||
uuid: string
|
||||
content_type: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
>
|
||||
>(TYPES.RevisionMetadataHttpMapper)
|
||||
.toConstantValue(new RevisionMetadataHttpMapper(container.get(TYPES.GetRequiredRoleToViewRevision)))
|
||||
|
||||
// ORM
|
||||
container
|
||||
@@ -136,6 +177,7 @@ export class ContainerConfigLoader {
|
||||
container.get(TYPES.ORMRevisionRepository),
|
||||
container.get(TYPES.RevisionMetadataPersistenceMapper),
|
||||
container.get(TYPES.RevisionPersistenceMapper),
|
||||
container.get(TYPES.Logger),
|
||||
),
|
||||
)
|
||||
if (env.get('S3_AWS_REGION', true)) {
|
||||
@@ -176,6 +218,8 @@ export class ContainerConfigLoader {
|
||||
container.get(TYPES.GetRevisionsMetada),
|
||||
container.get(TYPES.GetRevision),
|
||||
container.get(TYPES.DeleteRevision),
|
||||
container.get(TYPES.RevisionHttpMapper),
|
||||
container.get(TYPES.RevisionMetadataHttpMapper),
|
||||
container.get(TYPES.Logger),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -11,34 +11,45 @@ const maxQueryExecutionTime = env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
|
||||
? +env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
|
||||
: 45_000
|
||||
|
||||
export const AppDataSource = new DataSource({
|
||||
type: 'mysql',
|
||||
charset: 'utf8mb4',
|
||||
supportBigNumbers: true,
|
||||
bigNumberStrings: false,
|
||||
maxQueryExecutionTime,
|
||||
replication: {
|
||||
master: {
|
||||
host: env.get('DB_HOST'),
|
||||
const inReplicaMode = env.get('DB_REPLICA_HOST', true) ? true : false
|
||||
|
||||
const replicationConfig = {
|
||||
master: {
|
||||
host: env.get('DB_HOST'),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
slaves: [
|
||||
{
|
||||
host: env.get('DB_REPLICA_HOST', true),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
slaves: [
|
||||
{
|
||||
host: env.get('DB_REPLICA_HOST'),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
],
|
||||
removeNodeErrorCount: 10,
|
||||
restoreNodeTimeout: 5,
|
||||
},
|
||||
],
|
||||
removeNodeErrorCount: 10,
|
||||
restoreNodeTimeout: 5,
|
||||
}
|
||||
|
||||
const dataSource = new DataSource({
|
||||
type: 'mysql',
|
||||
charset: 'utf8mb4',
|
||||
supportBigNumbers: true,
|
||||
bigNumberStrings: false,
|
||||
maxQueryExecutionTime,
|
||||
replication: inReplicaMode ? replicationConfig : undefined,
|
||||
host: inReplicaMode ? undefined : env.get('DB_HOST'),
|
||||
port: inReplicaMode ? undefined : parseInt(env.get('DB_PORT')),
|
||||
username: inReplicaMode ? undefined : env.get('DB_USERNAME'),
|
||||
password: inReplicaMode ? undefined : env.get('DB_PASSWORD'),
|
||||
database: inReplicaMode ? undefined : env.get('DB_DATABASE'),
|
||||
entities: [TypeORMRevision],
|
||||
migrations: [env.get('DB_MIGRATIONS_PATH', true) ?? 'dist/migrations/*.js'],
|
||||
migrationsRun: true,
|
||||
logging: <LoggerOptions>env.get('DB_DEBUG_LEVEL'),
|
||||
})
|
||||
|
||||
export const AppDataSource = dataSource
|
||||
|
||||
@@ -8,6 +8,8 @@ const TYPES = {
|
||||
RevisionMetadataPersistenceMapper: Symbol.for('RevisionMetadataPersistenceMapper'),
|
||||
RevisionPersistenceMapper: Symbol.for('RevisionPersistenceMapper'),
|
||||
RevisionItemStringMapper: Symbol.for('RevisionItemStringMapper'),
|
||||
RevisionHttpMapper: Symbol.for('RevisionHttpMapper'),
|
||||
RevisionMetadataHttpMapper: Symbol.for('RevisionMetadataHttpMapper'),
|
||||
// ORM
|
||||
ORMRevisionRepository: Symbol.for('ORMRevisionRepository'),
|
||||
// Repositories
|
||||
@@ -28,6 +30,7 @@ const TYPES = {
|
||||
GetRevision: Symbol.for('GetRevision'),
|
||||
DeleteRevision: Symbol.for('DeleteRevision'),
|
||||
CopyRevisions: Symbol.for('CopyRevisions'),
|
||||
GetRequiredRoleToViewRevision: Symbol.for('GetRequiredRoleToViewRevision'),
|
||||
// Controller
|
||||
RevisionsController: Symbol.for('RevisionsController'),
|
||||
// Handlers
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
import { Result } from '@standardnotes/domain-core'
|
||||
import { Logger } from 'winston'
|
||||
|
||||
import { DeleteRevision } from '../Domain/UseCase/DeleteRevision/DeleteRevision'
|
||||
import { GetRevision } from '../Domain/UseCase/GetRevision/GetRevision'
|
||||
import { GetRevisionsMetada } from '../Domain/UseCase/GetRevisionsMetada/GetRevisionsMetada'
|
||||
|
||||
import { RevisionsController } from './RevisionsController'
|
||||
|
||||
describe('RevisionsController', () => {
|
||||
let getRevisionsMetadata: GetRevisionsMetada
|
||||
let getRevision: GetRevision
|
||||
let deleteRevision: DeleteRevision
|
||||
let logger: Logger
|
||||
|
||||
const createController = () => new RevisionsController(getRevisionsMetadata, getRevision, deleteRevision, logger)
|
||||
|
||||
beforeEach(() => {
|
||||
getRevisionsMetadata = {} as jest.Mocked<GetRevisionsMetada>
|
||||
getRevisionsMetadata.execute = jest.fn().mockReturnValue(Result.ok())
|
||||
|
||||
getRevision = {} as jest.Mocked<GetRevision>
|
||||
getRevision.execute = jest.fn().mockReturnValue(Result.ok())
|
||||
|
||||
deleteRevision = {} as jest.Mocked<DeleteRevision>
|
||||
deleteRevision.execute = jest.fn().mockReturnValue(Result.ok())
|
||||
|
||||
logger = {} as jest.Mocked<Logger>
|
||||
logger.warn = jest.fn()
|
||||
})
|
||||
|
||||
it('should get revisions list', async () => {
|
||||
const response = await createController().getRevisions({ itemUuid: '1-2-3', userUuid: '1-2-3' })
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
})
|
||||
|
||||
it('should indicate failure to get revisions list', async () => {
|
||||
getRevisionsMetadata.execute = jest.fn().mockReturnValue(Result.fail('Oops'))
|
||||
const response = await createController().getRevisions({ itemUuid: '1-2-3', userUuid: '1-2-3' })
|
||||
|
||||
expect(response.status).toEqual(400)
|
||||
})
|
||||
|
||||
it('should get revision', async () => {
|
||||
const response = await createController().getRevision({ revisionUuid: '1-2-3', userUuid: '1-2-3' })
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
})
|
||||
|
||||
it('should indicate failure to get revision', async () => {
|
||||
getRevision.execute = jest.fn().mockReturnValue(Result.fail('Oops'))
|
||||
const response = await createController().getRevision({ revisionUuid: '1-2-3', userUuid: '1-2-3' })
|
||||
|
||||
expect(response.status).toEqual(400)
|
||||
})
|
||||
|
||||
it('should delete revision', async () => {
|
||||
const response = await createController().deleteRevision({ revisionUuid: '1-2-3', userUuid: '1-2-3' })
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
})
|
||||
|
||||
it('should indicate failure to delete revision', async () => {
|
||||
deleteRevision.execute = jest.fn().mockReturnValue(Result.fail('Oops'))
|
||||
const response = await createController().deleteRevision({ revisionUuid: '1-2-3', userUuid: '1-2-3' })
|
||||
|
||||
expect(response.status).toEqual(400)
|
||||
})
|
||||
})
|
||||
@@ -9,12 +9,38 @@ import { GetRevision } from '../Domain/UseCase/GetRevision/GetRevision'
|
||||
import { DeleteRevision } from '../Domain/UseCase/DeleteRevision/DeleteRevision'
|
||||
import { GetRevisionsMetadataResponse } from '../Infra/Http/Response/GetRevisionsMetadataResponse'
|
||||
import { GetRevisionResponse } from '../Infra/Http/Response/GetRevisionResponse'
|
||||
import { MapperInterface } from '@standardnotes/domain-core'
|
||||
import { Revision } from '../Domain/Revision/Revision'
|
||||
import { RevisionMetadata } from '../Domain/Revision/RevisionMetadata'
|
||||
|
||||
export class RevisionsController {
|
||||
constructor(
|
||||
private getRevisionsMetadata: GetRevisionsMetada,
|
||||
private doGetRevision: GetRevision,
|
||||
private doDeleteRevision: DeleteRevision,
|
||||
private revisionHttpMapper: MapperInterface<
|
||||
Revision,
|
||||
{
|
||||
uuid: string
|
||||
itemUuid: string
|
||||
content: string | null
|
||||
contentType: string
|
||||
itemsKeyId: string | null
|
||||
encItemKey: string | null
|
||||
authHash: string | null
|
||||
createAt: string
|
||||
updateAt: string
|
||||
}
|
||||
>,
|
||||
private revisionMetadataHttpMapper: MapperInterface<
|
||||
RevisionMetadata,
|
||||
{
|
||||
uuid: string
|
||||
contentType: string
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
}
|
||||
>,
|
||||
private logger: Logger,
|
||||
) {}
|
||||
|
||||
@@ -37,9 +63,15 @@ export class RevisionsController {
|
||||
}
|
||||
}
|
||||
|
||||
const revisions = revisionMetadataOrError.getValue()
|
||||
|
||||
this.logger.debug(`Found ${revisions.length} revisions for item ${params.itemUuid}`)
|
||||
|
||||
return {
|
||||
status: HttpStatusCode.Success,
|
||||
data: { revisions: revisionMetadataOrError.getValue() },
|
||||
data: {
|
||||
revisions: revisions.map((revision) => this.revisionMetadataHttpMapper.toProjection(revision)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +96,7 @@ export class RevisionsController {
|
||||
|
||||
return {
|
||||
status: HttpStatusCode.Success,
|
||||
data: { revision: revisionOrError.getValue() },
|
||||
data: { revision: this.revisionHttpMapper.toProjection(revisionOrError.getValue()) },
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
|
||||
import { GetRequiredRoleToViewRevision } from './GetRequiredRoleToViewRevision'
|
||||
|
||||
describe('GetRequiredRoleToViewRevision', () => {
|
||||
let timer: TimerInterface
|
||||
|
||||
const createUseCase = () => new GetRequiredRoleToViewRevision(timer)
|
||||
|
||||
beforeEach(() => {
|
||||
timer = {} as jest.Mocked<TimerInterface>
|
||||
})
|
||||
|
||||
it('should return CoreUser if revision was created less than 30 days ago', () => {
|
||||
timer.dateWasNDaysAgo = jest.fn().mockReturnValue(29)
|
||||
|
||||
const useCase = createUseCase()
|
||||
|
||||
const result = useCase.execute({ createdAt: new Date() })
|
||||
|
||||
expect(result.getValue()).toEqual('CORE_USER')
|
||||
})
|
||||
|
||||
it('should return PlusUser if revision was created more than 30 days ago and less than 365 days ago', () => {
|
||||
timer.dateWasNDaysAgo = jest.fn().mockReturnValue(31)
|
||||
|
||||
const useCase = createUseCase()
|
||||
|
||||
const result = useCase.execute({ createdAt: new Date() })
|
||||
|
||||
expect(result.getValue()).toEqual('PLUS_USER')
|
||||
})
|
||||
|
||||
it('should return ProUser if revision was created more than 365 days ago', () => {
|
||||
timer.dateWasNDaysAgo = jest.fn().mockReturnValue(366)
|
||||
|
||||
const useCase = createUseCase()
|
||||
|
||||
const result = useCase.execute({ createdAt: new Date() })
|
||||
|
||||
expect(result.getValue()).toEqual('PRO_USER')
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,22 @@
|
||||
import { Result, RoleName, SyncUseCaseInterface } from '@standardnotes/domain-core'
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
|
||||
import { GetRequiredRoleToViewRevisionDTO } from './GetRequiredRoleToViewRevisionDTO'
|
||||
|
||||
export class GetRequiredRoleToViewRevision implements SyncUseCaseInterface<string> {
|
||||
constructor(private timer: TimerInterface) {}
|
||||
|
||||
execute(dto: GetRequiredRoleToViewRevisionDTO): Result<string> {
|
||||
const revisionCreatedNDaysAgo = this.timer.dateWasNDaysAgo(dto.createdAt)
|
||||
|
||||
if (revisionCreatedNDaysAgo > 30 && revisionCreatedNDaysAgo < 365) {
|
||||
return Result.ok(RoleName.NAMES.PlusUser)
|
||||
}
|
||||
|
||||
if (revisionCreatedNDaysAgo > 365) {
|
||||
return Result.ok(RoleName.NAMES.ProUser)
|
||||
}
|
||||
|
||||
return Result.ok(RoleName.NAMES.CoreUser)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export interface GetRequiredRoleToViewRevisionDTO {
|
||||
createdAt: Date
|
||||
}
|
||||
@@ -1,5 +1,13 @@
|
||||
import { Revision } from '../../../Domain/Revision/Revision'
|
||||
|
||||
export interface GetRevisionResponseBody {
|
||||
revision: Revision
|
||||
revision: {
|
||||
uuid: string
|
||||
itemUuid: string
|
||||
content: string | null
|
||||
contentType: string
|
||||
itemsKeyId: string | null
|
||||
encItemKey: string | null
|
||||
authHash: string | null
|
||||
createAt: string
|
||||
updateAt: string
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { RevisionMetadata } from '../../../Domain/Revision/RevisionMetadata'
|
||||
|
||||
export interface GetRevisionsMetadataResponseBody {
|
||||
revisions: Array<RevisionMetadata>
|
||||
revisions: Array<{
|
||||
uuid: string
|
||||
contentType: string
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
}>
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ export class InversifyExpressRevisionsController extends BaseHttpController {
|
||||
userUuid: response.locals.user.uuid,
|
||||
})
|
||||
|
||||
return this.json(result.data.error ? result.data : result.data.revisions, result.status)
|
||||
return this.json(result.data, result.status)
|
||||
}
|
||||
|
||||
@httpGet('/:uuid')
|
||||
@@ -28,7 +28,7 @@ export class InversifyExpressRevisionsController extends BaseHttpController {
|
||||
userUuid: response.locals.user.uuid,
|
||||
})
|
||||
|
||||
return this.json(result.data.error ? result.data : result.data.revision, result.status)
|
||||
return this.json(result.data, result.status)
|
||||
}
|
||||
|
||||
@httpDelete('/:uuid')
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { MapperInterface, Uuid } from '@standardnotes/domain-core'
|
||||
import { Repository } from 'typeorm'
|
||||
import { Logger } from 'winston'
|
||||
|
||||
import { Revision } from '../../Domain/Revision/Revision'
|
||||
import { RevisionMetadata } from '../../Domain/Revision/RevisionMetadata'
|
||||
@@ -11,6 +12,7 @@ export class MySQLRevisionRepository implements RevisionRepositoryInterface {
|
||||
private ormRepository: Repository<TypeORMRevision>,
|
||||
private revisionMetadataMapper: MapperInterface<RevisionMetadata, TypeORMRevision>,
|
||||
private revisionMapper: MapperInterface<Revision, TypeORMRevision>,
|
||||
private logger: Logger,
|
||||
) {}
|
||||
|
||||
async updateUserUuid(itemUuid: Uuid, userUuid: Uuid): Promise<void> {
|
||||
@@ -92,7 +94,12 @@ export class MySQLRevisionRepository implements RevisionRepositoryInterface {
|
||||
.andWhere('user_uuid = :userUuid', { userUuid: userUuid.value })
|
||||
.orderBy('created_at', 'DESC')
|
||||
|
||||
const simplifiedRevisions = await queryBuilder.getMany()
|
||||
const simplifiedRevisions = await queryBuilder.getRawMany()
|
||||
|
||||
this.logger.debug(
|
||||
`Found ${simplifiedRevisions.length} revisions MySQL entries for item ${itemUuid.value}`,
|
||||
simplifiedRevisions,
|
||||
)
|
||||
|
||||
const metadata = []
|
||||
for (const simplifiedRevision of simplifiedRevisions) {
|
||||
|
||||
59
packages/revisions/src/Mapping/RevisionHttpMapper.ts
Normal file
59
packages/revisions/src/Mapping/RevisionHttpMapper.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { MapperInterface } from '@standardnotes/domain-core'
|
||||
|
||||
import { Revision } from '../Domain/Revision/Revision'
|
||||
|
||||
export class RevisionHttpMapper
|
||||
implements
|
||||
MapperInterface<
|
||||
Revision,
|
||||
{
|
||||
uuid: string
|
||||
item_uuid: string
|
||||
content: string | null
|
||||
content_type: string
|
||||
items_key_id: string | null
|
||||
enc_item_key: string | null
|
||||
auth_hash: string | null
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
>
|
||||
{
|
||||
toDomain(_projection: {
|
||||
uuid: string
|
||||
item_uuid: string
|
||||
content: string | null
|
||||
content_type: string
|
||||
items_key_id: string | null
|
||||
enc_item_key: string | null
|
||||
auth_hash: string | null
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}): Revision {
|
||||
throw new Error('Method not implemented.')
|
||||
}
|
||||
|
||||
toProjection(domain: Revision): {
|
||||
uuid: string
|
||||
item_uuid: string
|
||||
content: string | null
|
||||
content_type: string
|
||||
items_key_id: string | null
|
||||
enc_item_key: string | null
|
||||
auth_hash: string | null
|
||||
created_at: string
|
||||
updated_at: string
|
||||
} {
|
||||
return {
|
||||
uuid: domain.id.toString(),
|
||||
item_uuid: domain.props.itemUuid.value,
|
||||
content: domain.props.content,
|
||||
content_type: domain.props.contentType.value as string,
|
||||
items_key_id: domain.props.itemsKeyId,
|
||||
enc_item_key: domain.props.encItemKey,
|
||||
auth_hash: domain.props.authHash,
|
||||
created_at: domain.props.dates.createdAt.toISOString(),
|
||||
updated_at: domain.props.dates.updatedAt.toISOString(),
|
||||
}
|
||||
}
|
||||
}
|
||||
45
packages/revisions/src/Mapping/RevisionMetadataHttpMapper.ts
Normal file
45
packages/revisions/src/Mapping/RevisionMetadataHttpMapper.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { MapperInterface, SyncUseCaseInterface } from '@standardnotes/domain-core'
|
||||
|
||||
import { RevisionMetadata } from '../Domain/Revision/RevisionMetadata'
|
||||
|
||||
export class RevisionMetadataHttpMapper
|
||||
implements
|
||||
MapperInterface<
|
||||
RevisionMetadata,
|
||||
{
|
||||
uuid: string
|
||||
content_type: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
required_role: string
|
||||
}
|
||||
>
|
||||
{
|
||||
constructor(private getRequiredRoleToViewRevision: SyncUseCaseInterface<string>) {}
|
||||
|
||||
toDomain(_projection: {
|
||||
uuid: string
|
||||
content_type: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
required_role: string
|
||||
}): RevisionMetadata {
|
||||
throw new Error('Method not implemented.')
|
||||
}
|
||||
|
||||
toProjection(domain: RevisionMetadata): {
|
||||
uuid: string
|
||||
content_type: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
required_role: string
|
||||
} {
|
||||
return {
|
||||
uuid: domain.id.toString(),
|
||||
content_type: domain.props.contentType.value as string,
|
||||
created_at: domain.props.dates.createdAt.toISOString(),
|
||||
updated_at: domain.props.dates.updatedAt.toISOString(),
|
||||
required_role: this.getRequiredRoleToViewRevision.execute({ createdAt: domain.props.dates.createdAt }).getValue(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,24 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.16.9](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.16.8...@standardnotes/scheduler-server@1.16.9) (2023-01-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
## [1.16.8](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.16.7...@standardnotes/scheduler-server@1.16.8) (2023-01-17)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* allow to run typeorm in non-replica mode ([f73129c](https://github.com/standardnotes/server/commit/f73129cd7e7d6a9b8a63e5c80284467597557982))
|
||||
|
||||
## [1.16.7](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.16.6...@standardnotes/scheduler-server@1.16.7) (2023-01-16)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
## [1.16.6](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.16.5...@standardnotes/scheduler-server@1.16.6) (2023-01-13)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
## [1.16.5](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.16.4...@standardnotes/scheduler-server@1.16.5) (2023-01-06)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/scheduler-server",
|
||||
"version": "1.16.5",
|
||||
"version": "1.16.9",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
@@ -37,7 +37,7 @@
|
||||
"dotenv": "^16.0.1",
|
||||
"inversify": "^6.0.1",
|
||||
"ioredis": "^5.2.4",
|
||||
"mysql2": "^2.3.3",
|
||||
"mysql2": "^3.0.1",
|
||||
"newrelic": "^9.6.0",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"typeorm": "^0.3.10",
|
||||
|
||||
@@ -10,31 +10,41 @@ const maxQueryExecutionTime = env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
|
||||
? +env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
|
||||
: 45_000
|
||||
|
||||
const inReplicaMode = env.get('DB_REPLICA_HOST', true) ? true : false
|
||||
|
||||
const replicationConfig = {
|
||||
master: {
|
||||
host: env.get('DB_HOST'),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
slaves: [
|
||||
{
|
||||
host: env.get('DB_REPLICA_HOST', true),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
],
|
||||
removeNodeErrorCount: 10,
|
||||
restoreNodeTimeout: 5,
|
||||
}
|
||||
|
||||
export const AppDataSource = new DataSource({
|
||||
type: 'mysql',
|
||||
charset: 'utf8mb4',
|
||||
supportBigNumbers: true,
|
||||
bigNumberStrings: false,
|
||||
maxQueryExecutionTime,
|
||||
replication: {
|
||||
master: {
|
||||
host: env.get('DB_HOST'),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
slaves: [
|
||||
{
|
||||
host: env.get('DB_REPLICA_HOST'),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
],
|
||||
removeNodeErrorCount: 10,
|
||||
},
|
||||
replication: inReplicaMode ? replicationConfig : undefined,
|
||||
host: inReplicaMode ? undefined : env.get('DB_HOST'),
|
||||
port: inReplicaMode ? undefined : parseInt(env.get('DB_PORT')),
|
||||
username: inReplicaMode ? undefined : env.get('DB_USERNAME'),
|
||||
password: inReplicaMode ? undefined : env.get('DB_PASSWORD'),
|
||||
database: inReplicaMode ? undefined : env.get('DB_DATABASE'),
|
||||
entities: [Job, Predicate],
|
||||
migrations: [env.get('DB_MIGRATIONS_PATH', true) ?? 'dist/migrations/*.js'],
|
||||
migrationsRun: true,
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.7.3](https://github.com/standardnotes/server/compare/@standardnotes/security@1.7.2...@standardnotes/security@1.7.3) (2023-01-13)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/security
|
||||
|
||||
## [1.7.2](https://github.com/standardnotes/server/compare/@standardnotes/security@1.7.1...@standardnotes/security@1.7.2) (2022-11-25)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/security
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/security",
|
||||
"version": "1.7.2",
|
||||
"version": "1.7.3",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
@@ -26,12 +26,12 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@standardnotes/common": "workspace:*",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"reflect-metadata": "^0.1.13"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.1.1",
|
||||
"@types/jsonwebtoken": "^8.5.8",
|
||||
"@types/jsonwebtoken": "^9.0.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.30.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"jest": "^29.1.2",
|
||||
|
||||
@@ -3,6 +3,31 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.28.10](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.28.9...@standardnotes/syncing-server@1.28.10) (2023-01-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/syncing-server
|
||||
|
||||
## [1.28.9](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.28.8...@standardnotes/syncing-server@1.28.9) (2023-01-17)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* allow to run typeorm in non-replica mode ([f73129c](https://github.com/standardnotes/syncing-server-js/commit/f73129cd7e7d6a9b8a63e5c80284467597557982))
|
||||
|
||||
## [1.28.8](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.28.7...@standardnotes/syncing-server@1.28.8) (2023-01-17)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **syncing-server-js:** add debug logs for dumping items for revisions creation ([8db19c3](https://github.com/standardnotes/syncing-server-js/commit/8db19c3e2b55af9230b92621f01ae0d7c514913a))
|
||||
* **syncing-server-js:** creating directory for revision dumps ([9b926fb](https://github.com/standardnotes/syncing-server-js/commit/9b926fbad6c40a2e3792cc0d7c54987febd6dced))
|
||||
|
||||
## [1.28.7](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.28.6...@standardnotes/syncing-server@1.28.7) (2023-01-16)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/syncing-server
|
||||
|
||||
## [1.28.6](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.28.5...@standardnotes/syncing-server@1.28.6) (2023-01-13)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/syncing-server
|
||||
|
||||
## [1.28.5](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.28.4...@standardnotes/syncing-server@1.28.5) (2023-01-04)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/syncing-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/syncing-server",
|
||||
"version": "1.28.5",
|
||||
"version": "1.28.10",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
@@ -47,8 +47,8 @@
|
||||
"inversify": "^6.0.1",
|
||||
"inversify-express-utils": "^6.4.3",
|
||||
"ioredis": "^5.2.4",
|
||||
"jsonwebtoken": "8.5.1",
|
||||
"mysql2": "^2.3.3",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"mysql2": "^3.0.1",
|
||||
"newrelic": "^9.6.0",
|
||||
"nodemon": "^2.0.19",
|
||||
"prettyjson": "^1.2.5",
|
||||
@@ -65,7 +65,7 @@
|
||||
"@types/inversify-express-utils": "^2.0.0",
|
||||
"@types/ioredis": "^5.0.0",
|
||||
"@types/jest": "^29.1.1",
|
||||
"@types/jsonwebtoken": "^8.5.0",
|
||||
"@types/jsonwebtoken": "^9.0.1",
|
||||
"@types/newrelic": "^7.0.4",
|
||||
"@types/prettyjson": "^0.0.30",
|
||||
"@types/ua-parser-js": "^0.7.36",
|
||||
|
||||
@@ -10,32 +10,41 @@ const maxQueryExecutionTime = env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
|
||||
? +env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
|
||||
: 45_000
|
||||
|
||||
const inReplicaMode = env.get('DB_REPLICA_HOST', true) ? true : false
|
||||
|
||||
const replicationConfig = {
|
||||
master: {
|
||||
host: env.get('DB_HOST'),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
slaves: [
|
||||
{
|
||||
host: env.get('DB_REPLICA_HOST', true),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
],
|
||||
removeNodeErrorCount: 10,
|
||||
restoreNodeTimeout: 5,
|
||||
}
|
||||
|
||||
export const AppDataSource = new DataSource({
|
||||
type: 'mysql',
|
||||
charset: 'utf8mb4',
|
||||
supportBigNumbers: true,
|
||||
bigNumberStrings: false,
|
||||
maxQueryExecutionTime,
|
||||
replication: {
|
||||
master: {
|
||||
host: env.get('DB_HOST'),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
slaves: [
|
||||
{
|
||||
host: env.get('DB_REPLICA_HOST'),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
],
|
||||
removeNodeErrorCount: 10,
|
||||
restoreNodeTimeout: 5,
|
||||
},
|
||||
replication: inReplicaMode ? replicationConfig : undefined,
|
||||
host: inReplicaMode ? undefined : env.get('DB_HOST'),
|
||||
port: inReplicaMode ? undefined : parseInt(env.get('DB_PORT')),
|
||||
username: inReplicaMode ? undefined : env.get('DB_USERNAME'),
|
||||
password: inReplicaMode ? undefined : env.get('DB_PASSWORD'),
|
||||
database: inReplicaMode ? undefined : env.get('DB_DATABASE'),
|
||||
entities: [Item, Revision],
|
||||
migrations: [env.get('DB_MIGRATIONS_PATH', true) ?? 'dist/migrations/*.js'],
|
||||
migrationsRun: true,
|
||||
|
||||
@@ -2,6 +2,8 @@ import { KeyParamsData } from '@standardnotes/responses'
|
||||
import { promises } from 'fs'
|
||||
import * as uuid from 'uuid'
|
||||
import { inject, injectable } from 'inversify'
|
||||
import { Logger } from 'winston'
|
||||
import { dirname } from 'path'
|
||||
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { Item } from '../../Domain/Item/Item'
|
||||
@@ -14,6 +16,7 @@ export class FSItemBackupService implements ItemBackupServiceInterface {
|
||||
constructor(
|
||||
@inject(TYPES.FILE_UPLOAD_PATH) private fileUploadPath: string,
|
||||
@inject(TYPES.ItemProjector) private itemProjector: ProjectorInterface<Item, ItemProjection>,
|
||||
@inject(TYPES.Logger) private logger: Logger,
|
||||
) {}
|
||||
|
||||
async backup(_items: Item[], _authParams: KeyParamsData): Promise<string> {
|
||||
@@ -27,6 +30,10 @@ export class FSItemBackupService implements ItemBackupServiceInterface {
|
||||
|
||||
const path = `${this.fileUploadPath}/dumps/${uuid.v4()}`
|
||||
|
||||
this.logger.debug(`Dumping item ${item.uuid} to ${path}`)
|
||||
|
||||
await promises.mkdir(dirname(path), { recursive: true })
|
||||
|
||||
await promises.writeFile(path, contents)
|
||||
|
||||
return path
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.5.5](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.5.4...@standardnotes/websockets-server@1.5.5) (2023-01-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/websockets-server
|
||||
|
||||
## [1.5.4](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.5.3...@standardnotes/websockets-server@1.5.4) (2023-01-13)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/websockets-server
|
||||
|
||||
## [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,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/websockets-server",
|
||||
"version": "1.5.3",
|
||||
"version": "1.5.5",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
@@ -37,7 +37,7 @@
|
||||
"inversify": "^6.0.1",
|
||||
"inversify-express-utils": "^6.4.3",
|
||||
"ioredis": "^5.2.4",
|
||||
"mysql2": "^2.3.3",
|
||||
"mysql2": "^3.0.1",
|
||||
"newrelic": "^9.6.0",
|
||||
"reflect-metadata": "0.1.13",
|
||||
"typeorm": "^0.3.10",
|
||||
|
||||
@@ -3,6 +3,24 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.19.8](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.7...@standardnotes/workspace-server@1.19.8) (2023-01-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/workspace-server
|
||||
|
||||
## [1.19.7](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.6...@standardnotes/workspace-server@1.19.7) (2023-01-17)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* allow to run typeorm in non-replica mode ([f73129c](https://github.com/standardnotes/server/commit/f73129cd7e7d6a9b8a63e5c80284467597557982))
|
||||
|
||||
## [1.19.6](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.5...@standardnotes/workspace-server@1.19.6) (2023-01-16)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/workspace-server
|
||||
|
||||
## [1.19.5](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.19.4...@standardnotes/workspace-server@1.19.5) (2023-01-13)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/workspace-server
|
||||
|
||||
## [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,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/workspace-server",
|
||||
"version": "1.19.4",
|
||||
"version": "1.19.8",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
@@ -39,7 +39,7 @@
|
||||
"inversify": "^6.0.1",
|
||||
"inversify-express-utils": "^6.4.3",
|
||||
"ioredis": "^5.2.4",
|
||||
"mysql2": "^2.3.3",
|
||||
"mysql2": "^3.0.1",
|
||||
"newrelic": "^9.6.0",
|
||||
"reflect-metadata": "0.1.13",
|
||||
"typeorm": "^0.3.10",
|
||||
|
||||
@@ -11,31 +11,41 @@ const maxQueryExecutionTime = env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
|
||||
? +env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
|
||||
: 45_000
|
||||
|
||||
const inReplicaMode = env.get('DB_REPLICA_HOST', true) ? true : false
|
||||
|
||||
const replicationConfig = {
|
||||
master: {
|
||||
host: env.get('DB_HOST'),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
slaves: [
|
||||
{
|
||||
host: env.get('DB_REPLICA_HOST', true),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
],
|
||||
removeNodeErrorCount: 10,
|
||||
restoreNodeTimeout: 5,
|
||||
}
|
||||
|
||||
export const AppDataSource = new DataSource({
|
||||
type: 'mysql',
|
||||
charset: 'utf8mb4',
|
||||
supportBigNumbers: true,
|
||||
bigNumberStrings: false,
|
||||
maxQueryExecutionTime,
|
||||
replication: {
|
||||
master: {
|
||||
host: env.get('DB_HOST'),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
slaves: [
|
||||
{
|
||||
host: env.get('DB_REPLICA_HOST'),
|
||||
port: parseInt(env.get('DB_PORT')),
|
||||
username: env.get('DB_USERNAME'),
|
||||
password: env.get('DB_PASSWORD'),
|
||||
database: env.get('DB_DATABASE'),
|
||||
},
|
||||
],
|
||||
removeNodeErrorCount: 10,
|
||||
},
|
||||
replication: inReplicaMode ? replicationConfig : undefined,
|
||||
host: inReplicaMode ? undefined : env.get('DB_HOST'),
|
||||
port: inReplicaMode ? undefined : parseInt(env.get('DB_PORT')),
|
||||
username: inReplicaMode ? undefined : env.get('DB_USERNAME'),
|
||||
password: inReplicaMode ? undefined : env.get('DB_PASSWORD'),
|
||||
database: inReplicaMode ? undefined : env.get('DB_DATABASE'),
|
||||
entities: [Workspace, WorkspaceUser, WorkspaceInvite],
|
||||
migrations: [env.get('DB_MIGRATIONS_PATH', true) ?? 'dist/migrations/*.js'],
|
||||
migrationsRun: true,
|
||||
|
||||
142
yarn.lock
142
yarn.lock
@@ -1893,7 +1893,7 @@ __metadata:
|
||||
ioredis: "npm:^5.2.4"
|
||||
jest: "npm:^29.1.2"
|
||||
mixpanel: "npm:^0.17.0"
|
||||
mysql2: "npm:^2.3.3"
|
||||
mysql2: "npm:^3.0.1"
|
||||
newrelic: "npm:^9.6.0"
|
||||
reflect-metadata: "npm:^0.1.13"
|
||||
ts-jest: "npm:^29.0.3"
|
||||
@@ -1918,7 +1918,7 @@ __metadata:
|
||||
"@types/express": "npm:^4.17.14"
|
||||
"@types/ioredis": "npm:^5.0.0"
|
||||
"@types/jest": "npm:^29.1.1"
|
||||
"@types/jsonwebtoken": "npm:^8.5.0"
|
||||
"@types/jsonwebtoken": "npm:^9.0.1"
|
||||
"@types/newrelic": "npm:^7.0.4"
|
||||
"@types/prettyjson": "npm:^0.0.30"
|
||||
"@typescript-eslint/eslint-plugin": "npm:^5.29.0"
|
||||
@@ -1929,12 +1929,13 @@ __metadata:
|
||||
eslint: "npm:^8.14.0"
|
||||
eslint-plugin-prettier: "npm:^4.0.0"
|
||||
express: "npm:^4.18.2"
|
||||
express-robots-txt: "npm:^1.0.0"
|
||||
helmet: "npm:^6.0.0"
|
||||
inversify: "npm:^6.0.1"
|
||||
inversify-express-utils: "npm:^6.4.3"
|
||||
ioredis: "npm:^5.2.4"
|
||||
jest: "npm:^29.1.2"
|
||||
jsonwebtoken: "npm:8.5.1"
|
||||
jsonwebtoken: "npm:^9.0.0"
|
||||
newrelic: "npm:^9.6.0"
|
||||
nodemon: "npm:^2.0.19"
|
||||
npm-check-updates: "npm:^16.0.1"
|
||||
@@ -2007,7 +2008,7 @@ __metadata:
|
||||
inversify-express-utils: "npm:^6.4.3"
|
||||
ioredis: "npm:^5.2.4"
|
||||
jest: "npm:^29.1.2"
|
||||
mysql2: "npm:^2.3.3"
|
||||
mysql2: "npm:^3.0.1"
|
||||
newrelic: "npm:^9.6.0"
|
||||
nodemon: "npm:^2.0.19"
|
||||
npm-check-updates: "npm:^16.0.1"
|
||||
@@ -2151,7 +2152,7 @@ __metadata:
|
||||
inversify: "npm:^6.0.1"
|
||||
ioredis: "npm:^5.2.4"
|
||||
jest: "npm:^29.1.2"
|
||||
mysql2: "npm:^2.3.3"
|
||||
mysql2: "npm:^3.0.1"
|
||||
newrelic: "npm:^9.6.0"
|
||||
reflect-metadata: "npm:0.1.13"
|
||||
ts-jest: "npm:^29.0.3"
|
||||
@@ -2203,7 +2204,7 @@ __metadata:
|
||||
"@types/express": "npm:^4.17.14"
|
||||
"@types/ioredis": "npm:^5.0.0"
|
||||
"@types/jest": "npm:^29.1.1"
|
||||
"@types/jsonwebtoken": "npm:^8.5.0"
|
||||
"@types/jsonwebtoken": "npm:^9.0.1"
|
||||
"@types/newrelic": "npm:^7.0.4"
|
||||
"@types/prettyjson": "npm:^0.0.30"
|
||||
"@types/uuid": "npm:^8.3.0"
|
||||
@@ -2216,13 +2217,14 @@ __metadata:
|
||||
eslint: "npm:^8.14.0"
|
||||
eslint-plugin-prettier: "npm:^4.0.0"
|
||||
express: "npm:^4.18.2"
|
||||
express-robots-txt: "npm:^1.0.0"
|
||||
express-winston: "npm:^4.0.5"
|
||||
helmet: "npm:^6.0.0"
|
||||
inversify: "npm:^6.0.1"
|
||||
inversify-express-utils: "npm:^6.4.3"
|
||||
ioredis: "npm:^5.2.4"
|
||||
jest: "npm:^29.1.2"
|
||||
jsonwebtoken: "npm:^8.5.1"
|
||||
jsonwebtoken: "npm:^9.0.0"
|
||||
newrelic: "npm:^9.6.0"
|
||||
nodemon: "npm:^2.0.19"
|
||||
npm-check-updates: "npm:^16.0.1"
|
||||
@@ -2346,7 +2348,7 @@ __metadata:
|
||||
inversify-express-utils: "npm:^6.4.3"
|
||||
ioredis: "npm:^5.2.4"
|
||||
jest: "npm:^29.1.2"
|
||||
mysql2: "npm:^2.3.3"
|
||||
mysql2: "npm:^3.0.1"
|
||||
newrelic: "npm:^9.6.0"
|
||||
npm-check-updates: "npm:^16.0.1"
|
||||
reflect-metadata: "npm:0.1.13"
|
||||
@@ -2382,7 +2384,7 @@ __metadata:
|
||||
inversify: "npm:^6.0.1"
|
||||
ioredis: "npm:^5.2.4"
|
||||
jest: "npm:^29.1.2"
|
||||
mysql2: "npm:^2.3.3"
|
||||
mysql2: "npm:^3.0.1"
|
||||
newrelic: "npm:^9.6.0"
|
||||
npm-check-updates: "npm:^16.0.1"
|
||||
reflect-metadata: "npm:^0.1.13"
|
||||
@@ -2399,11 +2401,11 @@ __metadata:
|
||||
dependencies:
|
||||
"@standardnotes/common": "workspace:*"
|
||||
"@types/jest": "npm:^29.1.1"
|
||||
"@types/jsonwebtoken": "npm:^8.5.8"
|
||||
"@types/jsonwebtoken": "npm:^9.0.1"
|
||||
"@typescript-eslint/eslint-plugin": "npm:^5.30.0"
|
||||
eslint-plugin-prettier: "npm:^4.2.1"
|
||||
jest: "npm:^29.1.2"
|
||||
jsonwebtoken: "npm:^8.5.1"
|
||||
jsonwebtoken: "npm:^9.0.0"
|
||||
reflect-metadata: "npm:^0.1.13"
|
||||
ts-jest: "npm:^29.0.3"
|
||||
typescript: "npm:^4.8.4"
|
||||
@@ -2495,7 +2497,7 @@ __metadata:
|
||||
"@types/inversify-express-utils": "npm:^2.0.0"
|
||||
"@types/ioredis": "npm:^5.0.0"
|
||||
"@types/jest": "npm:^29.1.1"
|
||||
"@types/jsonwebtoken": "npm:^8.5.0"
|
||||
"@types/jsonwebtoken": "npm:^9.0.1"
|
||||
"@types/newrelic": "npm:^7.0.4"
|
||||
"@types/prettyjson": "npm:^0.0.30"
|
||||
"@types/ua-parser-js": "npm:^0.7.36"
|
||||
@@ -2513,8 +2515,8 @@ __metadata:
|
||||
inversify-express-utils: "npm:^6.4.3"
|
||||
ioredis: "npm:^5.2.4"
|
||||
jest: "npm:^29.1.2"
|
||||
jsonwebtoken: "npm:8.5.1"
|
||||
mysql2: "npm:^2.3.3"
|
||||
jsonwebtoken: "npm:^9.0.0"
|
||||
mysql2: "npm:^3.0.1"
|
||||
newrelic: "npm:^9.6.0"
|
||||
nodemon: "npm:^2.0.19"
|
||||
npm-check-updates: "npm:^16.0.1"
|
||||
@@ -2598,7 +2600,7 @@ __metadata:
|
||||
inversify-express-utils: "npm:^6.4.3"
|
||||
ioredis: "npm:^5.2.4"
|
||||
jest: "npm:^29.1.2"
|
||||
mysql2: "npm:^2.3.3"
|
||||
mysql2: "npm:^3.0.1"
|
||||
newrelic: "npm:^9.6.0"
|
||||
reflect-metadata: "npm:0.1.13"
|
||||
ts-jest: "npm:^29.0.3"
|
||||
@@ -2638,7 +2640,7 @@ __metadata:
|
||||
inversify-express-utils: "npm:^6.4.3"
|
||||
ioredis: "npm:^5.2.4"
|
||||
jest: "npm:^29.1.2"
|
||||
mysql2: "npm:^2.3.3"
|
||||
mysql2: "npm:^3.0.1"
|
||||
newrelic: "npm:^9.6.0"
|
||||
reflect-metadata: "npm:0.1.13"
|
||||
ts-jest: "npm:^29.0.3"
|
||||
@@ -2913,12 +2915,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/jsonwebtoken@npm:^8.5.0, @types/jsonwebtoken@npm:^8.5.8":
|
||||
version: 8.5.9
|
||||
resolution: "@types/jsonwebtoken@npm:8.5.9"
|
||||
"@types/jsonwebtoken@npm:^9.0.1":
|
||||
version: 9.0.1
|
||||
resolution: "@types/jsonwebtoken@npm:9.0.1"
|
||||
dependencies:
|
||||
"@types/node": "npm:*"
|
||||
checksum: 3f15a76cd58fb56272cdcb1cf475e8f03b3127000ed9c49670b7be450a24460edeef6fa69837bb7feee554c1ead7d9ff4584eef0ea48d810282872dcfa03508e
|
||||
checksum: 44d3fccc6b35826ad231012e5b25f82d9ec9c5790b2c41263bb5095673a8bd57ea19c1969ec3849d07c036bb95c992655b70265a2e456b83f6fa2cb137a7670e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -4928,7 +4930,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"denque@npm:^2.0.1":
|
||||
"denque@npm:^2.0.1, denque@npm:^2.1.0":
|
||||
version: 2.1.0
|
||||
resolution: "denque@npm:2.1.0"
|
||||
checksum: 7e1c278144b7c5047ff46783edf7d736193644abbdea1c788e1b686b402b7669fcf417e168c9a9ccd8a346ff0d1e1b15696177e2b231fd1af66ee03c072b4066
|
||||
@@ -5580,6 +5582,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"express-robots-txt@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "express-robots-txt@npm:1.0.0"
|
||||
peerDependencies:
|
||||
express: ^4.12.1
|
||||
checksum: 54f066f6c305694ea2082d2b0a46bab8dcbf2b478780cf3f1bc404a5d8c83a4e2d6f06e15b42f0aec2c8866ffb97150487e0bb9abdd9604fa78ea68950946b43
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"express-winston@npm:^4.0.5":
|
||||
version: 4.2.0
|
||||
resolution: "express-winston@npm:4.2.0"
|
||||
@@ -7753,7 +7764,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"jsonwebtoken@npm:8.5.1, jsonwebtoken@npm:^8.5.1":
|
||||
"jsonwebtoken@npm:^8.5.1":
|
||||
version: 8.5.1
|
||||
resolution: "jsonwebtoken@npm:8.5.1"
|
||||
dependencies:
|
||||
@@ -7771,6 +7782,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"jsonwebtoken@npm:^9.0.0":
|
||||
version: 9.0.0
|
||||
resolution: "jsonwebtoken@npm:9.0.0"
|
||||
dependencies:
|
||||
jws: "npm:^3.2.2"
|
||||
lodash: "npm:^4.17.21"
|
||||
ms: "npm:^2.1.1"
|
||||
semver: "npm:^7.3.8"
|
||||
checksum: 7ccbd0b7bf6a8058458d84cf7551a96a9ad7c31094b9a1b83d90728b8008e5e3c42c8acb324b08511affef5d088d49499fe08e23b3347010ed2c1a069622066c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"jsrsasign@npm:^10.4.0":
|
||||
version: 10.6.1
|
||||
resolution: "jsrsasign@npm:10.6.1"
|
||||
@@ -8086,6 +8109,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"long@npm:^5.2.1":
|
||||
version: 5.2.1
|
||||
resolution: "long@npm:5.2.1"
|
||||
checksum: f81b18ff295bd2c97e6704ba9d38d787db014e26ccdb897f37a4448d8562a2fdd040bc19ba8aa20708cfd369fa051a001e22e23dbcf0fc85fcb8968e11ce1ee3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lowercase-keys@npm:^2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "lowercase-keys@npm:2.0.0"
|
||||
@@ -8100,16 +8130,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lru-cache@npm:^4.1.3":
|
||||
version: 4.1.5
|
||||
resolution: "lru-cache@npm:4.1.5"
|
||||
dependencies:
|
||||
pseudomap: "npm:^1.0.2"
|
||||
yallist: "npm:^2.1.2"
|
||||
checksum: 796f26ad9207f9f8654ff8784dcfcb6b86ec3fc5110389eb03ac0e898da22af566cefd5821062e3edba267ae869f86078aa9b74e5b74962c7cf8f943182f87dc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lru-cache@npm:^6.0.0":
|
||||
version: 6.0.0
|
||||
resolution: "lru-cache@npm:6.0.0"
|
||||
@@ -8119,6 +8139,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lru-cache@npm:^7.14.1":
|
||||
version: 7.14.1
|
||||
resolution: "lru-cache@npm:7.14.1"
|
||||
checksum: e4c8c073d9632585dde73bb2c857c22866f61f3ee75fea6e1dcc5412b59eca4107bc511c4b4ae4e038c7f59a15488b67448b24a3a1154def46c8ab1d07935d85
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lru-cache@npm:^7.4.4, lru-cache@npm:^7.5.1, lru-cache@npm:^7.7.1":
|
||||
version: 7.12.0
|
||||
resolution: "lru-cache@npm:7.12.0"
|
||||
@@ -8530,19 +8557,19 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"mysql2@npm:^2.3.3":
|
||||
version: 2.3.3
|
||||
resolution: "mysql2@npm:2.3.3"
|
||||
"mysql2@npm:^3.0.1":
|
||||
version: 3.0.1
|
||||
resolution: "mysql2@npm:3.0.1"
|
||||
dependencies:
|
||||
denque: "npm:^2.0.1"
|
||||
denque: "npm:^2.1.0"
|
||||
generate-function: "npm:^2.3.1"
|
||||
iconv-lite: "npm:^0.6.3"
|
||||
long: "npm:^4.0.0"
|
||||
lru-cache: "npm:^6.0.0"
|
||||
named-placeholders: "npm:^1.1.2"
|
||||
long: "npm:^5.2.1"
|
||||
lru-cache: "npm:^7.14.1"
|
||||
named-placeholders: "npm:^1.1.3"
|
||||
seq-queue: "npm:^0.0.5"
|
||||
sqlstring: "npm:^2.3.2"
|
||||
checksum: dda663a63195f6e7336155e585b185ce5c64e810d8f1b51969c7fa5bf2bb29dabde4fd7b81b5872812728fd4e32c4fdf3421bad7325fc8e80525b4df184d27f7
|
||||
checksum: 6bbee1ee05826ef665ef01b3a9ebeb5e811a3b793f4dacc5ae8faf86c5756fc7c8549715fdd6640bb33bd2771e42ce68d94819637339367761b3d64ae687bcb7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -8557,12 +8584,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"named-placeholders@npm:^1.1.2":
|
||||
version: 1.1.2
|
||||
resolution: "named-placeholders@npm:1.1.2"
|
||||
"named-placeholders@npm:^1.1.3":
|
||||
version: 1.1.3
|
||||
resolution: "named-placeholders@npm:1.1.3"
|
||||
dependencies:
|
||||
lru-cache: "npm:^4.1.3"
|
||||
checksum: 24477df960b120c1eb814efbeb7d7b6e859b788b922129f43f48ee95ae89a14e249dd37d67594cbb30dcea9283e9af40fc526e615c57b2a30788b63e497baba0
|
||||
lru-cache: "npm:^7.14.1"
|
||||
checksum: 1cd77eb10c4b2cc9b9d0a9d014542df5cda61118e682cffccc896769f74cf17f46225205d868be6a7c4aad7ae92ede7f1d435a76314f1a1c07618ff29fe7a9d5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -9613,13 +9640,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"pseudomap@npm:^1.0.2":
|
||||
version: 1.0.2
|
||||
resolution: "pseudomap@npm:1.0.2"
|
||||
checksum: 33cfbb99ac85cfad587ebd29aef15343a570aa2208fa68a3036ee317ef2ef4345cf1a20f7311177393558937cafdf981be4c125e47a90cbd7400d942352239a4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"pstree.remy@npm:^1.1.8":
|
||||
version: 1.1.8
|
||||
resolution: "pstree.remy@npm:1.1.8"
|
||||
@@ -10221,6 +10241,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"semver@npm:^7.3.8":
|
||||
version: 7.3.8
|
||||
resolution: "semver@npm:7.3.8"
|
||||
dependencies:
|
||||
lru-cache: "npm:^6.0.0"
|
||||
bin:
|
||||
semver: bin/semver.js
|
||||
checksum: 94ad80ee14889020cb4a14d809fb99d16cbf4ff3dc7f4c564fc72efe2c5763a60090a1c16a9fd18ceeb1e993a1303a4d870c0a22f26adaf435b368b46a7d8462
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"semver@npm:~7.0.0":
|
||||
version: 7.0.0
|
||||
resolution: "semver@npm:7.0.0"
|
||||
@@ -11930,13 +11961,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"yallist@npm:^2.1.2":
|
||||
version: 2.1.2
|
||||
resolution: "yallist@npm:2.1.2"
|
||||
checksum: f3ace13bed59d5f6cf13142e65482c0992f0ed3ef2c9e20331efe44774586fc5eb9cb80dd431118948a5366f351afabc48d1572a636ce1ef45f57b8cb93340be
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"yallist@npm:^4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "yallist@npm:4.0.0"
|
||||
|
||||
Reference in New Issue
Block a user