Compare commits

...

17 Commits

Author SHA1 Message Date
standardci
3462b60e47 chore(release): publish new version
- @standardnotes/event-store@1.1.4
 - @standardnotes/syncing-server@1.6.2
2022-07-11 10:57:54 +00:00
Karol Sójko
239d4ce4ec fix: add email backup tracing events 2022-07-11 12:56:25 +02:00
Karol Sójko
fc5cea11b5 fix: log errors on not being able to create a backup file 2022-07-11 12:56:25 +02:00
standardci
c54d721694 chore(release): publish new version
- @standardnotes/event-store@1.1.3
2022-07-11 10:41:44 +00:00
Karol Sójko
88d16d5392 fix: order of bindings 2022-07-11 12:39:29 +02:00
standardci
f1b22415c3 chore(release): publish new version
- @standardnotes/api-gateway@1.6.2
 - @standardnotes/auth-server@1.11.1
 - @standardnotes/domain-events-infra@1.7.6
 - @standardnotes/domain-events@2.39.1
 - @standardnotes/event-store@1.1.2
 - @standardnotes/files-server@1.5.1
 - @standardnotes/scheduler-server@1.5.1
 - @standardnotes/syncing-server@1.6.1
2022-07-11 10:36:50 +00:00
Karol Sójko
b4fae4b800 fix: remove unused MailBackupAttachmentTooBigEvent 2022-07-11 12:35:18 +02:00
standardci
b172177142 chore(release): publish new version
- @standardnotes/event-store@1.1.1
2022-07-11 10:17:12 +00:00
Karol Sójko
3fc11c5381 fix: optional migrations path 2022-07-11 12:15:40 +02:00
standardci
13cf896fe2 chore(release): publish new version
- @standardnotes/auth-server@1.11.0
 - @standardnotes/event-store@1.1.0
2022-07-11 10:00:23 +00:00
Karol Sójko
84ff915a56 feat: add event store package 2022-07-11 11:58:13 +02:00
Karol Sójko
74aedbccfe fix: publishing final image to docker hub 2022-07-08 12:45:12 +02:00
Karol Sójko
6e49298aea fix: add pre-deployment e2e tests 2022-07-08 12:18:20 +02:00
standardci
c1ba290e41 chore(release): publish new version
- @standardnotes/auth-server@1.10.0
 - @standardnotes/files-server@1.5.0
 - @standardnotes/sncrypto-node@1.10.0
2022-07-06 10:15:46 +00:00
Karol Sójko
60e8974580 feat: add sncryptio-node package 2022-07-06 12:14:05 +02:00
standardci
033eeda50a chore(release): publish new version
- @standardnotes/auth-server@1.9.0
 - @standardnotes/settings@1.17.0
 - @standardnotes/syncing-server@1.6.0
2022-07-06 10:07:30 +00:00
Karol Sójko
e7e34f3e16 feat: add settings package 2022-07-06 12:05:58 +02:00
93 changed files with 1995 additions and 155 deletions

View File

@@ -16,13 +16,42 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Set up Node
uses: actions/setup-node@v3
with:
registry-url: 'https://registry.npmjs.org'
node-version-file: '.nvmrc'
- run: yarn build
- run: yarn lint:api-gateway
- name: Build
run: yarn build
- name: Lint
run: yarn lint:api-gateway
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Publish Docker image for E2E testing
run: |
yarn docker build @standardnotes/api-gateway -t standardnotes/api-gateway:${{ github.sha }}
docker push standardnotes/api-gateway:${{ github.sha }}
- name: Run E2E test suite
uses: convictional/trigger-workflow-and-wait@v1.6.1
with:
owner: standardnotes
repo: e2e
github_token: ${{ secrets.CI_PAT_TOKEN }}
workflow_file_name: testing-with-stable-client.yml
wait_interval: 30
client_payload: '{"api_gateway_image_tag": "${{ github.sha }}"}'
propagate_failure: true
trigger_workflow: true
wait_workflow: true
publish-aws-ecr:
needs: test
@@ -68,11 +97,9 @@ jobs:
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build, tag, and push image to Docker Hub
- name: Publish Docker image as stable
run: |
yarn docker build @standardnotes/api-gateway -t standardnotes/api-gateway:${{ github.sha }}
docker push standardnotes/api-gateway:${{ github.sha }}
docker tag standardnotes/api-gateway:${{ github.sha }} standardnotes/api-gateway:latest
yarn docker build @standardnotes/api-gateway -t standardnotes/api-gateway:latest
docker push standardnotes/api-gateway:latest
deploy-web:

View File

@@ -16,14 +16,45 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Set up Node
uses: actions/setup-node@v3
with:
registry-url: 'https://registry.npmjs.org'
node-version-file: '.nvmrc'
- run: yarn build
- run: yarn lint:auth
- run: yarn test:auth
- name: Build
run: yarn build
- name: Lint
run: yarn lint:auth
- name: Test
run: yarn test:auth
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Publish Docker image for E2E testing
run: |
yarn docker build @standardnotes/auth-server -t standardnotes/auth:${{ github.sha }}
docker push standardnotes/auth:${{ github.sha }}
- name: Run E2E test suite
uses: convictional/trigger-workflow-and-wait@v1.6.1
with:
owner: standardnotes
repo: e2e
github_token: ${{ secrets.CI_PAT_TOKEN }}
workflow_file_name: testing-with-stable-client.yml
wait_interval: 30
client_payload: '{"auth_image_tag": "${{ github.sha }}"}'
propagate_failure: true
trigger_workflow: true
wait_workflow: true
publish-aws-ecr:
needs: test
@@ -69,11 +100,9 @@ jobs:
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build, tag, and push image to Docker Hub
- name: Publish Docker image as stable
run: |
yarn docker build @standardnotes/auth-server -t standardnotes/auth:${{ github.sha }}
docker push standardnotes/auth:${{ github.sha }}
docker tag standardnotes/auth:${{ github.sha }} standardnotes/auth:latest
yarn docker build @standardnotes/auth-server -t standardnotes/auth:latest
docker push standardnotes/auth:latest
deploy-web:

View File

@@ -0,0 +1,126 @@
name: Event Store
concurrency:
group: event-store
cancel-in-progress: true
on:
push:
tags:
- '*standardnotes/event-store*'
workflow_dispatch:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Node
uses: actions/setup-node@v3
with:
registry-url: 'https://registry.npmjs.org'
node-version-file: '.nvmrc'
- run: yarn build
- run: yarn lint:event-store
- run: yarn test:event-store
publish-aws-ecr:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build locally
run: yarn build
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build, tag, and push image to Amazon ECR
id: build-image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: event-store
IMAGE_TAG: ${{ github.sha }}
run: |
yarn docker build @standardnotes/event-store -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:latest
docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest
publish-docker-hub:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build locally
run: yarn build
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build, tag, and push image to Docker Hub
run: |
yarn docker build @standardnotes/event-store -t standardnotes/event-store:${{ github.sha }}
docker push standardnotes/event-store:${{ github.sha }}
docker tag standardnotes/event-store:${{ github.sha }} standardnotes/event-store:latest
docker push standardnotes/event-store:latest
deploy-worker:
needs: publish-aws-ecr
runs-on: ubuntu-latest
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: PROD - Download task definition
run: |
aws ecs describe-task-definition --task-definition event-store-prod --query taskDefinition > task-definition.json
- name: PROD - Fill in the new version in the Amazon ECS task definition
run: |
jq '(.containerDefinitions[] | select(.name=="event-store-prod") | .environment[] | select(.name=="VERSION")).value = "${{ github.sha }}"' task-definition.json > tmp.json && mv tmp.json task-definition.json
- name: PROD - Fill in the new image ID in the Amazon ECS task definition
id: task-def-prod
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: task-definition.json
container-name: event-store-prod
image: ${{ secrets.AWS_ECR_REGISTRY }}/event-store:${{ github.sha }}
- name: PROD - Deploy Amazon ECS task definition
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
task-definition: ${{ steps.task-def-prod.outputs.task-definition }}
service: event-store-prod
cluster: prod
wait-for-service-stability: true
newrelic:
needs: [ deploy-worker ]
runs-on: ubuntu-latest
steps:
- name: Create New Relic deployment marker for Worker
uses: newrelic/deployment-marker-action@v1
with:
accountId: ${{ secrets.NEW_RELIC_ACCOUNT_ID }}
apiKey: ${{ secrets.NEW_RELIC_API_KEY }}
applicationId: ${{ secrets.NEW_RELIC_APPLICATION_ID_EVENT_STORE_PROD }}
revision: "${{ github.sha }}"
description: "Automated Deployment via Github Actions"
user: "${{ github.actor }}"

View File

@@ -16,14 +16,45 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Set up Node
uses: actions/setup-node@v3
with:
registry-url: 'https://registry.npmjs.org'
node-version-file: '.nvmrc'
- run: yarn build
- run: yarn lint:files
- run: yarn test:files
- name: Build
run: yarn build
- name: Lint
run: yarn lint:files
- name: Test
run: yarn test:files
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Publish Docker image for E2E testing
run: |
yarn docker build @standardnotes/files-server -t standardnotes/files:${{ github.sha }}
docker push standardnotes/files:${{ github.sha }}
- name: Run E2E test suite
uses: convictional/trigger-workflow-and-wait@v1.6.1
with:
owner: standardnotes
repo: e2e
github_token: ${{ secrets.CI_PAT_TOKEN }}
workflow_file_name: testing-with-stable-client.yml
wait_interval: 30
client_payload: '{"files_image_tag": "${{ github.sha }}"}'
propagate_failure: true
trigger_workflow: true
wait_workflow: true
publish-aws-ecr:
needs: test
@@ -71,9 +102,7 @@ jobs:
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build, tag, and push image to Docker Hub
run: |
yarn docker build @standardnotes/files-server -t standardnotes/files:${{ github.sha }}
docker push standardnotes/files:${{ github.sha }}
docker tag standardnotes/files:${{ github.sha }} standardnotes/files:latest
yarn docker build @standardnotes/files-server -t standardnotes/files:latest
docker push standardnotes/files:latest
deploy-web:

View File

@@ -16,14 +16,45 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Set up Node
uses: actions/setup-node@v3
with:
registry-url: 'https://registry.npmjs.org'
node-version-file: '.nvmrc'
- run: yarn build
- run: yarn lint:syncing-server
- run: yarn test:syncing-server
- name: Build
run: yarn build
- name: Lint
run: yarn lint:syncing-server
- name: Test
run: yarn test:syncing-server
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Publish Docker image for E2E testing
run: |
yarn docker build @standardnotes/syncing-server -t standardnotes/syncing-server-js:${{ github.sha }}
docker push standardnotes/syncing-server-js:${{ github.sha }}
- name: Run E2E test suite
uses: convictional/trigger-workflow-and-wait@v1.6.1
with:
owner: standardnotes
repo: e2e
github_token: ${{ secrets.CI_PAT_TOKEN }}
workflow_file_name: testing-with-stable-client.yml
wait_interval: 30
client_payload: '{"syncing_server_js_image_tag": "${{ github.sha }}"}'
propagate_failure: true
trigger_workflow: true
wait_workflow: true
publish-aws-ecr:
needs: test
@@ -71,9 +102,7 @@ jobs:
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build, tag, and push image to Docker Hub
run: |
yarn docker build @standardnotes/syncing-server -t standardnotes/syncing-server-js:${{ github.sha }}
docker push standardnotes/syncing-server-js:${{ github.sha }}
docker tag standardnotes/syncing-server-js:${{ github.sha }} standardnotes/syncing-server-js:latest
yarn docker build @standardnotes/syncing-server -t standardnotes/syncing-server-js:latest
docker push standardnotes/syncing-server-js:latest
deploy-web:

152
.pnp.cjs generated
View File

