mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Fix issues with Infinity based login token lifetimes (#9113)
* Fix issues with Infinity based login token lifetimes Several areas of the Accounts system are using the current login token expiration millisecond limit for different `Date` based calculations. When `loginExpirationInDays` is set to `null`, and the Accounts system uses an expiration limit of `Infinity`, these `Date` based operations fail, since `Infinity` can't be converted to a `Date`. These changes replace the use of `Infinity` with a far future fixed date representation, that's used when `loginExpirationInDays` is set to `null`. Fixes #9066. * Small comment typo * Remove unnecessary comment
This commit is contained in:
@@ -213,19 +213,20 @@ export class AccountsCommon {
|
||||
}
|
||||
}
|
||||
|
||||
// The options argument is only used by tests.
|
||||
_getTokenLifetimeMs(options) {
|
||||
options = options || this._options;
|
||||
if (options.loginExpirationInDays === null) {
|
||||
// We disable login expiration by returning Infinity
|
||||
return Infinity;
|
||||
}
|
||||
return (options.loginExpirationInDays ||
|
||||
DEFAULT_LOGIN_EXPIRATION_DAYS) * 24 * 60 * 60 * 1000;
|
||||
_getTokenLifetimeMs() {
|
||||
// When loginExpirationInDays is set to null, we'll use a really high
|
||||
// number of days (LOGIN_UNEXPIRABLE_TOKEN_DAYS) to simulate an
|
||||
// unexpiring token.
|
||||
const loginExpirationInDays =
|
||||
(this._options.loginExpirationInDays === null)
|
||||
? LOGIN_UNEXPIRING_TOKEN_DAYS
|
||||
: this._options.loginExpirationInDays;
|
||||
return (loginExpirationInDays
|
||||
|| DEFAULT_LOGIN_EXPIRATION_DAYS) * 24 * 60 * 60 * 1000;
|
||||
}
|
||||
|
||||
_getPasswordResetTokenLifetimeMs() {
|
||||
return (this._options.passwordResetTokenExpirationInDays ||
|
||||
return (this._options.passwordResetTokenExpirationInDays ||
|
||||
DEFAULT_PASSWORD_RESET_TOKEN_EXPIRATION_DAYS) * 24 * 60 * 60 * 1000;
|
||||
}
|
||||
|
||||
@@ -273,7 +274,10 @@ Meteor.user = function () {
|
||||
};
|
||||
|
||||
// how long (in days) until a login token expires
|
||||
var DEFAULT_LOGIN_EXPIRATION_DAYS = 90;
|
||||
const DEFAULT_LOGIN_EXPIRATION_DAYS = 90;
|
||||
// Expose for testing.
|
||||
Ap.DEFAULT_LOGIN_EXPIRATION_DAYS = DEFAULT_LOGIN_EXPIRATION_DAYS;
|
||||
|
||||
// how long (in days) until reset password token expires
|
||||
var DEFAULT_PASSWORD_RESET_TOKEN_EXPIRATION_DAYS = 3;
|
||||
// how long (in days) until enrol password token expires
|
||||
@@ -288,6 +292,12 @@ EXPIRE_TOKENS_INTERVAL_MS = 600 * 1000; // 10 minutes
|
||||
// called
|
||||
CONNECTION_CLOSE_DELAY_MS = 10 * 1000;
|
||||
|
||||
// A large number of expiration days (approximately 100 years worth) that is
|
||||
// used when creating unexpiring tokens.
|
||||
const LOGIN_UNEXPIRING_TOKEN_DAYS = 365 * 100;
|
||||
// Expose for testing.
|
||||
Ap.LOGIN_UNEXPIRING_TOKEN_DAYS = LOGIN_UNEXPIRING_TOKEN_DAYS;
|
||||
|
||||
// loginServiceConfiguration and ConfigError are maintained for backwards compatibility
|
||||
Meteor.startup(function () {
|
||||
var ServiceConfiguration =
|
||||
|
||||
@@ -13,23 +13,49 @@ Tinytest.add('accounts - config validates keys', function (test) {
|
||||
});
|
||||
});
|
||||
|
||||
// test the loginExpirationInDays config
|
||||
|
||||
Tinytest.add( 'accounts - config - token limetime', function (test) {
|
||||
var config = { loginExpirationInDays: 2 };
|
||||
test.equal(Accounts._getTokenLifetimeMs(config), 2 * 24 * 60 * 60 * 1000);
|
||||
Tinytest.add('accounts - config - token lifetime', function (test) {
|
||||
const loginExpirationInDays = Accounts._options.loginExpirationInDays;
|
||||
Accounts._options.loginExpirationInDays = 2;
|
||||
test.equal(Accounts._getTokenLifetimeMs(), 2 * 24 * 60 * 60 * 1000);
|
||||
Accounts._options.loginExpirationInDays = loginExpirationInDays;
|
||||
});
|
||||
|
||||
Tinytest.add( 'accounts - config - unexpiring tokens', function (test) {
|
||||
var config = { loginExpirationInDays: null };
|
||||
test.equal(Accounts._getTokenLifetimeMs(config), Infinity);
|
||||
Tinytest.add('accounts - config - unexpiring tokens', function (test) {
|
||||
const loginExpirationInDays = Accounts._options.loginExpirationInDays;
|
||||
|
||||
// When setting loginExpirationInDays to null in the global Accounts
|
||||
// config object, make sure the returned token lifetime represents an
|
||||
// unexpiring token date (is very far into the future).
|
||||
Accounts._options.loginExpirationInDays = null;
|
||||
test.equal(
|
||||
Accounts._getTokenLifetimeMs(),
|
||||
Accounts.LOGIN_UNEXPIRING_TOKEN_DAYS * 24 * 60 * 60 * 1000,
|
||||
);
|
||||
|
||||
// Verify token expiration date retrieval returns a Date.
|
||||
// (verifies https://github.com/meteor/meteor/issues/9066)
|
||||
test.isTrue(
|
||||
!isNaN(Accounts._tokenExpiration(new Date())),
|
||||
'Returned token expiration should be a Date',
|
||||
);
|
||||
|
||||
// Verify the token expiration check works properly.
|
||||
// (verifies https://github.com/meteor/meteor/issues/9066)
|
||||
const futureDate = new Date();
|
||||
futureDate.setDate(futureDate.getDate() + 200);
|
||||
test.isFalse(Accounts._tokenExpiresSoon(futureDate));
|
||||
|
||||
Accounts._options.loginExpirationInDays = loginExpirationInDays;
|
||||
});
|
||||
|
||||
Tinytest.add( 'accounts - config - default token limetime', function(test) {
|
||||
var DEFAULT_LOGIN_EXPIRATION_DAYS = 90; // copied from accounts_common.js
|
||||
var config1 = {};
|
||||
var config2 = { loginExpirationInDays: DEFAULT_LOGIN_EXPIRATION_DAYS };
|
||||
test.equal(Accounts._getTokenLifetimeMs(config1), Accounts._getTokenLifetimeMs(config2));
|
||||
Tinytest.add('accounts - config - default token lifetime', function (test) {
|
||||
const options = Accounts._options;
|
||||
Accounts._options = {};
|
||||
test.equal(
|
||||
Accounts._getTokenLifetimeMs(),
|
||||
Accounts.DEFAULT_LOGIN_EXPIRATION_DAYS * 24 * 60 * 60 * 1000,
|
||||
);
|
||||
Accounts._options = options;
|
||||
});
|
||||
|
||||
var idsInValidateNewUser = {};
|
||||
|
||||
Reference in New Issue
Block a user