From fb7fed9757ddf286abd38b1193deea1f9e7df61b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-K=C3=A5re=20Solbakken?= Date: Thu, 8 Aug 2019 09:38:51 +0200 Subject: [PATCH 1/3] person lookup, not hooked up to any routes yet --- .eslintrc | 2 +- __mocks__/request.js | 29 +++++++ package-lock.json | 132 ++++++++++++++++---------------- src/server/authsupport.js | 19 ++++- src/server/authsupport.test.js | 54 ++++++++----- src/server/config.js | 7 ++ src/server/personlookup.js | 83 ++++++++++++++++++++ src/server/personlookup.test.js | 46 +++++++++++ src/server/server.js | 2 +- src/server/storage.test.js | 2 +- 10 files changed, 284 insertions(+), 92 deletions(-) create mode 100644 __mocks__/request.js create mode 100644 src/server/personlookup.js create mode 100644 src/server/personlookup.test.js diff --git a/.eslintrc b/.eslintrc index 2cf81a22a..a7a57817a 100644 --- a/.eslintrc +++ b/.eslintrc @@ -29,7 +29,7 @@ } }, { - "files": ["**/*.test.js"], + "files": ["**/*.test.js", "__mocks__/**/*.js"], "env": { "mocha": true, "node": true, diff --git a/__mocks__/request.js b/__mocks__/request.js new file mode 100644 index 000000000..dbadea971 --- /dev/null +++ b/__mocks__/request.js @@ -0,0 +1,29 @@ +'use strict'; + +jest.genMockFromModule('request'); + +let stsStatusCode = 0; +let stsResponseBody = {}; +let personStatusCode = 0; +let personResponseBody = {}; + +const setStsStatusCode = code => (stsStatusCode = code); +const setStsResponseBody = body => (stsResponseBody = body); +const setPersonStatusCode = code => (personStatusCode = code); +const setPersonResponseBody = body => (personResponseBody = body); + +const get = (url, options, callback) => { + if (url.includes('/sts/')) { + callback(null, { statusCode: stsStatusCode }, stsResponseBody); + } else { + callback(null, { statusCode: personStatusCode }, personResponseBody); + } +}; + +module.exports = { + get: get, + setStsStatusCode: setStsStatusCode, + setStsResponseBody: setStsResponseBody, + setPersonStatusCode: setPersonStatusCode, + setPersonResponseBody: setPersonResponseBody +}; diff --git a/package-lock.json b/package-lock.json index 5429bd46e..1f29117d3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5781,28 +5781,28 @@ "dependencies": { "abbrev": { "version": "1.1.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true, "optional": true }, "ansi-regex": { "version": "2.1.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true, "optional": true }, "aproba": { "version": "1.2.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "dev": true, "optional": true }, "are-we-there-yet": { "version": "1.1.5", - "resolved": false, + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", "dev": true, "optional": true, @@ -5813,14 +5813,14 @@ }, "balanced-match": { "version": "1.0.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true, "optional": true }, "brace-expansion": { "version": "1.1.11", - "resolved": false, + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "optional": true, @@ -5831,42 +5831,42 @@ }, "chownr": { "version": "1.1.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", "dev": true, "optional": true }, "code-point-at": { "version": "1.1.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true, "optional": true }, "concat-map": { "version": "0.0.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true, "optional": true }, "console-control-strings": { "version": "1.1.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", "dev": true, "optional": true }, "core-util-is": { "version": "1.0.2", - "resolved": false, + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true, "optional": true }, "debug": { "version": "4.1.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "optional": true, @@ -5876,28 +5876,28 @@ }, "deep-extend": { "version": "0.6.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true, "optional": true }, "delegates": { "version": "1.0.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", "dev": true, "optional": true }, "detect-libc": { "version": "1.0.3", - "resolved": false, + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", "dev": true, "optional": true }, "fs-minipass": { "version": "1.2.5", - "resolved": false, + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", "dev": true, "optional": true, @@ -5907,14 +5907,14 @@ }, "fs.realpath": { "version": "1.0.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true, "optional": true }, "gauge": { "version": "2.7.4", - "resolved": false, + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "dev": true, "optional": true, @@ -5931,7 +5931,7 @@ }, "glob": { "version": "7.1.3", - "resolved": false, + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "dev": true, "optional": true, @@ -5946,14 +5946,14 @@ }, "has-unicode": { "version": "2.0.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", "dev": true, "optional": true }, "iconv-lite": { "version": "0.4.24", - "resolved": false, + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "optional": true, @@ -5963,7 +5963,7 @@ }, "ignore-walk": { "version": "3.0.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", "dev": true, "optional": true, @@ -5973,7 +5973,7 @@ }, "inflight": { "version": "1.0.6", - "resolved": false, + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "optional": true, @@ -5984,21 +5984,21 @@ }, "inherits": { "version": "2.0.3", - "resolved": false, + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true, "optional": true }, "ini": { "version": "1.3.5", - "resolved": false, + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true, "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "optional": true, @@ -6008,14 +6008,14 @@ }, "isarray": { "version": "1.0.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true, "optional": true }, "minimatch": { "version": "3.0.4", - "resolved": false, + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "optional": true, @@ -6025,14 +6025,14 @@ }, "minimist": { "version": "0.0.8", - "resolved": false, + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true, "optional": true }, "minipass": { "version": "2.3.5", - "resolved": false, + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", "dev": true, "optional": true, @@ -6043,7 +6043,7 @@ }, "minizlib": { "version": "1.2.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz", "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", "dev": true, "optional": true, @@ -6053,7 +6053,7 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "optional": true, @@ -6063,14 +6063,14 @@ }, "ms": { "version": "2.1.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true, "optional": true }, "needle": { "version": "2.3.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/needle/-/needle-2.3.0.tgz", "integrity": "sha512-QBZu7aAFR0522EyaXZM0FZ9GLpq6lvQ3uq8gteiDUp7wKdy0lSd2hPlgFwVuW1CBkfEs9PfDQsQzZghLs/psdg==", "dev": true, "optional": true, @@ -6082,7 +6082,7 @@ }, "node-pre-gyp": { "version": "0.12.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz", "integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==", "dev": true, "optional": true, @@ -6101,7 +6101,7 @@ }, "nopt": { "version": "4.0.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", "dev": true, "optional": true, @@ -6112,14 +6112,14 @@ }, "npm-bundled": { "version": "1.0.6", - "resolved": false, + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.6.tgz", "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==", "dev": true, "optional": true }, "npm-packlist": { "version": "1.4.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.1.tgz", "integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==", "dev": true, "optional": true, @@ -6130,7 +6130,7 @@ }, "npmlog": { "version": "4.1.2", - "resolved": false, + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "dev": true, "optional": true, @@ -6143,21 +6143,21 @@ }, "number-is-nan": { "version": "1.0.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true, "optional": true }, "object-assign": { "version": "4.1.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true, "optional": true }, "once": { "version": "1.4.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "optional": true, @@ -6167,21 +6167,21 @@ }, "os-homedir": { "version": "1.0.2", - "resolved": false, + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true, "optional": true }, "os-tmpdir": { "version": "1.0.2", - "resolved": false, + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true, "optional": true }, "osenv": { "version": "0.1.5", - "resolved": false, + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", "dev": true, "optional": true, @@ -6192,21 +6192,21 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true, "optional": true }, "process-nextick-args": { "version": "2.0.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true, "optional": true }, "rc": { "version": "1.2.8", - "resolved": false, + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dev": true, "optional": true, @@ -6219,7 +6219,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true, "optional": true @@ -6228,7 +6228,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": false, + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "optional": true, @@ -6244,7 +6244,7 @@ }, "rimraf": { "version": "2.6.3", - "resolved": false, + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, "optional": true, @@ -6254,49 +6254,49 @@ }, "safe-buffer": { "version": "5.1.2", - "resolved": false, + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true, "optional": true }, "safer-buffer": { "version": "2.1.2", - "resolved": false, + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true, "optional": true }, "sax": { "version": "1.2.4", - "resolved": false, + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true, "optional": true }, "semver": { "version": "5.7.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "dev": true, "optional": true }, "set-blocking": { "version": "2.0.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true, "optional": true }, "signal-exit": { "version": "3.0.2", - "resolved": false, + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true, "optional": true }, "string-width": { "version": "1.0.2", - "resolved": false, + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "optional": true, @@ -6308,7 +6308,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "optional": true, @@ -6318,7 +6318,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "optional": true, @@ -6328,14 +6328,14 @@ }, "strip-json-comments": { "version": "2.0.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true, "optional": true }, "tar": { "version": "4.4.8", - "resolved": false, + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz", "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", "dev": true, "optional": true, @@ -6351,14 +6351,14 @@ }, "util-deprecate": { "version": "1.0.2", - "resolved": false, + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true, "optional": true }, "wide-align": { "version": "1.1.3", - "resolved": false, + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", "dev": true, "optional": true, @@ -6368,14 +6368,14 @@ }, "wrappy": { "version": "1.0.2", - "resolved": false, + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true, "optional": true }, "yallist": { "version": "3.0.3", - "resolved": false, + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", "dev": true, "optional": true diff --git a/src/server/authsupport.js b/src/server/authsupport.js index 672aa75de..a74a7abcf 100644 --- a/src/server/authsupport.js +++ b/src/server/authsupport.js @@ -1,6 +1,10 @@ 'use strict'; -const stillValid = token => { +const isValidNow = token => { + return isValidAt(token, Math.floor(Date.now()) / 1000); +}; + +const isValidAt = (token, timeInSeconds) => { if (!token) { return false; } @@ -8,14 +12,19 @@ const stillValid = token => { try { const claims = claimsFrom(token); const expirationTime = parseInt(claims['exp']); - const nowInSeconds = Math.floor(Date.now() / 1000); - return expirationTime >= nowInSeconds; + return expirationTime >= timeInSeconds; } catch (err) { console.log(`error while checking token validity: ${err}`); return false; } }; +const willExpireInLessThan = (seconds, token) => { + const timeToTest = Math.floor(Date.now() / 1000) + seconds; + const expirationTime = parseInt(claimsFrom(token)['exp']); + return timeToTest > expirationTime; +}; + const validateOidcCallback = (req, azureClient, config) => { const params = azureClient.callbackParams(req); const nonce = req.session.nonce; @@ -66,7 +75,9 @@ const nameFrom = token => { }; module.exports = { - stillValid: stillValid, + isValidAt: isValidAt, + isValidNow: isValidNow, + willExpireInLessThan: willExpireInLessThan, validateOidcCallback: validateOidcCallback, isMemberOf: isMemberOf, nameFrom: nameFrom diff --git a/src/server/authsupport.test.js b/src/server/authsupport.test.js index 842606bd4..3a2a38140 100644 --- a/src/server/authsupport.test.js +++ b/src/server/authsupport.test.js @@ -1,14 +1,12 @@ import { cleanup } from '@testing-library/react'; -const authsupport = require('./authsupport'); +const authsupport = require('../../src/server/authsupport'); const clgOrig = console.log; afterEach(cleanup); -afterEach(cleanup); - -beforeAll(() => { +beforeEach(() => { // reduce noise in log console.log = jest.fn(); }); @@ -17,51 +15,69 @@ afterAll(() => { console.log = clgOrig; }); -test('valid token has expiry in the future', async () => { +test('valid token has expiry in the future', () => { const nowInSeconds = Math.floor(Date.now() / 1000); const token = createToken({ exp: `${nowInSeconds + 10}` }); - expect(authsupport.stillValid(token)).toEqual(true); + expect(authsupport.isValidNow(token)).toEqual(true); }); -test('invalid token has expiry in the past', async () => { +test('invalid token has expiry in the past', () => { const nowInSeconds = Math.floor(Date.now() / 1000); const token = createToken({ exp: `${nowInSeconds - 10}` }); - expect(authsupport.stillValid(token)).toEqual(false); + expect(authsupport.isValidNow(token)).toEqual(false); +}); + +test('null token does not validate', () => { + expect(authsupport.isValidNow(null)).toEqual(false); }); -test('null token does not validate', async () => { - expect(authsupport.stillValid(null)).toEqual(false); +test('undefined token does not validate', () => { + expect(authsupport.isValidNow(undefined)).toEqual(false); }); -test('undefined token does not validate', async () => { - expect(authsupport.stillValid(undefined)).toEqual(false); +test('malformed token does not validate', () => { + expect(authsupport.isValidNow('bogustext')).toEqual(false); }); -test('malformed token does not validate', async () => { - expect(authsupport.stillValid('bogustext')).toEqual(false); +test('willExpireInLessThan is false if test time is before exp', () => { + const nowInSeconds = Math.floor(Date.now() / 1000); + const token = createToken({ exp: `${nowInSeconds + 30}` }); + expect(authsupport.willExpireInLessThan(29, token)).toEqual(false); +}); + +test('willExpireInLessThan is false if test time is at exp', () => { + const nowInSeconds = Math.floor(Date.now() / 1000); + const token = createToken({ exp: `${nowInSeconds + 30}` }); + expect(authsupport.willExpireInLessThan(30, token)).toEqual(false); +}); + +test('willExpireInLessThan is true if test time is after exp', () => { + const nowInSeconds = Math.floor(Date.now() / 1000); + const token = createToken({ exp: `${nowInSeconds + 30}` }); + expect(authsupport.willExpireInLessThan(31, token)).toEqual(true); }); -test('user is member of required group', async () => { +test('user is member of required group', () => { const token = createToken({ groups: ['group1', 'group2', 'group3'] }); expect(authsupport.isMemberOf('group3', token)).toEqual(true); }); -test('user is not member of required group', async () => { +test('user is not member of required group', () => { const token = createToken({ groups: ['group1', 'group2', 'group3'] }); expect(authsupport.isMemberOf('group4', token)).toEqual(false); }); -test('name extraction from jwt', async () => { +test('name extraction from jwt', () => { const token = createToken({ name: 'John Doe' }); expect(authsupport.nameFrom(token)).toEqual('John Doe'); }); -test('name extraction from jwt, name property missing', async () => { +test('name extraction from jwt, name property missing', () => { const token = createToken({}); expect(authsupport.nameFrom(token)).toEqual('unknown user'); }); -test('name extraction from jwt, malformed token', async () => { +test('name extraction from jwt, malformed token', () => { const token = 'invalid bogus'; expect(authsupport.nameFrom(token)).toEqual('unknown user'); }); diff --git a/src/server/config.js b/src/server/config.js index 8ba575e3c..f834200b6 100644 --- a/src/server/config.js +++ b/src/server/config.js @@ -24,3 +24,10 @@ exports.server = { port: 3000, sessionSecret: process.env.SESSION_SECRET }; + +exports.nav = { + serviceUserName: process.env.SERVICE_USER_NAME, + serviceUserPassword: process.env.SERVICE_USER_PASSWORD, + stsUrl: + process.env.STS_URL || 'http://security-token-service.svc.nais.local' +}; diff --git a/src/server/personlookup.js b/src/server/personlookup.js new file mode 100644 index 000000000..48e2d7e39 --- /dev/null +++ b/src/server/personlookup.js @@ -0,0 +1,83 @@ +'use strict'; + +const request = require('request'); +const authSupport = require('./authsupport'); + +let navConfig = null; +let cachedAccessToken = null; + +const init = config => { + navConfig = config; + cachedAccessToken = null; +}; + +const hentPerson = async aktørId => { + return new Promise((resolve, reject) => { + logonToNav() + .then(jwt => { + request.get( + `http://sparkel.svc.nais.local/api/person/${aktørId}`, + { + headers: { + Authorization: `Bearer: ${jwt}` + } + }, + (error, response, body) => { + if (error || response.statusCode !== 200) { + reject( + `Error during person lookup, got ${ + response.statusCode + } ${error || 'unknown error'}` + ); + } else { + resolve(body); + } + } + ); + }) + .catch(err => { + reject(err); + }); + }); +}; + +const logonToNav = async () => { + return new Promise((resolve, reject) => { + if ( + cachedAccessToken && + !authSupport.willExpireInLessThan(30, cachedAccessToken) + ) { + resolve(cachedAccessToken); + } else { + request.get( + `${navConfig.stsUrl}/rest/v1/sts/token?grant_type=client_credentials&scope=openid`, + { + headers: { + Authorization: + 'Basic ' + + Buffer.from( + `${navConfig.serviceUserName}:${navConfig.serviceUserPassword}` + ).toString('base64') + } + }, + (error, response, body) => { + if (error || response.statusCode !== 200) { + reject( + `Error during STS login, got ${ + response.statusCode + } ${error || 'unknown error'}` + ); + } else { + cachedAccessToken = body.access_token; + resolve(body.access_token); + } + } + ); + } + }); +}; + +module.exports = { + init: init, + hentPerson: hentPerson +}; diff --git a/src/server/personlookup.test.js b/src/server/personlookup.test.js new file mode 100644 index 000000000..54f777af3 --- /dev/null +++ b/src/server/personlookup.test.js @@ -0,0 +1,46 @@ +'use strict'; + +jest.mock('request'); + +const personLookup = require('../../src/server/personlookup'); + +beforeEach(() => { + personLookup.init({ + serviceUserName: 'da_usah', + serviceUserPassword: 'pazzwd', + stsUrl: 'http://localhost' + }); +}); + +test('successful person lookup resolves with person object', () => { + require('request').setStsStatusCode(200); + require('request').setStsResponseBody({ + access_token: 'some_token' + }); + require('request').setPersonStatusCode(200); + require('request').setPersonResponseBody({ navn: 'Navn Navnesen' }); + + expect(personLookup.hentPerson('12345')).resolves.toEqual({ + navn: 'Navn Navnesen' + }); +}); + +test('logon failure -> rejection', () => { + require('request').setStsStatusCode(500); + + expect(personLookup.hentPerson('12345')).rejects.toMatch( + 'Error during STS login' + ); +}); + +test('lookup failure -> rejection', () => { + require('request').setStsStatusCode(200); + require('request').setStsResponseBody({ + access_token: 'some_token' + }); + require('request').setPersonStatusCode(500); + + expect(personLookup.hentPerson('12345')).rejects.toMatch( + 'Error during person lookup' + ); +}); diff --git a/src/server/server.js b/src/server/server.js index 1b9b7a754..c43dff321 100644 --- a/src/server/server.js +++ b/src/server/server.js @@ -77,7 +77,7 @@ app.post('/callback', (req, res) => { app.use('/*', (req, res, next) => { if ( process.env.NODE_ENV === 'development' || - authsupport.stillValid(req.session.spadeToken) + authsupport.isValidNow(req.session.spadeToken) ) { next(); } else { diff --git a/src/server/storage.test.js b/src/server/storage.test.js index c0f656260..9e3734a79 100644 --- a/src/server/storage.test.js +++ b/src/server/storage.test.js @@ -13,7 +13,7 @@ beforeAll(done => { setupServer(); storage .init(`localhost:${port}`, 'anAccessKeyId', 'aSecretAccessKey') - .then(result => { + .then(() => { done(); }) .catch(err => { From e195c7476be0e67be196e655efc8877993bd8a88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-K=C3=A5re=20Solbakken?= Date: Thu, 8 Aug 2019 09:58:16 +0200 Subject: [PATCH 2/3] fixed path in require --- src/server/authsupport.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/authsupport.test.js b/src/server/authsupport.test.js index 3a2a38140..591adb709 100644 --- a/src/server/authsupport.test.js +++ b/src/server/authsupport.test.js @@ -1,6 +1,6 @@ import { cleanup } from '@testing-library/react'; -const authsupport = require('../../src/server/authsupport'); +const authsupport = require('./authsupport'); const clgOrig = console.log; From 89f5a63f6f40cc076ae497f5f61d6384a7764df4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-K=C3=A5re=20Solbakken?= Date: Thu, 8 Aug 2019 10:23:53 +0200 Subject: [PATCH 3/3] simplified mocking --- src/server/personlookup.test.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/server/personlookup.test.js b/src/server/personlookup.test.js index 54f777af3..04dfd0ea2 100644 --- a/src/server/personlookup.test.js +++ b/src/server/personlookup.test.js @@ -1,6 +1,6 @@ 'use strict'; -jest.mock('request'); +const request = require('request'); const personLookup = require('../../src/server/personlookup'); @@ -13,12 +13,12 @@ beforeEach(() => { }); test('successful person lookup resolves with person object', () => { - require('request').setStsStatusCode(200); - require('request').setStsResponseBody({ + request.setStsStatusCode(200); + request.setStsResponseBody({ access_token: 'some_token' }); - require('request').setPersonStatusCode(200); - require('request').setPersonResponseBody({ navn: 'Navn Navnesen' }); + request.setPersonStatusCode(200); + request.setPersonResponseBody({ navn: 'Navn Navnesen' }); expect(personLookup.hentPerson('12345')).resolves.toEqual({ navn: 'Navn Navnesen' @@ -26,7 +26,7 @@ test('successful person lookup resolves with person object', () => { }); test('logon failure -> rejection', () => { - require('request').setStsStatusCode(500); + request.setStsStatusCode(500); expect(personLookup.hentPerson('12345')).rejects.toMatch( 'Error during STS login' @@ -34,11 +34,11 @@ test('logon failure -> rejection', () => { }); test('lookup failure -> rejection', () => { - require('request').setStsStatusCode(200); - require('request').setStsResponseBody({ + request.setStsStatusCode(200); + request.setStsResponseBody({ access_token: 'some_token' }); - require('request').setPersonStatusCode(500); + request.setPersonStatusCode(500); expect(personLookup.hentPerson('12345')).rejects.toMatch( 'Error during person lookup'