Compare commits

...

28 Commits

Author SHA1 Message Date
standardci
b13fab76f3 chore(release): publish new version
- @standardnotes/auth-server@1.91.1
2023-03-06 13:28:57 +00:00
Karol Sójko
782a9d310d fix(auth): disable sign in emails on newly created accounts 2023-03-06 14:15:10 +01:00
standardci
537b1f2a29 chore(release): publish new version
- @standardnotes/auth-server@1.91.0
2023-03-06 10:00:13 +00:00
Karol Sójko
2fad6b62cb feat(auth): add cleanup of expired sessions 2023-03-06 10:43:53 +01:00
standardci
bf173b4ede chore(release): publish new version
- @standardnotes/auth-server@1.90.1
2023-03-06 09:17:04 +00:00
Eric Pierce
c52f038c76 fix: Adding support for redis databases with passwords (#468)
Redis databases with passwords can be supported by specifying the environment parameter REDIS_URL=redis://:$REDIS_PASSWORD@redis:6379
Without this change the redis URL will always be hardcoded without support for a password
2023-03-06 10:02:36 +01:00
mousta0x
b12ba98a5c fix: revisions server url (#469) 2023-03-06 09:57:56 +01:00
Karol Sójko
dbccdf342b fix(auth): prevent listing sessions on readonly access 2023-03-06 09:47:54 +01:00
standardci
49b6d029c4 chore(release): publish new version
- @standardnotes/auth-server@1.90.0
2023-03-02 14:10:08 +00:00
Karol Sójko
d6469954ce feat(auth): add configurable list of readonly users (#462) 2023-03-02 14:51:52 +01:00
standardci
5f40550ad4 chore(release): publish new version
- @standardnotes/auth-server@1.89.7
2023-03-02 11:20:59 +00:00
Karol Sójko
79ccbdf100 fix(auth): function naming for more clarity 2023-03-02 12:07:17 +01:00
standardci
1983cfcab2 chore(release): publish new version
- @standardnotes/auth-server@1.89.6
2023-03-02 10:32:02 +00:00
Karol Sójko
753f86707f fix(auth): changing the updated_at property on sessions 2023-03-02 11:16:32 +01:00
standardci
16d0ed505b chore(release): publish new version
- @standardnotes/auth-server@1.89.5
 - @standardnotes/revisions-server@1.12.7
 - @standardnotes/syncing-server@1.31.8
 - @standardnotes/websockets-server@1.6.6
2023-03-01 20:05:36 +00:00
Mo
9de09c55f8 chore: upgrade api and responses dependencies (#459) 2023-03-01 13:51:26 -06:00
standardci
c3d7a33aa2 chore(release): publish new version
- @standardnotes/auth-server@1.89.4
2023-03-01 12:01:59 +00:00
Karol Sójko
a9cc00a478 fix(auth): updating counter post authenticator verification 2023-03-01 12:48:10 +01:00
standardci
ec035ba648 chore(release): publish new version
- @standardnotes/auth-server@1.89.3
2023-02-27 10:59:56 +00:00
Karol Sójko
5446f3cae4 chore: upgrade @simplewebauthn lib 2023-02-27 11:46:00 +01:00
standardci
6a550092c2 chore(release): publish new version
- @standardnotes/api-gateway@1.49.4
2023-02-25 15:14:24 +00:00
Mo
1b691f6bcd refactor: remove explicit route since subscription token no longer required 2023-02-25 09:00:07 -06:00
standardci
98f45cc4c2 chore(release): publish new version
- @standardnotes/auth-server@1.89.2
2023-02-24 10:59:33 +00:00
Karol Sójko
edc4a20859 fix(auth): add cross-platform authenticator selection option 2023-02-24 11:45:33 +01:00
standardci
74e1380df8 chore(release): publish new version
- @standardnotes/api-gateway@1.49.3
2023-02-24 07:35:22 +00:00
Karol Sójko
dfa5187ff7 fix(api-gateywa): remove stale proxy references 2023-02-24 08:21:22 +01:00
Karol Sójko
c99c4425cd chore: update yarn lock 2023-02-24 08:14:33 +01:00
Karol Sójko
2d8919a079 chore: remove proxy service 2023-02-24 08:14:17 +01:00
96 changed files with 437 additions and 755 deletions

View File

@@ -94,81 +94,3 @@ jobs:
name: E2E
uses: standardnotes/server/.github/workflows/common-e2e.yml@main
secrets: inherit
legacy_e2e:
needs: build
name: Legacy E2E
strategy:
matrix:
application:
- { "service_name": "api-gateway", "workspace_name": "@standardnotes/api-gateway", "e2e_tag_parameter_name": "api_gateway_image_tag", "package_path": "packages/api-gateway" }
- { "service_name": "auth", "workspace_name": "@standardnotes/auth-server", "e2e_tag_parameter_name": "auth_image_tag", "package_path": "packages/auth" }
- { "service_name": "files", "workspace_name": "@standardnotes/files-server", "e2e_tag_parameter_name": "files_image_tag", "package_path": "packages/files" }
- { "service_name": "revisions", "workspace_name": "@standardnotes/revisions-server", "e2e_tag_parameter_name": "revisions_image_tag", "package_path": "packages/revisions"}
- { "service_name": "syncing-server-js", "workspace_name": "@standardnotes/syncing-server", "e2e_tag_parameter_name": "syncing_server_js_image_tag", "package_path": "packages/syncing-server" }
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Create Bundle Dir
id: bundle-dir
run: echo "temp_dir=$(mktemp -d -t ${{ matrix.application.service_name }}-${{ github.sha }}-XXXXXXX)" >> $GITHUB_OUTPUT
- name: Cache build
id: cache-build
uses: actions/cache@v3
with:
path: |
packages/**/dist
${{ needs.legacy_e2e.outputs.temp_dir }}
key: ${{ runner.os }}-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
- name: Bundle
run: yarn workspace ${{ matrix.application.workspace_name }} bundle --no-compress --output-directory ${{ steps.bundle-dir.outputs.temp_dir }}
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Set up QEMU
uses: docker/setup-qemu-action@master
with:
platforms: all
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@master
- name: Publish Docker image for E2E testing
uses: docker/build-push-action@v3
with:
builder: ${{ steps.buildx.outputs.name }}
context: ${{ steps.bundle-dir.outputs.temp_dir }}
file: ${{ steps.bundle-dir.outputs.temp_dir }}/${{ matrix.application.package_path }}/Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: standardnotes/${{ matrix.application.service_name }}:${{ github.sha }}
- name: Run E2E test suite
uses: convictional/trigger-workflow-and-wait@master
with:
owner: standardnotes
repo: self-hosted
github_token: ${{ secrets.CI_PAT_TOKEN }}
workflow_file_name: testing-with-updating-client-and-server.yml
wait_interval: 30
client_payload: '{"${{ matrix.application.e2e_tag_parameter_name }}": "${{ github.sha }}"}'
propagate_failure: true
trigger_workflow: true
wait_workflow: true

View File

@@ -1,22 +0,0 @@
name: Proxy Server
concurrency:
group: proxy_server
cancel-in-progress: true
on:
push:
tags:
- '*standardnotes/proxy-server*'
workflow_dispatch:
jobs:
call_server_application_workflow:
name: Server Application
uses: standardnotes/server/.github/workflows/common-server-application.yml@main
with:
service_name: proxy
workspace_name: "@standardnotes/proxy-server"
deploy_worker: false
package_path: packages/proxy
secrets: inherit

127
.pnp.cjs generated
View File

@@ -53,10 +53,6 @@ const RAW_RUNTIME_STATE =
"name": "@standardnotes/predicates",\
"reference": "workspace:packages/predicates"\
},\
{\
"name": "@standardnotes/proxy-server",\
"reference": "workspace:packages/proxy"\
},\
{\
"name": "@standardnotes/revisions-server",\
"reference": "workspace:packages/revisions"\
@@ -103,7 +99,6 @@ const RAW_RUNTIME_STATE =
["@standardnotes/event-store", ["workspace:packages/event-store"]],\
["@standardnotes/files-server", ["workspace:packages/files"]],\
["@standardnotes/predicates", ["workspace:packages/predicates"]],\
["@standardnotes/proxy-server", ["workspace:packages/proxy"]],\
["@standardnotes/revisions-server", ["workspace:packages/revisions"]],\
["@standardnotes/scheduler-server", ["workspace:packages/scheduler"]],\
["@standardnotes/security", ["workspace:packages/security"]],\
@@ -3965,26 +3960,26 @@ const RAW_RUNTIME_STATE =
}]\
]],\
["@simplewebauthn/iso-webcrypto", [\
["npm:7.0.0", {\
"packageLocation": "./.yarn/cache/@simplewebauthn-iso-webcrypto-npm-7.0.0-352babf4a0-c1644f9b68.zip/node_modules/@simplewebauthn/iso-webcrypto/",\
["npm:7.0.1", {\
"packageLocation": "./.yarn/cache/@simplewebauthn-iso-webcrypto-npm-7.0.1-bae5f6738c-ed506490e0.zip/node_modules/@simplewebauthn/iso-webcrypto/",\
"packageDependencies": [\
["@simplewebauthn/iso-webcrypto", "npm:7.0.0"]\
["@simplewebauthn/iso-webcrypto", "npm:7.0.1"]\
],\
"linkType": "HARD"\
}]\
]],\
["@simplewebauthn/server", [\
["npm:7.0.0", {\
"packageLocation": "./.yarn/cache/@simplewebauthn-server-npm-7.0.0-e34589f137-836eb9fb97.zip/node_modules/@simplewebauthn/server/",\
["npm:7.0.1", {\
"packageLocation": "./.yarn/cache/@simplewebauthn-server-npm-7.0.1-ac81233d49-d11c708008.zip/node_modules/@simplewebauthn/server/",\
"packageDependencies": [\
["@simplewebauthn/server", "npm:7.0.0"],\
["@simplewebauthn/server", "npm:7.0.1"],\
["@hexagon/base64", "npm:1.1.25"],\
["@peculiar/asn1-android", "npm:2.3.3"],\
["@peculiar/asn1-ecc", "npm:2.3.4"],\
["@peculiar/asn1-rsa", "npm:2.3.4"],\
["@peculiar/asn1-schema", "npm:2.3.3"],\
["@peculiar/asn1-x509", "npm:2.3.4"],\
["@simplewebauthn/iso-webcrypto", "npm:7.0.0"],\
["@simplewebauthn/iso-webcrypto", "npm:7.0.1"],\
["cbor-x", "npm:1.5.0"],\
["cross-fetch", "npm:3.1.5"],\
["debug", "virtual:b86a9fb34323a98c6519528ed55faa0d9b44ca8879307c0b29aa384bde47ff59a7d0c9051b31246f14521dfb71ba3c5d6d0b35c29fffc17bf875aa6ad977d9e8#npm:4.3.4"]\
@@ -4088,17 +4083,17 @@ const RAW_RUNTIME_STATE =
}]\
]],\
["@standardnotes/api", [\
["npm:1.24.10", {\
"packageLocation": "./.yarn/cache/@standardnotes-api-npm-1.24.10-63391538ba-1b9a97fdd8.zip/node_modules/@standardnotes/api/",\
["npm:1.25.3", {\
"packageLocation": "./.yarn/cache/@standardnotes-api-npm-1.25.3-29ba336725-bc7953c440.zip/node_modules/@standardnotes/api/",\
"packageDependencies": [\
["@standardnotes/api", "npm:1.24.10"],\
["@standardnotes/api", "npm:1.25.3"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/encryption", "npm:1.21.9"],\
["@standardnotes/models", "npm:1.42.11"],\
["@standardnotes/responses", "npm:1.13.6"],\
["@standardnotes/encryption", "npm:1.21.17"],\
["@standardnotes/models", "npm:1.43.5"],\
["@standardnotes/responses", "npm:1.13.9"],\
["@standardnotes/security", "workspace:packages/security"],\
["@standardnotes/utils", "npm:1.16.3"],\
["@standardnotes/utils", "npm:1.16.4"],\
["reflect-metadata", "npm:0.1.13"]\
],\
"linkType": "HARD"\
@@ -4161,16 +4156,16 @@ const RAW_RUNTIME_STATE =
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
["@sentry/node", "npm:7.28.1"],\
["@sentry/tracing", "npm:7.28.1"],\
["@simplewebauthn/server", "npm:7.0.0"],\
["@simplewebauthn/server", "npm:7.0.1"],\
["@simplewebauthn/typescript-types", "npm:7.0.0"],\
["@standardnotes/api", "npm:1.24.10"],\
["@standardnotes/api", "npm:1.25.3"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@standardnotes/features", "npm:1.58.4"],\
["@standardnotes/predicates", "workspace:packages/predicates"],\
["@standardnotes/responses", "npm:1.13.4"],\
["@standardnotes/responses", "npm:1.13.9"],\
["@standardnotes/security", "workspace:packages/security"],\
["@standardnotes/settings", "workspace:packages/settings"],\
["@standardnotes/sncrypto-common", "npm:1.13.0"],\
@@ -4307,15 +4302,15 @@ const RAW_RUNTIME_STATE =
}]\
]],\
["@standardnotes/encryption", [\
["npm:1.21.9", {\
"packageLocation": "./.yarn/cache/@standardnotes-encryption-npm-1.21.9-092bc2cb51-dc1336cc05.zip/node_modules/@standardnotes/encryption/",\
["npm:1.21.17", {\
"packageLocation": "./.yarn/cache/@standardnotes-encryption-npm-1.21.17-0801937c9c-ece7ac644e.zip/node_modules/@standardnotes/encryption/",\
"packageDependencies": [\
["@standardnotes/encryption", "npm:1.21.9"],\
["@standardnotes/encryption", "npm:1.21.17"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/models", "npm:1.42.11"],\
["@standardnotes/responses", "npm:1.13.6"],\
["@standardnotes/models", "npm:1.43.5"],\
["@standardnotes/responses", "npm:1.13.9"],\
["@standardnotes/sncrypto-common", "npm:1.13.3"],\
["@standardnotes/utils", "npm:1.16.3"],\
["@standardnotes/utils", "npm:1.16.4"],\
["reflect-metadata", "npm:0.1.13"]\
],\
"linkType": "HARD"\
@@ -4364,10 +4359,10 @@ const RAW_RUNTIME_STATE =
],\
"linkType": "HARD"\
}],\
["npm:1.58.6", {\
"packageLocation": "./.yarn/cache/@standardnotes-features-npm-1.58.6-7b1e198c39-98550416f1.zip/node_modules/@standardnotes/features/",\
["npm:1.58.8", {\
"packageLocation": "./.yarn/cache/@standardnotes-features-npm-1.58.8-d97ff2aae1-77bac7d0a0.zip/node_modules/@standardnotes/features/",\
"packageDependencies": [\
["@standardnotes/features", "npm:1.58.6"],\
["@standardnotes/features", "npm:1.58.8"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/security", "workspace:packages/security"],\
@@ -4433,14 +4428,14 @@ const RAW_RUNTIME_STATE =
}]\
]],\
["@standardnotes/models", [\
["npm:1.42.11", {\
"packageLocation": "./.yarn/cache/@standardnotes-models-npm-1.42.11-7db16001ef-6ff3409f70.zip/node_modules/@standardnotes/models/",\
["npm:1.43.5", {\
"packageLocation": "./.yarn/cache/@standardnotes-models-npm-1.43.5-5180388ed4-fd8e3b60bd.zip/node_modules/@standardnotes/models/",\
"packageDependencies": [\
["@standardnotes/models", "npm:1.42.11"],\
["@standardnotes/models", "npm:1.43.5"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/features", "npm:1.58.6"],\
["@standardnotes/responses", "npm:1.13.6"],\
["@standardnotes/utils", "npm:1.16.3"],\
["@standardnotes/features", "npm:1.58.8"],\
["@standardnotes/responses", "npm:1.13.9"],\
["@standardnotes/utils", "npm:1.16.4"],\
["lodash", "npm:4.17.21"]\
],\
"linkType": "HARD"\
@@ -4461,40 +4456,13 @@ const RAW_RUNTIME_STATE =
"linkType": "SOFT"\
}]\
]],\
["@standardnotes/proxy-server", [\
["workspace:packages/proxy", {\
"packageLocation": "./packages/proxy/",\
"packageDependencies": [\
["@standardnotes/proxy-server", "workspace:packages/proxy"],\
["@types/newrelic", "npm:9.4.0"],\
["@types/node", "npm:18.14.0"],\
["@typescript-eslint/eslint-plugin", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:5.48.2"],\
["eslint", "npm:8.32.0"],\
["eslint-plugin-prettier", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.2.1"],\
["newrelic", "npm:9.8.0"],\
["typescript", "patch:typescript@npm%3A4.8.4#optional!builtin<compat/typescript>::version=4.8.4&hash=701156"]\
],\
"linkType": "SOFT"\
}]\
]],\
["@standardnotes/responses", [\
["npm:1.13.4", {\
"packageLocation": "./.yarn/cache/@standardnotes-responses-npm-1.13.4-70cbd72561-4803ee14bd.zip/node_modules/@standardnotes/responses/",\
["npm:1.13.9", {\
"packageLocation": "./.yarn/cache/@standardnotes-responses-npm-1.13.9-5b1858da5d-5cb5daf9f3.zip/node_modules/@standardnotes/responses/",\
"packageDependencies": [\
["@standardnotes/responses", "npm:1.13.4"],\
["@standardnotes/responses", "npm:1.13.9"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/features", "npm:1.58.4"],\
["@standardnotes/security", "workspace:packages/security"],\
["reflect-metadata", "npm:0.1.13"]\
],\
"linkType": "HARD"\
}],\
["npm:1.13.6", {\
"packageLocation": "./.yarn/cache/@standardnotes-responses-npm-1.13.6-5df25fe3dd-c57e3e1fa1.zip/node_modules/@standardnotes/responses/",\
"packageDependencies": [\
["@standardnotes/responses", "npm:1.13.6"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/features", "npm:1.58.6"],\
["@standardnotes/features", "npm:1.58.8"],\
["@standardnotes/security", "workspace:packages/security"],\
["reflect-metadata", "npm:0.1.13"]\
],\
@@ -4510,11 +4478,12 @@ const RAW_RUNTIME_STATE =
["@aws-sdk/client-sqs", "npm:3.259.0"],\
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
["@sentry/node", "npm:7.28.1"],\
["@standardnotes/api", "npm:1.24.10"],\
["@standardnotes/api", "npm:1.25.3"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@standardnotes/responses", "npm:1.13.9"],\
["@standardnotes/security", "workspace:packages/security"],\
["@standardnotes/time", "workspace:packages/time"],\
["@types/cors", "npm:2.8.12"],\
@@ -4689,12 +4658,12 @@ const RAW_RUNTIME_STATE =
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
["@sentry/node", "npm:7.28.1"],\
["@sentry/tracing", "npm:7.28.1"],\
["@standardnotes/api", "npm:1.24.10"],\
["@standardnotes/api", "npm:1.25.3"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@standardnotes/responses", "npm:1.13.4"],\
["@standardnotes/responses", "npm:1.13.9"],\
["@standardnotes/security", "workspace:packages/security"],\
["@standardnotes/settings", "workspace:packages/settings"],\
["@standardnotes/time", "workspace:packages/time"],\
@@ -4767,10 +4736,10 @@ const RAW_RUNTIME_STATE =
],\
"linkType": "HARD"\
}],\
["npm:1.16.3", {\
"packageLocation": "./.yarn/cache/@standardnotes-utils-npm-1.16.3-87b47ad954-5c34beaafb.zip/node_modules/@standardnotes/utils/",\
["npm:1.16.4", {\
"packageLocation": "./.yarn/cache/@standardnotes-utils-npm-1.16.4-d7c627b154-ed29da54cb.zip/node_modules/@standardnotes/utils/",\
"packageDependencies": [\
["@standardnotes/utils", "npm:1.16.3"],\
["@standardnotes/utils", "npm:1.16.4"],\
["@standardnotes/common", "workspace:packages/common"],\
["dompurify", "npm:2.4.3"],\
["lodash", "npm:4.17.21"],\
@@ -4787,11 +4756,12 @@ const RAW_RUNTIME_STATE =
["@aws-sdk/client-sqs", "npm:3.259.0"],\
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
["@sentry/node", "npm:7.28.1"],\
["@standardnotes/api", "npm:1.24.10"],\
["@standardnotes/api", "npm:1.25.3"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@standardnotes/responses", "npm:1.13.9"],\
["@standardnotes/security", "workspace:packages/security"],\
["@standardnotes/utils", "npm:1.16.2"],\
["@types/cors", "npm:2.8.12"],\
@@ -5224,13 +5194,6 @@ const RAW_RUNTIME_STATE =
["@types/node", "npm:18.11.9"]\
],\
"linkType": "HARD"\
}],\
["npm:18.14.0", {\
"packageLocation": "./.yarn/cache/@types-node-npm-18.14.0-ddc1a221d2-d17dff07c7.zip/node_modules/@types/node/",\
"packageDependencies": [\
["@types/node", "npm:18.14.0"]\
],\
"linkType": "HARD"\
}]\
]],\
["@types/nodemailer", [\

Binary file not shown.

View File

@@ -327,7 +327,7 @@ endif
quiet_cmd_regen_makefile = ACTION Regenerating $@
cmd_regen_makefile = cd $(srcdir); /Users/mo/Desktop/sn/dev/server/.yarn/unplugged/node-gyp-npm-9.0.0-0eccfca4d1/node_modules/node-gyp/gyp/gyp_main.py -fmake --ignore-environment "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/Users/mo/Library/Caches/node-gyp/18.13.0" "-Dnode_gyp_dir=/Users/mo/Desktop/sn/dev/server/.yarn/unplugged/node-gyp-npm-9.0.0-0eccfca4d1/node_modules/node-gyp" "-Dnode_lib_file=/Users/mo/Library/Caches/node-gyp/18.13.0/<(target_arch)/node.lib" "-Dmodule_root_dir=/Users/mo/Desktop/sn/dev/server/.yarn/unplugged/@newrelic-native-metrics-npm-9.0.0-590d2e713a/node_modules/@newrelic/native-metrics" "-Dnode_engine=v8" "--depth=." "-Goutput_dir=." "--generator-output=build" -I/Users/mo/Desktop/sn/dev/server/.yarn/unplugged/@newrelic-native-metrics-npm-9.0.0-590d2e713a/node_modules/@newrelic/native-metrics/build/config.gypi -I/Users/mo/Desktop/sn/dev/server/.yarn/unplugged/node-gyp-npm-9.0.0-0eccfca4d1/node_modules/node-gyp/addon.gypi -I/Users/mo/Library/Caches/node-gyp/18.13.0/include/node/common.gypi "--toplevel-dir=." binding.gyp
Makefile: $(srcdir)/binding.gyp $(srcdir)/build/config.gypi $(srcdir)/../../../../node-gyp-npm-9.0.0-0eccfca4d1/node_modules/node-gyp/addon.gypi $(srcdir)/../../../../../../../../../../Library/Caches/node-gyp/18.13.0/include/node/common.gypi
Makefile: $(srcdir)/../../../../node-gyp-npm-9.0.0-0eccfca4d1/node_modules/node-gyp/addon.gypi $(srcdir)/binding.gyp $(srcdir)/../../../../../../../../../../Library/Caches/node-gyp/18.13.0/include/node/common.gypi $(srcdir)/build/config.gypi
$(call do_cmd,regen_makefile)
# "all" is a concatenation of the "all" targets from all the included

View File

@@ -58,7 +58,9 @@ if [ -z "$REDIS_HOST" ]; then
export REDIS_HOST="cache"
fi
export REDIS_URL="redis://$REDIS_HOST"
if [ -z "$REDIS_URL" ]; then
export REDIS_URL="redis://$REDIS_HOST"
fi
##########
# SHARED #
@@ -349,7 +351,7 @@ export API_GATEWAY_NEW_RELIC_NO_CONFIG_FILE=true
export API_GATEWAY_SYNCING_SERVER_JS_URL=http://localhost:$SYNCING_SERVER_PORT
export API_GATEWAY_AUTH_SERVER_URL=http://localhost:$AUTH_SERVER_PORT
export API_GATEWAY_REVISIONS_SERVER_URL=http://localhost:3005
export API_GATEWAY_REVISIONS_SERVER_URL=http://localhost:$REVISIONS_SERVER_PORT
if [ -z "$PUBLIC_FILES_SERVER_URL" ]; then
export PUBLIC_FILES_SERVER_URL=http://localhost:3125
fi

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.49.4](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.49.3...@standardnotes/api-gateway@1.49.4) (2023-02-25)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.49.3](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.49.2...@standardnotes/api-gateway@1.49.3) (2023-02-24)
### Bug Fixes
* **api-gateywa:** remove stale proxy references ([dfa5187](https://github.com/standardnotes/api-gateway/commit/dfa5187ff73833bf981d273da79f78ae0309a493))
## [1.49.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.49.1...@standardnotes/api-gateway@1.49.2) (2023-02-23)
**Note:** Version bump only for package @standardnotes/api-gateway

View File

@@ -20,7 +20,6 @@ import '../src/Controller/v1/OfflineController'
import '../src/Controller/v1/FilesController'
import '../src/Controller/v1/SubscriptionInvitesController'
import '../src/Controller/v1/AuthenticatorsController'
import '../src/Controller/v1/ProxyController'
import '../src/Controller/v2/PaymentsControllerV2'
import '../src/Controller/v2/ActionsControllerV2'

View File

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

View File

@@ -60,7 +60,6 @@ export class ContainerConfigLoader {
container.bind(TYPES.FILES_SERVER_URL).toConstantValue(env.get('FILES_SERVER_URL', true))
container.bind(TYPES.AUTH_JWT_SECRET).toConstantValue(env.get('AUTH_JWT_SECRET'))
container.bind(TYPES.WEB_SOCKET_SERVER_URL).toConstantValue(env.get('WEB_SOCKET_SERVER_URL', true))
container.bind(TYPES.PROXY_SERVER_URL).toConstantValue(env.get('PROXY_SERVER_URL', true))
container
.bind(TYPES.HTTP_CALL_TIMEOUT)
.toConstantValue(env.get('HTTP_CALL_TIMEOUT', true) ? +env.get('HTTP_CALL_TIMEOUT', true) : 60_000)

View File

@@ -10,7 +10,6 @@ const TYPES = {
REVISIONS_SERVER_URL: Symbol.for('REVISIONS_SERVER_URL'),
EMAIL_SERVER_URL: Symbol.for('EMAIL_SERVER_URL'),
WEB_SOCKET_SERVER_URL: Symbol.for('WEB_SOCKET_SERVER_URL'),
PROXY_SERVER_URL: Symbol.for('PROXY_SERVER_URL'),
AUTH_JWT_SECRET: Symbol.for('AUTH_JWT_SECRET'),
HTTP_CALL_TIMEOUT: Symbol.for('HTTP_CALL_TIMEOUT'),
VERSION: Symbol.for('VERSION'),

View File

@@ -145,11 +145,6 @@ export class PaymentsController extends BaseHttpController {
await this.httpService.callPaymentsServer(request, response, 'api/pro_users/stripe-setup-intent', request.body)
}
@httpGet('/pro_users/cp-prepayment-info', TYPES.SubscriptionTokenAuthMiddleware)
async coinpaymentsPrepaymentInfo(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer(request, response, 'api/pro_users/cp-prepayment-info', request.body)
}
@all('/pro_users(/*)?')
async proUsers(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer(request, response, request.path.replace('v1', 'api'), request.body)

View File

@@ -1,18 +0,0 @@
import { Request, Response } from 'express'
import { inject } from 'inversify'
import { all, BaseHttpController, controller } from 'inversify-express-utils'
import TYPES from '../../Bootstrap/Types'
import { HttpServiceInterface } from '../../Service/Http/HttpServiceInterface'
@controller('/v1/proxy')
export class ProxyController extends BaseHttpController {
constructor(@inject(TYPES.HTTPService) private httpService: HttpServiceInterface) {
super()
}
@all('*', TYPES.AuthMiddleware)
async createToken(request: Request, response: Response): Promise<void> {
await this.httpService.callProxyServer(request, response, request.path.replace('/v1/proxy', ''), request.body)
}
}

View File

@@ -19,7 +19,6 @@ export class HttpService implements HttpServiceInterface {
@inject(TYPES.WEB_SOCKET_SERVER_URL) private webSocketServerUrl: string,
@inject(TYPES.REVISIONS_SERVER_URL) private revisionsServerUrl: string,
@inject(TYPES.EMAIL_SERVER_URL) private emailServerUrl: string,
@inject(TYPES.PROXY_SERVER_URL) private proxyServerUrl: string,
@inject(TYPES.HTTP_CALL_TIMEOUT) private httpCallTimeout: number,
@inject(TYPES.CrossServiceTokenCache) private crossServiceTokenCache: CrossServiceTokenCacheInterface,
@inject(TYPES.Logger) private logger: Logger,
@@ -96,21 +95,6 @@ export class HttpService implements HttpServiceInterface {
await this.callServer(this.webSocketServerUrl, request, response, endpoint, payload)
}
async callProxyServer(
request: Request,
response: Response,
endpoint: string,
payload?: Record<string, unknown> | string,
): Promise<void> {
if (!this.proxyServerUrl) {
this.logger.debug('Proxy Server URL not defined. Skipped request to Proxy.')
return
}
await this.callServer(this.proxyServerUrl, request, response, endpoint, payload)
}
async callPaymentsServer(
request: Request,
response: Response,

View File

@@ -49,10 +49,4 @@ export interface HttpServiceInterface {
endpoint: string,
payload?: Record<string, unknown> | string,
): Promise<void>
callProxyServer(
request: Request,
response: Response,
endpoint: string,
payload?: Record<string, unknown> | string,
): Promise<void>
}

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.91.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.91.0...@standardnotes/auth-server@1.91.1) (2023-03-06)
### Bug Fixes
* **auth:** disable sign in emails on newly created accounts ([782a9d3](https://github.com/standardnotes/server/commit/782a9d310dc2d2819a49540138ed10b36ebd0d94))
# [1.91.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.90.1...@standardnotes/auth-server@1.91.0) (2023-03-06)
### Features
* **auth:** add cleanup of expired sessions ([2fad6b6](https://github.com/standardnotes/server/commit/2fad6b62cbb5bec38a3171a996d3f9c4eedf7836))
## [1.90.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.90.0...@standardnotes/auth-server@1.90.1) (2023-03-06)
### Bug Fixes
* **auth:** prevent listing sessions on readonly access ([dbccdf3](https://github.com/standardnotes/server/commit/dbccdf342b52f81fb14f246784d5dc6def2ff3fc))
# [1.90.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.89.7...@standardnotes/auth-server@1.90.0) (2023-03-02)
### Features
* **auth:** add configurable list of readonly users ([#462](https://github.com/standardnotes/server/issues/462)) ([d646995](https://github.com/standardnotes/server/commit/d6469954ceb24580c465535e61588b04924734ab))
## [1.89.7](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.89.6...@standardnotes/auth-server@1.89.7) (2023-03-02)
### Bug Fixes
* **auth:** function naming for more clarity ([79ccbdf](https://github.com/standardnotes/server/commit/79ccbdf1000c699074b5271f3c04a30fcb1b3311))
## [1.89.6](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.89.5...@standardnotes/auth-server@1.89.6) (2023-03-02)
### Bug Fixes
* **auth:** changing the updated_at property on sessions ([753f867](https://github.com/standardnotes/server/commit/753f86707ffdbab0d04f49b42275dbb28589780b))
## [1.89.5](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.89.4...@standardnotes/auth-server@1.89.5) (2023-03-01)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.89.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.89.3...@standardnotes/auth-server@1.89.4) (2023-03-01)
### Bug Fixes
* **auth:** updating counter post authenticator verification ([a9cc00a](https://github.com/standardnotes/server/commit/a9cc00a4783c12e71eb181a3ccf3218b418750d9))
## [1.89.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.89.2...@standardnotes/auth-server@1.89.3) (2023-02-27)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.89.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.89.1...@standardnotes/auth-server@1.89.2) (2023-02-24)
### Bug Fixes
* **auth:** add cross-platform authenticator selection option ([edc4a20](https://github.com/standardnotes/server/commit/edc4a2085952efe0b83c8e837a52555087714ef7))
## [1.89.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.89.0...@standardnotes/auth-server@1.89.1) (2023-02-23)
**Note:** Version bump only for package @standardnotes/auth-server

View File

@@ -8,6 +8,17 @@ import { ContainerConfigLoader } from '../src/Bootstrap/Container'
import TYPES from '../src/Bootstrap/Types'
import { Env } from '../src/Bootstrap/Env'
import { CleanupSessionTraces } from '../src/Domain/UseCase/CleanupSessionTraces/CleanupSessionTraces'
import { CleanupExpiredSessions } from '../src/Domain/UseCase/CleanupExpiredSessions/CleanupExpiredSessions'
const cleanup = async (
cleanupSessionTraces: CleanupSessionTraces,
cleanupExpiredSessions: CleanupExpiredSessions,
): Promise<void> => {
const date = new Date()
await cleanupSessionTraces.execute({ date })
await cleanupExpiredSessions.execute({ date })
}
const container = new ContainerConfigLoader()
void container.load().then((container) => {
@@ -16,22 +27,19 @@ void container.load().then((container) => {
const logger: Logger = container.get(TYPES.Logger)
logger.info('Starting session traces cleanup')
logger.info('Starting sessions and session traces cleanup')
const cleanupSessionTraces: CleanupSessionTraces = container.get(TYPES.CleanupSessionTraces)
const cleanupExpiredSessions: CleanupExpiredSessions = container.get(TYPES.CleanupExpiredSessions)
Promise.resolve(
cleanupSessionTraces.execute({
date: new Date(),
}),
)
Promise.resolve(cleanup(cleanupSessionTraces, cleanupExpiredSessions))
.then(() => {
logger.info('Expired session traces cleaned.')
logger.info('Expired sessions and session traces cleaned.')
process.exit(0)
})
.catch((error) => {
logger.error(`Could not clean session traces: ${error.message}`)
logger.error(`Could not clean sessions and session traces: ${error.message}`)
process.exit(1)
})

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/auth-server",
"version": "1.89.1",
"version": "1.91.1",
"engines": {
"node": ">=18.0.0 <19.0.0"
},
@@ -39,15 +39,15 @@
"@newrelic/winston-enricher": "^4.0.0",
"@sentry/node": "^7.28.1",
"@sentry/tracing": "^7.28.1",
"@simplewebauthn/server": "^7.0.0",
"@standardnotes/api": "^1.24.10",
"@simplewebauthn/server": "^7.0.1",
"@standardnotes/api": "^1.25.3",
"@standardnotes/common": "workspace:*",
"@standardnotes/domain-core": "workspace:^",
"@standardnotes/domain-events": "workspace:*",
"@standardnotes/domain-events-infra": "workspace:*",
"@standardnotes/features": "^1.58.4",
"@standardnotes/predicates": "workspace:*",
"@standardnotes/responses": "^1.13.4",
"@standardnotes/responses": "^1.13.9",
"@standardnotes/security": "workspace:*",
"@standardnotes/settings": "workspace:*",
"@standardnotes/sncrypto-common": "^1.9.0",

View File

@@ -216,6 +216,7 @@ import { DeleteAuthenticator } from '../Domain/UseCase/DeleteAuthenticator/Delet
import { GenerateRecoveryCodes } from '../Domain/UseCase/GenerateRecoveryCodes/GenerateRecoveryCodes'
import { SignInWithRecoveryCodes } from '../Domain/UseCase/SignInWithRecoveryCodes/SignInWithRecoveryCodes'
import { GetUserKeyParamsRecovery } from '../Domain/UseCase/GetUserKeyParamsRecovery/GetUserKeyParamsRecovery'
import { CleanupExpiredSessions } from '../Domain/UseCase/CleanupExpiredSessions/CleanupExpiredSessions'
// eslint-disable-next-line @typescript-eslint/no-var-requires
const newrelicFormatter = require('@newrelic/winston-enricher')
@@ -463,6 +464,10 @@ export class ContainerConfigLoader {
container
.bind(TYPES.U2F_REQUIRE_USER_VERIFICATION)
.toConstantValue(env.get('U2F_REQUIRE_USER_VERIFICATION', true) === 'true')
container
.bind(TYPES.READONLY_USERS)
.toConstantValue(env.get('READONLY_USERS', true) ? env.get('READONLY_USERS', true).split(',') : [])
// Services
container.bind<UAParser>(TYPES.DeviceDetector).toConstantValue(new UAParser())
container.bind<SessionService>(TYPES.SessionService).to(SessionService)
@@ -612,6 +617,9 @@ export class ContainerConfigLoader {
container
.bind<CleanupSessionTraces>(TYPES.CleanupSessionTraces)
.toConstantValue(new CleanupSessionTraces(container.get(TYPES.SessionTraceRepository)))
container
.bind<CleanupExpiredSessions>(TYPES.CleanupExpiredSessions)
.toConstantValue(new CleanupExpiredSessions(container.get(TYPES.SessionRepository)))
container.bind<AuthenticateUser>(TYPES.AuthenticateUser).to(AuthenticateUser)
container.bind<AuthenticateRequest>(TYPES.AuthenticateRequest).to(AuthenticateRequest)
container.bind<RefreshSessionToken>(TYPES.RefreshSessionToken).to(RefreshSessionToken)

View File

@@ -97,6 +97,7 @@ const TYPES = {
U2F_RELYING_PARTY_NAME: Symbol.for('U2F_RELYING_PARTY_NAME'),
U2F_EXPECTED_ORIGIN: Symbol.for('U2F_EXPECTED_ORIGIN'),
U2F_REQUIRE_USER_VERIFICATION: Symbol.for('U2F_REQUIRE_USER_VERIFICATION'),
READONLY_USERS: Symbol.for('READONLY_USERS'),
// use cases
AuthenticateUser: Symbol.for('AuthenticateUser'),
AuthenticateRequest: Symbol.for('AuthenticateRequest'),
@@ -137,6 +138,7 @@ const TYPES = {
ProcessUserRequest: Symbol.for('ProcessUserRequest'),
TraceSession: Symbol.for('TraceSession'),
CleanupSessionTraces: Symbol.for('CleanupSessionTraces'),
CleanupExpiredSessions: Symbol.for('CleanupExpiredSessions'),
PersistStatistics: Symbol.for('PersistStatistics'),
GenerateAuthenticatorRegistrationOptions: Symbol.for('GenerateAuthenticatorRegistrationOptions'),
VerifyAuthenticatorRegistrationResponse: Symbol.for('VerifyAuthenticatorRegistrationResponse'),

View File

@@ -2,12 +2,12 @@ import { inject, injectable } from 'inversify'
import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
import {
ApiVersion,
HttpStatusCode,
UserDeletionResponse,
UserRegistrationRequestParams,
UserRegistrationResponse,
UserServerInterface,
UserDeletionResponseBody,
UserRegistrationResponseBody,
} from '@standardnotes/api'
import { HttpResponse, HttpStatusCode } from '@standardnotes/responses'
import { ProtocolVersion } from '@standardnotes/common'
import TYPES from '../Bootstrap/Types'
@@ -16,13 +16,13 @@ import { Register } from '../Domain/UseCase/Register'
import { DomainEventFactoryInterface } from '../Domain/Event/DomainEventFactoryInterface'
import { SignInWithRecoveryCodes } from '../Domain/UseCase/SignInWithRecoveryCodes/SignInWithRecoveryCodes'
import { SignInWithRecoveryCodesRequestParams } from '../Infra/Http/Request/SignInWithRecoveryCodesRequestParams'
import { SignInWithRecoveryCodesResponse } from '../Infra/Http/Response/SignInWithRecoveryCodesResponse'
import { GetUserKeyParamsRecovery } from '../Domain/UseCase/GetUserKeyParamsRecovery/GetUserKeyParamsRecovery'
import { RecoveryKeyParamsRequestParams } from '../Infra/Http/Request/RecoveryKeyParamsRequestParams'
import { RecoveryKeyParamsResponse } from '../Infra/Http/Response/RecoveryKeyParamsResponse'
import { SignInWithRecoveryCodesResponseBody } from '../Infra/Http/Response/SignInWithRecoveryCodesResponseBody'
import { RecoveryKeyParamsResponseBody } from '../Infra/Http/Response/RecoveryKeyParamsResponseBody'
import { GenerateRecoveryCodesResponseBody } from '../Infra/Http/Response/GenerateRecoveryCodesResponseBody'
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()
@@ -38,11 +38,11 @@ export class AuthController implements UserServerInterface {
@inject(TYPES.Logger) private logger: Logger,
) {}
async deleteAccount(_params: never): Promise<UserDeletionResponse> {
async deleteAccount(_params: never): Promise<HttpResponse<UserDeletionResponseBody>> {
throw new Error('This method is implemented on the payments server.')
}
async register(params: UserRegistrationRequestParams): Promise<UserRegistrationResponse> {
async register(params: UserRegistrationRequestParams): Promise<HttpResponse<UserRegistrationResponseBody>> {
if (!params.email || !params.password) {
return {
status: HttpStatusCode.BadRequest,
@@ -93,7 +93,9 @@ export class AuthController implements UserServerInterface {
}
}
async generateRecoveryCodes(params: GenerateRecoveryCodesRequestParams): Promise<GenerateRecoveryCodesResponse> {
async generateRecoveryCodes(
params: GenerateRecoveryCodesRequestParams,
): Promise<HttpResponse<GenerateRecoveryCodesResponseBody>> {
const result = await this.doGenerateRecoveryCodes.execute({
userUuid: params.userUuid,
})
@@ -119,7 +121,7 @@ export class AuthController implements UserServerInterface {
async signInWithRecoveryCodes(
params: SignInWithRecoveryCodesRequestParams,
): Promise<SignInWithRecoveryCodesResponse> {
): Promise<HttpResponse<SignInWithRecoveryCodesResponseBody>> {
if (params.apiVersion !== ApiVersion.v0) {
return {
status: HttpStatusCode.BadRequest,
@@ -158,7 +160,9 @@ export class AuthController implements UserServerInterface {
}
}
async recoveryKeyParams(params: RecoveryKeyParamsRequestParams): Promise<RecoveryKeyParamsResponse> {
async recoveryKeyParams(
params: RecoveryKeyParamsRequestParams,
): Promise<HttpResponse<RecoveryKeyParamsResponseBody>> {
if (params.apiVersion !== ApiVersion.v0) {
return {
status: HttpStatusCode.BadRequest,

View File

@@ -1,4 +1,4 @@
import { HttpStatusCode } from '@standardnotes/api'
import { HttpResponse, HttpStatusCode } from '@standardnotes/responses'
import { MapperInterface } from '@standardnotes/domain-core'
import { Authenticator } from '../Domain/Authenticator/Authenticator'
import { DeleteAuthenticator } from '../Domain/UseCase/DeleteAuthenticator/DeleteAuthenticator'
@@ -13,11 +13,11 @@ import { GenerateAuthenticatorAuthenticationOptionsRequestParams } from '../Infr
import { GenerateAuthenticatorRegistrationOptionsRequestParams } from '../Infra/Http/Request/GenerateAuthenticatorRegistrationOptionsRequestParams'
import { ListAuthenticatorsRequestParams } from '../Infra/Http/Request/ListAuthenticatorsRequestParams'
import { VerifyAuthenticatorRegistrationResponseRequestParams } from '../Infra/Http/Request/VerifyAuthenticatorRegistrationResponseRequestParams'
import { DeleteAuthenticatorResponse } from '../Infra/Http/Response/DeleteAuthenticatorResponse'
import { GenerateAuthenticatorAuthenticationOptionsResponse } from '../Infra/Http/Response/GenerateAuthenticatorAuthenticationOptionsResponse'
import { GenerateAuthenticatorRegistrationOptionsResponse } from '../Infra/Http/Response/GenerateAuthenticatorRegistrationOptionsResponse'
import { ListAuthenticatorsResponse } from '../Infra/Http/Response/ListAuthenticatorsResponse'
import { VerifyAuthenticatorRegistrationResponseResponse } from '../Infra/Http/Response/VerifyAuthenticatorRegistrationResponseResponse'
import { DeleteAuthenticatorResponseBody } from '../Infra/Http/Response/DeleteAuthenticatorResponseBody'
import { GenerateAuthenticatorAuthenticationOptionsResponseBody } from '../Infra/Http/Response/GenerateAuthenticatorAuthenticationOptionsResponseBody'
import { GenerateAuthenticatorRegistrationOptionsResponseBody } from '../Infra/Http/Response/GenerateAuthenticatorRegistrationOptionsResponseBody'
import { ListAuthenticatorsResponseBody } from '../Infra/Http/Response/ListAuthenticatorsResponseBody'
import { VerifyAuthenticatorRegistrationResponseResponseBody } from '../Infra/Http/Response/VerifyAuthenticatorRegistrationResponseResponseBody'
export class AuthenticatorsController {
constructor(
@@ -29,7 +29,7 @@ export class AuthenticatorsController {
private authenticatorHttpMapper: MapperInterface<Authenticator, AuthenticatorHttpProjection>,
) {}
async list(params: ListAuthenticatorsRequestParams): Promise<ListAuthenticatorsResponse> {
async list(params: ListAuthenticatorsRequestParams): Promise<HttpResponse<ListAuthenticatorsResponseBody>> {
const result = await this.listAuthenticators.execute({
userUuid: params.userUuid,
})
@@ -44,7 +44,7 @@ export class AuthenticatorsController {
}
}
async delete(params: DeleteAuthenticatorRequestParams): Promise<DeleteAuthenticatorResponse> {
async delete(params: DeleteAuthenticatorRequestParams): Promise<HttpResponse<DeleteAuthenticatorResponseBody>> {
const result = await this.deleteAuthenticator.execute({
userUuid: params.userUuid,
authenticatorId: params.authenticatorId,
@@ -60,7 +60,7 @@ export class AuthenticatorsController {
async generateRegistrationOptions(
params: GenerateAuthenticatorRegistrationOptionsRequestParams,
): Promise<GenerateAuthenticatorRegistrationOptionsResponse> {
): Promise<HttpResponse<GenerateAuthenticatorRegistrationOptionsResponseBody>> {
const result = await this.generateAuthenticatorRegistrationOptions.execute({
userUuid: params.userUuid,
username: params.username,
@@ -85,7 +85,7 @@ export class AuthenticatorsController {
async verifyRegistrationResponse(
params: VerifyAuthenticatorRegistrationResponseRequestParams,
): Promise<VerifyAuthenticatorRegistrationResponseResponse> {
): Promise<HttpResponse<VerifyAuthenticatorRegistrationResponseResponseBody>> {
const result = await this.verifyAuthenticatorRegistrationResponse.execute({
userUuid: params.userUuid,
name: params.name,
@@ -111,7 +111,7 @@ export class AuthenticatorsController {
async generateAuthenticationOptions(
params: GenerateAuthenticatorAuthenticationOptionsRequestParams,
): Promise<GenerateAuthenticatorAuthenticationOptionsResponse> {
): Promise<HttpResponse<GenerateAuthenticatorAuthenticationOptionsResponseBody>> {
const result = await this.generateAuthenticatorAuthenticationOptions.execute({
username: params.username,
})

View File

@@ -4,7 +4,7 @@ import { BaseHttpController, controller, httpPost, results } from 'inversify-exp
import { Request, Response } from 'express'
import TYPES from '../Bootstrap/Types'
import { CreateListedAccount } from '../Domain/UseCase/CreateListedAccount/CreateListedAccount'
import { ErrorTag } from '@standardnotes/api'
import { ErrorTag } from '@standardnotes/responses'
@controller('/listed')
export class ListedController extends BaseHttpController {

View File

@@ -1,4 +1,4 @@
import { ErrorTag } from '@standardnotes/api'
import { ErrorTag } from '@standardnotes/responses'
import { Request, Response } from 'express'
import { inject } from 'inversify'
import {

View File

@@ -58,6 +58,10 @@ export class SessionsController extends BaseHttpController {
@httpGet('/', TYPES.AuthMiddleware, TYPES.SessionMiddleware)
async getSessions(_request: Request, response: Response): Promise<results.JsonResult> {
if (response.locals.readOnlyAccess) {
return this.json([])
}
const useCaseResponse = await this.getActiveSessionsForUser.execute({
userUuid: response.locals.user.uuid,
})

View File

@@ -1,4 +1,4 @@
import { ErrorTag } from '@standardnotes/api'
import { ErrorTag } from '@standardnotes/responses'
import { Request, Response } from 'express'
import { inject } from 'inversify'
import {

View File

@@ -1,19 +1,19 @@
import {
AppleIAPConfirmRequestParams,
AppleIAPConfirmResponse,
HttpStatusCode,
AppleIAPConfirmResponseBody,
SubscriptionInviteAcceptRequestParams,
SubscriptionInviteAcceptResponse,
SubscriptionInviteAcceptResponseBody,
SubscriptionInviteCancelRequestParams,
SubscriptionInviteCancelResponse,
SubscriptionInviteCancelResponseBody,
SubscriptionInviteDeclineRequestParams,
SubscriptionInviteDeclineResponse,
SubscriptionInviteDeclineResponseBody,
SubscriptionInviteListRequestParams,
SubscriptionInviteListResponse,
SubscriptionInviteListResponseBody,
SubscriptionInviteRequestParams,
SubscriptionInviteResponse,
SubscriptionInviteResponseBody,
SubscriptionServerInterface,
} from '@standardnotes/api'
import { HttpResponse, HttpStatusCode } from '@standardnotes/responses'
import { inject, injectable } from 'inversify'
import TYPES from '../Bootstrap/Types'
@@ -37,11 +37,13 @@ export class SubscriptionInvitesController implements SubscriptionServerInterfac
private listSharedSubscriptionInvitations: ListSharedSubscriptionInvitations,
) {}
async confirmAppleIAP(_params: AppleIAPConfirmRequestParams): Promise<AppleIAPConfirmResponse> {
async confirmAppleIAP(_params: AppleIAPConfirmRequestParams): Promise<HttpResponse<AppleIAPConfirmResponseBody>> {
throw new Error('Method implemented on the payments service.')
}
async acceptInvite(params: SubscriptionInviteAcceptRequestParams): Promise<SubscriptionInviteAcceptResponse> {
async acceptInvite(
params: SubscriptionInviteAcceptRequestParams,
): Promise<HttpResponse<SubscriptionInviteAcceptResponseBody>> {
const result = await this.acceptSharedSubscriptionInvitation.execute({
sharedSubscriptionInvitationUuid: params.inviteUuid,
})
@@ -59,7 +61,9 @@ export class SubscriptionInvitesController implements SubscriptionServerInterfac
}
}
async declineInvite(params: SubscriptionInviteDeclineRequestParams): Promise<SubscriptionInviteDeclineResponse> {
async declineInvite(
params: SubscriptionInviteDeclineRequestParams,
): Promise<HttpResponse<SubscriptionInviteDeclineResponseBody>> {
const result = await this.declineSharedSubscriptionInvitation.execute({
sharedSubscriptionInvitationUuid: params.inviteUuid,
})
@@ -77,7 +81,7 @@ export class SubscriptionInvitesController implements SubscriptionServerInterfac
}
}
async invite(params: SubscriptionInviteRequestParams): Promise<SubscriptionInviteResponse> {
async invite(params: SubscriptionInviteRequestParams): Promise<HttpResponse<SubscriptionInviteResponseBody>> {
if (!params.identifier) {
return {
status: HttpStatusCode.BadRequest,
@@ -109,7 +113,9 @@ export class SubscriptionInvitesController implements SubscriptionServerInterfac
}
}
async cancelInvite(params: SubscriptionInviteCancelRequestParams): Promise<SubscriptionInviteCancelResponse> {
async cancelInvite(
params: SubscriptionInviteCancelRequestParams,
): Promise<HttpResponse<SubscriptionInviteCancelResponseBody>> {
const result = await this.cancelSharedSubscriptionInvitation.execute({
sharedSubscriptionInvitationUuid: params.inviteUuid,
inviterEmail: params.inviterEmail as string,
@@ -128,7 +134,9 @@ export class SubscriptionInvitesController implements SubscriptionServerInterfac
}
}
async listInvites(params: SubscriptionInviteListRequestParams): Promise<SubscriptionInviteListResponse> {
async listInvites(
params: SubscriptionInviteListRequestParams,
): Promise<HttpResponse<SubscriptionInviteListResponseBody>> {
const result = await this.listSharedSubscriptionInvitations.execute({
inviterEmail: params.inviterEmail as string,
})

View File

@@ -1,5 +1,5 @@
import { CrossServiceTokenData, TokenEncoderInterface } from '@standardnotes/security'
import { ErrorTag } from '@standardnotes/api'
import { ErrorTag } from '@standardnotes/responses'
import { SettingName } from '@standardnotes/settings'
import { Request, Response } from 'express'
import { inject } from 'inversify'

View File

@@ -1,9 +1,5 @@
import {
HttpStatusCode,
UserRequestRequestParams,
UserRequestResponse,
UserRequestServerInterface,
} from '@standardnotes/api'
import { UserRequestRequestParams, UserRequestResponseBody, UserRequestServerInterface } from '@standardnotes/api'
import { HttpResponse, HttpStatusCode } from '@standardnotes/responses'
import { inject, injectable } from 'inversify'
import TYPES from '../Bootstrap/Types'
import { ProcessUserRequest } from '../Domain/UseCase/ProcessUserRequest/ProcessUserRequest'
@@ -12,7 +8,7 @@ import { ProcessUserRequest } from '../Domain/UseCase/ProcessUserRequest/Process
export class UserRequestsController implements UserRequestServerInterface {
constructor(@inject(TYPES.ProcessUserRequest) private processUserRequest: ProcessUserRequest) {}
async submitUserRequest(params: UserRequestRequestParams): Promise<UserRequestResponse> {
async submitUserRequest(params: UserRequestRequestParams): Promise<HttpResponse<UserRequestResponseBody>> {
const result = await this.processUserRequest.execute({
requestType: params.requestType,
userEmail: params.userEmail as string,

View File

@@ -1,6 +1,6 @@
import { Request, Response } from 'express'
import { inject } from 'inversify'
import { ErrorTag } from '@standardnotes/api'
import { ErrorTag } from '@standardnotes/responses'
import {
BaseHttpController,
controller,

View File

@@ -7,8 +7,7 @@ import {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
results,
} from 'inversify-express-utils'
import { CreateValetTokenPayload } from '@standardnotes/responses'
import { ErrorTag } from '@standardnotes/api'
import { CreateValetTokenPayload, ErrorTag } from '@standardnotes/responses'
import { ValetTokenOperation } from '@standardnotes/security'
import { Uuid } from '@standardnotes/domain-core'

View File

@@ -7,6 +7,7 @@ export interface AuthenticatorRepositoryInterface {
findById(id: UniqueEntityId): Promise<Authenticator | null>
findByUserUuidAndCredentialId(userUuid: Uuid, credentialId: string): Promise<Authenticator | null>
save(authenticator: Authenticator): Promise<void>
updateCounter(id: UniqueEntityId, counter: number): Promise<void>
remove(authenticator: Authenticator): Promise<void>
removeByUserUuid(userUuid: Uuid): Promise<void>
}

View File

@@ -12,4 +12,5 @@ export interface SessionRepositoryInterface {
save(session: Session): Promise<Session>
remove(session: Session): Promise<Session>
clearUserAgentByUserUuid(userUuid: string): Promise<void>
removeExpiredBefore(date: Date): Promise<void>
}

View File

@@ -34,6 +34,7 @@ describe('SessionService', () => {
let cryptoNode: CryptoNode
let traceSession: TraceSession
let userSubscriptionRepository: UserSubscriptionRepositoryInterface
const readonlyUsers = ['demo@standardnotes.com']
const createService = () =>
new SessionService(
@@ -49,6 +50,7 @@ describe('SessionService', () => {
cryptoNode,
traceSession,
userSubscriptionRepository,
readonlyUsers,
)
beforeEach(() => {
@@ -59,6 +61,7 @@ describe('SessionService', () => {
session.apiVersion = ApiVersion.v20200115
session.hashedAccessToken = '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce'
session.hashedRefreshToken = '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce'
session.readonlyAccess = false
revokedSession = {} as jest.Mocked<RevokedSession>
revokedSession.uuid = '2e1e43'
@@ -182,6 +185,42 @@ describe('SessionService', () => {
})
})
it('should create new readonly session for a user that is readonly restricted', async () => {
const user = {} as jest.Mocked<User>
user.email = 'demo@standardnotes.com'
user.uuid = '123'
const sessionPayload = await createService().createNewSessionForUser({
user,
apiVersion: '003',
userAgent: 'Google Chrome',
readonlyAccess: false,
})
expect(sessionRepository.save).toHaveBeenCalledWith(expect.any(Session))
expect(sessionRepository.save).toHaveBeenCalledWith({
accessExpiration: expect.any(Date),
apiVersion: '003',
createdAt: expect.any(Date),
hashedAccessToken: expect.any(String),
hashedRefreshToken: expect.any(String),
refreshExpiration: expect.any(Date),
updatedAt: expect.any(Date),
userAgent: 'Google Chrome',
userUuid: '123',
uuid: expect.any(String),
readonlyAccess: true,
})
expect(sessionPayload).toEqual({
access_expiration: 123,
access_token: expect.any(String),
refresh_expiration: 123,
refresh_token: expect.any(String),
readonly_access: true,
})
})
it('should create new session for a user with disabled user agent logging', async () => {
const user = {} as jest.Mocked<User>
user.uuid = '123'
@@ -409,9 +448,9 @@ describe('SessionService', () => {
})
it('should determine if a refresh token is valid', async () => {
expect(createService().isRefreshTokenValid(session, '1:2:3')).toBeTruthy()
expect(createService().isRefreshTokenValid(session, '1:2:4')).toBeFalsy()
expect(createService().isRefreshTokenValid(session, '1:2')).toBeFalsy()
expect(createService().isRefreshTokenMatchingHashedSessionToken(session, '1:2:3')).toBeTruthy()
expect(createService().isRefreshTokenMatchingHashedSessionToken(session, '1:2:4')).toBeFalsy()
expect(createService().isRefreshTokenMatchingHashedSessionToken(session, '1:2')).toBeFalsy()
})
it('should return device info based on user agent', () => {

View File

@@ -39,6 +39,7 @@ export class SessionService implements SessionServiceInterface {
@inject(TYPES.CryptoNode) private cryptoNode: CryptoNode,
@inject(TYPES.TraceSession) private traceSession: TraceSession,
@inject(TYPES.UserSubscriptionRepository) private userSubscriptionRepository: UserSubscriptionRepositoryInterface,
@inject(TYPES.READONLY_USERS) private readonlyUsers: string[],
) {}
async createNewSessionForUser(dto: {
@@ -113,7 +114,7 @@ export class SessionService implements SessionServiceInterface {
return sessionPayload
}
isRefreshTokenValid(session: Session, token: string): boolean {
isRefreshTokenMatchingHashedSessionToken(session: Session, token: string): boolean {
const tokenParts = token.split(':')
const refreshToken = tokenParts[2]
if (!refreshToken) {
@@ -268,7 +269,9 @@ export class SessionService implements SessionServiceInterface {
session.apiVersion = dto.apiVersion
session.createdAt = this.timer.getUTCDate()
session.updatedAt = this.timer.getUTCDate()
session.readonlyAccess = dto.readonlyAccess
const userIsReadonly = this.readonlyUsers.includes(dto.user.email)
session.readonlyAccess = userIsReadonly || dto.readonlyAccess
return session
}
@@ -302,7 +305,7 @@ export class SessionService implements SessionServiceInterface {
refresh_token: `${SessionService.SESSION_TOKEN_VERSION}:${session.uuid}:${refreshToken}`,
access_expiration: this.timer.convertStringDateToMilliseconds(accessTokenExpiration.toString()),
refresh_expiration: this.timer.convertStringDateToMilliseconds(refreshTokenExpiration.toString()),
readonly_access: false,
readonly_access: session.readonlyAccess,
}
}

View File

@@ -21,7 +21,7 @@ export interface SessionServiceInterface {
getRevokedSessionFromToken(token: string): Promise<RevokedSession | null>
markRevokedSessionAsReceived(revokedSession: RevokedSession): Promise<RevokedSession>
deleteSessionByToken(token: string): Promise<string | null>
isRefreshTokenValid(session: Session, token: string): boolean
isRefreshTokenMatchingHashedSessionToken(session: Session, token: string): boolean
getDeviceInfo(session: Session): string
getOperatingSystemInfoFromUserAgent(userAgent: string): string
getBrowserInfoFromUserAgent(userAgent: string): string

View File

@@ -51,7 +51,7 @@ export class SettingsAssociationService implements SettingsAssociationServiceInt
{
sensitive: false,
serverEncryptionVersion: EncryptionVersion.Unencrypted,
value: MuteSignInEmailsOption.NotMuted,
value: MuteSignInEmailsOption.Muted,
replaceable: false,
},
],

View File

@@ -0,0 +1,20 @@
import { SessionRepositoryInterface } from '../../Session/SessionRepositoryInterface'
import { CleanupExpiredSessions } from './CleanupExpiredSessions'
describe('CleanupExpiredSessions', () => {
let sessionsRepository: SessionRepositoryInterface
const createUseCase = () => new CleanupExpiredSessions(sessionsRepository)
beforeEach(() => {
sessionsRepository = {} as jest.Mocked<SessionRepositoryInterface>
sessionsRepository.removeExpiredBefore = jest.fn()
})
it('should remove stale sessions', async () => {
await createUseCase().execute({ date: new Date() })
expect(sessionsRepository.removeExpiredBefore).toHaveBeenCalled()
})
})

View File

@@ -0,0 +1,15 @@
import { Result, UseCaseInterface } from '@standardnotes/domain-core'
import { SessionRepositoryInterface } from '../../Session/SessionRepositoryInterface'
import { CleanupExpiredSessionsDTO } from './CleanupExpiredSessionsDTO'
export class CleanupExpiredSessions implements UseCaseInterface<string> {
constructor(private sessionTracesRepository: SessionRepositoryInterface) {}
async execute(dto: CleanupExpiredSessionsDTO): Promise<Result<string>> {
await this.sessionTracesRepository.removeExpiredBefore(dto.date)
return Result.ok('Expired sessions removed')
}
}

View File

@@ -0,0 +1,3 @@
export interface CleanupExpiredSessionsDTO {
date: Date
}

View File

@@ -38,7 +38,7 @@ export class GenerateAuthenticatorAuthenticationOptions implements UseCaseInterf
transports: [],
},
],
userVerification: 'preferred',
userVerification: 'discouraged',
})
return Result.ok(options)
@@ -57,7 +57,7 @@ export class GenerateAuthenticatorAuthenticationOptions implements UseCaseInterf
type: 'public-key',
transports: authenticator.props.transports,
})),
userVerification: 'preferred',
userVerification: 'discouraged',
})
const authenticatorChallengeOrError = AuthenticatorChallenge.create({

View File

@@ -34,6 +34,10 @@ export class GenerateAuthenticatorRegistrationOptions implements UseCaseInterfac
userID: userUuid.value,
userName: username.value,
attestationType: 'none',
authenticatorSelection: {
authenticatorAttachment: 'cross-platform',
userVerification: 'discouraged',
},
excludeCredentials: authenticators.map((authenticator) => ({
id: authenticator.props.credentialId,
type: 'public-key',

View File

@@ -25,7 +25,7 @@ describe('RefreshSessionToken', () => {
session.refreshExpiration = new Date(123)
sessionService = {} as jest.Mocked<SessionServiceInterface>
sessionService.isRefreshTokenValid = jest.fn().mockReturnValue(true)
sessionService.isRefreshTokenMatchingHashedSessionToken = jest.fn().mockReturnValue(true)
sessionService.getSessionFromToken = jest.fn().mockReturnValue(session)
sessionService.refreshTokens = jest.fn().mockReturnValue({
access_token: 'token1',
@@ -105,7 +105,7 @@ describe('RefreshSessionToken', () => {
})
it('should not refresh a session token if refresh token is not valid', async () => {
sessionService.isRefreshTokenValid = jest.fn().mockReturnValue(false)
sessionService.isRefreshTokenMatchingHashedSessionToken = jest.fn().mockReturnValue(false)
const result = await createUseCase().execute({
accessToken: '123',

View File

@@ -30,7 +30,7 @@ export class RefreshSessionToken {
}
}
if (!this.sessionService.isRefreshTokenValid(session, dto.refreshToken)) {
if (!this.sessionService.isRefreshTokenMatchingHashedSessionToken(session, dto.refreshToken)) {
return {
success: false,
errorTag: 'invalid-refresh-token',

View File

@@ -16,7 +16,7 @@ import { PKCERepositoryInterface } from '../User/PKCERepositoryInterface'
import { CrypterInterface } from '../Encryption/CrypterInterface'
import { SignInDTOV2Challenged } from './SignInDTOV2Challenged'
import { leftVersionGreaterThanOrEqualToRight, ProtocolVersion } from '@standardnotes/common'
import { HttpStatusCode } from '@standardnotes/api'
import { HttpStatusCode } from '@standardnotes/responses'
import { EmailLevel } from '@standardnotes/domain-core'
import { getBody, getSubject } from '../Email/UserSignedIn'

View File

@@ -1,4 +1,4 @@
import { HttpStatusCode } from '@standardnotes/api'
import { HttpStatusCode } from '@standardnotes/responses'
import { AuthResponse20161215 } from '../Auth/AuthResponse20161215'
import { AuthResponse20200115 } from '../Auth/AuthResponse20200115'

View File

@@ -36,7 +36,7 @@ describe('VerifyAuthenticatorAuthenticationResponse', () => {
authenticatorRepository = {} as jest.Mocked<AuthenticatorRepositoryInterface>
authenticatorRepository.findByUserUuidAndCredentialId = jest.fn().mockReturnValue(authenticator)
authenticatorRepository.save = jest.fn()
authenticatorRepository.updateCounter = jest.fn()
authenticatorChallengeRepository = {} as jest.Mocked<AuthenticatorChallengeRepositoryInterface>
authenticatorChallengeRepository.findByUserUuid = jest.fn().mockReturnValue({
@@ -221,6 +221,6 @@ describe('VerifyAuthenticatorAuthenticationResponse', () => {
})
expect(result.isFailed()).toBeFalsy()
expect(authenticatorRepository.save).toHaveBeenCalled()
expect(authenticatorRepository.updateCounter).toHaveBeenCalled()
})
})

View File

@@ -60,9 +60,7 @@ export class VerifyAuthenticatorAuthenticationResponse implements UseCaseInterfa
return Result.fail(`Could not verify authenticator authentication response: ${(error as Error).message}`)
}
authenticator.props.counter = verification.authenticationInfo.newCounter as number
await this.authenticatorRepository.save(authenticator)
await this.authenticatorRepository.updateCounter(authenticator.id, verification.authenticationInfo.newCounter)
return Result.ok(true)
}

View File

@@ -1,5 +1,5 @@
import * as crypto from 'crypto'
import { ErrorTag } from '@standardnotes/api'
import { ErrorTag } from '@standardnotes/responses'
import { SettingName } from '@standardnotes/settings'
import { v4 as uuidv4 } from 'uuid'
import { inject, injectable } from 'inversify'

View File

@@ -1,8 +0,0 @@
import { HttpErrorResponseBody, HttpResponse } from '@standardnotes/api'
import { Either } from '@standardnotes/common'
import { DeleteAuthenticatorResponseBody } from './DeleteAuthenticatorResponseBody'
export interface DeleteAuthenticatorResponse extends HttpResponse {
data: Either<DeleteAuthenticatorResponseBody, HttpErrorResponseBody>
}

View File

@@ -1,8 +0,0 @@
import { HttpErrorResponseBody, HttpResponse } from '@standardnotes/api'
import { Either } from '@standardnotes/common'
import { GenerateAuthenticatorAuthenticationOptionsResponseBody } from './GenerateAuthenticatorAuthenticationOptionsResponseBody'
export interface GenerateAuthenticatorAuthenticationOptionsResponse extends HttpResponse {
data: Either<GenerateAuthenticatorAuthenticationOptionsResponseBody, HttpErrorResponseBody>
}

View File

@@ -1,8 +0,0 @@
import { HttpErrorResponseBody, HttpResponse } from '@standardnotes/api'
import { Either } from '@standardnotes/common'
import { GenerateAuthenticatorRegistrationOptionsResponseBody } from './GenerateAuthenticatorRegistrationOptionsResponseBody'
export interface GenerateAuthenticatorRegistrationOptionsResponse extends HttpResponse {
data: Either<GenerateAuthenticatorRegistrationOptionsResponseBody, HttpErrorResponseBody>
}

View File

@@ -1,8 +0,0 @@
import { HttpErrorResponseBody, HttpResponse } from '@standardnotes/api'
import { Either } from '@standardnotes/common'
import { GenerateRecoveryCodesResponseBody } from './GenerateRecoveryCodesResponseBody'
export interface GenerateRecoveryCodesResponse extends HttpResponse {
data: Either<GenerateRecoveryCodesResponseBody, HttpErrorResponseBody>
}

View File

@@ -1,8 +0,0 @@
import { HttpErrorResponseBody, HttpResponse } from '@standardnotes/api'
import { Either } from '@standardnotes/common'
import { ListAuthenticatorsResponseBody } from './ListAuthenticatorsResponseBody'
export interface ListAuthenticatorsResponse extends HttpResponse {
data: Either<ListAuthenticatorsResponseBody, HttpErrorResponseBody>
}

View File

@@ -1,8 +0,0 @@
import { HttpErrorResponseBody, HttpResponse } from '@standardnotes/api'
import { Either } from '@standardnotes/common'
import { RecoveryKeyParamsResponseBody } from './RecoveryKeyParamsResponseBody'
export interface RecoveryKeyParamsResponse extends HttpResponse {
data: Either<RecoveryKeyParamsResponseBody, HttpErrorResponseBody>
}

View File

@@ -1,8 +0,0 @@
import { HttpErrorResponseBody, HttpResponse } from '@standardnotes/api'
import { Either } from '@standardnotes/common'
import { SignInWithRecoveryCodesResponseBody } from './SignInWithRecoveryCodesResponseBody'
export interface SignInWithRecoveryCodesResponse extends HttpResponse {
data: Either<SignInWithRecoveryCodesResponseBody, HttpErrorResponseBody>
}

View File

@@ -1,8 +0,0 @@
import { HttpErrorResponseBody, HttpResponse } from '@standardnotes/api'
import { Either } from '@standardnotes/common'
import { VerifyAuthenticatorAuthenticationResponseResponseBody } from './VerifyAuthenticatorAuthenticationResponseResponseBody'
export interface VerifyAuthenticatorAuthenticationResponseResponse extends HttpResponse {
data: Either<VerifyAuthenticatorAuthenticationResponseResponseBody, HttpErrorResponseBody>
}

View File

@@ -1,8 +0,0 @@
import { HttpErrorResponseBody, HttpResponse } from '@standardnotes/api'
import { Either } from '@standardnotes/common'
import { VerifyAuthenticatorRegistrationResponseResponseBody } from './VerifyAuthenticatorRegistrationResponseResponseBody'
export interface VerifyAuthenticatorRegistrationResponseResponse extends HttpResponse {
data: Either<VerifyAuthenticatorRegistrationResponseResponseBody, HttpErrorResponseBody>
}

View File

@@ -1,5 +1,5 @@
import { Request, Response } from 'express'
import { ErrorTag } from '@standardnotes/api'
import { ErrorTag } from '@standardnotes/responses'
import {
BaseHttpController,
controller,

View File

@@ -1,4 +1,4 @@
import { ErrorTag } from '@standardnotes/api'
import { ErrorTag } from '@standardnotes/responses'
import { TokenDecoderInterface, WebSocketConnectionTokenData } from '@standardnotes/security'
import { Request } from 'express'
import { inject } from 'inversify'

View File

@@ -11,6 +11,19 @@ export class MySQLAuthenticatorRepository implements AuthenticatorRepositoryInte
private mapper: MapperInterface<Authenticator, TypeORMAuthenticator>,
) {}
async updateCounter(id: UniqueEntityId, counter: number): Promise<void> {
await this.ormRepository
.createQueryBuilder()
.update()
.set({
counter,
})
.where('uuid = :uuid', {
uuid: id.toString(),
})
.execute()
}
async removeByUserUuid(userUuid: Uuid): Promise<void> {
await this.ormRepository
.createQueryBuilder()

View File

@@ -1,3 +1,4 @@
import { TimerInterface } from '@standardnotes/time'
import * as dayjs from 'dayjs'
import { inject, injectable } from 'inversify'
@@ -12,6 +13,7 @@ export class MySQLSessionRepository implements SessionRepositoryInterface {
constructor(
@inject(TYPES.ORMSessionRepository)
private ormRepository: Repository<Session>,
@inject(TYPES.Timer) private timer: TimerInterface,
) {}
async save(session: Session): Promise<Session> {
@@ -22,12 +24,17 @@ export class MySQLSessionRepository implements SessionRepositoryInterface {
return this.ormRepository.remove(session)
}
async removeExpiredBefore(date: Date): Promise<void> {
await this.ormRepository.createQueryBuilder().delete().where('refresh_expiration < :date', { date }).execute()
}
async clearUserAgentByUserUuid(userUuid: string): Promise<void> {
await this.ormRepository
.createQueryBuilder('session')
.update()
.set({
userAgent: null,
updatedAt: this.timer.getUTCDate(),
})
.where('user_uuid = :userUuid', { userUuid })
.execute()
@@ -40,6 +47,7 @@ export class MySQLSessionRepository implements SessionRepositoryInterface {
.set({
hashedAccessToken,
hashedRefreshToken,
updatedAt: this.timer.getUTCDate(),
})
.where('uuid = :uuid', { uuid })
.execute()
@@ -52,6 +60,7 @@ export class MySQLSessionRepository implements SessionRepositoryInterface {
.set({
accessExpiration,
refreshExpiration,
updatedAt: this.timer.getUTCDate(),
})
.where('uuid = :uuid', { uuid })
.execute()

View File

@@ -1 +0,0 @@
dist

View File

@@ -1,6 +0,0 @@
{
"extends": "../../.eslintrc",
"parserOptions": {
"project": "./linter.tsconfig.json"
}
}

View File

@@ -1,40 +0,0 @@
# Change Log
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.1.6](https://github.com/standardnotes/server/compare/@standardnotes/proxy-server@1.1.5...@standardnotes/proxy-server@1.1.6) (2023-02-23)
### Bug Fixes
* **proxy:** make healthcheck endpoint accessible at all times ([b1122a3](https://github.com/standardnotes/server/commit/b1122a3da5d0fe02b80b91da5e96cffbad994ce2))
## [1.1.5](https://github.com/standardnotes/server/compare/@standardnotes/proxy-server@1.1.4...@standardnotes/proxy-server@1.1.5) (2023-02-22)
**Note:** Version bump only for package @standardnotes/proxy-server
## [1.1.4](https://github.com/standardnotes/server/compare/@standardnotes/proxy-server@1.1.3...@standardnotes/proxy-server@1.1.4) (2023-02-22)
**Note:** Version bump only for package @standardnotes/proxy-server
## [1.1.3](https://github.com/standardnotes/server/compare/@standardnotes/proxy-server@1.1.2...@standardnotes/proxy-server@1.1.3) (2023-02-22)
**Note:** Version bump only for package @standardnotes/proxy-server
## [1.1.2](https://github.com/standardnotes/server/compare/@standardnotes/proxy-server@1.1.1...@standardnotes/proxy-server@1.1.2) (2023-02-22)
**Note:** Version bump only for package @standardnotes/proxy-server
## [1.1.1](https://github.com/standardnotes/server/compare/@standardnotes/proxy-server@1.1.0...@standardnotes/proxy-server@1.1.1) (2023-02-22)
**Note:** Version bump only for package @standardnotes/proxy-server
# 1.1.0 (2023-02-22)
### Bug Fixes
* **proxy:** prevent from passing auth tokens to proxy destination ([91c70a5](https://github.com/standardnotes/server/commit/91c70a51a067c606afc3570764367a6d60910ce3))
### Features
* **proxy:** add proxy server ([dfe30d7](https://github.com/standardnotes/server/commit/dfe30d7f5e8598ec1886db0e061b7d593cc27e29))

View File

@@ -1,17 +0,0 @@
FROM node:18.13.0-alpine
RUN apk add --update \
curl \
&& rm -rf /var/cache/apk/*
ENV NODE_ENV production
RUN corepack enable
COPY ./ /workspace
WORKDIR /workspace/packages/proxy
ENTRYPOINT [ "/workspace/packages/proxy/docker/entrypoint.sh" ]
CMD [ "start-web" ]

View File

@@ -1,91 +0,0 @@
import * as http from 'http'
import * as https from 'https'
import * as path from 'path'
const MAX_IMAGE_SIZE = 10 * 1024 * 1024
const ENABLED = false
http
.createServer((req, res) => {
if (req.url === '/healthcheck') {
res.writeHead(200)
res.end()
return
}
if (!ENABLED) {
res.writeHead(404)
res.end()
return
}
res.setHeader('Access-Control-Allow-Origin', '*')
res.setHeader('Access-Control-Request-Method', '*')
res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET')
res.setHeader('Access-Control-Allow-Headers', '*')
if (req.method === 'OPTIONS') {
res.writeHead(200)
res.end()
return
}
delete req.headers.authorization
delete req.headers['x-auth-token']
delete req.headers['x-auth-offline-token']
/** Remove / or // prefixes */
const target = (req.url as string).replace(/^\/+/, '')
try {
const url = new URL(target)
if (url.protocol !== 'http:' && url.protocol !== 'https:') {
throw new Error('Invalid URL protocol')
}
if (url.hostname === '') {
throw new Error('Invalid URL hostname')
}
const ext = path.extname(url.pathname)
if (!['.jpg', '.jpeg', '.png', '.gif'].includes(ext)) {
res.writeHead(400)
res.end('Only image files can be proxied')
return
}
const library = url.protocol === 'http:' ? http : https
const proxyRequest = library
.get(url.href, (targetRes) => {
let totalSize = 0
targetRes.on('data', (chunk) => {
totalSize += chunk.length
if (totalSize > MAX_IMAGE_SIZE) {
proxyRequest.destroy(new Error('Image size exceeds the limit.'))
}
})
targetRes.on('end', () => {
const contentType = targetRes.headers['content-type']
if (!contentType || !contentType.startsWith('image/')) {
res.writeHead(400, { 'Content-Type': 'text/plain' })
res.end(`Invalid content type: ${contentType}`)
return
}
res.writeHead(targetRes.statusCode as number, targetRes.headers)
targetRes.pipe(res)
})
})
.on('error', (error) => {
res.writeHead(500)
res.end(`Error: ${error.message}`)
})
} catch (error) {
res.writeHead(500)
res.end(`Invalid URL: ${target} Error: ${error}`)
}
})
.listen(3000)

View File

@@ -1,11 +0,0 @@
'use strict'
const path = require('path')
const pnp = require(path.normalize(path.resolve(__dirname, '../../..', '.pnp.cjs'))).setup()
const index = require(path.normalize(path.resolve(__dirname, '../dist/bin/server.js')))
Object.defineProperty(exports, '__esModule', { value: true })
exports.default = index

View File

@@ -1,17 +0,0 @@
#!/bin/sh
set -e
COMMAND=$1 && shift 1
case "$COMMAND" in
'start-web' )
echo "[Docker] Starting Web..."
node docker/entrypoint-server.js
;;
* )
echo "Unknown command"
;;
esac
exec "$@"

View File

@@ -1,4 +0,0 @@
{
"extends": "./tsconfig.json",
"exclude": ["dist"]
}

View File

@@ -1,32 +0,0 @@
{
"name": "@standardnotes/proxy-server",
"version": "1.1.6",
"engines": {
"node": ">=18.0.0 <19.0.0"
},
"private": true,
"description": "Proxy Server",
"main": "dist/src/index.js",
"typings": "dist/src/index.d.ts",
"repository": "git@github.com:standardnotes/server.git",
"author": "Karol Sójko <karolsojko@standardnotes.com>",
"license": "AGPL-3.0-or-later",
"scripts": {
"clean": "rm -fr dist",
"build": "tsc --build",
"lint": "eslint . --ext .ts",
"lint:fix": "eslint . --ext .ts --fix",
"start": "yarn node dist/bin/server.js"
},
"dependencies": {
"newrelic": "^9.8.0"
},
"devDependencies": {
"@types/newrelic": "^9.4.0",
"@types/node": "^18.14.0",
"@typescript-eslint/eslint-plugin": "^5.48.2",
"eslint": "^8.32.0",
"eslint-plugin-prettier": "^4.0.0",
"typescript": "^4.8.4"
}
}

View File

@@ -1,11 +0,0 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"composite": true,
"outDir": "./dist",
},
"include": [
"bin/**/*",
],
"references": []
}

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.12.7](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.12.6...@standardnotes/revisions-server@1.12.7) (2023-03-01)
**Note:** Version bump only for package @standardnotes/revisions-server
## [1.12.6](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.12.5...@standardnotes/revisions-server@1.12.6) (2023-02-23)
**Note:** Version bump only for package @standardnotes/revisions-server

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/revisions-server",
"version": "1.12.6",
"version": "1.12.7",
"engines": {
"node": ">=18.0.0 <19.0.0"
},
@@ -27,11 +27,12 @@
"@aws-sdk/client-sqs": "^3.259.0",
"@newrelic/winston-enricher": "^4.0.0",
"@sentry/node": "^7.28.1",
"@standardnotes/api": "^1.24.10",
"@standardnotes/api": "^1.25.3",
"@standardnotes/common": "workspace:^",
"@standardnotes/domain-core": "workspace:^",
"@standardnotes/domain-events": "workspace:*",
"@standardnotes/domain-events-infra": "workspace:*",
"@standardnotes/responses": "^1.13.9",
"@standardnotes/security": "workspace:^",
"@standardnotes/time": "workspace:^",
"cors": "2.8.5",

View File

@@ -1,5 +1,5 @@
import { Logger } from 'winston'
import { HttpResponse, HttpStatusCode } from '@standardnotes/api'
import { HttpResponse, HttpStatusCode } from '@standardnotes/responses'
import { GetRevisionsMetada } from '../Domain/UseCase/GetRevisionsMetada/GetRevisionsMetada'
import { GetRevisionsMetadataRequestParams } from '../Infra/Http/Request/GetRevisionsMetadataRequestParams'
@@ -7,8 +7,8 @@ import { GetRevisionRequestParams } from '../Infra/Http/Request/GetRevisionReque
import { DeleteRevisionRequestParams } from '../Infra/Http/Request/DeleteRevisionRequestParams'
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 { GetRevisionsMetadataResponseBody } from '../Infra/Http/Response/GetRevisionsMetadataResponseBody'
import { GetRevisionResponseBody } from '../Infra/Http/Response/GetRevisionResponseBody'
import { MapperInterface } from '@standardnotes/domain-core'
import { Revision } from '../Domain/Revision/Revision'
import { RevisionMetadata } from '../Domain/Revision/RevisionMetadata'
@@ -44,7 +44,9 @@ export class RevisionsController {
private logger: Logger,
) {}
async getRevisions(params: GetRevisionsMetadataRequestParams): Promise<GetRevisionsMetadataResponse> {
async getRevisions(
params: GetRevisionsMetadataRequestParams,
): Promise<HttpResponse<GetRevisionsMetadataResponseBody>> {
const revisionMetadataOrError = await this.getRevisionsMetadata.execute({
itemUuid: params.itemUuid,
userUuid: params.userUuid,
@@ -75,7 +77,7 @@ export class RevisionsController {
}
}
async getRevision(params: GetRevisionRequestParams): Promise<GetRevisionResponse> {
async getRevision(params: GetRevisionRequestParams): Promise<HttpResponse<GetRevisionResponseBody>> {
const revisionOrError = await this.doGetRevision.execute({
revisionUuid: params.revisionUuid,
userUuid: params.userUuid,

View File

@@ -1,8 +0,0 @@
import { HttpErrorResponseBody, HttpResponse } from '@standardnotes/api'
import { Either } from '@standardnotes/common'
import { GetRevisionResponseBody } from './GetRevisionResponseBody'
export interface GetRevisionResponse extends HttpResponse {
data: Either<GetRevisionResponseBody, HttpErrorResponseBody>
}

View File

@@ -1,8 +0,0 @@
import { HttpErrorResponseBody, HttpResponse } from '@standardnotes/api'
import { Either } from '@standardnotes/common'
import { GetRevisionsMetadataResponseBody } from './GetRevisionsMetadataResponseBody'
export interface GetRevisionsMetadataResponse extends HttpResponse {
data: Either<GetRevisionsMetadataResponseBody, HttpErrorResponseBody>
}

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.31.8](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.31.7...@standardnotes/syncing-server@1.31.8) (2023-03-01)
**Note:** Version bump only for package @standardnotes/syncing-server
## [1.31.7](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.31.6...@standardnotes/syncing-server@1.31.7) (2023-02-23)
**Note:** Version bump only for package @standardnotes/syncing-server

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/syncing-server",
"version": "1.31.7",
"version": "1.31.8",
"engines": {
"node": ">=18.0.0 <19.0.0"
},
@@ -31,12 +31,12 @@
"@newrelic/winston-enricher": "^4.0.0",
"@sentry/node": "^7.28.1",
"@sentry/tracing": "^7.28.1",
"@standardnotes/api": "^1.24.10",
"@standardnotes/api": "^1.25.3",
"@standardnotes/common": "workspace:*",
"@standardnotes/domain-core": "workspace:^",
"@standardnotes/domain-events": "workspace:*",
"@standardnotes/domain-events-infra": "workspace:*",
"@standardnotes/responses": "^1.13.4",
"@standardnotes/responses": "^1.13.9",
"@standardnotes/security": "workspace:*",
"@standardnotes/settings": "workspace:*",
"@standardnotes/time": "workspace:*",

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.6.6](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.6.5...@standardnotes/websockets-server@1.6.6) (2023-03-01)
**Note:** Version bump only for package @standardnotes/websockets-server
## [1.6.5](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.6.4...@standardnotes/websockets-server@1.6.5) (2023-02-23)
**Note:** Version bump only for package @standardnotes/websockets-server

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/websockets-server",
"version": "1.6.5",
"version": "1.6.6",
"engines": {
"node": ">=18.0.0 <19.0.0"
},
@@ -25,11 +25,12 @@
"@aws-sdk/client-sqs": "^3.259.0",
"@newrelic/winston-enricher": "^4.0.0",
"@sentry/node": "^7.28.1",
"@standardnotes/api": "^1.24.10",
"@standardnotes/api": "^1.25.3",
"@standardnotes/common": "workspace:^",
"@standardnotes/domain-core": "workspace:^",
"@standardnotes/domain-events": "workspace:^",
"@standardnotes/domain-events-infra": "workspace:^",
"@standardnotes/responses": "^1.13.9",
"@standardnotes/security": "workspace:^",
"@standardnotes/utils": "^1.16.2",
"axios": "^1.1.3",

View File

@@ -1,7 +1,7 @@
import { HttpStatusCode, HttpResponse } from '@standardnotes/responses'
import {
HttpStatusCode,
WebSocketConnectionTokenRequestParams,
WebSocketConnectionTokenResponse,
WebSocketConnectionTokenResponseBody,
WebSocketServerInterface,
} from '@standardnotes/api'
import { inject, injectable } from 'inversify'
@@ -18,7 +18,7 @@ export class WebSocketsController implements WebSocketServerInterface {
async createConnectionToken(
params: WebSocketConnectionTokenRequestParams,
): Promise<WebSocketConnectionTokenResponse> {
): Promise<HttpResponse<WebSocketConnectionTokenResponseBody>> {
const result = await this.createWebSocketConnectionToken.execute({ userUuid: params.userUuid as string })
return {

View File

@@ -53,9 +53,6 @@
{
"path": "./packages/predicates"
},
{
"path": "./packages/proxy"
},
{
"path": "./packages/revisions"
},

171
yarn.lock
View File

@@ -2893,7 +2893,7 @@ __metadata:
languageName: node
linkType: hard
"@peculiar/asn1-android@npm:^2.1.7":
"@peculiar/asn1-android@npm:^2.3.3":
version: 2.3.3
resolution: "@peculiar/asn1-android@npm:2.3.3"
dependencies:
@@ -2928,7 +2928,7 @@ __metadata:
languageName: node
linkType: hard
"@peculiar/asn1-schema@npm:^2.1.7, @peculiar/asn1-schema@npm:^2.3.3":
"@peculiar/asn1-schema@npm:^2.3.3":
version: 2.3.3
resolution: "@peculiar/asn1-schema@npm:2.3.3"
dependencies:
@@ -2939,7 +2939,7 @@ __metadata:
languageName: node
linkType: hard
"@peculiar/asn1-x509@npm:^2.1.7, @peculiar/asn1-x509@npm:^2.3.4":
"@peculiar/asn1-x509@npm:^2.3.4":
version: 2.3.4
resolution: "@peculiar/asn1-x509@npm:2.3.4"
dependencies:
@@ -3099,28 +3099,28 @@ __metadata:
languageName: node
linkType: hard
"@simplewebauthn/iso-webcrypto@npm:^7.0.0":
version: 7.0.0
resolution: "@simplewebauthn/iso-webcrypto@npm:7.0.0"
checksum: c1644f9b68dafc0e4afc76e671a3a59f5b86b7f6846f4e947718b97e3656afbf2a6499f2dff4cfc0ca302cf81564755774505863c76798da61e3d5daae55a837
"@simplewebauthn/iso-webcrypto@npm:^7.0.1":
version: 7.0.1
resolution: "@simplewebauthn/iso-webcrypto@npm:7.0.1"
checksum: ed506490e0818e22b81e8bbe452ff1dc8d82e459a428bc046e8fd02257c574112900dea383c434a5ac7d9fb2e02e047dc409d7569d46f6c7eedb357b9973aa23
languageName: node
linkType: hard
"@simplewebauthn/server@npm:^7.0.0":
version: 7.0.0
resolution: "@simplewebauthn/server@npm:7.0.0"
"@simplewebauthn/server@npm:^7.0.1":
version: 7.0.1
resolution: "@simplewebauthn/server@npm:7.0.1"
dependencies:
"@hexagon/base64": "npm:^1.1.25"
"@peculiar/asn1-android": "npm:^2.1.7"
"@peculiar/asn1-android": "npm:^2.3.3"
"@peculiar/asn1-ecc": "npm:^2.3.4"
"@peculiar/asn1-rsa": "npm:^2.3.4"
"@peculiar/asn1-schema": "npm:^2.1.7"
"@peculiar/asn1-x509": "npm:^2.1.7"
"@simplewebauthn/iso-webcrypto": "npm:^7.0.0"
"@peculiar/asn1-schema": "npm:^2.3.3"
"@peculiar/asn1-x509": "npm:^2.3.4"
"@simplewebauthn/iso-webcrypto": "npm:^7.0.1"
cbor-x: "npm:^1.4.1"
cross-fetch: "npm:^3.1.5"
debug: "npm:^4.3.2"
checksum: 836eb9fb97961e01fdb5f1b2719b5be1d4f28abd5aa24081584c2209a071aa37146235621d1005ba4c8a585661e7fb1c134f041a0d1c123012b1f198757a7b28
checksum: d11c708008845723f355624d309a476c32e4abcb3189ab477188583f41a618567852f027b71445d29e7a9ab36f4620e01a7bf334d0c8a01cf8fec4e0e8bdfcff
languageName: node
linkType: hard
@@ -3250,19 +3250,19 @@ __metadata:
languageName: unknown
linkType: soft
"@standardnotes/api@npm:^1.24.10":
version: 1.24.10
resolution: "@standardnotes/api@npm:1.24.10"
"@standardnotes/api@npm:^1.25.3":
version: 1.25.3
resolution: "@standardnotes/api@npm:1.25.3"
dependencies:
"@standardnotes/common": "npm:^1.46.4"
"@standardnotes/domain-core": "npm:^1.11.1"
"@standardnotes/encryption": "npm:1.21.9"
"@standardnotes/models": "npm:1.42.11"
"@standardnotes/responses": "npm:1.13.6"
"@standardnotes/domain-core": "npm:^1.11.3"
"@standardnotes/encryption": "npm:1.21.17"
"@standardnotes/models": "npm:1.43.5"
"@standardnotes/responses": "npm:1.13.9"
"@standardnotes/security": "npm:^1.7.5"
"@standardnotes/utils": "npm:1.16.3"
"@standardnotes/utils": "npm:1.16.4"
reflect-metadata: "npm:^0.1.13"
checksum: 1b9a97fdd8f2951dac9f9c8d730b23825e4093a3c882004128e618f43de64d1c9050f3de0609bd0ff3999a8bfce2d203a2bce36d2132be3cd42ea7f310509620
checksum: bc7953c4402ed3b96ae966717a1d81685e43187d3bdcc640e99256a8342d15901d7bdbd9cb34db99abba18fd86d1bb283bba66506f9a42598d86f11f01dd533d
languageName: node
linkType: hard
@@ -3277,16 +3277,16 @@ __metadata:
"@newrelic/winston-enricher": "npm:^4.0.0"
"@sentry/node": "npm:^7.28.1"
"@sentry/tracing": "npm:^7.28.1"
"@simplewebauthn/server": "npm:^7.0.0"
"@simplewebauthn/server": "npm:^7.0.1"
"@simplewebauthn/typescript-types": "npm:^7.0.0"
"@standardnotes/api": "npm:^1.24.10"
"@standardnotes/api": "npm:^1.25.3"
"@standardnotes/common": "workspace:*"
"@standardnotes/domain-core": "workspace:^"
"@standardnotes/domain-events": "workspace:*"
"@standardnotes/domain-events-infra": "workspace:*"
"@standardnotes/features": "npm:^1.58.4"
"@standardnotes/predicates": "workspace:*"
"@standardnotes/responses": "npm:^1.13.4"
"@standardnotes/responses": "npm:^1.13.9"
"@standardnotes/security": "workspace:*"
"@standardnotes/settings": "workspace:*"
"@standardnotes/sncrypto-common": "npm:^1.9.0"
@@ -3359,7 +3359,7 @@ __metadata:
languageName: node
linkType: hard
"@standardnotes/domain-core@npm:^1.11.1, @standardnotes/domain-core@workspace:^, @standardnotes/domain-core@workspace:packages/domain-core":
"@standardnotes/domain-core@npm:^1.11.1, @standardnotes/domain-core@npm:^1.11.3, @standardnotes/domain-core@workspace:^, @standardnotes/domain-core@workspace:packages/domain-core":
version: 0.0.0-use.local
resolution: "@standardnotes/domain-core@workspace:packages/domain-core"
dependencies:
@@ -3412,17 +3412,17 @@ __metadata:
languageName: unknown
linkType: soft
"@standardnotes/encryption@npm:1.21.9":
version: 1.21.9
resolution: "@standardnotes/encryption@npm:1.21.9"
"@standardnotes/encryption@npm:1.21.17":
version: 1.21.17
resolution: "@standardnotes/encryption@npm:1.21.17"
dependencies:
"@standardnotes/common": "npm:^1.46.4"
"@standardnotes/models": "npm:1.42.11"
"@standardnotes/responses": "npm:1.13.6"
"@standardnotes/models": "npm:1.43.5"
"@standardnotes/responses": "npm:1.13.9"
"@standardnotes/sncrypto-common": "npm:1.13.3"
"@standardnotes/utils": "npm:1.16.3"
"@standardnotes/utils": "npm:1.16.4"
reflect-metadata: "npm:^0.1.13"
checksum: dc1336cc052780a2b7d59b65c1e86e3ee008bc38ecf50d204514edc36ef0de6a92483cfb00e67bcf7acc541957059db0eb4611feccd3c8eff00ccc05763cf4ab
checksum: ece7ac644e1fd8e2a03c9b32a013ee6987b24c4a968ef228dc5bbc6c855518f711467dc63b517f112af71ecfbd28b408816a43d0642bed0bd9d5c336b59dc0ad
languageName: node
linkType: hard
@@ -3455,7 +3455,19 @@ __metadata:
languageName: unknown
linkType: soft
"@standardnotes/features@npm:1.58.4, @standardnotes/features@npm:^1.58.4":
"@standardnotes/features@npm:1.58.8":
version: 1.58.8
resolution: "@standardnotes/features@npm:1.58.8"
dependencies:
"@standardnotes/common": "npm:^1.46.4"
"@standardnotes/domain-core": "npm:^1.11.3"
"@standardnotes/security": "npm:^1.7.5"
reflect-metadata: "npm:^0.1.13"
checksum: 77bac7d0a024daa0d22d6cebebbccd0f5c1e8356e28670e959424bf0841d1b8ca98c43df45cdccc59ecab704a2bd638dfe629c1806e890d6715e6ab39f930499
languageName: node
linkType: hard
"@standardnotes/features@npm:^1.58.4":
version: 1.58.4
resolution: "@standardnotes/features@npm:1.58.4"
dependencies:
@@ -3467,18 +3479,6 @@ __metadata:
languageName: node
linkType: hard
"@standardnotes/features@npm:1.58.6":
version: 1.58.6
resolution: "@standardnotes/features@npm:1.58.6"
dependencies:
"@standardnotes/common": "npm:^1.46.4"
"@standardnotes/domain-core": "npm:^1.11.1"
"@standardnotes/security": "npm:^1.7.5"
reflect-metadata: "npm:^0.1.13"
checksum: 98550416f1e8fb588611356e9e93b2ff7580b62ceb30251a575a4c4a193519e63fcdcd0d0e06ff10a1184e371a2f673bc81033c9e7f210464917f3c42d45dc7c
languageName: node
linkType: hard
"@standardnotes/files-server@workspace:packages/files":
version: 0.0.0-use.local
resolution: "@standardnotes/files-server@workspace:packages/files"
@@ -3533,16 +3533,16 @@ __metadata:
languageName: unknown
linkType: soft
"@standardnotes/models@npm:1.42.11":
version: 1.42.11
resolution: "@standardnotes/models@npm:1.42.11"
"@standardnotes/models@npm:1.43.5":
version: 1.43.5
resolution: "@standardnotes/models@npm:1.43.5"
dependencies:
"@standardnotes/common": "npm:^1.46.4"
"@standardnotes/features": "npm:1.58.6"
"@standardnotes/responses": "npm:1.13.6"
"@standardnotes/utils": "npm:^1.16.3"
"@standardnotes/features": "npm:1.58.8"
"@standardnotes/responses": "npm:1.13.9"
"@standardnotes/utils": "npm:^1.16.4"
lodash: "npm:^4.17.21"
checksum: 6ff3409f70b576d97d530df1f597d04a8ca620240fcea6ba477b3b0c3cda9fcfbe5f9a17932543162fececffe02f84bea0e5dbefde790335a912e76ba11e54ef
checksum: fd8e3b60bdfcf1d25561082c669a540e4c1938ddb4bbde03b4da391d4639aaf9727d48db7d20f02f885f70d8643921791a916b6c2f3fbc4100e60e5b53445327
languageName: node
linkType: hard
@@ -3559,41 +3559,15 @@ __metadata:
languageName: unknown
linkType: soft
"@standardnotes/proxy-server@workspace:packages/proxy":
version: 0.0.0-use.local
resolution: "@standardnotes/proxy-server@workspace:packages/proxy"
dependencies:
"@types/newrelic": "npm:^9.4.0"
"@types/node": "npm:^18.14.0"
"@typescript-eslint/eslint-plugin": "npm:^5.48.2"
eslint: "npm:^8.32.0"
eslint-plugin-prettier: "npm:^4.0.0"
newrelic: "npm:^9.8.0"
typescript: "npm:^4.8.4"
languageName: unknown
linkType: soft
"@standardnotes/responses@npm:1.13.6":
version: 1.13.6
resolution: "@standardnotes/responses@npm:1.13.6"
"@standardnotes/responses@npm:1.13.9, @standardnotes/responses@npm:^1.13.9":
version: 1.13.9
resolution: "@standardnotes/responses@npm:1.13.9"
dependencies:
"@standardnotes/common": "npm:^1.46.4"
"@standardnotes/features": "npm:1.58.6"
"@standardnotes/features": "npm:1.58.8"
"@standardnotes/security": "npm:^1.7.5"
reflect-metadata: "npm:^0.1.13"
checksum: c57e3e1fa10333c6eaabec4b5c248a9fd8f2631e337113f9f165b30703b4074adebb8e48435786cfaddb63769f0939f167f64ae37b6a93cc156520dbeae795ae
languageName: node
linkType: hard
"@standardnotes/responses@npm:^1.13.4":
version: 1.13.4
resolution: "@standardnotes/responses@npm:1.13.4"
dependencies:
"@standardnotes/common": "npm:^1.46.4"
"@standardnotes/features": "npm:1.58.4"
"@standardnotes/security": "npm:^1.7.5"
reflect-metadata: "npm:^0.1.13"
checksum: 4803ee14bd036f8bc3690e3da29ea51d9041f2c283f03b9069e0c7a781e4953002039416f420a88f460157a183a560997d04d4e257ccdbf67981e8fec71dfa88
checksum: 5cb5daf9f3c5c402fadbea7a654267d8f9564ad7696f7919e1661a46ac4a1767f44e1b00e97f6e9e79f7a74600559502cdc5250e7eabd1934f632735e7ed1565
languageName: node
linkType: hard
@@ -3605,11 +3579,12 @@ __metadata:
"@aws-sdk/client-sqs": "npm:^3.259.0"
"@newrelic/winston-enricher": "npm:^4.0.0"
"@sentry/node": "npm:^7.28.1"
"@standardnotes/api": "npm:^1.24.10"
"@standardnotes/api": "npm:^1.25.3"
"@standardnotes/common": "workspace:^"
"@standardnotes/domain-core": "workspace:^"
"@standardnotes/domain-events": "workspace:*"
"@standardnotes/domain-events-infra": "workspace:*"
"@standardnotes/responses": "npm:^1.13.9"
"@standardnotes/security": "workspace:^"
"@standardnotes/time": "workspace:^"
"@types/cors": "npm:^2.8.9"
@@ -3772,12 +3747,12 @@ __metadata:
"@newrelic/winston-enricher": "npm:^4.0.0"
"@sentry/node": "npm:^7.28.1"
"@sentry/tracing": "npm:^7.28.1"
"@standardnotes/api": "npm:^1.24.10"
"@standardnotes/api": "npm:^1.25.3"
"@standardnotes/common": "workspace:*"
"@standardnotes/domain-core": "workspace:^"
"@standardnotes/domain-events": "workspace:*"
"@standardnotes/domain-events-infra": "workspace:*"
"@standardnotes/responses": "npm:^1.13.4"
"@standardnotes/responses": "npm:^1.13.9"
"@standardnotes/security": "workspace:*"
"@standardnotes/settings": "workspace:*"
"@standardnotes/time": "workspace:*"
@@ -3835,15 +3810,15 @@ __metadata:
languageName: unknown
linkType: soft
"@standardnotes/utils@npm:1.16.3, @standardnotes/utils@npm:^1.16.3":
version: 1.16.3
resolution: "@standardnotes/utils@npm:1.16.3"
"@standardnotes/utils@npm:1.16.4, @standardnotes/utils@npm:^1.16.4":
version: 1.16.4
resolution: "@standardnotes/utils@npm:1.16.4"
dependencies:
"@standardnotes/common": "npm:^1.46.4"
dompurify: "npm:^2.4.1"
lodash: "npm:^4.17.21"
reflect-metadata: "npm:^0.1.13"
checksum: 5c34beaafb732d43ebc4dd170b35c48985c09d6b2c02a817af19d0cfbf868750cfd81a8f8a8aa1d37b872e5c4fce54cd5a942f06008c9b5e1f8f93e903ac52ba
checksum: ed29da54cb222f11c4a64ce0618c612a4b16edf180a130434870ca93bffa0278e90b53e14f31f08a0c4fc8852c4267eeadbebb6f41d2184448ccb84d77490a14
languageName: node
linkType: hard
@@ -3866,11 +3841,12 @@ __metadata:
"@aws-sdk/client-sqs": "npm:^3.259.0"
"@newrelic/winston-enricher": "npm:^4.0.0"
"@sentry/node": "npm:^7.28.1"
"@standardnotes/api": "npm:^1.24.10"
"@standardnotes/api": "npm:^1.25.3"
"@standardnotes/common": "workspace:^"
"@standardnotes/domain-core": "workspace:^"
"@standardnotes/domain-events": "workspace:^"
"@standardnotes/domain-events-infra": "workspace:^"
"@standardnotes/responses": "npm:^1.13.9"
"@standardnotes/security": "workspace:^"
"@standardnotes/utils": "npm:^1.16.2"
"@types/cors": "npm:^2.8.9"
@@ -4245,13 +4221,6 @@ __metadata:
languageName: node
linkType: hard
"@types/node@npm:^18.14.0":
version: 18.14.0
resolution: "@types/node@npm:18.14.0"
checksum: d17dff07c712379d67af7750f1586b4840ade31ab814d04987aa25850f1d4ef29b63b9ed03a7a9dccee8c86106ca75ae3b6f8cdd17be3ef3f693e700b1ea437b
languageName: node
linkType: hard
"@types/nodemailer@npm:^6.4.1":
version: 6.4.6
resolution: "@types/nodemailer@npm:6.4.6"