Skip to content
25 changes: 17 additions & 8 deletions packages/rocketchat-2fa/server/lib/totp.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,39 @@ RocketChat.TOTP = {
},

verify({ secret, token, backupTokens, userId }) {
let verified;

// validates a backup code
if (token.length === 8 && backupTokens) {
const hashedCode = SHA256(token);
const usedCode = backupTokens.indexOf(hashedCode);

if (usedCode !== -1) {
verified = true;

backupTokens.splice(usedCode, 1);

// mark the code as used (remove it from the list)
RocketChat.models.Users.update2FABackupCodesByUserId(userId, backupTokens);
return true;
}
} else {
verified = speakeasy.totp.verify({

return false;
}

const maxDelta = RocketChat.settings.get('Accounts_TwoFactorAuthentication_MaxDelta');
if (maxDelta) {
const verifiedDelta = speakeasy.totp.verifyDelta({
secret,
encoding: 'base32',
token
token,
window: maxDelta
});

return verifiedDelta !== undefined;
}

return verified;
return speakeasy.totp.verify({
secret,
encoding: 'base32',
token
});
},

generateCodes() {
Expand Down
2 changes: 2 additions & 0 deletions packages/rocketchat-i18n/i18n/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@
"Accounts_SetDefaultAvatar": "Set Default Avatar",
"Accounts_SetDefaultAvatar_Description": "Tries to determine default avatar based on OAuth Account or Gravatar",
"Accounts_ShowFormLogin": "Show Form-Based Login",
"Accounts_TwoFactorAuthentication_MaxDelta": "Maximum Delta",
"Accounts_TwoFactorAuthentication_MaxDelta_Description": "The Maximum Delta determines how many tokens are valid at any given time. Tokens are generated every 30 seconds, and are valid for (30 * Maximum Delta) seconds. <br/>Example: With a Maximum Delta set to 10, each token can be used up to 300 seconds before or after it's timestamp. This is useful when the client's clock is not properly synced with the server.",
"Accounts_UseDefaultBlockedDomainsList": "Use Default Blocked Domains List",
"Accounts_UseDNSDomainCheck": "Use DNS Domain Check",
"Accounts_UserAddedEmail_Default": "<h2>Welcome to <h1>[Site_Name]</h1></h2><p>Go to <a href=\"[Site_URL]\">[Site_URL]</a> and try the best open source chat solution available today!</p><p>You may login using your email: [email] and password: [password]. You may be required to change it after your first login.",
Expand Down
8 changes: 8 additions & 0 deletions packages/rocketchat-lib/server/startup/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ RocketChat.settings.addGroup('Accounts', function() {
public: true
});

this.section('Two Factor Authentication', function() {
this.add('Accounts_TwoFactorAuthentication_MaxDelta', 1, {
type: 'int',
public: true,
i18nLabel: 'Accounts_TwoFactorAuthentication_MaxDelta'
});
});

this.section('Registration', function() {
this.add('Accounts_DefaultUsernamePrefixSuggestion', 'user', {
type: 'string'
Expand Down