This repository has been archived by the owner on Apr 3, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 107
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(email): add verification reminders
Fixes #1081
- Loading branch information
Showing
10 changed files
with
390 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
||
var config = require('../config') | ||
var P = require('./promise') | ||
var reminderConfig = config.get('verificationReminders') | ||
|
||
var LOG_REMINDERS_CREATED = 'verification-reminders.created' | ||
var LOG_REMINDERS_DELETED = 'verification-reminders.deleted' | ||
var LOG_REMINDERS_ERROR_CREATE = 'verification-reminder.create' | ||
var LOG_REMINDERS_ERROR_DELETE = 'verification-reminder.delete' | ||
|
||
module.exports = function (log, db) { | ||
/** | ||
* shouldRemind | ||
* | ||
* Determines if we should create a reminder for this user to verify their account. | ||
* | ||
* @returns {boolean} | ||
*/ | ||
function shouldRemind() { | ||
// random between 0 and 100, inclusive | ||
var rand = Math.floor(Math.random() * (100 + 1)) | ||
return rand < (reminderConfig.rate * 100) | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
vladikoff
Author
Contributor
|
||
} | ||
|
||
return { | ||
/** | ||
* Create a new reminder | ||
* @param reminderData | ||
* @param {string} reminderData.uid - The uid to remind. | ||
*/ | ||
create: function createReminder(reminderData) { | ||
if (! shouldRemind()) { | ||
// resolves if not part of the verification roll out | ||
return P.resolve(false) | ||
} | ||
|
||
reminderData.type = 'first' | ||
var firstReminder = db.createVerificationReminder(reminderData) | ||
reminderData.type = 'second' | ||
var secondReminder = db.createVerificationReminder(reminderData) | ||
|
||
return P.all([firstReminder, secondReminder]) | ||
.then( | ||
function () { | ||
log.increment(LOG_REMINDERS_CREATED) | ||
}, | ||
function (err) { | ||
log.error({ op: LOG_REMINDERS_ERROR_CREATE, err: err }) | ||
} | ||
) | ||
}, | ||
/** | ||
* Delete the reminder. Used if the user verifies their account. | ||
* | ||
* @param reminderData | ||
* @param {string} reminderData.uid - The uid for the reminder. | ||
*/ | ||
'delete': function deleteReminder(reminderData) { | ||
reminderData.type = 'first' | ||
var firstReminder = db.deleteVerificationReminder(reminderData) | ||
reminderData.type = 'second' | ||
var secondReminder = db.deleteVerificationReminder(reminderData) | ||
|
||
return P.all([firstReminder, secondReminder]) | ||
.then( | ||
function () { | ||
log.increment(LOG_REMINDERS_DELETED) | ||
}, | ||
function (err) { | ||
log.error({ op: LOG_REMINDERS_ERROR_DELETE, err: err }) | ||
} | ||
) | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
/* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
||
require('ass') | ||
var tap = require('tap') | ||
var test = tap.test | ||
var uuid = require('uuid') | ||
var log = { trace: console.log, info: console.log } | ||
|
||
var config = require('../../config').getProperties() | ||
var TestServer = require('../test_server') | ||
var Token = require('../../lib/tokens')(log) | ||
var DB = require('../../lib/db')( | ||
config.db.backend, | ||
log, | ||
Token.error, | ||
Token.SessionToken, | ||
Token.KeyFetchToken, | ||
Token.AccountResetToken, | ||
Token.PasswordForgotToken, | ||
Token.PasswordChangeToken | ||
) | ||
|
||
var zeroBuffer16 = Buffer('00000000000000000000000000000000', 'hex') | ||
var zeroBuffer32 = Buffer('0000000000000000000000000000000000000000000000000000000000000000', 'hex') | ||
|
||
function createTestAccount() { | ||
return { | ||
uid: uuid.v4('binary'), | ||
email: 'reminder' + Math.random() + '@bar.com', | ||
emailCode: zeroBuffer16, | ||
emailVerified: false, | ||
verifierVersion: 1, | ||
verifyHash: zeroBuffer32, | ||
authSalt: zeroBuffer32, | ||
kA: zeroBuffer32, | ||
wrapWrapKb: zeroBuffer32, | ||
acceptLanguage: 'bg-BG,en-US;q=0.7,ar-BH;q=0.3' | ||
} | ||
} | ||
|
||
var mockLog = require('../mocks').mockLog | ||
|
||
var dbServer, reminderConfig | ||
var dbConn = TestServer.start(config) | ||
.then( | ||
function (server) { | ||
dbServer = server | ||
reminderConfig = process.env.VERIFICATION_REMINDER_RATE | ||
process.env.VERIFICATION_REMINDER_RATE = 1 | ||
return DB.connect(config[config.db.backend]) | ||
} | ||
) | ||
|
||
test( | ||
'create', | ||
function (t) { | ||
var thisMockLog = mockLog({ | ||
increment: function (name) { | ||
t.equal(name, 'verification-reminders.created') | ||
} | ||
}) | ||
|
||
dbConn.then(function (db) { | ||
var account = createTestAccount() | ||
var reminder = { uid: account.uid.toString('hex') } | ||
|
||
var verificationReminder = require('../../lib/verification-reminders')(thisMockLog, db) | ||
return verificationReminder.create(reminder).then( | ||
function () { | ||
t.end() | ||
}, | ||
function () { | ||
t.fail() | ||
} | ||
) | ||
}) | ||
} | ||
) | ||
|
||
test( | ||
'delete', | ||
function (t) { | ||
var thisMockLog = mockLog({ | ||
increment: function (name) { | ||
if (name === 'verification-reminders.deleted') { | ||
t.ok(true, 'correct log message') | ||
} | ||
} | ||
}) | ||
|
||
dbConn.then(function (db) { | ||
var verificationReminder = require('../../lib/verification-reminders')(thisMockLog, db) | ||
var account = createTestAccount() | ||
var reminder = { uid: account.uid.toString('hex') } | ||
|
||
return verificationReminder.create(reminder) | ||
.then(function () { | ||
return verificationReminder.delete(reminder) | ||
}) | ||
.then(function () { | ||
t.end() | ||
}, function (err) { | ||
t.notOk(err) | ||
}) | ||
}) | ||
} | ||
) | ||
|
||
test( | ||
'teardown', | ||
function (t) { | ||
return dbConn.then(function(db) { | ||
return db.close() | ||
}).then(function() { | ||
return dbServer.stop() | ||
}).then(function () { | ||
process.env.VERIFICATION_REMINDER_RATE = reminderConfig | ||
t.end() | ||
}) | ||
} | ||
) |
Oops, something went wrong.
This doesn't seem right.
If
Math.random()
is0.991
,rand
will be100
,rand < (reminderConfig.rate * 100)
will befalse
even with1
asreminderConfig.rate
.