From b9cb8662380eb1de133129599e94bbee672bddf1 Mon Sep 17 00:00:00 2001 From: benoitguigal Date: Mon, 16 Nov 2020 11:12:42 +0100 Subject: [PATCH 1/2] fix GraphQL validation error displayed as internal server error --- back/package-lock.json | 239 +++++++++++++++++++++-- back/package.json | 4 +- back/src/__tests__/errors.integration.ts | 76 ++++--- back/src/server.ts | 7 + 4 files changed, 286 insertions(+), 40 deletions(-) diff --git a/back/package-lock.json b/back/package-lock.json index 99f059b3fa..4a41ddde53 100644 --- a/back/package-lock.json +++ b/back/package-lock.json @@ -76,7 +76,8 @@ "@apollographql/graphql-playground-html": { "version": "1.6.24", "resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.24.tgz", - "integrity": "sha512-8GqG48m1XqyXh4mIZrtB5xOhUwSsh1WsrrsaZQOEYYql3YN9DEu9OOSg0ILzXHZo/h2Q74777YE4YzlArQzQEQ==" + "integrity": "sha512-8GqG48m1XqyXh4mIZrtB5xOhUwSsh1WsrrsaZQOEYYql3YN9DEu9OOSg0ILzXHZo/h2Q74777YE4YzlArQzQEQ==", + "dev": true }, "@ardatan/aggregate-error": { "version": "0.0.1", @@ -3388,6 +3389,7 @@ "version": "2.8.6", "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.6.tgz", "integrity": "sha512-invOmosX0DqbpA+cE2yoHGUlF/blyf7nB0OGYBBiH27crcVm5NmFaZkLP4Ta1hGaesckCi5lVLlydNJCxkTOSg==", + "dev": true, "requires": { "@types/express": "*" } @@ -4096,6 +4098,7 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/apollo-cache-control/-/apollo-cache-control-0.11.0.tgz", "integrity": "sha512-dmRnQ9AXGw2SHahVGLzB/p4UW/taFBAJxifxubp8hqY5p9qdlSu4MPRq8zvV2ULMYf50rBtZyC4C+dZLqmHuHQ==", + "dev": true, "requires": { "apollo-server-env": "^2.4.4", "apollo-server-plugin-base": "^0.9.0" @@ -4105,6 +4108,7 @@ "version": "0.7.1", "resolved": "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-0.7.1.tgz", "integrity": "sha512-h++/jQAY7GA+4TBM+7ezvctFmmGNLrAPf51KsagZj+NkT9qvxp585rdsuatynVbSl59toPK2EuVmc6ilmQHf+g==", + "dev": true, "requires": { "apollo-server-caching": "^0.5.1", "apollo-server-env": "^2.4.4" @@ -4114,6 +4118,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/apollo-engine-reporting/-/apollo-engine-reporting-2.0.0.tgz", "integrity": "sha512-FvNwORsh3nxEfvQqd2xbd468a0q/R3kYar/Bk6YQdBX5qwqUhqmOcOSxLFk8Zb77HpwHij5CPpPWJb53TU1zcA==", + "dev": true, "requires": { "apollo-engine-reporting-protobuf": "^0.5.1", "apollo-graphql": "^0.4.0", @@ -4129,7 +4134,8 @@ "uuid": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.1.0.tgz", - "integrity": "sha512-CI18flHDznR0lq54xBycOVmphdCYnQLKn8abKn7PXUiKUGdEd+/l9LWNJmugXel4hXq7S+RMNl34ecyC9TntWg==" + "integrity": "sha512-CI18flHDznR0lq54xBycOVmphdCYnQLKn8abKn7PXUiKUGdEd+/l9LWNJmugXel4hXq7S+RMNl34ecyC9TntWg==", + "dev": true } } }, @@ -4137,6 +4143,7 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.5.1.tgz", "integrity": "sha512-TSfr9iAaInV8dhXkesdcmqsthRkVcJkzznmiM+1Ob/GScK7r6hBYCjVDt2613EHAg9SUzTOltIKlGD+N+GJRUw==", + "dev": true, "requires": { "@apollo/protobufjs": "^1.0.3" } @@ -4156,6 +4163,7 @@ "version": "0.4.4", "resolved": "https://registry.npmjs.org/apollo-graphql/-/apollo-graphql-0.4.4.tgz", "integrity": "sha512-i012iRKT5nfsOaNMx4MTwHw2jrlyaF1zikpejxsGHsKIf3OngGvGh3pyw20bEmwj413OrNQpRxvvIz5A7W/8xw==", + "dev": true, "requires": { "apollo-env": "^0.6.5", "lodash.sortby": "^4.7.0" @@ -4182,10 +4190,19 @@ "tslib": "^1.9.3" } }, + "apollo-reporting-protobuf": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-0.6.1.tgz", + "integrity": "sha512-qr4DheFP154PGZsd93SSIS9RkqHnR5b6vT+eCloWjy3UIpY+yZ3cVLlttlIjYvOG4xTJ25XEwcHiAExatQo/7g==", + "requires": { + "@apollo/protobufjs": "^1.0.3" + } + }, "apollo-server-caching": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-0.5.1.tgz", "integrity": "sha512-L7LHZ3k9Ao5OSf2WStvQhxdsNVplRQi7kCAPfqf9Z3GBEnQ2uaL0EgO0hSmtVHfXTbk5CTRziMT1Pe87bXrFIw==", + "dev": true, "requires": { "lru-cache": "^5.0.0" } @@ -4194,6 +4211,7 @@ "version": "2.14.1", "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-2.14.1.tgz", "integrity": "sha512-Uk/jJwLtm+5YvExghNoq9V2ZHJRXPfaVOt4cIyo+mcjWG6YymHhMg5h9pR/auz9HMI8NP7ykmfo/bsTR1qutWQ==", + "dev": true, "requires": { "@apollographql/apollo-tools": "^0.4.3", "@apollographql/graphql-playground-html": "1.6.24", @@ -4223,6 +4241,7 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-4.0.8.tgz", "integrity": "sha512-MW+ioleBrwhRjalKjYaLQbr+920pHBgy9vM/n47sswtns8+96sRn5M/G+J1eu7IMeKWiN/9p6tmwCHU7552VJg==", + "dev": true, "requires": { "apollo-link": "^1.2.14", "apollo-utilities": "^1.0.1", @@ -4234,7 +4253,8 @@ "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true } } }, @@ -4242,6 +4262,7 @@ "version": "2.4.4", "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-2.4.4.tgz", "integrity": "sha512-c2oddDS3lwAl6QNCIKCLEzt/dF9M3/tjjYRVdxOVN20TidybI7rAbnT4QOzf4tORnGXtiznEAvr/Kc9ahhKADg==", + "dev": true, "requires": { "node-fetch": "^2.1.2", "util.promisify": "^1.0.0" @@ -4250,21 +4271,23 @@ "apollo-server-errors": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-2.4.1.tgz", - "integrity": "sha512-7oEd6pUxqyWYUbQ9TA8tM0NU/3aGtXSEibo6+txUkuHe7QaxfZ2wHRp+pfT1LC1K3RXYjKj61/C2xEO19s3Kdg==" + "integrity": "sha512-7oEd6pUxqyWYUbQ9TA8tM0NU/3aGtXSEibo6+txUkuHe7QaxfZ2wHRp+pfT1LC1K3RXYjKj61/C2xEO19s3Kdg==", + "dev": true }, "apollo-server-express": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-2.14.1.tgz", - "integrity": "sha512-Ee1Oc+lzKfHh3BkDNRJL4s7Nnx+Nkmz606TBDi0ETSuNjJqXBNDbDM/YLS3LP7zJ5Oa37U7py72x8rrkPiZZNg==", + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-2.19.0.tgz", + "integrity": "sha512-3rgSrTme1SlLoecAYtSa8ThH6vYvz29QecgZCigq5Vdc6bFP2SZrCk0ls6BAdD8OZbVKUtizzRxd0yd/uREPAw==", "requires": { - "@apollographql/graphql-playground-html": "1.6.24", + "@apollographql/graphql-playground-html": "1.6.26", "@types/accepts": "^1.3.5", "@types/body-parser": "1.19.0", - "@types/cors": "^2.8.4", - "@types/express": "4.17.4", + "@types/cors": "2.8.8", + "@types/express": "4.17.7", + "@types/express-serve-static-core": "4.17.13", "accepts": "^1.3.5", - "apollo-server-core": "^2.14.1", - "apollo-server-types": "^0.5.0", + "apollo-server-core": "^2.19.0", + "apollo-server-types": "^0.6.1", "body-parser": "^1.18.3", "cors": "^2.8.4", "express": "^4.17.1", @@ -4275,6 +4298,162 @@ "type-is": "^1.6.16" }, "dependencies": { + "@apollographql/graphql-playground-html": { + "version": "1.6.26", + "resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.26.tgz", + "integrity": "sha512-XAwXOIab51QyhBxnxySdK3nuMEUohhDsHQ5Rbco/V1vjlP75zZ0ZLHD9dTpXTN8uxKxopb2lUvJTq+M4g2Q0HQ==", + "requires": { + "xss": "^1.0.6" + } + }, + "@types/cors": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.8.tgz", + "integrity": "sha512-fO3gf3DxU2Trcbr75O7obVndW/X5k8rJNZkLXlQWStTHhP71PkRqjwPIEI0yMnJdg9R9OasjU+Bsr+Hr1xy/0w==", + "requires": { + "@types/express": "*" + } + }, + "@types/express": { + "version": "4.17.7", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.7.tgz", + "integrity": "sha512-dCOT5lcmV/uC2J9k0rPafATeeyz+99xTt54ReX11/LObZgfzJqZNcW27zGhYyX+9iSEGXGt5qLPwRSvBZcLvtQ==", + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "*", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.13.tgz", + "integrity": "sha512-RgDi5a4nuzam073lRGKTUIaL3eF2+H7LJvJ8eUnCI0wA6SNjXc44DCmWNiTLs/AZ7QlsFWZiw/gTG3nSQGL0fA==", + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "apollo-cache-control": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/apollo-cache-control/-/apollo-cache-control-0.11.4.tgz", + "integrity": "sha512-FUKE8ASr8GxVq5rmky/tY8bsf++cleGT591lfLiqnPsP1fo3kAfgRfWA2QRHTCKFNlQxzUhVOEDv+PaysqiOjw==", + "requires": { + "apollo-server-env": "^2.4.5", + "apollo-server-plugin-base": "^0.10.2" + } + }, + "apollo-datasource": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-0.7.2.tgz", + "integrity": "sha512-ibnW+s4BMp4K2AgzLEtvzkjg7dJgCaw9M5b5N0YKNmeRZRnl/I/qBTQae648FsRKgMwTbRQIvBhQ0URUFAqFOw==", + "requires": { + "apollo-server-caching": "^0.5.2", + "apollo-server-env": "^2.4.5" + } + }, + "apollo-graphql": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/apollo-graphql/-/apollo-graphql-0.6.0.tgz", + "integrity": "sha512-BxTf5LOQe649e9BNTPdyCGItVv4Ll8wZ2BKnmiYpRAocYEXAVrQPWuSr3dO4iipqAU8X0gvle/Xu9mSqg5b7Qg==", + "requires": { + "apollo-env": "^0.6.5", + "lodash.sortby": "^4.7.0" + } + }, + "apollo-server-caching": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-0.5.2.tgz", + "integrity": "sha512-HUcP3TlgRsuGgeTOn8QMbkdx0hLPXyEJehZIPrcof0ATz7j7aTPA4at7gaiFHCo8gk07DaWYGB3PFgjboXRcWQ==", + "requires": { + "lru-cache": "^5.0.0" + } + }, + "apollo-server-core": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-2.19.0.tgz", + "integrity": "sha512-2aMKUVPyNbomJQaG2tkpfqvp1Tfgxgkdr7nX5zHudYNSzsPrHw+CcYlCbIVFFI/mTZsjoK9czNq1qerFRxZbJw==", + "requires": { + "@apollographql/apollo-tools": "^0.4.3", + "@apollographql/graphql-playground-html": "1.6.26", + "@types/graphql-upload": "^8.0.0", + "@types/ws": "^7.0.0", + "apollo-cache-control": "^0.11.4", + "apollo-datasource": "^0.7.2", + "apollo-graphql": "^0.6.0", + "apollo-reporting-protobuf": "^0.6.1", + "apollo-server-caching": "^0.5.2", + "apollo-server-env": "^2.4.5", + "apollo-server-errors": "^2.4.2", + "apollo-server-plugin-base": "^0.10.2", + "apollo-server-types": "^0.6.1", + "apollo-tracing": "^0.12.0", + "async-retry": "^1.2.1", + "fast-json-stable-stringify": "^2.0.0", + "graphql-extensions": "^0.12.6", + "graphql-tag": "^2.9.2", + "graphql-tools": "^4.0.0", + "graphql-upload": "^8.0.2", + "loglevel": "^1.6.7", + "lru-cache": "^5.0.0", + "sha.js": "^2.4.11", + "subscriptions-transport-ws": "^0.9.11", + "uuid": "^8.0.0", + "ws": "^6.0.0" + } + }, + "apollo-server-env": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-2.4.5.tgz", + "integrity": "sha512-nfNhmGPzbq3xCEWT8eRpoHXIPNcNy3QcEoBlzVMjeglrBGryLG2LXwBSPnVmTRRrzUYugX0ULBtgE3rBFNoUgA==", + "requires": { + "node-fetch": "^2.1.2", + "util.promisify": "^1.0.0" + } + }, + "apollo-server-errors": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-2.4.2.tgz", + "integrity": "sha512-FeGxW3Batn6sUtX3OVVUm7o56EgjxDlmgpTLNyWcLb0j6P8mw9oLNyAm3B+deHA4KNdNHO5BmHS2g1SJYjqPCQ==" + }, + "apollo-server-plugin-base": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.10.2.tgz", + "integrity": "sha512-uM5uL1lOxbXdgvt/aEIbgs40fV9xA45Y3Mmh0VtQ/ddqq0MXR5aG92nnf8rM+URarBCUfxKJKaYzJJ/CXAnEdA==", + "requires": { + "apollo-server-types": "^0.6.1" + } + }, + "apollo-server-types": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-0.6.1.tgz", + "integrity": "sha512-IEQ37aYvMLiTUzsySVLOSuvvhxuyYdhI05f3cnH6u2aN1HgGp7vX6bg+U3Ue8wbHfdcifcGIk5UEU+Q+QO6InA==", + "requires": { + "apollo-reporting-protobuf": "^0.6.1", + "apollo-server-caching": "^0.5.2", + "apollo-server-env": "^2.4.5" + } + }, + "apollo-tracing": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.12.0.tgz", + "integrity": "sha512-cMUYGE6mOEwb9HDqhf4fiPEo2JMhjPIqEprAQEC57El76avRpRig5NM0bnqMZcYJZR5QmLlNcttNccOwf9WrNg==", + "requires": { + "apollo-server-env": "^2.4.5", + "apollo-server-plugin-base": "^0.10.2" + } + }, + "graphql-extensions": { + "version": "0.12.6", + "resolved": "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.12.6.tgz", + "integrity": "sha512-EUNw+OIRXYTPxToSoJjhJvS5aGa94KkdkZnL1I9DCZT64/+rzQNeLeGj+goj2RYuYvoQe1Bmcx0CNZ1GqwBhng==", + "requires": { + "@apollographql/apollo-tools": "^0.4.3", + "apollo-server-env": "^2.4.5", + "apollo-server-types": "^0.6.1" + } + }, "graphql-tools": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-4.0.8.tgz", @@ -4285,12 +4464,19 @@ "deprecated-decorator": "^0.1.6", "iterall": "^1.1.3", "uuid": "^3.1.0" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + } } }, "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz", + "integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==" } } }, @@ -4310,6 +4496,7 @@ "version": "0.9.0", "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.9.0.tgz", "integrity": "sha512-LWcPrsy2+xqwlNseh/QaGa/MPNopS8c4qGgh0g0cAn0lZBRrJ9Yab7dq+iQ6vdUBwIhUWYN6s9dwUWCZw2SL8g==", + "dev": true, "requires": { "apollo-server-types": "^0.5.0" } @@ -4327,6 +4514,7 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-0.5.0.tgz", "integrity": "sha512-zhtsqqqfdeoJQAfc41Sy6WnnBVxKNgZ34BKXf/Q+kXmw7rbZ/B5SG3SJMvj1iFsbzZxILmWdUsE9aD20lEr0bg==", + "dev": true, "requires": { "apollo-engine-reporting-protobuf": "^0.5.1", "apollo-server-caching": "^0.5.1", @@ -4337,6 +4525,7 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.11.0.tgz", "integrity": "sha512-I9IFb/8lkBW8ZwOAi4LEojfT7dMfUSkpnV8LHQI8Rcj0HtzL9HObQ3woBmzyGHdGHLFuD/6/VHyFD67SesSrJg==", + "dev": true, "requires": { "apollo-server-env": "^2.4.4", "apollo-server-plugin-base": "^0.9.0" @@ -5711,6 +5900,11 @@ "delayed-stream": "~1.0.0" } }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, "common-tags": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", @@ -6208,6 +6402,11 @@ "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", "dev": true }, + "cssfilter": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz", + "integrity": "sha1-xtJnJjKi5cg+AT5oZKQs6N79IK4=" + }, "cssom": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", @@ -8775,6 +8974,7 @@ "version": "0.12.2", "resolved": "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.12.2.tgz", "integrity": "sha512-vFaZua5aLiCOOzxfY5qzHZ6S52BCqW7VVOwzvV52Wb5edRm3dn6u+1MR9yYyEqUHSf8LvdhEojYlOkKiaQ4ghA==", + "dev": true, "requires": { "@apollographql/apollo-tools": "^0.4.3", "apollo-server-env": "^2.4.4", @@ -19023,6 +19223,15 @@ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" }, + "xss": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.8.tgz", + "integrity": "sha512-3MgPdaXV8rfQ/pNn16Eio6VXYPTkqwa0vc7GkiymmY/DqR1SE/7VPAAVZz1GJsJFrllMYO3RHfEaiUGjab6TNw==", + "requires": { + "commander": "^2.20.3", + "cssfilter": "0.0.10" + } + }, "xstate": { "version": "4.13.0", "resolved": "https://registry.npmjs.org/xstate/-/xstate-4.13.0.tgz", diff --git a/back/package.json b/back/package.json index d356eaa46f..563bf53f79 100644 --- a/back/package.json +++ b/back/package.json @@ -30,7 +30,7 @@ "@graphql-tools/merge": "^6.0.15", "@sentry/integrations": "^5.15.5", "@sentry/node": "^5.15.5", - "apollo-server-express": "^2.13.1", + "apollo-server-express": "^2.19.0", "aws-sdk": "^2.682.0", "axios": "^0.19.2", "bcrypt": "^5.0.0", @@ -100,7 +100,7 @@ "@typescript-eslint/eslint-plugin": "^3.0.2", "@typescript-eslint/parser": "^3.0.2", "apollo-server-integration-testing": "^2.3.0", - "apollo-server-testing": "^2.13.1", + "apollo-server-testing": "^2.19.0", "concurrently": "^5.1.0", "copyfiles": "^2.2.0", "eslint": "^7.2.0", diff --git a/back/src/__tests__/errors.integration.ts b/back/src/__tests__/errors.integration.ts index 81ed04910b..60a8a6bda5 100644 --- a/back/src/__tests__/errors.integration.ts +++ b/back/src/__tests__/errors.integration.ts @@ -2,24 +2,37 @@ import { createTestClient } from "apollo-server-testing"; import { UserInputError, ApolloError } from "apollo-server-express"; import { readFileSync } from "fs"; import { ValidationError } from "yup"; +import { ErrorCode } from "../common/errors"; -const mockHello = jest.fn(); +const mockFoo = jest.fn(); +const mockBar = jest.fn(); jest.mock("../schema.ts", () => ({ typeDefs: ` type Query { - hello: String - } + foo: String + } + type Mutation { + bar(input: String!): String! + } `, resolvers: { Query: { - hello: () => mockHello() + foo: () => mockFoo() + }, + Mutation: { + bar: () => mockBar() } }, shieldRulesTree: {} })); -const HELLO = `query { hello }`; +const FOO = `query { foo }`; +const BAR = ` + mutation Bar($input: String!){ + bar(input: $input) + } +`; describe("Error handling", () => { const OLD_ENV = process.env; @@ -31,27 +44,27 @@ describe("Error handling", () => { afterEach(() => { process.env = OLD_ENV; - mockHello.mockReset(); + mockFoo.mockReset(); }); test("errors should be null if query resolve correctly", async () => { process.env.NODE_ENV = "production"; const server = require("../server").server; const { query } = createTestClient(server); - mockHello.mockResolvedValueOnce("world"); - const { errors, data } = await query({ query: HELLO }); + mockFoo.mockResolvedValueOnce("bar"); + const { errors, data } = await query({ query: FOO }); expect(errors).toBeUndefined(); - expect(data).toEqual({ hello: "world" }); + expect(data).toEqual({ foo: "bar" }); }); test("subclasses of Apollo errors should be formatted correctly when thrown", async () => { process.env.NODE_ENV = "production"; const server = require("../server").server; const { query } = createTestClient(server); - mockHello.mockImplementationOnce(() => { + mockFoo.mockImplementationOnce(() => { throw new UserInputError("Oups"); }); - const { errors } = await query({ query: HELLO }); + const { errors } = await query({ query: FOO }); expect(errors).toHaveLength(1); const error = errors[0]; expect(error.message).toEqual("Oups"); @@ -62,10 +75,10 @@ describe("Error handling", () => { process.env.NODE_ENV = "production"; const server = require("../server").server; const { query } = createTestClient(server); - mockHello.mockImplementationOnce(() => { + mockFoo.mockImplementationOnce(() => { return new UserInputError("Oups"); }); - const { errors } = await query({ query: HELLO }); + const { errors } = await query({ query: FOO }); expect(errors).toHaveLength(1); const error = errors[0]; expect(error.message).toEqual("Oups"); @@ -76,10 +89,10 @@ describe("Error handling", () => { process.env.NODE_ENV = "production"; const server = require("../server").server; const { query } = createTestClient(server); - mockHello.mockImplementationOnce(() => { + mockFoo.mockImplementationOnce(() => { throw new ApolloError("Bang"); }); - const { errors } = await query({ query: HELLO }); + const { errors } = await query({ query: FOO }); expect(errors).toHaveLength(1); const error = errors[0]; @@ -91,10 +104,10 @@ describe("Error handling", () => { process.env.NODE_ENV = "production"; const server = require("../server").server; const { query } = createTestClient(server); - mockHello.mockImplementationOnce(() => { + mockFoo.mockImplementationOnce(() => { readFileSync("path/does/not/exist"); }); - const { errors } = await query({ query: HELLO }); + const { errors } = await query({ query: FOO }); expect(errors).toHaveLength(1); const error = errors[0]; @@ -106,10 +119,10 @@ describe("Error handling", () => { process.env.NODE_ENV = "production"; const server = require("../server").server; const { query } = createTestClient(server); - mockHello.mockImplementationOnce(() => { + mockFoo.mockImplementationOnce(() => { return readFileSync("path/does/not/exist"); }); - const { errors } = await query({ query: HELLO }); + const { errors } = await query({ query: FOO }); expect(errors).toHaveLength(1); const error = errors[0]; @@ -121,10 +134,10 @@ describe("Error handling", () => { process.env.NODE_ENV = "dev"; const server = require("../server").server; const { query } = createTestClient(server); - mockHello.mockImplementationOnce(() => { + mockFoo.mockImplementationOnce(() => { throw new Error("Bang"); }); - const { errors } = await query({ query: HELLO }); + const { errors } = await query({ query: FOO }); const error = errors[0]; expect(error.extensions.code).toEqual("INTERNAL_SERVER_ERROR"); expect(error.message).toEqual("Bang"); @@ -134,12 +147,29 @@ describe("Error handling", () => { test("Yup validation errors should be displayed as an input error", async () => { const server = require("../server").server; const { query } = createTestClient(server); - mockHello.mockImplementationOnce(() => { + mockFoo.mockImplementationOnce(() => { throw new ValidationError("Bang", "Wrong value", "path"); }); - const { errors } = await query({ query: HELLO }); + const { errors } = await query({ query: FOO }); const error = errors[0]; expect(error.extensions.code).toEqual("BAD_USER_INPUT"); expect(error.message).toContain("Bang"); }); + + test("GRAPHQL_VALIDATION_FAILED should be returned when mutations variables are invalid", async () => { + process.env.NODE_ENV = "production"; + const server = require("../server").server; + const { mutate } = createTestClient(server); + // invalid variables `toto` instead of `input` + const variables = { toto: "toto" }; + const { errors } = await mutate({ + mutation: BAR, + variables + }); + const error = errors[0]; + expect(error.extensions.code).toEqual(ErrorCode.GRAPHQL_VALIDATION_FAILED); + expect(error.message).toEqual( + 'Variable "$input" of required type "String!" was not provided.' + ); + }); }); diff --git a/back/src/server.ts b/back/src/server.ts index da8a1aa405..87ad58a786 100644 --- a/back/src/server.ts +++ b/back/src/server.ts @@ -125,6 +125,13 @@ export const server = new ApolloServer({ err.extensions.code === ErrorCode.INTERNAL_SERVER_ERROR && NODE_ENV === "production" ) { + // Workaround for graphQL validation error displayed as internal server error + // when graphQL variables are of of invalid type + // See: https://github.com/apollographql/apollo-server/issues/3498 + if (err.message.startsWith(`Variable "`)) { + err.extensions.code = "GRAPHQL_VALIDATION_FAILED"; + return err; + } // Do not leak error for internal server error in production return new ApolloError("Erreur serveur", ErrorCode.INTERNAL_SERVER_ERROR); } From cbe2cdd8697b7aebe5be6940f26c413ec3177bd1 Mon Sep 17 00:00:00 2001 From: benoitguigal Date: Mon, 16 Nov 2020 11:25:39 +0100 Subject: [PATCH 2/2] Update Changelog --- Changelog.md | 1 + back/package-lock.json | 176 ++++++++++++++++++++++- back/src/__tests__/errors.integration.ts | 2 +- back/src/server.ts | 2 +- 4 files changed, 175 insertions(+), 6 deletions(-) diff --git a/Changelog.md b/Changelog.md index d5e432baa9..37a633c376 100644 --- a/Changelog.md +++ b/Changelog.md @@ -16,6 +16,7 @@ et le projet suit un schéma de versionning inspiré de [Calendar Versioning](ht #### :bug: Corrections de bugs - Correction de la mutation `duplicateForm` pour dupliquer l'entreposage provisoire, [PR 700](https://github.com/) +- Correction d'un bug affichant une erreur serveur à la place d'une erreur de validation graphQL lorsque le typage des variables graphQL est erronée [PR 711](https://github.com/MTES-MCT/trackdechets/pull/711) #### :nail_care: Améliorations diff --git a/back/package-lock.json b/back/package-lock.json index 4a41ddde53..3df2064328 100644 --- a/back/package-lock.json +++ b/back/package-lock.json @@ -4502,12 +4502,180 @@ } }, "apollo-server-testing": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/apollo-server-testing/-/apollo-server-testing-2.14.1.tgz", - "integrity": "sha512-d0xIySG7yqg/9QcHth0oC7tPgciK+xoyJsmkAXsOX9IUxIlTVOoDIZa71Vwh2d2uwbBoriZ8vY9Z6x8Q8IN5lQ==", + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/apollo-server-testing/-/apollo-server-testing-2.19.0.tgz", + "integrity": "sha512-ZrFflLC84ZzBZCfJehC2gLodkb5wwlwYLg+wMXZfDZpBIXDbC0Y9zR0zGqOYhrDMpmI1yIt3fUade33Y4UrNpA==", "dev": true, "requires": { - "apollo-server-core": "^2.14.1" + "apollo-server-core": "^2.19.0" + }, + "dependencies": { + "@apollographql/graphql-playground-html": { + "version": "1.6.26", + "resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.26.tgz", + "integrity": "sha512-XAwXOIab51QyhBxnxySdK3nuMEUohhDsHQ5Rbco/V1vjlP75zZ0ZLHD9dTpXTN8uxKxopb2lUvJTq+M4g2Q0HQ==", + "dev": true, + "requires": { + "xss": "^1.0.6" + } + }, + "apollo-cache-control": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/apollo-cache-control/-/apollo-cache-control-0.11.4.tgz", + "integrity": "sha512-FUKE8ASr8GxVq5rmky/tY8bsf++cleGT591lfLiqnPsP1fo3kAfgRfWA2QRHTCKFNlQxzUhVOEDv+PaysqiOjw==", + "dev": true, + "requires": { + "apollo-server-env": "^2.4.5", + "apollo-server-plugin-base": "^0.10.2" + } + }, + "apollo-datasource": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-0.7.2.tgz", + "integrity": "sha512-ibnW+s4BMp4K2AgzLEtvzkjg7dJgCaw9M5b5N0YKNmeRZRnl/I/qBTQae648FsRKgMwTbRQIvBhQ0URUFAqFOw==", + "dev": true, + "requires": { + "apollo-server-caching": "^0.5.2", + "apollo-server-env": "^2.4.5" + } + }, + "apollo-graphql": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/apollo-graphql/-/apollo-graphql-0.6.0.tgz", + "integrity": "sha512-BxTf5LOQe649e9BNTPdyCGItVv4Ll8wZ2BKnmiYpRAocYEXAVrQPWuSr3dO4iipqAU8X0gvle/Xu9mSqg5b7Qg==", + "dev": true, + "requires": { + "apollo-env": "^0.6.5", + "lodash.sortby": "^4.7.0" + } + }, + "apollo-server-caching": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-0.5.2.tgz", + "integrity": "sha512-HUcP3TlgRsuGgeTOn8QMbkdx0hLPXyEJehZIPrcof0ATz7j7aTPA4at7gaiFHCo8gk07DaWYGB3PFgjboXRcWQ==", + "dev": true, + "requires": { + "lru-cache": "^5.0.0" + } + }, + "apollo-server-core": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-2.19.0.tgz", + "integrity": "sha512-2aMKUVPyNbomJQaG2tkpfqvp1Tfgxgkdr7nX5zHudYNSzsPrHw+CcYlCbIVFFI/mTZsjoK9czNq1qerFRxZbJw==", + "dev": true, + "requires": { + "@apollographql/apollo-tools": "^0.4.3", + "@apollographql/graphql-playground-html": "1.6.26", + "@types/graphql-upload": "^8.0.0", + "@types/ws": "^7.0.0", + "apollo-cache-control": "^0.11.4", + "apollo-datasource": "^0.7.2", + "apollo-graphql": "^0.6.0", + "apollo-reporting-protobuf": "^0.6.1", + "apollo-server-caching": "^0.5.2", + "apollo-server-env": "^2.4.5", + "apollo-server-errors": "^2.4.2", + "apollo-server-plugin-base": "^0.10.2", + "apollo-server-types": "^0.6.1", + "apollo-tracing": "^0.12.0", + "async-retry": "^1.2.1", + "fast-json-stable-stringify": "^2.0.0", + "graphql-extensions": "^0.12.6", + "graphql-tag": "^2.9.2", + "graphql-tools": "^4.0.0", + "graphql-upload": "^8.0.2", + "loglevel": "^1.6.7", + "lru-cache": "^5.0.0", + "sha.js": "^2.4.11", + "subscriptions-transport-ws": "^0.9.11", + "uuid": "^8.0.0", + "ws": "^6.0.0" + } + }, + "apollo-server-env": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-2.4.5.tgz", + "integrity": "sha512-nfNhmGPzbq3xCEWT8eRpoHXIPNcNy3QcEoBlzVMjeglrBGryLG2LXwBSPnVmTRRrzUYugX0ULBtgE3rBFNoUgA==", + "dev": true, + "requires": { + "node-fetch": "^2.1.2", + "util.promisify": "^1.0.0" + } + }, + "apollo-server-errors": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-2.4.2.tgz", + "integrity": "sha512-FeGxW3Batn6sUtX3OVVUm7o56EgjxDlmgpTLNyWcLb0j6P8mw9oLNyAm3B+deHA4KNdNHO5BmHS2g1SJYjqPCQ==", + "dev": true + }, + "apollo-server-plugin-base": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.10.2.tgz", + "integrity": "sha512-uM5uL1lOxbXdgvt/aEIbgs40fV9xA45Y3Mmh0VtQ/ddqq0MXR5aG92nnf8rM+URarBCUfxKJKaYzJJ/CXAnEdA==", + "dev": true, + "requires": { + "apollo-server-types": "^0.6.1" + } + }, + "apollo-server-types": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-0.6.1.tgz", + "integrity": "sha512-IEQ37aYvMLiTUzsySVLOSuvvhxuyYdhI05f3cnH6u2aN1HgGp7vX6bg+U3Ue8wbHfdcifcGIk5UEU+Q+QO6InA==", + "dev": true, + "requires": { + "apollo-reporting-protobuf": "^0.6.1", + "apollo-server-caching": "^0.5.2", + "apollo-server-env": "^2.4.5" + } + }, + "apollo-tracing": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.12.0.tgz", + "integrity": "sha512-cMUYGE6mOEwb9HDqhf4fiPEo2JMhjPIqEprAQEC57El76avRpRig5NM0bnqMZcYJZR5QmLlNcttNccOwf9WrNg==", + "dev": true, + "requires": { + "apollo-server-env": "^2.4.5", + "apollo-server-plugin-base": "^0.10.2" + } + }, + "graphql-extensions": { + "version": "0.12.6", + "resolved": "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.12.6.tgz", + "integrity": "sha512-EUNw+OIRXYTPxToSoJjhJvS5aGa94KkdkZnL1I9DCZT64/+rzQNeLeGj+goj2RYuYvoQe1Bmcx0CNZ1GqwBhng==", + "dev": true, + "requires": { + "@apollographql/apollo-tools": "^0.4.3", + "apollo-server-env": "^2.4.5", + "apollo-server-types": "^0.6.1" + } + }, + "graphql-tools": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-4.0.8.tgz", + "integrity": "sha512-MW+ioleBrwhRjalKjYaLQbr+920pHBgy9vM/n47sswtns8+96sRn5M/G+J1eu7IMeKWiN/9p6tmwCHU7552VJg==", + "dev": true, + "requires": { + "apollo-link": "^1.2.14", + "apollo-utilities": "^1.0.1", + "deprecated-decorator": "^0.1.6", + "iterall": "^1.1.3", + "uuid": "^3.1.0" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } + } + }, + "uuid": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz", + "integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==", + "dev": true + } } }, "apollo-server-types": { diff --git a/back/src/__tests__/errors.integration.ts b/back/src/__tests__/errors.integration.ts index 60a8a6bda5..a8620b12ab 100644 --- a/back/src/__tests__/errors.integration.ts +++ b/back/src/__tests__/errors.integration.ts @@ -160,7 +160,7 @@ describe("Error handling", () => { process.env.NODE_ENV = "production"; const server = require("../server").server; const { mutate } = createTestClient(server); - // invalid variables `toto` instead of `input` + // invalid variable `toto` instead of `input` const variables = { toto: "toto" }; const { errors } = await mutate({ mutation: BAR, diff --git a/back/src/server.ts b/back/src/server.ts index 87ad58a786..e34319d2f8 100644 --- a/back/src/server.ts +++ b/back/src/server.ts @@ -128,7 +128,7 @@ export const server = new ApolloServer({ // Workaround for graphQL validation error displayed as internal server error // when graphQL variables are of of invalid type // See: https://github.com/apollographql/apollo-server/issues/3498 - if (err.message.startsWith(`Variable "`)) { + if (err.message && err.message.startsWith(`Variable "`)) { err.extensions.code = "GRAPHQL_VALIDATION_FAILED"; return err; }