Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP of auto-container-origin #386

Merged
merged 1 commit into from
Apr 3, 2017

Conversation

jonathanKingston
Copy link
Contributor

Super WIP PR just to demo the functionality for @johngruen and @groovecoder ...

STR (Assumes default search is google):

  1. create Google container
  2. add a new google container tab
  3. go to google.com
  4. right click, "Always open in this container"
  5. open a new non container tab
  6. Search string "test"

Tab created in step 6. Will be in "Google" container.

Loads of polish needed like:

  • Change context menu when already auto linking.
  • Show warning for paranoid users like myself on autolinking
  • Allow container based auto dismissal of paranoid warning
  • Potentially show URL autolinking in other menus

@groovecoder
Copy link
Member

This is for #306? Anything for #311 in here?


browser.contextMenus.onClicked.addListener((info, tab) => {
const pageUrl = new window.URL(info.pageUrl);
const userContextId = getUserContextIdFromCookieStore(tab.cookieStoreId);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉 tab.cookieStoreId Yay Firefox 52 WebExtensions!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to work for 51? Totally forgot about that :/

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. I introduced cookieStoreId, but it's not in FF51.... we can still retrieve the userContextId from the tab as we do in index.js.

@jonathanKingston
Copy link
Contributor Author

Sorry yea this is for #306.

Nothing for #311 here. There are other issues with doing that I need to explain there. I think we should keep them separate.

Copy link
Member

@groovecoder groovecoder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a good start. Some nits but overall it's coming along. Agree with the changes you already mention making.

}
});

browser.webRequest.onBeforeRequest.addListener((options) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we also add this check?

if (options.frameId !== 0) {
  return {}
}

So we only do this logic for the requests that happen in the top frame?

I.e., we just want to check the first/top request in the tab - not all the requests?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the check anyway for paranoia sake.

return false;
}

const storagePrefix = "originMap@@_";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: more descriptive name? originContainerMap@@_ ?

Copy link
Contributor Author

@jonathanKingston jonathanKingston Mar 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done... the @@_ is my paranoia about something merging with the key itself as it's just a boring key val store.

return {
cancel: true,
};
return {};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unreachable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup deleted.

console.log('err', e);
return {};
});
},{urls: ["<all_urls>"], types: ["main_frame"]}, ["blocking"]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, the main_frame RequestFilter here takes care of my concern about processing every request. 👍

@groovecoder
Copy link
Member

Show warning for paranoid users like myself on autolinking

Absolutely 👍

Allow container based auto dismissal of paranoid warning

I would leave this out at first, until users tell us they're sick of the warning? Based on the experience in Blok, I imagine most users will get their origins and containers linked in the first couple weeks, and it seems we should err on the side of reminding them about the privacy & security concerns of auto-linking rather than err on the side of users easily falling back into insecure browsing.

Potentially show URL autolinking in other menus

