fix(signin): add oauth query strings to sign in and sign up views #4584
Conversation
| <a href="/reset_password" class="left reset-password" data-flow-event="forgot-password">{{#t}}Forgot password?{{/t}}</a> | ||
| <a href="/#" class="right use-different" data-flow-event="use-different-account">{{#t}}Use a different account{{/t}}</a><br/> | ||
| <a href="/reset_password{{queryString}}" class="left reset-password" data-flow-event="forgot-password">{{#t}}Forgot password?{{/t}}</a> | ||
| <a href="/{{queryString}}" class="right use-different" data-flow-event="use-different-account">{{#t}}Use a different account{{/t}}</a><br/> |
vladikoff
Jan 4, 2017
Author
Contributor
the use-different is a messed up case, should we convert this to a button instead of a link, so it cannot be opened in a new tab, or we add /{{queryString}}&useDifferent=1 ?
the use-different is a messed up case, should we convert this to a button instead of a link, so it cannot be opened in a new tab, or we add /{{queryString}}&useDifferent=1 ?
shane-tomlinson
Jan 5, 2017
Member
use-different re-renders the signin page, so we should change the href to be /signin with the query string. We already have equivalent functionality to useDifferent=1, it's email=blank - see
and
, no need for a new query parameter.
use-different re-renders the signin page, so we should change the href to be /signin with the query string. We already have equivalent functionality to useDifferent=1, it's email=blank - see
shane-tomlinson
Jan 5, 2017
Member
Can you also add tests to ensure the queryString makes it into the templates where expected?
Can you also add tests to ensure the queryString makes it into the templates where expected?
vladikoff
Jan 16, 2017
Author
Contributor
the problem is useDifferent currently does:
this.user.removeAllAccounts();
Session.clear();
this._formPrefill.clear();
this.logViewEvent('use-different-account');
So we either need to add another query param or do the same with email=blank
the problem is useDifferent currently does:
this.user.removeAllAccounts();
Session.clear();
this._formPrefill.clear();
this.logViewEvent('use-different-account');
So we either need to add another query param or do the same with email=blank
shane-tomlinson
Jan 17, 2017
Member
I don't think email=blank needs to do anything extra, "email=blank" is from a user's P.O.V. equivalent to "Use another account"; the sign_in view will see target=blank and ignore the cached credentials.
As an aside, I have no problems re-visiting this code and why it's being done. I have a lot of grumbles about this section of code and cached accounts in general, it's so complex and hard to think about. First, it seems to me we should do away with storing multiple accounts locally. It's complicated. It's yucky. Nobody fully understands its behavior. Next, if we must store multiple accounts, getChooserAccount seems like it's misplaced - what does the model care about what account should be displayed to the user? That seems like it should be in the signin view. Next, if we must store multiple accounts and the the user chooses Use a different account, clearing all accounts seems equally erroneous. It seems we should keep all the account data and either not call getChooseAccount or pass in an override that returns an empty user. None of this for this PR of course.
I don't think email=blank needs to do anything extra, "email=blank" is from a user's P.O.V. equivalent to "Use another account"; the sign_in view will see target=blank and ignore the cached credentials.
As an aside, I have no problems re-visiting this code and why it's being done. I have a lot of grumbles about this section of code and cached accounts in general, it's so complex and hard to think about. First, it seems to me we should do away with storing multiple accounts locally. It's complicated. It's yucky. Nobody fully understands its behavior. Next, if we must store multiple accounts, getChooserAccount seems like it's misplaced - what does the model care about what account should be displayed to the user? That seems like it should be in the signin view. Next, if we must store multiple accounts and the the user chooses Use a different account, clearing all accounts seems equally erroneous. It seems we should keep all the account data and either not call getChooseAccount or pass in an override that returns an empty user. None of this for this PR of course.
philbooth
Jan 17, 2017
Contributor
...we should do away with storing multiple accounts locally.
This, this, a thousand times this.
...we should do away with storing multiple accounts locally.
This, this, a thousand times this.
vladikoff
Jan 19, 2017
Author
Contributor
After talking to Shane, we decided to leave use-different and add email=blank in this PR.
We can work on removing the removeAllAcounts and other jazz in followup #4635
After talking to Shane, we decided to leave use-different and add email=blank in this PR.
We can work on removing the removeAllAcounts and other jazz in followup #4635
|
Also Fixes #4400 |
|
This PR also brings up how we should handle the "back" link which always has an href of "#", which is also not new tab friendly. |
| @@ -138,6 +138,10 @@ define(function (require, exports, module) { | |||
|
|
|||
| return this.invokeBrokerMethod(brokerMethod, account) | |||
| .then(this.navigate.bind(this, this.model.get('redirectTo') || 'settings', {}, navigateData)); | |||
| }, | |||
|
|
|||
| getCurrentQueryString () { | |||
shane-tomlinson
Jan 5, 2017
Member
We call Query Search in other functions, can you use it here too? And remove the Current. You might as well just move this function to views/base.js with the others so it's available everywhere.
Pedantic as it is, this function also needs tests wherever it lands.
We call Query Search in other functions, can you use it here too? And remove the Current. You might as well just move this function to views/base.js with the others so it's available everywhere.
Pedantic as it is, this function also needs tests wherever it lands.
| @@ -84,6 +84,7 @@ define(function (require, exports, module) { | |||
| isAmoMigration: this.isAmoMigration(), | |||
| isSyncMigration: this.isSyncMigration(), | |||
| password: this._formPrefill.get('password'), | |||
| queryString: this.getCurrentQueryString(), | |||
shane-tomlinson
Jan 5, 2017
Member
If we call them Search parameters elsewhere, should we call it a searchString here and in the templates?
If we call them Search parameters elsewhere, should we call it a searchString here and in the templates?
| <a href="/reset_password" class="left reset-password" data-flow-event="forgot-password">{{#t}}Forgot password?{{/t}}</a> | ||
| <a href="/#" class="right use-different" data-flow-event="use-different-account">{{#t}}Use a different account{{/t}}</a><br/> | ||
| <a href="/reset_password{{queryString}}" class="left reset-password" data-flow-event="forgot-password">{{#t}}Forgot password?{{/t}}</a> | ||
| <a href="/{{queryString}}" class="right use-different" data-flow-event="use-different-account">{{#t}}Use a different account{{/t}}</a><br/> |
shane-tomlinson
Jan 5, 2017
Member
Can you also add tests to ensure the queryString makes it into the templates where expected?
Can you also add tests to ensure the queryString makes it into the templates where expected?
| @@ -20,7 +20,7 @@ | |||
| <div class="error"></div> | |||
| <div class="success"></div> | |||
| {{#isAmoMigration}} | |||
| <div class="info nudge pad" id="amo-migration">{{#unsafeTranslate}}Looking for your Add-ons data? <a href="/signup">Sign up</a> for a Firefox Account with your old Add-ons account email address.{{/unsafeTranslate}}</div> | |||
| <div class="info nudge pad" id="amo-migration">{{#unsafeTranslate}}Looking for your Add-ons data? <a href="%(signUpWithSearchString)s">Sign up</a> for a Firefox Account with your old Add-ons account email address.{{/unsafeTranslate}}</div> | |||
vladikoff
Jan 19, 2017
Author
Contributor
@shane-tomlinson the PR should be good to go except of this ^ I keep getting logger.js [sm]:73 String contains variables that are not escaped: Looking for your Add-ons data? <a href="%(signUpWithSearchString)s">Sign up</a> for a Firefox Account with your old Add-ons account email address.
@shane-tomlinson the PR should be good to go except of this ^ I keep getting logger.js [sm]:73 String contains variables that are not escaped: Looking for your Add-ons data? <a href="%(signUpWithSearchString)s">Sign up</a> for a Firefox Account with your old Add-ons account email address.
shane-tomlinson
Jan 23, 2017
Member
Two comments about this line.
- In the auth-mailer, anchors that must be translated don't even include the href, we use the form of
%(linkNameAttribute)s - see https://github.com/mozilla/fxa-auth-mailer/blob/d0cf24960cbc19278f42679da42842c822a20862/templates/verify_login.html#L65. Might be nice to keep a similar convention here where even the href portion is passed in.
- For
unsafeTranslate, all variables must be prefixed with escaped as a reminder to the reviewer to look for escaping. This is to keep us from unintentionally introducing XSS vulnerabilities via HTML. See
fxa-content-server/app/scripts/views/base.js
Line 394
in
af6cdd7
.
Two comments about this line.
- In the auth-mailer, anchors that must be translated don't even include the href, we use the form of
%(linkNameAttribute)s- see https://github.com/mozilla/fxa-auth-mailer/blob/d0cf24960cbc19278f42679da42842c822a20862/templates/verify_login.html#L65. Might be nice to keep a similar convention here where even thehrefportion is passed in. - For
unsafeTranslate, all variables must be prefixed withescapedas a reminder to the reviewer to look for escaping. This is to keep us from unintentionally introducing XSS vulnerabilities via HTML. See.fxa-content-server/app/scripts/views/base.js
Line 394 in af6cdd7
| @@ -162,7 +162,6 @@ define(function (require, exports, module) { | |||
| chooseWhatToSyncCheckbox: this.broker.hasCapability('chooseWhatToSyncCheckbox'), | |||
| email: prefillEmail, | |||
| error: this.error, | |||
| escapedSignInUri: encodeURI(this.broker.transformLink('/signin')), | |||
vladikoff
Jan 19, 2017
Author
Contributor
this is not used anymore AFAIK
this is not used anymore AFAIK
|
@vladikoff - While I was looking at this PR, I noticed the Here's what I came up with: diff --git a/app/scripts/models/auth_brokers/oauth.js b/app/scripts/models/auth_brokers/oauth.js
index 5e40ec3d..19697cb3 100644
--- a/app/scripts/models/auth_brokers/oauth.js
+++ b/app/scripts/models/auth_brokers/oauth.js
@@ -177,7 +177,12 @@ define(function (require, exports, module) {
link = '/' + link;
}
- return '/oauth' + link;
+ if (/^\/(signin|signup)/.test(link)) {
+ link = '/oauth' + link;
+ }
+
+ const windowSearchParams = Url.searchParams(this.window.location.search);
+ return Url.updateSearchString(link, windowSearchParams);
}
});
diff --git a/app/scripts/templates/sign_in.mustache b/app/scripts/templates/sign_in.mustache
index b26b34d0..58ca7283 100644
--- a/app/scripts/templates/sign_in.mustache
+++ b/app/scripts/templates/sign_in.mustache
@@ -46,7 +46,7 @@
<div class="links">
<a href="/reset_password" class="left reset-password" data-flow-event="forgot-password">{{#t}}Forgot password?{{/t}}</a>
- <a href="/#" class="right use-different" data-flow-event="use-different-account">{{#t}}Use a different account{{/t}}</a><br/>
+ <a href="/signin?email=blank" class="right use-different" data-flow-event="use-different-account">{{#t}}Use a different account{{/t}}</a><br/>
</div>
{{/chooserAskForPassword}}
@@ -56,7 +56,7 @@
</div>
<div class="links">
- <a href="/#" class="use-different" data-flow-event="use-different-account">{{#t}}Use a different account{{/t}}</a><br/>
+ <a href="/signin?email=blank" class="use-different" data-flow-event="use-different-account">{{#t}}Use a different account{{/t}}</a><br/>
</div>
{{/chooserAskForPassword}}
{{/suggestedAccount}}
diff --git a/app/scripts/views/mixins/service-mixin.js b/app/scripts/views/mixins/service-mixin.js
index 591472d7..56a0c128 100644
--- a/app/scripts/views/mixins/service-mixin.js
+++ b/app/scripts/views/mixins/service-mixin.js
@@ -9,13 +9,15 @@ define(function (require, exports, module) {
'use strict';
const BaseView = require('views/base');
+ const $ = require('jquery');
module.exports = {
transformLinks () {
- this.$('a[href~="/signin"]').attr('href',
- this.broker.transformLink('/signin'));
- this.$('a[href~="/signup"]').attr('href',
- this.broker.transformLink('/signup'));
+ const $linkEls = this.$('a[href^="/signin"],a[href^="/signup"],a[href^="/reset_password"]');
+ $linkEls.each((index, el) => {
+ const $linkEl = $(el);
+ $linkEl.attr('href', this.broker.transformLink($linkEl.attr('href')));
+ });
},
// override this method so we can fix signup/signin links in errors |
| .then(fillOutSignUp(bouncedEmail, PASSWORD)) | ||
|
|
||
| .then(testElementExists('fxa-confirm-header')) | ||
| .then(testElementExists('#fxa-confirm-header')) |
vladikoff
Jan 20, 2017
Author
Contributor
wat
wat
shane-tomlinson
Jan 23, 2017
Member
wat indeed.
wat indeed.
|
Other than the one small request to remove base.js->getSearchString, looks great! |
| @@ -20,7 +20,7 @@ | |||
| <div class="error"></div> | |||
| <div class="success"></div> | |||
| {{#isAmoMigration}} | |||
| <div class="info nudge pad" id="amo-migration">{{#unsafeTranslate}}Looking for your Add-ons data? <a href="/signup">Sign up</a> for a Firefox Account with your old Add-ons account email address.{{/unsafeTranslate}}</div> | |||
| <div class="info nudge pad" id="amo-migration">{{#unsafeTranslate}}Looking for your Add-ons data? <a href="%(signUpWithSearchString)s">Sign up</a> for a Firefox Account with your old Add-ons account email address.{{/unsafeTranslate}}</div> | |||
shane-tomlinson
Jan 23, 2017
Member
Two comments about this line.
- In the auth-mailer, anchors that must be translated don't even include the href, we use the form of
%(linkNameAttribute)s - see https://github.com/mozilla/fxa-auth-mailer/blob/d0cf24960cbc19278f42679da42842c822a20862/templates/verify_login.html#L65. Might be nice to keep a similar convention here where even the href portion is passed in.
- For
unsafeTranslate, all variables must be prefixed with escaped as a reminder to the reviewer to look for escaping. This is to keep us from unintentionally introducing XSS vulnerabilities via HTML. See
fxa-content-server/app/scripts/views/base.js
Line 394
in
af6cdd7
.
Two comments about this line.
- In the auth-mailer, anchors that must be translated don't even include the href, we use the form of
%(linkNameAttribute)s- see https://github.com/mozilla/fxa-auth-mailer/blob/d0cf24960cbc19278f42679da42842c822a20862/templates/verify_login.html#L65. Might be nice to keep a similar convention here where even thehrefportion is passed in. - For
unsafeTranslate, all variables must be prefixed withescapedas a reminder to the reviewer to look for escaping. This is to keep us from unintentionally introducing XSS vulnerabilities via HTML. See.fxa-content-server/app/scripts/views/base.js
Line 394 in af6cdd7
| .then(fillOutSignUp(bouncedEmail, PASSWORD)) | ||
|
|
||
| .then(testElementExists('fxa-confirm-header')) | ||
| .then(testElementExists('#fxa-confirm-header')) |
shane-tomlinson
Jan 23, 2017
Member
wat indeed.
wat indeed.
| }, | ||
|
|
||
| /** | ||
| * Get the full value from the URL search parameter |
shane-tomlinson
Jan 23, 2017
Member
I don't see this function referenced anymore.
I don't see this function referenced anymore.
Fixes #4547
@shane-tomlinson thoughts on this approach?