Compare commits

..

42 Commits

Author SHA1 Message Date
standardci
78ab4dc94d chore(release): publish new version
- @standardnotes/analytics@2.19.5
 - @standardnotes/auth-server@1.82.1
 - @standardnotes/event-store@1.6.59
 - @standardnotes/revisions-server@1.10.13
 - @standardnotes/scheduler-server@1.16.9
 - @standardnotes/syncing-server@1.28.10
 - @standardnotes/websockets-server@1.5.5
 - @standardnotes/workspace-server@1.19.8
2023-01-17 14:49:52 +00:00
Karol Sójko
6a5904cfaa chore(deps): upgrade mysql2 2023-01-17 15:47:43 +01:00
standardci
a6061ec2a9 chore(release): publish new version
- @standardnotes/revisions-server@1.10.12
2023-01-17 13:56:18 +00:00
Karol Sójko
51c777304b fix(revisions): fetching revisions metadata 2023-01-17 14:54:22 +01:00
standardci
fbd535f2c5 chore(release): publish new version
- @standardnotes/auth-server@1.82.0
2023-01-17 13:18:05 +00:00
Aman Harwara
7d456671c2 feat: super editor permissions migration (#414) 2023-01-17 18:45:20 +05:30
standardci
dd4924c925 chore(release): publish new version
- @standardnotes/analytics@2.19.4
 - @standardnotes/auth-server@1.81.11
 - @standardnotes/event-store@1.6.58
 - @standardnotes/revisions-server@1.10.11
 - @standardnotes/scheduler-server@1.16.8
 - @standardnotes/syncing-server@1.28.9
 - @standardnotes/workspace-server@1.19.7
2023-01-17 12:47:34 +00:00
Karol Sójko
f73129cd7e fix: allow to run typeorm in non-replica mode 2023-01-17 13:45:32 +01:00
standardci
4983c8741e chore(release): publish new version
- @standardnotes/revisions-server@1.10.10
2023-01-17 10:55:57 +00:00
Karol Sójko
c5798640ff fix(revisions): add debug logs for retrieving revisions metadata from mysql 2023-01-17 11:53:57 +01:00
standardci
5803a8018a chore(release): publish new version
- @standardnotes/revisions-server@1.10.9
2023-01-17 10:02:11 +00:00
Karol Sójko
e2aae8ac8a fix(revisions): response structure 2023-01-17 11:00:05 +01:00
Karol Sójko
2917aeeb32 fix: turn some of the applications into a utility publishing workflow 2023-01-17 10:24:45 +01:00
standardci
9377c03c3f chore(release): publish new version
- @standardnotes/syncing-server@1.28.8
2023-01-17 09:09:03 +00:00
Karol Sójko
9b926fbad6 fix(syncing-server-js): creating directory for revision dumps 2023-01-17 10:07:01 +01:00
Karol Sójko
8db19c3e2b fix(syncing-server-js): add debug logs for dumping items for revisions creation 2023-01-17 10:02:17 +01:00
standardci
ca970781c7 chore(release): publish new version
- @standardnotes/analytics@2.19.3
 - @standardnotes/auth-server@1.81.10
 - @standardnotes/domain-core@1.11.1
 - @standardnotes/revisions-server@1.10.8
 - @standardnotes/scheduler-server@1.16.7
 - @standardnotes/syncing-server@1.28.7
 - @standardnotes/workspace-server@1.19.6
2023-01-16 14:36:54 +00:00
Karol Sójko
e7beee2788 fix(revisions): add required role to revisions list response 2023-01-16 15:34:20 +01:00
standardci
d266eada88 chore(release): publish new version
- @standardnotes/revisions-server@1.10.7
2023-01-16 10:22:58 +00:00
Karol Sójko
11b8b078b4 fix(revisions): remove redundant specs 2023-01-16 11:20:58 +01:00
standardci
37912fa29a chore(release): publish new version
- @standardnotes/revisions-server@1.10.6
2023-01-16 10:14:55 +00:00
Karol Sójko
b97dafe6f3 fix(revisions): mapping to snake case 2023-01-16 11:12:29 +01:00
standardci
2a29151395 chore(release): publish new version
- @standardnotes/revisions-server@1.10.5
2023-01-16 10:01:02 +00:00
Karol Sójko
8b988d89c0 fix(revisions): response structure 2023-01-16 10:58:39 +01:00
standardci
c0908f1b58 chore(release): publish new version
- @standardnotes/api-gateway@1.46.0
2023-01-16 09:02:31 +00:00
Karol Sójko
bb46044f7c Merge pull request #366 from standardnotes/switch_revisions
feat(api-gateway): switch to fetching revisions from reivsions server
2023-01-16 10:00:37 +01:00
Karol Sójko
60b3dd6138 feat(api-gateway): add all revisions endpoints on v2 2023-01-16 09:40:07 +01:00
Karol Sójko
22c1f936c3 feat(api-gateway): switch to fetching revisions from reivsions server 2023-01-16 09:33:13 +01:00
standardci
e899874b04 chore(release): publish new version
- @standardnotes/api-gateway@1.45.3
2023-01-16 08:32:47 +00:00
Karol Sójko
04c6888cf6 fix(api-gateway): add noindex robots meta tag to api gateway homepage 2023-01-16 09:30:02 +01:00
standardci
29c56c6919 chore(release): publish new version
- @standardnotes/analytics@2.19.2
 - @standardnotes/api-gateway@1.45.2
 - @standardnotes/auth-server@1.81.9
 - @standardnotes/domain-events-infra@1.9.60
 - @standardnotes/domain-events@2.105.2
 - @standardnotes/event-store@1.6.57
 - @standardnotes/files-server@1.9.5
 - @standardnotes/revisions-server@1.10.4
 - @standardnotes/scheduler-server@1.16.6
 - @standardnotes/security@1.7.3
 - @standardnotes/syncing-server@1.28.6
 - @standardnotes/websockets-server@1.5.4
 - @standardnotes/workspace-server@1.19.5
2023-01-13 09:56:13 +00:00
Karol Sójko
c98ed9cc85 chore: update jsonwebtoken 2023-01-13 10:53:57 +01:00
standardci
88f7530c13 chore(release): publish new version
- @standardnotes/api-gateway@1.45.1
 - @standardnotes/files-server@1.9.4
2023-01-13 09:05:13 +00:00
Karol Sójko
bb820437af fix: add robots.txt setup for api-gateway and files server to disallow indexing 2023-01-13 10:03:03 +01:00
standardci
d1a4bd38e0 chore(release): publish new version
- @standardnotes/auth-server@1.81.8
2023-01-11 12:49:19 +00:00
Karol Sójko
d18f6ccd32 fix(auth): add relying party configuration options 2023-01-11 13:47:13 +01:00
standardci
aa317c964e chore(release): publish new version
- @standardnotes/auth-server@1.81.7
2023-01-09 14:31:00 +00:00
Karol Sójko
7ae8845ae9 fix(auth): failure messages for debug logs upon signing in with recovery codes 2023-01-09 15:28:35 +01:00
standardci
123a6dbe0c chore(release): publish new version
- @standardnotes/auth-server@1.81.6
2023-01-09 13:53:44 +00:00
Karol Sójko
dda8d79526 fix(auth): request parameters names 2023-01-09 14:51:48 +01:00
standardci
de5293955a chore(release): publish new version
- @standardnotes/auth-server@1.81.5
2023-01-09 12:59:21 +00:00
Karol Sójko
96669bff5b fix(auth): debuggin recovery sign in 2023-01-09 13:56:56 +01:00
94 changed files with 1277 additions and 425 deletions

View File

@@ -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

View 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

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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
View File

@@ -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.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -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

View File

@@ -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",

View File

@@ -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,

View File

@@ -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

View File

@@ -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({

View File

@@ -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",

View File

@@ -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
}

View File

@@ -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}`,
)
}
}

View File

@@ -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=

View File

@@ -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

View 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
}
}

View File

@@ -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",

View File

@@ -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

View File

@@ -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,

View File

@@ -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'),

View File

@@ -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 () => {

View File

@@ -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.',
},
},
}

View File

@@ -1,4 +0,0 @@
export enum RelyingParty {
RP_NAME = 'Standard Notes',
RP_ID = 'standardnotes.com',
}

View File

@@ -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({

View File

@@ -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',

View File

@@ -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 () => {

View File

@@ -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({

View File

@@ -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({

View File

@@ -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,

View File

@@ -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>

View File

@@ -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) {

View File

@@ -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,
})

View File

@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.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

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/domain-core",
"version": "1.11.0",
"version": "1.11.1",
"engines": {
"node": ">=18.0.0 <19.0.0"
},

View File

@@ -0,0 +1,5 @@
import { Result } from '../Core/Result'
export interface SyncUseCaseInterface<T> {
execute(...args: any[]): Result<T>
}

View File

@@ -35,4 +35,5 @@ export * from './Mapping/MapperInterface'
export * from './Subscription/SubscriptionPlanName'
export * from './Subscription/SubscriptionPlanNameProps'
export * from './UseCase/SyncUseCaseInterface'
export * from './UseCase/UseCaseInterface'

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.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

View File

@@ -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"
},

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [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

View File

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

View File

@@ -3,6 +3,20 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.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

View File

@@ -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",

View File

@@ -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,

View File

@@ -3,6 +3,16 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [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

View File

@@ -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({

View File

@@ -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",

View File

@@ -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

View File

@@ -7,5 +7,5 @@ module.exports = {
transform: {
...tsjPreset.transform,
},
coveragePathIgnorePatterns: ['/Bootstrap/', 'HealthCheckController', '/Infra/', '/Mapping/'],
coveragePathIgnorePatterns: ['/Bootstrap/', '/Controller/', 'HealthCheckController', '/Infra/', '/Mapping/'],
}

View File

@@ -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",

View File

@@ -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),
),
)

View File

@@ -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

View File

@@ -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

View File

@@ -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)
})
})

View File

@@ -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()) },
}
}

View File

@@ -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')
})
})

View File

@@ -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)
}
}

View File

@@ -0,0 +1,3 @@
export interface GetRequiredRoleToViewRevisionDTO {
createdAt: Date
}

View File

@@ -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
}
}

View File

@@ -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
}>
}

View File

@@ -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')

View File

@@ -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) {

View 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(),
}
}
}

View 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(),
}
}
}

View File

@@ -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

View File

@@ -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",

View File

@@ -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,

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.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

View File

@@ -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",

View File

@@ -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

View File

@@ -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",

View File

@@ -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,

View File

@@ -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

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.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

View File

@@ -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",

View File

@@ -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

View File

@@ -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",

View File

@@ -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
View File

@@ -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"