@@ -44,6 +44,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"name": "@standardnotes/domain-events-infra",\
"reference": "workspace:packages/domain-events-infra"\
},\
{\
"name": "@standardnotes/event-store",\
"reference": "workspace:packages/event-store"\
},\
{\
"name": "@standardnotes/files-server",\
"reference": "workspace:packages/files"\
@@ -60,6 +64,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"name": "@standardnotes/security",\
"reference": "workspace:packages/security"\
},\
{\
"name": "@standardnotes/settings",\
"reference": "workspace:packages/settings"\
},\
{\
"name": "@standardnotes/sncrypto-node",\
"reference": "workspace:packages/sncrypto-node"\
},\
{\
"name": "@standardnotes/syncing-server",\
"reference": "workspace:packages/syncing-server"\
@@ -78,11 +90,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["@standardnotes/common", ["workspace:packages/common"]],\
["@standardnotes/domain-events", ["workspace:packages/domain-events"]],\
["@standardnotes/domain-events-infra", ["workspace:packages/domain-events-infra"]],\
["@standardnotes/event-store", ["workspace:packages/event-store"]],\
["@standardnotes/files-server", ["workspace:packages/files"]],\
["@standardnotes/predicates", ["workspace:packages/predicates"]],\
["@standardnotes/scheduler-server", ["workspace:packages/scheduler"]],\
["@standardnotes/security", ["workspace:packages/security"]],\
["@standardnotes/server-monorepo", ["workspace:."]],\
["@standardnotes/settings", ["workspace:packages/settings"]],\
["@standardnotes/sncrypto-node", ["workspace:packages/sncrypto-node"]],\
["@standardnotes/syncing-server", ["workspace:packages/syncing-server"]],\
["@standardnotes/time", ["workspace:packages/time"]]\
],\
@@ -2752,9 +2767,9 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["@standardnotes/predicates", "workspace:packages/predicates"],\
["@standardnotes/responses", "npm:1.6.39"],\
["@standardnotes/security", "workspace:packages/security"],\
["@standardnotes/settings", "npm:1.15.0"],\
["@standardnotes/settings", "workspace:packages/settings"],\
["@standardnotes/sncrypto-common", "npm:1.9.0"],\
["@standardnotes/sncrypto-node", "npm:1.8.3"],\
["@standardnotes/sncrypto-node", "workspace:packages/sncrypto-node"],\
["@standardnotes/time", "workspace:packages/time"],\
["@types/bcryptjs", "npm:2.4.2"],\
["@types/cors", "npm:2.8.12"],\
@@ -2885,6 +2900,36 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"linkType": "HARD"\
}]\
]],\
["@standardnotes/event-store", [\
["workspace:packages/event-store", {\
"packageLocation": "./packages/event-store/",\
"packageDependencies": [\
["@standardnotes/event-store", "workspace:packages/event-store"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@standardnotes/time", "workspace:packages/time"],\
["@types/ioredis", "npm:4.28.10"],\
["@types/jest", "npm:28.1.4"],\
["@types/newrelic", "npm:7.0.3"],\
["@types/nodemailer", "npm:6.4.4"],\
["@typescript-eslint/eslint-plugin", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:5.30.5"],\
["aws-sdk", "npm:2.1168.0"],\
["dotenv", "npm:8.2.0"],\
["eslint", "npm:8.19.0"],\
["eslint-plugin-prettier", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:4.2.1"],\
["inversify", "npm:6.0.1"],\
["ioredis", "npm:5.1.0"],\
["jest", "virtual:e1128e9ebb31076ea8e955c00397fd108ee8bf0fb2df3b2a603c510b7014a507cfa360bccf848efc1ec8c431656aa94c5ad08bcec32950bdf1278d01cd890e4f#npm:28.1.2"],\
["mysql2", "npm:2.3.3"],\
["newrelic", "npm:8.14.1"],\
["reflect-metadata", "npm:0.1.13"],\
["ts-jest", "virtual:e1128e9ebb31076ea8e955c00397fd108ee8bf0fb2df3b2a603c510b7014a507cfa360bccf848efc1ec8c431656aa94c5ad08bcec32950bdf1278d01cd890e4f#npm:28.0.5"],\
["typeorm", "virtual:31b5a94a105c89c9294c3d524a7f8929fe63ee5a2efadf21951ca4c0cfd2ecf02e8f4ef5a066bbda091f1e3a56e57c6749069a080618c96b22e51131a330fc4a#npm:0.3.7"],\
["winston", "npm:3.3.3"]\
],\
"linkType": "SOFT"\
}]\
]],\
["@standardnotes/features", [\
["npm:1.50.0", {\
"packageLocation": "./.yarn/cache/@standardnotes-features-npm-1.50.0-dd65714983-b61b50695b.zip/node_modules/@standardnotes/features/",\
@@ -2909,7 +2954,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@standardnotes/security", "workspace:packages/security"],\
["@standardnotes/sncrypto-common", "npm:1.9.0"],\
["@standardnotes/sncrypto-node", "npm:1.8.3"],\
["@standardnotes/sncrypto-node", "workspace:packages/sncrypto-node"],\
["@standardnotes/time", "workspace:packages/time"],\
["@types/connect-busboy", "npm:1.0.0"],\
["@types/cors", "npm:2.8.12"],\
@@ -3100,12 +3145,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
}]\
]],\
["@standardnotes/settings", [\
["npm:1.15.0", {\
"packageLocation": "./.yarn/cache/@standardnotes-settings-npm-1.15.0-bfec86ee49-4397d453a1.zip/node_modules/@standardnotes/settings/",\
["workspace:packages/settings", {\
"packageLocation": "./packages/settings/",\
"packageDependencies": [\
["@standardnotes/settings", "npm:1.15.0"]\
["@standardnotes/settings", "workspace:packages/settings"],\
["@typescript-eslint/eslint-plugin", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:5.30.5"],\
["eslint-plugin-prettier", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.2.1"],\
["reflect-metadata", "npm:0.1.13"]\
],\
"linkType": "HARD"\
"linkType": "SOFT"\
}]\
]],\
["@standardnotes/sncrypto-common", [\
@@ -3118,13 +3166,22 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
}]\
]],\
["@standardnotes/sncrypto-node", [\
["npm:1.8.3", {\
"packageLocation": "./.yarn/cache/@standardnotes-sncrypto-node-npm-1.8.3-5d28cdd37d-b3c866bfba.zip/node_modules/@standardnotes/sncrypto-node/",\
["workspace:packages/sncrypto-node", {\
"packageLocation": "./packages/sncrypto-node/",\
"packageDependencies": [\
["@standardnotes/sncrypto-node", "npm:1.8.3"],\
["@standardnotes/sncrypto-common", "npm:1.9.0"]\
["@standardnotes/sncrypto-node", "workspace:packages/sncrypto-node"],\
["@standardnotes/sncrypto-common", "npm:1.9.0"],\
["@types/jest", "npm:28.1.4"],\
["@types/node", "npm:18.0.3"],\
["@typescript-eslint/eslint-plugin", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:5.30.5"],\
["eslint-plugin-prettier", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.2.1"],\
["jest", "virtual:e1128e9ebb31076ea8e955c00397fd108ee8bf0fb2df3b2a603c510b7014a507cfa360bccf848efc1ec8c431656aa94c5ad08bcec32950bdf1278d01cd890e4f#npm:28.1.2"],\
["reflect-metadata", "npm:0.1.13"],\
["regenerator-runtime", "npm:0.13.9"],\
["ts-jest", "virtual:e1128e9ebb31076ea8e955c00397fd108ee8bf0fb2df3b2a603c510b7014a507cfa360bccf848efc1ec8c431656aa94c5ad08bcec32950bdf1278d01cd890e4f#npm:28.0.5"],\
["ts-loader", "virtual:251b55e6186f136d0456117ba65ba163d1a38b49e5d09875aa42c66c71e5a9085f9a3cc24c7aae5da7499c53d95e6948b9284db4d7d1f035f288826df740c6bf#npm:9.3.1"]\
],\
"linkType": "HARD"\
"linkType": "SOFT"\
}]\
]],\
["@standardnotes/syncing-server", [\
@@ -3141,7 +3198,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["@standardnotes/payloads", "npm:1.5.1"],\
["@standardnotes/responses", "npm:1.6.39"],\
["@standardnotes/security", "workspace:packages/security"],\
["@standardnotes/settings", "npm:1.15.0"],\
["@standardnotes/settings", "workspace:packages/settings"],\
["@standardnotes/time", "workspace:packages/time"],\
["@types/cors", "npm:2.8.12"],\
["@types/dotenv", "npm:8.2.0"],\
@@ -3587,6 +3644,16 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"linkType": "HARD"\
}]\
]],\
["@types/nodemailer", [\
["npm:6.4.4", {\
"packageLocation": "./.yarn/cache/@types-nodemailer-npm-6.4.4-c5c500abe2-16ed1bad2c.zip/node_modules/@types/nodemailer/",\
"packageDependencies": [\
["@types/nodemailer", "npm:6.4.4"],\
["@types/node", "npm:18.0.3"]\
],\
"linkType": "HARD"\
}]\
]],\
["@types/normalize-package-data", [\
["npm:2.4.1", {\
"packageLocation": "./.yarn/cache/@types-normalize-package-data-npm-2.4.1-c31c56ae6a-e87bccbf11.zip/node_modules/@types/normalize-package-data/",\
@@ -6329,6 +6396,17 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"linkType": "HARD"\
}]\
]],\
["enhanced-resolve", [\
["npm:5.10.0", {\
"packageLocation": "./.yarn/cache/enhanced-resolve-npm-5.10.0-7941304306-0bb9830704.zip/node_modules/enhanced-resolve/",\
"packageDependencies": [\
["enhanced-resolve", "npm:5.10.0"],\
["graceful-fs", "npm:4.2.10"],\
["tapable", "npm:2.2.1"]\
],\
"linkType": "HARD"\
}]\
]],\
["env-paths", [\
["npm:2.2.1", {\
"packageLocation": "./.yarn/cache/env-paths-npm-2.2.1-7c7577428c-65b5df55a8.zip/node_modules/env-paths/",\
@@ -12170,6 +12248,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"linkType": "HARD"\
}]\
]],\
["regenerator-runtime", [\
["npm:0.13.9", {\
"packageLocation": "./.yarn/cache/regenerator-runtime-npm-0.13.9-6d02340eec-65ed455fe5.zip/node_modules/regenerator-runtime/",\
"packageDependencies": [\
["regenerator-runtime", "npm:0.13.9"]\
],\
"linkType": "HARD"\
}]\
]],\
["regexpp", [\
["npm:3.2.0", {\
"packageLocation": "./.yarn/cache/regexpp-npm-3.2.0-2513f32cfc-a78dc5c715.zip/node_modules/regexpp/",\
@@ -13116,6 +13203,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"linkType": "HARD"\
}]\
]],\
["tapable", [\
["npm:2.2.1", {\
"packageLocation": "./.yarn/cache/tapable-npm-2.2.1-8cf5ff3039-3b7a1b4d86.zip/node_modules/tapable/",\
"packageDependencies": [\
["tapable", "npm:2.2.1"]\
],\
"linkType": "HARD"\
}]\
]],\
["tar", [\
["npm:6.1.11", {\
"packageLocation": "./.yarn/cache/tar-npm-6.1.11-e6ac3cba9c-a04c07bb9e.zip/node_modules/tar/",\
@@ -13483,6 +13579,36 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"linkType": "HARD"\
}]\
]],\
["ts-loader", [\
["npm:9.3.1", {\
"packageLocation": "./.yarn/cache/ts-loader-npm-9.3.1-634433ef6a-462a8ac315.zip/node_modules/ts-loader/",\
"packageDependencies": [\
["ts-loader", "npm:9.3.1"]\
],\
"linkType": "SOFT"\
}],\
["virtual:251b55e6186f136d0456117ba65ba163d1a38b49e5d09875aa42c66c71e5a9085f9a3cc24c7aae5da7499c53d95e6948b9284db4d7d1f035f288826df740c6bf#npm:9.3.1", {\
"packageLocation": "./.yarn/__virtual__/ts-loader-virtual-2eeaee133b/0/cache/ts-loader-npm-9.3.1-634433ef6a-462a8ac315.zip/node_modules/ts-loader/",\
"packageDependencies": [\
["ts-loader", "virtual:251b55e6186f136d0456117ba65ba163d1a38b49e5d09875aa42c66c71e5a9085f9a3cc24c7aae5da7499c53d95e6948b9284db4d7d1f035f288826df740c6bf#npm:9.3.1"],\
["@types/typescript", null],\
["@types/webpack", null],\
["chalk", "npm:4.1.2"],\
["enhanced-resolve", "npm:5.10.0"],\
["micromatch", "npm:4.0.5"],\
["semver", "npm:7.3.7"],\
["typescript", null],\
["webpack", null]\
],\
"packagePeers": [\
"@types/typescript",\
"@types/webpack",\
"typescript",\
"webpack"\
],\
"linkType": "HARD"\
}]\
]],\
["ts-node", [\
["npm:10.8.2", {\
"packageLocation": "./.yarn/cache/ts-node-npm-10.8.2-f3c0c9eaee-1eede939be.zip/node_modules/ts-node/",\

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -17,11 +17,13 @@
"lint:syncing-server": "yarn workspace @standardnotes/syncing-server lint",
"lint:files": "yarn workspace @standardnotes/files-server lint",
"lint:api-gateway": "yarn workspace @standardnotes/api-gateway lint",
"lint:event-store": "yarn workspace @standardnotes/event-store lint",
"test": "yarn workspaces foreach -p -j 10 --verbose run test",
"test:auth": "yarn workspace @standardnotes/auth-server test",
"test:scheduler": "yarn workspace @standardnotes/scheduler-server test",
"test:syncing-server": "yarn workspace @standardnotes/syncing-server test",
"test:files": "yarn workspace @standardnotes/files-server test",
"test:event-store": "yarn workspace @standardnotes/event-store test",
"clean": "yarn workspaces foreach -p --verbose run clean",
"setup:env": "cp .env.sample .env && yarn workspaces foreach -p --verbose run setup:env",
"build": "yarn workspaces foreach -pt -j 10 --verbose run build",

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.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.6.1...@standardnotes/api-gateway@1.6.2) (2022-07-11)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.6.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.6.0...@standardnotes/api-gateway@1.6.1) (2022-07-06)
**Note:** Version bump only for package @standardnotes/api-gateway

View File

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

View File

@@ -3,6 +3,28 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.11.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.11.0...@standardnotes/auth-server@1.11.1) (2022-07-11)
**Note:** Version bump only for package @standardnotes/auth-server
# [1.11.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.10.0...@standardnotes/auth-server@1.11.0) (2022-07-11)
### Features
* add event store package ([84ff915](https://github.com/standardnotes/server/commit/84ff915a565e8e64410c4bf97a30d359649825c7))
# [1.10.0](https://github.com/standardnotes/auth/compare/@standardnotes/auth-server@1.9.0...@standardnotes/auth-server@1.10.0) (2022-07-06)
### Features
* add sncryptio-node package ([60e8974](https://github.com/standardnotes/auth/commit/60e8974580d498e7edf80813c32268a8bf7eda39))
# [1.9.0](https://github.com/standardnotes/auth/compare/@standardnotes/auth-server@1.8.0...@standardnotes/auth-server@1.9.0) (2022-07-06)
### Features
* add settings package ([e7e34f3](https://github.com/standardnotes/auth/commit/e7e34f3e16eb865f083b7b49b2f8f83fd8af8de0))
# [1.8.0](https://github.com/standardnotes/auth/compare/@standardnotes/auth-server@1.7.0...@standardnotes/auth-server@1.8.0) (2022-07-06)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/auth-server",
"version": "1.8.0",
"version": "1.11.1",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -8,7 +8,6 @@
"description": "Auth Server",
"main": "dist/src/index.js",
"typings": "dist/src/index.d.ts",
"repository": "git@github.com:standardnotes/auth.git",
"author": "Karol Sójko <karolsojko@standardnotes.com>",
"license": "AGPL-3.0-or-later",
"scripts": {
@@ -42,9 +41,9 @@
"@standardnotes/predicates": "workspace:*",
"@standardnotes/responses": "^1.6.39",
"@standardnotes/security": "workspace:*",
"@standardnotes/settings": "^1.15.0",
"@standardnotes/settings": "workspace:*",
"@standardnotes/sncrypto-common": "^1.9.0",
"@standardnotes/sncrypto-node": "^1.8.3",
"@standardnotes/sncrypto-node": "workspace:*",
"@standardnotes/time": "workspace:*",
"aws-sdk": "^2.1159.0",
"axios": "0.24.0",

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.7.6](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.7.5...@standardnotes/domain-events-infra@1.7.6) (2022-07-11)
**Note:** Version bump only for package @standardnotes/domain-events-infra
## [1.7.5](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.7.4...@standardnotes/domain-events-infra@1.7.5) (2022-07-06)
**Note:** Version bump only for package @standardnotes/domain-events-infra

View File

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

View File

@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.39.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.39.0...@standardnotes/domain-events@2.39.1) (2022-07-11)
### Bug Fixes
* remove unused MailBackupAttachmentTooBigEvent ([b4fae4b](https://github.com/standardnotes/server/commit/b4fae4b800fdef9bcfb28d8f332c5c0bbf576833))
# [2.39.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.38.0...@standardnotes/domain-events@2.39.0) (2022-07-06)
### Features

View File

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

View File

@@ -1,8 +0,0 @@
import { DomainEventInterface } from './DomainEventInterface'
import { MailBackupAttachmentTooBigEventPayload } from './MailBackupAttachmentTooBigEventPayload'
export interface MailBackupAttachmentTooBigEvent extends DomainEventInterface {
type: 'MAIL_BACKUP_ATTACHMENT_TOO_BIG'
payload: MailBackupAttachmentTooBigEventPayload
}

View File

@@ -1,7 +0,0 @@
export interface MailBackupAttachmentTooBigEventPayload {
allowedSize: string
attachmentSize: string
muteEmailsSettingUuid: string
extensionSettingUuid?: string
email: string
}

View File

@@ -38,8 +38,6 @@ export * from './Event/ListedAccountDeletedEvent'
export * from './Event/ListedAccountDeletedEventPayload'
export * from './Event/ListedAccountRequestedEvent'
export * from './Event/ListedAccountRequestedEventPayload'
export * from './Event/MailBackupAttachmentTooBigEvent'
export * from './Event/MailBackupAttachmentTooBigEventPayload'
export * from './Event/OfflineSubscriptionTokenCreatedEvent'
export * from './Event/OfflineSubscriptionTokenCreatedEventPayload'
export * from './Event/OneDriveBackupFailedEvent'

View File

@@ -0,0 +1,24 @@
LOG_LEVEL=debug
NODE_ENV=development
VERSION=development
DB_HOST=127.0.0.1
DB_REPLICA_HOST=127.0.0.1
DB_PORT=3306
DB_USERNAME=store
DB_PASSWORD=changeme123
DB_DATABASE=store
DB_DEBUG_LEVEL=all # "all" | "query" | "schema" | "error" | "warn" | "info" | "log" | "migration"
DB_MIGRATIONS_PATH=dist/migrations/*.js
SQS_QUEUE_URL=
SQS_AWS_REGION=
# (Optional) New Relic Setup
NEW_RELIC_ENABLED=false
NEW_RELIC_APP_NAME="Event Store"
NEW_RELIC_LICENSE_KEY=
NEW_RELIC_NO_CONFIG_FILE=true
NEW_RELIC_DISTRIBUTED_TRACING_ENABLED=false
NEW_RELIC_LOG_ENABLED=false
NEW_RELIC_LOG_LEVEL=info

View File

@@ -0,0 +1,2 @@
dist
test-setup.ts

View File

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

View File

@@ -0,0 +1,32 @@
# 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.4](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.1.3...@standardnotes/event-store@1.1.4) (2022-07-11)
### Bug Fixes
* add email backup tracing events ([239d4ce](https://github.com/standardnotes/server/commit/239d4ce4eca6a0c5dc0e1346829572a7240569cc))
## [1.1.3](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.1.2...@standardnotes/event-store@1.1.3) (2022-07-11)
### Bug Fixes
* order of bindings ([88d16d5](https://github.com/standardnotes/server/commit/88d16d53925761abed2cb8dc4c7aa5b4b5009357))
## [1.1.2](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.1.1...@standardnotes/event-store@1.1.2) (2022-07-11)
**Note:** Version bump only for package @standardnotes/event-store
## [1.1.1](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.1.0...@standardnotes/event-store@1.1.1) (2022-07-11)
### Bug Fixes
* optional migrations path ([3fc11c5](https://github.com/standardnotes/server/commit/3fc11c538111348723a92f838297ebd821566eb4))
# 1.1.0 (2022-07-11)
### Features
* add event store package ([84ff915](https://github.com/standardnotes/server/commit/84ff915a565e8e64410c4bf97a30d359649825c7))

View File

@@ -0,0 +1,27 @@
FROM node:16.15.1-alpine AS builder
# Install dependencies for building native libraries
RUN apk add --update git openssh-client python3 alpine-sdk
WORKDIR /workspace
# docker-build plugin copies everything needed for `yarn install` to `manifests` folder.
COPY manifests ./
RUN yarn install --immutable
FROM node:16.15.1-alpine
RUN apk add --update curl
WORKDIR /workspace
# Copy the installed dependencies from the previous stage.
COPY --from=builder /workspace ./
# docker-build plugin runs `yarn pack` in all workspace dependencies and copies them to `packs` folder.
COPY packs ./
ENTRYPOINT [ "/workspace/packages/event-store/docker/entrypoint.sh" ]
CMD [ "start-worker" ]

View File

@@ -0,0 +1,25 @@
import 'reflect-metadata'
import 'newrelic'
import { Logger } from 'winston'
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
import TYPES from '../src/Bootstrap/Types'
import { Env } from '../src/Bootstrap/Env'
import { DomainEventSubscriberFactoryInterface } from '@standardnotes/domain-events'
const container = new ContainerConfigLoader()
void container.load().then((container) => {
const env: Env = new Env()
env.load()
const logger: Logger = container.get(TYPES.Logger)
logger.info('Starting worker...')
const subscriberFactory: DomainEventSubscriberFactoryInterface = container.get(TYPES.DomainEventSubscriberFactory)
subscriberFactory.create().start()
setInterval(() => logger.info('Alive and kicking!'), 20 * 60 * 1000)
})

View File

@@ -0,0 +1,17 @@
#!/bin/sh
set -e
COMMAND=$1 && shift 1
case "$COMMAND" in
'start-worker' )
echo "Starting Worker..."
yarn workspace @standardnotes/event-store worker
;;
* )
echo "Unknown command"
;;
esac
exec "$@"

View File

@@ -0,0 +1,17 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const base = require('../../jest.config');
module.exports = {
...base,
globals: {
'ts-jest': {
tsconfig: 'tsconfig.json',
},
},
coveragePathIgnorePatterns: [
'/Bootstrap/'
],
setupFilesAfterEnv: [
'./test-setup.ts'
]
};

View File

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

View File

@@ -0,0 +1,16 @@
import { MigrationInterface, QueryRunner } from 'typeorm'
export class initDatabase1639394147420 implements MigrationInterface {
name = 'initDatabase1639394147420'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
'CREATE TABLE `events` (`uuid` varchar(36) NOT NULL, `user_identifier` varchar(255) NOT NULL, `user_identifier_type` varchar(255) NOT NULL, `event_type` varchar(255) NOT NULL, `event_payload` text NOT NULL, `timestamp` bigint NOT NULL, INDEX `index_events_on_user_identifier` (`user_identifier`), PRIMARY KEY (`uuid`)) ENGINE=InnoDB',
)
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query('DROP INDEX `index_events_on_user_identifier` ON `events`')
await queryRunner.query('DROP TABLE `events`')
}
}

View File

@@ -0,0 +1,47 @@
{
"name": "@standardnotes/event-store",
"version": "1.1.4",
"description": "Event Store Service",
"private": true,
"main": "dist/src/index.js",
"typings": "dist/src/index.d.ts",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
"scripts": {
"clean": "rm -fr dist",
"prebuild": "yarn clean",
"build": "tsc --rootDir ./",
"lint": "eslint . --ext .ts",
"pretest": "yarn lint && yarn build",
"test": "jest --coverage --config=./jest.config.js --maxWorkers=50%",
"worker": "yarn node dist/bin/worker.js"
},
"author": "Karol Sójko <karolsojko@standardnotes.com>",
"license": "AGPL-3.0-or-later",
"devDependencies": {
"@types/ioredis": "^4.28.10",
"@types/jest": "^28.1.3",
"@types/newrelic": "^7.0.3",
"@types/nodemailer": "^6.4.1",
"@typescript-eslint/eslint-plugin": "^5.30.5",
"eslint": "^8.14.0",
"eslint-plugin-prettier": "^4.2.1",
"jest": "^28.1.1",
"ts-jest": "^28.0.1"
},
"dependencies": {
"@standardnotes/domain-events": "workspace:*",
"@standardnotes/domain-events-infra": "workspace:*",
"@standardnotes/time": "workspace:*",
"aws-sdk": "^2.1159.0",
"dotenv": "8.2.0",
"inversify": "^6.0.1",
"ioredis": "^5.0.6",
"mysql2": "^2.3.3",
"newrelic": "^8.14.1",
"reflect-metadata": "0.1.13",
"typeorm": "^0.3.6",
"winston": "3.3.3"
}
}

View File

@@ -0,0 +1,99 @@
import * as AWS from 'aws-sdk'
import * as winston from 'winston'
import { Container } from 'inversify'
import { Event } from '../Domain/Event/Event'
import { Env } from './Env'
import TYPES from './Types'
import {
DomainEventHandlerInterface,
DomainEventMessageHandlerInterface,
DomainEventSubscriberFactoryInterface,
} from '@standardnotes/domain-events'
import {
SQSDomainEventSubscriberFactory,
SQSEventMessageHandler,
SQSNewRelicEventMessageHandler,
} from '@standardnotes/domain-events-infra'
import { Timer, TimerInterface } from '@standardnotes/time'
import { EventHandler } from '../Domain/Handler/EventHandler'
import { AppDataSource } from './DataSource'
import { Repository } from 'typeorm'
export class ContainerConfigLoader {
async load(): Promise<Container> {
const env: Env = new Env()
env.load()
const container = new Container()
await AppDataSource.initialize()
container.bind<AWS.SQS>(TYPES.SQS).toConstantValue(
new AWS.SQS({
apiVersion: 'latest',
region: env.get('SQS_AWS_REGION'),
}),
)
const logger = winston.createLogger({
level: env.get('LOG_LEVEL') || 'info',
format: winston.format.combine(winston.format.splat(), winston.format.json()),
transports: [new winston.transports.Console({ level: env.get('LOG_LEVEL') || 'info' })],
})
container.bind<winston.Logger>(TYPES.Logger).toConstantValue(logger)
container.bind<TimerInterface>(TYPES.Timer).toConstantValue(new Timer())
// env vars
container.bind(TYPES.SQS_AWS_REGION).toConstantValue(env.get('SQS_AWS_REGION'))
container.bind(TYPES.SQS_QUEUE_URL).toConstantValue(env.get('SQS_QUEUE_URL'))
// ORM
container.bind<Repository<Event>>(TYPES.ORMEventRepository).toConstantValue(AppDataSource.getRepository(Event))
// Handlers
container.bind<EventHandler>(TYPES.EventHandler).to(EventHandler)
const eventHandlers: Map<string, DomainEventHandlerInterface> = new Map([
['USER_REGISTERED', container.get(TYPES.EventHandler)],
['ACCOUNT_DELETION_REQUESTED', container.get(TYPES.EventHandler)],
['SUBSCRIPTION_PURCHASED', container.get(TYPES.EventHandler)],
['SUBSCRIPTION_CANCELLED', container.get(TYPES.EventHandler)],
['SUBSCRIPTION_RENEWED', container.get(TYPES.EventHandler)],
['SUBSCRIPTION_REFUNDED', container.get(TYPES.EventHandler)],
['SUBSCRIPTION_SYNC_REQUESTED', container.get(TYPES.EventHandler)],
['SUBSCRIPTION_EXPIRED', container.get(TYPES.EventHandler)],
['EXTENSION_KEY_GRANTED', container.get(TYPES.EventHandler)],
['SUBSCRIPTION_REASSIGNED', container.get(TYPES.EventHandler)],
['USER_EMAIL_CHANGED', container.get(TYPES.EventHandler)],
['FILE_UPLOADED', container.get(TYPES.EventHandler)],
['FILE_REMOVED', container.get(TYPES.EventHandler)],
['LISTED_ACCOUNT_REQUESTED', container.get(TYPES.EventHandler)],
['LISTED_ACCOUNT_CREATED', container.get(TYPES.EventHandler)],
['LISTED_ACCOUNT_DELETED', container.get(TYPES.EventHandler)],
['USER_SIGNED_IN', container.get(TYPES.EventHandler)],
['SHARED_SUBSCRIPTION_INVITATION_CREATED', container.get(TYPES.EventHandler)],
['EMAIL_BACKUP_ATTACHMENT_CREATED', container.get(TYPES.EventHandler)],
['EMAIL_BACKUP_REQUESTED', container.get(TYPES.EventHandler)],
])
container
.bind<DomainEventMessageHandlerInterface>(TYPES.DomainEventMessageHandler)
.toConstantValue(
env.get('NEW_RELIC_ENABLED', true) === 'true'
? new SQSNewRelicEventMessageHandler(eventHandlers, container.get(TYPES.Logger))
: new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Logger)),
)
container
.bind<DomainEventSubscriberFactoryInterface>(TYPES.DomainEventSubscriberFactory)
.toConstantValue(
new SQSDomainEventSubscriberFactory(
container.get(TYPES.SQS),
container.get(TYPES.SQS_QUEUE_URL),
container.get(TYPES.DomainEventMessageHandler),
),
)
return container
}
}

View File

@@ -0,0 +1,40 @@
import { DataSource, LoggerOptions } from 'typeorm'
import { Event } from '../Domain/Event/Event'
import { Env } from './Env'
const env: Env = new Env()
env.load()
const maxQueryExecutionTime = env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
? +env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
: 45_000
export const AppDataSource = new DataSource({
type: 'mysql',
supportBigNumbers: true,
bigNumberStrings: false,
maxQueryExecutionTime,
replication: {
master: {
host: env.get('DB_HOST'),
port: parseInt(env.get('DB_PORT')),
username: env.get('DB_USERNAME'),
password: env.get('DB_PASSWORD'),
database: env.get('DB_DATABASE'),
},
slaves: [
{
host: env.get('DB_REPLICA_HOST'),
port: parseInt(env.get('DB_PORT')),
username: env.get('DB_USERNAME'),
password: env.get('DB_PASSWORD'),
database: env.get('DB_DATABASE'),
},
],
removeNodeErrorCount: 10,
},
entities: [Event],
migrations: [env.get('DB_MIGRATIONS_PATH', true) ?? 'dist/migrations/*.js'],
migrationsRun: true,
logging: <LoggerOptions>env.get('DB_DEBUG_LEVEL'),
})

View File

@@ -0,0 +1,24 @@
import { config, DotenvParseOutput } from 'dotenv'
import { injectable } from 'inversify'
@injectable()
export class Env {
private env?: DotenvParseOutput
public load(): void {
const output = config()
this.env = <DotenvParseOutput>output.parsed
}
public get(key: string, optional = false): string {
if (!this.env) {
this.load()
}
if (!process.env[key] && !optional) {
throw new Error(`Environment variable ${key} not set`)
}
return <string>process.env[key]
}
}

View File

@@ -0,0 +1,17 @@
const TYPES = {
Logger: Symbol.for('Logger'),
SQS: Symbol.for('SQS'),
// env vars
SQS_QUEUE_URL: Symbol.for('SQS_QUEUE_URL'),
SQS_AWS_REGION: Symbol.for('SQS_AWS_REGION'),
// Handlers
DomainEventSubscriberFactory: Symbol.for('DomainEventSubscriberFactory'),
DomainEventMessageHandler: Symbol.for('DomainEventMessageHandler'),
EventHandler: Symbol.for('EventHandler'),
// ORM
ORMEventRepository: Symbol.for('ORMEventRepository'),
// Services
Timer: Symbol.for('Timer'),
}
export default TYPES

View File

@@ -0,0 +1,38 @@
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm'
@Entity({ name: 'events' })
export class Event {
@PrimaryGeneratedColumn('uuid')
declare uuid: string
@Column({
name: 'user_identifier',
length: 255,
})
@Index('index_events_on_user_identifier')
declare userIdentifier: string
@Column({
name: 'user_identifier_type',
length: 255,
})
declare userIdentifierType: string
@Column({
name: 'event_type',
length: 255,
})
declare eventType: string
@Column({
name: 'event_payload',
type: 'text',
})
declare eventPayload: string
@Column({
name: 'timestamp',
type: 'bigint',
})
declare timestamp: number
}

View File

@@ -0,0 +1,76 @@
import 'reflect-metadata'
import { TimerInterface } from '@standardnotes/time'
import { Repository } from 'typeorm'
import { EventHandler } from './EventHandler'
import { Event } from '../Event/Event'
import { Logger } from 'winston'
import { DomainEventInterface } from '@standardnotes/domain-events'
describe('EventHandler', () => {
let timer: TimerInterface
let repository: Repository<Event>
let logger: Logger
const createHandler = () => new EventHandler(timer, repository, logger)
beforeEach(() => {
timer = {} as jest.Mocked<TimerInterface>
timer.convertStringDateToMicroseconds = jest.fn().mockReturnValue(1)
repository = {} as jest.Mocked<Repository<Event>>
repository.save = jest.fn()
logger = {} as jest.Mocked<Logger>
logger.debug = jest.fn()
logger.error = jest.fn()
})
it('should persist as event in the store', async () => {
const event = {
type: 'test',
createdAt: new Date(2),
meta: {
correlation: {
userIdentifier: '1-2-3',
userIdentifierType: 'uuid',
},
},
payload: {
foo: 'bar',
},
} as jest.Mocked<DomainEventInterface>
await createHandler().handle(event)
expect(repository.save).toHaveBeenCalledWith({
eventType: 'test',
timestamp: 1,
userIdentifier: '1-2-3',
userIdentifierType: 'uuid',
eventPayload: '{"foo":"bar"}',
})
})
it('should inform about failure to saven the event in the store', async () => {
const event = {
type: 'test',
createdAt: new Date(2),
meta: {
correlation: {
userIdentifier: '1-2-3',
userIdentifierType: 'uuid',
},
},
payload: {
foo: 'bar',
},
} as jest.Mocked<DomainEventInterface>
repository.save = jest.fn().mockImplementation(() => {
throw new Error('Ooops')
})
await createHandler().handle(event)
expect(logger.error).toHaveBeenCalledWith('Could not store event %O in the event store: %s', event, 'Ooops')
})
})

View File

@@ -0,0 +1,33 @@
import { DomainEventHandlerInterface, DomainEventInterface } from '@standardnotes/domain-events'
import { TimerInterface } from '@standardnotes/time'
import { inject, injectable } from 'inversify'
import { Repository } from 'typeorm'
import { Logger } from 'winston'
import TYPES from '../../Bootstrap/Types'
import { Event } from '../Event/Event'
@injectable()
export class EventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.Timer) private timer: TimerInterface,
@inject(TYPES.ORMEventRepository) private eventRepository: Repository<Event>,
@inject(TYPES.Logger) private logger: Logger,
) {}
async handle(event: DomainEventInterface): Promise<void> {
this.logger.debug('Handling event: %O', event)
try {
const storedEvent = new Event()
storedEvent.eventType = event.type
storedEvent.userIdentifier = event.meta.correlation.userIdentifier
storedEvent.userIdentifierType = event.meta.correlation.userIdentifierType
storedEvent.eventPayload = JSON.stringify(event.payload)
storedEvent.timestamp = this.timer.convertStringDateToMicroseconds(event.createdAt.toString())
await this.eventRepository.save(storedEvent)
} catch (error) {
this.logger.error('Could not store event %O in the event store: %s', event, (error as Error).message)
}
}
}

View File

View File

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

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.5.1](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.5.0...@standardnotes/files-server@1.5.1) (2022-07-11)
**Note:** Version bump only for package @standardnotes/files-server
# [1.5.0](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.4.0...@standardnotes/files-server@1.5.0) (2022-07-06)
### Features
* add sncryptio-node package ([60e8974](https://github.com/standardnotes/files/commit/60e8974580d498e7edf80813c32268a8bf7eda39))
# [1.4.0](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.3.0...@standardnotes/files-server@1.4.0) (2022-07-06)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/files-server",
"version": "1.4.0",
"version": "1.5.1",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -32,7 +32,7 @@
"@standardnotes/domain-events-infra": "workspace:*",
"@standardnotes/security": "workspace:*",
"@standardnotes/sncrypto-common": "^1.9.0",
"@standardnotes/sncrypto-node": "^1.8.3",
"@standardnotes/sncrypto-node": "workspace:*",
"@standardnotes/time": "workspace:*",
"aws-sdk": "^2.1158.0",
"connect-busboy": "^1.0.0",

View File

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

View File

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

View File

@@ -0,0 +1 @@
dist

View File

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

View File

@@ -0,0 +1,208 @@
# Change Log
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# 1.17.0 (2022-07-06)
### Features
* add settings package ([e7e34f3](https://github.com/standardnotes/server/commit/e7e34f3e16eb865f083b7b49b2f8f83fd8af8de0))
## [1.15.1](https://github.com/standardnotes/snjs/compare/@standardnotes/settings@1.15.0...@standardnotes/settings@1.15.1) (2022-07-04)
### Bug Fixes
* add missing reflect-metadata package to all packages ([ce3a5bb](https://github.com/standardnotes/snjs/commit/ce3a5bbf3f1d2276ac4abc3eec3c6a44c8c3ba9b))
# [1.15.0](https://github.com/standardnotes/snjs/compare/@standardnotes/settings@1.14.3...@standardnotes/settings@1.15.0) (2022-06-24)
### Features
* add muting marketing emails setting ([4d811e3](https://github.com/standardnotes/snjs/commit/4d811e3adab30fa2f1abde2ed3ebcc399e933d9c))
## [1.14.3](https://github.com/standardnotes/snjs/compare/@standardnotes/settings@1.14.1...@standardnotes/settings@1.14.3) (2022-05-04)
**Note:** Version bump only for package @standardnotes/settings
## [1.14.2](https://github.com/standardnotes/snjs/compare/@standardnotes/settings@1.14.1...@standardnotes/settings@1.14.2) (2022-05-04)
**Note:** Version bump only for package @standardnotes/settings
## [1.14.1](https://github.com/standardnotes/snjs/compare/@standardnotes/settings@1.14.0...@standardnotes/settings@1.14.1) (2022-04-22)
**Note:** Version bump only for package @standardnotes/settings
# [1.14.0](https://github.com/standardnotes/snjs/compare/@standardnotes/settings@1.13.4...@standardnotes/settings@1.14.0) (2022-04-19)
### Features
* add subscription setting name ([66c739b](https://github.com/standardnotes/snjs/commit/66c739b9ee00d27d2cd3176224d884aed7e2b9f8))
## [1.13.4](https://github.com/standardnotes/snjs/compare/@standardnotes/settings@1.13.3...@standardnotes/settings@1.13.4) (2022-04-15)
**Note:** Version bump only for package @standardnotes/settings
## [1.13.3](https://github.com/standardnotes/snjs/compare/@standardnotes/settings@1.13.2...@standardnotes/settings@1.13.3) (2022-04-11)
**Note:** Version bump only for package @standardnotes/settings
## [1.13.2](https://github.com/standardnotes/snjs/compare/@standardnotes/settings@1.13.1...@standardnotes/settings@1.13.2) (2022-03-31)
**Note:** Version bump only for package @standardnotes/settings
## [1.13.1](https://github.com/standardnotes/snjs/compare/@standardnotes/settings@1.13.0...@standardnotes/settings@1.13.1) (2022-03-17)
**Note:** Version bump only for package @standardnotes/settings
# [1.13.0](https://github.com/standardnotes/snjs/compare/@standardnotes/settings@1.12.0...@standardnotes/settings@1.13.0) (2022-03-16)
### Features
* add log session user agent setting ([3937f97](https://github.com/standardnotes/snjs/commit/3937f97826f1d6ee7f6fab14e8cccf5a6c829d69))
# [1.12.0](https://github.com/standardnotes/snjs/compare/@standardnotes/settings@1.11.5...@standardnotes/settings@1.12.0) (2022-03-07)
### Bug Fixes
* naming of email mute option ([c7c1747](https://github.com/standardnotes/snjs/commit/c7c174733bfd96e71d3146e49601eb0564a306a8))
### Features
* add mute sign in emails ([366bc06](https://github.com/standardnotes/snjs/commit/366bc06a210bbb099b42fd9f780491fc3f21ee06))
## [1.11.5](https://github.com/standardnotes/snjs/compare/@standardnotes/settings@1.11.3...@standardnotes/settings@1.11.5) (2022-02-28)
### Bug Fixes
* add pseudo change to get lerna to trigger ([41e6817](https://github.com/standardnotes/snjs/commit/41e6817bbf726b0932cdf16f58622328b9e42803))
## [1.11.4](https://github.com/standardnotes/snjs/compare/@standardnotes/settings@1.11.3...@standardnotes/settings@1.11.4) (2022-02-28)
### Bug Fixes
* add pseudo change to get lerna to trigger ([41e6817](https://github.com/standardnotes/snjs/commit/41e6817bbf726b0932cdf16f58622328b9e42803))
## [1.11.3](https://github.com/standardnotes/snjs/compare/@standardnotes/settings@1.11.2...@standardnotes/settings@1.11.3) (2022-02-02)
### Bug Fixes
* listed author secrets flatten ([91bdbf4](https://github.com/standardnotes/snjs/commit/91bdbf4d9f052cd55130edca89f99c5d04c996e0))
## [1.11.2](https://github.com/standardnotes/snjs/compare/@standardnotes/settings@1.11.1...@standardnotes/settings@1.11.2) (2022-02-01)
### Bug Fixes
* listed authors secret data type to include author id ([d9a27da](https://github.com/standardnotes/snjs/commit/d9a27dab48f7b444bd07f27dee9ca7aad77c6bc9))
## [1.11.1](https://github.com/standardnotes/snjs/compare/@standardnotes/settings@1.11.0...@standardnotes/settings@1.11.1) (2022-01-31)
### Bug Fixes
* add listed author secrets data type ([a780672](https://github.com/standardnotes/snjs/commit/a78067242b011148aa40b16e1a2536fa88c44f8f))
# [1.11.0](https://github.com/standardnotes/snjs/compare/@standardnotes/settings@1.10.0...@standardnotes/settings@1.11.0) (2022-01-28)
### Features
* add listed author secrets as a setting ([fb47efb](https://github.com/standardnotes/snjs/commit/fb47efb9e1decbc60ea310390cc99aba45a4b7c3))
# [1.10.0](https://github.com/standardnotes/snjs/compare/@standardnotes/settings@1.9.0...@standardnotes/settings@1.10.0) (2022-01-18)
### Features
* add file upload settings ([e2b8575](https://github.com/standardnotes/snjs/commit/e2b85752ada2d32d0c3deaedf7014d5293de4315))
# [1.9.0](https://github.com/standardnotes/snjs/compare/@standardnotes/settings@1.8.1...@standardnotes/settings@1.9.0) (2022-01-06)
### Features
* expose urls needed for cloud backup integration ([#537](https://github.com/standardnotes/snjs/issues/537)) ([efa492f](https://github.com/standardnotes/snjs/commit/efa492f6ddd26e23b590150c00263ac14267f572))
## [1.8.1](https://github.com/standardnotes/snjs/compare/@standardnotes/settings@1.8.0...@standardnotes/settings@1.8.1) (2021-12-30)
### Bug Fixes
* cloud backups token setting name ([#533](https://github.com/standardnotes/snjs/issues/533)) ([59545f0](https://github.com/standardnotes/snjs/commit/59545f05cfb90f39f072d48bf6b4bf62ac81b877))
* correct gitignore paths ([cefc0cf](https://github.com/standardnotes/snjs/commit/cefc0cfcf98e3e5378e055b8c46931b53b23195e))
* include dist in static components ([d17ce0f](https://github.com/standardnotes/snjs/commit/d17ce0f67045c6e4c97bf4577709aa58794e72e6))
# [1.8.0](https://github.com/standardnotes/snjs/compare/@standardnotes/settings@1.7.0...@standardnotes/settings@1.8.0) (2021-12-23)
### Features
* add cloud backup settings names ([#524](https://github.com/standardnotes/snjs/issues/524)) ([942352b](https://github.com/standardnotes/snjs/commit/942352bb68623c6b718d854b26d645bac97be6ee))
# 1.7.0 (2021-12-23)
### Features
* rename email backup setting to email backup frequency ([25e7b46](https://github.com/standardnotes/snjs/commit/25e7b4620834711ac7f513ae893898c5eab1af53))
## 1.6.3 (2021-12-23)
### Bug Fixes
* lock package versions ([8aa2ce6](https://github.com/standardnotes/snjs/commit/8aa2ce676b57598ab72840adf851869d8e769022))
## 1.6.2 (2021-12-23)
### Bug Fixes
* add publishing from package version by lerna ([80433d0](https://github.com/standardnotes/snjs/commit/80433d044f258095753482b8322d73aba3d9a9e4))
## 1.6.1 (2021-12-23)
### Bug Fixes
* remove the ammend commit from lerna versioning ([f0400d9](https://github.com/standardnotes/snjs/commit/f0400d9a2f5a04eaece2e4c16da71166a2ddb251))
# 1.6.0 (2021-12-23)
### Features
* add one drive backup frequency setting ([#522](https://github.com/standardnotes/snjs/issues/522)) ([c27827f](https://github.com/standardnotes/snjs/commit/c27827f8c7969dd32511c9c75122ece372132c83))
## 1.5.4 (2021-12-23)
### Bug Fixes
* remove running tests upon deployment - ensured on PR status checks ([#523](https://github.com/standardnotes/snjs/issues/523)) ([5c795d1](https://github.com/standardnotes/snjs/commit/5c795d17b583d02955773576384e622c3ef7f418))
## 1.5.3 (2021-12-23)
### Bug Fixes
* pr template ([#518](https://github.com/standardnotes/snjs/issues/518)) ([b445bb6](https://github.com/standardnotes/snjs/commit/b445bb64841217ae27c2514887629235be95d2a3))
## 1.5.2 (2021-12-23)
### Bug Fixes
* checkout with personal access token ([773c1ef](https://github.com/standardnotes/snjs/commit/773c1ef91c4452ad411e928342060dcb59428e3c))
## 1.5.1 (2021-12-22)
### Bug Fixes
* gpg signing with CI StandardNotes user ([d72f61c](https://github.com/standardnotes/snjs/commit/d72f61c23cd15b31d37340cc756d16526634b9ee))
# 1.5.0 (2021-12-22)
### Bug Fixes
* mute email options to string types ([8767a17](https://github.com/standardnotes/snjs/commit/8767a17541d02f3511756ba9cd2f7deaed8d453b))
* rename mute failed email backup settings ([a40f25a](https://github.com/standardnotes/snjs/commit/a40f25ae11b32e900435ed1afcab3783a46ea7ff))
* versioning and package dependencies ([#509](https://github.com/standardnotes/snjs/issues/509)) ([fe1df94](https://github.com/standardnotes/snjs/commit/fe1df94eff3e90bcf9ba0cf45bdc44ac49204c71))
### Features
* add "Disabled" option to email backup frequency ([#499](https://github.com/standardnotes/snjs/issues/499)) ([90a56ac](https://github.com/standardnotes/snjs/commit/90a56aca2b64556dc98bc0b9eeef1982c88411cd))
* add email backup frequency setting values ([5f5c2ea](https://github.com/standardnotes/snjs/commit/5f5c2ea44f85e246e7a7f50cc0b6356bfc65e554))
* add email backup requested event and mute emails setting ([4e4c904](https://github.com/standardnotes/snjs/commit/4e4c9043739f0bd68cbebdc344652d2b5d1edecd))
* add email backup setting name ([8a4118a](https://github.com/standardnotes/snjs/commit/8a4118a534b7aa921e2f5576a49d898b0784386c))
* add extension key setting name ([efd6c8c](https://github.com/standardnotes/snjs/commit/efd6c8c8fa974910bbb36281ba3639e033b5b1b6))
* add settings payload domain definition ([#377](https://github.com/standardnotes/snjs/issues/377)) ([22d9533](https://github.com/standardnotes/snjs/commit/22d9533cc9b72271778124a52d83cc6b9da6edcc))
* extract settings and common package ([#372](https://github.com/standardnotes/snjs/issues/372)) ([4f89688](https://github.com/standardnotes/snjs/commit/4f89688054cdae88c001287c9fb3431debd0136c))
* settings service ([#384](https://github.com/standardnotes/snjs/issues/384)) ([c9c976f](https://github.com/standardnotes/snjs/commit/c9c976f15f158ce121f53341dc74f91beb27e6a2))
* upgrade node engine versions to latest active LTS ([#462](https://github.com/standardnotes/snjs/issues/462)) ([686fc15](https://github.com/standardnotes/snjs/commit/686fc15030d302b474ebb7ef1cd4dcc48ec42359))

View File

@@ -0,0 +1,11 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const base = require('../../jest.config');
module.exports = {
...base,
globals: {
'ts-jest': {
tsconfig: 'tsconfig.json',
},
}
};

View File

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

View File

@@ -0,0 +1,34 @@
{
"name": "@standardnotes/settings",
"version": "1.17.0",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
"description": "Settings SDK for Standard Notes projects",
"main": "dist/src/index.js",
"author": "Standard Notes",
"types": "dist/src/index.d.ts",
"files": [
"dist/src/**/*.js",
"dist/src/**/*.d.ts"
],
"publishConfig": {
"access": "public"
},
"license": "AGPL-3.0-or-later",
"scripts": {
"clean": "rm -fr dist",
"prestart": "yarn clean",
"start": "tsc -p tsconfig.json --watch",
"prebuild": "yarn clean",
"build": "tsc -p tsconfig.json",
"lint": "eslint . --ext .ts"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.30.0",
"eslint-plugin-prettier": "^4.2.1"
},
"dependencies": {
"reflect-metadata": "^0.1.13"
}
}

View File

@@ -0,0 +1,5 @@
export enum CloudProvider {
Dropbox = 'Dropbox',
Google = 'Google Drive',
OneDrive = 'OneDrive',
}

View File

@@ -0,0 +1,5 @@
export enum DropboxBackupFrequency {
Disabled = 'disabled',
Daily = 'daily',
Weekly = 'weekly',
}

View File

@@ -0,0 +1,5 @@
export enum EmailBackupFrequency {
Disabled = 'disabled',
Daily = 'daily',
Weekly = 'weekly',
}

View File

@@ -0,0 +1,5 @@
export enum GoogleDriveBackupFrequency {
Disabled = 'disabled',
Daily = 'daily',
Weekly = 'weekly',
}

View File

@@ -0,0 +1 @@
export type ListedAuthorSecretsData = Array<{ authorId: number; secret: string; hostUrl: string }>

View File

@@ -0,0 +1,4 @@
export enum LogSessionUserAgentOption {
Disabled = 'disabled',
Enabled = 'enabled',
}

View File

@@ -0,0 +1,4 @@
export enum MuteFailedBackupsEmailsOption {
Muted = 'muted',
NotMuted = 'not_muted',
}

View File

@@ -0,0 +1,4 @@
export enum MuteFailedCloudBackupsEmailsOption {
Muted = 'muted',
NotMuted = 'not_muted',
}

View File

@@ -0,0 +1,4 @@
export enum MuteMarketingEmailsOption {
Muted = 'muted',
NotMuted = 'not_muted',
}

View File

@@ -0,0 +1,4 @@
export enum MuteSignInEmailsOption {
Muted = 'muted',
NotMuted = 'not_muted',
}

View File

@@ -0,0 +1,5 @@
export enum OneDriveBackupFrequency {
Disabled = 'disabled',
Daily = 'daily',
Weekly = 'weekly',
}

View File

@@ -0,0 +1,3 @@
import { SettingName } from './SettingName'
export type SensitiveSettingName = SettingName.MfaSecret | SettingName.ExtensionKey

View File

@@ -0,0 +1,17 @@
export enum SettingName {
MfaSecret = 'MFA_SECRET',
ExtensionKey = 'EXTENSION_KEY',
EmailBackupFrequency = 'EMAIL_BACKUP_FREQUENCY',
DropboxBackupFrequency = 'DROPBOX_BACKUP_FREQUENCY',
DropboxBackupToken = 'DROPBOX_BACKUP_TOKEN',
OneDriveBackupFrequency = 'ONE_DRIVE_BACKUP_FREQUENCY',
OneDriveBackupToken = 'ONE_DRIVE_BACKUP_TOKEN',
GoogleDriveBackupFrequency = 'GOOGLE_DRIVE_BACKUP_FREQUENCY',
GoogleDriveBackupToken = 'GOOGLE_DRIVE_BACKUP_TOKEN',
MuteFailedBackupsEmails = 'MUTE_FAILED_BACKUPS_EMAILS',
MuteFailedCloudBackupsEmails = 'MUTE_FAILED_CLOUD_BACKUPS_EMAILS',
MuteSignInEmails = 'MUTE_SIGN_IN_EMAILS',
MuteMarketingEmails = 'MUTE_MARKETING_EMAILS',
ListedAuthorSecrets = 'LISTED_AUTHOR_SECRETS',
LogSessionUserAgent = 'LOG_SESSION_USER_AGENT',
}

View File

@@ -0,0 +1,4 @@
export enum SubscriptionSettingName {
FileUploadBytesLimit = 'FILE_UPLOAD_BYTES_LIMIT',
FileUploadBytesUsed = 'FILE_UPLOAD_BYTES_USED',
}

View File

@@ -0,0 +1,14 @@
export * from './CloudProvider/CloudProvider'
export * from './DropboxBackupFrequency/DropboxBackupFrequency'
export * from './EmailBackupFrequency/EmailBackupFrequency'
export * from './GoogleDriveBackupFrequency/GoogleDriveBackupFrequency'
export * from './ListedAuthorSecretsData/ListedAuthorSecretsData'
export * from './LogSessionUserAgent/LogSessionUserAgentOption'
export * from './MuteFailedBackupsEmails/MuteFailedBackupsEmailsOption'
export * from './MuteFailedCloudBackupsEmails/MuteFailedCloudBackupsEmailsOption'
export * from './MuteMarketingEmails/MuteMarketingEmailsOption'
export * from './MuteSignInEmails/MuteSignInEmailsOption'
export * from './OneDriveBackupFrequency/OneDriveBackupFrequency'
export * from './Setting/SensitiveSettingName'
export * from './Setting/SettingName'
export * from './Setting/SubscriptionSettingName'

View File

@@ -0,0 +1 @@
export * from './Domain'

View File

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

View File

@@ -0,0 +1,4 @@
dist
test
*.config.js
test-server.js

View File

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

View File

@@ -0,0 +1,89 @@
# Change Log
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# 1.10.0 (2022-07-06)
### Features
* add sncryptio-node package ([60e8974](https://github.com/standardnotes/server/commit/60e8974580d498e7edf80813c32268a8bf7eda39))
## [1.8.4](https://github.com/standardnotes/snjs/compare/@standardnotes/sncrypto-node@1.8.3...@standardnotes/sncrypto-node@1.8.4) (2022-07-04)
### Bug Fixes
* add missing reflect-metadata package to all packages ([ce3a5bb](https://github.com/standardnotes/snjs/commit/ce3a5bbf3f1d2276ac4abc3eec3c6a44c8c3ba9b))
* unit tests running ([9ddc55c](https://github.com/standardnotes/snjs/commit/9ddc55c59c781e2bcc366304a6d0cc88d0e0865d))
## [1.8.3](https://github.com/standardnotes/snjs/compare/@standardnotes/sncrypto-node@1.8.2...@standardnotes/sncrypto-node@1.8.3) (2022-05-20)
**Note:** Version bump only for package @standardnotes/sncrypto-node
## [1.8.2](https://github.com/standardnotes/snjs/compare/@standardnotes/sncrypto-node@1.8.0...@standardnotes/sncrypto-node@1.8.2) (2022-05-04)
### Bug Fixes
* config package missing dependencies ([3dec12f](https://github.com/standardnotes/snjs/commit/3dec12fa4a83a8aed8419819eafb7c34795cb09f))
## [1.8.1](https://github.com/standardnotes/snjs/compare/@standardnotes/sncrypto-node@1.8.0...@standardnotes/sncrypto-node@1.8.1) (2022-05-04)
### Bug Fixes
* config package missing dependencies ([3dec12f](https://github.com/standardnotes/snjs/commit/3dec12fa4a83a8aed8419819eafb7c34795cb09f))
# [1.8.0](https://github.com/standardnotes/snjs/compare/@standardnotes/sncrypto-node@1.7.0...@standardnotes/sncrypto-node@1.8.0) (2022-05-03)
### Features
* rename SNCryptoNode to CryptoNode and fix sha256 function ([2c0cd81](https://github.com/standardnotes/snjs/commit/2c0cd81f952edfbe1f770534a269ddcaf9fa6678))
# [1.7.0](https://github.com/standardnotes/snjs/compare/@standardnotes/sncrypto-node@1.6.8...@standardnotes/sncrypto-node@1.7.0) (2022-04-28)
### Features
* refactor sncrypto to add unified sha256 and base64 usage ([#715](https://github.com/standardnotes/snjs/issues/715)) ([93aef4d](https://github.com/standardnotes/snjs/commit/93aef4d39228a63f01aa90a88e5d28c3375ed707))
## [1.6.8](https://github.com/standardnotes/snjs/compare/@standardnotes/sncrypto-node@1.6.7...@standardnotes/sncrypto-node@1.6.8) (2022-04-22)
**Note:** Version bump only for package @standardnotes/sncrypto-node
## [1.6.7](https://github.com/standardnotes/snjs/compare/@standardnotes/sncrypto-node@1.6.6...@standardnotes/sncrypto-node@1.6.7) (2022-04-15)
**Note:** Version bump only for package @standardnotes/sncrypto-node
## [1.6.6](https://github.com/standardnotes/snjs/compare/@standardnotes/sncrypto-node@1.6.5...@standardnotes/sncrypto-node@1.6.6) (2022-04-11)
**Note:** Version bump only for package @standardnotes/sncrypto-node
## [1.6.5](https://github.com/standardnotes/snjs/compare/@standardnotes/sncrypto-node@1.6.4...@standardnotes/sncrypto-node@1.6.5) (2022-03-31)
**Note:** Version bump only for package @standardnotes/sncrypto-node
## [1.6.4](https://github.com/standardnotes/snjs/compare/@standardnotes/sncrypto-node@1.6.2...@standardnotes/sncrypto-node@1.6.4) (2022-02-28)
### Bug Fixes
* add pseudo change to get lerna to trigger ([41e6817](https://github.com/standardnotes/snjs/commit/41e6817bbf726b0932cdf16f58622328b9e42803))
* add pseudo change to get lerna to trigger ([74e8af6](https://github.com/standardnotes/snjs/commit/74e8af640e3d0b8c2f0fc7cf792f4e2cdf33b50c))
## [1.6.3](https://github.com/standardnotes/snjs/compare/@standardnotes/sncrypto-node@1.6.2...@standardnotes/sncrypto-node@1.6.3) (2022-02-28)
### Bug Fixes
* add pseudo change to get lerna to trigger ([41e6817](https://github.com/standardnotes/snjs/commit/41e6817bbf726b0932cdf16f58622328b9e42803))
* add pseudo change to get lerna to trigger ([74e8af6](https://github.com/standardnotes/snjs/commit/74e8af640e3d0b8c2f0fc7cf792f4e2cdf33b50c))
## [1.6.2](https://github.com/standardnotes/snjs/compare/@standardnotes/sncrypto-node@1.6.1...@standardnotes/sncrypto-node@1.6.2) (2022-02-24)
**Note:** Version bump only for package @standardnotes/sncrypto-node
## [1.6.1](https://github.com/standardnotes/snjs/compare/@standardnotes/sncrypto-node@1.6.0...@standardnotes/sncrypto-node@1.6.1) (2022-02-16)
**Note:** Version bump only for package @standardnotes/sncrypto-node
# 1.6.0 (2022-01-14)
### Features
* move sncrypto packages to snjs monorepo ([#554](https://github.com/standardnotes/snjs/issues/554)) ([db83991](https://github.com/standardnotes/snjs/commit/db8399190d9d10fdc31060568b836c62933fd525))

View File

@@ -0,0 +1,21 @@
# SNCrypto for Node.js
[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)
Cryptographic primitives as a Node.js library -- used by server-side Standard Notes services, e.g. [Files](https://github.com/standardnotes/files).
## Installing
```
yarn add @standardnotes/sncrypto-node
```
## Supported Algorithms
- AES-GCM
## Tests
```
yarn test
```

View File

@@ -0,0 +1,11 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const base = require('../../jest.config');
module.exports = {
...base,
globals: {
'ts-jest': {
tsconfig: 'tsconfig.json',
},
}
};

View File

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

View File

@@ -0,0 +1,40 @@
{
"name": "@standardnotes/sncrypto-node",
"version": "1.10.0",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
"description": "SNCrypto for Node.js",
"main": "dist/src/index.js",
"types": "dist/src/index.d.ts",
"files": [
"dist/**/*.js",
"dist/**/*.js.map",
"dist/**/*.d.ts"
],
"license": "AGPL-3.0-or-later",
"publishConfig": {
"access": "public"
},
"scripts": {
"clean": "rm -fr dist",
"prebuild": "yarn clean",
"build": "tsc -p tsconfig.json",
"lint": "eslint . --ext .ts",
"test:unit": "jest spec"
},
"dependencies": {
"@standardnotes/sncrypto-common": "^1.9.0",
"reflect-metadata": "^0.1.13"
},
"devDependencies": {
"@types/jest": "^28.1.3",
"@types/node": "^18.0.0",
"@typescript-eslint/eslint-plugin": "^5.30.0",
"eslint-plugin-prettier": "^4.2.1",
"jest": "^28.1.2",
"regenerator-runtime": "^0.13.9",
"ts-jest": "^28.0.5",
"ts-loader": "^9.2.6"
}
}

View File

@@ -0,0 +1,176 @@
import { CryptoNode } from './CryptoNode'
describe('CryptoNode', function () {
const crypto = new CryptoNode()
it('aes gcm', async function () {
const iv = await crypto.generateRandomKey(128)
const key = await crypto.generateRandomKey(256)
const unencrypted = 'hello world 🌍'
const encrypted = await crypto.aes256GcmEncrypt({ unencrypted, iv, key })
const decrypted = await crypto.aes256GcmDecrypt(encrypted, key)
expect(decrypted).toEqual(unencrypted)
})
// from https://github.com/xorbit/node-aes-gcm/blob/588f9066a217335acc56ab45559d2b46edc9fa83/test/test.js#L342
it('aes gcm NIST Test Case 15', async () => {
const key = 'feffe9928665731c6d6a8f9467308308' + 'feffe9928665731c6d6a8f9467308308'
const iv = 'cafebabefacedbaddecaf888'
const string =
'd9313225f88406e5a55909c5aff5269a' +
'86a7a9531534f7da2e4c303d8a318a72' +
'1c3c0c95956809532fcf0e2449a6b525' +
'b16aedf5aa0de657ba637b391aafd255'
const aad = ''
const desiredCiphertext = Buffer.from(
'522dc1f099567d07f47f37a32a84427d' +
'643a8cdcbfe5c0c97598a2bd2555d1aa' +
'8cb08e48590dbb3da7b08b1056828838' +
'c5f61e6393ba7a0abcc9f662898015ad',
'hex',
).toString('base64')
const desiredTag = 'b094dac5d93471bdec1a502270e3cc6c'
const encrypted = await crypto.aes256GcmEncrypt({
unencrypted: { string, encoding: 'hex' },
iv,
key,
aad,
})
expect(encrypted.ciphertext).toEqual(desiredCiphertext)
expect(encrypted.tag).toEqual(desiredTag)
expect(encrypted.iv).toEqual(iv)
const decrypted = await crypto.aes256GcmDecrypt(encrypted, key)
expect(decrypted).toEqual(string)
})
// from https://github.com/standardnotes/auth/blob/d5585b3ad0a27f58fb413ff2d85699d82b2e9b65/src/Domain/Encryption/Crypter.spec.ts#L32
it('should encrypt and decrypt data with an expected output', async () => {
const keys = [
'00000000000000000000000000000000' + '00000000000000000000000000000000',
'00000000000000000000000000000000' + '00000000000000000000000000000000',
'feffe9928665731c6d6a8f9467308308' + 'feffe9928665731c6d6a8f9467308308',
'feffe9928665731c6d6a8f9467308308' + 'feffe9928665731c6d6a8f9467308308',
'feffe9928665731c6d6a8f9467308308' + 'feffe9928665731c6d6a8f9467308308',
'feffe9928665731c6d6a8f9467308308' + 'feffe9928665731c6d6a8f9467308308',
]
const ivs = [
'000000000000000000000000',
'000000000000000000000000',
'cafebabefacedbaddecaf888',
'cafebabefacedbaddecaf888',
'cafebabefacedbad',
'9313225df88406e555909c5aff5269aa' +
'6a7a9538534f7da1e4c303d2a318a728' +
'c3c0c95156809539fcf0e2429a6b5254' +
'16aedbf5a0de6a57a637b39b',
]
const inputs = [
'',
'00000000000000000000000000000000',
'd9313225f88406e5a55909c5aff5269a' +
'86a7a9531534f7da2e4c303d8a318a72' +
'1c3c0c95956809532fcf0e2449a6b525' +
'b16aedf5aa0de657ba637b391aafd255',
'd9313225f88406e5a55909c5aff5269a' +
'86a7a9531534f7da2e4c303d8a318a72' +
'1c3c0c95956809532fcf0e2449a6b525' +
'b16aedf5aa0de657ba637b39',
'd9313225f88406e5a55909c5aff5269a' +
'86a7a9531534f7da2e4c303d8a318a72' +
'1c3c0c95956809532fcf0e2449a6b525' +
'b16aedf5aa0de657ba637b39',
'd9313225f88406e5a55909c5aff5269a' +
'86a7a9531534f7da2e4c303d8a318a72' +
'1c3c0c95956809532fcf0e2449a6b525' +
'b16aedf5aa0de657ba637b39',
]
const outputs = [
'',
'cea7403d4d606b6e074ec5d3baf39d18',
'522dc1f099567d07f47f37a32a84427d' +
'643a8cdcbfe5c0c97598a2bd2555d1aa' +
'8cb08e48590dbb3da7b08b1056828838' +
'c5f61e6393ba7a0abcc9f662898015ad',
'522dc1f099567d07f47f37a32a84427d' +
'643a8cdcbfe5c0c97598a2bd2555d1aa' +
'8cb08e48590dbb3da7b08b1056828838' +
'c5f61e6393ba7a0abcc9f662',
'c3762df1ca787d32ae47c13bf19844cb' +
'af1ae14d0b976afac52ff7d79bba9de0' +
'feb582d33934a4f0954cc2363bc73f78' +
'62ac430e64abe499f47c9b1f',
'5a8def2f0c9e53f1f75d7853659e2a20' +
'eeb2b22aafde6419a058ab4f6f746bf4' +
'0fc0c3b780f244452da3ebf1c5d82cde' +
'a2418997200ef82e44ae7e3f',
]
const aads = [
'',
'',
'',
'feedfacedeadbeeffeedfacedeadbeef' + 'abaddad2',
'feedfacedeadbeeffeedfacedeadbeef' + 'abaddad2',
'feedfacedeadbeeffeedfacedeadbeef' + 'abaddad2',
]
const tags = [
'530f8afbc74536b9a963b4f1c4cb738b',
'd0d1c8a799996bf0265b98b5d48ab919',
'b094dac5d93471bdec1a502270e3cc6c',
'76fc6ece0f4e1768cddf8853bb2d551b',
'3a337dbf46a792c45e454913fe2ea8f2',
'a44a8266ee1c8eb0c8b5d4cf5ae9f19a',
]
for (let i = 0; i < keys.length; i++) {
const string = inputs[i]
const aad = aads[i]
const iv = ivs[i]
const key = keys[i]
const desiredTag = tags[i]
const desiredCiphertext = Buffer.from(outputs[i], 'hex').toString('base64')
const encrypted = await crypto.aes256GcmEncrypt({
unencrypted: { string, encoding: 'hex' },
iv,
key,
aad,
})
expect(encrypted.ciphertext).toEqual(desiredCiphertext)
expect(encrypted.tag).toEqual(desiredTag)
expect(encrypted.iv).toEqual(iv)
const decrypted = await crypto.aes256GcmDecrypt(encrypted, key)
expect(decrypted).toEqual(string)
}
})
it('should encrypt data with SHA256', () => {
expect(crypto.sha256('eSyM3G8TkyzaCxDlQwXo0X7nkdrRkjEHN3TREmW7iQc4sKVibWj4pyQYZLacKAee')).toEqual(
'97e65d4c20152373cb0f787d73f480c6890076fec1753098768f60c93f8ef63a',
)
})
it('should base64 encode a utf8 string', () => {
expect(crypto.base64Encode('Hello World')).toEqual('SGVsbG8gV29ybGQ=')
})
it('should base64 encode a utf8 string with url safe option', () => {
expect(crypto.base64URLEncode('Hello World')).toEqual('SGVsbG8gV29ybGQ')
})
it('should base64 decode a utf8 string', () => {
expect(crypto.base64Decode('SGVsbG8gV29ybGQ=')).toEqual('Hello World')
})
})

View File

@@ -0,0 +1,81 @@
import {
Aes256GcmEncrypted,
Aes256GcmInput,
HexString,
CryptoAes256GcmInterface,
CryptoSha256Interface,
CryptoBase64Interface,
Utf8String,
Base64String,
} from '@standardnotes/sncrypto-common'
import { createCipheriv, createDecipheriv, randomBytes, createHash } from 'crypto'
import { getBufferWithEncoding } from './Utils'
export class CryptoNode
implements CryptoAes256GcmInterface<BufferEncoding>, CryptoSha256Interface, CryptoBase64Interface
{
async aes256GcmEncrypt({
unencrypted,
iv,
key,
aad = '',
}: Aes256GcmInput<BufferEncoding>): Promise<Aes256GcmEncrypted<BufferEncoding>> {
const { buffer: dataBuffer, encoding } = getBufferWithEncoding(unencrypted)
const ivBuffer = Buffer.from(iv, 'hex')
const keyBuffer = Buffer.from(key, 'hex')
const cipher = createCipheriv('aes-256-gcm', keyBuffer, ivBuffer)
const aadBuffer = Buffer.from(aad, 'hex')
cipher.setAAD(aadBuffer)
const ciphertext = Buffer.concat([cipher.update(dataBuffer), cipher.final()]).toString('base64')
const tag = cipher.getAuthTag().toString('hex')
return { iv, tag, aad, ciphertext, encoding }
}
async aes256GcmDecrypt(encrypted: Aes256GcmEncrypted<BufferEncoding>, key: HexString): Promise<string> {
const { iv, tag, ciphertext, encoding, aad } = encrypted
const decipher = createDecipheriv('aes-256-gcm', Buffer.from(key, 'hex'), Buffer.from(iv, 'hex'))
decipher.setAuthTag(Buffer.from(tag, 'hex'))
decipher.setAAD(Buffer.from(aad, 'hex'))
const decrypted = Buffer.concat([decipher.update(Buffer.from(ciphertext, 'base64')), decipher.final()])
return decrypted.toString(encoding)
}
async generateRandomKey(bits: number): Promise<HexString> {
const bytes = bits / 8
const buf = randomBytes(bytes)
return buf.toString('hex')
}
sha256(text: Utf8String): HexString {
const hash = createHash('sha256').update(text)
return hash.digest('hex')
}
base64Encode(text: Utf8String): Base64String {
const { buffer } = getBufferWithEncoding({ string: text, encoding: 'utf8' })
return buffer.toString('base64')
}
base64URLEncode(text: Utf8String): Base64String {
const { buffer } = getBufferWithEncoding({ string: text, encoding: 'utf8' })
return buffer.toString('base64url')
}
base64Decode(base64String: Base64String): Utf8String {
const { buffer } = getBufferWithEncoding({ string: base64String, encoding: 'base64' })
return buffer.toString('utf8')
}
}

View File

@@ -0,0 +1,20 @@
import { Unencrypted } from '@standardnotes/sncrypto-common'
/**
* Turns `unencrypted` into a `buffer` with `encoding`.
* @param unencrypted
*/
export function getBufferWithEncoding(unencrypted: Unencrypted<BufferEncoding>): {
buffer: Buffer
encoding: BufferEncoding
} {
if (typeof unencrypted === 'string') {
const encoding: BufferEncoding = 'utf-8'
const buffer = Buffer.from(unencrypted, encoding)
return { buffer, encoding }
}
const { string, encoding } = unencrypted
const buffer = Buffer.from(string, encoding)
return { buffer, encoding }
}

View File

@@ -0,0 +1,2 @@
export * from './CryptoNode'
export * from './Utils'

View File

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

View File

@@ -3,6 +3,24 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.6.2](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.6.1...@standardnotes/syncing-server@1.6.2) (2022-07-11)
### Bug Fixes
* log errors on not being able to create a backup file ([fc5cea1](https://github.com/standardnotes/syncing-server-js/commit/fc5cea11b5401f83a0f8cf2b386abbff90bd18d7))
## [1.6.1](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.6.0...@standardnotes/syncing-server@1.6.1) (2022-07-11)
### Bug Fixes
* remove unused MailBackupAttachmentTooBigEvent ([b4fae4b](https://github.com/standardnotes/syncing-server-js/commit/b4fae4b800fdef9bcfb28d8f332c5c0bbf576833))
# [1.6.0](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.5.0...@standardnotes/syncing-server@1.6.0) (2022-07-06)
### Features
* add settings package ([e7e34f3](https://github.com/standardnotes/syncing-server-js/commit/e7e34f3e16eb865f083b7b49b2f8f83fd8af8de0))
# [1.5.0](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.4.0...@standardnotes/syncing-server@1.5.0) (2022-07-06)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/syncing-server",
"version": "1.5.0",
"version": "1.6.2",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -33,7 +33,7 @@
"@standardnotes/payloads": "^1.5.1",
"@standardnotes/responses": "^1.6.39",
"@standardnotes/security": "workspace:*",
"@standardnotes/settings": "1.15.0",
"@standardnotes/settings": "workspace:*",
"@standardnotes/time": "workspace:*",
"aws-sdk": "^2.1159.0",
"axios": "0.24.0",

View File

@@ -118,33 +118,6 @@ describe('DomainEventFactory', () => {
})
})
it('should create a MAIL_BACKUP_ATTACHMENT_TOO_BIG event', () => {
expect(
createFactory().createMailBackupAttachmentTooBigEvent({
allowedSize: '1000',
attachmentSize: '1500',
muteEmailsSettingUuid: '1-2-3',
email: 'test@test.com',
}),
).toEqual({
createdAt: expect.any(Date),
meta: {
correlation: {
userIdentifier: 'test@test.com',
userIdentifierType: 'email',
},
origin: 'syncing-server',
},
payload: {
email: 'test@test.com',
muteEmailsSettingUuid: '1-2-3',
allowedSize: '1000',
attachmentSize: '1500',
},
type: 'MAIL_BACKUP_ATTACHMENT_TOO_BIG',
})
})
it('should create a EMAIL_ARCHIVE_EXTENSION_SYNCED event', () => {
expect(createFactory().createEmailArchiveExtensionSyncedEvent('1-2-3', '2-3-4')).toEqual({
createdAt: expect.any(Date),

View File

@@ -6,7 +6,6 @@ import {
EmailBackupAttachmentCreatedEvent,
GoogleDriveBackupFailedEvent,
ItemsSyncedEvent,
MailBackupAttachmentTooBigEvent,
OneDriveBackupFailedEvent,
UserRegisteredEvent,
} from '@standardnotes/domain-events'
@@ -91,26 +90,6 @@ export class DomainEventFactory implements DomainEventFactoryInterface {
}
}
createMailBackupAttachmentTooBigEvent(dto: {
allowedSize: string
attachmentSize: string
muteEmailsSettingUuid: string
email: string
}): MailBackupAttachmentTooBigEvent {
return {
type: 'MAIL_BACKUP_ATTACHMENT_TOO_BIG',
createdAt: this.timer.getUTCDate(),
meta: {
correlation: {
userIdentifier: dto.email,
userIdentifierType: 'email',
},
origin: DomainEventService.SyncingServer,
},
payload: dto,
}
}
createItemsSyncedEvent(dto: {
userUuid: string
extensionUrl: string

View File

@@ -5,7 +5,6 @@ import {
EmailBackupAttachmentCreatedEvent,
GoogleDriveBackupFailedEvent,
ItemsSyncedEvent,
MailBackupAttachmentTooBigEvent,
OneDriveBackupFailedEvent,
UserRegisteredEvent,
} from '@standardnotes/domain-events'
@@ -15,12 +14,6 @@ export interface DomainEventFactoryInterface {
createDropboxBackupFailedEvent(muteCloudEmailsSettingUuid: string, email: string): DropboxBackupFailedEvent
createGoogleDriveBackupFailedEvent(muteCloudEmailsSettingUuid: string, email: string): GoogleDriveBackupFailedEvent
createOneDriveBackupFailedEvent(muteCloudEmailsSettingUuid: string, email: string): OneDriveBackupFailedEvent
createMailBackupAttachmentTooBigEvent(dto: {
allowedSize: string
attachmentSize: string
muteEmailsSettingUuid: string
email: string
}): MailBackupAttachmentTooBigEvent
createItemsSyncedEvent(dto: {
userUuid: string
extensionUrl: string

View File

@@ -4,7 +4,6 @@ import {
DomainEventPublisherInterface,
EmailBackupRequestedEvent,
EmailBackupAttachmentCreatedEvent,
MailBackupAttachmentTooBigEvent,
} from '@standardnotes/domain-events'
import { Logger } from 'winston'
import { AuthHttpServiceInterface } from '../Auth/AuthHttpServiceInterface'
@@ -66,9 +65,6 @@ describe('EmailBackupRequestedEventHandler', () => {
domainEventFactory.createEmailBackupAttachmentCreatedEvent = jest
.fn()
.mockReturnValue({} as jest.Mocked<EmailBackupAttachmentCreatedEvent>)
domainEventFactory.createMailBackupAttachmentTooBigEvent = jest
.fn()
.mockReturnValue({} as jest.Mocked<MailBackupAttachmentTooBigEvent>)
itemTransferCalculator = {} as jest.Mocked<ItemTransferCalculatorInterface>
itemTransferCalculator.computeItemUuidBundlesToFetch = jest.fn().mockReturnValue([['1-2-3']])
@@ -76,6 +72,7 @@ describe('EmailBackupRequestedEventHandler', () => {
logger = {} as jest.Mocked<Logger>
logger.debug = jest.fn()
logger.warn = jest.fn()
logger.error = jest.fn()
})
it('should inform that backup attachment for email was created', async () => {

View File

@@ -63,18 +63,22 @@ export class EmailBackupRequestedEventHandler implements DomainEventHandlerInter
this.logger.debug(`Data backed up into: ${backupFileName}`)
if (backupFileName.length !== 0) {
this.logger.debug('Publishing EMAIL_BACKUP_ATTACHMENT_CREATED event')
if (backupFileName.length === 0) {
this.logger.error(`Could not create a backup file for user ${event.payload.userUuid}`)
await this.domainEventPublisher.publish(
this.domainEventFactory.createEmailBackupAttachmentCreatedEvent({
backupFileName,
backupFileIndex: bundleIndex++,
backupFilesTotal: itemUuidBundles.length,
email: authParams.identifier as string,
}),
)
return
}
this.logger.debug('Publishing EMAIL_BACKUP_ATTACHMENT_CREATED event')
await this.domainEventPublisher.publish(
this.domainEventFactory.createEmailBackupAttachmentCreatedEvent({
backupFileName,
backupFileIndex: bundleIndex++,
backupFilesTotal: itemUuidBundles.length,
email: authParams.identifier as string,
}),
)
}
}
}

View File

@@ -40,6 +40,9 @@
{
"path": "./packages/domain-events-infra"
},
{
"path": "./packages/event-store"
},
{
"path": "./packages/files"
},
@@ -52,6 +55,9 @@
{
"path": "./packages/security"
},
{
"path": "./packages/settings"
},
{
"path": "./packages/syncing-server"
},

125
yarn.lock
View File

@@ -2025,9 +2025,9 @@ __metadata:
"@standardnotes/predicates": "workspace:*"
"@standardnotes/responses": ^1.6.39
"@standardnotes/security": "workspace:*"
"@standardnotes/settings": ^1.15.0
"@standardnotes/settings": "workspace:*"
"@standardnotes/sncrypto-common": ^1.9.0
"@standardnotes/sncrypto-node": ^1.8.3
"@standardnotes/sncrypto-node": "workspace:*"
"@standardnotes/time": "workspace:*"
"@types/bcryptjs": ^2.4.2
"@types/cors": ^2.8.9
@@ -2159,6 +2159,34 @@ __metadata:
languageName: node
linkType: hard
"@standardnotes/event-store@workspace:packages/event-store":
version: 0.0.0-use.local
resolution: "@standardnotes/event-store@workspace:packages/event-store"
dependencies:
"@standardnotes/domain-events": "workspace:*"
"@standardnotes/domain-events-infra": "workspace:*"
"@standardnotes/time": "workspace:*"
"@types/ioredis": ^4.28.10
"@types/jest": ^28.1.3
"@types/newrelic": ^7.0.3
"@types/nodemailer": ^6.4.1
"@typescript-eslint/eslint-plugin": ^5.30.5
aws-sdk: ^2.1159.0
dotenv: 8.2.0
eslint: ^8.14.0
eslint-plugin-prettier: ^4.2.1
inversify: ^6.0.1
ioredis: ^5.0.6
jest: ^28.1.1
mysql2: ^2.3.3
newrelic: ^8.14.1
reflect-metadata: 0.1.13
ts-jest: ^28.0.1
typeorm: ^0.3.6
winston: 3.3.3
languageName: unknown
linkType: soft
"@standardnotes/features@npm:1.50.0, @standardnotes/features@npm:^1.36.3, @standardnotes/features@npm:^1.47.0":
version: 1.50.0
resolution: "@standardnotes/features@npm:1.50.0"
@@ -2181,7 +2209,7 @@ __metadata:
"@standardnotes/domain-events-infra": "workspace:*"
"@standardnotes/security": "workspace:*"
"@standardnotes/sncrypto-common": ^1.9.0
"@standardnotes/sncrypto-node": ^1.8.3
"@standardnotes/sncrypto-node": "workspace:*"
"@standardnotes/time": "workspace:*"
"@types/connect-busboy": ^1.0.0
"@types/cors": ^2.8.9
@@ -2358,12 +2386,15 @@ __metadata:
languageName: node
linkType: hard
"@standardnotes/settings@npm:1.15.0, @standardnotes/settings@npm:^1.15.0":
version: 1.15.0
resolution: "@standardnotes/settings@npm:1.15.0"
checksum: 4397d453a1a0cd5554012a5bf5ee2025c102ffc6d742841eecd2ab9cd46b0fbfe78da61b401451646274887d92801cafcef4c283bbfc6074b4d152103e15f861
languageName: node
linkType: hard
"@standardnotes/settings@workspace:*, @standardnotes/settings@workspace:packages/settings":
version: 0.0.0-use.local
resolution: "@standardnotes/settings@workspace:packages/settings"
dependencies:
"@typescript-eslint/eslint-plugin": ^5.30.0
eslint-plugin-prettier: ^4.2.1
reflect-metadata: ^0.1.13
languageName: unknown
linkType: soft
"@standardnotes/sncrypto-common@npm:^1.9.0":
version: 1.9.0
@@ -2372,14 +2403,22 @@ __metadata:
languageName: node
linkType: hard
"@standardnotes/sncrypto-node@npm:^1.8.3":
version: 1.8.3
resolution: "@standardnotes/sncrypto-node@npm:1.8.3"
"@standardnotes/sncrypto-node@workspace:*, @standardnotes/sncrypto-node@workspace:packages/sncrypto-node":
version: 0.0.0-use.local
resolution: "@standardnotes/sncrypto-node@workspace:packages/sncrypto-node"
dependencies:
"@standardnotes/sncrypto-common": ^1.9.0
checksum: b3c866bfba63fbf673ce78de0a25b0abff5f2cf2476892f3fba76d55554d0d84e304d6f454dd9a482f723585e995fc56565f47a67ea52e53f6c3075f1c160286
languageName: node
linkType: hard
"@types/jest": ^28.1.3
"@types/node": ^18.0.0
"@typescript-eslint/eslint-plugin": ^5.30.0
eslint-plugin-prettier: ^4.2.1
jest: ^28.1.2
reflect-metadata: ^0.1.13
regenerator-runtime: ^0.13.9
ts-jest: ^28.0.5
ts-loader: ^9.2.6
languageName: unknown
linkType: soft
"@standardnotes/syncing-server@workspace:packages/syncing-server":
version: 0.0.0-use.local
@@ -2394,7 +2433,7 @@ __metadata:
"@standardnotes/payloads": ^1.5.1
"@standardnotes/responses": ^1.6.39
"@standardnotes/security": "workspace:*"
"@standardnotes/settings": 1.15.0
"@standardnotes/settings": "workspace:*"
"@standardnotes/time": "workspace:*"
"@types/cors": ^2.8.9
"@types/dotenv": ^8.2.0
@@ -2785,6 +2824,15 @@ __metadata:
languageName: node
linkType: hard
"@types/nodemailer@npm:^6.4.1":
version: 6.4.4
resolution: "@types/nodemailer@npm:6.4.4"
dependencies:
"@types/node": "*"
checksum: 16ed1bad2cd8471fd3b026471e234da33ba3b65935dc44b31be3145eff7bdb067eb4d08ec4b41d23339b988075299abc1a0c0fe77b99f04ca235827bca95af81
languageName: node
linkType: hard
"@types/normalize-package-data@npm:^2.4.0":
version: 2.4.1
resolution: "@types/normalize-package-data@npm:2.4.1"
@@ -2901,7 +2949,7 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/eslint-plugin@npm:^5.12.1, @typescript-eslint/eslint-plugin@npm:^5.29.0, @typescript-eslint/eslint-plugin@npm:^5.30.0":
"@typescript-eslint/eslint-plugin@npm:^5.12.1, @typescript-eslint/eslint-plugin@npm:^5.29.0, @typescript-eslint/eslint-plugin@npm:^5.30.0, @typescript-eslint/eslint-plugin@npm:^5.30.5":
version: 5.30.5
resolution: "@typescript-eslint/eslint-plugin@npm:5.30.5"
dependencies:
@@ -4932,6 +4980,16 @@ __metadata:
languageName: node
linkType: hard
"enhanced-resolve@npm:^5.0.0":
version: 5.10.0
resolution: "enhanced-resolve@npm:5.10.0"
dependencies:
graceful-fs: ^4.2.4
tapable: ^2.2.0
checksum: 0bb9830704db271610f900e8d79d70a740ea16f251263362b0c91af545576d09fe50103496606c1300a05e588372d6f9780a9bc2e30ce8ef9b827ec8f44687ff
languageName: node
linkType: hard
"env-paths@npm:^2.2.0":
version: 2.2.1
resolution: "env-paths@npm:2.2.1"
@@ -5952,7 +6010,7 @@ __metadata:
languageName: node
linkType: hard
"graceful-fs@npm:^4.1.11, graceful-fs@npm:^4.1.15, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.10, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9":
"graceful-fs@npm:^4.1.11, graceful-fs@npm:^4.1.15, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.10, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9":
version: 4.2.10
resolution: "graceful-fs@npm:4.2.10"
checksum: 3f109d70ae123951905d85032ebeae3c2a5a7a997430df00ea30df0e3a6c60cf6689b109654d6fdacd28810a053348c4d14642da1d075049e6be1ba5216218da
@@ -8377,7 +8435,7 @@ __metadata:
languageName: node
linkType: hard
"micromatch@npm:^4.0.4":
"micromatch@npm:^4.0.0, micromatch@npm:^4.0.4":
version: 4.0.5
resolution: "micromatch@npm:4.0.5"
dependencies:
@@ -10109,6 +10167,13 @@ __metadata:
languageName: node
linkType: hard
"regenerator-runtime@npm:^0.13.9":
version: 0.13.9
resolution: "regenerator-runtime@npm:0.13.9"
checksum: 65ed455fe5afd799e2897baf691ca21c2772e1a969d19bb0c4695757c2d96249eb74ee3553ea34a91062b2a676beedf630b4c1551cc6299afb937be1426ec55e
languageName: node
linkType: hard
"regexpp@npm:^3.2.0":
version: 3.2.0
resolution: "regexpp@npm:3.2.0"
@@ -10962,6 +11027,13 @@ __metadata:
languageName: node
linkType: hard
"tapable@npm:^2.2.0":
version: 2.2.1
resolution: "tapable@npm:2.2.1"
checksum: 3b7a1b4d86fa940aad46d9e73d1e8739335efd4c48322cb37d073eb6f80f5281889bf0320c6d8ffcfa1a0dd5bfdbd0f9d037e252ef972aca595330538aac4d51
languageName: node
linkType: hard
"tar@npm:^6.1.11, tar@npm:^6.1.2":
version: 6.1.11
resolution: "tar@npm:6.1.11"
@@ -11267,6 +11339,21 @@ __metadata:
languageName: node
linkType: hard
"ts-loader@npm:^9.2.6":
version: 9.3.1
resolution: "ts-loader@npm:9.3.1"
dependencies:
chalk: ^4.1.0
enhanced-resolve: ^5.0.0
micromatch: ^4.0.0
semver: ^7.3.4
peerDependencies:
typescript: "*"
webpack: ^5.0.0
checksum: 462a8ac315017cf4961dafd2be29d5abe7c3af63c4515e325269f79b9d0212b35c59184d7fd01fc378749c88454752e1599301d2190eb6844ea5fe332de5f695
languageName: node
linkType: hard
"ts-node@npm:^10.4.0, ts-node@npm:^10.8.1":
version: 10.8.2
resolution: "ts-node@npm:10.8.2"