fix(email): send correct email when using unblock code (#6064), r=@philbooth, @shane-tomlinson
This commit is contained in:
Родитель
c2ac36d5d1
Коммит
e31e97afba
|
@ -37,6 +37,11 @@ define(function (require, exports, module) {
|
|||
// the user since. Is it enough to just move this field to the
|
||||
// 'defaults'?
|
||||
needsOptedInToMarketingEmail: undefined,
|
||||
// This property is set when a user has changed their primary email address and
|
||||
// attempts to login. Similar to logging in with a different email capitalization
|
||||
// the auth-server will return the proper email to reattempt the login. When reattempting
|
||||
// to login, this needs to be passed back to the auth-server.
|
||||
originalLoginEmail: undefined,
|
||||
// password field intentionally omitted to avoid unintentional leaks
|
||||
permissions: undefined,
|
||||
profileImageId: undefined,
|
||||
|
@ -439,8 +444,9 @@ define(function (require, exports, module) {
|
|||
// `originalLoginEmail` is specified when the account's primary email has changed.
|
||||
// This param lets the auth-server known that it should check that this email
|
||||
// is the current primary for the account.
|
||||
if (options.originalLoginEmail) {
|
||||
signinOptions.originalLoginEmail = options.originalLoginEmail;
|
||||
const originalLoginEmail = this.get('originalLoginEmail');
|
||||
if (originalLoginEmail) {
|
||||
signinOptions.originalLoginEmail = originalLoginEmail;
|
||||
}
|
||||
|
||||
if (options.verificationMethod) {
|
||||
|
@ -489,16 +495,26 @@ define(function (require, exports, module) {
|
|||
// the user's password with.
|
||||
if (AuthErrors.is(err, 'INCORRECT_EMAIL_CASE')) {
|
||||
|
||||
// Save the original email that was used for login so that the auth-server
|
||||
// can verify that this is the accounts primary email address.
|
||||
options.originalLoginEmail = email;
|
||||
// Save the original email that was used for login. This value will be
|
||||
// sent to the auth-server so that it can correctly look the account.
|
||||
this.set('originalLoginEmail', email);
|
||||
|
||||
// The server will respond with the canonical email
|
||||
// for this account. Use it hereafter.
|
||||
// The email returned in the `INCORRECT_EMAIL_CASE` is either the canonical email
|
||||
// address or if the primary email has changed, it is the email the account was first
|
||||
// created with.
|
||||
this.set('email', err.email);
|
||||
return this.signIn(password, relier, options);
|
||||
}
|
||||
} else if (AuthErrors.is(err, 'THROTTLED') ||
|
||||
AuthErrors.is(err, 'REQUEST_BLOCKED')) {
|
||||
|
||||
// On a throttled or block login request, the account model's email could be storing
|
||||
// a canonical email address or email the account was created with. If this is the case
|
||||
// set the account model's email to the email first used for the login request.
|
||||
const originalLoginEmail = this.get('originalLoginEmail');
|
||||
if (originalLoginEmail) {
|
||||
this.set('email', originalLoginEmail);
|
||||
}
|
||||
}
|
||||
throw err;
|
||||
});
|
||||
},
|
||||
|
|
|
@ -483,9 +483,49 @@ define(function (require, exports, module) {
|
|||
fxaClient.signIn.calledWith(EMAIL, PASSWORD, relier, secondExpectedOptions));
|
||||
|
||||
assert.equal(account.get('email'), EMAIL);
|
||||
assert.equal(account.get('originalLoginEmail'), upperCaseEmail);
|
||||
});
|
||||
});
|
||||
|
||||
['REQUEST_BLOCKED', 'THROTTLED'].forEach((errorName) => {
|
||||
describe(errorName, () => {
|
||||
const primaryEmail = 'primaryEmail@email.com';
|
||||
const oldPrimaryEmail = EMAIL;
|
||||
|
||||
beforeEach(() => {
|
||||
sinon.stub(fxaClient, 'signIn').callsFake(() => {
|
||||
if (fxaClient.signIn.callCount === 1) {
|
||||
const err = AuthErrors.toError('INCORRECT_EMAIL_CASE');
|
||||
err.email = oldPrimaryEmail;
|
||||
return Promise.reject(err);
|
||||
} else if (fxaClient.signIn.callCount === 2) {
|
||||
const err = AuthErrors.toError(errorName);
|
||||
return Promise.reject(err);
|
||||
} else {
|
||||
return Promise.resolve({});
|
||||
}
|
||||
});
|
||||
|
||||
account.set('email', primaryEmail);
|
||||
return account.signIn(PASSWORD, relier, {
|
||||
unblockCode: 'unblock code'
|
||||
}).then(assert.fail, (err) => {
|
||||
assert.isTrue(AuthErrors.is(err, errorName));
|
||||
});
|
||||
});
|
||||
|
||||
it('re-tries login and restores email to primary email address', () => {
|
||||
assert.equal(fxaClient.signIn.callCount, 2);
|
||||
let args = fxaClient.signIn.args[0];
|
||||
assert.equal(args[0], primaryEmail, 'sign-in first called with primary email');
|
||||
args = fxaClient.signIn.args[1];
|
||||
assert.equal(args[0], oldPrimaryEmail, 'sign-in then called with old primary email');
|
||||
assert.equal(account.get('email'), primaryEmail, 'primary email restored');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('error', () => {
|
||||
let err;
|
||||
|
||||
|
|
|
@ -194,6 +194,7 @@ module.exports = {
|
|||
EMAIL_FIELD: '.verification-email-message',
|
||||
HEADER: '#fxa-signin-unblock-header',
|
||||
SUBMIT: 'button[type="submit"]',
|
||||
VERIFICATION: '.verification-email-message',
|
||||
},
|
||||
SIGNUP: {
|
||||
AGE: '#age',
|
||||
|
|
|
@ -19,6 +19,7 @@ const NEW_PASSWORD = 'password1';
|
|||
|
||||
let email;
|
||||
let secondaryEmail;
|
||||
let newPrimaryEmail;
|
||||
|
||||
const {
|
||||
clearBrowserState,
|
||||
|
@ -29,12 +30,14 @@ const {
|
|||
fillOutCompleteResetPassword,
|
||||
fillOutSignUp,
|
||||
fillOutSignIn,
|
||||
fillOutSignInUnblock,
|
||||
openPage,
|
||||
openVerificationLinkInNewTab,
|
||||
openVerificationLinkInSameTab,
|
||||
switchToWindow,
|
||||
testElementExists,
|
||||
testElementTextEquals,
|
||||
testElementTextInclude,
|
||||
testErrorTextInclude,
|
||||
testSuccessWasShown,
|
||||
type,
|
||||
|
@ -169,6 +172,78 @@ registerSuite('settings change email', {
|
|||
.then(testElementExists(selectors.SIGNIN.HEADER))
|
||||
.then(fillOutSignIn(email, NEW_PASSWORD))
|
||||
.then(testElementExists(selectors.SETTINGS.HEADER));
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
registerSuite('settings change email - unblock', {
|
||||
beforeEach: function () {
|
||||
email = TestHelpers.createEmail();
|
||||
|
||||
// Create a new primary email that is always forced through the unblock flow
|
||||
newPrimaryEmail = TestHelpers.createEmail('block{id}');
|
||||
return this.remote.then(clearBrowserState())
|
||||
.then(openPage(SIGNUP_URL, selectors.SIGNUP.HEADER))
|
||||
.then(fillOutSignUp(email, PASSWORD))
|
||||
.then(testElementExists(selectors.CONFIRM_SIGNUP.HEADER))
|
||||
.then(openVerificationLinkInSameTab(email, 0))
|
||||
.then(testElementExists(selectors.SETTINGS.HEADER))
|
||||
.then(click(selectors.EMAIL.MENU_BUTTON))
|
||||
|
||||
// add secondary email, verify
|
||||
.then(type(selectors.EMAIL.INPUT, newPrimaryEmail))
|
||||
.then(click(selectors.EMAIL.ADD_BUTTON))
|
||||
.then(testElementExists(selectors.EMAIL.NOT_VERIFIED_LABEL))
|
||||
.then(openVerificationLinkInSameTab(newPrimaryEmail, 0, {}))
|
||||
.then(testSuccessWasShown())
|
||||
|
||||
// set new primary email
|
||||
.then(openPage(SETTINGS_URL, selectors.SETTINGS.HEADER))
|
||||
.then(click(selectors.EMAIL.MENU_BUTTON))
|
||||
.then(testElementTextEquals(selectors.EMAIL.ADDRESS_LABEL, newPrimaryEmail))
|
||||
.then(testElementExists(selectors.EMAIL.VERIFIED_LABEL))
|
||||
.then(click(selectors.EMAIL.SET_PRIMARY_EMAIL_BUTTON))
|
||||
.then(visibleByQSA(selectors.EMAIL.SUCCESS))
|
||||
|
||||
// sign out
|
||||
.then(click(selectors.SETTINGS.SIGNOUT))
|
||||
.then(testElementExists(selectors.SIGNIN.HEADER));
|
||||
},
|
||||
|
||||
afterEach: function () {
|
||||
return this.remote.then(clearBrowserState());
|
||||
},
|
||||
|
||||
tests: {
|
||||
'can change primary email, get blocked with invalid password, redirect login page': function () {
|
||||
return this.remote
|
||||
// sign in
|
||||
.then(openPage(SIGNIN_URL, selectors.SIGNIN.HEADER))
|
||||
.then(fillOutSignIn(newPrimaryEmail, 'INVALID_PASSWORD'))
|
||||
|
||||
// fill out unblock
|
||||
.then(testElementExists(selectors.SIGNIN_UNBLOCK.HEADER))
|
||||
.then(testElementTextInclude(selectors.SIGNIN_UNBLOCK.VERIFICATION, newPrimaryEmail))
|
||||
.then(fillOutSignInUnblock(newPrimaryEmail, 2))
|
||||
|
||||
// redirected to login
|
||||
.then(testElementExists(selectors.SIGNIN.HEADER));
|
||||
},
|
||||
|
||||
'can change primary email, get blocked with valid password, redirect settings page': function () {
|
||||
return this.remote
|
||||
// sign in
|
||||
.then(openPage(SIGNIN_URL, selectors.SIGNIN.HEADER))
|
||||
.then(fillOutSignIn(newPrimaryEmail, PASSWORD))
|
||||
|
||||
// fill out unblock
|
||||
.then(testElementExists(selectors.SIGNIN_UNBLOCK.HEADER))
|
||||
.then(testElementTextInclude(selectors.SIGNIN_UNBLOCK.VERIFICATION, newPrimaryEmail))
|
||||
.then(fillOutSignInUnblock(newPrimaryEmail, 2))
|
||||
|
||||
// redirected to settings
|
||||
.then(testElementExists(selectors.SETTINGS.HEADER));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче