From 5c9f6718fd59467b2172cd0167d7b0be541a638b Mon Sep 17 00:00:00 2001 From: Sai Prashanth Chandramouli Date: Thu, 28 Jul 2016 09:17:40 -0700 Subject: [PATCH] feat(location): add location data to emails (#180) r=vladikoff,shane-tomlinson * feat(location): add location data to emails * fix(templates): Ditch the style elements, move styles to elements themselves. Also - update the write-to-disk script to add location information. Also - add if conditionals around the ip and timestamp --- mailer.js | 51 +- npm-shrinkwrap.json | 1249 +++++++++++++++++++++---------- package.json | 1 + partials/new_device_login.html | 6 +- partials/verify_login.html | 7 +- scripts/write-to-disk.js | 9 +- templates/new_device_login.html | 6 +- templates/new_device_login.txt | 4 +- templates/verify_login.html | 7 +- templates/verify_login.txt | 6 +- test/local/mailer_tests.js | 35 + 11 files changed, 959 insertions(+), 422 deletions(-) diff --git a/mailer.js b/mailer.js index ed2f1e7a..8e9c22f2 100644 --- a/mailer.js +++ b/mailer.js @@ -5,6 +5,10 @@ var qs = require('querystring') var P = require('bluebird') var nodemailer = require('nodemailer') +var moment = require('moment-timezone') + +var DEFAULT_LOCALE = 'en' +var DEFAULT_TIMEZONE = 'Etc/UTC' module.exports = function (log) { function extend(target, source) { @@ -26,6 +30,19 @@ module.exports = function (log) { return 'href="' + url + '" style="color: #0095dd; text-decoration: none; font-family: sans-serif;"' } + function constructLocalTimeString (timeZone, locale) { + // if no timeZone is passed, use DEFAULT_TIMEZONE + moment.tz.setDefault(DEFAULT_TIMEZONE) + // if no locale is passed, use DEFAULT_LOCALE + locale = locale || DEFAULT_LOCALE + moment.locale(locale) + var time = moment() + if (timeZone) { + time = time.tz(timeZone) + } + // return a locale-specific time + return time.format('LTS (z) dddd, ll') + } function Mailer(translator, templates, config, sender) { var options = { @@ -95,6 +112,25 @@ module.exports = function (log) { return parts.join(', ') } + Mailer.prototype._constructLocationString = function (message) { + var translator = this.translator(message.acceptLanguage) + var location = message.location + // construct the location string from the location object + if (location) { + if (location.city) { + return translator.format(translator.gettext('%(city)s, %(country)s (estimated)'), location) + } else { + return translator.format(translator.gettext('%(country)s (estimated)'), location) + } + } + return '' + } + + Mailer.prototype._constructLocalTimeString = function (timeZone, acceptLanguage) { + var translator = this.translator(acceptLanguage) + return constructLocalTimeString(timeZone, translator.language) + } + Mailer.prototype.localize = function (message) { var translator = this.translator(message.acceptLanguage) @@ -218,12 +254,15 @@ module.exports = function (log) { templateValues: { device: this._formatUserAgentInfo(message), email: message.email, + ip: message.ip, link: link, + location: this._constructLocationString(message), oneClickLink: oneClickLink, passwordChangeLink: this.createPasswordChangeLink(message.email), passwordChangeLinkAttributes: this._passwordChangeLinkAttributes(message.email), supportLinkAttributes: linkAttributes(this.supportUrl), - supportUrl: this.supportUrl + supportUrl: this.supportUrl, + timestamp: this._constructLocalTimeString(message.timeZone, message.acceptLanguage) }, uid: message.uid }) @@ -326,12 +365,6 @@ module.exports = function (log) { log.trace({ op: 'mailer.newDeviceLoginEmail', email: message.email, uid: message.uid }) var link = this.createPasswordChangeLink(message.email) - // Make a human-readable timestamp string. - // For now it's always in UTC. - // Future iterations can localize this better. - var timestamp = new Date(message.timestamp || Date.now()) - var timestampStr = timestamp.toISOString().substr(0, 16).replace('T', ' ') + ' UTC' - return this.send({ acceptLanguage: message.acceptLanguage, email: message.email, @@ -342,11 +375,13 @@ module.exports = function (log) { template: 'newDeviceLoginEmail', templateValues: { device: this._formatUserAgentInfo(message), + ip: message.ip, + location: this._constructLocationString(message), passwordChangeLinkAttributes: this._passwordChangeLinkAttributes(message.email), resetLink: link, supportLinkAttributes: this._supportLinkAttributes(), supportUrl: this.supportUrl, - timestamp: timestampStr + timestamp: this._constructLocalTimeString(message.timeZone, message.acceptLanguage) }, uid: message.uid }) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index b34dd437..5e1274e5 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -96,119 +96,13 @@ }, "fxa-auth-db-mysql": { "version": "0.64.0", - "from": "git+https://github.com/mozilla/fxa-auth-db-mysql.git#master", - "resolved": "git+https://github.com/mozilla/fxa-auth-db-mysql.git#7d83b29b57f8d08a64c8c3e14f0fce3259ce83de", + "from": "git+https://github.com/mozilla/fxa-auth-db-mysql.git#617bab8af25e3432955e83f487921798eac83f0a", + "resolved": "git+https://github.com/mozilla/fxa-auth-db-mysql.git#617bab8af25e3432955e83f487921798eac83f0a", "dependencies": { "base64url": { - "version": "1.0.6", - "from": "https://registry.npmjs.org/base64url/-/base64url-1.0.6.tgz", - "resolved": "https://registry.npmjs.org/base64url/-/base64url-1.0.6.tgz", - "dependencies": { - "concat-stream": { - "version": "1.4.10", - "from": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.4.10.tgz", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.4.10.tgz", - "dependencies": { - "inherits": { - "version": "2.0.1", - "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" - }, - "typedarray": { - "version": "0.0.6", - "from": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz" - }, - "readable-stream": { - "version": "1.1.14", - "from": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "dependencies": { - "core-util-is": { - "version": "1.0.2", - "from": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" - }, - "isarray": { - "version": "0.0.1", - "from": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" - }, - "string_decoder": { - "version": "0.10.31", - "from": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" - } - } - } - } - }, - "meow": { - "version": "2.0.0", - "from": "https://registry.npmjs.org/meow/-/meow-2.0.0.tgz", - "resolved": "https://registry.npmjs.org/meow/-/meow-2.0.0.tgz", - "dependencies": { - "camelcase-keys": { - "version": "1.0.0", - "from": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-1.0.0.tgz", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-1.0.0.tgz", - "dependencies": { - "camelcase": { - "version": "1.2.1", - "from": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz" - }, - "map-obj": { - "version": "1.0.1", - "from": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz" - } - } - }, - "indent-string": { - "version": "1.2.2", - "from": "https://registry.npmjs.org/indent-string/-/indent-string-1.2.2.tgz", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-1.2.2.tgz", - "dependencies": { - "get-stdin": { - "version": "4.0.1", - "from": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz" - }, - "repeating": { - "version": "1.1.3", - "from": "https://registry.npmjs.org/repeating/-/repeating-1.1.3.tgz", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-1.1.3.tgz", - "dependencies": { - "is-finite": { - "version": "1.0.1", - "from": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.1.tgz", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.1.tgz", - "dependencies": { - "number-is-nan": { - "version": "1.0.0", - "from": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz" - } - } - } - } - } - } - }, - "minimist": { - "version": "1.2.0", - "from": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz" - }, - "object-assign": { - "version": "1.0.0", - "from": "https://registry.npmjs.org/object-assign/-/object-assign-1.0.0.tgz", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-1.0.0.tgz" - } - } - } - } + "version": "2.0.0", + "from": "https://registry.npmjs.org/base64url/-/base64url-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-2.0.0.tgz" }, "bluebird": { "version": "2.1.3", @@ -216,99 +110,39 @@ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.1.3.tgz" }, "clone": { - "version": "0.2.0", - "from": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", - "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz" + "version": "1.0.2", + "from": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz" }, "convict": { - "version": "1.0.1", - "from": "https://registry.npmjs.org/convict/-/convict-1.0.1.tgz", - "resolved": "https://registry.npmjs.org/convict/-/convict-1.0.1.tgz", + "version": "1.4.0", + "from": "https://registry.npmjs.org/convict/-/convict-1.4.0.tgz", + "resolved": "https://registry.npmjs.org/convict/-/convict-1.4.0.tgz", "dependencies": { - "cjson": { - "version": "0.3.1", - "from": "https://registry.npmjs.org/cjson/-/cjson-0.3.1.tgz", - "resolved": "https://registry.npmjs.org/cjson/-/cjson-0.3.1.tgz", - "dependencies": { - "jsonlint": { - "version": "1.6.0", - "from": "https://registry.npmjs.org/jsonlint/-/jsonlint-1.6.0.tgz", - "resolved": "https://registry.npmjs.org/jsonlint/-/jsonlint-1.6.0.tgz", - "dependencies": { - "nomnom": { - "version": "1.8.1", - "from": "https://registry.npmjs.org/nomnom/-/nomnom-1.8.1.tgz", - "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.8.1.tgz", - "dependencies": { - "underscore": { - "version": "1.6.0", - "from": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz" - }, - "chalk": { - "version": "0.4.0", - "from": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", - "dependencies": { - "has-color": { - "version": "0.1.7", - "from": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", - "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz" - }, - "ansi-styles": { - "version": "1.0.0", - "from": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz" - }, - "strip-ansi": { - "version": "0.1.1", - "from": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz" - } - } - } - } - }, - "JSV": { - "version": "4.0.2", - "from": "https://registry.npmjs.org/JSV/-/JSV-4.0.2.tgz", - "resolved": "https://registry.npmjs.org/JSV/-/JSV-4.0.2.tgz" - } - } - } - } - }, "depd": { - "version": "1.0.1", - "from": "https://registry.npmjs.org/depd/-/depd-1.0.1.tgz", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.0.1.tgz" + "version": "1.1.0", + "from": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz" + }, + "json5": { + "version": "0.5.0", + "from": "https://registry.npmjs.org/json5/-/json5-0.5.0.tgz", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.0.tgz" + }, + "minimist": { + "version": "1.2.0", + "from": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz" }, "moment": { - "version": "2.10.6", - "from": "https://registry.npmjs.org/moment/-/moment-2.10.6.tgz", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.10.6.tgz" - }, - "optimist": { - "version": "0.6.1", - "from": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "dependencies": { - "wordwrap": { - "version": "0.0.3", - "from": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz" - }, - "minimist": { - "version": "0.0.10", - "from": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz" - } - } + "version": "2.12.0", + "from": "https://registry.npmjs.org/moment/-/moment-2.12.0.tgz", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.12.0.tgz" }, "validator": { - "version": "3.43.0", - "from": "https://registry.npmjs.org/validator/-/validator-3.43.0.tgz", - "resolved": "https://registry.npmjs.org/validator/-/validator-3.43.0.tgz" + "version": "4.6.1", + "from": "https://registry.npmjs.org/validator/-/validator-4.6.1.tgz", + "resolved": "https://registry.npmjs.org/validator/-/validator-4.6.1.tgz" }, "varify": { "version": "0.1.1", @@ -337,14 +171,14 @@ } }, "fxa-jwtool": { - "version": "0.7.1", - "from": "https://registry.npmjs.org/fxa-jwtool/-/fxa-jwtool-0.7.1.tgz", - "resolved": "https://registry.npmjs.org/fxa-jwtool/-/fxa-jwtool-0.7.1.tgz", + "version": "0.7.2", + "from": "https://registry.npmjs.org/fxa-jwtool/-/fxa-jwtool-0.7.2.tgz", + "resolved": "https://registry.npmjs.org/fxa-jwtool/-/fxa-jwtool-0.7.2.tgz", "dependencies": { "bluebird": { - "version": "2.9.15", - "from": "https://registry.npmjs.org/bluebird/-/bluebird-2.9.15.tgz", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.9.15.tgz" + "version": "3.0.5", + "from": "https://registry.npmjs.org/bluebird/-/bluebird-3.0.5.tgz", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.0.5.tgz" }, "fetch": { "version": "0.3.6", @@ -397,14 +231,14 @@ } }, "mysql": { - "version": "2.10.0", - "from": "https://registry.npmjs.org/mysql/-/mysql-2.10.0.tgz", - "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.10.0.tgz", + "version": "2.11.1", + "from": "https://registry.npmjs.org/mysql/-/mysql-2.11.1.tgz", + "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.11.1.tgz", "dependencies": { "bignumber.js": { - "version": "2.1.2", - "from": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-2.1.2.tgz", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-2.1.2.tgz" + "version": "2.3.0", + "from": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-2.3.0.tgz" }, "readable-stream": { "version": "1.1.14", @@ -432,138 +266,227 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" } } + }, + "sqlstring": { + "version": "2.0.1", + "from": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.0.1.tgz" } } }, "request": { - "version": "2.53.0", - "from": "https://registry.npmjs.org/request/-/request-2.53.0.tgz", - "resolved": "https://registry.npmjs.org/request/-/request-2.53.0.tgz", + "version": "2.73.0", + "from": "https://registry.npmjs.org/request/-/request-2.73.0.tgz", + "resolved": "https://registry.npmjs.org/request/-/request-2.73.0.tgz", "dependencies": { + "aws-sign2": { + "version": "0.6.0", + "from": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz" + }, + "aws4": { + "version": "1.4.1", + "from": "https://registry.npmjs.org/aws4/-/aws4-1.4.1.tgz", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.4.1.tgz" + }, "bl": { - "version": "0.9.5", - "from": "https://registry.npmjs.org/bl/-/bl-0.9.5.tgz", - "resolved": "https://registry.npmjs.org/bl/-/bl-0.9.5.tgz", + "version": "1.1.2", + "from": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz", "dependencies": { "readable-stream": { - "version": "1.0.34", - "from": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "version": "2.0.6", + "from": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", "dependencies": { "core-util-is": { "version": "1.0.2", "from": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" }, + "inherits": { + "version": "2.0.1", + "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, "isarray": { - "version": "0.0.1", - "from": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + "version": "1.0.0", + "from": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + }, + "process-nextick-args": { + "version": "1.0.7", + "from": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz" }, "string_decoder": { "version": "0.10.31", "from": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" }, - "inherits": { - "version": "2.0.1", - "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + "util-deprecate": { + "version": "1.0.2", + "from": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" } } } } }, "caseless": { - "version": "0.9.0", - "from": "https://registry.npmjs.org/caseless/-/caseless-0.9.0.tgz", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.9.0.tgz" + "version": "0.11.0", + "from": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz" + }, + "combined-stream": { + "version": "1.0.5", + "from": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "dependencies": { + "delayed-stream": { + "version": "1.0.0", + "from": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" + } + } + }, + "extend": { + "version": "3.0.0", + "from": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz" }, "forever-agent": { - "version": "0.5.2", - "from": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz" + "version": "0.6.1", + "from": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz" }, "form-data": { - "version": "0.2.0", - "from": "https://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz", + "version": "1.0.0-rc4", + "from": "https://registry.npmjs.org/form-data/-/form-data-1.0.0-rc4.tgz", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.0-rc4.tgz", "dependencies": { "async": { - "version": "0.9.2", - "from": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz" + "version": "1.5.2", + "from": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz" } } }, - "json-stringify-safe": { - "version": "5.0.1", - "from": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" - }, - "mime-types": { - "version": "2.0.14", - "from": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz", + "har-validator": { + "version": "2.0.6", + "from": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", "dependencies": { - "mime-db": { - "version": "1.12.0", - "from": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz" + "chalk": { + "version": "1.1.3", + "from": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "from": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz" + }, + "escape-string-regexp": { + "version": "1.0.5", + "from": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + }, + "has-ansi": { + "version": "2.0.0", + "from": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "dependencies": { + "ansi-regex": { + "version": "2.0.0", + "from": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "from": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "dependencies": { + "ansi-regex": { + "version": "2.0.0", + "from": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" + } + } + }, + "supports-color": { + "version": "2.0.0", + "from": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" + } + } + }, + "commander": { + "version": "2.9.0", + "from": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "dependencies": { + "graceful-readlink": { + "version": "1.0.1", + "from": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz" + } + } + }, + "is-my-json-valid": { + "version": "2.13.1", + "from": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.13.1.tgz", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.13.1.tgz", + "dependencies": { + "generate-function": { + "version": "2.0.0", + "from": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz" + }, + "generate-object-property": { + "version": "1.2.0", + "from": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "dependencies": { + "is-property": { + "version": "1.0.2", + "from": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz" + } + } + }, + "jsonpointer": { + "version": "2.0.0", + "from": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-2.0.0.tgz" + }, + "xtend": { + "version": "4.0.1", + "from": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" + } + } + }, + "pinkie-promise": { + "version": "2.0.1", + "from": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "dependencies": { + "pinkie": { + "version": "2.0.4", + "from": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz" + } + } } } }, - "node-uuid": { - "version": "1.4.7", - "from": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz" - }, - "qs": { - "version": "2.3.3", - "from": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz", - "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz" - }, - "tunnel-agent": { - "version": "0.4.3", - "from": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz" - }, - "tough-cookie": { - "version": "2.2.2", - "from": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.2.2.tgz", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.2.2.tgz" - }, - "http-signature": { - "version": "0.10.1", - "from": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", - "dependencies": { - "assert-plus": { - "version": "0.1.5", - "from": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz" - }, - "asn1": { - "version": "0.1.11", - "from": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz" - }, - "ctype": { - "version": "0.5.3", - "from": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", - "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz" - } - } - }, - "oauth-sign": { - "version": "0.6.0", - "from": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.6.0.tgz", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.6.0.tgz" - }, "hawk": { - "version": "2.3.1", - "from": "https://registry.npmjs.org/hawk/-/hawk-2.3.1.tgz", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-2.3.1.tgz", + "version": "3.1.3", + "from": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", "dependencies": { "hoek": { "version": "2.16.3", @@ -587,32 +510,534 @@ } } }, - "aws-sign2": { - "version": "0.5.0", - "from": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz" + "http-signature": { + "version": "1.1.1", + "from": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "dependencies": { + "assert-plus": { + "version": "0.2.0", + "from": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz" + }, + "jsprim": { + "version": "1.3.0", + "from": "https://registry.npmjs.org/jsprim/-/jsprim-1.3.0.tgz", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.3.0.tgz", + "dependencies": { + "extsprintf": { + "version": "1.0.2", + "from": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz" + }, + "json-schema": { + "version": "0.2.2", + "from": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.2.tgz", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.2.tgz" + }, + "verror": { + "version": "1.3.6", + "from": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz" + } + } + }, + "sshpk": { + "version": "1.8.3", + "from": "https://registry.npmjs.org/sshpk/-/sshpk-1.8.3.tgz", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.8.3.tgz", + "dependencies": { + "asn1": { + "version": "0.2.3", + "from": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz" + }, + "assert-plus": { + "version": "1.0.0", + "from": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" + }, + "dashdash": { + "version": "1.14.0", + "from": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.0.tgz", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.0.tgz" + }, + "getpass": { + "version": "0.1.6", + "from": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz" + }, + "jsbn": { + "version": "0.1.0", + "from": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.0.tgz", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.0.tgz" + }, + "tweetnacl": { + "version": "0.13.3", + "from": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.13.3.tgz", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.13.3.tgz" + }, + "jodid25519": { + "version": "1.0.2", + "from": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz" + }, + "ecc-jsbn": { + "version": "0.1.1", + "from": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz" + } + } + } + } + }, + "is-typedarray": { + "version": "1.0.0", + "from": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" + }, + "isstream": { + "version": "0.1.2", + "from": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" + }, + "json-stringify-safe": { + "version": "5.0.1", + "from": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" + }, + "mime-types": { + "version": "2.1.11", + "from": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.11.tgz", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.11.tgz", + "dependencies": { + "mime-db": { + "version": "1.23.0", + "from": "https://registry.npmjs.org/mime-db/-/mime-db-1.23.0.tgz", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.23.0.tgz" + } + } + }, + "node-uuid": { + "version": "1.4.7", + "from": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz" + }, + "oauth-sign": { + "version": "0.8.2", + "from": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz" + }, + "qs": { + "version": "6.2.0", + "from": "https://registry.npmjs.org/qs/-/qs-6.2.0.tgz", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.0.tgz" }, "stringstream": { "version": "0.0.5", "from": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz" }, - "combined-stream": { - "version": "0.0.7", - "from": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", + "tough-cookie": { + "version": "2.2.2", + "from": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.2.2.tgz", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.2.2.tgz" + }, + "tunnel-agent": { + "version": "0.4.3", + "from": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz" + } + } + }, + "restify": { + "version": "4.1.1", + "from": "https://registry.npmjs.org/restify/-/restify-4.1.1.tgz", + "resolved": "https://registry.npmjs.org/restify/-/restify-4.1.1.tgz", + "dependencies": { + "assert-plus": { + "version": "0.1.5", + "from": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz" + }, + "backoff": { + "version": "2.5.0", + "from": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz", + "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz", "dependencies": { - "delayed-stream": { - "version": "0.0.5", - "from": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz" + "precond": { + "version": "0.2.3", + "from": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz", + "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz" } } }, - "isstream": { - "version": "0.1.2", - "from": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" + "bunyan": { + "version": "1.8.1", + "from": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.1.tgz", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.1.tgz", + "dependencies": { + "mv": { + "version": "2.1.1", + "from": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", + "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", + "dependencies": { + "ncp": { + "version": "2.0.0", + "from": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz" + }, + "rimraf": { + "version": "2.4.5", + "from": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", + "dependencies": { + "glob": { + "version": "6.0.4", + "from": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "dependencies": { + "inflight": { + "version": "1.0.5", + "from": "https://registry.npmjs.org/inflight/-/inflight-1.0.5.tgz", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.5.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.2", + "from": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + } + } + }, + "inherits": { + "version": "2.0.1", + "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, + "minimatch": { + "version": "3.0.2", + "from": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.2.tgz", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.2.tgz", + "dependencies": { + "brace-expansion": { + "version": "1.1.5", + "from": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.5.tgz", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.5.tgz", + "dependencies": { + "balanced-match": { + "version": "0.4.2", + "from": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz" + }, + "concat-map": { + "version": "0.0.1", + "from": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + } + } + } + } + }, + "path-is-absolute": { + "version": "1.0.0", + "from": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz" + } + } + } + } + } + } + }, + "safe-json-stringify": { + "version": "1.0.3", + "from": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.0.3.tgz", + "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.0.3.tgz" + }, + "moment": { + "version": "2.14.1", + "from": "https://registry.npmjs.org/moment/-/moment-2.14.1.tgz", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.14.1.tgz" + } + } + }, + "csv": { + "version": "0.4.6", + "from": "https://registry.npmjs.org/csv/-/csv-0.4.6.tgz", + "resolved": "https://registry.npmjs.org/csv/-/csv-0.4.6.tgz", + "dependencies": { + "csv-generate": { + "version": "0.0.6", + "from": "https://registry.npmjs.org/csv-generate/-/csv-generate-0.0.6.tgz", + "resolved": "https://registry.npmjs.org/csv-generate/-/csv-generate-0.0.6.tgz" + }, + "csv-parse": { + "version": "1.1.4", + "from": "https://registry.npmjs.org/csv-parse/-/csv-parse-1.1.4.tgz", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-1.1.4.tgz" + }, + "stream-transform": { + "version": "0.1.1", + "from": "https://registry.npmjs.org/stream-transform/-/stream-transform-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/stream-transform/-/stream-transform-0.1.1.tgz" + }, + "csv-stringify": { + "version": "0.0.8", + "from": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-0.0.8.tgz", + "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-0.0.8.tgz" + } + } + }, + "escape-regexp-component": { + "version": "1.0.2", + "from": "https://registry.npmjs.org/escape-regexp-component/-/escape-regexp-component-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/escape-regexp-component/-/escape-regexp-component-1.0.2.tgz" + }, + "formidable": { + "version": "1.0.17", + "from": "https://registry.npmjs.org/formidable/-/formidable-1.0.17.tgz", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.0.17.tgz" + }, + "http-signature": { + "version": "0.11.0", + "from": "https://registry.npmjs.org/http-signature/-/http-signature-0.11.0.tgz", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.11.0.tgz", + "dependencies": { + "asn1": { + "version": "0.1.11", + "from": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz" + }, + "ctype": { + "version": "0.5.3", + "from": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", + "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz" + } + } + }, + "keep-alive-agent": { + "version": "0.0.1", + "from": "https://registry.npmjs.org/keep-alive-agent/-/keep-alive-agent-0.0.1.tgz", + "resolved": "https://registry.npmjs.org/keep-alive-agent/-/keep-alive-agent-0.0.1.tgz" + }, + "lru-cache": { + "version": "4.0.1", + "from": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.1.tgz", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.1.tgz", + "dependencies": { + "pseudomap": { + "version": "1.0.2", + "from": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz" + }, + "yallist": { + "version": "2.0.0", + "from": "https://registry.npmjs.org/yallist/-/yallist-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.0.0.tgz" + } + } + }, + "mime": { + "version": "1.3.4", + "from": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz" + }, + "negotiator": { + "version": "0.6.1", + "from": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz" + }, + "node-uuid": { + "version": "1.4.7", + "from": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz" + }, + "once": { + "version": "1.3.3", + "from": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.2", + "from": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + } + } + }, + "qs": { + "version": "3.1.0", + "from": "https://registry.npmjs.org/qs/-/qs-3.1.0.tgz", + "resolved": "https://registry.npmjs.org/qs/-/qs-3.1.0.tgz" + }, + "semver": { + "version": "4.3.6", + "from": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz" + }, + "spdy": { + "version": "3.3.4", + "from": "https://registry.npmjs.com/spdy/-/spdy-3.3.4.tgz", + "resolved": "https://registry.npmjs.com/spdy/-/spdy-3.3.4.tgz", + "dependencies": { + "debug": { + "version": "2.2.0", + "from": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "dependencies": { + "ms": { + "version": "0.7.1", + "from": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz" + } + } + }, + "handle-thing": { + "version": "1.2.4", + "from": "https://registry.npmjs.org/handle-thing/-/handle-thing-1.2.4.tgz", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-1.2.4.tgz" + }, + "http-deceiver": { + "version": "1.2.7", + "from": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz" + }, + "select-hose": { + "version": "2.0.0", + "from": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz" + }, + "spdy-transport": { + "version": "2.0.11", + "from": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-2.0.11.tgz", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-2.0.11.tgz", + "dependencies": { + "hpack.js": { + "version": "2.1.4", + "from": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.4.tgz", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.4.tgz", + "dependencies": { + "inherits": { + "version": "2.0.1", + "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + } + } + }, + "obuf": { + "version": "1.1.1", + "from": "https://registry.npmjs.org/obuf/-/obuf-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.1.tgz" + }, + "readable-stream": { + "version": "2.1.4", + "from": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.4.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.4.tgz", + "dependencies": { + "buffer-shims": { + "version": "1.0.0", + "from": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz" + }, + "core-util-is": { + "version": "1.0.2", + "from": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" + }, + "inherits": { + "version": "2.0.1", + "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, + "isarray": { + "version": "1.0.0", + "from": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + }, + "process-nextick-args": { + "version": "1.0.7", + "from": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz" + }, + "string_decoder": { + "version": "0.10.31", + "from": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + }, + "util-deprecate": { + "version": "1.0.2", + "from": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + } + } + }, + "wbuf": { + "version": "1.7.2", + "from": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.2.tgz", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.2.tgz", + "dependencies": { + "minimalistic-assert": { + "version": "1.0.0", + "from": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz" + } + } + } + } + } + } + }, + "tunnel-agent": { + "version": "0.4.3", + "from": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz" + }, + "vasync": { + "version": "1.6.3", + "from": "https://registry.npmjs.org/vasync/-/vasync-1.6.3.tgz", + "resolved": "https://registry.npmjs.org/vasync/-/vasync-1.6.3.tgz", + "dependencies": { + "verror": { + "version": "1.6.0", + "from": "https://registry.npmjs.org/verror/-/verror-1.6.0.tgz", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.6.0.tgz", + "dependencies": { + "extsprintf": { + "version": "1.2.0", + "from": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.2.0.tgz" + } + } + } + } + }, + "verror": { + "version": "1.6.1", + "from": "https://registry.npmjs.org/verror/-/verror-1.6.1.tgz", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.6.1.tgz", + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "from": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" + }, + "extsprintf": { + "version": "1.2.0", + "from": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.2.0.tgz" + } + } + }, + "dtrace-provider": { + "version": "0.6.0", + "from": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.6.0.tgz", + "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.6.0.tgz", + "dependencies": { + "nan": { + "version": "2.4.0", + "from": "https://registry.npmjs.org/nan/-/nan-2.4.0.tgz", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.4.0.tgz" + } + } } } } @@ -620,8 +1045,8 @@ }, "fxa-content-server-l10n": { "version": "0.0.0", - "from": "git://github.com/mozilla/fxa-content-server-l10n.git", - "resolved": "git://github.com/mozilla/fxa-content-server-l10n.git#e71ca277304cd96f7e761184f40b9b3d7ea7eb0c" + "from": "git://github.com/mozilla/fxa-content-server-l10n.git#577f89e9a97a6b7de8d0bdd7ad3ce4a59e29a416", + "resolved": "git://github.com/mozilla/fxa-content-server-l10n.git#577f89e9a97a6b7de8d0bdd7ad3ce4a59e29a416" }, "fxa-conventional-changelog": { "version": "1.1.0", @@ -712,9 +1137,9 @@ "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz" }, "lodash.isarguments": { - "version": "3.0.8", + "version": "3.0.9", "from": "lodash.isarguments@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.0.8.tgz" + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.0.9.tgz" } } } @@ -1102,7 +1527,7 @@ }, "glob": { "version": "7.0.5", - "from": "glob@>=7.0.0 <8.0.0", + "from": "glob@>=7.0.0 <7.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.5.tgz", "dependencies": { "fs.realpath": { @@ -1163,7 +1588,7 @@ "dependencies": { "chalk": { "version": "1.1.3", - "from": "chalk@>=1.1.0 <1.2.0", + "from": "chalk@>=1.1.1 <1.2.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "dependencies": { "ansi-styles": { @@ -1310,9 +1735,9 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.2.tgz", "dependencies": { "brace-expansion": { - "version": "1.1.5", + "version": "1.1.6", "from": "brace-expansion@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.5.tgz", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz", "dependencies": { "balanced-match": { "version": "0.4.2", @@ -1402,9 +1827,9 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.2.tgz", "dependencies": { "brace-expansion": { - "version": "1.1.5", + "version": "1.1.6", "from": "brace-expansion@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.5.tgz", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz", "dependencies": { "balanced-match": { "version": "0.4.2", @@ -1760,7 +2185,7 @@ "dependencies": { "align-text": { "version": "0.1.4", - "from": "align-text@>=0.1.1 <0.2.0", + "from": "align-text@>=0.1.3 <0.2.0", "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", "dependencies": { "kind-of": { @@ -1854,9 +2279,9 @@ } }, "lodash": { - "version": "4.13.1", + "version": "4.14.0", "from": "lodash@>=4.0.0 <5.0.0", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.13.1.tgz" + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.14.0.tgz" }, "split": { "version": "1.0.0", @@ -1921,7 +2346,7 @@ "trim-off-newlines": { "version": "1.0.1", "from": "trim-off-newlines@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz" + "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz" } } }, @@ -1976,7 +2401,7 @@ "dependencies": { "spdx-license-ids": { "version": "1.2.1", - "from": "spdx-license-ids@>=1.0.2 <2.0.0", + "from": "spdx-license-ids@>=1.0.0 <2.0.0", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.1.tgz" } } @@ -2074,9 +2499,9 @@ "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz" }, "lodash.isarguments": { - "version": "3.0.8", + "version": "3.0.9", "from": "lodash.isarguments@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.0.8.tgz" + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.0.9.tgz" }, "lodash.isarray": { "version": "3.0.4", @@ -2172,7 +2597,7 @@ }, "normalize-package-data": { "version": "2.3.5", - "from": "normalize-package-data@>=2.3.4 <3.0.0", + "from": "normalize-package-data@>=2.3.2 <3.0.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.5.tgz", "dependencies": { "hosted-git-info": { @@ -2894,9 +3319,9 @@ } }, "rimraf": { - "version": "2.5.3", + "version": "2.5.4", "from": "rimraf@>=2.2.8 <3.0.0", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.3.tgz" + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz" } } }, @@ -2957,9 +3382,9 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.2.tgz", "dependencies": { "brace-expansion": { - "version": "1.1.5", + "version": "1.1.6", "from": "brace-expansion@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.5.tgz", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz", "dependencies": { "balanced-match": { "version": "0.4.2", @@ -3268,9 +3693,9 @@ } }, "lodash": { - "version": "4.13.1", + "version": "4.14.0", "from": "lodash@>=4.0.0 <5.0.0", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.13.1.tgz" + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.14.0.tgz" }, "optionator": { "version": "0.8.1", @@ -3298,9 +3723,9 @@ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz" }, "fast-levenshtein": { - "version": "1.1.3", + "version": "1.1.4", "from": "fast-levenshtein@>=1.1.0 <2.0.0", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.1.3.tgz" + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz" } } }, @@ -3451,7 +3876,7 @@ }, "grunt-nunjucks-2-html": { "version": "0.3.4", - "from": "vitkarpov/grunt-nunjucks-2-html#1900f91a756b2eaf900b20", + "from": "git://github.com/vitkarpov/grunt-nunjucks-2-html.git#1900f91a756b2eaf900b20ca7a28b10267ca55ba", "resolved": "git://github.com/vitkarpov/grunt-nunjucks-2-html.git#1900f91a756b2eaf900b20ca7a28b10267ca55ba", "dependencies": { "async": { @@ -3730,9 +4155,9 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.2.tgz", "dependencies": { "brace-expansion": { - "version": "1.1.5", + "version": "1.1.6", "from": "brace-expansion@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.5.tgz", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz", "dependencies": { "balanced-match": { "version": "0.4.2", @@ -3807,16 +4232,16 @@ "from": "node-pre-gyp@>=0.6.29 <0.7.0", "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.6.29.tgz" }, - "ansi-regex": { - "version": "2.0.0", - "from": "ansi-regex@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" - }, "abbrev": { "version": "1.0.9", "from": "abbrev@>=1.0.0 <2.0.0", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz" }, + "ansi-regex": { + "version": "2.0.0", + "from": "ansi-regex@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" + }, "ansi-styles": { "version": "2.2.1", "from": "ansi-styles@>=2.2.1 <3.0.0", @@ -3827,16 +4252,16 @@ "from": "aproba@>=1.0.3 <2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.0.4.tgz" }, - "asn1": { - "version": "0.2.3", - "from": "asn1@>=0.2.3 <0.3.0", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz" - }, "are-we-there-yet": { "version": "1.1.2", "from": "are-we-there-yet@>=1.1.2 <1.2.0", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.2.tgz" }, + "asn1": { + "version": "0.2.3", + "from": "asn1@>=0.2.3 <0.3.0", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz" + }, "assert-plus": { "version": "0.2.0", "from": "assert-plus@>=0.2.0 <0.3.0", @@ -3892,16 +4317,16 @@ "from": "chalk@>=1.1.1 <2.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz" }, - "combined-stream": { - "version": "1.0.5", - "from": "combined-stream@>=1.0.5 <1.1.0", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz" - }, "code-point-at": { "version": "1.0.0", "from": "code-point-at@>=1.0.0 <2.0.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.0.0.tgz" }, + "combined-stream": { + "version": "1.0.5", + "from": "combined-stream@>=1.0.5 <1.1.0", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz" + }, "commander": { "version": "2.9.0", "from": "commander@>=2.9.0 <3.0.0", @@ -3932,11 +4357,6 @@ "from": "debug@>=2.2.0 <2.3.0", "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz" }, - "deep-extend": { - "version": "0.4.1", - "from": "deep-extend@>=0.4.0 <0.5.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.1.tgz" - }, "delayed-stream": { "version": "1.0.0", "from": "delayed-stream@>=1.0.0 <1.1.0", @@ -3947,6 +4367,11 @@ "from": "delegates@>=1.0.0 <2.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz" }, + "deep-extend": { + "version": "0.4.1", + "from": "deep-extend@>=0.4.0 <0.5.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.1.tgz" + }, "ecc-jsbn": { "version": "0.1.1", "from": "ecc-jsbn@>=0.1.1 <0.2.0", @@ -4007,46 +4432,46 @@ "from": "generate-object-property@>=1.1.0 <2.0.0", "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz" }, - "glob": { - "version": "7.0.5", - "from": "glob@>=7.0.5 <8.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.5.tgz" - }, "graceful-fs": { "version": "4.1.4", "from": "graceful-fs@>=4.1.2 <5.0.0", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.4.tgz" }, + "glob": { + "version": "7.0.5", + "from": "glob@>=7.0.5 <8.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.5.tgz" + }, "graceful-readlink": { "version": "1.0.1", "from": "graceful-readlink@>=1.0.0", "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz" }, - "har-validator": { - "version": "2.0.6", - "from": "har-validator@>=2.0.6 <2.1.0", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz" - }, "has-ansi": { "version": "2.0.0", "from": "has-ansi@>=2.0.0 <3.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz" }, + "har-validator": { + "version": "2.0.6", + "from": "har-validator@>=2.0.6 <2.1.0", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz" + }, "has-color": { "version": "0.1.7", "from": "has-color@>=0.1.7 <0.2.0", "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz" }, - "has-unicode": { - "version": "2.0.1", - "from": "has-unicode@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz" - }, "hawk": { "version": "3.1.3", "from": "hawk@>=3.1.3 <3.2.0", "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz" }, + "has-unicode": { + "version": "2.0.1", + "from": "has-unicode@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz" + }, "hoek": { "version": "2.16.3", "from": "hoek@>=2.0.0 <3.0.0", @@ -4087,16 +4512,16 @@ "from": "is-property@>=1.0.0 <2.0.0", "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz" }, - "is-typedarray": { - "version": "1.0.0", - "from": "is-typedarray@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" - }, "isarray": { "version": "1.0.0", "from": "isarray@>=1.0.0 <1.1.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" }, + "is-typedarray": { + "version": "1.0.0", + "from": "is-typedarray@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" + }, "isstream": { "version": "0.1.2", "from": "isstream@>=0.1.2 <0.2.0", @@ -4192,6 +4617,11 @@ "from": "object-assign@>=4.1.0 <5.0.0", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz" }, + "once": { + "version": "1.3.3", + "from": "once@>=1.3.0 <2.0.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz" + }, "path-is-absolute": { "version": "1.0.0", "from": "path-is-absolute@>=1.0.0 <2.0.0", @@ -4202,11 +4632,6 @@ "from": "pinkie@>=2.0.0 <3.0.0", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz" }, - "once": { - "version": "1.3.3", - "from": "once@>=1.3.0 <2.0.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz" - }, "pinkie-promise": { "version": "2.0.1", "from": "pinkie-promise@>=2.0.0 <3.0.0", @@ -4423,7 +4848,7 @@ "dependencies": { "strip-ansi": { "version": "3.0.1", - "from": "strip-ansi@>=3.0.1 <4.0.0", + "from": "strip-ansi@>=3.0.0 <4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "dependencies": { "ansi-regex": { @@ -4638,9 +5063,9 @@ "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-1.2.1.tgz" }, "clean-css": { - "version": "3.4.18", + "version": "3.4.19", "from": "clean-css@>=3.1.9 <4.0.0", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.18.tgz", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.19.tgz", "dependencies": { "commander": { "version": "2.8.1", @@ -5178,9 +5603,9 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.2.tgz", "dependencies": { "brace-expansion": { - "version": "1.1.5", + "version": "1.1.6", "from": "brace-expansion@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.5.tgz", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz", "dependencies": { "balanced-match": { "version": "0.4.2", @@ -5325,13 +5750,13 @@ }, "minimatch": { "version": "3.0.2", - "from": "minimatch@>=3.0.0 <4.0.0", + "from": "minimatch@>=3.0.0 <3.1.0", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.2.tgz", "dependencies": { "brace-expansion": { - "version": "1.1.5", + "version": "1.1.6", "from": "brace-expansion@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.5.tgz", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz", "dependencies": { "balanced-match": { "version": "0.4.2", @@ -5406,6 +5831,18 @@ } } }, + "moment-timezone": { + "version": "0.5.4", + "from": "moment-timezone@0.5.4", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.4.tgz", + "dependencies": { + "moment": { + "version": "2.14.1", + "from": "moment@>=2.6.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.14.1.tgz" + } + } + }, "mozlog": { "version": "2.0.5", "from": "mozlog@2.0.5", @@ -6182,13 +6619,13 @@ }, "minimatch": { "version": "3.0.2", - "from": "minimatch@>=3.0.2 <4.0.0", + "from": "minimatch@>=2.0.0 <3.0.0||>=3.0.0 <4.0.0", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.2.tgz", "dependencies": { "brace-expansion": { - "version": "1.1.5", + "version": "1.1.6", "from": "brace-expansion@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.5.tgz", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz", "dependencies": { "balanced-match": { "version": "0.4.2", @@ -6238,9 +6675,9 @@ "resolved": "https://registry.npmjs.org/csv-generate/-/csv-generate-0.0.6.tgz" }, "csv-parse": { - "version": "1.1.4", + "version": "1.1.5", "from": "csv-parse@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-1.1.4.tgz" + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-1.1.5.tgz" }, "stream-transform": { "version": "0.1.1", @@ -6579,9 +7016,9 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.2.tgz", "dependencies": { "brace-expansion": { - "version": "1.1.5", + "version": "1.1.6", "from": "brace-expansion@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.5.tgz", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz", "dependencies": { "balanced-match": { "version": "0.4.2", @@ -8192,9 +8629,9 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.3.1.tgz" }, "tap-mocha-reporter": { - "version": "0.0.26", + "version": "0.0.27", "from": "tap-mocha-reporter@>=0.0.0 <0.1.0||>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.com/tap-mocha-reporter/-/tap-mocha-reporter-0.0.26.tgz", + "resolved": "https://registry.npmjs.org/tap-mocha-reporter/-/tap-mocha-reporter-0.0.27.tgz", "dependencies": { "color-support": { "version": "1.1.0", diff --git a/package.json b/package.json index 51de3a09..331b028f 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "handlebars": "1.3.0", "i18n-abide": "0.0.23", "jed": "0.5.4", + "moment-timezone": "0.5.4", "mozlog": "2.0.5", "nodemailer": "0.7.1", "po2json": "0.4.1", diff --git a/partials/new_device_login.html b/partials/new_device_login.html index 5efa2e04..3d43b5d0 100644 --- a/partials/new_device_login.html +++ b/partials/new_device_login.html @@ -1,4 +1,8 @@ <% extends "partials/base/base_text_only.html" %> <% block heading %>{{t "New sign-in to Firefox"}}<% endblock %> -<% block text_primary %>{{{ device }}}
{{ timestamp }}<% endblock %> +<% block text_primary %>{{{ device }}}
+{{#if ip }}{{t "IP address: %(ip)s" }}{{/if}} +{{#if location }}{{ location }}{{/if}} +{{#if timestamp }}{{ timestamp }}{{/if}} +<% endblock %> diff --git a/partials/verify_login.html b/partials/verify_login.html index 5bc2d793..9c1563ea 100644 --- a/partials/verify_login.html +++ b/partials/verify_login.html @@ -5,7 +5,12 @@

<% block verify_title %>{{t "New sign-in to Firefox"}}<% endblock %>

-

<% block verify_content %>{{t "For added security, please confirm this sign-in to begin syncing with %(device)s." }}<% endblock %>

+

<% block verify_content %>{{t "For added security, please confirm this sign-in to begin syncing with this device:"}}

+ {{{ device }}} + {{#if ip }}{{t "IP address: %(ip)s" }}{{/if}} + {{#if location }}{{ location }}{{/if}} + {{#if timestamp }}{{ timestamp }}{{/if}} + <% endblock %>

diff --git a/scripts/write-to-disk.js b/scripts/write-to-disk.js index 9c694bfa..b7db603f 100644 --- a/scripts/write-to-disk.js +++ b/scripts/write-to-disk.js @@ -17,7 +17,6 @@ * postVerifyEmail * recoveryEmail * suspiciousLocationEmail - * unlockEmail * verificationReminderEmail:first * verificationReminderEmail:second * verifyEmail @@ -82,14 +81,20 @@ function sendMail(mailer, messageToSend) { var messageSubType = parts[1] var message = { - acceptLanguage: 'en', + acceptLanguage: 'en;q=0.8,en-US;q=0.5,en;q=0.3"', code: 'ae35999f861ffc81d594034eb4560af8', email: 'testuser@testuser.com', + ip: '10.246.67.38', + location: { + city: 'Madrid', + country: 'Spain' + }, locations: [], redirectTo: 'https://redirect.com/', resume: 'eyJjYW1wYWlnbiI6bnVsbCwiZW50cnlwb2ludCI6bnVsbCwiZmxvd0lkIjoiM2Q1ODZiNzY4Mzc2NGJhOWFiNzhkMzMxMTdjZDU4Y2RmYjk3Mzk5MWU5NTk0NjgxODBlMDUyMmY2MThhNmEyMSIsInJlc2V0UGFzc3dvcmRDb25maXJtIjp0cnVlLCJ1bmlxdWVVc2VySWQiOiI1ODNkOGFlYS00NzU3LTRiZTQtYWJlNC0wZWQ2NWZhY2Y2YWQiLCJ1dG1DYW1wYWlnbiI6bnVsbCwidXRtQ29udGVudCI6bnVsbCwidXRtTWVkaXVtIjpudWxsLCJ1dG1Tb3VyY2UiOm51bGwsInV0bVRlcm0iOm51bGx9', service: 'sync', token: '47b22cd271963448cf36da95cccfcfb342b5693d66f58aa635f9a95579431002', + timeZone: 'Europe/Madrid', type: messageSubType, uaBrowser: 'Firefox', uaBrowserVersion: '47', diff --git a/templates/new_device_login.html b/templates/new_device_login.html index 5ca79f93..286a2915 100644 --- a/templates/new_device_login.html +++ b/templates/new_device_login.html @@ -20,7 +20,11 @@

{{t "New sign-in to Firefox"}}

-

{{{ device }}}
{{ timestamp }}

+

{{{ device }}}
+{{#if ip }}{{t "IP address: %(ip)s" }}{{/if}} +{{#if location }}{{ location }}{{/if}} +{{#if timestamp }}{{ timestamp }}{{/if}} +

diff --git a/templates/new_device_login.txt b/templates/new_device_login.txt index 96a8a32c..9e762d15 100644 --- a/templates/new_device_login.txt +++ b/templates/new_device_login.txt @@ -1,7 +1,9 @@ {{t "New sign-in to Firefox" }} {{ device }} -{{ timestamp }} +{{#if ip}}{{t "IP address: %(ip)s" }}{{/if}} +{{#if location}}{{ location }}{{/if}} +{{#if timestamp}}{{ timestamp }}{{/if}} {{t "This is an automated email; if you didn't add a new device to your Firefox Account, you should change your password immediately at %(resetLink)s."}} {{t "For more information, please visit %(supportUrl)s"}} diff --git a/templates/verify_login.html b/templates/verify_login.html index 40551fcc..1de844e0 100644 --- a/templates/verify_login.html +++ b/templates/verify_login.html @@ -20,7 +20,12 @@

{{t "New sign-in to Firefox"}}

-

{{t "For added security, please confirm this sign-in to begin syncing with %(device)s." }}

+

{{t "For added security, please confirm this sign-in to begin syncing with this device:"}}

+ {{{ device }}} + {{#if ip }}{{t "IP address: %(ip)s" }}{{/if}} + {{#if location }}{{ location }}{{/if}} + {{#if timestamp }}{{ timestamp }}{{/if}} +

diff --git a/templates/verify_login.txt b/templates/verify_login.txt index 296d3ded..59ce2ef3 100644 --- a/templates/verify_login.txt +++ b/templates/verify_login.txt @@ -1,5 +1,9 @@ {{t "New sign-in to Firefox"}} -{{t "For added security, please confirm this sign-in to begin syncing with %(device)s." }} +{{t "For added security, please confirm this sign-in to begin syncing with this device:" }} +{{ device }} +{{#if ip}}{{t "IP address: %(ip)s" }}{{/if}} +{{#if location}}{{ location }}{{/if}} +{{#if timestamp}}{{ timestamp }}{{/if}} {{t "Confirm sign-in"}} {{{link}}} {{t "If you suspect that someone is trying to gain access to your account, please change your password." }} {{{ passwordChangeLink }}} diff --git a/test/local/mailer_tests.js b/test/local/mailer_tests.js index 8195d89f..73d3851e 100644 --- a/test/local/mailer_tests.js +++ b/test/local/mailer_tests.js @@ -62,6 +62,11 @@ var typesContainIOSStoreLinks = [ 'postVerifyEmail' ] +var typesContainLocationData = [ + 'newDeviceLoginEmail', + 'verifyLoginEmail' +] + function includes(haystack, needle) { return (haystack.indexOf(needle) > -1) } @@ -182,6 +187,36 @@ P.all( ) } + if (includes(typesContainLocationData, type)) { + var location = { + city: 'Mountain View', + country: 'USA' + } + + message = { + device: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:48.0) Gecko/20100101 Firefox/48.0', + email: 'a@b.com', + ip: '219.129.234.194', + location: location, + timeZone: 'America/Los_Angeles' + } + + test( + 'Location and ip data is present in email template output for ' + type, + function (t) { + mailer.mailer.sendMail = function (emailConfig) { + t.ok(includes(emailConfig.html, location.city + ', ' + location.country)) + t.ok(includes(emailConfig.html, message.ip)) + + t.ok(includes(emailConfig.text, location.city + ', ' + location.country)) + t.ok(includes(emailConfig.text, message.ip)) + t.end() + } + mailer[type](message) + } + ) + } + if (type === 'verifyLoginEmail') { test( 'test verify token email',