diff --git a/packages/accounts-base/accounts_server.js b/packages/accounts-base/accounts_server.js index 13ac0c3ea8..b185288fe3 100644 --- a/packages/accounts-base/accounts_server.js +++ b/packages/accounts-base/accounts_server.js @@ -569,62 +569,6 @@ export class AccountsServer extends AccountsCommon { this.setUserId(null); }; - // Delete all the current user's tokens and close all open connections logged - // in as this user. Returns a fresh new login token that this client can - // use. Tests set Accounts._noConnectionCloseDelayForTest to delete tokens - // immediately instead of using a delay. - // - // XXX COMPAT WITH 0.7.2 - // This single `logoutOtherClients` method has been replaced with two - // methods, one that you call to get a new token, and another that you - // call to remove all tokens except your own. The new design allows - // clients to know when other clients have actually been logged - // out. (The `logoutOtherClients` method guarantees the caller that - // the other clients will be logged out at some point, but makes no - // guarantees about when.) This method is left in for backwards - // compatibility, especially since application code might be calling - // this method directly. - // - // @returns {Object} Object with token and tokenExpires keys. - methods.logoutOtherClients = function () { - const user = accounts.users.findOne(this.userId, { - fields: { - "services.resume.loginTokens": true - } - }); - if (user) { - // Save the current tokens in the database to be deleted in - // CONNECTION_CLOSE_DELAY_MS ms. This gives other connections in the - // caller's browser time to find the fresh token in localStorage. We save - // the tokens in the database in case we crash before actually deleting - // them. - const tokens = user.services.resume.loginTokens; - const newToken = accounts._generateStampedLoginToken(); - accounts.users.update(this.userId, { - $set: { - "services.resume.loginTokensToDelete": tokens, - "services.resume.haveLoginTokensToDelete": true - }, - $push: { "services.resume.loginTokens": accounts._hashStampedToken(newToken) } - }); - Meteor.setTimeout(() => { - // The observe on Meteor.users will take care of closing the connections - // associated with `tokens`. - accounts._deleteSavedTokensForUser(this.userId, tokens); - }, accounts._noConnectionCloseDelayForTest ? 0 : - CONNECTION_CLOSE_DELAY_MS); - // We do not set the login token on this connection, but instead the - // observe closes the connection and the client will reconnect with the - // new token. - return { - token: newToken.token, - tokenExpires: accounts._tokenExpiration(newToken.when) - }; - } else { - throw new Meteor.Error("You are not logged in."); - } - }; - // Generates a new login token with the same expiration as the // connection's current token and saves it to the database. Associates // the connection with this new token and returns it. Throws an error diff --git a/packages/accounts-password/password_client.js b/packages/accounts-password/password_client.js index 871393127a..d4d53c04d3 100644 --- a/packages/accounts-password/password_client.js +++ b/packages/accounts-password/password_client.js @@ -43,27 +43,7 @@ Meteor.loginWithPassword = (selector, password, callback) => { password: Accounts._hashPassword(password) }], userCallback: (error, result) => { - if (error && error.error === 400 && - error.reason === 'old password format') { - // The "reason" string should match the error thrown in the - // password login handler in password_server.js. - - // XXX COMPAT WITH 0.8.1.3 - // If this user's last login was with a previous version of - // Meteor that used SRP, then the server throws this error to - // indicate that we should try again. The error includes the - // user's SRP identity. We provide a value derived from the - // identity and the password to prove to the server that we know - // the password without requiring a full SRP flow, as well as - // SHA256(password), which the server bcrypts and stores in - // place of the old SRP information for this user. - srpUpgradePath({ - upgradeError: error, - userSelector: selector, - plaintextPassword: password - }, callback); - } - else if (error) { + if (error) { reportError(error, callback); } else { callback && callback(); @@ -77,35 +57,6 @@ Accounts._hashPassword = password => ({ algorithm: "sha-256" }); - -// XXX COMPAT WITH 0.8.1.3 -// The server requested an upgrade from the old SRP password format, -// so supply the needed SRP identity to login. Options: -// - upgradeError: the error object that the server returned to tell -// us to upgrade from SRP to bcrypt. -// - userSelector: selector to retrieve the user object -// - plaintextPassword: the password as a string -const srpUpgradePath = (options, callback) => { - let details; - try { - details = EJSON.parse(options.upgradeError.details); - } catch (e) {} - if (!(details && details.format === 'srp')) { - reportError( - new Meteor.Error(400, "Password is old. Please reset your " + - "password."), callback); - } else { - Accounts.callLoginMethod({ - methodArguments: [{ - user: options.userSelector, - srp: SHA256(`${details.identity}:${options.plaintextPassword}`), - password: Accounts._hashPassword(options.plaintextPassword) - }], - userCallback: callback - }); - } -}; - // Attempt to log in as a new user. /** @@ -172,30 +123,10 @@ Accounts.changePassword = (oldPassword, newPassword, callback) => { [oldPassword ? Accounts._hashPassword(oldPassword) : null, Accounts._hashPassword(newPassword)], (error, result) => { - if (error || !result) { - if (error && error.error === 400 && - error.reason === 'old password format') { - // XXX COMPAT WITH 0.8.1.3 - // The server is telling us to upgrade from SRP to bcrypt, as - // in Meteor.loginWithPassword. - srpUpgradePath({ - upgradeError: error, - userSelector: { id: Meteor.userId() }, - plaintextPassword: oldPassword - }, err => { - if (err) { - reportError(err, callback); - } else { - // Now that we've successfully migrated from srp to - // bcrypt, try changing the password again. - Accounts.changePassword(oldPassword, newPassword, callback); - } - }); - } else { - // A normal error, not an error telling us to upgrade to bcrypt - reportError( - error || new Error("No result from changePassword."), callback); - } + if (error || !result) { + // A normal error, not an error telling us to upgrade to bcrypt + reportError( + error || new Error("No result from changePassword."), callback); } else { callback && callback(); } diff --git a/packages/accounts-password/password_server.js b/packages/accounts-password/password_server.js index 2076985362..7879f5d808 100644 --- a/packages/accounts-password/password_server.js +++ b/packages/accounts-password/password_server.js @@ -351,79 +351,6 @@ Accounts.registerLoginHandler("password", options => { ); }); -// Handler to login using the SRP upgrade path. To use this login -// handler, the client must provide: -// - srp: H(identity + ":" + password) -// - password: a string or an object with properties 'digest' and 'algorithm' -// -// We use `options.srp` to verify that the client knows the correct -// password without doing a full SRP flow. Once we've checked that, we -// upgrade the user to bcrypt and remove the SRP information from the -// user document. -// -// The client ends up using this login handler after trying the normal -// login handler (above), which throws an error telling the client to -// try the SRP upgrade path. -// -// XXX COMPAT WITH 0.8.1.3 -Accounts.registerLoginHandler("password", options => { - if (!options.srp || !options.password) { - return undefined; // don't handle - } - - check(options, { - user: userQueryValidator, - srp: String, - password: passwordValidator - }); - - const user = Accounts._findUserByQuery(options.user, {fields: { - services: 1, - ...Accounts._checkPasswordUserFields, - }}); - 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) { - return checkPassword(user, options.password); - } - - if (!(user.services && user.services.password && user.services.password.srp)) { - handleError("User has no password set"); - } - - const v1 = user.services.password.srp.verifier; - const v2 = SRP.generateVerifier( - null, - { - hashedIdentityAndPassword: options.srp, - salt: user.services.password.srp.salt - } - ).verifier; - if (v1 !== v2) { - return { - userId: Accounts._options.ambiguousErrorMessages ? null : user._id, - error: handleError("Incorrect password", false) - }; - } - - // Upgrade to bcrypt on successful login. - const salted = hashPassword(options.password); - Meteor.users.update( - user._id, - { - $unset: { 'services.password.srp': 1 }, - $set: { 'services.password.bcrypt': salted } - } - ); - - return {userId: user._id}; -}); - - /// /// CHANGING /// @@ -470,12 +397,6 @@ Accounts.setUsername = (userId, newUsername) => { // password. `oldPassword` and `newPassword` should be objects with keys // `digest` and `algorithm` (representing the SHA256 of the password). // -// XXX COMPAT WITH 0.8.1.3 -// Like the login method, if the user hasn't been upgraded from SRP to -// bcrypt yet, then this method will throw an 'old password format' -// error. The client should call the SRP upgrade login handler and then -// retry this method again. -// // UNLIKE the login method, there is no way to avoid getting SRP upgrade // errors thrown. The reasoning for this is that clients using this // method directly will need to be updated anyway because we no longer @@ -497,18 +418,10 @@ Meteor.methods({changePassword: function (oldPassword, newPassword) { handleError("User not found"); } - if (!user.services || !user.services.password || - (!user.services.password.bcrypt && !user.services.password.srp)) { + if (!user.services || !user.services.password || !user.services.password.bcrypt) { handleError("User has no password set"); } - if (! user.services.password.bcrypt) { - throw new Meteor.Error(400, "old password format", EJSON.stringify({ - format: 'srp', - identity: user.services.password.srp.identity - })); - } - const result = checkPassword(user, oldPassword); if (result.error) { throw result.error; @@ -557,7 +470,6 @@ Accounts.setPassword = (userId, newPlaintextPassword, options) => { const update = { $unset: { - 'services.password.srp': 1, // XXX COMPAT WITH 0.8.1.3 'services.password.reset': 1 }, $set: {'services.password.bcrypt': hashPassword(newPlaintextPassword)} diff --git a/packages/ddp-client/client/client_convenience.js b/packages/ddp-client/client/client_convenience.js index 4111eac4cc..4f21582a37 100644 --- a/packages/ddp-client/client/client_convenience.js +++ b/packages/ddp-client/client/client_convenience.js @@ -55,13 +55,3 @@ Meteor.connection = DDP.connect(ddpUrl, { ].forEach(name => { Meteor[name] = Meteor.connection[name].bind(Meteor.connection); }); - -// Meteor.connection used to be called -// Meteor.default_connection. Provide backcompat as a courtesy even -// though it was never documented. -// XXX COMPAT WITH 0.6.4 -Meteor.default_connection = Meteor.connection; - -// We should transition from Meteor.connect to DDP.connect. -// XXX COMPAT WITH 0.6.4 -Meteor.connect = DDP.connect; diff --git a/packages/ddp-client/common/livedata_connection.js b/packages/ddp-client/common/livedata_connection.js index 740a7f4abb..320e4d60f9 100644 --- a/packages/ddp-client/common/livedata_connection.js +++ b/packages/ddp-client/common/livedata_connection.js @@ -1621,15 +1621,6 @@ export class Connection { this._heartbeat.messageReceived(); } - if (msg === null || !msg.msg) { - // XXX COMPAT WITH 0.6.6. ignore the old welcome message for back - // compat. Remove this 'if' once the server stops sending welcome - // messages (stream_server.js). - if (!(msg && msg.server_id)) - Meteor._debug('discarding invalid livedata message', msg); - return; - } - if (msg.msg === 'connected') { this._version = this._versionSuggestion; this._livedata_connected(msg); diff --git a/packages/ddp-server/server_convenience.js b/packages/ddp-server/server_convenience.js index 28fca40b2b..5d34986053 100755 --- a/packages/ddp-server/server_convenience.js +++ b/packages/ddp-server/server_convenience.js @@ -15,8 +15,3 @@ _.each(['publish', 'methods', 'call', 'apply', 'onConnection', 'onMessage'], function (name) { Meteor[name] = _.bind(Meteor.server[name], Meteor.server); }); - -// Meteor.server used to be called Meteor.default_server. Provide -// backcompat as a courtesy even though it was never documented. -// XXX COMPAT WITH 0.6.4 -Meteor.default_server = Meteor.server; diff --git a/packages/ddp-server/stream_server.js b/packages/ddp-server/stream_server.js index cf044a1d95..a949633a96 100644 --- a/packages/ddp-server/stream_server.js +++ b/packages/ddp-server/stream_server.js @@ -119,16 +119,9 @@ StreamServer = function () { }); self.open_sockets.push(socket); - // XXX COMPAT WITH 0.6.6. Send the old style welcome message, which - // will force old clients to reload. Remove this once we're not - // concerned about people upgrading from a pre-0.7.0 release. Also, - // remove the clause in the client that ignores the welcome message - // (livedata_connection.js) - socket.send(JSON.stringify({server_id: "0"})); - // call all our callbacks when we get a new socket. they will do the // work of setting up handlers and such for specific messages. - _.each(self.registration_callbacks, function (callback) { + self.registration_callbacks.forEach((callback) => { callback(socket); }); }); diff --git a/packages/deps/.gitignore b/packages/deprecated/deps/.gitignore similarity index 100% rename from packages/deps/.gitignore rename to packages/deprecated/deps/.gitignore diff --git a/packages/deps/README.md b/packages/deprecated/deps/README.md similarity index 100% rename from packages/deps/README.md rename to packages/deprecated/deps/README.md diff --git a/packages/deps/package.js b/packages/deprecated/deps/package.js similarity index 100% rename from packages/deps/package.js rename to packages/deprecated/deps/package.js diff --git a/packages/livedata/.gitignore b/packages/deprecated/livedata/.gitignore similarity index 100% rename from packages/livedata/.gitignore rename to packages/deprecated/livedata/.gitignore diff --git a/packages/livedata/DDP.md b/packages/deprecated/livedata/DDP.md similarity index 100% rename from packages/livedata/DDP.md rename to packages/deprecated/livedata/DDP.md diff --git a/packages/livedata/README.md b/packages/deprecated/livedata/README.md similarity index 100% rename from packages/livedata/README.md rename to packages/deprecated/livedata/README.md diff --git a/packages/livedata/package.js b/packages/deprecated/livedata/package.js similarity index 100% rename from packages/livedata/package.js rename to packages/deprecated/livedata/package.js diff --git a/packages/srp/.gitignore b/packages/deprecated/srp/.gitignore similarity index 100% rename from packages/srp/.gitignore rename to packages/deprecated/srp/.gitignore diff --git a/packages/srp/README.md b/packages/deprecated/srp/README.md similarity index 100% rename from packages/srp/README.md rename to packages/deprecated/srp/README.md diff --git a/packages/srp/biginteger.js b/packages/deprecated/srp/biginteger.js similarity index 100% rename from packages/srp/biginteger.js rename to packages/deprecated/srp/biginteger.js diff --git a/packages/srp/package.js b/packages/deprecated/srp/package.js similarity index 100% rename from packages/srp/package.js rename to packages/deprecated/srp/package.js diff --git a/packages/srp/srp.js b/packages/deprecated/srp/srp.js similarity index 100% rename from packages/srp/srp.js rename to packages/deprecated/srp/srp.js diff --git a/packages/srp/srp_tests.js b/packages/deprecated/srp/srp_tests.js similarity index 100% rename from packages/srp/srp_tests.js rename to packages/deprecated/srp/srp_tests.js diff --git a/packages/meteor-base/package.js b/packages/meteor-base/package.js index a8b550e634..3e47ccc3b1 100644 --- a/packages/meteor-base/package.js +++ b/packages/meteor-base/package.js @@ -20,7 +20,6 @@ Package.onUse(function(api) { // The protocol and client/server libraries that Meteor uses to send data 'ddp', - 'livedata', // XXX COMPAT WITH PACKAGES BUILT FOR 0.9.0. // This package uses the user agent of each incoming HTTP request to // decide whether to inject