From 0313761ab60e764fe7e8a1e738bbb019726e9db2 Mon Sep 17 00:00:00 2001 From: hawkspar <quentin.chevalier@polytechnique.edu> Date: Sat, 9 Feb 2019 11:50:37 +0100 Subject: [PATCH] clean peek User --- .env_dist | 2 +- ldap_config.json | 1 - ldap_credentials_dist.json | 2 +- package-lock.json | 417 ++++++++++++++--------------- src/ldap/export/group.js | 453 ++++++++++++++++++++++++++++++++ src/ldap/export/user.js | 332 +++++++++++++++++++++++ src/ldap/export/user.ts | 2 +- src/ldap/internal/basics.js | 330 +++++++++++++++++++++++ src/ldap/internal/config.js | 86 ++++++ src/ldap/internal/config.ts | 2 +- src/ldap/internal/tools.js | 509 ++++++++++++++++++++++++++++++++++++ src/ldap/test.js | 5 + 12 files changed, 1921 insertions(+), 220 deletions(-) create mode 100644 src/ldap/export/group.js create mode 100644 src/ldap/export/user.js create mode 100644 src/ldap/internal/basics.js create mode 100644 src/ldap/internal/config.js create mode 100644 src/ldap/internal/tools.js create mode 100644 src/ldap/test.js diff --git a/.env_dist b/.env_dist index 246780d..f79e0a2 100644 --- a/.env_dist +++ b/.env_dist @@ -1,6 +1,6 @@ # Modele du fichier '.env', definissant variables "d'environnement" utilisees dans divers fichiers de src/ et de db/. # (Ces variables sont chargees par le package dotenv dans `process.env`, dans les fichiers .js et .ts ou dotenv.config() est appele) -# Copier ce fichier en le renommant '.env', (le placer a la racine du repo,) et modifier les champs comme il faut. +#Copier et renommer .env TARGET_ENV=development PORT=3000 diff --git a/ldap_config.json b/ldap_config.json index 982ac05..62d56af 100644 --- a/ldap_config.json +++ b/ldap_config.json @@ -1,6 +1,5 @@ { "comment_1": "Tout ce fichier sert à protéger les vrais champs du LDAP dans les scripts dans src/ldap. Les champs ci-dessous contiennent le nécessaire à une première connexion par exemple.", - "comment_tmp": "Passer en LDAPS ASAP.", "comment_1bis": "Ce fichier est importé par src/ldap/internal/config.ts ; comme indiqué dans config.ts, la présence d'une variable d'environnement correspondante peut override les paramètres donnés ici.", "server_prod_old": "ldap://frankiz.eleves.polytechnique.fr:389", "server_dev_old": "ldap://localhost:389", diff --git a/ldap_credentials_dist.json b/ldap_credentials_dist.json index 7702f74..46253a9 100644 --- a/ldap_credentials_dist.json +++ b/ldap_credentials_dist.json @@ -1,5 +1,5 @@ { - "README": "Modele du fichier 'ldap_credentials.json', requis par src/ldap/. Copier ce fichier en le renommant 'ldap_credentials.json', (le placer a la racine du repo,) et modifier les champs comme il faut.", + "README": "Modele du fichier 'ldap_credentials.json', requis par src/ldap/. Copier ce fichier en le renommant 'ldap_credentials.json' (le placer a la racine du repo). A copier et renommer en local.", "dn": "uid=sigma,ou=services,dc=frankiz,dc=net", "passwd": "&vH}x%7;FK3j53eX" diff --git a/package-lock.json b/package-lock.json index daa192c..a812679 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "@apollographql/graphql-playground-html": { "version": "1.6.6", "resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.6.tgz", - "integrity": "sha512-lqK94b+caNtmKFs5oUVXlSpN3sm5IXZ+KfhMxOtr0LR2SqErzkoJilitjDvJ1WbjHlxLI7WtCjRmOLdOGJqtMQ==" + "integrity": "sha1-AiIJ4oorVH3N4VshnwxQ9HqlvrM=" }, "@babel/cli": { "version": "7.2.3", @@ -221,7 +221,7 @@ "@babel/helper-annotate-as-pure": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz", - "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", + "integrity": "sha1-Mj053QtQ4Qx8Bsp9djjmhk2MXDI=", "dev": true, "requires": { "@babel/types": "^7.0.0" @@ -243,7 +243,7 @@ "@babel/helper-builder-binary-assignment-operator-visitor": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz", - "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==", + "integrity": "sha1-a2lijf5Ah3mODE7Zjj1Kay+9L18=", "dev": true, "requires": { "@babel/helper-explode-assignable-expression": "^7.1.0", @@ -266,7 +266,7 @@ "@babel/helper-call-delegate": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.1.0.tgz", - "integrity": "sha512-YEtYZrw3GUK6emQHKthltKNZwszBcHK58Ygcis+gVUrF4/FmTVr5CCqQNSfmvg2y+YDEANyYoaLz/SHsnusCwQ==", + "integrity": "sha1-apV/EF83dV6GRTQ9MDiiLhRJzEo=", "dev": true, "requires": { "@babel/helper-hoist-variables": "^7.0.0", @@ -484,7 +484,7 @@ "@babel/helper-define-map": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.1.0.tgz", - "integrity": "sha512-yPPcW8dc3gZLN+U1mhYV91QU3n5uTbx7DUdf8NnPbjS0RMwBuHi9Xt2MUgppmNz7CJxTBWsGczTiEp1CSOTPRg==", + "integrity": "sha1-O3TK7DKbPIDBFikIh8DdmuRowgw=", "dev": true, "requires": { "@babel/helper-function-name": "^7.1.0", @@ -565,7 +565,7 @@ "@babel/helper-explode-assignable-expression": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz", - "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==", + "integrity": "sha1-U3+hP28WdN90WwwA7I/k6ZaByPY=", "dev": true, "requires": { "@babel/traverse": "^7.1.0", @@ -719,7 +719,7 @@ "@babel/helper-hoist-variables": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0.tgz", - "integrity": "sha512-Ggv5sldXUeSKsuzLkddtyhyHe2YantsxWKNi7A+7LeD12ExRDWTRk29JCXpaHPAbMaIPZSil7n+lq78WY2VY7w==", + "integrity": "sha1-Rq3ExedYZFrnpF3rkrqwkYwju4g=", "dev": true, "requires": { "@babel/types": "^7.0.0" @@ -741,7 +741,7 @@ "@babel/helper-member-expression-to-functions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz", - "integrity": "sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==", + "integrity": "sha1-jNFLCg33/wDwCefXpDaUX0fHoW8=", "dev": true, "requires": { "@babel/types": "^7.0.0" @@ -763,7 +763,7 @@ "@babel/helper-module-imports": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", - "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", + "integrity": "sha1-lggbcRHkhtpNLNlxrRpP4hbMLj0=", "dev": true, "requires": { "@babel/types": "^7.0.0" @@ -858,7 +858,7 @@ "@babel/helper-optimise-call-expression": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz", - "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==", + "integrity": "sha1-opIMVwKwc8Fd5REGIAqoytIEl9U=", "dev": true, "requires": { "@babel/types": "^7.0.0" @@ -880,13 +880,13 @@ "@babel/helper-plugin-utils": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", - "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", + "integrity": "sha1-u7P77phmHFaQNCN8wDlnupm08lA=", "dev": true }, "@babel/helper-regex": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.0.0.tgz", - "integrity": "sha512-TR0/N0NDCcUIUEbqV6dCO+LptmmSQFQ7q70lfcEB4URsjD0E1HzicrwUH+ap6BAQ2jhCX9Q4UqZy4wilujWlkg==", + "integrity": "sha1-LBcYkjtX+bvmRwX/5WQKxk2b2yc=", "dev": true, "requires": { "lodash": "^4.17.10" @@ -895,7 +895,7 @@ "@babel/helper-remap-async-to-generator": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz", - "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==", + "integrity": "sha1-Nh2AghtvONp1vT8HheziCojF/n8=", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.0.0", @@ -1168,7 +1168,7 @@ "@babel/helper-simple-access": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz", - "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==", + "integrity": "sha1-Ze65VMjCRb6qToWdphiPOdceWFw=", "dev": true, "requires": { "@babel/template": "^7.1.0", @@ -1237,7 +1237,7 @@ "@babel/helper-wrap-function": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", - "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==", + "integrity": "sha1-xOABJEV2nigVtVKW6tQ6lYVJ9vo=", "dev": true, "requires": { "@babel/helper-function-name": "^7.1.0", @@ -1525,7 +1525,7 @@ "@babel/plugin-proposal-async-generator-functions": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz", - "integrity": "sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==", + "integrity": "sha1-somzBmadzkrSCwJSiJoVdoydQX4=", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -1546,7 +1546,7 @@ "@babel/plugin-proposal-json-strings": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz", - "integrity": "sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg==", + "integrity": "sha1-Vo7MRGxhSK5rJn8CVREwiR4p8xc=", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -1566,7 +1566,7 @@ "@babel/plugin-proposal-optional-catch-binding": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz", - "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", + "integrity": "sha1-E12B7baKCB5V5W7EhUHs6AZcOPU=", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -1576,7 +1576,7 @@ "@babel/plugin-proposal-unicode-property-regex": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.2.0.tgz", - "integrity": "sha512-LvRVYb7kikuOtIoUeWTkOxQEV1kYvL5B6U3iWEGCzPNRus1MzJweFqORTj+0jkxozkTSYNJozPOddxmqdqsRpw==", + "integrity": "sha1-q+coH+Rsld3BQ6ZeU1hkd5IDlSA=", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -1587,7 +1587,7 @@ "@babel/plugin-syntax-async-generators": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz", - "integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==", + "integrity": "sha1-aeHw2zTG9aDPfiszI78VmnbIy38=", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" @@ -1596,7 +1596,7 @@ "@babel/plugin-syntax-json-strings": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz", - "integrity": "sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg==", + "integrity": "sha1-cr0T9v/h0lk4Ep0qGGsR/WKVFHA=", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" @@ -1605,7 +1605,7 @@ "@babel/plugin-syntax-object-rest-spread": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", - "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", + "integrity": "sha1-O3o+czUQxX6CC5FCpleayLDfrS4=", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" @@ -1614,7 +1614,7 @@ "@babel/plugin-syntax-optional-catch-binding": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz", - "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", + "integrity": "sha1-qUAT1u2okI3+akd+f57ahWVuz1w=", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" @@ -1632,7 +1632,7 @@ "@babel/plugin-transform-arrow-functions": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz", - "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==", + "integrity": "sha1-mur75Nb/xlY7+Pg3IJFijwB3lVA=", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" @@ -1641,7 +1641,7 @@ "@babel/plugin-transform-async-to-generator": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.2.0.tgz", - "integrity": "sha512-CEHzg4g5UraReozI9D4fblBYABs7IM6UerAVG7EJVrTLC5keh00aEuLUT+O40+mJCEzaXkYfTCUKIyeDfMOFFQ==", + "integrity": "sha1-aLikOGY+iFGeZbd2+JOPNEWxov8=", "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", @@ -1652,7 +1652,7 @@ "@babel/plugin-transform-block-scoped-functions": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz", - "integrity": "sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==", + "integrity": "sha1-XTzBHo1d3XUqpkyRSNDbbLef0ZA=", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" @@ -1661,7 +1661,7 @@ "@babel/plugin-transform-block-scoping": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.2.0.tgz", - "integrity": "sha512-vDTgf19ZEV6mx35yiPJe4fS02mPQUUcBNwWQSZFXSzTSbsJFQvHt7DqyS3LK8oOWALFOsJ+8bbqBgkirZteD5Q==", + "integrity": "sha1-8XxJ2R7tvN9d1QWX0W9fL3cBMtQ=", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -1766,7 +1766,7 @@ "@babel/plugin-transform-computed-properties": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz", - "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==", + "integrity": "sha1-g6ffamWIZbHI9kHVEMbzryICFto=", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" @@ -1775,7 +1775,7 @@ "@babel/plugin-transform-destructuring": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.2.0.tgz", - "integrity": "sha512-coVO2Ayv7g0qdDbrNiadE4bU7lvCd9H539m2gMknyVjjMdwF/iCOM7R+E8PkntoqLkltO0rk+3axhpp/0v68VQ==", + "integrity": "sha1-51JptLeInsOjMs0NDIz/j+0NxvM=", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" @@ -1784,7 +1784,7 @@ "@babel/plugin-transform-dotall-regex": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.2.0.tgz", - "integrity": "sha512-sKxnyHfizweTgKZf7XsXu/CNupKhzijptfTM+bozonIuyVrLWVUvYjE2bhuSBML8VQeMxq4Mm63Q9qvcvUcciQ==", + "integrity": "sha1-8Kq7k9EgqKxh6SXqC6RAgS2+Dkk=", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -1795,7 +1795,7 @@ "@babel/plugin-transform-duplicate-keys": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz", - "integrity": "sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw==", + "integrity": "sha1-2VLEkw8xKk2//xjwspFOYMNVMLM=", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" @@ -1804,7 +1804,7 @@ "@babel/plugin-transform-exponentiation-operator": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz", - "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==", + "integrity": "sha1-pjhoKJ5bQAf3BU1GSRr1FDV2YAg=", "dev": true, "requires": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0", @@ -1814,7 +1814,7 @@ "@babel/plugin-transform-for-of": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.2.0.tgz", - "integrity": "sha512-Kz7Mt0SsV2tQk6jG5bBv5phVbkd0gd27SgYD4hH1aLMJRchM0dzHaXvrWhVZ+WxAlDoAKZ7Uy3jVTW2mKXQ1WQ==", + "integrity": "sha1-q3RovvqA92S7A9PLXu+MyZjhytk=", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" @@ -1823,7 +1823,7 @@ "@babel/plugin-transform-function-name": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.2.0.tgz", - "integrity": "sha512-kWgksow9lHdvBC2Z4mxTsvc7YdY7w/V6B2vy9cTIPtLEE9NhwoWivaxdNM/S37elu5bqlLP/qOY906LukO9lkQ==", + "integrity": "sha1-95MDYoKf+ZoxdMOfCvzAJO9Zcxo=", "dev": true, "requires": { "@babel/helper-function-name": "^7.1.0", @@ -1903,7 +1903,7 @@ "@babel/plugin-transform-literals": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz", - "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==", + "integrity": "sha1-aQNT6B+SZ9rU/Yz9d+r6hqulPqE=", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" @@ -1912,7 +1912,7 @@ "@babel/plugin-transform-modules-amd": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz", - "integrity": "sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw==", + "integrity": "sha1-gqm85FuVRB9heiQBHcidEtp/TuY=", "dev": true, "requires": { "@babel/helper-module-transforms": "^7.1.0", @@ -1922,7 +1922,7 @@ "@babel/plugin-transform-modules-commonjs": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.2.0.tgz", - "integrity": "sha512-V6y0uaUQrQPXUrmj+hgnks8va2L0zcZymeU7TtWEgdRLNkceafKXEduv7QzgQAE4lT+suwooG9dC7LFhdRAbVQ==", + "integrity": "sha1-xPGTP1mR1RRenPrR39hI6hcn9AQ=", "dev": true, "requires": { "@babel/helper-module-transforms": "^7.1.0", @@ -1933,7 +1933,7 @@ "@babel/plugin-transform-modules-systemjs": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.2.0.tgz", - "integrity": "sha512-aYJwpAhoK9a+1+O625WIjvMY11wkB/ok0WClVwmeo3mCjcNRjt+/8gHWrB5i+00mUju0gWsBkQnPpdvQ7PImmQ==", + "integrity": "sha1-kSv+nl/5gpJMgdCTfJLSSZS7kGg=", "dev": true, "requires": { "@babel/helper-hoist-variables": "^7.0.0", @@ -1943,7 +1943,7 @@ "@babel/plugin-transform-modules-umd": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz", - "integrity": "sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw==", + "integrity": "sha1-dnjOdRafCHe46yI1U4wHQmjdAa4=", "dev": true, "requires": { "@babel/helper-module-transforms": "^7.1.0", @@ -1962,7 +1962,7 @@ "@babel/plugin-transform-new-target": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0.tgz", - "integrity": "sha512-yin069FYjah+LbqfGeTfzIBODex/e++Yfa0rH0fpfam9uTbuEeEOx5GLGr210ggOV77mVRNoeqSYqeuaqSzVSw==", + "integrity": "sha1-ro+9iVF/p4ktIOZWTmQeh3DDqko=", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" @@ -1971,7 +1971,7 @@ "@babel/plugin-transform-object-super": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz", - "integrity": "sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg==", + "integrity": "sha1-s11MEPVrq11lAEfa0PHY6IFLZZg=", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -1981,7 +1981,7 @@ "@babel/plugin-transform-parameters": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.2.0.tgz", - "integrity": "sha512-kB9+hhUidIgUoBQ0MsxMewhzr8i60nMa2KgeJKQWYrqQpqcBYtnpR+JgkadZVZoaEZ/eKu9mclFaVwhRpLNSzA==", + "integrity": "sha1-DVrRXcgF4uqGbfTdZoK/520UCMI=", "dev": true, "requires": { "@babel/helper-call-delegate": "^7.1.0", @@ -2014,7 +2014,7 @@ "@babel/plugin-transform-regenerator": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0.tgz", - "integrity": "sha512-sj2qzsEx8KDVv1QuJc/dEfilkg3RRPvPYx/VnKLtItVQRWt1Wqf5eVCOLZm29CiGFfYYsA3VPjfizTCV0S0Dlw==", + "integrity": "sha1-W0Foa07UC++HTX7WqEvdhJwT4ME=", "dev": true, "requires": { "regenerator-transform": "^0.13.3" @@ -2023,7 +2023,7 @@ "@babel/plugin-transform-shorthand-properties": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz", - "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==", + "integrity": "sha1-YzOu4vjW7n4oYVRXKYk0o7RhmPA=", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" @@ -2041,7 +2041,7 @@ "@babel/plugin-transform-sticky-regex": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz", - "integrity": "sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==", + "integrity": "sha1-oeRUtZlVYKnB4NU338FQYf0mh+E=", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -2051,7 +2051,7 @@ "@babel/plugin-transform-template-literals": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.2.0.tgz", - "integrity": "sha512-FkPix00J9A/XWXv4VoKJBMeSkyY9x/TqIh76wzcdfl57RJJcf8CehQ08uwfhCDNtRQYtHQKBTwKZDEyjE13Lwg==", + "integrity": "sha1-2H7QG46qx6kkc/YIyXwIneK6Hls=", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.0.0", @@ -2061,7 +2061,7 @@ "@babel/plugin-transform-typeof-symbol": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz", - "integrity": "sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw==", + "integrity": "sha1-EX0rzsL79ktLWdH5gZiUaC0p8rI=", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" @@ -2080,7 +2080,7 @@ "@babel/plugin-transform-unicode-regex": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.2.0.tgz", - "integrity": "sha512-m48Y0lMhrbXEJnVUaYly29jRXbQ3ksxPrS1Tg8t+MHqzXhtBYAvI51euOBaoAlZLPHsieY9XPVMf80a5x0cPcA==", + "integrity": "sha1-TrjbFvly+Ku1BiwWG4sRVUat4Is=", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -2163,7 +2163,7 @@ "@babel/preset-typescript": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.1.0.tgz", - "integrity": "sha512-LYveByuF9AOM8WrsNne5+N79k1YxjNB6gmpCQsnuSBAcV8QUeB+ZUxQzL7Rz7HksPbahymKkq2qBR+o36ggFZA==", + "integrity": "sha1-Sa1uIIT/C/tfH3+ztedsQ01ELH8=", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -2309,12 +2309,12 @@ "@protobufjs/base64": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + "integrity": "sha1-TIVzDlm5ofHzSQR9vyQpYDS7JzU=" }, "@protobufjs/codegen": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + "integrity": "sha1-fvN/DQEPsCitGtWXIuUG2SYoFcs=" }, "@protobufjs/eventemitter": { "version": "1.1.0", @@ -2358,7 +2358,7 @@ "@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==", + "integrity": "sha1-w0vsEVz8dG4E/loFnfTOfns5FXU=", "requires": { "@types/node": "*" } @@ -2394,7 +2394,7 @@ "@types/connect": { "version": "3.4.32", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz", - "integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==", + "integrity": "sha1-qg6WFrlDXMrQK8UrW0VP/Cxwuig=", "requires": { "@types/node": "*" } @@ -2420,7 +2420,7 @@ "@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==", + "integrity": "sha1-UJkadZopwLiUknUQCMavenyCZ7A=", "requires": { "@types/express": "*" } @@ -2428,7 +2428,7 @@ "@types/events": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", - "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==" + "integrity": "sha1-gaZzHOTfQ2GeXIyUU4Oz5iqJ6oY=" }, "@types/express": { "version": "4.11.1", @@ -2486,12 +2486,12 @@ "@types/long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz", - "integrity": "sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q==" + "integrity": "sha1-cZVR0jUtMBrIuB23Mqy2vcKNve8=" }, "@types/mime": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.0.tgz", - "integrity": "sha512-A2TAGbTFdBw9azHbpVd+/FkdW2T6msN1uct1O9bH3vTerEHKZhTXJUQXy+hNq1B0RagfU8U+KBdqiZpxjhOUQA==" + "integrity": "sha1-WnMG42fFObn2VDSZ3o3VGfrDeos=" }, "@types/node": { "version": "10.12.18", @@ -2541,7 +2541,7 @@ "@types/ws": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.1.tgz", - "integrity": "sha512-EzH8k1gyZ4xih/MaZTXwT2xOkPiIMSrhQ9b8wrlX88L0T02eYsddatQlwVFlEPyEqV0ChpdpNnE51QPH6NVT4Q==", + "integrity": "sha1-yno/N1aqEvYqCmIUXtFMbbJdWig=", "requires": { "@types/events": "*", "@types/node": "*" @@ -2573,7 +2573,7 @@ "@webassemblyjs/helper-buffer": { "version": "1.7.11", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", + "integrity": "sha1-MSLUjcxslFbtmC3r4WyPNxAd85s=", "dev": true }, "@webassemblyjs/helper-code-frame": { @@ -2606,7 +2606,7 @@ "@webassemblyjs/helper-wasm-section": { "version": "1.7.11", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", + "integrity": "sha1-nJrEHs+fvP/8lvbSZ14t4zgR5oo=", "dev": true, "requires": { "@webassemblyjs/ast": "1.7.11", @@ -2618,7 +2618,7 @@ "@webassemblyjs/ieee754": { "version": "1.7.11", "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", + "integrity": "sha1-yVg562N1ejGICq7HtlEtQZGsZAs=", "dev": true, "requires": { "@xtuc/ieee754": "^1.2.0" @@ -2627,7 +2627,7 @@ "@webassemblyjs/leb128": { "version": "1.7.11", "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", + "integrity": "sha1-1yZ6HunEWU/T9+NymIGOxlaH22M=", "dev": true, "requires": { "@xtuc/long": "4.2.1" @@ -2636,13 +2636,13 @@ "@webassemblyjs/utf8": { "version": "1.7.11", "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", + "integrity": "sha1-Btchjqn9yUpnk6qSIIFg2z0m7oI=", "dev": true }, "@webassemblyjs/wasm-edit": { "version": "1.7.11", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", + "integrity": "sha1-jHTKR01PlR0B266b1wgU7iKoIAU=", "dev": true, "requires": { "@webassemblyjs/ast": "1.7.11", @@ -2658,7 +2658,7 @@ "@webassemblyjs/wasm-gen": { "version": "1.7.11", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", + "integrity": "sha1-m7upQvIjdWhqb7dZr816ycRdoag=", "dev": true, "requires": { "@webassemblyjs/ast": "1.7.11", @@ -2671,7 +2671,7 @@ "@webassemblyjs/wasm-opt": { "version": "1.7.11", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", + "integrity": "sha1-szHo5874+OLwB9QsOjagWAp9bKc=", "dev": true, "requires": { "@webassemblyjs/ast": "1.7.11", @@ -2683,7 +2683,7 @@ "@webassemblyjs/wasm-parser": { "version": "1.7.11", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", + "integrity": "sha1-bj0g+mo1GfawhO+Tka1YIR77Cho=", "dev": true, "requires": { "@webassemblyjs/ast": "1.7.11", @@ -2722,7 +2722,7 @@ "@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "integrity": "sha1-7vAUoxRa5Hehy8AM0eVSM23Ot5A=", "dev": true }, "@xtuc/long": { @@ -2734,7 +2734,7 @@ "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "integrity": "sha1-+PLIh60Qv2f2NPAFtph/7TF5qsg=", "dev": true }, "accepts": { @@ -2792,7 +2792,7 @@ "ajv-errors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "integrity": "sha1-81mGrOuRr63sQQL72FAUlQzvpk0=", "dev": true }, "ajv-keywords": { @@ -2861,7 +2861,7 @@ "anymatch": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "integrity": "sha1-vLJLTzeTTZqnrBe0ra+J58du8us=", "dev": true, "requires": { "micromatch": "^3.1.4", @@ -3181,7 +3181,7 @@ "apollo-server-env": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-2.2.0.tgz", - "integrity": "sha512-wjJiI5nQWPBpNmpiLP389Ezpstp71szS6DHAeTgYLb/ulCw3CTuuA+0/E1bsThVWiQaDeHZE0sE3yI8q2zrYiA==", + "integrity": "sha1-Xuxdv0ZYH2Y/1mkrLgXH6K5tYDQ=", "requires": { "node-fetch": "^2.1.2", "util.promisify": "^1.0.0" @@ -3190,7 +3190,7 @@ "apollo-server-errors": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-2.2.0.tgz", - "integrity": "sha512-gV9EZG2tovFtT1cLuCTavnJu2DaKxnXPRNGSTo+SDI6IAk6cdzyW0Gje5N2+3LybI0Wq5KAbW6VLei31S4MWmg==" + "integrity": "sha1-W0UqHW/3ZEDrDxJ1EdxYAxqPPLU=" }, "apollo-server-express": { "version": "2.3.2", @@ -3286,7 +3286,7 @@ "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + "integrity": "sha1-aALmJk79GMeQobDVF/DyYnvyyUo=" }, "argparse": { "version": "1.0.10", @@ -3382,7 +3382,7 @@ "asn1.js": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "integrity": "sha1-ucK/WAXx5kqt7tbfOiv6+1pz9aA=", "dev": true, "requires": { "bn.js": "^4.0.0", @@ -3424,7 +3424,7 @@ "assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "integrity": "sha1-5gtrDo8wG9l+U3UhW9pAbIURjAs=", "dev": true }, "assign-symbols": { @@ -3452,12 +3452,12 @@ "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==" + "integrity": "sha1-ePrtjD0HSrgfIrTphdeehzj3IPg=" }, "async-retry": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.2.3.tgz", - "integrity": "sha512-tfDb02Th6CE6pJUF2gjW5ZVjsgwlucVXOEQMvEX9JgSJMs9gAX+Nz3xRuJBKuUYjTSYORqvDBORdAQ3LU59g7Q==", + "integrity": "sha1-plIfM4NY0yKxoAEreQMMb0EdHOA=", "requires": { "retry": "0.12.0" } @@ -3637,7 +3637,7 @@ "base64-js": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", - "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", + "integrity": "sha1-yrHmEY8FEJXli1KBrqjBzSK/wOM=", "dev": true }, "basic-auth": { @@ -3668,7 +3668,7 @@ "binary-extensions": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", - "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==", + "integrity": "sha1-wteA9T1Fu6gxeokC1M7q86Y4WxQ=", "dev": true }, "bluebird": { @@ -3679,7 +3679,7 @@ "bn.js": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "integrity": "sha1-LN4J617jQfSEdGuwMJsyU7GxRC8=", "dev": true }, "body-parser": { @@ -3752,7 +3752,7 @@ "boxen": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", - "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", + "integrity": "sha1-VcbDmouljZxhrSLNh3Uy3rZlogs=", "dev": true, "requires": { "ansi-align": "^2.0.0", @@ -3814,13 +3814,13 @@ "browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "integrity": "sha1-uqVZ7hTO1zRSIputcyZGfGH6vWA=", "dev": true }, "browserify-aes": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "integrity": "sha1-Mmc0ZC9APavDADIJhTu3CtQo70g=", "dev": true, "requires": { "buffer-xor": "^1.0.3", @@ -3834,7 +3834,7 @@ "browserify-cipher": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "integrity": "sha1-jWR0wbhwv9q807z8wZNKEOlPFfA=", "dev": true, "requires": { "browserify-aes": "^1.0.4", @@ -3845,7 +3845,7 @@ "browserify-des": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "integrity": "sha1-OvTx9Zg5QDVy8cZiBDdfen9wPpw=", "dev": true, "requires": { "cipher-base": "^1.0.1", @@ -3890,7 +3890,7 @@ "browserify-zlib": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "integrity": "sha1-KGlFnZqjviRf6P4sofRuLn9U1z8=", "dev": true, "requires": { "pako": "~1.0.5" @@ -3932,7 +3932,7 @@ "buffer-writer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", - "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==" + "integrity": "sha1-zn64Gjj3gp2wnIc/L7t5LAyY7AQ=" }, "buffer-xor": { "version": "1.0.3", @@ -4054,7 +4054,7 @@ "capture-stack-trace": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", - "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==", + "integrity": "sha1-psC74fOPOqC5Ijjstv9Cw0TUE10=", "dev": true }, "catharsis": { @@ -4078,7 +4078,7 @@ "chai": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "integrity": "sha1-dgqnLPION5XoSxKHfODoNzeqKeU=", "dev": true, "requires": { "assertion-error": "^1.1.0", @@ -4153,7 +4153,7 @@ "chokidar": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "integrity": "sha1-NW/04rDo5D4yLRijckYLvPOszSY=", "dev": true, "requires": { "anymatch": "^2.0.0", @@ -4179,7 +4179,7 @@ "chrome-trace-event": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz", - "integrity": "sha512-xDbVgyfDTT2piup/h8dK/y4QZfJRSa73bw1WZ8b4XM1o7fsFubUVGYcE+1ANtOzJJELGpYoG2961z0Z6OAld9A==", + "integrity": "sha1-Rakb0sIMlBHwljtarrmhuV4JzEg=", "dev": true, "requires": { "tslib": "^1.9.0" @@ -4188,13 +4188,13 @@ "ci-info": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", - "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "integrity": "sha1-LKINu5zrMtRSSmgzAzE/AwSx5Jc=", "dev": true }, "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "integrity": "sha1-h2Dk7MJy9MNjUy+SbYdKriwTl94=", "dev": true, "requires": { "inherits": "^2.0.1", @@ -4466,7 +4466,7 @@ "configstore": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", - "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "integrity": "sha1-xvJd767vJt8S3TNBSwAf6BpUP48=", "dev": true, "requires": { "dot-prop": "^4.1.0", @@ -4577,7 +4577,7 @@ "copy-concurrently": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "integrity": "sha1-kilzmMrjSTf8r9bsgTnBgFHwteA=", "requires": { "aproba": "^1.1.1", "fs-write-stream-atomic": "^1.0.8", @@ -4595,7 +4595,7 @@ "copy-webpack-plugin": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.6.0.tgz", - "integrity": "sha512-Y+SQCF+0NoWQryez2zXn5J5knmr9z/9qSQt7fbL78u83rxmigOy8X5+BFn8CFSuX+nKT8gpYwJX68ekqtQt6ZA==", + "integrity": "sha1-5/QN2KaEd9QF3Rt6hUquMksVi64=", "requires": { "cacache": "^10.0.4", "find-cache-dir": "^1.0.0", @@ -4620,7 +4620,7 @@ "cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "integrity": "sha1-6sEdpRWS3Ya58G9uesKTs9+HXSk=", "requires": { "object-assign": "^4", "vary": "^1" @@ -4634,7 +4634,7 @@ "create-ecdh": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "integrity": "sha1-yREbbzMEXEaX8UR4f5JUzcd8Rf8=", "dev": true, "requires": { "bn.js": "^4.1.0", @@ -4653,7 +4653,7 @@ "create-hash": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "integrity": "sha1-iJB4rxGmN1a8+1m9IhmWvjqe8ZY=", "dev": true, "requires": { "cipher-base": "^1.0.1", @@ -4666,7 +4666,7 @@ "create-hmac": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "integrity": "sha1-aRcMeLOrlXFHsriwRXLkfq0iQ/8=", "dev": true, "requires": { "cipher-base": "^1.0.3", @@ -4709,7 +4709,7 @@ "crypto-browserify": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "integrity": "sha1-OWz58xN/A+S45TLFj2mCVOAPgOw=", "dev": true, "requires": { "browserify-cipher": "^1.0.0", @@ -4790,7 +4790,7 @@ "deep-eql": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "integrity": "sha1-38lARACtHI/gI+faHfHBR8S0RN8=", "dev": true, "requires": { "type-detect": "^4.0.0" @@ -4816,7 +4816,7 @@ "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==", + "integrity": "sha1-z4jabL7ib+bbcJT2HYcMvYTO6fE=", "requires": { "object-keys": "^1.0.12" } @@ -4904,13 +4904,13 @@ "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "integrity": "sha1-gAwN0eCov7yVg1wgKtIg/jF+WhI=", "dev": true }, "diffie-hellman": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "integrity": "sha1-QOjumPVaIUlgcUaSHGPhrl89KHU=", "dev": true, "requires": { "bn.js": "^4.1.0", @@ -4921,7 +4921,7 @@ "dir-glob": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz", - "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==", + "integrity": "sha1-CyBdK2rvmCOMooZZioIE0p0KADQ=", "requires": { "arrify": "^1.0.1", "path-type": "^3.0.0" @@ -4969,7 +4969,7 @@ "domain-browser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "integrity": "sha1-PTH1AZGmdJ3RN1p/Ui6CPULlTto=", "dev": true }, "dot-case": { @@ -4984,7 +4984,7 @@ "dot-prop": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", - "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "integrity": "sha1-HxngwuGqDjJ5fEl5nyg3rGr2nFc=", "dev": true, "requires": { "is-obj": "^1.0.0" @@ -4993,7 +4993,7 @@ "dotenv": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz", - "integrity": "sha1-lBwEEFNdlCyL7PKNPzV9vZ1HYGQ=" + "integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==" }, "dtrace-provider": { "version": "0.8.6", @@ -5043,7 +5043,7 @@ "elliptic": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", - "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "integrity": "sha1-wtC3d2kRuGcixjLDwGxg8vgZk5o=", "dev": true, "requires": { "bn.js": "^4.4.0", @@ -5076,7 +5076,7 @@ "end-of-stream": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "integrity": "sha1-7SljTRm6ukY7bOa4CjchPqtx7EM=", "requires": { "once": "^1.4.0" } @@ -5141,7 +5141,7 @@ "es-to-primitive": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", - "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "integrity": "sha1-7fckeAM0VujdqO8J4ArZZQcH83c=", "requires": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -5549,7 +5549,7 @@ "esrecurse": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "integrity": "sha1-AHo7n9vCs7uH5IeeoZyS/b05Qs8=", "dev": true, "requires": { "estraverse": "^4.1.0" @@ -5574,7 +5574,7 @@ "eventemitter3": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", - "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==" + "integrity": "sha1-CQtNbNvWRe0Qv3UNS1QHlC17oWM=" }, "events": { "version": "3.0.0", @@ -5585,7 +5585,7 @@ "evp_bytestokey": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "integrity": "sha1-f8vbGY3HGVlDLv4ThCaE4FJaywI=", "dev": true, "requires": { "md5.js": "^1.3.4", @@ -5695,7 +5695,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "requires": { "ms": "2.0.0" } @@ -5899,7 +5899,7 @@ "figgy-pudding": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", - "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==", + "integrity": "sha1-hiRwESkBxyeg5JWoB0S9W6odZ5A=", "dev": true }, "figures": { @@ -5980,7 +5980,7 @@ "finalhandler": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", - "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "integrity": "sha1-7r9O2EAHnIP0JJA4ydcDAIMBsQU=", "requires": { "debug": "2.6.9", "encodeurl": "~1.0.2", @@ -6082,7 +6082,7 @@ "flush-write-stream": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", - "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==", + "integrity": "sha1-xdWG7zivYJdlC0m8QbVfq7GfNb0=", "requires": { "inherits": "^2.0.1", "readable-stream": "^2.0.4" @@ -6194,8 +6194,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -6238,8 +6237,7 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", @@ -6250,8 +6248,7 @@ "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -6368,8 +6365,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -6381,7 +6377,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -6411,7 +6406,6 @@ "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -6430,7 +6424,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -6524,7 +6517,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -6610,8 +6602,7 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -6647,7 +6638,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -6667,7 +6657,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -6711,14 +6700,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, @@ -6736,7 +6723,7 @@ "fuse.js": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-3.3.0.tgz", - "integrity": "sha512-ESBRkGLWMuVkapqYCcNO1uqMg5qbCKkgb+VS6wsy17Rix0/cMS9kSOZoYkjH8Ko//pgJ/EEGu0GTjk2mjX2LGQ==" + "integrity": "sha1-Hk/hcqYGhyMPtUpcskfrluLn6IU=" }, "get-caller-file": { "version": "1.0.3", @@ -6918,7 +6905,7 @@ "graphql-request": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-1.8.2.tgz", - "integrity": "sha512-dDX2M+VMsxXFCmUX0Vo0TopIZIX4ggzOtiCsThgtrKR4niiaagsGTDIHj3fsOMFETpa064vzovI+4YV4QnMbcg==", + "integrity": "sha1-OY0QrhXFhWdnQb3j/AHVypSPj74=", "dev": true, "requires": { "cross-fetch": "2.2.2" @@ -6927,7 +6914,7 @@ "graphql-subscriptions": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-1.0.0.tgz", - "integrity": "sha512-+ytmryoHF1LVf58NKEaNPRUzYyXplm120ntxfPcgOBC7TnK7Tv/4VRHeh4FAR9iL+O1bqhZs4nkibxQ+OA5cDQ==", + "integrity": "sha1-R1JnaUs71GWvZHfbq0Jjo/YnArg=", "requires": { "iterall": "^1.2.1" } @@ -7001,7 +6988,7 @@ "growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "integrity": "sha1-8nNdwig2dPpnR4sQGBBZNVw2nl4=", "dev": true }, "handlebars": { @@ -7113,7 +7100,7 @@ "hash.js": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "integrity": "sha1-C6vKU46NTuSg+JiNaIZlN6ADz0I=", "dev": true, "requires": { "inherits": "^2.0.3", @@ -7196,7 +7183,7 @@ "ieee754": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", - "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", + "integrity": "sha1-UL8k5bnIu5ivSWTJQc2wkY2ntgs=", "dev": true }, "iferr": { @@ -7467,12 +7454,12 @@ "is-callable": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" + "integrity": "sha1-HhrfIZ4e62hNaR+dagX/DTCiTXU=" }, "is-ci": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", - "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "integrity": "sha1-43ecjuF/zPQoSI9uKBGH8uYyhBw=", "dev": true, "requires": { "ci-info": "^1.5.0" @@ -7696,7 +7683,7 @@ "is-symbol": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", - "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "integrity": "sha1-oFX2rlcZLK7jKeeoYBGLSXqVDzg=", "requires": { "has-symbols": "^1.0.0" } @@ -7846,7 +7833,7 @@ "jsdoc-babel": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/jsdoc-babel/-/jsdoc-babel-0.5.0.tgz", - "integrity": "sha512-PYfTbc3LNTeR8TpZs2M94NLDWqARq0r9gx3SvuziJfmJS7/AeMKvtj0xjzOX0R/4MOVA7/FqQQK7d6U0iEoztQ==", + "integrity": "sha1-che4ggRp/mANzP3uiVZIxqDdSi4=", "dev": true, "requires": { "jsdoc-regex": "^1.0.1", @@ -7897,7 +7884,7 @@ "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "integrity": "sha1-u4Z8+zRQ5pEHwTHRxRS6s9yLyqk=", "dev": true }, "json-schema-traverse": { @@ -7919,7 +7906,7 @@ "jsonwebtoken": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.4.0.tgz", - "integrity": "sha512-coyXjRTCy0pw5WYBpMvWOMN+Kjaik2MwTUIq9cna/W7NpO9E+iYbumZONAz3hcr+tXFJECoQVrtmIoC3Oz0gvg==", + "integrity": "sha1-h1f3tMt0QNhtXi877O+nBTbI5Go=", "requires": { "jws": "^3.1.5", "lodash.includes": "^4.3.0", @@ -8096,7 +8083,7 @@ "jwa": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.1.6.tgz", - "integrity": "sha512-tBO/cf++BUsJkYql/kBbJroKOgHWEigTKBAjjBEmrMGYd1QMBC74Hr4Wo2zCZw6ZrVhlJPvoMrkcOnlWR/DJfw==", + "integrity": "sha1-hyQOdsmAjb3hh4PPImTvSSnuUOY=", "requires": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.10", @@ -8106,7 +8093,7 @@ "jws": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/jws/-/jws-3.1.5.tgz", - "integrity": "sha512-GsCSexFADNQUr8T5HPJvayTjvPIfoyJPtLQBwn5a4WZQchcrPMPMAWcC1AzJVRDKyD6ZPROPAxgv6rfHViO4uQ==", + "integrity": "sha1-gNEtBbKT0ehB58uLTmnlYa3Pg08=", "requires": { "jwa": "^1.1.5", "safe-buffer": "^5.0.1" @@ -8502,7 +8489,7 @@ "long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + "integrity": "sha1-mntxz7fTYaGU6lVSQckvdGjVvyg=" }, "longest": { "version": "1.0.1", @@ -8535,7 +8522,7 @@ "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "integrity": "sha1-b54wtHCE2XGnyCD/FabFFnt0wm8=", "dev": true }, "lru-cache": { @@ -8550,7 +8537,7 @@ "make-dir": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "integrity": "sha1-ecEDO4BRW9bSTsmTPoYMp17ifww=", "requires": { "pify": "^3.0.0" } @@ -8594,7 +8581,7 @@ "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "integrity": "sha1-tdB7jjIW4+J81yjXL3DR5qNCAF8=", "dev": true, "requires": { "hash-base": "^3.0.0", @@ -8605,7 +8592,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=", "dev": true } } @@ -8672,7 +8659,7 @@ "miller-rabin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "integrity": "sha1-8IA1HIZbDcViqEYpZtqlNUPHik0=", "dev": true, "requires": { "bn.js": "^4.0.0", @@ -8706,7 +8693,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==", + "integrity": "sha1-LhlN4ERibUoQ5/f7wAznPoPk1cc=", "dev": true }, "minimalistic-crypto-utils": { @@ -8731,7 +8718,7 @@ "mississippi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-2.0.0.tgz", - "integrity": "sha512-zHo8v+otD1J10j/tC+VNoGK9keCuByhKovAvdn74dmxJl9+mWHnx6EMsDN4lgRoMI/eYo2nchAxniIbUPb5onw==", + "integrity": "sha1-NEKlCPr8KFAEhv7qmUCWduTuWm8=", "requires": { "concat-stream": "^1.5.0", "duplexify": "^3.4.2", @@ -8781,7 +8768,7 @@ "mocha": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", - "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "integrity": "sha1-bYrlCPWRZ/lA8rWzxKYSrlDJCuY=", "dev": true, "requires": { "browser-stdout": "1.3.1", @@ -9127,7 +9114,7 @@ "object-keys": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", - "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==" + "integrity": "sha1-CcU4VTd1dTEMymL1W7M0q/97PtI=" }, "object-path": { "version": "0.11.4", @@ -9278,7 +9265,7 @@ "output-file-sync": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-2.0.1.tgz", - "integrity": "sha512-mDho4qm7WgIXIGf4eYU1RHN2UU5tPfVYVSRwDJw0uTmj35DQUt/eNp19N7v6T3SrR0ESTEf2up2CGO73qI35zQ==", + "integrity": "sha1-9TEYKC9fVTwnmVQXkrcjpMcUMMA=", "dev": true, "requires": { "graceful-fs": "^4.1.11", @@ -9559,7 +9546,7 @@ "path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "integrity": "sha1-zvMdyOCho7sNEFwM2Xzzv0f0428=", "requires": { "pify": "^3.0.0" } @@ -9578,7 +9565,7 @@ "pbkdf2": { "version": "3.0.17", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "integrity": "sha1-l2wgZTBhexTrsyEUI597CTNuk6Y=", "dev": true, "requires": { "create-hash": "^1.1.2", @@ -9662,7 +9649,7 @@ }, "pinkie-promise": { "version": "2.0.1", - "resolved": "http://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "dev": true, "requires": { @@ -9711,7 +9698,7 @@ "postgres-interval": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.1.2.tgz", - "integrity": "sha512-fC3xNHeTskCxL1dC8KOtxXt7YeFmlbTYtn7ul8MkVERuTmf7pI4DrkAxcw3kh1fQ9uz4wQmd03a1mRiXUZChfQ==", + "integrity": "sha1-v3H/kCY18hyyQaAT/EIdgdHbFak=", "requires": { "xtend": "^4.0.0" } @@ -9747,7 +9734,7 @@ "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + "integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o=" }, "progress": { "version": "2.0.3", @@ -9780,7 +9767,7 @@ "protobufjs": { "version": "6.8.8", "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz", - "integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==", + "integrity": "sha1-yLTxKC/XqQ5vWxCe0RyEr4KQjnw=", "requires": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -9826,7 +9813,7 @@ "public-encrypt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "integrity": "sha1-T8ydd6B+SLp1J+fL4N4z0HATMeA=", "dev": true, "requires": { "bn.js": "^4.1.0", @@ -9962,7 +9949,7 @@ "pump": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "integrity": "sha1-Ejma3W5M91Jtlzy8i1zi4pCLOQk=", "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -9971,7 +9958,7 @@ "pumpify": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "integrity": "sha1-NlE74karJ1cLGjdKXOJ4v9dDcM4=", "requires": { "duplexify": "^3.6.0", "inherits": "^2.0.3", @@ -10009,7 +9996,7 @@ "randombytes": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", - "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", + "integrity": "sha1-0wLFIpSFiISKjTAMkytEwkIx2oA=", "dev": true, "requires": { "safe-buffer": "^5.1.0" @@ -10018,7 +10005,7 @@ "randomfill": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "integrity": "sha1-ySGW/IarQr6YPxvzF3giSTHWFFg=", "dev": true, "requires": { "randombytes": "^2.0.5", @@ -10033,7 +10020,7 @@ "rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "integrity": "sha1-zZJL9SAKB1uDwYjNa54hG3/A0+0=", "dev": true, "requires": { "deep-extend": "^0.6.0", @@ -10044,7 +10031,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -10178,7 +10165,7 @@ "readdirp": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "integrity": "sha1-DodiKjMlqjPokihcr4tOhGUppSU=", "dev": true, "requires": { "graceful-fs": "^4.1.11", @@ -10291,13 +10278,13 @@ "regenerate": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "integrity": "sha1-SoVuxLVuQHfFV1icroXnpMiGmhE=", "dev": true }, "regenerate-unicode-properties": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz", - "integrity": "sha512-s5NGghCE4itSlUS+0WUj88G6cfMVMmH8boTPNvABf8od+2dhT9WDlWu8n01raQAJZMOK8Ch6jSexaRO7swd6aw==", + "integrity": "sha1-EHQFr8xKGQ7F7UUOyqAO0Mr6ekw=", "dev": true, "requires": { "regenerate": "^1.4.0" @@ -10311,7 +10298,7 @@ "regenerator-transform": { "version": "0.13.3", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.13.3.tgz", - "integrity": "sha512-5ipTrZFSq5vU2YoGoww4uaRVAK4wyYC4TSICibbfEPOruUu8FFP7ErV0BjmbIOEpn3O/k9na9UEdYR/3m7N6uA==", + "integrity": "sha1-JkvZ/zioziSwbgY2SWsshWtXvLs=", "dev": true, "requires": { "private": "^0.1.6" @@ -10385,7 +10372,7 @@ "regexpu-core": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.4.0.tgz", - "integrity": "sha512-eDDWElbwwI3K0Lo6CqbQbA6FwgtCz4kYTarrri1okfkRLZAqstU+B3voZBCjg8Fl6iq0gXrJG6MvRgLthfvgOA==", + "integrity": "sha1-jUPg0SZog5aXIDRecMJ17grsDTI=", "dev": true, "requires": { "regenerate": "^1.4.0", @@ -10399,7 +10386,7 @@ "registry-auth-token": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", - "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", + "integrity": "sha1-hR/UkDjuy1hpERFa+EUmDuyYPyA=", "dev": true, "requires": { "rc": "^1.1.6", @@ -10418,13 +10405,13 @@ "regjsgen": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz", - "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==", + "integrity": "sha1-p2NNwI+JIJwgSa3aNSVxH7lyZd0=", "dev": true }, "regjsparser": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", - "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", + "integrity": "sha1-8eaui32iuulsmTmbhozWyTOiupw=", "dev": true, "requires": { "jsesc": "~0.5.0" @@ -10572,7 +10559,7 @@ "ripemd160": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "integrity": "sha1-ocGm9iR1FXe6XQeRTLyShQWFiQw=", "dev": true, "requires": { "hash-base": "^3.0.0", @@ -10670,7 +10657,7 @@ "send": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", - "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "integrity": "sha1-bsyh4PjBVtFBWXVZhI32RzCmu8E=", "requires": { "debug": "2.6.9", "depd": "~1.1.2", @@ -10710,7 +10697,7 @@ "serialize-javascript": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.5.0.tgz", - "integrity": "sha512-Ga8c8NjAAp46Br4+0oZ2WxJCwIzwP60Gq1YPgU+39PiTVxyed/iKE/zyZI6+UlVYH5Q4PaQdHhcegIFPZTUfoQ==" + "integrity": "sha1-GqM2FiyIqJDdrVOEuuvJOmVRYf4=" }, "serve-favicon": { "version": "2.5.0", @@ -10734,7 +10721,7 @@ "serve-static": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", - "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "integrity": "sha1-CV6Ecv1bRiN9tQzkhqQ/S4bGzsE=", "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -10782,7 +10769,7 @@ "sha.js": { "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "integrity": "sha1-N6XPC4HsvGlD3hCbopYNGyZYSuc=", "dev": true, "requires": { "inherits": "^2.0.1", @@ -11044,7 +11031,7 @@ "split": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "integrity": "sha1-YFvZvjA6pZ+zX5Ip++oN3snqB9k=", "requires": { "through": "2" } @@ -11066,7 +11053,7 @@ "ssri": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/ssri/-/ssri-5.3.0.tgz", - "integrity": "sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ==", + "integrity": "sha1-ujhyycbTOgcEp9cf8EXl7EiZnQY=", "requires": { "safe-buffer": "^5.1.1" } @@ -11137,7 +11124,7 @@ "stream-http": { "version": "2.8.3", "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "integrity": "sha1-stJCRpKIpaJ+xP6JM6z2I95lFPw=", "dev": true, "requires": { "builtin-status-codes": "^3.0.0", @@ -11165,7 +11152,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "dev": true, "requires": { "safe-buffer": "~5.1.0" @@ -11250,7 +11237,7 @@ "subscriptions-transport-ws": { "version": "0.9.15", "resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.15.tgz", - "integrity": "sha512-f9eBfWdHsePQV67QIX+VRhf++dn1adyC/PZHP6XI5AfKnZ4n0FW+v5omxwdHVpd4xq2ZijaHEcmlQrhBY79ZWQ==", + "integrity": "sha1-aKi3ugA32MSJ+y9aEC0UlNspfQ0=", "requires": { "backo2": "^1.0.2", "eventemitter3": "^3.1.0", @@ -11262,7 +11249,7 @@ "ws": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", - "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "integrity": "sha1-3/7xSGa46NyRM1glFNG++vlumA8=", "requires": { "async-limiter": "~1.0.0" } @@ -11632,7 +11619,7 @@ "through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "integrity": "sha1-AcHjnrMdB8t9A6lqcIIyYLIxMs0=", "requires": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" @@ -11655,7 +11642,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "requires": { "safe-buffer": "~5.1.0" } @@ -11679,7 +11666,7 @@ "timers-browserify": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", - "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", + "integrity": "sha1-HSjj0qrfHVpZlsTp+VYBzQU0gK4=", "dev": true, "requires": { "setimmediate": "^1.0.4" @@ -11772,7 +11759,7 @@ "touch": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "integrity": "sha1-/jZfX3XsntTlaCXgu3bSSrdK+Ds=", "dev": true, "requires": { "nopt": "~1.0.10" @@ -11805,7 +11792,7 @@ "tslib": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "integrity": "sha1-1+TdeSRdhUKMTX5IIqeZF5VMooY=", "dev": true }, "tslint": { @@ -11855,7 +11842,7 @@ "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "integrity": "sha1-dkb7XxiHHPu3dJ5pvTmmOI63RQw=", "dev": true }, "type-is": { @@ -11930,7 +11917,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "requires": { "ms": "2.0.0" @@ -11964,13 +11951,13 @@ "unicode-canonical-property-names-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", - "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "integrity": "sha1-JhmADEyCWADv3YNDr33Zkzy+KBg=", "dev": true }, "unicode-match-property-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", - "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "integrity": "sha1-jtKjJWmWG86SJ9Cc0/+7j+1fAgw=", "dev": true, "requires": { "unicode-canonical-property-names-ecmascript": "^1.0.4", @@ -11980,13 +11967,13 @@ "unicode-match-property-value-ecmascript": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.0.2.tgz", - "integrity": "sha512-Rx7yODZC1L/T8XKo/2kNzVAQaRE88AaMvI1EF/Xnj3GW2wzN6fop9DDWuFAKUVFH7vozkz26DzP0qyWLKLIVPQ==", + "integrity": "sha1-nx3HaSbWzPRSMQVk/YNKzgWWY9Q=", "dev": true }, "unicode-property-aliases-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.4.tgz", - "integrity": "sha512-2WSLa6OdYd2ng8oqiGIWnJqyFArvhn+5vgx5GTxMbUYjCYKUcuKS62YLFF0R/BDGlB1yzXjQOLtPAfHsgirEpg==", + "integrity": "sha1-WlM/MbQxfqdvF9gH+g0RZUYRHdA=", "dev": true }, "union-value": { @@ -12096,13 +12083,13 @@ "upath": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", - "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", + "integrity": "sha1-NSVll+RqWB20eT0M5H+prr/J+r0=", "dev": true }, "update-notifier": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", - "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", + "integrity": "sha1-0HRFk+E/Fh5AassdlAi3LK0Ir/Y=", "dev": true, "requires": { "boxen": "^1.2.1", @@ -12236,7 +12223,7 @@ "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==", + "integrity": "sha1-RA9xZaRZyaFtwUXrjnLzVocJcDA=", "requires": { "define-properties": "^1.1.2", "object.getownpropertydescriptors": "^2.0.3" @@ -12345,7 +12332,7 @@ "watchpack": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", - "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", + "integrity": "sha1-S8EsLr6KonenHx0/FNaFx7RGzQA=", "dev": true, "requires": { "chokidar": "^2.0.2", @@ -12629,7 +12616,7 @@ "webpack-sources": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.3.0.tgz", - "integrity": "sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA==", + "integrity": "sha1-KijcufH0X+lg2PFJMlK17mUw+oU=", "dev": true, "requires": { "source-list-map": "^2.0.0", @@ -12666,7 +12653,7 @@ "widest-line": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", - "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", + "integrity": "sha1-dDh2RzDsfvQ4HOTfgvuYpTFCo/w=", "dev": true, "requires": { "string-width": "^2.1.1" @@ -12712,7 +12699,7 @@ "worker-farm": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz", - "integrity": "sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==", + "integrity": "sha1-rsxAWXb6talVJhgIRvDboojzpKA=", "dev": true, "requires": { "errno": "~0.1.7" diff --git a/src/ldap/export/group.js b/src/ldap/export/group.js new file mode 100644 index 0000000..fc2be13 --- /dev/null +++ b/src/ldap/export/group.js @@ -0,0 +1,453 @@ +"use strict"; +/** + * @file Ce fichier contient la classe de l'API du LDAP qui gère les opérations sur les groupes. Elle est destinée à être exportée pour être utilisée par les resolvers. + * @author hawkspar + */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +var config_1 = require("../internal/config"); +var basics_1 = require("../internal/basics"); +var tools_1 = require("../internal/tools"); +//------------------------------------------------------------------------------------------------------------------------ +// Classes à exporter TBT +//------------------------------------------------------------------------------------------------------------------------ +var Group = /** @class */ (function () { + /** + * @memberof LDAP + * @class Group + * @classdesc Cette classe est une des deux classes exportables permettant de faire des opérations sur les groupes. + * @summary Constructeur vide. + */ + function Group() { + } + /** + * @memberof LDAP + * @summary Fonction qui renvoit toutes les infos relatives à un groupe particulier. + * @desc Cette fonction utilise {@link Tools.peek} avec l'interface {@link groupData}. Elle rajoute les individus + * @arg {string} gid - Identifiant du groupe + * @return {Promise(groupData)} Informations recueillies ; renvoie une liste de dictionnaire avec le profil complet du groupe au format {@link groupData}. + * @static + * @async + */ + Group.peek = function (gid) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + try { + return [2 /*return*/, tools_1.Tools.peek("group", gid, config_1.groupData)]; + } + catch (err) { + throw "Erreur lors d'une recherche d'informations sur un groupe."; + } + return [2 /*return*/]; + }); + }); + }; + /** + * @memberof LDAP + * @summary Fonction qui retrouve le groupe qui ressemblent à l'input et qui correspond au type fourni. Etape 0 vers un vrai TOL (Trombino On Line) pour les groupes. + * @desc Cette fonction utilise {@link Tools.search}. + * @arg {groupData} input - String entré par l'utilisateur qui ressemble au nom du groupe. + * @return {Promise(string[])} Liste des gid dont le nom ressemble à l'input. + * @static + * @async + */ + Group.search = function (data) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + try { + return [2 /*return*/, tools_1.Tools.search("group", data)]; + } + catch (err) { + throw "Erreur lors de la recherche approximative d'un groupe."; + } + return [2 /*return*/]; + }); + }); + }; + /** + * @memberof LDAP + * @summary Fonction qui permet de rajouter un administrateur à un groupe. + * @desc Cette fonction fait essentiellement appel à {@link Tools.add}. Le nouvel administrateur ne devient pas membre ou porte-parole du groupe pour autant ! + * @arg {string} uid - Identifiant du membre futur admin + * @arg {string} gid - Identifiant du groupe + * @return {boolean} `true` si la modification s'est bien déroulée, false sinon + * @async + * @static + */ + Group.addAdmin = function (uid, gid) { + return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, tools_1.Tools.add(uid, gid, "admins")]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); }); + }; + /** + * @memberof LDAP + * @summary Fonction qui permet de supprimer un administrateur. + * @desc Cette fonction fait essentiellement appel à {@link Tools.remove}. + * Elle ne remonte pas les échelons, car cela permettrait à un admin d'un petit groupe de supprimer un admin d'un grand. + * @arg {string} uid - Identifiant de l'admin à dégrader, supposé membre + * @arg {string} gid - Identifiant du groupe + * @return {boolean} `true` si la modification s'est bien déroulée, false sinon + * @async + * @static + */ + Group.remAdmin = function (uid, gid) { + return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { + return [2 /*return*/, tools_1.Tools.remove(uid, gid, "admins")]; + }); }); + }; + /** + * @memberof LDAP + * @summary Fonction qui permet de rajouter un porte-parole à un groupe. + * @desc Cette fonction fait essentiellement appel à {@link Tools.add}. Elle ne rajoute pas l'utilisateur au groupe. + * @arg {string} uid - Identifiant du membre futur porte-parole + * @arg {string} gid - Identifiant du groupe + * @return {boolean} `true` si la modification s'est bien déroulée, false sinon + * @async + * @static + */ + Group.addSpeaker = function (uid, gid) { + return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, tools_1.Tools.add(uid, gid, "speakers")]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); }); + }; + /** + * @memberof LDAP + * @summary Fonction qui permet de rétrograder un membre du stade de porte-parole d'un groupe au stade d'utilisateur. + * @desc Cette fonction fait essentiellement appel à {@link Tools.remove}. Elle dégrade aussi d'un éventuel statut d'administrateur. + * @arg {string} uid - Identifiant de l'admin à dégrader (pas supposé valide) + * @arg {string} gid - Identifiant du groupe + * @return {boolean} `true` si la modification s'est bien déroulée, false sinon + * @async + * @static + */ + Group.remSpeaker = function (uid, gid) { + return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, tools_1.Tools.remove(uid, gid, "speakers")]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); }); + }; + /** + * @memberof LDAP + * @summary Fonction qui permet d'ajouter un utilisateur à un groupe. + * @desc Cette fonction fait essentiellement appel à {@link Tools.add}. + * @arg {string} uid - Identifiant de l'utilisateur à ajouter + * @arg {string} gid - Identifiant du groupe + * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon + * @async + * @static + */ + Group.addMember = function (uid, gid) { + return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { + return [2 /*return*/, tools_1.Tools.add(uid, gid, "members")]; + }); }); + }; + /** + * @memberof LDAP + * @summary Fonction qui permet de supprimer un membre existant d'un groupe. + * @desc Cette fonction fait essentiellement appel à {@link Tools.add}. + * Cette fonction supprime tous les droits de l'utilisateur sur le groupe, mais aussi sur les groupes sources si son statut de membre était hérité. + * @arg {string} uid - Identifiant de l'ex-membre (pas supposé valide) + * @arg {string} gid - Identifiant du groupe + * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon + * @async + * @static + */ + Group.remMember = function (uid, gid) { + return __awaiter(this, void 0, void 0, function () { + var stack, res, visited, cur_id, _a, _b, _c, _d, _e; + return __generator(this, function (_f) { + switch (_f.label) { + case 0: return [4 /*yield*/, tools_1.Tools.remove(uid, gid, "members")]; + case 1: return [2 /*return*/, _f.sent()]; + case 2: + if (!(stack.length > 0)) return [3 /*break*/, 11]; + cur_id = stack.pop(); + if (!(visited[cur_id] == undefined)) return [3 /*break*/, 10]; + visited[cur_id] = true; + _c = res; + if (!_c) return [3 /*break*/, 4]; + return [4 /*yield*/, tools_1.Tools.remove(uid, cur_id, "admins")]; + case 3: + _c = (_f.sent()); + _f.label = 4; + case 4: + _b = _c; + if (!_b) return [3 /*break*/, 6]; + return [4 /*yield*/, tools_1.Tools.remove(uid, cur_id, "speakers")]; + case 5: + _b = (_f.sent()); + _f.label = 6; + case 6: + _a = _b; + if (!_a) return [3 /*break*/, 8]; + return [4 /*yield*/, tools_1.Tools.remove(uid, cur_id, "members")]; + case 7: + _a = (_f.sent()); + _f.label = 8; + case 8: + res = _a; + _e = (_d = stack).concat; + return [4 /*yield*/, basics_1.Basics.searchSingle("group", config_1.ldapConfig.group.childs, cur_id)]; + case 9: + _e.apply(_d, [_f.sent()]); + _f.label = 10; + case 10: return [3 /*break*/, 2]; + case 11: return [2 /*return*/, res]; + } + }); + }); + }; + /** + * @memberof LDAP + * @summary Fonction qui permet d'ajouter un sympathisant à un groupe. + * @desc Cette fonction fait essentiellement appel à {@link Tools.add}. + * @arg {string} uid - Identifiant de l'utilisateur à ajouter + * @arg {string} gid - Identifiant du groupe + * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon + * @async + * @static + */ + Group.addFollower = function (uid, gid) { + return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { + return [2 /*return*/, tools_1.Tools.add(uid, gid, "followers")]; + }); }); + }; + /** + * @memberof LDAP + * @summary Fonction qui permet de supprimer un sympathisant d'un groupe. + * @desc Cette fonction fait essentiellement appel à {@link Tools.add}. + * @arg {string} uid - Identifiant de l'ex-sympathisant (pas supposé valide) + * @arg {string} gid - Identifiant du groupe + * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon + * @async + * @static + */ + Group.remFollower = function (uid, gid) { + return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { + return [2 /*return*/, tools_1.Tools.remove(uid, gid, "followers")]; + }); }); + }; + /** + * @memberof LDAP + * @summary Fonction qui créé un nouveau groupe dans le LDAP. + * @desc Cette fonction fait une utilisation massive d'eval pour anonymiser son code ; c'est mal et cela suppose que beaucoup de soins ont été pris lors de + * l'escape de ses paramètres. Appelle {@link LDAP.add} et {@link LDAP.change}, mais aussi {@link Tools.add} + * pour gérer les groupes du nouvel utilisateur. Cettte application permet de rajouter des utilisateurs à toutes les catégories du groupe. + * @arg {groupData} data - Dictionnaire des informations utilisateurs (voir détail des champs dans ldapConfig.json) + * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon + * @async + * @static + */ + Group.create = function (data) { + return __awaiter(this, void 0, void 0, function () { + var vals, gid, key_att, vals2, _loop_1, cat; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + vals = {}; + // gid de base généré à partir du nom standardisé, pas à partir de l'entrée 'gid' ! + try { + tools_1.Tools.generateReadableId(data['name']).then(function (id) { + vals[config_1.ldapConfig.key_id] = id; + vals[config_1.ldapConfig.group['name']] = id; + }); + } + catch (err) { + throw "Erreur lors de la génération d'un hruid pour créer un nouveau groupe."; + } + gid = vals[config_1.ldapConfig.key_id]; + // Ecriture de toutes les valeurs directement inscrites dans le LDAP + for (key_att in data) { + vals[config_1.ldapConfig.group[key_att]] = data[key_att]; + } + ; + return [4 /*yield*/, basics_1.Basics.add("group", vals)]; + case 1: + // Appel à la fonction de base + if (!(_a.sent())) { + throw "Erreur lors de la création d'une nouvelle feuille dans l'arbre des groupes."; + } + vals2 = {}; + // ?! + vals2[config_1.ldapConfig.group['password']] = "{CRYPT}" + data['password']; + // Génération id aléatoire et test contre le LDAP + try { + tools_1.Tools.generateId(config_1.ldapConfig.group["idNumber"], "group").then(function (id) { vals2[config_1.ldapConfig.group['idNumber']] = id; }); + } + catch (err) { + throw "Erreur lors de la génération d'un id numérique pour créer un nouveau groupe."; + } + // Code root + vals2[config_1.ldapConfig.group['cleanFullName']] = data['name'].replace(':', ';').toLowerCase().normalize('UFD'); + return [4 /*yield*/, basics_1.Basics.change("group", gid, "add", vals2)]; + case 2: + // Inscription des valeurs calculées par effet de bord + if (!(_a.sent())) { + throw "Erreur lors de l'ajout des valeurs intelligentes du nouveau groupe."; + } + ["posixGroup", "brGroup"].forEach(function (cst) { + var vals3 = {}; + vals3[config_1.ldapConfig.group['classes']] = cst; + basics_1.Basics.change("group", gid, "add", vals3).then(function (res) { + if (!res) { + throw "Erreur lors de l'ajout des valeurs constantes du nouveau groupe."; + } + }); + }); + _loop_1 = function (cat) { + data[cat].forEach(function (uid) { + tools_1.Tools.add(uid, gid, cat).then(function (res) { + if (!res) { + throw "Erreur de l'ajout d'un membre au nouveau groupe."; + } + }); + }); + }; + // Utilisation des fonctions adaptées pour assurer la cohérence de l'ensemble + for (cat in config_1.categories) { + _loop_1(cat); + } + return [2 /*return*/, true]; + } + }); + }); + }; + /** + * @memberof LDAP + * @summary Fonction qui supprime un groupe du LDAP. + * @desc Cette fonction commence par gérer les groupes du membre puis le supprime entièrement. A modifier une fois que le LDAP incluerait les groupes administres par une utilisateur. + * Appelle {@link LDAP.clear} bien sûr, mais aussi {@link Tools.remove} pour gérer les groupes de l'utilisateur sortant. + * @arg {string} gid - gid de la victime + * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon + * @async + * @static + */ + Group["delete"] = function (gid) { + return __awaiter(this, void 0, void 0, function () { + var profil, _loop_2, _i, categories_1, cat, err_1; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + _a.trys.push([0, 3, , 4]); + return [4 /*yield*/, Group.peek(gid)]; + case 1: + profil = _a.sent(); + _loop_2 = function (cat) { + profil[config_1.ldapConfig.group[cat]].forEach(function quickPartRemUser(uid) { + return __awaiter(this, void 0, void 0, function () { + var lg; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, tools_1.Tools.get(uid, "user", cat)]; + case 1: + lg = _a.sent(); + if (!lg.includes(gid)) return [3 /*break*/, 3]; + return [4 /*yield*/, basics_1.Basics.change("user", uid, "del", config_1.ldapConfig.user[cat])]; + case 2: + // Supprime tous les groupes + if (!(_a.sent())) { + throw "Erreur lors de la suppression de tous les groupes du membre."; + } + // Les rajoute un par un, sauf pour le groupe supprimé + lg.forEach(function (id) { + if (id != gid) { + tools_1.Tools.add(uid, id, cat).then(function (res) { + if (!res) { + throw "Erreur lors du ré-ajout des autres groupes"; + } + }); + } + }); + _a.label = 3; + case 3: return [2 /*return*/]; + } + }); + }); + }); + }; + for (_i = 0, categories_1 = config_1.categories; _i < categories_1.length; _i++) { + cat = categories_1[_i]; + _loop_2(cat); + } + return [4 /*yield*/, basics_1.Basics.clear("group", gid)]; + case 2: + // Elimination + if (!(_a.sent())) { + throw "Erreur lors de la suppression de la feuille dans l'arbre des groupes."; + } + return [2 /*return*/, true]; + case 3: + err_1 = _a.sent(); + throw "Erreur lors de l'obtention du profil d'un groupe pour le supprimer."; + case 4: return [2 /*return*/]; + } + }); + }); + }; + /** + * @memberof LDAP + * @summary Fonction qui édite un groupe existant dans le LDAP. Sans influence sur ses membres ou admins. + * @desc Appelle {@link Tools.edit}. + * @arg {groupData} data - Dictionnaire des informations du groupe. + * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon + * @async + * @static + */ + Group.edit = function (data) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + try { + return [2 /*return*/, tools_1.Tools.edit("group", data)]; + } + catch (err) { + throw "Erreur lors de la modification d'un groupe."; + } + return [2 /*return*/]; + }); + }); + }; + return Group; +}()); +exports.Group = Group; diff --git a/src/ldap/export/user.js b/src/ldap/export/user.js new file mode 100644 index 0000000..0828e17 --- /dev/null +++ b/src/ldap/export/user.js @@ -0,0 +1,332 @@ +"use strict"; +/** + * @file Ce fichier contient la classe de l'API du LDAP qui gère les opérations sur les groupes. Elle est destinée à être exportée pour être utilisée par les resolvers. + * @author hawkspar + */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +var config_1 = require("../internal/config"); +exports.userData = config_1.userData; +var basics_1 = require("../internal/basics"); +var tools_1 = require("../internal/tools"); +var User = /** @class */ (function () { + /** + * @memberof LDAP + * @class User + * @classdesc Cette classe est une des deux classes exportables permettant de faire des opérations sur les utilisateurs. + * @summary Constructeur vide. + */ + function User() { + } + /** + * @memberof LDAP + * @summary Fonction qui renvoit les infos de base relatives à un utilisateur particulier. + * @desc Cette fonction utilise {@link Tools.peek} avec l'interface {@link userData}. + * @arg {string} uid - Identifiant de l'utilisateur, supposé valide. + * @return {Promise(userData)} Informations recueillies au format {@link userData}. + * @static + * @async + */ + User.peek = function (uid) { + return __awaiter(this, void 0, void 0, function () { + var data, _a, _b, _i, cat, _c, _d, err_1; + return __generator(this, function (_e) { + switch (_e.label) { + case 0: + _e.trys.push([0, 6, , 7]); + return [4 /*yield*/, tools_1.Tools.peek("user", uid, config_1.userData)]; + case 1: + data = _e.sent(); + _a = []; + for (_b in config_1.categories) + _a.push(_b); + _i = 0; + _e.label = 2; + case 2: + if (!(_i < _a.length)) return [3 /*break*/, 5]; + cat = _a[_i]; + _c = data; + _d = cat; + return [4 /*yield*/, basics_1.Basics.searchSingle("group", config_1.ldapConfig.group[cat], "*", config_1.ldapConfig.group[cat] + "=" + uid)]; + case 3: + _c[_d] = _e.sent(); + _e.label = 4; + case 4: + _i++; + return [3 /*break*/, 2]; + case 5: return [2 /*return*/, data]; + case 6: + err_1 = _e.sent(); + throw "Error while peeking a user."; + case 7: return [2 /*return*/]; + } + }); + }); + }; + /** + * @memberof LDAP + * @summary Fonction qui retrouve les uid des paxs validant les critères de recherche. Utiliser {@link User.peek} au cas par cas après pour obtenir les vraies infos. + * @desc Cette fonction utilise {@link Tools.search}. + * @arg {userData} data - Dictionnaire contenant les données nécessaires à la recherche. Les valeurs sont celles entrées par l'utilisateur et sont par hypothèse + * comme des sous-parties compactes des valeurs renvoyées. Tous les champs ci-dessous peuvent être indifféremment des listes (par exemple pour chercher un membre + * de plusieurs groupes) ou des éléments isolés. Si un champ n'est pas pertinent, le mettre à '' ou undefined. + * @return {Promise(string[])} gids des profils qui "match" les critères proposés. + * @static + * @async + */ + User.search = function (data) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + try { + return [2 /*return*/, tools_1.Tools.search("user", data)]; + } + catch (err) { + throw "Erreur lors de la recherche approximative d'un utilisateur."; + } + return [2 /*return*/]; + }); + }); + }; + /** + * @memberof LDAP + * @summary Fonction qui créé un nouvel utilisateur dans le LDAP. + * @desc Appelle {@link LDAP.add} bien sûr, mais aussi {@link Tools.add} pour gérer les groupes du nouvel utilisateur. + * @arg {userData} data - Dictionnaire des informations utilisateurs. Des erreurs peuvent apparaître si tous les champs ne sont pas remplis. + * Cette application permet de rejoindre des groupes en masse pour toute catégorie. + * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon + * @async + * @static + */ + User.create = function (data) { + return __awaiter(this, void 0, void 0, function () { + var vals, uid, key_att, _loop_1, key_att, vals3, _a, _b, err_2, _i, categories_1, cat, _c, _d, gid; + return __generator(this, function (_e) { + switch (_e.label) { + case 0: + vals = {}; + // uid de base généré à partir de nom et prénom, plus potentiellement promo et un offset + // MEF mélange de Promise et de fonction standard + try { + tools_1.Tools.generateUid(data['givenName'], data['lastName'], data['birthdate']).then(function (id) { vals[config_1.ldapConfig.key_id] = id; }); + } + catch (err) { + throw "Erreur lors de la génération d'un hruid pour un nouvel utilisateur."; + } + uid = vals[config_1.ldapConfig.key_id]; + // Génère une erreur si un champ n'est pas rempli + for (key_att in data) { + // Ecriture de toutes les valeurs uniques + if (!Array.isArray(data[key_att])) { + vals[config_1.ldapConfig.user[key_att]] = data[key_att]; + } + } + return [4 /*yield*/, basics_1.Basics.add("user", vals)]; + case 1: + // Appel à la fonction de base + if (!(_e.sent())) { + throw "Erreur de l'ajout de la feuille à l'arbre utilisateur."; + } + _loop_1 = function (key_att) { + // Modifications multiples pour avoir plusieurs champs de même type ; boucle sur les attributs multiples + if (Array.isArray(data[key_att])) { + // On rajoute chaque valeur en entrée + data[key_att].forEach(function (val) { + var vals2 = {}; + vals2[config_1.ldapConfig.user[key_att]] = val; + basics_1.Basics.change("user", uid, "add", vals2).then(function (res) { + if (!res) { + throw "Erreur lors de l'ajout d'une valeur pour un champ à valeurs multiples à la feuille du nouvel utilisateur."; + } + }); + }); + } + }; + for (key_att in data) { + _loop_1(key_att); + } + vals3 = {}; + // ldapConfiguration du mot de passe utilisateur + // Le préfixe {CRYPT} signifie que le mdp est hashé dans OpenLDAP voir : https://www.openldap.org/doc/admin24/security.html + vals3[config_1.ldapConfig.user['password']] = "{CRYPT}" + data['password']; + // Ecriture d'un surnom s'il y a lieu + if ((data['nickname'] != undefined) && (data['nickname'] != '')) { + vals3[config_1.ldapConfig.user['nickname']] = data['nickname']; + } + _e.label = 2; + case 2: + _e.trys.push([2, 4, , 5]); + // Génération id aléatoire unique + _a = vals3; + _b = config_1.ldapConfig.user['id']; + return [4 /*yield*/, tools_1.Tools.generateId(config_1.ldapConfig.user['id'], "user")]; + case 3: + // Génération id aléatoire unique + _a[_b] = _e.sent(); + return [3 /*break*/, 5]; + case 4: + err_2 = _e.sent(); + throw "Erreur lors de la génération d'un id numérique pour un nouvel utilisateur."; + case 5: + // Code root + vals3[config_1.ldapConfig.user['cleanFullName']] = data['fullName'].replace(':', ';').toLowerCase().normalize('UFD'); + return [4 /*yield*/, basics_1.Basics.change("user", uid, "add", vals3)]; + case 6: + // Inscription des valeurs calculées + if (!(_e.sent())) { + throw "Erreur lors de l'ajout des valeurs calculées à la feuille du nouvel utilisateur."; + } + ["posixAccount", "shadowAccount", "brUser"].forEach(function (cst) { + var val3 = {}; + vals3[config_1.ldapConfig.user['class']] = cst; + basics_1.Basics.change("user", uid, "add", vals3).then(function (res) { + if (!res) { + throw "Erreur lors de l'ajout d'une valeur constante à la feuille du nouvel utilisateur."; + } + }); + }); + // Ajout dans les groupes à la catégorie voulue + for (_i = 0, categories_1 = config_1.categories; _i < categories_1.length; _i++) { + cat = categories_1[_i]; + for (_c = 0, _d = data[cat]; _c < _d.length; _c++) { + gid = _d[_c]; + tools_1.Tools.add(uid, gid, cat); + } + } + return [2 /*return*/, true]; + } + }); + }); + }; + //------------------------------------------------------------------------------------------------------------------------ + // Fonctions de suppression TBT + //------------------------------------------------------------------------------------------------------------------------ + /** + * @memberof LDAP + * @summary Fonction qui supprime un utilisateur du LDAP. + * @desc Cette fonction commence par gérer les groupes du membre puis le supprime entièrement. + * Appelle {@link LDAP.clear} bien sûr, mais aussi {@link Tools.remove} pour gérer les groupes de l'utilisateur sortant. + * @arg {string} uid - uid de la victime + * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon + * @async + * @static + */ + User["delete"] = function (uid) { + return __awaiter(this, void 0, void 0, function () { + var profil, _loop_2, _i, categories_2, cat, err_3; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + _a.trys.push([0, 2, , 3]); + return [4 /*yield*/, User.peek(uid)]; + case 1: + profil = _a.sent(); + _loop_2 = function (cat) { + profil[config_1.ldapConfig.user[cat]].forEach(function (gid) { + return __awaiter(this, void 0, void 0, function () { + var lm; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, tools_1.Tools.get(gid, "group", cat)]; + case 1: + lm = _a.sent(); + if (!lm.includes(uid)) return [3 /*break*/, 3]; + return [4 /*yield*/, basics_1.Basics.change("group", gid, "del", config_1.ldapConfig.group[cat])]; + case 2: + // Supprime tous les membres + if (!(_a.sent())) { + throw "Erreur lors de la suppression de tous les membres du groupe."; + } + // Les rajoute un par un, sauf pour le supprimé + lm.forEach(function (id) { + if (id != uid) { + tools_1.Tools.add(id, gid, cat).then(function (res) { + if (!res) { + throw "Erreur lors du ré-ajout d'un autre membre"; + } + }); + } + }); + _a.label = 3; + case 3: return [2 /*return*/]; + } + }); + }); + }); + }; + for (_i = 0, categories_2 = config_1.categories; _i < categories_2.length; _i++) { + cat = categories_2[_i]; + _loop_2(cat); + } + return [3 /*break*/, 3]; + case 2: + err_3 = _a.sent(); + throw "Erreur lors de l'obtention des informations de l'utilisateur à supprimer."; + case 3: + // Elimination + if (!basics_1.Basics.clear("user", uid)) { + throw "Erreur lors de la suppression de l'utilisateur."; + } + return [2 /*return*/, true]; + } + }); + }); + }; + /** + * @memberof LDAP + * @summary Fonction qui édite un utilisateur existant dans le LDAP. + * @desc Appelle simplement {@link Tools.edit}. Sans effet sur les groupes de l'utilisateur concerné. + * @arg {userData} data - Dictionnaire des informations utilisateurs + * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon + * @async + * @static + */ + User.edit = function (data) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + try { + return [2 /*return*/, tools_1.Tools.edit("user", data)]; + } + catch (err) { + throw "Erreur lors de la modification d'un utilisateur."; + } + return [2 /*return*/]; + }); + }); + }; + return User; +}()); +exports.User = User; diff --git a/src/ldap/export/user.ts b/src/ldap/export/user.ts index f3aa03e..0924928 100644 --- a/src/ldap/export/user.ts +++ b/src/ldap/export/user.ts @@ -34,7 +34,7 @@ export class User { static async peek(uid: string) : Promise<userData> { try { let data : userData = await Tools.peek<userData>("user", uid, userData); - for (let cat in categories) { data[cat] = await Basics.searchSingle("group", ldapConfig.group[cat], "*", ldapConfig.group[cat]+"="+uid); } + for (let cat in categories) { data[cat] = await Basics.searchSingle("group", ldapConfig.group.key_id, "*", ldapConfig.group[cat]+"="+uid); } return data; } catch(err) { diff --git a/src/ldap/internal/basics.js b/src/ldap/internal/basics.js new file mode 100644 index 0000000..a0a80e3 --- /dev/null +++ b/src/ldap/internal/basics.js @@ -0,0 +1,330 @@ +"use strict"; +/** + * @file Ce fichier regroupe les fonctions fondamentales aux interactions avec le LDAP. + * C'est ici que tout le filtrage est opéré, au plus bas niveau. + * Toutes les fonctions écrites ici sont asynchrones et renvoient des Promises ce qui nécessite de les appeler avec la synthaxe + * un peu particulière `f(args).then(res => ...)` pour exploiter leur résultat. + * @author hawkspar + */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +var ldapjs_1 = require("ldapjs"); +// Toutes les entrées utilisateur sont escapées par sécurité +var ldap_escape_1 = require("ldap-escape"); +// Fichier de ldapConfig du ldap +var config_1 = require("./config"); +// Connection au serveur LDAP avec des temps de timeout arbitraires +var client = ldapjs_1["default"].createClient({ url: config_1.ldapConfig.server }); +//------------------------------------------------------------------------------------------------------------------------ +// Fonctions de base agissant sur le LDAP +//------------------------------------------------------------------------------------------------------------------------ +var Basics = /** @class */ (function () { + /** + * @class Basics + * @classdesc Cette classe est la brique de base du fichier tout entier puisqu'elle contient les functions qui agissent directement sur le LDAP. + * @memberof LDAP + * @summary Constructeur vide. + */ + function Basics() { + } + /** + * @memberof LDAP + * @summary Fonction qui sert à s'identifier sur le LDAP. + * @desc Assez important en terme de sécurité, de gestion de conflit, et de droit d'accès. Méthode ldapjs + * (voir [`Client API`](http://ldapjs.org/client.html) méthode bind). + * @arg {string} dn - Nom de domaine ; identifiant de l'utilisateur cherchant à se connecter + * @arg {string} password - Mot de passe de l'utilisateur cherchant à se connecter + * @returns {Promise(boolean)} `true` si l'opération s'est bien déroulée, `false` sinon. + * @static + * @async + */ + Basics.bind = function (dn, password) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + // Escape DN as everywhere in this file, but password is taken as is + client.bind(dn, password, function (res) { + // Gestion erreur + try { + res; + } + catch (err) { + throw "Erreur lors de la connection au LDAP."; + } + }); + // End with a boolean + return [2 /*return*/, true]; + }); + }); + }; + /** + * @memberof LDAP + * @summary Fonction qui sert à s'identifier sur le LDAP avec plein pouvoirs. + * @desc Appelle {@link bind} avec un utilisateur tout puissant. + * @returns {Promise(boolean)} `true` si l'opération s'est bien déroulée, `false` sinon. + * @static + * @async + */ + Basics.adminBind = function () { + return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { + return [2 /*return*/, Basics.bind(config_1.credentialsLdapConfig.dn, config_1.credentialsLdapConfig.password)]; + }); }); + }; + /** + * @memberof LDAP + * @summary Fonction qui sert à se déconnecter du LDAP. + * @desc Assez important en terme de sécurité, de gestion de conflit, et de droit d'accès. + * Fait appel à {@link Basics.bind} avec deux champs vides. + * @returns {Promise(boolean)} `true` si l'opération s'est bien déroulée, `false` sinon. + * @static + * @async + */ + Basics.unbind = function () { + return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { + return [2 /*return*/, Basics.bind("", "")]; + }); }); + }; + /** + * @callback entryHandler + * @arg entry {*} - Convoluted ldap.js search result object + */ + /** + * @memberof LDAP + * @summary Fonction qui interroge le LDAP selon un protocole spécifié en argument et modifie une liste pour y insérer les valeurs trouvées. + * @desc Cette fonction utilise ldapjs (voir [`Client API`](http://ldapjs.org/client.html) méthode search). Cette fonction fait une demande au LDAP + * qu'elle filtre selon un schéma prédéfini dans `filter` et à chaque résultat (event SearchEntry) le met dans une liste, et renvoit la liste à l'issue (event end). + * @arg {'gr'|'us'} domain - Emplacement de la requête (groupe ou utilisateur) + * @arg {string[]} attributes - Attributs à renvoyer + * @arg {string} id [null] - Identifiant facultatif pour une recherche triviale en o(1) + * @arg {string} filter ["(objectClass=*)"] - Filtre logique de la recherche (format [`RFC2254`](https://tools.ietf.org/search/rfc2254)) déjà passé au ldapEscape + * @arg {entryHandler} handler - Wrapper pour gérer les requêtes simples ou multiples + * @return {void} Utilise handler pour gérer ses résultats au fur et à mesure + * @static + * @async + */ + Basics.search = function (domain, attributes, id, filter, handler) { + Basics.adminBind(); + var dn = ""; + if (id != null) { + dn += config_1.ldapConfig.key_id + '=' + ldap_escape_1["default"].dn("${txt}", { txt: id }) + ','; + } + dn += config_1.ldapConfig.dn[domain]; + // Interrogation LDAP selon filter + var promise = new Promise(function (resolve, reject) { + client.search(dn, { + "scope": "sub", + "filter": filter, + "attributes": attributes + }, function (err, res) { + // Gestion erreur ; pb car pas simple true / autre en sortie + if (err) { + throw "Erreur lors de la recherche sur le LDAP."; + } + else { + // Dès que la recherche renvoit une entrée, on stocke les attributs qui nous intéresse + res.on('searchEntry', function (entry) { handler(entry); }); + // Si la recherche renvoie une erreur, on renvoit + res.on('error', function (resErr) { throw resErr; }); + // Quand la recherche est finie on se déconnecte + res.on('end', function (_) { Basics.unbind(); resolve(); }); + } + }); + }); + return promise; + }; + /** + * @memberof LDAP + * @summary Fonction qui interroge le LDAP selon un protocole spécifié en argument et renvoit une liste de valeurs trouvées. + * @desc Cette fonction utilise {@link LDAP.search} directement. + * @arg {'gr'|'us'} domain - Emplacement de la requête (groupe ou utilisateur) + * @arg {string} attribute - Attribut unique à renvoyer + * @arg {string} id [null] - Identifiant facultatif pour une recherche triviale en o(1) + * @arg {string} filter ["(objectClass=*)"] - Filtre logique de la recherche (format [`RFC2254`](https://tools.ietf.org/search/rfc2254)) déjà passé au ldapEscape + * @return {Promise(string[])} Résultats de la recherche ; soit une liste de valeurs d'attributs, + * soit une liste de dictionnaires si on veut plus d'un attribut (les clés du dictionnaire sont celles du LDAP) + * @static + * @async + */ + Basics.searchSingle = function (domain, attribute, id, filter) { + if (id === void 0) { id = null; } + if (filter === void 0) { filter = "(objectClass=*)"; } + return __awaiter(this, void 0, void 0, function () { + var vals; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + vals = []; + return [4 /*yield*/, Basics.search(domain, [attribute], id, filter, function (entry) { + // Cas un seul attribut où le résultat est une liste directement + vals.push(entry.object[attribute]); + })]; + case 1: + _a.sent(); + return [2 /*return*/, vals]; + } + }); + }); + }; + /** + * @memberof LDAP + * @summary Fonction qui interroge le LDAP selon un protocole spécifié en argument et renvoit les valeurs trouvées. + * @desc Cette fonction utilise ldapjs (voir [`Client API`](http://ldapjs.org/client.html) méthode search). Cette fonction fait une demande au LDAP + * qu'elle filtre selon un schéma prédéfini dans `filter` et à chaque résultat (event SearchEntry) le met dans une liste, et renvoit la liste à l'issue (event end). + * @arg {'gr'|'us'} domain - Emplacement de la requête (groupe ou utilisateur) + * @arg {string[]} attributes - Liste des attributs qui figureront dans le résultat final ; peut aussi être un seul élément + * @arg {string} id [null] - Identifiant facultatif pour une recherche triviale en o(1) + * @arg {string} filter ["(objectClass=*)"] - Filtre logique de la recherche (format [`RFC2254`](https://tools.ietf.org/search/rfc2254)) déjà passé au ldapEscape + * @return {Promise(Array<dic>)} Résultats de la recherche ; soit une liste de valeurs d'attributs, + * soit une liste de dictionnaires si on veut plus d'un attribut (les clés du dictionnaire sont celles du LDAP) + * @static + * @async + */ + Basics.searchMultiple = function (domain, attributes, id, filter) { + if (id === void 0) { id = null; } + if (filter === void 0) { filter = "(objectClass=*)"; } + return __awaiter(this, void 0, void 0, function () { + var vals; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + vals = []; + return [4 /*yield*/, Basics.search(domain, attributes, id, filter, function (entry) { + // Cas plusieurs attributs donc résultat dictionnaire + vals.push({}); + attributes.forEach(function (attribute) { + vals.slice(-1)[0][attribute] = entry.object[attribute]; + }); + })]; + case 1: + _a.sent(); + return [2 /*return*/, vals]; + } + }); + }); + }; + //TBT + /** + * @memberof LDAP + * @summary Fonction qui permet de modifier un élément sur le LDAP. Gestion intelligente de l'appartenance à un binet. + * @desc Cette fonction traite la demande avec ldapjs (voir [`Client API`](http://ldapjs.org/client.html) méthode modify). + * @arg {'gr'|'us'} domain - Emplacement de la requête (groupe ou utilisateur) + * @arg {string} id - Identifiant unique de la feuille à modifier + * @arg {"add"|"del"|"replace"} op - Operation à réaliser sur le LDAP. Trois opération sont possibles ; "add", qui rajoute des attributs et qui peut créer des doublons, + * "del" qui en supprime, et "replace" qui remplace du contenu par un autre. + * @arg {dic} mod - Dictionnaire contenant les attributs à modifier et les nouvelles valeurs des attributs. + * @arg {string} mod[key] - Nouvelle valeur de l'attribut key. Une nouvelle valeur vide ("") est équivalent à la suppression de cet attribut. + * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, `false` sinon. + * @static + * @async + */ + Basics.change = function (domain, id, op, mod) { + return __awaiter(this, void 0, void 0, function () { + var dn; + return __generator(this, function (_a) { + Basics.adminBind(); + dn = config_1.ldapConfig.key_id + '=' + id + ','; + dn += config_1.ldapConfig.dn[domain]; + // Modification LDAP selon dn fourni en argument (pourrait prendre une liste de Changes) + client.modify(ldap_escape_1["default"].dn("${txt}", { txt: dn }), new ldapjs_1["default"].Change({ + operation: op, + modification: mod + }), function (err) { + throw "Erreur lors d'une opération de modification sur le LDAP."; + }); + Basics.unbind(); + return [2 /*return*/, true]; + }); + }); + }; + //TBT + /** + * @memberof LDAP + * @summary Fonction qui permet de rajouter un élément sur le LDAP. + * @desc Cette fonction traite la demande avec ldapjs (voir [`Client API`](http://ldapjs.org/client.html) méthode add). + * @arg {'gr'|'us'} domain - Emplacement de la requête (groupe ou utilisateur) + * @arg {Object.<string, string>} vals - Dictionnaire contenant les valeurs à créer (contient un champ en ldapConfig.key_id) + * @arg {Object} vals[key] - Nouvelle valeur pour le champ key + * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon. + * @static + * @async + */ + Basics.add = function (domain, vals) { + return __awaiter(this, void 0, void 0, function () { + var dn; + return __generator(this, function (_a) { + Basics.adminBind(); + dn = config_1.ldapConfig.key_id + "=" + vals[config_1.ldapConfig.key_id]; + dn += config_1.ldapConfig.dn[domain]; + // Ajout LDAP selon la ldapConfiguration en argument + client.add(ldap_escape_1["default"].dn("${txt}", { txt: dn }), vals, function (err) { + throw "Erreur lors d'une opération d'ajout sur le LDAP."; + }); + Basics.unbind(); + return [2 /*return*/, true]; + }); + }); + }; + //TBT + /** + * @memberof LDAP + * @summary Fonction qui permet de supprimer une feuille du LDAP. + * @desc Cette fonction traite la demande avec ldapjs (voir [`Client API`](http://ldapjs.org/client.html) méthode del). + * Elle est différente de modify avec "del" car elle affecte directement une feuille et pas un attribut. + * @arg {'gr'|'us'} domain - Emplacement de la requête (groupe ou utilisateur) + * @arg {string} id - Identifiant unique de la cible + * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon + * @static + * @async + */ + Basics.clear = function (domain, id) { + return __awaiter(this, void 0, void 0, function () { + var dn; + return __generator(this, function (_a) { + Basics.adminBind(); + dn = config_1.ldapConfig.key_id + '=' + id + ','; + dn += config_1.ldapConfig.dn[domain]; + // Suppression LDAP + client.del(ldap_escape_1["default"].dn("${txt}", { txt: dn }), function (err) { + throw "Erreur lors d'une opération de suppression sur le LDAP."; + }); + Basics.unbind(); + return [2 /*return*/, true]; + }); + }); + }; + return Basics; +}()); +exports.Basics = Basics; diff --git a/src/ldap/internal/config.js b/src/ldap/internal/config.js new file mode 100644 index 0000000..41d8b53 --- /dev/null +++ b/src/ldap/internal/config.js @@ -0,0 +1,86 @@ +"use strict"; +/** + * Namespace qui regroupe toutes les fonctions en rapport avec le LDAP - API et fonctions internes + * @namespace LDAP + * @file Importe la configuration du LDAP au sein de l'application, et remplace certaines valeurs en fonction des variables d'environnement. + * @memberof LDAP + * @author manifold, hawkspar + */ +exports.__esModule = true; +var fs_1 = require("fs"); +var path_1 = require("path"); +var colors_1 = require("colors"); +var dotenv_1 = require("dotenv"); +dotenv_1["default"].config(); +// Point central ; tous les champs de la BDD sont 'cachés' dans config.json et pas visibles directement +var path_config = path_1["default"].resolve(__dirname, '..', '..', '..', 'ldap_config.json'); +console.log(colors_1["default"].cyan("Loading LDAP config file from " + path_config)); +exports.ldapConfig = JSON.parse(fs_1["default"].readFileSync(path_config).toString()); +// Override config server from environment +if (process.env.LDAP_URI != null) { + exports.ldapConfig.server = process.env.LDAP_URI; +} +else { + if (process.env.TARGET_ENV == "production") { + exports.ldapConfig.server = exports.ldapConfig.server_prod; + } + else { + exports.ldapConfig.server = exports.ldapConfig.server_dev; + } +} +// Gestion des super-identifiants +var path_credentials = path_1["default"].resolve(__dirname, '..', '..', '..', 'ldap_credentials.json'); +console.log(colors_1["default"].cyan("Loading LDAP credentials from " + path_credentials)); +exports.credentialsLdapConfig = JSON.parse(fs_1["default"].readFileSync(path_credentials).toString()); +// Data formats and useful constants +exports.categories = ["admins", "speakers", "members", "followers"]; +/** + * @class userData + * @desc Interface avec toutes les données extractables pour un utilisateur. + * @var {string?} uid - Identifiant utilisateur + * @var {string?} password - Mot de passe généré en amont (utilisé seulement à l'initialialisation, pas stocké bien sûr) + * @var {string?} givenName - Prénom + * @var {string?} lastName - Nom + * @var {string?} nickname - Surnom + * @var {string?} gender - Sexe + * @var {string?} photo - Bytestring de la photo de l'utilisateur + * @var {string?} phone - Numéro(s) de téléphone + * @var {string?} address - Adresse(s) + * @var {string?} mail - Adresse(s) courriel + * @var {string?} birthdate - Date d'anniversaire + * @var {string?} nationality - Nationalité d'origine + * @var {string[]?} admins - Liste des gid (group id, inclus section sportive, binet, PA...) dont l'utilisateur est admin ; pas forcément sous-liste de members + * @var {string[]?} speakers - Liste des gid dont l'utilisateur est porte-parole ; pas forcément sous-liste de members + * @var {string[]?} members - Liste des gid dont l'utilisateur est membre + * @var {string[]?} followers - Liste des gid dont l'utilisateur est sympathisant + * @memberof LDAP + */ +var userData = /** @class */ (function () { + function userData() { + } + return userData; +}()); +exports.userData = userData; +/** + * @class groupData + * @var {string} gid - Identifiant du groupe + * @var {string} password - Mot de passe du groupe + * @var {string} name - Nom du groupe (souvent son nom mais pas nécessairement) + * @var {string} logo - Logo du groupe (en bytestring) + * @var {string} description - Description du groupe (script Markdown) + * @var {string} site - Site web du groupe (URL) + * @var {string} category - Statut du groupe ; binet, section sportive... (actuellement juste 'binet' ou 'free') + * @var {string[]} childs - Liste des groupes enfants de première génération de celui-ci + * @var {string[]} parents - Liste des groupes directement parents de celui-ci ; symétrique du précédent + * @var {string[]} admins - Liste des admins du groupe + * @var {string[]} speakers - Liste des porte-parole du groupe + * @var {string[]} members - Liste des membres du groupe + * @var {string[]} followers - Liste des sympathisants du groupe + * @memberof LDAP + */ +var groupData = /** @class */ (function () { + function groupData() { + } + return groupData; +}()); +exports.groupData = groupData; diff --git a/src/ldap/internal/config.ts b/src/ldap/internal/config.ts index 9f6d0d1..79c3b7d 100644 --- a/src/ldap/internal/config.ts +++ b/src/ldap/internal/config.ts @@ -10,7 +10,7 @@ import fs from 'fs'; import path from 'path'; import colors from 'colors'; import dotenv from 'dotenv'; -dotenv.config(); +dotenv.config({ path: path.resolve(__dirname, '..', '..', '..', '.env') }); // Point central ; tous les champs de la BDD sont 'cachés' dans config.json et pas visibles directement let path_config = path.resolve(__dirname, '..', '..', '..', 'ldap_config.json'); diff --git a/src/ldap/internal/tools.js b/src/ldap/internal/tools.js new file mode 100644 index 0000000..a1748de --- /dev/null +++ b/src/ldap/internal/tools.js @@ -0,0 +1,509 @@ +"use strict"; +/** + * @file Ce fichier regroupe les fonctions génériques de recherche et de test utiles, mais trop puissantes pour être exportées directement. + * @author hawkspar + */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +// Toutes les entrées utilisateur sont escapées par sécurité +var ldap_escape_1 = require("ldap-escape"); +// Imports internes +var config_1 = require("./config"); +var basics_1 = require("./basics"); +//------------------------------------------------------------------------------------------------------------------------ +// Fonctions intermédiaires TBT +//------------------------------------------------------------------------------------------------------------------------ +var Tools = /** @class */ (function () { + /** + * @memberof LDAP + * @class Tools + * @classdesc Cette classe contient des fonctions intermédiaires qui ne sont pas destinées à être utilisées dans les resolvers. + * @summary Constructeur vide. + */ + function Tools() { + } + /** + * @memberof LDAP + * @summary Fonction qui renvoit toutes les infos relatives à un groupe ou un utilisateur particulier. + * @desc Cette fonction utilise {@link LDAP.search} avec des attributs prédéfinis. Elle est naïve et n'opère pas de récursion. + * @param T - Format renvoyé (en pratique {@link userData} ou {@link groupData}) + * @arg {string} domain - Domaine de la recherche (utilisateur ou groupe) + * @arg {string} id - Identifiant de la feuille cherchée (uid ou gid) + * @return {Promise(T)} Informations recueillies ; renvoie une liste de dictionnaire avec le profil complet du groupe tel que défini par le paramètre T. + * @static + * @async + */ + Tools.peek = function (domain, id, type) { + return __awaiter(this, void 0, void 0, function () { + var dirtyKeys, cleanData, attr, dirtyData, uncleanKey, _i, _a, cleanKey; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + dirtyKeys = config_1.ldapConfig[domain]; + cleanData = new type(); + attr = Object.keys(dirtyKeys).map(function (key) { return dirtyKeys[key]; }); + return [4 /*yield*/, basics_1.Basics.searchMultiple(domain, attr, id)]; + case 1: + dirtyData = (_b.sent())[0]; + console.log(dirtyData); + console.log(cleanData); + // Rename output + for (uncleanKey in dirtyData) { + for (_i = 0, _a = Object.keys(cleanData); _i < _a.length; _i++) { + cleanKey = _a[_i]; + console.log(cleanKey); + if (uncleanKey == dirtyKeys[cleanKey]) { + cleanData[cleanKey] = dirtyData[uncleanKey]; + } + } + } + return [2 /*return*/, cleanData]; + } + }); + }); + }; + /** + * @memberof LDAP + * @summary Fonction qui retrouve les id des paxs ou groupes validant les critères de recherche. Etape vers vrai TOL (Trombino On Line). + * Utiliser {@link peekUser} au cas par cas après pour obtenir les vraies infos. + * @desc Cette fonction utilise {@link LDAP.search} mais avec un filtre généré à la volée. Accepte des champs exacts ou incomplets pour la plupart des champs + * mais pas approximatifs et ne gère pas l'auto-complete. MEF Timeout pour des recherches trop vagues. Va crasher si un champ n'est pas dans ldapConfig. + * @param T - Format renvoyé (en pratique {@link userData} ou {@link groupData}) + * @arg {"us"|"gr"} domain - Domaine de la recherche (utilisateur ou groupe) + * @arg {userData | groupData} data - Dictionnaire contenant les données nécessaires à la recherche. Les valeurs sont celles entrées par l'utilisateur et sont par hypothèse + * comme des sous-parties compactes des valeurs renvoyées. Tous les champs ci-dessous peuvent être indifféremment des listes (par exemple pour chercher un membre + * de plusieurs groupes) ou des éléments isolés. Si un champ n'est pas pertinent, le mettre à '' ou undefined. + * @return {Promise(string[])} ids des profils qui "match" les critères proposés. + * @static + * @async + */ + Tools.search = function (domain, data) { + return __awaiter(this, void 0, void 0, function () { + var filter, key; + return __generator(this, function (_a) { + filter = ""; + // Iteration pour chaque champ, alourdissement du filtre selon des trucs prédéfinis dans ldapConfig encore + for (key in data) { + if ((data[key] != undefined) && (data[key] != '')) { + if (!Array.isArray(data[key])) { + data[key] = [data[key]]; + } // Génération systématique d'une liste de valeurs à rechercher + // Iteration pour chaque valeur fournie par l'utilisateur + data[key].forEach(function (val) { + // Traduction en language LDAP + var attribute = ""; + attribute = config_1.ldapConfig[domain][key]; + // Escape user input + val = ldap_escape_1["default"].filter("${fil}", { fil: val }); + // Creation incrémentale du filtre + filter = "(&" + filter + "(|(" + attribute + "=" + val + ")" + // On cherche la valeur exacte + "(" + attribute + "=*" + val + ")" + // La valeur finale avec des trucs avant ; wildcard * (MEF la wildcart ne marche pas pour tous les attributs) + "(" + attribute + "=*" + val + "*)" + // La valeur du milieu avec des trucs avant et après + "(" + attribute + "=" + val + "*)))"; // La valeur du début avec des trucs après + }); + } + } + // Appel avec filtre de l'espace + return [2 /*return*/, basics_1.Basics.searchSingle(domain, config_1.ldapConfig.key_id, null, filter)]; + }); + }); + }; + /** + * @memberof LDAP + * @summary Fonction qui édite un groupe ou utilisateur existant dans le LDAP. N'agit pas sur l'apprtenance à un groupe. + * @desc Appelle {@link LDAP.change}. + * @arg {"us"|"gr"} domain - Domaine de l'opération' (utilisateur ou groupe). + * @arg {userData | groupData} data - Dictionnaire avec les nouvelles valeurs de la feuille. + * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon. + * @async + * @static + */ + Tools.edit = function (domain, data) { + return __awaiter(this, void 0, void 0, function () { + var id, id, dirtyKeys, dirtyData; + return __generator(this, function (_a) { + if (domain == "user") { + id = data['uid']; + } + else { + id = data['gid']; + } + dirtyKeys = config_1.ldapConfig[domain]; + dirtyData = {}; + Object.keys(data).forEach(function (key) { + // Some values edit can't change + if (!['readPerm', 'writePerm', 'groups', 'groupsIsAdmin', 'followers', 'members', 'speakers', 'admins'].includes(key)) { + dirtyData[dirtyKeys.key] = data[key]; + } + }); + return [2 /*return*/, basics_1.Basics.change(domain, id, "replace", dirtyData)]; + }); + }); + }; + /** + * @memberof LDAP + * @summary Fonction qui permet d'ajouter un utilisateur à une catégorie d'un groupe. + * @desc Cette fonction fait essentiellement appel à d'autres fonctions de {@link Tools} passées en argument et {@link LDAP.change}. + * Cette fonction ne créé pas de doublon et opère conjointement dans les deux arbres "group" et "user" + * @arg {string} uid - Identifiant du futur membre + * @arg {string} gid - Identifiant du groupe + * @arg {"admins"|"speakers"|"members"|"followers"} category - Categorie de l'utilisateur concerné (admin, speaker, member ou follower) + * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon + * @async + * @static + */ + Tools.add = function (uid, gid, category) { + return __awaiter(this, void 0, void 0, function () { + var lu, catName, err_1, lg, catName, err_2; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + _a.trys.push([0, 4, , 5]); + return [4 /*yield*/, Tools.get(gid, "group", category)]; + case 1: + lu = _a.sent(); + catName = config_1.ldapConfig.group[category]; + if (!!lu.includes(uid)) return [3 /*break*/, 3]; + return [4 /*yield*/, basics_1.Basics.change("group", gid, "add", catName)]; + case 2: + // Ajoute l'utilisateur dans la catégorie concernée + if (!(_a.sent())) { + throw "Erreur lors de la modification dans l'arbre des groupes pour ajouter un membre dans la catégorie voulue."; + } + _a.label = 3; + case 3: return [3 /*break*/, 5]; + case 4: + err_1 = _a.sent(); + throw "Erreur pour obtenir une liste de membres d'une catégorie d'un groupe pour ajouter un membre de cette categorie du groupe."; + case 5: + _a.trys.push([5, 9, , 10]); + return [4 /*yield*/, Tools.get(uid, "user", category)]; + case 6: + lg = _a.sent(); + catName = config_1.ldapConfig.user[category]; + if (!!lg.includes(gid)) return [3 /*break*/, 8]; + return [4 /*yield*/, basics_1.Basics.change("user", uid, "add", catName)]; + case 7: + // Ajoute l'utilisateur dans la categorie voulue + if (!(_a.sent())) { + throw "Erreur lors de l'ajout d'un utilisateur dans une catégorie d'un groupe."; + } + _a.label = 8; + case 8: return [2 /*return*/, true]; + case 9: + err_2 = _a.sent(); + throw "Erreur pour obtenir une liste de groupes d'une categorie d'un membre pour ajouter un groupe de cette category pour le membre."; + case 10: return [2 /*return*/]; + } + }); + }); + }; + /** + * @memberof LDAP + * @summary Fonction qui permet de supprimer un membre d'une catégorie existant d'un groupe. + * @desc Cette fonction fait essentiellement appel à d'autres fonctions de {@link Tools} passées en argument et {@link LDAP.change}. + * @arg {string} uid - Identifiant de l'ex-membre + * @arg {string} gid - Identifiant du groupe + * @arg {"admins"|"speakers"|"members"|"followers"} category - Categorie de l'utilisateur concerné (admin, speaker, member ou follower) + * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon + * @async + * @static + */ + Tools.remove = function (uid, gid, category) { + return __awaiter(this, void 0, void 0, function () { + var lu, catName, err_3, lg, catName, err_4; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + _a.trys.push([0, 4, , 5]); + return [4 /*yield*/, Tools.get(gid, "group", category)]; + case 1: + lu = _a.sent(); + catName = config_1.ldapConfig.group[category]; + if (!lu.includes(uid)) return [3 /*break*/, 3]; + return [4 /*yield*/, basics_1.Basics.change("group", gid, "del", catName)]; + case 2: + // Supprime tous les utilisateurs + if (!(_a.sent())) { + throw "Erreur lors de la suppression de tous les membres d'une catégorie du groupe."; + } + // Les rajoute un par un, sauf pour le supprimé + lu.forEach(function (id) { + if (id != uid) { + Tools.add(id, gid, category).then(function (res) { + if (!res) { + throw "Erreur lors du ré-ajout d'un autre membre d'une catégorie."; + } + }); + } + }); + _a.label = 3; + case 3: return [3 /*break*/, 5]; + case 4: + err_3 = _a.sent(); + throw "Erreur pour obtenir une liste de membres d'une catégorie d'un groupe pour supprimer un membre de cette categorie du groupe."; + case 5: + _a.trys.push([5, 9, , 10]); + return [4 /*yield*/, Tools.get(uid, "user", category)]; + case 6: + lg = _a.sent(); + catName = config_1.ldapConfig.user[category]; + if (!lg.includes(gid)) return [3 /*break*/, 8]; + return [4 /*yield*/, basics_1.Basics.change("user", uid, "del", catName)]; + case 7: + // Supprime tous les groupes de la catégorie pour l'utilisateur + if (!(_a.sent())) { + throw "Erreur lors de la suppression de tous les groupes d'un membre."; + } + // Les rajoute un par un, sauf pour le supprimé + lg.forEach(function (id) { + if (id != uid) { + Tools.add(id, gid, category).then(function (res) { + if (!res) { + throw "Erreur lors du ré-ajout d'un autre groupe."; + } + }); + } + }); + _a.label = 8; + case 8: return [2 /*return*/, true]; + case 9: + err_4 = _a.sent(); + throw "Erreur pour obtenir une liste de groupes d'une categorie d'un membre pour supprimer un groupe de cette category pour le membre."; + case 10: return [2 /*return*/]; + } + }); + }); + }; + /** + * @callback changeValueCallback + * @param {string} id - Id à modifier + * @param {number} n - Nombre d'itérations + * @return {string} Nouveau id + */ + /** + * @memberof LDAP + * @summary Cette fonction teste une valeur d'un attribut (typiquement un identifiant) et le fait évoluer jusqu'à ce qu'il soit unique. + * @desc Librement adapté de Stack Overflow. Appelle {@link LDAP.search} pour vérifier + * qu'il n'y a pas d'autres occurences de cette valeur pour cette attribut + * dans le dn fourni. + * @param {string} value - Valeur de l'attribut (le plus souvent un identifiant) à tester à cette itération + * @param {string} attribute - Attribut à tester + * @param {"gr"|"us"} domain - Domaine dans lequel l'attribut doit être unique + * @param {changeValueCallback} changeValue - Fonction qui prend uniquement en argument l'id courant et + * le nombre d'itérations et qui renvoit la prochaine valeur de l'attribut + * @param {number} n [0] - Nombre d'itérations (à initialiser à 0) + * @return {Promise(string)} Valeur unique dans le domaine spécifié de l'attribut spécifié + * @static + * @async + */ + Tools.ensureUnique = function (value, attribute, domain, changeValue, n) { + if (n === void 0) { n = 0; } + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + // Recherche d'autres occurences de l'id + try { + return [2 /*return*/, basics_1.Basics.searchSingle(domain, config_1.ldapConfig.key_id, null, "(" + attribute + "=" + value + ")").then(function (matches) { + if (!matches) { + throw ""; + } + else if (matches.length = 0) { + return value; + } + else { + return Tools.ensureUnique(changeValue(value, n + 1), attribute, domain, changeValue, n + 1); + } + })]; + } + catch (err) { + throw "Erreur lors de la recherche d'une valeur pour assurer son unicité."; + } + return [2 /*return*/]; + }); + }); + }; + /** + * @memberof LDAP + * @summary Cette fonction génère un uid standard, puis le fait évoluer jusqu'à ce qu'il soit unique. + * @desc Limité à un appel à {@link Tools.ensureUnique} avec les bons paramètres, et quelques opérations sur l'uid pour qu'il soit valide (escape, normalisation). + * @param {string} givenName - Prénom + * @param {string} lastName - Nom + * @param {string} promotion - Année de promotion + * @return {Promise(string)} Valeur unique dans le domaine spécifié de l'attribut spécifié + * @static + * @async + */ + Tools.generateUid = function (givenName, lastName, promotion) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + try { + // normalize et lowerCase standardisent le format + return [2 /*return*/, Tools.ensureUnique((givenName + '.' + lastName).toLowerCase().normalize('UFD'), config_1.ldapConfig.key_id, "user", function (id, n) { + if (n = 1) { + id += '.' + promotion; + } // Si prénom.nom existe déjà , on rajoute la promo + else if (n = 2) { + id += '.' + (n - 1).toString(); + } // Puis si prénom.nom.promo existe déjà on passe à nom.prenom.promo .1 + else if (n > 2) { + id += n; + } // Ensuite on continue .123, .1234, etc... + return id; + })]; + } + catch (err) { + throw "Erreur lors de l'assurance de l'unicité d'un human readable unique identifier (hruid)."; + } + return [2 /*return*/]; + }); + }); + }; + /** + * @memberof LDAP + * @summary Cette fonction génère un id lisible, puis le fait évoluer jusqu'à ce qu'il soit unique. + * @desc Limité à un appel à {@link Tools.ensureUnique} avec les bons paramètres, et quelques opérations sur l'uid pour qu'il soit valide (escape, normalisation). + * @param {string} name - Nom + * @return {Promise(string)} Valeur unique dans le domaine spécifié de l'attribut spécifié + * @static + * @async + */ + Tools.generateReadableId = function (name) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + try { + // normalize et lowerCase standardisent le format + return [2 /*return*/, Tools.ensureUnique(name.toLowerCase().normalize('UFD'), config_1.ldapConfig.key_id, "group", function (id, n) { + if (n = 1) { + id += '.' + n.toString(); + } // Si nom existe déjà , on essaie nom.1 + else if (n > 1) { + id += n.toString(); + } // Ensuite on continue .12, .123, etc... + return id; + })]; + } + catch (err) { + throw "Erreur lors de l'assurance de l'unicité d'un human readable unique identifier (hruid)."; + } + return [2 /*return*/]; + }); + }); + }; + /** + * @memberof LDAP + * @summary Cette fonction teste une valeur dummy (0) pour un identifiant numérique puis le fait évoluer aléatoirement (entre 1 et 100 000) jusqu'à ce qu'il soit unique. + * @param {string} attribut - Intitulé exact de l'id concerné + * @param {"gr"|"us"} domain - Domaine dans lequel l'attribut doit être unique + * @return {Promise(string)} Valeur unique dans le domaine spécifié de l'attribut spécifié + * @static + * @async + */ + Tools.generateId = function (attribut, domain) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + try { + return [2 /*return*/, Tools.ensureUnique("0", attribut, domain, function (id, n) { return Math.floor((Math.random() * 100000) + 1).toString(); })]; + } + catch (err) { + throw "Erreur lors de l'assurance de l'unicité d'un unique identifier numérique."; + } + return [2 /*return*/]; + }); + }); + }; + /** + * @memberof LDAP + * @summary Fonction qui retrouve les utilisateurs ou groupes respectivement correspondant à un groupe ou un utilisateur de la même catégorie. + * @desc Cette fonction utilise {@link LDAP.search} et va directement à la feuille de l'utilisateur ou du groupe interrogé. + * Pour autant, elle est moins naïve qu'elle en a l'air. Elle ne gère ni la descente des admins ni la remontée des membres et renvoit une réponse naïve. + * @param {string} id - Identifiant du groupe ou de l'individu à interroger (supposé valide) + * @param {"user"|"group"} domain - Arbre à interroger + * @param {"admins"|"speakers"|"members"|"followers"} category - Catégorie considérée + * @return {Promise(string[])} Liste des id de groupes ou d'utilisateurs de la bonne catégorie associé à l'id + * @static + * @async + */ + Tools.get = function (id, domain, category) { + return __awaiter(this, void 0, void 0, function () { + var stack, res, visited, cur_id, _a, _b, _c, _d, _e, _f, err_5; + return __generator(this, function (_g) { + switch (_g.label) { + case 0: + _g.trys.push([0, 11, , 12]); + return [4 /*yield*/, basics_1.Basics.searchSingle(domain, config_1.ldapConfig[domain][category], id)]; + case 1: return [2 /*return*/, _g.sent()]; + case 2: return [2 /*return*/, _g.sent()]; + case 3: + stack = []; + res = []; + visited = {}; + stack.push(id); + _g.label = 4; + case 4: + if (!(stack.length > 0)) return [3 /*break*/, 10]; + cur_id = stack.pop(); + if (!(visited[cur_id] == undefined)) return [3 /*break*/, 9]; + visited[cur_id] = true; + _b = (_a = res).concat; + return [4 /*yield*/, basics_1.Basics.searchSingle("group", config_1.ldapConfig.group[category], cur_id)]; + case 5: + _b.apply(_a, [_g.sent()]); + if (!(category == "members")) return [3 /*break*/, 7]; + _d = (_c = stack).concat; + return [4 /*yield*/, basics_1.Basics.searchSingle("group", config_1.ldapConfig.group.childs, cur_id)]; + case 6: + _d.apply(_c, [_g.sent()]); + return [3 /*break*/, 9]; + case 7: + _f = (_e = stack).concat; + return [4 /*yield*/, basics_1.Basics.searchSingle("group", config_1.ldapConfig.group.parents, cur_id)]; + case 8: + _f.apply(_e, [_g.sent()]); + _g.label = 9; + case 9: return [3 /*break*/, 4]; + case 10: return [3 /*break*/, 12]; + case 11: + err_5 = _g.sent(); + throw "Erreur lors d'une recherche générique d'un membre d'une certaine catégorie d'un groupe."; + case 12: return [2 /*return*/]; + } + }); + }); + }; + return Tools; +}()); +exports.Tools = Tools; diff --git a/src/ldap/test.js b/src/ldap/test.js new file mode 100644 index 0000000..5b8f1d1 --- /dev/null +++ b/src/ldap/test.js @@ -0,0 +1,5 @@ +var Group = require("./export/group"); + +console.log(Group.peek("faerix")); + +var User = require("./export/group"); \ No newline at end of file -- GitLab