👍 for the tab-bar context menu (is this possible in WebExtension?), the container icon in the Awesomebar (see #387 - possible in WebExtension?), and/or a new pageAction.

const storagePrefix = "originMap@@_";
const storageArea = browser.storage.local;

browser.contextMenus.onClicked.addListener((info, tab) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to add:

if (info.menuItemId !== "open-in-this-container") {
  return;
}

To make sure that clicks on other context menus don't trigger the assignment?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah if we add any certainly. There is a click handler per each menu item too, I just didn't test that out yet.

@jonathanKingston
Copy link
Contributor Author

I put in a rough warning when users are directed to a container, currently this opens in the container and I use history replace to move them into the same container. It might actually make more sense to use message passing to the background page to open in a selected container (this would allow the user flow of people who want to auto assign the container but also want to change it sometimes).

To make the never ask checkbox work I had to use message passing anyway.

I would have to put it a fair bit more work in to get any of these features:

  • container select box, picker whatever
  • container name (The background script would need to maintain/fetch just for this request the list of containers which actually would be a pain)

I think we should show the full URL here however... I also think it looks ugly :(

This really needs some of @johngruen's touch probably either way it's lower on the priorities I have on making pretty.
selection_515

@groovecoder
Copy link
Member

groovecoder commented Mar 22, 2017

👍 to some styling work on it.

Some clearer copy may also be:

"
Are you sure you want to open <url> in your pre-assigned container? The page will have access to this container's cookies and other data.

<Open in non-Container> <Open in pre-assigned container> <Never ask me this again>
"

@johngruen
Copy link
Contributor

hey @jonathanKingston @groovecoder work week this week has put me behind. Should be able to clean up by friday.


browser.contextMenus.onClicked.addListener((info, tab) => {
const pageUrl = new window.URL(info.pageUrl);
const userContextId = getUserContextIdFromCookieStore(tab.cookieStoreId);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. I introduced cookieStoreId, but it's not in FF51.... we can still retrieve the userContextId from the tab as we do in index.js.

if (neverAsk) {
browser.tabs.create({url, cookieStoreId: `firefox-container-${userContextId}`});
} else {
browser.tabs.create({url: `${loadPage}?url=${url}`, cookieStoreId: `firefox-container-${userContextId}`});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the position? We should open the new tab in the same position where we are.
Plus, doing this we are breaks the Back-Forward feature.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another point would be: what about if the URL is loaded from a window.open() ? This breaks also 'the web' because you will open a tab, instead of a window, and the parent window will not have a reference to the new one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would somewhat argue breaking window.opener is a feature. I'm not sure we can fix that through a web extension either right?

@groovecoder
Copy link
Member

The Firefox sec warning page is a good style to copy:

sec-warning

@jonathanKingston
Copy link
Contributor Author

jonathanKingston commented Mar 24, 2017

@groovecoder @bakulf @kjozwiak and @johngruen I pushed an update for the branch auto-container-origin

This has the index mentioned by @bakulf and the new error layout as discussed with @groovecoder and demoed in the meeting.

It is still missing the ability to unassign though.

@jonathanKingston jonathanKingston force-pushed the auto-container-origin branch 2 times, most recently from a2df62f to 90beb31 Compare March 28, 2017 01:53
Copy link
Member

@groovecoder groovecoder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly naming and copy nits. But a big-ish question is if we want to set a global "never ask" preference, or I thought we should start with a "Never ask again for this site".

Should we start out with the more secure/private/annoying UX - i.e., confirm for each individual assignment - and only relax it when users complain?

@@ -1,3 +1,174 @@
const assignManager = {
closeableWindows: new Set([
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: CLOSEABLE_WINDOWS to denote it is a constant/hard-coded set.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using uppercase here makes me cry a little (especially when it's not a const too), much like Hungarian notation does but I will not argue ;)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

200w_d

"about:home",
"about:blank"
]),
menuAssignId: "open-in-this-container",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MENU_ASSIGNED_ID

"about:blank"
]),
menuAssignId: "open-in-this-container",
menuRemoveId: "remove-open-in-this-container",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MENU_REMOVE_ID

});
});

browser.runtime.onMessage.addListener((request) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we change request to something more accurate like neverAskMessage? When I first read this, I thought request was an HTTP request of some kind.

},

getOriginStoreKey(url) {
const storagePrefix = "originContainerMap@@_";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: STORAGE_PREFIX to denote hard-coded constant string.

if (store[originStoreKey]) {
browser.contextMenus.create({
id: this.menuRemoveId,
title: "Remove Open in This Container",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe "Un-assign this site from this Container"

@@ -0,0 +1,25 @@
const redirectUrl = new URL(window.location).searchParams.get("url");
document.getElementById("redirect-url").textContent = redirectUrl;
const redirectOrigin = new URL(redirectUrl).origin;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const redirectHostname = new URL(redirectUrl).hostname and textContent = redirectHostname will probably look cleaner?

</p>
<div id="redirect-url"></div>
<p>
You asked for <span id="redirect-origin"></span> to always open in <span id="container-name">this</span> container, are you sure you want to confirm?<br />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe You assigned <span id="redirect-hostname"></span> to <span id="container-name">this</span> container, ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to change "asked for" to "added" as above however. I personally think that is less code'y.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either copy is fine there. But "are you sure you want to confirm" is redundant? Should be "Are you sure you want to open the page in this container?" right?

@@ -383,7 +383,7 @@ span ~ .panel-header-text {
.panel-footer {
align-items: center;
background: #efefef;
block-size: 55px;
block-size: 54px;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screw you 55th pixel!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was unrelated but part of the menu being unaligned.

"storage",
"tabs",
"webRequestBlocking",
"webRequest"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, we really are creating a tab-manager add-on.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We were just faking it till we made it before, now we are the real deal 🦊

Copy link
Member

@groovecoder groovecoder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost perfect. But, during my spot-checks, I still seemed to lose the context menu feature and the originSettings completely? I'm using jpm watchpost ... so maybe a file-change triggered an .xpi re-install? Will the origin settings survive an addon upgrade?

</p>
<div id="redirect-url"></div>
<p>
You asked for <span id="redirect-origin"></span> to always open in <span id="container-name">this</span> container, are you sure you want to confirm?<br />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either copy is fine there. But "are you sure you want to confirm" is redundant? Should be "Are you sure you want to open the page in this container?" right?

}
resolve(null);
}).catch(() => {
reject();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need a reason here. .catch((e) => { reject(e); }); would be fine.

@groovecoder
Copy link
Member

Also, this needs a version bump to 2.1.0

browser.notifications.create({
type: "basic",
title: "Containers",
message: `Successfully ${actionName} ${pageUrl.origin} to always open in this container`,
Copy link
Member

@groovecoder groovecoder Mar 29, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if we just remove the ${pageUrl.origin} completely? A significant origin string overflows the notification interface, and the important feedback here seems to be the action. Can we assume the user knows the origin they just assigned, since they just assigned it?

@kjozwiak
Copy link

kjozwiak commented Mar 29, 2017

Issues found while testing the auto-container-origin branch on jonathanKingston/testpilot-containers:


Bug [1] [FIXED/VERIFIED]

"Always Open in This Contianer" is being displayed under the context menu under about:privatebrowsing when opening a PB window while the currently focussed tab is a container.

STR:

  • open the personal container via the "+" new tab button and load any website
  • while the personal container is the currently focussed tab, open a new PB window
  • once the PB window opens, right click on the about:privatebrowsing page

screen shot 2017-03-29 at 3 53 46 pm


Bug [2] [FIXED/VERIFIED]

Once you've assigned an origin to a specific container, opening that particular origin within PB won't load the website and will produce the following error in the browser console:

Error: Illegal to set non-private cookieStorageId in a private window

Even though an origin has been assigned to a specific container, users should still be able to open that website within PB as those are two separate features. For example, lets say I assigned google.ca to my "Google" container but I want to search for something that won't appear in my history and I don't feel like creating a "throw away" container. I won't be able to use google.ca in this situation.

STR:

  • open the personal container via the "+" new tab button and load any website
  • open a PB window and load the same website within PB

Bug [3] [FIXED/VERIFIED]

The "Hey, we heard you liked containers!" intermediate window will still appear for origins that belonged to a specific container that have been deleted.

STR:

  • open the personal container and load any website within that container
  • right click on the website and select "Always Open in This Container"
  • close the personal tab
  • remove the personal container via the Containers Test Pilot icon
  • load the same origin... you'll get the "Hey, we heard you liked containers!" even thought it's loading in non-container tab due to the personal container being removed

Bug [4] [FIXED/VERIFIED]

Related to the above issue (bug 3), the "Always Open in This Container" item will appear under the context menu of an origin that used to belong to a container that has now been removed. Once a user deletes a container, we need to remove all origin associations with that particular container.

screen shot 2017-03-29 at 5 32 08 pm

STR:

  • open the personal container and load any website within that container
  • right click on the website and select "Always Open in This Container"
  • close the personal tab
  • remove the personal container via the Containers Test Pilot icon
  • load the same origin... you'll get the "Hey, we heard you liked containers!"
  • select "Take me there"
  • the origin will open in a non-default container.... right click on the page and you'll notice that the "Always Open in This Container" item is appearing under the context menu.

Suggestion, possible Bug [5] [currently not solvable as per @jonathanKingston]

I'm not sure if this is considered a bug or not, but I personally feel like it's going to be an issue. When clearing "everything" from FX using the "Clear Recent History" feature, should we be removing all the origin associations? Even though we've removed all the cookies, history etc... that origin association is still there and the user will get the "Hey, we heard you liked containers!" window.

STR:

  • associate several different origins with several containers
  • remove everything from FX via "Clear History"
  • load any of the previous origins into a non-container window and you'll still be presented with the "Hey, we heard you liked containers!" window.

Bug [6] [FIXED/VERIFIED]

Should we be saving the moz-extension:// warnings into History? I think we're just going to pollute users history data with useless data. You'll also get the following error message in the browser console when you attempt to open of the entries that belonged to a container that has been removed:

NS_ERROR_NOT_AVAILABLE: Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE) [nsIWebNavigation.loadURIWithOptions]  browser.js:848
	_loadURIWithFlags chrome://browser/content/browser.js:848:7
	loadURIWithFlags chrome://browser/content/tabbrowser.xml:7370:13
	openLinkIn chrome://browser/content/utilityOverlay.js:380:5
	openUILinkIn chrome://browser/content/utilityOverlay.js:197:3
	openUILink chrome://browser/content/utilityOverlay.js:102:3
	HM__onCommand chrome://browser/content/browser-places.js:822:7
	oncommand chrome://browser/content/browser.xul:1:1

screen shot 2017-03-29 at 6 06 57 pm

@jonathanKingston jonathanKingston force-pushed the auto-container-origin branch 2 times, most recently from c4f261d to e333f91 Compare March 30, 2017 19:51
@jonathanKingston
Copy link
Contributor Author

@kjozwiak Issues 1,2,6 are solved.

Issues 3,4,5 are not. I'm not actually sure 5 is solvable with the extension. 3,4 are not solvable in web extensions see: https://bugzilla.mozilla.org/show_bug.cgi?id=1352189 I will look into message passing from SDK when I get home (I was hoping to completely dog food web extensions here :( )

@jonathanKingston
Copy link
Contributor Author

TypeError: types.taggedTemplates.includes is not a function
    at isSafeNode (/home/jonathan/projects/testpilot-containers/node_modules/eslint-plugin-no-unescaped/lib/rules/enforce.js:91:37)
    at EventEmitter.AssignmentExpression (/home/jonathan/projects/testpilot-containers/node_modules/eslint-plugin-no-unescaped/lib/rules/enforce.js:152:18)
    at emitOne (events.js:82:20)
    at EventEmitter.emit (events.js:169:7)
    at NodeEventGenerator.enterNode (/home/jonathan/projects/testpilot-containers/node_modules/eslint/lib/util/node-event-generator.js:39:22)
    at CodePathAnalyzer.enterNode (/home/jonathan/projects/testpilot-containers/node_modules/eslint/lib/code-path-analysis/code-path-analyzer.js:607:23)
    at CommentEventGenerator.enterNode (/home/jonathan/projects/testpilot-containers/node_modules/eslint/lib/util/comment-event-generator.js:98:23)
    at Controller.enter (/home/jonathan/projects/testpilot-containers/node_modules/eslint/lib/eslint.js:928:36)
    at Controller.__execute (/home/jonathan/projects/testpilot-containers/node_modules/estraverse/estraverse.js:397:31)
    at Controller.traverse (/home/jonathan/projects/testpilot-containers/node_modules/estraverse/estraverse.js:501:28)

Linting rule I wrote is borked... should fix which is annoying as I want this rule to be replaced.

@jonathanKingston
Copy link
Contributor Author

Also... this latest patch fixes 3 and 4 and rebases.

@jonathanKingston jonathanKingston force-pushed the auto-container-origin branch 3 times, most recently from d2300f8 to ce8b4de Compare April 3, 2017 15:58
Copy link
Member

@groovecoder groovecoder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks good. Spot-checks look good.

@groovecoder
Copy link
Member

I would still be good to merge this, but I notice assigning a site to auto-open in a container now triggers a page-requests-completed-per-tab event with pageRequestCount of 0 for the confirm page being loaded in firefox-default container. 😐

@kjozwiak
Copy link

kjozwiak commented Apr 3, 2017

Verified that bug#1, 2, 3, 4 and 6 have been fixed.

@groovecoder groovecoder merged commit ca1a926 into mozilla:master Apr 3, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants