From 8aae845d6b26390a73840209a12c25d42b5a0e0f Mon Sep 17 00:00:00 2001 From: Matt Hamann Date: Thu, 17 Nov 2022 00:45:40 -0500 Subject: [PATCH 1/4] BREAKING CHANGE: separate user fetch and token validation errors --- .gitignore | 1 + examples/express/server.js | 2 +- package-lock.json | 438 +++++++++++++++++++------------------ package.json | 4 +- src/express/index.ts | 36 ++- src/lib/core.ts | 2 +- test/core.test.ts | 60 +++-- test/mocks.ts | 282 +++++++++++++----------- yarn.lock | 91 +++++--- 9 files changed, 511 insertions(+), 405 deletions(-) diff --git a/.gitignore b/.gitignore index 4c9d7c3..53b1dae 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .DS_Store node_modules dist +coverage diff --git a/examples/express/server.js b/examples/express/server.js index addac03..3dbff7a 100644 --- a/examples/express/server.js +++ b/examples/express/server.js @@ -11,7 +11,7 @@ app.get('/', (req, res) => { res.send('This is an unauthenticated route.'); }); -app.get('/dashboard', authenticate({ fetchUserInfo: true }), (req, res) => { +app.get('/dashboard', authenticate({ fetchUserInfo: true, errOnMissingUser: true }), (req, res) => { res.send({ message: 'You are authenticated!', tokenObj: req.tokenObj, diff --git a/package-lock.json b/package-lock.json index 6385a9c..fbdab89 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "MIT", "dependencies": { "debug": "^4.3.3", - "got": "^11.8.3", + "got": "^11.8.5", "jose": "^4.5.0", "lodash": "^4.17.21", "node-cache": "^5.1.2" @@ -3185,11 +3185,12 @@ "dev": true }, "node_modules/@sindresorhus/is": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.4.0.tgz", - "integrity": "sha512-QppPM/8l3Mawvh4rn9CNEYIU9bxpXUCRMaX9yUpvBk1nMKusLKpfXGDEKExKaPhLzcn3lzil7pR6rnJ11HgeRQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.3.0.tgz", + "integrity": "sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==", + "dev": true, "engines": { - "node": ">=10" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sindresorhus/is?sponsor=1" @@ -3264,14 +3265,15 @@ } }, "node_modules/@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "dev": true, "dependencies": { - "defer-to-connect": "^2.0.0" + "defer-to-connect": "^2.0.1" }, "engines": { - "node": ">=10" + "node": ">=14.16" } }, "node_modules/@tootallnate/once": { @@ -7955,9 +7957,9 @@ } }, "node_modules/form-data-encoder": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.0.1.tgz", - "integrity": "sha512-Oy+P9w5mnO4TWXVgUiQvggNKPI9/ummcSt5usuIV6HkaLKigwzPpoenhEqmGmx3zHqm6ZLJ+CR/99N8JLinaEw==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.3.tgz", + "integrity": "sha512-KqU0nnPMgIJcCOFTNJFEA8epcseEaoox4XZffTgy8jlI6pL/5EFyR54NRG7CnCJN0biY7q52DO3MH6/sJ/TKlQ==", "dev": true, "engines": { "node": ">= 14.17" @@ -8547,9 +8549,9 @@ } }, "node_modules/got": { - "version": "11.8.3", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.3.tgz", - "integrity": "sha512-7gtQ5KiPh1RtGS9/Jbv1ofDpBFuq42gyfEib+ejaRBJuj/3tQFeR5+gw57e4ipaU8c/rCjvX6fkQz2lyDlGAOg==", + "version": "11.8.5", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.5.tgz", + "integrity": "sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==", "dependencies": { "@sindresorhus/is": "^4.0.0", "@szmarczak/http-timer": "^4.0.5", @@ -8570,6 +8572,48 @@ "url": "https://github.com/sindresorhus/got?sponsor=1" } }, + "node_modules/got/node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/got/node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/got/node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/got/node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "engines": { + "node": ">=8" + } + }, "node_modules/graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", @@ -8831,12 +8875,13 @@ } }, "node_modules/http2-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.0.tgz", + "integrity": "sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==", + "dev": true, "dependencies": { "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" + "resolve-alpn": "^1.2.0" }, "engines": { "node": ">=10.19.0" @@ -10685,9 +10730,9 @@ } }, "node_modules/keyv": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.1.1.tgz", - "integrity": "sha512-tGv1yP6snQVDSM4X6yxrv2zzq/EvpW+oYiUz6aueW1u9CtS8RzUQYxxmFwgZlO2jSgCxQbchhxaqXXp2hnKGpQ==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", + "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", "dependencies": { "json-buffer": "3.0.1" } @@ -12403,11 +12448,12 @@ "dev": true }, "node_modules/p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "dev": true, "engines": { - "node": ">=8" + "node": ">=12.20" } }, "node_modules/p-each-series": { @@ -12519,39 +12565,33 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/package-json/node_modules/@sindresorhus/is": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.3.0.tgz", - "integrity": "sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==", + "node_modules/package-json/node_modules/cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", "dev": true, "engines": { "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" } }, - "node_modules/package-json/node_modules/@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "node_modules/package-json/node_modules/cacheable-request": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.2.tgz", + "integrity": "sha512-KxjQZM3UIo7/J6W4sLpwFvu1GB3Whv8NtZ8ZrUL284eiQjiXeeqWTdhixNrp/NLZ/JNuFBo6BD4ZaO8ZJ5BN8Q==", "dev": true, "dependencies": { - "defer-to-connect": "^2.0.1" + "@types/http-cache-semantics": "^4.0.1", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.0", + "keyv": "^4.5.0", + "mimic-response": "^4.0.0", + "normalize-url": "^7.2.0", + "responselike": "^3.0.0" }, "engines": { "node": ">=14.16" } }, - "node_modules/package-json/node_modules/cacheable-lookup": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz", - "integrity": "sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==", - "dev": true, - "engines": { - "node": ">=10.6.0" - } - }, "node_modules/package-json/node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -12565,24 +12605,22 @@ } }, "node_modules/package-json/node_modules/got": { - "version": "12.3.1", - "resolved": "https://registry.npmjs.org/got/-/got-12.3.1.tgz", - "integrity": "sha512-tS6+JMhBh4iXMSXF6KkIsRxmloPln31QHDlcb6Ec3bzxjjFJFr/8aXdpyuLmVc9I4i2HyBHYw1QU5K1ruUdpkw==", + "version": "12.5.3", + "resolved": "https://registry.npmjs.org/got/-/got-12.5.3.tgz", + "integrity": "sha512-8wKnb9MGU8IPGRIo+/ukTy9XLJBwDiCpIf5TVzQ9Cpol50eMTpBq2GAuDsuDIz7hTYmZgMgC1e9ydr6kSDWs3w==", "dev": true, "dependencies": { "@sindresorhus/is": "^5.2.0", "@szmarczak/http-timer": "^5.0.1", - "@types/cacheable-request": "^6.0.2", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^6.0.4", - "cacheable-request": "^7.0.2", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.1", "decompress-response": "^6.0.0", - "form-data-encoder": "^2.0.1", + "form-data-encoder": "^2.1.2", "get-stream": "^6.0.1", "http2-wrapper": "^2.1.10", "lowercase-keys": "^3.0.0", "p-cancelable": "^3.0.0", - "responselike": "^2.0.0" + "responselike": "^3.0.0" }, "engines": { "node": ">=14.16" @@ -12591,19 +12629,6 @@ "url": "https://github.com/sindresorhus/got?sponsor=1" } }, - "node_modules/package-json/node_modules/http2-wrapper": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.1.11.tgz", - "integrity": "sha512-aNAk5JzLturWEUiuhAN73Jcbq96R7rTitAoXV54FYMatvihnpD2+6PUgU4ce3D/m5VDbw+F5CsyKSF176ptitQ==", - "dev": true, - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, "node_modules/package-json/node_modules/lowercase-keys": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", @@ -12616,13 +12641,43 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/package-json/node_modules/p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "node_modules/package-json/node_modules/mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json/node_modules/normalize-url": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-7.2.0.tgz", + "integrity": "sha512-uhXOdZry0L6M2UIo9BTt7FdpBDiAGN/7oItedQwPKh8jh31ZlvC8U9Xl/EJ3aijDHaywXTW3QbZ6LuCocur1YA==", "dev": true, "engines": { "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json/node_modules/responselike": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "dev": true, + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/package-json/node_modules/semver": { @@ -13550,30 +13605,6 @@ "node": ">=14.9" } }, - "node_modules/release-it/node_modules/@sindresorhus/is": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.3.0.tgz", - "integrity": "sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/release-it/node_modules/@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", - "dev": true, - "dependencies": { - "defer-to-connect": "^2.0.1" - }, - "engines": { - "node": ">=14.16" - } - }, "node_modules/release-it/node_modules/ansi-escapes": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", @@ -13835,19 +13866,6 @@ "url": "https://github.com/sindresorhus/got?sponsor=1" } }, - "node_modules/release-it/node_modules/http2-wrapper": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.1.11.tgz", - "integrity": "sha512-aNAk5JzLturWEUiuhAN73Jcbq96R7rTitAoXV54FYMatvihnpD2+6PUgU4ce3D/m5VDbw+F5CsyKSF176ptitQ==", - "dev": true, - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, "node_modules/release-it/node_modules/human-signals": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-3.0.1.tgz", @@ -14033,15 +14051,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/release-it/node_modules/p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", - "dev": true, - "engines": { - "node": ">=12.20" - } - }, "node_modules/release-it/node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -19964,9 +19973,10 @@ } }, "@sindresorhus/is": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.4.0.tgz", - "integrity": "sha512-QppPM/8l3Mawvh4rn9CNEYIU9bxpXUCRMaX9yUpvBk1nMKusLKpfXGDEKExKaPhLzcn3lzil7pR6rnJ11HgeRQ==" + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.3.0.tgz", + "integrity": "sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==", + "dev": true }, "@sinonjs/commons": { "version": "1.8.3", @@ -20018,11 +20028,12 @@ } }, "@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "dev": true, "requires": { - "defer-to-connect": "^2.0.0" + "defer-to-connect": "^2.0.1" } }, "@tootallnate/once": { @@ -23696,9 +23707,9 @@ } }, "form-data-encoder": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.0.1.tgz", - "integrity": "sha512-Oy+P9w5mnO4TWXVgUiQvggNKPI9/ummcSt5usuIV6HkaLKigwzPpoenhEqmGmx3zHqm6ZLJ+CR/99N8JLinaEw==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.3.tgz", + "integrity": "sha512-KqU0nnPMgIJcCOFTNJFEA8epcseEaoox4XZffTgy8jlI6pL/5EFyR54NRG7CnCJN0biY7q52DO3MH6/sJ/TKlQ==", "dev": true }, "formdata-polyfill": { @@ -24157,9 +24168,9 @@ } }, "got": { - "version": "11.8.3", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.3.tgz", - "integrity": "sha512-7gtQ5KiPh1RtGS9/Jbv1ofDpBFuq42gyfEib+ejaRBJuj/3tQFeR5+gw57e4ipaU8c/rCjvX6fkQz2lyDlGAOg==", + "version": "11.8.5", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.5.tgz", + "integrity": "sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==", "requires": { "@sindresorhus/is": "^4.0.0", "@szmarczak/http-timer": "^4.0.5", @@ -24172,6 +24183,35 @@ "lowercase-keys": "^2.0.0", "p-cancelable": "^2.0.0", "responselike": "^2.0.0" + }, + "dependencies": { + "@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==" + }, + "@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "requires": { + "defer-to-connect": "^2.0.0" + } + }, + "http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "requires": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + } + }, + "p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==" + } } }, "graceful-fs": { @@ -24370,12 +24410,13 @@ } }, "http2-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.0.tgz", + "integrity": "sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==", + "dev": true, "requires": { "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" + "resolve-alpn": "^1.2.0" } }, "https-proxy-agent": { @@ -25758,9 +25799,9 @@ } }, "keyv": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.1.1.tgz", - "integrity": "sha512-tGv1yP6snQVDSM4X6yxrv2zzq/EvpW+oYiUz6aueW1u9CtS8RzUQYxxmFwgZlO2jSgCxQbchhxaqXXp2hnKGpQ==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", + "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", "requires": { "json-buffer": "3.0.1" } @@ -27045,9 +27086,10 @@ "dev": true }, "p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "dev": true }, "p-each-series": { "version": "2.2.0", @@ -27125,27 +27167,27 @@ "semver": "^7.3.7" }, "dependencies": { - "@sindresorhus/is": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.3.0.tgz", - "integrity": "sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==", + "cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", "dev": true }, - "@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "cacheable-request": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.2.tgz", + "integrity": "sha512-KxjQZM3UIo7/J6W4sLpwFvu1GB3Whv8NtZ8ZrUL284eiQjiXeeqWTdhixNrp/NLZ/JNuFBo6BD4ZaO8ZJ5BN8Q==", "dev": true, "requires": { - "defer-to-connect": "^2.0.1" + "@types/http-cache-semantics": "^4.0.1", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.0", + "keyv": "^4.5.0", + "mimic-response": "^4.0.0", + "normalize-url": "^7.2.0", + "responselike": "^3.0.0" } }, - "cacheable-lookup": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz", - "integrity": "sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==", - "dev": true - }, "get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -27153,34 +27195,22 @@ "dev": true }, "got": { - "version": "12.3.1", - "resolved": "https://registry.npmjs.org/got/-/got-12.3.1.tgz", - "integrity": "sha512-tS6+JMhBh4iXMSXF6KkIsRxmloPln31QHDlcb6Ec3bzxjjFJFr/8aXdpyuLmVc9I4i2HyBHYw1QU5K1ruUdpkw==", + "version": "12.5.3", + "resolved": "https://registry.npmjs.org/got/-/got-12.5.3.tgz", + "integrity": "sha512-8wKnb9MGU8IPGRIo+/ukTy9XLJBwDiCpIf5TVzQ9Cpol50eMTpBq2GAuDsuDIz7hTYmZgMgC1e9ydr6kSDWs3w==", "dev": true, "requires": { "@sindresorhus/is": "^5.2.0", "@szmarczak/http-timer": "^5.0.1", - "@types/cacheable-request": "^6.0.2", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^6.0.4", - "cacheable-request": "^7.0.2", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.1", "decompress-response": "^6.0.0", - "form-data-encoder": "^2.0.1", + "form-data-encoder": "^2.1.2", "get-stream": "^6.0.1", "http2-wrapper": "^2.1.10", "lowercase-keys": "^3.0.0", "p-cancelable": "^3.0.0", - "responselike": "^2.0.0" - } - }, - "http2-wrapper": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.1.11.tgz", - "integrity": "sha512-aNAk5JzLturWEUiuhAN73Jcbq96R7rTitAoXV54FYMatvihnpD2+6PUgU4ce3D/m5VDbw+F5CsyKSF176ptitQ==", - "dev": true, - "requires": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" + "responselike": "^3.0.0" } }, "lowercase-keys": { @@ -27189,12 +27219,27 @@ "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", "dev": true }, - "p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "dev": true + }, + "normalize-url": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-7.2.0.tgz", + "integrity": "sha512-uhXOdZry0L6M2UIo9BTt7FdpBDiAGN/7oItedQwPKh8jh31ZlvC8U9Xl/EJ3aijDHaywXTW3QbZ6LuCocur1YA==", "dev": true }, + "responselike": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "dev": true, + "requires": { + "lowercase-keys": "^3.0.0" + } + }, "semver": { "version": "7.3.7", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", @@ -27926,21 +27971,6 @@ "yargs-parser": "21.1.1" }, "dependencies": { - "@sindresorhus/is": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.3.0.tgz", - "integrity": "sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==", - "dev": true - }, - "@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", - "dev": true, - "requires": { - "defer-to-connect": "^2.0.1" - } - }, "ansi-escapes": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", @@ -28115,16 +28145,6 @@ "responselike": "^2.0.0" } }, - "http2-wrapper": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.1.11.tgz", - "integrity": "sha512-aNAk5JzLturWEUiuhAN73Jcbq96R7rTitAoXV54FYMatvihnpD2+6PUgU4ce3D/m5VDbw+F5CsyKSF176ptitQ==", - "dev": true, - "requires": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" - } - }, "human-signals": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-3.0.1.tgz", @@ -28246,12 +28266,6 @@ "wcwidth": "^1.0.1" } }, - "p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", - "dev": true - }, "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", diff --git a/package.json b/package.json index 63455f5..1d936fd 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "scripts": { "start": "tsdx watch", "build": "tsdx build", - "test": "tsdx test", + "test": "tsdx test --collect-coverage", "lint": "tsdx lint", "prepare": "tsdx build", "release": "release-it", @@ -91,7 +91,7 @@ }, "dependencies": { "debug": "^4.3.3", - "got": "^11.8.3", + "got": "^11.8.5", "jose": "^4.5.0", "lodash": "^4.17.21", "node-cache": "^5.1.2" diff --git a/src/express/index.ts b/src/express/index.ts index 4e8aa31..fab2c1a 100644 --- a/src/express/index.ts +++ b/src/express/index.ts @@ -6,6 +6,7 @@ import { RowndInstance } from '../lib/rownd'; type AuthenticateOpts = { fetchUserInfo?: boolean; errOnInvalidToken?: boolean; + errOnMissingUser?: boolean; }; type RowndRequest = express.Request & { @@ -29,6 +30,7 @@ export class RowndExpressClient implements IRowndExpressClient { opts = { fetchUserInfo: false, errOnInvalidToken: true, + errOnMissingUser: false, ...opts, }; @@ -55,27 +57,39 @@ export class RowndExpressClient implements IRowndExpressClient { _: express.Response, next: express.NextFunction ) => { + let tokenInfo; try { - let tokenInfo = await plugin.rownd.validateToken(authHeader); + tokenInfo = await plugin.rownd.validateToken(authHeader); req.tokenInfo = tokenInfo; req.authenticated = req.isAuthenticated = true; - - if (opts.fetchUserInfo) { - let userInfo = await plugin.rownd.fetchUserInfo({ - user_id: tokenInfo.user_id, - }); - req.user = userInfo.data; - } - - next(); } catch (err) { let wrappingError = new WrappedError( `The provided token was invalid. Reason: ${(err as Error).message}` ); wrappingError.innerError = err as Error; wrappingError.statusCode = 401; - opts.errOnInvalidToken ? next(wrappingError) : next(); + return opts.errOnInvalidToken ? next(wrappingError) : next(); } + + if (opts.fetchUserInfo) { + try { + let userInfo = await plugin.rownd.fetchUserInfo({ + user_id: tokenInfo.user_id, + }); + req.user = userInfo.data; + } catch (err) { + if (opts.errOnMissingUser) { + let wrappingError = new WrappedError( + `The user '${tokenInfo.user_id}' could not be retrieved. Reason: ${(err as Error).message}` + ); + wrappingError.innerError = err as Error; + wrappingError.statusCode = 404; + return next(wrappingError); + } + } + } + + next(); })(req, _, next); }; } diff --git a/src/lib/core.ts b/src/lib/core.ts index d1ea25b..6c64138 100644 --- a/src/lib/core.ts +++ b/src/lib/core.ts @@ -70,7 +70,7 @@ export async function fetchAppConfig( }, retry: { limit: Infinity, // retry forever so we hopefully don't leave the system in a bad state permanently - }, + } }) .json(); diff --git a/test/core.test.ts b/test/core.test.ts index d4e9cad..3e4f0d0 100644 --- a/test/core.test.ts +++ b/test/core.test.ts @@ -1,37 +1,59 @@ import { fetchRowndWellKnownConfig } from '../src/lib/core'; import { createInstance } from '../src'; +import { fetchAppConfig } from '../src/lib/core'; import { IRowndClient } from '../src/types'; import { server } from './mocks'; -const TOKEN: string = - 'eyJhbGciOiJFZERTQSIsImtpZCI6InNpZy0xNjQ0ODU5MTUwIn0.eyJqdGkiOiIwOGVkZTBlZC01NDRlLTQ2Y2ItOThmNi03NGE2NmYyMDY0ZGEiLCJhdWQiOlsiYXBwOjI5MDE2NzI4MTczMjgxMzMxNSIsImh0dHBzOi8vYXBpLmRldi5yb3duZC5pbyJdLCJzdWIiOiJhdXRoMHw2MWYzMDUzMjUxZjI0MjAwNjk0NTU5NzYiLCJpYXQiOjE2NTA2NTczNDQsImh0dHBzOi8vYXV0aC5yb3duZC5pby9hcHBfdXNlcl9pZCI6IjcxZjZjZWViLWVlMGEtNDQzNy05YjQ0LWU2MjI5ZGVmYmFiOCIsImh0dHBzOi8vYXV0aC5yb3duZC5pby9pc192ZXJpZmllZF91c2VyIjp0cnVlLCJpc3MiOiJodHRwczovL2FwaS5kZXYucm93bmQuaW8iLCJleHAiOjE2NTA2NjA5NDR9.-SNdqdbk_GLXYSFzwYgr4XOAjeEWsmoRPArFyjASHyvhylKHMdM5WvDrRDuMGlVVL8nkZZrrBRZjV0H09j8WCQ'; +const TOKEN: string = 'eyJhbGciOiJFZERTQSIsImtpZCI6InNpZy0xNjQ0ODU5MTUwIn0.eyJqdGkiOiIwOGVkZTBlZC01NDRlLTQ2Y2ItOThmNi03NGE2NmYyMDY0ZGEiLCJhdWQiOlsiYXBwOjI5MDE2NzI4MTczMjgxMzMxNSIsImh0dHBzOi8vYXBpLmRldi5yb3duZC5pbyJdLCJzdWIiOiJhdXRoMHw2MWYzMDUzMjUxZjI0MjAwNjk0NTU5NzYiLCJpYXQiOjE2NTA2NTczNDQsImh0dHBzOi8vYXV0aC5yb3duZC5pby9hcHBfdXNlcl9pZCI6IjcxZjZjZWViLWVlMGEtNDQzNy05YjQ0LWU2MjI5ZGVmYmFiOCIsImh0dHBzOi8vYXV0aC5yb3duZC5pby9pc192ZXJpZmllZF91c2VyIjp0cnVlLCJpc3MiOiJodHRwczovL2FwaS5kZXYucm93bmQuaW8iLCJleHAiOjE2NTA2NjA5NDR9.-SNdqdbk_GLXYSFzwYgr4XOAjeEWsmoRPArFyjASHyvhylKHMdM5WvDrRDuMGlVVL8nkZZrrBRZjV0H09j8WCQ'; const testConfig = { api_url: 'https://mock-api.local', }; -describe('validate token', () => { +describe('core tests', () => { let rowndInstance: IRowndClient; - beforeAll(() => { - server.listen(); - rowndInstance = createInstance(testConfig); - }); + beforeAll(() => { + server.listen(); + rowndInstance = createInstance(testConfig); + }); - afterEach(() => { - server.resetHandlers(); - }); + afterEach(() => { + server.resetHandlers(); + }); - afterAll(() => { - server.close(); - return new Promise(resolve => setTimeout(() => resolve(null), 100)); - }); + afterAll(() => { + server.close(); + return new Promise(resolve => setTimeout(() => resolve(null), 100)); + }); - it('fetches well known config', async () => { - let resp = await fetchRowndWellKnownConfig(testConfig.api_url); - expect(resp).toBeDefined(); + describe('resiliently fetch app config', () => { + it('fetches the app config', async () => { + const appConfig = await fetchAppConfig(testConfig.api_url, 'test-app-key'); + expect(appConfig).toBeDefined(); + expect(appConfig.id).toBe('290167281732813315'); + }); + + it('fetches the app config after retrying', async () => { + jest.setTimeout(30000); + try { + const appConfig = await fetchAppConfig('https://mock-api-2.local', 'test-app-key'); + expect(appConfig).toBeDefined(); + expect(appConfig.id).toBe('290167281732813315'); + } catch (err) { + console.error(err); + fail('should not ever throw an error'); + } + }); }); - it('throws on expired token', async () => { - await expect(rowndInstance.validateToken(TOKEN)).rejects.toThrow(Error); + describe('validate token', () => { + it('fetches well known config', async () => { + let resp = await fetchRowndWellKnownConfig(testConfig.api_url); + expect(resp).toBeDefined(); + }); + + it('throws on expired token', async () => { + await expect(rowndInstance.validateToken(TOKEN)).rejects.toThrow(Error); + }); }); }); diff --git a/test/mocks.ts b/test/mocks.ts index d2e6aef..54c0c01 100644 --- a/test/mocks.ts +++ b/test/mocks.ts @@ -28,6 +28,138 @@ export async function generateTestToken() { return jwt; } +const appConfig = { + app: { + name: 'Rownd (dev)', + id: '290167281732813315', + schema: { + email: { + display_name: 'Email', + type: 'string', + data_category: 'pii_basic', + required: false, + owned_by: 'user', + user_visible: true, + revoke_after: '1 month', + required_retention: 'none', + collection_justification: + 'This piece of personal data is needed to make your customer experience the best it can be. We do not resell this data.', + opt_out_warning: + 'By turning off your e-mail, your account will no longer work as designed. You may not be able to log-in, get updates, or reset your password', + }, + first_name: { + display_name: 'First name', + type: 'string', + data_category: 'pii_basic', + required: false, + owned_by: 'user', + user_visible: true, + revoke_after: '1 month', + required_retention: 'none', + collection_justification: + 'We collect this data to personalize your Rownd experience. ', + opt_out_warning: + 'We will not be able to call you by your first name. ', + third_party_sharing: false, + }, + last_name: { + display_name: 'Last name', + type: 'string', + data_category: 'pii_basic', + required: false, + owned_by: 'user', + user_visible: true, + revoke_after: '1 month', + required_retention: 'none', + collection_justification: '', + opt_out_warning: '', + }, + zip_code: { + display_name: 'Zip code', + type: 'string', + data_category: 'pii_basic', + required: false, + owned_by: 'user', + user_visible: true, + revoke_after: '1 month', + required_retention: 'none', + collection_justification: '', + opt_out_warning: '', + }, + phone_number: { + display_name: 'Phone number', + type: 'string', + data_category: 'pii_basic', + required: false, + owned_by: 'user', + user_visible: true, + revoke_after: '1 month', + required_retention: 'none', + collection_justification: + 'This piece of personal data is needed to make your customer experience the best it can be. We do not resell this data.', + }, + crypto_wallet_address: { + display_name: 'Wallet Address', + type: 'string', + data_category: 'custom', + required: false, + owned_by: 'app', + user_visible: false, + revoke_after: 'never', + required_retention: 'none', + collection_justification: '', + opt_out_warning: '', + }, + google_id: { + display_name: 'Google ID', + type: 'string', + data_category: 'custom', + required: false, + owned_by: 'app', + user_visible: false, + revoke_after: 'never', + required_retention: 'none', + collection_justification: '', + opt_out_warning: '', + }, + }, + user_verification_field: 'email', + user_verification_fields: ['email', 'phone_number', 'google_id'], + icon: 'https://storage-dev.rownd.io/icon-app-290167281732813315', + config: { + hub: { + customizations: { + rounded_corners: true, + offset_y: 72, + visual_swoops: true, + blur_background: true, + dark_mode: 'disabled', + }, + auth: { + audience: ['https://api.dev.rownd.io'], + sign_in_methods: { + email: { enabled: true }, + phone: { enabled: true }, + apple: { enabled: false, client_id: '' }, + google: { + enabled: true, + client_id: + '437354109064-pmkrcopm4r88dm6jluf8av0ds06mps9k.apps.googleusercontent.com', + client_secret: '********', + ios_client_id: '', + scopes: [''], + }, + crypto_wallet: { enabled: false }, + }, + show_app_icon: false, + }, + }, + content_gates: [], + }, + }, +}; + +let appConfigRetryCounter = 0; const handlers = [ rest.get( 'https://mock-api.local/hub/auth/.well-known/oauth-authorization-server', @@ -86,139 +218,29 @@ const handlers = [ rest.get('https://mock-api.local/hub/app-config', (_, res, ctx) => { return res( - ctx.json({ - app: { - name: 'Rownd (dev)', - id: '290167281732813315', - schema: { - email: { - display_name: 'Email', - type: 'string', - data_category: 'pii_basic', - required: false, - owned_by: 'user', - user_visible: true, - revoke_after: '1 month', - required_retention: 'none', - collection_justification: - 'This piece of personal data is needed to make your customer experience the best it can be. We do not resell this data.', - opt_out_warning: - 'By turning off your e-mail, your account will no longer work as designed. You may not be able to log-in, get updates, or reset your password', - }, - first_name: { - display_name: 'First name', - type: 'string', - data_category: 'pii_basic', - required: false, - owned_by: 'user', - user_visible: true, - revoke_after: '1 month', - required_retention: 'none', - collection_justification: - 'We collect this data to personalize your Rownd experience. ', - opt_out_warning: - 'We will not be able to call you by your first name. ', - third_party_sharing: false, - }, - last_name: { - display_name: 'Last name', - type: 'string', - data_category: 'pii_basic', - required: false, - owned_by: 'user', - user_visible: true, - revoke_after: '1 month', - required_retention: 'none', - collection_justification: '', - opt_out_warning: '', - }, - zip_code: { - display_name: 'Zip code', - type: 'string', - data_category: 'pii_basic', - required: false, - owned_by: 'user', - user_visible: true, - revoke_after: '1 month', - required_retention: 'none', - collection_justification: '', - opt_out_warning: '', - }, - phone_number: { - display_name: 'Phone number', - type: 'string', - data_category: 'pii_basic', - required: false, - owned_by: 'user', - user_visible: true, - revoke_after: '1 month', - required_retention: 'none', - collection_justification: - 'This piece of personal data is needed to make your customer experience the best it can be. We do not resell this data.', - }, - crypto_wallet_address: { - display_name: 'Wallet Address', - type: 'string', - data_category: 'custom', - required: false, - owned_by: 'app', - user_visible: false, - revoke_after: 'never', - required_retention: 'none', - collection_justification: '', - opt_out_warning: '', - }, - google_id: { - display_name: 'Google ID', - type: 'string', - data_category: 'custom', - required: false, - owned_by: 'app', - user_visible: false, - revoke_after: 'never', - required_retention: 'none', - collection_justification: '', - opt_out_warning: '', - }, - }, - user_verification_field: 'email', - user_verification_fields: ['email', 'phone_number', 'google_id'], - icon: 'https://storage-dev.rownd.io/icon-app-290167281732813315', - config: { - hub: { - customizations: { - rounded_corners: true, - offset_y: 72, - visual_swoops: true, - blur_background: true, - dark_mode: 'disabled', - }, - auth: { - audience: ['https://api.dev.rownd.io'], - sign_in_methods: { - email: { enabled: true }, - phone: { enabled: true }, - apple: { enabled: false, client_id: '' }, - google: { - enabled: true, - client_id: - '437354109064-pmkrcopm4r88dm6jluf8av0ds06mps9k.apps.googleusercontent.com', - client_secret: '********', - ios_client_id: '', - scopes: [''], - }, - crypto_wallet: { enabled: false }, - }, - show_app_icon: false, - }, - }, - content_gates: [], - }, - }, - }) + ctx.json(appConfig) ); }), + rest.get('https://mock-api-2.local/hub/app-config', async (_, res, ctx) => { + appConfigRetryCounter++; + switch (appConfigRetryCounter) { + case 1: + case 2: + case 3: + case 4: + await require('timers/promises').setTimeout(2500); + return res( + ctx.status(500), + ctx.text('') + ); + default: + return res( + ctx.json(appConfig) + ); + } + }), + rest.get( 'https://mock-api.local/applications/290167281732813315/users/rownd-test-user-1/data', (_, res, ctx) => { diff --git a/yarn.lock b/yarn.lock index 4d62cbf..c40694b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1547,9 +1547,9 @@ "picomatch" "^2.2.2" "@sindresorhus/is@^4.0.0": - "integrity" "sha512-QppPM/8l3Mawvh4rn9CNEYIU9bxpXUCRMaX9yUpvBk1nMKusLKpfXGDEKExKaPhLzcn3lzil7pR6rnJ11HgeRQ==" - "resolved" "https://registry.npmjs.org/@sindresorhus/is/-/is-4.4.0.tgz" - "version" "4.4.0" + "integrity" "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==" + "resolved" "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz" + "version" "4.6.0" "@sindresorhus/is@^5.2.0": "integrity" "sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==" @@ -1736,7 +1736,7 @@ dependencies: "@types/node" "*" -"@types/http-cache-semantics@*": +"@types/http-cache-semantics@*", "@types/http-cache-semantics@^4.0.1": "integrity" "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" "resolved" "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz" "version" "4.0.1" @@ -2681,6 +2681,24 @@ "resolved" "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz" "version" "6.1.0" +"cacheable-lookup@^7.0.0": + "integrity" "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==" + "resolved" "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz" + "version" "7.0.0" + +"cacheable-request@^10.2.1": + "integrity" "sha512-KxjQZM3UIo7/J6W4sLpwFvu1GB3Whv8NtZ8ZrUL284eiQjiXeeqWTdhixNrp/NLZ/JNuFBo6BD4ZaO8ZJ5BN8Q==" + "resolved" "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.2.tgz" + "version" "10.2.2" + dependencies: + "@types/http-cache-semantics" "^4.0.1" + "get-stream" "^6.0.1" + "http-cache-semantics" "^4.1.0" + "keyv" "^4.5.0" + "mimic-response" "^4.0.0" + "normalize-url" "^7.2.0" + "responselike" "^3.0.0" + "cacheable-request@^7.0.2": "integrity" "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==" "resolved" "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz" @@ -4504,10 +4522,10 @@ "resolved" "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz" "version" "0.6.1" -"form-data-encoder@^2.0.1": - "integrity" "sha512-Oy+P9w5mnO4TWXVgUiQvggNKPI9/ummcSt5usuIV6HkaLKigwzPpoenhEqmGmx3zHqm6ZLJ+CR/99N8JLinaEw==" - "resolved" "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.0.1.tgz" - "version" "2.0.1" +"form-data-encoder@^2.0.1", "form-data-encoder@^2.1.2": + "integrity" "sha512-KqU0nnPMgIJcCOFTNJFEA8epcseEaoox4XZffTgy8jlI6pL/5EFyR54NRG7CnCJN0biY7q52DO3MH6/sJ/TKlQ==" + "resolved" "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.3.tgz" + "version" "2.1.3" "form-data@~2.3.2": "integrity" "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==" @@ -4845,10 +4863,10 @@ dependencies: "get-intrinsic" "^1.1.3" -"got@^11.8.3": - "integrity" "sha512-7gtQ5KiPh1RtGS9/Jbv1ofDpBFuq42gyfEib+ejaRBJuj/3tQFeR5+gw57e4ipaU8c/rCjvX6fkQz2lyDlGAOg==" - "resolved" "https://registry.npmjs.org/got/-/got-11.8.3.tgz" - "version" "11.8.3" +"got@^11.8.5": + "integrity" "sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==" + "resolved" "https://registry.npmjs.org/got/-/got-11.8.5.tgz" + "version" "11.8.5" dependencies: "@sindresorhus/is" "^4.0.0" "@szmarczak/http-timer" "^4.0.5" @@ -4863,23 +4881,21 @@ "responselike" "^2.0.0" "got@^12.1.0": - "integrity" "sha512-tS6+JMhBh4iXMSXF6KkIsRxmloPln31QHDlcb6Ec3bzxjjFJFr/8aXdpyuLmVc9I4i2HyBHYw1QU5K1ruUdpkw==" - "resolved" "https://registry.npmjs.org/got/-/got-12.3.1.tgz" - "version" "12.3.1" + "integrity" "sha512-8wKnb9MGU8IPGRIo+/ukTy9XLJBwDiCpIf5TVzQ9Cpol50eMTpBq2GAuDsuDIz7hTYmZgMgC1e9ydr6kSDWs3w==" + "resolved" "https://registry.npmjs.org/got/-/got-12.5.3.tgz" + "version" "12.5.3" dependencies: "@sindresorhus/is" "^5.2.0" "@szmarczak/http-timer" "^5.0.1" - "@types/cacheable-request" "^6.0.2" - "@types/responselike" "^1.0.0" - "cacheable-lookup" "^6.0.4" - "cacheable-request" "^7.0.2" + "cacheable-lookup" "^7.0.0" + "cacheable-request" "^10.2.1" "decompress-response" "^6.0.0" - "form-data-encoder" "^2.0.1" + "form-data-encoder" "^2.1.2" "get-stream" "^6.0.1" "http2-wrapper" "^2.1.10" "lowercase-keys" "^3.0.0" "p-cancelable" "^3.0.0" - "responselike" "^2.0.0" + "responselike" "^3.0.0" "got@12.3.1": "integrity" "sha512-tS6+JMhBh4iXMSXF6KkIsRxmloPln31QHDlcb6Ec3bzxjjFJFr/8aXdpyuLmVc9I4i2HyBHYw1QU5K1ruUdpkw==" @@ -5051,7 +5067,7 @@ "resolved" "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz" "version" "2.0.2" -"http-cache-semantics@^4.0.0": +"http-cache-semantics@^4.0.0", "http-cache-semantics@^4.1.0": "integrity" "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" "resolved" "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz" "version" "4.1.0" @@ -5094,9 +5110,9 @@ "resolve-alpn" "^1.0.0" "http2-wrapper@^2.1.10": - "integrity" "sha512-aNAk5JzLturWEUiuhAN73Jcbq96R7rTitAoXV54FYMatvihnpD2+6PUgU4ce3D/m5VDbw+F5CsyKSF176ptitQ==" - "resolved" "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.1.11.tgz" - "version" "2.1.11" + "integrity" "sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==" + "resolved" "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.0.tgz" + "version" "2.2.0" dependencies: "quick-lru" "^5.1.1" "resolve-alpn" "^1.2.0" @@ -6362,10 +6378,10 @@ "array-includes" "^3.1.3" "object.assign" "^4.1.2" -"keyv@^4.0.0": - "integrity" "sha512-tGv1yP6snQVDSM4X6yxrv2zzq/EvpW+oYiUz6aueW1u9CtS8RzUQYxxmFwgZlO2jSgCxQbchhxaqXXp2hnKGpQ==" - "resolved" "https://registry.npmjs.org/keyv/-/keyv-4.1.1.tgz" - "version" "4.1.1" +"keyv@^4.0.0", "keyv@^4.5.0": + "integrity" "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==" + "resolved" "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz" + "version" "4.5.2" dependencies: "json-buffer" "3.0.1" @@ -6753,6 +6769,11 @@ "resolved" "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz" "version" "3.1.0" +"mimic-response@^4.0.0": + "integrity" "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==" + "resolved" "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz" + "version" "4.0.0" + "min-indent@^1.0.0": "integrity" "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==" "resolved" "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz" @@ -7025,6 +7046,11 @@ "resolved" "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz" "version" "6.1.0" +"normalize-url@^7.2.0": + "integrity" "sha512-uhXOdZry0L6M2UIo9BTt7FdpBDiAGN/7oItedQwPKh8jh31ZlvC8U9Xl/EJ3aijDHaywXTW3QbZ6LuCocur1YA==" + "resolved" "https://registry.npmjs.org/normalize-url/-/normalize-url-7.2.0.tgz" + "version" "7.2.0" + "npm-run-path@^2.0.0": "integrity" "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=" "resolved" "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz" @@ -8132,6 +8158,13 @@ dependencies: "lowercase-keys" "^2.0.0" +"responselike@^3.0.0": + "integrity" "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==" + "resolved" "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz" + "version" "3.0.0" + dependencies: + "lowercase-keys" "^3.0.0" + "restore-cursor@^2.0.0": "integrity" "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=" "resolved" "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz" From a8e9f3b8812deb3d95a065f9987c8903a476238c Mon Sep 17 00:00:00 2001 From: Matt Hamann Date: Thu, 17 Nov 2022 00:48:25 -0500 Subject: [PATCH 2/4] chore: lint fixes --- src/express/index.ts | 4 +++- src/lib/core.ts | 2 +- test/core.test.ts | 35 +++++++++++++++++++++-------------- test/mocks.ts | 16 ++++------------ 4 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/express/index.ts b/src/express/index.ts index fab2c1a..61aedc0 100644 --- a/src/express/index.ts +++ b/src/express/index.ts @@ -80,7 +80,9 @@ export class RowndExpressClient implements IRowndExpressClient { } catch (err) { if (opts.errOnMissingUser) { let wrappingError = new WrappedError( - `The user '${tokenInfo.user_id}' could not be retrieved. Reason: ${(err as Error).message}` + `The user '${ + tokenInfo.user_id + }' could not be retrieved. Reason: ${(err as Error).message}` ); wrappingError.innerError = err as Error; wrappingError.statusCode = 404; diff --git a/src/lib/core.ts b/src/lib/core.ts index 6c64138..d1ea25b 100644 --- a/src/lib/core.ts +++ b/src/lib/core.ts @@ -70,7 +70,7 @@ export async function fetchAppConfig( }, retry: { limit: Infinity, // retry forever so we hopefully don't leave the system in a bad state permanently - } + }, }) .json(); diff --git a/test/core.test.ts b/test/core.test.ts index 3e4f0d0..a8be1e7 100644 --- a/test/core.test.ts +++ b/test/core.test.ts @@ -4,7 +4,8 @@ import { fetchAppConfig } from '../src/lib/core'; import { IRowndClient } from '../src/types'; import { server } from './mocks'; -const TOKEN: string = 'eyJhbGciOiJFZERTQSIsImtpZCI6InNpZy0xNjQ0ODU5MTUwIn0.eyJqdGkiOiIwOGVkZTBlZC01NDRlLTQ2Y2ItOThmNi03NGE2NmYyMDY0ZGEiLCJhdWQiOlsiYXBwOjI5MDE2NzI4MTczMjgxMzMxNSIsImh0dHBzOi8vYXBpLmRldi5yb3duZC5pbyJdLCJzdWIiOiJhdXRoMHw2MWYzMDUzMjUxZjI0MjAwNjk0NTU5NzYiLCJpYXQiOjE2NTA2NTczNDQsImh0dHBzOi8vYXV0aC5yb3duZC5pby9hcHBfdXNlcl9pZCI6IjcxZjZjZWViLWVlMGEtNDQzNy05YjQ0LWU2MjI5ZGVmYmFiOCIsImh0dHBzOi8vYXV0aC5yb3duZC5pby9pc192ZXJpZmllZF91c2VyIjp0cnVlLCJpc3MiOiJodHRwczovL2FwaS5kZXYucm93bmQuaW8iLCJleHAiOjE2NTA2NjA5NDR9.-SNdqdbk_GLXYSFzwYgr4XOAjeEWsmoRPArFyjASHyvhylKHMdM5WvDrRDuMGlVVL8nkZZrrBRZjV0H09j8WCQ'; +const TOKEN: string = + 'eyJhbGciOiJFZERTQSIsImtpZCI6InNpZy0xNjQ0ODU5MTUwIn0.eyJqdGkiOiIwOGVkZTBlZC01NDRlLTQ2Y2ItOThmNi03NGE2NmYyMDY0ZGEiLCJhdWQiOlsiYXBwOjI5MDE2NzI4MTczMjgxMzMxNSIsImh0dHBzOi8vYXBpLmRldi5yb3duZC5pbyJdLCJzdWIiOiJhdXRoMHw2MWYzMDUzMjUxZjI0MjAwNjk0NTU5NzYiLCJpYXQiOjE2NTA2NTczNDQsImh0dHBzOi8vYXV0aC5yb3duZC5pby9hcHBfdXNlcl9pZCI6IjcxZjZjZWViLWVlMGEtNDQzNy05YjQ0LWU2MjI5ZGVmYmFiOCIsImh0dHBzOi8vYXV0aC5yb3duZC5pby9pc192ZXJpZmllZF91c2VyIjp0cnVlLCJpc3MiOiJodHRwczovL2FwaS5kZXYucm93bmQuaW8iLCJleHAiOjE2NTA2NjA5NDR9.-SNdqdbk_GLXYSFzwYgr4XOAjeEWsmoRPArFyjASHyvhylKHMdM5WvDrRDuMGlVVL8nkZZrrBRZjV0H09j8WCQ'; const testConfig = { api_url: 'https://mock-api.local', @@ -12,23 +13,26 @@ const testConfig = { describe('core tests', () => { let rowndInstance: IRowndClient; - beforeAll(() => { - server.listen(); - rowndInstance = createInstance(testConfig); - }); + beforeAll(() => { + server.listen(); + rowndInstance = createInstance(testConfig); + }); - afterEach(() => { - server.resetHandlers(); - }); + afterEach(() => { + server.resetHandlers(); + }); - afterAll(() => { - server.close(); - return new Promise(resolve => setTimeout(() => resolve(null), 100)); - }); + afterAll(() => { + server.close(); + return new Promise(resolve => setTimeout(() => resolve(null), 100)); + }); describe('resiliently fetch app config', () => { it('fetches the app config', async () => { - const appConfig = await fetchAppConfig(testConfig.api_url, 'test-app-key'); + const appConfig = await fetchAppConfig( + testConfig.api_url, + 'test-app-key' + ); expect(appConfig).toBeDefined(); expect(appConfig.id).toBe('290167281732813315'); }); @@ -36,7 +40,10 @@ describe('core tests', () => { it('fetches the app config after retrying', async () => { jest.setTimeout(30000); try { - const appConfig = await fetchAppConfig('https://mock-api-2.local', 'test-app-key'); + const appConfig = await fetchAppConfig( + 'https://mock-api-2.local', + 'test-app-key' + ); expect(appConfig).toBeDefined(); expect(appConfig.id).toBe('290167281732813315'); } catch (err) { diff --git a/test/mocks.ts b/test/mocks.ts index 54c0c01..c5eb0eb 100644 --- a/test/mocks.ts +++ b/test/mocks.ts @@ -58,8 +58,7 @@ const appConfig = { required_retention: 'none', collection_justification: 'We collect this data to personalize your Rownd experience. ', - opt_out_warning: - 'We will not be able to call you by your first name. ', + opt_out_warning: 'We will not be able to call you by your first name. ', third_party_sharing: false, }, last_name: { @@ -217,9 +216,7 @@ const handlers = [ }), rest.get('https://mock-api.local/hub/app-config', (_, res, ctx) => { - return res( - ctx.json(appConfig) - ); + return res(ctx.json(appConfig)); }), rest.get('https://mock-api-2.local/hub/app-config', async (_, res, ctx) => { @@ -230,14 +227,9 @@ const handlers = [ case 3: case 4: await require('timers/promises').setTimeout(2500); - return res( - ctx.status(500), - ctx.text('') - ); + return res(ctx.status(500), ctx.text('')); default: - return res( - ctx.json(appConfig) - ); + return res(ctx.json(appConfig)); } }), From 343864d683cd9884711eb26fd84a81010b44504b Mon Sep 17 00:00:00 2001 From: Matt Hamann Date: Thu, 17 Nov 2022 10:09:09 -0500 Subject: [PATCH 3/4] fix(api): set user agent --- package-lock.json | 13 +++++++++++++ package.json | 2 ++ src/lib/constants.ts | 4 ++++ src/lib/got.ts | 4 ++++ src/version.ts | 1 + test/constants.test.ts | 7 +++++++ test/mocks.ts | 3 ++- tsconfig.json | 8 +++++++- types/awaitable-timers.d.ts | 5 +++++ yarn.lock | 5 +++++ 10 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 src/lib/constants.ts create mode 100644 src/version.ts create mode 100644 test/constants.test.ts create mode 100644 types/awaitable-timers.d.ts diff --git a/package-lock.json b/package-lock.json index fbdab89..f4f83a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "@types/jsonwebtoken": "^8.5.8", "@types/lodash": "^4.14.179", "@types/node-jose": "^1.1.8", + "awaitable-timers": "^1.0.0", "commitlint": "^17.0.3", "express": "^4.17.2", "husky": "^7.0.4", @@ -4268,6 +4269,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/awaitable-timers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/awaitable-timers/-/awaitable-timers-1.0.0.tgz", + "integrity": "sha512-ZZVaSfw/O5dycGhKUqIbc9sWBiUGV3vWcHzAhdtAyo/h33pCcld1elT7OEmoq0C2Lvztci3jhWqkpbXyCE/t0A==", + "dev": true + }, "node_modules/aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", @@ -20834,6 +20841,12 @@ "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", "dev": true }, + "awaitable-timers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/awaitable-timers/-/awaitable-timers-1.0.0.tgz", + "integrity": "sha512-ZZVaSfw/O5dycGhKUqIbc9sWBiUGV3vWcHzAhdtAyo/h33pCcld1elT7OEmoq0C2Lvztci3jhWqkpbXyCE/t0A==", + "dev": true + }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", diff --git a/package.json b/package.json index 1d936fd..3b099d9 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ }, "scripts": { "start": "tsdx watch", + "prebuild": "node -p \"'export const LIB_VERSION = ' + JSON.stringify(require('./package.json').version) + ';'\" > src/version.ts", "build": "tsdx build", "test": "tsdx test --collect-coverage", "lint": "tsdx lint", @@ -79,6 +80,7 @@ "@types/jsonwebtoken": "^8.5.8", "@types/lodash": "^4.14.179", "@types/node-jose": "^1.1.8", + "awaitable-timers": "^1.0.0", "commitlint": "^17.0.3", "express": "^4.17.2", "husky": "^7.0.4", diff --git a/src/lib/constants.ts b/src/lib/constants.ts new file mode 100644 index 0000000..45e1de0 --- /dev/null +++ b/src/lib/constants.ts @@ -0,0 +1,4 @@ +import * as os from 'os'; +import { LIB_VERSION } from '../version'; + +export const DEFAULT_API_USER_AGENT = `Rownd SDK for Node.js/${LIB_VERSION} (Language: Node.js; Platform=${os.arch()}/${os.platform()} ${os.release()}};)`; \ No newline at end of file diff --git a/src/lib/got.ts b/src/lib/got.ts index b03fce4..46cf758 100644 --- a/src/lib/got.ts +++ b/src/lib/got.ts @@ -1,10 +1,14 @@ import got from 'got'; import debugLib from 'debug'; import { pick } from 'lodash'; +import { DEFAULT_API_USER_AGENT } from './constants'; const debug = debugLib('rownd:got'); const instance = got.extend({ + headers: { + 'user-agent': DEFAULT_API_USER_AGENT, + }, hooks: { beforeRequest: [ options => { diff --git a/src/version.ts b/src/version.ts new file mode 100644 index 0000000..b70e96d --- /dev/null +++ b/src/version.ts @@ -0,0 +1 @@ +export const LIB_VERSION = "2.2.0"; diff --git a/test/constants.test.ts b/test/constants.test.ts new file mode 100644 index 0000000..b06783f --- /dev/null +++ b/test/constants.test.ts @@ -0,0 +1,7 @@ +import { DEFAULT_API_USER_AGENT } from '../src/lib/constants'; + +describe('constants compile and resolve', () => { + it('user agent string compiles', () => { + expect(DEFAULT_API_USER_AGENT).toBeDefined(); + }) +}); diff --git a/test/mocks.ts b/test/mocks.ts index c5eb0eb..aea3608 100644 --- a/test/mocks.ts +++ b/test/mocks.ts @@ -2,6 +2,7 @@ import { setupServer } from 'msw/node'; import { rest } from 'msw'; import * as jose from 'jose'; import { CLAIM_USER_ID } from '../src/lib/core'; +import * as timers from 'awaitable-timers'; // Init JWK let keyPair: Promise = jose.generateKeyPair( @@ -226,7 +227,7 @@ const handlers = [ case 2: case 3: case 4: - await require('timers/promises').setTimeout(2500); + await timers.setTimeout(2500); return res(ctx.status(500), ctx.text('')); default: return res(ctx.json(appConfig)); diff --git a/tsconfig.json b/tsconfig.json index 2d7419f..cfc84a8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -21,6 +21,8 @@ "noUnusedParameters": true, // use Node's module resolution algorithm, instead of the legacy TS one "moduleResolution": "node", + // allow importing of json files + "resolveJsonModule": true, // transpile JSX to React.createElement "jsx": "react", // interop between ESM and CJS modules. Recommended by TS @@ -30,6 +32,10 @@ // error out if import and file system have a casing mismatch. Recommended by TS "forceConsistentCasingInFileNames": true, // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true + "noEmit": true, + "typeRoots": [ + "./types", + "./node_modules/@types" + ] } } diff --git a/types/awaitable-timers.d.ts b/types/awaitable-timers.d.ts new file mode 100644 index 0000000..99cd621 --- /dev/null +++ b/types/awaitable-timers.d.ts @@ -0,0 +1,5 @@ +declare module 'awaitable-timers' { + export function setImmediate(): Promise; + export function setTimeout(timeout: Number): Promise; + export function setInterval(interval: Number): Promise +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index c40694b..de07aac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2311,6 +2311,11 @@ "resolved" "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz" "version" "1.0.5" +"awaitable-timers@^1.0.0": + "integrity" "sha512-ZZVaSfw/O5dycGhKUqIbc9sWBiUGV3vWcHzAhdtAyo/h33pCcld1elT7OEmoq0C2Lvztci3jhWqkpbXyCE/t0A==" + "resolved" "https://registry.npmjs.org/awaitable-timers/-/awaitable-timers-1.0.0.tgz" + "version" "1.0.0" + "aws-sign2@~0.7.0": "integrity" "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" "resolved" "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz" From 62c3c5866946744892d036f00766fa87ab47ef41 Mon Sep 17 00:00:00 2001 From: Matt Hamann Date: Thu, 17 Nov 2022 10:18:33 -0500 Subject: [PATCH 4/4] chore: lint fixes --- src/lib/constants.ts | 2 +- src/version.ts | 2 +- test/constants.test.ts | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lib/constants.ts b/src/lib/constants.ts index 45e1de0..b29df5f 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -1,4 +1,4 @@ import * as os from 'os'; import { LIB_VERSION } from '../version'; -export const DEFAULT_API_USER_AGENT = `Rownd SDK for Node.js/${LIB_VERSION} (Language: Node.js; Platform=${os.arch()}/${os.platform()} ${os.release()}};)`; \ No newline at end of file +export const DEFAULT_API_USER_AGENT = `Rownd SDK for Node.js/${LIB_VERSION} (Language: Node.js; Platform=${os.arch()}/${os.platform()} ${os.release()}};)`; diff --git a/src/version.ts b/src/version.ts index b70e96d..3357445 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const LIB_VERSION = "2.2.0"; +export const LIB_VERSION = '2.2.0'; diff --git a/test/constants.test.ts b/test/constants.test.ts index b06783f..dc6375c 100644 --- a/test/constants.test.ts +++ b/test/constants.test.ts @@ -1,7 +1,7 @@ import { DEFAULT_API_USER_AGENT } from '../src/lib/constants'; describe('constants compile and resolve', () => { - it('user agent string compiles', () => { - expect(DEFAULT_API_USER_AGENT).toBeDefined(); - }) + it('user agent string compiles', () => { + expect(DEFAULT_API_USER_AGENT).toBeDefined(); + }); });