Skip to content
This repository has been archived by the owner. It is now read-only.

fix(signin): add oauth query strings to sign in and sign up views #4584

Merged
merged 1 commit into from Jan 23, 2017

Conversation

@vladikoff
Copy link
Contributor

@vladikoff vladikoff commented Jan 4, 2017

Fixes #4547

@shane-tomlinson thoughts on this approach?

<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/>

This comment has been minimized.

@vladikoff

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 ?

This comment has been minimized.

@shane-tomlinson

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

email: Vat.email().allow(Constants.DISALLOW_CACHED_CREDENTIALS),
and
DISALLOW_CACHED_CREDENTIALS: 'blank',
, no need for a new query parameter.

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Jan 5, 2017
Member

Can you also add tests to ensure the queryString makes it into the templates where expected?

This comment has been minimized.

@vladikoff

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

This comment has been minimized.

@shane-tomlinson

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.

This comment has been minimized.

@philbooth

philbooth Jan 17, 2017
Contributor

...we should do away with storing multiple accounts locally.

This, this, a thousand times this.

This comment has been minimized.

@vladikoff

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

@vladikoff
Copy link
Contributor Author

@vladikoff vladikoff commented Jan 4, 2017

Also Fixes #4400

Copy link
Member

@shane-tomlinson shane-tomlinson left a comment

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 () {

This comment has been minimized.

@shane-tomlinson

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.

@@ -84,6 +84,7 @@ define(function (require, exports, module) {
isAmoMigration: this.isAmoMigration(),
isSyncMigration: this.isSyncMigration(),
password: this._formPrefill.get('password'),
queryString: this.getCurrentQueryString(),

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Jan 5, 2017
Member

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/>

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Jan 5, 2017
Member

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>

This comment has been minimized.

@vladikoff

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.

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Jan 23, 2017
Member

Two comments about this line.

  1. 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.
  2. 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
    if (Strings.hasUnsafeVariables(text)) {
    .
@@ -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')),

This comment has been minimized.

@vladikoff

vladikoff Jan 19, 2017
Author Contributor

this is not used anymore AFAIK

@vladikoff vladikoff dismissed shane-tomlinson’s stale review Jan 19, 2017

made changes

@vladikoff vladikoff requested a review from shane-tomlinson Jan 19, 2017
@shane-tomlinson
Copy link
Member

@shane-tomlinson shane-tomlinson commented Jan 20, 2017

@vladikoff - While I was looking at this PR, I noticed the service-mixin and realized we can use that to do all the extra stuff we need it to, with only minimal updates to the templates.

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'))

This comment has been minimized.

@vladikoff

vladikoff Jan 20, 2017
Author Contributor

wat

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Jan 23, 2017
Member

wat indeed.

Copy link
Member

@shane-tomlinson shane-tomlinson left a comment

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>

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Jan 23, 2017
Member

Two comments about this line.

  1. 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.
  2. 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
    if (Strings.hasUnsafeVariables(text)) {
    .
.then(fillOutSignUp(bouncedEmail, PASSWORD))

.then(testElementExists('fxa-confirm-header'))
.then(testElementExists('#fxa-confirm-header'))

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Jan 23, 2017
Member

wat indeed.

},

/**
* Get the full value from the URL search parameter

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Jan 23, 2017
Member

I don't see this function referenced anymore.

@shane-tomlinson shane-tomlinson merged commit 6bf3da9 into master Jan 23, 2017
4 checks passed
4 checks passed
ci/circleci Your tests passed on CircleCI!
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
continuous-integration/travis-ci/push The Travis CI build passed
Details
coverage/coveralls Coverage increased (+0.001%) to 98.477%
Details
@shane-tomlinson shane-tomlinson deleted the i4547 branch Jan 23, 2017
@rfk rfk added this to the FxA-0: quality milestone Feb 6, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

4 participants