From 75427dcbc7441e6e03edfbe665822dd8abe2bbd4 Mon Sep 17 00:00:00 2001 From: morsh Date: Thu, 30 Mar 2017 16:56:07 +0300 Subject: [PATCH] first go at authentication --- package.json | 4 + scripts/deployment/azure-deploy.cmd | 3 +- scripts/deployment/web.config | 61 +++++++ server/app.js | 191 +++++++++++++++++++- yarn.lock | 258 ++++++++++++++++++++++++++-- 5 files changed, 496 insertions(+), 21 deletions(-) create mode 100644 scripts/deployment/web.config diff --git a/package.json b/package.json index d4e26f4..0f7cd6e 100644 --- a/package.json +++ b/package.json @@ -23,10 +23,14 @@ "alt": "^0.18.6", "alt-utils": "^1.0.0", "body-parser": "^1.17.1", + "cookie-parser": "^1.4.3", + "express-session": "^1.15.2", "lodash": "^4.17.4", "material-colors": "^1.2.5", "moment": "^2.18.0", "morgan": "^1.8.1", + "passport": "^0.3.2", + "passport-azure-ad": "^3.0.5", "react": "^15.4.2", "react-addons-css-transition-group": "^15.4.2", "react-addons-transition-group": "^15.4.2", diff --git a/scripts/deployment/azure-deploy.cmd b/scripts/deployment/azure-deploy.cmd index 908c49f..cd3e8fa 100644 --- a/scripts/deployment/azure-deploy.cmd +++ b/scripts/deployment/azure-deploy.cmd @@ -25,6 +25,8 @@ SET ARTIFACTS=%~dp0%..\artifacts IF NOT DEFINED DEPLOYMENT_SOURCE ( SET DEPLOYMENT_SOURCE=%~dp0%. ) +SET WEB_CONFIG=%DEPLOYMENT_SOURCE%/scripts/deployment/web.config + IF NOT DEFINED DEPLOYMENT_TARGET ( SET DEPLOYMENT_TARGET=%ARTIFACTS%\wwwroot @@ -112,7 +114,6 @@ IF EXIST "%DEPLOYMENT_TARGET%\package.json" ( echo Yarn is installed ) - call :ExecuteCmd yarn install call :ExecuteCmd yarn build IF !ERRORLEVEL! NEQ 0 goto error diff --git a/scripts/deployment/web.config b/scripts/deployment/web.config new file mode 100644 index 0000000..86c9c01 --- /dev/null +++ b/scripts/deployment/web.config @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/server/app.js b/server/app.js index 75f017f..7b4cadb 100644 --- a/server/app.js +++ b/server/app.js @@ -1,20 +1,106 @@ -// server/app.js -const express = require('express'); -const morgan = require('morgan'); -const path = require('path'); + const fs = require('fs'); +const path = require('path'); +const express = require('express'); +const expressSession = require('express-session'); +const morgan = require('morgan'); const bodyParser = require('body-parser'); +const cookieParser = require('cookie-parser'); +const passport = require('passport'); +const passportAzureAD = require('passport-azure-ad'); +const config = require('./config.private'); + +const OIDCStrategy = passportAzureAD.OIDCStrategy; + +// Passport session setup. (Section 2) + +// To support persistent login sessions, Passport needs to be able to +// serialize users into and deserialize users out of the session. Typically, +// this will be as simple as storing the user ID when serializing, and finding +// the user by ID when deserializing. +passport.serializeUser(function(user, done) { + done(null, user.email); +}); + +passport.deserializeUser(function(id, done) { + findByEmail(id, function (err, user) { + done(err, user); + }); +}); + +// array to hold logged in users +var users = []; + +var findByEmail = function(email, fn) { + for (var i = 0, len = users.length; i < len; i++) { + var user = users[i]; + console.info('we are using user: ', user); + if (user.email === email) { + return fn(null, user); + } + } + return fn(null, null); +}; + +// Use the OIDCStrategy within Passport. (Section 2) +// +// Strategies in passport require a `validate` function, which accept +// credentials (in this case, an OpenID identifier), and invoke a callback +// with a user object. +passport.use(new OIDCStrategy({ + redirectUrl: config.creds.redirectUrl, + allowHttpForRedirectUrl: config.creds.allowHttpForRedirectUrl, + realm: config.creds.realm, + clientID: config.creds.clientID, + clientSecret: config.creds.clientSecret, + oidcIssuer: config.creds.issuer, + identityMetadata: config.creds.identityMetadata, + skipUserProfile: config.creds.skipUserProfile, + responseType: config.creds.responseType, + responseMode: config.creds.responseMode, + validateIssuer: config.creds.validateIssuer + }, + function(iss, sub, profile, accessToken, refreshToken, done) { + + profile.email = profile.email || profile.upn; + + if (!profile.email) { + return done(new Error("No email found"), null); + } + // asynchronous verification, for effect... + process.nextTick(function () { + findByEmail(profile.email, function(err, user) { + if (err) { + return done(err); + } + if (!user) { + // "Auto-registration" + users.push(profile); + return done(null, profile); + } + return done(null, user); + }); + }); + } +)); const app = express(); + +app.use(cookieParser()); +app.use(expressSession({ secret: 'keyboard cat', resave: true, saveUninitialized: false })); app.use(bodyParser.json()); // to support JSON-encoded bodies -app.use(bodyParser.urlencoded({ // to support URL-encoded bodies - extended: true -})); +app.use(bodyParser.urlencoded({ extended : true })); + +// Initialize Passport! Also use passport.session() middleware, to support +// persistent login sessions (recommended). +app.use(passport.initialize()); +app.use(passport.session()); // Setup logger app.use(morgan(':remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] :response-time ms')); // Serve static assets +app.use(exclude('/auth/', ensureAuthenticated)); app.use(express.static(path.resolve(__dirname, '..', 'build'))); function getFiles(dir, files_) { @@ -69,9 +155,96 @@ app.post('/api/dashboard.js', (req, res) => { }) }); + +// Authentications Routes + +// app.get('/account', ensureAuthenticated, function(req, res){ +// res.render('account', { user: req.user }); +// }); + +app.get('/auth/login', + passport.authenticate('azuread-openidconnect', { failureRedirect: '/login' }), + function(req, res) { + console.info('Login was called in the Sample'); + res.redirect('/'); +}); + +// POST /auth/openid +// Use passport.authenticate() as route middleware to authenticate the +// request. The first step in OpenID authentication will involve redirecting +// the user to their OpenID provider. After authenticating, the OpenID +// provider will redirect the user back to this application at +// /auth/openid/return +app.get('/auth/openid', + passport.authenticate('azuread-openidconnect', { failureRedirect: '/login' }), + function(req, res) { + console.info('Authentication was called in the Sample'); + res.redirect('/'); + }); + +// GET /auth/openid/return +// Use passport.authenticate() as route middleware to authenticate the +// request. If authentication fails, the user will be redirected back to the +// login page. Otherwise, the primary route function function will be called, +// which, in this example, will redirect the user to the home page. +app.get('/auth/openid/return', + passport.authenticate('azuread-openidconnect', { failureRedirect: '/login' }), + function(req, res) { + console.info('We received a return from AzureAD.'); + res.redirect('/'); + }); + +// GET /auth/openid/return +// Use passport.authenticate() as route middleware to authenticate the +// request. If authentication fails, the user will be redirected back to the +// login page. Otherwise, the primary route function function will be called, +// which, in this example, will redirect the user to the home page. +app.post('/auth/openid/return', + passport.authenticate('azuread-openidconnect', { failureRedirect: '/login' }), + function(req, res) { + console.info('We received a return from AzureAD.'); + res.redirect('/'); + }); + +app.get('/auth/logout', function(req, res){ + req.logout(); + res.redirect('/'); +}); + + // Always return the main index.html, so react-router render the route in the client -app.get('*', (req, res) => { +app.get('*', ensureAuthenticated, (req, res) => { res.sendFile(path.resolve(__dirname, '..', 'build', 'index.html')); }); -module.exports = app; \ No newline at end of file +module.exports = app; + +// Simple route middleware to ensure user is authenticated. (Section 4) + +// Use this route middleware on any resource that needs to be protected. If +// the request is authenticated (typically via a persistent login session), +// the request will proceed. Otherwise, the user will be redirected to the +// login page. +function ensureAuthenticated(req, res, next) { + if (req.isAuthenticated()) { return next(); } + res.redirect('/auth/login') +} + +function exclude(paths, middleware) { + return function(req, res, next) { + + // Exclude single string path + if (typeof paths === 'string') { + if (req.path.startsWith(paths)) { return next(); } + } + + // Exclude a string from an array + if (Array.isArray(paths)) { + for (let path in paths) { + if (req.path.startsWith(path)) { return next(); } + } + } + + return middleware(req, res, next); + }; +}; \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index ab6f2c3..c3c50c2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -223,6 +223,14 @@ asap@~2.0.3: version "2.0.5" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.5.tgz#522765b50c3510490e52d7dcfe085ef9ba96958f" +asn1.js@^4.5.2: + version "4.9.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.9.1.tgz#48ba240b45a9280e94748990ba597d216617fd40" + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + asn1@~0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" @@ -253,14 +261,14 @@ async-foreach@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542" +async@1.5.2, async@^1.3.0, async@^1.4.0, async@^1.4.2, async@^1.5.0, async@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + async@^0.9.0: version "0.9.2" resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" -async@^1.3.0, async@^1.4.0, async@^1.4.2, async@^1.5.0: - version "1.5.2" - resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" - async@^2.1.4: version "2.1.5" resolved "https://registry.yarnpkg.com/async/-/async-2.1.5.tgz#e587c68580994ac67fc56ff86d3ac56bdbe810bc" @@ -443,6 +451,10 @@ base64-js@^1.0.2: version "1.2.0" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.0.tgz#a39992d723584811982be5e290bb6a53d86700f1" +base64url@2.0.0, base64url@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/base64url/-/base64url-2.0.0.tgz#eac16e03ea1438eff9423d69baa36262ed1f70bb" + basic-auth@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-1.1.0.tgz#45221ee429f7ee1e5035be3f51533f1cdfd29884" @@ -475,6 +487,10 @@ bluebird@^3.4.6: version "3.5.0" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c" +bn.js@^4.0.0, bn.js@^4.4.0: + version "4.11.6" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" + body-parser@^1.17.1: version "1.17.1" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.17.1.tgz#75b3bc98ddd6e7e0d8ffe750dfaca5c66993fa47" @@ -527,6 +543,10 @@ braces@^1.8.2: preserve "^0.2.0" repeat-element "^1.1.2" +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + browser-resolve@^1.11.2: version "1.11.2" resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce" @@ -558,6 +578,10 @@ bser@1.0.2: dependencies: node-int64 "^0.4.0" +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + buffer-shims@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" @@ -584,6 +608,15 @@ builtin-status-codes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" +bunyan@^1.8.0: + version "1.8.9" + resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.9.tgz#2c7c9d422ea64ee2465d52b4decd72de0657401a" + optionalDependencies: + dtrace-provider "~0.8" + moment "^2.10.6" + mv "~2" + safe-json-stringify "~1" + bytes@2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.3.0.tgz#d5b680a165b6201739acb611542aabc2d8ceb070" @@ -592,6 +625,13 @@ bytes@2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.4.0.tgz#7d97196f9d5baf7f6935e25985549edd2a6c2339" +cache-manager@^2.0.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/cache-manager/-/cache-manager-2.4.0.tgz#272e4eee3a4ecebb281fcb086499804e59a6a251" + dependencies: + async "1.5.2" + lru-cache "4.0.0" + callsites@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" @@ -903,6 +943,13 @@ convert-source-map@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.4.0.tgz#e3dad195bf61bfe13a7a3c73e9876ec14a0268f3" +cookie-parser@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/cookie-parser/-/cookie-parser-1.4.3.tgz#0fe31fa19d000b95f4aadf1f53fdc2b8a203baa5" + dependencies: + cookie "0.3.1" + cookie-signature "1.0.6" + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" @@ -934,6 +981,10 @@ cosmiconfig@^2.1.0, cosmiconfig@^2.1.1: parse-json "^2.2.0" require-from-string "^1.1.0" +crc@3.4.4: + version "3.4.4" + resolved "https://registry.yarnpkg.com/crc/-/crc-3.4.4.tgz#9da1e980e3bd44fc5c93bf5ab3da3378d85e466b" + create-error-class@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" @@ -1166,12 +1217,18 @@ date-now@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" -debug@2.6.1, debug@^2.1.0, debug@^2.1.1, debug@^2.2.0: +debug@2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.1.tgz#79855090ba2c4e3115cc7d8769491d58f0491351" dependencies: ms "0.7.2" +debug@2.6.3, debug@^2.1.0, debug@^2.1.1, debug@^2.2.0: + version "2.6.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.3.tgz#0f7eb8c30965ec08c72accfa0130c8b79984141d" + dependencies: + ms "0.7.2" + debug@~2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" @@ -1315,6 +1372,12 @@ dotenv@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-2.0.0.tgz#bd759c357aaa70365e01c96b7b0bec08a6e0d949" +dtrace-provider@~0.8: + version "0.8.1" + resolved "https://registry.yarnpkg.com/dtrace-provider/-/dtrace-provider-0.8.1.tgz#cd4d174a233bea1bcf4a1fbfa5798f44f48cda9f" + dependencies: + nan "^2.3.3" + duplexer3@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" @@ -1329,6 +1392,13 @@ ecc-jsbn@~0.1.1: dependencies: jsbn "~0.1.0" +ecdsa-sig-formatter@1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.9.tgz#4bc926274ec3b5abb5016e7e1d60921ac262b2a1" + dependencies: + base64url "^2.0.0" + safe-buffer "^5.0.1" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -1337,6 +1407,18 @@ electron-to-chromium@^1.2.5: version "1.2.7" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.2.7.tgz#4f748061407e478c76256d04496972b71f647407" +elliptic@^6.2.3: + version "6.4.0" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df" + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + emojis-list@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" @@ -1499,6 +1581,20 @@ expand-range@^1.8.1: dependencies: fill-range "^2.1.0" +express-session@^1.15.2: + version "1.15.2" + resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.15.2.tgz#d98516443a4ccb8688e1725ae584c02daa4093d4" + dependencies: + cookie "0.3.1" + cookie-signature "1.0.6" + crc "3.4.4" + debug "2.6.3" + depd "~1.1.0" + on-headers "~1.0.1" + parseurl "~1.3.1" + uid-safe "~2.1.4" + utils-merge "1.0.0" + express@^4.13.3: version "4.15.2" resolved "https://registry.yarnpkg.com/express/-/express-4.15.2.tgz#af107fc148504457f2dca9a6f2571d7129b97b35" @@ -1810,6 +1906,16 @@ glob-parent@^2.0.0: dependencies: is-glob "^2.0.0" +glob@^6.0.1: + version "6.0.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@~7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" @@ -1932,6 +2038,12 @@ has@^1.0.1: dependencies: function-bind "^1.0.2" +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.0.3.tgz#1332ff00156c0a0ffdd8236013d07b77a0451573" + dependencies: + inherits "^2.0.1" + hawk@~3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" @@ -1958,6 +2070,14 @@ history@^3.0.0: query-string "^4.2.2" warning "^3.0.0" +hmac-drbg@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.0.tgz#3db471f45aae4a994a0688322171f51b8b91bee5" + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + hoek@2.x.x: version "2.16.3" resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" @@ -2069,11 +2189,11 @@ https-browserify@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82" -iconv-lite@0.4.13, iconv-lite@~0.4.13: +iconv-lite@0.4.13: version "0.4.13" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2" -iconv-lite@0.4.15: +iconv-lite@0.4.15, iconv-lite@~0.4.13: version "0.4.15" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb" @@ -2690,6 +2810,31 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.3.6" +jwa@^1.1.4: + version "1.1.5" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.1.5.tgz#a0552ce0220742cd52e153774a32905c30e756e5" + dependencies: + base64url "2.0.0" + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.9" + safe-buffer "^5.0.1" + +jwk-to-pem@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/jwk-to-pem/-/jwk-to-pem-1.2.6.tgz#d507cece40089c5248e09ec68266a2030a9c6325" + dependencies: + asn1.js "^4.5.2" + elliptic "^6.2.3" + safe-buffer "^5.0.1" + +jws@^3.1.3: + version "3.1.4" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.1.4.tgz#f9e8b9338e8a847277d6444b1464f61880e050a2" + dependencies: + base64url "^2.0.0" + jwa "^1.1.4" + safe-buffer "^5.0.1" + keycode@^2.1.7: version "2.1.8" resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.1.8.tgz#94d2b7098215eff0e8f9a8931d5a59076c4532fb" @@ -2862,7 +3007,7 @@ lodash.uniq@^4.3.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" -"lodash@>=3.5 <5", lodash@^4.0.0, lodash@^4.14.0, lodash@^4.16.4, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.2.0, lodash@~4.17.2, lodash@~4.17.4: +"lodash@>=3.5 <5", lodash@^4.0.0, lodash@^4.11.2, lodash@^4.14.0, lodash@^4.16.4, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.2.0, lodash@~4.17.2, lodash@~4.17.4: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" @@ -2899,6 +3044,13 @@ lru-cache@2: version "2.7.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" +lru-cache@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.0.tgz#b5cbf01556c16966febe54ceec0fb4dc90df6c28" + dependencies: + pseudomap "^1.0.1" + yallist "^2.0.0" + lru-cache@^4.0.0, lru-cache@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.2.tgz#1d17679c069cda5d040991a09dbc2c0db377e55e" @@ -3037,6 +3189,14 @@ min-document@^2.19.0: dependencies: dom-walk "^0.1.0" +minimalistic-assert@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz#702be2dda6b37f4836bcb3f5db56641b64a1d3d3" + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + minimatch@0.3: version "0.3.0" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd" @@ -3070,7 +3230,7 @@ minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0: dependencies: minimist "0.0.8" -moment@^2.18.0: +moment@^2.10.6, moment@^2.18.0: version "2.18.0" resolved "https://registry.yarnpkg.com/moment/-/moment-2.18.0.tgz#6cfec6a495eca915d02600a67020ed994937252c" @@ -3092,6 +3252,14 @@ ms@0.7.2: version "0.7.2" resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" +mv@~2: + version "2.1.1" + resolved "https://registry.yarnpkg.com/mv/-/mv-2.1.1.tgz#ae6ce0d6f6d5e0a4f7d893798d03c1ea9559b6a2" + dependencies: + mkdirp "~0.5.1" + ncp "~2.0.0" + rimraf "~2.4.0" + mz@^2.4.0: version "2.6.0" resolved "https://registry.yarnpkg.com/mz/-/mz-2.6.0.tgz#c8b8521d958df0a4f2768025db69c719ee4ef1ce" @@ -3100,7 +3268,7 @@ mz@^2.4.0: object-assign "^4.0.1" thenify-all "^1.0.0" -nan@^2.3.0, nan@^2.3.2: +nan@^2.3.0, nan@^2.3.2, nan@^2.3.3: version "2.5.1" resolved "https://registry.yarnpkg.com/nan/-/nan-2.5.1.tgz#d5b01691253326a97a2bbee9e61c55d8d60351e2" @@ -3114,6 +3282,10 @@ ncname@1.0.x: dependencies: xml-char-classes "^1.0.0" +ncp@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3" + negotiator@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" @@ -3330,6 +3502,10 @@ oauth-sign@~0.8.1: version "0.8.2" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" +oauth@0.9.14: + version "0.9.14" + resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.14.tgz#c5748883a40b53de30ade9cabf2100414b8a0971" + object-assign@4.1.1, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -3484,6 +3660,34 @@ parseurl@~1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.1.tgz#c8ab8c9223ba34888aa64a297b28853bec18da56" +passport-azure-ad@^3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/passport-azure-ad/-/passport-azure-ad-3.0.5.tgz#de72d2b9fb0030166f7aa7bf39f6dd461ae38f3a" + dependencies: + async "^1.5.2" + base64url "^2.0.0" + bunyan "^1.8.0" + cache-manager "^2.0.0" + jwk-to-pem "^1.2.6" + jws "^3.1.3" + lodash "^4.11.2" + oauth "0.9.14" + passport "^0.3.2" + pkginfo "^0.4.0" + request "^2.72.0" + valid-url "^1.0.6" + +passport-strategy@1.x.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" + +passport@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/passport/-/passport-0.3.2.tgz#9dd009f915e8fe095b0124a01b8f82da07510102" + dependencies: + passport-strategy "1.x.x" + pause "0.0.1" + path-browserify@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" @@ -3530,6 +3734,10 @@ pause-stream@0.0.11: dependencies: through "~2.3" +pause@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" + pbkdf2-compat@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/pbkdf2-compat/-/pbkdf2-compat-2.0.1.tgz#b6e0c8fa99494d94e0511575802a59a5c142f288" @@ -3552,6 +3760,10 @@ pinkie@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" +pkginfo@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.0.tgz#349dbb7ffd38081fcadc0853df687f0c7744cd65" + postcss-calc@^5.2.0: version "5.3.1" resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-5.3.1.tgz#77bae7ca928ad85716e2fda42f261bf7c1d65b5e" @@ -3941,6 +4153,10 @@ raf@^3.1.0, raf@^3.2.0: dependencies: performance-now "~0.2.0" +random-bytes@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/random-bytes/-/random-bytes-1.0.0.tgz#4f68a1dc0ae58bd3fb95848c30324db75d64360b" + randomatic@^1.1.3: version "1.1.6" resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.6.tgz#110dcabff397e9dcff7c0789ccc0a49adf1ec5bb" @@ -4340,7 +4556,7 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" -request@2, request@^2.61.0, request@^2.79.0: +request@2, request@^2.61.0, request@^2.72.0, request@^2.79.0: version "2.81.0" resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" dependencies: @@ -4411,6 +4627,12 @@ rimraf@2, rimraf@^2.2.8, rimraf@^2.4.3, rimraf@^2.4.4: dependencies: glob "^7.0.5" +rimraf@~2.4.0: + version "2.4.5" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.4.5.tgz#ee710ce5d93a8fdb856fb5ea8ff0e2d75934b2da" + dependencies: + glob "^6.0.1" + rimraf@~2.5.1, rimraf@~2.5.4: version "2.5.4" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.5.4.tgz#96800093cbf1a0c86bd95b4625467535c29dfa04" @@ -4425,6 +4647,10 @@ safe-buffer@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7" +safe-json-stringify@~1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/safe-json-stringify/-/safe-json-stringify-1.0.4.tgz#81a098f447e4bbc3ff3312a243521bc060ef5911" + sane@~1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/sane/-/sane-1.4.1.tgz#88f763d74040f5f0c256b6163db399bf110ac715" @@ -5044,6 +5270,12 @@ uid-number@~0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" +uid-safe@~2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/uid-safe/-/uid-safe-2.1.4.tgz#3ad6f38368c6d4c8c75ec17623fb79aa1d071d81" + dependencies: + random-bytes "~1.0.0" + uniq@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" @@ -5161,6 +5393,10 @@ uuid@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" +valid-url@^1.0.6: + version "1.0.9" + resolved "https://registry.yarnpkg.com/valid-url/-/valid-url-1.0.9.tgz#1c14479b40f1397a75782f115e4086447433a200" + validate-npm-package-license@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc"