Disable prompts to save logins while on extension pages #74
Disable prompts to save logins while on extension pages #74
Conversation
await disableRememberSignons(); | ||
}); | ||
it("does not enable login saving for origin when given true", async () => { | ||
await commonTest(true, false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mild corner case here: If the user has turned off saving logins globally in options, getLoginSavingEnabled
always returns false no matter what the setting might be.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! I'm not sure which, if any, parts of the logins API will work if logins are globally disabled. I think this needs investigation; could you file a bug?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From my own experiences, the CRUD portion of the upstream API works just fine regardless of what the global pref and this specific callout are set to.
const origin = browser.extension.getURL("").slice(0, -1); | ||
const savingEnabled = await browser.experiments.logins | ||
.getLoginSavingEnabled(origin); | ||
if (savingEnabled) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checking whether saving is enabled to ensure we keep it off. The user could enable login save globally or manually delete the exception from the list in options. Kind of edge casey, but bleh.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems unlikely that users are going to mess with this manually. That said, the browser APIs are available from extension pages, so we could just run this check when the management page is loaded (or, to get kind of extreme about the "user messes things up" edge case, we could run this check on page load and whenever the page visibility API's visibilitychange
event fires).
Hmm, so I only ensure saving is off on startup of the addon. The user could later enable saving in options or delete the exception - and then we'd see the login save prompt come up until next add-on startup. I wonder if I should make a check more often? Like, say, whenever the browser action button is clicked? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is working well for me.
Hmm, so I only ensure saving is off on startup of the addon. The user could later enable saving in options or delete the exception - and then we'd see the login save prompt come up until next add-on startup.
I wonder if I should make a check more often? Like, say, whenever the browser action button is clicked?
I think it would be pretty rare for someone to go and manually delete that rule, If they did I think it's fine to respect it until the next addon startup.
I think we can start with this, and see how it goes. If we do it more frequently, I'd argue for whenever we think the management page is loaded. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work overall! Technically, I think this can land as-is, but I do have some suggestions to consider.
src/experiments/logins/api.js
Outdated
@@ -49,6 +49,20 @@ this.logins = class extends ExtensionAPI { | |||
// - fooLogin = login as vanilla JS object | |||
// - fooLoginInfo = login as nsILoginInfo | |||
// - fooBag = (subset of) login fields as nsIPropertyBag | |||
getLoginSavingEnabled(aHost) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really dislike the aFoo
naming convention. How about just calling this origin
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Heh, I used aHost to match the upstream API, but I can change it if necessary
src/experiments/logins/api.js
Outdated
@@ -49,6 +49,20 @@ this.logins = class extends ExtensionAPI { | |||
// - fooLogin = login as vanilla JS object | |||
// - fooLoginInfo = login as nsILoginInfo | |||
// - fooBag = (subset of) login fields as nsIPropertyBag | |||
getLoginSavingEnabled(aHost) { | |||
try { | |||
return Services.logins.getLoginSavingEnabled(aHost); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The trailing slash thing seems like a super annoying gotcha. I think we should either handle it here (strip it out or throw if it's detected), or document this annoyance in the schema docs.
src/experiments/logins/schema.json
Outdated
{ | ||
"name": "getLoginSavingEnabled", | ||
"type": "function", | ||
"description": "For the given origin, gets a boolean flag which determines whether login saving is enabled", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should also mention that the returned promise is rejected if the URL is malformed.
"parameters": [{ | ||
"name": "aHost", | ||
"type": "string", | ||
"description": "The origin for which to check the status of login saving" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just use the description from the IDL: The hostname to check. This argument should be in the origin URL format, with no pathname. For example: "https://www.site.com".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, looking at the schema docs, I haven't been super strict about reusing the IDL descriptions. This could be fine as is (but aHost
does bug me ;-P).
src/experiments/logins/schema.json
Outdated
{ | ||
"name": "setLoginSavingEnabled", | ||
"type": "function", | ||
"description": "For the given origin, uses the given value to set a boolean flag which determines whether login saving is enabled", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The IDL docs may be clearer here. Also, be sure to mention cases in which the returned promise is rejected, which I think is just if the URL is malformed.
src/experiments/logins/api.js
Outdated
throw new ExtensionError(ex); | ||
} | ||
}, | ||
setLoginSavingEnabled(aHost, isEnabled) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about origin
and shouldSaveLogins
for the arguments?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, same as above, I was trying to follow the underlying API rather than invent new names
const enableRememberSignons = async () => { | ||
await webext.inChrome(); | ||
await driver.executeScript(` | ||
Services.prefs.setBoolPref("signon.rememberSignons", true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be good to actually call the Services.logins.get/setLoginSavingEnabled for a specific origin, then test it's correctly returned when you call the API. I wonder what happens if you accidentally leave in a trailing slash, for instance. This could be left for a followup commit.
await disableRememberSignons(); | ||
}); | ||
it("does not enable login saving for origin when given true", async () => { | ||
await commonTest(true, false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! I'm not sure which, if any, parts of the logins API will work if logins are globally disabled. I think this needs investigation; could you file a bug?
Whoops! Didn't see Matt had already reviewed. Sorry to pile on :-P |
|
d253c8c
to
59c1ce4
Compare
- Add getLoginSavingEnabled and setLoginSavingEnabled methods to the Logins experiment API - Disable login saving for extension pages on background startup Fixes mozilla-lockwise#57
59c1ce4
to
a6efbfa
Compare
Actually, you know what: Never mind my last commit. It occurred to me over the weekend that this PR without the event handler to automatically re-enable the exception was already 80% of the solution and pretty much reviewed. My commit that uses the permission events still needs time to bake, so I'll do it in a follow-up PR. I can probably add some more test cases there, too |
I wish to verify the fix of this issue, but I'm lacking some steps here. How am I supposed to reproduce/verify this issue? Thanks. |
Add getLoginSavingEnabled and setLoginSavingEnabled methods to the
Logins experiment API
Disable login saving for extension pages on background startup
Fixes #57