From 48a3c0a337be3493a5138c3c89e27ab0fdd5d43e Mon Sep 17 00:00:00 2001 From: Will JALLET <wilson.jallet@polytechnique.edu> Date: Fri, 31 Aug 2018 14:06:34 +0200 Subject: [PATCH] Remplacement de express-graphql par Apollo Server --- README.md | 10 +- package-lock.json | 544 +++++++++++++++++++- package.json | 2 +- src/graphql/schema.js | 5 +- src/index.ts | 2 +- src/{admin_view => routing}/admin.router.ts | 0 src/server.ts | 88 ++-- src/views/home.pug | 28 +- src/views/layout.pug | 3 +- 9 files changed, 605 insertions(+), 77 deletions(-) rename src/{admin_view => routing}/admin.router.ts (100%) diff --git a/README.md b/README.md index d41a124..e2265c4 100644 --- a/README.md +++ b/README.md @@ -65,9 +65,15 @@ Il est accessible au path `/adminview/admin` ; n'importe quel path devrait redir Le panneau d'administration sert (ou plutôt, servira à terme) à accéder directement à la BDD propre de sigma. On accède à la table `table_name` par une requête GET à `/adminview/db/table_name`' et aux colonnes `columns` de cette table par une requête GET à `/adminview/db/table_name`?columns=`columns`. Ces pages sont protégées pour n'être accessibles qu'en étant authentifié. -### GraphiQL et Voyager +### GraphQL Playground et Voyager -A partir du panneau d'admin, en faisant des requêtes GET à `/graphiql` et `/voyager` respectivement, on accède à GraphiQL et à GraphQL Voyager. Ces pages sont protégées pour n'être accessibles qu'en étant authentifié. +Accéder via un navigateur à `/graphql` et `/voyager` respectivement renvoie les apps GraphQL Playground et GraphQL Voyager. + +Il s'agit du même `/graphql` que l'_endpoint_ de l'API, mais le serveur est configuré de sorte à renvoyer Playground lorsqu'il détecte un accès via navigateur. Les requêtes dans le Playground sont donc soumises au mêmes permissions que dans l'API. + +L'app Voyager permet de visualiser le « graphe » sous-jacent à la structure de l'API. Cet _endpoint_ devrait être protégé **en prod**. + +**En production**, ## Scripts diff --git a/package-lock.json b/package-lock.json index 5c1d6d6..9c47187 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,21 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@apollographql/apollo-upload-server": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@apollographql/apollo-upload-server/-/apollo-upload-server-5.0.3.tgz", + "integrity": "sha512-tGAp3ULNyoA8b5o9LsU2Lq6SwgVPUOKAqKywu2liEtTvrFSGPrObwanhYwArq3GPeOqp2bi+JknSJCIU3oQN1Q==", + "requires": { + "@babel/runtime-corejs2": "^7.0.0-rc.1", + "busboy": "^0.2.14", + "object-path": "^0.11.4" + } + }, + "@apollographql/graphql-playground-html": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.0.tgz", + "integrity": "sha512-QAZIFrfVRkjvMkUHIQKZXZ3La0V5t12w5PWrhihYEabHwzIZV/txQd/kSYHgYPXC4s5OURxsXZop9f0BzI2QIQ==" + }, "@babel/code-frame": { "version": "7.0.0-beta.44", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.44.tgz", @@ -66,6 +81,27 @@ "js-tokens": "^3.0.0" } }, + "@babel/runtime-corejs2": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.0.0.tgz", + "integrity": "sha512-Yww0jXgolNtkhcK+Txo5JN+DjBpNmmAtD7G99HOebhEjBzjnACG09Tip9C8lSOF6PrhA56OeJWeOZduNJaKxBA==", + "requires": { + "core-js": "^2.5.7", + "regenerator-runtime": "^0.12.0" + }, + "dependencies": { + "core-js": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==" + }, + "regenerator-runtime": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", + "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==" + } + } + }, "@babel/template": { "version": "7.0.0-beta.44", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.44.tgz", @@ -164,6 +200,60 @@ "integrity": "sha512-LAQ1d4OPfSJ/BMbI2DuizmYrrkD9JMaTdi2hQTlI53lQ4kRQPyZQRS4CYQ7O66bnBBnP/oYdRxbk++X0xuFU6A==", "dev": true }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + }, "@samverschueren/stream-to-observable": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz", @@ -179,6 +269,14 @@ "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==", "dev": true }, + "@types/accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==", + "requires": { + "@types/node": "*" + } + }, "@types/babel-types": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.1.tgz", @@ -201,6 +299,14 @@ "@types/node": "*" } }, + "@types/connect": { + "version": "3.4.32", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz", + "integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==", + "requires": { + "@types/node": "*" + } + }, "@types/connect-ensure-login": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/@types/connect-ensure-login/-/connect-ensure-login-0.1.4.tgz", @@ -219,6 +325,14 @@ "@types/express": "*" } }, + "@types/cors": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.4.tgz", + "integrity": "sha512-ipZjBVsm2tF/n8qFGOuGBkUij9X9ZswVi9G3bx/6dz7POpVa6gVHcj1wsX/LVEn9MMF41fxK/PnZPPoTD1UFPw==", + "requires": { + "@types/express": "*" + } + }, "@types/events": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", @@ -258,6 +372,11 @@ "@types/node": "*" } }, + "@types/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz", + "integrity": "sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q==" + }, "@types/mime": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.0.tgz", @@ -291,6 +410,15 @@ "@types/mime": "*" } }, + "@types/ws": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-5.1.2.tgz", + "integrity": "sha512-NkTXUKTYdXdnPE2aUUbGOXE1XfMK527SCvU/9bj86kyFF6kZ9ZnOQ3mK5jADn98Y2vEUD/7wKDgZa7Qst2wYOg==", + "requires": { + "@types/events": "*", + "@types/node": "*" + } + }, "@webassemblyjs/ast": { "version": "1.5.13", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.5.13.tgz", @@ -626,6 +754,15 @@ "normalize-path": "^2.1.1" } }, + "apollo-cache-control": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/apollo-cache-control/-/apollo-cache-control-0.2.2.tgz", + "integrity": "sha512-N5A1hO6nHZBCR+OCV58IlE7k6hZrFJZTf/Ab2WD8wduLSa0qLLRlCp3rXvD05+jpWa6sdKw03whW2omJ+SyT+w==", + "requires": { + "apollo-server-env": "2.0.2", + "graphql-extensions": "0.1.2" + } + }, "apollo-codegen": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/apollo-codegen/-/apollo-codegen-0.19.1.tgz", @@ -787,6 +924,35 @@ } } }, + "apollo-datasource": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-0.1.2.tgz", + "integrity": "sha512-AbUxS7Qkz9+T+g19zKRJiA+tBVGVVunzXwd4ftDSYGx1VrF5LJJO7Gc57bk719gWIZneZ02HsVCEZd6NxFF8RQ==", + "requires": { + "apollo-server-caching": "0.1.2", + "apollo-server-env": "2.0.2" + } + }, + "apollo-engine-reporting": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/apollo-engine-reporting/-/apollo-engine-reporting-0.0.2.tgz", + "integrity": "sha512-Fe/1oxC8rUXRrBTMUiqs5PSb6hnMOJHuttJMhs83u5POfplc4QrKJZtEEU4Ui8mxeJGaGNWbWf+D4q645xdQLA==", + "requires": { + "apollo-engine-reporting-protobuf": "0.0.1", + "apollo-server-env": "2.0.2", + "async-retry": "^1.2.1", + "graphql-extensions": "0.1.2", + "lodash": "^4.17.10" + } + }, + "apollo-engine-reporting-protobuf": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.0.1.tgz", + "integrity": "sha512-AySoDgog2p1Nph44FyyqaU4AfRZOXx8XZxRsVHvYY4dHlrMmDDhhjfF3Jswa7Wr8X/ivvx3xA0jimRn6rsG8Ew==", + "requires": { + "protobufjs": "^6.8.6" + } + }, "apollo-link": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.2.tgz", @@ -804,6 +970,120 @@ } } }, + "apollo-server-caching": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-0.1.2.tgz", + "integrity": "sha512-jBRnsTgXN0m8yVpumoelaUq9mXR7YpJ3EE+y/alI7zgXY+0qFDqksRApU8dEfg3q6qUnO7rFxRhdG5eyc0+1ig==", + "requires": { + "lru-cache": "^4.1.3" + }, + "dependencies": { + "lru-cache": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", + "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + } + } + }, + "apollo-server-core": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-2.0.4.tgz", + "integrity": "sha512-6kNaQYZfX2GvAT1g9ih0rodfRl4hPL1jXb7b+FvQ1foFR5Yyb3oqL2DOcP65gQi/7pGhyNRUAncPU18Vo3u9rQ==", + "requires": { + "@apollographql/apollo-upload-server": "^5.0.3", + "@types/ws": "^5.1.2", + "apollo-cache-control": "0.2.2", + "apollo-datasource": "0.1.2", + "apollo-engine-reporting": "0.0.2", + "apollo-server-caching": "0.1.2", + "apollo-server-env": "2.0.2", + "apollo-server-errors": "2.0.2", + "apollo-tracing": "0.2.2", + "graphql-extensions": "0.1.2", + "graphql-subscriptions": "^0.5.8", + "graphql-tag": "^2.9.2", + "graphql-tools": "^3.0.4", + "hash.js": "^1.1.3", + "lodash": "^4.17.10", + "subscriptions-transport-ws": "^0.9.11", + "ws": "^5.2.0" + } + }, + "apollo-server-env": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-2.0.2.tgz", + "integrity": "sha512-LsSh2TSF1Sh+TnKxCv2To+UNTnoPpBGCXn6fPsmiNqVaBaSagfZEU/aaSu3ftMlmfXr4vXAfYNUDMKEi+7E6Bg==", + "requires": { + "node-fetch": "^2.1.2", + "util.promisify": "^1.0.0" + }, + "dependencies": { + "node-fetch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.2.0.tgz", + "integrity": "sha512-OayFWziIxiHY8bCUyLX6sTpDH8Jsbp4FfYd1j1f7vZyfgkcOnAyM4oQR16f8a0s7Gl/viMGRey8eScYk4V4EZA==" + } + } + }, + "apollo-server-errors": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-2.0.2.tgz", + "integrity": "sha512-zyWDqAVDCkj9espVsoUpZr9PwDznM8UW6fBfhV+i1br//s2AQb07N6ektZ9pRIEvkhykDZW+8tQbDwAO0vUROg==" + }, + "apollo-server-express": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-2.0.4.tgz", + "integrity": "sha512-9mxcFpnTgQTmrsvVRRofEY7N1bJYholjv99IfN8puu5lhNqj8ZbOPZYrw+zd+Yh4rZSonwx76ZzTRzM00Yllfw==", + "requires": { + "@apollographql/apollo-upload-server": "^5.0.3", + "@apollographql/graphql-playground-html": "^1.6.0", + "@types/accepts": "^1.3.5", + "@types/body-parser": "1.17.0", + "@types/cors": "^2.8.4", + "@types/express": "4.16.0", + "accepts": "^1.3.5", + "apollo-server-core": "2.0.4", + "body-parser": "^1.18.3", + "cors": "^2.8.4", + "graphql-subscriptions": "^0.5.8", + "graphql-tools": "^3.0.4", + "type-is": "^1.6.16" + }, + "dependencies": { + "@types/body-parser": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.0.tgz", + "integrity": "sha512-a2+YeUjPkztKJu5aIF2yArYFQQp8d51wZ7DavSHjFuY1mqVgidGyzEQ41JIVNy82fXj8yPgy2vJmfIywgESW6w==", + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/express": { + "version": "4.16.0", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.16.0.tgz", + "integrity": "sha512-TtPEYumsmSTtTetAPXlJVf3kEqb6wZK0bZojpJQrnD/djV4q1oB6QQ8aKvKqwNPACoe02GNiy5zDzcYivR5Z2w==", + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "*", + "@types/serve-static": "*" + } + } + } + }, + "apollo-tracing": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.2.2.tgz", + "integrity": "sha512-zrpLRvaAqtzGufc1GfV+691xQtzq5elfBydg/7wzuaFszlMH66hkLas5Dw36drUX21CbCljOuGYvYzqSiKykuQ==", + "requires": { + "apollo-server-env": "2.0.2", + "graphql-extensions": "0.1.2" + } + }, "apollo-utilities": { "version": "1.0.20", "resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.0.20.tgz", @@ -959,6 +1239,19 @@ "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", "dev": true }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" + }, + "async-retry": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.2.1.tgz", + "integrity": "sha512-FadV8UDcyZDjzb6eV7MCJj0bfrNjwKw7/X0QHPFCbYP6T20FXgZCYXpJKlQC8RxEQP1E6Xs8pNHdh3bcrZAuAw==", + "requires": { + "retry": "0.10.1" + } + }, "atob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz", @@ -1866,6 +2159,11 @@ "integrity": "sha512-5Hlm13BJVAioCHpImtFqNOF2H3ieTOHd0fmFGMxOJ9jgeFqeAwsv3u5P5cR7CSeFrkgHsT19DgFJkHV0/Mcd8g==", "dev": true }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" + }, "backoff": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz", @@ -2235,6 +2533,38 @@ "safe-json-stringify": "~1" } }, + "busboy": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", + "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", + "requires": { + "dicer": "0.2.5", + "readable-stream": "1.1.x" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, "bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", @@ -3082,6 +3412,14 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, "define-property": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", @@ -3206,6 +3544,38 @@ "repeating": "^2.0.0" } }, + "dicer": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", + "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", + "requires": { + "readable-stream": "1.1.x", + "streamsearch": "0.1.2" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", @@ -3430,6 +3800,28 @@ "is-arrayish": "^0.2.1" } }, + "es-abstract": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", + "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", + "requires": { + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" + } + }, + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "requires": { + "is-callable": "^1.1.1", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.1" + } + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -3756,6 +4148,11 @@ "through": "~2.3.1" } }, + "eventemitter3": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", + "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==" + }, "events": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", @@ -3966,17 +4363,6 @@ } } }, - "express-graphql": { - "version": "0.6.12", - "resolved": "https://registry.npmjs.org/express-graphql/-/express-graphql-0.6.12.tgz", - "integrity": "sha512-ouLWV0hRw4hnaLtXzzwhdC79ewxKbY2PRvm05mPc/zOH5W5WVCHDQ1SmNxEPBQdUeeSNh29aIqW9zEQkA3kMuA==", - "requires": { - "accepts": "^1.3.0", - "content-type": "^1.0.4", - "http-errors": "^1.3.0", - "raw-body": "^2.3.2" - } - }, "express-jwt": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/express-jwt/-/express-jwt-5.3.1.tgz", @@ -4435,12 +4821,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4460,7 +4848,8 @@ "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", @@ -4582,7 +4971,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -4608,6 +4998,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5207,6 +5598,14 @@ "iterall": "^1.2.2" } }, + "graphql-extensions": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.1.2.tgz", + "integrity": "sha512-A81kfGtOKG0/1sDQGm23u60bkTuk9VDof0SrQrz7yNpPLY48JF11b8+4LNlYfEBVvceDbLAs1KRfyLQskJjJSg==", + "requires": { + "apollo-server-env": "2.0.2" + } + }, "graphql-import": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/graphql-import/-/graphql-import-0.4.5.tgz", @@ -5224,6 +5623,19 @@ "cross-fetch": "2.0.0" } }, + "graphql-subscriptions": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-0.5.8.tgz", + "integrity": "sha512-0CaZnXKBw2pwnIbvmVckby5Ge5e2ecmjofhYCdyeACbCly2j3WXDP/pl+s+Dqd2GQFC7y99NB+53jrt55CKxYQ==", + "requires": { + "iterall": "^1.2.1" + } + }, + "graphql-tag": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.9.2.tgz", + "integrity": "sha512-qnNmof9pAqj/LUzs3lStP0Gw1qhdVCUS7Ab7+SUB6KD5aX1uqxWQRwMnOGTkhKuLvLNIs1TvNz+iS9kUGl1MhA==" + }, "graphql-tools": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-3.1.1.tgz", @@ -5352,7 +5764,6 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.5.tgz", "integrity": "sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA==", - "dev": true, "requires": { "inherits": "^2.0.3", "minimalistic-assert": "^1.0.1" @@ -5638,6 +6049,11 @@ "builtin-modules": "^1.0.0" } }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" + }, "is-ci": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.1.0.tgz", @@ -5665,6 +6081,11 @@ } } }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" + }, "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", @@ -5929,6 +6350,11 @@ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=" + }, "is-unc-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", @@ -7214,8 +7640,7 @@ "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" }, "minimalistic-crypto-utils": { "version": "1.0.1", @@ -7646,6 +8071,16 @@ "integrity": "sha512-05KzQ70lSeGSrZJQXE5wNDiTkBJDlUT/myi6RX9dVIvz7a7Qh4oH93BQdiPMn27nldYvVQCKMUaM83AfizZlsQ==", "dev": true }, + "object-keys": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==" + }, + "object-path": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.4.tgz", + "integrity": "sha1-NwrnUvvzfePqcKhhwju6iRVpGUk=" + }, "object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", @@ -7665,6 +8100,15 @@ "isobject": "^3.0.0" } }, + "object.getownpropertydescriptors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", + "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" + } + }, "object.map": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", @@ -8399,6 +8843,33 @@ "object-assign": "^4.1.1" } }, + "protobufjs": { + "version": "6.8.8", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz", + "integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.0", + "@types/node": "^10.1.0", + "long": "^4.0.0" + }, + "dependencies": { + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + } + } + }, "proxy-addr": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz", @@ -9136,6 +9607,11 @@ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" }, + "retry": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", + "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=" + }, "right-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", @@ -9770,6 +10246,11 @@ "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" }, + "streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" + }, "strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", @@ -9861,6 +10342,18 @@ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true }, + "subscriptions-transport-ws": { + "version": "0.9.14", + "resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.14.tgz", + "integrity": "sha512-n1+mgupVdJn1MIls1ZhSJurJjc+islp7Tv9EIaEJ3HAd9DaINneKq0KRqOYNOrvUI7orVWGomEnlIxoudjfbeA==", + "requires": { + "backo2": "^1.0.2", + "eventemitter3": "^3.1.0", + "iterall": "^1.2.1", + "symbol-observable": "^1.0.4", + "ws": "^5.2.0" + } + }, "supports-color": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", @@ -10516,6 +11009,15 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, + "util.promisify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", + "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "requires": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" + } + }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -11178,6 +11680,14 @@ "signal-exit": "^3.0.2" } }, + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "requires": { + "async-limiter": "~1.0.0" + } + }, "xdg-basedir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", diff --git a/package.json b/package.json index 542b537..ce15eab 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "author": "Binet Réseau", "license": "ISC", "dependencies": { + "apollo-server-express": "^2.0.4", "body-parser": "^1.18.3", "colors": "^1.3.2", "connect-ensure-login": "^0.1.1", @@ -25,7 +26,6 @@ "copy-webpack-plugin": "^4.5.2", "cors": "^2.8.4", "express": "^4.16.2", - "express-graphql": "^0.6.12", "express-jwt": "^5.3.1", "express-session": "^1.15.6", "file-loader": "^1.1.11", diff --git a/src/graphql/schema.js b/src/graphql/schema.js index 212e583..77c8811 100644 --- a/src/graphql/schema.js +++ b/src/graphql/schema.js @@ -3,18 +3,17 @@ * @author akka vodol */ -import { makeExecutableSchema } from 'graphql-tools'; import actionDefs from './typeDefs/actions.graphql'; import objectDefs from './typeDefs/objects.graphql'; import { resolvers } from './resolvers'; const typeDefs = actionDefs.concat(objectDefs); -const schema = makeExecutableSchema({ +const schema = { typeDefs, resolvers, logger: {log: e => console.log(e)}, inheritResolversFromInterfaces: true -}); +}; export default schema; \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 4773230..38462df 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,5 +8,5 @@ import colors from 'colors'; const port = process.env.PORT || 3000; app.listen(port, () => { - console.log(colors.blue("Express server listening on port %s."), port); + console.log(colors.blue("🚀 Server ready on port %s."), port); }); diff --git a/src/admin_view/admin.router.ts b/src/routing/admin.router.ts similarity index 100% rename from src/admin_view/admin.router.ts rename to src/routing/admin.router.ts diff --git a/src/server.ts b/src/server.ts index 7483cc1..75f997d 100644 --- a/src/server.ts +++ b/src/server.ts @@ -13,12 +13,14 @@ import express from 'express'; import bodyParser from 'body-parser'; // packages pour graphql import { express as graphqlVoyager } from 'graphql-voyager/middleware'; -import graphqlHTTP from 'express-graphql'; // new name of 'graphql-server-express' (mai 2018). cf npmjs.com. +// replacement of express-graphql, which hasn't been updated in 6 months +import { ApolloServer } from 'apollo-server-express'; +// typeDefs and resolvers import schema from './graphql/schema'; // packages pour adminview import { ensureLoggedIn } from 'connect-ensure-login'; import flash from 'connect-flash'; -import router from './admin_view/admin.router'; +import router from './routing/admin.router'; // packages pour l'authentification import passport from 'passport'; import session from 'express-session'; @@ -189,44 +191,54 @@ app.post('/login', */ const environment = process.env.NODE_ENV || 'development'; -app.use('/graphql', - graphqlHTTP(async (req, res, params) => { - // vary the options *on a per-request basis* - let uid; - let password; +/** + * @desc Define GraphQL request context object, through a callback, with authorization. + * See: https://github.com/apollographql/apollo-server/blob/master/docs/source/best-practices/authentication.md + * + */ +const context = async ({ req }) => { + let uid; + let password; + + console.log("Responding to graphql request..."); + console.log(` + | User: ${req.user ? req.user.uid : "none"} + | Authorization: ${req.headers.authorization} + | Authenticated: ${req.isAuthenticated()} + `.trim()); + + if(req.isAuthenticated()) { + console.log("graphql API is receiving a request from an authenticated user! \\o/"); + try { + uid = req.user.uid; + password = "mythe"; + } catch (err) { + console.log("Error: req is authenticated, but pb when trying to extract uid from req.user. Probably user was either not serialized or not deserialized properly"); + console.log(err); + } + } else { + // FOR DEVELOPMENT ONLY. for production, replace with a "publicUser" or "notLoggedInUser" or something. + uid = dn.split("=")[1].split(",")[0]; + password = passwd; + } + + return { + request: req, + bindUser: { uid, password } + } +} - console.log("Responding to graphql request..."); - console.log(` -| User: ${req.user ? req.user.uid : "none"} -| Authorization: ${req.headers.authorization} -| Authenticated: ${req.isAuthenticated()} - `.trim()); - - if(req.isAuthenticated()) { - console.log("graphql API is receiving a request from an authenticated user! \\o/"); - try { - uid = req.user.uid; - password = "mythe"; - } catch (err) { - console.log("Error: req is authenticated, but pb when trying to extract uid from req.user. Probably user was either not serialized or not deserialized properly"); - console.log(err); - } - } else { - // FOR DEVELOPMENT ONLY. for production, replace with a "publicUser" or "notLoggedInUser" or something. - uid = dn.split("=")[1].split(",")[0]; - password = passwd; +const graphServer = new ApolloServer({ + ...schema, + context, + playground: { + settings: { + "editor.theme": "light", + "editor.cursorShape": 'line' } - - return { - schema, - graphiql: environment == 'development', // gives access to GraphiQL if req comes from browser (je crois) - context: { - request: req, - bindUser: { uid: uid, password: password } - } // accessible in every single resolver as the third argument - }; - }) -); + } +}); +graphServer.applyMiddleware({ app }); /** * FIN API GRAPHQL diff --git a/src/views/home.pug b/src/views/home.pug index 34e410c..9667698 100644 --- a/src/views/home.pug +++ b/src/views/home.pug @@ -1,10 +1,15 @@ extends layout.pug block content - h1 Welcome to API server - h2 Query the database - p Hello, world! This is server talking to you live on port #{port}! - p You can query the database using the form below. + img(src="/assets/logo_sigma_large.png", width="240px", id='logo', alt="Logo sigma") + div(class="logged-in-header") + p #{userName}. + form(action="/adminview/avlogout", method="post") + button.form-control(type="submit",class="button") Déconnexion + h1 API Sigma + p Ceci est l'API de Sigma. + h2 Requêtes BDD + p Pour faire des requêtes à la BDD interne de Sigma, utilisez le formulaire ci-dessous. form(action="/adminview/db", method="get") div.form-group label(for="table") Table @@ -12,14 +17,11 @@ block content div.form-group label(for="columns") Columns input.form-control(type="search", name="columns") - button.form-control(type="submit",class="button") Recherche/<em>Search</em> + button.form-control(type="submit",class="button") Recherche | - h2 GraphiQL and Voyager - p GraphiQL is an interactive environment to make GraphQL requests to the database. - p GraphQL Voyager is an application that displays the GraphQL schema as an actual graph. - a(class="button button-small",href="/graphql") GraphiQL + h2 GraphQL Playground + p GraphQL playground permet d'interagir avec l'API GraphQL, la tester, la débeuguer. + a(class="button button-small",href="/graphql") Playground + h2 GraphQL Voyager + p Voyager est un outil de visualisation du « graphe » derrière l'API. a(class="button button-small",href="/voyager") Voyager - | - p Currently logged in as: #{userName}. - form(action="/adminview/avlogout", method="post") - button.form-control(type="submit",class="button") Déconnexion/<em>Logout</em> diff --git a/src/views/layout.pug b/src/views/layout.pug index 6bb139b..7b49bd1 100644 --- a/src/views/layout.pug +++ b/src/views/layout.pug @@ -7,7 +7,6 @@ html(lang="en") style include ../css/style.css block extraStyles - title API server - #{title} + title API Sigma - #{title} body block content - \ No newline at end of file -- GitLab