From 430db6354af6597edb116f4b464cf8f028cc5cb5 Mon Sep 17 00:00:00 2001 From: Gus Narea Date: Tue, 30 Nov 2021 10:17:19 +0000 Subject: [PATCH 01/24] update deps --- package-lock.json | 468 ++++++++++++++++++++++++++++++++++++++++++---- package.json | 3 +- 2 files changed, 433 insertions(+), 38 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7ba492d0f..65f99018c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1295,15 +1295,15 @@ } }, "@peculiar/webcrypto": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@peculiar/webcrypto/-/webcrypto-1.2.2.tgz", - "integrity": "sha512-xb8MEgfq93TAkIb70kn+llZgIFQwhdiCiOJHzekVTAS74Y+ae5bZn8KEsuycop/LXAm1kx+Kad/v9eTDTWuY/w==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@peculiar/webcrypto/-/webcrypto-1.2.3.tgz", + "integrity": "sha512-q7wDfZy3k/tpnsYB23/MyyDkjn6IdHh8w+xwoVMS5cu6CjVoFzngXDZEOOuSE4zus2yO6ciQhhHxd4XkLpwVnQ==", "requires": { - "@peculiar/asn1-schema": "^2.0.38", + "@peculiar/asn1-schema": "^2.0.44", "@peculiar/json-schema": "^1.1.12", "pvtsutils": "^1.2.1", "tslib": "^2.3.1", - "webcrypto-core": "^1.3.0" + "webcrypto-core": "^1.4.0" }, "dependencies": { "tslib": { @@ -1381,6 +1381,25 @@ "uuid-random": "^1.3.0" } }, + "@relaycorp/keystore-db": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@relaycorp/keystore-db/-/keystore-db-1.1.0.tgz", + "integrity": "sha512-29VeyHtxpsmIxeerj6W3GVxpryP+nCaZw2BWjtR5hoSxss7LSkE4eDDjRGbHqCPF7gJquWZV4CndMeTLhBpfvA==", + "requires": { + "@relaycorp/relaynet-core": "^1.56.2", + "buffer-to-arraybuffer": "0.0.6", + "date-fns": "^2.26.0", + "date-fns-tz": "^1.1.6", + "typeorm": "^0.2.41" + }, + "dependencies": { + "date-fns": { + "version": "2.27.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.27.0.tgz", + "integrity": "sha512-sj+J0Mo2p2X1e306MHq282WS4/A8Pz/95GIFcsPNMPMZVI3EUrAdSv90al1k+p74WGLCruMXk23bfEDZa71X9Q==" + } + } + }, "@relaycorp/keystore-vault": { "version": "1.2.12", "resolved": "https://registry.npmjs.org/@relaycorp/keystore-vault/-/keystore-vault-1.2.12.tgz", @@ -1418,14 +1437,14 @@ } }, "@relaycorp/relaynet-core": { - "version": "1.54.7", - "resolved": "https://registry.npmjs.org/@relaycorp/relaynet-core/-/relaynet-core-1.54.7.tgz", - "integrity": "sha512-K1Uzc7RolJuPQ4sEIG8JBPZvrbfm37JXD3J7TLX6ZPeTI1I6V4ReCRhFbvkiMwEGzK1fmbrOZTa79WEAWxJ6iA==", + "version": "1.56.2", + "resolved": "https://registry.npmjs.org/@relaycorp/relaynet-core/-/relaynet-core-1.56.2.tgz", + "integrity": "sha512-RD4WjA61aW2SFmM9D7OLb4+jE19AkZEstQVNW0mzUHb2HCJ9MNVVw6Cu0yywgpQNTMBIK+GKiYtn2LLIVAhl0Q==", "requires": { - "@peculiar/webcrypto": "^1.2.2", + "@peculiar/webcrypto": "^1.2.3", + "@stablelib/aes-kw": "^1.0.1", "@types/verror": "^1.10.5", "asn1js": "^2.1.1", - "binary-parser": "^2.0.1", "buffer-to-arraybuffer": "0.0.6", "dohdec": "^3.1.0", "is-valid-domain": "^0.1.4", @@ -1433,7 +1452,8 @@ "pkijs": "^2.2.1", "smart-buffer": "^4.2.0", "uuid4": "^2.0.2", - "verror": "^1.10.1" + "verror": "^1.10.1", + "webcrypto-core": "^1.4.0" }, "dependencies": { "pkijs": { @@ -1913,6 +1933,61 @@ "@sinonjs/commons": "^1.7.0" } }, + "@sqltools/formatter": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.3.tgz", + "integrity": "sha512-O3uyB/JbkAEMZaP3YqyHH7TMnex7tWyCbCI4EfJdOCoN6HIhqdJBWTM6aCCiWQ/5f5wxjgU735QAIpJbjDvmzg==" + }, + "@stablelib/aes": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/aes/-/aes-1.0.1.tgz", + "integrity": "sha512-bMiezJDeFONDHbMEa+Kic26962+bwkZfsHPAmcqTjLaHCAhEQuK3i1H0POPOkcHCdj75oVRIqFCraCA0cyHPvw==", + "requires": { + "@stablelib/binary": "^1.0.1", + "@stablelib/blockcipher": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/aes-kw": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/aes-kw/-/aes-kw-1.0.1.tgz", + "integrity": "sha512-KrOkiRex1tQTbWk+hFB5fFw4vqKhNnTUtlCRf1bhUEOFp7hadWe49/sLa/P4X4FBQVoh3Z9Lj0zS1OWu/AHA1w==", + "requires": { + "@stablelib/aes": "^1.0.1", + "@stablelib/binary": "^1.0.1", + "@stablelib/blockcipher": "^1.0.1", + "@stablelib/constant-time": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/binary": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/binary/-/binary-1.0.1.tgz", + "integrity": "sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==", + "requires": { + "@stablelib/int": "^1.0.1" + } + }, + "@stablelib/blockcipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/blockcipher/-/blockcipher-1.0.1.tgz", + "integrity": "sha512-4bkpV8HUAv0CgI1fUqkPUEEvv3RXQ3qBkuZaSWhshXGAz1JCpriesgiO9Qs4f0KzBJkCtvcho5n7d/RKvnHbew==" + }, + "@stablelib/constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/constant-time/-/constant-time-1.0.1.tgz", + "integrity": "sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg==" + }, + "@stablelib/int": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/int/-/int-1.0.1.tgz", + "integrity": "sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w==" + }, + "@stablelib/wipe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/wipe/-/wipe-1.0.1.tgz", + "integrity": "sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==" + }, "@stroncium/procfs": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@stroncium/procfs/-/procfs-1.2.1.tgz", @@ -2245,6 +2320,11 @@ "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==", "dev": true }, + "@types/zen-observable": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.3.tgz", + "integrity": "sha512-fbF6oTd4sGGy0xjHPKAt+eS2CrxJ3+6gQ3FGcBoIJR2TLAyCkCyI8JqZNy+FeON0AhVgNJoUumVoZQjBFUqHkw==" + }, "JSONStream": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", @@ -2385,6 +2465,11 @@ "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=", "dev": true }, + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" + }, "anymatch": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", @@ -2395,6 +2480,11 @@ "picomatch": "^2.0.4" } }, + "app-root-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.0.0.tgz", + "integrity": "sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw==" + }, "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", @@ -2736,8 +2826,7 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "base": { "version": "0.11.2", @@ -2825,11 +2914,6 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, - "binary-parser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/binary-parser/-/binary-parser-2.0.1.tgz", - "integrity": "sha512-7kZx8vZCq+V/0XkaOjLpCkBdOYCzjau+yt1PDMM04Q73WgtNYSoM6gOpl/Ky7qbANrEkcbX9ya+6Fdmj1WeU+w==" - }, "bl": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", @@ -2892,7 +2976,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3141,6 +3224,64 @@ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true }, + "cli-highlight": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", + "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", + "requires": { + "chalk": "^4.0.0", + "highlight.js": "^10.7.1", + "mz": "^2.4.0", + "parse5": "^5.1.1", + "parse5-htmlparser2-tree-adapter": "^6.0.0", + "yargs": "^16.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "cli-table": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.6.tgz", @@ -3246,8 +3387,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "configstore": { "version": "5.0.1", @@ -3465,6 +3605,11 @@ "integrity": "sha512-5ycpauovVyAk0kXNZz6ZoB9AYMZB4DObse7P3BPWmyEjXNORTI8EJ6X0uaSAq4sCHzM1uajzrkr6HnsLQpxGXA==", "dev": true }, + "date-fns-tz": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-1.1.6.tgz", + "integrity": "sha512-nyy+URfFI3KUY7udEJozcoftju+KduaqkVfwyTIE0traBiVye09QnyWKLZK7drRr5h9B7sPJITmQnS3U6YOdQg==" + }, "dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", @@ -3721,6 +3866,11 @@ "is-obj": "^2.0.0" } }, + "dotenv": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", + "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==" + }, "duplexer2": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", @@ -4566,8 +4716,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { "version": "2.3.2", @@ -4731,7 +4880,6 @@ "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -4961,6 +5109,11 @@ "resolved": "https://registry.npmjs.org/hash-stream-validation/-/hash-stream-validation-0.2.4.tgz", "integrity": "sha512-Gjzu0Xn7IagXVkSu9cSFuK1fqzwtLwFhNhVL8IFJijRNMgUttFbBSIAzKuSIrsFMO1+g1RlsoN49zPIbwPDMGQ==" }, + "highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==" + }, "hook-std": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-2.0.0.tgz", @@ -5128,7 +5281,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -5401,9 +5553,9 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "is-valid-domain": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-valid-domain/-/is-valid-domain-0.1.4.tgz", - "integrity": "sha512-Caa6rwGze6pihA29wy3T1yNXzd53caGHvL0OfJ8RLtv0tVVzVZGlxFcQ0W8kls/uG0QUrv2B3J9xi/YB5/cfUQ==", + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/is-valid-domain/-/is-valid-domain-0.1.5.tgz", + "integrity": "sha512-ilzfGo1kXzoVpSLplJWOexoiuAc6mRK+vPlNAeEPVJ29RagETpCz0izg6CZfY72DCuA+PCrEAEJeaecRLMNq5Q==", "requires": { "punycode": "^2.1.1" } @@ -7787,7 +7939,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -7972,6 +8123,16 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "requires": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -10308,6 +10469,11 @@ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "dev": true }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", @@ -10525,8 +10691,22 @@ "parse5": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", - "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", - "dev": true + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==" + }, + "parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "requires": { + "parse5": "^6.0.1" + }, + "dependencies": { + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + } + } }, "pascalcase": { "version": "0.1.1", @@ -10543,8 +10723,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-key": { "version": "3.1.1", @@ -11671,6 +11850,15 @@ } } }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -12341,6 +12529,22 @@ "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", "dev": true }, + "thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "requires": { + "any-promise": "^1.0.0" + } + }, + "thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", + "requires": { + "thenify": ">= 3.1.0 < 4" + } + }, "throat": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", @@ -12827,6 +13031,182 @@ "is-typedarray": "^1.0.0" } }, + "typeorm": { + "version": "0.2.41", + "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.2.41.tgz", + "integrity": "sha512-/d8CLJJxKPgsnrZWiMyPI0rz2MFZnBQrnQ5XP3Vu3mswv2WPexb58QM6BEtmRmlTMYN5KFWUz8SKluze+wS9xw==", + "requires": { + "@sqltools/formatter": "^1.2.2", + "app-root-path": "^3.0.0", + "buffer": "^6.0.3", + "chalk": "^4.1.0", + "cli-highlight": "^2.1.11", + "debug": "^4.3.1", + "dotenv": "^8.2.0", + "glob": "^7.1.6", + "js-yaml": "^4.0.0", + "mkdirp": "^1.0.4", + "reflect-metadata": "^0.1.13", + "sha.js": "^2.4.11", + "tslib": "^2.1.0", + "xml2js": "^0.4.23", + "yargs": "^17.0.1", + "zen-observable-ts": "^1.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "requires": { + "ms": "2.1.2" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "requires": { + "argparse": "^2.0.1" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "xml2js": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + } + }, + "xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, + "yargs": { + "version": "17.2.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.2.1.tgz", + "integrity": "sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q==", + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" + } + } + }, "typescript": { "version": "3.9.10", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", @@ -13058,11 +13438,11 @@ } }, "webcrypto-core": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.3.0.tgz", - "integrity": "sha512-/+Hz+uNM6T8FtizWRYMNdGTXxWaljLFzQ5GKU4WqCTZKpaki94YqDA39h/SpWxEZfgkVMZzrqqtPlfy2+BloQw==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.4.0.tgz", + "integrity": "sha512-HY3Zo0GcRIQUUDnlZ/shGjN+4f7LVMkdJZoGPog+oHhJsJdMz6iM8Za5xZ0t6qg7Fx/JXXz+oBv2J2p982hGTQ==", "requires": { - "@peculiar/asn1-schema": "^2.0.38", + "@peculiar/asn1-schema": "^2.0.44", "@peculiar/json-schema": "^1.1.12", "asn1js": "^2.1.1", "pvtsutils": "^1.2.0", @@ -13346,6 +13726,20 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" + }, + "zen-observable": { + "version": "0.8.15", + "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz", + "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==" + }, + "zen-observable-ts": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-1.1.0.tgz", + "integrity": "sha512-1h4zlLSqI2cRLPJUHJFL8bCWHhkpuXkF+dbGkRaWjgDIG26DmzyshUMrdV/rL3UnR+mhaX4fRq8LPouq0MYYIA==", + "requires": { + "@types/zen-observable": "0.8.3", + "zen-observable": "0.8.15" + } } } } diff --git a/package.json b/package.json index ca16145e8..7e753ac26 100644 --- a/package.json +++ b/package.json @@ -71,10 +71,11 @@ "dependencies": { "@grpc/grpc-js": "^1.3.7", "@relaycorp/cogrpc": "^1.3.23", + "@relaycorp/keystore-db": "^1.1.0", "@relaycorp/keystore-vault": "^1.2.12", "@relaycorp/object-storage": "^1.4.5", "@relaycorp/pino-cloud": "^1.0.4", - "@relaycorp/relaynet-core": "^1.54.7", + "@relaycorp/relaynet-core": "^1.56.2", "@relaycorp/relaynet-pohttp": "^1.7.6", "@typegoose/typegoose": "^8.1.1", "abort-controller": "^3.0.0", From 1ed23bda290cbc41dcc3e37ee3d6a28b5649e146 Mon Sep 17 00:00:00 2001 From: Gus Narea Date: Tue, 30 Nov 2021 10:55:43 +0000 Subject: [PATCH 02/24] uninstall @relaycorp/keystore-db --- package-lock.json | 376 ++-------------------------------------------- package.json | 1 - 2 files changed, 14 insertions(+), 363 deletions(-) diff --git a/package-lock.json b/package-lock.json index 65f99018c..258818f19 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1381,25 +1381,6 @@ "uuid-random": "^1.3.0" } }, - "@relaycorp/keystore-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@relaycorp/keystore-db/-/keystore-db-1.1.0.tgz", - "integrity": "sha512-29VeyHtxpsmIxeerj6W3GVxpryP+nCaZw2BWjtR5hoSxss7LSkE4eDDjRGbHqCPF7gJquWZV4CndMeTLhBpfvA==", - "requires": { - "@relaycorp/relaynet-core": "^1.56.2", - "buffer-to-arraybuffer": "0.0.6", - "date-fns": "^2.26.0", - "date-fns-tz": "^1.1.6", - "typeorm": "^0.2.41" - }, - "dependencies": { - "date-fns": { - "version": "2.27.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.27.0.tgz", - "integrity": "sha512-sj+J0Mo2p2X1e306MHq282WS4/A8Pz/95GIFcsPNMPMZVI3EUrAdSv90al1k+p74WGLCruMXk23bfEDZa71X9Q==" - } - } - }, "@relaycorp/keystore-vault": { "version": "1.2.12", "resolved": "https://registry.npmjs.org/@relaycorp/keystore-vault/-/keystore-vault-1.2.12.tgz", @@ -1933,11 +1914,6 @@ "@sinonjs/commons": "^1.7.0" } }, - "@sqltools/formatter": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.3.tgz", - "integrity": "sha512-O3uyB/JbkAEMZaP3YqyHH7TMnex7tWyCbCI4EfJdOCoN6HIhqdJBWTM6aCCiWQ/5f5wxjgU735QAIpJbjDvmzg==" - }, "@stablelib/aes": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@stablelib/aes/-/aes-1.0.1.tgz", @@ -2320,11 +2296,6 @@ "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==", "dev": true }, - "@types/zen-observable": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.3.tgz", - "integrity": "sha512-fbF6oTd4sGGy0xjHPKAt+eS2CrxJ3+6gQ3FGcBoIJR2TLAyCkCyI8JqZNy+FeON0AhVgNJoUumVoZQjBFUqHkw==" - }, "JSONStream": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", @@ -2465,11 +2436,6 @@ "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=", "dev": true }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" - }, "anymatch": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", @@ -2480,11 +2446,6 @@ "picomatch": "^2.0.4" } }, - "app-root-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.0.0.tgz", - "integrity": "sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw==" - }, "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", @@ -2826,7 +2787,8 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true }, "base": { "version": "0.11.2", @@ -2976,6 +2938,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3224,64 +3187,6 @@ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true }, - "cli-highlight": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", - "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", - "requires": { - "chalk": "^4.0.0", - "highlight.js": "^10.7.1", - "mz": "^2.4.0", - "parse5": "^5.1.1", - "parse5-htmlparser2-tree-adapter": "^6.0.0", - "yargs": "^16.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "cli-table": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.6.tgz", @@ -3387,7 +3292,8 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "configstore": { "version": "5.0.1", @@ -3605,11 +3511,6 @@ "integrity": "sha512-5ycpauovVyAk0kXNZz6ZoB9AYMZB4DObse7P3BPWmyEjXNORTI8EJ6X0uaSAq4sCHzM1uajzrkr6HnsLQpxGXA==", "dev": true }, - "date-fns-tz": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-1.1.6.tgz", - "integrity": "sha512-nyy+URfFI3KUY7udEJozcoftju+KduaqkVfwyTIE0traBiVye09QnyWKLZK7drRr5h9B7sPJITmQnS3U6YOdQg==" - }, "dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", @@ -3866,11 +3767,6 @@ "is-obj": "^2.0.0" } }, - "dotenv": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", - "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==" - }, "duplexer2": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", @@ -4716,7 +4612,8 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true }, "fsevents": { "version": "2.3.2", @@ -4880,6 +4777,7 @@ "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -5109,11 +5007,6 @@ "resolved": "https://registry.npmjs.org/hash-stream-validation/-/hash-stream-validation-0.2.4.tgz", "integrity": "sha512-Gjzu0Xn7IagXVkSu9cSFuK1fqzwtLwFhNhVL8IFJijRNMgUttFbBSIAzKuSIrsFMO1+g1RlsoN49zPIbwPDMGQ==" }, - "highlight.js": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==" - }, "hook-std": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-2.0.0.tgz", @@ -5281,6 +5174,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -7939,6 +7833,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -8123,16 +8018,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "requires": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -10469,11 +10354,6 @@ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "dev": true }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", @@ -10691,22 +10571,8 @@ "parse5": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", - "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==" - }, - "parse5-htmlparser2-tree-adapter": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", - "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", - "requires": { - "parse5": "^6.0.1" - }, - "dependencies": { - "parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" - } - } + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "dev": true }, "pascalcase": { "version": "0.1.1", @@ -10723,7 +10589,8 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true }, "path-key": { "version": "3.1.1", @@ -11850,15 +11717,6 @@ } } }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -12529,22 +12387,6 @@ "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", "dev": true }, - "thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "requires": { - "any-promise": "^1.0.0" - } - }, - "thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", - "requires": { - "thenify": ">= 3.1.0 < 4" - } - }, "throat": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", @@ -13031,182 +12873,6 @@ "is-typedarray": "^1.0.0" } }, - "typeorm": { - "version": "0.2.41", - "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.2.41.tgz", - "integrity": "sha512-/d8CLJJxKPgsnrZWiMyPI0rz2MFZnBQrnQ5XP3Vu3mswv2WPexb58QM6BEtmRmlTMYN5KFWUz8SKluze+wS9xw==", - "requires": { - "@sqltools/formatter": "^1.2.2", - "app-root-path": "^3.0.0", - "buffer": "^6.0.3", - "chalk": "^4.1.0", - "cli-highlight": "^2.1.11", - "debug": "^4.3.1", - "dotenv": "^8.2.0", - "glob": "^7.1.6", - "js-yaml": "^4.0.0", - "mkdirp": "^1.0.4", - "reflect-metadata": "^0.1.13", - "sha.js": "^2.4.11", - "tslib": "^2.1.0", - "xml2js": "^0.4.23", - "yargs": "^17.0.1", - "zen-observable-ts": "^1.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "requires": { - "ms": "2.1.2" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "requires": { - "argparse": "^2.0.1" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - }, - "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "requires": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - } - }, - "xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yargs": { - "version": "17.2.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.2.1.tgz", - "integrity": "sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q==", - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" - } - } - }, "typescript": { "version": "3.9.10", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", @@ -13726,20 +13392,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" - }, - "zen-observable": { - "version": "0.8.15", - "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz", - "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==" - }, - "zen-observable-ts": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-1.1.0.tgz", - "integrity": "sha512-1h4zlLSqI2cRLPJUHJFL8bCWHhkpuXkF+dbGkRaWjgDIG26DmzyshUMrdV/rL3UnR+mhaX4fRq8LPouq0MYYIA==", - "requires": { - "@types/zen-observable": "0.8.3", - "zen-observable": "0.8.15" - } } } } diff --git a/package.json b/package.json index 7e753ac26..3888a7d8c 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,6 @@ "dependencies": { "@grpc/grpc-js": "^1.3.7", "@relaycorp/cogrpc": "^1.3.23", - "@relaycorp/keystore-db": "^1.1.0", "@relaycorp/keystore-vault": "^1.2.12", "@relaycorp/object-storage": "^1.4.5", "@relaycorp/pino-cloud": "^1.0.4", From ec1cff20f0bc932a6d83f62bb07ab4f37dc2f7f4 Mon Sep 17 00:00:00 2001 From: Gus Narea Date: Tue, 30 Nov 2021 11:10:11 +0000 Subject: [PATCH 03/24] move pub key store to keystores dir --- src/backingServices/mongo.spec.ts | 2 +- src/backingServices/mongo.ts | 3 ++- src/{ => keystores}/MongoPublicKeyStore.spec.ts | 4 ++-- src/{ => keystores}/MongoPublicKeyStore.ts | 2 +- src/queueWorkers/crcIncoming.spec.ts | 2 +- src/queueWorkers/crcIncoming.ts | 2 +- 6 files changed, 8 insertions(+), 7 deletions(-) rename src/{ => keystores}/MongoPublicKeyStore.spec.ts (97%) rename src/{ => keystores}/MongoPublicKeyStore.ts (96%) diff --git a/src/backingServices/mongo.spec.ts b/src/backingServices/mongo.spec.ts index 0f25aaa47..1280c27b1 100644 --- a/src/backingServices/mongo.spec.ts +++ b/src/backingServices/mongo.spec.ts @@ -2,7 +2,7 @@ import { EnvVarError } from 'env-var'; import mongoose, { Connection } from 'mongoose'; import { mockSpy, MONGO_ENV_VARS } from '../_test_utils'; -import { MongoPublicKeyStore } from '../MongoPublicKeyStore'; +import { MongoPublicKeyStore } from '../keystores/MongoPublicKeyStore'; import { configureMockEnvVars } from '../services/_test_utils'; import { createMongooseConnectionFromEnv, diff --git a/src/backingServices/mongo.ts b/src/backingServices/mongo.ts index fa564139c..0c169bdee 100644 --- a/src/backingServices/mongo.ts +++ b/src/backingServices/mongo.ts @@ -1,7 +1,8 @@ import { PublicKeyStore } from '@relaycorp/relaynet-core'; import { get as getEnvVar } from 'env-var'; import { Connection, ConnectionOptions, createConnection } from 'mongoose'; -import { MongoPublicKeyStore } from '../MongoPublicKeyStore'; + +import { MongoPublicKeyStore } from '../keystores/MongoPublicKeyStore'; export function getMongooseConnectionArgsFromEnv(): { readonly uri: string; diff --git a/src/MongoPublicKeyStore.spec.ts b/src/keystores/MongoPublicKeyStore.spec.ts similarity index 97% rename from src/MongoPublicKeyStore.spec.ts rename to src/keystores/MongoPublicKeyStore.spec.ts index e564807ed..068d905d6 100644 --- a/src/MongoPublicKeyStore.spec.ts +++ b/src/keystores/MongoPublicKeyStore.spec.ts @@ -10,8 +10,8 @@ import { import * as typegoose from '@typegoose/typegoose'; import { Connection } from 'mongoose'; -import { mockSpy } from './_test_utils'; -import { PeerPublicKeyData } from './models'; +import { mockSpy } from '../_test_utils'; +import { PeerPublicKeyData } from '../models'; import { MongoPublicKeyStore } from './MongoPublicKeyStore'; const STUB_CONNECTION: Connection = { what: 'the-stub-connection' } as any; diff --git a/src/MongoPublicKeyStore.ts b/src/keystores/MongoPublicKeyStore.ts similarity index 96% rename from src/MongoPublicKeyStore.ts rename to src/keystores/MongoPublicKeyStore.ts index 1b0c5a859..517ba0cbd 100644 --- a/src/MongoPublicKeyStore.ts +++ b/src/keystores/MongoPublicKeyStore.ts @@ -2,7 +2,7 @@ import { PublicKeyStore, SessionPublicKeyData } from '@relaycorp/relaynet-core'; import { getModelForClass } from '@typegoose/typegoose'; import { Connection, Model } from 'mongoose'; -import { PeerPublicKeyData } from './models'; +import { PeerPublicKeyData } from '../models'; export class MongoPublicKeyStore extends PublicKeyStore { protected readonly keyDataModel: Model; diff --git a/src/queueWorkers/crcIncoming.spec.ts b/src/queueWorkers/crcIncoming.spec.ts index a72ce994d..a103ee525 100644 --- a/src/queueWorkers/crcIncoming.spec.ts +++ b/src/queueWorkers/crcIncoming.spec.ts @@ -28,7 +28,7 @@ import * as mongo from '../backingServices/mongo'; import { NatsStreamingClient } from '../backingServices/natsStreaming'; import * as objectStorage from '../backingServices/objectStorage'; import * as vault from '../backingServices/vault'; -import * as mongoPublicKeyStore from '../MongoPublicKeyStore'; +import * as mongoPublicKeyStore from '../keystores/MongoPublicKeyStore'; import { ParcelStore } from '../parcelStore'; import { castMock, diff --git a/src/queueWorkers/crcIncoming.ts b/src/queueWorkers/crcIncoming.ts index 5d9c20fb3..b88e9400c 100644 --- a/src/queueWorkers/crcIncoming.ts +++ b/src/queueWorkers/crcIncoming.ts @@ -18,7 +18,7 @@ import { createMongooseConnectionFromEnv } from '../backingServices/mongo'; import { NatsStreamingClient } from '../backingServices/natsStreaming'; import { initObjectStoreFromEnv } from '../backingServices/objectStorage'; import { initVaultKeyStore } from '../backingServices/vault'; -import { MongoPublicKeyStore } from '../MongoPublicKeyStore'; +import { MongoPublicKeyStore } from '../keystores/MongoPublicKeyStore'; import { ParcelStore } from '../parcelStore'; import { configureExitHandling } from '../utilities/exitHandling'; import { makeLogger } from '../utilities/logging'; From a88e3c92e98f346044ee8622f7e1103804e8232c Mon Sep 17 00:00:00 2001 From: Gus Narea Date: Tue, 30 Nov 2021 14:35:17 +0000 Subject: [PATCH 04/24] implement MongoCertificateStore --- .gitignore | 3 + jest-mongodb-config.js | 11 + jest.config.js | 11 +- package-lock.json | 293 ++++++++++++++++++++ package.json | 1 + src/keystores/MongoCertificateStore.spec.ts | 182 ++++++++++++ src/keystores/MongoCertificateStore.ts | 59 ++++ src/models.ts | 15 + 8 files changed, 569 insertions(+), 6 deletions(-) create mode 100644 jest-mongodb-config.js create mode 100644 src/keystores/MongoCertificateStore.spec.ts create mode 100644 src/keystores/MongoCertificateStore.ts diff --git a/.gitignore b/.gitignore index b2aa9c28b..ddad907bf 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,6 @@ docs/vendor chart/charts chart/tmpcharts + +# Work around https://github.com/shelfio/jest-mongodb/issues/214 +/globalConfig.json diff --git a/jest-mongodb-config.js b/jest-mongodb-config.js new file mode 100644 index 000000000..7f52fd6aa --- /dev/null +++ b/jest-mongodb-config.js @@ -0,0 +1,11 @@ +module.exports = { + mongodbMemoryServerOptions: { + binary: { + version: '4.0.3', + skipMD5: false, + }, + instance: {}, + autoStart: false, + }, + useSharedDBForAllJestWorkers: false, +}; diff --git a/jest.config.js b/jest.config.js index 1eed54567..6067d5016 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,5 +1,4 @@ -// For a detailed explanation regarding each configuration property, visit: -// https://jestjs.io/docs/en/configuration.html +const { defaults: tsjPreset } = require('ts-jest/presets'); module.exports = { // All imported modules in your tests should be mocked automatically @@ -90,7 +89,7 @@ module.exports = { // notifyMode: "failure-change", // A preset that is used as a base for Jest's configuration - preset: "ts-jest", + preset: "@shelf/jest-mongodb", // Run tests from one or more projects // projects: null, @@ -130,8 +129,8 @@ module.exports = { // A list of paths to snapshot serializer modules Jest should use for snapshot testing // snapshotSerializers: [], - // The test environment that will be used for testing - testEnvironment: "node", + // Work around https://github.com/shelfio/jest-mongodb/issues/109 + // testEnvironment: "node", // Options that will be passed to the testEnvironment // testEnvironmentOptions: {}, @@ -167,7 +166,7 @@ module.exports = { // timers: "real", // A map from regular expressions to paths to transformers - // transform: null, + transform: tsjPreset.transform, // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation // transformIgnorePatterns: [ diff --git a/package-lock.json b/package-lock.json index 258818f19..e0a020f46 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1859,6 +1859,34 @@ } } }, + "@shelf/jest-mongodb": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@shelf/jest-mongodb/-/jest-mongodb-2.1.0.tgz", + "integrity": "sha512-sSSS/QnU8sKJUpVqKvcR4CR5ca8Mb1MpQY49H/we9bzyg/UsBhEcVehwaRSEZ13dOd8orGrNa8OW8438l2Gt1g==", + "dev": true, + "requires": { + "debug": "4.3.2", + "mongodb-memory-server": "7.3.6", + "uuid": "8.3.2" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, "@sindresorhus/df": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@sindresorhus/df/-/df-3.1.1.tgz", @@ -2267,6 +2295,12 @@ "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==", "dev": true }, + "@types/tmp": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.2.2.tgz", + "integrity": "sha512-MhSa0yylXtVMsyT8qFpHA1DLHj4DvQGH5ntxrhHSh8PxUVNi35Wk+P5hVgqbO2qZqOotqr9jaoPRL+iRjWYm/A==", + "dev": true + }, "@types/verror": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.5.tgz", @@ -2555,6 +2589,23 @@ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, + "async-mutex": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.3.2.tgz", + "integrity": "sha512-HuTK7E7MT7jZEh1P9GtRW9+aTWiDWWi9InbZ5hjxrnRa39KS4BW04+xLBhYNS2aXhHUIKZSw3gj4Pn1pj+qGAA==", + "dev": true, + "requires": { + "tslib": "^2.3.1" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + } + } + }, "async-retry": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.1.tgz", @@ -2992,6 +3043,12 @@ "isarray": "^1.0.0" } }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, "buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", @@ -3265,6 +3322,12 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, "compare-func": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", @@ -4454,6 +4517,15 @@ "bser": "2.1.1" } }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, "figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -4472,6 +4544,17 @@ "to-regex-range": "^5.0.1" } }, + "find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, "find-my-way": { "version": "4.3.3", "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-4.3.3.tgz", @@ -4598,6 +4681,12 @@ } } }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, "fs-extra": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", @@ -4684,6 +4773,12 @@ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true }, + "get-port": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", + "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", + "dev": true + }, "get-stream": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", @@ -7708,6 +7803,12 @@ } } }, + "md5-file": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/md5-file/-/md5-file-5.0.0.tgz", + "integrity": "sha512-xbEFXCYVWrSx/gEKS1VPlg84h/4L20znVIulKw6kMfmBUAZNAnF00eczz9ICMl+/hjQGo5KSXRxbL/47X3rmMw==", + "dev": true + }, "memory-pager": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", @@ -7918,6 +8019,93 @@ "saslprep": "^1.0.0" } }, + "mongodb-memory-server": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/mongodb-memory-server/-/mongodb-memory-server-7.3.6.tgz", + "integrity": "sha512-JfuY7uJD9TZxq6C4YVuCjiP2v0V/NYb19Wki6rFovdJvkgxGp5/KXKaazu47leECYAtJc2ajW1c009M3hRM+6A==", + "dev": true, + "requires": { + "mongodb-memory-server-core": "7.3.6", + "tslib": "^2.3.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + } + } + }, + "mongodb-memory-server-core": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/mongodb-memory-server-core/-/mongodb-memory-server-core-7.3.6.tgz", + "integrity": "sha512-dxprJ5Xqb0y/9nqv709BGf8Cz4dnInhG3sTuYvMJijK4cAHYxk0xkKrvZX2X9PrYiCQqKix59hHMBGyBetN3hg==", + "dev": true, + "requires": { + "@types/tmp": "^0.2.0", + "async-mutex": "^0.3.0", + "camelcase": "^6.1.0", + "debug": "^4.2.0", + "find-cache-dir": "^3.3.1", + "get-port": "^5.1.1", + "https-proxy-agent": "^5.0.0", + "md5-file": "^5.0.0", + "mkdirp": "^1.0.4", + "mongodb": "^3.6.9", + "new-find-package-json": "^1.1.0", + "semver": "^7.3.5", + "tar-stream": "^2.1.4", + "tmp": "^0.2.1", + "tslib": "^2.3.0", + "uuid": "^8.3.1", + "yauzl": "^2.10.0" + }, + "dependencies": { + "camelcase": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz", + "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==", + "dev": true + }, + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + } + } + }, "mongoose": { "version": "5.13.7", "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.13.7.tgz", @@ -8064,6 +8252,39 @@ "integrity": "sha1-5tq3/r9a2Bbqgc9cYpxaDr3nLBo=", "dev": true }, + "new-find-package-json": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/new-find-package-json/-/new-find-package-json-1.1.0.tgz", + "integrity": "sha512-KOH3BNZcTKPzEkaJgG2iSUaurxKmefqRKmCOYH+8xqJytNIgjqU4J88BHfK+gy/UlEzlhccLyuJDJAcCgexSwA==", + "dev": true, + "requires": { + "debug": "^4.3.2", + "tslib": "^2.3.0" + }, + "dependencies": { + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + } + } + }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -10612,6 +10833,12 @@ "pify": "^3.0.0" } }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -12321,6 +12548,42 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + } + } + }, "teeny-request": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.1.1.tgz", @@ -12413,6 +12676,26 @@ "resolved": "https://registry.npmjs.org/tiny-lru/-/tiny-lru-7.0.6.tgz", "integrity": "sha512-zNYO0Kvgn5rXzWpL0y3RS09sMK67eGaQj9805jlK9G6pSadfriTczzLHFXa/xcW4mIRfmlB9HyQ/+SgL0V1uow==" }, + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "requires": { + "rimraf": "^3.0.0" + }, + "dependencies": { + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, "tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", @@ -13382,6 +13665,16 @@ "decamelize": "^1.2.0" } }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/package.json b/package.json index 3888a7d8c..be8fed969 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "@relaycorp/shared-config": "^1.6.0", "@relaycorp/ws-mock": "^4.2.0", "@semantic-release/exec": "^5.0.0", + "@shelf/jest-mongodb": "^2.1.0", "@types/jest": "^26.0.24", "@types/mongoose": "^5.10.5", "@types/pino": "^6.3.11", diff --git a/src/keystores/MongoCertificateStore.spec.ts b/src/keystores/MongoCertificateStore.spec.ts new file mode 100644 index 000000000..7baba1a64 --- /dev/null +++ b/src/keystores/MongoCertificateStore.spec.ts @@ -0,0 +1,182 @@ +import { + Certificate, + generateRSAKeyPair, + getPrivateAddressFromIdentityKey, + issueGatewayCertificate, +} from '@relaycorp/relaynet-core'; +import { getModelForClass, ReturnModelType } from '@typegoose/typegoose'; +import { addDays, addSeconds, subSeconds } from 'date-fns'; +import { Connection, createConnection } from 'mongoose'; + +import { Certificate as CertificateModel } from '../models'; +import { MongoCertificateStore } from './MongoCertificateStore'; + +let connection: Connection; +let certificateModel: ReturnModelType; +beforeAll(async () => { + connection = await createConnection((global as any).__MONGO_URI__, { + useNewUrlParser: true, + useUnifiedTopology: true, + }); + certificateModel = getModelForClass(CertificateModel, { existingConnection: connection }); +}); + +beforeEach(async () => { + await certificateModel.deleteMany(); +}); + +afterAll(async () => { + await connection.close(); +}); + +let identityKeyPair: CryptoKeyPair; +let subjectPrivateAddress: string; +let validCertificate: Certificate; +let expiredCertificate: Certificate; +beforeAll(async () => { + identityKeyPair = await generateRSAKeyPair(); + subjectPrivateAddress = await getPrivateAddressFromIdentityKey(identityKeyPair.publicKey); + + validCertificate = await issueGatewayCertificate({ + issuerPrivateKey: identityKeyPair.privateKey, + subjectPublicKey: identityKeyPair.publicKey, + validityEndDate: addSeconds(new Date(), 15), + }); + expiredCertificate = await issueGatewayCertificate({ + issuerPrivateKey: identityKeyPair.privateKey, + subjectPublicKey: identityKeyPair.publicKey, + validityEndDate: subSeconds(new Date(), 1), + validityStartDate: subSeconds(new Date(), 2), + }); +}); + +describe('saveData', () => { + test('All attributes should be saved', async () => { + const store = new MongoCertificateStore(connection); + + await store.save(validCertificate); + + const certificateStored = await certificateModel.findOne({ subjectPrivateAddress }).exec(); + expect(certificateStored).toMatchObject>({ + certificateSerialized: Buffer.from(validCertificate.serialize()), + expiryDate: validCertificate.expiryDate, + }); + }); + + test('The same subject should be allowed to have multiple certificates', async () => { + const store = new MongoCertificateStore(connection); + const certificate2 = await issueGatewayCertificate({ + issuerPrivateKey: identityKeyPair.privateKey, + subjectPublicKey: identityKeyPair.publicKey, + validityEndDate: addDays(validCertificate.expiryDate, 1), + }); + + await store.save(validCertificate); + await store.save(certificate2); + + const certificateRecords = await certificateModel.find({ subjectPrivateAddress }).exec(); + expect(certificateRecords).toHaveLength(2); + expect(certificateRecords[0]).toMatchObject>({ + certificateSerialized: Buffer.from(validCertificate.serialize()), + expiryDate: validCertificate.expiryDate, + }); + expect(certificateRecords[1]).toMatchObject>({ + certificateSerialized: Buffer.from(certificate2.serialize()), + expiryDate: certificate2.expiryDate, + }); + }); + + test('Certificates with the same subject and expiry date should be deduped', async () => { + const store = new MongoCertificateStore(connection); + const certificate2 = await issueGatewayCertificate({ + issuerPrivateKey: identityKeyPair.privateKey, + subjectPublicKey: identityKeyPair.publicKey, + validityEndDate: validCertificate.expiryDate, + }); + + await store.save(validCertificate); + await store.save(certificate2); + + const certificateRecords = await certificateModel.find({ subjectPrivateAddress }).exec(); + expect(certificateRecords).toHaveLength(1); + expect(certificateRecords[0]).toMatchObject>({ + certificateSerialized: Buffer.from(certificate2.serialize()), + expiryDate: certificate2.expiryDate, + }); + }); +}); + +describe('retrieveLatestSerialization', () => { + test('Nothing should be returned if subject has no certificates', async () => { + const store = new MongoCertificateStore(connection); + + await expect(store.retrieveLatest(subjectPrivateAddress)).resolves.toBeNull(); + }); + + test('Expired certificates should not be returned', async () => { + const store = new MongoCertificateStore(connection); + + await store.save(expiredCertificate); + + await expect(store.retrieveLatest(subjectPrivateAddress)).resolves.toBeNull(); + }); + + test('The latest valid certificate should be returned', async () => { + const store = new MongoCertificateStore(connection); + await store.save(validCertificate); + const newestCertificate = await issueGatewayCertificate({ + issuerPrivateKey: identityKeyPair.privateKey, + subjectPublicKey: identityKeyPair.publicKey, + validityEndDate: addSeconds(validCertificate.expiryDate, 1), + }); + await store.save(newestCertificate); + + await expect(store.retrieveLatest(subjectPrivateAddress)).resolves.toSatisfy((c) => + newestCertificate.isEqual(c), + ); + }); +}); + +describe('retrieveAllSerializations', () => { + test('Nothing should be returned if there are no certificates', async () => { + const store = new MongoCertificateStore(connection); + + await expect(store.retrieveAll(subjectPrivateAddress)).resolves.toBeEmpty(); + }); + + test('Expired certificates should not be returned', async () => { + const store = new MongoCertificateStore(connection); + await store.save(expiredCertificate); + + await expect(store.retrieveAll(subjectPrivateAddress)).resolves.toBeEmpty(); + }); + + test('All valid certificates should be returned', async () => { + const store = new MongoCertificateStore(connection); + await store.save(expiredCertificate); + await store.save(validCertificate); + const newestCertificate = await issueGatewayCertificate({ + issuerPrivateKey: identityKeyPair.privateKey, + subjectPublicKey: identityKeyPair.publicKey, + validityEndDate: addSeconds(validCertificate.expiryDate, 1), + }); + await store.save(newestCertificate); + + const allCertificates = await store.retrieveAll(subjectPrivateAddress); + + expect(allCertificates).toHaveLength(2); + expect(allCertificates.filter((c) => c.isEqual(validCertificate))).not.toBeEmpty(); + expect(allCertificates.filter((c) => c.isEqual(newestCertificate))).not.toBeEmpty(); + }); +}); + +describe('deleteExpired', () => { + test('Valid certificates should not be deleted', async () => { + const store = new MongoCertificateStore(connection); + await store.save(validCertificate); + + await store.deleteExpired(); + + await expect(store.retrieveAll(subjectPrivateAddress)).resolves.toHaveLength(1); + }); +}); diff --git a/src/keystores/MongoCertificateStore.ts b/src/keystores/MongoCertificateStore.ts new file mode 100644 index 000000000..2022c0e69 --- /dev/null +++ b/src/keystores/MongoCertificateStore.ts @@ -0,0 +1,59 @@ +import { CertificateStore } from '@relaycorp/relaynet-core'; +import { getModelForClass, ReturnModelType } from '@typegoose/typegoose'; +import bufferToArray from 'buffer-to-arraybuffer'; +import { Connection } from 'mongoose'; + +import { Certificate } from '../models'; + +export class MongoCertificateStore extends CertificateStore { + protected readonly certificateModel: ReturnModelType; + + constructor(connection: Connection) { + super(); + + this.certificateModel = getModelForClass(Certificate, { existingConnection: connection }); + } + + public async deleteExpired(): Promise { + // Do nothing. Trust that the model will delete expired records. + } + + protected async saveData( + subjectPrivateAddress: string, + subjectCertificateSerialized: ArrayBuffer, + subjectCertificateExpiryDate: Date, + ): Promise { + const record: Certificate = { + certificateSerialized: Buffer.from(subjectCertificateSerialized), + expiryDate: subjectCertificateExpiryDate, + subjectPrivateAddress, + }; + await this.certificateModel + .updateOne( + { + expiryDate: subjectCertificateExpiryDate, + subjectPrivateAddress, + }, + record, + { upsert: true }, + ) + .exec(); + } + + protected async retrieveLatestSerialization( + subjectPrivateAddress: string, + ): Promise { + const record = await this.certificateModel + .findOne({ subjectPrivateAddress }) + .sort({ expiryDate: -1 }) + .exec(); + return record ? bufferToArray(record.certificateSerialized) : null; + } + + protected async retrieveAllSerializations( + subjectPrivateAddress: string, + ): Promise { + const records = await this.certificateModel.find({ subjectPrivateAddress }).exec(); + return records.map((r) => bufferToArray(r.certificateSerialized)); + } +} diff --git a/src/models.ts b/src/models.ts index 77dc13e62..459c55319 100644 --- a/src/models.ts +++ b/src/models.ts @@ -4,11 +4,26 @@ import { index, prop } from '@typegoose/typegoose'; const SECONDS_IN_A_DAY = 86400; +/** + * @deprecated Use [Certificate] instead + */ export class OwnCertificate { @prop({ required: true }) public serializationDer!: Buffer; } +@index({ subjectPrivateAddress: 1 }) +export class Certificate { + @prop({ required: true }) + public subjectPrivateAddress!: string; + + @prop({ required: true }) + public certificateSerialized!: Buffer; + + @prop({ required: true, expires: 0 }) + public expiryDate!: Date; +} + export class PeerPublicKeyData { protected static TTL_DAYS = 30; From 4d170306316a46d1e32f9a706b477672eb9da1e3 Mon Sep 17 00:00:00 2001 From: Gus Narea Date: Tue, 30 Nov 2021 15:00:24 +0000 Subject: [PATCH 05/24] implement key/value config --- src/_test_utils.ts | 18 +++++++ src/keystores/MongoCertificateStore.spec.ts | 29 ++-------- src/keystores/MongoCertificateStore.ts | 2 +- src/models.ts | 8 +++ src/utilities/config.spec.ts | 60 +++++++++++++++++++++ src/utilities/config.ts | 26 +++++++++ 6 files changed, 118 insertions(+), 25 deletions(-) create mode 100644 src/utilities/config.spec.ts create mode 100644 src/utilities/config.ts diff --git a/src/_test_utils.ts b/src/_test_utils.ts index 8ce7b0d26..d1dad9585 100644 --- a/src/_test_utils.ts +++ b/src/_test_utils.ts @@ -9,6 +9,7 @@ import { } from '@relaycorp/relaynet-core'; import bufferToArray from 'buffer-to-arraybuffer'; import { BinaryLike, createHash, Hash } from 'crypto'; +import { Connection, createConnection } from 'mongoose'; import pino, { symbols as PinoSymbols } from 'pino'; import split2 from 'split2'; @@ -219,3 +220,20 @@ export function useFakeTimers(): void { jest.useRealTimers(); }); } + +export function setUpTestDBConnection(): () => Connection { + let connection: Connection; + + beforeAll(async () => { + connection = await createConnection((global as any).__MONGO_URI__, { + useNewUrlParser: true, + useUnifiedTopology: true, + }); + }); + + afterAll(async () => { + await connection.close(); + }); + + return () => connection; +} diff --git a/src/keystores/MongoCertificateStore.spec.ts b/src/keystores/MongoCertificateStore.spec.ts index 7baba1a64..9706a55f6 100644 --- a/src/keystores/MongoCertificateStore.spec.ts +++ b/src/keystores/MongoCertificateStore.spec.ts @@ -6,29 +6,24 @@ import { } from '@relaycorp/relaynet-core'; import { getModelForClass, ReturnModelType } from '@typegoose/typegoose'; import { addDays, addSeconds, subSeconds } from 'date-fns'; -import { Connection, createConnection } from 'mongoose'; +import { setUpTestDBConnection } from '../_test_utils'; import { Certificate as CertificateModel } from '../models'; import { MongoCertificateStore } from './MongoCertificateStore'; -let connection: Connection; +const getConnection = setUpTestDBConnection(); let certificateModel: ReturnModelType; +let store: MongoCertificateStore; beforeAll(async () => { - connection = await createConnection((global as any).__MONGO_URI__, { - useNewUrlParser: true, - useUnifiedTopology: true, - }); + const connection = getConnection(); certificateModel = getModelForClass(CertificateModel, { existingConnection: connection }); + store = new MongoCertificateStore(connection); }); beforeEach(async () => { await certificateModel.deleteMany(); }); -afterAll(async () => { - await connection.close(); -}); - let identityKeyPair: CryptoKeyPair; let subjectPrivateAddress: string; let validCertificate: Certificate; @@ -52,8 +47,6 @@ beforeAll(async () => { describe('saveData', () => { test('All attributes should be saved', async () => { - const store = new MongoCertificateStore(connection); - await store.save(validCertificate); const certificateStored = await certificateModel.findOne({ subjectPrivateAddress }).exec(); @@ -64,7 +57,6 @@ describe('saveData', () => { }); test('The same subject should be allowed to have multiple certificates', async () => { - const store = new MongoCertificateStore(connection); const certificate2 = await issueGatewayCertificate({ issuerPrivateKey: identityKeyPair.privateKey, subjectPublicKey: identityKeyPair.publicKey, @@ -87,7 +79,6 @@ describe('saveData', () => { }); test('Certificates with the same subject and expiry date should be deduped', async () => { - const store = new MongoCertificateStore(connection); const certificate2 = await issueGatewayCertificate({ issuerPrivateKey: identityKeyPair.privateKey, subjectPublicKey: identityKeyPair.publicKey, @@ -108,21 +99,16 @@ describe('saveData', () => { describe('retrieveLatestSerialization', () => { test('Nothing should be returned if subject has no certificates', async () => { - const store = new MongoCertificateStore(connection); - await expect(store.retrieveLatest(subjectPrivateAddress)).resolves.toBeNull(); }); test('Expired certificates should not be returned', async () => { - const store = new MongoCertificateStore(connection); - await store.save(expiredCertificate); await expect(store.retrieveLatest(subjectPrivateAddress)).resolves.toBeNull(); }); test('The latest valid certificate should be returned', async () => { - const store = new MongoCertificateStore(connection); await store.save(validCertificate); const newestCertificate = await issueGatewayCertificate({ issuerPrivateKey: identityKeyPair.privateKey, @@ -139,20 +125,16 @@ describe('retrieveLatestSerialization', () => { describe('retrieveAllSerializations', () => { test('Nothing should be returned if there are no certificates', async () => { - const store = new MongoCertificateStore(connection); - await expect(store.retrieveAll(subjectPrivateAddress)).resolves.toBeEmpty(); }); test('Expired certificates should not be returned', async () => { - const store = new MongoCertificateStore(connection); await store.save(expiredCertificate); await expect(store.retrieveAll(subjectPrivateAddress)).resolves.toBeEmpty(); }); test('All valid certificates should be returned', async () => { - const store = new MongoCertificateStore(connection); await store.save(expiredCertificate); await store.save(validCertificate); const newestCertificate = await issueGatewayCertificate({ @@ -172,7 +154,6 @@ describe('retrieveAllSerializations', () => { describe('deleteExpired', () => { test('Valid certificates should not be deleted', async () => { - const store = new MongoCertificateStore(connection); await store.save(validCertificate); await store.deleteExpired(); diff --git a/src/keystores/MongoCertificateStore.ts b/src/keystores/MongoCertificateStore.ts index 2022c0e69..200a49f4d 100644 --- a/src/keystores/MongoCertificateStore.ts +++ b/src/keystores/MongoCertificateStore.ts @@ -6,7 +6,7 @@ import { Connection } from 'mongoose'; import { Certificate } from '../models'; export class MongoCertificateStore extends CertificateStore { - protected readonly certificateModel: ReturnModelType; + private readonly certificateModel: ReturnModelType; constructor(connection: Connection) { super(); diff --git a/src/models.ts b/src/models.ts index 459c55319..87271983f 100644 --- a/src/models.ts +++ b/src/models.ts @@ -4,6 +4,14 @@ import { index, prop } from '@typegoose/typegoose'; const SECONDS_IN_A_DAY = 86400; +export class ConfigItem { + @prop({ required: true, unique: true }) + public key!: string; + + @prop({ required: true }) + public value!: string; +} + /** * @deprecated Use [Certificate] instead */ diff --git a/src/utilities/config.spec.ts b/src/utilities/config.spec.ts new file mode 100644 index 000000000..90d6d53ba --- /dev/null +++ b/src/utilities/config.spec.ts @@ -0,0 +1,60 @@ +import { getModelForClass, ReturnModelType } from '@typegoose/typegoose'; + +import { setUpTestDBConnection } from '../_test_utils'; +import { ConfigItem } from '../models'; +import { Config, ConfigKey } from './config'; + +const getConnection = setUpTestDBConnection(); +let configItemModel: ReturnModelType; +beforeAll(async () => { + configItemModel = getModelForClass(ConfigItem, { existingConnection: getConnection() }); +}); + +beforeEach(async () => { + await configItemModel.deleteMany(); +}); + +const PRIVATE_ADDRESS = '0deafbeef'; + +describe('Config', () => { + describe('set', () => { + test('Item should be created if it does not already exist', async () => { + const config = new Config(getConnection()); + + await config.set(ConfigKey.CURRENT_PRIVATE_ADDRESS, PRIVATE_ADDRESS); + + await expect( + configItemModel.countDocuments({ + key: ConfigKey.CURRENT_PRIVATE_ADDRESS, + value: PRIVATE_ADDRESS, + }), + ).resolves.toEqual(1); + }); + + test('Item should be updated if it already exists', async () => { + const config = new Config(getConnection()); + await config.set(ConfigKey.CURRENT_PRIVATE_ADDRESS, PRIVATE_ADDRESS); + const newValue = `new ${PRIVATE_ADDRESS}`; + await config.set(ConfigKey.CURRENT_PRIVATE_ADDRESS, newValue); + + await expect( + configItemModel.countDocuments({ key: ConfigKey.CURRENT_PRIVATE_ADDRESS, value: newValue }), + ).resolves.toEqual(1); + }); + }); + + describe('get', () => { + test('Null should be returned for non-existing item', async () => { + const config = new Config(getConnection()); + + await expect(config.get(ConfigKey.CURRENT_PRIVATE_ADDRESS)).resolves.toBeNull(); + }); + + test('Value should be returned if item exists', async () => { + const config = new Config(getConnection()); + await config.set(ConfigKey.CURRENT_PRIVATE_ADDRESS, PRIVATE_ADDRESS); + + await expect(config.get(ConfigKey.CURRENT_PRIVATE_ADDRESS)).resolves.toEqual(PRIVATE_ADDRESS); + }); + }); +}); diff --git a/src/utilities/config.ts b/src/utilities/config.ts new file mode 100644 index 000000000..ec8f05a8b --- /dev/null +++ b/src/utilities/config.ts @@ -0,0 +1,26 @@ +import { getModelForClass, ReturnModelType } from '@typegoose/typegoose'; + +import { Connection } from 'mongoose'; +import { ConfigItem } from '../models'; + +export enum ConfigKey { + CURRENT_PRIVATE_ADDRESS = 'current_private_address', +} + +export class Config { + private readonly configItemModel: ReturnModelType; + + constructor(connection: Connection) { + this.configItemModel = getModelForClass(ConfigItem, { existingConnection: connection }); + } + + public async set(key: ConfigKey, value: string): Promise { + const record: ConfigItem = { key, value }; + await this.configItemModel.updateOne({ key }, record, { upsert: true }); + } + + public async get(key: ConfigKey): Promise { + const record = await this.configItemModel.findOne({ key }).exec(); + return record?.value ?? null; + } +} From b3af393da6112038cc517e8117e4d31218a3e96d Mon Sep 17 00:00:00 2001 From: Gus Narea Date: Tue, 30 Nov 2021 15:35:28 +0000 Subject: [PATCH 06/24] update generate-keypairs.ts --- package-lock.json | 13 +++--- package.json | 4 +- src/bin/generate-keypairs.ts | 59 +++++++----------------- src/functionalTests/poweb_server.test.ts | 10 +--- src/functionalTests/utils.ts | 17 ------- 5 files changed, 26 insertions(+), 77 deletions(-) diff --git a/package-lock.json b/package-lock.json index e0a020f46..560504bbd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1418,9 +1418,9 @@ } }, "@relaycorp/relaynet-core": { - "version": "1.56.2", - "resolved": "https://registry.npmjs.org/@relaycorp/relaynet-core/-/relaynet-core-1.56.2.tgz", - "integrity": "sha512-RD4WjA61aW2SFmM9D7OLb4+jE19AkZEstQVNW0mzUHb2HCJ9MNVVw6Cu0yywgpQNTMBIK+GKiYtn2LLIVAhl0Q==", + "version": "1.57.0", + "resolved": "https://registry.npmjs.org/@relaycorp/relaynet-core/-/relaynet-core-1.57.0.tgz", + "integrity": "sha512-nAUK8UPHmWCmJIpJlE+u8lGUw/t91wRvJV5V2aaJ0GmZmIGbBDl7Aj9tdCjAJ47BFR8zXx8al/tsNF1HN7fCuA==", "requires": { "@peculiar/webcrypto": "^1.2.3", "@stablelib/aes-kw": "^1.0.1", @@ -3569,10 +3569,9 @@ "integrity": "sha512-7u+uNfnjWkX+YFQfivvW24TjaJG6ahvTrfw1auq7KlC7osuGcZBIWGBvB9UcENjH6JnLVhMqlRripk1dSHjAUA==" }, "date-fns": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.23.0.tgz", - "integrity": "sha512-5ycpauovVyAk0kXNZz6ZoB9AYMZB4DObse7P3BPWmyEjXNORTI8EJ6X0uaSAq4sCHzM1uajzrkr6HnsLQpxGXA==", - "dev": true + "version": "2.27.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.27.0.tgz", + "integrity": "sha512-sj+J0Mo2p2X1e306MHq282WS4/A8Pz/95GIFcsPNMPMZVI3EUrAdSv90al1k+p74WGLCruMXk23bfEDZa71X9Q==" }, "dateformat": { "version": "3.0.3", diff --git a/package.json b/package.json index be8fed969..e74f34cd8 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,6 @@ "@types/split2": "^3.2.1", "@types/verror": "^1.10.5", "@types/ws": "^7.4.7", - "date-fns": "^2.23.0", "fastify-plugin": "^3.0.0", "jest": "^26.6.3", "jest-extended": "^0.11.5", @@ -75,12 +74,13 @@ "@relaycorp/keystore-vault": "^1.2.12", "@relaycorp/object-storage": "^1.4.5", "@relaycorp/pino-cloud": "^1.0.4", - "@relaycorp/relaynet-core": "^1.56.2", + "@relaycorp/relaynet-core": "^1.57.0", "@relaycorp/relaynet-pohttp": "^1.7.6", "@typegoose/typegoose": "^8.1.1", "abort-controller": "^3.0.0", "abortable-iterator": "^3.0.0", "buffer-to-arraybuffer": "0.0.6", + "date-fns": "^2.27.0", "env-var": "^7.0.1", "fastify": "^3.20.2", "fastify-mongoose": "^0.3.0", diff --git a/src/bin/generate-keypairs.ts b/src/bin/generate-keypairs.ts index e7ae53e9d..bebdbfdc8 100644 --- a/src/bin/generate-keypairs.ts +++ b/src/bin/generate-keypairs.ts @@ -1,11 +1,10 @@ -import { Certificate, generateRSAKeyPair, issueGatewayCertificate } from '@relaycorp/relaynet-core'; -import { getModelForClass } from '@typegoose/typegoose'; -import bufferToArray from 'buffer-to-arraybuffer'; -import { get as getEnvVar } from 'env-var'; +import { generateRSAKeyPair, issueGatewayCertificate } from '@relaycorp/relaynet-core'; +import { addDays } from 'date-fns'; import { createMongooseConnectionFromEnv } from '../backingServices/mongo'; import { initVaultKeyStore } from '../backingServices/vault'; -import { OwnCertificate } from '../models'; +import { MongoCertificateStore } from '../keystores/MongoCertificateStore'; +import { Config, ConfigKey } from '../utilities/config'; import { configureExitHandling } from '../utilities/exitHandling'; import { makeLogger } from '../utilities/logging'; @@ -14,57 +13,33 @@ configureExitHandling(LOGGER); const NODE_CERTIFICATE_TTL_DAYS = 360; -const KEY_ID_BASE64 = getEnvVar('GATEWAY_KEY_ID').required().asString(); - const privateKeyStore = initVaultKeyStore(); async function main(): Promise { - const keyId = Buffer.from(KEY_ID_BASE64, 'base64'); - try { - await privateKeyStore.fetchNodeKey(keyId); - LOGGER.warn(`Gateway key ${KEY_ID_BASE64} already exists`); + const connection = await createMongooseConnectionFromEnv(); + const config = new Config(connection); + + const currentPrivateAddress = await config.get(ConfigKey.CURRENT_PRIVATE_ADDRESS); + if (currentPrivateAddress) { + LOGGER.info({ privateAddress: currentPrivateAddress }, `Gateway key pair already exists`); return; - } catch (error) { - LOGGER.info(`Gateway key will be created because it doesn't already exist`); } + LOGGER.info(`Gateway key will be created because it doesn't already exist`); const gatewayKeyPair = await generateRSAKeyPair(); + const privateAddress = await privateKeyStore.saveIdentityKey(gatewayKeyPair.privateKey); - const nodeCertEndDate = new Date(); - nodeCertEndDate.setDate(nodeCertEndDate.getDate() + NODE_CERTIFICATE_TTL_DAYS); + const certificateStore = new MongoCertificateStore(connection); const gatewayCertificate = await issueGatewayCertificate({ issuerPrivateKey: gatewayKeyPair.privateKey, subjectPublicKey: gatewayKeyPair.publicKey, - validityEndDate: nodeCertEndDate, + validityEndDate: addDays(new Date(), NODE_CERTIFICATE_TTL_DAYS), }); - // Force the certificate to have the serial number specified in GATEWAY_KEY_ID. This nasty - // hack won't be necessary once https://github.com/relaycorp/relaynet-internet-gateway/issues/49 - // is done. - // tslint:disable-next-line:no-object-mutation - (gatewayCertificate as any).pkijsCertificate.serialNumber.valueBlock.valueHex = - bufferToArray(keyId); - - await privateKeyStore.saveNodeKey(gatewayKeyPair.privateKey, gatewayCertificate); - await saveOwnCertificate(gatewayCertificate); + await certificateStore.save(gatewayCertificate); - LOGGER.info( - { - gatewayCertificate: base64Encode(gatewayCertificate.serialize()), - keyPairId: KEY_ID_BASE64, - }, - 'Identity key pair was successfully generated', - ); -} - -async function saveOwnCertificate(certificate: Certificate): Promise { - const connection = await createMongooseConnectionFromEnv(); - const ownCertificateModel = getModelForClass(OwnCertificate, { existingConnection: connection }); - await ownCertificateModel.create({ serializationDer: Buffer.from(certificate.serialize()) }); - await connection.close(); -} + await config.set(ConfigKey.CURRENT_PRIVATE_ADDRESS, privateAddress); -function base64Encode(payload: ArrayBuffer | Buffer): string { - return Buffer.from(payload).toString('base64'); + LOGGER.info({ privateAddress }, 'Identity key pair was successfully generated'); } main(); diff --git a/src/functionalTests/poweb_server.test.ts b/src/functionalTests/poweb_server.test.ts index 50d2c2f9a..7a37e6d49 100644 --- a/src/functionalTests/poweb_server.test.ts +++ b/src/functionalTests/poweb_server.test.ts @@ -19,12 +19,7 @@ import pipe from 'it-pipe'; import { asyncIterableToArray, ExternalPdaChain, iterableTake } from '../_test_utils'; import { expectBuffersToEqual } from '../services/_test_utils'; import { GW_POWEB_LOCAL_PORT } from './services'; -import { - createAndRegisterPrivateGateway, - getPublicGatewayCertificate, - registerPrivateGateway, - sleep, -} from './utils'; +import { createAndRegisterPrivateGateway, registerPrivateGateway, sleep } from './utils'; describe('PoWeb server', () => { describe('Node registration', () => { @@ -38,9 +33,6 @@ describe('PoWeb server', () => { derSerializePublicKey(await registration.privateNodeCertificate.getPublicKey()), ).resolves.toEqual(await derSerializePublicKey(privateGatewayKeyPair.publicKey)); - const actualPublicGatewayCertificate = await getPublicGatewayCertificate(); - expect(actualPublicGatewayCertificate.isEqual(registration.gatewayCertificate)).toBeTrue(); - await expect( registration.privateNodeCertificate.getCertificationPath( [], diff --git a/src/functionalTests/utils.ts b/src/functionalTests/utils.ts index c3d4666a8..2d409518c 100644 --- a/src/functionalTests/utils.ts +++ b/src/functionalTests/utils.ts @@ -1,13 +1,11 @@ import { initObjectStoreClient, ObjectStoreClient } from '@relaycorp/object-storage'; import { - Certificate, generateRSAKeyPair, issueDeliveryAuthorization, issueEndpointCertificate, PrivateNodeRegistration, PrivateNodeRegistrationRequest, SessionKey, - UnboundKeyPair, } from '@relaycorp/relaynet-core'; import { PoWebClient } from '@relaycorp/relaynet-poweb'; import { get as getEnvVar } from 'env-var'; @@ -15,7 +13,6 @@ import { connect as stanConnect, Stan } from 'node-nats-streaming'; import uuid from 'uuid-random'; import { ExternalPdaChain } from '../_test_utils'; -import { initVaultKeyStore } from '../backingServices/vault'; import { GW_POWEB_LOCAL_PORT } from './services'; export const IS_GITHUB = getEnvVar('IS_GITHUB').asBool(); @@ -47,20 +44,6 @@ export function connectToNatsStreaming(): Promise { }); } -async function getPublicGatewayKeyPair(): Promise { - const privateKeyStore = initVaultKeyStore(); - const publicGatewayKeyId = Buffer.from( - getEnvVar('GATEWAY_KEY_ID').required().asString(), - 'base64', - ); - return privateKeyStore.fetchNodeKey(publicGatewayKeyId); -} - -export async function getPublicGatewayCertificate(): Promise { - const keyPair = await getPublicGatewayKeyPair(); - return keyPair.certificate; -} - export interface PrivateGatewayRegistration { readonly pdaChain: ExternalPdaChain; readonly publicGatewaySessionKey: SessionKey; From 2171fd63e26aa81dd8c7ee1d79b4ba1eb21fd376 Mon Sep 17 00:00:00 2001 From: Gus Narea Date: Tue, 30 Nov 2021 16:56:58 +0000 Subject: [PATCH 07/24] update CogRPC service --- src/_test_utils.ts | 17 +++++-- src/backingServices/mongo.spec.ts | 15 ++++-- src/backingServices/mongo.ts | 2 +- src/services/cogrpc/server.spec.ts | 5 +- src/services/cogrpc/server.ts | 4 +- src/services/cogrpc/service.spec.ts | 71 ++++++++++++++++------------- src/services/cogrpc/service.ts | 17 ++++--- 7 files changed, 77 insertions(+), 54 deletions(-) diff --git a/src/_test_utils.ts b/src/_test_utils.ts index d1dad9585..6a264ce88 100644 --- a/src/_test_utils.ts +++ b/src/_test_utils.ts @@ -224,15 +224,26 @@ export function useFakeTimers(): void { export function setUpTestDBConnection(): () => Connection { let connection: Connection; - beforeAll(async () => { - connection = await createConnection((global as any).__MONGO_URI__, { + const connect = () => + createConnection((global as any).__MONGO_URI__, { useNewUrlParser: true, useUnifiedTopology: true, }); + + beforeAll(async () => { + connection = await connect(); + }); + + beforeEach(async () => { + if (connection.readyState === 0) { + connection = await connect(); + } }); afterAll(async () => { - await connection.close(); + if (connection.readyState !== 0) { + await connection.close(); + } }); return () => connection; diff --git a/src/backingServices/mongo.spec.ts b/src/backingServices/mongo.spec.ts index 1280c27b1..425365f4b 100644 --- a/src/backingServices/mongo.spec.ts +++ b/src/backingServices/mongo.spec.ts @@ -2,6 +2,7 @@ import { EnvVarError } from 'env-var'; import mongoose, { Connection } from 'mongoose'; import { mockSpy, MONGO_ENV_VARS } from '../_test_utils'; +import { MongoCertificateStore } from '../keystores/MongoCertificateStore'; import { MongoPublicKeyStore } from '../keystores/MongoPublicKeyStore'; import { configureMockEnvVars } from '../services/_test_utils'; import { @@ -10,7 +11,7 @@ import { initMongoDBKeyStore, } from './mongo'; -const MOCK_MONGOOSE_CONNECTION = { what: 'The connection' }; +const MOCK_MONGOOSE_CONNECTION = { model: { bind: mockSpy(jest.fn()) } } as any as Connection; const MOCK_MONGOOSE_CREATE_CONNECTION = mockSpy( jest.spyOn(mongoose, 'createConnection'), jest.fn().mockResolvedValue(MOCK_MONGOOSE_CONNECTION), @@ -125,11 +126,17 @@ describe('createMongooseConnectionFromEnv', () => { }); describe('initMongoDBKeyStore', () => { - const mongooseConnection = { model: { bind: jest.fn() } } as any as Connection; - test('MongoPublicKeyStore instance should be returned', () => { - const keyStore = initMongoDBKeyStore(mongooseConnection); + const keyStore = initMongoDBKeyStore(MOCK_MONGOOSE_CONNECTION); expect(keyStore).toBeInstanceOf(MongoPublicKeyStore); }); }); + +describe('initMongoDBCertificateStore', () => { + test('MongoCertificateStore instance should be returned', () => { + const certStore = initMongoDBKeyStore(MOCK_MONGOOSE_CONNECTION); + + expect(certStore).toBeInstanceOf(MongoCertificateStore); + }); +}); diff --git a/src/backingServices/mongo.ts b/src/backingServices/mongo.ts index 0c169bdee..55ffa6c68 100644 --- a/src/backingServices/mongo.ts +++ b/src/backingServices/mongo.ts @@ -30,7 +30,7 @@ export async function createMongooseConnectionFromEnv(): Promise { } /** - * Return the public key store used by the gateway. + * Return the public key store. * * @param connection * diff --git a/src/services/cogrpc/server.spec.ts b/src/services/cogrpc/server.spec.ts index 3e37b47a2..5ffe16b2d 100644 --- a/src/services/cogrpc/server.spec.ts +++ b/src/services/cogrpc/server.spec.ts @@ -5,6 +5,7 @@ import { Logger } from 'pino'; import selfsigned from 'selfsigned'; import { makeMockLogging, mockSpy, partialPinoLog } from '../../_test_utils'; +import { createMongooseConnectionFromEnv } from '../../backingServices/mongo'; import { MAX_RAMF_MESSAGE_SIZE } from '../../constants'; import * as exitHandling from '../../utilities/exitHandling'; import * as logging from '../../utilities/logging'; @@ -37,7 +38,6 @@ const mockSelfSigned = mockSpy(jest.spyOn(selfsigned, 'generate'), () => mockSel const mockExitHandler = mockSpy(jest.spyOn(exitHandling, 'configureExitHandling')); const BASE_ENV_VARS = { - GATEWAY_KEY_ID: 'base64-encoded key id', NATS_CLUSTER_ID: 'nats-cluster-id', NATS_SERVER_URL: 'nats://example.com', OBJECT_STORE_BUCKET: 'bucket-name', @@ -58,7 +58,6 @@ describe('runServer', () => { }); test.each([ - 'GATEWAY_KEY_ID', 'NATS_SERVER_URL', 'NATS_CLUSTER_ID', 'OBJECT_STORE_BUCKET', @@ -129,7 +128,7 @@ describe('runServer', () => { debug: expect.anything(), error: expect.anything(), }), - gatewayKeyIdBase64: BASE_ENV_VARS.GATEWAY_KEY_ID, + getMongooseConnection: createMongooseConnectionFromEnv, natsClusterId: BASE_ENV_VARS.NATS_CLUSTER_ID, natsServerUrl: BASE_ENV_VARS.NATS_SERVER_URL, parcelStoreBucket: BASE_ENV_VARS.OBJECT_STORE_BUCKET, diff --git a/src/services/cogrpc/server.ts b/src/services/cogrpc/server.ts index 2df6e0fcf..c33346672 100644 --- a/src/services/cogrpc/server.ts +++ b/src/services/cogrpc/server.ts @@ -4,6 +4,7 @@ import { get as getEnvVar } from 'env-var'; import * as grpcHealthCheck from 'grpc-js-health-check'; import { Logger } from 'pino'; import * as selfsigned from 'selfsigned'; +import { createMongooseConnectionFromEnv } from '../../backingServices/mongo'; import { configureExitHandling } from '../../utilities/exitHandling'; import { MAX_RAMF_MESSAGE_SIZE } from '../../constants'; @@ -23,7 +24,6 @@ export async function runServer(logger?: Logger): Promise { const baseLogger = logger ?? makeLogger(); configureExitHandling(baseLogger); - const gatewayKeyIdBase64 = getEnvVar('GATEWAY_KEY_ID').required().asString(); const publicAddress = getEnvVar('PUBLIC_ADDRESS').required().asString(); const parcelStoreBucket = getEnvVar('OBJECT_STORE_BUCKET').required().asString(); const natsServerUrl = getEnvVar('NATS_SERVER_URL').required().asString(); @@ -40,7 +40,7 @@ export async function runServer(logger?: Logger): Promise { const serviceImplementation = await makeServiceImplementation({ baseLogger, - gatewayKeyIdBase64, + getMongooseConnection: createMongooseConnectionFromEnv, natsClusterId, natsServerUrl, parcelStoreBucket, diff --git a/src/services/cogrpc/service.spec.ts b/src/services/cogrpc/service.spec.ts index 8bb04d886..5683db88b 100644 --- a/src/services/cogrpc/service.spec.ts +++ b/src/services/cogrpc/service.spec.ts @@ -9,7 +9,6 @@ import { InvalidMessageError, issueEndpointCertificate, MockPrivateKeyStore, - MockPublicKeyStore, Parcel, ParcelCollectionAck, RAMFSyntaxError, @@ -18,10 +17,9 @@ import { SessionKeyPair, UnknownKeyError, } from '@relaycorp/relaynet-core'; -import * as typegoose from '@typegoose/typegoose'; import bufferToArray from 'buffer-to-arraybuffer'; +import { addDays } from 'date-fns'; import { EventEmitter } from 'events'; -import mongoose from 'mongoose'; import { arrayBufferFrom, @@ -34,15 +32,17 @@ import { partialPinoLog, partialPinoLogger, PdaChain, + setUpTestDBConnection, UUID4_REGEX, } from '../../_test_utils'; -import * as mongo from '../../backingServices/mongo'; import * as natsStreaming from '../../backingServices/natsStreaming'; import * as vault from '../../backingServices/vault'; import * as ccaFulfillments from '../../ccaFulfilments'; import * as certs from '../../certs'; +import { MongoCertificateStore } from '../../keystores/MongoCertificateStore'; import * as parcelCollectionAck from '../../parcelCollection'; import { ParcelStore } from '../../parcelStore'; +import { Config, ConfigKey } from '../../utilities/config'; import { configureMockEnvVars, generatePdaChain, getMockInstance } from '../_test_utils'; import { MockGrpcBidiCall } from './_test_utils'; import { makeServiceImplementation, ServiceImplementationOptions } from './service'; @@ -55,8 +55,7 @@ const OBJECT_STORE_BUCKET = 'parcels-bucket'; const NATS_SERVER_URL = 'nats://example.com'; const NATS_CLUSTER_ID = 'nats-cluster-id'; -const TOMORROW = new Date(); -TOMORROW.setDate(TOMORROW.getDate() + 1); +const TOMORROW = addDays(new Date(), 1); let pdaChain: PdaChain; let cdaChain: CDAChain; @@ -67,12 +66,7 @@ beforeAll(async () => { privateGatewayAddress = await pdaChain.privateGatewayCert.calculateSubjectPrivateAddress(); }); -const MOCK_MONGOOSE_CONNECTION: mongoose.Connection = new EventEmitter() as any; -const MOCK_CREATE_MONGOOSE_CONNECTION = mockSpy( - jest.spyOn(mongo, 'createMongooseConnectionFromEnv'), - jest.fn().mockResolvedValue(MOCK_MONGOOSE_CONNECTION), -); -beforeEach(() => MOCK_MONGOOSE_CONNECTION.removeAllListeners()); +const getMongooseConnection = setUpTestDBConnection(); configureMockEnvVars({ OBJECT_STORE_ACCESS_KEY_ID: 'id', @@ -91,7 +85,7 @@ beforeEach(() => { MOCK_LOGS = mockLogging.logs; SERVICE_IMPLEMENTATION_OPTIONS = { baseLogger: mockLogging.logger, - gatewayKeyIdBase64: pdaChain.publicGatewayCert.getSerialNumber().toString('base64'), + getMongooseConnection: jest.fn().mockImplementation(getMongooseConnection), natsClusterId: NATS_CLUSTER_ID, natsServerUrl: NATS_SERVER_URL, parcelStoreBucket: OBJECT_STORE_BUCKET, @@ -104,16 +98,18 @@ beforeEach(() => { describe('makeServiceImplementation', () => { describe('Mongoose connection', () => { test('Connection should be created preemptively before any RPC', async () => { - expect(MOCK_CREATE_MONGOOSE_CONNECTION).not.toBeCalled(); + expect(SERVICE_IMPLEMENTATION_OPTIONS.getMongooseConnection).not.toBeCalled(); await makeServiceImplementation(SERVICE_IMPLEMENTATION_OPTIONS); - expect(MOCK_CREATE_MONGOOSE_CONNECTION).toBeCalledTimes(1); + expect(SERVICE_IMPLEMENTATION_OPTIONS.getMongooseConnection).toBeCalled(); }); test('Errors while establishing connection should be propagated', async () => { const error = new Error('Database credentials are wrong'); - MOCK_CREATE_MONGOOSE_CONNECTION.mockRejectedValue(error); + getMockInstance(SERVICE_IMPLEMENTATION_OPTIONS.getMongooseConnection).mockRejectedValue( + error, + ); await expect(makeServiceImplementation(SERVICE_IMPLEMENTATION_OPTIONS)).rejects.toEqual( error, @@ -121,11 +117,15 @@ describe('makeServiceImplementation', () => { }); test('Errors after establishing connection should be logged', async (cb) => { + const mockConnection = new EventEmitter(); + getMockInstance(SERVICE_IMPLEMENTATION_OPTIONS.getMongooseConnection).mockResolvedValue( + mockConnection, + ); await makeServiceImplementation(SERVICE_IMPLEMENTATION_OPTIONS); const error = new Error('Database credentials are wrong'); - MOCK_MONGOOSE_CONNECTION.on('error', (err) => { + mockConnection.on('error', (err) => { expect(MOCK_LOGS).toContainEqual( partialPinoLog('error', 'Mongoose connection error', { err: expect.objectContaining({ message: err.message }), @@ -133,7 +133,7 @@ describe('makeServiceImplementation', () => { ); cb(); }); - MOCK_MONGOOSE_CONNECTION.emit('error', error); + mockConnection.emit('error', error); }); }); }); @@ -405,28 +405,37 @@ describe('deliverCargo', () => { describe('collectCargo', () => { const PRIVATE_KEY_STORE = new MockPrivateKeyStore(); - mockSpy(jest.spyOn(vault, 'initVaultKeyStore'), () => PRIVATE_KEY_STORE); let publicGatewaySessionKeyPair: SessionKeyPair; beforeAll(async () => { publicGatewaySessionKeyPair = await SessionKeyPair.generate(); }); beforeEach(async () => { PRIVATE_KEY_STORE.clear(); - await PRIVATE_KEY_STORE.registerNodeKey( - pdaChain.publicGatewayPrivateKey, - pdaChain.publicGatewayCert, - ); - await PRIVATE_KEY_STORE.saveSubsequentSessionKey( + await PRIVATE_KEY_STORE.saveIdentityKey(pdaChain.publicGatewayPrivateKey); + await PRIVATE_KEY_STORE.saveBoundSessionKey( publicGatewaySessionKeyPair.privateKey, publicGatewaySessionKeyPair.sessionKey.keyId, privateGatewayAddress, ); }); + mockSpy(jest.spyOn(vault, 'initVaultKeyStore'), () => PRIVATE_KEY_STORE); - const PUBLIC_KEYS_STORE = new MockPublicKeyStore(); - mockSpy(jest.spyOn(mongo, 'initMongoDBKeyStore'), (connection) => { - expect(connection).toBe(MOCK_MONGOOSE_CONNECTION); - return PUBLIC_KEYS_STORE; + beforeEach(async () => { + const connection = getMongooseConnection(); + + const certificateStore = new MongoCertificateStore(connection); + await certificateStore.save(pdaChain.publicGatewayCert); + + const config = new Config(connection); + await config.set( + ConfigKey.CURRENT_PRIVATE_ADDRESS, + await pdaChain.publicGatewayCert.calculateSubjectPrivateAddress(), + ); + }); + afterEach(async () => { + const connection = getMongooseConnection(); + + Object.values(connection.collections).map((c) => c.deleteMany({})); }); let SERVICE: CargoRelayServerMethodSet; @@ -450,8 +459,6 @@ describe('collectCargo', () => { }, ); - mockSpy(jest.spyOn(typegoose, 'getModelForClass')); - const MOCK_WAS_CCA_FULFILLED = mockSpy( jest.spyOn(ccaFulfillments, 'wasCCAFulfilled'), async () => false, @@ -830,7 +837,7 @@ describe('collectCargo', () => { expect(MOCK_GENERATE_PCAS).toBeCalledTimes(1); expect(MOCK_GENERATE_PCAS).toBeCalledWith( await pdaChain.privateGatewayCert.calculateSubjectPrivateAddress(), - MOCK_MONGOOSE_CONNECTION, + getMongooseConnection(), ); }); @@ -888,7 +895,7 @@ describe('collectCargo', () => { const cca = await CargoCollectionAuthorization.deserialize(bufferToArray(ccaSerialized)); expect(MOCK_RECORD_CCA_FULFILLMENT).toBeCalledWith( expect.objectContaining({ id: cca.id }), - MOCK_MONGOOSE_CONNECTION, + getMongooseConnection(), ); }); diff --git a/src/services/cogrpc/service.ts b/src/services/cogrpc/service.ts index 286ca650c..a13caff83 100644 --- a/src/services/cogrpc/service.ts +++ b/src/services/cogrpc/service.ts @@ -14,7 +14,7 @@ import { Connection } from 'mongoose'; import { Logger } from 'pino'; import uuid from 'uuid-random'; -import { createMongooseConnectionFromEnv, initMongoDBKeyStore } from '../../backingServices/mongo'; +import { initMongoDBKeyStore } from '../../backingServices/mongo'; import { NatsStreamingClient, PublisherMessage } from '../../backingServices/natsStreaming'; import { initObjectStoreFromEnv } from '../../backingServices/objectStorage'; import { initVaultKeyStore } from '../../backingServices/vault'; @@ -22,6 +22,7 @@ import { recordCCAFulfillment, wasCCAFulfilled } from '../../ccaFulfilments'; import { retrieveOwnCertificates } from '../../certs'; import { generatePCAs } from '../../parcelCollection'; import { ParcelObject, ParcelStore } from '../../parcelStore'; +import { Config, ConfigKey } from '../../utilities/config'; const INTERNAL_SERVER_ERROR = { code: grpc.status.UNAVAILABLE, @@ -30,7 +31,7 @@ const INTERNAL_SERVER_ERROR = { export interface ServiceImplementationOptions { readonly baseLogger: Logger; - readonly gatewayKeyIdBase64: string; + readonly getMongooseConnection: () => Promise; readonly parcelStoreBucket: string; readonly natsServerUrl: string; readonly natsClusterId: string; @@ -43,11 +44,9 @@ export async function makeServiceImplementation( const objectStoreClient = initObjectStoreFromEnv(); const parcelStore = new ParcelStore(objectStoreClient, options.parcelStoreBucket); - const currentKeyId = Buffer.from(options.gatewayKeyIdBase64, 'base64'); - const vaultKeyStore = initVaultKeyStore(); - const mongooseConnection = await createMongooseConnectionFromEnv(); + const mongooseConnection = await options.getMongooseConnection(); mongooseConnection.on('error', (err) => options.baseLogger.error({ err }, 'Mongoose connection error'), ); @@ -79,7 +78,6 @@ export async function makeServiceImplementation( call, mongooseConnection, options.publicAddress, - currentKeyId, parcelStore, vaultKeyStore, logger, @@ -149,7 +147,6 @@ async function collectCargo( call: grpc.ServerDuplexStream, mongooseConnection: Connection, ownPublicAddress: string, - currentKeyId: Buffer, parcelStore: ParcelStore, vaultKeyStore: VaultPrivateKeyStore, logger: Logger, @@ -224,10 +221,12 @@ async function collectCargo( let cargoesCollected = 0; async function* encapsulateMessagesInCargo(messages: CargoMessageStream): AsyncIterable { - const { privateKey } = await vaultKeyStore.fetchNodeKey(currentKeyId); + const config = new Config(mongooseConnection); + const privateAddress = await config.get(ConfigKey.CURRENT_PRIVATE_ADDRESS); + const privateKey = await vaultKeyStore.retrieveIdentityKey(privateAddress!!); yield* await gateway.generateCargoes( messages, - cca.senderCertificate, + await cca.senderCertificate.calculateSubjectPrivateAddress(), privateKey, ccr.cargoDeliveryAuthorization, ); From 8428a7a297736be09beee1b16cac730b64fe9fef Mon Sep 17 00:00:00 2001 From: Gus Narea Date: Tue, 30 Nov 2021 17:15:02 +0000 Subject: [PATCH 08/24] refactor --- src/_test_utils.ts | 11 +++-- src/keystores/MongoCertificateStore.spec.ts | 4 -- src/services/cogrpc/service.spec.ts | 54 ++++++++------------- src/utilities/config.spec.ts | 4 -- 4 files changed, 26 insertions(+), 47 deletions(-) diff --git a/src/_test_utils.ts b/src/_test_utils.ts index 6a264ce88..367bacc37 100644 --- a/src/_test_utils.ts +++ b/src/_test_utils.ts @@ -187,6 +187,7 @@ export async function generateCDAChain(pdaChain: ExternalPdaChain): Promise Connection { } }); + afterEach(async () => { + Object.values(connection.collections).map((c) => c.deleteMany({})); + }); + afterAll(async () => { - if (connection.readyState !== 0) { - await connection.close(); - } + await connection.close(true); }); return () => connection; diff --git a/src/keystores/MongoCertificateStore.spec.ts b/src/keystores/MongoCertificateStore.spec.ts index 9706a55f6..b585ce4fd 100644 --- a/src/keystores/MongoCertificateStore.spec.ts +++ b/src/keystores/MongoCertificateStore.spec.ts @@ -20,10 +20,6 @@ beforeAll(async () => { store = new MongoCertificateStore(connection); }); -beforeEach(async () => { - await certificateModel.deleteMany(); -}); - let identityKeyPair: CryptoKeyPair; let subjectPrivateAddress: string; let validCertificate: Certificate; diff --git a/src/services/cogrpc/service.spec.ts b/src/services/cogrpc/service.spec.ts index 5683db88b..ad9a4f531 100644 --- a/src/services/cogrpc/service.spec.ts +++ b/src/services/cogrpc/service.spec.ts @@ -37,7 +37,7 @@ import { } from '../../_test_utils'; import * as natsStreaming from '../../backingServices/natsStreaming'; import * as vault from '../../backingServices/vault'; -import * as ccaFulfillments from '../../ccaFulfilments'; +import { recordCCAFulfillment, wasCCAFulfilled } from '../../ccaFulfilments'; import * as certs from '../../certs'; import { MongoCertificateStore } from '../../keystores/MongoCertificateStore'; import * as parcelCollectionAck from '../../parcelCollection'; @@ -432,11 +432,6 @@ describe('collectCargo', () => { await pdaChain.publicGatewayCert.calculateSubjectPrivateAddress(), ); }); - afterEach(async () => { - const connection = getMongooseConnection(); - - Object.values(connection.collections).map((c) => c.deleteMany({})); - }); let SERVICE: CargoRelayServerMethodSet; beforeEach(async () => { @@ -459,15 +454,6 @@ describe('collectCargo', () => { }, ); - const MOCK_WAS_CCA_FULFILLED = mockSpy( - jest.spyOn(ccaFulfillments, 'wasCCAFulfilled'), - async () => false, - ); - const MOCK_RECORD_CCA_FULFILLMENT = mockSpy( - jest.spyOn(ccaFulfillments, 'recordCCAFulfillment'), - async () => null, - ); - let DUMMY_PARCEL: Parcel; let DUMMY_PARCEL_SERIALIZED: Buffer; beforeAll(async () => { @@ -485,6 +471,7 @@ describe('collectCargo', () => { DUMMY_PARCEL_SERIALIZED = Buffer.from(await DUMMY_PARCEL.serialize(keyPair.privateKey)); }); + let cca: CargoCollectionAuthorization; let ccaSerialized: Buffer; let privateGatewaySessionPrivateKey: CryptoKey; beforeAll(async () => { @@ -494,6 +481,7 @@ describe('collectCargo', () => { publicGatewaySessionKeyPair.sessionKey, pdaChain.privateGatewayPrivateKey, ); + cca = generatedCCA.cca; ccaSerialized = generatedCCA.ccaSerialized; privateGatewaySessionPrivateKey = generatedCCA.sessionPrivateKey; }); @@ -653,7 +641,7 @@ describe('collectCargo', () => { }); test('INVALID_ARGUMENT should be returned if CCA recipient is malformed', async (cb) => { - const cca = new CargoCollectionAuthorization( + const malformedCCA = new CargoCollectionAuthorization( '0deadbeef', pdaChain.privateGatewayCert, Buffer.from([]), @@ -661,7 +649,7 @@ describe('collectCargo', () => { CALL.on('error', (error) => { expect(MOCK_LOGS).toContainEqual( partialPinoLog('info', 'Refusing CCA with malformed recipient', { - ccaRecipientAddress: cca.recipientAddress, + ccaRecipientAddress: malformedCCA.recipientAddress, grpcClient: CALL.getPeer(), grpcMethod: 'collectCargo', peerGatewayAddress: privateGatewayAddress, @@ -676,7 +664,7 @@ describe('collectCargo', () => { }); const invalidCCASerialized = Buffer.from( - await cca.serialize(pdaChain.privateGatewayPrivateKey), + await malformedCCA.serialize(pdaChain.privateGatewayPrivateKey), ); CALL.metadata.add('Authorization', `Relaynet-CCA ${invalidCCASerialized.toString('base64')}`); @@ -684,7 +672,7 @@ describe('collectCargo', () => { }); test('INVALID_ARGUMENT should be returned if CCA is not bound for current gateway', async (cb) => { - const cca = new CargoCollectionAuthorization( + const invalidCCA = new CargoCollectionAuthorization( `https://different-${PUBLIC_ADDRESS}`, pdaChain.privateGatewayCert, Buffer.from([]), @@ -692,7 +680,7 @@ describe('collectCargo', () => { CALL.on('error', (error) => { expect(MOCK_LOGS).toContainEqual( partialPinoLog('info', 'Refusing CCA bound for another gateway', { - ccaRecipientAddress: cca.recipientAddress, + ccaRecipientAddress: invalidCCA.recipientAddress, grpcClient: CALL.getPeer(), grpcMethod: 'collectCargo', peerGatewayAddress: privateGatewayAddress, @@ -707,7 +695,7 @@ describe('collectCargo', () => { }); const invalidCCASerialized = Buffer.from( - await cca.serialize(pdaChain.privateGatewayPrivateKey), + await invalidCCA.serialize(pdaChain.privateGatewayPrivateKey), ); CALL.metadata.add('Authorization', `Relaynet-CCA ${invalidCCASerialized.toString('base64')}`); @@ -715,6 +703,8 @@ describe('collectCargo', () => { }); test('PERMISSION_DENIED should be returned if CCA was already fulfilled', async (cb) => { + await recordCCAFulfillment(cca, getMongooseConnection()); + CALL.on('error', (error) => { expect(MOCK_LOGS).toContainEqual( partialPinoLog('info', 'Refusing CCA that was already fulfilled', { @@ -731,7 +721,6 @@ describe('collectCargo', () => { cb(); }); - MOCK_WAS_CCA_FULFILLED.mockResolvedValue(true); CALL.metadata.add('Authorization', serializeAuthzMetadata(ccaSerialized)); await SERVICE.collectCargo(CALL.convertToGrpcStream()); @@ -891,12 +880,7 @@ describe('collectCargo', () => { await SERVICE.collectCargo(CALL.convertToGrpcStream()); - expect(MOCK_RECORD_CCA_FULFILLMENT).toBeCalledTimes(1); - const cca = await CargoCollectionAuthorization.deserialize(bufferToArray(ccaSerialized)); - expect(MOCK_RECORD_CCA_FULFILLMENT).toBeCalledWith( - expect.objectContaining({ id: cca.id }), - getMongooseConnection(), - ); + await expect(wasCCAFulfilled(cca, getMongooseConnection())).resolves.toBeTrue(); }); test('CCA fulfillment should be logged and end the call', async () => { @@ -958,7 +942,7 @@ describe('collectCargo', () => { cb(); }); - await SERVICE.collectCargo(CALL.convertToGrpcStream()); + SERVICE.collectCargo(CALL.convertToGrpcStream()); }); test('Call should end with an error for the client', async (cb) => { @@ -971,16 +955,16 @@ describe('collectCargo', () => { cb(); }); - await SERVICE.collectCargo(CALL.convertToGrpcStream()); + SERVICE.collectCargo(CALL.convertToGrpcStream()); }); test('CCA should not be marked as fulfilled', async (cb) => { - CALL.on('error', () => { - expect(MOCK_RECORD_CCA_FULFILLMENT).not.toBeCalled(); + CALL.on('error', async () => { + await expect(wasCCAFulfilled(cca, getMongooseConnection())).resolves.toBeFalse(); cb(); }); - await SERVICE.collectCargo(CALL.convertToGrpcStream()); + SERVICE.collectCargo(CALL.convertToGrpcStream()); }); }); @@ -992,12 +976,12 @@ describe('collectCargo', () => { recipientAddress: string, payload: ArrayBuffer, ): Promise { - const cca = new CargoCollectionAuthorization( + const auth = new CargoCollectionAuthorization( recipientAddress, pdaChain.privateGatewayCert, Buffer.from(payload), ); - return Buffer.from(await cca.serialize(pdaChain.privateGatewayPrivateKey)); + return Buffer.from(await auth.serialize(pdaChain.privateGatewayPrivateKey)); } async function validateCargoDelivery( diff --git a/src/utilities/config.spec.ts b/src/utilities/config.spec.ts index 90d6d53ba..ceeecd3bc 100644 --- a/src/utilities/config.spec.ts +++ b/src/utilities/config.spec.ts @@ -10,10 +10,6 @@ beforeAll(async () => { configItemModel = getModelForClass(ConfigItem, { existingConnection: getConnection() }); }); -beforeEach(async () => { - await configItemModel.deleteMany(); -}); - const PRIVATE_ADDRESS = '0deafbeef'; describe('Config', () => { From ec1ab44e58aad56957290eb1f91eab87792276c4 Mon Sep 17 00:00:00 2001 From: Gus Narea Date: Tue, 30 Nov 2021 17:46:22 +0000 Subject: [PATCH 09/24] update PoHTTP and PoWeb services --- src/services/_test_utils.ts | 4 +-- src/services/pohttp/routes.spec.ts | 2 +- src/services/poweb/RouteOptions.ts | 6 +--- src/services/poweb/_test_utils.ts | 38 +++++++++++++++------ src/services/poweb/parcelCollection.spec.ts | 10 +++--- src/services/poweb/parcelDelivery.spec.ts | 2 +- src/services/poweb/preRegistration.ts | 16 +++++---- src/services/poweb/registration.spec.ts | 13 ++++--- src/services/poweb/registration.ts | 26 ++++++++------ src/services/poweb/server.spec.ts | 12 +------ src/services/poweb/server.ts | 18 +--------- 11 files changed, 69 insertions(+), 78 deletions(-) diff --git a/src/services/_test_utils.ts b/src/services/_test_utils.ts index 71e0c3411..33735b1b0 100644 --- a/src/services/_test_utils.ts +++ b/src/services/_test_utils.ts @@ -194,11 +194,11 @@ export function testDisallowedMethods( }); } -export function mockFastifyMongoose(mockMongoProperty: { readonly db: Connection }): void { +export function mockFastifyMongoose(mockMongoProperty: () => { readonly db: Connection }): void { const mockFastifyPlugin = fastifyPlugin; jest.mock('fastify-mongoose', () => { function mockFunc(fastify: FastifyInstance, _options: any, next: () => void): void { - fastify.decorate('mongo', mockMongoProperty); + fastify.decorate('mongo', mockMongoProperty()); next(); } diff --git a/src/services/pohttp/routes.spec.ts b/src/services/pohttp/routes.spec.ts index a69a415ae..5e6c011a5 100644 --- a/src/services/pohttp/routes.spec.ts +++ b/src/services/pohttp/routes.spec.ts @@ -18,7 +18,7 @@ import { makeServer } from './server'; jest.mock('../../utilities/exitHandling'); const mockFastifyMongooseObject = { db: { what: 'The mongoose.Connection' } as any, ObjectId: {} }; -mockFastifyMongoose(mockFastifyMongooseObject); +mockFastifyMongoose(() => mockFastifyMongooseObject); const validRequestOptions: InjectOptions = { headers: { diff --git a/src/services/poweb/RouteOptions.ts b/src/services/poweb/RouteOptions.ts index f6c451119..34d16f845 100644 --- a/src/services/poweb/RouteOptions.ts +++ b/src/services/poweb/RouteOptions.ts @@ -1,5 +1 @@ -import { UnboundKeyPair } from '@relaycorp/relaynet-core'; - -export default interface RouteOptions { - readonly keyPairRetriever: () => Promise; -} +export default interface RouteOptions {} diff --git a/src/services/poweb/_test_utils.ts b/src/services/poweb/_test_utils.ts index 0dff1eea4..a735be0b7 100644 --- a/src/services/poweb/_test_utils.ts +++ b/src/services/poweb/_test_utils.ts @@ -1,20 +1,28 @@ import { MockPrivateKeyStore, Parcel } from '@relaycorp/relaynet-core'; import { Connection } from 'mongoose'; -import { arrayToAsyncIterable, mockSpy, MONGO_ENV_VARS, PdaChain } from '../../_test_utils'; +import { + arrayToAsyncIterable, + mockSpy, + MONGO_ENV_VARS, + PdaChain, + setUpTestDBConnection, +} from '../../_test_utils'; import * as vault from '../../backingServices/vault'; +import { MongoCertificateStore } from '../../keystores/MongoCertificateStore'; import { ParcelStore } from '../../parcelStore'; +import { Config, ConfigKey } from '../../utilities/config'; import { configureMockEnvVars, generatePdaChain, mockFastifyMongoose } from '../_test_utils'; export interface FixtureSet extends PdaChain { - readonly mongooseConnection: Connection; + readonly getMongooseConnection: () => Connection; readonly parcelStore: ParcelStore; readonly privateKeyStore: MockPrivateKeyStore; } export function setUpCommonFixtures(): () => FixtureSet { - const mockMongooseConnection: Connection = { whatIsThis: 'The Mongoose connection' } as any; - mockFastifyMongoose({ db: mockMongooseConnection }); + const getMongooseConnection = setUpTestDBConnection(); + mockFastifyMongoose(() => ({ db: getMongooseConnection() })); const mockParcelStore: ParcelStore = { liveStreamActiveParcelsForGateway: mockSpy( @@ -45,25 +53,33 @@ export function setUpCommonFixtures(): () => FixtureSet { let mockPrivateKeyStore: MockPrivateKeyStore; beforeEach(async () => { mockPrivateKeyStore = new MockPrivateKeyStore(); - await mockPrivateKeyStore.registerNodeKey( - certificatePath.publicGatewayPrivateKey, - certificatePath.publicGatewayCert, - ); + await mockPrivateKeyStore.saveIdentityKey(certificatePath.publicGatewayPrivateKey); }); mockSpy(jest.spyOn(vault, 'initVaultKeyStore'), () => mockPrivateKeyStore); + beforeEach(async () => { + const connection = getMongooseConnection(); + + const certificateStore = new MongoCertificateStore(connection); + await certificateStore.save(certificatePath.publicGatewayCert); + + const config = new Config(connection); + await config.set( + ConfigKey.CURRENT_PRIVATE_ADDRESS, + await certificatePath.publicGatewayCert.calculateSubjectPrivateAddress(), + ); + }); + const mockEnvVars = configureMockEnvVars(MONGO_ENV_VARS); beforeEach(() => { - const gatewayCertificate = certificatePath.publicGatewayCert; mockEnvVars({ ...MONGO_ENV_VARS, - GATEWAY_KEY_ID: gatewayCertificate.getSerialNumber().toString('base64'), GATEWAY_VERSION: '1.0.2', }); }); return () => ({ - mongooseConnection: mockMongooseConnection, + getMongooseConnection, parcelStore: mockParcelStore, privateKeyStore: mockPrivateKeyStore, ...certificatePath, diff --git a/src/services/poweb/parcelCollection.spec.ts b/src/services/poweb/parcelCollection.spec.ts index 26c8857a4..7afc68819 100644 --- a/src/services/poweb/parcelCollection.spec.ts +++ b/src/services/poweb/parcelCollection.spec.ts @@ -51,7 +51,7 @@ let mockLogging: MockLogging; beforeEach(() => { mockLogging = makeMockLogging(); mockWSServer = makeWebSocketServer( - getFixtures().mongooseConnection, + getFixtures().getMongooseConnection(), REQUEST_ID_HEADER, mockLogging.logger, ); @@ -68,7 +68,7 @@ beforeAll(async () => { const MOCK_RETRIEVE_OWN_CERTIFICATES = mockSpy( jest.spyOn(certs, 'retrieveOwnCertificates'), async (connection) => { - expect(connection).toBe(getFixtures().mongooseConnection); + expect(connection).toBe(getFixtures().getMongooseConnection()); const fixtures = getFixtures(); return [fixtures.publicGatewayCert]; }, @@ -90,7 +90,7 @@ mockSpy(jest.spyOn(WS, 'createWebSocketStream'), createMockWebSocketStream); describe('WebSocket server configuration', () => { test('Path should be /v1/parcel-collection', () => { const wsServer = makeWebSocketServer( - getFixtures().mongooseConnection, + getFixtures().getMongooseConnection(), REQUEST_ID_HEADER, mockLogging.logger, ); @@ -100,7 +100,7 @@ describe('WebSocket server configuration', () => { test('Maximum incoming payload size should be 2 kib', () => { const wsServer = makeWebSocketServer( - getFixtures().mongooseConnection, + getFixtures().getMongooseConnection(), REQUEST_ID_HEADER, mockLogging.logger, ); @@ -110,7 +110,7 @@ describe('WebSocket server configuration', () => { test('Clients should not be tracked', () => { const wsServer = makeWebSocketServer( - getFixtures().mongooseConnection, + getFixtures().getMongooseConnection(), REQUEST_ID_HEADER, mockLogging.logger, ); diff --git a/src/services/poweb/parcelDelivery.spec.ts b/src/services/poweb/parcelDelivery.spec.ts index 3e2cd2acb..a69773584 100644 --- a/src/services/poweb/parcelDelivery.spec.ts +++ b/src/services/poweb/parcelDelivery.spec.ts @@ -192,7 +192,7 @@ test('Valid parcels should result in an HTTP 202 response', async () => { expect.objectContaining({ id: PARCEL.id }), Buffer.from(PARCEL_SERIALIZED), await fixtures.privateGatewayCert.calculateSubjectPrivateAddress(), - fixtures.mongooseConnection, + fixtures.getMongooseConnection(), mockNatsStreamingConnection, expect.objectContaining({ debug: expect.toBeFunction(), info: expect.toBeFunction() }), ); diff --git a/src/services/poweb/preRegistration.ts b/src/services/poweb/preRegistration.ts index 84426227f..3373eb61e 100644 --- a/src/services/poweb/preRegistration.ts +++ b/src/services/poweb/preRegistration.ts @@ -1,20 +1,20 @@ import { PrivateNodeRegistrationAuthorization } from '@relaycorp/relaynet-core'; import bufferToArray from 'buffer-to-arraybuffer'; import { FastifyInstance, FastifyReply } from 'fastify'; +import { initVaultKeyStore } from '../../backingServices/vault'; +import { Config, ConfigKey } from '../../utilities/config'; import { registerDisallowedMethods } from '../fastify'; import { CONTENT_TYPES } from './contentTypes'; -import RouteOptions from './RouteOptions'; const ENDPOINT_URL = '/v1/pre-registrations'; const SHA256_HEX_DIGEST_LENGTH = 64; -export default async function registerRoutes( - fastify: FastifyInstance, - options: RouteOptions, -): Promise { +export default async function registerRoutes(fastify: FastifyInstance): Promise { registerDisallowedMethods(['POST'], ENDPOINT_URL, fastify); + const privateKeyStore = initVaultKeyStore(); + fastify.route<{ readonly Body: string }>({ method: 'POST', url: ENDPOINT_URL, @@ -28,10 +28,12 @@ export default async function registerRoutes( return reply.code(400).send({ message: 'Payload is not a SHA-256 digest' }); } - const publicGatewayKeyPair = await options.keyPairRetriever(); + const config = new Config((fastify as any).mongo); + const privateAddress = await config.get(ConfigKey.CURRENT_PRIVATE_ADDRESS); + const privateKey = await privateKeyStore.retrieveIdentityKey(privateAddress!!); const authorizationSerialized = await generateAuthorization( privateGatewayPublicKeyDigest, - publicGatewayKeyPair.privateKey, + privateKey, ); return reply .header('Content-Type', CONTENT_TYPES.GATEWAY_REGISTRATION.AUTHORIZATION) diff --git a/src/services/poweb/registration.spec.ts b/src/services/poweb/registration.spec.ts index 97eeb4644..a72e7199d 100644 --- a/src/services/poweb/registration.spec.ts +++ b/src/services/poweb/registration.spec.ts @@ -4,7 +4,7 @@ import { PrivateNodeRegistration, PrivateNodeRegistrationAuthorization, PrivateNodeRegistrationRequest, - SubsequentSessionPrivateKeyData, + SessionPrivateKeyData, } from '@relaycorp/relaynet-core'; import bufferToArray from 'buffer-to-arraybuffer'; import { FastifyInstance } from 'fastify'; @@ -218,12 +218,11 @@ describe('Successful registration', () => { const registration = await PrivateNodeRegistration.deserialize( bufferToArray(response.rawPayload), ); - const keyData = fixtures.privateKeyStore.keys[registration.sessionKey!!.keyId.toString('hex')]; - expect(keyData).toBeTruthy(); - expect(keyData.type).toEqual('session-subsequent'); - expect((keyData as SubsequentSessionPrivateKeyData).peerPrivateAddress).toEqual( - await fixtures.privateGatewayCert.calculateSubjectPrivateAddress(), - ); + const keyData = + fixtures.privateKeyStore.sessionKeys[registration.sessionKey!!.keyId.toString('hex')]; + expect(keyData).toMatchObject>({ + peerPrivateAddress: await fixtures.privateGatewayCert.calculateSubjectPrivateAddress(), + }); }); async function completeRegistration(fixtures: FixtureSet): Promise { diff --git a/src/services/poweb/registration.ts b/src/services/poweb/registration.ts index 24d60f54d..c7bb5663a 100644 --- a/src/services/poweb/registration.ts +++ b/src/services/poweb/registration.ts @@ -10,11 +10,12 @@ import { import bufferToArray from 'buffer-to-arraybuffer'; import { FastifyInstance, FastifyReply } from 'fastify'; import { initVaultKeyStore } from '../../backingServices/vault'; +import { MongoCertificateStore } from '../../keystores/MongoCertificateStore'; +import { Config, ConfigKey } from '../../utilities/config'; import { sha256 } from '../../utilities/crypto'; import { registerDisallowedMethods } from '../fastify'; import { CONTENT_TYPES } from './contentTypes'; -import RouteOptions from './RouteOptions'; const ENDPOINT_URL = '/v1/nodes'; @@ -27,10 +28,7 @@ const PRIVATE_GATEWAY_CERTIFICATE_START_OFFSET_HOURS = 3; const PRIVATE_GATEWAY_CERTIFICATE_VALIDITY_YEARS = 1; -export default async function registerRoutes( - fastify: FastifyInstance, - options: RouteOptions, -): Promise { +export default async function registerRoutes(fastify: FastifyInstance): Promise { registerDisallowedMethods(['POST'], ENDPOINT_URL, fastify); fastify.addContentTypeParser( @@ -61,13 +59,19 @@ export default async function registerRoutes( .send({ message: 'Payload is not a valid Private Node Registration Request' }); } - const publicGatewayKeyPair = await options.keyPairRetriever(); + const mongooseConnection = (fastify as any).mongo; + const config = new Config(mongooseConnection); + const privateAddress = await config.get(ConfigKey.CURRENT_PRIVATE_ADDRESS); + const privateKey = await privateKeyStore.retrieveIdentityKey(privateAddress!!); + + const certificateStore = new MongoCertificateStore(mongooseConnection); + const publicGatewayCertificate = await certificateStore.retrieveLatest(privateAddress!!); let registrationAuthorization: PrivateNodeRegistrationAuthorization; try { registrationAuthorization = await PrivateNodeRegistrationAuthorization.deserialize( registrationRequest.pnraSerialized, - await publicGatewayKeyPair.certificate.getPublicKey(), + await publicGatewayCertificate!!.getPublicKey(), ); } catch (err) { request.log.info({ err }, 'PNRR contains invalid authorization'); @@ -88,18 +92,18 @@ export default async function registerRoutes( const privateGatewayCertificate = await issuePrivateGatewayCertificate( registrationRequest.privateNodePublicKey, - publicGatewayKeyPair.privateKey, - publicGatewayKeyPair.certificate, + privateKey, + publicGatewayCertificate!!, ); const sessionKeyPair = await SessionKeyPair.generate(); - await privateKeyStore.saveSubsequentSessionKey( + await privateKeyStore.saveBoundSessionKey( sessionKeyPair.privateKey, sessionKeyPair.sessionKey.keyId, await privateGatewayCertificate.calculateSubjectPrivateAddress(), ); const registration = new PrivateNodeRegistration( privateGatewayCertificate, - publicGatewayKeyPair.certificate, + publicGatewayCertificate!!, sessionKeyPair.sessionKey, ); return reply diff --git a/src/services/poweb/server.spec.ts b/src/services/poweb/server.spec.ts index eb9754821..fe9d8cfc7 100644 --- a/src/services/poweb/server.spec.ts +++ b/src/services/poweb/server.spec.ts @@ -3,12 +3,11 @@ import pino from 'pino'; import { mockSpy } from '../../_test_utils'; import * as fastifyUtils from '../fastify'; import { setUpCommonFixtures } from './_test_utils'; -import RouteOptions from './RouteOptions'; import { makeServer } from './server'; jest.mock('../../utilities/exitHandling'); -const getFixtures = setUpCommonFixtures(); +setUpCommonFixtures(); const mockFastifyInstance = {}; const mockConfigureFastify = mockSpy( @@ -17,15 +16,6 @@ const mockConfigureFastify = mockSpy( ); describe('makeServer', () => { - test('Function to retrieve the key pair should be added to the options', async () => { - await makeServer(); - - const routeOptions = mockConfigureFastify.mock.calls[0][1] as RouteOptions; - const retriever = routeOptions.keyPairRetriever; - const retrieverCertificate = (await retriever()).certificate; - expect(retrieverCertificate.isEqual(getFixtures().publicGatewayCert)).toBeTrue(); - }); - test('No logger should be passed by default', async () => { await makeServer(); diff --git a/src/services/poweb/server.ts b/src/services/poweb/server.ts index b3f3e468a..07777a396 100644 --- a/src/services/poweb/server.ts +++ b/src/services/poweb/server.ts @@ -1,9 +1,6 @@ -import { UnboundKeyPair } from '@relaycorp/relaynet-core'; -import { get as getEnvVar } from 'env-var'; import { FastifyInstance, FastifyPluginCallback } from 'fastify'; import { Logger } from 'pino'; -import { initVaultKeyStore } from '../../backingServices/vault'; import { configureFastify } from '../fastify'; import healthcheck from './healthcheck'; import parcelCollection from './parcelCollection'; @@ -26,18 +23,5 @@ const ROUTES: ReadonlyArray> = [ * This function doesn't call .listen() so we can use .inject() for testing purposes. */ export async function makeServer(logger?: Logger): Promise { - return configureFastify( - ROUTES, - { - keyPairRetriever: makeKeyPairRetriever(), - }, - logger, - ); -} - -function makeKeyPairRetriever(): () => Promise { - const gatewayKeyIdBase64 = getEnvVar('GATEWAY_KEY_ID').required().asString(); - const gatewayKeyId = Buffer.from(gatewayKeyIdBase64, 'base64'); - const privateKeyStore = initVaultKeyStore(); - return () => privateKeyStore.fetchNodeKey(gatewayKeyId); + return configureFastify(ROUTES, {}, logger); } From b347a8bf12b9bb21078b4022d1a07f29d2f3adf1 Mon Sep 17 00:00:00 2001 From: Gus Narea Date: Tue, 30 Nov 2021 17:47:27 +0000 Subject: [PATCH 10/24] remove test that shouldn't have been comitted --- src/backingServices/mongo.spec.ts | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/backingServices/mongo.spec.ts b/src/backingServices/mongo.spec.ts index 425365f4b..166d087b2 100644 --- a/src/backingServices/mongo.spec.ts +++ b/src/backingServices/mongo.spec.ts @@ -2,7 +2,6 @@ import { EnvVarError } from 'env-var'; import mongoose, { Connection } from 'mongoose'; import { mockSpy, MONGO_ENV_VARS } from '../_test_utils'; -import { MongoCertificateStore } from '../keystores/MongoCertificateStore'; import { MongoPublicKeyStore } from '../keystores/MongoPublicKeyStore'; import { configureMockEnvVars } from '../services/_test_utils'; import { @@ -132,11 +131,3 @@ describe('initMongoDBKeyStore', () => { expect(keyStore).toBeInstanceOf(MongoPublicKeyStore); }); }); - -describe('initMongoDBCertificateStore', () => { - test('MongoCertificateStore instance should be returned', () => { - const certStore = initMongoDBKeyStore(MOCK_MONGOOSE_CONNECTION); - - expect(certStore).toBeInstanceOf(MongoCertificateStore); - }); -}); From a372242ca9946a8bd8e701d95a7f5fee4e584663 Mon Sep 17 00:00:00 2001 From: Gus Narea Date: Tue, 30 Nov 2021 17:53:30 +0000 Subject: [PATCH 11/24] fix crcIncoming.spec.ts --- src/queueWorkers/crcIncoming.spec.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/queueWorkers/crcIncoming.spec.ts b/src/queueWorkers/crcIncoming.spec.ts index a103ee525..d27bfaef6 100644 --- a/src/queueWorkers/crcIncoming.spec.ts +++ b/src/queueWorkers/crcIncoming.spec.ts @@ -115,11 +115,8 @@ beforeAll(async () => { }); beforeEach(async () => { - await mockPrivateKeyStore.registerNodeKey( - certificateChain.publicGatewayPrivateKey, - certificateChain.publicGatewayCert, - ); - await mockPrivateKeyStore.saveInitialSessionKey( + await mockPrivateKeyStore.saveIdentityKey(certificateChain.publicGatewayPrivateKey); + await mockPrivateKeyStore.saveUnboundSessionKey( publicGatewaySessionPrivateKey, publicGatewaySessionKey.keyId, ); From 477bbfc98cbb06d9f144220e2ef83b7019629447 Mon Sep 17 00:00:00 2001 From: Gus Narea Date: Tue, 30 Nov 2021 17:56:52 +0000 Subject: [PATCH 12/24] Delete all references to GATEWAY_KEY_ID env var --- chart/templates/cogrpc-deploy.yml | 3 --- chart/templates/generated-cm.yml | 11 ----------- chart/templates/keygen-job.yml | 2 -- chart/templates/poweb-deploy.yml | 3 --- chart/values.schema.json | 3 --- skaffold.yaml | 1 - src/functionalTests/jest.setup.ts | 1 - 7 files changed, 24 deletions(-) delete mode 100644 chart/templates/generated-cm.yml diff --git a/chart/templates/cogrpc-deploy.yml b/chart/templates/cogrpc-deploy.yml index f8c7f0a5c..9906e4a15 100644 --- a/chart/templates/cogrpc-deploy.yml +++ b/chart/templates/cogrpc-deploy.yml @@ -18,7 +18,6 @@ spec: {{- toYaml .Values.podAnnotations | nindent 8 }} {{- end }} global-cm-digest: {{ include "relaynet-internet-gateway.resourceDigest" (merge (dict "fileName" "global-cm.yml") .) }} - generated-cm-digest: {{ include "relaynet-internet-gateway.resourceDigest" (merge (dict "fileName" "generated-cm.yml") .) }} mongo-cm-digest: {{ include "relaynet-internet-gateway.resourceDigest" (merge (dict "fileName" "mongo-cm.yml") .) }} global-secret-digest: {{ include "relaynet-internet-gateway.resourceDigest" (merge (dict "fileName" "global-secret.yml") .) }} labels: @@ -50,8 +49,6 @@ spec: envFrom: - configMapRef: name: {{ include "relaynet-internet-gateway.fullname" . }} - - configMapRef: - name: {{ include "relaynet-internet-gateway.fullname" . }}-generated - configMapRef: name: {{ include "relaynet-internet-gateway.fullname" . }}-mongo - secretRef: diff --git a/chart/templates/generated-cm.yml b/chart/templates/generated-cm.yml deleted file mode 100644 index 50f96bf45..000000000 --- a/chart/templates/generated-cm.yml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ include "relaynet-internet-gateway.fullname" . }}-generated - annotations: - "helm.sh/hook": "pre-install" - "helm.sh/hook-weight": "-5" - labels: - {{- include "relaynet-internet-gateway.labels" . | nindent 4 }} -data: - GATEWAY_KEY_ID: {{ default (randAlphaNum 12 | b64enc) .Values.gatewayKeyId | quote }} diff --git a/chart/templates/keygen-job.yml b/chart/templates/keygen-job.yml index f6250f08c..e31f48ba6 100644 --- a/chart/templates/keygen-job.yml +++ b/chart/templates/keygen-job.yml @@ -29,8 +29,6 @@ spec: envFrom: - configMapRef: name: {{ include "relaynet-internet-gateway.fullname" . }} - - configMapRef: - name: {{ include "relaynet-internet-gateway.fullname" . }}-generated - configMapRef: name: {{ include "relaynet-internet-gateway.fullname" . }}-mongo - secretRef: diff --git a/chart/templates/poweb-deploy.yml b/chart/templates/poweb-deploy.yml index 89ce05d97..9319b082f 100644 --- a/chart/templates/poweb-deploy.yml +++ b/chart/templates/poweb-deploy.yml @@ -18,7 +18,6 @@ spec: {{- toYaml .Values.podAnnotations | nindent 8 }} {{- end }} global-cm-digest: {{ include "relaynet-internet-gateway.resourceDigest" (merge (dict "fileName" "global-cm.yml") .) }} - generated-cm-digest: {{ include "relaynet-internet-gateway.resourceDigest" (merge (dict "fileName" "generated-cm.yml") .) }} mongo-cm-digest: {{ include "relaynet-internet-gateway.resourceDigest" (merge (dict "fileName" "mongo-cm.yml") .) }} global-secret-digest: {{ include "relaynet-internet-gateway.resourceDigest" (merge (dict "fileName" "global-secret.yml") .) }} labels: @@ -44,8 +43,6 @@ spec: envFrom: - configMapRef: name: {{ include "relaynet-internet-gateway.fullname" . }} - - configMapRef: - name: {{ include "relaynet-internet-gateway.fullname" . }}-generated - configMapRef: name: {{ include "relaynet-internet-gateway.fullname" . }}-mongo - secretRef: diff --git a/chart/values.schema.json b/chart/values.schema.json index 3ec6ff0c4..1ad631dec 100644 --- a/chart/values.schema.json +++ b/chart/values.schema.json @@ -73,9 +73,6 @@ } } }, - "gatewayKeyId": { - "type": "string" - }, "proxyRequestIdHeader": { "type": "string" }, diff --git a/skaffold.yaml b/skaffold.yaml index c147ed064..d56e0c349 100644 --- a/skaffold.yaml +++ b/skaffold.yaml @@ -16,7 +16,6 @@ deploy: artifactOverrides: image.repository: public-gateway setValues: - gatewayKeyId: MTM1NzkK relaynet-pong.current_endpoint_key_id: aGVsbG8K relaynet-pong.current_endpoint_session_key_id: OTc1MzEK wait: true diff --git a/src/functionalTests/jest.setup.ts b/src/functionalTests/jest.setup.ts index b2a5155f0..8360ce956 100644 --- a/src/functionalTests/jest.setup.ts +++ b/src/functionalTests/jest.setup.ts @@ -2,7 +2,6 @@ jest.setTimeout(10_000); const TEST_ENV_VARS = { COGRPC_REQUIRE_TLS: 'false', - GATEWAY_KEY_ID: 'MTM1NzkK', NATS_CLUSTER_ID: 'stan', NATS_SERVER_URL: 'nats://127.0.0.1:4222', OBJECT_STORE_ACCESS_KEY_ID: 'test-key', From abe3ab3a429fb4d724661ed5a18ab0d34d2db40d Mon Sep 17 00:00:00 2001 From: Gus Narea Date: Tue, 30 Nov 2021 18:21:20 +0000 Subject: [PATCH 13/24] migrate retrieveOwnCertificates --- src/bin/generate-keypairs.ts | 41 ++++++++++++++-- src/certs.spec.ts | 95 +++++++++++++++--------------------- src/certs.ts | 13 ++--- 3 files changed, 85 insertions(+), 64 deletions(-) diff --git a/src/bin/generate-keypairs.ts b/src/bin/generate-keypairs.ts index bebdbfdc8..79dca0aff 100644 --- a/src/bin/generate-keypairs.ts +++ b/src/bin/generate-keypairs.ts @@ -1,9 +1,13 @@ -import { generateRSAKeyPair, issueGatewayCertificate } from '@relaycorp/relaynet-core'; +import { Certificate, generateRSAKeyPair, issueGatewayCertificate } from '@relaycorp/relaynet-core'; +import { getModelForClass } from '@typegoose/typegoose'; +import bufferToArray from 'buffer-to-arraybuffer'; import { addDays } from 'date-fns'; +import { Connection } from 'mongoose'; import { createMongooseConnectionFromEnv } from '../backingServices/mongo'; import { initVaultKeyStore } from '../backingServices/vault'; import { MongoCertificateStore } from '../keystores/MongoCertificateStore'; +import { OwnCertificate } from '../models'; import { Config, ConfigKey } from '../utilities/config'; import { configureExitHandling } from '../utilities/exitHandling'; import { makeLogger } from '../utilities/logging'; @@ -17,8 +21,17 @@ const privateKeyStore = initVaultKeyStore(); async function main(): Promise { const connection = await createMongooseConnectionFromEnv(); - const config = new Config(connection); + const certificateStore = new MongoCertificateStore(connection); + + await generateKeyPair(connection, certificateStore); + await migrateDeprecatedCertificates(connection, certificateStore); +} +async function generateKeyPair( + connection: Connection, + certificateStore: MongoCertificateStore, +): Promise { + const config = new Config(connection); const currentPrivateAddress = await config.get(ConfigKey.CURRENT_PRIVATE_ADDRESS); if (currentPrivateAddress) { LOGGER.info({ privateAddress: currentPrivateAddress }, `Gateway key pair already exists`); @@ -29,7 +42,6 @@ async function main(): Promise { const gatewayKeyPair = await generateRSAKeyPair(); const privateAddress = await privateKeyStore.saveIdentityKey(gatewayKeyPair.privateKey); - const certificateStore = new MongoCertificateStore(connection); const gatewayCertificate = await issueGatewayCertificate({ issuerPrivateKey: gatewayKeyPair.privateKey, subjectPublicKey: gatewayKeyPair.publicKey, @@ -42,4 +54,27 @@ async function main(): Promise { LOGGER.info({ privateAddress }, 'Identity key pair was successfully generated'); } +// TODO: Delete once we've deployed it to Frankfurt +async function migrateDeprecatedCertificates( + connection: Connection, + certificateStore: MongoCertificateStore, +): Promise { + const deprecatedCertificateModel = getModelForClass(OwnCertificate, { + existingConnection: connection, + }); + const deprecatedCertificateRecords = await deprecatedCertificateModel.find({}); + const deprecatedCertificates = deprecatedCertificateRecords.map((c) => + Certificate.deserialize(bufferToArray(c.serializationDer)), + ); + + await Promise.all(deprecatedCertificates.map((c) => certificateStore.save(c))); + + await deprecatedCertificateModel.deleteMany({}); + + LOGGER.info( + { deprecatedCertificates: deprecatedCertificates.length }, + 'Migrated deprecated certificates', + ); +} + main(); diff --git a/src/certs.spec.ts b/src/certs.spec.ts index 7a43ed72f..91283b89f 100644 --- a/src/certs.spec.ts +++ b/src/certs.spec.ts @@ -1,81 +1,66 @@ -/* tslint:disable:no-object-mutation */ +import { Certificate, generateRSAKeyPair, issueGatewayCertificate } from '@relaycorp/relaynet-core'; +import { addMinutes } from 'date-fns'; -import { generateRSAKeyPair } from '@relaycorp/relaynet-core'; -import * as typegoose from '@typegoose/typegoose'; -import bufferToArray from 'buffer-to-arraybuffer'; -import { Connection } from 'mongoose'; - -import { mockSpy } from './_test_utils'; +import { setUpTestDBConnection } from './_test_utils'; import { retrieveOwnCertificates } from './certs'; -import { OwnCertificate } from './models'; -import { expectBuffersToEqual, generateStubEndpointCertificate } from './services/_test_utils'; - -const stubConnection: Connection = { whoAreYou: 'the-stub-connection' } as any; +import { MongoCertificateStore } from './keystores/MongoCertificateStore'; +import { Config, ConfigKey } from './utilities/config'; -const stubFind = mockSpy(jest.fn(), () => []); -const stubGetModelForClass = mockSpy(jest.spyOn(typegoose, 'getModelForClass'), () => ({ - find: stubFind, -})); +const getMongooseConnection = setUpTestDBConnection(); -let stubOwnCerts: readonly OwnCertificate[]; +let certificate1: Certificate; +let certificate2: Certificate; beforeAll(async () => { - const keyPair1 = await generateRSAKeyPair(); - const ownCert1 = new OwnCertificate(); - ownCert1.serializationDer = Buffer.from( - (await generateStubEndpointCertificate(keyPair1)).serialize(), - ); - - const keyPair2 = await generateRSAKeyPair(); - const ownCert2 = new OwnCertificate(); - ownCert2.serializationDer = Buffer.from( - (await generateStubEndpointCertificate(keyPair2)).serialize(), - ); - - stubOwnCerts = [ownCert1, ownCert2]; + const identityKeyPair = await generateRSAKeyPair(); + certificate1 = await issueGatewayCertificate({ + issuerPrivateKey: identityKeyPair.privateKey, + subjectPublicKey: identityKeyPair.publicKey, + validityEndDate: addMinutes(new Date(), 1), + }); + certificate2 = await issueGatewayCertificate({ + issuerPrivateKey: identityKeyPair.privateKey, + subjectPublicKey: identityKeyPair.publicKey, + validityEndDate: addMinutes(new Date(), 3), + }); }); -describe('retrieveOwnCertificates', () => { - test('The specified connection should be used', async () => { - await retrieveOwnCertificates(stubConnection); - - expect(stubGetModelForClass).toBeCalledTimes(1); - expect(stubGetModelForClass).toBeCalledWith(OwnCertificate, { - existingConnection: stubConnection, - }); - }); +let certificateStore: MongoCertificateStore; +beforeEach(async () => { + const connection = getMongooseConnection(); - test('All records should be queried', async () => { - await retrieveOwnCertificates(stubConnection); + certificateStore = new MongoCertificateStore(connection); - expect(stubFind).toBeCalledTimes(1); - expect(stubFind).toBeCalledWith({}); - }); + const config = new Config(connection); + await config.set( + ConfigKey.CURRENT_PRIVATE_ADDRESS, + await certificate1.calculateSubjectPrivateAddress(), + ); +}); +describe('retrieveOwnCertificates', () => { test('An empty array should be returned when there are no certificates', async () => { - const certs = await retrieveOwnCertificates(stubConnection); + const certs = await retrieveOwnCertificates(getMongooseConnection()); expect(certs).toEqual([]); }); test('A single certificate should be returned when there is one certificate', async () => { - stubFind.mockReset(); - stubFind.mockResolvedValueOnce([stubOwnCerts[0]]); + await certificateStore.save(certificate1); - const certs = await retrieveOwnCertificates(stubConnection); + const certs = await retrieveOwnCertificates(getMongooseConnection()); expect(certs).toHaveLength(1); - expectBuffersToEqual(certs[0].serialize(), bufferToArray(stubOwnCerts[0].serializationDer)); + expect(certificate1.isEqual(certs[0])).toBeTrue(); }); test('Multiple certificates should be retuned when there are multiple certificates', async () => { - stubFind.mockReset(); - stubFind.mockResolvedValueOnce(stubOwnCerts); + await certificateStore.save(certificate1); + await certificateStore.save(certificate2); - const certs = await retrieveOwnCertificates(stubConnection); + const certs = await retrieveOwnCertificates(getMongooseConnection()); - expect(certs).toHaveLength(stubOwnCerts.length); - for (let i = 0; i < stubOwnCerts.length; i++) { - expectBuffersToEqual(certs[i].serialize(), bufferToArray(stubOwnCerts[i].serializationDer)); - } + expect(certs).toHaveLength(2); + expect(certs.filter((c) => certificate1.isEqual(c))).toHaveLength(1); + expect(certs.filter((c) => certificate2.isEqual(c))).toHaveLength(1); }); }); diff --git a/src/certs.ts b/src/certs.ts index 55350cf97..1c6f34a9d 100644 --- a/src/certs.ts +++ b/src/certs.ts @@ -1,14 +1,15 @@ import { Certificate } from '@relaycorp/relaynet-core'; -import { getModelForClass } from '@typegoose/typegoose'; -import bufferToArray from 'buffer-to-arraybuffer'; import { Connection } from 'mongoose'; -import { OwnCertificate } from './models'; +import { MongoCertificateStore } from './keystores/MongoCertificateStore'; +import { Config, ConfigKey } from './utilities/config'; export async function retrieveOwnCertificates( connection: Connection, ): Promise { - const ownCertificateModel = getModelForClass(OwnCertificate, { existingConnection: connection }); - const ownCerts = await ownCertificateModel.find({}); - return ownCerts.map((c) => Certificate.deserialize(bufferToArray(c.serializationDer))); + const store = new MongoCertificateStore(connection); + const config = new Config(connection); + + const privateAddress = await config.get(ConfigKey.CURRENT_PRIVATE_ADDRESS); + return store.retrieveAll(privateAddress!!); } From 0ebccc2b282260e9778a7dbc98b89b7cf13ee317 Mon Sep 17 00:00:00 2001 From: Gus Narea Date: Tue, 30 Nov 2021 18:24:28 +0000 Subject: [PATCH 14/24] upgrade vault keystore --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 560504bbd..64edb5754 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1382,11 +1382,11 @@ } }, "@relaycorp/keystore-vault": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@relaycorp/keystore-vault/-/keystore-vault-1.2.12.tgz", - "integrity": "sha512-7JpMMI5ST2q4jLqMI5X5jHnyfuHlk8m2+IQHSikM1b9NiyDeSsg7+VEmsoJkXHHPka1a7zfLzDG230EmnoVqfQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@relaycorp/keystore-vault/-/keystore-vault-2.0.2.tgz", + "integrity": "sha512-PQYSqia0kCV6L+ruoT4t1l1pldX2UdHGir9iXzkH45psOW+lErwjLAbqWhVznVDY6/sQ1QypXyMH5BQNZYUyVQ==", "requires": { - "@relaycorp/relaynet-core": "^1.54.4", + "@relaycorp/relaynet-core": "^1.56.1", "axios": "^0.24.0" }, "dependencies": { diff --git a/package.json b/package.json index e74f34cd8..09fc9316e 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "dependencies": { "@grpc/grpc-js": "^1.3.7", "@relaycorp/cogrpc": "^1.3.23", - "@relaycorp/keystore-vault": "^1.2.12", + "@relaycorp/keystore-vault": "^2.0.2", "@relaycorp/object-storage": "^1.4.5", "@relaycorp/pino-cloud": "^1.0.4", "@relaycorp/relaynet-core": "^1.57.0", From fd40d6c2b6300cff02d26af25bfed7d533e51d37 Mon Sep 17 00:00:00 2001 From: Gus Narea Date: Tue, 30 Nov 2021 18:35:38 +0000 Subject: [PATCH 15/24] fix tests in CI --- jest.config.ci.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jest.config.ci.js b/jest.config.ci.js index eddfca3e2..acc397218 100644 --- a/jest.config.ci.js +++ b/jest.config.ci.js @@ -3,7 +3,7 @@ const mainJestConfig = require('./jest.config'); module.exports = Object.assign({}, mainJestConfig, { collectCoverageFrom: ['services/**/*.js'], moduleFileExtensions: ['js'], - preset: null, + transform: null, roots: ['build/main'], testPathIgnorePatterns: [ "build/main/functionalTests" From ebdb2e3379f3335ad717952764fe580c583d17f6 Mon Sep 17 00:00:00 2001 From: Gus Narea Date: Tue, 30 Nov 2021 19:02:24 +0000 Subject: [PATCH 16/24] upgrdae mongod used in unit tests --- jest-mongodb-config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jest-mongodb-config.js b/jest-mongodb-config.js index 7f52fd6aa..ac564d5ae 100644 --- a/jest-mongodb-config.js +++ b/jest-mongodb-config.js @@ -1,7 +1,7 @@ module.exports = { mongodbMemoryServerOptions: { binary: { - version: '4.0.3', + version: '4.2.17', skipMD5: false, }, instance: {}, From afd1f870af87127629b8e8113047e3c60c642c9a Mon Sep 17 00:00:00 2001 From: Gus Narea Date: Tue, 30 Nov 2021 19:21:02 +0000 Subject: [PATCH 17/24] generate-keypairs.ts: close mongodb conn --- src/bin/generate-keypairs.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/bin/generate-keypairs.ts b/src/bin/generate-keypairs.ts index 79dca0aff..b7eae21eb 100644 --- a/src/bin/generate-keypairs.ts +++ b/src/bin/generate-keypairs.ts @@ -21,10 +21,14 @@ const privateKeyStore = initVaultKeyStore(); async function main(): Promise { const connection = await createMongooseConnectionFromEnv(); - const certificateStore = new MongoCertificateStore(connection); + try { + const certificateStore = new MongoCertificateStore(connection); - await generateKeyPair(connection, certificateStore); - await migrateDeprecatedCertificates(connection, certificateStore); + await generateKeyPair(connection, certificateStore); + await migrateDeprecatedCertificates(connection, certificateStore); + } finally { + await connection.close(); + } } async function generateKeyPair( From dc4978566f828164fd03fdd51cbd486235211186 Mon Sep 17 00:00:00 2001 From: Gus Narea Date: Tue, 30 Nov 2021 19:26:41 +0000 Subject: [PATCH 18/24] enable useCreateIndex in mongoose to avoid warnings --- src/_test_utils.ts | 1 + src/backingServices/mongo.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/_test_utils.ts b/src/_test_utils.ts index 367bacc37..179c5b308 100644 --- a/src/_test_utils.ts +++ b/src/_test_utils.ts @@ -227,6 +227,7 @@ export function setUpTestDBConnection(): () => Connection { const connect = () => createConnection((global as any).__MONGO_URI__, { + useCreateIndex: true, useNewUrlParser: true, useUnifiedTopology: true, }); diff --git a/src/backingServices/mongo.ts b/src/backingServices/mongo.ts index 55ffa6c68..5a575344a 100644 --- a/src/backingServices/mongo.ts +++ b/src/backingServices/mongo.ts @@ -16,6 +16,7 @@ export function getMongooseConnectionArgsFromEnv(): { options: { dbName: mongoDb, pass: mongoPassword, + useCreateIndex: true, useNewUrlParser: true, useUnifiedTopology: true, user: mongoUser, From 04470ae9c3ed33ed29cd4cad1f150d2cea5fad76 Mon Sep 17 00:00:00 2001 From: Gus Narea Date: Tue, 30 Nov 2021 19:35:30 +0000 Subject: [PATCH 19/24] fix jest config for functional tests --- src/functionalTests/jest.config.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/functionalTests/jest.config.js b/src/functionalTests/jest.config.js index 5b0f5739b..100faa01a 100644 --- a/src/functionalTests/jest.config.js +++ b/src/functionalTests/jest.config.js @@ -2,11 +2,8 @@ const mainJestConfig = require('../../jest.config'); module.exports = { moduleFileExtensions: mainJestConfig.moduleFileExtensions, - preset: mainJestConfig.preset, + preset: 'ts-jest', roots: ['.'], - testEnvironment: mainJestConfig.testEnvironment, - setupFilesAfterEnv: [ - ...mainJestConfig.setupFilesAfterEnv, - './jest.setup.ts', - ], + testEnvironment: 'node', + setupFilesAfterEnv: [...mainJestConfig.setupFilesAfterEnv, './jest.setup.ts'], }; From 3594298ad31253262b25093fa759ac837cf13a55 Mon Sep 17 00:00:00 2001 From: Gus Narea Date: Tue, 30 Nov 2021 19:46:09 +0000 Subject: [PATCH 20/24] fix mongo connection lookup --- src/services/poweb/preRegistration.ts | 2 +- src/services/poweb/registration.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/poweb/preRegistration.ts b/src/services/poweb/preRegistration.ts index 3373eb61e..c42067cb1 100644 --- a/src/services/poweb/preRegistration.ts +++ b/src/services/poweb/preRegistration.ts @@ -28,7 +28,7 @@ export default async function registerRoutes(fastify: FastifyInstance): Promise< return reply.code(400).send({ message: 'Payload is not a SHA-256 digest' }); } - const config = new Config((fastify as any).mongo); + const config = new Config((fastify as any).mongo.db); const privateAddress = await config.get(ConfigKey.CURRENT_PRIVATE_ADDRESS); const privateKey = await privateKeyStore.retrieveIdentityKey(privateAddress!!); const authorizationSerialized = await generateAuthorization( diff --git a/src/services/poweb/registration.ts b/src/services/poweb/registration.ts index c7bb5663a..55f4b54c6 100644 --- a/src/services/poweb/registration.ts +++ b/src/services/poweb/registration.ts @@ -59,7 +59,7 @@ export default async function registerRoutes(fastify: FastifyInstance): Promise< .send({ message: 'Payload is not a valid Private Node Registration Request' }); } - const mongooseConnection = (fastify as any).mongo; + const mongooseConnection = (fastify as any).mongo.db; const config = new Config(mongooseConnection); const privateAddress = await config.get(ConfigKey.CURRENT_PRIVATE_ADDRESS); const privateKey = await privateKeyStore.retrieveIdentityKey(privateAddress!!); From bc15e9951d267c13399b24b020e05e4766c65802 Mon Sep 17 00:00:00 2001 From: Gus Narea Date: Tue, 30 Nov 2021 19:49:26 +0000 Subject: [PATCH 21/24] drop ability to access Vault from func tests --- .github/workflows/ci-cd.yml | 1 - src/functionalTests/jest.setup.ts | 3 --- 2 files changed, 4 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 72b7dd5b5..6a5a121f3 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -61,7 +61,6 @@ jobs: kubectl port-forward --address 127.0.0.1 svc/public-gateway-pohttp 8081:8080 & kubectl port-forward --address 127.0.0.1 svc/public-gateway-cogrpc 8082:8081 & kubectl port-forward --address 127.0.0.1 svc/relaynet-pong-pohttp 8083:80 & - kubectl port-forward --address 127.0.0.1 svc/public-gateway-vault 8200:8200 & kubectl port-forward --address 127.0.0.1 svc/nats 4222:4222 & kubectl port-forward --address 127.0.0.1 svc/minio 9000:9000 & diff --git a/src/functionalTests/jest.setup.ts b/src/functionalTests/jest.setup.ts index 8360ce956..fa52194dd 100644 --- a/src/functionalTests/jest.setup.ts +++ b/src/functionalTests/jest.setup.ts @@ -10,9 +10,6 @@ const TEST_ENV_VARS = { OBJECT_STORE_SECRET_KEY: 'test-secret', OBJECT_STORE_TLS_ENABLED: 'false', POHTTP_TLS_REQUIRED: 'false', - VAULT_KV_PREFIX: 'gw-keys', - VAULT_TOKEN: 'root', - VAULT_URL: 'http://127.0.0.1:8200', }; // tslint:disable-next-line:no-object-mutation Object.assign(process.env, TEST_ENV_VARS); From 489335bf8458cc07f4888b3037724c1987d04c11 Mon Sep 17 00:00:00 2001 From: Gus Narea Date: Tue, 30 Nov 2021 19:54:43 +0000 Subject: [PATCH 22/24] run unit tests using TS --- .github/workflows/ci-cd.yml | 2 +- jest.config.ci.js | 11 ----------- package.json | 2 -- 3 files changed, 1 insertion(+), 14 deletions(-) delete mode 100644 jest.config.ci.js diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 6a5a121f3..e7c92d256 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -22,7 +22,7 @@ jobs: - name: Install dependencies run: npm ci - run: npm run static-checks - - run: npm run test:ci:unit + - run: npm test - uses: azure/setup-helm@v1 with: diff --git a/jest.config.ci.js b/jest.config.ci.js deleted file mode 100644 index acc397218..000000000 --- a/jest.config.ci.js +++ /dev/null @@ -1,11 +0,0 @@ -const mainJestConfig = require('./jest.config'); - -module.exports = Object.assign({}, mainJestConfig, { - collectCoverageFrom: ['services/**/*.js'], - moduleFileExtensions: ['js'], - transform: null, - roots: ['build/main'], - testPathIgnorePatterns: [ - "build/main/functionalTests" - ], -}); diff --git a/package.json b/package.json index 09fc9316e..a0a567922 100644 --- a/package.json +++ b/package.json @@ -14,8 +14,6 @@ "static-checks": "run-p static-checks:*", "static-checks:lint": "tslint --project .", "static-checks:prettier": "prettier \"src/**/*.ts\" --list-different", - "test:ci:unit": "run-s build test:ci:unit:jest", - "test:ci:unit:jest": "jest --config jest.config.ci.js --coverage", "cov": "run-s build test:unit && opn coverage/lcov-report/index.html", "clean": "trash build test coverage" }, From c3b3b667d8b81334e0530689c90ad894667d2bca Mon Sep 17 00:00:00 2001 From: Gus Narea Date: Tue, 30 Nov 2021 19:56:28 +0000 Subject: [PATCH 23/24] ci: avoid running static checks tywice --- .github/workflows/ci-cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index e7c92d256..ad87c9b82 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -22,7 +22,7 @@ jobs: - name: Install dependencies run: npm ci - run: npm run static-checks - - run: npm test + - run: npm run test:unit - uses: azure/setup-helm@v1 with: From a7363540181a99e2e889a7bf4b201869854cdcf8 Mon Sep 17 00:00:00 2001 From: Gus Narea Date: Tue, 30 Nov 2021 20:41:43 +0000 Subject: [PATCH 24/24] refactor / isolate potential bug --- src/services/poweb/registration.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/services/poweb/registration.ts b/src/services/poweb/registration.ts index 55f4b54c6..7340b8e92 100644 --- a/src/services/poweb/registration.ts +++ b/src/services/poweb/registration.ts @@ -66,12 +66,13 @@ export default async function registerRoutes(fastify: FastifyInstance): Promise< const certificateStore = new MongoCertificateStore(mongooseConnection); const publicGatewayCertificate = await certificateStore.retrieveLatest(privateAddress!!); + const gatewayPublicKey = await publicGatewayCertificate!!.getPublicKey(); let registrationAuthorization: PrivateNodeRegistrationAuthorization; try { registrationAuthorization = await PrivateNodeRegistrationAuthorization.deserialize( registrationRequest.pnraSerialized, - await publicGatewayCertificate!!.getPublicKey(), + gatewayPublicKey, ); } catch (err) { request.log.info({ err }, 'PNRR contains invalid authorization');