├── .gitignore ├── LICENSE.md ├── README.md ├── documentation ├── KeePassHttp-Connector.md ├── chromeIPass - old readme from web store.txt ├── chromeIPass-changelog └── images │ ├── cip-autocomplete.png │ ├── cip-browser-icon.png │ ├── cip-choose-credential-fields.png │ ├── cip-console-background.png │ ├── cip-console-inline.png │ ├── cip-context-menu.png │ ├── cip-extensions-developer-mode.png │ ├── cip-extensions-normal-mode.png │ ├── cip-password-generator.png │ ├── cip-popup-choose-credentials.png │ ├── cip-popup-connect.png │ ├── cip-popup-normal.png │ ├── cip-popup-remember-update.png │ ├── cip-popup-remember.png │ ├── cip-settings-connected-databases.png │ ├── cip-settings-general.png │ ├── cip-settings-specified-credential-fields.png │ ├── cip-store-screenshot.png │ ├── http-auth-request.png │ ├── keepass-association-key.png │ ├── keepass-password-generation-options.png │ └── psd │ ├── cip-autocomplete.psd │ ├── cip-browser-icon.psd │ ├── cip-choose-credential-fields.psd │ ├── cip-console-background.psd │ ├── cip-console-inline.psd │ ├── cip-context-menu.psd │ ├── cip-extensions-developer-mode.psd │ ├── cip-extensions-normal-mode.psd │ ├── cip-password-generator.psd │ ├── cip-popup-choose-credentials.psd │ ├── cip-popup-connect.psd │ ├── cip-popup-normal.psd │ ├── cip-popup-remember-update.psd │ ├── cip-popup-remember.psd │ ├── cip-settings-connected-databases.psd │ ├── cip-settings-general.psd │ ├── cip-settings-specified-credential-fields.psd │ ├── cip-store-screenshot.psd │ ├── http-auth-request.psd │ ├── keepass-association-key.psd │ └── keepass-password-generation-options.psd └── src ├── background ├── aes.js ├── browserAction.js ├── cryptoHelpers.js ├── event.js ├── httpauth.js ├── init.js ├── keepass.js ├── page.js ├── sjcl.js ├── utf8.js └── utils.js ├── bootstrap-btn.css ├── browser-polyfill.min.js ├── icons ├── 19x19 │ ├── icon_bang_aqua-inverse_19x19.png │ ├── icon_bang_aqua_19x19.png │ ├── icon_bang_blue-inverse_19x19.png │ ├── icon_bang_blue_19x19.png │ ├── icon_bang_green-inverse_19x19.png │ ├── icon_bang_green_19x19.png │ ├── icon_bang_grey-inverse_19x19.png │ ├── icon_bang_grey_19x19.png │ ├── icon_bang_orange-inverse_19x19.png │ ├── icon_bang_orange_19x19.png │ ├── icon_bang_pink-inverse_19x19.png │ ├── icon_bang_pink_19x19.png │ ├── icon_bang_purple-inverse_19x19.png │ ├── icon_bang_purple_19x19.png │ ├── icon_bang_red-inverse_19x19.png │ ├── icon_bang_red_19x19.png │ ├── icon_bang_yellow-inverse_19x19.png │ ├── icon_bang_yellow_19x19.png │ ├── icon_cross_aqua-inverse_19x19.png │ ├── icon_cross_aqua_19x19.png │ ├── icon_cross_blue-inverse_19x19.png │ ├── icon_cross_blue_19x19.png │ ├── icon_cross_green-inverse_19x19.png │ ├── icon_cross_green_19x19.png │ ├── icon_cross_grey-inverse_19x19.png │ ├── icon_cross_grey_19x19.png │ ├── icon_cross_orange-inverse_19x19.png │ ├── icon_cross_orange_19x19.png │ ├── icon_cross_pink-inverse_19x19.png │ ├── icon_cross_pink_19x19.png │ ├── icon_cross_purple-inverse_19x19.png │ ├── icon_cross_purple_19x19.png │ ├── icon_cross_red-inverse_19x19.png │ ├── icon_cross_red_19x19.png │ ├── icon_cross_yellow-inverse_19x19.png │ ├── icon_cross_yellow_19x19.png │ ├── icon_new_bang_aqua-inverse_19x19.png │ ├── icon_new_bang_aqua_19x19.png │ ├── icon_new_bang_blue-inverse_19x19.png │ ├── icon_new_bang_blue_19x19.png │ ├── icon_new_bang_green-inverse_19x19.png │ ├── icon_new_bang_green_19x19.png │ ├── icon_new_bang_grey-inverse_19x19.png │ ├── icon_new_bang_grey_19x19.png │ ├── icon_new_bang_orange-inverse_19x19.png │ ├── icon_new_bang_orange_19x19.png │ ├── icon_new_bang_pink-inverse_19x19.png │ ├── icon_new_bang_pink_19x19.png │ ├── icon_new_bang_purple-inverse_19x19.png │ ├── icon_new_bang_purple_19x19.png │ ├── icon_new_bang_red-inverse_19x19.png │ ├── icon_new_bang_red_19x19.png │ ├── icon_new_bang_yellow-inverse_19x19.png │ ├── icon_new_bang_yellow_19x19.png │ ├── icon_new_cross_aqua-inverse_19x19.png │ ├── icon_new_cross_aqua_19x19.png │ ├── icon_new_cross_blue-inverse_19x19.png │ ├── icon_new_cross_blue_19x19.png │ ├── icon_new_cross_green-inverse_19x19.png │ ├── icon_new_cross_green_19x19.png │ ├── icon_new_cross_grey-inverse_19x19.png │ ├── icon_new_cross_grey_19x19.png │ ├── icon_new_cross_orange-inverse_19x19.png │ ├── icon_new_cross_orange_19x19.png │ ├── icon_new_cross_pink-inverse_19x19.png │ ├── icon_new_cross_pink_19x19.png │ ├── icon_new_cross_purple-inverse_19x19.png │ ├── icon_new_cross_purple_19x19.png │ ├── icon_new_cross_red-inverse_19x19.png │ ├── icon_new_cross_red_19x19.png │ ├── icon_new_cross_yellow-inverse_19x19.png │ ├── icon_new_cross_yellow_19x19.png │ ├── icon_new_normal_aqua-inverse_19x19.png │ ├── icon_new_normal_aqua_19x19.png │ ├── icon_new_normal_blue-inverse_19x19.png │ ├── icon_new_normal_blue_19x19.png │ ├── icon_new_normal_green-inverse_19x19.png │ ├── icon_new_normal_green_19x19.png │ ├── icon_new_normal_grey-inverse_19x19.png │ ├── icon_new_normal_grey_19x19.png │ ├── icon_new_normal_orange-inverse_19x19.png │ ├── icon_new_normal_orange_19x19.png │ ├── icon_new_normal_pink-inverse_19x19.png │ ├── icon_new_normal_pink_19x19.png │ ├── icon_new_normal_purple-inverse_19x19.png │ ├── icon_new_normal_purple_19x19.png │ ├── icon_new_normal_red-inverse_19x19.png │ ├── icon_new_normal_red_19x19.png │ ├── icon_new_normal_yellow-inverse_19x19.png │ ├── icon_new_normal_yellow_19x19.png │ ├── icon_new_questionmark_aqua-inverse_19x19.png │ ├── icon_new_questionmark_aqua_19x19.png │ ├── icon_new_questionmark_blue-inverse_19x19.png │ ├── icon_new_questionmark_blue_19x19.png │ ├── icon_new_questionmark_green-inverse_19x19.png │ ├── icon_new_questionmark_green_19x19.png │ ├── icon_new_questionmark_grey-inverse_19x19.png │ ├── icon_new_questionmark_grey_19x19.png │ ├── icon_new_questionmark_orange-inverse_19x19.png │ ├── icon_new_questionmark_orange_19x19.png │ ├── icon_new_questionmark_pink-inverse_19x19.png │ ├── icon_new_questionmark_pink_19x19.png │ ├── icon_new_questionmark_purple-inverse_19x19.png │ ├── icon_new_questionmark_purple_19x19.png │ ├── icon_new_questionmark_red-inverse_19x19.png │ ├── icon_new_questionmark_red_19x19.png │ ├── icon_new_questionmark_yellow-inverse_19x19.png │ ├── icon_new_questionmark_yellow_19x19.png │ ├── icon_normal_aqua-inverse_19x19.png │ ├── icon_normal_aqua_19x19.png │ ├── icon_normal_blue-inverse_19x19.png │ ├── icon_normal_blue_19x19.png │ ├── icon_normal_green-inverse_19x19.png │ ├── icon_normal_green_19x19.png │ ├── icon_normal_grey-inverse_19x19.png │ ├── icon_normal_grey_19x19.png │ ├── icon_normal_orange-inverse_19x19.png │ ├── icon_normal_orange_19x19.png │ ├── icon_normal_pink-inverse_19x19.png │ ├── icon_normal_pink_19x19.png │ ├── icon_normal_purple-inverse_19x19.png │ ├── icon_normal_purple_19x19.png │ ├── icon_normal_red-inverse_19x19.png │ ├── icon_normal_red_19x19.png │ ├── icon_normal_yellow-inverse_19x19.png │ ├── icon_normal_yellow_19x19.png │ ├── icon_questionmark_aqua-inverse_19x19.png │ ├── icon_questionmark_aqua_19x19.png │ ├── icon_questionmark_blue-inverse_19x19.png │ ├── icon_questionmark_blue_19x19.png │ ├── icon_questionmark_green-inverse_19x19.png │ ├── icon_questionmark_green_19x19.png │ ├── icon_questionmark_grey-inverse_19x19.png │ ├── icon_questionmark_grey_19x19.png │ ├── icon_questionmark_orange-inverse_19x19.png │ ├── icon_questionmark_orange_19x19.png │ ├── icon_questionmark_pink-inverse_19x19.png │ ├── icon_questionmark_pink_19x19.png │ ├── icon_questionmark_purple-inverse_19x19.png │ ├── icon_questionmark_purple_19x19.png │ ├── icon_questionmark_red-inverse_19x19.png │ ├── icon_questionmark_red_19x19.png │ ├── icon_questionmark_yellow-inverse_19x19.png │ ├── icon_questionmark_yellow_19x19.png │ ├── icon_remember_red_background_19x19.png │ └── icon_remember_red_lock_19x19.png ├── keepass_128x128.png ├── keepass_16x16.png ├── keepass_38x38.png ├── keepass_48x48.png ├── key_16x16.png └── key_24x24.png ├── images ├── ui-icons_444444_256x240.png ├── ui-icons_555555_256x240.png ├── ui-icons_777620_256x240.png ├── ui-icons_777777_256x240.png ├── ui-icons_cc0000_256x240.png └── ui-icons_ffffff_256x240.png ├── jquery-3.2.1.min.js ├── jquery-ui.min.css ├── jquery-ui.min.js ├── kphc.css ├── kphc.js ├── manifest.json ├── options ├── bootstrap-theme.min.css ├── bootstrap.min.css ├── bootstrap.min.js ├── http-auth-dialog.png ├── options.html └── options.js └── popups ├── popup.css ├── popup.html ├── popup.js ├── popup_functions.js ├── popup_httpauth.html ├── popup_httpauth.js ├── popup_login.html ├── popup_login.js ├── popup_multiple-fields.html ├── popup_remember.html ├── popup_remember.js └── throbber.gif /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | /nbproject/ 3 | chromeipass.pem 4 | /chromeipass-data/ 5 | .idea/ 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KeePassHttp-Connector 2 | 3 | is an extension to integrate [KeePass](http://keepass.info)/[KeePassXC](https://keepassxc.org/) as a password manager with Mozilla Firefox and Google Chrome browsers. 4 | 5 | They require [KeePassHttp](https://github.com/pfn/keepasshttp/), a KeePass plugin to expose password entries securely (256bit AES/CBC) over HTTP. 6 | 7 | It was forked from [chromeIPass/passIFox](https://github.com/pfn/passifox), with support for newer versions of Firefox (42+). 8 | 9 | ## Deprecation Notice 10 | 11 | This extension will no longer be maintained since KeePassXC 2.3.0 now includes support for the [keepassxc-browser](https://github.com/keepassxreboot/keepassxc-browser) extension, and will be removing KeePassHTTP support in a future release. 12 | 13 | For KeePass, you can use my [KeePassNatMsg](https://github.com/smorks/keepassnatmsg) plugin, which also works with the keepassxc-browser extension. 14 | 15 | ## Downloads 16 | 17 | - Mozilla Firefox - [Add-on](https://addons.mozilla.org/en-US/firefox/addon/keepasshttp-connector/) 18 | - Google Chrome - [Extension](https://chrome.google.com/webstore/detail/keepasshttp-connector/dafgdjggglmmknipkhngniifhplpcldb) 19 | 20 | ## Documentation 21 | 22 | - [Documentation](https://github.com/smorks/keepasshttp-connector/blob/master/documentation/KeePassHttp-Connector.md) (features, installation guide, troubleshooting, functionality, etc.) 23 | 24 | Support is always welcome. 25 | 26 | ## Troubleshooting 27 | 28 | If you [open an issue](https://github.com/smorks/keepasshttp-connector/issues/), always give us the following information: 29 | 30 | 1. the extension are you using and its version 31 | 2. version of your browser 32 | 3. KeePassHttp version 33 | 4. KeePass/KeePassXC version 34 | 5. pages on which the error occur 35 | -------------------------------------------------------------------------------- /documentation/chromeIPass - old readme from web store.txt: -------------------------------------------------------------------------------- 1 | KeePass integration for browser Chrome using KeePassHttp 2 | 3 | NEW UPDATE, Version 2.2.1, brings many requested features to ChromeIPass. 4 | 5 | ChromeIPass brings KeePass integration to the Google Chrome browser! 6 | 7 | For users of KeePass 2.17 and newer, please make sure to use KeePassHttp 1.0.4.0 or newer; previous versions will not work. For users of KeePass 2.16 and older, be sure to use KeePassHttp 1.0.3.9 and lower. It is strongly recommended that you use the latest versions of KeePassHttp and KeePass. 8 | 9 | Changes: 10 | 2.3.4: Lukas Schulze: fix "checking status" bug 11 | 2.3.3: Lukas Schulze: added permissions for update-function for KeePassHttp; added keyboard support for context-menu; fixed escaping identifiers; fixed detection of field combinations when pressing Ctrl+Shift+U; redesigned dialog of password-generator 12 | 2.3.1: Lukas Schulze: added password-generator (only works with the latest version of KeePassHttp, disabled for older versions); changed the way of identifying and accessing credential fields (no longer uses only the ID of an field, because several sites don't use unique IDs); improved feature choose-own-credential-fields 13 | 2.2.3: Lukas Schulze: fix jQuery css styling issues (chromeipass no longer override web-site appearance). Fix jquery date pickers. 14 | 2.2.1: Update to webstore manifest version2. Completely re-worked for the updated Chrome extension APIs, supports updating and saving new KeePass entries, supports HTTP authentication (Basic and Digest auth). Many more new features. All new enhancements are courtesy of Lukas Schulze, thank you! 15 | 1.0.7: fix forms that use HTML5's type="email" for username (e.g. amazon) 16 | 1.0.4: minor bugfix in getFields, filter user fields to only be text 17 | 1.0.6: utf8 support for login and password fields, thanks DeniSix 18 | 19 | Support: 20 | * Please post any questions or support issues at the github messenger/tracker (the "Developer Website" link to the right) 21 | 22 | Features: 23 | * Secure integration with KeePass using the KeePassHttp plugin (https://github.com/pfn/keepasshttp/ download from https://passifox.appspot.com/KeePassHttp.plgx) 24 | * Automated password form fill 25 | * Support for multiple logins at a single site (intuitive pageAction-based workflow) 26 | * Context menu entries for manually selecting username and password fields to fill 27 | * Notifications are always displayed whenever passwords are retrieved from KeePass, in some instances it is even possible to deny and allow access. (When the host names do not match exactly, user interaction is required to allow access; the decision can be remembered). 28 | * Open source, available for inspection at https://github.com/pfn/passifox 29 | * Also supported on Firefox4: use the same KeePass database for Google Chrome and Firefox 30 | 31 | Future features and enhancements: 32 | * Automatic password generation and entry creation 33 | 34 | Requirements: 35 | * KeePass 2 (http://keepass.info) version 2.17 or newer 36 | * KeePassHttp (https://github.com/pfn/keepasshttp/ download at https://passifox.appspot.com/KeePassHttp.plgx) 37 | 38 | Directions: 39 | 1) Install KeePass 40 | 2) Install KeePassHttp by dropping KeePassHttp.plgx into the KeePass Program Files directory 41 | 2a) Log into KeePass 42 | 2b) Verify KeePassHttp has been installed correctly by checking Tools > Plugins 43 | 3) Navigate to any page containing a password 44 | 4) Click the KeePass icon in the URL bar and click the "Connect" button 45 | 5) Switch to the KeePass window and enter a descriptive name for your "Chrome Browser" into the dialog that popped up and click save. 46 | 6) Your passwords are now securely retrieved from KeePass and automatically entered into password forms and fields when needed. 47 | 7) Passwords in KeePass should be entered with the "Title" containing the domain or host name for the site in question; KeePassHttp does some basic pattern matching, for example "google.com" would match http://login.google.com/ if there were such a thing. (KeePassHttp 1.0.2.0 now searches the "URL" field in the same way) 48 | 8) If you are ever lost, click on the KeePass icon in the URL bar and it will let you know status as well as any available options. 49 | 50 | Linux and Mac users: 51 | If you are using KeePass with Mono, then you're in luck. I have tested KeePassHttp with Mono 2.6.7 and it appears to work well. I cannot get the plgx file to work on Linux, perhaps you may have more luck, but I can get my dll files to work directly when put into the KeePass directory (possibly the Plugin directory as well, I have not tried). You can get KeePassHttp.dll and Newtonsoft.Json.dll from https://github.com/pfn/keepasshttp/tree/master/KeePassHttp 52 | 53 | Windows users: 54 | If the PLGX file does not work, it is possible to use the DLL files as mentioned above for Linux and Mac users. The above DLLs are universal binaries and work cross-platform. 55 | 56 | It is recommended to disable the builtin Chrome password management when using this extension. -------------------------------------------------------------------------------- /documentation/chromeIPass-changelog: -------------------------------------------------------------------------------- 1 | 2.3.4: Lukas Schulze: fix "checking status" bug 2 | 2.3.3: Lukas Schulze: added permissions for update-function for KeePassHttp; added keyboard support for context-menu; fixed escaping identifiers; fixed detection of field combinations when pressing Ctrl+Shift+U; redesigned dialog of password-generator 3 | 2.3.1: Lukas Schulze: added password-generator (only works with the latest version of KeePassHttp, disabled for older versions); changed the way of identifying and accessing credential fields (no longer uses only the ID of an field, because several sites don't use unique IDs); improved feature choose-own-credential-fields 4 | 2.2.3: Lukas Schulze: fix jQuery css styling issues (chromeipass no longer override web-site appearance). Fix jquery date pickers. 5 | 2.2.1: Update to webstore manifest version2. Completely re-worked for the updated Chrome extension APIs, supports updating and saving new KeePass entries, supports HTTP authentication (Basic and Digest auth). Many more new features. All new enhancements are courtesy of Lukas Schulze, thank you! 6 | 1.0.7: fix forms that use HTML5's type="email" for username (e.g. amazon) 7 | 1.0.4: minor bugfix in getFields, filter user fields to only be text 8 | 1.0.6: utf8 support for login and password fields, thanks DeniSix -------------------------------------------------------------------------------- /documentation/images/cip-autocomplete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/cip-autocomplete.png -------------------------------------------------------------------------------- /documentation/images/cip-browser-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/cip-browser-icon.png -------------------------------------------------------------------------------- /documentation/images/cip-choose-credential-fields.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/cip-choose-credential-fields.png -------------------------------------------------------------------------------- /documentation/images/cip-console-background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/cip-console-background.png -------------------------------------------------------------------------------- /documentation/images/cip-console-inline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/cip-console-inline.png -------------------------------------------------------------------------------- /documentation/images/cip-context-menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/cip-context-menu.png -------------------------------------------------------------------------------- /documentation/images/cip-extensions-developer-mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/cip-extensions-developer-mode.png -------------------------------------------------------------------------------- /documentation/images/cip-extensions-normal-mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/cip-extensions-normal-mode.png -------------------------------------------------------------------------------- /documentation/images/cip-password-generator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/cip-password-generator.png -------------------------------------------------------------------------------- /documentation/images/cip-popup-choose-credentials.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/cip-popup-choose-credentials.png -------------------------------------------------------------------------------- /documentation/images/cip-popup-connect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/cip-popup-connect.png -------------------------------------------------------------------------------- /documentation/images/cip-popup-normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/cip-popup-normal.png -------------------------------------------------------------------------------- /documentation/images/cip-popup-remember-update.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/cip-popup-remember-update.png -------------------------------------------------------------------------------- /documentation/images/cip-popup-remember.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/cip-popup-remember.png -------------------------------------------------------------------------------- /documentation/images/cip-settings-connected-databases.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/cip-settings-connected-databases.png -------------------------------------------------------------------------------- /documentation/images/cip-settings-general.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/cip-settings-general.png -------------------------------------------------------------------------------- /documentation/images/cip-settings-specified-credential-fields.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/cip-settings-specified-credential-fields.png -------------------------------------------------------------------------------- /documentation/images/cip-store-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/cip-store-screenshot.png -------------------------------------------------------------------------------- /documentation/images/http-auth-request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/http-auth-request.png -------------------------------------------------------------------------------- /documentation/images/keepass-association-key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/keepass-association-key.png -------------------------------------------------------------------------------- /documentation/images/keepass-password-generation-options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/keepass-password-generation-options.png -------------------------------------------------------------------------------- /documentation/images/psd/cip-autocomplete.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/psd/cip-autocomplete.psd -------------------------------------------------------------------------------- /documentation/images/psd/cip-browser-icon.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/psd/cip-browser-icon.psd -------------------------------------------------------------------------------- /documentation/images/psd/cip-choose-credential-fields.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/psd/cip-choose-credential-fields.psd -------------------------------------------------------------------------------- /documentation/images/psd/cip-console-background.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/psd/cip-console-background.psd -------------------------------------------------------------------------------- /documentation/images/psd/cip-console-inline.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/psd/cip-console-inline.psd -------------------------------------------------------------------------------- /documentation/images/psd/cip-context-menu.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/psd/cip-context-menu.psd -------------------------------------------------------------------------------- /documentation/images/psd/cip-extensions-developer-mode.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/psd/cip-extensions-developer-mode.psd -------------------------------------------------------------------------------- /documentation/images/psd/cip-extensions-normal-mode.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/psd/cip-extensions-normal-mode.psd -------------------------------------------------------------------------------- /documentation/images/psd/cip-password-generator.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/psd/cip-password-generator.psd -------------------------------------------------------------------------------- /documentation/images/psd/cip-popup-choose-credentials.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/psd/cip-popup-choose-credentials.psd -------------------------------------------------------------------------------- /documentation/images/psd/cip-popup-connect.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/psd/cip-popup-connect.psd -------------------------------------------------------------------------------- /documentation/images/psd/cip-popup-normal.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/psd/cip-popup-normal.psd -------------------------------------------------------------------------------- /documentation/images/psd/cip-popup-remember-update.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/psd/cip-popup-remember-update.psd -------------------------------------------------------------------------------- /documentation/images/psd/cip-popup-remember.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/psd/cip-popup-remember.psd -------------------------------------------------------------------------------- /documentation/images/psd/cip-settings-connected-databases.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/psd/cip-settings-connected-databases.psd -------------------------------------------------------------------------------- /documentation/images/psd/cip-settings-general.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/psd/cip-settings-general.psd -------------------------------------------------------------------------------- /documentation/images/psd/cip-settings-specified-credential-fields.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/psd/cip-settings-specified-credential-fields.psd -------------------------------------------------------------------------------- /documentation/images/psd/cip-store-screenshot.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/psd/cip-store-screenshot.psd -------------------------------------------------------------------------------- /documentation/images/psd/http-auth-request.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/psd/http-auth-request.psd -------------------------------------------------------------------------------- /documentation/images/psd/keepass-association-key.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/psd/keepass-association-key.psd -------------------------------------------------------------------------------- /documentation/images/psd/keepass-password-generation-options.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/documentation/images/psd/keepass-password-generation-options.psd -------------------------------------------------------------------------------- /src/background/browserAction.js: -------------------------------------------------------------------------------- 1 | var browserAction = {}; 2 | 3 | var BLINK_TIMEOUT_DEFAULT = 7500; 4 | var BLINK_TIMEOUT_REDIRECT_THRESHOLD_TIME_DEFAULT = -1; 5 | var BLINK_TIMEOUT_REDIRECT_COUNT_DEFAULT = 1; 6 | 7 | browserAction.show = function(callback, tab) { 8 | var data = {}; 9 | if(!page.tabs[tab.id] || page.tabs[tab.id].stack.length == 0) { 10 | browserAction.showDefault(callback, tab); 11 | return; 12 | } 13 | else { 14 | data = page.tabs[tab.id].stack[page.tabs[tab.id].stack.length - 1]; 15 | } 16 | 17 | browser.browserAction.setIcon({ 18 | tabId: tab.id, 19 | path: "/icons/19x19/" + browserAction.generateIconName(data.iconType, data.icon) 20 | }); 21 | 22 | if(data.popup) { 23 | browser.browserAction.setPopup({ 24 | tabId: tab.id, 25 | popup: "popups/" + data.popup 26 | }); 27 | } 28 | } 29 | 30 | browserAction.update = function(interval) { 31 | if(!page.tabs[page.currentTabId] || page.tabs[page.currentTabId].stack.length == 0) { 32 | return; 33 | } 34 | 35 | var data = page.tabs[page.currentTabId].stack[page.tabs[page.currentTabId].stack.length - 1]; 36 | 37 | if(typeof data.visibleForMilliSeconds != "undefined") { 38 | if(data.visibleForMilliSeconds <= 0) { 39 | browserAction.stackPop(page.currentTabId); 40 | browserAction.show(null, {"id": page.currentTabId}); 41 | page.clearCredentials(page.currentTabId); 42 | return; 43 | } 44 | data.visibleForMilliSeconds -= interval; 45 | } 46 | 47 | if(data.intervalIcon) { 48 | data.intervalIcon.counter += 1; 49 | if(data.intervalIcon.counter < data.intervalIcon.max) { 50 | return; 51 | } 52 | 53 | data.intervalIcon.counter = 0; 54 | data.intervalIcon.index += 1; 55 | 56 | if(data.intervalIcon.index > data.intervalIcon.icons.length - 1) { 57 | data.intervalIcon.index = 0; 58 | } 59 | 60 | browser.browserAction.setIcon({ 61 | tabId: page.currentTabId, 62 | path: "/icons/19x19/" + browserAction.generateIconName(null, data.intervalIcon.icons[data.intervalIcon.index]) 63 | }); 64 | } 65 | } 66 | 67 | browserAction.showDefault = function(callback, tab) { 68 | var stackData = { 69 | level: 1, 70 | iconType: "normal", 71 | popup: "popup.html" 72 | } 73 | keepass.isConfigured().then((configured) => { 74 | if(!configured || keepass.isDatabaseClosed || !keepass.isKeePassHttpAvailable || page.tabs[tab.id].errorMessage) { 75 | stackData.iconType = "cross"; 76 | } 77 | 78 | if(page.tabs[tab.id].loginList.length > 0) { 79 | stackData.iconType = "questionmark"; 80 | stackData.popup = "popup_login.html"; 81 | } 82 | 83 | browserAction.stackUnshift(stackData, tab.id); 84 | 85 | browserAction.show(null, tab); 86 | }); 87 | } 88 | 89 | browserAction.stackAdd = function(callback, tab, icon, popup, level, push, visibleForMilliSeconds, visibleForPageUpdates, redirectOffset, dontShow) { 90 | var id = tab.id || page.currentTabId; 91 | 92 | if(!level) { 93 | level = 1; 94 | } 95 | 96 | var stackData = { 97 | "level": level, 98 | "icon": icon 99 | } 100 | 101 | if(popup) { 102 | stackData.popup = popup; 103 | } 104 | 105 | if(visibleForMilliSeconds) { 106 | stackData.visibleForMilliSeconds = visibleForMilliSeconds; 107 | } 108 | 109 | if(visibleForPageUpdates) { 110 | stackData.visibleForPageUpdates = visibleForPageUpdates; 111 | } 112 | 113 | if(redirectOffset) { 114 | stackData.redirectOffset = redirectOffset; 115 | } 116 | 117 | if(push) { 118 | browserAction.stackPush(stackData, id); 119 | } 120 | else { 121 | browserAction.stackUnshift(stackData, id); 122 | } 123 | 124 | if(!dontShow) { 125 | browserAction.show(null, {"id": id}); 126 | } 127 | } 128 | 129 | 130 | browserAction.removeLevelFromStack = function(callback, tab, level, type, dontShow) { 131 | if(!page.tabs[tab.id]) { 132 | return; 133 | } 134 | 135 | if(!type) { 136 | type = "<="; 137 | } 138 | 139 | var newStack = []; 140 | for(var i = 0; i < page.tabs[tab.id].stack.length; i++) { 141 | if( 142 | (type == "<" && page.tabs[tab.id].stack[i].level >= level) || 143 | (type == "<=" && page.tabs[tab.id].stack[i].level > level) || 144 | (type == "=" && page.tabs[tab.id].stack[i].level != level) || 145 | (type == "==" && page.tabs[tab.id].stack[i].level != level) || 146 | (type == "!=" && page.tabs[tab.id].stack[i].level == level) || 147 | (type == ">" && page.tabs[tab.id].stack[i].level <= level) || 148 | (type == ">=" && page.tabs[tab.id].stack[i].level < level) 149 | ) { 150 | newStack.push(page.tabs[tab.id].stack[i]); 151 | } 152 | } 153 | 154 | page.tabs[tab.id].stack = newStack; 155 | 156 | if(!dontShow) { 157 | browserAction.show(callback, tab); 158 | } 159 | } 160 | 161 | browserAction.stackPop = function(tabId) { 162 | var id = tabId || page.currentTabId; 163 | 164 | page.tabs[id].stack.pop(); 165 | }; 166 | 167 | browserAction.stackPush = function(data, tabId) { 168 | var id = tabId || page.currentTabId; 169 | 170 | browserAction.removeLevelFromStack(null, {"id": id}, data.level, "<=", true); 171 | page.tabs[id].stack.push(data); 172 | }; 173 | 174 | browserAction.stackUnshift = function(data, tabId) { 175 | var id = tabId || page.currentTabId; 176 | 177 | browserAction.removeLevelFromStack(null, {"id": id}, data.level, "<=", true); 178 | page.tabs[id].stack.unshift(data); 179 | }; 180 | 181 | 182 | browserAction.removeRememberPopup = function(callback, tab, removeImmediately) { 183 | if(!page.tabs[tab.id]) { 184 | return; 185 | } 186 | 187 | if(page.tabs[tab.id].stack.length == 0) { 188 | page.clearCredentials(tab.id); 189 | return; 190 | } 191 | var data = page.tabs[tab.id].stack[page.tabs[tab.id].stack.length - 1]; 192 | 193 | if(removeImmediately || !isNaN(data.visibleForPageUpdates)) { 194 | var currentMS = Date.now(); 195 | if( removeImmediately || (data.visibleForPageUpdates <= 0 && data.redirectOffset > 0)) { 196 | browserAction.stackPop(tab.id); 197 | browserAction.show(null, {"id": tab.id}); 198 | page.clearCredentials(tab.id); 199 | return; 200 | } 201 | else if (!isNaN(data.visibleForPageUpdates) && data.redirectOffset > 0 && currentMS >= data.redirectOffset) { 202 | data.visibleForPageUpdates = data.visibleForPageUpdates - 1; 203 | } 204 | } 205 | }; 206 | 207 | browserAction.setRememberPopup = function(tabId, username, password, url, usernameExists, credentialsList) { 208 | browser.storage.local.get({'settings': {}}).then(function(item) { 209 | var settings = item.settings; 210 | var id = tabId || page.currentTabId; 211 | 212 | var timeoutMinMillis = parseInt(getValueOrDefault(settings, "blinkMinTimeout", BLINK_TIMEOUT_REDIRECT_THRESHOLD_TIME_DEFAULT, 0)) ; 213 | if (timeoutMinMillis > 0) { 214 | timeoutMinMillis += Date.now(); 215 | } 216 | var blinkTimeout = getValueOrDefault(settings, "blinkTimeout", BLINK_TIMEOUT_DEFAULT, 0); 217 | var pageUpdateAllowance = getValueOrDefault(settings, "allowedRedirect", BLINK_TIMEOUT_REDIRECT_COUNT_DEFAULT, 0); 218 | 219 | var stackData = { 220 | visibleForMilliSeconds: blinkTimeout, 221 | visibleForPageUpdates: pageUpdateAllowance, 222 | redirectOffset: timeoutMinMillis, 223 | level: 10, 224 | intervalIcon: { 225 | index: 0, 226 | counter: 0, 227 | max: 2, 228 | icons: ["icon_remember_red_background_19x19.png", "icon_remember_red_lock_19x19.png"] 229 | }, 230 | icon: "icon_remember_red_background_19x19.png", 231 | popup: "popup_remember.html" 232 | } 233 | 234 | browserAction.stackPush(stackData, id); 235 | 236 | page.tabs[id].credentials = { 237 | "username": username, 238 | "password": password, 239 | "url": url, 240 | "usernameExists": usernameExists, 241 | "list": credentialsList 242 | }; 243 | 244 | browserAction.show(null, {"id": id}); 245 | }); 246 | } 247 | 248 | function getValueOrDefault(settings, key, defaultVal, min) { 249 | try { 250 | var val = settings[key]; 251 | if (isNaN(val) || val < min) { 252 | val = defaultVal; 253 | } 254 | return val; 255 | } catch(e) { return defaultVal; } 256 | } 257 | 258 | browserAction.generateIconName = function(iconType, icon) { 259 | if(icon) { 260 | return icon; 261 | } 262 | 263 | var name = "icon_"; 264 | name += (keepass.keePassHttpUpdateAvailable()) ? "new_" : ""; 265 | name += (!iconType || iconType == "normal") ? "normal_" : iconType + "_"; 266 | name += keepass.getIconColor(); 267 | name += "_19x19.png"; 268 | 269 | return name; 270 | } 271 | -------------------------------------------------------------------------------- /src/background/cryptoHelpers.js: -------------------------------------------------------------------------------- 1 | /* 2 | * cryptoHelpers.js: implements AES - Advanced Encryption Standard 3 | * from the SlowAES project, http://code.google.com/p/slowaes/ 4 | * 5 | * Copyright (c) 2008 Josh Davis ( http://www.josh-davis.org ), 6 | * Mark Percival ( http://mpercival.com ), 7 | * Johan Sundstrom ( http://ecmanaut.blogspot.com ), 8 | * John Resig ( http://ejohn.org ) 9 | * 10 | * Licensed under the Apache License, Version 2.0 11 | * http://www.apache.org/licenses/ 12 | */ 13 | 14 | var cryptoHelpers = { 15 | // encodes a unicode string to UTF8 (8 bit characters are critical to AES functioning properly) 16 | encode_utf8:function(s) 17 | { 18 | try{return unescape(encodeURIComponent(s));} 19 | catch(e){throw 'error during utf8 encoding: cryptoHelpers.encode_utf8.';} 20 | }, 21 | 22 | // decodes a UTF8 string back to unicode 23 | decode_utf8:function(s) 24 | { 25 | try{return decodeURIComponent(escape(s));} 26 | catch(e){throw('error during utf8 decoding: cryptoHelpers.decode_utf8.');} 27 | }, 28 | 29 | //convert a number array to a hex string 30 | toHex:function() 31 | { 32 | var array = []; 33 | if(arguments.length == 1 && arguments[0].constructor == Array) 34 | array = arguments[0]; 35 | else 36 | array = arguments; 37 | var ret = ''; 38 | for(var i = 0;i < array.length;i++) 39 | ret += (array[i] < 16 ? '0' : '') + array[i].toString(16); 40 | return ret.toLowerCase(); 41 | }, 42 | 43 | //convert a hex string to a number array 44 | toNumbers:function(s) 45 | { 46 | var ret = []; 47 | s.replace(/(..)/g,function(s){ 48 | ret.push(parseInt(s,16)); 49 | }); 50 | return ret; 51 | }, 52 | 53 | // get a random number in the range [min,max] 54 | getRandom:function(min,max) 55 | { 56 | if(min === null) 57 | min = 0; 58 | if(max === null) 59 | max = 1; 60 | return Math.floor(Math.random()*(max+1)) + min; 61 | }, 62 | 63 | generateSharedKey:function(len) 64 | { 65 | if(len === null) 66 | len = 16; 67 | var key = []; 68 | for(var i = 0; i < len*2; i++) 69 | key.push(this.getRandom(0,255)); 70 | return key; 71 | }, 72 | 73 | generatePrivateKey:function(s,size) 74 | { 75 | var sha = jsHash.sha2.arr_sha256(s); 76 | return sha.slice(0,size); 77 | }, 78 | 79 | convertStringToByteArray: function(s) 80 | { 81 | var byteArray = []; 82 | for(var i = 0;i < s.length;i++) 83 | { 84 | byteArray.push(s.charCodeAt(i)); 85 | } 86 | return byteArray; 87 | }, 88 | 89 | convertByteArrayToString: function(byteArray) 90 | { 91 | var s = ''; 92 | for(var i = 0;i < byteArray.length;i++) 93 | { 94 | s += String.fromCharCode(byteArray[i]) 95 | } 96 | return s; 97 | }, 98 | 99 | base64: { 100 | // Takes a Nx16x1 byte array and converts it to Base64 101 | chars: [ 102 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 103 | 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 104 | 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 105 | 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 106 | 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 107 | 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 108 | 'w', 'x', 'y', 'z', '0', '1', '2', '3', 109 | '4', '5', '6', '7', '8', '9', '+', '/', 110 | '=', // for decoding purposes 111 | ], 112 | 113 | encode_line: function(flatArr){ 114 | var b64 = ''; 115 | 116 | for (var i = 0; i < flatArr.length; i += 3){ 117 | b64 += this.chars[flatArr[i] >> 2]; 118 | b64 += this.chars[((flatArr[i] & 3) << 4) | (flatArr[i + 1] >> 4)]; 119 | if (!(flatArr[i + 1] == null)){ 120 | b64 += this.chars[((flatArr[i + 1] & 15) << 2) | (flatArr[i + 2] >> 6)]; 121 | }else{ 122 | b64 += '='; 123 | } 124 | if (!(flatArr[i + 2] == null)){ 125 | b64 += this.chars[flatArr[i + 2] & 63]; 126 | }else{ 127 | b64 += '='; 128 | } 129 | } 130 | return b64; 131 | }, 132 | 133 | encode: function(flatArr) 134 | { 135 | var b64 = this.encode_line(flatArr); 136 | // OpenSSL is super particular about line breaks 137 | var broken_b64 = b64.slice(0, 64) + '\n'; 138 | for (var i = 1; i < (Math.ceil(b64.length / 64)); i++) 139 | { 140 | broken_b64 += b64.slice(i * 64, i * 64 + 64) + (Math.ceil(b64.length / 64) == i + 1 ? '': '\n'); 141 | } 142 | return broken_b64; 143 | }, 144 | 145 | decode: function(string) 146 | { 147 | string = string.replace(/[\r\n\t ]+/g, '') + '===='; // drop all whitespaces and pad with '=' (end of b64 marker) 148 | var flatArr = []; 149 | var c = []; 150 | var b = []; 151 | for (var i = 0; ; i = i + 4){ 152 | c[0] = this.chars.indexOf(string.charAt(i)); 153 | if(c[0] == 64){ 154 | return flatArr; 155 | } 156 | c[1] = this.chars.indexOf(string.charAt(i + 1)); 157 | c[2] = this.chars.indexOf(string.charAt(i + 2)); 158 | c[3] = this.chars.indexOf(string.charAt(i + 3)); 159 | 160 | if( 161 | (c[0] < 0) || // char1 is wrong 162 | (c[1] < 0) || (c[1] == 64) || // char2 is wrong 163 | (c[2] < 0) || // char3 is neither an valid char nor '=' 164 | (c[3] < 0) // char4 is neither an valid char nor '=' 165 | ){ 166 | throw 'error during base64 decoding at pos '+i+': cryptoHelpers.base64.decode.'; 167 | } 168 | 169 | flatArr.push((c[0] << 2) | (c[1] >> 4)); 170 | if(c[2] >= 0 && c[2] < 64){ 171 | flatArr.push(((c[1] & 15) << 4) | (c[2] >> 2)); 172 | if(c[3] >= 0 && c[2] < 64){ 173 | flatArr.push(((c[2] & 3) << 6) | c[3]); 174 | } 175 | } 176 | } 177 | }, 178 | 179 | }, 180 | 181 | }; 182 | -------------------------------------------------------------------------------- /src/background/event.js: -------------------------------------------------------------------------------- 1 | var cipevent = {}; 2 | 3 | cipevent.onMessage = function(request, sender, callback) { 4 | if (request.action in cipevent.messageHandlers) { 5 | //console.log("onMessage(" + request.action + ") for #" + sender.tab.id); 6 | 7 | if(!sender.hasOwnProperty('tab') || sender.tab.id < 1) { 8 | sender.tab = {}; 9 | sender.tab.id = page.currentTabId; 10 | } 11 | 12 | cipevent.invoke(cipevent.messageHandlers[request.action], callback, sender.tab.id, request.args); 13 | 14 | // onMessage closes channel for callback automatically 15 | // if this method does not return true 16 | if(callback) { 17 | return true; 18 | } 19 | } 20 | } 21 | 22 | /** 23 | * Get interesting information about the given tab. 24 | * Function adapted from AdBlock-Plus. 25 | * 26 | * @param {function} handler to call after invoke 27 | * @param {function} callback to call after handler or null 28 | * @param {integer} senderTabId 29 | * @param {array} args 30 | * @param {bool} secondTime 31 | * @returns null (asynchronous) 32 | */ 33 | cipevent.invoke = function(handler, callback, senderTabId, args, secondTime) { 34 | if(senderTabId < 1) { 35 | return; 36 | } 37 | 38 | if(!page.tabs[senderTabId]) { 39 | page.createTabEntry(senderTabId); 40 | } 41 | 42 | // remove information from no longer existing tabs 43 | page.removePageInformationFromNotExistingTabs(); 44 | 45 | browser.tabs.get(senderTabId).then(function(tab) { 46 | if(!tab) { 47 | return; 48 | } 49 | 50 | if (!tab.url) { 51 | // Issue 6877: tab URL is not set directly after you opened a window 52 | // using window.open() 53 | if (!secondTime) { 54 | window.setTimeout(function() { 55 | cipevent.invoke(handler, callback, senderTabId, args, true); 56 | }, 250); 57 | } 58 | return; 59 | } 60 | 61 | if(!page.tabs[tab.id]) { 62 | page.createTabEntry(tab.id); 63 | } 64 | 65 | args = args || []; 66 | 67 | args.unshift(tab); 68 | args.unshift(callback); 69 | 70 | if(handler) { 71 | handler.apply(this, args); 72 | } 73 | else { 74 | console.log("undefined handler for tab " + tab.id); 75 | } 76 | }); 77 | } 78 | 79 | cipevent.onShowAlert = function(callback, tab, message) { 80 | if( page.settings.supressAlerts === true ){ console.log(message); } 81 | else { browser.tabs.executeScript({code: 'alert(\''+message+'\')'}); } 82 | } 83 | 84 | cipevent.onLoadSettings = function(callback, tab) { 85 | page.initSettings().then((settings) => { 86 | callback(settings); 87 | }, (err) => { 88 | console.log('error loading settings: ' + err); 89 | }); 90 | } 91 | 92 | cipevent.onLoadKeyRing = function(callback, tab) { 93 | browser.storage.local.get({'keyRing': {}}).then(function(item) { 94 | keepass.keyRing = item.keyRing; 95 | if(keepass.isAssociated() && !keepass.keyRing[keepass.associated.hash]) { 96 | keepass.associated = { 97 | "value": false, 98 | "hash": null 99 | }; 100 | } 101 | callback(item.keyRing); 102 | }, (err) => { 103 | console.log('error loading keyRing: ' + err); 104 | }); 105 | } 106 | 107 | cipevent.onSaveSettings = function(callback, tab, settings) { 108 | browser.storage.local.set({'settings': settings}).then(function() { 109 | cipevent.onLoadSettings(); 110 | }); 111 | } 112 | 113 | cipevent.onGetStatus = function(callback, tab) { 114 | keepass.testAssociation(tab).then((configured) => { 115 | var keyId = null; 116 | if (configured) { 117 | keyId = keepass.keyRing[keepass.databaseHash].id; 118 | } 119 | 120 | browserAction.showDefault(null, tab); 121 | 122 | callback({ 123 | identifier: keyId, 124 | configured: configured, 125 | databaseClosed: keepass.isDatabaseClosed, 126 | keePassHttpAvailable: keepass.isKeePassHttpAvailable, 127 | encryptionKeyUnrecognized: keepass.isEncryptionKeyUnrecognized, 128 | associated: keepass.isAssociated(), 129 | error: page.tabs[tab.id].errorMessage 130 | }); 131 | }); 132 | } 133 | 134 | cipevent.onPopStack = function(callback, tab) { 135 | browserAction.stackPop(tab.id); 136 | browserAction.show(null, tab); 137 | } 138 | 139 | cipevent.onGetTabInformation = function(callback, tab) { 140 | var id = tab.id || page.currentTabId; 141 | 142 | callback(page.tabs[id]); 143 | } 144 | 145 | cipevent.onGetConnectedDatabase = function(callback, tab) { 146 | callback({ 147 | "count": Object.keys(keepass.keyRing).length, 148 | "identifier": (keepass.keyRing[keepass.associated.hash]) ? keepass.keyRing[keepass.associated.hash].id : null 149 | }); 150 | } 151 | 152 | cipevent.onGetKeePassHttpVersions = function(callback, tab) { 153 | if(keepass.currentKeePassHttp.version == 0) { 154 | keepass.getDatabaseHash(tab).then(() => { 155 | callback({"current": keepass.currentKeePassHttp.version, "latest": keepass.latestKeePassHttp.version}); 156 | }); 157 | } else { 158 | callback({"current": keepass.currentKeePassHttp.version, "latest": keepass.latestKeePassHttp.version}); 159 | } 160 | } 161 | 162 | cipevent.onCheckUpdateKeePassHttp = function(callback, tab) { 163 | keepass.checkForNewKeePassHttpVersion(); 164 | callback({"current": keepass.currentKeePassHttp.version, "latest": keepass.latestKeePassHttp.version}); 165 | } 166 | 167 | cipevent.onUpdateAvailableKeePassHttp = function(callback, tab) { 168 | callback(keepass.keePassHttpUpdateAvailable()); 169 | } 170 | 171 | cipevent.onRemoveCredentialsFromTabInformation = function(callback, tab) { 172 | var id = tab.id || page.currentTabId; 173 | 174 | page.clearCredentials(id); 175 | } 176 | 177 | cipevent.onSetRememberPopup = function(callback, tab, username, password, url, usernameExists, credentialsList) { 178 | browserAction.setRememberPopup(tab.id, username, password, url, usernameExists, credentialsList); 179 | } 180 | 181 | cipevent.onLoginPopup = function(callback, tab, logins) { 182 | var stackData = { 183 | level: 1, 184 | iconType: "questionmark", 185 | popup: "popup_login.html" 186 | } 187 | browserAction.stackUnshift(stackData, tab.id); 188 | 189 | page.tabs[tab.id].loginList = logins; 190 | 191 | browserAction.show(null, tab); 192 | } 193 | 194 | cipevent.onHTTPAuthPopup = function(callback, tab, data) { 195 | var stackData = { 196 | level: 1, 197 | iconType: "questionmark", 198 | popup: "popup_httpauth.html" 199 | } 200 | browserAction.stackUnshift(stackData, tab.id); 201 | 202 | page.tabs[tab.id].loginList = data; 203 | 204 | browserAction.show(null, tab); 205 | } 206 | 207 | cipevent.onMultipleFieldsPopup = function(callback, tab) { 208 | var stackData = { 209 | level: 1, 210 | iconType: "normal", 211 | popup: "popup_multiple-fields.html" 212 | } 213 | browserAction.stackUnshift(stackData, tab.id); 214 | 215 | browserAction.show(null, tab); 216 | } 217 | 218 | cipevent.pageClearLogins = function(callback, tab) { 219 | page.clearLogins(tab.id); 220 | callback(); 221 | } 222 | 223 | cipevent.isFirefox = function(callback) { 224 | callback(utils.isFirefox); 225 | } 226 | 227 | cipevent.initHttpAuth = function(callback) { 228 | httpAuth.init(); 229 | callback(); 230 | } 231 | 232 | // all methods named in this object have to be declared BEFORE this! 233 | cipevent.messageHandlers = { 234 | 'add_credentials': keepass.addCredentials, 235 | 'alert': cipevent.onShowAlert, 236 | 'associate': keepass.associate, 237 | 'check_update_keepasshttp': cipevent.onCheckUpdateKeePassHttp, 238 | 'get_connected_database': cipevent.onGetConnectedDatabase, 239 | 'get_keepasshttp_versions': cipevent.onGetKeePassHttpVersions, 240 | 'get_status': cipevent.onGetStatus, 241 | 'get_tab_information': cipevent.onGetTabInformation, 242 | 'init_http_auth': cipevent.initHttpAuth, 243 | 'load_keyring': cipevent.onLoadKeyRing, 244 | 'load_settings': cipevent.onLoadSettings, 245 | 'page_clear_logins': cipevent.pageClearLogins, 246 | 'pop_stack': cipevent.onPopStack, 247 | 'popup_login': cipevent.onLoginPopup, 248 | 'popup_multiple-fields': cipevent.onMultipleFieldsPopup, 249 | 'remove_credentials_from_tab_information': cipevent.onRemoveCredentialsFromTabInformation, 250 | 'retrieve_credentials': keepass.retrieveCredentials, 251 | 'show_default_browseraction': browserAction.showDefault, 252 | 'update_credentials': keepass.updateCredentials, 253 | 'save_settings': cipevent.onSaveSettings, 254 | 'set_remember_credentials': cipevent.onSetRememberPopup, 255 | 'stack_add': browserAction.stackAdd, 256 | 'update_available_keepasshttp': cipevent.onUpdateAvailableKeePassHttp, 257 | 'generate_password': keepass.generatePassword, 258 | 'is_firefox': cipevent.isFirefox 259 | }; 260 | -------------------------------------------------------------------------------- /src/background/httpauth.js: -------------------------------------------------------------------------------- 1 | var httpAuth = httpAuth || {}; 2 | 3 | httpAuth.requests = []; 4 | 5 | httpAuth.init = function () { 6 | 7 | var handleReq = httpAuth.handleRequestPromise; 8 | var reqType = 'blocking'; 9 | 10 | if (!utils.isFirefox) { 11 | handleReq = httpAuth.handleRequestCallback; 12 | reqType = 'asyncBlocking'; 13 | } 14 | 15 | if (browser.webRequest.onAuthRequired.hasListener(handleReq)) { 16 | browser.webRequest.onAuthRequired.removeListener(handleReq); 17 | browser.webRequest.onCompleted.removeListener(httpAuth.requestCompleted); 18 | browser.webRequest.onErrorOccurred.removeListener(httpAuth.requestCompleted); 19 | } 20 | 21 | // only intercept http auth requests if the option is turned on. 22 | if (page.settings.autoFillAndSend === true) { 23 | var opts = { urls: [''] }; 24 | 25 | browser.webRequest.onAuthRequired.addListener(handleReq, opts, [reqType]); 26 | browser.webRequest.onCompleted.addListener(httpAuth.requestCompleted, opts); 27 | browser.webRequest.onErrorOccurred.addListener(httpAuth.requestCompleted, opts); 28 | } 29 | } 30 | 31 | httpAuth.requestCompleted = function (details) { 32 | var idx = httpAuth.requests.indexOf(details.requestId); 33 | if (idx >= 0) { 34 | httpAuth.requests.splice(idx, 1); 35 | } 36 | } 37 | 38 | httpAuth.handleRequestPromise = function (details) { 39 | return new Promise((resolve, reject) => { 40 | httpAuth.processPendingCallbacks(details, resolve, reject); 41 | }); 42 | } 43 | 44 | httpAuth.handleRequestCallback = function (details, callback) { 45 | httpAuth.processPendingCallbacks(details, callback, callback); 46 | } 47 | 48 | httpAuth.retrieveCredentials = function (tabId, url, submitUrl, forceCallback) { 49 | return new Promise((resolve, reject) => { 50 | keepass.retrieveCredentials((logins) => { 51 | resolve(logins); 52 | }, tabId, url, submitUrl, forceCallback); 53 | }); 54 | }; 55 | 56 | httpAuth.processPendingCallbacks = function (details, resolve, reject) { 57 | 58 | if (httpAuth.requests.indexOf(details.requestId) >= 0 || !page.tabs[details.tabId]) { 59 | reject({}); 60 | return; 61 | } 62 | 63 | httpAuth.requests.push(details.requestId); 64 | 65 | if (details.challenger) { 66 | details.proxyUrl = details.challenger.host; 67 | } 68 | 69 | details.searchUrl = (details.isProxy && details.proxyUrl) ? details.proxyUrl : details.url; 70 | 71 | httpAuth.retrieveCredentials({ "id": details.tabId }, details.searchUrl, details.searchUrl, true) 72 | .then((logins) => { 73 | httpAuth.loginOrShowCredentials(logins, details, resolve, reject); 74 | }); 75 | } 76 | 77 | httpAuth.loginOrShowCredentials = function (logins, details, resolve, reject) { 78 | // at least one login found --> use first to login 79 | if (logins.length > 0 && page.settings.autoFillAndSend === true) { 80 | if (logins.length == 1) { 81 | resolve({ 82 | authCredentials: { 83 | username: logins[0].Login, 84 | password: logins[0].Password 85 | } 86 | }); 87 | } else { 88 | cipevent.onHTTPAuthPopup(null, { "id": details.tabId }, { "logins": logins, "url": details.searchUrl, 'resolve': resolve }); 89 | } 90 | } 91 | // no logins found 92 | else { 93 | reject({}); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/background/init.js: -------------------------------------------------------------------------------- 1 | // since version 2.0 the extension is using a keyRing instead of a single key-name-pair 2 | keepass.migrateKeyRing().then(() => { 3 | // load settings 4 | page.initSettings().then(() => { 5 | page.initOpenedTabs().then(() => { 6 | httpAuth.init(); 7 | // initial connection with KeePassHttp 8 | keepass.getDatabaseHash({ id: page.currentTabId }); 9 | }); 10 | }); 11 | }); 12 | 13 | // Milliseconds for intervall (e.g. to update browserAction) 14 | var _interval = 250; 15 | 16 | /** 17 | * Generate information structure for created tab and invoke all needed 18 | * functions if tab is created in foreground 19 | * @param {object} tab 20 | */ 21 | browser.tabs.onCreated.addListener(function(tab) { 22 | if(tab.id > 0) { 23 | //console.log("browser.tabs.onCreated(" + tab.id+ ")"); 24 | if(tab.selected) { 25 | page.currentTabId = tab.id; 26 | cipevent.invoke(page.switchTab, null, tab.id, []); 27 | } 28 | } 29 | }); 30 | 31 | /** 32 | * Remove information structure of closed tab for freeing memory 33 | * @param {integer} tabId 34 | * @param {object} removeInfo 35 | */ 36 | browser.tabs.onRemoved.addListener(function(tabId, removeInfo) { 37 | delete page.tabs[tabId]; 38 | if(page.currentTabId == tabId) { 39 | page.currentTabId = -1; 40 | } 41 | }); 42 | 43 | /** 44 | * Remove stored credentials on switching tabs. 45 | * Invoke functions to retrieve credentials for focused tab 46 | * @param {object} activeInfo 47 | */ 48 | browser.tabs.onActivated.addListener(function(activeInfo) { 49 | // remove possible credentials from old tab information 50 | page.clearCredentials(page.currentTabId, true); 51 | browserAction.removeRememberPopup(null, {"id": page.currentTabId}, true); 52 | 53 | browser.tabs.get(activeInfo.tabId).then(function(info) { 54 | //console.log(info.id + ": " + info.url); 55 | if(info && info.id) { 56 | page.currentTabId = info.id; 57 | if(info.status == "complete") { 58 | //console.log("event.invoke(page.switchTab, null, "+info.id + ", []);"); 59 | cipevent.invoke(page.switchTab, null, info.id, []); 60 | } 61 | } 62 | }); 63 | }); 64 | 65 | /** 66 | * Update browserAction on every update of the page 67 | * @param {integer} tabId 68 | * @param {object} changeInfo 69 | */ 70 | browser.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) { 71 | if(changeInfo.status == "complete") { 72 | cipevent.invoke(browserAction.removeRememberPopup, null, tabId, []); 73 | } 74 | }); 75 | 76 | /** 77 | * Interaction between background-script and front-script 78 | */ 79 | browser.runtime.onMessage.addListener(cipevent.onMessage); 80 | 81 | var menuContexts = ['editable']; 82 | 83 | if (utils.isFirefox) { 84 | menuContexts.push('password'); 85 | } 86 | 87 | /** 88 | * Add context menu entry for filling in username + password 89 | */ 90 | browser.contextMenus.create({ 91 | "title": "Fill User + Pass", 92 | "contexts": menuContexts, 93 | "onclick": function(info, tab) { 94 | browser.tabs.sendMessage(tab.id, { 95 | action: "fill_user_pass" 96 | }); 97 | } 98 | }); 99 | 100 | /** 101 | * Add context menu entry for filling in only password which matches for given username 102 | */ 103 | browser.contextMenus.create({ 104 | "title": "Fill Pass Only", 105 | "contexts": menuContexts, 106 | "onclick": function(info, tab) { 107 | browser.tabs.sendMessage(tab.id, { 108 | action: "fill_pass_only" 109 | }); 110 | } 111 | }); 112 | 113 | /** 114 | * Add context menu entry for creating icon for generate-password dialog 115 | */ 116 | browser.contextMenus.create({ 117 | "title": "Show Password Generator Icons", 118 | "contexts": menuContexts, 119 | "onclick": function(info, tab) { 120 | browser.tabs.sendMessage(tab.id, { 121 | action: "activate_password_generator" 122 | }); 123 | } 124 | }); 125 | 126 | /** 127 | * Add context menu entry for creating icon for generate-password dialog 128 | */ 129 | browser.contextMenus.create({ 130 | "title": "Save credentials", 131 | "contexts": menuContexts, 132 | "onclick": function(info, tab) { 133 | browser.tabs.sendMessage(tab.id, { 134 | action: "remember_credentials" 135 | }); 136 | } 137 | }); 138 | 139 | /** 140 | * Listen for keyboard shortcuts specified by user 141 | */ 142 | browser.commands.onCommand.addListener(function(command) { 143 | 144 | if(command === "fill-username-password") { 145 | browser.tabs.query({ active: true, currentWindow: true }, function(tabs) { 146 | if (tabs.length) { 147 | browser.tabs.sendMessage(tabs[0].id, { action: "fill_user_pass" }); 148 | } 149 | }); 150 | } 151 | 152 | if(command === "fill-password") { 153 | browser.tabs.query({ active: true, currentWindow: true }, function(tabs) { 154 | if (tabs.length) { 155 | browser.tabs.sendMessage(tabs[0].id, { action: "fill_pass_only" }); 156 | } 157 | }); 158 | } 159 | }); 160 | 161 | /** 162 | * Interval which updates the browserAction (e.g. blinking icon) 163 | */ 164 | window.setInterval(function() { 165 | browserAction.update(_interval); 166 | }, _interval); 167 | -------------------------------------------------------------------------------- /src/background/page.js: -------------------------------------------------------------------------------- 1 | var page = {}; 2 | 3 | // special information for every tab 4 | page.tabs = {}; 5 | 6 | page.currentTabId = -1; 7 | page.blockedTabs = {}; 8 | 9 | page.initSettings = function() { 10 | return new Promise((resolve, reject) => { 11 | browser.storage.local.get({'settings': {}}).then((item) => { 12 | page.settings = item.settings; 13 | if(!("checkUpdateKeePassHttp" in page.settings)) { 14 | page.settings.checkUpdateKeePassHttp = 3; 15 | } 16 | if(!("autoCompleteUsernames" in page.settings) || page.settings.autoCompleteUsernames === 1) { 17 | page.settings.autoCompleteUsernames = true; 18 | } 19 | if(!("autoFillAndSend" in page.settings) || page.settings.autoFillAndSend === 1) { 20 | page.settings.autoFillAndSend = true; 21 | } 22 | if(!("usePasswordGenerator" in page.settings) || page.settings.usePasswordGenerator === 1) { 23 | page.settings.usePasswordGenerator = true; 24 | } 25 | if(!("autoFillSingleEntry" in page.settings)) { 26 | page.settings.autoFillSingleEntry = false; 27 | } 28 | if(!("autoRetrieveCredentials" in page.settings) || page.settings.autoRetrieveCredentials === 1) { 29 | page.settings.autoRetrieveCredentials = true; 30 | } 31 | if(!("hostname" in page.settings)) { 32 | page.settings.hostname = "localhost"; 33 | } 34 | if(!("port" in page.settings)) { 35 | page.settings.port = "19455"; 36 | } 37 | if(!("supressAlerts" in page.settings)) { 38 | page.settings.supressAlerts = true; 39 | } 40 | if(!("respectMaxLength" in page.settings)) { 41 | page.settings.respectMaxLength = false; 42 | } 43 | browser.storage.local.set({'settings': page.settings}); 44 | resolve(page.settings); 45 | }); 46 | }); 47 | } 48 | 49 | page.initOpenedTabs = function () { 50 | return new Promise((resolve, reject) => { 51 | browser.tabs.query({}).then(function (tabs) { 52 | for (var i = 0; i < tabs.length; i++) { 53 | page.createTabEntry(tabs[i].id); 54 | } 55 | 56 | // set initial tab-ID 57 | browser.tabs.query({ "active": true, "currentWindow": true }).then(function (tabs) { 58 | if (tabs.length === 0) { 59 | resolve(); 60 | return; // For example: only the background devtools or a popup are opened 61 | } 62 | page.currentTabId = tabs[0].id; 63 | browserAction.show(null, tabs[0]); 64 | resolve(); 65 | }); 66 | }); 67 | }); 68 | } 69 | 70 | page.isValidProtocol = function(url) { 71 | var protocol = url.substring(0, url.indexOf(":")); 72 | protocol = protocol.toLowerCase(); 73 | return !(url.indexOf(".") == -1 || (protocol != "http" && protocol != "https" && protocol != "ftp" && protocol != "sftp")); 74 | } 75 | 76 | page.switchTab = function(callback, tab) { 77 | browserAction.showDefault(null, tab); 78 | 79 | browser.tabs.sendMessage(tab.id, {action: "activated_tab"}); 80 | } 81 | 82 | page.clearCredentials = function(tabId, complete) { 83 | if(!page.tabs[tabId]) { 84 | return; 85 | } 86 | 87 | page.tabs[tabId].credentials = {}; 88 | delete page.tabs[tabId].credentials; 89 | 90 | if(complete) { 91 | page.clearLogins(tabId); 92 | 93 | browser.tabs.sendMessage(tabId, { 94 | action: "clear_credentials" 95 | }); 96 | } 97 | } 98 | 99 | page.clearLogins = function(tabId) { 100 | page.tabs[tabId].loginList = []; 101 | } 102 | 103 | page.createTabEntry = function(tabId) { 104 | //console.log("page.createTabEntry("+tabId+")"); 105 | page.tabs[tabId] = { 106 | "stack": [], 107 | "errorMessage": null, 108 | "loginList": {} 109 | }; 110 | } 111 | 112 | page.removePageInformationFromNotExistingTabs = function() { 113 | var rand = Math.floor(Math.random()*1001); 114 | if(rand == 28) { 115 | browser.tabs.query({}).then(function(tabs) { 116 | var $tabIds = {}; 117 | var $infoIds = Object.keys(page.tabs); 118 | 119 | for(var i = 0; i < tabs.length; i++) { 120 | $tabIds[tabs[i].id] = true; 121 | } 122 | 123 | for(var i = 0; i < $infoIds.length; i++) { 124 | if(!($infoIds[i] in $tabIds)) { 125 | delete page.tabs[$infoIds[i]]; 126 | } 127 | } 128 | }); 129 | } 130 | }; 131 | 132 | page.debugConsole = function() { 133 | if(arguments.length > 1) { 134 | console.log(page.sprintf(arguments[0], arguments)); 135 | } 136 | else { 137 | console.log(arguments[0]); 138 | } 139 | }; 140 | 141 | page.sprintf = function(input, args) { 142 | return input.replace(/{(\d+)}/g, function(match, number) { 143 | return typeof args[number] != 'undefined' 144 | ? (typeof args[number] == 'object' ? JSON.stringify(args[number]) : args[number]) 145 | : match; 146 | }); 147 | } 148 | 149 | page.debugDummy = function() {}; 150 | 151 | page.debug = page.debugDummy; 152 | 153 | page.setDebug = function(bool) { 154 | if(bool) { 155 | page.debug = page.debugConsole; 156 | return "Debug mode enabled"; 157 | } 158 | else { 159 | page.debug = page.debugDummy; 160 | return "Debug mode disabled"; 161 | } 162 | }; 163 | -------------------------------------------------------------------------------- /src/background/sjcl.js: -------------------------------------------------------------------------------- 1 | /** @fileOverview Javascript cryptography implementation. 2 | * 3 | * Crush to remove comments, shorten variable names and 4 | * generally reduce transmission size. 5 | * 6 | * @author Emily Stark 7 | * @author Mike Hamburg 8 | * @author Dan Boneh 9 | */ 10 | 11 | "use strict"; 12 | /*jslint indent: 2, bitwise: false, nomen: false, plusplus: false, white: false, regexp: false */ 13 | /*global document, window, escape, unescape */ 14 | 15 | /** @namespace The Stanford Javascript Crypto Library, top-level namespace. */ 16 | var sjcl = { 17 | /** @namespace Symmetric ciphers. */ 18 | cipher: {}, 19 | 20 | /** @namespace Hash functions. Right now only SHA256 is implemented. */ 21 | hash: {}, 22 | 23 | /** @namespace Key exchange functions. Right now only SRP is implemented. */ 24 | keyexchange: {}, 25 | 26 | /** @namespace Block cipher modes of operation. */ 27 | mode: {}, 28 | 29 | /** @namespace Miscellaneous. HMAC and PBKDF2. */ 30 | misc: {}, 31 | 32 | /** 33 | * @namespace Bit array encoders and decoders. 34 | * 35 | * @description 36 | * The members of this namespace are functions which translate between 37 | * SJCL's bitArrays and other objects (usually strings). Because it 38 | * isn't always clear which direction is encoding and which is decoding, 39 | * the method names are "fromBits" and "toBits". 40 | */ 41 | codec: {}, 42 | 43 | /** @namespace Exceptions. */ 44 | exception: { 45 | /** @class Ciphertext is corrupt. */ 46 | corrupt: function(message) { 47 | this.toString = function() { return "CORRUPT: "+this.message; }; 48 | this.message = message; 49 | }, 50 | 51 | /** @class Invalid parameter. */ 52 | invalid: function(message) { 53 | this.toString = function() { return "INVALID: "+this.message; }; 54 | this.message = message; 55 | }, 56 | 57 | /** @class Bug or missing feature in SJCL. */ 58 | bug: function(message) { 59 | this.toString = function() { return "BUG: "+this.message; }; 60 | this.message = message; 61 | }, 62 | 63 | /** @class Something isn't ready. */ 64 | notReady: function(message) { 65 | this.toString = function() { return "NOT READY: "+this.message; }; 66 | this.message = message; 67 | } 68 | } 69 | }; 70 | /** @fileOverview Low-level AES implementation. 71 | * 72 | * This file contains a low-level implementation of AES, optimized for 73 | * size and for efficiency on several browsers. It is based on 74 | * OpenSSL's aes_core.c, a public-domain implementation by Vincent 75 | * Rijmen, Antoon Bosselaers and Paulo Barreto. 76 | * 77 | * An older version of this implementation is available in the public 78 | * domain, but this one is (c) Emily Stark, Mike Hamburg, Dan Boneh, 79 | * Stanford University 2008-2010 and BSD-licensed for liability 80 | * reasons. 81 | * 82 | * @author Emily Stark 83 | * @author Mike Hamburg 84 | * @author Dan Boneh 85 | */ 86 | 87 | /** 88 | * Schedule out an AES key for both encryption and decryption. This 89 | * is a low-level class. Use a cipher mode to do bulk encryption. 90 | * 91 | * @constructor 92 | * @param {Array} key The key as an array of 4, 6 or 8 words. 93 | * 94 | * @class Advanced Encryption Standard (low-level interface) 95 | */ 96 | sjcl.cipher.aes = function (key) { 97 | if (!this._tables[0][0][0]) { 98 | this._precompute(); 99 | } 100 | 101 | var i, j, tmp, 102 | encKey, decKey, 103 | sbox = this._tables[0][4], decTable = this._tables[1], 104 | keyLen = key.length, rcon = 1; 105 | 106 | if (keyLen !== 4 && keyLen !== 6 && keyLen !== 8) { 107 | throw new sjcl.exception.invalid("invalid aes key size"); 108 | } 109 | 110 | this._key = [encKey = key.slice(0), decKey = []]; 111 | 112 | // schedule encryption keys 113 | for (i = keyLen; i < 4 * keyLen + 28; i++) { 114 | tmp = encKey[i-1]; 115 | 116 | // apply sbox 117 | if (i%keyLen === 0 || (keyLen === 8 && i%keyLen === 4)) { 118 | tmp = sbox[tmp>>>24]<<24 ^ sbox[tmp>>16&255]<<16 ^ sbox[tmp>>8&255]<<8 ^ sbox[tmp&255]; 119 | 120 | // shift rows and add rcon 121 | if (i%keyLen === 0) { 122 | tmp = tmp<<8 ^ tmp>>>24 ^ rcon<<24; 123 | rcon = rcon<<1 ^ (rcon>>7)*283; 124 | } 125 | } 126 | 127 | encKey[i] = encKey[i-keyLen] ^ tmp; 128 | } 129 | 130 | // schedule decryption keys 131 | for (j = 0; i; j++, i--) { 132 | tmp = encKey[j&3 ? i : i - 4]; 133 | if (i<=4 || j<4) { 134 | decKey[j] = tmp; 135 | } else { 136 | decKey[j] = decTable[0][sbox[tmp>>>24 ]] ^ 137 | decTable[1][sbox[tmp>>16 & 255]] ^ 138 | decTable[2][sbox[tmp>>8 & 255]] ^ 139 | decTable[3][sbox[tmp & 255]]; 140 | } 141 | } 142 | }; 143 | 144 | sjcl.cipher.aes.prototype = { 145 | // public 146 | /* Something like this might appear here eventually 147 | name: "AES", 148 | blockSize: 4, 149 | keySizes: [4,6,8], 150 | */ 151 | 152 | /** 153 | * Encrypt an array of 4 big-endian words. 154 | * @param {Array} data The plaintext. 155 | * @return {Array} The ciphertext. 156 | */ 157 | encrypt:function (data) { return this._crypt(data,0); }, 158 | 159 | /** 160 | * Decrypt an array of 4 big-endian words. 161 | * @param {Array} data The ciphertext. 162 | * @return {Array} The plaintext. 163 | */ 164 | decrypt:function (data) { return this._crypt(data,1); }, 165 | 166 | /** 167 | * The expanded S-box and inverse S-box tables. These will be computed 168 | * on the client so that we don't have to send them down the wire. 169 | * 170 | * There are two tables, _tables[0] is for encryption and 171 | * _tables[1] is for decryption. 172 | * 173 | * The first 4 sub-tables are the expanded S-box with MixColumns. The 174 | * last (_tables[01][4]) is the S-box itself. 175 | * 176 | * @private 177 | */ 178 | _tables: [[[],[],[],[],[]],[[],[],[],[],[]]], 179 | 180 | /** 181 | * Expand the S-box tables. 182 | * 183 | * @private 184 | */ 185 | _precompute: function () { 186 | var encTable = this._tables[0], decTable = this._tables[1], 187 | sbox = encTable[4], sboxInv = decTable[4], 188 | i, x, xInv, d=[], th=[], x2, x4, x8, s, tEnc, tDec; 189 | 190 | // Compute double and third tables 191 | for (i = 0; i < 256; i++) { 192 | th[( d[i] = i<<1 ^ (i>>7)*283 )^i]=i; 193 | } 194 | 195 | for (x = xInv = 0; !sbox[x]; x ^= x2 || 1, xInv = th[xInv] || 1) { 196 | // Compute sbox 197 | s = xInv ^ xInv<<1 ^ xInv<<2 ^ xInv<<3 ^ xInv<<4; 198 | s = s>>8 ^ s&255 ^ 99; 199 | sbox[x] = s; 200 | sboxInv[s] = x; 201 | 202 | // Compute MixColumns 203 | x8 = d[x4 = d[x2 = d[x]]]; 204 | tDec = x8*0x1010101 ^ x4*0x10001 ^ x2*0x101 ^ x*0x1010100; 205 | tEnc = d[s]*0x101 ^ s*0x1010100; 206 | 207 | for (i = 0; i < 4; i++) { 208 | encTable[i][x] = tEnc = tEnc<<24 ^ tEnc>>>8; 209 | decTable[i][s] = tDec = tDec<<24 ^ tDec>>>8; 210 | } 211 | } 212 | 213 | // Compactify. Considerable speedup on Firefox. 214 | for (i = 0; i < 5; i++) { 215 | encTable[i] = encTable[i].slice(0); 216 | decTable[i] = decTable[i].slice(0); 217 | } 218 | }, 219 | 220 | /** 221 | * Encryption and decryption core. 222 | * @param {Array} input Four words to be encrypted or decrypted. 223 | * @param dir The direction, 0 for encrypt and 1 for decrypt. 224 | * @return {Array} The four encrypted or decrypted words. 225 | * @private 226 | */ 227 | _crypt:function (input, dir) { 228 | if (input.length !== 4) { 229 | throw new sjcl.exception.invalid("invalid aes block size"); 230 | } 231 | 232 | var key = this._key[dir], 233 | // state variables a,b,c,d are loaded with pre-whitened data 234 | a = input[0] ^ key[0], 235 | b = input[dir ? 3 : 1] ^ key[1], 236 | c = input[2] ^ key[2], 237 | d = input[dir ? 1 : 3] ^ key[3], 238 | a2, b2, c2, 239 | 240 | nInnerRounds = key.length/4 - 2, 241 | i, 242 | kIndex = 4, 243 | out = [0,0,0,0], 244 | table = this._tables[dir], 245 | 246 | // load up the tables 247 | t0 = table[0], 248 | t1 = table[1], 249 | t2 = table[2], 250 | t3 = table[3], 251 | sbox = table[4]; 252 | 253 | // Inner rounds. Cribbed from OpenSSL. 254 | for (i = 0; i < nInnerRounds; i++) { 255 | a2 = t0[a>>>24] ^ t1[b>>16 & 255] ^ t2[c>>8 & 255] ^ t3[d & 255] ^ key[kIndex]; 256 | b2 = t0[b>>>24] ^ t1[c>>16 & 255] ^ t2[d>>8 & 255] ^ t3[a & 255] ^ key[kIndex + 1]; 257 | c2 = t0[c>>>24] ^ t1[d>>16 & 255] ^ t2[a>>8 & 255] ^ t3[b & 255] ^ key[kIndex + 2]; 258 | d = t0[d>>>24] ^ t1[a>>16 & 255] ^ t2[b>>8 & 255] ^ t3[c & 255] ^ key[kIndex + 3]; 259 | kIndex += 4; 260 | a=a2; b=b2; c=c2; 261 | } 262 | 263 | // Last round. 264 | for (i = 0; i < 4; i++) { 265 | out[dir ? 3&-i : i] = 266 | sbox[a>>>24 ]<<24 ^ 267 | sbox[b>>16 & 255]<<16 ^ 268 | sbox[c>>8 & 255]<<8 ^ 269 | sbox[d & 255] ^ 270 | key[kIndex++]; 271 | a2=a; a=b; b=c; c=d; d=a2; 272 | } 273 | 274 | return out; 275 | } 276 | }; 277 | 278 | /** @fileOverview Arrays of bits, encoded as arrays of Numbers. 279 | * 280 | * @author Emily Stark 281 | * @author Mike Hamburg 282 | * @author Dan Boneh 283 | */ 284 | 285 | /** @namespace Arrays of bits, encoded as arrays of Numbers. 286 | * 287 | * @description 288 | *

289 | * These objects are the currency accepted by SJCL's crypto functions. 290 | *

291 | * 292 | *

293 | * Most of our crypto primitives operate on arrays of 4-byte words internally, 294 | * but many of them can take arguments that are not a multiple of 4 bytes. 295 | * This library encodes arrays of bits (whose size need not be a multiple of 8 296 | * bits) as arrays of 32-bit words. The bits are packed, big-endian, into an 297 | * array of words, 32 bits at a time. Since the words are double-precision 298 | * floating point numbers, they fit some extra data. We use this (in a private, 299 | * possibly-changing manner) to encode the number of bits actually present 300 | * in the last word of the array. 301 | *

302 | * 303 | *

304 | * Because bitwise ops clear this out-of-band data, these arrays can be passed 305 | * to ciphers like AES which want arrays of words. 306 | *

307 | */ 308 | sjcl.bitArray = { 309 | /** 310 | * Array slices in units of bits. 311 | * @param {bitArray a} The array to slice. 312 | * @param {Number} bstart The offset to the start of the slice, in bits. 313 | * @param {Number} bend The offset to the end of the slice, in bits. If this is undefined, 314 | * slice until the end of the array. 315 | * @return {bitArray} The requested slice. 316 | */ 317 | bitSlice: function (a, bstart, bend) { 318 | a = sjcl.bitArray._shiftRight(a.slice(bstart/32), 32 - (bstart & 31)).slice(1); 319 | return (bend === undefined) ? a : sjcl.bitArray.clamp(a, bend-bstart); 320 | }, 321 | 322 | /** 323 | * Extract a number packed into a bit array. 324 | * @param {bitArray} a The array to slice. 325 | * @param {Number} bstart The offset to the start of the slice, in bits. 326 | * @param {Number} length The length of the number to extract. 327 | * @return {Number} The requested slice. 328 | */ 329 | extract: function(a, bstart, blength) { 330 | // FIXME: this Math.floor is not necessary at all, but for some reason 331 | // seems to suppress a bug in the Chromium JIT. 332 | var x, sh = Math.floor((-bstart-blength) & 31); 333 | if ((bstart + blength - 1 ^ bstart) & -32) { 334 | // it crosses a boundary 335 | x = (a[bstart/32|0] << (32 - sh)) ^ (a[bstart/32+1|0] >>> sh); 336 | } else { 337 | // within a single word 338 | x = a[bstart/32|0] >>> sh; 339 | } 340 | return x & ((1< 0 && len) { 386 | a[l-1] = sjcl.bitArray.partial(len, a[l-1] & 0x80000000 >> (len-1), 1); 387 | } 388 | return a; 389 | }, 390 | 391 | /** 392 | * Make a partial word for a bit array. 393 | * @param {Number} len The number of bits in the word. 394 | * @param {Number} x The bits. 395 | * @param {Number} [0] _end Pass 1 if x has already been shifted to the high side. 396 | * @return {Number} The partial word. 397 | */ 398 | partial: function (len, x, _end) { 399 | if (len === 32) { return x; } 400 | return (_end ? x|0 : x << (32-len)) + len * 0x10000000000; 401 | }, 402 | 403 | /** 404 | * Get the number of bits used by a partial word. 405 | * @param {Number} x The partial word. 406 | * @return {Number} The number of bits used by the partial word. 407 | */ 408 | getPartial: function (x) { 409 | return Math.round(x/0x10000000000) || 32; 410 | }, 411 | 412 | /** 413 | * Compare two arrays for equality in a predictable amount of time. 414 | * @param {bitArray} a The first array. 415 | * @param {bitArray} b The second array. 416 | * @return {boolean} true if a == b; false otherwise. 417 | */ 418 | equal: function (a, b) { 419 | if (sjcl.bitArray.bitLength(a) !== sjcl.bitArray.bitLength(b)) { 420 | return false; 421 | } 422 | var x = 0, i; 423 | for (i=0; i= 32; shift -= 32) { 441 | out.push(carry); 442 | carry = 0; 443 | } 444 | if (shift === 0) { 445 | return out.concat(a); 446 | } 447 | 448 | for (i=0; i>>shift); 450 | carry = a[i] << (32-shift); 451 | } 452 | last2 = a.length ? a[a.length-1] : 0; 453 | shift2 = sjcl.bitArray.getPartial(last2); 454 | out.push(sjcl.bitArray.partial(shift+shift2 & 31, (shift + shift2 > 32) ? carry : out.pop(),1)); 455 | return out; 456 | }, 457 | 458 | /** xor a block of 4 words together. 459 | * @private 460 | */ 461 | _xor4: function(x,y) { 462 | return [x[0]^y[0],x[1]^y[1],x[2]^y[2],x[3]^y[3]]; 463 | } 464 | }; 465 | /** @fileOverview CBC mode implementation 466 | * 467 | * @author Emily Stark 468 | * @author Mike Hamburg 469 | * @author Dan Boneh 470 | */ 471 | 472 | /** @namespace 473 | * Dangerous: CBC mode with PKCS#5 padding. 474 | * 475 | * @author Emily Stark 476 | * @author Mike Hamburg 477 | * @author Dan Boneh 478 | */ 479 | sjcl.mode.cbc = { 480 | /** The name of the mode. 481 | * @constant 482 | */ 483 | name: "cbc", 484 | 485 | /** Encrypt in CBC mode with PKCS#5 padding. 486 | * @param {Object} prp The block cipher. It must have a block size of 16 bytes. 487 | * @param {bitArray} plaintext The plaintext data. 488 | * @param {bitArray} iv The initialization value. 489 | * @param {bitArray} [adata=[]] The authenticated data. Must be empty. 490 | * @return The encrypted data, an array of bytes. 491 | * @throws {sjcl.exception.invalid} if the IV isn't exactly 128 bits, or if any adata is specified. 492 | */ 493 | encrypt: function(prp, plaintext, iv, adata) { 494 | if (adata && adata.length) { 495 | throw new sjcl.exception.invalid("cbc can't authenticate data"); 496 | } 497 | if (sjcl.bitArray.bitLength(iv) !== 128) { 498 | throw new sjcl.exception.invalid("cbc iv must be 128 bits"); 499 | } 500 | var i, 501 | w = sjcl.bitArray, 502 | xor = w._xor4, 503 | bl = w.bitLength(plaintext), 504 | bp = 0, 505 | output = []; 506 | 507 | if (bl&7) { 508 | throw new sjcl.exception.invalid("pkcs#5 padding only works for multiples of a byte"); 509 | } 510 | 511 | for (i=0; bp+128 <= bl; i+=4, bp+=128) { 512 | /* Encrypt a non-final block */ 513 | iv = prp.encrypt(xor(iv, plaintext.slice(i,i+4))); 514 | output.splice(i,0,iv[0],iv[1],iv[2],iv[3]); 515 | } 516 | 517 | /* Construct the pad. */ 518 | bl = (16 - ((bl >> 3) & 15)) * 0x1010101; 519 | 520 | /* Pad and encrypt. */ 521 | iv = prp.encrypt(xor(iv,w.concat(plaintext,[bl,bl,bl,bl]).slice(i,i+4))); 522 | output.splice(i,0,iv[0],iv[1],iv[2],iv[3]); 523 | return output; 524 | }, 525 | 526 | /** Decrypt in CBC mode. 527 | * @param {Object} prp The block cipher. It must have a block size of 16 bytes. 528 | * @param {bitArray} ciphertext The ciphertext data. 529 | * @param {bitArray} iv The initialization value. 530 | * @param {bitArray} [adata=[]] The authenticated data. It must be empty. 531 | * @return The decrypted data, an array of bytes. 532 | * @throws {sjcl.exception.invalid} if the IV isn't exactly 128 bits, or if any adata is specified. 533 | * @throws {sjcl.exception.corrupt} if if the message is corrupt. 534 | */ 535 | decrypt: function(prp, ciphertext, iv, adata) { 536 | if (adata && adata.length) { 537 | throw new sjcl.exception.invalid("cbc can't authenticate data"); 538 | } 539 | if (sjcl.bitArray.bitLength(iv) !== 128) { 540 | throw new sjcl.exception.invalid("cbc iv must be 128 bits"); 541 | } 542 | if ((sjcl.bitArray.bitLength(ciphertext) & 127) || !ciphertext.length) { 543 | throw new sjcl.exception.corrupt("cbc ciphertext must be a positive multiple of the block size"); 544 | } 545 | var i, 546 | w = sjcl.bitArray, 547 | xor = w._xor4, 548 | bi, bo, 549 | output = []; 550 | 551 | adata = adata || []; 552 | 553 | for (i=0; i 16) { 563 | throw new sjcl.exception.corrupt("pkcs#5 padding corrupt"); 564 | } 565 | bo = bi * 0x1010101; 566 | if (!w.equal(w.bitSlice([bo,bo,bo,bo], 0, bi*8), 567 | w.bitSlice(output, output.length*32 - bi*8, output.length*32))) { 568 | throw new sjcl.exception.corrupt("pkcs#5 padding corrupt"); 569 | } 570 | 571 | return w.bitSlice(output, 0, output.length*32 - bi*8); 572 | } 573 | }; 574 | -------------------------------------------------------------------------------- /src/background/utf8.js: -------------------------------------------------------------------------------- 1 | var UTF8 = { 2 | decode : function (utftext) { 3 | var string = ""; 4 | var i = 0; 5 | var c = c1 = c2 = 0; 6 | 7 | while (i < utftext.length) { 8 | c = utftext.charCodeAt(i); 9 | if (c < 128) { 10 | string += String.fromCharCode(c); 11 | i++; 12 | } 13 | else if((c > 191) && (c < 224)) { 14 | c2 = utftext.charCodeAt(i+1); 15 | string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); 16 | i += 2; 17 | } else { 18 | c2 = utftext.charCodeAt(i+1); 19 | c3 = utftext.charCodeAt(i+2); 20 | string += String.fromCharCode( 21 | ((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); 22 | i += 3; 23 | } 24 | 25 | } 26 | return string; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/background/utils.js: -------------------------------------------------------------------------------- 1 | 2 | var utils = {}; 3 | 4 | utils.isFirefox = false; 5 | 6 | if (!(/Chrome/.test(navigator.userAgent) && /Google/.test(navigator.vendor))) { 7 | utils.isFirefox = true; 8 | } 9 | -------------------------------------------------------------------------------- /src/bootstrap-btn.css: -------------------------------------------------------------------------------- 1 | .b2c-btn { 2 | display: inline-block; 3 | *display: inline; 4 | padding: 4px 14px; 5 | margin-bottom: 0; 6 | *margin-left: .3em; 7 | font-size: 14px; 8 | line-height: 20px; 9 | *line-height: 20px; 10 | color: #333333; 11 | text-align: center; 12 | text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); 13 | vertical-align: middle; 14 | cursor: pointer; 15 | background-color: #f5f5f5; 16 | *background-color: #e6e6e6; 17 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); 18 | background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); 19 | background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); 20 | background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); 21 | background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); 22 | background-repeat: repeat-x; 23 | border: 1px solid #bbbbbb; 24 | *border: 0; 25 | border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); 26 | border-color: #e6e6e6 #e6e6e6 #bfbfbf; 27 | border-bottom-color: #a2a2a2; 28 | -webkit-border-radius: 4px; 29 | -moz-border-radius: 4px; 30 | border-radius: 4px; 31 | filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); 32 | filter: progid:dximagetransform.microsoft.gradient(enabled=false); 33 | *zoom: 1; 34 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); 35 | -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); 36 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); 37 | } 38 | 39 | .b2c-btn:hover, 40 | .b2c-btn:active, 41 | .b2c-btn.active, 42 | .b2c-btn.disabled, 43 | .b2c-btn[disabled] { 44 | color: #333333; 45 | background-color: #e6e6e6; 46 | *background-color: #d9d9d9; 47 | } 48 | 49 | .b2c-btn:active, 50 | .b2c-btn.active { 51 | background-color: #cccccc \9; 52 | } 53 | 54 | .b2c-btn:first-child { 55 | *margin-left: 0; 56 | } 57 | 58 | .b2c-btn:hover { 59 | color: #333333; 60 | text-decoration: none; 61 | background-color: #e6e6e6; 62 | *background-color: #d9d9d9; 63 | /* Buttons in IE7 don't get borders, so darken on hover */ 64 | 65 | background-position: 0 -15px; 66 | -webkit-transition: background-position 0.1s linear; 67 | -moz-transition: background-position 0.1s linear; 68 | -o-transition: background-position 0.1s linear; 69 | transition: background-position 0.1s linear; 70 | } 71 | 72 | .b2c-btn:focus { 73 | outline: thin dotted #333; 74 | outline: 5px auto -webkit-focus-ring-color; 75 | outline-offset: -2px; 76 | } 77 | 78 | .b2c-btn.active, 79 | .b2c-btn:active { 80 | background-color: #e6e6e6; 81 | background-color: #d9d9d9 \9; 82 | background-image: none; 83 | outline: 0; 84 | -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); 85 | -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); 86 | box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); 87 | } 88 | 89 | .b2c-btn.disabled, 90 | .b2c-btn[disabled] { 91 | cursor: default; 92 | background-color: #e6e6e6; 93 | background-image: none; 94 | opacity: 0.65; 95 | filter: alpha(opacity=65); 96 | -webkit-box-shadow: none; 97 | -moz-box-shadow: none; 98 | box-shadow: none; 99 | } 100 | 101 | .b2c-btn-large { 102 | padding: 9px 14px; 103 | font-size: 16px; 104 | line-height: normal; 105 | -webkit-border-radius: 5px; 106 | -moz-border-radius: 5px; 107 | border-radius: 5px; 108 | } 109 | 110 | .b2c-btn-large [class^="icon-"] { 111 | margin-top: 2px; 112 | } 113 | 114 | .b2c-btn-small { 115 | padding: 3px 9px; 116 | font-size: 12px; 117 | line-height: 18px; 118 | } 119 | 120 | .b2c-btn-small [class^="icon-"] { 121 | margin-top: 0; 122 | } 123 | 124 | .b2c-btn-mini { 125 | padding: 2px 6px; 126 | font-size: 11px; 127 | line-height: 17px; 128 | } 129 | 130 | .b2c-btn-block { 131 | display: block; 132 | width: 100%; 133 | padding-right: 0; 134 | padding-left: 0; 135 | -webkit-box-sizing: border-box; 136 | -moz-box-sizing: border-box; 137 | box-sizing: border-box; 138 | } 139 | 140 | .b2c-btn-block + .b2c-btn-block { 141 | margin-top: 5px; 142 | } 143 | 144 | input[type="submit"].b2c-btn-block, 145 | input[type="reset"].b2c-btn-block, 146 | input[type="button"].b2c-btn-block { 147 | width: 100%; 148 | } 149 | 150 | .b2c-btn-primary.active, 151 | .b2c-btn-warning.active, 152 | .b2c-btn-danger.active, 153 | .b2c-btn-success.active, 154 | .b2c-btn-info.active, 155 | .b2c-btn-inverse.active { 156 | color: rgba(255, 255, 255, 0.75); 157 | } 158 | 159 | .b2c-btn { 160 | border-color: #c5c5c5; 161 | border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25); 162 | } 163 | 164 | .b2c-btn-primary { 165 | color: #ffffff; 166 | text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); 167 | background-color: #006dcc; 168 | *background-color: #0044cc; 169 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); 170 | background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); 171 | background-image: -o-linear-gradient(top, #0088cc, #0044cc); 172 | background-image: linear-gradient(to bottom, #0088cc, #0044cc); 173 | background-image: -moz-linear-gradient(top, #0088cc, #0044cc); 174 | background-repeat: repeat-x; 175 | border-color: #0044cc #0044cc #002a80; 176 | border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); 177 | filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0); 178 | filter: progid:dximagetransform.microsoft.gradient(enabled=false); 179 | } 180 | 181 | .b2c-btn-primary:hover, 182 | .b2c-btn-primary:active, 183 | .b2c-btn-primary.active, 184 | .b2c-btn-primary.disabled, 185 | .b2c-btn-primary[disabled] { 186 | color: #ffffff; 187 | background-color: #0044cc; 188 | *background-color: #003bb3; 189 | } 190 | 191 | .b2c-btn-primary:active, 192 | .b2c-btn-primary.active { 193 | background-color: #003399 \9; 194 | } 195 | 196 | .b2c-btn-warning { 197 | color: #ffffff; 198 | text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); 199 | background-color: #faa732; 200 | *background-color: #f89406; 201 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); 202 | background-image: -webkit-linear-gradient(top, #fbb450, #f89406); 203 | background-image: -o-linear-gradient(top, #fbb450, #f89406); 204 | background-image: linear-gradient(to bottom, #fbb450, #f89406); 205 | background-image: -moz-linear-gradient(top, #fbb450, #f89406); 206 | background-repeat: repeat-x; 207 | border-color: #f89406 #f89406 #ad6704; 208 | border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); 209 | filter: progid:dximagetransform.microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); 210 | filter: progid:dximagetransform.microsoft.gradient(enabled=false); 211 | } 212 | 213 | .b2c-btn-warning:hover, 214 | .b2c-btn-warning:active, 215 | .b2c-btn-warning.active, 216 | .b2c-btn-warning.disabled, 217 | .b2c-btn-warning[disabled] { 218 | color: #ffffff; 219 | background-color: #f89406; 220 | *background-color: #df8505; 221 | } 222 | 223 | .b2c-btn-warning:active, 224 | .b2c-btn-warning.active { 225 | background-color: #c67605 \9; 226 | } 227 | 228 | .b2c-btn-danger { 229 | color: #ffffff; 230 | text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); 231 | background-color: #da4f49; 232 | *background-color: #bd362f; 233 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f)); 234 | background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f); 235 | background-image: -o-linear-gradient(top, #ee5f5b, #bd362f); 236 | background-image: linear-gradient(to bottom, #ee5f5b, #bd362f); 237 | background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f); 238 | background-repeat: repeat-x; 239 | border-color: #bd362f #bd362f #802420; 240 | border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); 241 | filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0); 242 | filter: progid:dximagetransform.microsoft.gradient(enabled=false); 243 | } 244 | 245 | .b2c-btn-danger:hover, 246 | .b2c-btn-danger:active, 247 | .b2c-btn-danger.active, 248 | .b2c-btn-danger.disabled, 249 | .b2c-btn-danger[disabled] { 250 | color: #ffffff; 251 | background-color: #bd362f; 252 | *background-color: #a9302a; 253 | } 254 | 255 | .b2c-btn-danger:active, 256 | .b2c-btn-danger.active { 257 | background-color: #942a25 \9; 258 | } 259 | 260 | .b2c-btn-success { 261 | color: #ffffff; 262 | text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); 263 | background-color: #5bb75b; 264 | *background-color: #51a351; 265 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351)); 266 | background-image: -webkit-linear-gradient(top, #62c462, #51a351); 267 | background-image: -o-linear-gradient(top, #62c462, #51a351); 268 | background-image: linear-gradient(to bottom, #62c462, #51a351); 269 | background-image: -moz-linear-gradient(top, #62c462, #51a351); 270 | background-repeat: repeat-x; 271 | border-color: #51a351 #51a351 #387038; 272 | border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); 273 | filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0); 274 | filter: progid:dximagetransform.microsoft.gradient(enabled=false); 275 | } 276 | 277 | .b2c-btn-success:hover, 278 | .b2c-btn-success:active, 279 | .b2c-btn-success.active, 280 | .b2c-btn-success.disabled, 281 | .b2c-btn-success[disabled] { 282 | color: #ffffff; 283 | background-color: #51a351; 284 | *background-color: #499249; 285 | } 286 | 287 | .b2c-btn-success:active, 288 | .b2c-btn-success.active { 289 | background-color: #408140 \9; 290 | } 291 | 292 | .b2c-btn-info { 293 | color: #ffffff; 294 | text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); 295 | background-color: #49afcd; 296 | *background-color: #2f96b4; 297 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4)); 298 | background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4); 299 | background-image: -o-linear-gradient(top, #5bc0de, #2f96b4); 300 | background-image: linear-gradient(to bottom, #5bc0de, #2f96b4); 301 | background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4); 302 | background-repeat: repeat-x; 303 | border-color: #2f96b4 #2f96b4 #1f6377; 304 | border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); 305 | filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0); 306 | filter: progid:dximagetransform.microsoft.gradient(enabled=false); 307 | } 308 | 309 | .b2c-btn-info:hover, 310 | .b2c-btn-info:active, 311 | .b2c-btn-info.active, 312 | .b2c-btn-info.disabled, 313 | .b2c-btn-info[disabled] { 314 | color: #ffffff; 315 | background-color: #2f96b4; 316 | *background-color: #2a85a0; 317 | } 318 | 319 | .b2c-btn-info:active, 320 | .b2c-btn-info.active { 321 | background-color: #24748c \9; 322 | } 323 | 324 | .b2c-btn-inverse { 325 | color: #ffffff; 326 | text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); 327 | background-color: #363636; 328 | *background-color: #222222; 329 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222)); 330 | background-image: -webkit-linear-gradient(top, #444444, #222222); 331 | background-image: -o-linear-gradient(top, #444444, #222222); 332 | background-image: linear-gradient(to bottom, #444444, #222222); 333 | background-image: -moz-linear-gradient(top, #444444, #222222); 334 | background-repeat: repeat-x; 335 | border-color: #222222 #222222 #000000; 336 | border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); 337 | filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0); 338 | filter: progid:dximagetransform.microsoft.gradient(enabled=false); 339 | } 340 | 341 | .b2c-btn-inverse:hover, 342 | .b2c-btn-inverse:active, 343 | .b2c-btn-inverse.active, 344 | .b2c-btn-inverse.disabled, 345 | .b2c-btn-inverse[disabled] { 346 | color: #ffffff; 347 | background-color: #222222; 348 | *background-color: #151515; 349 | } 350 | 351 | .b2c-btn-inverse:active, 352 | .b2c-btn-inverse.active { 353 | background-color: #080808 \9; 354 | } 355 | 356 | button.b2c-btn, 357 | input[type="submit"].b2c-btn { 358 | *padding-top: 3px; 359 | *padding-bottom: 3px; 360 | } 361 | 362 | button.b2c-btn::-moz-focus-inner, 363 | input[type="submit"].b2c-btn::-moz-focus-inner { 364 | padding: 0; 365 | border: 0; 366 | } 367 | 368 | button.b2c-btn.b2c-btn-large, 369 | input[type="submit"].b2c-btn.b2c-btn-large { 370 | *padding-top: 7px; 371 | *padding-bottom: 7px; 372 | } 373 | 374 | button.b2c-btn.b2c-btn-small, 375 | input[type="submit"].b2c-btn.b2c-btn-small { 376 | *padding-top: 3px; 377 | *padding-bottom: 3px; 378 | } 379 | 380 | button.b2c-btn.b2c-btn-mini, 381 | input[type="submit"].b2c-btn.b2c-btn-mini { 382 | *padding-top: 1px; 383 | *padding-bottom: 1px; 384 | } 385 | 386 | .b2c-input-append { 387 | display: inline-block; 388 | margin-bottom: 10px; 389 | white-space: nowrap; 390 | vertical-align: middle; 391 | } 392 | 393 | .b2c-input-append input, 394 | .b2c-input-append select, 395 | .b2c-input-append .b2c-uneditable-input, 396 | .b2c-input-append .b2c-dropdown-menu, 397 | .b2c-input-append .b2c-popover { 398 | font-size: 14px; 399 | } 400 | 401 | .b2c-input-append input, 402 | .b2c-input-append select, 403 | .b2c-input-append .b2c-uneditable-input { 404 | position: relative; 405 | margin-bottom: 0; 406 | *margin-left: 0; 407 | vertical-align: top; 408 | -webkit-border-radius: 0 4px 4px 0; 409 | -moz-border-radius: 0 4px 4px 0; 410 | border-radius: 0 4px 4px 0; 411 | } 412 | 413 | .b2c-input-append input:focus, 414 | .b2c-input-append select:focus, 415 | .b2c-input-append .b2c-b2c-uneditable-input:focus { 416 | z-index: 2; 417 | } 418 | 419 | .b2c-input-append .b2c-add-on { 420 | display: inline-block; 421 | width: auto; 422 | height: 20px; 423 | min-width: 16px; 424 | padding: 4px 5px; 425 | font-size: 14px; 426 | font-weight: normal; 427 | line-height: 20px; 428 | text-align: center; 429 | text-shadow: 0 1px 0 #ffffff; 430 | background-color: #eeeeee; 431 | border: 1px solid #ccc; 432 | } 433 | 434 | .b2c-input-append .b2c-add-on, 435 | .b2c-input-append .b2c-btn, 436 | .b2c-input-append .b2c-btn-group > .b2c-dropdown-toggle { 437 | vertical-align: top; 438 | -webkit-border-radius: 0; 439 | -moz-border-radius: 0; 440 | border-radius: 0; 441 | } 442 | 443 | .b2c-input-append .b2c-active { 444 | background-color: #a9dba9; 445 | border-color: #46a546; 446 | } 447 | 448 | .b2c-input-append input, 449 | .b2c-input-append select, 450 | .b2c-input-append .b2c-uneditable-input { 451 | -webkit-border-radius: 4px 0 0 4px; 452 | -moz-border-radius: 4px 0 0 4px; 453 | border-radius: 4px 0 0 4px; 454 | } 455 | 456 | .b2c-input-append .b2c-add-on, 457 | .b2c-input-append .b2c-btn, 458 | .b2c-input-append .b2c-btn-group { 459 | margin-left: -1px; 460 | } 461 | 462 | .b2c-input-append .b2c-add-on:last-child, 463 | .b2c-input-append .b2c-btn:last-child, 464 | .b2c-input-append .b2c-btn-group:last-child > .b2c-dropdown-toggle { 465 | -webkit-border-radius: 0 4px 4px 0; 466 | -moz-border-radius: 0 4px 4px 0; 467 | border-radius: 0 4px 4px 0; 468 | } -------------------------------------------------------------------------------- /src/browser-polyfill.min.js: -------------------------------------------------------------------------------- 1 | "use strict";if("undefined"==typeof browser){this.browser=(()=>{class c extends WeakMap{constructor(m,n=void 0){super(n),this.createItem=m}get(m){return this.has(m)||this.set(m,this.createItem(m)),super.get(m)}}const d=m=>{return m&&"object"==typeof m&&"function"==typeof m.then},e=m=>{return(...n)=>{chrome.runtime.lastError?m.reject(chrome.runtime.lastError):1===n.length?m.resolve(n[0]):m.resolve(n)}},f=(m,n)=>{const o=p=>1==p?"argument":"arguments";return function(q,...r){if(r.lengthn.maxArgs)throw new Error(`Expected at most ${n.maxArgs} ${o(n.maxArgs)} for ${m}(), got ${r.length}`);return new Promise((s,t)=>{q[m](...r,e({resolve:s,reject:t}))})}},g=(m,n,o)=>{return new Proxy(n,{apply(p,q,r){return o.call(q,m,...r)}})};let h=Function.call.bind(Object.prototype.hasOwnProperty);const i=(m,n={},o={})=>{let p=Object.create(null),q={has(r,s){return s in r||s in p},get(r,s){if(s in p)return p[s];if(s in r){let u=r[s];if("function"==typeof u){if("function"==typeof n[s])u=g(r,r[s],n[s]);else if(h(o,s)){let v=f(s,o[s]);u=g(r,r[s],v)}else u=u.bind(r);}else if("object"==typeof u&&null!==u&&(h(n,s)||h(o,s)))u=i(u,n[s],o[s]);else return Object.defineProperty(p,s,{configurable:!0,enumerable:!0,get(){return r[s]},set(v){r[s]=v}}),u;return p[s]=u,u}},set(r,s,t){return s in p?p[s]=t:r[s]=t,!0},defineProperty(r,s,t){return Reflect.defineProperty(p,s,t)},deleteProperty(r,s){return Reflect.deleteProperty(p,s)}};return new Proxy(m,q)},k=new c(m=>{return"function"==typeof m?function(o,p,q){let r=!1,s=m(o,p,function(t){r=!0,q(t)});return r||!0===s?s:d(s)?(s.then(q,t=>{console.error(t),q(t)}),!0):void(void 0!==s&&q(s))}:m}),l={runtime:{onMessage:(m=>({addListener(n,o,...p){n.addListener(m.get(o),...p)},hasListener(n,o){return n.hasListener(m.get(o))},removeListener(n,o){n.removeListener(m.get(o))}}))(k)}};return i(chrome,l,{alarms:{clear:{minArgs:0,maxArgs:1},clearAll:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getAll:{minArgs:0,maxArgs:0}},bookmarks:{create:{minArgs:1,maxArgs:1},"export":{minArgs:0,maxArgs:0},get:{minArgs:1,maxArgs:1},getChildren:{minArgs:1,maxArgs:1},getRecent:{minArgs:1,maxArgs:1},getTree:{minArgs:0,maxArgs:0},getSubTree:{minArgs:1,maxArgs:1},"import":{minArgs:0,maxArgs:0},move:{minArgs:2,maxArgs:2},remove:{minArgs:1,maxArgs:1},removeTree:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1},update:{minArgs:2,maxArgs:2}},browserAction:{getBadgeBackgroundColor:{minArgs:1,maxArgs:1},getBadgeText:{minArgs:1,maxArgs:1},getPopup:{minArgs:1,maxArgs:1},getTitle:{minArgs:1,maxArgs:1},setIcon:{minArgs:1,maxArgs:1}},commands:{getAll:{minArgs:0,maxArgs:0}},contextMenus:{update:{minArgs:2,maxArgs:2},remove:{minArgs:1,maxArgs:1},removeAll:{minArgs:0,maxArgs:0}},cookies:{get:{minArgs:1,maxArgs:1},getAll:{minArgs:1,maxArgs:1},getAllCookieStores:{minArgs:0,maxArgs:0},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}},downloads:{download:{minArgs:1,maxArgs:1},cancel:{minArgs:1,maxArgs:1},erase:{minArgs:1,maxArgs:1},getFileIcon:{minArgs:1,maxArgs:2},open:{minArgs:1,maxArgs:1},pause:{minArgs:1,maxArgs:1},removeFile:{minArgs:1,maxArgs:1},resume:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1},show:{minArgs:1,maxArgs:1}},extension:{isAllowedFileSchemeAccess:{minArgs:0,maxArgs:0},isAllowedIncognitoAccess:{minArgs:0,maxArgs:0}},history:{addUrl:{minArgs:1,maxArgs:1},getVisits:{minArgs:1,maxArgs:1},deleteAll:{minArgs:0,maxArgs:0},deleteRange:{minArgs:1,maxArgs:1},deleteUrl:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1}},i18n:{detectLanguage:{minArgs:1,maxArgs:1},getAcceptLanguages:{minArgs:0,maxArgs:0}},idle:{queryState:{minArgs:1,maxArgs:1}},management:{get:{minArgs:1,maxArgs:1},getAll:{minArgs:0,maxArgs:0},getSelf:{minArgs:0,maxArgs:0},uninstallSelf:{minArgs:0,maxArgs:1}},notifications:{clear:{minArgs:1,maxArgs:1},create:{minArgs:1,maxArgs:2},getAll:{minArgs:0,maxArgs:0},getPermissionLevel:{minArgs:0,maxArgs:0},update:{minArgs:2,maxArgs:2}},pageAction:{getPopup:{minArgs:1,maxArgs:1},getTitle:{minArgs:1,maxArgs:1},hide:{minArgs:0,maxArgs:0},setIcon:{minArgs:1,maxArgs:1},show:{minArgs:0,maxArgs:0}},runtime:{getBackgroundPage:{minArgs:0,maxArgs:0},getBrowserInfo:{minArgs:0,maxArgs:0},getPlatformInfo:{minArgs:0,maxArgs:0},openOptionsPage:{minArgs:0,maxArgs:0},requestUpdateCheck:{minArgs:0,maxArgs:0},sendMessage:{minArgs:1,maxArgs:3},sendNativeMessage:{minArgs:2,maxArgs:2},setUninstallURL:{minArgs:1,maxArgs:1}},storage:{local:{clear:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}},managed:{get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1}},sync:{clear:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}}},tabs:{create:{minArgs:1,maxArgs:1},captureVisibleTab:{minArgs:0,maxArgs:2},detectLanguage:{minArgs:0,maxArgs:1},duplicate:{minArgs:1,maxArgs:1},executeScript:{minArgs:1,maxArgs:2},get:{minArgs:1,maxArgs:1},getCurrent:{minArgs:0,maxArgs:0},getZoom:{minArgs:0,maxArgs:1},getZoomSettings:{minArgs:0,maxArgs:1},highlight:{minArgs:1,maxArgs:1},insertCSS:{minArgs:1,maxArgs:2},move:{minArgs:2,maxArgs:2},reload:{minArgs:0,maxArgs:2},remove:{minArgs:1,maxArgs:1},query:{minArgs:1,maxArgs:1},removeCSS:{minArgs:1,maxArgs:2},sendMessage:{minArgs:2,maxArgs:3},setZoom:{minArgs:1,maxArgs:2},setZoomSettings:{minArgs:1,maxArgs:2},update:{minArgs:1,maxArgs:2}},webNavigation:{getAllFrames:{minArgs:1,maxArgs:1},getFrame:{minArgs:1,maxArgs:1}},webRequest:{handlerBehaviorChanged:{minArgs:0,maxArgs:0}},windows:{create:{minArgs:0,maxArgs:1},get:{minArgs:1,maxArgs:2},getAll:{minArgs:0,maxArgs:1},getCurrent:{minArgs:0,maxArgs:1},getLastFocused:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},update:{minArgs:2,maxArgs:2}}})})()} 2 | //# sourceMappingURL=browser-polyfill.min.js.map 3 | 4 | 5 | // webextension-polyfill v.0.1.0 (https://github.com/mozilla/webextension-polyfill) 6 | 7 | /* This Source Code Form is subject to the terms of the Mozilla Public 8 | * License, v. 2.0. If a copy of the MPL was not distributed with this 9 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -------------------------------------------------------------------------------- /src/icons/19x19/icon_bang_aqua-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_bang_aqua-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_bang_aqua_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_bang_aqua_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_bang_blue-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_bang_blue-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_bang_blue_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_bang_blue_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_bang_green-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_bang_green-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_bang_green_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_bang_green_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_bang_grey-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_bang_grey-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_bang_grey_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_bang_grey_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_bang_orange-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_bang_orange-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_bang_orange_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_bang_orange_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_bang_pink-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_bang_pink-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_bang_pink_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_bang_pink_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_bang_purple-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_bang_purple-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_bang_purple_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_bang_purple_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_bang_red-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_bang_red-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_bang_red_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_bang_red_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_bang_yellow-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_bang_yellow-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_bang_yellow_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_bang_yellow_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_cross_aqua-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_cross_aqua-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_cross_aqua_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_cross_aqua_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_cross_blue-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_cross_blue-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_cross_blue_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_cross_blue_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_cross_green-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_cross_green-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_cross_green_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_cross_green_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_cross_grey-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_cross_grey-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_cross_grey_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_cross_grey_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_cross_orange-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_cross_orange-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_cross_orange_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_cross_orange_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_cross_pink-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_cross_pink-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_cross_pink_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_cross_pink_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_cross_purple-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_cross_purple-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_cross_purple_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_cross_purple_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_cross_red-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_cross_red-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_cross_red_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_cross_red_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_cross_yellow-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_cross_yellow-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_cross_yellow_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_cross_yellow_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_bang_aqua-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_bang_aqua-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_bang_aqua_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_bang_aqua_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_bang_blue-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_bang_blue-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_bang_blue_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_bang_blue_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_bang_green-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_bang_green-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_bang_green_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_bang_green_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_bang_grey-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_bang_grey-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_bang_grey_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_bang_grey_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_bang_orange-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_bang_orange-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_bang_orange_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_bang_orange_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_bang_pink-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_bang_pink-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_bang_pink_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_bang_pink_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_bang_purple-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_bang_purple-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_bang_purple_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_bang_purple_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_bang_red-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_bang_red-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_bang_red_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_bang_red_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_bang_yellow-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_bang_yellow-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_bang_yellow_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_bang_yellow_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_cross_aqua-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_cross_aqua-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_cross_aqua_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_cross_aqua_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_cross_blue-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_cross_blue-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_cross_blue_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_cross_blue_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_cross_green-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_cross_green-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_cross_green_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_cross_green_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_cross_grey-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_cross_grey-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_cross_grey_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_cross_grey_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_cross_orange-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_cross_orange-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_cross_orange_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_cross_orange_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_cross_pink-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_cross_pink-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_cross_pink_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_cross_pink_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_cross_purple-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_cross_purple-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_cross_purple_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_cross_purple_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_cross_red-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_cross_red-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_cross_red_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_cross_red_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_cross_yellow-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_cross_yellow-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_cross_yellow_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_cross_yellow_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_normal_aqua-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_normal_aqua-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_normal_aqua_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_normal_aqua_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_normal_blue-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_normal_blue-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_normal_blue_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_normal_blue_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_normal_green-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_normal_green-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_normal_green_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_normal_green_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_normal_grey-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_normal_grey-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_normal_grey_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_normal_grey_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_normal_orange-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_normal_orange-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_normal_orange_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_normal_orange_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_normal_pink-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_normal_pink-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_normal_pink_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_normal_pink_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_normal_purple-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_normal_purple-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_normal_purple_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_normal_purple_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_normal_red-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_normal_red-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_normal_red_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_normal_red_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_normal_yellow-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_normal_yellow-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_normal_yellow_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_normal_yellow_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_questionmark_aqua-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_questionmark_aqua-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_questionmark_aqua_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_questionmark_aqua_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_questionmark_blue-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_questionmark_blue-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_questionmark_blue_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_questionmark_blue_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_questionmark_green-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_questionmark_green-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_questionmark_green_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_questionmark_green_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_questionmark_grey-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_questionmark_grey-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_questionmark_grey_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_questionmark_grey_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_questionmark_orange-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_questionmark_orange-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_questionmark_orange_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_questionmark_orange_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_questionmark_pink-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_questionmark_pink-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_questionmark_pink_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_questionmark_pink_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_questionmark_purple-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_questionmark_purple-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_questionmark_purple_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_questionmark_purple_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_questionmark_red-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_questionmark_red-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_questionmark_red_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_questionmark_red_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_questionmark_yellow-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_questionmark_yellow-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_new_questionmark_yellow_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_new_questionmark_yellow_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_normal_aqua-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_normal_aqua-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_normal_aqua_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_normal_aqua_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_normal_blue-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_normal_blue-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_normal_blue_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_normal_blue_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_normal_green-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_normal_green-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_normal_green_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_normal_green_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_normal_grey-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_normal_grey-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_normal_grey_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_normal_grey_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_normal_orange-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_normal_orange-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_normal_orange_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_normal_orange_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_normal_pink-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_normal_pink-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_normal_pink_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_normal_pink_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_normal_purple-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_normal_purple-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_normal_purple_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_normal_purple_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_normal_red-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_normal_red-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_normal_red_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_normal_red_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_normal_yellow-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_normal_yellow-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_normal_yellow_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_normal_yellow_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_questionmark_aqua-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_questionmark_aqua-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_questionmark_aqua_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_questionmark_aqua_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_questionmark_blue-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_questionmark_blue-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_questionmark_blue_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_questionmark_blue_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_questionmark_green-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_questionmark_green-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_questionmark_green_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_questionmark_green_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_questionmark_grey-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_questionmark_grey-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_questionmark_grey_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_questionmark_grey_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_questionmark_orange-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_questionmark_orange-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_questionmark_orange_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_questionmark_orange_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_questionmark_pink-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_questionmark_pink-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_questionmark_pink_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_questionmark_pink_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_questionmark_purple-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_questionmark_purple-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_questionmark_purple_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_questionmark_purple_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_questionmark_red-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_questionmark_red-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_questionmark_red_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_questionmark_red_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_questionmark_yellow-inverse_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_questionmark_yellow-inverse_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_questionmark_yellow_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_questionmark_yellow_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_remember_red_background_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_remember_red_background_19x19.png -------------------------------------------------------------------------------- /src/icons/19x19/icon_remember_red_lock_19x19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/19x19/icon_remember_red_lock_19x19.png -------------------------------------------------------------------------------- /src/icons/keepass_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/keepass_128x128.png -------------------------------------------------------------------------------- /src/icons/keepass_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/keepass_16x16.png -------------------------------------------------------------------------------- /src/icons/keepass_38x38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/keepass_38x38.png -------------------------------------------------------------------------------- /src/icons/keepass_48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/keepass_48x48.png -------------------------------------------------------------------------------- /src/icons/key_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/key_16x16.png -------------------------------------------------------------------------------- /src/icons/key_24x24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/icons/key_24x24.png -------------------------------------------------------------------------------- /src/images/ui-icons_444444_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/images/ui-icons_444444_256x240.png -------------------------------------------------------------------------------- /src/images/ui-icons_555555_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/images/ui-icons_555555_256x240.png -------------------------------------------------------------------------------- /src/images/ui-icons_777620_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/images/ui-icons_777620_256x240.png -------------------------------------------------------------------------------- /src/images/ui-icons_777777_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/images/ui-icons_777777_256x240.png -------------------------------------------------------------------------------- /src/images/ui-icons_cc0000_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/images/ui-icons_cc0000_256x240.png -------------------------------------------------------------------------------- /src/images/ui-icons_ffffff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/images/ui-icons_ffffff_256x240.png -------------------------------------------------------------------------------- /src/kphc.css: -------------------------------------------------------------------------------- 1 | .kphc .ui-autocomplete li.ui-menu-item { 2 | text-align: left !important; 3 | font-size: 12px !important; 4 | font-weight: normal !important; 5 | font-style: normal !important; 6 | font-family: Verdana, Arial, sans-serif !important; 7 | color: #222222 !important; 8 | } 9 | .kphc .widget-overlay { 10 | background: none !important; 11 | z-index: 2147483601 !important; 12 | } 13 | .kphc .ui-dialog { 14 | z-index: 2147483602 !important; 15 | } 16 | .kphc .ui-dialog .ui-dialog-title { 17 | font-size:.9em !important; 18 | } 19 | .kphc .ui-dialog .ui-dialog-titlebar { 20 | padding:.1em .5em !important; 21 | } 22 | .kphc .ui-dialog-content { 23 | font-size: .9em !important; 24 | } 25 | 26 | .ui-helper-hidden-accessible { 27 | display: none !important; 28 | } 29 | 30 | #cip-genpw-dialog { 31 | text-align: left !important; 32 | } 33 | #cip-genpw-dialog button { 34 | height: 26px !important; 35 | } 36 | .cip-genpw-clearfix:after { 37 | clear: both; 38 | line-height: 0; 39 | content: ""; 40 | display: table; 41 | } 42 | .cip-genpw-icon { 43 | position: absolute; 44 | cursor: pointer; 45 | } 46 | .cip-genpw-icon.cip-icon-key-small { 47 | width: 16px; 48 | height: 16px; 49 | } 50 | .cip-genpw-icon.cip-icon-key-big { 51 | width: 24px; 52 | height: 24px; 53 | } 54 | .cip-genpw-password-frame { 55 | margin-top: 5px !important; 56 | margin-bottom: 5px !important; 57 | } 58 | .cip-genpw-password-frame > * { 59 | height: 20px !important; 60 | font-size: 11px !important; 61 | } 62 | .cip-genpw-textfield { 63 | background: none !important; 64 | font-size: 11px !important; 65 | display: inline !important; 66 | border: 1px solid rgb(170, 170, 170) !important; 67 | padding: 1px 2px !important; 68 | max-width: none !important; 69 | min-width: 0 !important; 70 | font-size: 1em !important; 71 | width: 240px !important; 72 | padding-left: 5px !important; 73 | } 74 | #cip-genpw-quality { 75 | width: 50px !important; 76 | padding-top: 1px !important; 77 | padding-bottom: 1px !important; 78 | } 79 | .cip-genpw-label { 80 | display: block !important; 81 | margin: 5px 0 !important; 82 | } 83 | .cip-genpw-checkbox { 84 | vertical-align: middle !important; 85 | } 86 | #cip-genpw-btn-fillin { 87 | margin-right: 5px; 88 | } 89 | 90 | .b2c-modal-backdrop { 91 | position: fixed; 92 | top: 0; 93 | right: 0; 94 | bottom: 0; 95 | left: 0; 96 | z-index: 2147483645; 97 | } 98 | .b2c-modal-backdrop:after { 99 | content:''; 100 | position: fixed; 101 | top: 0; 102 | right: 0; 103 | bottom: 0; 104 | left: 0; 105 | background-color: #000000; 106 | opacity: 0.8; 107 | filter: alpha(opacity=80); 108 | } 109 | #b2c-cipDefine-fields { 110 | z-index: 2147483646; 111 | } 112 | #b2c-cipDefine-description { 113 | z-index: 2147483646; 114 | color: #efefef; 115 | border: 2px solid #555555; 116 | padding: 7px 5px; 117 | position: absolute; 118 | top: 100px; 119 | left: 150px; 120 | text-align: left; 121 | cursor: pointer; 122 | background-color:rgba(255,255,255,0.3); 123 | font-size: 15px; 124 | } 125 | #b2c-cipDefine-description div:first-of-type { 126 | margin-top: 0; 127 | padding-top: 0; 128 | text-align: left; 129 | color: #efefef; 130 | padding-bottom: 8px; 131 | font-weight: bold; 132 | font-size: 160%; 133 | } 134 | #b2c-cipDefine-description p { 135 | margin-top: 10px; 136 | padding-top: 10px; 137 | color: #efefef; 138 | border-top: 2px solid #666666; 139 | line-height: 110%; 140 | } 141 | #b2c-help { 142 | margin-bottom: 3px; 143 | } 144 | .b2c-fixed-field { 145 | position: absolute; 146 | border: 2px solid #efefef; 147 | cursor: pointer; 148 | z-index: 2147483646; 149 | text-align: left; 150 | font-weight: bold; 151 | background-color:rgba(239,239,239,0.4); 152 | } 153 | .b2c-fixed-hover-field { 154 | border: 2px solid orange; 155 | background-color:rgba(255,165,239,0.4); 156 | } 157 | .b2c-fixed-password-field { 158 | border: 2px solid red; 159 | color: #efefef; 160 | background-color:rgba(255,0,0,0.4); 161 | } 162 | .b2c-fixed-username-field { 163 | border: 2px solid limegreen; 164 | color: #efefef; 165 | background-color:rgba(50,205,50,0.4); 166 | } 167 | .b2c-fixed-string-field { 168 | border: 2px solid deepskyblue; 169 | color: #efefef; 170 | background-color:rgba(30,144,255,0.4); 171 | } 172 | -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "KeePassHttp-Connector", 3 | "version": "1.0.11", 4 | "manifest_version": 2, 5 | "description": "KeePass integration for browsers using KeePassHttp", 6 | "icons": { 7 | "16": "icons/keepass_16x16.png", 8 | "48": "icons/keepass_48x48.png", 9 | "128": "icons/keepass_128x128.png" 10 | }, 11 | "applications": { 12 | "gecko": { 13 | "id": "keepasshttp-connector@addons.brandt.tech" 14 | } 15 | }, 16 | "browser_action": { 17 | "default_icon": { 18 | "19": "icons/19x19/icon_normal_blue_19x19.png", 19 | "38": "icons/keepass_38x38.png" 20 | }, 21 | "default_title": "KeePassHttp-Connector", 22 | "default_popup": "popups/popup.html" 23 | }, 24 | "options_ui": { 25 | "page": "options/options.html", 26 | "open_in_tab": true 27 | }, 28 | "background": { 29 | "scripts": [ 30 | "browser-polyfill.min.js", 31 | "background/aes.js", 32 | "background/cryptoHelpers.js", 33 | "background/utf8.js", 34 | "background/utils.js", 35 | "background/keepass.js", 36 | "background/httpauth.js", 37 | "background/browserAction.js", 38 | "background/page.js", 39 | "background/event.js", 40 | "background/init.js" 41 | ] 42 | }, 43 | "content_scripts": [ 44 | { 45 | "matches": [ 46 | "http://*/*", 47 | "https://*/*" 48 | ], 49 | "exclude_matches": [ 50 | "*://*/*.xml", 51 | "*://*/*.xsd" 52 | ], 53 | "js": [ 54 | "browser-polyfill.min.js", 55 | "jquery-3.2.1.min.js", 56 | "jquery-ui.min.js", 57 | "kphc.js" 58 | ], 59 | "css": [ 60 | "jquery-ui.min.css", 61 | "bootstrap-btn.css", 62 | "kphc.css" 63 | ], 64 | "run_at": "document_idle", 65 | "all_frames": true 66 | } 67 | ], 68 | "commands": { 69 | "fill-username-password": { 70 | "description": "Insert username + password", 71 | "suggested_key": { 72 | "default": "Alt+Shift+U", 73 | "mac": "Alt+Shift+U" 74 | } 75 | }, 76 | "fill-password": { 77 | "description": "Insert a password", 78 | "suggested_key": { 79 | "default": "Alt+Shift+P", 80 | "mac": "Alt+Shift+P" 81 | } 82 | } 83 | }, 84 | "web_accessible_resources": [ 85 | "jquery.min.map", 86 | "icons/key_16x16.png", 87 | "icons/key_24x24.png", 88 | "images/*" 89 | ], 90 | "permissions": [ 91 | "activeTab", 92 | "contextMenus", 93 | "clipboardWrite", 94 | "storage", 95 | "tabs", 96 | "webRequest", 97 | "webRequestBlocking", 98 | "https://*/*", 99 | "http://*/*", 100 | "http://localhost:19455/", 101 | "http://localhost/", 102 | "https://raw.github.com/" 103 | ] 104 | } -------------------------------------------------------------------------------- /src/options/http-auth-dialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/options/http-auth-dialog.png -------------------------------------------------------------------------------- /src/options/options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Settings | KeePassHttp-Connector 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 74 | 75 | 76 |
77 |
78 |

logo KeePassHttp-Connector

79 | 91 |
92 | 93 | 94 |
95 |

General Settings

96 |
97 |

98 | If you just want to insert username + password into the fields where your focus is, press Ctrl + Shift + U. 99 |
100 | If you only want to insert the password, just press Alt + Shift + P. You can customize these shortcuts on chrome://extensions/configureCommands page. 101 |

102 |

103 | 104 |

105 |
106 | 107 | 108 |
109 | 110 | What is the maximum time (ms) the icon should blink after detecting new credentials 111 |
112 | Default: 7500 113 |
114 |
115 |

116 |

117 | 118 |

119 |
120 | 121 | 122 |
123 | 124 | What is the minimum time (ms) the icon should blink before deactivating due to page redirects. 125 |
126 | -1 to only use Blink Time ignoring Redirect Allowance (old behavior) 127 |
128 | Default: -1, Recommended: 2000 129 |
130 |
131 |

132 |

133 | 134 |

135 |
136 | 137 | 138 |
139 | 140 | How many pages should the tab cycle through after the redirect offset before deactivating the icon 141 |
142 | Default: 1 143 |
144 |
145 |

146 |
147 |

148 | 151 | For all password-fields there will be an icon added to generate a new password.
152 | It is generated by KeePass with the profile for automatically generated passwords for new entries.
153 |

154 |
155 |

156 | 159 | KeePassHttp-Connector will immediately retrieve the credentials when the tab is activated. 160 |

161 |
162 |

163 | 166 | If KeePassHttp-Connector does only receive a single entry from KeePassHttp it automatically fills this credentials into the found credential fields. 167 |

168 |
169 |

170 | 173 | For all username fields on a page a dropdown list appears which contains all available credentials. 174 |

175 |
176 |

177 | Check for updates of KeePassHttp: 178 |
179 | 180 | 181 | 182 | 183 |

184 |
185 | KeePassHttp-Connector needs the plugin KeePassHttp to retrieve credentials from and send them to KeePass. 186 |
187 | You can download the latest stable version from here: https://github.com/pfn/keepasshttp 188 |
189 |
190 |
191 |
Your version of KeePassHttp:
192 |
193 |
194 |
195 |
Latest available version of KeePassHttp:
196 |
197 |
198 |
199 |
200 |

201 | 204 | 205 | If credentials are found for a page and the login-type is an HTTP Auth request, KeePassHttp-Connector tries to login with the first given credentials. 206 |
207 | An HTTP Auth dialog looks like this: 208 |
209 | http-auth-dialog 210 |

211 |
212 |
213 | Attention! Please change the following settings only if you know what you are doing! 214 |
215 | 216 |
217 |
218 |

219 | KeePassHttp-Connector communicates on http://[hostname]:[port] with KeePassHTTP. 220 |
221 | If you want to run KeePass on a remote computer, you have to change the hostname. 222 |
223 | Sometimes the default port is still in use and you have to change the port number in KeePassHTTP to get it running. So you have to set the same port number in KeePassHttp-Connector and KeePassHTTP. 224 |

225 |

226 | 227 |

228 |
229 | 230 | 231 |
232 | 233 | Default: localhost 234 | 235 |
236 |

237 |

238 | 239 |

240 |
241 | 242 | 243 |
244 | 245 | Change the port if you have trouble with running KeePassHTTP on the default port. 246 |
247 | You have to set the same port number in KeePassHTTP options! 248 |
249 | Default: 19455 250 |
251 |
252 |

253 |

254 | 257 | Disables communicating errors and warnings via JavaScript alert. 258 |

259 |

260 | 263 | Limit the field filled in to the maximum number of characters allowed by 264 | maxlength="" in the input as set by the website admin?
265 | There is a possibility of this causing issues with sites that have decreased this value after 266 | you have already created one, or have increased it before the fact and the password stored in keepass itself is longer than maxlength. 267 |
268 |

269 |
270 |
271 | 272 | 273 |
274 |

Connected Databases

275 |
276 |

277 | If you are using several KeePass databases you can define a specific icon-color to each of them. 278 |
279 | This will help you to easily determine from which database the credentials are retrieved. 280 |

281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 325 | 326 | 327 | 328 | 329 | 330 |
IdentifierIconLast usedCreatedDelete
No connected databases found.
298 | 324 |
331 |
332 | 333 |
334 | 352 |
353 | 354 | 355 |
356 |

Specified credential fields

357 |
358 |

359 | If KeePassHttp-Connector detects the wrong credential fields, you are able to specify the correct fields by yourself. 360 |
361 | Just go to the page and click on the KeePassHttp-Connector-Icon, now select Choose own credential fields for this page. 362 |
363 | On this page you can manage theses specified credential fields. 364 |

365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 |
Page URLDelete
No specified credential fields found.
382 | 400 |
401 | 402 | 403 |
404 |

About

405 |
406 |

407 | Developed by Perry Nguyen and Lukas Schulze.
408 | WebExtension (Firefox) compatibility by Angus Gratton and Andy Brandt. 409 |

410 |

411 | Visit extension's page in Chrome Web store 412 |

413 |

414 | Visit project's page in GitHub. 415 |

416 |
417 |
418 |
KeePassHttp-Connector Version:
419 |
420 |
421 |
422 |
KeePassHttp Version:
423 |
424 |
425 |
426 |
427 | 430 |
431 | 432 | 433 | -------------------------------------------------------------------------------- /src/options/options.js: -------------------------------------------------------------------------------- 1 | if(jQuery) { 2 | var $ = jQuery.noConflict(true); 3 | } 4 | 5 | $(function() { 6 | browser.runtime.sendMessage({ action: 'load_settings' }).then((settings) => { 7 | options.settings = settings; 8 | browser.runtime.sendMessage({ action: 'load_keyring' }).then((keyRing) => { 9 | options.keyRing = keyRing; 10 | options.initMenu(); 11 | options.initGeneralSettings(); 12 | options.initConnectedDatabases(); 13 | options.initSpecifiedCredentialFields(); 14 | options.initAbout(); 15 | }); 16 | }); 17 | }); 18 | 19 | var options = options || {}; 20 | 21 | options.saveSettings = function() { 22 | browser.storage.local.set({'settings': options.settings}); 23 | browser.runtime.sendMessage({ 24 | action: 'load_settings' 25 | }); 26 | }; 27 | 28 | options.saveSettingsPromise = function() { 29 | return new Promise((resolve, reject) => { 30 | browser.storage.local.set({'settings': options.settings}).then((item) => { 31 | browser.runtime.sendMessage({ 32 | action: 'load_settings' 33 | }).then((settings) => { 34 | resolve(settings); 35 | }); 36 | }); 37 | }); 38 | } 39 | 40 | options.saveKeyRing = function() { 41 | browser.storage.local.set({'keyRing': options.keyRing}); 42 | browser.runtime.sendMessage({ 43 | action: 'load_keyring' 44 | }); 45 | }; 46 | 47 | options.initMenu = function() { 48 | $(".navbar:first ul.nav:first li a").click(function(e) { 49 | e.preventDefault(); 50 | $(".navbar:first ul.nav:first li").removeClass("active"); 51 | $(this).parent("li").addClass("active"); 52 | $("div.tab").hide(); 53 | $("div.tab#tab-" + $(this).attr("href").substring(1)).fadeIn(); 54 | }); 55 | 56 | $("div.tab:first").show(); 57 | } 58 | 59 | options.initGeneralSettings = function() { 60 | $("#tab-general-settings input[type=checkbox]").each(function() { 61 | $(this).attr("checked", options.settings[$(this).attr("name")]); 62 | }); 63 | 64 | $("#tab-general-settings input[type=checkbox]").change(function() { 65 | var name = $(this).attr('name'); 66 | options.settings[name] = $(this).is(':checked'); 67 | options.saveSettingsPromise().then((x) => { 68 | if (name === 'autoFillAndSend') { 69 | browser.runtime.sendMessage({action: 'init_http_auth'}); 70 | } 71 | }); 72 | }); 73 | 74 | $("#tab-general-settings input[type=radio]").each(function() { 75 | if($(this).val() == options.settings[$(this).attr("name")]) { 76 | $(this).attr("checked", options.settings[$(this).attr("name")]); 77 | } 78 | }); 79 | 80 | $("#tab-general-settings input[type=radio]").change(function() { 81 | options.settings[$(this).attr("name")] = $(this).val(); 82 | options.saveSettings(); 83 | }); 84 | 85 | browser.runtime.sendMessage({ 86 | action: "get_keepasshttp_versions" 87 | }).then(options.showKeePassHttpVersions); 88 | 89 | $("#tab-general-settings button.checkUpdateKeePassHttp:first").click(function(e) { 90 | e.preventDefault(); 91 | $(this).attr("disabled", true); 92 | browser.runtime.sendMessage({ 93 | action: "check_update_keepasshttp" 94 | }).then(options.showKeePassHttpVersions); 95 | }); 96 | 97 | $("#showDangerousSettings").click(function() { 98 | $('#dangerousSettings').is(":visible") ? $(this).text("Show these settings anyway") : $(this).text("Hide"); 99 | $("#dangerousSettings").toggle(); 100 | }); 101 | 102 | $("#hostname").val(options.settings["hostname"]); 103 | $("#port").val(options.settings["port"]); 104 | $("#blinkTimeout").val(options.settings["blinkTimeout"]); 105 | $("#blinkMinTimeout").val(options.settings["blinkMinTimeout"]); 106 | $("#allowedRedirect").val(options.settings["allowedRedirect"]); 107 | 108 | $("#portButton").click(function() { 109 | var port = $.trim($("#port").val()); 110 | var portNumber = parseInt(port); 111 | if(isNaN(port) || portNumber < 1025 || portNumber > 99999) { 112 | $("#port").closest(".control-group").addClass("error"); 113 | alert("The port number has to be in range 1025 - 99999.\nNothing saved!"); 114 | return; 115 | } 116 | 117 | options.settings["port"] = portNumber.toString(); 118 | $("#port").closest(".control-group").removeClass("error").addClass("success"); 119 | setTimeout(function() {$("#port").closest(".control-group").removeClass("success")}, 2500); 120 | 121 | options.saveSettings(); 122 | }); 123 | 124 | $("#hostnameButton").click(function() { 125 | var hostname = $("#hostname").val(); 126 | if($.trim(hostname) == "") { 127 | $("#hostname").closest(".control-group").addClass("error"); 128 | alert("Hostname cannot be empty.\nNothing saved!"); 129 | return; 130 | } 131 | 132 | options.settings["hostname"] = hostname; 133 | $("#hostname").closest(".control-group").removeClass("error").addClass("success"); 134 | setTimeout(function() {$("#hostname").closest(".control-group").removeClass("success")}, 2500); 135 | 136 | options.saveSettings(); 137 | }); 138 | 139 | $("#blinkTimeoutButton").click(function(){ 140 | var blinkTimeout = $.trim($("#blinkTimeout").val()); 141 | var blinkTimeoutval = parseInt(blinkTimeout); 142 | 143 | options.settings["blinkTimeout"] = blinkTimeoutval.toString(); 144 | 145 | $("#blinkTimeout").closest(".control-group").removeClass("error").addClass("success"); 146 | setTimeout(function() {$("#blinkTimeout").closest(".control-group").removeClass("success")}, 2500); 147 | 148 | options.saveSettings(); 149 | }); 150 | 151 | $("#blinkMinTimeoutButton").click(function(){ 152 | var blinkMinTimeout = $.trim($("#blinkMinTimeout").val()); 153 | var blinkMinTimeoutval = parseInt(blinkMinTimeout); 154 | 155 | options.settings["blinkMinTimeout"] = blinkMinTimeoutval.toString(); 156 | $("#blinkMinTimeout").closest(".control-group").removeClass("error").addClass("success"); 157 | setTimeout(function() {$("#blinkMinTimeout").closest(".control-group").removeClass("success")}, 2500); 158 | 159 | options.saveSettings(); 160 | }); 161 | 162 | $("#allowedRedirectButton").click(function(){ 163 | var allowedRedirect = $.trim($("#allowedRedirect").val()); 164 | var allowedRedirectval = parseInt(allowedRedirect); 165 | 166 | options.settings["allowedRedirect"] = allowedRedirectval.toString(); 167 | $("#allowedRedirect").closest(".control-group").removeClass("error").addClass("success"); 168 | setTimeout(function() {$("#allowedRedirect").closest(".control-group").removeClass("success")}, 2500); 169 | 170 | options.saveSettings(); 171 | }); 172 | 173 | if (!browser.webRequest.onAuthRequired) { 174 | /* onAuthRequired isn't supported on current Firefox, so hide this feature. */ 175 | $("#http-auth-options").hide(); 176 | } 177 | }; 178 | 179 | options.showKeePassHttpVersions = function(response) { 180 | if(response.current <= 0) { 181 | response.current = "unknown"; 182 | } 183 | if(response.latest <= 0) { 184 | response.latest = "unknown"; 185 | } 186 | $("#tab-general-settings .kphVersion:first em.yourVersion:first").text(response.current); 187 | $("#tab-general-settings .kphVersion:first em.latestVersion:first").text(response.latest); 188 | 189 | $("#tab-about em.versionKPH").text(response.current); 190 | 191 | $("#tab-general-settings button.checkUpdateKeePassHttp:first").attr("disabled", false); 192 | } 193 | 194 | options.initConnectedDatabases = function() { 195 | $("#dialogDeleteConnectedDatabase").modal({keyboard: true, show: false, backdrop: true}); 196 | $("#tab-connected-databases tr.clone:first button.delete:first").click(function(e) { 197 | e.preventDefault(); 198 | $("#dialogDeleteConnectedDatabase").data("hash", $(this).closest("tr").data("hash")); 199 | $("#dialogDeleteConnectedDatabase .modal-body:first span:first").text($(this).closest("tr").children("td:first").text()); 200 | $("#dialogDeleteConnectedDatabase").modal("show"); 201 | }); 202 | 203 | $("#dialogDeleteConnectedDatabase .modal-footer:first button.yes:first").click(function(e) { 204 | $("#dialogDeleteConnectedDatabase").modal("hide"); 205 | 206 | var $hash = $("#dialogDeleteConnectedDatabase").data("hash"); 207 | $("#tab-connected-databases #tr-cd-" + $hash).remove(); 208 | 209 | delete options.keyRing[$hash]; 210 | options.saveKeyRing(); 211 | 212 | if($("#tab-connected-databases table tbody:first tr").length > 2) { 213 | $("#tab-connected-databases table tbody:first tr.empty:first").hide(); 214 | } 215 | else { 216 | $("#tab-connected-databases table tbody:first tr.empty:first").show(); 217 | } 218 | }); 219 | 220 | $("#tab-connected-databases tr.clone:first .dropdown-menu:first").width("230px"); 221 | 222 | $("#tab-connected-databases tr.clone:first .color.dropdown .dropdown-menu a").click(function(e) { 223 | e.preventDefault(); 224 | var $icon = $(this).attr("href").substring(1); 225 | var $hash = $(this).closest("tr").data("hash"); 226 | 227 | $(this).parent().parent().find("a.dropdown-toggle:first").find("img:first").attr("src", "/icons/19x19/icon_normal_" + $icon + "_19x19.png"); 228 | 229 | options.keyRing[$hash].icon = $icon; 230 | options.saveKeyRing(); 231 | }); 232 | 233 | var $trClone = $("#tab-connected-databases table tr.clone:first").clone(true); 234 | $trClone.removeClass("clone"); 235 | for(var hash in options.keyRing) { 236 | var $tr = $trClone.clone(true); 237 | $tr.data("hash", hash); 238 | $tr.attr("id", "tr-cd-" + hash); 239 | 240 | var $icon = options.keyRing[hash].icon || "blue"; 241 | $("a.dropdown-toggle:first img:first", $tr).attr("src", "/icons/19x19/icon_normal_" + $icon + "_19x19.png"); 242 | 243 | $tr.children("td:first").text(options.keyRing[hash].id); 244 | var lastUsed = (options.keyRing[hash].lastUsed) ? new Date(options.keyRing[hash].lastUsed).toLocaleString() : "unknown"; 245 | $tr.children("td:eq(2)").text(lastUsed); 246 | var date = (options.keyRing[hash].created) ? new Date(options.keyRing[hash].created).toLocaleDateString() : "unknown"; 247 | $tr.children("td:eq(3)").text(date); 248 | $("#tab-connected-databases table tbody:first").append($tr); 249 | } 250 | 251 | if($("#tab-connected-databases table tbody:first tr").length > 2) { 252 | $("#tab-connected-databases table tbody:first tr.empty:first").hide(); 253 | } 254 | else { 255 | $("#tab-connected-databases table tbody:first tr.empty:first").show(); 256 | } 257 | $("#connect-button").click(function() { 258 | browser.runtime.sendMessage({ 259 | action: "associate" 260 | }); 261 | }); 262 | } 263 | 264 | options.initSpecifiedCredentialFields = function() { 265 | $("#dialogDeleteSpecifiedCredentialFields").modal({keyboard: true, show: false, backdrop: true}); 266 | $("#tab-specified-fields tr.clone:first button.delete:first").click(function(e) { 267 | e.preventDefault(); 268 | $("#dialogDeleteSpecifiedCredentialFields").data("url", $(this).closest("tr").data("url")); 269 | $("#dialogDeleteSpecifiedCredentialFields").data("tr-id", $(this).closest("tr").attr("id")); 270 | $("#dialogDeleteSpecifiedCredentialFields .modal-body:first strong:first").text($(this).closest("tr").children("td:first").text()); 271 | $("#dialogDeleteSpecifiedCredentialFields").modal("show"); 272 | }); 273 | 274 | $("#dialogDeleteSpecifiedCredentialFields .modal-footer:first button.yes:first").click(function(e) { 275 | $("#dialogDeleteSpecifiedCredentialFields").modal("hide"); 276 | 277 | var $url = $("#dialogDeleteSpecifiedCredentialFields").data("url"); 278 | var $trId = $("#dialogDeleteSpecifiedCredentialFields").data("tr-id"); 279 | $("#tab-specified-fields #" + $trId).remove(); 280 | 281 | delete options.settings["defined-credential-fields"][$url]; 282 | options.saveSettings(); 283 | 284 | if($("#tab-specified-fields table tbody:first tr").length > 2) { 285 | $("#tab-specified-fields table tbody:first tr.empty:first").hide(); 286 | } 287 | else { 288 | $("#tab-specified-fields table tbody:first tr.empty:first").show(); 289 | } 290 | }); 291 | 292 | var $trClone = $("#tab-specified-fields table tr.clone:first").clone(true); 293 | $trClone.removeClass("clone"); 294 | var counter = 1; 295 | for(var url in options.settings["defined-credential-fields"]) { 296 | var $tr = $trClone.clone(true); 297 | $tr.data("url", url); 298 | $tr.attr("id", "tr-scf" + counter); 299 | counter += 1; 300 | 301 | $tr.children("td:first").text(url); 302 | $("#tab-specified-fields table tbody:first").append($tr); 303 | } 304 | 305 | if($("#tab-specified-fields table tbody:first tr").length > 2) { 306 | $("#tab-specified-fields table tbody:first tr.empty:first").hide(); 307 | } 308 | else { 309 | $("#tab-specified-fields table tbody:first tr.empty:first").show(); 310 | } 311 | } 312 | 313 | options.initAbout = function() { 314 | var manifest = browser.runtime.getManifest(); 315 | $("#tab-about em.versionCIP").text(manifest.version); 316 | browser.runtime.sendMessage({ action: 'is_firefox' }).then((isFirefox) => { 317 | if (isFirefox) { 318 | $("#chrome-web-store-link").remove(); 319 | } 320 | }); 321 | } 322 | -------------------------------------------------------------------------------- /src/popups/popup.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: sans-serif; 3 | min-width:357px; 4 | overflow-x:hidden; 5 | background: #eee; 6 | font-size: 15px; 7 | } 8 | .credentials ul { 9 | margin-left: 0; 10 | margin-right: 0; 11 | padding-left: 0; 12 | padding-right: 0; 13 | list-style-position: inside; 14 | } 15 | .credentials li { 16 | list-style: none; 17 | padding-top: 1px; 18 | padding-bottom: 1px; 19 | padding-left: 10px; 20 | padding-right: 5px; 21 | margin-left: 10px; 22 | margin-right: 5px; 23 | } 24 | .credentials a { 25 | cursor: pointer; 26 | display: block; 27 | color: #336; 28 | } 29 | .credentials li:hover { 30 | cursor: pointer; 31 | background: #ccc; 32 | } 33 | 34 | .settings { 35 | padding-bottom: 10px; 36 | margin-bottom: 10px; 37 | border-bottom: 1px solid #333; 38 | font-size: 90%; 39 | } 40 | .settings label { 41 | display: block; 42 | } 43 | .settings label input { 44 | vertical-align: middle; 45 | } 46 | .settings .description { 47 | margin-top: 3px; 48 | font-size: 80%; 49 | color: #787878; 50 | } 51 | .small { 52 | margin-top: 3px; 53 | margin-left: 12px; 54 | font-size: 80%; 55 | color: #787878; 56 | } 57 | #update-available { 58 | display: none; 59 | font-size: 90%; 60 | color: #cc0000; 61 | font-weight: bold; 62 | border-top: 1px solid #333; 63 | padding-top: 10px; 64 | margin-top: 10px; 65 | } 66 | #update-available a:link, 67 | #update-available a:visited { 68 | text-decoration: underline; 69 | color: #cc0000; 70 | } 71 | #update-available a:hover, 72 | #update-available a:active { 73 | text-decoration: none; 74 | } -------------------------------------------------------------------------------- /src/popups/popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | KeePass - Popup 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 |
17 | You use an old version of KeePassHttp. 18 |
19 | Please download the latest version from GitHub. 20 |
21 |
22 | 23 |
24 |

Checking status...

25 |
26 | 27 | 36 | 37 | 49 | 50 | 57 | 58 | 68 | 69 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /src/popups/popup.js: -------------------------------------------------------------------------------- 1 | function status_response(r) { 2 | $('#initial-state').hide(); 3 | $('#error-encountered').hide(); 4 | $('#need-reconfigure').hide(); 5 | $('#not-configured').hide(); 6 | $('#configured-and-associated').hide(); 7 | $('#configured-not-associated').hide(); 8 | 9 | 10 | if(!r.keePassHttpAvailable || r.databaseClosed) { 11 | $('#error-message').html(r.error); 12 | $('#error-encountered').show(); 13 | } 14 | else if(!r.configured) { 15 | $('#not-configured').show(); 16 | } 17 | else if(r.encryptionKeyUnrecognized) { 18 | $('#need-reconfigure').show(); 19 | $('#need-reconfigure-message').html(r.error); 20 | } 21 | else if(!r.associated) { 22 | //$('#configured-not-associated').show(); 23 | //$('#unassociated-identifier').html(r.identifier); 24 | $('#need-reconfigure').show(); 25 | $('#need-reconfigure-message').html(r.error); 26 | } 27 | else if(typeof(r.error) != "undefined") { 28 | $('#error-encountered').show(); 29 | $('#error-message').html(r.error); 30 | } 31 | else { 32 | $('#configured-and-associated').show(); 33 | $('#associated-identifier').html(r.identifier); 34 | } 35 | } 36 | 37 | $(function() { 38 | $("#connect-button").click(function() { 39 | browser.runtime.sendMessage({ 40 | action: "associate" 41 | }); 42 | close(); 43 | }); 44 | 45 | $("#reconnect-button").click(function() { 46 | browser.runtime.sendMessage({ 47 | action: "associate" 48 | }); 49 | close(); 50 | }); 51 | 52 | $("#reload-status-button").click(function() { 53 | browser.runtime.sendMessage({ 54 | action: "get_status" 55 | }).then(status_response); 56 | }); 57 | 58 | $("#redetect-fields-button").click(function() { 59 | browser.tabs.query({"active": true, "currentWindow": true}).then(function(tabs) { 60 | if (tabs.length === 0) 61 | return; // For example: only the background devtools or a popup are opened 62 | var tab = tabs[0]; 63 | 64 | browser.tabs.sendMessage(tab.id, { 65 | action: "redetect_fields" 66 | }); 67 | }); 68 | }); 69 | 70 | browser.runtime.sendMessage({ 71 | action: "get_status" 72 | }).then(status_response); 73 | }); 74 | -------------------------------------------------------------------------------- /src/popups/popup_functions.js: -------------------------------------------------------------------------------- 1 | var $ = jQuery.noConflict(true); 2 | 3 | function updateAvailableResponse(available) { 4 | if(available) { 5 | $("#update-available").show(); 6 | } 7 | else { 8 | $("#update-available").hide(); 9 | } 10 | } 11 | 12 | function initSettings() { 13 | $("#settings #btn-options").click(function() { 14 | browser.tabs.create({ 15 | url: "/options/options.html" 16 | }).then(close); 17 | }); 18 | 19 | $("#settings #btn-choose-credential-fields").click(function() { 20 | browser.runtime.getBackgroundPage().then(function(global) { 21 | browser.tabs.sendMessage(global.page.currentTabId, { 22 | action: "choose_credential_fields" 23 | }); 24 | close(); 25 | }); 26 | }); 27 | } 28 | 29 | 30 | $(function() { 31 | initSettings(); 32 | 33 | browser.runtime.sendMessage({ 34 | action: "update_available_keepasshttp" 35 | }).then(updateAvailableResponse); 36 | }); 37 | -------------------------------------------------------------------------------- /src/popups/popup_httpauth.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | KeePass - Popup 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 |
17 | You use an old version of KeePassHttp. 18 |
19 | Please download the latest version from GitHub. 20 |
21 |
22 | 23 |
24 |

25 | Select the login information you would like to get logged in with: 26 |

27 |
    28 |
    29 | 30 | 31 | -------------------------------------------------------------------------------- /src/popups/popup_httpauth.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | browser.runtime.getBackgroundPage().then(function (global) { 3 | browser.tabs.query({ "active": true, "currentWindow": true }).then(function (tabs) { 4 | //var data = global.tab_httpauth_list["tab" + tab.id]; 5 | var tab = tabs[0]; 6 | var data = global.page.tabs[tab.id].loginList; 7 | var ul = document.getElementById("login-list"); 8 | for (var i = 0; i < data.logins.length; i++) { 9 | var li = document.createElement("li"); 10 | var a = document.createElement("a"); 11 | a.textContent = data.logins[i].Login + " (" + data.logins[i].Name + ")"; 12 | li.appendChild(a); 13 | $(a).data('creds', data.logins[i]); 14 | $(a).click(function () { 15 | if (data.resolve) { 16 | var creds = $(this).data('creds'); 17 | data.resolve({ 18 | authCredentials: { 19 | username: creds.Login, 20 | password: creds.Password 21 | } 22 | }); 23 | } 24 | close(); 25 | }); 26 | ul.appendChild(li); 27 | } 28 | }); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /src/popups/popup_login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | KeePass - Popup 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
    13 | 14 | 15 | 16 |
    17 | You use an old version of KeePassHttp. 18 |
    19 | Please download the latest version from GitHub. 20 |
    21 |
    22 | 23 |
    24 |

    25 | Select the login information you would like to get entered into the page: 26 |

    27 |
      28 |
      29 | 30 | 31 | -------------------------------------------------------------------------------- /src/popups/popup_login.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | browser.runtime.getBackgroundPage().then(function(global) { 3 | browser.tabs.query({"active": true, "currentWindow": true}).then(function(tabs) { 4 | if (tabs.length === 0) 5 | return; // For example: only the background devtools or a popup are opened 6 | var tab = tabs[0]; 7 | 8 | var logins = global.page.tabs[tab.id].loginList; 9 | var ul = document.getElementById("login-list"); 10 | for (var i = 0; i < logins.length; i++) { 11 | var li = document.createElement("li"); 12 | var a = document.createElement("a"); 13 | a.textContent = logins[i]; 14 | li.appendChild(a); 15 | a.setAttribute("id", "" + i); 16 | a.addEventListener('click', function(e) { 17 | var id = e.target.id; 18 | browser.tabs.sendMessage(tab.id, { 19 | action: 'fill_user_pass_with_specific_login', 20 | id: id 21 | }); 22 | close(); 23 | }); 24 | ul.appendChild(li); 25 | } 26 | }); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /src/popups/popup_multiple-fields.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | KeePass - Popup 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
      12 | 13 | 14 | 15 |
      16 | You use an old version of KeePassHttp. 17 |
      18 | Please download the latest version from GitHub. 19 |
      20 |
      21 | 22 |
      23 |

      24 | KeePassHttp-Connector found more than one password field on this page. To enter your 25 | logins, right-click on one of the password fields, and choose either the 26 | "Fill User + Pass" or "Fill Pass Only" command. 27 |

      28 |
      29 | 30 | 31 | -------------------------------------------------------------------------------- /src/popups/popup_remember.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | KeePass - Popup 4 | 5 | 6 | 7 | 8 | 9 | 10 | 18 | 19 | 20 |
      21 |

      22 | Username or password changed! Save it? 23 |
      24 | Url: 25 |
      26 | Username: 27 |

      28 |

      29 | 30 | 31 | 32 |

      33 |
      34 | 35 |
      36 |

      Credentials will be saved in connected database with identifier .

      37 |
      38 | 39 |
      40 |

      The used username is currently not saved!

      41 |

      The credentials with the used username are marked bold.

      42 |

      43 | Please choose the credentials you want to update: 44 |

      45 |
        46 |
        47 | 48 | 49 | -------------------------------------------------------------------------------- /src/popups/popup_remember.js: -------------------------------------------------------------------------------- 1 | var _tab; 2 | 3 | function _initialize(tab) { 4 | _tab = tab; 5 | 6 | // no credentials set or credentials already cleared 7 | if(!_tab.credentials.username) { 8 | _close(); 9 | return; 10 | } 11 | 12 | // no existing credentials to update --> disable update-button 13 | if(_tab.credentials.list.length == 0) { 14 | $("#btn-update").attr("disabled", true).removeClass("b2c-btn-warning"); 15 | } 16 | 17 | var url = _tab.credentials.url; 18 | url = (url.length > 50) ? url.substring(0, 50) + "..." : url; 19 | $(".information-url:first span:first").text(url); 20 | $(".information-username:first span:first").text(_tab.credentials.username); 21 | 22 | $("#btn-new").click(function(e) { 23 | browser.runtime.sendMessage({ 24 | action: 'add_credentials', 25 | args: [_tab.credentials.username, _tab.credentials.password, _tab.credentials.url] 26 | }).then(_verifyResult); 27 | }); 28 | 29 | $("#btn-update").click(function(e) { 30 | e.preventDefault(); 31 | 32 | // only one entry which could be updated 33 | if(_tab.credentials.list.length == 1) { 34 | browser.runtime.sendMessage({ 35 | action: 'update_credentials', 36 | args: [_tab.credentials.list[0].Uuid, _tab.credentials.username, _tab.credentials.password, _tab.credentials.url] 37 | }).then(_verifyResult); 38 | } 39 | else { 40 | $(".credentials:first .username-new:first strong:first").text(_tab.credentials.username); 41 | $(".credentials:first .username-exists:first strong:first").text(_tab.credentials.username); 42 | 43 | if(_tab.credentials.usernameExists) { 44 | $(".credentials:first .username-new:first").hide(); 45 | $(".credentials:first .username-exists:first").show(); 46 | } 47 | else { 48 | $(".credentials:first .username-new:first").show(); 49 | $(".credentials:first .username-exists:first").hide(); 50 | } 51 | 52 | for(var i = 0; i < _tab.credentials.list.length; i++) { 53 | var $a = $("") 54 | .attr("href", "#") 55 | .text(_tab.credentials.list[i].Login + " (" + _tab.credentials.list[i].Name + ")") 56 | .data("entryId", i) 57 | .click(function(e) { 58 | e.preventDefault(); 59 | browser.runtime.sendMessage({ 60 | action: 'update_credentials', 61 | args: [_tab.credentials.list[$(this).data("entryId")].Uuid, _tab.credentials.username, _tab.credentials.password, _tab.credentials.url] 62 | }).then(_verifyResult); 63 | }); 64 | 65 | if(_tab.credentials.usernameExists && _tab.credentials.username == _tab.credentials.list[i].Login) { 66 | $a.css("font-weight", "bold"); 67 | } 68 | 69 | var $li = $("
      • ").append($a); 70 | $("ul#list").append($li); 71 | } 72 | 73 | $(".credentials").show(); 74 | } 75 | }); 76 | 77 | $("#btn-dismiss").click(function(e) { 78 | e.preventDefault(); 79 | _close(); 80 | }); 81 | } 82 | 83 | function _connected_database(db) { 84 | if(db.count > 1 && db.identifier) { 85 | $(".connected-database:first em:first").text(db.identifier); 86 | $(".connected-database:first").show(); 87 | } 88 | else { 89 | $(".connected-database:first").hide(); 90 | } 91 | } 92 | 93 | function _verifyResult(code) { 94 | if(code == "success") { 95 | _close(); 96 | } 97 | } 98 | 99 | function _close() { 100 | browser.runtime.sendMessage({ 101 | action: 'remove_credentials_from_tab_information' 102 | }); 103 | 104 | browser.runtime.sendMessage({ 105 | action: 'pop_stack' 106 | }); 107 | 108 | close(); 109 | } 110 | 111 | $(function() { 112 | browser.runtime.sendMessage({ 113 | action: 'stack_add', 114 | args: ["icon_remember_red_background_19x19.png", "popup_remember.html", 10, true, 0] 115 | }); 116 | 117 | browser.runtime.sendMessage({ 118 | action: 'get_tab_information' 119 | }).then(_initialize); 120 | 121 | browser.runtime.sendMessage({ 122 | action: 'get_connected_database' 123 | }).then(_connected_database); 124 | }); 125 | -------------------------------------------------------------------------------- /src/popups/throbber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorks/keepasshttp-connector/6732907aa4df87c1831339a18fe2342e27952175/src/popups/throbber.gif --------------------------------------------------------------------------------