From a7806860988527e4e7e854f9e53dcd0eee2209ec Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Mon, 27 Mar 2017 18:26:49 -0400 Subject: [PATCH 01/60] Bump package versions for 1.4.4-rc.2 release. We (@abernix and I) have decided to abandon 1.4.3.3 in favor of 1.4.4, because the changes we wanted to include are slightly more significant than seems appropriate for a "patch" update. --- packages/babel-compiler/package.js | 2 +- packages/ddp-client/package.js | 2 +- packages/ddp-server/package.js | 2 +- packages/ecmascript/package.js | 2 +- packages/force-ssl-common/package.js | 2 +- packages/force-ssl/package.js | 2 +- packages/meteor-tool/package.js | 2 +- packages/minifier-js/package.js | 2 +- packages/modules/package.js | 2 +- packages/standard-minifier-js/package.js | 2 +- packages/standard-minifiers/package.js | 2 +- scripts/admin/meteor-release-experimental.json | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/babel-compiler/package.js b/packages/babel-compiler/package.js index cdce3221b4..422dc92fdf 100644 --- a/packages/babel-compiler/package.js +++ b/packages/babel-compiler/package.js @@ -6,7 +6,7 @@ Package.describe({ // isn't possible because you can't publish a non-recommended // release with package versions that don't have a pre-release // identifier at the end (eg, -dev) - version: '6.18.0-rc.1' + version: '6.18.0-rc.2' }); Npm.depends({ diff --git a/packages/ddp-client/package.js b/packages/ddp-client/package.js index ac5b74701a..7a3ccb6fc8 100644 --- a/packages/ddp-client/package.js +++ b/packages/ddp-client/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Meteor's latency-compensated distributed data client", - version: '1.3.4-rc.1', + version: '1.3.4-rc.2', documentation: null }); diff --git a/packages/ddp-server/package.js b/packages/ddp-server/package.js index 1d08da588f..72c2a351ce 100644 --- a/packages/ddp-server/package.js +++ b/packages/ddp-server/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Meteor's latency-compensated distributed data server", - version: '1.3.14-rc.1', + version: '1.3.14-rc.2', documentation: null }); diff --git a/packages/ecmascript/package.js b/packages/ecmascript/package.js index be0bf99380..d46052909e 100644 --- a/packages/ecmascript/package.js +++ b/packages/ecmascript/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'ecmascript', - version: '0.7.1-rc.1', + version: '0.7.1-rc.2', summary: 'Compiler plugin that supports ES2015+ in all .js files', documentation: 'README.md' }); diff --git a/packages/force-ssl-common/package.js b/packages/force-ssl-common/package.js index 54353d56b4..1c4a3bb3d1 100644 --- a/packages/force-ssl-common/package.js +++ b/packages/force-ssl-common/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: 'Internal force-ssl common code.', - version: '1.0.14-rc.1' + version: '1.0.14-rc.2' }); Npm.depends({ diff --git a/packages/force-ssl/package.js b/packages/force-ssl/package.js index 980c9a11ae..d8a2c07c90 100644 --- a/packages/force-ssl/package.js +++ b/packages/force-ssl/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Require this application to use HTTPS", - version: "1.0.14-rc.1", + version: "1.0.14-rc.2", prodOnly: true }); diff --git a/packages/meteor-tool/package.js b/packages/meteor-tool/package.js index b05c502219..23ce82c821 100644 --- a/packages/meteor-tool/package.js +++ b/packages/meteor-tool/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "The Meteor command-line tool", - version: '1.4.3-3-rc.1' + version: '1.4.4-rc.2' }); Package.includeTool(); diff --git a/packages/minifier-js/package.js b/packages/minifier-js/package.js index fabf1bb57c..bcd35faf17 100644 --- a/packages/minifier-js/package.js +++ b/packages/minifier-js/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "JavaScript minifier", - version: "2.0.0-rc.1" + version: "2.0.0-rc.2" }); Npm.depends({ diff --git a/packages/modules/package.js b/packages/modules/package.js index 166c3a4d06..3d89fdb371 100644 --- a/packages/modules/package.js +++ b/packages/modules/package.js @@ -1,6 +1,6 @@ Package.describe({ name: "modules", - version: "0.8.1-rc.1", + version: "0.8.1-rc.2", summary: "CommonJS module system", documentation: "README.md" }); diff --git a/packages/standard-minifier-js/package.js b/packages/standard-minifier-js/package.js index 0f5edc1a33..4a4794677b 100644 --- a/packages/standard-minifier-js/package.js +++ b/packages/standard-minifier-js/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'standard-minifier-js', - version: '2.0.0-rc.1', + version: '2.0.0-rc.2', summary: 'Standard javascript minifiers used with Meteor apps by default.', documentation: 'README.md', }); diff --git a/packages/standard-minifiers/package.js b/packages/standard-minifiers/package.js index 33b75f5ed9..9bc6965de7 100644 --- a/packages/standard-minifiers/package.js +++ b/packages/standard-minifiers/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'standard-minifiers', - version: '1.1.0-rc.1', + version: '1.1.0-rc.2', summary: 'Standard minifiers used with Meteor apps by default.', documentation: 'README.md' }); diff --git a/scripts/admin/meteor-release-experimental.json b/scripts/admin/meteor-release-experimental.json index fb9320c571..d582dde7e2 100644 --- a/scripts/admin/meteor-release-experimental.json +++ b/scripts/admin/meteor-release-experimental.json @@ -1,6 +1,6 @@ { "track": "METEOR", - "version": "1.4.3.3-rc.1", + "version": "1.4.4-rc.2", "recommended": false, "official": false, "description": "Meteor" From d49f3e270423ab451b43101df90ede8f473282ed Mon Sep 17 00:00:00 2001 From: Jeremy Shimko Date: Wed, 22 Mar 2017 12:54:07 -0400 Subject: [PATCH 02/60] Use fs.move() from fs-extra to fix EXDEV cross device error in docker builds. (#8491) Use fs.move to fix EXDEV cross device error in docker builds. Fixes #7852. --- scripts/dev-bundle-tool-package.js | 1 + tools/fs/files.js | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/scripts/dev-bundle-tool-package.js b/scripts/dev-bundle-tool-package.js index b239addde1..19b74b7f69 100644 --- a/scripts/dev-bundle-tool-package.js +++ b/scripts/dev-bundle-tool-package.js @@ -18,6 +18,7 @@ var packageJson = { "meteor-promise": "0.8.0", fibers: "1.0.15", promise: "7.1.1", + "fs-extra": "2.1.0", // So that Babel 6 can emit require("babel-runtime/helpers/...") calls. "babel-runtime": "6.9.2", // For various ES2015 polyfills, such as Map and Set. diff --git a/tools/fs/files.js b/tools/fs/files.js index ee7f4b5e92..8a62569b7c 100644 --- a/tools/fs/files.js +++ b/tools/fs/files.js @@ -5,7 +5,9 @@ /// var assert = require("assert"); -var fs = require("fs"); +var fs = require('fs'); +fs.move = require('fs-extra').move; +fs.moveSync = require('fs-extra').moveSync; var path = require('path'); var os = require('os'); var util = require('util'); @@ -981,7 +983,7 @@ files.renameDirAlmostAtomically = function (fromDir, toDir) { // Get old dir out of the way, if it exists. var movedOldDir = true; try { - files.rename(toDir, garbageDir); + files.move(toDir, garbageDir); } catch (e) { if (e.code !== 'ENOENT') { throw e; @@ -990,7 +992,7 @@ files.renameDirAlmostAtomically = function (fromDir, toDir) { } // Now rename the directory. - files.rename(fromDir, toDir); + files.move(fromDir, toDir); // ... and delete the old one. if (movedOldDir) { @@ -1608,6 +1610,7 @@ wrapFsFunc("readFile", [0], { wrapFsFunc("stat", [0]); wrapFsFunc("lstat", [0]); wrapFsFunc("rename", [0, 1]); +wrapFsFunc("move", [0]); // After the outermost files.withCache call returns, the withCacheCache is // reset to null so that it does not survive server restarts. From 3966d7027f84a87dff78ae03819909ccfb197b0c Mon Sep 17 00:00:00 2001 From: Erik Demaine Date: Wed, 22 Mar 2017 11:31:54 -0400 Subject: [PATCH 03/60] Upgrade to mailcomposer@4 and smtp-connection@2. Fix #8425 (#8495) * Switch from mailcomposer 0.1.15 -> 4.0.1 (latest, still MIT license). * Switch from simplesmtp (which only supports mailcomposer 0.1) to smtp-connection (which supports any mail composer). * Use smtp-connection@2 (instead of latest) which shares nodemailer-shared codebase with mailcomposer 4.0.1. * Add test for long header lines (the original bug being fixed here) * Add extra test for HTML + text messages * Document some extra options arguments supported by new mailcomposer --- .../email/.npm/package/npm-shrinkwrap.json | 83 +++++++-- packages/email/email.js | 87 +++++---- packages/email/email_tests.js | 168 +++++++++++++++--- packages/email/package.js | 10 +- 4 files changed, 251 insertions(+), 97 deletions(-) diff --git a/packages/email/.npm/package/npm-shrinkwrap.json b/packages/email/.npm/package/npm-shrinkwrap.json index 5aabb63284..4028b03706 100644 --- a/packages/email/.npm/package/npm-shrinkwrap.json +++ b/packages/email/.npm/package/npm-shrinkwrap.json @@ -1,34 +1,79 @@ { "dependencies": { + "addressparser": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz", + "from": "addressparser@1.0.1" + }, + "buildmail": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/buildmail/-/buildmail-4.0.1.tgz", + "from": "buildmail@4.0.1" + }, + "httpntlm": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/httpntlm/-/httpntlm-1.6.1.tgz", + "from": "httpntlm@1.6.1" + }, + "httpreq": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/httpreq/-/httpreq-0.4.23.tgz", + "from": "httpreq@>=0.4.22" + }, + "iconv-lite": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", + "from": "iconv-lite@0.4.15" + }, + "libbase64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/libbase64/-/libbase64-0.1.0.tgz", + "from": "libbase64@0.1.0" + }, + "libmime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/libmime/-/libmime-3.0.0.tgz", + "from": "libmime@3.0.0" + }, + "libqp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/libqp/-/libqp-1.1.0.tgz", + "from": "libqp@1.1.0" + }, "mailcomposer": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/mailcomposer/-/mailcomposer-0.1.15.tgz", - "from": "mailcomposer@0.1.15" + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/mailcomposer/-/mailcomposer-4.0.1.tgz", + "from": "mailcomposer@4.0.1" }, - "mimelib-noiconv": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/mimelib-noiconv/-/mimelib-noiconv-0.1.9.tgz", - "from": "mimelib-noiconv@*" + "nodemailer-fetch": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/nodemailer-fetch/-/nodemailer-fetch-1.6.0.tgz", + "from": "nodemailer-fetch@1.6.0" }, - "rai": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/rai/-/rai-0.1.12.tgz", - "from": "rai@>=0.1.11 <0.2.0" + "nodemailer-shared": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/nodemailer-shared/-/nodemailer-shared-1.1.0.tgz", + "from": "nodemailer-shared@1.1.0" }, - "simplesmtp": { - "version": "0.3.34", - "resolved": "https://registry.npmjs.org/simplesmtp/-/simplesmtp-0.3.34.tgz", - "from": "simplesmtp@0.3.34" + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "from": "punycode@1.4.1" + }, + "smtp-connection": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/smtp-connection/-/smtp-connection-2.12.2.tgz", + "from": "smtp-connection@2.12.2" }, "stream-buffers": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-0.2.5.tgz", "from": "stream-buffers@0.2.5" }, - "xoauth2": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/xoauth2/-/xoauth2-0.1.8.tgz", - "from": "xoauth2@>=0.1.8 <0.2.0" + "underscore": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", + "from": "underscore@>=1.7.0 <1.8.0" } } } diff --git a/packages/email/email.js b/packages/email/email.js index 7531b8c3d6..ae8e652eba 100644 --- a/packages/email/email.js +++ b/packages/email/email.js @@ -1,5 +1,6 @@ var Future = Npm.require('fibers/future'); var urlModule = Npm.require('url'); +var SMTPConnection = Npm.require('smtp-connection'); Email = {}; EmailTest = {}; @@ -13,7 +14,7 @@ EmailInternals = { } }; -var MailComposer = EmailInternals.NpmModules.mailcomposer.module.MailComposer; +var mailcomposer = EmailInternals.NpmModules.mailcomposer.module; var makePool = function (mailUrlString) { var mailUrl = urlModule.parse(mailUrlString); @@ -29,15 +30,18 @@ var makePool = function (mailUrlString) { pass: parts[1]}; } - var simplesmtp = Npm.require('simplesmtp'); - var pool = simplesmtp.createClientPool( - port, // Defaults to 25 - mailUrl.hostname, // Defaults to "localhost" - { secureConnection: (port === 465) || (mailUrl.protocol === 'smtps:'), - // XXX allow maxConnections to be configured? - auth: auth }); + var pool = new SMTPConnection({ + port: port, // Defaults to 25 + host: mailUrl.hostname, // Defaults to "localhost" + secure: (port === 465) || (mailUrl.protocol === 'smtps:') + }); + Meteor.wrapAsync(pool.connect, pool)(); + if (auth) { + //_.bind(Future.wrap(pool.login), pool)(auth).wait(); + Meteor.wrapAsync(pool.login, pool)(auth); + } - pool._future_wrapped_sendMail = _.bind(Future.wrap(pool.sendMail), pool); + pool._syncSend = Meteor.wrapAsync(pool.send, pool); return pool; }; @@ -75,18 +79,18 @@ var devModeSend = function (mc) { stream.write("====== BEGIN MAIL #" + devmode_mail_id + " ======\n"); stream.write("(Mail not sent; to enable sending, set the MAIL_URL " + "environment variable.)\n"); - mc.streamMessage(); - mc.pipe(stream, {end: false}); + var readStream = mc.createReadStream(); + readStream.pipe(stream, {end: false}); var future = new Future; - mc.on('end', function () { + readStream.on('end', function () { stream.write("====== END MAIL #" + devmode_mail_id + " ======\n"); - future['return'](); + future.return(); }); future.wait(); }; var smtpSend = function (pool, mc) { - pool._future_wrapped_sendMail(mc).wait(); + pool._syncSend(mc.getEnvelope(), mc.createReadStream()); }; /** @@ -131,25 +135,33 @@ EmailTest.hookSend = function (f) { * If the `MAIL_URL` environment variable is set, actually sends the email. * Otherwise, prints the contents of the email to standard out. * - * Note that this package is based on mailcomposer version `0.1.15`, so make + * Note that this package is based on mailcomposer version `4.0.1`, so make * sure to refer to the documentation for that version if using the * `attachments` or `mailComposer` options. - * [Click here to read the mailcomposer 0.1.15 docs](https://github.com/andris9/mailcomposer/blob/7c0422b2de2dc61a60ba27cfa3353472f662aeb5/README.md). + * [Click here to read the mailcomposer 4.0.1 docs](https://github.com/nodemailer/mailcomposer/blob/v4.0.1/README.md). * * @locus Server * @param {Object} options - * @param {String} options.from "From:" address (required) + * @param {String} [options.from] "From:" address (required) * @param {String|String[]} options.to,cc,bcc,replyTo * "To:", "Cc:", "Bcc:", and "Reply-To:" addresses + * @param {String} [options.inReplyTo] Message-ID this message is replying to + * @param {String|String[]} [options.references] Array (or space-separated string) of Message-IDs to refer to + * @param {String} [options.messageId] Message-ID for this message; otherwise, will be set to a random value * @param {String} [options.subject] "Subject:" line * @param {String} [options.text|html] Mail body (in plain text and/or HTML) + * @param {String} [options.watchHtml] Mail body in HTML specific for Apple Watch + * @param {String} [options.icalEvent] iCalendar event attachment * @param {Object} [options.headers] Dictionary of custom headers * @param {Object[]} [options.attachments] Array of attachment objects, as - * described in the [mailcomposer documentation](https://github.com/andris9/mailcomposer/blob/7c0422b2de2dc61a60ba27cfa3353472f662aeb5/README.md#add-attachments). + * described in the [mailcomposer documentation](https://github.com/nodemailer/mailcomposer/blob/v4.0.1/README.md#attachments). * @param {MailComposer} [options.mailComposer] A [MailComposer](https://github.com/andris9/mailcomposer) - * object representing the message to be sent. Overrides all other options. You - * can access the `mailcomposer` npm module at - * `EmailInternals.NpmModules.mailcomposer.module`. + * object (or its `compile()` output) representing the message to be sent. + * Overrides all other options. You can access the `mailcomposer` npm module at + * `EmailInternals.NpmModules.mailcomposer.module`. This module is a function + * which assembles a MailComposer object and immediately `compile()`s it. + * Alternatively, you can create and pass a MailComposer object via + * `new EmailInternals.NpmModules.mailcomposer.module.MailComposer`. */ Email.send = function (options) { for (var i = 0; i < sendHooks.length; i++) @@ -159,32 +171,17 @@ Email.send = function (options) { var mc; if (options.mailComposer) { mc = options.mailComposer; - } else { - mc = new MailComposer(); - - // setup message data - mc.setMessageOption({ - from: options.from, - to: options.to, - cc: options.cc, - bcc: options.bcc, - replyTo: options.replyTo, - subject: options.subject, - text: options.text, - html: options.html - }); - - _.each(options.headers, function (value, name) { - mc.addHeader(name, value); - }); - - if (!options.headers || !options.headers.hasOwnProperty('Date')) { - mc.addHeader('Date', new Date().toUTCString().replace(/GMT/, '+0000')); + if (mc.compile) { + mc = mc.compile(); } + } else { + // mailcomposer now automatically adds date if omitted + //if (!options.hasOwnProperty('date') && + // (!options.headers || !options.headers.hasOwnProperty('Date'))) { + // options['date'] = new Date().toUTCString().replace(/GMT/, '+0000'); + //} - _.each(options.attachments, function(attachment){ - mc.addAttachment(attachment); - }); + mc = mailcomposer(options); } var pool = getPool(); diff --git a/packages/email/email_tests.js b/packages/email/email_tests.js index 9f0ab53b8b..6fe9a30954 100644 --- a/packages/email/email_tests.js +++ b/packages/email/email_tests.js @@ -18,6 +18,13 @@ function smokeEmailTest(testFunction) { } } +function canonicalize(string) { + // Remove generated content for test.equal to succeed. + return string.replace(/Message-ID: <[^<>]*>\r\n/, "Message-ID: <...>\r\n") + .replace(/Date: (?!dummy).*\r\n/, "Date: ...\r\n") + .replace(/----[^\s"]+/g, "----..."); +} + Tinytest.add("email - fully customizable", function (test) { smokeEmailTest(function(stream) { Email.send({ @@ -32,22 +39,23 @@ Tinytest.add("email - fully customizable", function (test) { }, }); // XXX brittle if mailcomposer changes header order, etc - test.equal(stream.getContentsAsString("utf8"), + test.equal(canonicalize(stream.getContentsAsString("utf8")), "====== BEGIN MAIL #0 ======\n" + devWarningBanner + - "MIME-Version: 1.0\r\n" + + "Content-Type: text/plain\r\n" + "X-Meteor-Test: a custom header\r\n" + "Date: dummy\r\n" + "From: foo@example.com\r\n" + "To: bar@example.com\r\n" + "Cc: friends@example.com, enemies@example.com\r\n" + "Subject: This is the subject\r\n" + - "Content-Type: text/plain; charset=utf-8\r\n" + - "Content-Transfer-Encoding: quoted-printable\r\n" + + "Message-ID: <...>\r\n" + + "Content-Transfer-Encoding: 7bit\r\n" + + "MIME-Version: 1.0\r\n" + "\r\n" + - "This is the body\r\n" + - "of the message\r\n" + - "From us.\r\n" + + "This is the body\n" + + "of the message\n" + + "From us." + "====== END MAIL #0 ======\n"); }); }); @@ -61,7 +69,7 @@ Tinytest.add("email - undefined headers sends properly", function (test) { text: "This is the body\nof the message\nFrom us.", }); - test.matches(stream.getContentsAsString("utf8"), + test.matches(canonicalize(stream.getContentsAsString("utf8")), /^====== BEGIN MAIL #0 ======$[\s\S]+^To: bar@example.com$/m); }); }); @@ -77,7 +85,7 @@ Tinytest.add("email - multiple e-mails same stream", function (test) { var contents; - contents = stream.getContentsAsString("utf8"); + contents = canonicalize(stream.getContentsAsString("utf8")); test.matches(contents, /^====== BEGIN MAIL #0 ======$/m); test.matches(contents, /^From: foo@example.com$/m); test.matches(contents, /^To: bar@example.com$/m); @@ -89,7 +97,7 @@ Tinytest.add("email - multiple e-mails same stream", function (test) { text: "This is another message\nFrom Qux.", }); - contents = stream.getContentsAsString("utf8"); + contents = canonicalize(stream.getContentsAsString("utf8")); test.matches(contents, /^====== BEGIN MAIL #1 ======$/m); test.matches(contents, /^From: qux@example.com$/m); test.matches(contents, /^To: baz@example.com$/m); @@ -100,28 +108,39 @@ Tinytest.add("email - multiple e-mails same stream", function (test) { Tinytest.add("email - using mail composer", function (test) { smokeEmailTest(function (stream) { // Test direct MailComposer usage. - var mc = new EmailInternals.NpmModules.mailcomposer.module.MailComposer; - mc.setMessageOption({ - from: "a@b.com", - text: "body" - }); - Email.send({mailComposer: mc}); - test.equal(stream.getContentsAsString("utf8"), - "====== BEGIN MAIL #0 ======\n" + - devWarningBanner + - "MIME-Version: 1.0\r\n" + - "From: a@b.com\r\n" + - "Content-Type: text/plain; charset=utf-8\r\n" + - "Content-Transfer-Encoding: quoted-printable\r\n" + - "\r\n" + - "body\r\n" + - "====== END MAIL #0 ======\n"); + var mcs = [ + // Test with MailComposer object (without compiling). + new EmailInternals.NpmModules.mailcomposer.module.MailComposer({ + from: "a@b.com", + text: "body" + }), + // Test calling module as a function, which compiles MailComposer object. + EmailInternals.NpmModules.mailcomposer.module({ + from: "a@b.com", + text: "body" + }) + ]; + for (var i = 0; i < mcs.length; i++) { + Email.send({mailComposer: mcs[i]}); + test.equal(canonicalize(stream.getContentsAsString("utf8")), + "====== BEGIN MAIL #"+i+" ======\n" + + devWarningBanner + + "Content-Type: text/plain\r\n" + + "From: a@b.com\r\n" + + "Message-ID: <...>\r\n" + + "Content-Transfer-Encoding: 7bit\r\n" + + "Date: ...\r\n" + + "MIME-Version: 1.0\r\n" + + "\r\n" + + "body" + + "====== END MAIL #"+i+" ======\n"); + } }); }); Tinytest.add("email - date auto generated", function (test) { smokeEmailTest(function (stream) { - // Test if date header is automaticall generated, if not specified + // Test if date header is automatically generated, if not specified Email.send({ from: "foo@example.com", to: "bar@example.com", @@ -132,7 +151,100 @@ Tinytest.add("email - date auto generated", function (test) { }, }); - test.matches(stream.getContentsAsString("utf8"), + test.matches(canonicalize(stream.getContentsAsString("utf8")), /^Date: .+$/m); }); }); + +Tinytest.add("email - long lines", function (test) { + smokeEmailTest(function (stream) { + // Test that long header lines get wrapped with single leading whitespace, + // and that long body lines get wrapped with quoted-printable conventions. + Email.send({ + from: "foo@example.com", + to: "bar@example.com", + subject: "This is a very very very very very very very very very very very very long subject", + text: "This is a very very very very very very very very very very very very long text", + }); + + test.equal(canonicalize(stream.getContentsAsString("utf8")), + "====== BEGIN MAIL #0 ======\n" + + devWarningBanner + + "Content-Type: text/plain\r\n" + + "From: foo@example.com\r\n" + + "To: bar@example.com\r\n" + + "Subject: This is a very very very very very very very very " + + "very very very\r\n very long subject\r\n" + + "Message-ID: <...>\r\n" + + "Content-Transfer-Encoding: quoted-printable\r\n" + + "Date: ...\r\n" + + "MIME-Version: 1.0\r\n" + + "\r\n" + + "This is a very very very very very very very very very very " + + "very very long =\r\ntext" + + "====== END MAIL #0 ======\n"); + }); +}); + +Tinytest.add("email - unicode", function (test) { + smokeEmailTest(function (stream) { + // Test that unicode characters in header and body get encoded. + Email.send({ + from: "foo@example.com", + to: "bar@example.com", + subject: "\u263a", + text: "I \u2665 Meteor", + }); + + test.equal(canonicalize(stream.getContentsAsString("utf8")), + "====== BEGIN MAIL #0 ======\n" + + devWarningBanner + + "Content-Type: text/plain; charset=utf-8\r\n" + + "From: foo@example.com\r\n" + + "To: bar@example.com\r\n" + + "Subject: =?UTF-8?B?4pi6?=\r\n" + + "Message-ID: <...>\r\n" + + "Content-Transfer-Encoding: quoted-printable\r\n" + + "Date: ...\r\n" + + "MIME-Version: 1.0\r\n" + + "\r\n" + + "I =E2=99=A5 Meteor" + + "====== END MAIL #0 ======\n"); + }); +}); + +Tinytest.add("email - text and html", function (test) { + smokeEmailTest(function (stream) { + // Test including both text and HTML versions of message. + Email.send({ + from: "foo@example.com", + to: "bar@example.com", + text: "*Cool*, man", + html: "Cool, man", + }); + + test.equal(canonicalize(stream.getContentsAsString("utf8")), + "====== BEGIN MAIL #0 ======\n" + + devWarningBanner + + "Content-Type: multipart/alternative;\r\n" + + ' boundary="----..."\r\n' + + "From: foo@example.com\r\n" + + "To: bar@example.com\r\n" + + "Message-ID: <...>\r\n" + + "Date: ...\r\n" + + "MIME-Version: 1.0\r\n" + + "\r\n" + + "----...\r\n" + + "Content-Type: text/plain\r\n" + + "Content-Transfer-Encoding: 7bit\r\n" + + "\r\n" + + "*Cool*, man\r\n" + + "----...\r\n" + + "Content-Type: text/html\r\n" + + "Content-Transfer-Encoding: 7bit\r\n" + + "\r\n" + + "Cool, man\r\n" + + "----...\r\n" + + "====== END MAIL #0 ======\n"); + }); +}); diff --git a/packages/email/package.js b/packages/email/package.js index dad8b2d8b3..36f09e1601 100644 --- a/packages/email/package.js +++ b/packages/email/package.js @@ -1,13 +1,13 @@ Package.describe({ summary: "Send email messages", - version: "1.1.18" + version: "1.2.0" }); Npm.depends({ - // Pinned at older version. 0.1.16+ uses mimelib, not mimelib-noiconv which is - // much bigger. We need a better solution. - mailcomposer: "0.1.15", - simplesmtp: "0.3.34", + mailcomposer: "4.0.1", + // Using smtp-connection@2 (instead of latest) because it shares + // nodemailer-shared with mailcomposer@4: + "smtp-connection": "2.12.2", "stream-buffers": "0.2.5"}); Package.onUse(function (api) { From 393fe17f4b0c424e7bb471bb2ff253ab139f81c2 Mon Sep 17 00:00:00 2001 From: Phuc Nguyen Date: Wed, 22 Mar 2017 22:16:52 +0700 Subject: [PATCH 04/60] Make sure manifest.json contains AUTOUPDATE_VERSION (if specified) (#8480) Fixes https://github.com/meteor/meteor/issues/8479 --- packages/webapp/webapp_server.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/webapp/webapp_server.js b/packages/webapp/webapp_server.js index dc1d161088..24a6cd7ad7 100644 --- a/packages/webapp/webapp_server.js +++ b/packages/webapp/webapp_server.js @@ -500,8 +500,12 @@ var runWebAppServer = function () { var program = { format: "web-program-pre1", manifest: manifest, - version: WebAppHashing.calculateClientHash(manifest, null, _.pick( - __meteor_runtime_config__, 'PUBLIC_SETTINGS')), + version: process.env.AUTOUPDATE_VERSION || + WebAppHashing.calculateClientHash( + manifest, + null, + _.pick(__meteor_runtime_config__, "PUBLIC_SETTINGS") + ), cordovaCompatibilityVersions: clientJson.cordovaCompatibilityVersions, PUBLIC_SETTINGS: __meteor_runtime_config__.PUBLIC_SETTINGS }; From d60b20015b571fb32dc42c6f7a3145aad98f6b87 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Tue, 28 Mar 2017 16:04:10 +0300 Subject: [PATCH 05/60] Bump $BUNDLE_VERSION to 4.7.20 before rebuilding dev bundle. Due to the addition of d49f3e270423ab451b43101df90ede8f473282ed. --- meteor | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/meteor b/meteor index 0174586239..ba342e221e 100755 --- a/meteor +++ b/meteor @@ -1,8 +1,6 @@ #!/usr/bin/env bash -### Skip 4.7.19, used on `devel` -BUNDLE_VERSION=4.7.18 -### Skip 4.7.19, used on `devel` +BUNDLE_VERSION=4.7.20 # OS Check. Put here because here is where we download the precompiled # bundles that are arch specific. From efc61160b05a6cd9fd18377403397072c960c527 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Tue, 28 Mar 2017 16:11:49 +0300 Subject: [PATCH 06/60] Add `-rc.n` suffix to `email` before republishing. --- packages/email/package.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/email/package.js b/packages/email/package.js index 36f09e1601..de45f06105 100644 --- a/packages/email/package.js +++ b/packages/email/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Send email messages", - version: "1.2.0" + version: "1.2.0-rc.2" }); Npm.depends({ From 01d7aca90aa4dc59c01c499ccc3c5d0ced00600c Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Tue, 28 Mar 2017 16:17:22 +0300 Subject: [PATCH 07/60] Add `-rc.n` suffix to `webapp` before republishing. --- packages/webapp/package.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/webapp/package.js b/packages/webapp/package.js index b370ab0453..10c1a2ec67 100644 --- a/packages/webapp/package.js +++ b/packages/webapp/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Serves a Meteor app over HTTP", - version: '1.3.14' + version: '1.3.15-rc.2' }); Npm.depends({connect: "2.30.2", From 4c26a51bd8be4662254df85322a6eddfdebbaef3 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Tue, 28 Mar 2017 16:19:18 +0300 Subject: [PATCH 08/60] Bump package versions for 1.4.4-rc.3 release. --- packages/babel-compiler/package.js | 2 +- packages/ddp-client/package.js | 2 +- packages/ddp-server/package.js | 2 +- packages/ecmascript/package.js | 2 +- packages/email/package.js | 2 +- packages/force-ssl-common/package.js | 2 +- packages/force-ssl/package.js | 2 +- packages/meteor-tool/package.js | 2 +- packages/minifier-js/package.js | 2 +- packages/modules/package.js | 2 +- packages/standard-minifier-js/package.js | 2 +- packages/standard-minifiers/package.js | 2 +- packages/webapp/package.js | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/babel-compiler/package.js b/packages/babel-compiler/package.js index 422dc92fdf..ec97cc425b 100644 --- a/packages/babel-compiler/package.js +++ b/packages/babel-compiler/package.js @@ -6,7 +6,7 @@ Package.describe({ // isn't possible because you can't publish a non-recommended // release with package versions that don't have a pre-release // identifier at the end (eg, -dev) - version: '6.18.0-rc.2' + version: '6.18.0-rc.3' }); Npm.depends({ diff --git a/packages/ddp-client/package.js b/packages/ddp-client/package.js index 7a3ccb6fc8..2accbe3747 100644 --- a/packages/ddp-client/package.js +++ b/packages/ddp-client/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Meteor's latency-compensated distributed data client", - version: '1.3.4-rc.2', + version: '1.3.4-rc.3', documentation: null }); diff --git a/packages/ddp-server/package.js b/packages/ddp-server/package.js index 72c2a351ce..86fe3865c7 100644 --- a/packages/ddp-server/package.js +++ b/packages/ddp-server/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Meteor's latency-compensated distributed data server", - version: '1.3.14-rc.2', + version: '1.3.14-rc.3', documentation: null }); diff --git a/packages/ecmascript/package.js b/packages/ecmascript/package.js index d46052909e..6611919861 100644 --- a/packages/ecmascript/package.js +++ b/packages/ecmascript/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'ecmascript', - version: '0.7.1-rc.2', + version: '0.7.1-rc.3', summary: 'Compiler plugin that supports ES2015+ in all .js files', documentation: 'README.md' }); diff --git a/packages/email/package.js b/packages/email/package.js index de45f06105..60477402cf 100644 --- a/packages/email/package.js +++ b/packages/email/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Send email messages", - version: "1.2.0-rc.2" + version: "1.2.0-rc.3" }); Npm.depends({ diff --git a/packages/force-ssl-common/package.js b/packages/force-ssl-common/package.js index 1c4a3bb3d1..06bd8bf2a8 100644 --- a/packages/force-ssl-common/package.js +++ b/packages/force-ssl-common/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: 'Internal force-ssl common code.', - version: '1.0.14-rc.2' + version: '1.0.14-rc.3' }); Npm.depends({ diff --git a/packages/force-ssl/package.js b/packages/force-ssl/package.js index d8a2c07c90..c9620e6d16 100644 --- a/packages/force-ssl/package.js +++ b/packages/force-ssl/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Require this application to use HTTPS", - version: "1.0.14-rc.2", + version: "1.0.14-rc.3", prodOnly: true }); diff --git a/packages/meteor-tool/package.js b/packages/meteor-tool/package.js index 23ce82c821..9ab753c5a7 100644 --- a/packages/meteor-tool/package.js +++ b/packages/meteor-tool/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "The Meteor command-line tool", - version: '1.4.4-rc.2' + version: '1.4.4-rc.3' }); Package.includeTool(); diff --git a/packages/minifier-js/package.js b/packages/minifier-js/package.js index bcd35faf17..842c3b8d85 100644 --- a/packages/minifier-js/package.js +++ b/packages/minifier-js/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "JavaScript minifier", - version: "2.0.0-rc.2" + version: "2.0.0-rc.3" }); Npm.depends({ diff --git a/packages/modules/package.js b/packages/modules/package.js index 3d89fdb371..a971ed908b 100644 --- a/packages/modules/package.js +++ b/packages/modules/package.js @@ -1,6 +1,6 @@ Package.describe({ name: "modules", - version: "0.8.1-rc.2", + version: "0.8.1-rc.3", summary: "CommonJS module system", documentation: "README.md" }); diff --git a/packages/standard-minifier-js/package.js b/packages/standard-minifier-js/package.js index 4a4794677b..26ece4629b 100644 --- a/packages/standard-minifier-js/package.js +++ b/packages/standard-minifier-js/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'standard-minifier-js', - version: '2.0.0-rc.2', + version: '2.0.0-rc.3', summary: 'Standard javascript minifiers used with Meteor apps by default.', documentation: 'README.md', }); diff --git a/packages/standard-minifiers/package.js b/packages/standard-minifiers/package.js index 9bc6965de7..ffbd72c388 100644 --- a/packages/standard-minifiers/package.js +++ b/packages/standard-minifiers/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'standard-minifiers', - version: '1.1.0-rc.2', + version: '1.1.0-rc.3', summary: 'Standard minifiers used with Meteor apps by default.', documentation: 'README.md' }); diff --git a/packages/webapp/package.js b/packages/webapp/package.js index 10c1a2ec67..29ab57ec69 100644 --- a/packages/webapp/package.js +++ b/packages/webapp/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Serves a Meteor app over HTTP", - version: '1.3.15-rc.2' + version: '1.3.15-rc.3' }); Npm.depends({connect: "2.30.2", From be79aa87083a96b0f171273de5b0a71d1a07ec30 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Tue, 28 Mar 2017 17:06:29 +0300 Subject: [PATCH 09/60] Bump version for 1.4.4-rc.3 release. --- scripts/admin/meteor-release-experimental.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/admin/meteor-release-experimental.json b/scripts/admin/meteor-release-experimental.json index d582dde7e2..50691cd490 100644 --- a/scripts/admin/meteor-release-experimental.json +++ b/scripts/admin/meteor-release-experimental.json @@ -1,6 +1,6 @@ { "track": "METEOR", - "version": "1.4.4-rc.2", + "version": "1.4.4-rc.3", "recommended": false, "official": false, "description": "Meteor" From fa1746e9bfe74600746544e63f13626356a3a5fb Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Tue, 28 Mar 2017 20:44:07 +0300 Subject: [PATCH 10/60] [backport] Upgrade Facebook Graph API to use v2.8 This is a backport of 873f13d743053fc080b5562dec786784bc52a610 for the Meteor 1.4.2.x series. In testing for #7715, I discovered that the v2.2 Graph API endpoint was still in use in the `facebook` package which was due to sunset on 2017-03-25. See Facebook Graph API Changelog here: https://developers.facebook.com/docs/apps/changelog When a Graph API endpoint is sunset, it (is claimed) to automatically turn over to the next more recent version, in this case v2.3. v2.3 has a breaking-change over v2.2, notably listed in "Changes from v2.2 to v2.3": > [Oauth Access Token] Format - The response format of https://www.facebook.com/v2.3/oauth/access_token returned when you exchange a code for an access_token now return valid JSON instead of being URL encoded. The new format of this response is {"access_token": {TOKEN}, "token_type":{TYPE}, "expires_in":{TIME}}. We made this update to be compliant with section 5.1 of RFC 6749. This change updates both Graph APIs to v2.8 which has LTS until "At least October 2018". --- packages/facebook/facebook_server.js | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/packages/facebook/facebook_server.js b/packages/facebook/facebook_server.js index c52ab64ce9..1987a0bde6 100644 --- a/packages/facebook/facebook_server.js +++ b/packages/facebook/facebook_server.js @@ -1,7 +1,5 @@ Facebook = {}; -var querystring = Npm.require('querystring'); - Facebook.handleAuthFromAccessToken = function handleAuthFromAccessToken(accessToken, expiresAt) { // include all fields from facebook // http://developers.facebook.com/docs/reference/login/public-profile-and-friend-list/ @@ -54,30 +52,21 @@ var getTokenResponse = function (query) { try { // Request an access token responseContent = HTTP.get( - "https://graph.facebook.com/v2.2/oauth/access_token", { + "https://graph.facebook.com/v2.8/oauth/access_token", { params: { client_id: config.appId, redirect_uri: OAuth._redirectUri('facebook', config), client_secret: OAuth.openSecret(config.secret), code: query.code } - }).content; + }).data; } catch (err) { throw _.extend(new Error("Failed to complete OAuth handshake with Facebook. " + err.message), {response: err.response}); } - // If 'responseContent' parses as JSON, it is an error. - // XXX which facebook error causes this behvaior? - if (isJSON(responseContent)) { - throw new Error("Failed to complete OAuth handshake with Facebook. " + responseContent); - } - - // Success! Extract the facebook access token and expiration - // time from the response - var parsedResponse = querystring.parse(responseContent); - var fbAccessToken = parsedResponse.access_token; - var fbExpires = parsedResponse.expires; + var fbAccessToken = responseContent.access_token; + var fbExpires = responseContent.expires_in; if (!fbAccessToken) { throw new Error("Failed to complete OAuth handshake with facebook " + @@ -91,7 +80,7 @@ var getTokenResponse = function (query) { var getIdentity = function (accessToken, fields) { try { - return HTTP.get("https://graph.facebook.com/v2.4/me", { + return HTTP.get("https://graph.facebook.com/v2.8/me", { params: { access_token: accessToken, fields: fields From 51965ff921ec65a8c4c7ee745ae2bd2df5216fc5 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Tue, 28 Mar 2017 20:45:55 +0300 Subject: [PATCH 11/60] [backport] Explicitly join the fields array to a comma-delimited string. This is a backport of 2c5dda1675a9e3526e3a926d3ec2b45d0fab14c6gu for the Meteor 1.4.2.x series. With https://github.com/meteor/meteor/pull/8261 merged, arrays are no longer concatenated (with commas) into a string during `HTTP.call` requests so we need to specify the exact behavior we want. Any previous behavior of this type was purely accidental. The definition of this field in Facebook's API is that it should be a comma-separated field: https://developers.facebook.com/docs/graph-api/using-graph-api --- packages/facebook/facebook_server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/facebook/facebook_server.js b/packages/facebook/facebook_server.js index 1987a0bde6..04a5179f31 100644 --- a/packages/facebook/facebook_server.js +++ b/packages/facebook/facebook_server.js @@ -83,7 +83,7 @@ var getIdentity = function (accessToken, fields) { return HTTP.get("https://graph.facebook.com/v2.8/me", { params: { access_token: accessToken, - fields: fields + fields: fields.join(",") } }).data; } catch (err) { From 03e29dcfa8964002c5e824e6c86a9a625084dfcb Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Tue, 28 Mar 2017 20:48:38 +0300 Subject: [PATCH 12/60] Bump versions `facebook`/`accounts-facebook` in preparation for publishing. --- packages/accounts-facebook/package.js | 4 ++-- packages/facebook/package.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/accounts-facebook/package.js b/packages/accounts-facebook/package.js index c323e43ebb..0ed2f30838 100644 --- a/packages/accounts-facebook/package.js +++ b/packages/accounts-facebook/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Login service for Facebook accounts", - version: "1.0.11" + version: "1.0.12" }); Package.onUse(function(api) { @@ -8,7 +8,7 @@ Package.onUse(function(api) { // Export Accounts (etc) to packages using this one. api.imply('accounts-base', ['client', 'server']); api.use('accounts-oauth', ['client', 'server']); - api.use('facebook', ['client', 'server']); + api.use('facebook@1.2.11', ['client', 'server']); api.addFiles('facebook_login_button.css', 'client'); diff --git a/packages/facebook/package.js b/packages/facebook/package.js index 1d8cbc7539..c6e068e8eb 100644 --- a/packages/facebook/package.js +++ b/packages/facebook/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Facebook OAuth flow", - version: "1.2.10" + version: "1.2.11" }); Package.onUse(function(api) { From 3c011c9dc69c2a6b825159656272c85a97d26ac8 Mon Sep 17 00:00:00 2001 From: mutdmour Date: Wed, 29 Mar 2017 17:21:14 +0200 Subject: [PATCH 13/60] [fix #8218] cleaning up reset tokens also cleans up enroll tokens (#8474) * solved issue 8218 with expireresettoken removing enroll tokens * style fix * tests fix * solved issue 8218 with expireresettoken removing enroll tokens * style fix --- packages/accounts-base/accounts_server.js | 10 +++--- packages/accounts-password/password_tests.js | 34 ++++++++++++++++++-- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/packages/accounts-base/accounts_server.js b/packages/accounts-base/accounts_server.js index 57ea4eb6e0..d2aa2adb65 100644 --- a/packages/accounts-base/accounts_server.js +++ b/packages/accounts-base/accounts_server.js @@ -1076,14 +1076,16 @@ Ap._generateStampedLoginToken = function () { /// function expirePasswordToken(accounts, oldestValidDate, tokenFilter, userId) { - var userFilter = userId ? {_id: userId} : {}; - - accounts.users.update(_.extend(userFilter, tokenFilter, { + const userFilter = userId ? {_id: userId} : {}; + const resetRangeOr = { $or: [ { "services.password.reset.when": { $lt: oldestValidDate } }, { "services.password.reset.when": { $lt: +oldestValidDate } } ] - }), { + }; + const expireFilter = { $and: [tokenFilter, resetRangeOr] }; + + accounts.users.update({...userFilter, ...expireFilter}, { $unset: { "services.password.reset": "" } diff --git a/packages/accounts-password/password_tests.js b/packages/accounts-password/password_tests.js index 3a3e564f21..b09274ed4e 100644 --- a/packages/accounts-password/password_tests.js +++ b/packages/accounts-password/password_tests.js @@ -1474,7 +1474,7 @@ if (Meteor.isServer) (function () { ); Tinytest.add( - 'passwords - reset password doesn\t work if email changed after email sent', + "passwords - reset password doesn't work if email changed after email sent", function (test) { var username = Random.id(); var email = username + '-intercept@example.com'; @@ -1688,15 +1688,45 @@ if (Meteor.isServer) (function () { function (test) { var email = test.id + '-intercept@example.com'; var userId = Accounts.createUser({email: email, password: 'password'}); + Accounts.sendEnrollmentEmail(userId, email); test.isTrue(!!Meteor.users.findOne(userId).services.password.reset); Accounts._expirePasswordEnrollTokens(new Date(), userId); - test.isUndefined(Meteor.users.findOne(userId).services.password.reset); } ) + Tinytest.add( + "passwords - enroll tokens don't get cleaned up when reset tokens are cleaned up", + function (test) { + var email = test.id + '-intercept@example.com'; + var userId = Accounts.createUser({email: email, password: 'password'}); + + Accounts.sendEnrollmentEmail(userId, email); + var enrollToken = Meteor.users.findOne(userId).services.password.reset; + test.isTrue(enrollToken); + + Accounts._expirePasswordResetTokens(new Date(), userId); + test.equal(enrollToken, Meteor.users.findOne(userId).services.password.reset); + } + ) + + Tinytest.add( + "passwords - reset tokens don't get cleaned up when enroll tokens are cleaned up", + function (test) { + var email = test.id + '-intercept@example.com'; + var userId = Accounts.createUser({email: email, password: 'password'}); + + Accounts.sendResetPasswordEmail(userId, email); + var resetToken = Meteor.users.findOne(userId).services.password.reset; + test.isTrue(resetToken); + + Accounts._expirePasswordEnrollTokens(new Date(), userId); + test.equal(resetToken,Meteor.users.findOne(userId).services.password.reset); + } + ) + // We should be able to change the username Tinytest.add("passwords - change username", function (test) { var username = Random.id(); From e30f30f04c5200363d9a47092248b62b2a50622f Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Wed, 29 Mar 2017 18:25:33 +0300 Subject: [PATCH 14/60] Add TOOL_NODE_FLAGS support for Windows in the same way as Unix. (#8517) In Unix we support adding `TOOL_NODE_FLAGS` when debugging the Meteor tool itself, however Windows did not currently support it. This should add that support. As this is a .bat file, I have every reason to believe that this syntax should work on older versions of Windows as the syntax of .bat files hasn't changed much. Helps with meteor/meteor#8513. --- meteor.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meteor.bat b/meteor.bat index 3f9f7a7066..c134cddeda 100644 --- a/meteor.bat +++ b/meteor.bat @@ -38,7 +38,7 @@ IF EXIST "%~dp0\.git" ( SET NODE_PATH=%~dp0\dev_bundle\lib\node_modules SET BABEL_CACHE_DIR=%~dp0\.babel-cache -"%~dp0\dev_bundle\bin\node.exe" "%~dp0\tools\index.js" %* +"%~dp0\dev_bundle\bin\node.exe" %TOOL_NODE_FLAGS% "%~dp0\tools\index.js" %* ENDLOCAL EXIT /b %ERRORLEVEL% From 6f25191d03e115dcc5e724f079899516f0504aaa Mon Sep 17 00:00:00 2001 From: Gabriel Engel Date: Wed, 29 Mar 2017 12:30:11 -0300 Subject: [PATCH 15/60] Remove ES6 from ddp-client (#8516) Follow-up to https://github.com/meteor/meteor/pull/8516/commits/05be2c784cd51033b3c8da8b21984589639839b8 which added new ES6 syntax, but failed to add `ecmascript`. * Remove ecmascript Object function shorthand notation. as the `rate-limit` package doesn't currently use `ecmacsript` and using it for just this one instance of ES6 isn't worth it. * Remove `ecmascript` from `rate-limit` as it is now unused. * Bump `rate-limit` version in preparation for publishing. Fixes #8515 --- packages/rate-limit/package.js | 2 +- packages/rate-limit/rate-limit.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rate-limit/package.js b/packages/rate-limit/package.js index 6dead5d1de..8fb323d567 100644 --- a/packages/rate-limit/package.js +++ b/packages/rate-limit/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'rate-limit', - version: '1.0.7', + version: '1.0.8', // Brief, one-line summary of the package. summary: 'An algorithm for rate limiting anything', // URL to the Git repository containing the source code for this package. diff --git a/packages/rate-limit/rate-limit.js b/packages/rate-limit/rate-limit.js index 95f5168896..7e772a7e26 100644 --- a/packages/rate-limit/rate-limit.js +++ b/packages/rate-limit/rate-limit.js @@ -102,7 +102,7 @@ _.extend(Rule.prototype, { self.counters = {}; self._lastResetTime = new Date().getTime(); }, - _executeCallback(reply, ruleInput) { + _executeCallback: function (reply, ruleInput) { try { if (this.options.callback) { this.options.callback(reply, ruleInput); From fdef0dd972a1062bcd4867c9bc8ae0ad32408359 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Wed, 29 Mar 2017 23:16:54 +0300 Subject: [PATCH 16/60] Fixed trailing whitespace introduced into `accounts-*`. Follows-up on 3c011c9dc. --- packages/accounts-base/accounts_server.js | 2 +- packages/accounts-password/password_tests.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/accounts-base/accounts_server.js b/packages/accounts-base/accounts_server.js index d2aa2adb65..ab62e14618 100644 --- a/packages/accounts-base/accounts_server.js +++ b/packages/accounts-base/accounts_server.js @@ -1077,7 +1077,7 @@ Ap._generateStampedLoginToken = function () { function expirePasswordToken(accounts, oldestValidDate, tokenFilter, userId) { const userFilter = userId ? {_id: userId} : {}; - const resetRangeOr = { + const resetRangeOr = { $or: [ { "services.password.reset.when": { $lt: oldestValidDate } }, { "services.password.reset.when": { $lt: +oldestValidDate } } diff --git a/packages/accounts-password/password_tests.js b/packages/accounts-password/password_tests.js index b09274ed4e..a34b3b9a7d 100644 --- a/packages/accounts-password/password_tests.js +++ b/packages/accounts-password/password_tests.js @@ -1688,7 +1688,7 @@ if (Meteor.isServer) (function () { function (test) { var email = test.id + '-intercept@example.com'; var userId = Accounts.createUser({email: email, password: 'password'}); - + Accounts.sendEnrollmentEmail(userId, email); test.isTrue(!!Meteor.users.findOne(userId).services.password.reset); @@ -1702,7 +1702,7 @@ if (Meteor.isServer) (function () { function (test) { var email = test.id + '-intercept@example.com'; var userId = Accounts.createUser({email: email, password: 'password'}); - + Accounts.sendEnrollmentEmail(userId, email); var enrollToken = Meteor.users.findOne(userId).services.password.reset; test.isTrue(enrollToken); From 08d6d9f7229cb179543dbc2535eaed580035d69b Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Wed, 29 Mar 2017 23:17:37 +0300 Subject: [PATCH 17/60] Add 1.4.4 `-rc.n` suffixes on `accounts-base`/`accounts-server` versions. --- packages/accounts-base/package.js | 2 +- packages/accounts-password/package.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/accounts-base/package.js b/packages/accounts-base/package.js index 53f2945ec9..3c726b3133 100644 --- a/packages/accounts-base/package.js +++ b/packages/accounts-base/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "A user account system", - version: "1.2.15" + version: "1.2.16-rc.3" }); Package.onUse(function (api) { diff --git a/packages/accounts-password/package.js b/packages/accounts-password/package.js index 67781b8484..27c2f79266 100644 --- a/packages/accounts-password/package.js +++ b/packages/accounts-password/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Password support for accounts", - version: "1.3.4" + version: "1.3.5-rc.3" }); Package.onUse(function(api) { From 6d2b7c80703d81f4d41584d647a7bc32a2889164 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Wed, 29 Mar 2017 23:49:49 +0300 Subject: [PATCH 18/60] Merge pull request #8520 from dhrubins/accounts-password-ambiguous-errors Add ambiguous error messages option to Accounts config --- packages/accounts-base/accounts_common.js | 7 +- packages/accounts-password/password_server.js | 119 ++++++++++++------ 2 files changed, 86 insertions(+), 40 deletions(-) diff --git a/packages/accounts-base/accounts_common.js b/packages/accounts-base/accounts_common.js index e968ec2e5e..8c936b8da4 100644 --- a/packages/accounts-base/accounts_common.js +++ b/packages/accounts-base/accounts_common.js @@ -86,6 +86,9 @@ export class AccountsCommon { // - passwordResetTokenExpirationInDays {Number} // Number of days since password reset token creation until the // token cannt be used any longer (password reset token expires). + // - ambiguousErrorMessages {Boolean} + // Return ambiguous error messages from login failures to prevent + // user enumeration. /** * @summary Set global accounts options. @@ -98,6 +101,7 @@ export class AccountsCommon { * @param {String} options.oauthSecretKey When using the `oauth-encryption` package, the 16 byte key using to encrypt sensitive account credentials in the database, encoded in base64. This option may only be specifed on the server. See packages/oauth-encryption/README.md for details. * @param {Number} options.passwordResetTokenExpirationInDays The number of days from when a link to reset password is sent until token expires and user can't reset password with the link anymore. Defaults to 3. * @param {Number} options.passwordEnrollTokenExpirationInDays The number of days from when a link to set inital password is sent until token expires and user can't set password with the link anymore. Defaults to 30. + * @param {Boolean} options.ambiguousErrorMessages Return ambiguous error messages from login failures to prevent user enumeration. Defaults to false. */ config(options) { var self = this; @@ -130,7 +134,8 @@ export class AccountsCommon { // validate option keys var VALID_KEYS = ["sendVerificationEmail", "forbidClientAccountCreation", "passwordEnrollTokenExpirationInDays", - "restrictCreationByEmailDomain", "loginExpirationInDays", "passwordResetTokenExpirationInDays"]; + "restrictCreationByEmailDomain", "loginExpirationInDays", "passwordResetTokenExpirationInDays", + "ambiguousErrorMessages"]; _.each(_.keys(options), function (key) { if (!_.contains(VALID_KEYS, key)) { throw new Error("Accounts.config: Invalid key: " + key); diff --git a/packages/accounts-password/password_server.js b/packages/accounts-password/password_server.js index 5bc154917b..9102743fec 100644 --- a/packages/accounts-password/password_server.js +++ b/packages/accounts-password/password_server.js @@ -66,13 +66,29 @@ Accounts._checkPassword = function (user, password) { password = getPasswordString(password); if (! bcryptCompare(password, user.services.password.bcrypt)) { - result.error = new Meteor.Error(403, "Incorrect password"); + result.error = handleError("Incorrect password", false); } return result; }; var checkPassword = Accounts._checkPassword; +/// +/// ERROR HANDLER +/// +const handleError = (msg, throwError = true) => { + const error = new Meteor.Error( + 403, + Accounts._options.ambiguousErrorMessages + ? "Login failure. Please check your login credentials." + : msg + ); + if (throwError) { + throw error; + } + return error; +}; + /// /// LOGIN /// @@ -202,7 +218,7 @@ var checkForCaseInsensitiveDuplicates = function (fieldName, displayName, fieldV // Otherwise, check to see if there are multiple matches or a match // that is not us (matchedUsers.length > 1 || matchedUsers[0]._id !== ownUserId))) { - throw new Meteor.Error(403, displayName + " already exists."); + handleError(displayName + " already exists."); } } }; @@ -254,12 +270,14 @@ Accounts.registerLoginHandler("password", function (options) { var user = Accounts._findUserByQuery(options.user); - if (!user) - throw new Meteor.Error(403, "User not found"); + if (!user) { + handleError("User not found"); + } if (!user.services || !user.services.password || - !(user.services.password.bcrypt || user.services.password.srp)) - throw new Meteor.Error(403, "User has no password set"); + !(user.services.password.bcrypt || user.services.password.srp)) { + handleError("User has no password set"); + } if (!user.services.password.bcrypt) { if (typeof options.password === "string") { @@ -273,8 +291,8 @@ Accounts.registerLoginHandler("password", function (options) { if (verifier.verifier !== newVerifier.verifier) { return { - userId: user._id, - error: new Meteor.Error(403, "Incorrect password") + userId: Accounts._options.ambiguousErrorMessages ? null : user._id, + error: handleError("Incorrect password", false) }; } @@ -310,8 +328,9 @@ Accounts.registerLoginHandler("password", function (options) { // // XXX COMPAT WITH 0.8.1.3 Accounts.registerLoginHandler("password", function (options) { - if (!options.srp || !options.password) + if (!options.srp || !options.password) { return undefined; // don't handle + } check(options, { user: userQueryValidator, @@ -320,16 +339,19 @@ Accounts.registerLoginHandler("password", function (options) { }); var user = Accounts._findUserByQuery(options.user); - if (!user) - throw new Meteor.Error(403, "User not found"); + if (!user) { + handleError("User not found"); + } // Check to see if another simultaneous login has already upgraded // the user record to bcrypt. - if (user.services && user.services.password && user.services.password.bcrypt) + if (user.services && user.services.password && user.services.password.bcrypt) { return checkPassword(user, options.password); + } - if (!(user.services && user.services.password && user.services.password.srp)) - throw new Meteor.Error(403, "User has no password set"); + if (!(user.services && user.services.password && user.services.password.srp)) { + handleError("User has no password set"); + } var v1 = user.services.password.srp.verifier; var v2 = SRP.generateVerifier( @@ -339,11 +361,12 @@ Accounts.registerLoginHandler("password", function (options) { salt: user.services.password.srp.salt } ).verifier; - if (v1 !== v2) + if (v1 !== v2) { return { - userId: user._id, - error: new Meteor.Error(403, "Incorrect password") + userId: Accounts._options.ambiguousErrorMessages ? null : user._id, + error: handleError("Incorrect password", false) }; + } // Upgrade to bcrypt on successful login. var salted = hashPassword(options.password); @@ -377,8 +400,9 @@ Accounts.setUsername = function (userId, newUsername) { check(newUsername, NonEmptyString); var user = Meteor.users.findOne(userId); - if (!user) - throw new Meteor.Error(403, "User not found"); + if (!user) { + handleError("User not found"); + } var oldUsername = user.username; @@ -417,16 +441,19 @@ Meteor.methods({changePassword: function (oldPassword, newPassword) { check(oldPassword, passwordValidator); check(newPassword, passwordValidator); - if (!this.userId) + if (!this.userId) { throw new Meteor.Error(401, "Must be logged in"); + } var user = Meteor.users.findOne(this.userId); - if (!user) - throw new Meteor.Error(403, "User not found"); + if (!user) { + handleError("User not found"); + } if (!user.services || !user.services.password || - (!user.services.password.bcrypt && !user.services.password.srp)) - throw new Meteor.Error(403, "User has no password set"); + (!user.services.password.bcrypt && !user.services.password.srp)) { + handleError("User has no password set"); + } if (! user.services.password.bcrypt) { throw new Meteor.Error(400, "old password format", EJSON.stringify({ @@ -436,8 +463,9 @@ Meteor.methods({changePassword: function (oldPassword, newPassword) { } var result = checkPassword(user, oldPassword); - if (result.error) + if (result.error) { throw result.error; + } var hashed = hashPassword(newPassword); @@ -476,8 +504,9 @@ Accounts.setPassword = function (userId, newPlaintextPassword, options) { options = _.extend({logout: true}, options); var user = Meteor.users.findOne(userId); - if (!user) + if (!user) { throw new Meteor.Error(403, "User not found"); + } var update = { $unset: { @@ -505,8 +534,9 @@ Meteor.methods({forgotPassword: function (options) { check(options, {email: String}); var user = Accounts.findUserByEmail(options.email); - if (!user) - throw new Meteor.Error(403, "User not found"); + if (!user) { + handleError("User not found"); + } const emails = _.pluck(user.emails || [], 'address'); const caseSensitiveEmail = _.find(emails, email => { @@ -529,14 +559,19 @@ Meteor.methods({forgotPassword: function (options) { Accounts.sendResetPasswordEmail = function (userId, email) { // Make sure the user exists, and email is one of their addresses. var user = Meteor.users.findOne(userId); - if (!user) - throw new Error("Can't find user"); + if (!user) { + handleError("Can't find user"); + } + // pick the first email if we weren't passed an email. - if (!email && user.emails && user.emails[0]) + if (!email && user.emails && user.emails[0]) { email = user.emails[0].address; + } + // make sure we have a valid email - if (!email || !_.contains(_.pluck(user.emails || [], 'address'), email)) - throw new Error("No such email for user."); + if (!email || !_.contains(_.pluck(user.emails || [], 'address'), email)) { + handleError("No such email for user."); + } var token = Random.secret(); var when = new Date(); @@ -567,9 +602,10 @@ Accounts.sendResetPasswordEmail = function (userId, email) { Accounts.emailTemplates.resetPassword.text(user, resetPasswordUrl); } - if (typeof Accounts.emailTemplates.resetPassword.html === 'function') + if (typeof Accounts.emailTemplates.resetPassword.html === 'function') { options.html = Accounts.emailTemplates.resetPassword.html(user, resetPasswordUrl); + } if (typeof Accounts.emailTemplates.headers === 'object') { options.headers = Accounts.emailTemplates.headers; @@ -598,14 +634,17 @@ Accounts.sendEnrollmentEmail = function (userId, email) { // Make sure the user exists, and email is in their addresses. var user = Meteor.users.findOne(userId); - if (!user) + if (!user) { throw new Error("Can't find user"); + } // pick the first email if we weren't passed an email. - if (!email && user.emails && user.emails[0]) + if (!email && user.emails && user.emails[0]) { email = user.emails[0].address; + } // make sure we have a valid email - if (!email || !_.contains(_.pluck(user.emails || [], 'address'), email)) + if (!email || !_.contains(_.pluck(user.emails || [], 'address'), email)) { throw new Error("No such email for user."); + } var token = Random.secret(); var when = new Date(); @@ -637,9 +676,10 @@ Accounts.sendEnrollmentEmail = function (userId, email) { Accounts.emailTemplates.enrollAccount.text(user, enrollAccountUrl); } - if (typeof Accounts.emailTemplates.enrollAccount.html === 'function') + if (typeof Accounts.emailTemplates.enrollAccount.html === 'function') { options.html = Accounts.emailTemplates.enrollAccount.html(user, enrollAccountUrl); + } if (typeof Accounts.emailTemplates.headers === 'object') { options.headers = Accounts.emailTemplates.headers; @@ -664,8 +704,9 @@ Meteor.methods({resetPassword: function (token, newPassword) { var user = Meteor.users.findOne({ "services.password.reset.token": token}); - if (!user) + if (!user) { throw new Meteor.Error(403, "Token expired"); + } var when = user.services.password.reset.when; var reason = user.services.password.reset.reason; var tokenLifetimeMs = Accounts._getPasswordResetTokenLifetimeMs(); From 3257bafc84de9624d69cff50c93aec23b7cbc5c9 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Thu, 30 Mar 2017 01:07:24 +0300 Subject: [PATCH 19/60] Change `wrapFsFunc` for "move" to acknowledge _both_ arguments as paths. The `wrapFsFunc` function accepts an array of indexes indicating which arguments are paths. This is particularly important on Windows, due to the path-conversation which takes place on those strings. The docs say: > Indices of arguments that have paths, these arguments will be > converted to the correct OS slashes This follows up on the change made from meteor/meteor#8491 which failed in our release pipeline when publishing for the Windows architecture for `1.4.4-rc.3`. --- tools/fs/files.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/fs/files.js b/tools/fs/files.js index 8a62569b7c..e77e504cbe 100644 --- a/tools/fs/files.js +++ b/tools/fs/files.js @@ -1610,7 +1610,7 @@ wrapFsFunc("readFile", [0], { wrapFsFunc("stat", [0]); wrapFsFunc("lstat", [0]); wrapFsFunc("rename", [0, 1]); -wrapFsFunc("move", [0]); +wrapFsFunc("move", [0, 1]); // After the outermost files.withCache call returns, the withCacheCache is // reset to null so that it does not survive server restarts. From fcbd398ab7e1dc970d296946b8910bea14fddc62 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Wed, 29 Mar 2017 18:45:32 -0400 Subject: [PATCH 20/60] Appending module identifier extensions should not match directories. This logic needed to change not only in meteor/tools/isobuild/resolver.js but also in the runtime module system: https://github.com/benjamn/install/commit/cfcc42272575348239685882a2a406272203b094 Fixes #8539. --- packages/modules-runtime/.npm/package/npm-shrinkwrap.json | 6 +++--- packages/modules-runtime/package.js | 4 ++-- tools/isobuild/resolver.js | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/modules-runtime/.npm/package/npm-shrinkwrap.json b/packages/modules-runtime/.npm/package/npm-shrinkwrap.json index 4c74093233..5186366969 100644 --- a/packages/modules-runtime/.npm/package/npm-shrinkwrap.json +++ b/packages/modules-runtime/.npm/package/npm-shrinkwrap.json @@ -1,9 +1,9 @@ { "dependencies": { "install": { - "version": "0.8.7", - "resolved": "https://registry.npmjs.org/install/-/install-0.8.7.tgz", - "from": "install@0.8.7" + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/install/-/install-0.8.8.tgz", + "from": "install@0.8.8" } } } diff --git a/packages/modules-runtime/package.js b/packages/modules-runtime/package.js index 667414d5ec..bf651c454f 100644 --- a/packages/modules-runtime/package.js +++ b/packages/modules-runtime/package.js @@ -1,13 +1,13 @@ Package.describe({ name: "modules-runtime", - version: "0.7.9", + version: "0.7.10", summary: "CommonJS module system", git: "https://github.com/benjamn/install", documentation: "README.md" }); Npm.depends({ - install: "0.8.7" + install: "0.8.8" }); Package.onUse(function(api) { diff --git a/tools/isobuild/resolver.js b/tools/isobuild/resolver.js index 3737b60429..499178f703 100644 --- a/tools/isobuild/resolver.js +++ b/tools/isobuild/resolver.js @@ -176,7 +176,7 @@ export default class Resolver { this.extensions.some(ext => { const pathWithExt = path + ext; const stat = this.statOrNull(pathWithExt); - if (stat) { + if (stat && ! stat.isDirectory()) { return result = { path: pathWithExt, stat }; } }); From 276f828359a3f7e16abf90b693b15aa0c439cf44 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Thu, 30 Mar 2017 02:16:40 +0300 Subject: [PATCH 21/60] Bump package versions for 1.4.4-rc.4 release. --- packages/accounts-base/package.js | 2 +- packages/accounts-password/package.js | 2 +- packages/babel-compiler/package.js | 2 +- packages/ddp-client/package.js | 2 +- packages/ddp-server/package.js | 2 +- packages/ecmascript/package.js | 2 +- packages/email/package.js | 2 +- packages/force-ssl-common/package.js | 2 +- packages/force-ssl/package.js | 2 +- packages/meteor-tool/package.js | 2 +- packages/minifier-js/package.js | 2 +- packages/modules/package.js | 2 +- packages/standard-minifier-js/package.js | 2 +- packages/standard-minifiers/package.js | 2 +- packages/webapp/package.js | 2 +- scripts/admin/meteor-release-experimental.json | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/accounts-base/package.js b/packages/accounts-base/package.js index 3c726b3133..2f8e27efe4 100644 --- a/packages/accounts-base/package.js +++ b/packages/accounts-base/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "A user account system", - version: "1.2.16-rc.3" + version: "1.2.16-rc.4" }); Package.onUse(function (api) { diff --git a/packages/accounts-password/package.js b/packages/accounts-password/package.js index 27c2f79266..f936764950 100644 --- a/packages/accounts-password/package.js +++ b/packages/accounts-password/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Password support for accounts", - version: "1.3.5-rc.3" + version: "1.3.5-rc.4" }); Package.onUse(function(api) { diff --git a/packages/babel-compiler/package.js b/packages/babel-compiler/package.js index ec97cc425b..a70599fe3a 100644 --- a/packages/babel-compiler/package.js +++ b/packages/babel-compiler/package.js @@ -6,7 +6,7 @@ Package.describe({ // isn't possible because you can't publish a non-recommended // release with package versions that don't have a pre-release // identifier at the end (eg, -dev) - version: '6.18.0-rc.3' + version: '6.18.0-rc.4' }); Npm.depends({ diff --git a/packages/ddp-client/package.js b/packages/ddp-client/package.js index 2accbe3747..6d6d7895e1 100644 --- a/packages/ddp-client/package.js +++ b/packages/ddp-client/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Meteor's latency-compensated distributed data client", - version: '1.3.4-rc.3', + version: '1.3.4-rc.4', documentation: null }); diff --git a/packages/ddp-server/package.js b/packages/ddp-server/package.js index 86fe3865c7..7159f7e1cf 100644 --- a/packages/ddp-server/package.js +++ b/packages/ddp-server/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Meteor's latency-compensated distributed data server", - version: '1.3.14-rc.3', + version: '1.3.14-rc.4', documentation: null }); diff --git a/packages/ecmascript/package.js b/packages/ecmascript/package.js index 6611919861..67b8014114 100644 --- a/packages/ecmascript/package.js +++ b/packages/ecmascript/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'ecmascript', - version: '0.7.1-rc.3', + version: '0.7.1-rc.4', summary: 'Compiler plugin that supports ES2015+ in all .js files', documentation: 'README.md' }); diff --git a/packages/email/package.js b/packages/email/package.js index 60477402cf..3dfd20268f 100644 --- a/packages/email/package.js +++ b/packages/email/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Send email messages", - version: "1.2.0-rc.3" + version: "1.2.0-rc.4" }); Npm.depends({ diff --git a/packages/force-ssl-common/package.js b/packages/force-ssl-common/package.js index 06bd8bf2a8..578f38155f 100644 --- a/packages/force-ssl-common/package.js +++ b/packages/force-ssl-common/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: 'Internal force-ssl common code.', - version: '1.0.14-rc.3' + version: '1.0.14-rc.4' }); Npm.depends({ diff --git a/packages/force-ssl/package.js b/packages/force-ssl/package.js index c9620e6d16..d7900a7ab4 100644 --- a/packages/force-ssl/package.js +++ b/packages/force-ssl/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Require this application to use HTTPS", - version: "1.0.14-rc.3", + version: "1.0.14-rc.4", prodOnly: true }); diff --git a/packages/meteor-tool/package.js b/packages/meteor-tool/package.js index 9ab753c5a7..a3e99f06e3 100644 --- a/packages/meteor-tool/package.js +++ b/packages/meteor-tool/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "The Meteor command-line tool", - version: '1.4.4-rc.3' + version: '1.4.4-rc.4' }); Package.includeTool(); diff --git a/packages/minifier-js/package.js b/packages/minifier-js/package.js index 842c3b8d85..c35c417d5e 100644 --- a/packages/minifier-js/package.js +++ b/packages/minifier-js/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "JavaScript minifier", - version: "2.0.0-rc.3" + version: "2.0.0-rc.4" }); Npm.depends({ diff --git a/packages/modules/package.js b/packages/modules/package.js index a971ed908b..d6e068118f 100644 --- a/packages/modules/package.js +++ b/packages/modules/package.js @@ -1,6 +1,6 @@ Package.describe({ name: "modules", - version: "0.8.1-rc.3", + version: "0.8.1-rc.4", summary: "CommonJS module system", documentation: "README.md" }); diff --git a/packages/standard-minifier-js/package.js b/packages/standard-minifier-js/package.js index 26ece4629b..850e5b04a4 100644 --- a/packages/standard-minifier-js/package.js +++ b/packages/standard-minifier-js/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'standard-minifier-js', - version: '2.0.0-rc.3', + version: '2.0.0-rc.4', summary: 'Standard javascript minifiers used with Meteor apps by default.', documentation: 'README.md', }); diff --git a/packages/standard-minifiers/package.js b/packages/standard-minifiers/package.js index ffbd72c388..11e0b81faa 100644 --- a/packages/standard-minifiers/package.js +++ b/packages/standard-minifiers/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'standard-minifiers', - version: '1.1.0-rc.3', + version: '1.1.0-rc.4', summary: 'Standard minifiers used with Meteor apps by default.', documentation: 'README.md' }); diff --git a/packages/webapp/package.js b/packages/webapp/package.js index 29ab57ec69..c9a6230e9d 100644 --- a/packages/webapp/package.js +++ b/packages/webapp/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Serves a Meteor app over HTTP", - version: '1.3.15-rc.3' + version: '1.3.15-rc.4' }); Npm.depends({connect: "2.30.2", diff --git a/scripts/admin/meteor-release-experimental.json b/scripts/admin/meteor-release-experimental.json index 50691cd490..4437ef3139 100644 --- a/scripts/admin/meteor-release-experimental.json +++ b/scripts/admin/meteor-release-experimental.json @@ -1,6 +1,6 @@ { "track": "METEOR", - "version": "1.4.4-rc.3", + "version": "1.4.4-rc.4", "recommended": false, "official": false, "description": "Meteor" From de11f73477e3c6881f09b613d87063489756686d Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Thu, 30 Mar 2017 02:17:18 +0300 Subject: [PATCH 22/60] Add `-rc.n` suffix to `modules-runtime`. --- packages/modules-runtime/package.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/modules-runtime/package.js b/packages/modules-runtime/package.js index bf651c454f..4e8df094b1 100644 --- a/packages/modules-runtime/package.js +++ b/packages/modules-runtime/package.js @@ -1,6 +1,6 @@ Package.describe({ name: "modules-runtime", - version: "0.7.10", + version: "0.7.10-rc.4", summary: "CommonJS module system", git: "https://github.com/benjamn/install", documentation: "README.md" From e3d9bac133acff91ee8d230ccafce7ba4bcf8591 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Thu, 30 Mar 2017 03:14:45 +0300 Subject: [PATCH 23/60] Add `-rc.n` suffix to `rate-limit`. --- packages/rate-limit/package.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rate-limit/package.js b/packages/rate-limit/package.js index 8fb323d567..50572a34ca 100644 --- a/packages/rate-limit/package.js +++ b/packages/rate-limit/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'rate-limit', - version: '1.0.8', + version: '1.0.8-rc.4', // Brief, one-line summary of the package. summary: 'An algorithm for rate limiting anything', // URL to the Git repository containing the source code for this package. From 2fd61b83a78d23636a43d81463a652066c875655 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Thu, 30 Mar 2017 15:47:07 +0300 Subject: [PATCH 24/60] Bump package versions for 1.4.4-rc.5 release. --- packages/accounts-base/package.js | 2 +- packages/accounts-password/package.js | 2 +- packages/babel-compiler/package.js | 2 +- packages/ddp-client/package.js | 2 +- packages/ddp-server/package.js | 2 +- packages/ecmascript/package.js | 2 +- packages/email/package.js | 2 +- packages/force-ssl-common/package.js | 2 +- packages/force-ssl/package.js | 2 +- packages/meteor-tool/package.js | 2 +- packages/minifier-js/package.js | 2 +- packages/modules-runtime/package.js | 2 +- packages/modules/package.js | 2 +- packages/rate-limit/package.js | 2 +- packages/standard-minifier-js/package.js | 2 +- packages/standard-minifiers/package.js | 2 +- packages/webapp/package.js | 2 +- scripts/admin/meteor-release-experimental.json | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/packages/accounts-base/package.js b/packages/accounts-base/package.js index 2f8e27efe4..7176cbf8bf 100644 --- a/packages/accounts-base/package.js +++ b/packages/accounts-base/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "A user account system", - version: "1.2.16-rc.4" + version: "1.2.16-rc.5" }); Package.onUse(function (api) { diff --git a/packages/accounts-password/package.js b/packages/accounts-password/package.js index f936764950..e0cd07569b 100644 --- a/packages/accounts-password/package.js +++ b/packages/accounts-password/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Password support for accounts", - version: "1.3.5-rc.4" + version: "1.3.5-rc.5" }); Package.onUse(function(api) { diff --git a/packages/babel-compiler/package.js b/packages/babel-compiler/package.js index a70599fe3a..dd9111b6c1 100644 --- a/packages/babel-compiler/package.js +++ b/packages/babel-compiler/package.js @@ -6,7 +6,7 @@ Package.describe({ // isn't possible because you can't publish a non-recommended // release with package versions that don't have a pre-release // identifier at the end (eg, -dev) - version: '6.18.0-rc.4' + version: '6.18.0-rc.5' }); Npm.depends({ diff --git a/packages/ddp-client/package.js b/packages/ddp-client/package.js index 6d6d7895e1..6c37f4e6be 100644 --- a/packages/ddp-client/package.js +++ b/packages/ddp-client/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Meteor's latency-compensated distributed data client", - version: '1.3.4-rc.4', + version: '1.3.4-rc.5', documentation: null }); diff --git a/packages/ddp-server/package.js b/packages/ddp-server/package.js index 7159f7e1cf..e4cffb5edd 100644 --- a/packages/ddp-server/package.js +++ b/packages/ddp-server/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Meteor's latency-compensated distributed data server", - version: '1.3.14-rc.4', + version: '1.3.14-rc.5', documentation: null }); diff --git a/packages/ecmascript/package.js b/packages/ecmascript/package.js index 67b8014114..6bd81361e0 100644 --- a/packages/ecmascript/package.js +++ b/packages/ecmascript/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'ecmascript', - version: '0.7.1-rc.4', + version: '0.7.1-rc.5', summary: 'Compiler plugin that supports ES2015+ in all .js files', documentation: 'README.md' }); diff --git a/packages/email/package.js b/packages/email/package.js index 3dfd20268f..61e21ffd01 100644 --- a/packages/email/package.js +++ b/packages/email/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Send email messages", - version: "1.2.0-rc.4" + version: "1.2.0-rc.5" }); Npm.depends({ diff --git a/packages/force-ssl-common/package.js b/packages/force-ssl-common/package.js index 578f38155f..e3e521e717 100644 --- a/packages/force-ssl-common/package.js +++ b/packages/force-ssl-common/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: 'Internal force-ssl common code.', - version: '1.0.14-rc.4' + version: '1.0.14-rc.5' }); Npm.depends({ diff --git a/packages/force-ssl/package.js b/packages/force-ssl/package.js index d7900a7ab4..ef4cd6a4e7 100644 --- a/packages/force-ssl/package.js +++ b/packages/force-ssl/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Require this application to use HTTPS", - version: "1.0.14-rc.4", + version: "1.0.14-rc.5", prodOnly: true }); diff --git a/packages/meteor-tool/package.js b/packages/meteor-tool/package.js index a3e99f06e3..8559002ee6 100644 --- a/packages/meteor-tool/package.js +++ b/packages/meteor-tool/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "The Meteor command-line tool", - version: '1.4.4-rc.4' + version: '1.4.4-rc.5' }); Package.includeTool(); diff --git a/packages/minifier-js/package.js b/packages/minifier-js/package.js index c35c417d5e..381e33ef25 100644 --- a/packages/minifier-js/package.js +++ b/packages/minifier-js/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "JavaScript minifier", - version: "2.0.0-rc.4" + version: "2.0.0-rc.5" }); Npm.depends({ diff --git a/packages/modules-runtime/package.js b/packages/modules-runtime/package.js index 4e8df094b1..e711b80417 100644 --- a/packages/modules-runtime/package.js +++ b/packages/modules-runtime/package.js @@ -1,6 +1,6 @@ Package.describe({ name: "modules-runtime", - version: "0.7.10-rc.4", + version: "0.7.10-rc.5", summary: "CommonJS module system", git: "https://github.com/benjamn/install", documentation: "README.md" diff --git a/packages/modules/package.js b/packages/modules/package.js index d6e068118f..1ac52e4b7c 100644 --- a/packages/modules/package.js +++ b/packages/modules/package.js @@ -1,6 +1,6 @@ Package.describe({ name: "modules", - version: "0.8.1-rc.4", + version: "0.8.1-rc.5", summary: "CommonJS module system", documentation: "README.md" }); diff --git a/packages/rate-limit/package.js b/packages/rate-limit/package.js index 50572a34ca..ff938de70a 100644 --- a/packages/rate-limit/package.js +++ b/packages/rate-limit/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'rate-limit', - version: '1.0.8-rc.4', + version: '1.0.8-rc.5', // Brief, one-line summary of the package. summary: 'An algorithm for rate limiting anything', // URL to the Git repository containing the source code for this package. diff --git a/packages/standard-minifier-js/package.js b/packages/standard-minifier-js/package.js index 850e5b04a4..e1cbadedbe 100644 --- a/packages/standard-minifier-js/package.js +++ b/packages/standard-minifier-js/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'standard-minifier-js', - version: '2.0.0-rc.4', + version: '2.0.0-rc.5', summary: 'Standard javascript minifiers used with Meteor apps by default.', documentation: 'README.md', }); diff --git a/packages/standard-minifiers/package.js b/packages/standard-minifiers/package.js index 11e0b81faa..a87eae6bd7 100644 --- a/packages/standard-minifiers/package.js +++ b/packages/standard-minifiers/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'standard-minifiers', - version: '1.1.0-rc.4', + version: '1.1.0-rc.5', summary: 'Standard minifiers used with Meteor apps by default.', documentation: 'README.md' }); diff --git a/packages/webapp/package.js b/packages/webapp/package.js index c9a6230e9d..f0aa0db24d 100644 --- a/packages/webapp/package.js +++ b/packages/webapp/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Serves a Meteor app over HTTP", - version: '1.3.15-rc.4' + version: '1.3.15-rc.5' }); Npm.depends({connect: "2.30.2", diff --git a/scripts/admin/meteor-release-experimental.json b/scripts/admin/meteor-release-experimental.json index 4437ef3139..7b4586663a 100644 --- a/scripts/admin/meteor-release-experimental.json +++ b/scripts/admin/meteor-release-experimental.json @@ -1,6 +1,6 @@ { "track": "METEOR", - "version": "1.4.4-rc.4", + "version": "1.4.4-rc.5", "recommended": false, "official": false, "description": "Meteor" From 0a73a80b4b09d33f5197ec490567e42ed2eed5b1 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Mon, 3 Apr 2017 16:52:43 -0400 Subject: [PATCH 25/60] Upgrade uglify-js in an attempt to fix #8536. --- packages/minifier-js/.npm/package/npm-shrinkwrap.json | 6 +++--- packages/minifier-js/package.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/minifier-js/.npm/package/npm-shrinkwrap.json b/packages/minifier-js/.npm/package/npm-shrinkwrap.json index d0d9c85776..d8ce156456 100644 --- a/packages/minifier-js/.npm/package/npm-shrinkwrap.json +++ b/packages/minifier-js/.npm/package/npm-shrinkwrap.json @@ -61,9 +61,9 @@ "from": "source-map@>=0.5.1 <0.6.0" }, "uglify-js": { - "version": "2.8.16", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.16.tgz", - "from": "uglify-js@2.8.16" + "version": "2.8.21", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.21.tgz", + "from": "uglify-js@2.8.21" }, "uglify-to-browserify": { "version": "1.0.2", diff --git a/packages/minifier-js/package.js b/packages/minifier-js/package.js index 381e33ef25..4cdbd87e2f 100644 --- a/packages/minifier-js/package.js +++ b/packages/minifier-js/package.js @@ -4,7 +4,7 @@ Package.describe({ }); Npm.depends({ - "uglify-js": "2.8.16" + "uglify-js": "2.8.21" }); Package.onUse(function (api) { From 954efa7f5a9d7022f7fd39a7ee54b95adfef34d9 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Mon, 3 Apr 2017 17:07:12 -0400 Subject: [PATCH 26/60] Support Google Sign-In in google-oauth package. (#8549) * Support Google Sign-In in google-oauth package. Addresses #8253. * Use Meteor.startup instead of listening for deviceready event. * Fix mobile-config.js typo. * Bump accounts-google and google-oauth package versions. I'm only bumping the patch versions, even though the recent changes to these packages may seem significant, for two reasons: 1. Bumping the minor versions would force Meteor 1.4.3 developers to upgrade to Meteor 1.4.4 if they wanted to use these changes. 2. The accounts-google and google-oauth packages without these changes will stop working completely in two weeks, which is much worse than the risks of upgrading. --- packages/accounts-google/google.js | 9 +++ packages/accounts-google/package.js | 2 +- packages/google-oauth/google_client.js | 2 +- packages/google-oauth/google_server.js | 30 ++++++++- packages/google-oauth/google_sign-in.js | 84 +++++++++++++++++++++++++ packages/google-oauth/namespace.js | 6 ++ packages/google-oauth/package.js | 11 +++- tools/cordova/README.md | 2 +- 8 files changed, 140 insertions(+), 6 deletions(-) create mode 100644 packages/google-oauth/google_sign-in.js create mode 100644 packages/google-oauth/namespace.js diff --git a/packages/accounts-google/google.js b/packages/accounts-google/google.js index f6e092f930..ab5c4c97ea 100644 --- a/packages/accounts-google/google.js +++ b/packages/accounts-google/google.js @@ -8,6 +8,15 @@ if (Meteor.isClient) { options = null; } + if (Meteor.isCordova && + Google.signIn) { + // After 20 April 2017, Google OAuth login will no longer work from + // a WebView, so Cordova apps must use Google Sign-In instead. + // https://github.com/meteor/meteor/issues/8253 + Google.signIn(options, callback); + return; + } + // Use Google's domain-specific login page if we want to restrict creation to // a particular email domain. (Don't use it if restrictCreationByEmailDomain // is a function.) Note that all this does is change Google's UI --- diff --git a/packages/accounts-google/package.js b/packages/accounts-google/package.js index 4b398a98df..6c624c9e08 100644 --- a/packages/accounts-google/package.js +++ b/packages/accounts-google/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Login service for Google accounts", - version: "1.1.1" + version: "1.1.2" }); Package.onUse(function(api) { diff --git a/packages/google-oauth/google_client.js b/packages/google-oauth/google_client.js index b8af26fee4..c7b54dccfb 100644 --- a/packages/google-oauth/google_client.js +++ b/packages/google-oauth/google_client.js @@ -1,4 +1,4 @@ -Google = {}; +var Google = require("./namespace.js"); // Request Google credentials for the user // @param options {optional} diff --git a/packages/google-oauth/google_server.js b/packages/google-oauth/google_server.js index 33bdac656b..4b647a37d5 100644 --- a/packages/google-oauth/google_server.js +++ b/packages/google-oauth/google_server.js @@ -1,12 +1,38 @@ -Google = {}; +var Google = require("./namespace.js"); +var Accounts = require("meteor/accounts-base").Accounts; // https://developers.google.com/accounts/docs/OAuth2Login#userinfocall Google.whitelistedFields = ['id', 'email', 'verified_email', 'name', 'given_name', 'family_name', 'picture', 'locale', 'timezone', 'gender']; +Accounts.registerLoginHandler(function (request) { + if (request.googleSignIn !== true) { + return; + } + + var res = HTTP.get( + "https://www.googleapis.com/oauth2/v3/tokeninfo", + { headers: { "User-Agent": "Meteor/1.0" }, + params: { id_token: request.idToken }} + ); + + if (res.error) { + throw res.error; + } + + if (res.statusCode === 200 && + res.data.sub === request.userId) { + return Accounts.updateOrCreateUserFromExternalService("google", { + id: request.userId, + idToken: request.idToken, + accessToken: request.accessToken, + email: request.email, + picture: request.imageUrl + }); + } +}); OAuth.registerService('google', 2, null, function(query) { - var response = getTokens(query); var expiresAt = (+new Date) + (1000 * parseInt(response.expiresIn, 10)); var accessToken = response.accessToken; diff --git a/packages/google-oauth/google_sign-in.js b/packages/google-oauth/google_sign-in.js new file mode 100644 index 0000000000..4d21403264 --- /dev/null +++ b/packages/google-oauth/google_sign-in.js @@ -0,0 +1,84 @@ +var Google = require("./namespace.js"); + +var gplusPromise = new Promise(function (resolve, reject) { + if (! Meteor.isCordova) { + reject(new Error("plugins.googleplus requires Cordova")); + return; + } + + Meteor.startup(function () { + var plugins = global.plugins; + var gplus = plugins && plugins.googleplus; + if (gplus) { + resolve(gplus); + } else { + reject(new Error("plugins.googleplus not defined")); + } + }); +}); + +function tolerateUnhandledRejection() {} +gplusPromise.catch(tolerateUnhandledRejection); + +// After 20 April 2017, Google OAuth login will no longer work from a +// WebView, so Cordova apps must use Google Sign-In instead. +// https://github.com/meteor/meteor/issues/8253 +exports.signIn = Google.signIn = function (options, callback) { + // support a callback without options + if (! callback && typeof options === "function") { + callback = options; + options = null; + } + + gplusPromise.then(function (gplus) { + var config = ServiceConfiguration.configurations.findOne({ + service: "google" + }); + + if (! config) { + throw new ServiceConfiguration.ConfigError(); + } + + options = Object.assign(Object.create(null), options); + + gplus.login({ + scopes: getScopes(options).join(" "), + webClientId: config.clientId, + offline: true + }, function (response) { + Accounts.callLoginMethod({ + methodArguments: [Object.assign({ + googleSignIn: true + }, response)], + userCallback: callback + }); + }, callback); + + }).catch(callback); +}; + +function getScopes(options) { + // we need the email scope to get user id from google. + var requiredScopes = ['email']; + var scopes = ['profile']; + if (options && options.requestPermissions) { + scopes = options.requestPermissions; + } + return _.union(scopes, requiredScopes); +} + +exports.signOut = Google.signOut = function () { + return gplusPromise.then(function (gplus) { + return new Promise(function (resolve) { + gplus.logout(resolve); + }); + }); +}; + +// Make sure we don't stay logged in with Google Sign-In after the client +// calls Meteor.logout(). +Meteor.startup(function () { + Accounts.onLogout(function () { + Google.signOut().catch(tolerateUnhandledRejection); + }); +}); diff --git a/packages/google-oauth/namespace.js b/packages/google-oauth/namespace.js new file mode 100644 index 0000000000..ba7feea718 --- /dev/null +++ b/packages/google-oauth/namespace.js @@ -0,0 +1,6 @@ +// The module.exports object of this module becomes the Google namespace +// for other modules in this package. +Google = module.exports; + +// So that api.export finds the "Google" property. +Google.Google = Google; diff --git a/packages/google-oauth/package.js b/packages/google-oauth/package.js index 7b8f76d401..8193e069b2 100644 --- a/packages/google-oauth/package.js +++ b/packages/google-oauth/package.js @@ -1,9 +1,15 @@ Package.describe({ summary: "Google OAuth flow", - version: "1.2.0" + version: "1.2.1" +}); + +Cordova.depends({ + "cordova-plugin-googleplus": "5.1.1" }); Package.onUse(function(api) { + api.use("modules"); + api.use("promise"); api.use('oauth2', ['client', 'server']); api.use('oauth', ['client', 'server']); api.use('http', ['server']); @@ -12,6 +18,9 @@ Package.onUse(function(api) { api.addFiles('google_server.js', 'server'); api.addFiles('google_client.js', 'client'); + api.addFiles('google_sign-in.js', 'web.cordova'); + + api.mainModule('namespace.js'); api.export('Google'); }); diff --git a/tools/cordova/README.md b/tools/cordova/README.md index 192745b27f..eeab6c8e8c 100644 --- a/tools/cordova/README.md +++ b/tools/cordova/README.md @@ -111,7 +111,7 @@ app bundle (`pluginVersionsFromStarManifest`, a combination of `.meteor/cordova-plugins` for stand-alone plugin installs and the plugins added as dependencies of packages through `Cordova.depends`). The `pluginsConfiguration` comes from `App.configurePlugin` calls in -`meteor-config.js`. +`mobile-config.js`. Uses methods `CordovaProject#listInstalledPluginVersions()`, `CordovaProject#addPlugin(name, version, config)`, From 87d0a33067dbcd8f25467d677bcc13cebe89683b Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Mon, 3 Apr 2017 18:43:54 -0400 Subject: [PATCH 27/60] Get Cordova plugin test to pass by adding time. --- tools/tests/cordova-plugins.js | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/tests/cordova-plugins.js b/tools/tests/cordova-plugins.js index 796e1740b9..e17fbd21a0 100644 --- a/tools/tests/cordova-plugins.js +++ b/tools/tests/cordova-plugins.js @@ -141,6 +141,7 @@ selftest.define("change cordova plugins", ["cordova"], function () { run = s.run(); run.match("myapp"); run.match("proxy"); + run.waitSecs(30); run.match("MongoDB"); run.match("your app"); run.match("running at"); From f3c2eaf5bf7c91a70779c7fea93dec71cad528bf Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Mon, 3 Apr 2017 20:18:49 -0400 Subject: [PATCH 28/60] Bump package versions for 1.4.4-rc.6 release. --- packages/accounts-base/package.js | 2 +- packages/accounts-google/package.js | 2 +- packages/accounts-password/package.js | 2 +- packages/babel-compiler/package.js | 2 +- packages/ddp-client/package.js | 2 +- packages/ddp-server/package.js | 2 +- packages/ecmascript/package.js | 2 +- packages/email/package.js | 2 +- packages/force-ssl-common/package.js | 2 +- packages/force-ssl/package.js | 2 +- packages/google-oauth/package.js | 2 +- packages/meteor-tool/package.js | 2 +- packages/minifier-js/package.js | 2 +- packages/modules-runtime/package.js | 2 +- packages/modules/package.js | 2 +- packages/rate-limit/package.js | 2 +- packages/standard-minifier-js/package.js | 2 +- packages/standard-minifiers/package.js | 2 +- packages/webapp/package.js | 2 +- scripts/admin/meteor-release-experimental.json | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/packages/accounts-base/package.js b/packages/accounts-base/package.js index 7176cbf8bf..d6557e088f 100644 --- a/packages/accounts-base/package.js +++ b/packages/accounts-base/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "A user account system", - version: "1.2.16-rc.5" + version: "1.2.16-rc.6" }); Package.onUse(function (api) { diff --git a/packages/accounts-google/package.js b/packages/accounts-google/package.js index 6c624c9e08..590ab6de53 100644 --- a/packages/accounts-google/package.js +++ b/packages/accounts-google/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Login service for Google accounts", - version: "1.1.2" + version: "1.1.2-rc.6" }); Package.onUse(function(api) { diff --git a/packages/accounts-password/package.js b/packages/accounts-password/package.js index e0cd07569b..81489fa982 100644 --- a/packages/accounts-password/package.js +++ b/packages/accounts-password/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Password support for accounts", - version: "1.3.5-rc.5" + version: "1.3.5-rc.6" }); Package.onUse(function(api) { diff --git a/packages/babel-compiler/package.js b/packages/babel-compiler/package.js index dd9111b6c1..56f818406c 100644 --- a/packages/babel-compiler/package.js +++ b/packages/babel-compiler/package.js @@ -6,7 +6,7 @@ Package.describe({ // isn't possible because you can't publish a non-recommended // release with package versions that don't have a pre-release // identifier at the end (eg, -dev) - version: '6.18.0-rc.5' + version: '6.18.0-rc.6' }); Npm.depends({ diff --git a/packages/ddp-client/package.js b/packages/ddp-client/package.js index 6c37f4e6be..796da6604c 100644 --- a/packages/ddp-client/package.js +++ b/packages/ddp-client/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Meteor's latency-compensated distributed data client", - version: '1.3.4-rc.5', + version: '1.3.4-rc.6', documentation: null }); diff --git a/packages/ddp-server/package.js b/packages/ddp-server/package.js index e4cffb5edd..a3d7dccc24 100644 --- a/packages/ddp-server/package.js +++ b/packages/ddp-server/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Meteor's latency-compensated distributed data server", - version: '1.3.14-rc.5', + version: '1.3.14-rc.6', documentation: null }); diff --git a/packages/ecmascript/package.js b/packages/ecmascript/package.js index 6bd81361e0..7d47878923 100644 --- a/packages/ecmascript/package.js +++ b/packages/ecmascript/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'ecmascript', - version: '0.7.1-rc.5', + version: '0.7.1-rc.6', summary: 'Compiler plugin that supports ES2015+ in all .js files', documentation: 'README.md' }); diff --git a/packages/email/package.js b/packages/email/package.js index 61e21ffd01..24244afa6a 100644 --- a/packages/email/package.js +++ b/packages/email/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Send email messages", - version: "1.2.0-rc.5" + version: "1.2.0-rc.6" }); Npm.depends({ diff --git a/packages/force-ssl-common/package.js b/packages/force-ssl-common/package.js index e3e521e717..e06ced7f8d 100644 --- a/packages/force-ssl-common/package.js +++ b/packages/force-ssl-common/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: 'Internal force-ssl common code.', - version: '1.0.14-rc.5' + version: '1.0.14-rc.6' }); Npm.depends({ diff --git a/packages/force-ssl/package.js b/packages/force-ssl/package.js index ef4cd6a4e7..d90092c493 100644 --- a/packages/force-ssl/package.js +++ b/packages/force-ssl/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Require this application to use HTTPS", - version: "1.0.14-rc.5", + version: "1.0.14-rc.6", prodOnly: true }); diff --git a/packages/google-oauth/package.js b/packages/google-oauth/package.js index 8193e069b2..1e36bee903 100644 --- a/packages/google-oauth/package.js +++ b/packages/google-oauth/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Google OAuth flow", - version: "1.2.1" + version: "1.2.1-rc.6" }); Cordova.depends({ diff --git a/packages/meteor-tool/package.js b/packages/meteor-tool/package.js index 8559002ee6..657c1ea21b 100644 --- a/packages/meteor-tool/package.js +++ b/packages/meteor-tool/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "The Meteor command-line tool", - version: '1.4.4-rc.5' + version: '1.4.4-rc.6' }); Package.includeTool(); diff --git a/packages/minifier-js/package.js b/packages/minifier-js/package.js index 4cdbd87e2f..ce35819fab 100644 --- a/packages/minifier-js/package.js +++ b/packages/minifier-js/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "JavaScript minifier", - version: "2.0.0-rc.5" + version: "2.0.0-rc.6" }); Npm.depends({ diff --git a/packages/modules-runtime/package.js b/packages/modules-runtime/package.js index e711b80417..2e306441ed 100644 --- a/packages/modules-runtime/package.js +++ b/packages/modules-runtime/package.js @@ -1,6 +1,6 @@ Package.describe({ name: "modules-runtime", - version: "0.7.10-rc.5", + version: "0.7.10-rc.6", summary: "CommonJS module system", git: "https://github.com/benjamn/install", documentation: "README.md" diff --git a/packages/modules/package.js b/packages/modules/package.js index 1ac52e4b7c..8efe28d7b7 100644 --- a/packages/modules/package.js +++ b/packages/modules/package.js @@ -1,6 +1,6 @@ Package.describe({ name: "modules", - version: "0.8.1-rc.5", + version: "0.8.1-rc.6", summary: "CommonJS module system", documentation: "README.md" }); diff --git a/packages/rate-limit/package.js b/packages/rate-limit/package.js index ff938de70a..728b2c45cc 100644 --- a/packages/rate-limit/package.js +++ b/packages/rate-limit/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'rate-limit', - version: '1.0.8-rc.5', + version: '1.0.8-rc.6', // Brief, one-line summary of the package. summary: 'An algorithm for rate limiting anything', // URL to the Git repository containing the source code for this package. diff --git a/packages/standard-minifier-js/package.js b/packages/standard-minifier-js/package.js index e1cbadedbe..59e1085e75 100644 --- a/packages/standard-minifier-js/package.js +++ b/packages/standard-minifier-js/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'standard-minifier-js', - version: '2.0.0-rc.5', + version: '2.0.0-rc.6', summary: 'Standard javascript minifiers used with Meteor apps by default.', documentation: 'README.md', }); diff --git a/packages/standard-minifiers/package.js b/packages/standard-minifiers/package.js index a87eae6bd7..2b00a181b5 100644 --- a/packages/standard-minifiers/package.js +++ b/packages/standard-minifiers/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'standard-minifiers', - version: '1.1.0-rc.5', + version: '1.1.0-rc.6', summary: 'Standard minifiers used with Meteor apps by default.', documentation: 'README.md' }); diff --git a/packages/webapp/package.js b/packages/webapp/package.js index f0aa0db24d..2e6095148d 100644 --- a/packages/webapp/package.js +++ b/packages/webapp/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Serves a Meteor app over HTTP", - version: '1.3.15-rc.5' + version: '1.3.15-rc.6' }); Npm.depends({connect: "2.30.2", diff --git a/scripts/admin/meteor-release-experimental.json b/scripts/admin/meteor-release-experimental.json index 7b4586663a..d15ae376cd 100644 --- a/scripts/admin/meteor-release-experimental.json +++ b/scripts/admin/meteor-release-experimental.json @@ -1,6 +1,6 @@ { "track": "METEOR", - "version": "1.4.4-rc.5", + "version": "1.4.4-rc.6", "recommended": false, "official": false, "description": "Meteor" From a376c909cfb48a9628f052fc78a3295452f09262 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Tue, 4 Apr 2017 13:01:02 +0300 Subject: [PATCH 29/60] Update Node.js to v4.8.1. Notable changes: https://nodejs.org/en/blog/release/v4.8.1/ --- scripts/build-dev-bundle-common.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build-dev-bundle-common.sh b/scripts/build-dev-bundle-common.sh index 5f0746786e..627e3c463c 100644 --- a/scripts/build-dev-bundle-common.sh +++ b/scripts/build-dev-bundle-common.sh @@ -6,7 +6,7 @@ set -u UNAME=$(uname) ARCH=$(uname -m) MONGO_VERSION=3.2.12 -NODE_VERSION=4.8.0 +NODE_VERSION=4.8.1 NPM_VERSION=4.3.0 if [ "$UNAME" == "Linux" ] ; then From 8bdd0142cd297dca755dea3933363bc978d22808 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Tue, 4 Apr 2017 12:39:03 +0300 Subject: [PATCH 30/60] Disable display of update msg about `npm` itself, since it's bundled. As of npm 4.4.0 this is necessary as it will now self-check once per day for updates. Meteor pre-bundles the version of npm though so this message will be confusing to users of the `meteor` tool. https://github.com/npm/npm/releases/tag/v4.4.0 --- tools/cli/dev-bundle-bin-helpers.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/cli/dev-bundle-bin-helpers.js b/tools/cli/dev-bundle-bin-helpers.js index 3f90762bdf..5a5bef6c3d 100644 --- a/tools/cli/dev-bundle-bin-helpers.js +++ b/tools/cli/dev-bundle-bin-helpers.js @@ -77,6 +77,9 @@ exports.getEnv = function (options) { var env = Object.create(process.env); + // Make sure notifications to update npm aren't presented to the user. + env.NPM_CONFIG_NO_UPDATE_NOTIFIER = true; + // Make sure `meteor npm install --global ...` installs into // dev_bundle/lib/node_modules by default. if (! env.NPM_CONFIG_PREFIX) { From 7915afbbc1abb28812b4c162b1ced8890f9fb3ea Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Tue, 4 Apr 2017 19:39:25 +0300 Subject: [PATCH 31/60] Update `npm` package to v4.4.4. Notable changes: https://github.com/npm/npm/releases/tag/v4.4.4 --- scripts/build-dev-bundle-common.sh | 2 +- scripts/dev-bundle-tool-package.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/build-dev-bundle-common.sh b/scripts/build-dev-bundle-common.sh index 627e3c463c..d0c9b1fdd5 100644 --- a/scripts/build-dev-bundle-common.sh +++ b/scripts/build-dev-bundle-common.sh @@ -7,7 +7,7 @@ UNAME=$(uname) ARCH=$(uname -m) MONGO_VERSION=3.2.12 NODE_VERSION=4.8.1 -NPM_VERSION=4.3.0 +NPM_VERSION=4.4.4 if [ "$UNAME" == "Linux" ] ; then if [ "$ARCH" != "i686" -a "$ARCH" != "x86_64" ] ; then diff --git a/scripts/dev-bundle-tool-package.js b/scripts/dev-bundle-tool-package.js index 19b74b7f69..0f7a15fb74 100644 --- a/scripts/dev-bundle-tool-package.js +++ b/scripts/dev-bundle-tool-package.js @@ -11,7 +11,7 @@ var packageJson = { dependencies: { // Explicit dependency because we are replacing it with a bundled version // and we want to make sure there are no dependencies on a higher version - npm: "4.3.0", + npm: "4.4.4", "node-gyp": "3.5.0", "node-pre-gyp": "0.6.33", "meteor-babel": "0.19.1", From cba8c633402432f88abf6a6b47b03695097a8e2f Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Tue, 4 Apr 2017 19:40:02 +0300 Subject: [PATCH 32/60] Update `node-gyp` and `node-pre-gyp` packages. * `node-gyp` - Adds support for Visual Studio 2017. - https://github.com/nodejs/node-gyp/blob/master/CHANGELOG.md#v360-2017-03-16 * `node-pre-gyp` - Nothing notable. - https://github.com/mapbox/node-pre-gyp/blob/master/CHANGELOG.md#0634 --- scripts/dev-bundle-tool-package.js | 4 ++-- tools/isobuild/bundler.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/dev-bundle-tool-package.js b/scripts/dev-bundle-tool-package.js index 0f7a15fb74..90ef636b87 100644 --- a/scripts/dev-bundle-tool-package.js +++ b/scripts/dev-bundle-tool-package.js @@ -12,8 +12,8 @@ var packageJson = { // Explicit dependency because we are replacing it with a bundled version // and we want to make sure there are no dependencies on a higher version npm: "4.4.4", - "node-gyp": "3.5.0", - "node-pre-gyp": "0.6.33", + "node-gyp": "3.6.0", + "node-pre-gyp": "0.6.34", "meteor-babel": "0.19.1", "meteor-promise": "0.8.0", fibers: "1.0.15", diff --git a/tools/isobuild/bundler.js b/tools/isobuild/bundler.js index 67c13e50cd..526b5e1eed 100644 --- a/tools/isobuild/bundler.js +++ b/tools/isobuild/bundler.js @@ -2244,8 +2244,8 @@ class ServerTarget extends JsImageTarget { serverPkgJson.scripts = serverPkgJson.scripts || {}; serverPkgJson.scripts.install = "node npm-rebuild.js"; - serverPkgJson.dependencies["node-gyp"] = "3.5.0"; - serverPkgJson.dependencies["node-pre-gyp"] = "0.6.33"; + serverPkgJson.dependencies["node-gyp"] = "3.6.0"; + serverPkgJson.dependencies["node-pre-gyp"] = "0.6.34"; builder.write('package.json', { data: new Buffer( From fc626eaf4ceaaab3ac7844ef8db1791abf5c84f5 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Tue, 4 Apr 2017 15:26:11 -0400 Subject: [PATCH 33/60] Use fork of cordova-plugin-googleplus to ease iOS keychain sharing. https://github.com/meteor/meteor/issues/8253 https://github.com/EddyVerbruggen/cordova-plugin-googleplus/pull/366 --- packages/google-oauth/package.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/google-oauth/package.js b/packages/google-oauth/package.js index 1e36bee903..715209e9e6 100644 --- a/packages/google-oauth/package.js +++ b/packages/google-oauth/package.js @@ -3,8 +3,14 @@ Package.describe({ version: "1.2.1-rc.6" }); +var cordovaPluginGooglePlusURL = + // This revision is from the "update-entitlements-plist-files" branch. + // This logic can be reverted when/if this PR is merged: + // https://github.com/EddyVerbruggen/cordova-plugin-googleplus/pull/366 + "https://github.com/meteor/cordova-plugin-googleplus.git#3095abe327e710ab04059ae9d3521bd4037c5a37"; + Cordova.depends({ - "cordova-plugin-googleplus": "5.1.1" + "cordova-plugin-googleplus": cordovaPluginGooglePlusURL }); Package.onUse(function(api) { From 76ea56ad4983a36b5bbdb8c0ad0877cf75934f2c Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Wed, 5 Apr 2017 09:56:16 +0300 Subject: [PATCH 34/60] Add `History.md` entries about core package updates. --- History.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/History.md b/History.md index 521e2fcbb0..253ffe3368 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,16 @@ ## v.NEXT +* Node has been upgraded to version 4.8.1. + +* The `npm` npm package has been upgraded to version 4.4.4. + It should be noted that this version reduces extra noise + previously included in some npm errors. + +* The `node-gyp` npm package has been upgraded to 3.6.0 which + adds support for VS2017 on Windows. + +* The `node-pre-gyp` npm package has been updated to 0.6.36. + * Thanks to the outstanding efforts of @sethmurphy18, the `minifier-js` package now uses [Babili](https://github.com/babel/babili) instead of [UglifyJS](https://github.com/mishoo/UglifyJS2), resolving numerous From 74cb8ebdc2231e982d9bc9769b1ceba89a1317cf Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Wed, 5 Apr 2017 12:58:32 +0300 Subject: [PATCH 35/60] Improve `fs-extra`s `move` calls for Windows platform. (#8560) * Improve `fs-extra.move` calls for Windows platform. This is a follow-up to meteor/meteor#8491 which worked properly on Unix platforms, but failed in a variety of ways on Windows due to its lack of Fiber-awareness and desire to create symlinks as unprivileged users (something not always possible on Windows). The Fiber issue was observed when trying to remove "src" directories within the `move` function (which tries a variety of OS/OS/arch-specific techniques to accomplish its goal) after they had been copied to "dest". On Windows, this resulted in `EDIRNOTEMPTY` errors since Windows appears to temporarily cache the file-handle or doesn't release the file-handle until the next tick. The symlink issue will hopefully improve in an upcoming release of Windows (Creator Edition) when Microsoft makes it possible to create symlinks as an unprivileged user, however it will still require enabling "Developer" mode in Windows settings. This implements the same catch which was already in place for `fs.rename` on the `fs.move` provided by `fs-extra`. Performance gains were the same in tests comparing before and after these changes. Relates to: https://github.com/meteor/meteor/issues/8558#issuecomment-291194385 * A few code-cleanups to my original commit. --- scripts/dev-bundle-tool-package.js | 2 +- tools/fs/files.js | 76 +++++++++++++++++++----------- 2 files changed, 50 insertions(+), 28 deletions(-) diff --git a/scripts/dev-bundle-tool-package.js b/scripts/dev-bundle-tool-package.js index 90ef636b87..87f10c8d30 100644 --- a/scripts/dev-bundle-tool-package.js +++ b/scripts/dev-bundle-tool-package.js @@ -18,7 +18,7 @@ var packageJson = { "meteor-promise": "0.8.0", fibers: "1.0.15", promise: "7.1.1", - "fs-extra": "2.1.0", + "fs-extra": "2.1.2", // So that Babel 6 can emit require("babel-runtime/helpers/...") calls. "babel-runtime": "6.9.2", // For various ES2015 polyfills, such as Map and Set. diff --git a/tools/fs/files.js b/tools/fs/files.js index e77e504cbe..69ed764ce1 100644 --- a/tools/fs/files.js +++ b/tools/fs/files.js @@ -278,18 +278,16 @@ function statOrNull(path, preserveSymlinks) { } } -// Like rm -r. -files.rm_recursive = Profile("files.rm_recursive", function (p) { - const path = files.convertToOSPath(p); +function callAndTolerateBusyFilesystem(syncFsFunc, asyncFsFunc, ...args) { try { - rimraf.sync(path); + syncFsFunc.apply(this, args); } catch (e) { if (e.code === "ENOTEMPTY" && Fiber.current && Fiber.yield && ! Fiber.yield.disallowed) { new Promise((resolve, reject) => { - rimraf(path, err => { + asyncFsFunc.call(this, ...args, err => { err ? reject(err) : resolve(); }); }).await(); @@ -297,6 +295,38 @@ files.rm_recursive = Profile("files.rm_recursive", function (p) { } throw e; } +} + +function callWithRetries(fsFunc, tolerableFsErrorCodes=[], ...args) { + // retries are probably only necessary only on Windows, since some fs calls + // can fail with EBUSY (or similar), which means the file is "busy" (for now). + let maxTries = 10; + let success = false; + while (! success && maxTries-- > 0) { + try { + fsFunc.apply(this, args); + success = true; + } catch (err) { + if (! tolerableFsErrorCodes.includes(err.code)) { + throw err; + } + } + } + return success; +} + +// The move and moveSync functions from fs-extra, while great at many things +// aren't capable of resolving busy filesystem issues (such as those encountered +// on Windows) since it's not Fiber-aware. +files.moveWithFsTolerance = Profile("files.moveWithFsTolerance", function (f, t) { + return callAndTolerateBusyFilesystem(fs.moveSync, fs.move, + files.convertToOSPath(f), files.convertToOSPath(t)); +}); + +// Like rm -r. +files.rm_recursive = Profile("files.rm_recursive", function (p) { + return callAndTolerateBusyFilesystem(rimraf.sync, rimraf, + files.convertToOSPath(p)); }); // Makes all files in a tree read-only. @@ -983,7 +1013,7 @@ files.renameDirAlmostAtomically = function (fromDir, toDir) { // Get old dir out of the way, if it exists. var movedOldDir = true; try { - files.move(toDir, garbageDir); + files.moveWithFsTolerance(toDir, garbageDir); } catch (e) { if (e.code !== 'ENOENT') { throw e; @@ -992,7 +1022,7 @@ files.renameDirAlmostAtomically = function (fromDir, toDir) { } // Now rename the directory. - files.move(fromDir, toDir); + files.moveWithFsTolerance(fromDir, toDir); // ... and delete the old one. if (movedOldDir) { @@ -1684,28 +1714,20 @@ files.existsSync = function (path, callback) { }; if (files.isWindowsLikeFilesystem()) { - var rename = files.rename; + const tolerableFsErrorCodes = ['EPERM', 'EACCES']; - files.rename = function (from, to) { - // retries are necessarily only on Windows, because the rename call can fail - // with EBUSY, which means the file is "busy" - var maxTries = 10; - var success = false; - while (! success && maxTries-- > 0) { - try { - rename(from, to); - success = true; - } catch (err) { - if (err.code !== 'EPERM' && err.code !== 'EACCES') { - throw err; - } + function makeRenamesqueFunction(name) { + const original = files[name]; + files[name] = function (from, to) { + if (! callWithRetries(original, tolerableFsErrorCodes, from, to)) { + files.cp_r(from, to); + files.rm_recursive(from); } - } - if (! success) { - files.cp_r(from, to); - files.rm_recursive(from); - } - }; + }; + } + + makeRenamesqueFunction("rename"); + makeRenamesqueFunction("move"); } // Warning: doesn't convert slashes in the second 'cache' arg From eb578e864bbdbf6ccfede4f96cc4f3eb7c8321e7 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Wed, 5 Apr 2017 12:59:57 +0300 Subject: [PATCH 36/60] Bump $BUNDLE_VERSION to 4.7.22 before rebuilding dev bundle. --- meteor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meteor b/meteor index ba342e221e..4e187d594c 100755 --- a/meteor +++ b/meteor @@ -1,6 +1,6 @@ #!/usr/bin/env bash -BUNDLE_VERSION=4.7.20 +BUNDLE_VERSION=4.7.22 # OS Check. Put here because here is where we download the precompiled # bundles that are arch specific. From e9f723881968211b782abba103b2afcf614f9003 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Wed, 5 Apr 2017 14:24:49 +0300 Subject: [PATCH 37/60] Updates to `History.md` for 1.4.4. * Remove: Duplicate `reify` mention. * Add: `fs-extra` updates. * Add: `Accounts.config` now supports `ambiguousErrorMessages`. * Add: `mailcomposer` & `smtp-connection` npm updates. * Add: Bugfix for enrollment tokens. * Change: Windows note about Node.js version mismatch. --- History.md | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/History.md b/History.md index 253ffe3368..6fb7b5a5e8 100644 --- a/History.md +++ b/History.md @@ -23,8 +23,6 @@ introduced by Meteor 1.4.3 (see below), including [issue #8461](https://github.com/meteor/meteor/issues/8461). -* The `reify` npm package has been upgraded to version 0.6.6. - * The Reify module compiler is now a Babel plugin, making it possible for other custom Babel plugins configured in `.babelrc` or `package.json` files to run before Reify, fixing bugs that resulted from running Reify @@ -42,6 +40,12 @@ * https://github.com/leebyron/ecmascript-export-ns-from * https://github.com/leebyron/ecmascript-export-default-from +* The `fs-extra` npm is now used for certain file-system operations in order to + accommodate environments where some tasks (like sym-links) aren't possible. + [Issue #7852](https://github.com/meteor/meteor/issues/7852) + [PR #8491](https://github.com/meteor/meteor/pull/8491) + [PR #8560](https://github.com/meteor/meteor/pull/8560) + * When `Meteor.call` is used on the server to invoke a method that returns a `Promise` object, the result will no longer be the `Promise` object, but the resolved value of the `Promise`. @@ -53,14 +57,27 @@ [Issue #8367](https://github.com/meteor/meteor/issues/8367), https://github.com/meteor/meteor/commit/0cbd25111d1249a61ca7adce23fad5215408c821 +* The `mailcomposer` and `smtp-connection` npms have been updated to resolve an + issue with the encoding of long header lines. + [Issue #8425](https://github.com/meteor/meteor/issues/8425) + [PR #8495](https://github.com/meteor/meteor/pull/8495) + +* `Accounts.config` now supports an `ambiguousErrorMessages` option which + enabled generalization of messages produced by the `accounts-*` packages. + [PR #8520](https://github.com/meteor/meteor/pull/8520) + +* A bug which caused account enrollment tokens to be deleted too soon was fixed. + [Issue #8218](https://github.com/meteor/meteor/issues/8218) + [PR #8474](https://github.com/meteor/meteor/pull/8474) + * On Windows, bundles built during `meteor build` or `meteor deploy` will maintain the executable bit for commands installed in the `node_modules\.bin` directory. [PR #8503](https://github.com/meteor/meteor/pull/8503) -* On Windows, the upgrades to Node, `npm` and `mongodb` mentioned in the 1.4.3.2 - release are now included after being mistakenly overlooked. An admin script - enhancement has been applied this from happening again. +* On Windows, the upgrades to Node.js, `npm` and `mongodb` are now in-sync with + other archs again after being mistakenly overlooked in 1.4.3.2. An admin + script enhancement has been applied to prevent this from happening again. [PR #8505](https://github.com/meteor/meteor/pull/8505) ## v1.4.3.2, 2017-03-14 From eb827b2515064d9a404324db79b603a001f50e6b Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Wed, 5 Apr 2017 14:43:22 +0300 Subject: [PATCH 38/60] Bump package versions for 1.4.4-rc.7 release. --- packages/accounts-base/package.js | 2 +- packages/accounts-google/package.js | 2 +- packages/accounts-password/package.js | 2 +- packages/babel-compiler/package.js | 2 +- packages/ddp-client/package.js | 2 +- packages/ddp-server/package.js | 2 +- packages/ecmascript/package.js | 2 +- packages/email/package.js | 2 +- packages/force-ssl-common/package.js | 2 +- packages/force-ssl/package.js | 2 +- packages/google-oauth/package.js | 2 +- packages/meteor-tool/package.js | 2 +- packages/minifier-js/package.js | 2 +- packages/modules-runtime/package.js | 2 +- packages/modules/package.js | 2 +- packages/rate-limit/package.js | 2 +- packages/standard-minifier-js/package.js | 2 +- packages/standard-minifiers/package.js | 2 +- packages/webapp/package.js | 2 +- scripts/admin/meteor-release-experimental.json | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/packages/accounts-base/package.js b/packages/accounts-base/package.js index d6557e088f..cbb8da049a 100644 --- a/packages/accounts-base/package.js +++ b/packages/accounts-base/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "A user account system", - version: "1.2.16-rc.6" + version: "1.2.16-rc.7" }); Package.onUse(function (api) { diff --git a/packages/accounts-google/package.js b/packages/accounts-google/package.js index 590ab6de53..968ae903da 100644 --- a/packages/accounts-google/package.js +++ b/packages/accounts-google/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Login service for Google accounts", - version: "1.1.2-rc.6" + version: "1.1.2-rc.7" }); Package.onUse(function(api) { diff --git a/packages/accounts-password/package.js b/packages/accounts-password/package.js index 81489fa982..6d6fd1ec6d 100644 --- a/packages/accounts-password/package.js +++ b/packages/accounts-password/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Password support for accounts", - version: "1.3.5-rc.6" + version: "1.3.5-rc.7" }); Package.onUse(function(api) { diff --git a/packages/babel-compiler/package.js b/packages/babel-compiler/package.js index 56f818406c..a074258ffb 100644 --- a/packages/babel-compiler/package.js +++ b/packages/babel-compiler/package.js @@ -6,7 +6,7 @@ Package.describe({ // isn't possible because you can't publish a non-recommended // release with package versions that don't have a pre-release // identifier at the end (eg, -dev) - version: '6.18.0-rc.6' + version: '6.18.0-rc.7' }); Npm.depends({ diff --git a/packages/ddp-client/package.js b/packages/ddp-client/package.js index 796da6604c..7ebd18999f 100644 --- a/packages/ddp-client/package.js +++ b/packages/ddp-client/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Meteor's latency-compensated distributed data client", - version: '1.3.4-rc.6', + version: '1.3.4-rc.7', documentation: null }); diff --git a/packages/ddp-server/package.js b/packages/ddp-server/package.js index a3d7dccc24..8195999f4d 100644 --- a/packages/ddp-server/package.js +++ b/packages/ddp-server/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Meteor's latency-compensated distributed data server", - version: '1.3.14-rc.6', + version: '1.3.14-rc.7', documentation: null }); diff --git a/packages/ecmascript/package.js b/packages/ecmascript/package.js index 7d47878923..ea725a3b86 100644 --- a/packages/ecmascript/package.js +++ b/packages/ecmascript/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'ecmascript', - version: '0.7.1-rc.6', + version: '0.7.1-rc.7', summary: 'Compiler plugin that supports ES2015+ in all .js files', documentation: 'README.md' }); diff --git a/packages/email/package.js b/packages/email/package.js index 24244afa6a..523021e041 100644 --- a/packages/email/package.js +++ b/packages/email/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Send email messages", - version: "1.2.0-rc.6" + version: "1.2.0-rc.7" }); Npm.depends({ diff --git a/packages/force-ssl-common/package.js b/packages/force-ssl-common/package.js index e06ced7f8d..bd25f2c065 100644 --- a/packages/force-ssl-common/package.js +++ b/packages/force-ssl-common/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: 'Internal force-ssl common code.', - version: '1.0.14-rc.6' + version: '1.0.14-rc.7' }); Npm.depends({ diff --git a/packages/force-ssl/package.js b/packages/force-ssl/package.js index d90092c493..13aa8f2084 100644 --- a/packages/force-ssl/package.js +++ b/packages/force-ssl/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Require this application to use HTTPS", - version: "1.0.14-rc.6", + version: "1.0.14-rc.7", prodOnly: true }); diff --git a/packages/google-oauth/package.js b/packages/google-oauth/package.js index 715209e9e6..c1cf515ba2 100644 --- a/packages/google-oauth/package.js +++ b/packages/google-oauth/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Google OAuth flow", - version: "1.2.1-rc.6" + version: "1.2.1-rc.7" }); var cordovaPluginGooglePlusURL = diff --git a/packages/meteor-tool/package.js b/packages/meteor-tool/package.js index 657c1ea21b..c5f3843e0f 100644 --- a/packages/meteor-tool/package.js +++ b/packages/meteor-tool/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "The Meteor command-line tool", - version: '1.4.4-rc.6' + version: '1.4.4-rc.7' }); Package.includeTool(); diff --git a/packages/minifier-js/package.js b/packages/minifier-js/package.js index ce35819fab..40e72afa66 100644 --- a/packages/minifier-js/package.js +++ b/packages/minifier-js/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "JavaScript minifier", - version: "2.0.0-rc.6" + version: "2.0.0-rc.7" }); Npm.depends({ diff --git a/packages/modules-runtime/package.js b/packages/modules-runtime/package.js index 2e306441ed..7cce8e878f 100644 --- a/packages/modules-runtime/package.js +++ b/packages/modules-runtime/package.js @@ -1,6 +1,6 @@ Package.describe({ name: "modules-runtime", - version: "0.7.10-rc.6", + version: "0.7.10-rc.7", summary: "CommonJS module system", git: "https://github.com/benjamn/install", documentation: "README.md" diff --git a/packages/modules/package.js b/packages/modules/package.js index 8efe28d7b7..50ef923b5b 100644 --- a/packages/modules/package.js +++ b/packages/modules/package.js @@ -1,6 +1,6 @@ Package.describe({ name: "modules", - version: "0.8.1-rc.6", + version: "0.8.1-rc.7", summary: "CommonJS module system", documentation: "README.md" }); diff --git a/packages/rate-limit/package.js b/packages/rate-limit/package.js index 728b2c45cc..7db423c7fd 100644 --- a/packages/rate-limit/package.js +++ b/packages/rate-limit/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'rate-limit', - version: '1.0.8-rc.6', + version: '1.0.8-rc.7', // Brief, one-line summary of the package. summary: 'An algorithm for rate limiting anything', // URL to the Git repository containing the source code for this package. diff --git a/packages/standard-minifier-js/package.js b/packages/standard-minifier-js/package.js index 59e1085e75..02353b2ad3 100644 --- a/packages/standard-minifier-js/package.js +++ b/packages/standard-minifier-js/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'standard-minifier-js', - version: '2.0.0-rc.6', + version: '2.0.0-rc.7', summary: 'Standard javascript minifiers used with Meteor apps by default.', documentation: 'README.md', }); diff --git a/packages/standard-minifiers/package.js b/packages/standard-minifiers/package.js index 2b00a181b5..bad7620009 100644 --- a/packages/standard-minifiers/package.js +++ b/packages/standard-minifiers/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'standard-minifiers', - version: '1.1.0-rc.6', + version: '1.1.0-rc.7', summary: 'Standard minifiers used with Meteor apps by default.', documentation: 'README.md' }); diff --git a/packages/webapp/package.js b/packages/webapp/package.js index 2e6095148d..0adf2255fe 100644 --- a/packages/webapp/package.js +++ b/packages/webapp/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Serves a Meteor app over HTTP", - version: '1.3.15-rc.6' + version: '1.3.15-rc.7' }); Npm.depends({connect: "2.30.2", diff --git a/scripts/admin/meteor-release-experimental.json b/scripts/admin/meteor-release-experimental.json index d15ae376cd..51b4cae38d 100644 --- a/scripts/admin/meteor-release-experimental.json +++ b/scripts/admin/meteor-release-experimental.json @@ -1,6 +1,6 @@ { "track": "METEOR", - "version": "1.4.4-rc.6", + "version": "1.4.4-rc.7", "recommended": false, "official": false, "description": "Meteor" From 27819a164b1973f99ac48a9512e0136feefd5b19 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Wed, 5 Apr 2017 18:46:29 +0300 Subject: [PATCH 39/60] Update `installNpmModule` to properly capture newer `npm` error formats. (#8564) Previously, we captured and displayed shorter error messages for the more complicated and unnecessarily verbose messages which npm produced. While updating npm to 4.4.4, I observed the changelog for 4.4.0 indicated it would now produce less verbose messages. In searching for possible Meteor conflicts with this, I discovered that `installNpmModule` had already regressed on providing pretty messages. This fixes those messages to be parsed properly and adds tests which ensure if npm changes again that we can capture them. Follows-up on: https://github.com/meteor/meteor/pull/8562 --- tools/isobuild/meteor-npm.js | 40 +++++++++++++---------------- tools/tests/npm.js | 50 +++++++++++++++++++++++++++++------- 2 files changed, 59 insertions(+), 31 deletions(-) diff --git a/tools/isobuild/meteor-npm.js b/tools/isobuild/meteor-npm.js index 7c7da429d0..2b47f44bcb 100644 --- a/tools/isobuild/meteor-npm.js +++ b/tools/isobuild/meteor-npm.js @@ -948,38 +948,34 @@ var getShrinkwrappedDependencies = function (dir) { return treeToDependencies(getShrinkwrappedDependenciesTree(dir)); }; -var installNpmModule = function (name, version, dir) { +const installNpmModule = meteorNpm.installNpmModule = (name, version, dir) => { - var installArg = utils.isNpmUrl(version) - ? version : (name + "@" + version); + const installArg = utils.isNpmUrl(version) + ? version + : `${name}@${version}`; // We don't use npm.commands.install since we couldn't figure out // how to silence all output (specifically the installed tree which // is printed out with `console.log`) - // - // We used to use --force here, because the NPM cache is broken! See - // https://github.com/npm/npm/issues/3265 Basically, switching - // back and forth between a tarball fork of version X and the real - // version X could confuse NPM. But the main reason to use tarball - // URLs is to get a fork of the latest version with some fix, so - // it was easy to trigger this! - // - // We now use a forked version of npm with our PR - // https://github.com/npm/npm/pull/5137 to work around this. - var result = runNpmCommand(["install", installArg], dir); + const result = runNpmCommand(["install", installArg], dir); if (! result.success) { - var pkgNotFound = "404 '" + utils.quotemeta(name) + - "' is not in the npm registry"; - var versionNotFound = "version not found: " + utils.quotemeta(name) + - '@' + utils.quotemeta(version); + const pkgNotFound = + `404 '${utils.quotemeta(name)}' is not in the npm registry`; + + const versionNotFound = + "No compatible version found: " + + `${utils.quotemeta(name)}@${utils.quotemeta(version)}`; + if (result.stderr.match(new RegExp(pkgNotFound))) { - buildmessage.error("there is no npm package named '" + name + "'"); + buildmessage.error( + `there is no npm package named '${name}' in the npm registry`); } else if (result.stderr.match(new RegExp(versionNotFound))) { - buildmessage.error(name + " version " + version + " " + - "is not available in the npm registry"); + buildmessage.error( + `${name} version ${version} is not available in the npm registry`); } else { - buildmessage.error(`couldn't install npm package ${name}@${version}: ${result.error}`); + buildmessage.error( + `couldn't install npm package ${name}@${version}: ${result.error}`); } // Recover by returning false from updateDependencies diff --git a/tools/tests/npm.js b/tools/tests/npm.js index 3a633b3248..d6198e784d 100644 --- a/tools/tests/npm.js +++ b/tools/tests/npm.js @@ -1,13 +1,15 @@ -var selftest = require('../tool-testing/selftest.js'); -var Sandbox = selftest.Sandbox; -var _ = require('underscore'); +import selftest from '../tool-testing/selftest.js'; +import files from '../fs/files.js'; +import { installNpmModule } from '../isobuild/meteor-npm.js'; -var MONGO_LISTENING = +const Sandbox = selftest.Sandbox; + +const MONGO_LISTENING = { stdout: " [initandlisten] waiting for connections on port" }; -selftest.define("npm", ["net"], function () { - var s = new Sandbox({ fakeMongo: true }); - var run; +selftest.define("npm", ["net"], () => { + const s = new Sandbox({ fakeMongo: true }); + let run; s.createApp("npmtestapp", "npmtest", { dontPrepareApp: true }); s.cd("npmtestapp"); @@ -16,10 +18,10 @@ selftest.define("npm", ["net"], function () { // Regression test for https://github.com/meteor/meteor/pull/1808 // Before this fix, the module would work on the first execution but not on a // subsequent one. - _.times(2, function (i) { + [1, 2].forEach(i => { run = s.run("--once", "--raw-logs"); run.tellMongo(MONGO_LISTENING); - if (i === 0) { + if (i === 1) { run.waitSecs(30); // use match instead of read because on a built release we can // also get an update message here. @@ -31,3 +33,33 @@ selftest.define("npm", ["net"], function () { run.expectExit(0); }); }); + +function testThatNpmInstallThrows(name, version, regexMatcher) { + const tmpDir = files.convertToOSPath(files.mkdtemp()); + let didThrow = false; + try { + installNpmModule(name, version, tmpDir); + } catch (err) { + didThrow = true; + selftest.expectTrue(regexMatcher.test(err.message)); + } + selftest.expectTrue(didThrow); +} + +selftest.define("npm - install - messages - error installing package", ["net"], () => { + // the 'error-prone' npm intentionally errors in the preinstall script. + testThatNpmInstallThrows("error-prone", "1.0.0", + /couldn't install npm package error-prone@1.0.0/); +}); + +selftest.define("npm - install - messages - npm doesn't exist", ["net"], () => { + // this test is obviously prone to sabotage. + testThatNpmInstallThrows("non-existant-package-gggg", "100.0.0", + /no npm package named 'non-existant-package-gggg' in the npm registry/); +}); + +selftest.define("npm - install - messages - npm version doesn't exist", ["net"], () => { + // the 'cost-of-modules' npm really exists but hopefully never this minor ver. + testThatNpmInstallThrows("cost-of-modules", "0.999.2", + /cost-of-modules version 0.999.2 is not available in the npm registry/); +}); From 5bbdcc9baa5a5be45c0f819ead0a9741c1730e11 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Wed, 5 Apr 2017 16:57:34 +0300 Subject: [PATCH 40/60] Change order that functions are defined so `move` is wrapped correctly. --- tools/fs/files.js | 125 ++++++++++++++++++++++++---------------------- 1 file changed, 64 insertions(+), 61 deletions(-) diff --git a/tools/fs/files.js b/tools/fs/files.js index 69ed764ce1..7bb3dc1fc7 100644 --- a/tools/fs/files.js +++ b/tools/fs/files.js @@ -315,20 +315,6 @@ function callWithRetries(fsFunc, tolerableFsErrorCodes=[], ...args) { return success; } -// The move and moveSync functions from fs-extra, while great at many things -// aren't capable of resolving busy filesystem issues (such as those encountered -// on Windows) since it's not Fiber-aware. -files.moveWithFsTolerance = Profile("files.moveWithFsTolerance", function (f, t) { - return callAndTolerateBusyFilesystem(fs.moveSync, fs.move, - files.convertToOSPath(f), files.convertToOSPath(t)); -}); - -// Like rm -r. -files.rm_recursive = Profile("files.rm_recursive", function (p) { - return callAndTolerateBusyFilesystem(rimraf.sync, rimraf, - files.convertToOSPath(p)); -}); - // Makes all files in a tree read-only. var makeTreeReadOnly = function (p) { try { @@ -1000,53 +986,6 @@ files.createTarball = function (dirPath, tarball, options) { }).await(); }; -// Use this if you'd like to replace a directory with another -// directory as close to atomically as possible. It's better than -// recursively deleting the target directory first and then -// renaming. (Failure modes here include "there's a brief moment where -// toDir does not exist" and "you can end up with garbage directories -// sitting around", but not "there's any time where toDir exists but -// is in a state other than initial or final".) -files.renameDirAlmostAtomically = function (fromDir, toDir) { - var garbageDir = toDir + '-garbage-' + utils.randomToken(); - - // Get old dir out of the way, if it exists. - var movedOldDir = true; - try { - files.moveWithFsTolerance(toDir, garbageDir); - } catch (e) { - if (e.code !== 'ENOENT') { - throw e; - } - movedOldDir = false; - } - - // Now rename the directory. - files.moveWithFsTolerance(fromDir, toDir); - - // ... and delete the old one. - if (movedOldDir) { - files.rm_recursive(garbageDir); - } -}; -files.renameDirAlmostAtomically = Profile("files.renameDirAlmostAtomically", - files.renameDirAlmostAtomically); - -files.writeFileAtomically = function (filename, contents) { - const parentDir = files.pathDirname(filename); - files.mkdir_p(parentDir); - - const tmpFile = files.pathJoin( - parentDir, - '.' + files.pathBasename(filename) + '.' + utils.randomToken() - ); - - files.writeFile(tmpFile, contents); - files.rename(tmpFile, filename); -}; -files.writeFileAtomically = Profile("files.writeFileAtomically", - files.writeFileAtomically); - // Like fs.symlinkSync, but creates a temporay link and renames it over the // file; this means it works even if the file already exists. // Do not use this function on Windows, it won't work. @@ -1642,6 +1581,8 @@ wrapFsFunc("lstat", [0]); wrapFsFunc("rename", [0, 1]); wrapFsFunc("move", [0, 1]); + + // After the outermost files.withCache call returns, the withCacheCache is // reset to null so that it does not survive server restarts. let withCacheCache = null; @@ -1730,6 +1671,20 @@ if (files.isWindowsLikeFilesystem()) { makeRenamesqueFunction("move"); } +// The move and moveSync functions from fs-extra, while great at many things +// aren't capable of resolving busy filesystem issues (such as those encountered +// on Windows) since it's not Fiber-aware. +files.moveWithFsTolerance = Profile("files.moveWithFsTolerance", function (f, t) { + return callAndTolerateBusyFilesystem(fs.moveSync, fs.move, + files.convertToOSPath(f), files.convertToOSPath(t)); +}); + +// Like rm -r. +files.rm_recursive = Profile("files.rm_recursive", function (p) { + return callAndTolerateBusyFilesystem(rimraf.sync, rimraf, + files.convertToOSPath(p)); +}); + // Warning: doesn't convert slashes in the second 'cache' arg wrapFsFunc("realpath", [0], { modifyReturnValue: files.convertToStandardPath @@ -1754,6 +1709,54 @@ wrapFsFunc("close", []); wrapFsFunc("symlink", [0, 1]); wrapFsFunc("readlink", [0]); +// Use this if you'd like to replace a directory with another +// directory as close to atomically as possible. It's better than +// recursively deleting the target directory first and then +// renaming. (Failure modes here include "there's a brief moment where +// toDir does not exist" and "you can end up with garbage directories +// sitting around", but not "there's any time where toDir exists but +// is in a state other than initial or final".) +files.renameDirAlmostAtomically = function (fromDir, toDir) { + var garbageDir = toDir + '-garbage-' + utils.randomToken(); + + // Get old dir out of the way, if it exists. + var movedOldDir = true; + try { + files.moveWithFsTolerance(toDir, garbageDir); + } catch (e) { + if (e.code !== 'ENOENT') { + throw e; + } + movedOldDir = false; + } + + // Now rename the directory. + files.moveWithFsTolerance(fromDir, toDir); + + // ... and delete the old one. + if (movedOldDir) { + files.rm_recursive(garbageDir); + } +}; +files.renameDirAlmostAtomically = Profile("files.renameDirAlmostAtomically", + files.renameDirAlmostAtomically); + +files.writeFileAtomically = function (filename, contents) { + const parentDir = files.pathDirname(filename); + files.mkdir_p(parentDir); + + const tmpFile = files.pathJoin( + parentDir, + '.' + files.pathBasename(filename) + '.' + utils.randomToken() + ); + + files.writeFile(tmpFile, contents); + files.rename(tmpFile, filename); +}; +files.writeFileAtomically = Profile("files.writeFileAtomically", + files.writeFileAtomically); + + // These don't need to be Fiberized files.createReadStream = function (...args) { args[0] = files.convertToOSPath(args[0]); From 6a0767bbacd99d705ae53929d846e5a45c811a20 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Wed, 5 Apr 2017 19:04:22 +0300 Subject: [PATCH 41/60] Don't reassign, just `Profile` the `*Atomically` functions directly. --- tools/fs/files.js | 65 ++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 35 deletions(-) diff --git a/tools/fs/files.js b/tools/fs/files.js index 7bb3dc1fc7..f2986057d3 100644 --- a/tools/fs/files.js +++ b/tools/fs/files.js @@ -1581,8 +1581,6 @@ wrapFsFunc("lstat", [0]); wrapFsFunc("rename", [0, 1]); wrapFsFunc("move", [0, 1]); - - // After the outermost files.withCache call returns, the withCacheCache is // reset to null so that it does not survive server restarts. let withCacheCache = null; @@ -1716,46 +1714,43 @@ wrapFsFunc("readlink", [0]); // toDir does not exist" and "you can end up with garbage directories // sitting around", but not "there's any time where toDir exists but // is in a state other than initial or final".) -files.renameDirAlmostAtomically = function (fromDir, toDir) { - var garbageDir = toDir + '-garbage-' + utils.randomToken(); +files.renameDirAlmostAtomically = + Profile("files.renameDirAlmostAtomically", function (fromDir, toDir) { + var garbageDir = toDir + '-garbage-' + utils.randomToken(); - // Get old dir out of the way, if it exists. - var movedOldDir = true; - try { - files.moveWithFsTolerance(toDir, garbageDir); - } catch (e) { - if (e.code !== 'ENOENT') { - throw e; + // Get old dir out of the way, if it exists. + var movedOldDir = true; + try { + files.moveWithFsTolerance(toDir, garbageDir); + } catch (e) { + if (e.code !== 'ENOENT') { + throw e; + } + movedOldDir = false; } - movedOldDir = false; - } - // Now rename the directory. - files.moveWithFsTolerance(fromDir, toDir); + // Now rename the directory. + files.moveWithFsTolerance(fromDir, toDir); - // ... and delete the old one. - if (movedOldDir) { - files.rm_recursive(garbageDir); - } -}; -files.renameDirAlmostAtomically = Profile("files.renameDirAlmostAtomically", - files.renameDirAlmostAtomically); + // ... and delete the old one. + if (movedOldDir) { + files.rm_recursive(garbageDir); + } + }); -files.writeFileAtomically = function (filename, contents) { - const parentDir = files.pathDirname(filename); - files.mkdir_p(parentDir); +files.writeFileAtomically = + Profile("files.writeFileAtomically", function (filename, contents) { + const parentDir = files.pathDirname(filename); + files.mkdir_p(parentDir); - const tmpFile = files.pathJoin( - parentDir, - '.' + files.pathBasename(filename) + '.' + utils.randomToken() - ); - - files.writeFile(tmpFile, contents); - files.rename(tmpFile, filename); -}; -files.writeFileAtomically = Profile("files.writeFileAtomically", - files.writeFileAtomically); + const tmpFile = files.pathJoin( + parentDir, + '.' + files.pathBasename(filename) + '.' + utils.randomToken() + ); + files.writeFile(tmpFile, contents); + files.rename(tmpFile, filename); + }); // These don't need to be Fiberized files.createReadStream = function (...args) { From f62b25e3f076c455a37e20dd40b0a6693f2370f8 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Wed, 5 Apr 2017 20:09:52 +0300 Subject: [PATCH 42/60] Bump package versions for 1.4.4-rc.8 release. --- packages/accounts-base/package.js | 2 +- packages/accounts-google/package.js | 2 +- packages/accounts-password/package.js | 2 +- packages/babel-compiler/package.js | 2 +- packages/ddp-client/package.js | 2 +- packages/ddp-server/package.js | 2 +- packages/ecmascript/package.js | 2 +- packages/email/package.js | 2 +- packages/force-ssl-common/package.js | 2 +- packages/force-ssl/package.js | 2 +- packages/google-oauth/package.js | 2 +- packages/meteor-tool/package.js | 2 +- packages/minifier-js/package.js | 2 +- packages/modules-runtime/package.js | 2 +- packages/modules/package.js | 2 +- packages/rate-limit/package.js | 2 +- packages/standard-minifier-js/package.js | 2 +- packages/standard-minifiers/package.js | 2 +- packages/webapp/package.js | 2 +- scripts/admin/meteor-release-experimental.json | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/packages/accounts-base/package.js b/packages/accounts-base/package.js index cbb8da049a..53f5c580bc 100644 --- a/packages/accounts-base/package.js +++ b/packages/accounts-base/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "A user account system", - version: "1.2.16-rc.7" + version: "1.2.16-rc.8" }); Package.onUse(function (api) { diff --git a/packages/accounts-google/package.js b/packages/accounts-google/package.js index 968ae903da..955232aafc 100644 --- a/packages/accounts-google/package.js +++ b/packages/accounts-google/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Login service for Google accounts", - version: "1.1.2-rc.7" + version: "1.1.2-rc.8" }); Package.onUse(function(api) { diff --git a/packages/accounts-password/package.js b/packages/accounts-password/package.js index 6d6fd1ec6d..ca375f1582 100644 --- a/packages/accounts-password/package.js +++ b/packages/accounts-password/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Password support for accounts", - version: "1.3.5-rc.7" + version: "1.3.5-rc.8" }); Package.onUse(function(api) { diff --git a/packages/babel-compiler/package.js b/packages/babel-compiler/package.js index a074258ffb..0e8ad572f3 100644 --- a/packages/babel-compiler/package.js +++ b/packages/babel-compiler/package.js @@ -6,7 +6,7 @@ Package.describe({ // isn't possible because you can't publish a non-recommended // release with package versions that don't have a pre-release // identifier at the end (eg, -dev) - version: '6.18.0-rc.7' + version: '6.18.0-rc.8' }); Npm.depends({ diff --git a/packages/ddp-client/package.js b/packages/ddp-client/package.js index 7ebd18999f..55c62ec2b4 100644 --- a/packages/ddp-client/package.js +++ b/packages/ddp-client/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Meteor's latency-compensated distributed data client", - version: '1.3.4-rc.7', + version: '1.3.4-rc.8', documentation: null }); diff --git a/packages/ddp-server/package.js b/packages/ddp-server/package.js index 8195999f4d..9ee1cfed00 100644 --- a/packages/ddp-server/package.js +++ b/packages/ddp-server/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Meteor's latency-compensated distributed data server", - version: '1.3.14-rc.7', + version: '1.3.14-rc.8', documentation: null }); diff --git a/packages/ecmascript/package.js b/packages/ecmascript/package.js index ea725a3b86..ab84ce87b3 100644 --- a/packages/ecmascript/package.js +++ b/packages/ecmascript/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'ecmascript', - version: '0.7.1-rc.7', + version: '0.7.1-rc.8', summary: 'Compiler plugin that supports ES2015+ in all .js files', documentation: 'README.md' }); diff --git a/packages/email/package.js b/packages/email/package.js index 523021e041..4d61509027 100644 --- a/packages/email/package.js +++ b/packages/email/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Send email messages", - version: "1.2.0-rc.7" + version: "1.2.0-rc.8" }); Npm.depends({ diff --git a/packages/force-ssl-common/package.js b/packages/force-ssl-common/package.js index bd25f2c065..0c27b65fe3 100644 --- a/packages/force-ssl-common/package.js +++ b/packages/force-ssl-common/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: 'Internal force-ssl common code.', - version: '1.0.14-rc.7' + version: '1.0.14-rc.8' }); Npm.depends({ diff --git a/packages/force-ssl/package.js b/packages/force-ssl/package.js index 13aa8f2084..2a3888cdc6 100644 --- a/packages/force-ssl/package.js +++ b/packages/force-ssl/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Require this application to use HTTPS", - version: "1.0.14-rc.7", + version: "1.0.14-rc.8", prodOnly: true }); diff --git a/packages/google-oauth/package.js b/packages/google-oauth/package.js index c1cf515ba2..5ba2f3f923 100644 --- a/packages/google-oauth/package.js +++ b/packages/google-oauth/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Google OAuth flow", - version: "1.2.1-rc.7" + version: "1.2.1-rc.8" }); var cordovaPluginGooglePlusURL = diff --git a/packages/meteor-tool/package.js b/packages/meteor-tool/package.js index c5f3843e0f..ba94276973 100644 --- a/packages/meteor-tool/package.js +++ b/packages/meteor-tool/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "The Meteor command-line tool", - version: '1.4.4-rc.7' + version: '1.4.4-rc.8' }); Package.includeTool(); diff --git a/packages/minifier-js/package.js b/packages/minifier-js/package.js index 40e72afa66..b15613e284 100644 --- a/packages/minifier-js/package.js +++ b/packages/minifier-js/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "JavaScript minifier", - version: "2.0.0-rc.7" + version: "2.0.0-rc.8" }); Npm.depends({ diff --git a/packages/modules-runtime/package.js b/packages/modules-runtime/package.js index 7cce8e878f..5a860f753c 100644 --- a/packages/modules-runtime/package.js +++ b/packages/modules-runtime/package.js @@ -1,6 +1,6 @@ Package.describe({ name: "modules-runtime", - version: "0.7.10-rc.7", + version: "0.7.10-rc.8", summary: "CommonJS module system", git: "https://github.com/benjamn/install", documentation: "README.md" diff --git a/packages/modules/package.js b/packages/modules/package.js index 50ef923b5b..1c39a30386 100644 --- a/packages/modules/package.js +++ b/packages/modules/package.js @@ -1,6 +1,6 @@ Package.describe({ name: "modules", - version: "0.8.1-rc.7", + version: "0.8.1-rc.8", summary: "CommonJS module system", documentation: "README.md" }); diff --git a/packages/rate-limit/package.js b/packages/rate-limit/package.js index 7db423c7fd..7f50bb26c0 100644 --- a/packages/rate-limit/package.js +++ b/packages/rate-limit/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'rate-limit', - version: '1.0.8-rc.7', + version: '1.0.8-rc.8', // Brief, one-line summary of the package. summary: 'An algorithm for rate limiting anything', // URL to the Git repository containing the source code for this package. diff --git a/packages/standard-minifier-js/package.js b/packages/standard-minifier-js/package.js index 02353b2ad3..c2d8a27a6e 100644 --- a/packages/standard-minifier-js/package.js +++ b/packages/standard-minifier-js/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'standard-minifier-js', - version: '2.0.0-rc.7', + version: '2.0.0-rc.8', summary: 'Standard javascript minifiers used with Meteor apps by default.', documentation: 'README.md', }); diff --git a/packages/standard-minifiers/package.js b/packages/standard-minifiers/package.js index bad7620009..b2d8ec2861 100644 --- a/packages/standard-minifiers/package.js +++ b/packages/standard-minifiers/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'standard-minifiers', - version: '1.1.0-rc.7', + version: '1.1.0-rc.8', summary: 'Standard minifiers used with Meteor apps by default.', documentation: 'README.md' }); diff --git a/packages/webapp/package.js b/packages/webapp/package.js index 0adf2255fe..46082d97d1 100644 --- a/packages/webapp/package.js +++ b/packages/webapp/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Serves a Meteor app over HTTP", - version: '1.3.15-rc.7' + version: '1.3.15-rc.8' }); Npm.depends({connect: "2.30.2", diff --git a/scripts/admin/meteor-release-experimental.json b/scripts/admin/meteor-release-experimental.json index 51b4cae38d..390494d6e9 100644 --- a/scripts/admin/meteor-release-experimental.json +++ b/scripts/admin/meteor-release-experimental.json @@ -1,6 +1,6 @@ { "track": "METEOR", - "version": "1.4.4-rc.7", + "version": "1.4.4-rc.8", "recommended": false, "official": false, "description": "Meteor" From 9e0f61c4b39f406627d8a19628a9982047e40170 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Thu, 6 Apr 2017 06:34:30 +0300 Subject: [PATCH 43/60] Revert "Use fs.move() from fs-extra to fix EXDEV cross device error in docker builds. (#8491)" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unfortunately, `fs-extra` is still not as perfect at handling various file system conditions as would be ideal. It seemed sensical to try and use a library like this however, it turns out that the Meteor suite of file system functions stands up best on Windows, which is where I encountered most problems. For example, `fs-extra` still tries to create symlinks as an unprivileged user – a forbidden task on Windows unless running as Administrator. In addition, I ran into a constant stream of other errors: `ENOTEMPTY`, `EBUSY`, `EEXIST` – all for various reasons. My current recommendation is that we remove `fs-extra` and replace the `Builder#complete` `renameDirAlmostAtomically` call (which does not absolutely _have_ to be done atomically) with a `try`/`catch` which resorts to a basic copy if `err.code === 'EXDEV'`. All other functionality stays the same. This reverts commits: * d49f3e270423ab451b43101df90ede8f473282ed * 3257bafc84de9624d69cff50c93aec23b7cbc5c9 * 74cb8ebdc2231e982d9bc9769b1ceba89a1317cf * 5bbdcc9baa5a5be45c0f819ead0a9741c1730e11 * 6a0767bbacd99d705ae53929d846e5a45c811a20 --- scripts/dev-bundle-tool-package.js | 1 - tools/fs/files.js | 171 +++++++++++++---------------- 2 files changed, 74 insertions(+), 98 deletions(-) diff --git a/scripts/dev-bundle-tool-package.js b/scripts/dev-bundle-tool-package.js index 87f10c8d30..f7d2ed362e 100644 --- a/scripts/dev-bundle-tool-package.js +++ b/scripts/dev-bundle-tool-package.js @@ -18,7 +18,6 @@ var packageJson = { "meteor-promise": "0.8.0", fibers: "1.0.15", promise: "7.1.1", - "fs-extra": "2.1.2", // So that Babel 6 can emit require("babel-runtime/helpers/...") calls. "babel-runtime": "6.9.2", // For various ES2015 polyfills, such as Map and Set. diff --git a/tools/fs/files.js b/tools/fs/files.js index f2986057d3..ee7f4b5e92 100644 --- a/tools/fs/files.js +++ b/tools/fs/files.js @@ -5,9 +5,7 @@ /// var assert = require("assert"); -var fs = require('fs'); -fs.move = require('fs-extra').move; -fs.moveSync = require('fs-extra').moveSync; +var fs = require("fs"); var path = require('path'); var os = require('os'); var util = require('util'); @@ -278,16 +276,18 @@ function statOrNull(path, preserveSymlinks) { } } -function callAndTolerateBusyFilesystem(syncFsFunc, asyncFsFunc, ...args) { +// Like rm -r. +files.rm_recursive = Profile("files.rm_recursive", function (p) { + const path = files.convertToOSPath(p); try { - syncFsFunc.apply(this, args); + rimraf.sync(path); } catch (e) { if (e.code === "ENOTEMPTY" && Fiber.current && Fiber.yield && ! Fiber.yield.disallowed) { new Promise((resolve, reject) => { - asyncFsFunc.call(this, ...args, err => { + rimraf(path, err => { err ? reject(err) : resolve(); }); }).await(); @@ -295,25 +295,7 @@ function callAndTolerateBusyFilesystem(syncFsFunc, asyncFsFunc, ...args) { } throw e; } -} - -function callWithRetries(fsFunc, tolerableFsErrorCodes=[], ...args) { - // retries are probably only necessary only on Windows, since some fs calls - // can fail with EBUSY (or similar), which means the file is "busy" (for now). - let maxTries = 10; - let success = false; - while (! success && maxTries-- > 0) { - try { - fsFunc.apply(this, args); - success = true; - } catch (err) { - if (! tolerableFsErrorCodes.includes(err.code)) { - throw err; - } - } - } - return success; -} +}); // Makes all files in a tree read-only. var makeTreeReadOnly = function (p) { @@ -986,6 +968,53 @@ files.createTarball = function (dirPath, tarball, options) { }).await(); }; +// Use this if you'd like to replace a directory with another +// directory as close to atomically as possible. It's better than +// recursively deleting the target directory first and then +// renaming. (Failure modes here include "there's a brief moment where +// toDir does not exist" and "you can end up with garbage directories +// sitting around", but not "there's any time where toDir exists but +// is in a state other than initial or final".) +files.renameDirAlmostAtomically = function (fromDir, toDir) { + var garbageDir = toDir + '-garbage-' + utils.randomToken(); + + // Get old dir out of the way, if it exists. + var movedOldDir = true; + try { + files.rename(toDir, garbageDir); + } catch (e) { + if (e.code !== 'ENOENT') { + throw e; + } + movedOldDir = false; + } + + // Now rename the directory. + files.rename(fromDir, toDir); + + // ... and delete the old one. + if (movedOldDir) { + files.rm_recursive(garbageDir); + } +}; +files.renameDirAlmostAtomically = Profile("files.renameDirAlmostAtomically", + files.renameDirAlmostAtomically); + +files.writeFileAtomically = function (filename, contents) { + const parentDir = files.pathDirname(filename); + files.mkdir_p(parentDir); + + const tmpFile = files.pathJoin( + parentDir, + '.' + files.pathBasename(filename) + '.' + utils.randomToken() + ); + + files.writeFile(tmpFile, contents); + files.rename(tmpFile, filename); +}; +files.writeFileAtomically = Profile("files.writeFileAtomically", + files.writeFileAtomically); + // Like fs.symlinkSync, but creates a temporay link and renames it over the // file; this means it works even if the file already exists. // Do not use this function on Windows, it won't work. @@ -1579,7 +1608,6 @@ wrapFsFunc("readFile", [0], { wrapFsFunc("stat", [0]); wrapFsFunc("lstat", [0]); wrapFsFunc("rename", [0, 1]); -wrapFsFunc("move", [0, 1]); // After the outermost files.withCache call returns, the withCacheCache is // reset to null so that it does not survive server restarts. @@ -1653,36 +1681,30 @@ files.existsSync = function (path, callback) { }; if (files.isWindowsLikeFilesystem()) { - const tolerableFsErrorCodes = ['EPERM', 'EACCES']; + var rename = files.rename; - function makeRenamesqueFunction(name) { - const original = files[name]; - files[name] = function (from, to) { - if (! callWithRetries(original, tolerableFsErrorCodes, from, to)) { - files.cp_r(from, to); - files.rm_recursive(from); + files.rename = function (from, to) { + // retries are necessarily only on Windows, because the rename call can fail + // with EBUSY, which means the file is "busy" + var maxTries = 10; + var success = false; + while (! success && maxTries-- > 0) { + try { + rename(from, to); + success = true; + } catch (err) { + if (err.code !== 'EPERM' && err.code !== 'EACCES') { + throw err; + } } - }; - } - - makeRenamesqueFunction("rename"); - makeRenamesqueFunction("move"); + } + if (! success) { + files.cp_r(from, to); + files.rm_recursive(from); + } + }; } -// The move and moveSync functions from fs-extra, while great at many things -// aren't capable of resolving busy filesystem issues (such as those encountered -// on Windows) since it's not Fiber-aware. -files.moveWithFsTolerance = Profile("files.moveWithFsTolerance", function (f, t) { - return callAndTolerateBusyFilesystem(fs.moveSync, fs.move, - files.convertToOSPath(f), files.convertToOSPath(t)); -}); - -// Like rm -r. -files.rm_recursive = Profile("files.rm_recursive", function (p) { - return callAndTolerateBusyFilesystem(rimraf.sync, rimraf, - files.convertToOSPath(p)); -}); - // Warning: doesn't convert slashes in the second 'cache' arg wrapFsFunc("realpath", [0], { modifyReturnValue: files.convertToStandardPath @@ -1707,51 +1729,6 @@ wrapFsFunc("close", []); wrapFsFunc("symlink", [0, 1]); wrapFsFunc("readlink", [0]); -// Use this if you'd like to replace a directory with another -// directory as close to atomically as possible. It's better than -// recursively deleting the target directory first and then -// renaming. (Failure modes here include "there's a brief moment where -// toDir does not exist" and "you can end up with garbage directories -// sitting around", but not "there's any time where toDir exists but -// is in a state other than initial or final".) -files.renameDirAlmostAtomically = - Profile("files.renameDirAlmostAtomically", function (fromDir, toDir) { - var garbageDir = toDir + '-garbage-' + utils.randomToken(); - - // Get old dir out of the way, if it exists. - var movedOldDir = true; - try { - files.moveWithFsTolerance(toDir, garbageDir); - } catch (e) { - if (e.code !== 'ENOENT') { - throw e; - } - movedOldDir = false; - } - - // Now rename the directory. - files.moveWithFsTolerance(fromDir, toDir); - - // ... and delete the old one. - if (movedOldDir) { - files.rm_recursive(garbageDir); - } - }); - -files.writeFileAtomically = - Profile("files.writeFileAtomically", function (filename, contents) { - const parentDir = files.pathDirname(filename); - files.mkdir_p(parentDir); - - const tmpFile = files.pathJoin( - parentDir, - '.' + files.pathBasename(filename) + '.' + utils.randomToken() - ); - - files.writeFile(tmpFile, contents); - files.rename(tmpFile, filename); - }); - // These don't need to be Fiberized files.createReadStream = function (...args) { args[0] = files.convertToOSPath(args[0]); From 523c7ce9d4d47442becc307817a35d6bb9800915 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Thu, 6 Apr 2017 06:54:37 +0300 Subject: [PATCH 44/60] If `EXDEV` is encountered, resort to a delete and `cp_r`. This operation does not have to be done atomically and this should allow cross-device copies to be made if necessary. --- tools/isobuild/builder.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tools/isobuild/builder.js b/tools/isobuild/builder.js index c36f853077..2a6e3def3e 100644 --- a/tools/isobuild/builder.js +++ b/tools/isobuild/builder.js @@ -687,7 +687,16 @@ Previous builder: ${previousBuilder.outputPath}, this builder: ${outputPath}` // case of renameDirAlmostAtomically since that one is constructing files to // be checked in to version control, but here we could get away with it. if (this.buildPath !== this.outputPath) { - files.renameDirAlmostAtomically(this.buildPath, this.outputPath); + try { + files.rename(this.buildPath, this.outputPath); + } catch (e) { + if (e.code === "EXDEV") { + files.rm_recursive(this.outputPath); + files.cp_r(this.buildPath, this.outputPath); + } else { + throw e; + } + } } } From 7090129f8920ca27d045af437e547528abe05658 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Thu, 6 Apr 2017 17:16:03 +0300 Subject: [PATCH 45/60] Re-implement `renameDirAlmostAtomically` in `Builder#complete`. The `rename` is not sufficient on its own since it won't pave the way for the new directory by ensuring that it's empty first. `renameDirAlmostAtomically` will do that. --- tools/isobuild/builder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/isobuild/builder.js b/tools/isobuild/builder.js index 2a6e3def3e..f97aa2e401 100644 --- a/tools/isobuild/builder.js +++ b/tools/isobuild/builder.js @@ -688,7 +688,7 @@ Previous builder: ${previousBuilder.outputPath}, this builder: ${outputPath}` // be checked in to version control, but here we could get away with it. if (this.buildPath !== this.outputPath) { try { - files.rename(this.buildPath, this.outputPath); + files.renameDirAlmostAtomically(this.buildPath, this.outputPath); } catch (e) { if (e.code === "EXDEV") { files.rm_recursive(this.outputPath); From af1bc232d66f4d153378e4fe1d23df21f2ac7d12 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Thu, 6 Apr 2017 17:15:11 +0300 Subject: [PATCH 46/60] Hoist "Can we Fiber?" logic up to a helper function. This also makes it possible to disable it in places where we were not checking against the `METEOR_DISABLE_FS_FIBERS` env. variable, like in `rm_recursive`. --- tools/fs/files.js | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/tools/fs/files.js b/tools/fs/files.js index ee7f4b5e92..ddc0586143 100644 --- a/tools/fs/files.js +++ b/tools/fs/files.js @@ -48,6 +48,19 @@ var useParsedSourceMap = function (pathForSourceMap) { // Try this source map first sourceMapRetrieverStack.push(useParsedSourceMap); +// Fibers are disabled by default for files.* operations unless +// process.env.METEOR_DISABLE_FS_FIBERS parses to a falsy value. +const YIELD_ALLOWED = !! ( + _.has(process.env, "METEOR_DISABLE_FS_FIBERS") && + ! JSON.parse(process.env.METEOR_DISABLE_FS_FIBERS)); + +function canYield() { + return YIELD_ALLOWED && + Fiber.current && + Fiber.yield && + ! Fiber.yield.disallowed; +} + // given a predicate function and a starting path, traverse upwards // from the path until we find a path that satisfies the predicate. // @@ -283,9 +296,7 @@ files.rm_recursive = Profile("files.rm_recursive", function (p) { rimraf.sync(path); } catch (e) { if (e.code === "ENOTEMPTY" && - Fiber.current && - Fiber.yield && - ! Fiber.yield.disallowed) { + canYield()) { new Promise((resolve, reject) => { rimraf(path, err => { err ? reject(err) : resolve(); @@ -1472,12 +1483,6 @@ files.readLinkToMeteorScript = function (linkLocation, platform) { // A helpful file to import for this purpose is colon-converter.js, which also // knows how to convert various configuration file formats. -// Fibers are disabled by default for files.* operations unless -// process.env.METEOR_DISABLE_FS_FIBERS parses to a falsy value. -const YIELD_ALLOWED = !! ( - _.has(process.env, "METEOR_DISABLE_FS_FIBERS") && - ! JSON.parse(process.env.METEOR_DISABLE_FS_FIBERS)); - files.fsFixPath = {}; /** * Wrap a function from node's fs module to use the right slashes for this OS @@ -1511,11 +1516,6 @@ function wrapFsFunc(fsFuncName, pathArgIndices, options) { args[i] = files.convertToOSPath(args[i]); } - const canYield = YIELD_ALLOWED && - Fiber.current && - Fiber.yield && - ! Fiber.yield.disallowed; - const shouldBeSync = alwaysSync || sync; // There's some overhead in awaiting a Promise of an async call, // vs just doing the sync call, which for a call like "stat" @@ -1527,7 +1527,9 @@ function wrapFsFunc(fsFuncName, pathArgIndices, options) { fsFuncName === 'rename' || fsFuncName === 'symlink'); - if (canYield && shouldBeSync && !isQuickie) { + if (canYield() && + shouldBeSync && + ! isQuickie) { const promise = new Promise((resolve, reject) => { args.push((err, value) => { if (options.noErr) { From e9a2f6d22cdc7d975052352cce9039183caa9f6d Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Thu, 6 Apr 2017 19:30:06 +0300 Subject: [PATCH 47/60] Just `Profile` the `*Atomically` functions directly. ...Versus reassigning them immediately after. (Whitespace-only view is recommended, due to indentation change) --- tools/fs/files.js | 68 +++++++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/tools/fs/files.js b/tools/fs/files.js index ddc0586143..4d47514f08 100644 --- a/tools/fs/files.js +++ b/tools/fs/files.js @@ -986,45 +986,49 @@ files.createTarball = function (dirPath, tarball, options) { // toDir does not exist" and "you can end up with garbage directories // sitting around", but not "there's any time where toDir exists but // is in a state other than initial or final".) -files.renameDirAlmostAtomically = function (fromDir, toDir) { - var garbageDir = toDir + '-garbage-' + utils.randomToken(); +files.renameDirAlmostAtomically = + Profile("files.renameDirAlmostAtomically", function (fromDir, toDir) { + var garbageDir = toDir + '-garbage-' + utils.randomToken(); - // Get old dir out of the way, if it exists. - var movedOldDir = true; - try { - files.rename(toDir, garbageDir); - } catch (e) { - if (e.code !== 'ENOENT') { - throw e; + // Get old dir out of the way, if it exists. + var movedOldDir = true; + try { + files.rename(toDir, garbageDir); + } catch (e) { + if (e.code !== 'ENOENT') { + throw e; + } + movedOldDir = false; } - movedOldDir = false; - } - // Now rename the directory. - files.rename(fromDir, toDir); + // Now rename the directory. + try { + files.rename(fromDir, toDir); + } catch (e) { + if (e.code === "EXDEV") { + files.cp_r + } + } - // ... and delete the old one. - if (movedOldDir) { - files.rm_recursive(garbageDir); - } -}; -files.renameDirAlmostAtomically = Profile("files.renameDirAlmostAtomically", - files.renameDirAlmostAtomically); + // ... and delete the old one. + if (movedOldDir) { + files.rm_recursive(garbageDir); + } + }); -files.writeFileAtomically = function (filename, contents) { - const parentDir = files.pathDirname(filename); - files.mkdir_p(parentDir); +files.writeFileAtomically = + Profile("files.writeFileAtomically", function (filename, contents) { + const parentDir = files.pathDirname(filename); + files.mkdir_p(parentDir); - const tmpFile = files.pathJoin( - parentDir, - '.' + files.pathBasename(filename) + '.' + utils.randomToken() - ); + const tmpFile = files.pathJoin( + parentDir, + '.' + files.pathBasename(filename) + '.' + utils.randomToken() + ); - files.writeFile(tmpFile, contents); - files.rename(tmpFile, filename); -}; -files.writeFileAtomically = Profile("files.writeFileAtomically", - files.writeFileAtomically); + files.writeFile(tmpFile, contents); + files.rename(tmpFile, filename); + }); // Like fs.symlinkSync, but creates a temporay link and renames it over the // file; this means it works even if the file already exists. From 960e78c250a6e3b3b0c2e5a419fd6d348a08a0c1 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Thu, 6 Apr 2017 19:54:31 +0300 Subject: [PATCH 48/60] Sacrifice atomicity in the event that the file-system won't allow it. /cc @benjamn --- tools/fs/files.js | 48 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/tools/fs/files.js b/tools/fs/files.js index 4d47514f08..9303d05665 100644 --- a/tools/fs/files.js +++ b/tools/fs/files.js @@ -987,31 +987,53 @@ files.createTarball = function (dirPath, tarball, options) { // sitting around", but not "there's any time where toDir exists but // is in a state other than initial or final".) files.renameDirAlmostAtomically = - Profile("files.renameDirAlmostAtomically", function (fromDir, toDir) { - var garbageDir = toDir + '-garbage-' + utils.randomToken(); + Profile("files.renameDirAlmostAtomically", (fromDir, toDir) => { + const garbageDir = `${toDir}-garbage-${utils.randomToken()}`; // Get old dir out of the way, if it exists. - var movedOldDir = true; + let cleanupGarbage = false; + let forceCopy = false; try { files.rename(toDir, garbageDir); + cleanupGarbage = true; } catch (e) { - if (e.code !== 'ENOENT') { + if (e.code === 'EXDEV') { + // Some (notably Docker) file systems will fail to do a seemingly + // harmless operation, such as renaming, on what is apparently the same + // file system. AUFS will do this even if the `fromDir` and `toDir` + // are on the same layer, and OverlayFS will fail if the `fromDir` and + // `toDir` are on different layers. In these cases, we will not be + // atomic and will need to do a recursive copy. + forceCopy = true; + } else if (e.code !== 'ENOENT') { + // No such file or directory is okay, but anything else is not. throw e; } - movedOldDir = false; } - // Now rename the directory. - try { - files.rename(fromDir, toDir); - } catch (e) { - if (e.code === "EXDEV") { - files.cp_r + if (! forceCopy) { + try { + files.rename(fromDir, toDir); + } catch (e) { + // It's possible that there may not have been a `toDir` to have + // advanced warning about this, so we're prepared to handle it again. + if (e.code === 'EXDEV') { + forceCopy = true; + } else { + throw e; + } } } - // ... and delete the old one. - if (movedOldDir) { + // If we've been forced to jeopardize our atomicity due to file-system + // limitations, we'll resort to copying. + if (forceCopy) { + files.rm_recursive(toDir); + files.cp_r(fromDir, toDir); + } + + // ... and take out the trash. + if (cleanupGarbage) { files.rm_recursive(garbageDir); } }); From 0cf0fb12c3c3aeef414143f804994feef73f42e8 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Thu, 6 Apr 2017 20:03:35 +0300 Subject: [PATCH 49/60] Remove `catch`-ing of `EXDEV` from `Builder#complete`. This logic is now handled in `files.renameDirAlmostAtomically`. --- tools/isobuild/builder.js | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/tools/isobuild/builder.js b/tools/isobuild/builder.js index f97aa2e401..c36f853077 100644 --- a/tools/isobuild/builder.js +++ b/tools/isobuild/builder.js @@ -687,16 +687,7 @@ Previous builder: ${previousBuilder.outputPath}, this builder: ${outputPath}` // case of renameDirAlmostAtomically since that one is constructing files to // be checked in to version control, but here we could get away with it. if (this.buildPath !== this.outputPath) { - try { - files.renameDirAlmostAtomically(this.buildPath, this.outputPath); - } catch (e) { - if (e.code === "EXDEV") { - files.rm_recursive(this.outputPath); - files.cp_r(this.buildPath, this.outputPath); - } else { - throw e; - } - } + files.renameDirAlmostAtomically(this.buildPath, this.outputPath); } } From ae35f13ed2b7511cf82b8d263657e349bf45dd5a Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Thu, 6 Apr 2017 20:18:38 +0300 Subject: [PATCH 50/60] Use new `rm_recursive_async` to cleanup garbage directory w/o waiting. --- tools/fs/files.js | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/tools/fs/files.js b/tools/fs/files.js index 9303d05665..f26e1eb9ff 100644 --- a/tools/fs/files.js +++ b/tools/fs/files.js @@ -289,19 +289,22 @@ function statOrNull(path, preserveSymlinks) { } } +files.rm_recursive_async = (path) => { + return new Promise((resolve, reject) => { + rimraf(files.convertToOSPath(path), err => err + ? reject(err) + : resolve()); + }); +}; + // Like rm -r. -files.rm_recursive = Profile("files.rm_recursive", function (p) { - const path = files.convertToOSPath(p); +files.rm_recursive = Profile("files.rm_recursive", (path) => { try { - rimraf.sync(path); + rimraf.sync(files.convertToOSPath(path)); } catch (e) { if (e.code === "ENOTEMPTY" && canYield()) { - new Promise((resolve, reject) => { - rimraf(path, err => { - err ? reject(err) : resolve(); - }); - }).await(); + files.rm_recursive_async(path).await(); return; } throw e; @@ -1034,7 +1037,8 @@ files.renameDirAlmostAtomically = // ... and take out the trash. if (cleanupGarbage) { - files.rm_recursive(garbageDir); + // We don't care about how long this takes, so we'll let it go async. + files.rm_recursive_async(garbageDir); } }); From a4b3dd7f57e87c7d6ccb49603612f5ab448b9bf9 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Thu, 6 Apr 2017 21:17:24 +0300 Subject: [PATCH 51/60] Bump $BUNDLE_VERSION to 4.7.23 before rebuilding dev bundle. --- meteor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meteor b/meteor index 4e187d594c..886256dfb7 100755 --- a/meteor +++ b/meteor @@ -1,6 +1,6 @@ #!/usr/bin/env bash -BUNDLE_VERSION=4.7.22 +BUNDLE_VERSION=4.7.23 # OS Check. Put here because here is where we download the precompiled # bundles that are arch specific. From 13c55e734cbee24053b59487929253ce3a6abdcc Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Thu, 6 Apr 2017 22:51:33 +0300 Subject: [PATCH 52/60] Bump package versions for 1.4.4-rc.9 release. --- packages/accounts-base/package.js | 2 +- packages/accounts-google/package.js | 2 +- packages/accounts-password/package.js | 2 +- packages/babel-compiler/package.js | 2 +- packages/ddp-client/package.js | 2 +- packages/ddp-server/package.js | 2 +- packages/ecmascript/package.js | 2 +- packages/email/package.js | 2 +- packages/force-ssl-common/package.js | 2 +- packages/force-ssl/package.js | 2 +- packages/google-oauth/package.js | 2 +- packages/meteor-tool/package.js | 2 +- packages/minifier-js/package.js | 2 +- packages/modules-runtime/package.js | 2 +- packages/modules/package.js | 2 +- packages/rate-limit/package.js | 2 +- packages/standard-minifier-js/package.js | 2 +- packages/standard-minifiers/package.js | 2 +- packages/webapp/package.js | 2 +- scripts/admin/meteor-release-experimental.json | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/packages/accounts-base/package.js b/packages/accounts-base/package.js index 53f5c580bc..e7577a575d 100644 --- a/packages/accounts-base/package.js +++ b/packages/accounts-base/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "A user account system", - version: "1.2.16-rc.8" + version: "1.2.16-rc.9" }); Package.onUse(function (api) { diff --git a/packages/accounts-google/package.js b/packages/accounts-google/package.js index 955232aafc..60f19abf1a 100644 --- a/packages/accounts-google/package.js +++ b/packages/accounts-google/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Login service for Google accounts", - version: "1.1.2-rc.8" + version: "1.1.2-rc.9" }); Package.onUse(function(api) { diff --git a/packages/accounts-password/package.js b/packages/accounts-password/package.js index ca375f1582..b20ce34572 100644 --- a/packages/accounts-password/package.js +++ b/packages/accounts-password/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Password support for accounts", - version: "1.3.5-rc.8" + version: "1.3.5-rc.9" }); Package.onUse(function(api) { diff --git a/packages/babel-compiler/package.js b/packages/babel-compiler/package.js index 0e8ad572f3..550fcc83fa 100644 --- a/packages/babel-compiler/package.js +++ b/packages/babel-compiler/package.js @@ -6,7 +6,7 @@ Package.describe({ // isn't possible because you can't publish a non-recommended // release with package versions that don't have a pre-release // identifier at the end (eg, -dev) - version: '6.18.0-rc.8' + version: '6.18.0-rc.9' }); Npm.depends({ diff --git a/packages/ddp-client/package.js b/packages/ddp-client/package.js index 55c62ec2b4..67fc668558 100644 --- a/packages/ddp-client/package.js +++ b/packages/ddp-client/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Meteor's latency-compensated distributed data client", - version: '1.3.4-rc.8', + version: '1.3.4-rc.9', documentation: null }); diff --git a/packages/ddp-server/package.js b/packages/ddp-server/package.js index 9ee1cfed00..3ba1f27523 100644 --- a/packages/ddp-server/package.js +++ b/packages/ddp-server/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Meteor's latency-compensated distributed data server", - version: '1.3.14-rc.8', + version: '1.3.14-rc.9', documentation: null }); diff --git a/packages/ecmascript/package.js b/packages/ecmascript/package.js index ab84ce87b3..93ff3885b6 100644 --- a/packages/ecmascript/package.js +++ b/packages/ecmascript/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'ecmascript', - version: '0.7.1-rc.8', + version: '0.7.1-rc.9', summary: 'Compiler plugin that supports ES2015+ in all .js files', documentation: 'README.md' }); diff --git a/packages/email/package.js b/packages/email/package.js index 4d61509027..32e23e9778 100644 --- a/packages/email/package.js +++ b/packages/email/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Send email messages", - version: "1.2.0-rc.8" + version: "1.2.0-rc.9" }); Npm.depends({ diff --git a/packages/force-ssl-common/package.js b/packages/force-ssl-common/package.js index 0c27b65fe3..739f314165 100644 --- a/packages/force-ssl-common/package.js +++ b/packages/force-ssl-common/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: 'Internal force-ssl common code.', - version: '1.0.14-rc.8' + version: '1.0.14-rc.9' }); Npm.depends({ diff --git a/packages/force-ssl/package.js b/packages/force-ssl/package.js index 2a3888cdc6..6cb15ece6d 100644 --- a/packages/force-ssl/package.js +++ b/packages/force-ssl/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Require this application to use HTTPS", - version: "1.0.14-rc.8", + version: "1.0.14-rc.9", prodOnly: true }); diff --git a/packages/google-oauth/package.js b/packages/google-oauth/package.js index 5ba2f3f923..f0f24934c4 100644 --- a/packages/google-oauth/package.js +++ b/packages/google-oauth/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Google OAuth flow", - version: "1.2.1-rc.8" + version: "1.2.1-rc.9" }); var cordovaPluginGooglePlusURL = diff --git a/packages/meteor-tool/package.js b/packages/meteor-tool/package.js index ba94276973..5031c86ba9 100644 --- a/packages/meteor-tool/package.js +++ b/packages/meteor-tool/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "The Meteor command-line tool", - version: '1.4.4-rc.8' + version: '1.4.4-rc.9' }); Package.includeTool(); diff --git a/packages/minifier-js/package.js b/packages/minifier-js/package.js index b15613e284..88dabedb8d 100644 --- a/packages/minifier-js/package.js +++ b/packages/minifier-js/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "JavaScript minifier", - version: "2.0.0-rc.8" + version: "2.0.0-rc.9" }); Npm.depends({ diff --git a/packages/modules-runtime/package.js b/packages/modules-runtime/package.js index 5a860f753c..180b681e3c 100644 --- a/packages/modules-runtime/package.js +++ b/packages/modules-runtime/package.js @@ -1,6 +1,6 @@ Package.describe({ name: "modules-runtime", - version: "0.7.10-rc.8", + version: "0.7.10-rc.9", summary: "CommonJS module system", git: "https://github.com/benjamn/install", documentation: "README.md" diff --git a/packages/modules/package.js b/packages/modules/package.js index 1c39a30386..2a2c16fc8f 100644 --- a/packages/modules/package.js +++ b/packages/modules/package.js @@ -1,6 +1,6 @@ Package.describe({ name: "modules", - version: "0.8.1-rc.8", + version: "0.8.1-rc.9", summary: "CommonJS module system", documentation: "README.md" }); diff --git a/packages/rate-limit/package.js b/packages/rate-limit/package.js index 7f50bb26c0..d21d9abdb1 100644 --- a/packages/rate-limit/package.js +++ b/packages/rate-limit/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'rate-limit', - version: '1.0.8-rc.8', + version: '1.0.8-rc.9', // Brief, one-line summary of the package. summary: 'An algorithm for rate limiting anything', // URL to the Git repository containing the source code for this package. diff --git a/packages/standard-minifier-js/package.js b/packages/standard-minifier-js/package.js index c2d8a27a6e..0f8b8badb5 100644 --- a/packages/standard-minifier-js/package.js +++ b/packages/standard-minifier-js/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'standard-minifier-js', - version: '2.0.0-rc.8', + version: '2.0.0-rc.9', summary: 'Standard javascript minifiers used with Meteor apps by default.', documentation: 'README.md', }); diff --git a/packages/standard-minifiers/package.js b/packages/standard-minifiers/package.js index b2d8ec2861..672cbcd18d 100644 --- a/packages/standard-minifiers/package.js +++ b/packages/standard-minifiers/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'standard-minifiers', - version: '1.1.0-rc.8', + version: '1.1.0-rc.9', summary: 'Standard minifiers used with Meteor apps by default.', documentation: 'README.md' }); diff --git a/packages/webapp/package.js b/packages/webapp/package.js index 46082d97d1..0e23a4daa3 100644 --- a/packages/webapp/package.js +++ b/packages/webapp/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Serves a Meteor app over HTTP", - version: '1.3.15-rc.8' + version: '1.3.15-rc.9' }); Npm.depends({connect: "2.30.2", diff --git a/scripts/admin/meteor-release-experimental.json b/scripts/admin/meteor-release-experimental.json index 390494d6e9..bbb4447f23 100644 --- a/scripts/admin/meteor-release-experimental.json +++ b/scripts/admin/meteor-release-experimental.json @@ -1,6 +1,6 @@ { "track": "METEOR", - "version": "1.4.4-rc.8", + "version": "1.4.4-rc.9", "recommended": false, "official": false, "description": "Meteor" From e85de8fe4b745ee87c4f9b049fb64748e6fa52d5 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Thu, 6 Apr 2017 19:27:07 -0400 Subject: [PATCH 53/60] Remove mention of `fs-extra` npm package from History.md. PR #8569 by @abernix undid the changes this bullet point was referring to. --- History.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/History.md b/History.md index 6fb7b5a5e8..aaa06fe02a 100644 --- a/History.md +++ b/History.md @@ -40,12 +40,6 @@ * https://github.com/leebyron/ecmascript-export-ns-from * https://github.com/leebyron/ecmascript-export-default-from -* The `fs-extra` npm is now used for certain file-system operations in order to - accommodate environments where some tasks (like sym-links) aren't possible. - [Issue #7852](https://github.com/meteor/meteor/issues/7852) - [PR #8491](https://github.com/meteor/meteor/pull/8491) - [PR #8560](https://github.com/meteor/meteor/pull/8560) - * When `Meteor.call` is used on the server to invoke a method that returns a `Promise` object, the result will no longer be the `Promise` object, but the resolved value of the `Promise`. From 68afef2050ae0f2e2dd1e98cbdd5d2641494e16d Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Fri, 7 Apr 2017 13:55:36 +0300 Subject: [PATCH 54/60] Bump package versions for the official 1.4.4 release. --- packages/accounts-base/package.js | 2 +- packages/accounts-google/package.js | 2 +- packages/accounts-password/package.js | 2 +- packages/babel-compiler/package.js | 2 +- packages/ddp-client/package.js | 2 +- packages/ddp-server/package.js | 2 +- packages/ecmascript/package.js | 2 +- packages/email/package.js | 2 +- packages/force-ssl-common/package.js | 2 +- packages/force-ssl/package.js | 2 +- packages/google-oauth/package.js | 2 +- packages/meteor-tool/package.js | 2 +- packages/minifier-js/package.js | 2 +- packages/modules-runtime/package.js | 2 +- packages/modules/package.js | 2 +- packages/rate-limit/package.js | 2 +- packages/standard-minifier-js/package.js | 2 +- packages/standard-minifiers/package.js | 2 +- packages/webapp/package.js | 2 +- scripts/admin/meteor-release-official.json | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/packages/accounts-base/package.js b/packages/accounts-base/package.js index e7577a575d..568d29e33a 100644 --- a/packages/accounts-base/package.js +++ b/packages/accounts-base/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "A user account system", - version: "1.2.16-rc.9" + version: "1.2.16" }); Package.onUse(function (api) { diff --git a/packages/accounts-google/package.js b/packages/accounts-google/package.js index 60f19abf1a..6c624c9e08 100644 --- a/packages/accounts-google/package.js +++ b/packages/accounts-google/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Login service for Google accounts", - version: "1.1.2-rc.9" + version: "1.1.2" }); Package.onUse(function(api) { diff --git a/packages/accounts-password/package.js b/packages/accounts-password/package.js index b20ce34572..77fb819816 100644 --- a/packages/accounts-password/package.js +++ b/packages/accounts-password/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Password support for accounts", - version: "1.3.5-rc.9" + version: "1.3.5" }); Package.onUse(function(api) { diff --git a/packages/babel-compiler/package.js b/packages/babel-compiler/package.js index 550fcc83fa..0a80fcbb09 100644 --- a/packages/babel-compiler/package.js +++ b/packages/babel-compiler/package.js @@ -6,7 +6,7 @@ Package.describe({ // isn't possible because you can't publish a non-recommended // release with package versions that don't have a pre-release // identifier at the end (eg, -dev) - version: '6.18.0-rc.9' + version: '6.18.0' }); Npm.depends({ diff --git a/packages/ddp-client/package.js b/packages/ddp-client/package.js index 67fc668558..a285362f9c 100644 --- a/packages/ddp-client/package.js +++ b/packages/ddp-client/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Meteor's latency-compensated distributed data client", - version: '1.3.4-rc.9', + version: '1.3.4', documentation: null }); diff --git a/packages/ddp-server/package.js b/packages/ddp-server/package.js index 3ba1f27523..14e9d22ba4 100644 --- a/packages/ddp-server/package.js +++ b/packages/ddp-server/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Meteor's latency-compensated distributed data server", - version: '1.3.14-rc.9', + version: '1.3.14', documentation: null }); diff --git a/packages/ecmascript/package.js b/packages/ecmascript/package.js index 93ff3885b6..4214093ea2 100644 --- a/packages/ecmascript/package.js +++ b/packages/ecmascript/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'ecmascript', - version: '0.7.1-rc.9', + version: '0.7.1', summary: 'Compiler plugin that supports ES2015+ in all .js files', documentation: 'README.md' }); diff --git a/packages/email/package.js b/packages/email/package.js index 32e23e9778..36f09e1601 100644 --- a/packages/email/package.js +++ b/packages/email/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Send email messages", - version: "1.2.0-rc.9" + version: "1.2.0" }); Npm.depends({ diff --git a/packages/force-ssl-common/package.js b/packages/force-ssl-common/package.js index 739f314165..fda41c4f54 100644 --- a/packages/force-ssl-common/package.js +++ b/packages/force-ssl-common/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: 'Internal force-ssl common code.', - version: '1.0.14-rc.9' + version: '1.0.14' }); Npm.depends({ diff --git a/packages/force-ssl/package.js b/packages/force-ssl/package.js index 6cb15ece6d..bc9c4bf6ed 100644 --- a/packages/force-ssl/package.js +++ b/packages/force-ssl/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Require this application to use HTTPS", - version: "1.0.14-rc.9", + version: "1.0.14", prodOnly: true }); diff --git a/packages/google-oauth/package.js b/packages/google-oauth/package.js index f0f24934c4..d977bb6d16 100644 --- a/packages/google-oauth/package.js +++ b/packages/google-oauth/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Google OAuth flow", - version: "1.2.1-rc.9" + version: "1.2.1" }); var cordovaPluginGooglePlusURL = diff --git a/packages/meteor-tool/package.js b/packages/meteor-tool/package.js index 5031c86ba9..c3c173509a 100644 --- a/packages/meteor-tool/package.js +++ b/packages/meteor-tool/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "The Meteor command-line tool", - version: '1.4.4-rc.9' + version: '1.4.4' }); Package.includeTool(); diff --git a/packages/minifier-js/package.js b/packages/minifier-js/package.js index 88dabedb8d..9223acefba 100644 --- a/packages/minifier-js/package.js +++ b/packages/minifier-js/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "JavaScript minifier", - version: "2.0.0-rc.9" + version: "2.0.0" }); Npm.depends({ diff --git a/packages/modules-runtime/package.js b/packages/modules-runtime/package.js index 180b681e3c..bf651c454f 100644 --- a/packages/modules-runtime/package.js +++ b/packages/modules-runtime/package.js @@ -1,6 +1,6 @@ Package.describe({ name: "modules-runtime", - version: "0.7.10-rc.9", + version: "0.7.10", summary: "CommonJS module system", git: "https://github.com/benjamn/install", documentation: "README.md" diff --git a/packages/modules/package.js b/packages/modules/package.js index 2a2c16fc8f..1153f2f9cb 100644 --- a/packages/modules/package.js +++ b/packages/modules/package.js @@ -1,6 +1,6 @@ Package.describe({ name: "modules", - version: "0.8.1-rc.9", + version: "0.8.1", summary: "CommonJS module system", documentation: "README.md" }); diff --git a/packages/rate-limit/package.js b/packages/rate-limit/package.js index d21d9abdb1..8fb323d567 100644 --- a/packages/rate-limit/package.js +++ b/packages/rate-limit/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'rate-limit', - version: '1.0.8-rc.9', + version: '1.0.8', // Brief, one-line summary of the package. summary: 'An algorithm for rate limiting anything', // URL to the Git repository containing the source code for this package. diff --git a/packages/standard-minifier-js/package.js b/packages/standard-minifier-js/package.js index 0f8b8badb5..e2bc14e36e 100644 --- a/packages/standard-minifier-js/package.js +++ b/packages/standard-minifier-js/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'standard-minifier-js', - version: '2.0.0-rc.9', + version: '2.0.0', summary: 'Standard javascript minifiers used with Meteor apps by default.', documentation: 'README.md', }); diff --git a/packages/standard-minifiers/package.js b/packages/standard-minifiers/package.js index 672cbcd18d..4a02d43dec 100644 --- a/packages/standard-minifiers/package.js +++ b/packages/standard-minifiers/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'standard-minifiers', - version: '1.1.0-rc.9', + version: '1.1.0', summary: 'Standard minifiers used with Meteor apps by default.', documentation: 'README.md' }); diff --git a/packages/webapp/package.js b/packages/webapp/package.js index 0e23a4daa3..c283fe57d0 100644 --- a/packages/webapp/package.js +++ b/packages/webapp/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "Serves a Meteor app over HTTP", - version: '1.3.15-rc.9' + version: '1.3.15' }); Npm.depends({connect: "2.30.2", diff --git a/scripts/admin/meteor-release-official.json b/scripts/admin/meteor-release-official.json index df3b85c3e1..3d3e6088d8 100644 --- a/scripts/admin/meteor-release-official.json +++ b/scripts/admin/meteor-release-official.json @@ -1,6 +1,6 @@ { "track": "METEOR", - "version": "1.4.3.2", + "version": "1.4.4", "recommended": false, "official": true, "description": "The Official Meteor Distribution" From bbabc83d9a42c01281b0ec180355de0d1da9c4ee Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Fri, 7 Apr 2017 12:29:02 -0400 Subject: [PATCH 55/60] Add heading to History.md for Meteor 1.4.4. --- History.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/History.md b/History.md index aaa06fe02a..cff259a083 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,7 @@ ## v.NEXT +## v1.4.4, 2017-04-07 + * Node has been upgraded to version 4.8.1. * The `npm` npm package has been upgraded to version 4.4.4. From 6055b49f8deb4153d45cdb9048997ca2be0b3083 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Fri, 7 Apr 2017 16:06:32 -0400 Subject: [PATCH 56/60] Wait on removal of garbage directories. This would have been a nice optimization if it had worked, but (in addition to leaving garbage directories lying around sometimes if the process was killed), it appears to have some unintended consequences for meteorNpm.rebuildIfNonPortable and related functions, since the garbage directories are easily confused for npm package directories. Example stack trace: Error: ENOENT: no such file or directory, open '/home/travis/build/meteor/galaxy-server/node_modules/heapdump-garbage-1c2jqib/package.json' at Error (native) => awaited here: at Promise.await (/home/travis/.meteor/packages/less/.2.7.9.9fh5c1++os+web.browser+web.cordova/plugin.compileLessBatch.os/npm/node_modules/meteor/promise/node_modules/meteor-promise/promise_server.js:39:12) at copyFileHelper (/tools/fs/files.js:633:6) at Object.files.cp_r (/tools/fs/files.js:532:7) at /tools/isobuild/meteor-npm.js:393:11 at Array.forEach (native) at copyNpmPackageWithSymlinkedNodeModules (/tools/isobuild/meteor-npm.js:386:29) at /tools/isobuild/meteor-npm.js:325:5 at Array.forEach (native) at Object.rebuildIfNonPortable (/tools/isobuild/meteor-npm.js:315:17) at NodeModulesDirectory.rebuildIfNonPortable (/tools/isobuild/bundler.js:273:22) at /tools/isobuild/compiler.js:650:13 --- tools/fs/files.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/fs/files.js b/tools/fs/files.js index f26e1eb9ff..b9b618476a 100644 --- a/tools/fs/files.js +++ b/tools/fs/files.js @@ -1038,7 +1038,7 @@ files.renameDirAlmostAtomically = // ... and take out the trash. if (cleanupGarbage) { // We don't care about how long this takes, so we'll let it go async. - files.rm_recursive_async(garbageDir); + files.rm_recursive(garbageDir); } }); From e1ac5bf1f3be7520f670bb77f53e45ee95c5d7c9 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Fri, 7 Apr 2017 11:51:37 -0400 Subject: [PATCH 57/60] Replace module.importSync with module.import in older Meteor versions. Also bumping the ecmascript version because it registers a compiler plugin that uses babel-compiler. Fixes #8572, albeit somewhat hackily. --- packages/babel-compiler/babel-compiler.js | 19 +++++++++++++++++++ packages/babel-compiler/package.js | 2 +- packages/ecmascript/package.js | 2 +- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/packages/babel-compiler/babel-compiler.js b/packages/babel-compiler/babel-compiler.js index d54ed73fdc..7a06290419 100644 --- a/packages/babel-compiler/babel-compiler.js +++ b/packages/babel-compiler/babel-compiler.js @@ -1,3 +1,5 @@ +var semver = Npm.require("semver"); + /** * A compiler that can be instantiated with features and used inside * Plugin.registerCompiler @@ -13,6 +15,10 @@ var BCp = BabelCompiler.prototype; var excludedFileExtensionPattern = /\.(es5|min)\.js$/i; var hasOwn = Object.prototype.hasOwnProperty; +// There's no way to tell the current Meteor version, but we can infer +// whether it's Meteor 1.4.4 or earlier by checking the Node version. +var isMeteorPre144 = semver.lt(process.version, "4.8.1"); + BCp.processFilesForTarget = function (inputFiles) { // Reset this cache for each batch processed. this._babelrcCache = null; @@ -103,6 +109,19 @@ BCp.processOneFileForTarget = function (inputFile, source) { throw e; } + if (isMeteorPre144) { + // Versions of meteor-tool earlier than 1.4.4 do not understand that + // module.importSync is synonymous with the deprecated module.import + // and thus fail to register dependencies for importSync calls. + // This string replacement may seem a bit hacky, but it will tide us + // over until everyone has updated to Meteor 1.4.4. + // https://github.com/meteor/meteor/issues/8572 + result.code = result.code.replace( + /\bmodule\.importSync\b/g, + "module.import" + ); + } + toBeAdded.data = result.code; toBeAdded.hash = result.hash; toBeAdded.sourceMap = result.map; diff --git a/packages/babel-compiler/package.js b/packages/babel-compiler/package.js index 0a80fcbb09..44bc595b9c 100644 --- a/packages/babel-compiler/package.js +++ b/packages/babel-compiler/package.js @@ -6,7 +6,7 @@ Package.describe({ // isn't possible because you can't publish a non-recommended // release with package versions that don't have a pre-release // identifier at the end (eg, -dev) - version: '6.18.0' + version: '6.18.1' }); Npm.depends({ diff --git a/packages/ecmascript/package.js b/packages/ecmascript/package.js index 4214093ea2..4c27300bbe 100644 --- a/packages/ecmascript/package.js +++ b/packages/ecmascript/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'ecmascript', - version: '0.7.1', + version: '0.7.2', summary: 'Compiler plugin that supports ES2015+ in all .js files', documentation: 'README.md' }); From ce29815ae7ed8436dd90ac1ef85b334e188b7be9 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Fri, 7 Apr 2017 16:27:22 -0400 Subject: [PATCH 58/60] Bump package versions for 1.4.4.1-rc.0 release. --- packages/meteor-tool/package.js | 2 +- scripts/admin/meteor-release-experimental.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/meteor-tool/package.js b/packages/meteor-tool/package.js index c3c173509a..813f60c951 100644 --- a/packages/meteor-tool/package.js +++ b/packages/meteor-tool/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "The Meteor command-line tool", - version: '1.4.4' + version: '1.4.4-1-rc.0' }); Package.includeTool(); diff --git a/scripts/admin/meteor-release-experimental.json b/scripts/admin/meteor-release-experimental.json index bbb4447f23..6e271282a4 100644 --- a/scripts/admin/meteor-release-experimental.json +++ b/scripts/admin/meteor-release-experimental.json @@ -1,6 +1,6 @@ { "track": "METEOR", - "version": "1.4.4-rc.9", + "version": "1.4.4.1-rc.0", "recommended": false, "official": false, "description": "Meteor" From 22cefeec150aa6245a54e8b534d8ff1207b5afa2 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Fri, 7 Apr 2017 16:50:57 -0400 Subject: [PATCH 59/60] Update History.md to reflect changes in Meteor 1.4.4.1. --- History.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/History.md b/History.md index cff259a083..2fa43c551b 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,13 @@ ## v.NEXT +## v1.4.4.1, TBD + +* A change in Meteor 1.4.4 to remove "garbage" directories asynchronously + in `files.renameDirAlmostAtomically` had unintended consequences for + rebuilding some npm packages, so that change was reverted, and those + directories are now removed before `files.renameDirAlmostAtomically` + returns. [PR #8574](https://github.com/meteor/meteor/pull/8574) + ## v1.4.4, 2017-04-07 * Node has been upgraded to version 4.8.1. From 384023ecbdffaadf84ff41f44efeeef7de7d69d3 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Fri, 7 Apr 2017 17:58:50 -0400 Subject: [PATCH 60/60] Bump package versions for the official 1.4.4.1 release. --- packages/meteor-tool/package.js | 2 +- scripts/admin/meteor-release-official.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/meteor-tool/package.js b/packages/meteor-tool/package.js index 813f60c951..ef6a96411f 100644 --- a/packages/meteor-tool/package.js +++ b/packages/meteor-tool/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "The Meteor command-line tool", - version: '1.4.4-1-rc.0' + version: '1.4.4_1' }); Package.includeTool(); diff --git a/scripts/admin/meteor-release-official.json b/scripts/admin/meteor-release-official.json index 3d3e6088d8..748abf611f 100644 --- a/scripts/admin/meteor-release-official.json +++ b/scripts/admin/meteor-release-official.json @@ -1,6 +1,6 @@ { "track": "METEOR", - "version": "1.4.4", + "version": "1.4.4.1", "recommended": false, "official": true, "description": "The Official Meteor Distribution"