diff --git a/stored-credentials/README.md b/stored-credentials/README.md new file mode 100644 index 0000000..b9d70f7 --- /dev/null +++ b/stored-credentials/README.md @@ -0,0 +1,32 @@ +# stored-credentials + +**Although this add-on uses a stored password to authenticate to a web server, +it should not be taken as an example of how to store or work securely with +passwords. It's only a demonstration of how to use the +[`webRequest.onAuthRequired`](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/webRequest/onAuthRequired) API.** + +This add-on uses the [`webRequest.onAuthRequired`](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/webRequest/onAuthRequired) API to log the user into +the demo site at https://httpbin.org/basic-auth/user/passwd using a stored +username and password. + +This add-on stores a username and password using the [`storage.local`](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/storage/local) API. +The default value is the correct value +for the demo site: + + username: "user" + password: "passwd" + +You can change the default values in the add-on's [options page](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Options_pages). + +The add-on then uses `webRequest.onAuthRequired` to intercept authentication +requests from the demo site. When it gets +such a request, it fetches the stored credentials and supplies them +asynchronously. + +To try out the add-on: + +* Before installing the add-on, visit https://httpbin.org/basic-auth/user/passwd, +and see that it asks for a username and password. +* [Install the add-on](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Temporary_Installation_in_Firefox) in Firefox 54 or later. +* Visit https://httpbin.org/basic-auth/user/passwd again, and see that authentication succeeds automatically. + diff --git a/stored-credentials/auth.js b/stored-credentials/auth.js new file mode 100644 index 0000000..a5d4778 --- /dev/null +++ b/stored-credentials/auth.js @@ -0,0 +1,48 @@ + +var target = "https://httpbin.org/basic-auth/*"; + +var pendingRequests = []; + +/* +A request has completed. We can stop worrying about it. +*/ +function completed(requestDetails) { + console.log("completed: " + requestDetails.requestId); + var index = pendingRequests.indexOf(requestDetails.requestId); + if (index > -1) { + pendingRequests.splice(index, 1); + } +} + +function provideCredentialsAsync(requestDetails) { + // If we have seen this request before, + // then assume our credentials were bad, + // and give up. + if (pendingRequests.indexOf(requestDetails.requestId) != -1) { + console.log("bad credentials for: " + requestDetails.requestId); + return {cancel: true}; + + } else { + pendingRequests.push(requestDetails.requestId); + console.log("providing credentials for: " + requestDetails.requestId); + // we can return a promise that will be resolved + // with the stored credentials + return browser.storage.local.get(null); + } +} + +browser.webRequest.onAuthRequired.addListener( + provideCredentialsAsync, + {urls: [target]}, + ["blocking"] + ); + +browser.webRequest.onCompleted.addListener( + completed, + {urls: [target]} +); + +browser.webRequest.onErrorOccurred.addListener( + completed, + {urls: [target]} +); diff --git a/stored-credentials/icons/LICENSE b/stored-credentials/icons/LICENSE new file mode 100644 index 0000000..f39164e --- /dev/null +++ b/stored-credentials/icons/LICENSE @@ -0,0 +1 @@ +The "lock".svg" icon is taken from the Material Core iconset and is used under the terms of its license: https://www.iconfinder.com/iconsets/material-core. diff --git a/stored-credentials/icons/lock.svg b/stored-credentials/icons/lock.svg new file mode 100644 index 0000000..1037a7d --- /dev/null +++ b/stored-credentials/icons/lock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/stored-credentials/manifest.json b/stored-credentials/manifest.json new file mode 100644 index 0000000..3e19a85 --- /dev/null +++ b/stored-credentials/manifest.json @@ -0,0 +1,31 @@ +{ + "description": "Performs basic authentication by supplying stored credentials.", + "manifest_version": 2, + "name": "stored-credentials", + "version": "2.0", + "homepage_url": "https://github.com/mdn/webextensions-examples/tree/master/stored-credentials", + "icons": { + "48": "icons/lock.svg" + }, + + "applications": { + "gecko": { + "strict_min_version": "54.0a1" + } + }, + + "background": { + "scripts": ["storage.js", "auth.js"] + }, + + "options_ui": { + "page": "options/options.html" + }, + + "permissions": [ + "webRequest", + "webRequestBlocking", + "storage", + "https://httpbin.org/basic-auth/*" + ] +} diff --git a/stored-credentials/options/options.css b/stored-credentials/options/options.css new file mode 100644 index 0000000..f54cbcf --- /dev/null +++ b/stored-credentials/options/options.css @@ -0,0 +1,23 @@ + +body { + width: 25em; + font-family: "Open Sans Light", sans-serif; + font-size: 0.9em; + font-weight: 300; +} + + +.title { + font-size: 1.2em; + margin-bottom: 0.5em; +} + +label { + float: right; +} + +input { + margin: 0.5em; + width: 200px; + height: 2.5em; +} diff --git a/stored-credentials/options/options.html b/stored-credentials/options/options.html new file mode 100644 index 0000000..235dd6a --- /dev/null +++ b/stored-credentials/options/options.html @@ -0,0 +1,22 @@ + + + +
+ + + + + + +