From 1138b06eaad457e3a82c2bc761a7bb7f72df28e9 Mon Sep 17 00:00:00 2001 From: Nelson Pereira Date: Wed, 16 May 2018 19:27:55 +0100 Subject: [PATCH 01/21] working on adding shibboleth to Dendro --- src/bootup/models/shibboleth/shibboleth.js | 36 ++++++++++ src/bootup/routes/load_logic_routes.js | 79 ++++++++++++++++++++++ src/views/auth/login.ejs | 4 ++ 3 files changed, 119 insertions(+) create mode 100644 src/bootup/models/shibboleth/shibboleth.js diff --git a/src/bootup/models/shibboleth/shibboleth.js b/src/bootup/models/shibboleth/shibboleth.js new file mode 100644 index 00000000..926b9919 --- /dev/null +++ b/src/bootup/models/shibboleth/shibboleth.js @@ -0,0 +1,36 @@ +const slug = require("slug"); +const path = require("path"); + +const Pathfinder = global.Pathfinder; +const isNull = require(Pathfinder.absPathInSrcFolder("/utils/null.js")).isNull; +const Logger = require(Pathfinder.absPathInSrcFolder("utils/logger.js")).Logger; + +const Config = require(Pathfinder.absPathInSrcFolder("models/meta/config.js")).Config; +const _ = require("underscore"); + +class Shibboleth +{ + constructor (shibbolethConfig) + { + this.__CALLBACK_URL = shibbolethConfig.CALLBACK_URL; + this.__ENTRY_POINT = shibbolethConfig.ENTRY_POINT; + this.__ISSUER = shibbolethConfig.ISSUER; + this.__SESSION_SECRET = shibbolethConfig.SESSION_SECRET; + this.__button_text = shibbolethConfig.button_text; + this.__idp_cert = shibbolethConfig.idp_cert; + this.__key = shibbolethConfig.key; + this.__cert = shibbolethConfig.cert; + } + + + /* + addNewSocket (newSocket) + { + let self = this; + self.__sockets.push(newSocket); + Logger.log("info", "Num connectedSockets for user " + self.__userUri + " : " + self.__sockets.length); + }; + */ +} + +module.exports.Shibboleth = Shibboleth; diff --git a/src/bootup/routes/load_logic_routes.js b/src/bootup/routes/load_logic_routes.js index 6413ddaa..e6a612e8 100644 --- a/src/bootup/routes/load_logic_routes.js +++ b/src/bootup/routes/load_logic_routes.js @@ -2,6 +2,7 @@ const path = require("path"); const Pathfinder = global.Pathfinder; const Config = require(Pathfinder.absPathInSrcFolder("models/meta/config.js")).Config; const Logger = require(Pathfinder.absPathInSrcFolder("utils/logger.js")).Logger; +const _ = require("underscore"); const isNull = require(Pathfinder.absPathInSrcFolder("/utils/null.js")).isNull; const Permissions = Object.create(require(Pathfinder.absPathInSrcFolder("/models/meta/permissions.js")).Permissions); @@ -30,6 +31,7 @@ const datasets = require(Pathfinder.absPathInSrcFolder("/controllers/datasets")) const posts = require(Pathfinder.absPathInSrcFolder("/controllers/posts")); const timeline = require(Pathfinder.absPathInSrcFolder("/controllers/timeline")); const notifications = require(Pathfinder.absPathInSrcFolder("/controllers/notifications")); +const Shibboleth = require(Pathfinder.absPathInSrcFolder("bootup/models/shibboleth/shibboleth.js")).Shibboleth; let recommendation; @@ -227,6 +229,83 @@ const loadRoutes = function (app, callback) }); } + if(!isNull(Config.authentication.shibboleth)) + { + let saml = require("passport-saml"); + _.each(Config.authentication.shibboleth, function (shibbolethConfig) { + console.log("This is a shibbolethConfig: " + JSON.stringify(shibbolethConfig)); + if(!isNull(shibbolethConfig.enabled) && shibbolethConfig.enabled === true) + { + let newShibboleth = new Shibboleth(shibbolethConfig); + let samlStrategy = new saml.Strategy({ + // URL that goes from the Identity Provider -> Service Provider + callbackUrl: newShibboleth.__CALLBACK_URL, + // URL that goes from the Service Provider -> Identity Provider + entryPoint: newShibboleth.__ENTRY_POINT, + // Usually specified as `/shibboleth` from site root + issuer: newShibboleth.__ISSUER, + identifierFormat: null, + // Service Provider private key + decryptionPvk: newShibboleth.__key, + // Service Provider Certificate + privateCert: newShibboleth.__key, + // Identity Provider's public key + cert: newShibboleth.__idp_cert, + validateInResponseTo: false, + disableRequestedAuthnContext: true + }, function(profile, done) { + return done(null, profile); + }); + + passport.use(samlStrategy); + + function ensureAuthenticated(req, res, next) { + if (req.isAuthenticated()) + return next(); + else + return res.redirect("/login"); + } + + app.get("/", + ensureAuthenticated, + function(req, res) { + res.send('Authenticated'); + } + ); + + app.get("/login", + passport.authenticate("saml", { failureRedirect: "/login/fail" }), + function (req, res) { + res.redirect("/"); + } + ); + + app.post("/login/callback", + passport.authenticate("saml", { failureRedirect: "/login/fail" }), + function(req, res) { + res.redirect("/"); + } + ); + + app.get("/login/fail", + function(req, res) { + res.status(401).send("Login failed"); + } + ); + + app.get('/Shibboleth.sso/Metadata', + function(req, res) { + res.type('application/xml'); + //res.status(200).send(samlStrategy.generateServiceProviderMetadata(fs.readFileSync(__dirname + '/cert/cert.pem', 'utf8'))); + res.status(200).send(samlStrategy.generateServiceProviderMetadata(newShibboleth.__cert)); + } + ); + + } + }); + console.log("Ended!"); + } + /** * Helper function to add the requested resource URI to the parameters, based on the human readable URI, * in case APIs are called with the human readable URI of a resource diff --git a/src/views/auth/login.ejs b/src/views/auth/login.ejs index fbfbee4c..2dfd3d7c 100644 --- a/src/views/auth/login.ejs +++ b/src/views/auth/login.ejs @@ -87,6 +87,10 @@ <%if (Config.authentication.orcid.enabled) { %> <%= Config.authentication.saml.button_text %> <% } %> + + <%if (Config.authentication.shibboleth.UP.enabled) { %> + <%= Config.authentication.shibboleth.UP.button_text %> + <% } %> From 0f56f65344d69da793c7c879eee5e87400d1b20d Mon Sep 17 00:00:00 2001 From: Nelson Pereira Date: Thu, 17 May 2018 16:04:33 +0100 Subject: [PATCH 02/21] changed parameters type --- conf/deployment_configs.json | 12 ++ src/bootup/models/shibboleth/shibboleth.js | 31 +++-- src/bootup/routes/load_logic_routes.js | 130 ++++++++++----------- src/views/auth/login.ejs | 4 +- 4 files changed, 101 insertions(+), 76 deletions(-) diff --git a/conf/deployment_configs.json b/conf/deployment_configs.json index 4d9720e7..48a0be65 100644 --- a/conf/deployment_configs.json +++ b/conf/deployment_configs.json @@ -385,6 +385,18 @@ "entry_point": "https://openidp.feide.no/simplesaml/saml2/idp/SSOService.php", "issuer": "passport-saml", "button_text": "Sign-in with SIGARRA" + }, + "shibbolethUP": + { + "enabled": true, + "CALLBACK_URL": "http://167.99.131.75:3007/login/callback", + "ENTRY_POINT": "https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO", + "ISSUER": "https://167.99.131.75/shibboleth", + "SESSION_SECRET": "secret123", + "button_text": "Sign-in with shibboleth UP", + "idp_cert_path": "/Users/nelsonpereira/Desktop/infolaRepos/dendroRepo/dendro/conf/cert/idp_cert.pem", + "key_path": "/Users/nelsonpereira/Desktop/infolaRepos/dendroRepo/dendro/conf/cert/key.pem", + "cert_path": "/Users/nelsonpereira/Desktop/infolaRepos/dendroRepo/dendro/conf/cert/cert.pem" } }, "numCPUs": 4 diff --git a/src/bootup/models/shibboleth/shibboleth.js b/src/bootup/models/shibboleth/shibboleth.js index 926b9919..e3189fad 100644 --- a/src/bootup/models/shibboleth/shibboleth.js +++ b/src/bootup/models/shibboleth/shibboleth.js @@ -7,19 +7,34 @@ const Logger = require(Pathfinder.absPathInSrcFolder("utils/logger.js")).Logger; const Config = require(Pathfinder.absPathInSrcFolder("models/meta/config.js")).Config; const _ = require("underscore"); +const fs = require("fs"); class Shibboleth { constructor (shibbolethConfig) { - this.__CALLBACK_URL = shibbolethConfig.CALLBACK_URL; - this.__ENTRY_POINT = shibbolethConfig.ENTRY_POINT; - this.__ISSUER = shibbolethConfig.ISSUER; - this.__SESSION_SECRET = shibbolethConfig.SESSION_SECRET; - this.__button_text = shibbolethConfig.button_text; - this.__idp_cert = shibbolethConfig.idp_cert; - this.__key = shibbolethConfig.key; - this.__cert = shibbolethConfig.cert; + try + { + this.__CALLBACK_URL = shibbolethConfig.CALLBACK_URL; + this.__ENTRY_POINT = shibbolethConfig.ENTRY_POINT; + this.__ISSUER = shibbolethConfig.ISSUER; + this.__SESSION_SECRET = shibbolethConfig.SESSION_SECRET; + this.__button_text = shibbolethConfig.button_text; + + /* + this.__idp_cert = shibbolethConfig.idp_cert; + this.__key = shibbolethConfig.key; + this.__cert = shibbolethConfig.cert; + */ + + this.__idp_cert = fs.readFileSync(shibbolethConfig.idp_cert_path); + this.__key = fs.readFileSync(shibbolethConfig.key_path); + this.__cert = fs.readFileSync(shibbolethConfig.cert_path); + } + catch (error) + { + throw error; + } } diff --git a/src/bootup/routes/load_logic_routes.js b/src/bootup/routes/load_logic_routes.js index e6a612e8..b7e5a5b0 100644 --- a/src/bootup/routes/load_logic_routes.js +++ b/src/bootup/routes/load_logic_routes.js @@ -229,80 +229,78 @@ const loadRoutes = function (app, callback) }); } - if(!isNull(Config.authentication.shibboleth)) + if(!isNull(Config.authentication.shibbolethUP)) { let saml = require("passport-saml"); - _.each(Config.authentication.shibboleth, function (shibbolethConfig) { - console.log("This is a shibbolethConfig: " + JSON.stringify(shibbolethConfig)); - if(!isNull(shibbolethConfig.enabled) && shibbolethConfig.enabled === true) - { - let newShibboleth = new Shibboleth(shibbolethConfig); - let samlStrategy = new saml.Strategy({ - // URL that goes from the Identity Provider -> Service Provider - callbackUrl: newShibboleth.__CALLBACK_URL, - // URL that goes from the Service Provider -> Identity Provider - entryPoint: newShibboleth.__ENTRY_POINT, - // Usually specified as `/shibboleth` from site root - issuer: newShibboleth.__ISSUER, - identifierFormat: null, - // Service Provider private key - decryptionPvk: newShibboleth.__key, - // Service Provider Certificate - privateCert: newShibboleth.__key, - // Identity Provider's public key - cert: newShibboleth.__idp_cert, - validateInResponseTo: false, - disableRequestedAuthnContext: true - }, function(profile, done) { - return done(null, profile); - }); - - passport.use(samlStrategy); - - function ensureAuthenticated(req, res, next) { - if (req.isAuthenticated()) - return next(); - else - return res.redirect("/login"); - } + console.log("This is a shibbolethUP config: " + JSON.stringify(Config.authentication.shibbolethUP)); + if(!isNull(Config.authentication.shibbolethUP.enabled) && Config.authentication.shibbolethUP.enabled === true) + { + let newShibboleth = new Shibboleth(Config.authentication.shibbolethUP); + let samlStrategy = new saml.Strategy({ + // URL that goes from the Identity Provider -> Service Provider + callbackUrl: newShibboleth.__CALLBACK_URL, + // URL that goes from the Service Provider -> Identity Provider + entryPoint: newShibboleth.__ENTRY_POINT, + // Usually specified as `/shibboleth` from site root + issuer: newShibboleth.__ISSUER, + identifierFormat: null, + // Service Provider private key + decryptionPvk: newShibboleth.__key, + // Service Provider Certificate + privateCert: newShibboleth.__key, + // Identity Provider's public key + cert: newShibboleth.__idp_cert, + validateInResponseTo: false, + disableRequestedAuthnContext: true + }, function(profile, done) { + return done(null, profile); + }); - app.get("/", - ensureAuthenticated, - function(req, res) { - res.send('Authenticated'); - } - ); + passport.use(samlStrategy); - app.get("/login", - passport.authenticate("saml", { failureRedirect: "/login/fail" }), - function (req, res) { - res.redirect("/"); - } - ); + function ensureAuthenticated(req, res, next) { + if (req.isAuthenticated()) + return next(); + else + return res.redirect("/login"); + } - app.post("/login/callback", - passport.authenticate("saml", { failureRedirect: "/login/fail" }), - function(req, res) { - res.redirect("/"); - } - ); + app.get("/", + ensureAuthenticated, + function(req, res) { + res.send('Authenticated'); + } + ); - app.get("/login/fail", - function(req, res) { - res.status(401).send("Login failed"); - } - ); + app.get("/login", + passport.authenticate("saml", { failureRedirect: "/login/fail" }), + function (req, res) { + res.redirect("/"); + } + ); - app.get('/Shibboleth.sso/Metadata', - function(req, res) { - res.type('application/xml'); - //res.status(200).send(samlStrategy.generateServiceProviderMetadata(fs.readFileSync(__dirname + '/cert/cert.pem', 'utf8'))); - res.status(200).send(samlStrategy.generateServiceProviderMetadata(newShibboleth.__cert)); - } - ); + app.post("/login/callback", + passport.authenticate("saml", { failureRedirect: "/login/fail" }), + function(req, res) { + res.redirect("/"); + } + ); - } - }); + app.get("/login/fail", + function(req, res) { + res.status(401).send("Login failed"); + } + ); + + app.get('/Shibboleth.sso/Metadata', + function(req, res) { + res.type('application/xml'); + //res.status(200).send(samlStrategy.generateServiceProviderMetadata(fs.readFileSync(__dirname + '/cert/cert.pem', 'utf8'))); + res.status(200).send(samlStrategy.generateServiceProviderMetadata(newShibboleth.__cert)); + } + ); + + } console.log("Ended!"); } diff --git a/src/views/auth/login.ejs b/src/views/auth/login.ejs index 2dfd3d7c..473d32de 100644 --- a/src/views/auth/login.ejs +++ b/src/views/auth/login.ejs @@ -88,8 +88,8 @@ <%= Config.authentication.saml.button_text %> <% } %> - <%if (Config.authentication.shibboleth.UP.enabled) { %> - <%= Config.authentication.shibboleth.UP.button_text %> + <%if (Config.authentication.shibbolethUP.enabled) { %> + <%= Config.authentication.shibbolethUP.button_text %> <% } %> From 8cb7c8ed82d31be35d59b830585f3c4990102798 Mon Sep 17 00:00:00 2001 From: Nelson Pereira Date: Mon, 21 May 2018 14:59:19 +0100 Subject: [PATCH 03/21] Update load_logic_routes.js --- src/bootup/routes/load_logic_routes.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/bootup/routes/load_logic_routes.js b/src/bootup/routes/load_logic_routes.js index b7e5a5b0..61dfe348 100644 --- a/src/bootup/routes/load_logic_routes.js +++ b/src/bootup/routes/load_logic_routes.js @@ -282,12 +282,15 @@ const loadRoutes = function (app, callback) app.post("/login/callback", passport.authenticate("saml", { failureRedirect: "/login/fail" }), function(req, res) { + console.log("Authenticated with success, checking req.user next:"); + console.log("req.user: " + req.user); res.redirect("/"); } ); app.get("/login/fail", function(req, res) { + console.log("failed to login with Shibboleth!") res.status(401).send("Login failed"); } ); From 6ac96c100f43aacd127a83f2e874a2226f328ca9 Mon Sep 17 00:00:00 2001 From: Nelson Pereira Date: Mon, 21 May 2018 16:02:59 +0100 Subject: [PATCH 04/21] Update bower.json --- public/bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/bower.json b/public/bower.json index 619141bd..7ab9909e 100644 --- a/public/bower.json +++ b/public/bower.json @@ -24,7 +24,7 @@ "angular-mocks": "1.6.1", "angular-resource": "1.6.1", "angular-route": "1.6.1", - "angular-sanitize": "^1.6.1", + "angular-sanitize": "1.6.1", "angular-touch": "1.6.1", "angular-loading-bar": "^0.8.0", "angular-ui-tree": "^2.15.0", From 9f715255c7c77fceaff826086553c4530de70c68 Mon Sep 17 00:00:00 2001 From: Nelson Pereira Date: Mon, 21 May 2018 17:44:05 +0100 Subject: [PATCH 05/21] still working on UP Shibboleth --- conf/deployment_configs.json | 5 +- package-lock.json | 1881 ++++++++++------- .../controllers/social/timeline_controller.js | 7 +- .../partial/authorInformationPartial.html | 3 +- public/bower.json | 2 +- src/bootup/models/shibboleth/shibboleth.js | 77 + src/bootup/routes/load_logic_routes.js | 12 +- src/views/auth/login.ejs | 2 +- 8 files changed, 1171 insertions(+), 818 deletions(-) diff --git a/conf/deployment_configs.json b/conf/deployment_configs.json index 48a0be65..5531828a 100644 --- a/conf/deployment_configs.json +++ b/conf/deployment_configs.json @@ -389,9 +389,10 @@ "shibbolethUP": { "enabled": true, - "CALLBACK_URL": "http://167.99.131.75:3007/login/callback", + "CALLBACK_URL": "http://207.154.250.99:3007/Shibboleth/login/callback", + "URL": "http://207.154.250.99:3007/Shibboleth", "ENTRY_POINT": "https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO", - "ISSUER": "https://167.99.131.75/shibboleth", + "ISSUER": "https://207.154.250.99/shibboleth", "SESSION_SECRET": "secret123", "button_text": "Sign-in with shibboleth UP", "idp_cert_path": "/Users/nelsonpereira/Desktop/infolaRepos/dendroRepo/dendro/conf/cert/idp_cert.pem", diff --git a/package-lock.json b/package-lock.json index fa1501f8..568faf85 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,17 +5,17 @@ "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.0.0-beta.46", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.46.tgz", - "integrity": "sha512-7BKRkmYaPZm3Yff5HGZJKCz7RqZ5jUjknsXT6Gz5YKG23J3uq9hAj0epncCB0rlqmnZ8Q+UUpQB2tCR5mT37vw==", + "version": "7.0.0-beta.47", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.47.tgz", + "integrity": "sha512-W7IeG4MoVf4oUvWfHUx9VG9if3E0xSUDf1urrnNYtC2ow1dz2ptvQ6YsJfyVXDuPTFXz66jkHhzMW7a5Eld7TA==", "requires": { - "@babel/highlight": "7.0.0-beta.46" + "@babel/highlight": "7.0.0-beta.47" } }, "@babel/highlight": { - "version": "7.0.0-beta.46", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.46.tgz", - "integrity": "sha512-r4snW6Q8ICL3Y8hGzYJRvyG/+sc+kvkewXNedG9tQjoHmUFMwMSv/o45GWQUQswevGnWghiGkpRPivFfOuMsOA==", + "version": "7.0.0-beta.47", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.47.tgz", + "integrity": "sha512-d505K3Hth1eg0b2swfEF7oFMw3J9M8ceFg0s6dhCSxOOF+07WDvJ0HKT/YbK/Jk9wn8Wyr6HIRAUPKJ9Wfv8Rg==", "requires": { "chalk": "^2.0.0", "esutils": "^2.0.2", @@ -78,9 +78,9 @@ } }, "@types/babel-types": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.1.tgz", - "integrity": "sha512-EkcOk09rjhivbovP8WreGRbXW20YRfe/qdgXOGq3it3u3aAOWDRNsQhL/XPAWFF7zhZZ+uR+nT+3b+TCkIap1w==" + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.2.tgz", + "integrity": "sha512-ylggu8DwwxT6mk3jVoJeohWAePWMNWEYm06MSoJ19kwp3hT9eY2Z4NNZn3oevzgFmClgNQ2GQF500hPDvNsGHg==" }, "@types/babylon": { "version": "6.16.2", @@ -91,9 +91,9 @@ } }, "@types/node": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.0.0.tgz", - "integrity": "sha512-kctoM36XiNZT86a7tPsUje+Q/yl+dqELjtYApi0T5eOQ90Elhu0MI10rmYk44yEP4v1jdDvtjQ9DFtpRtHf2Bw==" + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.1.2.tgz", + "integrity": "sha512-bjk1RIeZBCe/WukrFToIVegOf91Pebr8cXYBwLBIsfiGWVQ+ifwWsT59H3RxrWzWrzd1l/Amk1/ioY5Fq3/bpA==" }, "JSONSelect": { "version": "0.4.0", @@ -232,9 +232,9 @@ } }, "angular": { - "version": "1.6.10", - "resolved": "https://registry.npmjs.org/angular/-/angular-1.6.10.tgz", - "integrity": "sha512-PCZ5/hVdvPQiYyH0VwsPjrErPHRcITnaXxhksceOXgtJeesKHLA7KDu4X/yvcAi+1zdGgGF+9pDxkJvghXI9Wg==" + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/angular/-/angular-1.7.0.tgz", + "integrity": "sha512-3LboCLjrOuC7dWh953O0+dI3dJ7PexYRSCIrfqoN5qoHyja/wak3eWoxPKb2Sl2qwiPbrUV5KJXwgpUQ48McBQ==" }, "ansi-escapes": { "version": "3.1.0", @@ -675,11 +675,11 @@ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" }, "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", "requires": { - "lodash": "^4.14.0" + "lodash": "^4.17.10" } }, "async-each": { @@ -742,9 +742,9 @@ }, "dependencies": { "core-js": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.5.tgz", - "integrity": "sha1-sU3ek2xkDAV5prUMq8wTLdYSfjs=" + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.6.tgz", + "integrity": "sha512-lQUVfQi0aLix2xpyjrrJEvfuYCqPc/HwmTKsC/VNf8q0zsjX7SQZtp4+oRONN5Tsur9GDETPjj+Ub2iDiGZfSQ==" } } }, @@ -958,20 +958,20 @@ "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" }, "body-parser": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", - "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", "requires": { "bytes": "3.0.0", "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "~1.1.1", - "http-errors": "~1.6.2", - "iconv-lite": "0.4.19", + "depd": "~1.1.2", + "http-errors": "~1.6.3", + "iconv-lite": "0.4.23", "on-finished": "~2.3.0", - "qs": "6.5.1", - "raw-body": "2.3.2", - "type-is": "~1.6.15" + "qs": "6.5.2", + "raw-body": "2.3.3", + "type-is": "~1.6.16" }, "dependencies": { "debug": { @@ -990,11 +990,18 @@ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" }, "boom": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", - "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz", + "integrity": "sha1-emNune1O/O+xnO9JR6PGffrukRs=", "requires": { - "hoek": "4.x.x" + "hoek": "0.9.x" + }, + "dependencies": { + "hoek": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz", + "integrity": "sha1-PTIkYrrfB3Fup+uFuviAec3c5QU=" + } } }, "bower": { @@ -1298,9 +1305,9 @@ } }, "chai-dom": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chai-dom/-/chai-dom-1.7.0.tgz", - "integrity": "sha512-yUkuqa+3tLzFenmaEcRtSKzAvs/aYusNXHjnN8g5t7deC+9WPx9Fecfz63cM5ZJtfKbvQqFrmY8tsjOCyzrZEQ==" + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/chai-dom/-/chai-dom-1.8.0.tgz", + "integrity": "sha512-MNw5x1gyH++fEJkaPOCLLH78ftL7Of2/KI4YPyttVrwTC36GRQe21H66mIn1Pb/O6psHoHEz/SDLFoQTTLxxvA==" }, "chai-http": { "version": "3.0.0", @@ -1496,9 +1503,9 @@ "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=" }, "circular-json": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.3.tgz", - "integrity": "sha512-YlxLOimeIoQGHnMe3kbf8qIV2Bj7uXLbljMPRguNT49GmSAzooNfS9EJ91rSJKbLBOOzM5agvtx0WyechZN/Hw==" + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.4.tgz", + "integrity": "sha512-vnJA8KS0BfOihugYEUkLRcnmq21FbuivbxgzDLXNs3zIk4KllV4Mx4UuTzBXht9F00C7QfD1YqMXg1zP6EXpig==" }, "cjson": { "version": "0.2.1", @@ -1539,32 +1546,11 @@ "readable-stream": "~1.0.26" } }, - "boom": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz", - "integrity": "sha1-emNune1O/O+xnO9JR6PGffrukRs=", - "requires": { - "hoek": "0.9.x" - } - }, - "cryptiles": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz", - "integrity": "sha1-7ZH/HxetE9N0gohZT4pIoNJvMlw=", - "requires": { - "boom": "0.4.x" - } - }, "delayed-stream": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz", "integrity": "sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8=" }, - "hoek": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz", - "integrity": "sha1-PTIkYrrfB3Fup+uFuviAec3c5QU=" - }, "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", @@ -1593,9 +1579,9 @@ }, "dependencies": { "request": { - "version": "2.85.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz", - "integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==", + "version": "2.87.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", + "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.6.0", @@ -1605,7 +1591,6 @@ "forever-agent": "~0.6.1", "form-data": "~2.3.1", "har-validator": "~5.0.3", - "hawk": "~6.0.2", "http-signature": "~1.2.0", "is-typedarray": "~1.0.0", "isstream": "~0.1.2", @@ -1615,7 +1600,6 @@ "performance-now": "^2.1.0", "qs": "~6.5.1", "safe-buffer": "^5.1.1", - "stringstream": "~0.0.5", "tough-cookie": "~2.3.3", "tunnel-agent": "^0.6.0", "uuid": "^3.1.0" @@ -1720,17 +1704,6 @@ } } }, - "hawk": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-1.1.1.tgz", - "integrity": "sha1-h81JH5tG5OKurKM1QWdmiF0tHtk=", - "requires": { - "boom": "0.4.x", - "cryptiles": "0.2.x", - "hoek": "0.9.x", - "sntp": "0.2.x" - } - }, "http-signature": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", @@ -1763,14 +1736,6 @@ } } }, - "sntp": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz", - "integrity": "sha1-+4hfGLDzqtGJ+CSGJTa87ux1CQA=", - "requires": { - "hoek": "0.9.x" - } - }, "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", @@ -2178,9 +2143,9 @@ "integrity": "sha1-2BH9bIT1kClJmorEQ2ICk1uSvjE=" }, "colors": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.1.tgz", - "integrity": "sha512-s8+wktIuDSLffCywiwSxQOMqtPxML11a/dtHE17tMn4B1MSWw/C22EKf7M2KGUBcDaVFEGT+S8N02geDXeuNKg==" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.0.tgz", + "integrity": "sha512-EDpX3a7wHMWFA7PUHWPHNWqOxIIRSJetuwl0AS5Oi/5FMV8kWm69RTlgm00GKjBO1xFHMtBbL49yRtMMdticBw==" }, "colorspace": { "version": "1.0.1", @@ -2431,9 +2396,9 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "coveralls": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.0.tgz", - "integrity": "sha512-ZppXR9y5PraUOrf/DzHJY6gzNUhXYE3b9D43xEXs4QYZ7/Oe0Gy0CS+IPKWFfvQFXB3RG9QduaQUFehzSpGAFw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.1.tgz", + "integrity": "sha512-FAzXwiDOYLGDWH+zgoIA+8GbWv50hlx+kpEJyvzLKOdnIBv9uWoVl4DhqGgyUHpiRjAlF8KYZSipWXYtllWH6Q==", "dev": true, "requires": { "js-yaml": "^3.6.1", @@ -2513,9 +2478,9 @@ } }, "cross-env": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.1.4.tgz", - "integrity": "sha512-Mx8mw6JWhfpYoEk7PGvHxJMLQwQHORAs8+2bX+C1lGQ4h3GkDb1zbzC2Nw85YH9ZQMlO0BHZxMacgrfPmMFxbg==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.1.5.tgz", + "integrity": "sha512-GSiNTbvTU3pXzewRKGP0Y+rVP2CzifY2pqSEdtHzLLj41pRdkrgY7e4uSnBoR/pmYaqZr/lwwjg/Q4kNX30hWQ==", "dev": true, "requires": { "cross-spawn": "^5.1.0", @@ -2538,21 +2503,11 @@ "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=" }, "cryptiles": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", - "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz", + "integrity": "sha1-7ZH/HxetE9N0gohZT4pIoNJvMlw=", "requires": { - "boom": "5.x.x" - }, - "dependencies": { - "boom": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", - "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", - "requires": { - "hoek": "4.x.x" - } - } + "boom": "0.4.x" } }, "crypto": { @@ -3015,9 +2970,9 @@ } }, "domhandler": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz", - "integrity": "sha1-iS5HAAqZvlW783dP/qBWHYh5wlk=", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", "requires": { "domelementtype": "1" } @@ -3064,9 +3019,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "ejs": { - "version": "2.5.9", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.9.tgz", - "integrity": "sha512-GJCAeDBKfREgkBtgrYSf9hQy9kTb3helv0zGdzqhM7iAkW8FA/ZF97VQDbwFiwIT8MQLLOe5VlPZOEvZAqtUAQ==" + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.1.tgz", + "integrity": "sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==" }, "elasticsearch": { "version": "14.2.2", @@ -3535,9 +3490,9 @@ } }, "eslint-plugin-import": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.11.0.tgz", - "integrity": "sha1-Fa7qN6Z0mdhI6OmBgG1GJ7VQOBY=", + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.12.0.tgz", + "integrity": "sha1-2tMXgSktZmSyUxf9BJ0uKy8CIF0=", "dev": true, "requires": { "contains-path": "^0.1.0", @@ -3947,6 +3902,23 @@ "vary": "~1.1.2" }, "dependencies": { + "body-parser": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", + "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "requires": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.1", + "http-errors": "~1.6.2", + "iconv-lite": "0.4.19", + "on-finished": "~2.3.0", + "qs": "6.5.1", + "raw-body": "2.3.2", + "type-is": "~1.6.15" + } + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -3955,6 +3927,50 @@ "ms": "2.0.0" } }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" + }, + "raw-body": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", + "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "unpipe": "1.0.0" + }, + "dependencies": { + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" + }, + "http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "requires": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": ">= 1.3.1 < 2" + } + }, + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" + } + } + }, "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", @@ -4188,13 +4204,13 @@ "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=" }, "fill-range": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", - "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", "requires": { "is-number": "^2.1.0", "isobject": "^2.0.0", - "randomatic": "^1.1.3", + "randomatic": "^3.0.0", "repeat-element": "^1.1.2", "repeat-string": "^1.5.2" } @@ -4306,9 +4322,9 @@ "integrity": "sha1-PjKNj95BKtR+c44751C00pAENJg=" }, "follow-redirects": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.4.1.tgz", - "integrity": "sha512-uxYePVPogtya1ktGnAAXOacnbIuRMB4dkvqeNz2qTtTQsuzSfbDolV+wMMKxAmCx0bLgAKLbBOkjItMbbkR1vg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.0.tgz", + "integrity": "sha512-fdrt472/9qQ6Kgjvb935ig6vJCuofpBUD14f9Vb+SLlm7xIe4Qva5gey8EKtv8lp7ahE1wilg3xL1znpVGtZIA==", "requires": { "debug": "^3.1.0" } @@ -4415,13 +4431,13 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.3.tgz", - "integrity": "sha512-X+57O5YkDTiEQGiw8i7wYc2nQgweIekqkepI8Q3y4wVlurgBt2SuwxTeYUYMZIGpLZH3r/TsMjczCMXE5ZOt7Q==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", + "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", "optional": true, "requires": { "nan": "^2.9.2", - "node-pre-gyp": "^0.9.0" + "node-pre-gyp": "^0.10.0" }, "dependencies": { "abbrev": { @@ -4490,7 +4506,7 @@ } }, "deep-extend": { - "version": "0.4.2", + "version": "0.5.1", "bundled": true, "optional": true }, @@ -4652,7 +4668,7 @@ } }, "node-pre-gyp": { - "version": "0.9.1", + "version": "0.10.0", "bundled": true, "optional": true, "requires": { @@ -4748,11 +4764,11 @@ "optional": true }, "rc": { - "version": "1.2.6", + "version": "1.2.7", "bundled": true, "optional": true, "requires": { - "deep-extend": "~0.4.0", + "deep-extend": "^0.5.1", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" @@ -5095,9 +5111,9 @@ } }, "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==" + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" }, "grunt": { "version": "1.0.2", @@ -5404,9 +5420,9 @@ } }, "has-binary2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.2.tgz", - "integrity": "sha1-6D26SfC5vk0CbSc2U1DZ8D9Uvpg=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", "requires": { "isarray": "2.0.1" }, @@ -5516,14 +5532,21 @@ } }, "hawk": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", - "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-1.1.1.tgz", + "integrity": "sha1-h81JH5tG5OKurKM1QWdmiF0tHtk=", "requires": { - "boom": "4.x.x", - "cryptiles": "3.x.x", - "hoek": "4.x.x", - "sntp": "2.x.x" + "boom": "0.4.x", + "cryptiles": "0.2.x", + "hoek": "0.9.x", + "sntp": "0.2.x" + }, + "dependencies": { + "hoek": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz", + "integrity": "sha1-PTIkYrrfB3Fup+uFuviAec3c5QU=" + } } }, "he": { @@ -5623,9 +5646,12 @@ "dev": true }, "iconv-lite": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } }, "identicon.js": { "version": "2.3.2", @@ -6332,6 +6358,14 @@ "nan": "2.9.2" }, "dependencies": { + "async": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", + "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "requires": { + "lodash": "^4.14.0" + } + }, "lodash": { "version": "4.17.5", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", @@ -7057,13 +7091,13 @@ } }, "karma-coverage": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-1.1.1.tgz", - "integrity": "sha1-Wv+LOc9plNwi3kyENix2ABtjfPY=", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-1.1.2.tgz", + "integrity": "sha512-eQawj4Cl3z/CjxslYy9ariU4uDh7cCNFZHNWXWRpl0pNeblY/4wHR7M7boTYXWrn9bY0z2pZmr11eKje/S/hIw==", "requires": { "dateformat": "^1.0.6", "istanbul": "^0.4.0", - "lodash": "^3.8.0", + "lodash": "^4.17.0", "minimatch": "^3.0.0", "source-map": "^0.5.1" }, @@ -7077,11 +7111,6 @@ "meow": "^3.3.0" } }, - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" - }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -7347,9 +7376,9 @@ "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" }, "lru-cache": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.2.tgz", - "integrity": "sha512-wgeVXhrDwAWnIF/yZARsFnMBtdFXOg1b8RIrhilp+0iDYN4mdQcNZElDZ0e4B64BhaxeQ5zN7PMyvu7we1kPeQ==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", + "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", "requires": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" @@ -7418,6 +7447,11 @@ } } }, + "math-random": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", + "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=" + }, "maxmin": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/maxmin/-/maxmin-1.1.0.tgz", @@ -7606,9 +7640,9 @@ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, "minipass": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.4.tgz", - "integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.1.tgz", + "integrity": "sha512-liT0Gjaz7OHXg2qsfefVFfryBE9uAsqVFWQ6wVf4KNMzI2edsrCDjdGDpTxRaykbxhSKHu/SDtRRcMEcCcTQ2g==", "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -7662,39 +7696,29 @@ "integrity": "sha1-67Opd+evHGg65v2hK1Raa6bFhT0=" }, "mocha": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.1.1.tgz", - "integrity": "sha512-kKKs/H1KrMMQIEsWNxGmb4/BGsmj0dkeyotEvbrAuQ01FcWRLssUNXCEUZk6SZtyJBi6EE7SL0zDDtItw1rGhw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", "requires": { "browser-stdout": "1.3.1", - "commander": "2.11.0", + "commander": "2.15.1", "debug": "3.1.0", "diff": "3.5.0", "escape-string-regexp": "1.0.5", "glob": "7.1.2", - "growl": "1.10.3", + "growl": "1.10.5", "he": "1.1.1", "minimatch": "3.0.4", "mkdirp": "0.5.1", - "supports-color": "4.4.0" + "supports-color": "5.4.0" }, "dependencies": { - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==" - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" - }, "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "requires": { - "has-flag": "^2.0.0" + "has-flag": "^3.0.0" } } } @@ -7711,9 +7735,9 @@ "integrity": "sha512-shJkRTSebXvsVqk56I+lkb2latjBs8I+pc2TzWc545y2iFnSjm7Wg0QMh+ZWcdSLQyGEau5jI8ocnmkyTgr9YQ==" }, "moment-timezone": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.16.tgz", - "integrity": "sha512-4d1l92plNNqnMkqI/7boWNVXJvwGL2WyByl1Hxp3h/ao3HZiAqaoQY+6KBkYdiN5QtNDpndq+58ozl8W4GVoNw==", + "version": "0.5.17", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.17.tgz", + "integrity": "sha512-Y/JpVEWIOA9Gho4vO15MTnW1FCmHi3ypprrkUaxsZ1TKg3uqC8q/qMBjTddkHoiwwZN3qvZSr4zJP7x9V3LpXA==", "requires": { "moment": ">= 2.9.0" } @@ -7846,11 +7870,12 @@ } }, "multiparty": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/multiparty/-/multiparty-4.1.3.tgz", - "integrity": "sha1-PEPH/LGJbhdGBDap3Qtu8WaOT5Q=", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/multiparty/-/multiparty-4.1.4.tgz", + "integrity": "sha1-TJbcvcEeP3kX4WFeZAtLUCK+ZP0=", "requires": { - "fd-slicer": "~1.0.1" + "fd-slicer": "~1.0.1", + "safe-buffer": "5.1.2" } }, "mute-stream": { @@ -8134,9 +8159,9 @@ "integrity": "sha1-oRaYI9PLkbez1m7WIYDMM4UmI34=" }, "npm": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/npm/-/npm-5.8.0.tgz", - "integrity": "sha512-DowXzQwtSWDtbAjuWecuEiismR0VdNEYaL3VxNTYTdW6AGkYxfGk9LUZ/rt6etEyiH4IEk95HkJeGfXE5Rz9xQ==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/npm/-/npm-5.10.0.tgz", + "integrity": "sha512-lvjvjgR5wG2RJ2uqak1xtZcVAWMwVOzN5HkUlUj/n8rU1f3A0fNn+7HwOzH9Lyf0Ppyu9ApgsEpHczOSnx1cwA==", "requires": { "JSONStream": "^1.3.2", "abbrev": "~1.1.1", @@ -8147,9 +8172,11 @@ "archy": "~1.0.0", "bin-links": "^1.1.0", "bluebird": "~3.5.1", + "byte-size": "^4.0.2", "cacache": "^10.0.4", "call-limit": "~1.1.0", "chownr": "~1.0.1", + "cli-columns": "^3.1.2", "cli-table2": "~0.2.0", "cmd-shim": "~2.0.2", "columnify": "~1.5.4", @@ -8174,11 +8201,12 @@ "ini": "^1.3.5", "init-package-json": "^1.10.3", "is-cidr": "~1.0.0", - "json-parse-better-errors": "^1.0.1", + "json-parse-better-errors": "^1.0.2", "lazy-property": "~1.0.0", - "libcipm": "^1.6.0", - "libnpx": "^10.0.1", - "lockfile": "~1.0.3", + "libcipm": "^1.6.2", + "libnpx": "^10.2.0", + "lock-verify": "^2.0.2", + "lockfile": "^1.0.4", "lodash._baseindexof": "*", "lodash._baseuniq": "~4.6.0", "lodash._bindcallback": "*", @@ -8190,20 +8218,23 @@ "lodash.union": "~4.6.0", "lodash.uniq": "~4.5.0", "lodash.without": "~4.4.0", - "lru-cache": "~4.1.1", + "lru-cache": "^4.1.2", "meant": "~1.0.1", "mississippi": "^3.0.0", "mkdirp": "~0.5.1", "move-concurrently": "^1.0.1", + "node-gyp": "^3.6.2", "nopt": "~4.0.1", "normalize-package-data": "~2.4.0", + "npm-audit-report": "^1.0.9", "npm-cache-filename": "~1.0.2", "npm-install-checks": "~3.0.0", "npm-lifecycle": "^2.0.1", - "npm-package-arg": "~6.0.0", + "npm-package-arg": "^6.1.0", "npm-packlist": "~1.1.10", "npm-profile": "^3.0.1", "npm-registry-client": "^8.5.1", + "npm-registry-fetch": "^1.1.0", "npm-user-validate": "~1.0.0", "npmlog": "~4.1.2", "once": "~1.4.0", @@ -8212,39 +8243,40 @@ "pacote": "^7.6.1", "path-is-inside": "~1.0.2", "promise-inflight": "~1.0.1", - "qrcode-terminal": "~0.11.0", - "query-string": "^5.1.0", + "qrcode-terminal": "^0.12.0", + "query-string": "^6.1.0", "qw": "~1.0.1", "read": "~1.0.7", "read-cmd-shim": "~1.0.1", "read-installed": "~4.0.3", "read-package-json": "^2.0.13", - "read-package-tree": "~5.1.6", - "readable-stream": "^2.3.5", + "read-package-tree": "^5.2.1", + "readable-stream": "^2.3.6", "readdir-scoped-modules": "*", - "request": "~2.83.0", - "retry": "~0.10.1", + "request": "^2.85.0", + "retry": "^0.12.0", "rimraf": "~2.6.2", - "safe-buffer": "~5.1.1", + "safe-buffer": "^5.1.2", "semver": "^5.5.0", "sha": "~2.0.1", "slide": "~1.1.6", "sorted-object": "~2.0.1", "sorted-union-stream": "~2.1.3", - "ssri": "^5.2.4", + "ssri": "^5.3.0", "strip-ansi": "~4.0.0", - "tar": "^4.4.0", + "tar": "^4.4.2", "text-table": "~0.2.0", + "tiny-relative-date": "^1.3.0", "uid-number": "0.0.6", "umask": "~1.1.0", "unique-filename": "~1.1.0", "unpipe": "~1.0.0", - "update-notifier": "~2.3.0", + "update-notifier": "^2.5.0", "uuid": "^3.2.1", - "validate-npm-package-license": "*", + "validate-npm-package-license": "^3.0.3", "validate-npm-package-name": "~3.0.0", "which": "~1.3.0", - "worker-farm": "^1.5.4", + "worker-farm": "^1.6.0", "wrappy": "~1.0.2", "write-file-atomic": "^2.3.0" }, @@ -8307,6 +8339,10 @@ "version": "3.5.1", "bundled": true }, + "byte-size": { + "version": "4.0.2", + "bundled": true + }, "cacache": { "version": "10.0.4", "bundled": true, @@ -8472,6 +8508,50 @@ "version": "1.0.1", "bundled": true }, + "cli-columns": { + "version": "3.1.2", + "bundled": true, + "requires": { + "string-width": "^2.0.0", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "string-width": { + "version": "2.1.1", + "bundled": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true + }, + "strip-ansi": { + "version": "4.0.0", + "bundled": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "bundled": true + } + } + } + } + }, "cli-table2": { "version": "0.2.0", "bundled": true, @@ -8789,7 +8869,7 @@ } }, "json-parse-better-errors": { - "version": "1.0.1", + "version": "1.0.2", "bundled": true }, "lazy-property": { @@ -8797,7 +8877,7 @@ "bundled": true }, "libcipm": { - "version": "1.6.0", + "version": "1.6.2", "bundled": true, "requires": { "bin-links": "^1.1.0", @@ -8816,7 +8896,7 @@ }, "dependencies": { "lock-verify": { - "version": "2.0.0", + "version": "2.0.1", "bundled": true, "requires": { "npm-package-arg": "^5.1.2", @@ -8851,38 +8931,11 @@ "bundled": true } } - }, - "worker-farm": { - "version": "1.5.4", - "bundled": true, - "requires": { - "errno": "~0.1.7", - "xtend": "~4.0.1" - }, - "dependencies": { - "errno": { - "version": "0.1.7", - "bundled": true, - "requires": { - "prr": "~1.0.1" - }, - "dependencies": { - "prr": { - "version": "1.0.1", - "bundled": true - } - } - }, - "xtend": { - "version": "4.0.1", - "bundled": true - } - } } } }, "libnpx": { - "version": "10.0.1", + "version": "10.2.0", "bundled": true, "requires": { "dotenv": "^5.0.1", @@ -8922,7 +8975,7 @@ }, "dependencies": { "cliui": { - "version": "4.0.0", + "version": "4.1.0", "bundled": true, "requires": { "string-width": "^2.1.1", @@ -9196,9 +9249,26 @@ } } }, + "lock-verify": { + "version": "2.0.2", + "bundled": true, + "requires": { + "npm-package-arg": "^5.1.2 || 6", + "semver": "^5.4.1" + } + }, "lockfile": { - "version": "1.0.3", - "bundled": true + "version": "1.0.4", + "bundled": true, + "requires": { + "signal-exit": "^3.0.2" + }, + "dependencies": { + "signal-exit": { + "version": "3.0.2", + "bundled": true + } + } }, "lodash._baseindexof": { "version": "3.1.0", @@ -9262,7 +9332,7 @@ "bundled": true }, "lru-cache": { - "version": "4.1.1", + "version": "4.1.2", "bundled": true, "requires": { "pseudomap": "^1.0.2", @@ -9471,32 +9541,119 @@ } } }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "normalize-package-data": { - "version": "2.4.0", + "node-gyp": { + "version": "3.6.2", "bundled": true, "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "fstream": "^1.0.0", + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "minimatch": "^3.0.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": "2", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^2.0.0", + "which": "1" }, "dependencies": { - "is-builtin-module": { - "version": "1.0.0", + "fstream": { + "version": "1.0.11", "bundled": true, "requires": { - "builtin-modules": "^1.0.0" + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "requires": { + "brace-expansion": "^1.1.7" }, "dependencies": { - "builtin-modules": { + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "bundled": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true + } + } + } + } + }, + "nopt": { + "version": "3.0.6", + "bundled": true, + "requires": { + "abbrev": "1" + } + }, + "semver": { + "version": "5.3.0", + "bundled": true + }, + "tar": { + "version": "2.2.1", + "bundled": true, + "requires": { + "block-stream": "*", + "fstream": "^1.0.2", + "inherits": "2" + }, + "dependencies": { + "block-stream": { + "version": "0.0.9", + "bundled": true, + "requires": { + "inherits": "~2.0.0" + } + } + } + } + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "bundled": true, + "requires": { + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "is-builtin-module": { + "version": "1.0.0", + "bundled": true, + "requires": { + "builtin-modules": "^1.0.0" + }, + "dependencies": { + "builtin-modules": { "version": "1.1.1", "bundled": true } @@ -9504,6 +9661,20 @@ } } }, + "npm-audit-report": { + "version": "1.0.9", + "bundled": true, + "requires": { + "cli-table2": "^0.2.0", + "console-control-strings": "^1.1.0" + }, + "dependencies": { + "console-control-strings": { + "version": "1.1.0", + "bundled": true + } + } + }, "npm-cache-filename": { "version": "1.0.2", "bundled": true @@ -9533,93 +9704,6 @@ "version": "5.0.0", "bundled": true }, - "node-gyp": { - "version": "3.6.2", - "bundled": true, - "requires": { - "fstream": "^1.0.0", - "glob": "^7.0.3", - "graceful-fs": "^4.1.2", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.0", - "nopt": "2 || 3", - "npmlog": "0 || 1 || 2 || 3 || 4", - "osenv": "0", - "request": "2", - "rimraf": "2", - "semver": "~5.3.0", - "tar": "^2.0.0", - "which": "1" - }, - "dependencies": { - "fstream": { - "version": "1.0.11", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - } - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "requires": { - "brace-expansion": "^1.1.7" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - }, - "dependencies": { - "balanced-match": { - "version": "1.0.0", - "bundled": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true - } - } - } - } - }, - "nopt": { - "version": "3.0.6", - "bundled": true, - "requires": { - "abbrev": "1" - } - }, - "semver": { - "version": "5.3.0", - "bundled": true - }, - "tar": { - "version": "2.2.1", - "bundled": true, - "requires": { - "block-stream": "*", - "fstream": "^1.0.2", - "inherits": "2" - }, - "dependencies": { - "block-stream": { - "version": "0.0.9", - "bundled": true, - "requires": { - "inherits": "~2.0.0" - } - } - } - } - } - }, "resolve-from": { "version": "4.0.0", "bundled": true @@ -9627,12 +9711,12 @@ } }, "npm-package-arg": { - "version": "6.0.0", + "version": "6.1.0", "bundled": true, "requires": { - "hosted-git-info": "^2.5.0", - "osenv": "^0.1.4", - "semver": "^5.4.1", + "hosted-git-info": "^2.6.0", + "osenv": "^0.1.5", + "semver": "^5.5.0", "validate-npm-package-name": "^3.0.0" } }, @@ -10008,6 +10092,10 @@ "err-code": { "version": "1.1.2", "bundled": true + }, + "retry": { + "version": "0.10.1", + "bundled": true } } }, @@ -10097,6 +10185,264 @@ "bundled": true } } + }, + "retry": { + "version": "0.10.1", + "bundled": true + } + } + }, + "npm-registry-fetch": { + "version": "1.1.0", + "bundled": true, + "requires": { + "bluebird": "^3.5.1", + "figgy-pudding": "^2.0.1", + "lru-cache": "^4.1.2", + "make-fetch-happen": "^3.0.0", + "npm-package-arg": "^6.0.0", + "safe-buffer": "^5.1.1" + }, + "dependencies": { + "figgy-pudding": { + "version": "2.0.1", + "bundled": true + }, + "make-fetch-happen": { + "version": "3.0.0", + "bundled": true, + "requires": { + "agentkeepalive": "^3.4.1", + "cacache": "^10.0.4", + "http-cache-semantics": "^3.8.1", + "http-proxy-agent": "^2.1.0", + "https-proxy-agent": "^2.2.0", + "lru-cache": "^4.1.2", + "mississippi": "^3.0.0", + "node-fetch-npm": "^2.0.2", + "promise-retry": "^1.1.1", + "socks-proxy-agent": "^3.0.1", + "ssri": "^5.2.4" + }, + "dependencies": { + "agentkeepalive": { + "version": "3.4.1", + "bundled": true, + "requires": { + "humanize-ms": "^1.2.1" + }, + "dependencies": { + "humanize-ms": { + "version": "1.2.1", + "bundled": true, + "requires": { + "ms": "^2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "bundled": true + } + } + } + } + }, + "http-cache-semantics": { + "version": "3.8.1", + "bundled": true + }, + "http-proxy-agent": { + "version": "2.1.0", + "bundled": true, + "requires": { + "agent-base": "4", + "debug": "3.1.0" + }, + "dependencies": { + "agent-base": { + "version": "4.2.0", + "bundled": true, + "requires": { + "es6-promisify": "^5.0.0" + }, + "dependencies": { + "es6-promisify": { + "version": "5.0.0", + "bundled": true, + "requires": { + "es6-promise": "^4.0.3" + }, + "dependencies": { + "es6-promise": { + "version": "4.2.4", + "bundled": true + } + } + } + } + }, + "debug": { + "version": "3.1.0", + "bundled": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "bundled": true + } + } + } + } + }, + "https-proxy-agent": { + "version": "2.2.1", + "bundled": true, + "requires": { + "agent-base": "^4.1.0", + "debug": "^3.1.0" + }, + "dependencies": { + "agent-base": { + "version": "4.2.0", + "bundled": true, + "requires": { + "es6-promisify": "^5.0.0" + }, + "dependencies": { + "es6-promisify": { + "version": "5.0.0", + "bundled": true, + "requires": { + "es6-promise": "^4.0.3" + }, + "dependencies": { + "es6-promise": { + "version": "4.2.4", + "bundled": true + } + } + } + } + }, + "debug": { + "version": "3.1.0", + "bundled": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "bundled": true + } + } + } + } + }, + "node-fetch-npm": { + "version": "2.0.2", + "bundled": true, + "requires": { + "encoding": "^0.1.11", + "json-parse-better-errors": "^1.0.0", + "safe-buffer": "^5.1.1" + }, + "dependencies": { + "encoding": { + "version": "0.1.12", + "bundled": true, + "requires": { + "iconv-lite": "~0.4.13" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.21", + "bundled": true, + "requires": { + "safer-buffer": "^2.1.0" + }, + "dependencies": { + "safer-buffer": { + "version": "2.1.2", + "bundled": true + } + } + } + } + } + } + }, + "promise-retry": { + "version": "1.1.1", + "bundled": true, + "requires": { + "err-code": "^1.0.0", + "retry": "^0.10.0" + }, + "dependencies": { + "err-code": { + "version": "1.1.2", + "bundled": true + }, + "retry": { + "version": "0.10.1", + "bundled": true + } + } + }, + "socks-proxy-agent": { + "version": "3.0.1", + "bundled": true, + "requires": { + "agent-base": "^4.1.0", + "socks": "^1.1.10" + }, + "dependencies": { + "agent-base": { + "version": "4.2.0", + "bundled": true, + "requires": { + "es6-promisify": "^5.0.0" + }, + "dependencies": { + "es6-promisify": { + "version": "5.0.0", + "bundled": true, + "requires": { + "es6-promise": "^4.0.3" + }, + "dependencies": { + "es6-promise": { + "version": "4.2.4", + "bundled": true + } + } + } + } + }, + "socks": { + "version": "1.1.10", + "bundled": true, + "requires": { + "ip": "^1.1.4", + "smart-buffer": "^1.0.13" + }, + "dependencies": { + "ip": { + "version": "1.1.5", + "bundled": true + }, + "smart-buffer": { + "version": "1.1.15", + "bundled": true + } + } + } + } + } + } } } }, @@ -10674,6 +11020,10 @@ "err-code": { "version": "1.1.2", "bundled": true + }, + "retry": { + "version": "0.10.1", + "bundled": true } } }, @@ -10701,28 +11051,23 @@ "bundled": true }, "qrcode-terminal": { - "version": "0.11.0", + "version": "0.12.0", "bundled": true }, "query-string": { - "version": "5.1.0", + "version": "6.1.0", "bundled": true, "requires": { "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" + "strict-uri-encode": "^2.0.0" }, "dependencies": { "decode-uri-component": { "version": "0.2.0", "bundled": true }, - "object-assign": { - "version": "4.1.1", - "bundled": true - }, "strict-uri-encode": { - "version": "1.1.0", + "version": "2.0.0", "bundled": true } } @@ -10792,7 +11137,7 @@ } }, "read-package-tree": { - "version": "5.1.6", + "version": "5.2.1", "bundled": true, "requires": { "debuglog": "^1.0.1", @@ -10803,7 +11148,7 @@ } }, "readable-stream": { - "version": "2.3.5", + "version": "2.3.6", "bundled": true, "requires": { "core-util-is": "~1.0.0", @@ -10811,7 +11156,7 @@ "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", - "string_decoder": "~1.0.3", + "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" }, "dependencies": { @@ -10828,7 +11173,7 @@ "bundled": true }, "string_decoder": { - "version": "1.0.3", + "version": "1.1.1", "bundled": true, "requires": { "safe-buffer": "~5.1.0" @@ -10851,7 +11196,7 @@ } }, "request": { - "version": "2.83.0", + "version": "2.85.0", "bundled": true, "requires": { "aws-sign2": "~0.7.0", @@ -10891,7 +11236,7 @@ "bundled": true }, "combined-stream": { - "version": "1.0.5", + "version": "1.0.6", "bundled": true, "requires": { "delayed-stream": "~1.0.0" @@ -10912,11 +11257,11 @@ "bundled": true }, "form-data": { - "version": "2.3.1", + "version": "2.3.2", "bundled": true, "requires": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.5", + "combined-stream": "1.0.6", "mime-types": "^2.1.12" }, "dependencies": { @@ -10935,13 +11280,13 @@ }, "dependencies": { "ajv": { - "version": "5.2.3", + "version": "5.5.2", "bundled": true, "requires": { "co": "^4.6.0", "fast-deep-equal": "^1.0.0", - "json-schema-traverse": "^0.3.0", - "json-stable-stringify": "^1.0.1" + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" }, "dependencies": { "co": { @@ -10949,25 +11294,16 @@ "bundled": true }, "fast-deep-equal": { - "version": "1.0.0", + "version": "1.1.0", + "bundled": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", "bundled": true }, "json-schema-traverse": { "version": "0.3.1", "bundled": true - }, - "json-stable-stringify": { - "version": "1.0.1", - "bundled": true, - "requires": { - "jsonify": "~0.0.0" - }, - "dependencies": { - "jsonify": { - "version": "0.0.0", - "bundled": true - } - } } } }, @@ -11011,11 +11347,11 @@ } }, "hoek": { - "version": "4.2.0", + "version": "4.2.1", "bundled": true }, "sntp": { - "version": "2.0.2", + "version": "2.1.0", "bundled": true, "requires": { "hoek": "4.x.x" @@ -11072,7 +11408,7 @@ } }, "sshpk": { - "version": "1.13.1", + "version": "1.14.1", "bundled": true, "requires": { "asn1": "~0.2.3", @@ -11146,14 +11482,14 @@ "bundled": true }, "mime-types": { - "version": "2.1.17", + "version": "2.1.18", "bundled": true, "requires": { - "mime-db": "~1.30.0" + "mime-db": "~1.33.0" }, "dependencies": { "mime-db": { - "version": "1.30.0", + "version": "1.33.0", "bundled": true } } @@ -11175,7 +11511,7 @@ "bundled": true }, "tough-cookie": { - "version": "2.3.3", + "version": "2.3.4", "bundled": true, "requires": { "punycode": "^1.4.1" @@ -11197,7 +11533,7 @@ } }, "retry": { - "version": "0.10.1", + "version": "0.12.0", "bundled": true }, "rimraf": { @@ -11208,7 +11544,7 @@ } }, "safe-buffer": { - "version": "5.1.1", + "version": "5.1.2", "bundled": true }, "semver": { @@ -11290,7 +11626,7 @@ } }, "ssri": { - "version": "5.2.4", + "version": "5.3.0", "bundled": true, "requires": { "safe-buffer": "^5.1.1" @@ -11310,14 +11646,15 @@ } }, "tar": { - "version": "4.4.0", + "version": "4.4.2", "bundled": true, "requires": { "chownr": "^1.0.1", - "fs-minipass": "^1.2.3", - "minipass": "^2.2.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.2.4", "minizlib": "^1.1.0", "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", "yallist": "^3.0.2" }, "dependencies": { @@ -11329,9 +11666,10 @@ } }, "minipass": { - "version": "2.2.1", + "version": "2.2.4", "bundled": true, "requires": { + "safe-buffer": "^5.1.1", "yallist": "^3.0.0" } }, @@ -11342,6 +11680,10 @@ "minipass": "^2.2.1" } }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true + }, "yallist": { "version": "3.0.2", "bundled": true @@ -11352,6 +11694,10 @@ "version": "0.2.0", "bundled": true }, + "tiny-relative-date": { + "version": "1.3.0", + "bundled": true + }, "uid-number": { "version": "0.0.6", "bundled": true @@ -11381,13 +11727,14 @@ "bundled": true }, "update-notifier": { - "version": "2.3.0", + "version": "2.5.0", "bundled": true, "requires": { "boxen": "^1.2.1", "chalk": "^2.0.1", "configstore": "^3.0.0", "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", "is-installed-globally": "^0.1.0", "is-npm": "^1.0.0", "latest-version": "^3.0.0", @@ -11396,7 +11743,7 @@ }, "dependencies": { "boxen": { - "version": "1.2.1", + "version": "1.3.0", "bundled": true, "requires": { "ansi-align": "^2.0.0", @@ -11405,7 +11752,7 @@ "cli-boxes": "^1.0.0", "string-width": "^2.0.0", "term-size": "^1.2.0", - "widest-line": "^1.0.0" + "widest-line": "^2.0.0" }, "dependencies": { "ansi-align": { @@ -11519,75 +11866,32 @@ } }, "widest-line": { - "version": "1.0.0", + "version": "2.0.0", "bundled": true, "requires": { - "string-width": "^1.0.1" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "bundled": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "dependencies": { - "code-point-at": { - "version": "1.1.0", - "bundled": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "requires": { - "number-is-nan": "^1.0.0" - }, - "dependencies": { - "number-is-nan": { - "version": "1.0.1", - "bundled": true - } - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "bundled": true - } - } - } - } - } + "string-width": "^2.1.1" } } } }, "chalk": { - "version": "2.1.0", + "version": "2.4.1", "bundled": true, "requires": { - "ansi-styles": "^3.1.0", + "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", - "supports-color": "^4.0.0" + "supports-color": "^5.3.0" }, "dependencies": { "ansi-styles": { - "version": "3.2.0", + "version": "3.2.1", "bundled": true, "requires": { "color-convert": "^1.9.0" }, "dependencies": { "color-convert": { - "version": "1.9.0", + "version": "1.9.1", "bundled": true, "requires": { "color-name": "^1.1.1" @@ -11606,14 +11910,14 @@ "bundled": true }, "supports-color": { - "version": "4.4.0", + "version": "5.4.0", "bundled": true, "requires": { - "has-flag": "^2.0.0" + "has-flag": "^3.0.0" }, "dependencies": { "has-flag": { - "version": "2.0.0", + "version": "3.0.0", "bundled": true } } @@ -11621,7 +11925,7 @@ } }, "configstore": { - "version": "3.1.1", + "version": "3.1.2", "bundled": true, "requires": { "dot-prop": "^4.1.0", @@ -11646,14 +11950,14 @@ } }, "make-dir": { - "version": "1.0.0", + "version": "1.2.0", "bundled": true, "requires": { - "pify": "^2.3.0" + "pify": "^3.0.0" }, "dependencies": { "pify": { - "version": "2.3.0", + "version": "3.0.0", "bundled": true } } @@ -11677,6 +11981,19 @@ "version": "2.1.0", "bundled": true }, + "is-ci": { + "version": "1.1.0", + "bundled": true, + "requires": { + "ci-info": "^1.0.0" + }, + "dependencies": { + "ci-info": { + "version": "1.1.3", + "bundled": true + } + } + }, "is-installed-globally": { "version": "0.1.0", "bundled": true, @@ -11686,14 +12003,14 @@ }, "dependencies": { "global-dirs": { - "version": "0.1.0", + "version": "0.1.1", "bundled": true, "requires": { "ini": "^1.3.4" } }, "is-path-inside": { - "version": "1.0.0", + "version": "1.0.1", "bundled": true, "requires": { "path-is-inside": "^1.0.1" @@ -11773,7 +12090,7 @@ "bundled": true }, "lowercase-keys": { - "version": "1.0.0", + "version": "1.0.1", "bundled": true }, "timed-out": { @@ -11800,7 +12117,7 @@ } }, "registry-auth-token": { - "version": "3.3.1", + "version": "3.3.2", "bundled": true, "requires": { "rc": "^1.1.6", @@ -11808,17 +12125,17 @@ }, "dependencies": { "rc": { - "version": "1.2.1", + "version": "1.2.7", "bundled": true, "requires": { - "deep-extend": "~0.4.0", + "deep-extend": "^0.5.1", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "dependencies": { "deep-extend": { - "version": "0.4.2", + "version": "0.5.1", "bundled": true }, "minimist": { @@ -11841,17 +12158,17 @@ }, "dependencies": { "rc": { - "version": "1.2.1", + "version": "1.2.7", "bundled": true, "requires": { - "deep-extend": "~0.4.0", + "deep-extend": "^0.5.1", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "dependencies": { "deep-extend": { - "version": "0.4.2", + "version": "0.5.1", "bundled": true }, "minimist": { @@ -11888,29 +12205,44 @@ "bundled": true }, "validate-npm-package-license": { - "version": "3.0.1", + "version": "3.0.3", "bundled": true, "requires": { - "spdx-correct": "~1.0.0", - "spdx-expression-parse": "~1.0.0" + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" }, "dependencies": { "spdx-correct": { - "version": "1.0.2", + "version": "3.0.0", "bundled": true, "requires": { - "spdx-license-ids": "^1.0.2" + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" }, "dependencies": { "spdx-license-ids": { - "version": "1.2.2", + "version": "3.0.0", "bundled": true } } }, "spdx-expression-parse": { - "version": "1.0.4", - "bundled": true + "version": "3.0.0", + "bundled": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + }, + "dependencies": { + "spdx-exceptions": { + "version": "2.1.0", + "bundled": true + }, + "spdx-license-ids": { + "version": "3.0.0", + "bundled": true + } + } } } }, @@ -11941,11 +12273,10 @@ } }, "worker-farm": { - "version": "1.5.4", + "version": "1.6.0", "bundled": true, "requires": { - "errno": "~0.1.7", - "xtend": "~4.0.1" + "errno": "~0.1.7" }, "dependencies": { "errno": { @@ -11960,10 +12291,6 @@ "bundled": true } } - }, - "xtend": { - "version": "4.0.1", - "bundled": true } } }, @@ -12024,9 +12351,9 @@ "integrity": "sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ==" }, "nyc": { - "version": "11.7.1", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-11.7.1.tgz", - "integrity": "sha512-EGePURSKUEpS1jWnEKAMhY+GWZzi7JC+f8iBDOATaOsLZW5hM/9eYx2dHGaEXa1ITvMm44CJugMksvP3NwMQMw==", + "version": "11.8.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-11.8.0.tgz", + "integrity": "sha512-PUFq1PSsx5OinSk5g5aaZygcDdI3QQT5XUlbR9QRMihtMS6w0Gm8xj4BxmKeeAlpQXC5M2DIhH16Y+KejceivQ==", "dev": true, "requires": { "archy": "^1.0.0", @@ -12046,11 +12373,11 @@ "istanbul-lib-source-maps": "^1.2.3", "istanbul-reports": "^1.4.0", "md5-hex": "^1.2.0", - "merge-source-map": "^1.0.2", - "micromatch": "^2.3.11", + "merge-source-map": "^1.1.0", + "micromatch": "^3.1.10", "mkdirp": "^0.5.0", "resolve-from": "^2.0.0", - "rimraf": "^2.5.4", + "rimraf": "^2.6.2", "signal-exit": "^3.0.1", "spawn-wrap": "^1.4.2", "test-exclude": "^4.2.0", @@ -12097,12 +12424,9 @@ "dev": true }, "arr-diff": { - "version": "2.0.0", + "version": "4.0.0", "bundled": true, - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } + "dev": true }, "arr-flatten": { "version": "1.1.0", @@ -12115,7 +12439,7 @@ "dev": true }, "array-unique": { - "version": "0.2.1", + "version": "0.3.2", "bundled": true, "dev": true }, @@ -12135,7 +12459,7 @@ "dev": true }, "atob": { - "version": "2.1.0", + "version": "2.1.1", "bundled": true, "dev": true }, @@ -12300,13 +12624,30 @@ } }, "braces": { - "version": "1.8.5", + "version": "2.3.2", "bundled": true, "dev": true, "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } } }, "builtin-modules": { @@ -12460,7 +12801,7 @@ "dev": true }, "core-js": { - "version": "2.5.5", + "version": "2.5.6", "bundled": true, "dev": true }, @@ -12604,19 +12945,35 @@ } }, "expand-brackets": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", + "version": "2.1.4", "bundled": true, "dev": true, "requires": { - "fill-range": "^2.1.0" + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } } }, "extend-shallow": { @@ -12639,28 +12996,88 @@ } }, "extglob": { - "version": "0.3.2", + "version": "2.0.4", "bundled": true, "dev": true, "requires": { - "is-extglob": "^1.0.0" + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "kind-of": { + "version": "6.0.2", + "bundled": true, + "dev": true + } } }, - "filename-regex": { - "version": "2.0.1", - "bundled": true, - "dev": true - }, "fill-range": { - "version": "2.2.3", + "version": "4.0.0", "bundled": true, "dev": true, "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^1.1.3", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } } }, "find-cache-dir": { @@ -12686,14 +13103,6 @@ "bundled": true, "dev": true }, - "for-own": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, "foreground-child": { "version": "1.5.6", "bundled": true, @@ -12744,23 +13153,6 @@ "path-is-absolute": "^1.0.0" } }, - "glob-base": { - "version": "0.3.0", - "bundled": true, - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, "globals": { "version": "9.18.0", "bundled": true, @@ -12947,29 +13339,11 @@ } } }, - "is-dotfile": { - "version": "1.0.3", - "bundled": true, - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "bundled": true, - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, "is-extendable": { "version": "0.1.1", "bundled": true, "dev": true }, - "is-extglob": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, "is-finite": { "version": "1.0.2", "bundled": true, @@ -12983,16 +13357,8 @@ "bundled": true, "dev": true }, - "is-glob": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, "is-number": { - "version": "2.1.0", + "version": "3.0.0", "bundled": true, "dev": true, "requires": { @@ -13029,16 +13395,6 @@ } } }, - "is-posix-bracket": { - "version": "0.1.1", - "bundled": true, - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, "is-stream": { "version": "1.1.0", "bundled": true, @@ -13065,12 +13421,9 @@ "dev": true }, "isobject": { - "version": "2.1.0", + "version": "3.0.1", "bundled": true, - "dev": true, - "requires": { - "isarray": "1.0.0" - } + "dev": true }, "istanbul-lib-coverage": { "version": "1.2.0", @@ -13211,7 +13564,7 @@ } }, "lodash": { - "version": "4.17.5", + "version": "4.17.10", "bundled": true, "dev": true }, @@ -13229,7 +13582,7 @@ } }, "lru-cache": { - "version": "4.1.2", + "version": "4.1.3", "bundled": true, "dev": true, "requires": { @@ -13287,23 +13640,30 @@ } }, "micromatch": { - "version": "2.3.11", + "version": "3.1.10", "bundled": true, "dev": true, "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "bundled": true, + "dev": true + } } }, "mimic-fn": { @@ -13403,14 +13763,6 @@ "validate-npm-package-license": "^3.0.1" } }, - "normalize-path": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, "npm-run-path": { "version": "2.0.2", "bundled": true, @@ -13464,15 +13816,6 @@ } } }, - "object.omit": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, "object.pick": { "version": "1.3.0", "bundled": true, @@ -13546,17 +13889,6 @@ "bundled": true, "dev": true }, - "parse-glob": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, "parse-json": { "version": "2.2.0", "bundled": true, @@ -13645,53 +13977,11 @@ "bundled": true, "dev": true }, - "preserve": { - "version": "0.2.0", - "bundled": true, - "dev": true - }, "pseudomap": { "version": "1.0.2", "bundled": true, "dev": true }, - "randomatic": { - "version": "1.1.7", - "bundled": true, - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "bundled": true, - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "read-pkg": { "version": "1.1.0", "bundled": true, @@ -13727,14 +14017,6 @@ "bundled": true, "dev": true }, - "regex-cache": { - "version": "0.4.4", - "bundled": true, - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, "regex-not": { "version": "1.0.2", "bundled": true, @@ -13744,11 +14026,6 @@ "safe-regex": "^1.1.0" } }, - "remove-trailing-separator": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, "repeat-element": { "version": "1.1.2", "bundled": true, @@ -14659,7 +14936,7 @@ "dev": true }, "cliui": { - "version": "4.0.0", + "version": "4.1.0", "bundled": true, "dev": true, "requires": { @@ -15327,9 +15604,9 @@ "dev": true }, "pm2": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/pm2/-/pm2-2.10.3.tgz", - "integrity": "sha512-C3fEC4jkr4iR1mUfTdX4CoR9RRe1165MDbGToVm+H7lCuXeh25CgckjrsXHv6QMLFT0hNbQr5m44YYyWotBTAA==", + "version": "2.10.4", + "resolved": "https://registry.npmjs.org/pm2/-/pm2-2.10.4.tgz", + "integrity": "sha512-AuAA6DoF/R3L9zSuYtKzaEd6UFvhCKqfW49dgLe0Q4SQtYmQMmXmyEAp5tr1iduJrqGRwpb5ytVm2rWZ56/4Vg==", "requires": { "async": "^2.5", "blessed": "^0.1.81", @@ -15818,9 +16095,9 @@ "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" }, "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, "query-string": { "version": "4.3.4", @@ -15855,39 +16132,24 @@ "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=" }, "randomatic": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", - "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.0.0.tgz", + "integrity": "sha512-VdxFOIEY3mNO5PtSRkkle/hPJDHvQhK21oa73K4yAc9qmp6N429gAyF1gZMOTMeS0/AYzaV/2Trcef+NaIonSA==", "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" }, "dependencies": { "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" }, "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "requires": { - "is-buffer": "^1.1.5" - } + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" } } }, @@ -15897,37 +16159,14 @@ "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" }, "raw-body": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", - "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", "requires": { "bytes": "3.0.0", - "http-errors": "1.6.2", - "iconv-lite": "0.4.19", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", "unpipe": "1.0.0" - }, - "dependencies": { - "depd": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" - }, - "http-errors": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", - "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", - "requires": { - "depd": "1.1.1", - "inherits": "2.0.3", - "setprototypeof": "1.0.3", - "statuses": ">= 1.3.1 < 2" - } - }, - "setprototypeof": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" - } } }, "read": { @@ -16318,9 +16557,9 @@ } }, "request": { - "version": "2.85.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz", - "integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==", + "version": "2.87.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", + "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.6.0", @@ -16330,7 +16569,6 @@ "forever-agent": "~0.6.1", "form-data": "~2.3.1", "har-validator": "~5.0.3", - "hawk": "~6.0.2", "http-signature": "~1.2.0", "is-typedarray": "~1.0.0", "isstream": "~0.1.2", @@ -16340,7 +16578,6 @@ "performance-now": "^2.1.0", "qs": "~6.5.1", "safe-buffer": "^5.1.1", - "stringstream": "~0.0.5", "tough-cookie": "~2.3.3", "tunnel-agent": "^0.6.0", "uuid": "^3.1.0" @@ -16573,6 +16810,11 @@ "ret": "~0.1.10" } }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", @@ -16905,9 +17147,9 @@ } }, "slugify": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.2.9.tgz", - "integrity": "sha512-n0cdJ+kN3slJu8SbZXt/EHjljBqF6MxvMGSg/NPpBzoY7yyXoH38wp/ox20a1JaG1KgmdTN5Lf3aS9+xB2Y2aQ==" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.3.0.tgz", + "integrity": "sha512-vvz+9ANt7CtdTHwJpfrsHOnGkgxky+CUPnvtzDZBZYFo/H/CdZkd5lJL7z7RqtH/x9QW/ItYYfHlcGf38CBK1w==" }, "snapdragon": { "version": "0.8.2", @@ -17020,23 +17262,30 @@ } }, "sntp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", - "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz", + "integrity": "sha1-+4hfGLDzqtGJ+CSGJTa87ux1CQA=", "requires": { - "hoek": "4.x.x" + "hoek": "0.9.x" + }, + "dependencies": { + "hoek": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz", + "integrity": "sha1-PTIkYrrfB3Fup+uFuviAec3c5QU=" + } } }, "socket.io": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.1.0.tgz", - "integrity": "sha512-KS+3CNWWNtLbVN5j0/B+1hjxRzey+oTK6ejpAOoxMZis6aXeB8cUtfuvjHl97tuZx+t/qD/VyqFMjuzu2Js6uQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.1.1.tgz", + "integrity": "sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA==", "requires": { "debug": "~3.1.0", "engine.io": "~3.2.0", "has-binary2": "~1.0.2", "socket.io-adapter": "~1.1.0", - "socket.io-client": "2.1.0", + "socket.io-client": "2.1.1", "socket.io-parser": "~3.2.0" } }, @@ -17046,9 +17295,9 @@ "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=" }, "socket.io-client": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.0.tgz", - "integrity": "sha512-TvKPpL0cBON5LduQfR8Rxrr+ktj70bLXGvqHCL3er5avBXruB3gpnbaud5ikFYVfANH1gCABAvo0qN8Axpg2ew==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz", + "integrity": "sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ==", "requires": { "backo2": "1.0.2", "base64-arraybuffer": "0.1.5", @@ -17089,11 +17338,11 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, "source-map-resolve": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.1.tgz", - "integrity": "sha512-0KW2wvzfxm8NCTb30z0LMNyPqWCdDGE2viwzUaucqJdkTRXtZiSY3I+2A6nVAjmdOy0I4gU8DwnVVGsk9jvP2A==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", "requires": { - "atob": "^2.0.0", + "atob": "^2.1.1", "decode-uri-component": "^0.2.0", "resolve-url": "^0.2.1", "source-map-url": "^0.4.0", @@ -17101,9 +17350,9 @@ } }, "source-map-support": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.5.tgz", - "integrity": "sha512-mR7/Nd5l1z6g99010shcXJiNEaf3fEtmLhRB/sBcQVJGodcHCULPp2y4Sfa43Kv2zq7T+Izmfp/WHCR6dYkQCA==", + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.6.tgz", + "integrity": "sha512-N4KXEz7jcKqPf2b2vZF11lQIz9W5ZMuUcIOGj243lduidkf2fjkVKJS9vNxVWn3u/uxX38AcE8U9nnH9FPcq+g==", "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -17677,9 +17926,9 @@ } }, "stringstream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", + "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==" }, "strip-ansi": { "version": "3.0.1", @@ -17885,9 +18134,9 @@ "integrity": "sha1-cAcEaNbSl3ylI3suUZyn0Gouo/0=" }, "swagger-ui-express": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-3.0.8.tgz", - "integrity": "sha1-dbSkJx9Q7EDHdLfmbgh3jbJnBJ8=" + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-3.0.9.tgz", + "integrity": "sha1-6SqsKdtjjEMX4thy7yFfMwppP1c=" }, "symbol-tree": { "version": "3.2.2", @@ -17940,16 +18189,16 @@ } }, "tar": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.1.tgz", - "integrity": "sha512-O+v1r9yN4tOsvl90p5HAP4AEqbYhx4036AGMm075fH9F8Qwi3oJ+v4u50FkT/KkvywNGtwkk0zRI+8eYm1X/xg==", + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.2.tgz", + "integrity": "sha512-BfkE9CciGGgDsATqkikUHrQrraBCO+ke/1f6SFAEMnxyyfN9lxC+nW1NFWMpqH865DhHIy9vQi682gk1X7friw==", "requires": { "chownr": "^1.0.1", "fs-minipass": "^1.2.5", "minipass": "^2.2.4", "minizlib": "^1.1.0", "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.1", + "safe-buffer": "^5.1.2", "yallist": "^3.0.2" }, "dependencies": { @@ -17961,15 +18210,15 @@ } }, "tar-stream": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.0.tgz", - "integrity": "sha512-lh2iAPG/BHNmN6WB9Ybdynk9rEJ5GD/dy4zscHmVlwa1dq2tpE+BH78i5vjYwYVWEaOXGBjzxr89aVACF17Cpw==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.1.tgz", + "integrity": "sha512-IFLM5wp3QrJODQFPm6/to3LJZrONdBY/otxcvDIQzu217zKye6yVR3hhi9lAjrC2Z+m/j5oDxMPb1qcd8cIvpA==", "requires": { "bl": "^1.0.0", "buffer-alloc": "^1.1.0", "end-of-stream": "^1.0.0", "fs-constants": "^1.0.0", - "readable-stream": "^2.0.0", + "readable-stream": "^2.3.0", "to-buffer": "^1.1.0", "xtend": "^4.0.0" } @@ -18262,9 +18511,9 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "uglify-js": { - "version": "3.3.23", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.23.tgz", - "integrity": "sha512-Ks+KqLGDsYn4z+pU7JsKCzC0T3mPYl+rU+VcPZiQOazjE4Uqi4UCRY3qPMDbJi7ze37n1lDXj3biz1ik93vqvw==", + "version": "3.3.26", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.26.tgz", + "integrity": "sha512-XHxutZNxbx0UnqNUrjL/wvABLxirEYpbAnjCWGakPfQRJbbAGF2dI+YYw300F5mYKm7zBtgYiw3kOiQFobzglQ==", "requires": { "commander": "~2.15.0", "source-map": "~0.6.1" @@ -18417,9 +18666,9 @@ "integrity": "sha1-uYTwh3/AqJwsdzzB73tbIytbBv4=" }, "upath": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.0.5.tgz", - "integrity": "sha512-qbKn90aDQ0YEwvXoLqj0oiuUYroLX2lVHZ+b+xwjozFasAOC4GneDq5+OaIG5Zj+jFmbz/uO+f7a9qxjktJQww==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", + "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==" }, "uri-path": { "version": "1.0.0", @@ -18722,6 +18971,13 @@ "integrity": "sha512-jLBwwKUhi8WtBfsMQlL4bUUcT8sMkAtQinscJAe/M4KHCkHuUJAF6vuB0tueNIw4c8ziO6AkRmgY+jL3a0iiPw==", "requires": { "iconv-lite": "0.4.19" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" + } } }, "whatwg-mimetype": { @@ -19181,14 +19437,21 @@ "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" }, "z-schema": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-3.20.0.tgz", - "integrity": "sha512-9opdfBBL7+6L6rryjV0XVTvgv2SqC8kdUvSelx2pO+hOC0ZBoq/rxgvry1tyUYW33ea50ZOrg3Keq7dXmUxcnQ==", + "version": "3.22.0", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-3.22.0.tgz", + "integrity": "sha512-Oq82unxX2PTcJ031gFGcksDHE5PNBs5CbcQ1tbre0Sl4Mu5habZTVmEAkuZS4cK//VgIdNg9UG9PMgMlN6KmiA==", "requires": { "commander": "^2.7.1", "lodash.get": "^4.0.0", "lodash.isequal": "^4.0.0", - "validator": "^9.0.0" + "validator": "^10.0.0" + }, + "dependencies": { + "validator": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-10.2.0.tgz", + "integrity": "sha512-gz/uknWtNfZTj1BLUzYHDxOoiQ7A4wZ6xPuuE6RpxswR4cNyT4I5kN9jmU0AQr7IBEap9vfYChI2TpssTN6Itg==" + } } }, "zip-stream": { diff --git a/public/app/js/controllers/social/timeline_controller.js b/public/app/js/controllers/social/timeline_controller.js index f7fe5422..f2bbd2a4 100644 --- a/public/app/js/controllers/social/timeline_controller.js +++ b/public/app/js/controllers/social/timeline_controller.js @@ -2,7 +2,7 @@ angular.module("dendroApp.controllers") /** * Project administration controller */ - .controller("timelineCtrl", function ($scope, $http, $filter, usersService, timelineService, projectsService, $window, $element, usSpinnerService) + .controller("timelineCtrl", function ($scope, $http, $filter, usersService, timelineService, projectsService, $window, $element, usSpinnerService, moment) { $scope.myTab = $element; $scope.posts = []; @@ -72,6 +72,11 @@ angular.module("dendroApp.controllers") }); }; + $scope.returnTimeElapsedHumanized = function (dateString) { + //return moment(new Date(dateString)).fromNow(); + return moment(new Date(dateString)).calendar(); + }; + // THIS IS THE FUNCTION THAT GETS THE postsURIs for the timeline $scope.get_all_posts = function (currentPage) { diff --git a/public/app/views/social/partial/authorInformationPartial.html b/public/app/views/social/partial/authorInformationPartial.html index 125a8876..49420478 100644 --- a/public/app/views/social/partial/authorInformationPartial.html +++ b/public/app/views/social/partial/authorInformationPartial.html @@ -2,7 +2,8 @@ -

{{postsContents[postUri].ddr.modified | date : "dd/MMM/yyyy"}}

+ +

{{returnTimeElapsedHumanized(postsContents[postUri].ddr.modified)}}

In project {{fullProjectsInfo[postsContents[postUri].ddr.projectUri].title}}

{{fullUsersInfo[postsContents[postUri].dcterms.creator].ddr.username}} diff --git a/public/bower.json b/public/bower.json index 619141bd..7ab9909e 100644 --- a/public/bower.json +++ b/public/bower.json @@ -24,7 +24,7 @@ "angular-mocks": "1.6.1", "angular-resource": "1.6.1", "angular-route": "1.6.1", - "angular-sanitize": "^1.6.1", + "angular-sanitize": "1.6.1", "angular-touch": "1.6.1", "angular-loading-bar": "^0.8.0", "angular-ui-tree": "^2.15.0", diff --git a/src/bootup/models/shibboleth/shibboleth.js b/src/bootup/models/shibboleth/shibboleth.js index e3189fad..f313fcb4 100644 --- a/src/bootup/models/shibboleth/shibboleth.js +++ b/src/bootup/models/shibboleth/shibboleth.js @@ -27,9 +27,15 @@ class Shibboleth this.__cert = shibbolethConfig.cert; */ + /* this.__idp_cert = fs.readFileSync(shibbolethConfig.idp_cert_path); this.__key = fs.readFileSync(shibbolethConfig.key_path); this.__cert = fs.readFileSync(shibbolethConfig.cert_path); + */ + this.__idp_cert = fs.readFileSync(shibbolethConfig.idp_cert_path, "utf8"); + this.__key = fs.readFileSync(shibbolethConfig.key_path, "utf8"); + this.__cert = fs.readFileSync(shibbolethConfig.cert_path, "utf8"); + console.log("Done!"); } catch (error) { @@ -46,6 +52,77 @@ class Shibboleth Logger.log("info", "Num connectedSockets for user " + self.__userUri + " : " + self.__sockets.length); }; */ + + registerAuthenticationRoutes (app, passport) + { + let saml = require("passport-saml"); + let samlStrategy = new saml.Strategy({ + // URL that goes from the Identity Provider -> Service Provider + callbackUrl: this.__CALLBACK_URL, + // URL that goes from the Service Provider -> Identity Provider + entryPoint: this.__ENTRY_POINT, + // Usually specified as `/shibboleth` from site root + issuer: this.__ISSUER, + identifierFormat: null, + // Service Provider private key + decryptionPvk: this.__key, + // Service Provider Certificate + privateCert: this.__key, + // Identity Provider's public key + cert: this.__idp_cert, + validateInResponseTo: false, + disableRequestedAuthnContext: true + }, function(profile, done) { + return done(null, profile); + }); + + passport.use(samlStrategy); + + function ensureAuthenticated(req, res, next) { + if (req.isAuthenticated()) + return next(); + else + return res.redirect("/Shibboleth/login"); + } + + app.get("/Shibboleth", + ensureAuthenticated, + function(req, res) { + res.send('Authenticated'); + } + ); + + app.get("/Shibboleth/login", + passport.authenticate("saml", { failureRedirect: "/login/fail" }), + function (req, res) { + res.redirect("/"); + } + ); + + app.post("/Shibboleth/login/callback", + passport.authenticate("saml", { failureRedirect: "/login/fail" }), + function(req, res) { + console.log("will check req.user!!"); + console.log(req.user); + //TODO login or register user in DENDRO here + res.redirect("/"); + } + ); + + app.get("/Shibboleth/login/fail", + function(req, res) { + console.log("Login failed!"); + res.status(401).send("Login failed"); + } + ); + + app.get('/Shibboleth.sso/Metadata', + function(req, res) { + res.type('application/xml'); + res.status(200).send(samlStrategy.generateServiceProviderMetadata(this.__cert)); + } + ); + } } module.exports.Shibboleth = Shibboleth; diff --git a/src/bootup/routes/load_logic_routes.js b/src/bootup/routes/load_logic_routes.js index b7e5a5b0..6c43cb39 100644 --- a/src/bootup/routes/load_logic_routes.js +++ b/src/bootup/routes/load_logic_routes.js @@ -231,11 +231,13 @@ const loadRoutes = function (app, callback) if(!isNull(Config.authentication.shibbolethUP)) { - let saml = require("passport-saml"); - console.log("This is a shibbolethUP config: " + JSON.stringify(Config.authentication.shibbolethUP)); + //let saml = require("passport-saml"); + //console.log("This is a shibbolethUP config: " + JSON.stringify(Config.authentication.shibbolethUP)); if(!isNull(Config.authentication.shibbolethUP.enabled) && Config.authentication.shibbolethUP.enabled === true) { let newShibboleth = new Shibboleth(Config.authentication.shibbolethUP); + newShibboleth.registerAuthenticationRoutes(app, passport); + /* let samlStrategy = new saml.Strategy({ // URL that goes from the Identity Provider -> Service Provider callbackUrl: newShibboleth.__CALLBACK_URL, @@ -282,12 +284,16 @@ const loadRoutes = function (app, callback) app.post("/login/callback", passport.authenticate("saml", { failureRedirect: "/login/fail" }), function(req, res) { + console.log("will check req.user!!"); + console.log(req.user); + //TODO login or register user in DENDRO here res.redirect("/"); } ); app.get("/login/fail", function(req, res) { + console.log("Login failed!"); res.status(401).send("Login failed"); } ); @@ -299,7 +305,7 @@ const loadRoutes = function (app, callback) res.status(200).send(samlStrategy.generateServiceProviderMetadata(newShibboleth.__cert)); } ); - + */ } console.log("Ended!"); } diff --git a/src/views/auth/login.ejs b/src/views/auth/login.ejs index 473d32de..a7487310 100644 --- a/src/views/auth/login.ejs +++ b/src/views/auth/login.ejs @@ -89,7 +89,7 @@ <% } %> <%if (Config.authentication.shibbolethUP.enabled) { %> - <%= Config.authentication.shibbolethUP.button_text %> + <%= Config.authentication.shibbolethUP.button_text %> <% } %> From 45e550c0fc65ef67b6e03bee1dbc688f206b4595 Mon Sep 17 00:00:00 2001 From: Nelson Pereira Date: Tue, 22 May 2018 15:14:55 +0100 Subject: [PATCH 06/21] Changed console.log calls to Logger --- src/bootup/models/shibboleth/shibboleth.js | 32 ++++------------------ 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/src/bootup/models/shibboleth/shibboleth.js b/src/bootup/models/shibboleth/shibboleth.js index f313fcb4..553bfa74 100644 --- a/src/bootup/models/shibboleth/shibboleth.js +++ b/src/bootup/models/shibboleth/shibboleth.js @@ -21,21 +21,9 @@ class Shibboleth this.__SESSION_SECRET = shibbolethConfig.SESSION_SECRET; this.__button_text = shibbolethConfig.button_text; - /* - this.__idp_cert = shibbolethConfig.idp_cert; - this.__key = shibbolethConfig.key; - this.__cert = shibbolethConfig.cert; - */ - - /* - this.__idp_cert = fs.readFileSync(shibbolethConfig.idp_cert_path); - this.__key = fs.readFileSync(shibbolethConfig.key_path); - this.__cert = fs.readFileSync(shibbolethConfig.cert_path); - */ this.__idp_cert = fs.readFileSync(shibbolethConfig.idp_cert_path, "utf8"); this.__key = fs.readFileSync(shibbolethConfig.key_path, "utf8"); this.__cert = fs.readFileSync(shibbolethConfig.cert_path, "utf8"); - console.log("Done!"); } catch (error) { @@ -43,16 +31,6 @@ class Shibboleth } } - - /* - addNewSocket (newSocket) - { - let self = this; - self.__sockets.push(newSocket); - Logger.log("info", "Num connectedSockets for user " + self.__userUri + " : " + self.__sockets.length); - }; - */ - registerAuthenticationRoutes (app, passport) { let saml = require("passport-saml"); @@ -93,17 +71,17 @@ class Shibboleth ); app.get("/Shibboleth/login", - passport.authenticate("saml", { failureRedirect: "/login/fail" }), + passport.authenticate("saml", { failureRedirect: "/Shibboleth/login/fail" }), function (req, res) { res.redirect("/"); } ); app.post("/Shibboleth/login/callback", - passport.authenticate("saml", { failureRedirect: "/login/fail" }), + passport.authenticate("saml", { failureRedirect: "/Shibboleth/login/fail" }), function(req, res) { - console.log("will check req.user!!"); - console.log(req.user); + Logger.log("info", "will check req.user!!"); + Logger.log("info", req.user); //TODO login or register user in DENDRO here res.redirect("/"); } @@ -111,7 +89,7 @@ class Shibboleth app.get("/Shibboleth/login/fail", function(req, res) { - console.log("Login failed!"); + Logger.log("Login failed!"); res.status(401).send("Login failed"); } ); From 42f1cc9e9797d7232e2c7da4411ad87116db740a Mon Sep 17 00:00:00 2001 From: Nelson Pereira Date: Thu, 24 May 2018 10:51:08 +0100 Subject: [PATCH 07/21] first iteration of shibboleth sign-in working --- conf/deployment_configs.json | 6 +- .../partial/authorInformationPartial.html | 4 +- src/bootup/models/shibboleth/shibboleth.js | 304 ++++++++++++++---- src/bootup/models/shibboleth/shibboleth_UP.js | 99 ++++++ src/bootup/routes/load_logic_routes.js | 79 +---- src/models/meta/elements.js | 6 + 6 files changed, 353 insertions(+), 145 deletions(-) create mode 100644 src/bootup/models/shibboleth/shibboleth_UP.js diff --git a/conf/deployment_configs.json b/conf/deployment_configs.json index 5531828a..27dae400 100644 --- a/conf/deployment_configs.json +++ b/conf/deployment_configs.json @@ -389,10 +389,10 @@ "shibbolethUP": { "enabled": true, - "CALLBACK_URL": "http://207.154.250.99:3007/Shibboleth/login/callback", - "URL": "http://207.154.250.99:3007/Shibboleth", + "CALLBACK_URL": "http://bfdbeb54.ngrok.io/Shibboleth/login/callback", + "URL": "http://bfdbeb54.ngrok.io/Shibboleth", "ENTRY_POINT": "https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO", - "ISSUER": "https://207.154.250.99/shibboleth", + "ISSUER": "https://bfdbeb54.ngrok.io/shibboleth", "SESSION_SECRET": "secret123", "button_text": "Sign-in with shibboleth UP", "idp_cert_path": "/Users/nelsonpereira/Desktop/infolaRepos/dendroRepo/dendro/conf/cert/idp_cert.pem", diff --git a/public/app/views/social/partial/authorInformationPartial.html b/public/app/views/social/partial/authorInformationPartial.html index 49420478..119e6504 100644 --- a/public/app/views/social/partial/authorInformationPartial.html +++ b/public/app/views/social/partial/authorInformationPartial.html @@ -2,8 +2,8 @@ - -

{{returnTimeElapsedHumanized(postsContents[postUri].ddr.modified)}}

+

{{postsContents[postUri].ddr.modified | date : "dd/MMM/yyyy"}}

+

In project {{fullProjectsInfo[postsContents[postUri].ddr.projectUri].title}}

{{fullUsersInfo[postsContents[postUri].dcterms.creator].ddr.username}} diff --git a/src/bootup/models/shibboleth/shibboleth.js b/src/bootup/models/shibboleth/shibboleth.js index 553bfa74..a4f7678f 100644 --- a/src/bootup/models/shibboleth/shibboleth.js +++ b/src/bootup/models/shibboleth/shibboleth.js @@ -4,6 +4,8 @@ const path = require("path"); const Pathfinder = global.Pathfinder; const isNull = require(Pathfinder.absPathInSrcFolder("/utils/null.js")).isNull; const Logger = require(Pathfinder.absPathInSrcFolder("utils/logger.js")).Logger; +const User = require(Pathfinder.absPathInSrcFolder("models/user.js")).User; +const UploadManager = require(Pathfinder.absPathInSrcFolder("/models/uploads/upload_manager.js")).UploadManager; const Config = require(Pathfinder.absPathInSrcFolder("models/meta/config.js")).Config; const _ = require("underscore"); @@ -15,15 +17,94 @@ class Shibboleth { try { - this.__CALLBACK_URL = shibbolethConfig.CALLBACK_URL; - this.__ENTRY_POINT = shibbolethConfig.ENTRY_POINT; - this.__ISSUER = shibbolethConfig.ISSUER; - this.__SESSION_SECRET = shibbolethConfig.SESSION_SECRET; - this.__button_text = shibbolethConfig.button_text; - - this.__idp_cert = fs.readFileSync(shibbolethConfig.idp_cert_path, "utf8"); - this.__key = fs.readFileSync(shibbolethConfig.key_path, "utf8"); - this.__cert = fs.readFileSync(shibbolethConfig.cert_path, "utf8"); + let __CALLBACK_URL = shibbolethConfig.CALLBACK_URL; + let __ENTRY_POINT = shibbolethConfig.ENTRY_POINT; + let __ISSUER = shibbolethConfig.ISSUER; + let __SESSION_SECRET = shibbolethConfig.SESSION_SECRET; + let __button_text = shibbolethConfig.button_text; + + let __idp_cert = fs.readFileSync(shibbolethConfig.idp_cert_path, "utf8"); + let __key = fs.readFileSync(shibbolethConfig.key_path, "utf8"); + let __cert = fs.readFileSync(shibbolethConfig.cert_path, "utf8"); + + let __mboxKey = null; + let __firstNameKey = null; + let __surnameKey = null; + let __usernameKey = null; + + /***GETS***/ + this.getCallbackURl = function () + { + return __CALLBACK_URL; + }; + + this.getEntryPoint = function () + { + return __ENTRY_POINT; + }; + + this.getIssuer = function () + { + return __ISSUER; + }; + + this.getSessionSecret = function () + { + return __SESSION_SECRET; + }; + + this.getButtonText = function () + { + return __button_text; + }; + + this.getIdpCert = function () + { + return __idp_cert; + }; + + this.getKey = function () + { + return __key; + }; + + this.getCert = function () + { + return __cert; + }; + + this.getMBoxKey = function () { + return __mboxKey; + }; + + this.getFirstNameKey = function () { + return __firstNameKey; + }; + + this.getSurnameKey = function () { + return __surnameKey; + }; + + this.getUsernameKey = function () { + return __usernameKey; + }; + + /***SETS***/ + this.setMBoxKey = function (mboxKey) { + __mboxKey = mboxKey; + }; + + this.setFirstNameKey = function (firstNameKey) { + __firstNameKey = firstNameKey; + }; + + this.setSurnameKey = function (surnameKey) { + __surnameKey = surnameKey + }; + + this.setUsernameKey = function (usernameKey) { + __usernameKey = usernameKey; + }; } catch (error) { @@ -33,73 +114,166 @@ class Shibboleth registerAuthenticationRoutes (app, passport) { - let saml = require("passport-saml"); - let samlStrategy = new saml.Strategy({ - // URL that goes from the Identity Provider -> Service Provider - callbackUrl: this.__CALLBACK_URL, - // URL that goes from the Service Provider -> Identity Provider - entryPoint: this.__ENTRY_POINT, - // Usually specified as `/shibboleth` from site root - issuer: this.__ISSUER, - identifierFormat: null, - // Service Provider private key - decryptionPvk: this.__key, - // Service Provider Certificate - privateCert: this.__key, - // Identity Provider's public key - cert: this.__idp_cert, - validateInResponseTo: false, - disableRequestedAuthnContext: true - }, function(profile, done) { - return done(null, profile); - }); - passport.use(samlStrategy); + } - function ensureAuthenticated(req, res, next) { - if (req.isAuthenticated()) - return next(); - else - return res.redirect("/Shibboleth/login"); - } + loginUser(user, req, res) + { + req.logIn(user, function (err) + { + if (isNull(err)) + { + req.session.isAdmin = false; + req.session.upload_manager = new UploadManager(user.ddr.username); + + req.flash("success", "Welcome, " + user.foaf.firstName + " " + user.foaf.surname + "."); - app.get("/Shibboleth", - ensureAuthenticated, - function(req, res) { - res.send('Authenticated'); + if (Config.debug.permissions.log_authorizations) + { + Logger.log("User " + user.ddr.username + " signed in."); + } + + if (req.body.redirect) + { + res.redirect(req.body.redirect); + } + else + { + res.redirect("/projects/my"); + } + } + else + { + req.flash("success", "There was an error signing you in."); + Logger.log("Error signing in user " + JSON.stringify(err)); + throw err; } - ); + }); + } - app.get("/Shibboleth/login", - passport.authenticate("saml", { failureRedirect: "/Shibboleth/login/fail" }), - function (req, res) { - res.redirect("/"); + auth(req, res) + { + const self = this; + self.getMatchingUserInDendro(req.user, function (err, newUser) { + if(!isNull(err)) + { + Logger.log("error", "Error signing in user " + JSON.stringify(newUser)); + req.flash("success", "There was an error signing you in."); + return res.redirect("/"); } - ); - - app.post("/Shibboleth/login/callback", - passport.authenticate("saml", { failureRedirect: "/Shibboleth/login/fail" }), - function(req, res) { - Logger.log("info", "will check req.user!!"); - Logger.log("info", req.user); - //TODO login or register user in DENDRO here - res.redirect("/"); + else if(isNull(newUser)) + { + Logger.log("error", "Error signing in user " + "newUser is null"); + req.flash("success", "There was an error signing you in."); + return res.redirect("/"); + } + else + { + self.loginUser(newUser, req, res); } - ); + }); + } - app.get("/Shibboleth/login/fail", - function(req, res) { - Logger.log("Login failed!"); - res.status(401).send("Login failed"); + getMatchingUserInDendro(shibbolethUser, callback) + { + const validUserKeysAndValues = function (mboxKey, firstNameKey, surnameKey, usernameKey, shibbolethUser) + { + let isValid = false; + if(!isNull(mboxKey) && !isNull(firstNameKey) && !isNull(surnameKey) && !isNull(usernameKey) && !isNull(shibbolethUser)) + { + let mbox = shibbolethUser[mboxKey]; + let firstName = shibbolethUser[firstNameKey]; + let surname = shibbolethUser[surnameKey]; + let username = shibbolethUser[usernameKey]; + if(!isNull(mbox) && !isNull(firstName) && !isNull(surname) && !isNull(username)) + { + isValid = true; + } } - ); + return isValid; + }; + + let self = this; + if(!isNull(shibbolethUser)) + { + let mboxKey = self.getMBoxKey(); + let firstNameKey = self.getFirstNameKey(); + let surnameKey = self.getSurnameKey(); + let usernameKey = self.getUsernameKey(); - app.get('/Shibboleth.sso/Metadata', - function(req, res) { - res.type('application/xml'); - res.status(200).send(samlStrategy.generateServiceProviderMetadata(this.__cert)); + if(validUserKeysAndValues(mboxKey, firstNameKey, surnameKey, usernameKey, shibbolethUser) === true) + { + let mbox = shibbolethUser[mboxKey]; + let firstName = shibbolethUser[firstNameKey]; + let surname = shibbolethUser[surnameKey]; + let username = shibbolethUser[usernameKey]; + User.findByEmail(mbox, function (err, user) { + if(isNull(err)) + { + if(isNull(user)) + { + let password = self.constructor.name + "__" + new Date().getTime(); + let isShibbolethUser = true; + User.createAndInsertFromObject({ + foaf: { + mbox: mbox, + firstName: firstName, + surname: surname + }, + ddr: { + username: username, + password: password, + isShibbolethUser: isShibbolethUser + } + }, + function (err, newUser) + { + if(!isNull(err)) + { + const errorMessage = "Error when creating a new user for the first time in Dendro from a Shibboleth source, error: " + JSON.stringify(err); + Logger.log("error", errorMessage); + return callback(true, err); + } + else if(isNull(newUser)) + { + const errorMessage = "Error when creating a new user for the first time in Dendro from a Shibboleth source, error: " + "newUser is null"; + Logger.log("error", errorMessage); + const err = new Error(errorMessage); + return callback(true, err); + } + else + { + return callback(err, newUser); + } + }); + } + else + { + return callback(null, user); + } + } + else + { + Logger.log("error", "Error at getMatchingUserInDendro: " + JSON.stringify(err)); + return callback(true, err) + } + }); } - ); + else + { + const errorMessage = "Invalid user keys and values at getMatchingUserInDendro"; + const err = new Error(errorMessage); + Logger.log("error", errorMessage); + return callback(true, err) + } + } + else + { + const errorMessage = "Shibboleth user object is missing!"; + const error = new Error(errorMessage); + Logger.log("error", errorMessage); + return callback(true, error); + } } } diff --git a/src/bootup/models/shibboleth/shibboleth_UP.js b/src/bootup/models/shibboleth/shibboleth_UP.js new file mode 100644 index 00000000..1bb11a0d --- /dev/null +++ b/src/bootup/models/shibboleth/shibboleth_UP.js @@ -0,0 +1,99 @@ +const slug = require("slug"); +const path = require("path"); + +const Pathfinder = global.Pathfinder; +const isNull = require(Pathfinder.absPathInSrcFolder("/utils/null.js")).isNull; +const Logger = require(Pathfinder.absPathInSrcFolder("utils/logger.js")).Logger; + +const Config = require(Pathfinder.absPathInSrcFolder("models/meta/config.js")).Config; +const Shibboleth = require(Pathfinder.absPathInSrcFolder("bootup/models/shibboleth/shibboleth.js")).Shibboleth; +const User = require(Pathfinder.absPathInSrcFolder("models/user.js")).User; +const UploadManager = require(Pathfinder.absPathInSrcFolder("/models/uploads/upload_manager.js")).UploadManager; +const _ = require("underscore"); +const fs = require("fs"); + +class ShibbolethUP extends Shibboleth +{ + constructor(shibbolethConfig) + { + super(shibbolethConfig); + const self = this; + self.setMBoxKey("urn:oid:1.3.6.1.4.1.5923.1.1.1.6"); + self.setFirstNameKey("urn:oid:2.5.4.42"); + self.setSurnameKey("urn:oid:2.5.4.4"); + self.setUsernameKey("urn:oid:1.3.6.1.4.1.5923.1.1.1.6"); + } + + registerAuthenticationRoutes(app, passport) + { + const self = this; + let saml = require("passport-saml"); + let samlStrategy = new saml.Strategy({ + // URL that goes from the Identity Provider -> Service Provider + callbackUrl: self.getCallbackURl(), + // URL that goes from the Service Provider -> Identity Provider + entryPoint: self.getEntryPoint(), + // Usually specified as `/shibboleth` from site root + issuer: self.getIssuer(), + identifierFormat: null, + // Service Provider private key + decryptionPvk: self.getKey(), + // Service Provider Certificate + privateCert: self.getKey(), + // Identity Provider's public key + cert: self.getIdpCert(), + validateInResponseTo: false, + disableRequestedAuthnContext: true + }, function(profile, done) { + return done(null, profile); + }); + + passport.use(samlStrategy); + + function ensureAuthenticated(req, res, next) { + if (req.isAuthenticated()) + return next(); + else + return res.redirect("/Shibboleth/login"); + } + + app.get("/Shibboleth", + ensureAuthenticated, + function(req, res) { + res.send('Authenticated'); + } + ); + + app.get("/Shibboleth/login", + passport.authenticate("saml", { failureRedirect: "/Shibboleth/login/fail" }), + function (req, res) { + res.redirect("/"); + } + ); + + app.post("/Shibboleth/login/callback", + passport.authenticate("saml", { failureRedirect: "/Shibboleth/login/fail" }), + function(req, res) { + Logger.log("info", "will check req.user!!"); + Logger.log("info", req.user); + self.auth(req, res); + } + ); + + app.get("/Shibboleth/login/fail", + function(req, res) { + Logger.log("Login failed!"); + res.status(401).send("Login failed"); + } + ); + + app.get("/Shibboleth.sso/Metadata", + function(req, res) { + res.type("application/xml"); + res.status(200).send(samlStrategy.generateServiceProviderMetadata(self.getCert())); + } + ); + } +} + +module.exports.ShibbolethUP = ShibbolethUP; \ No newline at end of file diff --git a/src/bootup/routes/load_logic_routes.js b/src/bootup/routes/load_logic_routes.js index 6c43cb39..131e8479 100644 --- a/src/bootup/routes/load_logic_routes.js +++ b/src/bootup/routes/load_logic_routes.js @@ -31,7 +31,8 @@ const datasets = require(Pathfinder.absPathInSrcFolder("/controllers/datasets")) const posts = require(Pathfinder.absPathInSrcFolder("/controllers/posts")); const timeline = require(Pathfinder.absPathInSrcFolder("/controllers/timeline")); const notifications = require(Pathfinder.absPathInSrcFolder("/controllers/notifications")); -const Shibboleth = require(Pathfinder.absPathInSrcFolder("bootup/models/shibboleth/shibboleth.js")).Shibboleth; +//const Shibboleth = require(Pathfinder.absPathInSrcFolder("bootup/models/shibboleth/shibboleth.js")).Shibboleth; +const ShibbolethUP = require(Pathfinder.absPathInSrcFolder("bootup/models/shibboleth/shibboleth_UP.js")).ShibbolethUP; let recommendation; @@ -231,83 +232,11 @@ const loadRoutes = function (app, callback) if(!isNull(Config.authentication.shibbolethUP)) { - //let saml = require("passport-saml"); - //console.log("This is a shibbolethUP config: " + JSON.stringify(Config.authentication.shibbolethUP)); if(!isNull(Config.authentication.shibbolethUP.enabled) && Config.authentication.shibbolethUP.enabled === true) { - let newShibboleth = new Shibboleth(Config.authentication.shibbolethUP); - newShibboleth.registerAuthenticationRoutes(app, passport); - /* - let samlStrategy = new saml.Strategy({ - // URL that goes from the Identity Provider -> Service Provider - callbackUrl: newShibboleth.__CALLBACK_URL, - // URL that goes from the Service Provider -> Identity Provider - entryPoint: newShibboleth.__ENTRY_POINT, - // Usually specified as `/shibboleth` from site root - issuer: newShibboleth.__ISSUER, - identifierFormat: null, - // Service Provider private key - decryptionPvk: newShibboleth.__key, - // Service Provider Certificate - privateCert: newShibboleth.__key, - // Identity Provider's public key - cert: newShibboleth.__idp_cert, - validateInResponseTo: false, - disableRequestedAuthnContext: true - }, function(profile, done) { - return done(null, profile); - }); - - passport.use(samlStrategy); - - function ensureAuthenticated(req, res, next) { - if (req.isAuthenticated()) - return next(); - else - return res.redirect("/login"); - } - - app.get("/", - ensureAuthenticated, - function(req, res) { - res.send('Authenticated'); - } - ); - - app.get("/login", - passport.authenticate("saml", { failureRedirect: "/login/fail" }), - function (req, res) { - res.redirect("/"); - } - ); - - app.post("/login/callback", - passport.authenticate("saml", { failureRedirect: "/login/fail" }), - function(req, res) { - console.log("will check req.user!!"); - console.log(req.user); - //TODO login or register user in DENDRO here - res.redirect("/"); - } - ); - - app.get("/login/fail", - function(req, res) { - console.log("Login failed!"); - res.status(401).send("Login failed"); - } - ); - - app.get('/Shibboleth.sso/Metadata', - function(req, res) { - res.type('application/xml'); - //res.status(200).send(samlStrategy.generateServiceProviderMetadata(fs.readFileSync(__dirname + '/cert/cert.pem', 'utf8'))); - res.status(200).send(samlStrategy.generateServiceProviderMetadata(newShibboleth.__cert)); - } - ); - */ + let newShibbolethUP = new ShibbolethUP(Config.authentication.shibbolethUP); + newShibbolethUP.registerAuthenticationRoutes(app, passport); } - console.log("Ended!"); } /** diff --git a/src/models/meta/elements.js b/src/models/meta/elements.js index 7d71467b..1e005a45 100644 --- a/src/models/meta/elements.js +++ b/src/models/meta/elements.js @@ -798,6 +798,12 @@ Elements.ontologies.foaf = */ Elements.ontologies.ddr = { + isShibbolethUser : + { + type: Elements.types.boolean, + private: true, + locked: true + }, hasErrors: { type: Elements.types.string, From f349db1e1718aed211f64e8f848227c1f39a07eb Mon Sep 17 00:00:00 2001 From: Nelson Pereira Date: Thu, 24 May 2018 14:41:20 +0100 Subject: [PATCH 08/21] Shibboleth users are now blocked from editing their profile in Dendro, they can only change their Avatar. --- src/controllers/users.js | 219 +++++++++++++++++++++------------------ src/views/users/edit.ejs | 157 ++++++++++++++-------------- 2 files changed, 199 insertions(+), 177 deletions(-) diff --git a/src/controllers/users.js b/src/controllers/users.js index cc247c51..e2861585 100644 --- a/src/controllers/users.js +++ b/src/controllers/users.js @@ -732,6 +732,15 @@ var checkIfIsEmail = function (email) exports.edit = function (req, res, next) { + const isShibbolethUser = function (user) { + let result = false; + if(!isNull(user) && !isNull(user.ddr) && !isNull(user.ddr.isShibbolethUser) && user.ddr.isShibbolethUser === true) + { + result = true; + } + return result; + }; + let changedPassword = false; if (!isNull(req.user)) { @@ -739,130 +748,140 @@ exports.edit = function (req, res, next) { if (!err && !isNull(user)) { - async.series([ - function (callback) - { - if (!isNull(req.body.email) && checkIfIsEmail(req.body.email)) + if(isShibbolethUser(user) === false) + { + async.series([ + function (callback) { - user.foaf.mbox = req.body.email; - return callback(null, null); - } - let msg = "Invalid email format!"; - return callback(true, msg); - }, - function (callback) - { - if (!isNull(req.body.firstname)) + if (!isNull(req.body.email) && checkIfIsEmail(req.body.email)) + { + user.foaf.mbox = req.body.email; + return callback(null, null); + } + let msg = "Invalid email format!"; + return callback(true, msg); + }, + function (callback) { - user.foaf.firstName = req.body.firstname; - } - callback(null, null); - }, - function (callback) - { - if (!isNull(req.body.surname)) + if (!isNull(req.body.firstname)) + { + user.foaf.firstName = req.body.firstname; + } + callback(null, null); + }, + function (callback) { - user.foaf.surname = req.body.surname; - } - callback(null, null); - }, - function (callback) - { - if (!isNull(req.body.password) && !isNull(req.body.repeat_password) && req.body.password.length > 0 && req.body.repeat_password.length > 0) + if (!isNull(req.body.surname)) + { + user.foaf.surname = req.body.surname; + } + callback(null, null); + }, + function (callback) { - if (req.body.password === req.body.repeat_password && req.body.password.length >= 8) + if (!isNull(req.body.password) && !isNull(req.body.repeat_password) && req.body.password.length > 0 && req.body.repeat_password.length > 0) { - const bcrypt = require("bcryptjs"); - bcrypt.hash(req.body.password, user.ddr.salt, function (err, hashedPassword) + if (req.body.password === req.body.repeat_password && req.body.password.length >= 8) { - if (!err) + const bcrypt = require("bcryptjs"); + bcrypt.hash(req.body.password, user.ddr.salt, function (err, hashedPassword) { - user.ddr.password = hashedPassword; - changedPassword = true; - return callback(null, null); - } - let msg = "Error encrypting password"; + if (!err) + { + user.ddr.password = hashedPassword; + changedPassword = true; + return callback(null, null); + } + let msg = "Error encrypting password"; + Logger.log("error", msg); + /* req.flash('error', msg); + res.redirect('/me'); */ + return callback(true, msg); + }); + } + else + { + let msg = "Passwords fields must be the same and at least 8 characters in length!"; Logger.log("error", msg); - /* req.flash('error', msg); - res.redirect('/me'); */ + // req.flash('error', msg); + // res.redirect('/me'); return callback(true, msg); - }); + } } else { - let msg = "Passwords fields must be the same and at least 8 characters in length!"; - Logger.log("error", msg); - // req.flash('error', msg); - // res.redirect('/me'); - return callback(true, msg); + return callback(null, null); } } - else - { - return callback(null, null); - } - } - ], function (err, results) - { - if (!err) + ], function (err, results) { - user.save(function (err, editedUser) + if (!err) { - if (!err) + user.save(function (err, editedUser) { - let auth = require(Pathfinder.absPathInSrcFolder("/controllers/auth.js")); - req.flash("success", "User " + editedUser.ddr.username + " edited."); - // Logger.log("User " + editedUser.ddr.username + " edited."); - // res.redirect('/me'); - if (changedPassword) - { - req.flash("info", "Since you changed your password, you need to login again!"); - auth.logout(req, res); - } - else + if (!err) { - req.body.username = editedUser.ddr.username; - if (req.user instanceof User) + let auth = require(Pathfinder.absPathInSrcFolder("/controllers/auth.js")); + req.flash("success", "User " + editedUser.ddr.username + " edited."); + // Logger.log("User " + editedUser.ddr.username + " edited."); + // res.redirect('/me'); + if (changedPassword) { - req.logIn(user, function (err) - { - if (!err) - { - res.redirect("back"); - } - else - { - let msg = "Error updating user session. Error reported: " + JSON.stringify(err); - Logger.log("error", msg); - req.flash("error", msg); - auth.logout(req, res); - } - }); + req.flash("info", "Since you changed your password, you need to login again!"); + auth.logout(req, res); } else { - req.flash("info", "Session was lost! Please login again."); - auth.logout(req, res); + req.body.username = editedUser.ddr.username; + if (req.user instanceof User) + { + req.logIn(user, function (err) + { + if (!err) + { + res.redirect("back"); + } + else + { + let msg = "Error updating user session. Error reported: " + JSON.stringify(err); + Logger.log("error", msg); + req.flash("error", msg); + auth.logout(req, res); + } + }); + } + else + { + req.flash("info", "Session was lost! Please login again."); + auth.logout(req, res); + } } } - } - else - { - let msg = "Error editing user " + user.uri + ". Error reported :" + editedUser; - Logger.log("error", msg); - req.flash("error", msg); - res.redirect("/me"); - } - }); - } - else - { - let msg = "Error editing user " + user.uri + ". Error reported :" + JSON.stringify(results); - Logger.log("error", msg); - req.flash("error", msg); - res.redirect("/me"); - } - }); + else + { + let msg = "Error editing user " + user.uri + ". Error reported :" + editedUser; + Logger.log("error", msg); + req.flash("error", msg); + res.redirect("/me"); + } + }); + } + else + { + let msg = "Error editing user " + user.uri + ". Error reported :" + JSON.stringify(results); + Logger.log("error", msg); + req.flash("error", msg); + res.redirect("/me"); + } + }); + } + else + { + let msg = "Cannot edit a Shibboleth User"; + Logger.log("error", msg); + req.flash("error", msg); + res.redirect("/me"); + } } else { diff --git a/src/views/users/edit.ejs b/src/views/users/edit.ejs index 667a5498..515886b2 100644 --- a/src/views/users/edit.ejs +++ b/src/views/users/edit.ejs @@ -51,95 +51,98 @@
-
-
-
-
-
- -
- +

user.ddr.isShibbolethUser : <%=user.ddr.isShibbolethUser%>

+<%if(user.ddr.isShibbolethUser !==true){%> + +
+
+
+
+ +
+ value="joaorosilva@gmail.com" - <% } else {%> + <% } else {%> value="<%=locals.user.foaf.mbox%>" - <%}%> - name="email"> -

Your email address

+ <%}%> + name="email"> +

Your email address

+
-
-
- -
- +
+ +
+ value="jrocha" - <%}%> - name="password"> -

Your intended password, leave this field blank if you do not wish to change your password.

+ <%}%> + name="password"> +

Your intended password, leave this field blank if you do not wish to change your password.

+
-
-
- -
- - value="jrocha" - <%} %> - name="repeat_password"> -

Repeat your intended password, leave this field blank if you do not wish to change your password

+
+ +
+ + value="jrocha" + <%} %> + name="repeat_password"> +

Repeat your intended password, leave this field blank if you do not wish to change your password

+
-
-
- -
- - value="João" - <%} else {%> - value="<%=locals.user.foaf.firstName%>" - <%}%> - name="firstname"> -

Your first name

+
+ +
+ + value="João" + <%} else {%> + value="<%=locals.user.foaf.firstName%>" + <%}%> + name="firstname"> +

Your first name

+
-
-
- -
- - value="Rocha" - <%} else {%> - value="<%=locals.user.foaf.surname%>" - <%}%> - name="surname"> -

Your surname

+
+ +
+ + value="Rocha" + <%} else {%> + value="<%=locals.user.foaf.surname%>" + <%}%> + name="surname"> +

Your surname

+
-
- + +
-
- + +<%}%> <%- include ../layout/footer.ejs %> From 8c38dc6dadb9c8063ee2361118110c6d106e6b36 Mon Sep 17 00:00:00 2001 From: Nelson Pereira Date: Thu, 24 May 2018 16:28:45 +0100 Subject: [PATCH 09/21] Users authenticated via federated sign-in can only edit their avatar --- src/views/users/edit.ejs | 70 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 5 deletions(-) diff --git a/src/views/users/edit.ejs b/src/views/users/edit.ejs index 515886b2..190ff32f 100644 --- a/src/views/users/edit.ejs +++ b/src/views/users/edit.ejs @@ -1,8 +1,14 @@ <%- include ../layout/header.ejs %> -

- Editing user <%= user.foaf.firstName %> <%= user.foaf.surname %> -

+<%if(user.ddr.isShibbolethUser ===true){%> +

+ Editing user <%= user.foaf.firstName %> <%= user.foaf.surname %> Via Federated Sign-in! +

+<%}else {%> +

+ Editing user <%= user.foaf.firstName %> <%= user.foaf.surname %> +

+<%}%>
@@ -50,8 +56,6 @@
- -

user.ddr.isShibbolethUser : <%=user.ddr.isShibbolethUser%>

<%if(user.ddr.isShibbolethUser !==true){%>
@@ -142,6 +146,62 @@
+<%}else{%> +
+
+
+
+ +
+ + value="joaorosilva@gmail.com" + <% } else {%> + value="<%=locals.user.foaf.mbox%>" + <%}%> + name="email" disabled> +

Your email address

+
+
+
+ +
+ + value="João" + <%} else {%> + value="<%=locals.user.foaf.firstName%>" + <%}%> + name="firstname" disabled> +

Your first name

+
+
+
+ +
+ + value="Rocha" + <%} else {%> + value="<%=locals.user.foaf.surname%>" + <%}%> + name="surname" disabled> +

Your surname

+
+
+
+
+
<%}%> From 0ff7f6b0c5e1033b087b123de6a466d1faad683f Mon Sep 17 00:00:00 2001 From: Nelson Pereira Date: Thu, 24 May 2018 17:09:11 +0100 Subject: [PATCH 10/21] added the configuration "shibbolethUP" to the remaining configurations in the deployment_configs.json file --- conf/deployment_configs.json | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/conf/deployment_configs.json b/conf/deployment_configs.json index 27dae400..ef23f035 100644 --- a/conf/deployment_configs.json +++ b/conf/deployment_configs.json @@ -783,6 +783,18 @@ "entry_point": "https://openidp.feide.no/simplesaml/saml2/idp/SSOService.php", "issuer": "passport-saml", "button_text": "Sign-in with SIGARRA" + }, + "shibbolethUP": { + "enabled": false, + "CALLBACK_URL": "defaultString", + "URL": "defaultString", + "ENTRY_POINT": "defaultString", + "ISSUER": "defaultString", + "SESSION_SECRET": "defaultString", + "button_text": "Sign-in with shibboleth UP", + "idp_cert_path": "defaultString", + "key_path": "defaultString", + "cert_path": "defaultString" } }, "numCPUs": 1 @@ -1168,6 +1180,18 @@ "entry_point": "https://openidp.feide.no/simplesaml/saml2/idp/SSOService.php", "issuer": "passport-saml", "button_text": "Sign-in with SIGARRA" + }, + "shibbolethUP": { + "enabled": false, + "CALLBACK_URL": "defaultString", + "URL": "defaultString", + "ENTRY_POINT": "defaultString", + "ISSUER": "defaultString", + "SESSION_SECRET": "defaultString", + "button_text": "Sign-in with shibboleth UP", + "idp_cert_path": "defaultString", + "key_path": "defaultString", + "cert_path": "defaultString" } }, "numCPUs": 1 @@ -1553,6 +1577,18 @@ "entry_point": "https://openidp.feide.no/simplesaml/saml2/idp/SSOService.php", "issuer": "passport-saml", "button_text": "Sign-in with SIGARRA" + }, + "shibbolethUP": { + "enabled": false, + "CALLBACK_URL": "defaultString", + "URL": "defaultString", + "ENTRY_POINT": "defaultString", + "ISSUER": "defaultString", + "SESSION_SECRET": "defaultString", + "button_text": "Sign-in with shibboleth UP", + "idp_cert_path": "defaultString", + "key_path": "defaultString", + "cert_path": "defaultString" } }, "numCPUs": 1 From 475782c45dd0016f7071c1251e59ef8a8d28c4db Mon Sep 17 00:00:00 2001 From: Nelson Pereira Date: Fri, 25 May 2018 14:57:43 +0100 Subject: [PATCH 11/21] - Changed the name of the routes for ShibbolethUP - Replaced the call to "User.findByEmail" by "User.findByUsername" when looking/creating the corresponding Shibboleth user in Dendro. --- conf/deployment_configs.json | 70 +++++++++---------- src/bootup/models/shibboleth/shibboleth.js | 18 ++--- src/bootup/models/shibboleth/shibboleth_UP.js | 14 ++-- src/views/auth/login.ejs | 3 +- 4 files changed, 53 insertions(+), 52 deletions(-) diff --git a/conf/deployment_configs.json b/conf/deployment_configs.json index ef23f035..2c6c5e05 100644 --- a/conf/deployment_configs.json +++ b/conf/deployment_configs.json @@ -389,11 +389,11 @@ "shibbolethUP": { "enabled": true, - "CALLBACK_URL": "http://bfdbeb54.ngrok.io/Shibboleth/login/callback", - "URL": "http://bfdbeb54.ngrok.io/Shibboleth", - "ENTRY_POINT": "https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO", - "ISSUER": "https://bfdbeb54.ngrok.io/shibboleth", - "SESSION_SECRET": "secret123", + "callback_url": "http://6a8faf9c.ngrok.io/ShibbolethUP/login/callback", + "button_url": "http://6a8faf9c.ngrok.io/ShibbolethUP", + "entry_point": "https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO", + "issuer": "https://6a8faf9c.ngrok.io/shibboleth", + "session_secret": "secret123", "button_text": "Sign-in with shibboleth UP", "idp_cert_path": "/Users/nelsonpereira/Desktop/infolaRepos/dendroRepo/dendro/conf/cert/idp_cert.pem", "key_path": "/Users/nelsonpereira/Desktop/infolaRepos/dendroRepo/dendro/conf/cert/key.pem", @@ -785,16 +785,16 @@ "button_text": "Sign-in with SIGARRA" }, "shibbolethUP": { - "enabled": false, - "CALLBACK_URL": "defaultString", - "URL": "defaultString", - "ENTRY_POINT": "defaultString", - "ISSUER": "defaultString", - "SESSION_SECRET": "defaultString", - "button_text": "Sign-in with shibboleth UP", - "idp_cert_path": "defaultString", - "key_path": "defaultString", - "cert_path": "defaultString" + "enabled": false, + "callback_url": "default_string", + "button_url": "default_string", + "entry_point": "default_string", + "issuer": "default_string", + "session_secret": "default_string", + "button_text": "default_string", + "idp_cert_path": "default_string", + "key_path": "default_string", + "cert_path": "default_string" } }, "numCPUs": 1 @@ -1182,16 +1182,16 @@ "button_text": "Sign-in with SIGARRA" }, "shibbolethUP": { - "enabled": false, - "CALLBACK_URL": "defaultString", - "URL": "defaultString", - "ENTRY_POINT": "defaultString", - "ISSUER": "defaultString", - "SESSION_SECRET": "defaultString", - "button_text": "Sign-in with shibboleth UP", - "idp_cert_path": "defaultString", - "key_path": "defaultString", - "cert_path": "defaultString" + "enabled": false, + "callback_url": "default_string", + "button_url": "default_string", + "entry_point": "default_string", + "issuer": "default_string", + "session_secret": "default_string", + "button_text": "default_string", + "idp_cert_path": "default_string", + "key_path": "default_string", + "cert_path": "default_string" } }, "numCPUs": 1 @@ -1579,16 +1579,16 @@ "button_text": "Sign-in with SIGARRA" }, "shibbolethUP": { - "enabled": false, - "CALLBACK_URL": "defaultString", - "URL": "defaultString", - "ENTRY_POINT": "defaultString", - "ISSUER": "defaultString", - "SESSION_SECRET": "defaultString", - "button_text": "Sign-in with shibboleth UP", - "idp_cert_path": "defaultString", - "key_path": "defaultString", - "cert_path": "defaultString" + "enabled": false, + "callback_url": "default_string", + "button_url": "default_string", + "entry_point": "default_string", + "issuer": "default_string", + "session_secret": "default_string", + "button_text": "default_string", + "idp_cert_path": "default_string", + "key_path": "default_string", + "cert_path": "default_string" } }, "numCPUs": 1 diff --git a/src/bootup/models/shibboleth/shibboleth.js b/src/bootup/models/shibboleth/shibboleth.js index a4f7678f..a0e4d034 100644 --- a/src/bootup/models/shibboleth/shibboleth.js +++ b/src/bootup/models/shibboleth/shibboleth.js @@ -17,10 +17,10 @@ class Shibboleth { try { - let __CALLBACK_URL = shibbolethConfig.CALLBACK_URL; - let __ENTRY_POINT = shibbolethConfig.ENTRY_POINT; - let __ISSUER = shibbolethConfig.ISSUER; - let __SESSION_SECRET = shibbolethConfig.SESSION_SECRET; + let __callback_url = shibbolethConfig.callback_url; + let __entry_point = shibbolethConfig.entry_point; + let __issuer = shibbolethConfig.issuer; + let __session_secret = shibbolethConfig.session_secret; let __button_text = shibbolethConfig.button_text; let __idp_cert = fs.readFileSync(shibbolethConfig.idp_cert_path, "utf8"); @@ -35,22 +35,22 @@ class Shibboleth /***GETS***/ this.getCallbackURl = function () { - return __CALLBACK_URL; + return __callback_url; }; this.getEntryPoint = function () { - return __ENTRY_POINT; + return __entry_point; }; this.getIssuer = function () { - return __ISSUER; + return __issuer; }; this.getSessionSecret = function () { - return __SESSION_SECRET; + return __session_secret; }; this.getButtonText = function () @@ -207,7 +207,7 @@ class Shibboleth let firstName = shibbolethUser[firstNameKey]; let surname = shibbolethUser[surnameKey]; let username = shibbolethUser[usernameKey]; - User.findByEmail(mbox, function (err, user) { + User.findByUsername(username, function (err, user) { if(isNull(err)) { if(isNull(user)) diff --git a/src/bootup/models/shibboleth/shibboleth_UP.js b/src/bootup/models/shibboleth/shibboleth_UP.js index 1bb11a0d..f2b37517 100644 --- a/src/bootup/models/shibboleth/shibboleth_UP.js +++ b/src/bootup/models/shibboleth/shibboleth_UP.js @@ -54,25 +54,25 @@ class ShibbolethUP extends Shibboleth if (req.isAuthenticated()) return next(); else - return res.redirect("/Shibboleth/login"); + return res.redirect("/ShibbolethUP/login"); } - app.get("/Shibboleth", + app.get("/ShibbolethUP", ensureAuthenticated, function(req, res) { res.send('Authenticated'); } ); - app.get("/Shibboleth/login", - passport.authenticate("saml", { failureRedirect: "/Shibboleth/login/fail" }), + app.get("/ShibbolethUP/login", + passport.authenticate("saml", { failureRedirect: "/ShibbolethUP/login/fail" }), function (req, res) { res.redirect("/"); } ); - app.post("/Shibboleth/login/callback", - passport.authenticate("saml", { failureRedirect: "/Shibboleth/login/fail" }), + app.post("/ShibbolethUP/login/callback", + passport.authenticate("saml", { failureRedirect: "/ShibbolethUP/login/fail" }), function(req, res) { Logger.log("info", "will check req.user!!"); Logger.log("info", req.user); @@ -80,7 +80,7 @@ class ShibbolethUP extends Shibboleth } ); - app.get("/Shibboleth/login/fail", + app.get("/ShibbolethUP/login/fail", function(req, res) { Logger.log("Login failed!"); res.status(401).send("Login failed"); diff --git a/src/views/auth/login.ejs b/src/views/auth/login.ejs index a7487310..89d9a5cb 100644 --- a/src/views/auth/login.ejs +++ b/src/views/auth/login.ejs @@ -89,12 +89,13 @@ <% } %> <%if (Config.authentication.shibbolethUP.enabled) { %> - <%= Config.authentication.shibbolethUP.button_text %> + <%= Config.authentication.shibbolethUP.button_text %> <% } %>
<% } %>
+
<%- include ../layout/footer.ejs %> From c4b263e0b2bec242e069dd493e51f550bf2f9ad5 Mon Sep 17 00:00:00 2001 From: Nelson Pereira Date: Wed, 6 Jun 2018 17:04:21 +0100 Subject: [PATCH 12/21] Changed Shibboleth_UP class --- conf/deployment_configs.json | 13 +-- src/bootup/models/shibboleth/shibboleth.js | 71 ++++++++++++++-- src/bootup/models/shibboleth/shibboleth_UP.js | 84 +------------------ src/bootup/routes/load_logic_routes.js | 24 ++++-- src/views/auth/login.ejs | 6 +- 5 files changed, 95 insertions(+), 103 deletions(-) diff --git a/conf/deployment_configs.json b/conf/deployment_configs.json index 2c6c5e05..0662b1ba 100644 --- a/conf/deployment_configs.json +++ b/conf/deployment_configs.json @@ -380,21 +380,22 @@ "callback_url": "/auth/orcid/callback" }, "saml": { - "enabled": true, + "enabled": false, "callback_path": "/auth/saml/callback", "entry_point": "https://openidp.feide.no/simplesaml/saml2/idp/SSOService.php", "issuer": "passport-saml", "button_text": "Sign-in with SIGARRA" }, - "shibbolethUP": + "shibboleth": { "enabled": true, - "callback_url": "http://6a8faf9c.ngrok.io/ShibbolethUP/login/callback", - "button_url": "http://6a8faf9c.ngrok.io/ShibbolethUP", + "businessLogicHandler": "bootup/models/shibboleth/shibboleth_UP.js", + "callback_url": "http://e6a8c957.ngrok.io/Shibboleth/login/callback", + "button_url": "http://e6a8c957.ngrok.io/Shibboleth", "entry_point": "https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO", - "issuer": "https://6a8faf9c.ngrok.io/shibboleth", + "issuer": "https://e6a8c957.ngrok.io/shibboleth", "session_secret": "secret123", - "button_text": "Sign-in with shibboleth UP", + "button_text": "UP-Sign-in", "idp_cert_path": "/Users/nelsonpereira/Desktop/infolaRepos/dendroRepo/dendro/conf/cert/idp_cert.pem", "key_path": "/Users/nelsonpereira/Desktop/infolaRepos/dendroRepo/dendro/conf/cert/key.pem", "cert_path": "/Users/nelsonpereira/Desktop/infolaRepos/dendroRepo/dendro/conf/cert/cert.pem" diff --git a/src/bootup/models/shibboleth/shibboleth.js b/src/bootup/models/shibboleth/shibboleth.js index a0e4d034..8a9c6a00 100644 --- a/src/bootup/models/shibboleth/shibboleth.js +++ b/src/bootup/models/shibboleth/shibboleth.js @@ -1,6 +1,3 @@ -const slug = require("slug"); -const path = require("path"); - const Pathfinder = global.Pathfinder; const isNull = require(Pathfinder.absPathInSrcFolder("/utils/null.js")).isNull; const Logger = require(Pathfinder.absPathInSrcFolder("utils/logger.js")).Logger; @@ -8,7 +5,6 @@ const User = require(Pathfinder.absPathInSrcFolder("models/user.js")).User; const UploadManager = require(Pathfinder.absPathInSrcFolder("/models/uploads/upload_manager.js")).UploadManager; const Config = require(Pathfinder.absPathInSrcFolder("models/meta/config.js")).Config; -const _ = require("underscore"); const fs = require("fs"); class Shibboleth @@ -112,9 +108,74 @@ class Shibboleth } } - registerAuthenticationRoutes (app, passport) + registerAuthenticationRoutes(app, passport) { + const self = this; + let saml = require("passport-saml"); + let samlStrategy = new saml.Strategy({ + // URL that goes from the Identity Provider -> Service Provider + callbackUrl: self.getCallbackURl(), + // URL that goes from the Service Provider -> Identity Provider + entryPoint: self.getEntryPoint(), + // Usually specified as `/shibboleth` from site root + issuer: self.getIssuer(), + identifierFormat: null, + // Service Provider private key + decryptionPvk: self.getKey(), + // Service Provider Certificate + privateCert: self.getKey(), + // Identity Provider's public key + cert: self.getIdpCert(), + validateInResponseTo: false, + disableRequestedAuthnContext: true + }, function(profile, done) { + return done(null, profile); + }); + + passport.use(samlStrategy); + + function ensureAuthenticated(req, res, next) { + if (req.isAuthenticated()) + return next(); + else + return res.redirect("/Shibboleth/login"); + } + + app.get("/Shibboleth", + ensureAuthenticated, + function(req, res) { + res.send('Authenticated'); + } + ); + + app.get("/Shibboleth/login", + passport.authenticate("saml", { failureRedirect: "/Shibboleth/login/fail" }), + function (req, res) { + res.redirect("/"); + } + ); + + app.post("/Shibboleth/login/callback", + passport.authenticate("saml", { failureRedirect: "/Shibboleth/login/fail" }), + function(req, res) { + Logger.log("info", "will check req.user!!"); + self.auth(req, res); + } + ); + + app.get("/Shibboleth/login/fail", + function(req, res) { + Logger.log("Login failed!"); + res.status(401).send("Login failed"); + } + ); + app.get("/Shibboleth.sso/Metadata", + function(req, res) { + res.type("application/xml"); + res.status(200).send(samlStrategy.generateServiceProviderMetadata(self.getCert())); + } + ); } loginUser(user, req, res) diff --git a/src/bootup/models/shibboleth/shibboleth_UP.js b/src/bootup/models/shibboleth/shibboleth_UP.js index f2b37517..13964710 100644 --- a/src/bootup/models/shibboleth/shibboleth_UP.js +++ b/src/bootup/models/shibboleth/shibboleth_UP.js @@ -1,16 +1,5 @@ -const slug = require("slug"); -const path = require("path"); - const Pathfinder = global.Pathfinder; -const isNull = require(Pathfinder.absPathInSrcFolder("/utils/null.js")).isNull; -const Logger = require(Pathfinder.absPathInSrcFolder("utils/logger.js")).Logger; - -const Config = require(Pathfinder.absPathInSrcFolder("models/meta/config.js")).Config; const Shibboleth = require(Pathfinder.absPathInSrcFolder("bootup/models/shibboleth/shibboleth.js")).Shibboleth; -const User = require(Pathfinder.absPathInSrcFolder("models/user.js")).User; -const UploadManager = require(Pathfinder.absPathInSrcFolder("/models/uploads/upload_manager.js")).UploadManager; -const _ = require("underscore"); -const fs = require("fs"); class ShibbolethUP extends Shibboleth { @@ -23,77 +12,6 @@ class ShibbolethUP extends Shibboleth self.setSurnameKey("urn:oid:2.5.4.4"); self.setUsernameKey("urn:oid:1.3.6.1.4.1.5923.1.1.1.6"); } - - registerAuthenticationRoutes(app, passport) - { - const self = this; - let saml = require("passport-saml"); - let samlStrategy = new saml.Strategy({ - // URL that goes from the Identity Provider -> Service Provider - callbackUrl: self.getCallbackURl(), - // URL that goes from the Service Provider -> Identity Provider - entryPoint: self.getEntryPoint(), - // Usually specified as `/shibboleth` from site root - issuer: self.getIssuer(), - identifierFormat: null, - // Service Provider private key - decryptionPvk: self.getKey(), - // Service Provider Certificate - privateCert: self.getKey(), - // Identity Provider's public key - cert: self.getIdpCert(), - validateInResponseTo: false, - disableRequestedAuthnContext: true - }, function(profile, done) { - return done(null, profile); - }); - - passport.use(samlStrategy); - - function ensureAuthenticated(req, res, next) { - if (req.isAuthenticated()) - return next(); - else - return res.redirect("/ShibbolethUP/login"); - } - - app.get("/ShibbolethUP", - ensureAuthenticated, - function(req, res) { - res.send('Authenticated'); - } - ); - - app.get("/ShibbolethUP/login", - passport.authenticate("saml", { failureRedirect: "/ShibbolethUP/login/fail" }), - function (req, res) { - res.redirect("/"); - } - ); - - app.post("/ShibbolethUP/login/callback", - passport.authenticate("saml", { failureRedirect: "/ShibbolethUP/login/fail" }), - function(req, res) { - Logger.log("info", "will check req.user!!"); - Logger.log("info", req.user); - self.auth(req, res); - } - ); - - app.get("/ShibbolethUP/login/fail", - function(req, res) { - Logger.log("Login failed!"); - res.status(401).send("Login failed"); - } - ); - - app.get("/Shibboleth.sso/Metadata", - function(req, res) { - res.type("application/xml"); - res.status(200).send(samlStrategy.generateServiceProviderMetadata(self.getCert())); - } - ); - } } -module.exports.ShibbolethUP = ShibbolethUP; \ No newline at end of file +module.exports.Shibboleth = ShibbolethUP; \ No newline at end of file diff --git a/src/bootup/routes/load_logic_routes.js b/src/bootup/routes/load_logic_routes.js index 131e8479..8196b840 100644 --- a/src/bootup/routes/load_logic_routes.js +++ b/src/bootup/routes/load_logic_routes.js @@ -31,8 +31,7 @@ const datasets = require(Pathfinder.absPathInSrcFolder("/controllers/datasets")) const posts = require(Pathfinder.absPathInSrcFolder("/controllers/posts")); const timeline = require(Pathfinder.absPathInSrcFolder("/controllers/timeline")); const notifications = require(Pathfinder.absPathInSrcFolder("/controllers/notifications")); -//const Shibboleth = require(Pathfinder.absPathInSrcFolder("bootup/models/shibboleth/shibboleth.js")).Shibboleth; -const ShibbolethUP = require(Pathfinder.absPathInSrcFolder("bootup/models/shibboleth/shibboleth_UP.js")).ShibbolethUP; +//const ShibbolethUP = require(Pathfinder.absPathInSrcFolder("bootup/models/shibboleth/shibboleth_UP.js")).ShibbolethUP; let recommendation; @@ -230,15 +229,28 @@ const loadRoutes = function (app, callback) }); } - if(!isNull(Config.authentication.shibbolethUP)) + if(!isNull(Config.authentication.shibboleth)) { - if(!isNull(Config.authentication.shibbolethUP.enabled) && Config.authentication.shibbolethUP.enabled === true) + if(!isNull(Config.authentication.shibboleth.enabled) && Config.authentication.shibboleth.enabled === true && !isNull(Config.authentication.shibboleth.businessLogicHandler)) { - let newShibbolethUP = new ShibbolethUP(Config.authentication.shibbolethUP); - newShibbolethUP.registerAuthenticationRoutes(app, passport); + if(fs.existsSync(Pathfinder.absPathInSrcFolder(Config.authentication.shibboleth.businessLogicHandler))) + { + const Shibboleth = require(Pathfinder.absPathInSrcFolder(Config.authentication.shibboleth.businessLogicHandler)).Shibboleth; + let newShibboleth = new Shibboleth(Config.authentication.shibboleth); + newShibboleth.registerAuthenticationRoutes(app, passport); + } + else + { + const errorMessage = "[FATAL ERROR] shibboleth.businessLogicHandler file: " + "\"" + Config.authentication.shibboleth.businessLogicHandler + "\"" + " does not exist!"; + const error = new Error(errorMessage); + Logger.log("error", errorMessage); + throw error; + } } } + + /** * Helper function to add the requested resource URI to the parameters, based on the human readable URI, * in case APIs are called with the human readable URI of a resource diff --git a/src/views/auth/login.ejs b/src/views/auth/login.ejs index 89d9a5cb..3d40aee7 100644 --- a/src/views/auth/login.ejs +++ b/src/views/auth/login.ejs @@ -84,12 +84,12 @@ Sign in with ORCID <% } %> - <%if (Config.authentication.orcid.enabled) { %> + <%if (Config.authentication.saml.enabled) { %> <%= Config.authentication.saml.button_text %> <% } %> - <%if (Config.authentication.shibbolethUP.enabled) { %> - <%= Config.authentication.shibbolethUP.button_text %> + <%if (Config.authentication.shibboleth.enabled) { %> + <%= Config.authentication.shibboleth.button_text %> <% } %>
From 4d8eec8c29f31fda11e2a5fe2cdad8727c0f2628 Mon Sep 17 00:00:00 2001 From: Nelson Pereira Date: Wed, 6 Jun 2018 17:29:08 +0100 Subject: [PATCH 13/21] refactored code --- conf/deployment_configs.json | 2 +- src/bootup/routes/load_logic_routes.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/conf/deployment_configs.json b/conf/deployment_configs.json index 0662b1ba..f1e95733 100644 --- a/conf/deployment_configs.json +++ b/conf/deployment_configs.json @@ -389,7 +389,7 @@ "shibboleth": { "enabled": true, - "businessLogicHandler": "bootup/models/shibboleth/shibboleth_UP.js", + "business_logic_handler": "bootup/models/shibboleth/shibboleth_UP.js", "callback_url": "http://e6a8c957.ngrok.io/Shibboleth/login/callback", "button_url": "http://e6a8c957.ngrok.io/Shibboleth", "entry_point": "https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO", diff --git a/src/bootup/routes/load_logic_routes.js b/src/bootup/routes/load_logic_routes.js index 8196b840..928a465e 100644 --- a/src/bootup/routes/load_logic_routes.js +++ b/src/bootup/routes/load_logic_routes.js @@ -231,17 +231,17 @@ const loadRoutes = function (app, callback) if(!isNull(Config.authentication.shibboleth)) { - if(!isNull(Config.authentication.shibboleth.enabled) && Config.authentication.shibboleth.enabled === true && !isNull(Config.authentication.shibboleth.businessLogicHandler)) + if(!isNull(Config.authentication.shibboleth.enabled) && Config.authentication.shibboleth.enabled === true && !isNull(Config.authentication.shibboleth.business_logic_handler)) { - if(fs.existsSync(Pathfinder.absPathInSrcFolder(Config.authentication.shibboleth.businessLogicHandler))) + if(fs.existsSync(Pathfinder.absPathInSrcFolder(Config.authentication.shibboleth.business_logic_handler))) { - const Shibboleth = require(Pathfinder.absPathInSrcFolder(Config.authentication.shibboleth.businessLogicHandler)).Shibboleth; + const Shibboleth = require(Pathfinder.absPathInSrcFolder(Config.authentication.shibboleth.business_logic_handler)).Shibboleth; let newShibboleth = new Shibboleth(Config.authentication.shibboleth); newShibboleth.registerAuthenticationRoutes(app, passport); } else { - const errorMessage = "[FATAL ERROR] shibboleth.businessLogicHandler file: " + "\"" + Config.authentication.shibboleth.businessLogicHandler + "\"" + " does not exist!"; + const errorMessage = "[FATAL ERROR] shibboleth.business_logic_handler file: " + "\"" + Config.authentication.shibboleth.business_logic_handler + "\"" + " does not exist!"; const error = new Error(errorMessage); Logger.log("error", errorMessage); throw error; From 65841602c1df6c57e4b0331cbb6e211bc9fcc203 Mon Sep 17 00:00:00 2001 From: Nelson Pereira Date: Wed, 6 Jun 2018 19:19:25 +0100 Subject: [PATCH 14/21] Edited the shibboleth options for the other Dendro configs(test, travis, buildserver, etc) --- conf/deployment_configs.json | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/conf/deployment_configs.json b/conf/deployment_configs.json index f1e95733..e56c01b8 100644 --- a/conf/deployment_configs.json +++ b/conf/deployment_configs.json @@ -785,8 +785,9 @@ "issuer": "passport-saml", "button_text": "Sign-in with SIGARRA" }, - "shibbolethUP": { + "shibboleth": { "enabled": false, + "business_logic_handler": "default_string", "callback_url": "default_string", "button_url": "default_string", "entry_point": "default_string", @@ -1182,8 +1183,9 @@ "issuer": "passport-saml", "button_text": "Sign-in with SIGARRA" }, - "shibbolethUP": { + "shibboleth": { "enabled": false, + "business_logic_handler": "default_string", "callback_url": "default_string", "button_url": "default_string", "entry_point": "default_string", @@ -1579,8 +1581,9 @@ "issuer": "passport-saml", "button_text": "Sign-in with SIGARRA" }, - "shibbolethUP": { + "shibboleth": { "enabled": false, + "business_logic_handler": "default_string", "callback_url": "default_string", "button_url": "default_string", "entry_point": "default_string", From c0bf86a610a1dce40603c105f62e088f7a0349fc Mon Sep 17 00:00:00 2001 From: Nelson Pereira Date: Wed, 6 Jun 2018 19:25:41 +0100 Subject: [PATCH 15/21] Removed code that originated from another branch where I was working on Social Dendro changes --- public/app/js/controllers/social/timeline_controller.js | 9 ++------- .../views/social/partial/authorInformationPartial.html | 1 - src/bootup/routes/load_logic_routes.js | 1 - 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/public/app/js/controllers/social/timeline_controller.js b/public/app/js/controllers/social/timeline_controller.js index f2bbd2a4..23a18419 100644 --- a/public/app/js/controllers/social/timeline_controller.js +++ b/public/app/js/controllers/social/timeline_controller.js @@ -2,7 +2,7 @@ angular.module("dendroApp.controllers") /** * Project administration controller */ - .controller("timelineCtrl", function ($scope, $http, $filter, usersService, timelineService, projectsService, $window, $element, usSpinnerService, moment) + .controller("timelineCtrl", function ($scope, $http, $filter, usersService, timelineService, projectsService, $window, $element, usSpinnerService) { $scope.myTab = $element; $scope.posts = []; @@ -71,12 +71,7 @@ angular.module("dendroApp.controllers") usSpinnerService.stop("social-dendro-spinner"); }); }; - - $scope.returnTimeElapsedHumanized = function (dateString) { - //return moment(new Date(dateString)).fromNow(); - return moment(new Date(dateString)).calendar(); - }; - + // THIS IS THE FUNCTION THAT GETS THE postsURIs for the timeline $scope.get_all_posts = function (currentPage) { diff --git a/public/app/views/social/partial/authorInformationPartial.html b/public/app/views/social/partial/authorInformationPartial.html index 119e6504..125a8876 100644 --- a/public/app/views/social/partial/authorInformationPartial.html +++ b/public/app/views/social/partial/authorInformationPartial.html @@ -3,7 +3,6 @@ {{postsContents[postUri].dcterms.creator}}-->

{{postsContents[postUri].ddr.modified | date : "dd/MMM/yyyy"}}

-

In project {{fullProjectsInfo[postsContents[postUri].ddr.projectUri].title}}

{{fullUsersInfo[postsContents[postUri].dcterms.creator].ddr.username}} diff --git a/src/bootup/routes/load_logic_routes.js b/src/bootup/routes/load_logic_routes.js index 928a465e..1d4db346 100644 --- a/src/bootup/routes/load_logic_routes.js +++ b/src/bootup/routes/load_logic_routes.js @@ -31,7 +31,6 @@ const datasets = require(Pathfinder.absPathInSrcFolder("/controllers/datasets")) const posts = require(Pathfinder.absPathInSrcFolder("/controllers/posts")); const timeline = require(Pathfinder.absPathInSrcFolder("/controllers/timeline")); const notifications = require(Pathfinder.absPathInSrcFolder("/controllers/notifications")); -//const ShibbolethUP = require(Pathfinder.absPathInSrcFolder("bootup/models/shibboleth/shibboleth_UP.js")).ShibbolethUP; let recommendation; From eaf17c994a3c93ae5a78f90f10aea9a2af100adc Mon Sep 17 00:00:00 2001 From: Nelson Pereira Date: Thu, 14 Jun 2018 17:10:20 +0100 Subject: [PATCH 16/21] Login via UP sign in is now working --- conf/deployment_configs.json | 8 ++++---- src/bootup/models/shibboleth/shibboleth_UP.js | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/conf/deployment_configs.json b/conf/deployment_configs.json index e56c01b8..4048a038 100644 --- a/conf/deployment_configs.json +++ b/conf/deployment_configs.json @@ -390,10 +390,10 @@ { "enabled": true, "business_logic_handler": "bootup/models/shibboleth/shibboleth_UP.js", - "callback_url": "http://e6a8c957.ngrok.io/Shibboleth/login/callback", - "button_url": "http://e6a8c957.ngrok.io/Shibboleth", - "entry_point": "https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO", - "issuer": "https://e6a8c957.ngrok.io/shibboleth", + "callback_url": "http://dendropessoal.up.pt:3001/Shibboleth/login/callback", + "button_url": "http://dendropessoal.up.pt:3001/Shibboleth", + "entry_point": "https://stark.up.pt/idp/profile/SAML2/Redirect/SSO", + "issuer": "https://dendropessoal.up.pt/shibboleth", "session_secret": "secret123", "button_text": "UP-Sign-in", "idp_cert_path": "/Users/nelsonpereira/Desktop/infolaRepos/dendroRepo/dendro/conf/cert/idp_cert.pem", diff --git a/src/bootup/models/shibboleth/shibboleth_UP.js b/src/bootup/models/shibboleth/shibboleth_UP.js index 13964710..6714b4ca 100644 --- a/src/bootup/models/shibboleth/shibboleth_UP.js +++ b/src/bootup/models/shibboleth/shibboleth_UP.js @@ -7,10 +7,10 @@ class ShibbolethUP extends Shibboleth { super(shibbolethConfig); const self = this; - self.setMBoxKey("urn:oid:1.3.6.1.4.1.5923.1.1.1.6"); - self.setFirstNameKey("urn:oid:2.5.4.42"); - self.setSurnameKey("urn:oid:2.5.4.4"); - self.setUsernameKey("urn:oid:1.3.6.1.4.1.5923.1.1.1.6"); + self.setMBoxKey("Mail"); + self.setFirstNameKey("GivenName"); + self.setSurnameKey("Surname"); + self.setUsernameKey("urn:oid:2.16.620.1.23"); } } From 23ea83a09fd78f8970ad060400ec13b8543d2feb Mon Sep 17 00:00:00 2001 From: Nelson Pereira Date: Thu, 14 Jun 2018 17:57:47 +0100 Subject: [PATCH 17/21] Added a few TODOs --- src/bootup/models/shibboleth/shibboleth_UP.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/bootup/models/shibboleth/shibboleth_UP.js b/src/bootup/models/shibboleth/shibboleth_UP.js index 6714b4ca..c0f33ba1 100644 --- a/src/bootup/models/shibboleth/shibboleth_UP.js +++ b/src/bootup/models/shibboleth/shibboleth_UP.js @@ -7,6 +7,9 @@ class ShibbolethUP extends Shibboleth { super(shibbolethConfig); const self = this; + //TODO check if the user has all the required fields + //TODO update this values everytime the user logs in + //TODO Display error message self.setMBoxKey("Mail"); self.setFirstNameKey("GivenName"); self.setSurnameKey("Surname"); From cbc091d9e03bc7b07f4c0d1110e7597be5305cc8 Mon Sep 17 00:00:00 2001 From: Nelson Pereira Date: Fri, 15 Jun 2018 16:39:17 +0100 Subject: [PATCH 18/21] working on updating user info everytime the user login via shibboleth --- src/bootup/models/shibboleth/shibboleth.js | 55 ++++++++++++++++++---- src/controllers/auth.js | 28 +++++++++++ 2 files changed, 75 insertions(+), 8 deletions(-) diff --git a/src/bootup/models/shibboleth/shibboleth.js b/src/bootup/models/shibboleth/shibboleth.js index 8a9c6a00..6c5ab01e 100644 --- a/src/bootup/models/shibboleth/shibboleth.js +++ b/src/bootup/models/shibboleth/shibboleth.js @@ -215,18 +215,26 @@ class Shibboleth auth(req, res) { const self = this; + const auth = require(Pathfinder.absPathInSrcFolder("/controllers/auth")); self.getMatchingUserInDendro(req.user, function (err, newUser) { if(!isNull(err)) { - Logger.log("error", "Error signing in user " + JSON.stringify(newUser)); - req.flash("success", "There was an error signing you in."); - return res.redirect("/"); + const errorMessage = "Error signing in user " + newUser; + Logger.log("error", errorMessage); + auth.failLogin(req, res, errorMessage); + //req.flash("success", "There was an error signing you in: " + JSON.stringify(newUser)); + //req.flash("error", "There was an error signing you in: " + newUser); + //return res.redirect("/"); + //TODO change this to auth.failLogin(req, res, reason); } else if(isNull(newUser)) { - Logger.log("error", "Error signing in user " + "newUser is null"); - req.flash("success", "There was an error signing you in."); - return res.redirect("/"); + const errorMessage = "Error signing in user " + "newUser is null"; + Logger.log("error", errorMessage); + //req.flash("success", "There was an error signing you in."); + //return res.redirect("/"); + //TODO change this to auth.failLogin(req, res, reason); + auth.failLogin(req, res, errorMessage); } else { @@ -237,6 +245,30 @@ class Shibboleth getMatchingUserInDendro(shibbolethUser, callback) { + + const updateExistingUser = function (dendroUser, shibbolethUser, callback) { + + let mboxKey = self.getMBoxKey(); + let firstNameKey = self.getFirstNameKey(); + let surnameKey = self.getSurnameKey(); + let usernameKey = self.getUsernameKey(); + + let mbox = shibbolethUser[mboxKey]; + let firstName = shibbolethUser[firstNameKey]; + let surname = shibbolethUser[surnameKey]; + let username = shibbolethUser[usernameKey]; + + dendroUser.foaf.mbox = mbox; + dendroUser.foaf.firstName = firstName; + dendroUser.foaf.surname = surname; + dendroUser.ddr.username = username; + + dendroUser.save(function (err, editedUser) + { + callback(err, editedUser); + }); + }; + const validUserKeysAndValues = function (mboxKey, firstNameKey, surnameKey, usernameKey, shibbolethUser) { let isValid = false; @@ -262,6 +294,9 @@ class Shibboleth let surnameKey = self.getSurnameKey(); let usernameKey = self.getUsernameKey(); + //TODO this line here is only for testing purposes + //shibbolethUser[mboxKey] = null; + if(validUserKeysAndValues(mboxKey, firstNameKey, surnameKey, usernameKey, shibbolethUser) === true) { let mbox = shibbolethUser[mboxKey]; @@ -310,7 +345,11 @@ class Shibboleth } else { - return callback(null, user); + //TODO update user here with new values from the user Keys + updateExistingUser(user, shibbolethUser, function (err, user) { + return callback(err, user); + }); + //return callback(null, user); } } else @@ -322,7 +361,7 @@ class Shibboleth } else { - const errorMessage = "Invalid user keys and values at getMatchingUserInDendro"; + const errorMessage = "You have no registered email. Contact the helpdesk to register your institutional email in the system."; const err = new Error(errorMessage); Logger.log("error", errorMessage); return callback(true, err) diff --git a/src/controllers/auth.js b/src/controllers/auth.js index 60947d2d..359c7574 100644 --- a/src/controllers/auth.js +++ b/src/controllers/auth.js @@ -168,16 +168,29 @@ module.exports.login = function (req, res, next) } }; + +const unAuthenticateUser = function (req, res) { + req.logOut(); + delete req.user; + delete req.session.isAdmin; + delete req.session.upload_manager; + delete res.locals.user; + delete res.locals.session; +}; + module.exports.logout = function (req, res) { if (!isNull(req.user)) { + /* req.logOut(); delete req.user; delete req.session.isAdmin; delete req.session.upload_manager; delete res.locals.user; delete res.locals.session; + */ + unAuthenticateUser(req, res); req.flash("success", "Successfully logged out"); res.redirect("/"); @@ -189,6 +202,21 @@ module.exports.logout = function (req, res) } }; +module.exports.failLogin = function(req, res, reason) +{ + /* + req.logOut(); + delete req.user; + delete req.session.isAdmin; + delete req.session.upload_manager; + delete res.locals.user; + delete res.locals.session; + */ + unAuthenticateUser(req, res); + req.flash("error", reason); + res.redirect("/"); +}; + module.exports.register = function (req, res) { const acceptsHTML = req.accepts("html"); From f91cebb256c1df8757985bd40c0a8da182b5fcd1 Mon Sep 17 00:00:00 2001 From: Nelson Pereira Date: Mon, 18 Jun 2018 15:18:03 +0100 Subject: [PATCH 19/21] Cleaned code a bit --- src/bootup/models/shibboleth/shibboleth.js | 48 +++++++++++++--------- src/controllers/auth.js | 17 -------- 2 files changed, 29 insertions(+), 36 deletions(-) diff --git a/src/bootup/models/shibboleth/shibboleth.js b/src/bootup/models/shibboleth/shibboleth.js index 6c5ab01e..4837ec84 100644 --- a/src/bootup/models/shibboleth/shibboleth.js +++ b/src/bootup/models/shibboleth/shibboleth.js @@ -144,6 +144,7 @@ class Shibboleth app.get("/Shibboleth", ensureAuthenticated, function(req, res) { + Logger.log("info", "User is already authenticated!!"); res.send('Authenticated'); } ); @@ -222,18 +223,11 @@ class Shibboleth const errorMessage = "Error signing in user " + newUser; Logger.log("error", errorMessage); auth.failLogin(req, res, errorMessage); - //req.flash("success", "There was an error signing you in: " + JSON.stringify(newUser)); - //req.flash("error", "There was an error signing you in: " + newUser); - //return res.redirect("/"); - //TODO change this to auth.failLogin(req, res, reason); } else if(isNull(newUser)) { const errorMessage = "Error signing in user " + "newUser is null"; Logger.log("error", errorMessage); - //req.flash("success", "There was an error signing you in."); - //return res.redirect("/"); - //TODO change this to auth.failLogin(req, res, reason); auth.failLogin(req, res, errorMessage); } else @@ -269,16 +263,15 @@ class Shibboleth }); }; - const validUserKeysAndValues = function (mboxKey, firstNameKey, surnameKey, usernameKey, shibbolethUser) + const validUserKeysAndValues = function (firstNameKey, surnameKey, usernameKey, shibbolethUser) { let isValid = false; - if(!isNull(mboxKey) && !isNull(firstNameKey) && !isNull(surnameKey) && !isNull(usernameKey) && !isNull(shibbolethUser)) + if(!isNull(firstNameKey) && !isNull(surnameKey) && !isNull(usernameKey) && !isNull(shibbolethUser)) { - let mbox = shibbolethUser[mboxKey]; let firstName = shibbolethUser[firstNameKey]; let surname = shibbolethUser[surnameKey]; let username = shibbolethUser[usernameKey]; - if(!isNull(mbox) && !isNull(firstName) && !isNull(surname) && !isNull(username)) + if(!isNull(firstName) && !isNull(surname) && !isNull(username)) { isValid = true; } @@ -286,6 +279,19 @@ class Shibboleth return isValid; }; + const userHasEmail = function (mboxKey) { + let result = false; + if(!isNull(mboxKey) && !isNull(shibbolethUser)) + { + let mbox = shibbolethUser[mboxKey]; + if(!isNull(mbox)) + { + result = true; + } + } + return result; + }; + let self = this; if(!isNull(shibbolethUser)) { @@ -294,10 +300,14 @@ class Shibboleth let surnameKey = self.getSurnameKey(); let usernameKey = self.getUsernameKey(); - //TODO this line here is only for testing purposes - //shibbolethUser[mboxKey] = null; - - if(validUserKeysAndValues(mboxKey, firstNameKey, surnameKey, usernameKey, shibbolethUser) === true) + if(userHasEmail(mboxKey) === false) + { + const errorMessage = "You have no registered email. Contact the helpdesk to register your institutional email in the system!"; + const err = new Error(errorMessage); + Logger.log("error", errorMessage); + return callback(true, err) + } + else if(validUserKeysAndValues(firstNameKey, surnameKey, usernameKey, shibbolethUser) === true) { let mbox = shibbolethUser[mboxKey]; let firstName = shibbolethUser[firstNameKey]; @@ -345,11 +355,11 @@ class Shibboleth } else { - //TODO update user here with new values from the user Keys + //update user here with new values from the user Keys + Logger.log("info", "Will update existing user at login time"); updateExistingUser(user, shibbolethUser, function (err, user) { return callback(err, user); }); - //return callback(null, user); } } else @@ -361,9 +371,9 @@ class Shibboleth } else { - const errorMessage = "You have no registered email. Contact the helpdesk to register your institutional email in the system."; + const errorMessage = "There seems to be a problem with the Service provider institution, please contact the System Administrator!"; const err = new Error(errorMessage); - Logger.log("error", errorMessage); + Logger.log("error", "The service provider is not sending the proper user information in the login callback handler!"); return callback(true, err) } } diff --git a/src/controllers/auth.js b/src/controllers/auth.js index 359c7574..97478c98 100644 --- a/src/controllers/auth.js +++ b/src/controllers/auth.js @@ -182,16 +182,7 @@ module.exports.logout = function (req, res) { if (!isNull(req.user)) { - /* - req.logOut(); - delete req.user; - delete req.session.isAdmin; - delete req.session.upload_manager; - delete res.locals.user; - delete res.locals.session; - */ unAuthenticateUser(req, res); - req.flash("success", "Successfully logged out"); res.redirect("/"); } @@ -204,14 +195,6 @@ module.exports.logout = function (req, res) module.exports.failLogin = function(req, res, reason) { - /* - req.logOut(); - delete req.user; - delete req.session.isAdmin; - delete req.session.upload_manager; - delete res.locals.user; - delete res.locals.session; - */ unAuthenticateUser(req, res); req.flash("error", reason); res.redirect("/"); From 3386217b933564b007b03038298672c38a31eecc Mon Sep 17 00:00:00 2001 From: Nelson Pereira Date: Tue, 19 Jun 2018 11:40:19 +0100 Subject: [PATCH 20/21] Cleaned code --- src/bootup/models/shibboleth/shibboleth.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/bootup/models/shibboleth/shibboleth.js b/src/bootup/models/shibboleth/shibboleth.js index 4837ec84..c664fc41 100644 --- a/src/bootup/models/shibboleth/shibboleth.js +++ b/src/bootup/models/shibboleth/shibboleth.js @@ -300,6 +300,13 @@ class Shibboleth let surnameKey = self.getSurnameKey(); let usernameKey = self.getUsernameKey(); + if(validUserKeysAndValues(firstNameKey, surnameKey, usernameKey, shibbolethUser) === false) + { + const errorMessage = "There seems to be a problem with the Service provider institution, please contact the System Administrator!"; + const err = new Error(errorMessage); + Logger.log("error", "The service provider is not sending the proper user information in the login callback handler!"); + return callback(true, err) + } if(userHasEmail(mboxKey) === false) { const errorMessage = "You have no registered email. Contact the helpdesk to register your institutional email in the system!"; @@ -307,8 +314,9 @@ class Shibboleth Logger.log("error", errorMessage); return callback(true, err) } - else if(validUserKeysAndValues(firstNameKey, surnameKey, usernameKey, shibbolethUser) === true) + else { + //everything is ok, proceed with login let mbox = shibbolethUser[mboxKey]; let firstName = shibbolethUser[firstNameKey]; let surname = shibbolethUser[surnameKey]; @@ -369,13 +377,6 @@ class Shibboleth } }); } - else - { - const errorMessage = "There seems to be a problem with the Service provider institution, please contact the System Administrator!"; - const err = new Error(errorMessage); - Logger.log("error", "The service provider is not sending the proper user information in the login callback handler!"); - return callback(true, err) - } } else { From 7c08a2ac163fcb0407dbb28df32d4fce5824b8e1 Mon Sep 17 00:00:00 2001 From: Nelson Pereira Date: Tue, 19 Jun 2018 14:59:55 +0100 Subject: [PATCH 21/21] Edited error message --- src/bootup/models/shibboleth/shibboleth.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bootup/models/shibboleth/shibboleth.js b/src/bootup/models/shibboleth/shibboleth.js index c664fc41..30271ad2 100644 --- a/src/bootup/models/shibboleth/shibboleth.js +++ b/src/bootup/models/shibboleth/shibboleth.js @@ -302,12 +302,12 @@ class Shibboleth if(validUserKeysAndValues(firstNameKey, surnameKey, usernameKey, shibbolethUser) === false) { - const errorMessage = "There seems to be a problem with the Service provider institution, please contact the System Administrator!"; + const errorMessage = "There seems to be a problem with the Identity provider institution, please contact the System Administrator!"; const err = new Error(errorMessage); Logger.log("error", "The service provider is not sending the proper user information in the login callback handler!"); return callback(true, err) } - if(userHasEmail(mboxKey) === false) + else if(userHasEmail(mboxKey) === false) { const errorMessage = "You have no registered email. Contact the helpdesk to register your institutional email in the system!"; const err = new Error(errorMessage);