@@ -14,6 +14,7 @@ const HttpMocks = require('node-mocks-http')
1414const PasswordResetEmailRequest = require ( '../../lib/requests/password-reset-email-request' )
1515const AccountManager = require ( '../../lib/models/account-manager' )
1616const SolidHost = require ( '../../lib/models/solid-host' )
17+ const EmailService = require ( '../../lib/services/email-service' )
1718
1819describe ( 'PasswordResetEmailRequest' , ( ) => {
1920 describe ( 'constructor()' , ( ) => {
@@ -153,6 +154,39 @@ describe('PasswordResetEmailRequest', () => {
153154 expect ( request . error ) . to . not . have . been . called ( )
154155 } )
155156 } )
157+
158+ it ( 'should hande a reset request with no username without privacy leakage' , ( ) => {
159+ const host = SolidHost . from ( { serverUri : 'https://example.com' } )
160+ const store = { suffixAcl : '.acl' }
161+ const accountManager = AccountManager . from ( { host, multiuser : true , store } )
162+ accountManager . loadAccountRecoveryEmail = sinon . stub ( ) . resolves ( '[email protected] ' ) 163+ accountManager . sendPasswordResetEmail = sinon . stub ( ) . resolves ( )
164+ accountManager . accountExists = sinon . stub ( ) . resolves ( false )
165+
166+ const returnToUrl = 'https://example.com/resource'
167+ const username = 'alice'
168+ const response = HttpMocks . createResponse ( )
169+ response . render = sinon . stub ( )
170+
171+ const options = { accountManager, username, returnToUrl, response }
172+ const request = new PasswordResetEmailRequest ( options )
173+
174+ sinon . spy ( request , 'error' )
175+ sinon . spy ( request , 'validate' )
176+ sinon . spy ( request , 'loadUser' )
177+
178+ return PasswordResetEmailRequest . handlePost ( request )
179+ . then ( ( ) => {
180+ expect ( request . validate ) . to . have . been . called ( )
181+ expect ( request . loadUser ) . to . have . been . called ( )
182+ expect ( request . loadUser ) . to . throw ( )
183+ } ) . catch ( ( ) => {
184+ expect ( request . error ) . to . have . been . called ( )
185+ expect ( response . render ) . to . have . been . calledWith ( 'auth/reset-link-sent' )
186+ expect ( accountManager . loadAccountRecoveryEmail ) . to . not . have . been . called ( )
187+ expect ( accountManager . sendPasswordResetEmail ) . to . not . have . been . called ( )
188+ } )
189+ } )
156190 } )
157191
158192 describe ( 'loadUser()' , ( ) => {
@@ -175,16 +209,26 @@ describe('PasswordResetEmailRequest', () => {
175209 it ( 'should throw an error if the user does not exist' , done => {
176210 const host = SolidHost . from ( { serverUri : 'https://example.com' } )
177211 const store = { suffixAcl : '.acl' }
178- const accountManager = AccountManager . from ( { host, multiuser : true , store } )
212+ const emailService = sinon . stub ( ) . returns ( EmailService )
213+ const accountManager = AccountManager . from ( { host, multiuser : true , store, emailService } )
179214 accountManager . accountExists = sinon . stub ( ) . resolves ( false )
180215 const username = 'alice'
181-
182216 const options = { accountManager, username }
183217 const request = new PasswordResetEmailRequest ( options )
184218
219+ sinon . spy ( request , 'resetLinkMessage' )
220+ sinon . spy ( accountManager , 'userAccountFrom' )
221+ sinon . spy ( accountManager , 'verifyEmailDependencies' )
222+
185223 request . loadUser ( )
186- . catch ( error => {
187- expect ( error . message ) . to . equal ( 'Account not found for that username' )
224+ . then ( ( ) => {
225+ expect ( accountManager . userAccountFrom ) . to . have . been . called ( )
226+ expect ( accountManager . verifyEmailDependencies ) . to . have . been . called ( )
227+ expect ( accountManager . verifyEmailDependencies ) . to . throw ( )
228+ done ( )
229+ } )
230+ . catch ( ( ) => {
231+ expect ( request . resetLinkMessage ) . to . have . been . called ( )
188232 done ( )
189233 } )
190234 } )
0 commit comments