mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-30 07:05:19 -05:00
Merge branch 'emailverification'
This commit is contained in:
commit
e4011b9ba1
26 changed files with 522 additions and 85 deletions
1
services/web/.gitignore
vendored
1
services/web/.gitignore
vendored
|
@ -44,6 +44,7 @@ cookies.txt
|
|||
requestQueueWorker.js
|
||||
TpdsWorker.js
|
||||
BackgroundJobsWorker.js
|
||||
UserAndProjectPopulator.coffee
|
||||
|
||||
public/js/history/versiondetail.js
|
||||
!public/js/libs/
|
||||
|
|
|
@ -299,7 +299,7 @@ module.exports = (grunt) ->
|
|||
|
||||
settings = require "settings-sharelatex"
|
||||
UserRegistrationHandler = require "./app/js/Features/User/UserRegistrationHandler"
|
||||
PasswordResetTokenHandler = require "./app/js/Features/PasswordReset/PasswordResetTokenHandler"
|
||||
OneTimeTokenHandler = require "./app/js/Features/Security/OneTimeTokenHandler"
|
||||
UserRegistrationHandler.registerNewUser {
|
||||
email: email
|
||||
password: require("crypto").randomBytes(32).toString("hex")
|
||||
|
@ -310,7 +310,7 @@ module.exports = (grunt) ->
|
|||
user.save (error) ->
|
||||
throw error if error?
|
||||
ONE_WEEK = 7 * 24 * 60 * 60 # seconds
|
||||
PasswordResetTokenHandler.getNewToken user._id, { expiresIn: ONE_WEEK }, (err, token)->
|
||||
OneTimeTokenHandler.getNewToken user._id, { expiresIn: ONE_WEEK }, (err, token)->
|
||||
return next(err) if err?
|
||||
|
||||
console.log ""
|
||||
|
|
|
@ -88,6 +88,28 @@ templates.projectSharedWithYou =
|
|||
<p> <a href="<%= siteUrl %>">#{settings.appName}</a></p>
|
||||
"""
|
||||
|
||||
|
||||
templates.completeJoinGroupAccount =
|
||||
subject: _.template "Verify Email to join <%= group_name %> group"
|
||||
layout: NotificationEmailLayout
|
||||
type:"notification"
|
||||
compiledTemplate: _.template """
|
||||
<p>Hi, please verify your email to join the <%= group_name %> and get your free premium account</p>
|
||||
<center>
|
||||
<div style="width:200px;background-color:#a93629;border:1px solid #e24b3b;border-radius:3px;padding:15px; margin:24px;">
|
||||
<div style="padding-right:10px;padding-left:10px">
|
||||
<a href="<%= completeJoinUrl %>" style="text-decoration:none" target="_blank">
|
||||
<span style= "font-size:16px;font-family:Helvetica,Arial;font-weight:400;color:#fff;white-space:nowrap;display:block; text-align:center">
|
||||
Verify now
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</center>
|
||||
<p> Thank you</p>
|
||||
<p> <a href="<%= siteUrl %>">#{settings.appName}</a></p>
|
||||
"""
|
||||
|
||||
module.exports =
|
||||
templates: templates
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
settings = require("settings-sharelatex")
|
||||
async = require("async")
|
||||
UserGetter = require("../User/UserGetter")
|
||||
PasswordResetTokenHandler = require("./PasswordResetTokenHandler")
|
||||
OneTimeTokenHandler = require("../Security/OneTimeTokenHandler")
|
||||
EmailHandler = require("../Email/EmailHandler")
|
||||
AuthenticationManager = require("../Authentication/AuthenticationManager")
|
||||
logger = require("logger-sharelatex")
|
||||
|
@ -14,7 +14,7 @@ module.exports =
|
|||
if !user? or user.holdingAccount
|
||||
logger.err email:email, "user could not be found for password reset"
|
||||
return callback(null, false)
|
||||
PasswordResetTokenHandler.getNewToken user._id, (err, token)->
|
||||
OneTimeTokenHandler.getNewToken user._id, (err, token)->
|
||||
if err then return callback(err)
|
||||
emailOptions =
|
||||
to : email
|
||||
|
@ -24,7 +24,7 @@ module.exports =
|
|||
callback null, true
|
||||
|
||||
setNewUserPassword: (token, password, callback = (error, found) ->)->
|
||||
PasswordResetTokenHandler.getUserIdFromTokenAndExpire token, (err, user_id)->
|
||||
OneTimeTokenHandler.getValueFromTokenAndExpire token, (err, user_id)->
|
||||
if err then return callback(err)
|
||||
if !user_id?
|
||||
return callback null, false
|
||||
|
|
|
@ -10,21 +10,21 @@ buildKey = (token)-> return "password_token:#{token}"
|
|||
|
||||
module.exports =
|
||||
|
||||
getNewToken: (user_id, options = {}, callback)->
|
||||
getNewToken: (value, options = {}, callback)->
|
||||
# options is optional
|
||||
if typeof options == "function"
|
||||
callback = options
|
||||
options = {}
|
||||
expiresIn = options.expiresIn or ONE_HOUR_IN_S
|
||||
logger.log user_id:user_id, "generating token for password reset"
|
||||
logger.log value:value, "generating token for password reset"
|
||||
token = crypto.randomBytes(32).toString("hex")
|
||||
multi = rclient.multi()
|
||||
multi.set buildKey(token), user_id
|
||||
multi.set buildKey(token), value
|
||||
multi.expire buildKey(token), expiresIn
|
||||
multi.exec (err)->
|
||||
callback(err, token)
|
||||
|
||||
getUserIdFromTokenAndExpire: (token, callback)->
|
||||
getValueFromTokenAndExpire: (token, callback)->
|
||||
logger.log token:token, "getting user id from password token"
|
||||
multi = rclient.multi()
|
||||
multi.get buildKey(token)
|
|
@ -8,7 +8,7 @@ RecurlyWrapper = require './RecurlyWrapper'
|
|||
Settings = require 'settings-sharelatex'
|
||||
logger = require('logger-sharelatex')
|
||||
GeoIpLookup = require("../../infrastructure/GeoIpLookup")
|
||||
|
||||
SubscriptionDomainHandler = require("./SubscriptionDomainHandler")
|
||||
|
||||
module.exports = SubscriptionController =
|
||||
|
||||
|
@ -84,9 +84,13 @@ module.exports = SubscriptionController =
|
|||
SecurityManager.getCurrentUser req, (error, user) =>
|
||||
return next(error) if error?
|
||||
LimitationsManager.userHasSubscriptionOrIsGroupMember user, (err, hasSubOrIsGroupMember, subscription)->
|
||||
groupLicenceInviteUrl = SubscriptionDomainHandler.getDomainLicencePage(user)
|
||||
if subscription?.customAccount
|
||||
logger.log user: user, "redirecting to plans"
|
||||
res.redirect "/user/subscription/custom_account"
|
||||
else if groupLicenceInviteUrl? and !hasSubOrIsGroupMember
|
||||
logger.log user:user, "redirecting to group subscription invite page"
|
||||
res.redirect groupLicenceInviteUrl
|
||||
else if !hasSubOrIsGroupMember
|
||||
logger.log user: user, "redirecting to plans"
|
||||
res.redirect "/user/subscription/plans"
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
async = require("async")
|
||||
_ = require("underscore")
|
||||
settings = require("settings-sharelatex")
|
||||
SubscriptionGroupHandler = require("./SubscriptionGroupHandler")
|
||||
_s = require("underscore.string")
|
||||
|
||||
module.exports = SubscriptionDomainAllocator =
|
||||
|
||||
autoAllocate: (user, callback = ->)->
|
||||
licence = SubscriptionDomainAllocator._findDomainLicence(user.email)
|
||||
if licence?
|
||||
SubscriptionGroupHandler.addUserToGroup licence.adminUser_id, user.email, callback
|
||||
else
|
||||
callback()
|
||||
|
||||
|
||||
_findDomainLicence: (email)->
|
||||
licence = _.find settings.domainLicences, (licence)->
|
||||
_.find licence.domains, (domain)->
|
||||
_s.endsWith email, domain
|
||||
|
||||
return licence
|
||||
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
async = require("async")
|
||||
_ = require("underscore")
|
||||
settings = require("settings-sharelatex")
|
||||
SubscriptionGroupHandler = require("./SubscriptionGroupHandler")
|
||||
_s = require("underscore.string")
|
||||
|
||||
module.exports = SubscriptionDomainHandler =
|
||||
|
||||
|
||||
getLicenceUserCanJoin: (user, callback)->
|
||||
licence = SubscriptionDomainHandler._findDomainLicence(user.email)
|
||||
if licence?
|
||||
callback null, licence
|
||||
else
|
||||
callback()
|
||||
|
||||
attemptToJoinGroup: (user, callback)->
|
||||
licence = SubscriptionDomainHandler._findDomainLicence(user.email)
|
||||
if licence? and user.emailVerified
|
||||
SubscriptionGroupHandler.addUserToGroup licence.adminUser_id, user.email, callback
|
||||
else
|
||||
callback "user not verified"
|
||||
|
||||
rejectInvitationToGroup: (user, subscription, callback)->
|
||||
removeUserFromGroup(subscription.admin_id, user._id, callback)
|
||||
|
||||
|
||||
getDomainLicencePage: (user)->
|
||||
licence = SubscriptionDomainHandler._findDomainLicence(user.email)
|
||||
if licence?.verifyEmail
|
||||
return "/user/subscription/#{licence.subscription_id}/group/invited"
|
||||
else
|
||||
return undefined
|
||||
|
||||
|
||||
autoAllocate: (user, callback = ->)->
|
||||
licence = SubscriptionDomainHandler._findDomainLicence(user.email)
|
||||
#
|
||||
if licence?
|
||||
SubscriptionGroupHandler.addUserToGroup licence.adminUser_id, user.email, callback
|
||||
else
|
||||
callback()
|
||||
|
||||
|
||||
_findDomainLicence: (email)->
|
||||
licence = _.find settings.domainLicences, (licence)->
|
||||
_.find licence.domains, (domain)->
|
||||
_s.endsWith email, domain
|
||||
|
||||
return licence
|
||||
|
||||
findDomainLicenceBySubscriptionId: (subscription_id)->
|
||||
licence = _.find settings.domainLicences, (licence)->
|
||||
licence?.subscription_id == subscription_id
|
||||
return licence
|
||||
|
|
@ -2,6 +2,12 @@ SubscriptionGroupHandler = require("./SubscriptionGroupHandler")
|
|||
logger = require("logger-sharelatex")
|
||||
SubscriptionLocator = require("./SubscriptionLocator")
|
||||
|
||||
ErrorsController = require("../Errors/ErrorController")
|
||||
settings = require("settings-sharelatex")
|
||||
|
||||
SubscriptionDomainHandler = require("./SubscriptionDomainHandler")
|
||||
_ = require("underscore")
|
||||
|
||||
module.exports =
|
||||
|
||||
addUserToGroup: (req, res)->
|
||||
|
@ -32,3 +38,50 @@ module.exports =
|
|||
title: 'group_admin'
|
||||
users: users
|
||||
subscription: subscription
|
||||
|
||||
renderGroupInvitePage: (req, res)->
|
||||
subscription_id = req.params.subscription_id
|
||||
user_id = req.session.user._id
|
||||
licence = SubscriptionDomainHandler.findDomainLicenceBySubscriptionId(subscription_id)
|
||||
if !licence?
|
||||
return ErrorsController.notFound(req, res)
|
||||
SubscriptionGroupHandler.isUserPartOfGroup user_id, licence.subscription_id, (err, partOfGroup)->
|
||||
if partOfGroup
|
||||
return res.redirect("/user/subscription/custom_account")
|
||||
else
|
||||
res.render "subscriptions/group/invite",
|
||||
title: "Group Invitation"
|
||||
subscription_id:subscription_id
|
||||
licenceName:licence.name
|
||||
|
||||
beginJoinGroup: (req, res)->
|
||||
subscription_id = req.params.subscription_id
|
||||
user_id = req.session.user._id
|
||||
licence = SubscriptionDomainHandler.findDomainLicenceBySubscriptionId(subscription_id)
|
||||
if !licence?
|
||||
return ErrorsController.notFound(req, res)
|
||||
SubscriptionGroupHandler.sendVerificationEmail subscription_id, licence.name, req.session.user.email, (err)->
|
||||
if err?
|
||||
res.send 500
|
||||
else
|
||||
res.send 200
|
||||
|
||||
completeJoin: (req, res)->
|
||||
subscription_id = req.params.subscription_id
|
||||
if !SubscriptionDomainHandler.findDomainLicenceBySubscriptionId(subscription_id)?
|
||||
return ErrorsController.notFound(req, res)
|
||||
SubscriptionGroupHandler.processGroupVerification req.session.user.email, subscription_id, req.query.token, (err)->
|
||||
if err?
|
||||
res.send 500
|
||||
else
|
||||
res.redirect "/user/subscription/#{subscription_id}/group/successful-join"
|
||||
|
||||
renderSuccessfulJoinPage: (req, res)->
|
||||
subscription_id = req.params.subscription_id
|
||||
licence = SubscriptionDomainHandler.findDomainLicenceBySubscriptionId(subscription_id)
|
||||
if !SubscriptionDomainHandler.findDomainLicenceBySubscriptionId(subscription_id)?
|
||||
return ErrorsController.notFound(req, res)
|
||||
res.render "subscriptions/group/successful_join",
|
||||
title: "Sucessfully joined group"
|
||||
licenceName:licence.name
|
||||
|
||||
|
|
|
@ -5,9 +5,12 @@ SubscriptionUpdater = require("./SubscriptionUpdater")
|
|||
SubscriptionLocator = require("./SubscriptionLocator")
|
||||
UserLocator = require("../User/UserLocator")
|
||||
LimitationsManager = require("./LimitationsManager")
|
||||
logger = require("logger-sharelatex")
|
||||
OneTimeTokenHandler = require("../Security/OneTimeTokenHandler")
|
||||
EmailHandler = require("../Email/EmailHandler")
|
||||
settings = require("settings-sharelatex")
|
||||
|
||||
|
||||
module.exports =
|
||||
module.exports = SubscriptionGroupHandler =
|
||||
|
||||
addUserToGroup: (adminUser_id, newEmail, callback)->
|
||||
UserCreator.getUserOrCreateHoldingAccount newEmail, (err, user)->
|
||||
|
@ -37,6 +40,32 @@ module.exports =
|
|||
async.series jobs, (err)->
|
||||
callback(err, users)
|
||||
|
||||
isUserPartOfGroup: (user_id, subscription_id, callback=(err, partOfGroup)->)->
|
||||
SubscriptionLocator.getSubscriptionByMemberIdAndId user_id, subscription_id, (err, subscription)->
|
||||
if subscription?
|
||||
partOfGroup = true
|
||||
else
|
||||
partOfGroup = false
|
||||
logger.log user_id:user_id, subscription_id:subscription_id, partOfGroup:partOfGroup, "checking if user is part of a group"
|
||||
callback(err, partOfGroup)
|
||||
|
||||
|
||||
sendVerificationEmail: (subscription_id, licenceName, email, callback)->
|
||||
OneTimeTokenHandler.getNewToken subscription_id, (err, token)->
|
||||
opts =
|
||||
to : email
|
||||
group_name: licenceName
|
||||
completeJoinUrl: "#{settings.siteUrl}/user/subscription/#{subscription_id}/group/complete-join?token=#{token}"
|
||||
EmailHandler.sendEmail "completeJoinGroupAccount", opts, callback
|
||||
|
||||
processGroupVerification: (userEmail, subscription_id, token, callback)->
|
||||
OneTimeTokenHandler.getValueFromTokenAndExpire token, (err, token_subscription_id)->
|
||||
if err? or subscription_id != token_subscription_id
|
||||
logger.err userEmail:userEmail, token:token, "token value not found for processing group verification"
|
||||
return callback("token not found")
|
||||
SubscriptionLocator.getSubscription subscription_id, (err, subscription)->
|
||||
SubscriptionGroupHandler.addUserToGroup subscription.admin_id, userEmail, callback
|
||||
|
||||
|
||||
buildUserViewModel = (user)->
|
||||
u =
|
||||
|
|
|
@ -15,3 +15,9 @@ module.exports =
|
|||
getMemberSubscriptions: (user_id, callback) ->
|
||||
logger.log user_id: user_id, "getting users group subscriptions"
|
||||
Subscription.find(member_ids: user_id).populate("admin_id").exec callback
|
||||
|
||||
getSubscription: (subscription_id, callback)->
|
||||
Subscription.findOne _id:subscription_id, callback
|
||||
|
||||
getSubscriptionByMemberIdAndId: (user_id, subscription_id, callback)->
|
||||
Subscription.findOne member_ids: user_id, _id:subscription_id, callback
|
||||
|
|
|
@ -24,6 +24,10 @@ module.exports =
|
|||
app.post '/subscription/group/user', AuthenticationController.requireLogin(), SubscriptionGroupController.addUserToGroup
|
||||
app.del '/subscription/group/user/:user_id', AuthenticationController.requireLogin(), SubscriptionGroupController.removeUserFromGroup
|
||||
|
||||
app.get '/user/subscription/:subscription_id/group/invited', AuthenticationController.requireLogin(), SubscriptionGroupController.renderGroupInvitePage
|
||||
app.post '/user/subscription/:subscription_id/group/begin-join', AuthenticationController.requireLogin(), SubscriptionGroupController.beginJoinGroup
|
||||
app.get '/user/subscription/:subscription_id/group/complete-join', AuthenticationController.requireLogin(), SubscriptionGroupController.completeJoin
|
||||
app.get '/user/subscription/:subscription_id/group/successful-join', AuthenticationController.requireLogin(), SubscriptionGroupController.renderSuccessfulJoinPage
|
||||
|
||||
#recurly callback
|
||||
app.post '/user/subscription/callback', SubscriptionController.recurlyNotificationParser, SubscriptionController.recurlyCallback
|
||||
|
|
|
@ -8,9 +8,9 @@ metrics = require("../../infrastructure/Metrics")
|
|||
Url = require("url")
|
||||
AuthenticationManager = require("../Authentication/AuthenticationManager")
|
||||
UserUpdater = require("./UserUpdater")
|
||||
SubscriptionDomainAllocator = require("../Subscription/SubscriptionDomainAllocator")
|
||||
SubscriptionDomainHandler = require("../Subscription/SubscriptionDomainHandler")
|
||||
EmailHandler = require("../Email/EmailHandler")
|
||||
PasswordResetTokenHandler = require "../PasswordReset/PasswordResetTokenHandler"
|
||||
OneTimeTokenHandler = require "../Security/OneTimeTokenHandler"
|
||||
settings = require "settings-sharelatex"
|
||||
crypto = require "crypto"
|
||||
|
||||
|
@ -98,7 +98,7 @@ module.exports =
|
|||
logger.log {email}, "user already exists, resending welcome email"
|
||||
|
||||
ONE_WEEK = 7 * 24 * 60 * 60 # seconds
|
||||
PasswordResetTokenHandler.getNewToken user._id, { expiresIn: ONE_WEEK }, (err, token)->
|
||||
OneTimeTokenHandler.getNewToken user._id, { expiresIn: ONE_WEEK }, (err, token)->
|
||||
return next(err) if err?
|
||||
|
||||
setNewPasswordUrl = "#{settings.siteUrl}/user/password/set?passwordResetToken=#{token}&email=#{encodeURIComponent(email)}"
|
||||
|
|
|
@ -53,7 +53,6 @@ UserSchema = new Schema
|
|||
# has this set to true, despite never having had a free trial
|
||||
hadFreeTrial: {type: Boolean, default: false}
|
||||
|
||||
|
||||
UserSchema.statics.getAllIds = (callback)->
|
||||
this.find {}, ["first_name"], callback
|
||||
|
||||
|
|
35
services/web/app/views/subscriptions/group/invite.jade
Normal file
35
services/web/app/views/subscriptions/group/invite.jade
Normal file
|
@ -0,0 +1,35 @@
|
|||
extends ../../layout
|
||||
|
||||
block scripts
|
||||
script(type='text/javascript').
|
||||
window.subscription_id = '#{subscription_id}'
|
||||
|
||||
block content
|
||||
.content.content-alt
|
||||
.container
|
||||
.row
|
||||
.col-md-8.col-md-offset-2(ng-cloak)
|
||||
.card(ng-controller="GroupSubscriptionInviteController")
|
||||
.page-header
|
||||
h1.text-centered #{translate("you_are_invited_to_group", {groupName:licenceName})}
|
||||
div(ng-show="!requestSent").row.text-centered
|
||||
.row
|
||||
.col-md-12 #{translate("group_provides_you_with_premium_account", {groupName:licenceName})}
|
||||
.row
|
||||
.col-md-12
|
||||
.row
|
||||
.col-md-12
|
||||
.text-center
|
||||
a.btn.btn-default(href="/project") #{translate("not_now")}
|
||||
|
||||
a.btn.btn.btn-primary(ng-click="joinGroup()") #{translate("verify_email_address")}
|
||||
|
||||
|
||||
span(ng-show="requestSent").row.text-centered.text-center
|
||||
.row
|
||||
.col-md-12 #{translate("check_email_to_complete_the_upgrade")}
|
||||
.row
|
||||
.col-md-12
|
||||
.row
|
||||
.col-md-12
|
||||
a.btn.btn.btn-primary(href="/project") #{translate("done")}
|
|
@ -0,0 +1,25 @@
|
|||
extends ../../layout
|
||||
|
||||
block scripts
|
||||
script(type='text/javascript').
|
||||
window.subscription_id = '#{subscription_id}'
|
||||
|
||||
block content
|
||||
.content.content-alt
|
||||
.container
|
||||
.row
|
||||
.col-md-8.col-md-offset-2(ng-cloak)
|
||||
.card
|
||||
.page-header.row.text-centered
|
||||
h1 #{translate("you_have_joined", {groupName:licenceName})}
|
||||
div(ng-show="!requestSent").row.text-centered
|
||||
.row
|
||||
.span-md-12 #{translate("claim_premium_account", {groupName:licenceName})}
|
||||
div
|
||||
.row
|
||||
.col-md-12
|
||||
.row
|
||||
.span-md-12
|
||||
a.btn.btn-success(href="/project") #{translate("Done")}
|
||||
|
||||
|
|
@ -349,6 +349,10 @@ module.exports =
|
|||
|
||||
reloadModuleViewsOnEachRequest: true
|
||||
|
||||
domainLicences: [
|
||||
|
||||
]
|
||||
|
||||
# ShareLaTeX Server Pro options (https://www.sharelatex.com/university/onsite.html)
|
||||
# ----------
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ define [
|
|||
"main/new-subscription"
|
||||
"main/annual-upgrade"
|
||||
"main/register-users"
|
||||
"main/subscription/group-subscription-invite-controller"
|
||||
"analytics/AbTestingManager"
|
||||
"directives/asyncForm"
|
||||
"directives/stopPropagation"
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
define [
|
||||
"base"
|
||||
], (App) ->
|
||||
App.controller "GroupSubscriptionInviteController", ($scope, $http) ->
|
||||
|
||||
$scope.requestSent = false
|
||||
|
||||
$scope.joinGroup = ->
|
||||
$scope.requestSent = true
|
||||
request = $http.post "/user/subscription/#{subscription_id}/group/begin-join", {_csrf:window.csrfToken}
|
||||
request.success (data, status)->
|
||||
if status != 200 # assume request worked
|
||||
$scope.requestSent = false
|
||||
request.error (data, status)->
|
||||
console.log "the request failed"
|
|
@ -12,9 +12,9 @@ describe "PasswordResetHandler", ->
|
|||
|
||||
@settings =
|
||||
siteUrl: "www.sharelatex.com"
|
||||
@PasswordResetTokenHandler =
|
||||
@OneTimeTokenHandler =
|
||||
getNewToken:sinon.stub()
|
||||
getUserIdFromTokenAndExpire:sinon.stub()
|
||||
getValueFromTokenAndExpire:sinon.stub()
|
||||
@UserGetter =
|
||||
getUser:sinon.stub()
|
||||
@EmailHandler =
|
||||
|
@ -23,7 +23,7 @@ describe "PasswordResetHandler", ->
|
|||
setUserPassword:sinon.stub()
|
||||
@PasswordResetHandler = SandboxedModule.require modulePath, requires:
|
||||
"../User/UserGetter": @UserGetter
|
||||
"./PasswordResetTokenHandler": @PasswordResetTokenHandler
|
||||
"../Security/OneTimeTokenHandler": @OneTimeTokenHandler
|
||||
"../Email/EmailHandler":@EmailHandler
|
||||
"../Authentication/AuthenticationManager":@AuthenticationManager
|
||||
"settings-sharelatex": @settings
|
||||
|
@ -41,7 +41,7 @@ describe "PasswordResetHandler", ->
|
|||
|
||||
it "should check the user exists", (done)->
|
||||
@UserGetter.getUser.callsArgWith(1)
|
||||
@PasswordResetTokenHandler.getNewToken.callsArgWith(1)
|
||||
@OneTimeTokenHandler.getNewToken.callsArgWith(1)
|
||||
@PasswordResetHandler.generateAndEmailResetToken @user.email, (err, exists)=>
|
||||
exists.should.equal false
|
||||
done()
|
||||
|
@ -50,7 +50,7 @@ describe "PasswordResetHandler", ->
|
|||
it "should send the email with the token", (done)->
|
||||
|
||||
@UserGetter.getUser.callsArgWith(1, null, @user)
|
||||
@PasswordResetTokenHandler.getNewToken.callsArgWith(1, null, @token)
|
||||
@OneTimeTokenHandler.getNewToken.callsArgWith(1, null, @token)
|
||||
@EmailHandler.sendEmail.callsArgWith(2)
|
||||
@PasswordResetHandler.generateAndEmailResetToken @user.email, (err, exists)=>
|
||||
@EmailHandler.sendEmail.called.should.equal true
|
||||
|
@ -63,7 +63,7 @@ describe "PasswordResetHandler", ->
|
|||
it "should return exists = false for a holdingAccount", (done) ->
|
||||
@user.holdingAccount = true
|
||||
@UserGetter.getUser.callsArgWith(1, null, @user)
|
||||
@PasswordResetTokenHandler.getNewToken.callsArgWith(1)
|
||||
@OneTimeTokenHandler.getNewToken.callsArgWith(1)
|
||||
@PasswordResetHandler.generateAndEmailResetToken @user.email, (err, exists)=>
|
||||
exists.should.equal false
|
||||
done()
|
||||
|
@ -71,14 +71,14 @@ describe "PasswordResetHandler", ->
|
|||
describe "setNewUserPassword", ->
|
||||
|
||||
it "should return false if no user id can be found", (done)->
|
||||
@PasswordResetTokenHandler.getUserIdFromTokenAndExpire.callsArgWith(1)
|
||||
@OneTimeTokenHandler.getValueFromTokenAndExpire.callsArgWith(1)
|
||||
@PasswordResetHandler.setNewUserPassword @token, @password, (err, found) =>
|
||||
found.should.equal false
|
||||
@AuthenticationManager.setUserPassword.called.should.equal false
|
||||
done()
|
||||
|
||||
it "should set the user password", (done)->
|
||||
@PasswordResetTokenHandler.getUserIdFromTokenAndExpire.callsArgWith(1, null, @user_id)
|
||||
@OneTimeTokenHandler.getValueFromTokenAndExpire.callsArgWith(1, null, @user_id)
|
||||
@AuthenticationManager.setUserPassword.callsArgWith(2)
|
||||
@PasswordResetHandler.setNewUserPassword @token, @password, (err, found) =>
|
||||
found.should.equal true
|
||||
|
|
|
@ -3,13 +3,13 @@ SandboxedModule = require('sandboxed-module')
|
|||
assert = require('assert')
|
||||
path = require('path')
|
||||
sinon = require('sinon')
|
||||
modulePath = path.join __dirname, "../../../../app/js/Features/PasswordReset/PasswordResetTokenHandler"
|
||||
modulePath = path.join __dirname, "../../../../app/js/Features/Security/OneTimeTokenHandler"
|
||||
expect = require("chai").expect
|
||||
|
||||
describe "PasswordResetTokenHandler", ->
|
||||
describe "OneTimeTokenHandler", ->
|
||||
|
||||
beforeEach ->
|
||||
@user_id = "user id here"
|
||||
@value = "user id here"
|
||||
@stubbedToken = require("crypto").randomBytes(32)
|
||||
|
||||
@settings =
|
||||
|
@ -22,7 +22,7 @@ describe "PasswordResetTokenHandler", ->
|
|||
expire:sinon.stub()
|
||||
exec:sinon.stub()
|
||||
self = @
|
||||
@PasswordResetTokenHandler = SandboxedModule.require modulePath, requires:
|
||||
@OneTimeTokenHandler = SandboxedModule.require modulePath, requires:
|
||||
"redis-sharelatex" :
|
||||
createClient: =>
|
||||
auth:->
|
||||
|
@ -37,30 +37,30 @@ describe "PasswordResetTokenHandler", ->
|
|||
|
||||
it "should set a new token into redis with a ttl", (done)->
|
||||
@redisMulti.exec.callsArgWith(0)
|
||||
@PasswordResetTokenHandler.getNewToken @user_id, (err, token) =>
|
||||
@redisMulti.set.calledWith("password_token:#{@stubbedToken.toString("hex")}", @user_id).should.equal true
|
||||
@OneTimeTokenHandler.getNewToken @value, (err, token) =>
|
||||
@redisMulti.set.calledWith("password_token:#{@stubbedToken.toString("hex")}", @value).should.equal true
|
||||
@redisMulti.expire.calledWith("password_token:#{@stubbedToken.toString("hex")}", 60 * 60).should.equal true
|
||||
done()
|
||||
|
||||
it "should return if there was an error", (done)->
|
||||
@redisMulti.exec.callsArgWith(0, "error")
|
||||
@PasswordResetTokenHandler.getNewToken @user_id, (err, token)=>
|
||||
@OneTimeTokenHandler.getNewToken @value, (err, token)=>
|
||||
err.should.exist
|
||||
done()
|
||||
|
||||
it "should allow the expiry time to be overridden", (done) ->
|
||||
@redisMulti.exec.callsArgWith(0)
|
||||
@ttl = 42
|
||||
@PasswordResetTokenHandler.getNewToken @user_id, {expiresIn: @ttl}, (err, token) =>
|
||||
@OneTimeTokenHandler.getNewToken @value, {expiresIn: @ttl}, (err, token) =>
|
||||
@redisMulti.expire.calledWith("password_token:#{@stubbedToken.toString("hex")}", @ttl).should.equal true
|
||||
done()
|
||||
|
||||
describe "getUserIdFromTokenAndExpire", ->
|
||||
describe "getValueFromTokenAndExpire", ->
|
||||
|
||||
it "should get and delete the token", (done)->
|
||||
@redisMulti.exec.callsArgWith(0, null, [@user_id])
|
||||
@PasswordResetTokenHandler.getUserIdFromTokenAndExpire @stubbedToken, (err, user_id)=>
|
||||
user_id.should.equal @user_id
|
||||
@redisMulti.exec.callsArgWith(0, null, [@value])
|
||||
@OneTimeTokenHandler.getValueFromTokenAndExpire @stubbedToken, (err, value)=>
|
||||
value.should.equal @value
|
||||
@redisMulti.get.calledWith("password_token:#{@stubbedToken}").should.equal true
|
||||
@redisMulti.del.calledWith("password_token:#{@stubbedToken}").should.equal true
|
||||
done()
|
|
@ -58,7 +58,8 @@ describe "SubscriptionController sanboxed", ->
|
|||
gaExperiments:{}
|
||||
@GeoIpLookup =
|
||||
getCurrencyCode:sinon.stub()
|
||||
|
||||
@SubscriptionDomainHandler =
|
||||
getDomainLicencePage:sinon.stub()
|
||||
@SubscriptionController = SandboxedModule.require modulePath, requires:
|
||||
'../../managers/SecurityManager': @SecurityManager
|
||||
'./SubscriptionHandler': @SubscriptionHandler
|
||||
|
@ -69,6 +70,7 @@ describe "SubscriptionController sanboxed", ->
|
|||
'./RecurlyWrapper': @RecurlyWrapper
|
||||
"logger-sharelatex": log:->
|
||||
"settings-sharelatex": @settings
|
||||
"./SubscriptionDomainHandler":@SubscriptionDomainHandler
|
||||
|
||||
|
||||
@res = new MockResponse()
|
||||
|
@ -206,6 +208,31 @@ describe "SubscriptionController sanboxed", ->
|
|||
@res.redirected.should.equal true
|
||||
@res.redirectedTo.should.equal "/user/subscription/plans"
|
||||
|
||||
describe "with a potential domain licence", ->
|
||||
beforeEach () ->
|
||||
@groupUrl = "/go/over-here"
|
||||
@SubscriptionDomainHandler.getDomainLicencePage.returns(@groupUrl)
|
||||
|
||||
describe "without an existing subscription", ->
|
||||
beforeEach (done)->
|
||||
@res.callback = done
|
||||
@LimitationsManager.userHasSubscriptionOrIsGroupMember.callsArgWith(1, null, false)
|
||||
@SubscriptionController.userSubscriptionPage @req, @res
|
||||
|
||||
it "should redirect to the group invite url", ->
|
||||
@res.redirected.should.equal true
|
||||
@res.redirectedTo.should.equal @groupUrl
|
||||
|
||||
describe "with an existing subscription", ->
|
||||
beforeEach (done)->
|
||||
@res.callback = done
|
||||
@LimitationsManager.userHasSubscriptionOrIsGroupMember.callsArgWith(1, null, true)
|
||||
@SubscriptionController.userSubscriptionPage @req, @res
|
||||
|
||||
|
||||
it "should render the dashboard", ->
|
||||
@res.renderedTemplate.should.equal "subscriptions/dashboard"
|
||||
|
||||
describe "with a user with a paid subscription", ->
|
||||
beforeEach (done) ->
|
||||
@res.callback = done
|
||||
|
|
|
@ -3,10 +3,10 @@ SandboxedModule = require('sandboxed-module')
|
|||
assert = require('assert')
|
||||
path = require('path')
|
||||
sinon = require('sinon')
|
||||
modulePath = path.join __dirname, "../../../../app/js/Features/Subscription/SubscriptionDomainAllocator"
|
||||
modulePath = path.join __dirname, "../../../../app/js/Features/Subscription/SubscriptionDomainHandler"
|
||||
expect = require("chai").expect
|
||||
|
||||
describe "SubscriptionDomainAllocator", ->
|
||||
describe "SubscriptionDomainHandler", ->
|
||||
|
||||
beforeEach ->
|
||||
|
||||
|
@ -18,43 +18,41 @@ describe "SubscriptionDomainAllocator", ->
|
|||
]
|
||||
@SubscriptionGroupHandler =
|
||||
addUserToGroup: sinon.stub().callsArg(2)
|
||||
@SubscriptionDomainAllocator = SandboxedModule.require modulePath, requires:
|
||||
@SubscriptionDomainHandler = SandboxedModule.require modulePath, requires:
|
||||
"settings-sharelatex":@settings
|
||||
"logger-sharelatex": log:->
|
||||
"./SubscriptionGroupHandler": @SubscriptionGroupHandler
|
||||
|
||||
|
||||
|
||||
describe "_findDomainLicence", ->
|
||||
|
||||
it "should find the domain", (done)->
|
||||
licence = @SubscriptionDomainAllocator._findDomainLicence "bob@uni.edu"
|
||||
licence = @SubscriptionDomainHandler._findDomainLicence "bob@uni.edu"
|
||||
licence.adminUser_id.should.equal @adminUser_id
|
||||
done()
|
||||
|
||||
it "should find one of the other emails in the domain list", (done)->
|
||||
licence = @SubscriptionDomainAllocator._findDomainLicence "sally@student.uni.edu"
|
||||
licence = @SubscriptionDomainHandler._findDomainLicence "sally@student.uni.edu"
|
||||
licence.adminUser_id.should.equal @adminUser_id
|
||||
done()
|
||||
|
||||
it "should return undefined if no licence matches", (done)->
|
||||
licence = @SubscriptionDomainAllocator._findDomainLicence "bob@other.edu"
|
||||
licence = @SubscriptionDomainHandler._findDomainLicence "bob@other.edu"
|
||||
expect(licence).to.not.exist
|
||||
done(licence)
|
||||
|
||||
describe "autoAllocate", ->
|
||||
beforeEach ->
|
||||
@email = "bob@somewhere.com"
|
||||
@SubscriptionDomainAllocator._findDomainLicence = sinon.stub()
|
||||
@SubscriptionDomainHandler._findDomainLicence = sinon.stub()
|
||||
|
||||
it "should call the SubscriptionGroupHandler if there is licence", (done)->
|
||||
@SubscriptionDomainAllocator._findDomainLicence.returns(@settings.domainLicences[1])
|
||||
@SubscriptionDomainAllocator.autoAllocate {email:@email}, (err)=>
|
||||
@SubscriptionDomainHandler._findDomainLicence.returns(@settings.domainLicences[1])
|
||||
@SubscriptionDomainHandler.autoAllocate {email:@email}, (err)=>
|
||||
@SubscriptionGroupHandler.addUserToGroup.calledWith(@adminUser_id, @email).should.equal true
|
||||
done()
|
||||
|
||||
it "should not call the SubscriptionGroupHandler if there is no licence", (done)->
|
||||
@SubscriptionDomainAllocator._findDomainLicence.returns()
|
||||
@SubscriptionDomainAllocator.autoAllocate {email:@email}, (err)=>
|
||||
@SubscriptionDomainHandler._findDomainLicence.returns()
|
||||
@SubscriptionDomainHandler.autoAllocate {email:@email}, (err)=>
|
||||
@SubscriptionGroupHandler.addUserToGroup.called.should.equal false
|
||||
done()
|
|
@ -13,16 +13,42 @@ describe "Subscription Group Controller", ->
|
|||
@GroupHandler =
|
||||
addUserToGroup: sinon.stub().callsArgWith(2, null, @user)
|
||||
removeUserFromGroup: sinon.stub().callsArgWith(2)
|
||||
isUserPartOfGroup: sinon.stub()
|
||||
sendVerificationEmail:sinon.stub()
|
||||
processGroupVerification:sinon.stub()
|
||||
|
||||
@SubscriptionLocator = getUsersSubscription: sinon.stub().callsArgWith(1, null, @subscription)
|
||||
|
||||
@SubscriptionDomainHandler =
|
||||
findDomainLicenceBySubscriptionId:sinon.stub()
|
||||
|
||||
@OneTimeTokenHandler =
|
||||
getValueFromTokenAndExpire:sinon.stub()
|
||||
|
||||
|
||||
@ErrorsController =
|
||||
notFound:sinon.stub()
|
||||
|
||||
@Controller = SandboxedModule.require modulePath, requires:
|
||||
"./SubscriptionGroupHandler":@GroupHandler
|
||||
"logger-sharelatex": log:->
|
||||
"./SubscriptionLocator": @SubscriptionLocator
|
||||
"./SubscriptionDomainHandler":@SubscriptionDomainHandler
|
||||
"../Errors/ErrorController":@ErrorsController
|
||||
|
||||
@adminUserId = "123jlkj"
|
||||
@subscription_id = "123434325412"
|
||||
@user_email = "bob@gmail.com"
|
||||
@req =
|
||||
session:
|
||||
user: _id: @adminUserId
|
||||
user:
|
||||
_id: @adminUserId
|
||||
email:@user_email
|
||||
params:
|
||||
subscription_id:@subscription_id
|
||||
query:{}
|
||||
|
||||
@token = "super-secret-token"
|
||||
|
||||
|
||||
describe "addUserToGroup", ->
|
||||
|
@ -59,3 +85,85 @@ describe "Subscription Group Controller", ->
|
|||
path.should.equal("/")
|
||||
done()
|
||||
@Controller.renderSubscriptionGroupAdminPage @req, res
|
||||
|
||||
|
||||
describe "renderGroupInvitePage", ->
|
||||
describe "with a valid licence", ->
|
||||
beforeEach ->
|
||||
@SubscriptionDomainHandler.findDomainLicenceBySubscriptionId.returns({subscription_id:@subscription_id, adminUser_id:@adminUserId})
|
||||
|
||||
it "should render subscriptions/group/invite if not part of group", (done)->
|
||||
@GroupHandler.isUserPartOfGroup.callsArgWith(2, null, false)
|
||||
res =
|
||||
render : (pageName)=>
|
||||
pageName.should.equal "subscriptions/group/invite"
|
||||
done()
|
||||
@Controller.renderGroupInvitePage @req, res
|
||||
|
||||
it "should redirect to custom page if is already part of group", (done)->
|
||||
@GroupHandler.isUserPartOfGroup.callsArgWith(2, null, true)
|
||||
res =
|
||||
redirect : (location)=>
|
||||
location.should.equal "/user/subscription/custom_account"
|
||||
done()
|
||||
@Controller.renderGroupInvitePage @req, res
|
||||
|
||||
describe "without a valid licence", ->
|
||||
beforeEach ->
|
||||
@SubscriptionDomainHandler.findDomainLicenceBySubscriptionId.returns(undefined)
|
||||
|
||||
it "should send a 500", (done)->
|
||||
@Controller.renderGroupInvitePage @req, {}
|
||||
@ErrorsController.notFound.called.should.equal true
|
||||
done()
|
||||
|
||||
|
||||
|
||||
describe "beginJoinGroup", ->
|
||||
describe "with a valid licence", ->
|
||||
beforeEach ->
|
||||
@licenceName = "get amazing licence"
|
||||
@SubscriptionDomainHandler.findDomainLicenceBySubscriptionId.returns({name:@licenceName})
|
||||
@GroupHandler.sendVerificationEmail.callsArgWith(3)
|
||||
|
||||
it "should ask the SubscriptionGroupHandler to send the verification email", (done)->
|
||||
res =
|
||||
send : (statusCode)=>
|
||||
statusCode.should.equal 200
|
||||
@GroupHandler.sendVerificationEmail.calledWith(@subscription_id, @licenceName, @user_email).should.equal true
|
||||
done()
|
||||
@Controller.beginJoinGroup @req, res
|
||||
|
||||
describe "without a valid licence", ->
|
||||
beforeEach ->
|
||||
@SubscriptionDomainHandler.findDomainLicenceBySubscriptionId.returns(undefined)
|
||||
|
||||
it "should send a 500", (done)->
|
||||
@Controller.beginJoinGroup @req, {}
|
||||
@ErrorsController.notFound.called.should.equal true
|
||||
done()
|
||||
|
||||
|
||||
describe "completeJoin", ->
|
||||
describe "with a valid licence", ->
|
||||
beforeEach ->
|
||||
@GroupHandler.processGroupVerification.callsArgWith(3)
|
||||
@SubscriptionDomainHandler.findDomainLicenceBySubscriptionId.returns({name:@licenceName})
|
||||
|
||||
it "should redirect to the success page upon processGroupVerification", (done)->
|
||||
@req.query.token = @token
|
||||
res =
|
||||
redirect : (location)=>
|
||||
@GroupHandler.processGroupVerification.calledWith(@user_email, @subscription_id, @token).should.equal true
|
||||
location.should.equal "/user/subscription/#{@subscription_id}/group/successful-join"
|
||||
done()
|
||||
@Controller.completeJoin @req, res
|
||||
|
||||
describe "without a valid licence", ->
|
||||
beforeEach ->
|
||||
@SubscriptionDomainHandler.findDomainLicenceBySubscriptionId.returns(undefined)
|
||||
|
||||
it "should send a 500", (done)->
|
||||
@Controller.completeJoin @req, {}
|
||||
@ErrorsController.notFound.called.should.equal true
|
||||
done()
|
|
@ -10,10 +10,13 @@ describe "Subscription Group Handler", ->
|
|||
beforeEach ->
|
||||
@adminUser_id = "12321"
|
||||
@newEmail = "bob@smith.com"
|
||||
@user = {_id:"3121321", email:@newEmail}
|
||||
@user_id = "3121321"
|
||||
@user = {_id:@user_id, email:@newEmail}
|
||||
|
||||
@SubscriptionLocator =
|
||||
getUsersSubscription: sinon.stub()
|
||||
getSubscriptionByMemberIdAndId: sinon.stub()
|
||||
getSubscription: sinon.stub()
|
||||
|
||||
@UserCreator =
|
||||
getUserOrCreateHoldingAccount: sinon.stub().callsArgWith(1, null, @user)
|
||||
|
@ -28,6 +31,16 @@ describe "Subscription Group Handler", ->
|
|||
@LimitationsManager =
|
||||
hasGroupMembersLimitReached: sinon.stub()
|
||||
|
||||
@OneTimeTokenHandler =
|
||||
getValueFromTokenAndExpire:sinon.stub()
|
||||
getNewToken:sinon.stub()
|
||||
|
||||
@EmailHandler =
|
||||
sendEmail:sinon.stub()
|
||||
|
||||
@settings =
|
||||
siteUrl:"http://www.sharelatex.com"
|
||||
|
||||
@Handler = SandboxedModule.require modulePath, requires:
|
||||
"logger-sharelatex": log:->
|
||||
"../User/UserCreator": @UserCreator
|
||||
|
@ -35,6 +48,13 @@ describe "Subscription Group Handler", ->
|
|||
"./SubscriptionLocator": @SubscriptionLocator
|
||||
"../User/UserLocator": @UserLocator
|
||||
"./LimitationsManager": @LimitationsManager
|
||||
"../Security/OneTimeTokenHandler":@OneTimeTokenHandler
|
||||
"../Email/EmailHandler":@EmailHandler
|
||||
"settings-sharelatex":@settings
|
||||
"logger-sharelatex":
|
||||
err:->
|
||||
log:->
|
||||
|
||||
|
||||
describe "addUserToGroup", ->
|
||||
it "should find or create the user", (done)->
|
||||
|
@ -100,3 +120,57 @@ describe "Subscription Group Handler", ->
|
|||
assert.deepEqual users[2], {_id:@subscription.member_ids[2]}
|
||||
done()
|
||||
|
||||
describe "isUserPartOfGroup", ->
|
||||
beforeEach ->
|
||||
@subscription_id = "123ed13123"
|
||||
|
||||
it "should return true when user is part of subscription", (done)->
|
||||
@SubscriptionLocator.getSubscriptionByMemberIdAndId.callsArgWith(2, null, {_id:@subscription_id})
|
||||
@Handler.isUserPartOfGroup @user_id, @subscription_id, (err, partOfGroup)->
|
||||
partOfGroup.should.equal true
|
||||
done()
|
||||
|
||||
it "should return false when no subscription is found", (done)->
|
||||
@SubscriptionLocator.getSubscriptionByMemberIdAndId.callsArgWith(2, null)
|
||||
@Handler.isUserPartOfGroup @user_id, @subscription_id, (err, partOfGroup)->
|
||||
partOfGroup.should.equal false
|
||||
done()
|
||||
|
||||
|
||||
describe "sendVerificationEmail", ->
|
||||
beforeEach ->
|
||||
@token = "secret token"
|
||||
@subscription_id = "123ed13123"
|
||||
@licenceName = "great licnece"
|
||||
@email = "bob@smith.com"
|
||||
@OneTimeTokenHandler.getNewToken.callsArgWith(1, null, @token)
|
||||
@EmailHandler.sendEmail.callsArgWith(2)
|
||||
|
||||
it "should put a one time token into the email", (done)->
|
||||
@Handler.sendVerificationEmail @subscription_id, @licenceName, @email, (err)=>
|
||||
emailOpts = @EmailHandler.sendEmail.args[0][1]
|
||||
emailOpts.completeJoinUrl.should.equal "#{@settings.siteUrl}/user/subscription/#{@subscription_id}/group/complete-join?token=#{@token}"
|
||||
emailOpts.to.should.equal @email
|
||||
emailOpts.group_name.should.equal @licenceName
|
||||
done()
|
||||
|
||||
describe "processGroupVerification", ->
|
||||
beforeEach ->
|
||||
@token = "31dDAd2Da"
|
||||
@subscription_id = "31DSd1123D"
|
||||
@admin_id = "eDSda1ew"
|
||||
@OneTimeTokenHandler.getValueFromTokenAndExpire.callsArgWith(1, null, @subscription_id)
|
||||
@SubscriptionLocator.getSubscription.callsArgWith(1, null, {admin_id:@admin_id})
|
||||
@Handler.addUserToGroup = sinon.stub().callsArgWith(2)
|
||||
|
||||
it "should addUserToGroup", (done)->
|
||||
@Handler.processGroupVerification @email, @subscription_id, @token, (err)=>
|
||||
@Handler.addUserToGroup.calledWith(@admin_id, @email).should.equal true
|
||||
done()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -36,13 +36,13 @@ describe "UserController", ->
|
|||
setUserPassword: sinon.stub()
|
||||
@ReferalAllocator =
|
||||
allocate:sinon.stub()
|
||||
@SubscriptionDomainAllocator =
|
||||
@SubscriptionDomainHandler =
|
||||
autoAllocate:sinon.stub()
|
||||
@UserUpdater =
|
||||
changeEmailAddress:sinon.stub()
|
||||
@EmailHandler =
|
||||
sendEmail:sinon.stub().callsArgWith(2)
|
||||
@PasswordResetTokenHandler =
|
||||
@OneTimeTokenHandler =
|
||||
getNewToken: sinon.stub()
|
||||
@settings =
|
||||
siteUrl: "sharelatex.example.com"
|
||||
|
@ -56,9 +56,9 @@ describe "UserController", ->
|
|||
"../Authentication/AuthenticationController": @AuthenticationController
|
||||
"../Authentication/AuthenticationManager": @AuthenticationManager
|
||||
"../Referal/ReferalAllocator":@ReferalAllocator
|
||||
"../Subscription/SubscriptionDomainAllocator":@SubscriptionDomainAllocator
|
||||
"../Subscription/SubscriptionDomainHandler":@SubscriptionDomainHandler
|
||||
"../Email/EmailHandler": @EmailHandler
|
||||
"../PasswordReset/PasswordResetTokenHandler": @PasswordResetTokenHandler
|
||||
"../Security/OneTimeTokenHandler": @OneTimeTokenHandler
|
||||
"crypto": @crypto = {}
|
||||
"settings-sharelatex": @settings
|
||||
"logger-sharelatex": {log:->}
|
||||
|
@ -177,7 +177,7 @@ describe "UserController", ->
|
|||
beforeEach ->
|
||||
@req.body.email = @user.email = "email@example.com"
|
||||
@crypto.randomBytes = sinon.stub().returns({toString: () => @password = "mock-password"})
|
||||
@PasswordResetTokenHandler.getNewToken.callsArgWith(2, null, @token = "mock-token")
|
||||
@OneTimeTokenHandler.getNewToken.callsArgWith(2, null, @token = "mock-token")
|
||||
|
||||
describe "with a new user", ->
|
||||
beforeEach ->
|
||||
|
@ -192,7 +192,7 @@ describe "UserController", ->
|
|||
}).should.equal true
|
||||
|
||||
it "should generate a new password reset token", ->
|
||||
@PasswordResetTokenHandler.getNewToken
|
||||
@OneTimeTokenHandler.getNewToken
|
||||
.calledWith(@user_id, expiresIn: 7 * 24 * 60 * 60)
|
||||
.should.equal true
|
||||
|
||||
|
@ -218,7 +218,7 @@ describe "UserController", ->
|
|||
@UserController.register @req, @res
|
||||
|
||||
it "should still generate a new password token and email", ->
|
||||
@PasswordResetTokenHandler.getNewToken.called.should.equal true
|
||||
@OneTimeTokenHandler.getNewToken.called.should.equal true
|
||||
@EmailHandler.sendEmail.called.should.equal true
|
||||
|
||||
describe "changePassword", ->
|
||||
|
|
Loading…
Reference in a new issue