mirror of
https://github.com/standardnotes/server
synced 2026-01-25 02:01:08 -05:00
Compare commits
24 Commits
@standardn
...
@standardn
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d2342f9ee | ||
|
|
60838a1b7e | ||
|
|
63401b7640 | ||
|
|
6a5b669ec4 | ||
|
|
ca201447d2 | ||
|
|
f1d3117518 | ||
|
|
8559948a5a | ||
|
|
a3b4aa3b4a | ||
|
|
0347fa381f | ||
|
|
3d475cc779 | ||
|
|
ceec74fb70 | ||
|
|
f5296a947e | ||
|
|
5b5fcd9372 | ||
|
|
c38817c62e | ||
|
|
ba08c6a707 | ||
|
|
1797bc8181 | ||
|
|
657aaf75ec | ||
|
|
dac3c733b3 | ||
|
|
d02b6b67b5 | ||
|
|
52ce5f3a2f | ||
|
|
1d316e17cb | ||
|
|
6193f4b87a | ||
|
|
de5a30e46c | ||
|
|
973acd22ca |
423
.pnp.cjs
generated
423
.pnp.cjs
generated
@@ -132,7 +132,7 @@ const RAW_RUNTIME_STATE =
|
||||
["@types/node", "npm:18.11.9"],\
|
||||
["@typescript-eslint/parser", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:5.40.1"],\
|
||||
["eslint", "npm:8.32.0"],\
|
||||
["eslint-config-prettier", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:8.5.0"],\
|
||||
["eslint-config-prettier", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:8.6.0"],\
|
||||
["ini", "npm:3.0.0"],\
|
||||
["newrelic", "npm:9.8.0"],\
|
||||
["npm-check-updates", "npm:16.0.1"],\
|
||||
@@ -914,6 +914,60 @@ const RAW_RUNTIME_STATE =
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@cbor-extract/cbor-extract-darwin-arm64", [\
|
||||
["npm:2.1.1", {\
|
||||
"packageLocation": "./.yarn/unplugged/@cbor-extract-cbor-extract-darwin-arm64-npm-2.1.1-7f6025512f/node_modules/@cbor-extract/cbor-extract-darwin-arm64/",\
|
||||
"packageDependencies": [\
|
||||
["@cbor-extract/cbor-extract-darwin-arm64", "npm:2.1.1"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@cbor-extract/cbor-extract-darwin-x64", [\
|
||||
["npm:2.1.1", {\
|
||||
"packageLocation": "./.yarn/unplugged/@cbor-extract-cbor-extract-darwin-x64-npm-2.1.1-9c0e0a67cc/node_modules/@cbor-extract/cbor-extract-darwin-x64/",\
|
||||
"packageDependencies": [\
|
||||
["@cbor-extract/cbor-extract-darwin-x64", "npm:2.1.1"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@cbor-extract/cbor-extract-linux-arm", [\
|
||||
["npm:2.1.1", {\
|
||||
"packageLocation": "./.yarn/unplugged/@cbor-extract-cbor-extract-linux-arm-npm-2.1.1-95d0b66b34/node_modules/@cbor-extract/cbor-extract-linux-arm/",\
|
||||
"packageDependencies": [\
|
||||
["@cbor-extract/cbor-extract-linux-arm", "npm:2.1.1"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@cbor-extract/cbor-extract-linux-arm64", [\
|
||||
["npm:2.1.1", {\
|
||||
"packageLocation": "./.yarn/unplugged/@cbor-extract-cbor-extract-linux-arm64-npm-2.1.1-23a641c278/node_modules/@cbor-extract/cbor-extract-linux-arm64/",\
|
||||
"packageDependencies": [\
|
||||
["@cbor-extract/cbor-extract-linux-arm64", "npm:2.1.1"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@cbor-extract/cbor-extract-linux-x64", [\
|
||||
["npm:2.1.1", {\
|
||||
"packageLocation": "./.yarn/unplugged/@cbor-extract-cbor-extract-linux-x64-npm-2.1.1-4471164400/node_modules/@cbor-extract/cbor-extract-linux-x64/",\
|
||||
"packageDependencies": [\
|
||||
["@cbor-extract/cbor-extract-linux-x64", "npm:2.1.1"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@cbor-extract/cbor-extract-win32-x64", [\
|
||||
["npm:2.1.1", {\
|
||||
"packageLocation": "./.yarn/unplugged/@cbor-extract-cbor-extract-win32-x64-npm-2.1.1-b206bdfc73/node_modules/@cbor-extract/cbor-extract-win32-x64/",\
|
||||
"packageDependencies": [\
|
||||
["@cbor-extract/cbor-extract-win32-x64", "npm:2.1.1"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@colors/colors", [\
|
||||
["npm:1.5.0", {\
|
||||
"packageLocation": "./.yarn/cache/@colors-colors-npm-1.5.0-875af3a8b4-5e08870799.zip/node_modules/@colors/colors/",\
|
||||
@@ -1216,6 +1270,15 @@ const RAW_RUNTIME_STATE =
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@hexagon/base64", [\
|
||||
["npm:1.1.25", {\
|
||||
"packageLocation": "./.yarn/cache/@hexagon-base64-npm-1.1.25-44c8260698-0b42e9b676.zip/node_modules/@hexagon/base64/",\
|
||||
"packageDependencies": [\
|
||||
["@hexagon/base64", "npm:1.1.25"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@humanwhocodes/config-array", [\
|
||||
["npm:0.11.8", {\
|
||||
"packageLocation": "./.yarn/cache/@humanwhocodes-config-array-npm-0.11.8-7955bfecc2-010892ba3c.zip/node_modules/@humanwhocodes/config-array/",\
|
||||
@@ -1954,15 +2017,6 @@ const RAW_RUNTIME_STATE =
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@noble/ed25519", [\
|
||||
["npm:1.7.1", {\
|
||||
"packageLocation": "./.yarn/cache/@noble-ed25519-npm-1.7.1-177d9beb01-b1aa4b9264.zip/node_modules/@noble/ed25519/",\
|
||||
"packageDependencies": [\
|
||||
["@noble/ed25519", "npm:1.7.1"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@nodelib/fs.scandir", [\
|
||||
["npm:2.1.5", {\
|
||||
"packageLocation": "./.yarn/cache/@nodelib-fs.scandir-npm-2.1.5-89c67370dd-5f309a3b37.zip/node_modules/@nodelib/fs.scandir/",\
|
||||
@@ -2331,6 +2385,32 @@ const RAW_RUNTIME_STATE =
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@peculiar/asn1-ecc", [\
|
||||
["npm:2.3.4", {\
|
||||
"packageLocation": "./.yarn/cache/@peculiar-asn1-ecc-npm-2.3.4-d498135879-351f9e0a4f.zip/node_modules/@peculiar/asn1-ecc/",\
|
||||
"packageDependencies": [\
|
||||
["@peculiar/asn1-ecc", "npm:2.3.4"],\
|
||||
["@peculiar/asn1-schema", "npm:2.3.3"],\
|
||||
["@peculiar/asn1-x509", "npm:2.3.4"],\
|
||||
["asn1js", "npm:3.0.5"],\
|
||||
["tslib", "npm:2.4.1"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@peculiar/asn1-rsa", [\
|
||||
["npm:2.3.4", {\
|
||||
"packageLocation": "./.yarn/cache/@peculiar-asn1-rsa-npm-2.3.4-5015f8b5ba-89bcb894f4.zip/node_modules/@peculiar/asn1-rsa/",\
|
||||
"packageDependencies": [\
|
||||
["@peculiar/asn1-rsa", "npm:2.3.4"],\
|
||||
["@peculiar/asn1-schema", "npm:2.3.3"],\
|
||||
["@peculiar/asn1-x509", "npm:2.3.4"],\
|
||||
["asn1js", "npm:3.0.5"],\
|
||||
["tslib", "npm:2.4.1"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@peculiar/asn1-schema", [\
|
||||
["npm:2.3.3", {\
|
||||
"packageLocation": "./.yarn/cache/@peculiar-asn1-schema-npm-2.3.3-7c2b9469c4-f584f79d5a.zip/node_modules/@peculiar/asn1-schema/",\
|
||||
@@ -2531,30 +2611,39 @@ const RAW_RUNTIME_STATE =
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@simplewebauthn/server", [\
|
||||
["npm:6.2.2", {\
|
||||
"packageLocation": "./.yarn/cache/@simplewebauthn-server-npm-6.2.2-ca870b05c2-5ffb9b1c15.zip/node_modules/@simplewebauthn/server/",\
|
||||
["@simplewebauthn/iso-webcrypto", [\
|
||||
["npm:7.0.0", {\
|
||||
"packageLocation": "./.yarn/cache/@simplewebauthn-iso-webcrypto-npm-7.0.0-352babf4a0-c1644f9b68.zip/node_modules/@simplewebauthn/iso-webcrypto/",\
|
||||
"packageDependencies": [\
|
||||
["@simplewebauthn/server", "npm:6.2.2"],\
|
||||
["@noble/ed25519", "npm:1.7.1"],\
|
||||
["@simplewebauthn/iso-webcrypto", "npm:7.0.0"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@simplewebauthn/server", [\
|
||||
["npm:7.0.0", {\
|
||||
"packageLocation": "./.yarn/cache/@simplewebauthn-server-npm-7.0.0-e34589f137-836eb9fb97.zip/node_modules/@simplewebauthn/server/",\
|
||||
"packageDependencies": [\
|
||||
["@simplewebauthn/server", "npm:7.0.0"],\
|
||||
["@hexagon/base64", "npm:1.1.25"],\
|
||||
["@peculiar/asn1-android", "npm:2.3.3"],\
|
||||
["@peculiar/asn1-ecc", "npm:2.3.4"],\
|
||||
["@peculiar/asn1-rsa", "npm:2.3.4"],\
|
||||
["@peculiar/asn1-schema", "npm:2.3.3"],\
|
||||
["@peculiar/asn1-x509", "npm:2.3.4"],\
|
||||
["base64url", "npm:3.0.1"],\
|
||||
["cbor", "npm:5.2.0"],\
|
||||
["debug", "virtual:b86a9fb34323a98c6519528ed55faa0d9b44ca8879307c0b29aa384bde47ff59a7d0c9051b31246f14521dfb71ba3c5d6d0b35c29fffc17bf875aa6ad977d9e8#npm:4.3.4"],\
|
||||
["jsrsasign", "npm:10.6.1"],\
|
||||
["jwk-to-pem", "npm:2.0.5"],\
|
||||
["node-fetch", "virtual:25a5f5382d53dbf298bf7a1191760bc2e0a523a619eeb0e667b99a8649e8ad183f9e2e0b45f6fb831b92f4078b61622aa567cf79565f6aa5af9597e3c84864f6#npm:2.6.7"]\
|
||||
["@simplewebauthn/iso-webcrypto", "npm:7.0.0"],\
|
||||
["cbor-x", "npm:1.5.0"],\
|
||||
["cross-fetch", "npm:3.1.5"],\
|
||||
["debug", "virtual:b86a9fb34323a98c6519528ed55faa0d9b44ca8879307c0b29aa384bde47ff59a7d0c9051b31246f14521dfb71ba3c5d6d0b35c29fffc17bf875aa6ad977d9e8#npm:4.3.4"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@simplewebauthn/typescript-types", [\
|
||||
["npm:6.3.0-alpha.1", {\
|
||||
"packageLocation": "./.yarn/cache/@simplewebauthn-typescript-types-npm-6.3.0-alpha.1-629da05c10-5667c214e9.zip/node_modules/@simplewebauthn/typescript-types/",\
|
||||
["npm:7.0.0", {\
|
||||
"packageLocation": "./.yarn/cache/@simplewebauthn-typescript-types-npm-7.0.0-cc6ca20415-124238ea18.zip/node_modules/@simplewebauthn/typescript-types/",\
|
||||
"packageDependencies": [\
|
||||
["@simplewebauthn/typescript-types", "npm:6.3.0-alpha.1"]\
|
||||
["@simplewebauthn/typescript-types", "npm:7.0.0"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
@@ -2645,17 +2734,17 @@ const RAW_RUNTIME_STATE =
|
||||
}]\
|
||||
]],\
|
||||
["@standardnotes/api", [\
|
||||
["npm:1.24.5", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-api-npm-1.24.5-2a2f029be6-742a9d0936.zip/node_modules/@standardnotes/api/",\
|
||||
["npm:1.24.9", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-api-npm-1.24.9-b92f13a962-73bfd0fe3b.zip/node_modules/@standardnotes/api/",\
|
||||
"packageDependencies": [\
|
||||
["@standardnotes/api", "npm:1.24.5"],\
|
||||
["@standardnotes/api", "npm:1.24.9"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
|
||||
["@standardnotes/encryption", "npm:1.21.5"],\
|
||||
["@standardnotes/models", "npm:1.42.7"],\
|
||||
["@standardnotes/responses", "npm:1.13.4"],\
|
||||
["@standardnotes/encryption", "npm:1.21.9"],\
|
||||
["@standardnotes/models", "npm:1.42.11"],\
|
||||
["@standardnotes/responses", "npm:1.13.6"],\
|
||||
["@standardnotes/security", "workspace:packages/security"],\
|
||||
["@standardnotes/utils", "npm:1.16.2"],\
|
||||
["@standardnotes/utils", "npm:1.16.3"],\
|
||||
["reflect-metadata", "npm:0.1.13"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
@@ -2712,12 +2801,14 @@ const RAW_RUNTIME_STATE =
|
||||
"packageLocation": "./packages/auth/",\
|
||||
"packageDependencies": [\
|
||||
["@standardnotes/auth-server", "workspace:packages/auth"],\
|
||||
["@cbor-extract/cbor-extract-linux-arm64", "npm:2.1.1"],\
|
||||
["@cbor-extract/cbor-extract-linux-x64", "npm:2.1.1"],\
|
||||
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
|
||||
["@sentry/node", "npm:7.28.1"],\
|
||||
["@sentry/tracing", "npm:7.28.1"],\
|
||||
["@simplewebauthn/server", "npm:6.2.2"],\
|
||||
["@simplewebauthn/typescript-types", "npm:6.3.0-alpha.1"],\
|
||||
["@standardnotes/api", "npm:1.24.5"],\
|
||||
["@simplewebauthn/server", "npm:7.0.0"],\
|
||||
["@simplewebauthn/typescript-types", "npm:7.0.0"],\
|
||||
["@standardnotes/api", "npm:1.24.9"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
|
||||
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
|
||||
@@ -2863,15 +2954,15 @@ const RAW_RUNTIME_STATE =
|
||||
}]\
|
||||
]],\
|
||||
["@standardnotes/encryption", [\
|
||||
["npm:1.21.5", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-encryption-npm-1.21.5-3a48807445-652b8859ff.zip/node_modules/@standardnotes/encryption/",\
|
||||
["npm:1.21.9", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-encryption-npm-1.21.9-092bc2cb51-dc1336cc05.zip/node_modules/@standardnotes/encryption/",\
|
||||
"packageDependencies": [\
|
||||
["@standardnotes/encryption", "npm:1.21.5"],\
|
||||
["@standardnotes/encryption", "npm:1.21.9"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["@standardnotes/models", "npm:1.42.7"],\
|
||||
["@standardnotes/responses", "npm:1.13.4"],\
|
||||
["@standardnotes/models", "npm:1.42.11"],\
|
||||
["@standardnotes/responses", "npm:1.13.6"],\
|
||||
["@standardnotes/sncrypto-common", "npm:1.13.3"],\
|
||||
["@standardnotes/utils", "npm:1.16.2"],\
|
||||
["@standardnotes/utils", "npm:1.16.3"],\
|
||||
["reflect-metadata", "npm:0.1.13"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
@@ -2919,6 +3010,17 @@ const RAW_RUNTIME_STATE =
|
||||
["reflect-metadata", "npm:0.1.13"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}],\
|
||||
["npm:1.58.6", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-features-npm-1.58.6-7b1e198c39-98550416f1.zip/node_modules/@standardnotes/features/",\
|
||||
"packageDependencies": [\
|
||||
["@standardnotes/features", "npm:1.58.6"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
|
||||
["@standardnotes/security", "workspace:packages/security"],\
|
||||
["reflect-metadata", "npm:0.1.13"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@standardnotes/files-server", [\
|
||||
@@ -2976,11 +3078,15 @@ const RAW_RUNTIME_STATE =
|
||||
}]\
|
||||
]],\
|
||||
["@standardnotes/models", [\
|
||||
["npm:1.42.7", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-models-npm-1.42.7-6c0d7e2ac9-66271be0a9.zip/node_modules/@standardnotes/models/",\
|
||||
["npm:1.42.11", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-models-npm-1.42.11-7db16001ef-6ff3409f70.zip/node_modules/@standardnotes/models/",\
|
||||
"packageDependencies": [\
|
||||
["@standardnotes/models", "npm:1.42.7"],\
|
||||
["@standardnotes/utils", "npm:1.16.2"]\
|
||||
["@standardnotes/models", "npm:1.42.11"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["@standardnotes/features", "npm:1.58.6"],\
|
||||
["@standardnotes/responses", "npm:1.13.6"],\
|
||||
["@standardnotes/utils", "npm:1.16.3"],\
|
||||
["lodash", "npm:4.17.21"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
@@ -3011,6 +3117,17 @@ const RAW_RUNTIME_STATE =
|
||||
["reflect-metadata", "npm:0.1.13"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}],\
|
||||
["npm:1.13.6", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-responses-npm-1.13.6-5df25fe3dd-c57e3e1fa1.zip/node_modules/@standardnotes/responses/",\
|
||||
"packageDependencies": [\
|
||||
["@standardnotes/responses", "npm:1.13.6"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["@standardnotes/features", "npm:1.58.6"],\
|
||||
["@standardnotes/security", "workspace:packages/security"],\
|
||||
["reflect-metadata", "npm:0.1.13"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@standardnotes/revisions-server", [\
|
||||
@@ -3020,7 +3137,7 @@ const RAW_RUNTIME_STATE =
|
||||
["@standardnotes/revisions-server", "workspace:packages/revisions"],\
|
||||
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
|
||||
["@sentry/node", "npm:7.28.1"],\
|
||||
["@standardnotes/api", "npm:1.24.5"],\
|
||||
["@standardnotes/api", "npm:1.24.9"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
|
||||
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
|
||||
@@ -3129,7 +3246,7 @@ const RAW_RUNTIME_STATE =
|
||||
["@types/node", "npm:18.11.9"],\
|
||||
["@typescript-eslint/parser", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:5.40.1"],\
|
||||
["eslint", "npm:8.32.0"],\
|
||||
["eslint-config-prettier", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:8.5.0"],\
|
||||
["eslint-config-prettier", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:8.6.0"],\
|
||||
["ini", "npm:3.0.0"],\
|
||||
["newrelic", "npm:9.8.0"],\
|
||||
["npm-check-updates", "npm:16.0.1"],\
|
||||
@@ -3199,6 +3316,7 @@ const RAW_RUNTIME_STATE =
|
||||
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
|
||||
["@sentry/node", "npm:7.28.1"],\
|
||||
["@sentry/tracing", "npm:7.28.1"],\
|
||||
["@standardnotes/api", "npm:1.24.9"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
|
||||
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
|
||||
@@ -3278,6 +3396,17 @@ const RAW_RUNTIME_STATE =
|
||||
["reflect-metadata", "npm:0.1.13"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}],\
|
||||
["npm:1.16.3", {\
|
||||
"packageLocation": "./.yarn/cache/@standardnotes-utils-npm-1.16.3-87b47ad954-5c34beaafb.zip/node_modules/@standardnotes/utils/",\
|
||||
"packageDependencies": [\
|
||||
["@standardnotes/utils", "npm:1.16.3"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["dompurify", "npm:2.4.3"],\
|
||||
["lodash", "npm:4.17.21"],\
|
||||
["reflect-metadata", "npm:0.1.13"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@standardnotes/websockets-server", [\
|
||||
@@ -3287,7 +3416,7 @@ const RAW_RUNTIME_STATE =
|
||||
["@standardnotes/websockets-server", "workspace:packages/websockets"],\
|
||||
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
|
||||
["@sentry/node", "npm:7.28.1"],\
|
||||
["@standardnotes/api", "npm:1.24.5"],\
|
||||
["@standardnotes/api", "npm:1.24.9"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
|
||||
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
|
||||
@@ -3329,12 +3458,12 @@ const RAW_RUNTIME_STATE =
|
||||
["@standardnotes/workspace-server", "workspace:packages/workspace"],\
|
||||
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
|
||||
["@sentry/node", "npm:7.28.1"],\
|
||||
["@standardnotes/api", "npm:1.24.5"],\
|
||||
["@standardnotes/api", "npm:1.24.9"],\
|
||||
["@standardnotes/common", "workspace:packages/common"],\
|
||||
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
|
||||
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
|
||||
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
|
||||
["@standardnotes/models", "npm:1.42.7"],\
|
||||
["@standardnotes/models", "npm:1.42.11"],\
|
||||
["@standardnotes/security", "workspace:packages/security"],\
|
||||
["@standardnotes/time", "workspace:packages/time"],\
|
||||
["@types/cors", "npm:2.8.12"],\
|
||||
@@ -4733,19 +4862,6 @@ const RAW_RUNTIME_STATE =
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["asn1.js", [\
|
||||
["npm:5.4.1", {\
|
||||
"packageLocation": "./.yarn/cache/asn1.js-npm-5.4.1-37c7edbcb0-5c36f81388.zip/node_modules/asn1.js/",\
|
||||
"packageDependencies": [\
|
||||
["asn1.js", "npm:5.4.1"],\
|
||||
["bn.js", "npm:4.12.0"],\
|
||||
["inherits", "npm:2.0.4"],\
|
||||
["minimalistic-assert", "npm:1.0.1"],\
|
||||
["safer-buffer", "npm:2.1.2"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["asn1js", [\
|
||||
["npm:3.0.5", {\
|
||||
"packageLocation": "./.yarn/cache/asn1js-npm-3.0.5-cf5558af33-d0bc57da97.zip/node_modules/asn1js/",\
|
||||
@@ -4971,15 +5087,6 @@ const RAW_RUNTIME_STATE =
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["base64url", [\
|
||||
["npm:3.0.1", {\
|
||||
"packageLocation": "./.yarn/cache/base64url-npm-3.0.1-4c171c4917-72e1401ffe.zip/node_modules/base64url/",\
|
||||
"packageDependencies": [\
|
||||
["base64url", "npm:3.0.1"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["bcryptjs", [\
|
||||
["npm:2.4.3", {\
|
||||
"packageLocation": "./.yarn/cache/bcryptjs-npm-2.4.3-32de4957eb-bf6a43e9c4.zip/node_modules/bcryptjs/",\
|
||||
@@ -4998,15 +5105,6 @@ const RAW_RUNTIME_STATE =
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["bignumber.js", [\
|
||||
["npm:9.1.1", {\
|
||||
"packageLocation": "./.yarn/cache/bignumber.js-npm-9.1.1-5929e8d8dc-e44d008049.zip/node_modules/bignumber.js/",\
|
||||
"packageDependencies": [\
|
||||
["bignumber.js", "npm:9.1.1"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["binary-extensions", [\
|
||||
["npm:2.2.0", {\
|
||||
"packageLocation": "./.yarn/cache/binary-extensions-npm-2.2.0-180c33fec7-16cf7c0cfd.zip/node_modules/binary-extensions/",\
|
||||
@@ -5028,15 +5126,6 @@ const RAW_RUNTIME_STATE =
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["bn.js", [\
|
||||
["npm:4.12.0", {\
|
||||
"packageLocation": "./.yarn/cache/bn.js-npm-4.12.0-3ec6c884f6-bfb4590775.zip/node_modules/bn.js/",\
|
||||
"packageDependencies": [\
|
||||
["bn.js", "npm:4.12.0"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["body-parser", [\
|
||||
["npm:1.20.1", {\
|
||||
"packageLocation": "./.yarn/cache/body-parser-npm-1.20.1-759fd14db9-33f202c9d5.zip/node_modules/body-parser/",\
|
||||
@@ -5104,15 +5193,6 @@ const RAW_RUNTIME_STATE =
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["brorand", [\
|
||||
["npm:1.1.0", {\
|
||||
"packageLocation": "./.yarn/cache/brorand-npm-1.1.0-ea86634c4b-f736e127fb.zip/node_modules/brorand/",\
|
||||
"packageDependencies": [\
|
||||
["brorand", "npm:1.1.0"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["browserslist", [\
|
||||
["npm:4.21.1", {\
|
||||
"packageLocation": "./.yarn/cache/browserslist-npm-4.21.1-930e90b93a-617d624493.zip/node_modules/browserslist/",\
|
||||
@@ -5348,13 +5428,29 @@ const RAW_RUNTIME_STATE =
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["cbor", [\
|
||||
["npm:5.2.0", {\
|
||||
"packageLocation": "./.yarn/cache/cbor-npm-5.2.0-4f6440587f-d60986b9d0.zip/node_modules/cbor/",\
|
||||
["cbor-extract", [\
|
||||
["npm:2.1.1", {\
|
||||
"packageLocation": "./.yarn/unplugged/cbor-extract-npm-2.1.1-bcad1459e1/node_modules/cbor-extract/",\
|
||||
"packageDependencies": [\
|
||||
["cbor", "npm:5.2.0"],\
|
||||
["bignumber.js", "npm:9.1.1"],\
|
||||
["nofilter", "npm:1.0.4"]\
|
||||
["cbor-extract", "npm:2.1.1"],\
|
||||
["@cbor-extract/cbor-extract-darwin-arm64", "npm:2.1.1"],\
|
||||
["@cbor-extract/cbor-extract-darwin-x64", "npm:2.1.1"],\
|
||||
["@cbor-extract/cbor-extract-linux-arm", "npm:2.1.1"],\
|
||||
["@cbor-extract/cbor-extract-linux-arm64", "npm:2.1.1"],\
|
||||
["@cbor-extract/cbor-extract-linux-x64", "npm:2.1.1"],\
|
||||
["@cbor-extract/cbor-extract-win32-x64", "npm:2.1.1"],\
|
||||
["node-gyp", "npm:9.0.0"],\
|
||||
["node-gyp-build-optional-packages", "npm:5.0.3"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["cbor-x", [\
|
||||
["npm:1.5.0", {\
|
||||
"packageLocation": "./.yarn/cache/cbor-x-npm-1.5.0-9baf767c60-c9de4515b0.zip/node_modules/cbor-x/",\
|
||||
"packageDependencies": [\
|
||||
["cbor-x", "npm:1.5.0"],\
|
||||
["cbor-extract", "npm:2.1.1"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
@@ -6042,6 +6138,16 @@ const RAW_RUNTIME_STATE =
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["cross-fetch", [\
|
||||
["npm:3.1.5", {\
|
||||
"packageLocation": "./.yarn/cache/cross-fetch-npm-3.1.5-e414995db9-83fa7b1318.zip/node_modules/cross-fetch/",\
|
||||
"packageDependencies": [\
|
||||
["cross-fetch", "npm:3.1.5"],\
|
||||
["node-fetch", "virtual:25a5f5382d53dbf298bf7a1191760bc2e0a523a619eeb0e667b99a8649e8ad183f9e2e0b45f6fb831b92f4078b61622aa567cf79565f6aa5af9597e3c84864f6#npm:2.6.7"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["cross-spawn", [\
|
||||
["npm:7.0.3", {\
|
||||
"packageLocation": "./.yarn/cache/cross-spawn-npm-7.0.3-e4ff3e65b3-37ec685f91.zip/node_modules/cross-spawn/",\
|
||||
@@ -6483,22 +6589,6 @@ const RAW_RUNTIME_STATE =
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["elliptic", [\
|
||||
["npm:6.5.4", {\
|
||||
"packageLocation": "./.yarn/cache/elliptic-npm-6.5.4-0ca8204a86-4453b008cf.zip/node_modules/elliptic/",\
|
||||
"packageDependencies": [\
|
||||
["elliptic", "npm:6.5.4"],\
|
||||
["bn.js", "npm:4.12.0"],\
|
||||
["brorand", "npm:1.1.0"],\
|
||||
["hash.js", "npm:1.1.7"],\
|
||||
["hmac-drbg", "npm:1.0.1"],\
|
||||
["inherits", "npm:2.0.4"],\
|
||||
["minimalistic-assert", "npm:1.0.1"],\
|
||||
["minimalistic-crypto-utils", "npm:1.0.1"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["emittery", [\
|
||||
["npm:0.10.2", {\
|
||||
"packageLocation": "./.yarn/cache/emittery-npm-0.10.2-aac10498b5-c55b286714.zip/node_modules/emittery/",\
|
||||
@@ -6761,10 +6851,17 @@ const RAW_RUNTIME_STATE =
|
||||
],\
|
||||
"linkType": "SOFT"\
|
||||
}],\
|
||||
["virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:8.5.0", {\
|
||||
"packageLocation": "./.yarn/__virtual__/eslint-config-prettier-virtual-d5f61497f8/0/cache/eslint-config-prettier-npm-8.5.0-a1dd58b6d8-fb61fae9c1.zip/node_modules/eslint-config-prettier/",\
|
||||
["npm:8.6.0", {\
|
||||
"packageLocation": "./.yarn/cache/eslint-config-prettier-npm-8.6.0-00192c9409-2aeb302e53.zip/node_modules/eslint-config-prettier/",\
|
||||
"packageDependencies": [\
|
||||
["eslint-config-prettier", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:8.5.0"],\
|
||||
["eslint-config-prettier", "npm:8.6.0"]\
|
||||
],\
|
||||
"linkType": "SOFT"\
|
||||
}],\
|
||||
["virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:8.6.0", {\
|
||||
"packageLocation": "./.yarn/__virtual__/eslint-config-prettier-virtual-9308b15a23/0/cache/eslint-config-prettier-npm-8.6.0-00192c9409-2aeb302e53.zip/node_modules/eslint-config-prettier/",\
|
||||
"packageDependencies": [\
|
||||
["eslint-config-prettier", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:8.6.0"],\
|
||||
["@types/eslint", null],\
|
||||
["eslint", "npm:8.32.0"]\
|
||||
],\
|
||||
@@ -7953,17 +8050,6 @@ const RAW_RUNTIME_STATE =
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["hash.js", [\
|
||||
["npm:1.1.7", {\
|
||||
"packageLocation": "./.yarn/cache/hash.js-npm-1.1.7-f1ad187358-e4266370d1.zip/node_modules/hash.js/",\
|
||||
"packageDependencies": [\
|
||||
["hash.js", "npm:1.1.7"],\
|
||||
["inherits", "npm:2.0.4"],\
|
||||
["minimalistic-assert", "npm:1.0.1"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["helmet", [\
|
||||
["npm:6.0.0", {\
|
||||
"packageLocation": "./.yarn/cache/helmet-npm-6.0.0-2285459f57-73b6ba802d.zip/node_modules/helmet/",\
|
||||
@@ -7982,18 +8068,6 @@ const RAW_RUNTIME_STATE =
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["hmac-drbg", [\
|
||||
["npm:1.0.1", {\
|
||||
"packageLocation": "./.yarn/cache/hmac-drbg-npm-1.0.1-3499ad31cd-4e88d58ffc.zip/node_modules/hmac-drbg/",\
|
||||
"packageDependencies": [\
|
||||
["hmac-drbg", "npm:1.0.1"],\
|
||||
["hash.js", "npm:1.1.7"],\
|
||||
["minimalistic-assert", "npm:1.0.1"],\
|
||||
["minimalistic-crypto-utils", "npm:1.0.1"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["hosted-git-info", [\
|
||||
["npm:2.8.9", {\
|
||||
"packageLocation": "./.yarn/cache/hosted-git-info-npm-2.8.9-62c44fa93f-c24da52f98.zip/node_modules/hosted-git-info/",\
|
||||
@@ -9586,15 +9660,6 @@ const RAW_RUNTIME_STATE =
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["jsrsasign", [\
|
||||
["npm:10.6.1", {\
|
||||
"packageLocation": "./.yarn/cache/jsrsasign-npm-10.6.1-a8fa295369-e8e9c1b24f.zip/node_modules/jsrsasign/",\
|
||||
"packageDependencies": [\
|
||||
["jsrsasign", "npm:10.6.1"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["jwa", [\
|
||||
["npm:1.4.1", {\
|
||||
"packageLocation": "./.yarn/cache/jwa-npm-1.4.1-4f19d6572c-0cc3e68b68.zip/node_modules/jwa/",\
|
||||
@@ -9607,18 +9672,6 @@ const RAW_RUNTIME_STATE =
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["jwk-to-pem", [\
|
||||
["npm:2.0.5", {\
|
||||
"packageLocation": "./.yarn/cache/jwk-to-pem-npm-2.0.5-aff7d9f125-fced3a75b0.zip/node_modules/jwk-to-pem/",\
|
||||
"packageDependencies": [\
|
||||
["jwk-to-pem", "npm:2.0.5"],\
|
||||
["asn1.js", "npm:5.4.1"],\
|
||||
["elliptic", "npm:6.5.4"],\
|
||||
["safe-buffer", "npm:5.2.1"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["jws", [\
|
||||
["npm:3.2.2", {\
|
||||
"packageLocation": "./.yarn/cache/jws-npm-3.2.2-c1ae59c7af-347ed7c334.zip/node_modules/jws/",\
|
||||
@@ -10174,24 +10227,6 @@ const RAW_RUNTIME_STATE =
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["minimalistic-assert", [\
|
||||
["npm:1.0.1", {\
|
||||
"packageLocation": "./.yarn/cache/minimalistic-assert-npm-1.0.1-dc8bb23d29-e2310081d8.zip/node_modules/minimalistic-assert/",\
|
||||
"packageDependencies": [\
|
||||
["minimalistic-assert", "npm:1.0.1"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["minimalistic-crypto-utils", [\
|
||||
["npm:1.0.1", {\
|
||||
"packageLocation": "./.yarn/cache/minimalistic-crypto-utils-npm-1.0.1-e66b10822e-7d909decd2.zip/node_modules/minimalistic-crypto-utils/",\
|
||||
"packageDependencies": [\
|
||||
["minimalistic-crypto-utils", "npm:1.0.1"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["minimatch", [\
|
||||
["npm:3.1.2", {\
|
||||
"packageLocation": "./.yarn/cache/minimatch-npm-3.1.2-9405269906-97f5615ee8.zip/node_modules/minimatch/",\
|
||||
@@ -10559,6 +10594,15 @@ const RAW_RUNTIME_STATE =
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["node-gyp-build-optional-packages", [\
|
||||
["npm:5.0.3", {\
|
||||
"packageLocation": "./.yarn/cache/node-gyp-build-optional-packages-npm-5.0.3-50b9c76481-18e2444d34.zip/node_modules/node-gyp-build-optional-packages/",\
|
||||
"packageDependencies": [\
|
||||
["node-gyp-build-optional-packages", "npm:5.0.3"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["node-int64", [\
|
||||
["npm:0.4.0", {\
|
||||
"packageLocation": "./.yarn/cache/node-int64-npm-0.4.0-0dc04ec3b2-5333c7f5b1.zip/node_modules/node-int64/",\
|
||||
@@ -10596,15 +10640,6 @@ const RAW_RUNTIME_STATE =
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["nofilter", [\
|
||||
["npm:1.0.4", {\
|
||||
"packageLocation": "./.yarn/cache/nofilter-npm-1.0.4-1cbdc6c03a-9a26874e7d.zip/node_modules/nofilter/",\
|
||||
"packageDependencies": [\
|
||||
["nofilter", "npm:1.0.4"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["nopt", [\
|
||||
["npm:1.0.10", {\
|
||||
"packageLocation": "./.yarn/cache/nopt-npm-1.0.10-f3db192976-efa5a9c2c1.zip/node_modules/nopt/",\
|
||||
|
||||
BIN
.yarn/cache/@cbor-extract-cbor-extract-darwin-x64-npm-2.1.1-9c0e0a67cc-9.zip
vendored
Normal file
BIN
.yarn/cache/@cbor-extract-cbor-extract-darwin-x64-npm-2.1.1-9c0e0a67cc-9.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@cbor-extract-cbor-extract-linux-arm64-npm-2.1.1-23a641c278-8de27a1ba1.zip
vendored
Normal file
BIN
.yarn/cache/@cbor-extract-cbor-extract-linux-arm64-npm-2.1.1-23a641c278-8de27a1ba1.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@cbor-extract-cbor-extract-linux-x64-npm-2.1.1-4471164400-cf4577e652.zip
vendored
Normal file
BIN
.yarn/cache/@cbor-extract-cbor-extract-linux-x64-npm-2.1.1-4471164400-cf4577e652.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@hexagon-base64-npm-1.1.25-44c8260698-0b42e9b676.zip
vendored
Normal file
BIN
.yarn/cache/@hexagon-base64-npm-1.1.25-44c8260698-0b42e9b676.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@peculiar-asn1-ecc-npm-2.3.4-d498135879-351f9e0a4f.zip
vendored
Normal file
BIN
.yarn/cache/@peculiar-asn1-ecc-npm-2.3.4-d498135879-351f9e0a4f.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@peculiar-asn1-rsa-npm-2.3.4-5015f8b5ba-89bcb894f4.zip
vendored
Normal file
BIN
.yarn/cache/@peculiar-asn1-rsa-npm-2.3.4-5015f8b5ba-89bcb894f4.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@simplewebauthn-iso-webcrypto-npm-7.0.0-352babf4a0-c1644f9b68.zip
vendored
Normal file
BIN
.yarn/cache/@simplewebauthn-iso-webcrypto-npm-7.0.0-352babf4a0-c1644f9b68.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@simplewebauthn-server-npm-7.0.0-e34589f137-836eb9fb97.zip
vendored
Normal file
BIN
.yarn/cache/@simplewebauthn-server-npm-7.0.0-e34589f137-836eb9fb97.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@simplewebauthn-typescript-types-npm-7.0.0-cc6ca20415-124238ea18.zip
vendored
Normal file
BIN
.yarn/cache/@simplewebauthn-typescript-types-npm-7.0.0-cc6ca20415-124238ea18.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@standardnotes-features-npm-1.58.6-7b1e198c39-98550416f1.zip
vendored
Normal file
BIN
.yarn/cache/@standardnotes-features-npm-1.58.6-7b1e198c39-98550416f1.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@standardnotes-responses-npm-1.13.6-5df25fe3dd-c57e3e1fa1.zip
vendored
Normal file
BIN
.yarn/cache/@standardnotes-responses-npm-1.13.6-5df25fe3dd-c57e3e1fa1.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@standardnotes-utils-npm-1.16.3-87b47ad954-5c34beaafb.zip
vendored
Normal file
BIN
.yarn/cache/@standardnotes-utils-npm-1.16.3-87b47ad954-5c34beaafb.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/cbor-extract-npm-2.1.1-bcad1459e1-b73b9084a3.zip
vendored
Normal file
BIN
.yarn/cache/cbor-extract-npm-2.1.1-bcad1459e1-b73b9084a3.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/cbor-npm-5.2.0-4f6440587f-d60986b9d0.zip
vendored
BIN
.yarn/cache/cbor-npm-5.2.0-4f6440587f-d60986b9d0.zip
vendored
Binary file not shown.
BIN
.yarn/cache/cbor-x-npm-1.5.0-9baf767c60-c9de4515b0.zip
vendored
Normal file
BIN
.yarn/cache/cbor-x-npm-1.5.0-9baf767c60-c9de4515b0.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/cross-fetch-npm-3.1.5-e414995db9-83fa7b1318.zip
vendored
Normal file
BIN
.yarn/cache/cross-fetch-npm-3.1.5-e414995db9-83fa7b1318.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/eslint-config-prettier-npm-8.6.0-00192c9409-2aeb302e53.zip
vendored
Normal file
BIN
.yarn/cache/eslint-config-prettier-npm-8.6.0-00192c9409-2aeb302e53.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/node-gyp-build-optional-packages-npm-5.0.3-50b9c76481-18e2444d34.zip
vendored
Normal file
BIN
.yarn/cache/node-gyp-build-optional-packages-npm-5.0.3-50b9c76481-18e2444d34.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
0
.yarn/unplugged/@cbor-extract-cbor-extract-darwin-x64-npm-2.1.1-9c0e0a67cc/node_modules/@cbor-extract/cbor-extract-darwin-x64/.ready
generated
vendored
Normal file
0
.yarn/unplugged/@cbor-extract-cbor-extract-darwin-x64-npm-2.1.1-9c0e0a67cc/node_modules/@cbor-extract/cbor-extract-darwin-x64/.ready
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Platform specific binary for cbor-extract on darwin OS with x64 architecture
|
||||
BIN
.yarn/unplugged/@cbor-extract-cbor-extract-darwin-x64-npm-2.1.1-9c0e0a67cc/node_modules/@cbor-extract/cbor-extract-darwin-x64/node.abi108.glibc.node
generated
vendored
Executable file
BIN
.yarn/unplugged/@cbor-extract-cbor-extract-darwin-x64-npm-2.1.1-9c0e0a67cc/node_modules/@cbor-extract/cbor-extract-darwin-x64/node.abi108.glibc.node
generated
vendored
Executable file
Binary file not shown.
BIN
.yarn/unplugged/@cbor-extract-cbor-extract-darwin-x64-npm-2.1.1-9c0e0a67cc/node_modules/@cbor-extract/cbor-extract-darwin-x64/node.napi.glibc.node
generated
vendored
Executable file
BIN
.yarn/unplugged/@cbor-extract-cbor-extract-darwin-x64-npm-2.1.1-9c0e0a67cc/node_modules/@cbor-extract/cbor-extract-darwin-x64/node.napi.glibc.node
generated
vendored
Executable file
Binary file not shown.
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "@cbor-extract/cbor-extract-darwin-x64",
|
||||
"version": "2.1.1",
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"author": "Kris Zyp",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://github.com/kriszyp/cbor-extract"
|
||||
},
|
||||
"description": "Platform specific binary for cbor-extract on darwin OS with x64 architecture"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Platform specific binary for cbor-extract on linux OS with arm64 architecture
|
||||
BIN
.yarn/unplugged/@cbor-extract-cbor-extract-linux-arm64-npm-2.1.1-23a641c278/node_modules/@cbor-extract/cbor-extract-linux-arm64/node.abi108.glibc.node
generated
vendored
Executable file
BIN
.yarn/unplugged/@cbor-extract-cbor-extract-linux-arm64-npm-2.1.1-23a641c278/node_modules/@cbor-extract/cbor-extract-linux-arm64/node.abi108.glibc.node
generated
vendored
Executable file
Binary file not shown.
BIN
.yarn/unplugged/@cbor-extract-cbor-extract-linux-arm64-npm-2.1.1-23a641c278/node_modules/@cbor-extract/cbor-extract-linux-arm64/node.abi108.musl.node
generated
vendored
Executable file
BIN
.yarn/unplugged/@cbor-extract-cbor-extract-linux-arm64-npm-2.1.1-23a641c278/node_modules/@cbor-extract/cbor-extract-linux-arm64/node.abi108.musl.node
generated
vendored
Executable file
Binary file not shown.
BIN
.yarn/unplugged/@cbor-extract-cbor-extract-linux-arm64-npm-2.1.1-23a641c278/node_modules/@cbor-extract/cbor-extract-linux-arm64/node.napi.glibc.node
generated
vendored
Executable file
BIN
.yarn/unplugged/@cbor-extract-cbor-extract-linux-arm64-npm-2.1.1-23a641c278/node_modules/@cbor-extract/cbor-extract-linux-arm64/node.napi.glibc.node
generated
vendored
Executable file
Binary file not shown.
BIN
.yarn/unplugged/@cbor-extract-cbor-extract-linux-arm64-npm-2.1.1-23a641c278/node_modules/@cbor-extract/cbor-extract-linux-arm64/node.napi.musl.node
generated
vendored
Executable file
BIN
.yarn/unplugged/@cbor-extract-cbor-extract-linux-arm64-npm-2.1.1-23a641c278/node_modules/@cbor-extract/cbor-extract-linux-arm64/node.napi.musl.node
generated
vendored
Executable file
Binary file not shown.
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "@cbor-extract/cbor-extract-linux-arm64",
|
||||
"version": "2.1.1",
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"author": "Kris Zyp",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://github.com/kriszyp/cbor-extract"
|
||||
},
|
||||
"description": "Platform specific binary for cbor-extract on linux OS with arm64 architecture"
|
||||
}
|
||||
0
.yarn/unplugged/@cbor-extract-cbor-extract-linux-x64-npm-2.1.1-4471164400/node_modules/@cbor-extract/cbor-extract-linux-x64/.ready
generated
vendored
Normal file
0
.yarn/unplugged/@cbor-extract-cbor-extract-linux-x64-npm-2.1.1-4471164400/node_modules/@cbor-extract/cbor-extract-linux-x64/.ready
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Platform specific binary for cbor-extract on linux OS with x64 architecture
|
||||
0
.yarn/unplugged/@cbor-extract-cbor-extract-linux-x64-npm-2.1.1-4471164400/node_modules/@cbor-extract/cbor-extract-linux-x64/index.js
generated
vendored
Normal file
0
.yarn/unplugged/@cbor-extract-cbor-extract-linux-x64-npm-2.1.1-4471164400/node_modules/@cbor-extract/cbor-extract-linux-x64/index.js
generated
vendored
Normal file
BIN
.yarn/unplugged/@cbor-extract-cbor-extract-linux-x64-npm-2.1.1-4471164400/node_modules/@cbor-extract/cbor-extract-linux-x64/node.abi108.glibc.node
generated
vendored
Executable file
BIN
.yarn/unplugged/@cbor-extract-cbor-extract-linux-x64-npm-2.1.1-4471164400/node_modules/@cbor-extract/cbor-extract-linux-x64/node.abi108.glibc.node
generated
vendored
Executable file
Binary file not shown.
BIN
.yarn/unplugged/@cbor-extract-cbor-extract-linux-x64-npm-2.1.1-4471164400/node_modules/@cbor-extract/cbor-extract-linux-x64/node.abi108.musl.node
generated
vendored
Executable file
BIN
.yarn/unplugged/@cbor-extract-cbor-extract-linux-x64-npm-2.1.1-4471164400/node_modules/@cbor-extract/cbor-extract-linux-x64/node.abi108.musl.node
generated
vendored
Executable file
Binary file not shown.
BIN
.yarn/unplugged/@cbor-extract-cbor-extract-linux-x64-npm-2.1.1-4471164400/node_modules/@cbor-extract/cbor-extract-linux-x64/node.napi.glibc.node
generated
vendored
Executable file
BIN
.yarn/unplugged/@cbor-extract-cbor-extract-linux-x64-npm-2.1.1-4471164400/node_modules/@cbor-extract/cbor-extract-linux-x64/node.napi.glibc.node
generated
vendored
Executable file
Binary file not shown.
BIN
.yarn/unplugged/@cbor-extract-cbor-extract-linux-x64-npm-2.1.1-4471164400/node_modules/@cbor-extract/cbor-extract-linux-x64/node.napi.musl.node
generated
vendored
Executable file
BIN
.yarn/unplugged/@cbor-extract-cbor-extract-linux-x64-npm-2.1.1-4471164400/node_modules/@cbor-extract/cbor-extract-linux-x64/node.napi.musl.node
generated
vendored
Executable file
Binary file not shown.
17
.yarn/unplugged/@cbor-extract-cbor-extract-linux-x64-npm-2.1.1-4471164400/node_modules/@cbor-extract/cbor-extract-linux-x64/package.json
generated
vendored
Normal file
17
.yarn/unplugged/@cbor-extract-cbor-extract-linux-x64-npm-2.1.1-4471164400/node_modules/@cbor-extract/cbor-extract-linux-x64/package.json
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "@cbor-extract/cbor-extract-linux-x64",
|
||||
"version": "2.1.1",
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"author": "Kris Zyp",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://github.com/kriszyp/cbor-extract"
|
||||
},
|
||||
"description": "Platform specific binary for cbor-extract on linux OS with x64 architecture"
|
||||
}
|
||||
0
.yarn/unplugged/cbor-extract-npm-2.1.1-bcad1459e1/node_modules/cbor-extract/.ready
generated
vendored
Normal file
0
.yarn/unplugged/cbor-extract-npm-2.1.1-bcad1459e1/node_modules/cbor-extract/.ready
generated
vendored
Normal file
21
.yarn/unplugged/cbor-extract-npm-2.1.1-bcad1459e1/node_modules/cbor-extract/LICENSE
generated
vendored
Normal file
21
.yarn/unplugged/cbor-extract-npm-2.1.1-bcad1459e1/node_modules/cbor-extract/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Kris Zyp
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
5
.yarn/unplugged/cbor-extract-npm-2.1.1-bcad1459e1/node_modules/cbor-extract/README.md
generated
vendored
Normal file
5
.yarn/unplugged/cbor-extract-npm-2.1.1-bcad1459e1/node_modules/cbor-extract/README.md
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
## Summary
|
||||
This module is designed to do fast and efficient native/C-level extraction of strings from CBOR binary data. This works by calling `extractStrings(buffer, start, end)`, and it will extract strings by doing partial CBOR parsing, and scanning to find the string data in the range specified in the buffer. It will return an array of strings that it finds. When it finds strings that can be represented with latin-1/one-byte strings (and important V8 optimization), it will attempt return a continuous string of CBOR data that contains multiple sub-strings, so the decoder can slice off strings by offset. When a string contains non-latin characters, and must be represented as a two-byte string, this will always be returned as the string alone without combination with any other strings. The extractor will return an array of a maximum of 256 strings. The decoder can call the extractStrings again, with a new offset to continue extracting more strings as necessary.
|
||||
|
||||
## License
|
||||
MIT
|
||||
11
.yarn/unplugged/cbor-extract-npm-2.1.1-bcad1459e1/node_modules/cbor-extract/bin/download-prebuilds.js
generated
vendored
Normal file
11
.yarn/unplugged/cbor-extract-npm-2.1.1-bcad1459e1/node_modules/cbor-extract/bin/download-prebuilds.js
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const { dirname } = require('path');
|
||||
const { fileURLToPath } = require('url');
|
||||
const { exec } = require('child_process');
|
||||
|
||||
process.chdir(dirname(__dirname));
|
||||
exec('prebuildify-ci download', (error, stdout, stderr) => {
|
||||
console.error(stderr);
|
||||
console.log(stdout);
|
||||
});
|
||||
60
.yarn/unplugged/cbor-extract-npm-2.1.1-bcad1459e1/node_modules/cbor-extract/binding.gyp
generated
vendored
Normal file
60
.yarn/unplugged/cbor-extract-npm-2.1.1-bcad1459e1/node_modules/cbor-extract/binding.gyp
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"variables": {
|
||||
"os_linux_compiler%": "gcc",
|
||||
"enable_v8%": "true",
|
||||
"enable_pointer_compression%": "false",
|
||||
"build_v8_with_gn": "false"
|
||||
},
|
||||
"conditions": [
|
||||
['OS=="win"', {
|
||||
"variables": {
|
||||
"enable_v8%": "<!(echo %ENABLE_V8_FUNCTIONS%)",
|
||||
}
|
||||
}],
|
||||
['OS!="win"', {
|
||||
"variables": {
|
||||
"enable_v8%": "<!(echo $ENABLE_V8_FUNCTIONS)",
|
||||
}
|
||||
}]
|
||||
],
|
||||
"targets": [
|
||||
{
|
||||
"target_name": "extract",
|
||||
"sources": [
|
||||
"src/extract.cpp",
|
||||
],
|
||||
"defines": [ "NAPI_DISABLE_CPP_EXCEPTIONS" ],
|
||||
"conditions": [
|
||||
["OS=='linux'", {
|
||||
"variables": {
|
||||
"gcc_version" : "<!(<(os_linux_compiler) -dumpversion | cut -d '.' -f 1)",
|
||||
},
|
||||
"cflags_cc": [
|
||||
"-fPIC",
|
||||
"-fvisibility=hidden",
|
||||
"-fvisibility-inlines-hidden",
|
||||
],
|
||||
"conditions": [
|
||||
["gcc_version>=7", {
|
||||
"cflags": [
|
||||
"-Wimplicit-fallthrough=2",
|
||||
],
|
||||
}],
|
||||
],
|
||||
"ldflags": [
|
||||
"-fPIC",
|
||||
"-fvisibility=hidden"
|
||||
],
|
||||
"cflags": [
|
||||
"-fPIC",
|
||||
"-fvisibility=hidden",
|
||||
"-O3"
|
||||
],
|
||||
}],
|
||||
["enable_v8!='false'", {
|
||||
"defines": ["ENABLE_V8_API=1"]
|
||||
}],
|
||||
],
|
||||
}
|
||||
]
|
||||
}
|
||||
1
.yarn/unplugged/cbor-extract-npm-2.1.1-bcad1459e1/node_modules/cbor-extract/index.js
generated
vendored
Normal file
1
.yarn/unplugged/cbor-extract-npm-2.1.1-bcad1459e1/node_modules/cbor-extract/index.js
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require('node-gyp-build-optional-packages')(__dirname)
|
||||
48
.yarn/unplugged/cbor-extract-npm-2.1.1-bcad1459e1/node_modules/cbor-extract/package.json
generated
vendored
Normal file
48
.yarn/unplugged/cbor-extract-npm-2.1.1-bcad1459e1/node_modules/cbor-extract/package.json
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "cbor-extract",
|
||||
"author": "Kris Zyp",
|
||||
"version": "2.1.1",
|
||||
"description": "Node addon for string extraction for cbor-x",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://github.com/kriszyp/cbor-extract"
|
||||
},
|
||||
"scripts": {
|
||||
"install": "node-gyp-build-optional-packages",
|
||||
"recompile": "node-gyp rebuild",
|
||||
"before-publish": "prebuildify-ci download && node set-optional-deps.cjs",
|
||||
"prebuild": "prebuildify-platform-packages --target 18.12.0",
|
||||
"prebuild-win32": "prebuildify-platform-packages --target 18.12.0 && set ENABLE_V8_FUNCTIONS=false&& prebuildify-platform-packages --platform-packages --napi --target 18.12.0",
|
||||
"prebuild-libc": "prebuildify-platform-packages --tag-libc --target 18.12.0 && prebuildify-platform-packages --platform-packages --napi --tag-libc --target 16.14.2 && ENABLE_V8_FUNCTIONS=false prebuildify-platform-packages --platform-packages --napi --tag-libc --target 18.12.0",
|
||||
"prebuild-libc-alpine": "prebuildify-cross --image alpine --tag-libc --target 18.12.0",
|
||||
"publish-all": "cd prebuilds/win32-x64 && npm publish --access public && cd ../darwin-x64 && npm publish --access public && cd ../darwin-arm64 && npm publish --access public && cd ../linux-x64 && npm publish --access public && cd ../linux-arm64 && npm publish --access public && cd ../linux-arm && npm publish --access public && cd ../.. && npm publish --access public",
|
||||
"test": "node ./index.js"
|
||||
},
|
||||
"main": "./index.js",
|
||||
"gypfile": true,
|
||||
"dependencies": {
|
||||
"node-gyp-build-optional-packages": "5.0.3"
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
"/src",
|
||||
"/*.gyp",
|
||||
"/bin"
|
||||
],
|
||||
"bin": {
|
||||
"download-cbor-prebuilds": "./bin/download-prebuilds.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prebuildify-platform-packages": "5.0.2",
|
||||
"prebuildify-ci": "^1.0.5"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@cbor-extract/cbor-extract-darwin-arm64": "2.1.1",
|
||||
"@cbor-extract/cbor-extract-darwin-x64": "2.1.1",
|
||||
"@cbor-extract/cbor-extract-linux-arm": "2.1.1",
|
||||
"@cbor-extract/cbor-extract-linux-arm64": "2.1.1",
|
||||
"@cbor-extract/cbor-extract-linux-x64": "2.1.1",
|
||||
"@cbor-extract/cbor-extract-win32-x64": "2.1.1"
|
||||
}
|
||||
}
|
||||
198
.yarn/unplugged/cbor-extract-npm-2.1.1-bcad1459e1/node_modules/cbor-extract/src/extract.cpp
generated
vendored
Normal file
198
.yarn/unplugged/cbor-extract-npm-2.1.1-bcad1459e1/node_modules/cbor-extract/src/extract.cpp
generated
vendored
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
This is responsible for extracting the strings, in bulk, from a CBOR buffer. Creating strings from buffers can
|
||||
be one of the biggest performance bottlenecks of parsing, but creating an array of extracting strings all at once
|
||||
provides much better performance. This will parse and produce up to 256 strings at once .The JS parser can call this multiple
|
||||
times as necessary to get more strings. This must be partially capable of parsing CBOR so it can know where to
|
||||
find the string tokens and determine their position and length. All strings are decoded as UTF-8.
|
||||
*/
|
||||
#include <node_api.h>
|
||||
#if ENABLE_V8_API
|
||||
#include <v8.h>
|
||||
#endif
|
||||
|
||||
#ifndef thread_local
|
||||
#ifdef __GNUC__
|
||||
# define thread_local __thread
|
||||
#elif __STDC_VERSION__ >= 201112L
|
||||
# define thread_local _Thread_local
|
||||
#elif defined(_MSC_VER)
|
||||
# define thread_local __declspec(thread)
|
||||
#else
|
||||
# define thread_local
|
||||
#endif
|
||||
#endif
|
||||
|
||||
const int MAX_TARGET_SIZE = 255;
|
||||
napi_value unexpectedEnd(napi_env env) {
|
||||
napi_value returnValue;
|
||||
napi_get_undefined(env, &returnValue);
|
||||
napi_throw_type_error(env, NULL, "Unexpected end of buffer reading string");
|
||||
return returnValue;
|
||||
}
|
||||
class Extractor {
|
||||
public:
|
||||
napi_value target[MAX_TARGET_SIZE + 1]; // leave one for the queued string
|
||||
|
||||
uint8_t* source;
|
||||
int position = 0;
|
||||
int writePosition = 0;
|
||||
int stringStart = 0;
|
||||
int lastStringEnd = 0;
|
||||
|
||||
void readString(napi_env env, int length, bool allowStringBlocks) {
|
||||
int start = position;
|
||||
int end = position + length;
|
||||
if (allowStringBlocks) { // for larger strings, we don't bother to check every character for being latin, and just go right to creating a new string
|
||||
while(position < end) {
|
||||
if (source[position] < 0x80) // ensure we character is latin and can be decoded as one byte
|
||||
position++;
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (position < end) {
|
||||
// non-latin character
|
||||
if (lastStringEnd) {
|
||||
napi_value value;
|
||||
napi_create_string_latin1(env, (const char*) source + stringStart, lastStringEnd - stringStart, &value);
|
||||
target[writePosition++] = value;
|
||||
lastStringEnd = 0;
|
||||
}
|
||||
// use standard utf-8 conversion
|
||||
napi_value value;
|
||||
napi_create_string_utf8(env, (const char*) source + start, (int) length, &value);
|
||||
target[writePosition++] = value;
|
||||
position = end;
|
||||
return;
|
||||
}
|
||||
|
||||
if (lastStringEnd) {
|
||||
if (start - lastStringEnd > 40 || end - stringStart > 6000) {
|
||||
napi_value value;
|
||||
napi_create_string_latin1(env, (const char*) source + stringStart, lastStringEnd - stringStart, &value);
|
||||
target[writePosition++] = value;
|
||||
stringStart = start;
|
||||
}
|
||||
} else {
|
||||
stringStart = start;
|
||||
}
|
||||
lastStringEnd = end;
|
||||
}
|
||||
napi_value extractStrings(napi_env env, int startingPosition, int size, int firstStringSize, uint8_t* inputSource) {
|
||||
writePosition = 0;
|
||||
lastStringEnd = 0;
|
||||
position = startingPosition;
|
||||
source = inputSource;
|
||||
readString(env, firstStringSize, firstStringSize < 0x100);
|
||||
while (position < size) {
|
||||
uint8_t token = source[position++];
|
||||
uint8_t majorType = token >> 5;
|
||||
token = token & 0x1f;
|
||||
if (majorType == 2 || majorType == 3) {
|
||||
int length;
|
||||
switch (token) {
|
||||
case 0x18:
|
||||
if (position + 1 > size) {
|
||||
return unexpectedEnd(env);
|
||||
}
|
||||
length = source[position++];
|
||||
break;
|
||||
case 0x19:
|
||||
if (position + 2 > size) {
|
||||
return unexpectedEnd(env);
|
||||
}
|
||||
length = source[position++] << 8;
|
||||
length += source[position++];
|
||||
break;
|
||||
case 0x1a:
|
||||
if (position + 4 > size) {
|
||||
return unexpectedEnd(env);
|
||||
}
|
||||
length = source[position++] << 24;
|
||||
length += source[position++] << 16;
|
||||
length += source[position++] << 8;
|
||||
length += source[position++];
|
||||
break;
|
||||
case 0x1b:
|
||||
return unexpectedEnd(env);
|
||||
default:
|
||||
length = token;
|
||||
}
|
||||
if (majorType == 3) {
|
||||
// string
|
||||
if (length + position > size) {
|
||||
return unexpectedEnd(env);
|
||||
}
|
||||
readString(env, length, length < 0x100);
|
||||
if (writePosition >= MAX_TARGET_SIZE)
|
||||
break;
|
||||
} else { // binary data
|
||||
position += length;
|
||||
}
|
||||
|
||||
} else { // all other tokens
|
||||
switch (token) {
|
||||
case 0x18:
|
||||
position++;
|
||||
break;
|
||||
case 0x19:
|
||||
position += 2;
|
||||
break;
|
||||
case 0x1a:
|
||||
position += 4;
|
||||
break;
|
||||
case 0x1b:
|
||||
position += 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lastStringEnd) {
|
||||
napi_value value;
|
||||
napi_create_string_latin1(env, (const char*) source + stringStart, lastStringEnd - stringStart, &value);
|
||||
if (writePosition == 0) {
|
||||
return value;
|
||||
}
|
||||
target[writePosition++] = value;
|
||||
} else if (writePosition == 1) {
|
||||
return target[0];
|
||||
}
|
||||
napi_value array;
|
||||
#if ENABLE_V8_API
|
||||
v8::Local<v8::Array> v8Array = v8::Array::New(v8::Isolate::GetCurrent(), (v8::Local<v8::Value>*) target, writePosition);
|
||||
memcpy(&array, &v8Array, sizeof(array));
|
||||
#else
|
||||
napi_create_array_with_length(env, writePosition, &array);
|
||||
for (int i = 0; i < writePosition; i++) {
|
||||
napi_set_element(env, array, i, target[i]);
|
||||
}
|
||||
#endif
|
||||
return array;
|
||||
}
|
||||
};
|
||||
|
||||
static thread_local Extractor* extractor;
|
||||
|
||||
napi_value extractStrings(napi_env env, napi_callback_info info) {
|
||||
size_t argc = 4;
|
||||
napi_value args[4];
|
||||
napi_get_cb_info(env, info, &argc, args, NULL, NULL);
|
||||
uint32_t position;
|
||||
uint32_t size;
|
||||
uint32_t firstStringSize;
|
||||
napi_get_value_uint32(env, args[0], &position);
|
||||
napi_get_value_uint32(env, args[1], &size);
|
||||
napi_get_value_uint32(env, args[2], &firstStringSize);
|
||||
uint8_t* source;
|
||||
size_t buffer_size;
|
||||
napi_get_buffer_info(env, args[3], (void**) &source, &buffer_size);
|
||||
return extractor->extractStrings(env, position, size, firstStringSize, source);
|
||||
}
|
||||
#define EXPORT_NAPI_FUNCTION(name, func) { napi_property_descriptor desc = { name, 0, func, 0, 0, 0, (napi_property_attributes) (napi_writable | napi_configurable), 0 }; napi_define_properties(env, exports, 1, &desc); }
|
||||
|
||||
NAPI_MODULE_INIT() {
|
||||
extractor = new Extractor(); // create our thread-local extractor
|
||||
EXPORT_NAPI_FUNCTION("extractStrings", extractStrings);
|
||||
return exports;
|
||||
}
|
||||
@@ -52,7 +52,7 @@
|
||||
"@types/node": "^18.11.9",
|
||||
"@typescript-eslint/parser": "^5.40.1",
|
||||
"eslint": "^8.32.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-config-prettier": "^8.6.0",
|
||||
"ini": "^3.0.0",
|
||||
"npm-check-updates": "^16.0.1",
|
||||
"prettier": "^2.7.1",
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.19.13](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.19.12...@standardnotes/analytics@2.19.13) (2023-01-24)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.19.12](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.19.11...@standardnotes/analytics@2.19.12) (2023-01-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/analytics",
|
||||
"version": "2.19.12",
|
||||
"version": "2.19.13",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
|
||||
@@ -71,3 +71,4 @@ WEB_SOCKET_CONNECTION_TOKEN_SECRET=
|
||||
# (Optional) U2F Setup
|
||||
U2F_RELYING_PARTY_ID=
|
||||
U2F_RELYING_PARTY_NAME=
|
||||
U2F_EXPECTED_ORIGIN=
|
||||
|
||||
@@ -3,6 +3,66 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.87.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.87.0...@standardnotes/auth-server@1.87.1) (2023-01-24)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/auth-server
|
||||
|
||||
# [1.87.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.86.4...@standardnotes/auth-server@1.87.0) (2023-01-24)
|
||||
|
||||
### Features
|
||||
|
||||
* **auth:** add U2F to MFA verification ([6a5b669](https://github.com/standardnotes/server/commit/6a5b669ec47d3fd71fec3e362d66480d91c544d0))
|
||||
|
||||
## [1.86.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.86.3...@standardnotes/auth-server@1.86.4) (2023-01-24)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** add cleanup of authenticator devices upon sign in with recovery codes ([f1d3117](https://github.com/standardnotes/server/commit/f1d311751832a2abdbe124cede7f020b28cbcd9d))
|
||||
|
||||
## [1.86.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.86.2...@standardnotes/auth-server@1.86.3) (2023-01-24)
|
||||
|
||||
### Reverts
|
||||
|
||||
* Revert "fix(auth): fido options user verification as discouraged" ([a3b4aa3](https://github.com/standardnotes/server/commit/a3b4aa3b4a8eb39acf0d907e0f3ab6ffadd9d056))
|
||||
|
||||
## [1.86.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.86.1...@standardnotes/auth-server@1.86.2) (2023-01-24)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** fido options user verification as discouraged ([3d475cc](https://github.com/standardnotes/server/commit/3d475cc779f13c7da961a62f8f6abe69f76609fc))
|
||||
|
||||
## [1.86.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.86.0...@standardnotes/auth-server@1.86.1) (2023-01-24)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** buffer types on authenticator credentials ([f5296a9](https://github.com/standardnotes/server/commit/f5296a947eabe4d3db22e3afdf1690efa5670532))
|
||||
|
||||
# [1.86.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.85.0...@standardnotes/auth-server@1.86.0) (2023-01-23)
|
||||
|
||||
### Features
|
||||
|
||||
* **auth:** add configurable user verification requirement on u2f via env vars ([c38817c](https://github.com/standardnotes/server/commit/c38817c62e8109f1d5837dcda4a07f1b73976c72))
|
||||
|
||||
# [1.85.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.84.11...@standardnotes/auth-server@1.85.0) (2023-01-23)
|
||||
|
||||
### Features
|
||||
|
||||
* **auth:** add configuring u2f expect origin ([1797bc8](https://github.com/standardnotes/server/commit/1797bc81812be879b92c7d631085e76a36d37d45))
|
||||
|
||||
## [1.84.11](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.84.10...@standardnotes/auth-server@1.84.11) (2023-01-23)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/auth-server
|
||||
|
||||
## [1.84.10](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.84.9...@standardnotes/auth-server@1.84.10) (2023-01-23)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** upgrade simplewebauthn types ([52ce5f3](https://github.com/standardnotes/server/commit/52ce5f3a2f3790042793ac73ddad70cd1b578a6b))
|
||||
|
||||
## [1.84.9](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.84.8...@standardnotes/auth-server@1.84.9) (2023-01-23)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/auth-server
|
||||
|
||||
## [1.84.8](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.84.7...@standardnotes/auth-server@1.84.8) (2023-01-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/auth-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/auth-server",
|
||||
"version": "1.84.8",
|
||||
"version": "1.87.1",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
@@ -32,12 +32,13 @@
|
||||
"upgrade:snjs": "yarn ncu -u '@standardnotes/*'"
|
||||
},
|
||||
"dependencies": {
|
||||
"@cbor-extract/cbor-extract-linux-arm64": "^2.1.1",
|
||||
"@cbor-extract/cbor-extract-linux-x64": "^2.1.1",
|
||||
"@newrelic/winston-enricher": "^4.0.0",
|
||||
"@sentry/node": "^7.28.1",
|
||||
"@sentry/tracing": "^7.28.1",
|
||||
"@simplewebauthn/server": "^6.2.2",
|
||||
"@simplewebauthn/typescript-types": "^6.3.0-alpha.1",
|
||||
"@standardnotes/api": "^1.24.5",
|
||||
"@simplewebauthn/server": "^7.0.0",
|
||||
"@standardnotes/api": "^1.24.9",
|
||||
"@standardnotes/common": "workspace:*",
|
||||
"@standardnotes/domain-core": "workspace:^",
|
||||
"@standardnotes/domain-events": "workspace:*",
|
||||
@@ -71,6 +72,7 @@
|
||||
"winston": "^3.8.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@simplewebauthn/typescript-types": "^7.0.0",
|
||||
"@types/bcryptjs": "^2.4.2",
|
||||
"@types/cors": "^2.8.9",
|
||||
"@types/express": "^4.17.14",
|
||||
|
||||
@@ -462,6 +462,12 @@ export class ContainerConfigLoader {
|
||||
container
|
||||
.bind(TYPES.U2F_RELYING_PARTY_ID)
|
||||
.toConstantValue(env.get('U2F_RELYING_PARTY_ID', true) ?? 'standardnotes.com')
|
||||
container
|
||||
.bind(TYPES.U2F_EXPECTED_ORIGIN)
|
||||
.toConstantValue(env.get('U2F_EXPECTED_ORIGIN', true) ?? 'https://app.standardnotes.com')
|
||||
container
|
||||
.bind(TYPES.U2F_REQUIRE_USER_VERIFICATION)
|
||||
.toConstantValue(env.get('U2F_REQUIRE_USER_VERIFICATION', true) === 'true')
|
||||
// Services
|
||||
container.bind<UAParser>(TYPES.DeviceDetector).toConstantValue(new UAParser())
|
||||
container.bind<SessionService>(TYPES.SessionService).to(SessionService)
|
||||
@@ -575,6 +581,8 @@ export class ContainerConfigLoader {
|
||||
container.get(TYPES.AuthenticatorRepository),
|
||||
container.get(TYPES.AuthenticatorChallengeRepository),
|
||||
container.get(TYPES.U2F_RELYING_PARTY_ID),
|
||||
container.get(TYPES.U2F_EXPECTED_ORIGIN),
|
||||
container.get(TYPES.U2F_REQUIRE_USER_VERIFICATION),
|
||||
),
|
||||
)
|
||||
container
|
||||
@@ -592,6 +600,8 @@ export class ContainerConfigLoader {
|
||||
container.get(TYPES.AuthenticatorRepository),
|
||||
container.get(TYPES.AuthenticatorChallengeRepository),
|
||||
container.get(TYPES.U2F_RELYING_PARTY_ID),
|
||||
container.get(TYPES.U2F_EXPECTED_ORIGIN),
|
||||
container.get(TYPES.U2F_REQUIRE_USER_VERIFICATION),
|
||||
),
|
||||
)
|
||||
container
|
||||
@@ -655,6 +665,7 @@ export class ContainerConfigLoader {
|
||||
container.get(TYPES.IncreaseLoginAttempts),
|
||||
container.get(TYPES.ClearLoginAttempts),
|
||||
container.get(TYPES.DeleteSetting),
|
||||
container.get(TYPES.AuthenticatorRepository),
|
||||
),
|
||||
)
|
||||
container.bind<DeleteAccount>(TYPES.DeleteAccount).to(DeleteAccount)
|
||||
|
||||
@@ -96,6 +96,8 @@ const TYPES = {
|
||||
SESSION_TRACE_DAYS_TTL: Symbol.for('SESSION_TRACE_DAYS_TTL'),
|
||||
U2F_RELYING_PARTY_ID: Symbol.for('U2F_RELYING_PARTY_ID'),
|
||||
U2F_RELYING_PARTY_NAME: Symbol.for('U2F_RELYING_PARTY_NAME'),
|
||||
U2F_EXPECTED_ORIGIN: Symbol.for('U2F_EXPECTED_ORIGIN'),
|
||||
U2F_REQUIRE_USER_VERIFICATION: Symbol.for('U2F_REQUIRE_USER_VERIFICATION'),
|
||||
// use cases
|
||||
AuthenticateUser: Symbol.for('AuthenticateUser'),
|
||||
AuthenticateRequest: Symbol.for('AuthenticateRequest'),
|
||||
|
||||
@@ -93,7 +93,7 @@ export class AuthenticatorsController {
|
||||
const result = await this.verifyAuthenticatorRegistrationResponse.execute({
|
||||
userUuid: params.userUuid,
|
||||
name: params.name,
|
||||
registrationCredential: params.registrationCredential,
|
||||
attestationResponse: params.attestationResponse,
|
||||
})
|
||||
|
||||
if (result.isFailed()) {
|
||||
@@ -142,7 +142,7 @@ export class AuthenticatorsController {
|
||||
): Promise<VerifyAuthenticatorAuthenticationResponseResponse> {
|
||||
const result = await this.verifyAuthenticatorAuthenticationResponse.execute({
|
||||
userUuid: params.userUuid,
|
||||
authenticationCredential: params.authenticationCredential,
|
||||
authenticatorResponse: params.authenticatorResponse,
|
||||
})
|
||||
|
||||
if (result.isFailed()) {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { BaseHttpController, controller, httpPost, results } from 'inversify-exp
|
||||
import { Request, Response } from 'express'
|
||||
import TYPES from '../Bootstrap/Types'
|
||||
import { CreateListedAccount } from '../Domain/UseCase/CreateListedAccount/CreateListedAccount'
|
||||
import { ErrorTag } from '@standardnotes/common'
|
||||
import { ErrorTag } from '@standardnotes/api'
|
||||
|
||||
@controller('/listed')
|
||||
export class ListedController extends BaseHttpController {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ErrorTag } from '@standardnotes/common'
|
||||
import { ErrorTag } from '@standardnotes/api'
|
||||
import { Request, Response } from 'express'
|
||||
import { inject } from 'inversify'
|
||||
import {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ErrorTag } from '@standardnotes/common'
|
||||
import { ErrorTag } from '@standardnotes/api'
|
||||
import { Request, Response } from 'express'
|
||||
import { inject } from 'inversify'
|
||||
import {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { CrossServiceTokenData, TokenEncoderInterface } from '@standardnotes/security'
|
||||
import { ErrorTag } from '@standardnotes/common'
|
||||
import { ErrorTag } from '@standardnotes/api'
|
||||
import { SettingName } from '@standardnotes/settings'
|
||||
import { Request, Response } from 'express'
|
||||
import { inject } from 'inversify'
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Request, Response } from 'express'
|
||||
import { inject } from 'inversify'
|
||||
import { ErrorTag } from '@standardnotes/api'
|
||||
import {
|
||||
BaseHttpController,
|
||||
controller,
|
||||
@@ -18,7 +19,6 @@ import { GetUserSubscription } from '../Domain/UseCase/GetUserSubscription/GetUs
|
||||
import { ClearLoginAttempts } from '../Domain/UseCase/ClearLoginAttempts'
|
||||
import { IncreaseLoginAttempts } from '../Domain/UseCase/IncreaseLoginAttempts'
|
||||
import { ChangeCredentials } from '../Domain/UseCase/ChangeCredentials/ChangeCredentials'
|
||||
import { ErrorTag } from '@standardnotes/common'
|
||||
|
||||
@controller('/users')
|
||||
export class UsersController extends BaseHttpController {
|
||||
|
||||
@@ -8,12 +8,12 @@ import {
|
||||
results,
|
||||
} from 'inversify-express-utils'
|
||||
import { CreateValetTokenPayload } from '@standardnotes/responses'
|
||||
import { ErrorTag } from '@standardnotes/api'
|
||||
import { ValetTokenOperation } from '@standardnotes/security'
|
||||
import { Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
import TYPES from '../Bootstrap/Types'
|
||||
import { CreateValetToken } from '../Domain/UseCase/CreateValetToken/CreateValetToken'
|
||||
import { ErrorTag } from '@standardnotes/common'
|
||||
import { ValetTokenOperation } from '@standardnotes/security'
|
||||
import { Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
@controller('/valet-tokens', TYPES.ApiGatewayAuthMiddleware)
|
||||
export class ValetTokenController extends BaseHttpController {
|
||||
|
||||
@@ -3,8 +3,8 @@ import { Dates, Uuid } from '@standardnotes/domain-core'
|
||||
export interface AuthenticatorProps {
|
||||
name: string
|
||||
userUuid: Uuid
|
||||
credentialId: Buffer
|
||||
credentialPublicKey: Buffer
|
||||
credentialId: Uint8Array
|
||||
credentialPublicKey: Uint8Array
|
||||
counter: number
|
||||
credentialDeviceType: string
|
||||
credentialBackedUp: boolean
|
||||
|
||||
@@ -8,4 +8,5 @@ export interface AuthenticatorRepositoryInterface {
|
||||
findByUserUuidAndCredentialId(userUuid: Uuid, credentialId: Buffer): Promise<Authenticator | null>
|
||||
save(authenticator: Authenticator): Promise<void>
|
||||
remove(authenticator: Authenticator): Promise<void>
|
||||
removeByUserUuid(userUuid: Uuid): Promise<void>
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Result } from '@standardnotes/domain-core'
|
||||
|
||||
import { AuthResponse20200115 } from '../../Auth/AuthResponse20200115'
|
||||
import { AuthResponseFactory20200115 } from '../../Auth/AuthResponseFactory20200115'
|
||||
import { AuthenticatorRepositoryInterface } from '../../Authenticator/AuthenticatorRepositoryInterface'
|
||||
import { CrypterInterface } from '../../Encryption/CrypterInterface'
|
||||
import { Setting } from '../../Setting/Setting'
|
||||
import { SettingServiceInterface } from '../../Setting/SettingServiceInterface'
|
||||
@@ -24,6 +25,7 @@ describe('SignInWithRecoveryCodes', () => {
|
||||
let increaseLoginAttempts: IncreaseLoginAttempts
|
||||
let clearLoginAttempts: ClearLoginAttempts
|
||||
let deleteSetting: DeleteSetting
|
||||
let authenticatorRepository: AuthenticatorRepositoryInterface
|
||||
|
||||
const createUseCase = () =>
|
||||
new SignInWithRecoveryCodes(
|
||||
@@ -36,12 +38,13 @@ describe('SignInWithRecoveryCodes', () => {
|
||||
increaseLoginAttempts,
|
||||
clearLoginAttempts,
|
||||
deleteSetting,
|
||||
authenticatorRepository,
|
||||
)
|
||||
|
||||
beforeEach(() => {
|
||||
userRepository = {} as jest.Mocked<UserRepositoryInterface>
|
||||
userRepository.findOneByEmail = jest.fn().mockReturnValue({
|
||||
uuid: '1-2-3',
|
||||
uuid: '00000000-0000-0000-0000-000000000000',
|
||||
encryptedPassword: '$2a$11$K3g6XoTau8VmLJcai1bB0eD9/YvBSBRtBhMprJOaVZ0U3SgasZH3a',
|
||||
} as jest.Mocked<User>)
|
||||
|
||||
@@ -69,6 +72,9 @@ describe('SignInWithRecoveryCodes', () => {
|
||||
|
||||
deleteSetting = {} as jest.Mocked<DeleteSetting>
|
||||
deleteSetting.execute = jest.fn()
|
||||
|
||||
authenticatorRepository = {} as jest.Mocked<AuthenticatorRepositoryInterface>
|
||||
authenticatorRepository.removeByUserUuid = jest.fn()
|
||||
})
|
||||
|
||||
it('should return error if password is not provided', async () => {
|
||||
@@ -209,6 +215,24 @@ describe('SignInWithRecoveryCodes', () => {
|
||||
expect(result.getError()).toBe('Could not sign in with recovery codes: Oops')
|
||||
})
|
||||
|
||||
it('should return error if user has an invalid uuid', async () => {
|
||||
userRepository.findOneByEmail = jest.fn().mockReturnValue({
|
||||
uuid: '1-2-3',
|
||||
encryptedPassword: '$2a$11$K3g6XoTau8VmLJcai1bB0eD9/YvBSBRtBhMprJOaVZ0U3SgasZH3a',
|
||||
} as jest.Mocked<User>)
|
||||
|
||||
const result = await createUseCase().execute({
|
||||
userAgent: 'user-agent',
|
||||
username: 'test@test.te',
|
||||
password: 'qweqwe123123',
|
||||
codeVerifier: 'code-verifier',
|
||||
recoveryCodes: 'foo',
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe('Invalid user uuid')
|
||||
})
|
||||
|
||||
it('should return auth response', async () => {
|
||||
const result = await createUseCase().execute({
|
||||
userAgent: 'user-agent',
|
||||
@@ -220,6 +244,7 @@ describe('SignInWithRecoveryCodes', () => {
|
||||
|
||||
expect(clearLoginAttempts.execute).toHaveBeenCalled()
|
||||
expect(deleteSetting.execute).toHaveBeenCalled()
|
||||
expect(authenticatorRepository.removeByUserUuid).toHaveBeenCalled()
|
||||
expect(result.isFailed()).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as bcrypt from 'bcryptjs'
|
||||
import { Result, UseCaseInterface, Username, Validator } from '@standardnotes/domain-core'
|
||||
import { Result, UseCaseInterface, Username, Uuid, Validator } from '@standardnotes/domain-core'
|
||||
import { SettingName } from '@standardnotes/settings'
|
||||
import { ApiVersion } from '@standardnotes/api'
|
||||
|
||||
@@ -15,6 +15,7 @@ import { AuthResponseFactory20200115 } from '../../Auth/AuthResponseFactory20200
|
||||
import { IncreaseLoginAttempts } from '../IncreaseLoginAttempts'
|
||||
import { ClearLoginAttempts } from '../ClearLoginAttempts'
|
||||
import { DeleteSetting } from '../DeleteSetting/DeleteSetting'
|
||||
import { AuthenticatorRepositoryInterface } from '../../Authenticator/AuthenticatorRepositoryInterface'
|
||||
|
||||
export class SignInWithRecoveryCodes implements UseCaseInterface<AuthResponse20200115> {
|
||||
constructor(
|
||||
@@ -27,6 +28,7 @@ export class SignInWithRecoveryCodes implements UseCaseInterface<AuthResponse202
|
||||
private increaseLoginAttempts: IncreaseLoginAttempts,
|
||||
private clearLoginAttempts: ClearLoginAttempts,
|
||||
private deleteSetting: DeleteSetting,
|
||||
private authenticatorRepository: AuthenticatorRepositoryInterface,
|
||||
) {}
|
||||
|
||||
async execute(dto: SignInWithRecoveryCodesDTO): Promise<Result<AuthResponse20200115>> {
|
||||
@@ -65,6 +67,14 @@ export class SignInWithRecoveryCodes implements UseCaseInterface<AuthResponse202
|
||||
return Result.fail('Could not find user')
|
||||
}
|
||||
|
||||
const userUuidOrError = Uuid.create(user.uuid)
|
||||
if (userUuidOrError.isFailed()) {
|
||||
await this.increaseLoginAttempts.execute({ email: username.value })
|
||||
|
||||
return Result.fail('Invalid user uuid')
|
||||
}
|
||||
const userUuid = userUuidOrError.getValue()
|
||||
|
||||
const passwordMatches = await bcrypt.compare(dto.password, user.encryptedPassword)
|
||||
if (!passwordMatches) {
|
||||
await this.increaseLoginAttempts.execute({ email: username.value })
|
||||
@@ -110,6 +120,8 @@ export class SignInWithRecoveryCodes implements UseCaseInterface<AuthResponse202
|
||||
userUuid: user.uuid,
|
||||
})
|
||||
|
||||
await this.authenticatorRepository.removeByUserUuid(userUuid)
|
||||
|
||||
await this.clearLoginAttempts.execute({ email: username.value })
|
||||
|
||||
return Result.ok(authResponse as AuthResponse20200115)
|
||||
|
||||
@@ -17,6 +17,8 @@ describe('VerifyAuthenticatorAuthenticationResponse', () => {
|
||||
authenticatorRepository,
|
||||
authenticatorChallengeRepository,
|
||||
'standardnotes.com',
|
||||
'https://app.standardnotes.com',
|
||||
true,
|
||||
)
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -49,7 +51,7 @@ describe('VerifyAuthenticatorAuthenticationResponse', () => {
|
||||
|
||||
const result = await useCase.execute({
|
||||
userUuid: 'invalid',
|
||||
authenticationCredential: {
|
||||
authenticatorResponse: {
|
||||
authenticatorAttachment: 'platform',
|
||||
clientExtensionResults: {},
|
||||
id: 'id',
|
||||
@@ -77,7 +79,7 @@ describe('VerifyAuthenticatorAuthenticationResponse', () => {
|
||||
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
authenticationCredential: {
|
||||
authenticatorResponse: {
|
||||
authenticatorAttachment: 'platform',
|
||||
clientExtensionResults: {},
|
||||
id: 'id',
|
||||
@@ -105,7 +107,7 @@ describe('VerifyAuthenticatorAuthenticationResponse', () => {
|
||||
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
authenticationCredential: {
|
||||
authenticatorResponse: {
|
||||
authenticatorAttachment: 'platform',
|
||||
clientExtensionResults: {},
|
||||
id: 'id',
|
||||
@@ -134,7 +136,7 @@ describe('VerifyAuthenticatorAuthenticationResponse', () => {
|
||||
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
authenticationCredential: {
|
||||
authenticatorResponse: {
|
||||
authenticatorAttachment: 'platform',
|
||||
clientExtensionResults: {},
|
||||
id: 'id',
|
||||
@@ -167,7 +169,7 @@ describe('VerifyAuthenticatorAuthenticationResponse', () => {
|
||||
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
authenticationCredential: {
|
||||
authenticatorResponse: {
|
||||
authenticatorAttachment: 'platform',
|
||||
clientExtensionResults: {},
|
||||
id: 'id',
|
||||
@@ -203,7 +205,7 @@ describe('VerifyAuthenticatorAuthenticationResponse', () => {
|
||||
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
authenticationCredential: {
|
||||
authenticatorResponse: {
|
||||
authenticatorAttachment: 'platform',
|
||||
clientExtensionResults: {},
|
||||
id: 'id',
|
||||
|
||||
@@ -11,6 +11,8 @@ export class VerifyAuthenticatorAuthenticationResponse implements UseCaseInterfa
|
||||
private authenticatorRepository: AuthenticatorRepositoryInterface,
|
||||
private authenticatorChallengeRepository: AuthenticatorChallengeRepositoryInterface,
|
||||
private relyingPartyId: string,
|
||||
private expectedOrigin: string,
|
||||
private requireUserVerification: boolean,
|
||||
) {}
|
||||
|
||||
async execute(dto: VerifyAuthenticatorAuthenticationResponseDTO): Promise<Result<boolean>> {
|
||||
@@ -27,21 +29,22 @@ export class VerifyAuthenticatorAuthenticationResponse implements UseCaseInterfa
|
||||
|
||||
const authenticator = await this.authenticatorRepository.findByUserUuidAndCredentialId(
|
||||
userUuid,
|
||||
Buffer.from(dto.authenticationCredential.id as string),
|
||||
Buffer.from(dto.authenticatorResponse.id as string),
|
||||
)
|
||||
if (!authenticator) {
|
||||
return Result.fail(
|
||||
`Could not verify authenticator authentication response: authenticator ${dto.authenticationCredential.id} not found`,
|
||||
`Could not verify authenticator authentication response: authenticator ${dto.authenticatorResponse.id} not found`,
|
||||
)
|
||||
}
|
||||
|
||||
let verification: VerifiedAuthenticationResponse
|
||||
try {
|
||||
verification = await verifyAuthenticationResponse({
|
||||
credential: dto.authenticationCredential,
|
||||
response: dto.authenticatorResponse,
|
||||
expectedChallenge: authenticatorChallenge.props.challenge.toString(),
|
||||
expectedOrigin: `https://${this.relyingPartyId}`,
|
||||
expectedOrigin: this.expectedOrigin,
|
||||
expectedRPID: this.relyingPartyId,
|
||||
requireUserVerification: this.requireUserVerification,
|
||||
authenticator: {
|
||||
counter: authenticator.props.counter,
|
||||
credentialID: authenticator.props.credentialId,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export interface VerifyAuthenticatorAuthenticationResponseDTO {
|
||||
userUuid: string
|
||||
authenticationCredential: Record<string, unknown>
|
||||
authenticatorResponse: Record<string, unknown>
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ describe('VerifyAuthenticatorRegistrationResponse', () => {
|
||||
authenticatorRepository,
|
||||
authenticatorChallengeRepository,
|
||||
'standardnotes.com',
|
||||
'https://app.standardnotes.com',
|
||||
true,
|
||||
)
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -37,7 +39,7 @@ describe('VerifyAuthenticatorRegistrationResponse', () => {
|
||||
const result = await useCase.execute({
|
||||
userUuid: 'invalid',
|
||||
name: 'name',
|
||||
registrationCredential: {
|
||||
attestationResponse: {
|
||||
id: Buffer.from('id'),
|
||||
rawId: Buffer.from('rawId'),
|
||||
response: {
|
||||
@@ -60,7 +62,7 @@ describe('VerifyAuthenticatorRegistrationResponse', () => {
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
name: '',
|
||||
registrationCredential: {
|
||||
attestationResponse: {
|
||||
id: Buffer.from('id'),
|
||||
rawId: Buffer.from('rawId'),
|
||||
response: {
|
||||
@@ -83,7 +85,7 @@ describe('VerifyAuthenticatorRegistrationResponse', () => {
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
name: 'name',
|
||||
registrationCredential: {
|
||||
attestationResponse: {
|
||||
id: Buffer.from('id'),
|
||||
rawId: Buffer.from('rawId'),
|
||||
response: {
|
||||
@@ -115,8 +117,8 @@ describe('VerifyAuthenticatorRegistrationResponse', () => {
|
||||
counter: 1,
|
||||
credentialBackedUp: true,
|
||||
credentialDeviceType: 'singleDevice',
|
||||
credentialID: Buffer.from('test'),
|
||||
credentialPublicKey: Buffer.from('test'),
|
||||
credentialID: Uint8Array.from([1, 2, 3]),
|
||||
credentialPublicKey: Uint8Array.from([1, 2, 3]),
|
||||
},
|
||||
} as jest.Mocked<VerifiedRegistrationResponse>)
|
||||
})
|
||||
@@ -124,7 +126,7 @@ describe('VerifyAuthenticatorRegistrationResponse', () => {
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
name: 'name',
|
||||
registrationCredential: {
|
||||
attestationResponse: {
|
||||
id: Buffer.from('id'),
|
||||
rawId: Buffer.from('rawId'),
|
||||
response: {
|
||||
@@ -158,7 +160,7 @@ describe('VerifyAuthenticatorRegistrationResponse', () => {
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
name: 'name',
|
||||
registrationCredential: {
|
||||
attestationResponse: {
|
||||
id: Buffer.from('id'),
|
||||
rawId: Buffer.from('rawId'),
|
||||
response: {
|
||||
@@ -194,7 +196,7 @@ describe('VerifyAuthenticatorRegistrationResponse', () => {
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
name: 'name',
|
||||
registrationCredential: {
|
||||
attestationResponse: {
|
||||
id: Buffer.from('id'),
|
||||
rawId: Buffer.from('rawId'),
|
||||
response: {
|
||||
@@ -230,8 +232,8 @@ describe('VerifyAuthenticatorRegistrationResponse', () => {
|
||||
counter: 1,
|
||||
credentialBackedUp: true,
|
||||
credentialDeviceType: 'singleDevice',
|
||||
credentialID: Buffer.from('test'),
|
||||
credentialPublicKey: Buffer.from('test'),
|
||||
credentialID: Uint8Array.from([1, 2, 3]),
|
||||
credentialPublicKey: Uint8Array.from([1, 2, 3]),
|
||||
},
|
||||
} as jest.Mocked<VerifiedRegistrationResponse>)
|
||||
})
|
||||
@@ -244,7 +246,7 @@ describe('VerifyAuthenticatorRegistrationResponse', () => {
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
name: 'name',
|
||||
registrationCredential: {
|
||||
attestationResponse: {
|
||||
id: Buffer.from('id'),
|
||||
rawId: Buffer.from('rawId'),
|
||||
response: {
|
||||
@@ -279,8 +281,8 @@ describe('VerifyAuthenticatorRegistrationResponse', () => {
|
||||
counter: 1,
|
||||
credentialBackedUp: true,
|
||||
credentialDeviceType: 'singleDevice',
|
||||
credentialID: Buffer.from('test'),
|
||||
credentialPublicKey: Buffer.from('test'),
|
||||
credentialID: Uint8Array.from([1, 2, 3]),
|
||||
credentialPublicKey: Uint8Array.from([1, 2, 3]),
|
||||
},
|
||||
} as jest.Mocked<VerifiedRegistrationResponse>)
|
||||
})
|
||||
@@ -288,7 +290,7 @@ describe('VerifyAuthenticatorRegistrationResponse', () => {
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
name: 'name',
|
||||
registrationCredential: {
|
||||
attestationResponse: {
|
||||
id: Buffer.from('id'),
|
||||
rawId: Buffer.from('rawId'),
|
||||
response: {
|
||||
|
||||
@@ -11,6 +11,8 @@ export class VerifyAuthenticatorRegistrationResponse implements UseCaseInterface
|
||||
private authenticatorRepository: AuthenticatorRepositoryInterface,
|
||||
private authenticatorChallengeRepository: AuthenticatorChallengeRepositoryInterface,
|
||||
private relyingPartyId: string,
|
||||
private expectedOrigin: string,
|
||||
private requireUserVerification: boolean,
|
||||
) {}
|
||||
|
||||
async execute(dto: VerifyAuthenticatorRegistrationResponseDTO): Promise<Result<boolean>> {
|
||||
@@ -33,10 +35,11 @@ export class VerifyAuthenticatorRegistrationResponse implements UseCaseInterface
|
||||
let verification: VerifiedRegistrationResponse
|
||||
try {
|
||||
verification = await verifyRegistrationResponse({
|
||||
credential: dto.registrationCredential,
|
||||
response: dto.attestationResponse,
|
||||
expectedChallenge: authenticatorChallenge.props.challenge.toString(),
|
||||
expectedOrigin: `https://${this.relyingPartyId}`,
|
||||
expectedOrigin: this.expectedOrigin,
|
||||
expectedRPID: this.relyingPartyId,
|
||||
requireUserVerification: this.requireUserVerification,
|
||||
})
|
||||
|
||||
if (!verification.verified) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export interface VerifyAuthenticatorRegistrationResponseDTO {
|
||||
userUuid: string
|
||||
name: string
|
||||
registrationCredential: Record<string, unknown>
|
||||
attestationResponse: Record<string, unknown>
|
||||
}
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
import 'reflect-metadata'
|
||||
import { authenticator } from 'otplib'
|
||||
import { SettingName } from '@standardnotes/settings'
|
||||
import { SelectorInterface } from '@standardnotes/security'
|
||||
import { Result, UseCaseInterface } from '@standardnotes/domain-core'
|
||||
|
||||
import { User } from '../User/User'
|
||||
import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
|
||||
import { VerifyMFA } from './VerifyMFA'
|
||||
import { Setting } from '../Setting/Setting'
|
||||
import { SettingServiceInterface } from '../Setting/SettingServiceInterface'
|
||||
import { SettingName } from '@standardnotes/settings'
|
||||
import { SelectorInterface } from '@standardnotes/security'
|
||||
import { LockRepositoryInterface } from '../User/LockRepositoryInterface'
|
||||
import { AuthenticatorRepositoryInterface } from '../Authenticator/AuthenticatorRepositoryInterface'
|
||||
|
||||
import { VerifyMFA } from './VerifyMFA'
|
||||
import { Logger } from 'winston'
|
||||
import { Authenticator } from '../Authenticator/Authenticator'
|
||||
|
||||
describe('VerifyMFA', () => {
|
||||
let user: User
|
||||
@@ -17,13 +22,27 @@ describe('VerifyMFA', () => {
|
||||
let settingService: SettingServiceInterface
|
||||
let booleanSelector: SelectorInterface<boolean>
|
||||
let lockRepository: LockRepositoryInterface
|
||||
let authenticatorRepository: AuthenticatorRepositoryInterface
|
||||
let verifyAuthenticatorAuthenticationResponse: UseCaseInterface<boolean>
|
||||
let logger: Logger
|
||||
const pseudoKeyParamsKey = 'foobar'
|
||||
|
||||
const createVerifyMFA = () =>
|
||||
new VerifyMFA(userRepository, settingService, booleanSelector, lockRepository, pseudoKeyParamsKey)
|
||||
new VerifyMFA(
|
||||
userRepository,
|
||||
settingService,
|
||||
booleanSelector,
|
||||
lockRepository,
|
||||
pseudoKeyParamsKey,
|
||||
authenticatorRepository,
|
||||
verifyAuthenticatorAuthenticationResponse,
|
||||
logger,
|
||||
)
|
||||
|
||||
beforeEach(() => {
|
||||
user = {} as jest.Mocked<User>
|
||||
user = {
|
||||
uuid: '00000000-0000-0000-0000-000000000000',
|
||||
} as jest.Mocked<User>
|
||||
|
||||
userRepository = {} as jest.Mocked<UserRepositoryInterface>
|
||||
userRepository.findOneByEmail = jest.fn().mockReturnValue(user)
|
||||
@@ -42,164 +61,270 @@ describe('VerifyMFA', () => {
|
||||
|
||||
settingService = {} as jest.Mocked<SettingServiceInterface>
|
||||
settingService.findSettingWithDecryptedValue = jest.fn().mockReturnValue(setting)
|
||||
|
||||
authenticatorRepository = {} as jest.Mocked<AuthenticatorRepositoryInterface>
|
||||
authenticatorRepository.findByUserUuid = jest.fn().mockReturnValue([])
|
||||
|
||||
verifyAuthenticatorAuthenticationResponse = {} as jest.Mocked<UseCaseInterface<boolean>>
|
||||
verifyAuthenticatorAuthenticationResponse.execute = jest.fn().mockReturnValue(Result.ok())
|
||||
|
||||
logger = {} as jest.Mocked<Logger>
|
||||
logger.debug = jest.fn()
|
||||
})
|
||||
|
||||
it('should pass MFA verification if user has no MFA enabled', async () => {
|
||||
settingService.findSettingWithDecryptedValue = jest.fn().mockReturnValue(null)
|
||||
describe('2FA', () => {
|
||||
it('should pass MFA verification if user has no MFA enabled', async () => {
|
||||
settingService.findSettingWithDecryptedValue = jest.fn().mockReturnValue(null)
|
||||
|
||||
expect(
|
||||
await createVerifyMFA().execute({ email: 'test@test.te', requestParams: {}, preventOTPFromFurtherUsage: true }),
|
||||
).toEqual({
|
||||
success: true,
|
||||
})
|
||||
|
||||
expect(lockRepository.lockSuccessfullOTP).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should pass MFA verification if user has MFA deleted', async () => {
|
||||
setting = {
|
||||
name: SettingName.MfaSecret,
|
||||
value: null,
|
||||
} as jest.Mocked<Setting>
|
||||
|
||||
settingService.findSettingWithDecryptedValue = jest.fn().mockReturnValue(setting)
|
||||
|
||||
expect(
|
||||
await createVerifyMFA().execute({ email: 'test@test.te', requestParams: {}, preventOTPFromFurtherUsage: true }),
|
||||
).toEqual({
|
||||
success: true,
|
||||
})
|
||||
|
||||
expect(lockRepository.lockSuccessfullOTP).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should pass MFA verification if user is not found and pseudo mfa is not required', async () => {
|
||||
userRepository.findOneByEmail = jest.fn().mockReturnValue(null)
|
||||
expect(
|
||||
await createVerifyMFA().execute({ email: 'test@test.te', requestParams: {}, preventOTPFromFurtherUsage: true }),
|
||||
).toEqual({
|
||||
success: true,
|
||||
})
|
||||
|
||||
expect(lockRepository.lockSuccessfullOTP).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should not pass MFA verification if user is not found and pseudo mfa is required', async () => {
|
||||
booleanSelector.select = jest.fn().mockReturnValue(true)
|
||||
userRepository.findOneByEmail = jest.fn().mockReturnValue(null)
|
||||
|
||||
expect(
|
||||
await createVerifyMFA().execute({ email: 'test@test.te', requestParams: {}, preventOTPFromFurtherUsage: true }),
|
||||
).toEqual({
|
||||
success: false,
|
||||
errorTag: 'mfa-required',
|
||||
errorMessage: 'Please enter your two-factor authentication code.',
|
||||
errorPayload: { mfa_key: expect.stringMatching(/^mfa_/) },
|
||||
})
|
||||
})
|
||||
|
||||
it('should pass MFA verification if mfa key is correctly encrypted', async () => {
|
||||
expect(
|
||||
await createVerifyMFA().execute({
|
||||
email: 'test@test.te',
|
||||
requestParams: { 'mfa_1-2-3': authenticator.generate('shhhh') },
|
||||
preventOTPFromFurtherUsage: true,
|
||||
}),
|
||||
).toEqual({
|
||||
success: true,
|
||||
})
|
||||
|
||||
expect(lockRepository.lockSuccessfullOTP).toHaveBeenCalledWith('test@test.te', expect.any(String))
|
||||
})
|
||||
|
||||
it('should pass MFA verification without locking otp', async () => {
|
||||
expect(
|
||||
await createVerifyMFA().execute({
|
||||
email: 'test@test.te',
|
||||
requestParams: { 'mfa_1-2-3': authenticator.generate('shhhh') },
|
||||
preventOTPFromFurtherUsage: false,
|
||||
}),
|
||||
).toEqual({
|
||||
success: true,
|
||||
})
|
||||
|
||||
expect(lockRepository.lockSuccessfullOTP).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should not pass MFA verification if otp is already used within lock out period', async () => {
|
||||
lockRepository.isOTPLocked = jest.fn().mockReturnValue(true)
|
||||
|
||||
expect(
|
||||
await createVerifyMFA().execute({
|
||||
email: 'test@test.te',
|
||||
requestParams: { 'mfa_1-2-3': authenticator.generate('shhhh') },
|
||||
preventOTPFromFurtherUsage: true,
|
||||
}),
|
||||
).toEqual({
|
||||
success: false,
|
||||
errorTag: 'mfa-invalid',
|
||||
errorMessage:
|
||||
'The two-factor authentication code you entered has been already utilized. Please try again in a while.',
|
||||
errorPayload: { mfa_key: 'mfa_1-2-3' },
|
||||
})
|
||||
|
||||
expect(lockRepository.lockSuccessfullOTP).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should not pass MFA verification if mfa is not correct', async () => {
|
||||
setting = {
|
||||
name: SettingName.MfaSecret,
|
||||
value: 'shhhh2',
|
||||
} as jest.Mocked<Setting>
|
||||
|
||||
settingService = {} as jest.Mocked<SettingServiceInterface>
|
||||
settingService.findSettingWithDecryptedValue = jest.fn().mockReturnValue(setting)
|
||||
|
||||
expect(
|
||||
await createVerifyMFA().execute({
|
||||
email: 'test@test.te',
|
||||
requestParams: { 'mfa_1-2-3': 'test' },
|
||||
preventOTPFromFurtherUsage: true,
|
||||
}),
|
||||
).toEqual({
|
||||
success: false,
|
||||
errorTag: 'mfa-invalid',
|
||||
errorMessage: 'The two-factor authentication code you entered is incorrect. Please try again.',
|
||||
errorPayload: { mfa_key: 'mfa_1-2-3' },
|
||||
})
|
||||
})
|
||||
|
||||
it('should not pass MFA verification if no mfa param is found in the request', async () => {
|
||||
expect(
|
||||
await createVerifyMFA().execute({
|
||||
email: 'test@test.te',
|
||||
requestParams: { foo: 'bar' },
|
||||
preventOTPFromFurtherUsage: true,
|
||||
}),
|
||||
).toEqual({
|
||||
success: false,
|
||||
errorTag: 'mfa-required',
|
||||
errorMessage: 'Please enter your two-factor authentication code.',
|
||||
errorPayload: { mfa_key: expect.stringMatching(/^mfa_/) },
|
||||
})
|
||||
})
|
||||
|
||||
it('should throw an error if the error is not handled mfa validation error', async () => {
|
||||
settingService.findSettingWithDecryptedValue = jest.fn().mockImplementation(() => {
|
||||
throw new Error('oops!')
|
||||
})
|
||||
|
||||
let error = null
|
||||
try {
|
||||
await createVerifyMFA().execute({
|
||||
email: 'test@test.te',
|
||||
requestParams: { 'mfa_1-2-3': 'test' },
|
||||
preventOTPFromFurtherUsage: true,
|
||||
expect(
|
||||
await createVerifyMFA().execute({ email: 'test@test.te', requestParams: {}, preventOTPFromFurtherUsage: true }),
|
||||
).toEqual({
|
||||
success: true,
|
||||
})
|
||||
} catch (caughtError) {
|
||||
error = caughtError
|
||||
}
|
||||
|
||||
expect(error).not.toBeNull()
|
||||
expect(lockRepository.lockSuccessfullOTP).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should pass MFA verification if user has MFA deleted', async () => {
|
||||
setting = {
|
||||
name: SettingName.MfaSecret,
|
||||
value: null,
|
||||
} as jest.Mocked<Setting>
|
||||
|
||||
settingService.findSettingWithDecryptedValue = jest.fn().mockReturnValue(setting)
|
||||
|
||||
expect(
|
||||
await createVerifyMFA().execute({ email: 'test@test.te', requestParams: {}, preventOTPFromFurtherUsage: true }),
|
||||
).toEqual({
|
||||
success: true,
|
||||
})
|
||||
|
||||
expect(lockRepository.lockSuccessfullOTP).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should pass MFA verification if user is not found and pseudo mfa is not required', async () => {
|
||||
userRepository.findOneByEmail = jest.fn().mockReturnValue(null)
|
||||
expect(
|
||||
await createVerifyMFA().execute({ email: 'test@test.te', requestParams: {}, preventOTPFromFurtherUsage: true }),
|
||||
).toEqual({
|
||||
success: true,
|
||||
})
|
||||
|
||||
expect(lockRepository.lockSuccessfullOTP).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should not pass MFA verification if user is not found and pseudo mfa is required', async () => {
|
||||
booleanSelector.select = jest.fn().mockReturnValue(true)
|
||||
userRepository.findOneByEmail = jest.fn().mockReturnValue(null)
|
||||
|
||||
expect(
|
||||
await createVerifyMFA().execute({ email: 'test@test.te', requestParams: {}, preventOTPFromFurtherUsage: true }),
|
||||
).toEqual({
|
||||
success: false,
|
||||
errorTag: 'mfa-required',
|
||||
errorMessage: 'Please enter your two-factor authentication code.',
|
||||
errorPayload: { mfa_key: expect.stringMatching(/^mfa_/) },
|
||||
})
|
||||
})
|
||||
|
||||
it('should pass MFA verification if mfa key is correctly encrypted', async () => {
|
||||
expect(
|
||||
await createVerifyMFA().execute({
|
||||
email: 'test@test.te',
|
||||
requestParams: { 'mfa_1-2-3': authenticator.generate('shhhh') },
|
||||
preventOTPFromFurtherUsage: true,
|
||||
}),
|
||||
).toEqual({
|
||||
success: true,
|
||||
})
|
||||
|
||||
expect(lockRepository.lockSuccessfullOTP).toHaveBeenCalledWith('test@test.te', expect.any(String))
|
||||
})
|
||||
|
||||
it('should pass MFA verification without locking otp', async () => {
|
||||
expect(
|
||||
await createVerifyMFA().execute({
|
||||
email: 'test@test.te',
|
||||
requestParams: { 'mfa_1-2-3': authenticator.generate('shhhh') },
|
||||
preventOTPFromFurtherUsage: false,
|
||||
}),
|
||||
).toEqual({
|
||||
success: true,
|
||||
})
|
||||
|
||||
expect(lockRepository.lockSuccessfullOTP).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should not pass MFA verification if otp is already used within lock out period', async () => {
|
||||
lockRepository.isOTPLocked = jest.fn().mockReturnValue(true)
|
||||
|
||||
expect(
|
||||
await createVerifyMFA().execute({
|
||||
email: 'test@test.te',
|
||||
requestParams: { 'mfa_1-2-3': authenticator.generate('shhhh') },
|
||||
preventOTPFromFurtherUsage: true,
|
||||
}),
|
||||
).toEqual({
|
||||
success: false,
|
||||
errorTag: 'mfa-invalid',
|
||||
errorMessage:
|
||||
'The two-factor authentication code you entered has been already utilized. Please try again in a while.',
|
||||
errorPayload: { mfa_key: 'mfa_1-2-3' },
|
||||
})
|
||||
|
||||
expect(lockRepository.lockSuccessfullOTP).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should not pass MFA verification if mfa is not correct', async () => {
|
||||
setting = {
|
||||
name: SettingName.MfaSecret,
|
||||
value: 'shhhh2',
|
||||
} as jest.Mocked<Setting>
|
||||
|
||||
settingService = {} as jest.Mocked<SettingServiceInterface>
|
||||
settingService.findSettingWithDecryptedValue = jest.fn().mockReturnValue(setting)
|
||||
|
||||
expect(
|
||||
await createVerifyMFA().execute({
|
||||
email: 'test@test.te',
|
||||
requestParams: { 'mfa_1-2-3': 'test' },
|
||||
preventOTPFromFurtherUsage: true,
|
||||
}),
|
||||
).toEqual({
|
||||
success: false,
|
||||
errorTag: 'mfa-invalid',
|
||||
errorMessage: 'The two-factor authentication code you entered is incorrect. Please try again.',
|
||||
errorPayload: { mfa_key: 'mfa_1-2-3' },
|
||||
})
|
||||
})
|
||||
|
||||
it('should not pass MFA verification if no mfa param is found in the request', async () => {
|
||||
expect(
|
||||
await createVerifyMFA().execute({
|
||||
email: 'test@test.te',
|
||||
requestParams: { foo: 'bar' },
|
||||
preventOTPFromFurtherUsage: true,
|
||||
}),
|
||||
).toEqual({
|
||||
success: false,
|
||||
errorTag: 'mfa-required',
|
||||
errorMessage: 'Please enter your two-factor authentication code.',
|
||||
errorPayload: { mfa_key: expect.stringMatching(/^mfa_/) },
|
||||
})
|
||||
})
|
||||
|
||||
it('should throw an error if the error is not handled mfa validation error', async () => {
|
||||
settingService.findSettingWithDecryptedValue = jest.fn().mockImplementation(() => {
|
||||
throw new Error('oops!')
|
||||
})
|
||||
|
||||
let error = null
|
||||
try {
|
||||
await createVerifyMFA().execute({
|
||||
email: 'test@test.te',
|
||||
requestParams: { 'mfa_1-2-3': 'test' },
|
||||
preventOTPFromFurtherUsage: true,
|
||||
})
|
||||
} catch (caughtError) {
|
||||
error = caughtError
|
||||
}
|
||||
|
||||
expect(error).not.toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
describe('U2F', () => {
|
||||
beforeEach(() => {
|
||||
settingService.findSettingWithDecryptedValue = jest.fn().mockReturnValue(null)
|
||||
|
||||
authenticatorRepository.findByUserUuid = jest.fn().mockReturnValue([{} as jest.Mocked<Authenticator>])
|
||||
})
|
||||
|
||||
it('should not pass if the user has an invalid uuid', async () => {
|
||||
userRepository.findOneByEmail = jest.fn().mockReturnValue({ uuid: 'invalid' } as jest.Mocked<User>)
|
||||
|
||||
expect(
|
||||
await createVerifyMFA().execute({
|
||||
email: 'test@test.te',
|
||||
requestParams: {},
|
||||
preventOTPFromFurtherUsage: true,
|
||||
}),
|
||||
).toEqual({
|
||||
success: false,
|
||||
errorMessage: 'User UUID is invalid.',
|
||||
})
|
||||
})
|
||||
|
||||
it('should not pass if the request is missing authenticator response', async () => {
|
||||
expect(
|
||||
await createVerifyMFA().execute({
|
||||
email: 'test@test.te',
|
||||
requestParams: {},
|
||||
preventOTPFromFurtherUsage: true,
|
||||
}),
|
||||
).toEqual({
|
||||
success: false,
|
||||
errorTag: 'mfa-required',
|
||||
errorMessage: 'Please authenticate with your U2F device.',
|
||||
})
|
||||
})
|
||||
|
||||
it('should not pass if the authenticator response verification fails', async () => {
|
||||
verifyAuthenticatorAuthenticationResponse.execute = jest.fn().mockReturnValue(Result.fail('oops!'))
|
||||
|
||||
expect(
|
||||
await createVerifyMFA().execute({
|
||||
email: 'test@test.te',
|
||||
requestParams: {
|
||||
authenticator_response: {
|
||||
id: Buffer.from([1]),
|
||||
},
|
||||
},
|
||||
preventOTPFromFurtherUsage: true,
|
||||
}),
|
||||
).toEqual({
|
||||
success: false,
|
||||
errorTag: 'mfa-invalid',
|
||||
errorMessage: 'Could not verify U2F device.',
|
||||
})
|
||||
})
|
||||
|
||||
it('should not pass if the authenticator is not verified', async () => {
|
||||
verifyAuthenticatorAuthenticationResponse.execute = jest.fn().mockReturnValue(Result.ok(false))
|
||||
|
||||
expect(
|
||||
await createVerifyMFA().execute({
|
||||
email: 'test@test.te',
|
||||
requestParams: {
|
||||
authenticator_response: {
|
||||
id: Buffer.from([1]),
|
||||
},
|
||||
},
|
||||
preventOTPFromFurtherUsage: true,
|
||||
}),
|
||||
).toEqual({
|
||||
success: false,
|
||||
errorTag: 'mfa-invalid',
|
||||
errorMessage: 'Could not verify U2F device.',
|
||||
})
|
||||
})
|
||||
|
||||
it('should pass if the authenticator is verified', async () => {
|
||||
verifyAuthenticatorAuthenticationResponse.execute = jest.fn().mockReturnValue(Result.ok(true))
|
||||
|
||||
expect(
|
||||
await createVerifyMFA().execute({
|
||||
email: 'test@test.te',
|
||||
requestParams: {
|
||||
authenticator_response: {
|
||||
id: Buffer.from([1]),
|
||||
},
|
||||
},
|
||||
preventOTPFromFurtherUsage: true,
|
||||
}),
|
||||
).toEqual({
|
||||
success: true,
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,19 +1,24 @@
|
||||
import * as crypto from 'crypto'
|
||||
import { ErrorTag } from '@standardnotes/common'
|
||||
import { ErrorTag } from '@standardnotes/api'
|
||||
import { SettingName } from '@standardnotes/settings'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { inject, injectable } from 'inversify'
|
||||
import { authenticator } from 'otplib'
|
||||
import { SelectorInterface } from '@standardnotes/security'
|
||||
import { UseCaseInterface as DomainUseCaseInterface, Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { MFAValidationError } from '../Error/MFAValidationError'
|
||||
import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
|
||||
import { SettingServiceInterface } from '../Setting/SettingServiceInterface'
|
||||
import { LockRepositoryInterface } from '../User/LockRepositoryInterface'
|
||||
import { AuthenticatorRepositoryInterface } from '../Authenticator/AuthenticatorRepositoryInterface'
|
||||
|
||||
import { UseCaseInterface } from './UseCaseInterface'
|
||||
import { VerifyMFADTO } from './VerifyMFADTO'
|
||||
import { VerifyMFAResponse } from './VerifyMFAResponse'
|
||||
import { SettingServiceInterface } from '../Setting/SettingServiceInterface'
|
||||
import { SelectorInterface } from '@standardnotes/security'
|
||||
import { LockRepositoryInterface } from '../User/LockRepositoryInterface'
|
||||
import { Logger } from 'winston'
|
||||
import { Setting } from '../Setting/Setting'
|
||||
|
||||
@injectable()
|
||||
export class VerifyMFA implements UseCaseInterface {
|
||||
@@ -23,6 +28,10 @@ export class VerifyMFA implements UseCaseInterface {
|
||||
@inject(TYPES.BooleanSelector) private booleanSelector: SelectorInterface<boolean>,
|
||||
@inject(TYPES.LockRepository) private lockRepository: LockRepositoryInterface,
|
||||
@inject(TYPES.PSEUDO_KEY_PARAMS_KEY) private pseudoKeyParamsKey: string,
|
||||
@inject(TYPES.AuthenticatorRepository) private authenticatorRepository: AuthenticatorRepositoryInterface,
|
||||
@inject(TYPES.VerifyAuthenticatorAuthenticationResponse)
|
||||
private verifyAuthenticatorAuthenticationResponse: DomainUseCaseInterface<boolean>,
|
||||
@inject(TYPES.Logger) private logger: Logger,
|
||||
) {}
|
||||
|
||||
async execute(dto: VerifyMFADTO): Promise<VerifyMFAResponse> {
|
||||
@@ -48,24 +57,78 @@ export class VerifyMFA implements UseCaseInterface {
|
||||
}
|
||||
}
|
||||
|
||||
const userUuidOrError = Uuid.create(user.uuid)
|
||||
if (userUuidOrError.isFailed()) {
|
||||
return {
|
||||
success: false,
|
||||
errorMessage: 'User UUID is invalid.',
|
||||
}
|
||||
}
|
||||
const userUuid = userUuidOrError.getValue()
|
||||
|
||||
let u2fEnabled = false
|
||||
const u2fAuthenticators = await this.authenticatorRepository.findByUserUuid(userUuid)
|
||||
if (u2fAuthenticators.length > 0) {
|
||||
u2fEnabled = true
|
||||
}
|
||||
|
||||
const mfaSecret = await this.settingService.findSettingWithDecryptedValue({
|
||||
userUuid: user.uuid,
|
||||
settingName: SettingName.MfaSecret,
|
||||
})
|
||||
if (mfaSecret === null || mfaSecret.value === null) {
|
||||
const twoFactorEnabled = mfaSecret !== null && mfaSecret.value !== null
|
||||
|
||||
if (u2fEnabled === false && twoFactorEnabled === false) {
|
||||
return {
|
||||
success: true,
|
||||
}
|
||||
}
|
||||
|
||||
const verificationResult = await this.verifyMFASecret(
|
||||
dto.email,
|
||||
mfaSecret.value,
|
||||
dto.requestParams,
|
||||
dto.preventOTPFromFurtherUsage,
|
||||
)
|
||||
if (u2fEnabled) {
|
||||
if (!dto.requestParams.authenticator_response) {
|
||||
return {
|
||||
success: false,
|
||||
errorTag: ErrorTag.MfaRequired,
|
||||
errorMessage: 'Please authenticate with your U2F device.',
|
||||
}
|
||||
}
|
||||
|
||||
return verificationResult
|
||||
const verificationResultOrError = await this.verifyAuthenticatorAuthenticationResponse.execute({
|
||||
userUuid: userUuid.value,
|
||||
authenticatorResponse: dto.requestParams.authenticator_response,
|
||||
})
|
||||
if (verificationResultOrError.isFailed()) {
|
||||
this.logger.debug(`Could not verify U2F authentication: ${verificationResultOrError.getError()}`)
|
||||
|
||||
return {
|
||||
success: false,
|
||||
errorTag: ErrorTag.MfaInvalid,
|
||||
errorMessage: 'Could not verify U2F device.',
|
||||
}
|
||||
}
|
||||
|
||||
const verificationResult = verificationResultOrError.getValue()
|
||||
if (verificationResult === false) {
|
||||
return {
|
||||
success: false,
|
||||
errorTag: ErrorTag.MfaInvalid,
|
||||
errorMessage: 'Could not verify U2F device.',
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
}
|
||||
} else {
|
||||
const verificationResult = await this.verifyMFASecret(
|
||||
dto.email,
|
||||
(mfaSecret as Setting).value as string,
|
||||
dto.requestParams,
|
||||
dto.preventOTPFromFurtherUsage,
|
||||
)
|
||||
|
||||
return verificationResult
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof MFAValidationError) {
|
||||
return {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export interface VerifyAuthenticatorAuthenticationResponseRequestParams {
|
||||
userUuid: string
|
||||
authenticationCredential: Record<string, unknown>
|
||||
authenticatorResponse: Record<string, unknown>
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export interface VerifyAuthenticatorRegistrationResponseRequestParams {
|
||||
userUuid: string
|
||||
name: string
|
||||
registrationCredential: Record<string, unknown>
|
||||
attestationResponse: Record<string, unknown>
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Request, Response } from 'express'
|
||||
import { ErrorTag } from '@standardnotes/api'
|
||||
import {
|
||||
BaseHttpController,
|
||||
controller,
|
||||
@@ -16,7 +17,6 @@ import { VerifyMFA } from '../../Domain/UseCase/VerifyMFA'
|
||||
import { IncreaseLoginAttempts } from '../../Domain/UseCase/IncreaseLoginAttempts'
|
||||
import { Logger } from 'winston'
|
||||
import { GetUserKeyParams } from '../../Domain/UseCase/GetUserKeyParams/GetUserKeyParams'
|
||||
import { ErrorTag } from '@standardnotes/common'
|
||||
import { inject } from 'inversify'
|
||||
import { AuthController } from '../../Controller/AuthController'
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ export class InversifyExpressAuthenticatorsController extends BaseHttpController
|
||||
async verifyRegistration(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
const result = await this.authenticatorsController.verifyRegistrationResponse({
|
||||
userUuid: response.locals.user.uuid,
|
||||
registrationCredential: request.body.registrationCredential,
|
||||
attestationResponse: request.body.attestationResponse,
|
||||
name: request.body.name,
|
||||
})
|
||||
|
||||
@@ -71,7 +71,7 @@ export class InversifyExpressAuthenticatorsController extends BaseHttpController
|
||||
async verifyAuthentication(request: Request, response: Response): Promise<results.JsonResult> {
|
||||
const result = await this.authenticatorsController.verifyAuthenticationResponse({
|
||||
userUuid: response.locals.user.uuid,
|
||||
authenticationCredential: request.body,
|
||||
authenticatorResponse: request.body,
|
||||
})
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ErrorTag } from '@standardnotes/common'
|
||||
import { ErrorTag } from '@standardnotes/api'
|
||||
import { TokenDecoderInterface, WebSocketConnectionTokenData } from '@standardnotes/security'
|
||||
import { Request } from 'express'
|
||||
import { inject } from 'inversify'
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user