mirror of https://github.com/keeweb/keeweb
browser extension settings page
parent
4ed8a67eda
commit
3fd799ee74
|
@ -20,7 +20,16 @@ const Links = {
|
|||
YubiKeyManual: 'https://github.com/keeweb/keeweb/wiki/YubiKey',
|
||||
YubiKeyManagerInstall: 'https://github.com/Yubico/yubikey-manager#installation',
|
||||
HaveIBeenPwned: 'https://haveibeenpwned.com',
|
||||
HaveIBeenPwnedPrivacy: 'https://haveibeenpwned.com/Passwords'
|
||||
HaveIBeenPwnedPrivacy: 'https://haveibeenpwned.com/Passwords',
|
||||
KeeWebConnectForChrome: 'https://TODO',
|
||||
KeeWebConnectForFirefox: 'https://TODO',
|
||||
KeeWebConnectForEdge: 'https://TODO',
|
||||
KeeWebConnectForSafari: 'https://TODO',
|
||||
KeePassXcBrowserForChrome:
|
||||
'https://chrome.google.com/webstore/detail/keepassxc-browser/oboonakemofpalcgghocfoadofidjkkk',
|
||||
KeePassXcBrowserForFirefox: 'https://addons.mozilla.org/firefox/addon/keepassxc-browser/',
|
||||
KeePassXcBrowserForEdge:
|
||||
'https://microsoftedge.microsoft.com/addons/detail/keepassxcbrowser/pdffhmdngciaglkoonimfcmckehcpafo'
|
||||
};
|
||||
|
||||
export { Links };
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
"oneWeek": "one week",
|
||||
"oneMonth": "one month",
|
||||
"oneYear": "one year",
|
||||
"for": "for",
|
||||
|
||||
"cache": "cache",
|
||||
"file": "file",
|
||||
|
@ -49,6 +50,7 @@
|
|||
"menuColors": "Colors",
|
||||
"menuTrash": "Trash",
|
||||
"menuSetGeneral": "General",
|
||||
"menuSetBrowser": "Browser",
|
||||
"menuSetAbout": "About",
|
||||
"menuSetDevices": "Devices",
|
||||
"menuAlertNoTags": "No tags",
|
||||
|
@ -494,7 +496,7 @@
|
|||
"setGenAuditPasswordEntropy": "Check password length and randomness",
|
||||
"setGenExcludePinsFromAudit": "Never check short numeric PIN codes, such as 123456",
|
||||
"setGenCheckPasswordsOnHIBP": "Check passwords using an online service {}",
|
||||
"setGenHelpHIBP": "KeeWeb can check if your passwords have been previously exposed in a data breach using an online service. Your password cannot be recovered based on data sent online, however the number of passwords checked this way may be exposed. More about your privacy when using this service can be found {}. If this option is enabled, KeeWeb will automatically check your passwords there.",
|
||||
"setGenHelpHIBP": "KeeWeb can check if your passwords have been previously exposed in a data breach using an online service. Your password cannot be recovered based on data sent online, however, the number of passwords checked this way may be exposed. More about your privacy when using this service can be found {}. If this option is enabled, KeeWeb will automatically check your passwords there.",
|
||||
"setGenHelpHIBPLink": "here",
|
||||
"setGenAuditPasswordAge": "Old passwords",
|
||||
"setGenAuditPasswordAgeOff": "Don't show warnings about old passwords",
|
||||
|
@ -638,6 +640,14 @@
|
|||
"setPlAutoUpdate": "Update automatically",
|
||||
"setPlLoadGallery": "Load plugin gallery",
|
||||
|
||||
"setBrowserTitle": "Browser",
|
||||
"setBrowserIntroDesktop": "KeeWeb can enter passwords using auto-type, however, a browser extension may be more convenient. There are two browser extensions available for KeeWeb:",
|
||||
"setBrowserIntroKeeWebConnect": "the official KeeWeb extension, it's built with features of KeeWeb kept in mind, but if you used other extensions before, you may miss some advanced features.",
|
||||
"setBrowserIntroKeePassXcBrowser": "this extension was developed for KeePassXC, it's been on the market for a while and it is quite solid.",
|
||||
"setBrowserIntroWeb": "Install our browser extension to auto-fill passwords from KeeWeb on different pages. The browser extension will connect to a KeeWeb tab in your browser to fetch passwords. Click here to download the extension:",
|
||||
"setBrowserNotEnabled": "Browser integration is not enabled, extensions won't be able to connect to KeeWeb. Use the checkboxes below to enable it:",
|
||||
"setBrowserEnablePerBrowser": "Enable browser integration using the checkboxes below:",
|
||||
|
||||
"setDevicesTitle": "Devices",
|
||||
"setDevicesEnableUsb": "Enable interaction with USB devices",
|
||||
"setDevicesYubiKeyIntro": "It's recommended to read {} before using a YubiKey.",
|
||||
|
|
|
@ -8,6 +8,7 @@ import { MenuSectionModel } from 'models/menu/menu-section-model';
|
|||
import { StringFormat } from 'util/formatting/string-format';
|
||||
import { Locale } from 'util/locale';
|
||||
import { Launcher } from 'comp/launcher';
|
||||
import { Features } from 'util/features';
|
||||
|
||||
class MenuModel extends Model {
|
||||
constructor() {
|
||||
|
@ -113,6 +114,11 @@ class MenuModel extends Model {
|
|||
this.shortcutsSection = new MenuSectionModel([
|
||||
{ locTitle: 'shortcuts', icon: 'keyboard', page: 'shortcuts' }
|
||||
]);
|
||||
if (Features.supportsBrowserExtensions) {
|
||||
this.browserSection = new MenuSectionModel([
|
||||
{ locTitle: 'menuSetBrowser', icon: Features.browserIcon, page: 'browser' }
|
||||
]);
|
||||
}
|
||||
this.pluginsSection = new MenuSectionModel([
|
||||
{ locTitle: 'plugins', icon: 'puzzle-piece', page: 'plugins' }
|
||||
]);
|
||||
|
@ -133,6 +139,7 @@ class MenuModel extends Model {
|
|||
[
|
||||
this.generalSection,
|
||||
this.shortcutsSection,
|
||||
this.browserSection,
|
||||
this.pluginsSection,
|
||||
this.devicesSection,
|
||||
this.aboutSection,
|
||||
|
|
|
@ -17,19 +17,19 @@ const Features = {
|
|||
!/^http(s?):\/\/((localhost:8085)|((app|beta)\.keeweb\.info))/.test(location.href),
|
||||
isLocal: location.origin.indexOf('localhost') >= 0,
|
||||
|
||||
supportsTitleBarStyles() {
|
||||
get supportsTitleBarStyles() {
|
||||
return isDesktop && (this.isMac || this.isWindows);
|
||||
},
|
||||
supportsCustomTitleBarAndDraggableWindow() {
|
||||
get supportsCustomTitleBarAndDraggableWindow() {
|
||||
return isDesktop && this.isMac;
|
||||
},
|
||||
renderCustomTitleBar() {
|
||||
get renderCustomTitleBar() {
|
||||
return isDesktop && this.isWindows;
|
||||
},
|
||||
hasUnicodeFlags() {
|
||||
get hasUnicodeFlags() {
|
||||
return this.isMac;
|
||||
},
|
||||
getBrowserCssClass() {
|
||||
get browserCssClass() {
|
||||
if (window.chrome && window.navigator.userAgent.indexOf('Chrome/') > -1) {
|
||||
return 'chrome';
|
||||
}
|
||||
|
@ -40,6 +40,45 @@ const Features = {
|
|||
return 'standalone';
|
||||
}
|
||||
return '';
|
||||
},
|
||||
get browserIcon() {
|
||||
if (this._browserIcon) {
|
||||
return this._browserIcon;
|
||||
}
|
||||
|
||||
if (this.isDesktop) {
|
||||
this._browserIcon = this.isMac ? 'safari' : this.isWindows ? 'edge' : 'chrome';
|
||||
} else if (/Gecko\//.test(navigator.userAgent)) {
|
||||
this._browserIcon = 'firefox-browser';
|
||||
} else if (/Edg\//.test(navigator.userAgent)) {
|
||||
this._browserIcon = 'edge';
|
||||
} else if (/Chrome\//.test(navigator.userAgent)) {
|
||||
this._browserIcon = 'chrome';
|
||||
} else if (this.isMac && /Safari\//.test(navigator.userAgent)) {
|
||||
this._browserIcon = 'safari';
|
||||
} else {
|
||||
this._browserIcon = 'window-maximize';
|
||||
}
|
||||
|
||||
return this._browserIcon;
|
||||
},
|
||||
get supportsBrowserExtensions() {
|
||||
return this.isDesktop || this.browserIcon !== 'safari';
|
||||
},
|
||||
get extensionBrowserFamily() {
|
||||
if (Features.isDesktop) {
|
||||
return undefined;
|
||||
} else if (/Gecko\//.test(navigator.userAgent)) {
|
||||
return 'Firefox';
|
||||
} else if (/Edg\//.test(navigator.userAgent)) {
|
||||
return 'Edge';
|
||||
} else if (/Chrome\//.test(navigator.userAgent)) {
|
||||
return 'Chrome';
|
||||
} else if (this.isMac && /Safari\//.test(navigator.userAgent)) {
|
||||
return 'Safari';
|
||||
} else {
|
||||
return 'Chrome';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ class AppView extends View {
|
|||
this.views.list.dragView = this.views.listDrag;
|
||||
this.views.details = new DetailsView(undefined, { ownParent: true });
|
||||
this.views.details.appModel = this.model;
|
||||
if (this.titlebarStyle !== 'default' && Features.renderCustomTitleBar()) {
|
||||
if (this.titlebarStyle !== 'default' && Features.renderCustomTitleBar) {
|
||||
this.views.titlebar = new TitlebarView(this.model);
|
||||
}
|
||||
|
||||
|
@ -119,13 +119,13 @@ class AppView extends View {
|
|||
}
|
||||
|
||||
setWindowClass() {
|
||||
const getBrowserCssClass = Features.getBrowserCssClass();
|
||||
if (getBrowserCssClass) {
|
||||
document.body.classList.add(getBrowserCssClass);
|
||||
const browserCssClass = Features.browserCssClass;
|
||||
if (browserCssClass) {
|
||||
document.body.classList.add(browserCssClass);
|
||||
}
|
||||
if (this.titlebarStyle !== 'default') {
|
||||
document.body.classList.add('titlebar-' + this.titlebarStyle);
|
||||
if (Features.renderCustomTitleBar()) {
|
||||
if (Features.renderCustomTitleBar) {
|
||||
document.body.classList.add('titlebar-custom');
|
||||
}
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ class AppView extends View {
|
|||
super.render({
|
||||
beta: this.model.isBeta,
|
||||
titlebarStyle: this.titlebarStyle,
|
||||
customTitlebar: Features.renderCustomTitleBar()
|
||||
customTitlebar: Features.renderCustomTitleBar
|
||||
});
|
||||
this.panelEl = this.$el.find('.app__panel:first');
|
||||
this.views.listWrap.render();
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
import { View } from 'framework/views/view';
|
||||
import template from 'templates/settings/settings-browser.hbs';
|
||||
import { Features } from 'util/features';
|
||||
import { Links } from 'const/links';
|
||||
import { AppSettingsModel } from 'models/app-settings-model';
|
||||
|
||||
class SettingsBrowserView extends View {
|
||||
template = template;
|
||||
|
||||
events = {
|
||||
'change .check-enable-for-browser': 'changeEnableForBrowser'
|
||||
};
|
||||
|
||||
render() {
|
||||
const data = {
|
||||
desktop: Features.isDesktop,
|
||||
icon: Features.browserIcon
|
||||
};
|
||||
if (Features.isDesktop) {
|
||||
data.settingsPerBrowser = this.getSettingsPerBrowser();
|
||||
data.anyBrowserIsEnabled = data.settingsPerBrowser.some((s) => s.kwc || s.kpxc);
|
||||
} else {
|
||||
const extensionBrowserFamily = Features.extensionBrowserFamily;
|
||||
data.extensionBrowserFamily = Features.extensionBrowserFamily;
|
||||
data.extensionDownloadLink = Links[`KeeWebConnectFor${extensionBrowserFamily}`];
|
||||
}
|
||||
super.render(data);
|
||||
}
|
||||
|
||||
getSettingsPerBrowser() {
|
||||
const browsers = ['Chrome', 'Firefox', 'Edge'];
|
||||
if (Features.isMac) {
|
||||
browsers.unshift('Safari');
|
||||
}
|
||||
return browsers.map((browser) => {
|
||||
return {
|
||||
browser,
|
||||
kwc: !!AppSettingsModel[`kwcEnabledFor${browser}`],
|
||||
kpxc: !!AppSettingsModel[`kpxcEnabledFor${browser}`]
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
changeEnableForBrowser(e) {
|
||||
const enabled = e.target.checked;
|
||||
const browser = e.target.dataset.browser;
|
||||
const extension = e.target.dataset.extension;
|
||||
|
||||
const setting = `${extension}EnabledFor${browser}`;
|
||||
if (setting) {
|
||||
AppSettingsModel[setting] = enabled;
|
||||
} else {
|
||||
delete AppSettingsModel[setting];
|
||||
}
|
||||
|
||||
this.render();
|
||||
}
|
||||
}
|
||||
|
||||
export { SettingsBrowserView };
|
|
@ -136,8 +136,9 @@ class SettingsGeneralView extends View {
|
|||
useGroupIconForEntries: AppSettingsModel.useGroupIconForEntries,
|
||||
directAutotype: AppSettingsModel.directAutotype,
|
||||
fieldLabelDblClickAutoType: AppSettingsModel.fieldLabelDblClickAutoType,
|
||||
supportsTitleBarStyles: Features.supportsTitleBarStyles(),
|
||||
supportsCustomTitleBarAndDraggableWindow: Features.supportsCustomTitleBarAndDraggableWindow(),
|
||||
supportsTitleBarStyles: Features.supportsTitleBarStyles,
|
||||
supportsCustomTitleBarAndDraggableWindow:
|
||||
Features.supportsCustomTitleBarAndDraggableWindow,
|
||||
titlebarStyle: AppSettingsModel.titlebarStyle,
|
||||
storageProviders,
|
||||
showReloadApp: Features.isStandalone,
|
||||
|
|
|
@ -72,7 +72,7 @@ class SettingsPluginsView extends View {
|
|||
galleryLoadError: PluginGallery.loadError,
|
||||
galleryPlugins: this.getGalleryPlugins(),
|
||||
searchStr: this.searchStr,
|
||||
hasUnicodeFlags: Features.hasUnicodeFlags(),
|
||||
hasUnicodeFlags: Features.hasUnicodeFlags,
|
||||
pluginDevLink: Links.PluginDevelopStart,
|
||||
translateLink: Links.Translation
|
||||
});
|
||||
|
|
|
@ -307,6 +307,14 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
&__browser {
|
||||
&-table {
|
||||
th,
|
||||
td {
|
||||
padding: $base-padding;
|
||||
}
|
||||
}
|
||||
}
|
||||
&__donate-btn {
|
||||
background: #fff;
|
||||
border: 2px solid #89abed;
|
||||
|
|
|
@ -200,3 +200,5 @@ $fa-var-titlebar-close: next-fa-glyph();
|
|||
$fa-var-titlebar-maximize: next-fa-glyph();
|
||||
$fa-var-titlebar-minimize: next-fa-glyph();
|
||||
$fa-var-titlebar-restore: next-fa-glyph();
|
||||
$fa-var-window-maximize: next-fa-glyph();
|
||||
$fa-var-download: next-fa-glyph();
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
<div class="settings__content">
|
||||
<h1><i class="fa fa-{{icon}} settings__head-icon"></i> {{res 'setBrowserTitle'}}</h1>
|
||||
{{#if desktop}}
|
||||
<p>{{res 'setBrowserIntroDesktop'}}</p>
|
||||
<p>KeeWeb Connect: {{res 'setBrowserIntroKeeWebConnect'}}</p>
|
||||
<p>KeePassXC-Browser: {{res 'setBrowserIntroKeePassXcBrowser'}}</p>
|
||||
{{#if anyBrowserIsEnabled}}
|
||||
<p>{{res 'setBrowserEnablePerBrowser'}}</p>
|
||||
{{else}}
|
||||
<p class="error-color">{{res 'setBrowserNotEnabled'}}</p>
|
||||
{{/if}}
|
||||
<table class="settings__browser-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>KeeWeb Connect</th>
|
||||
<th>KeePassXC-Browser</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each settingsPerBrowser as |perBrowser|}}
|
||||
<tr>
|
||||
<td>{{perBrowser.browser}}</td>
|
||||
<td>
|
||||
<input type="checkbox"
|
||||
class="check-enable-for-browser"
|
||||
{{#if perBrowser.kwc}}checked{{/if}}
|
||||
id="check-enable-kwc-for-{{perBrowser.browser}}"
|
||||
data-browser="{{perBrowser.browser}}"
|
||||
data-extension="kwc" />
|
||||
<label for="check-enable-kwc-for-{{perBrowser.browser}}"></label>
|
||||
{{#if perBrowser.kwc}}
|
||||
<i class="fa fa-download"></i>
|
||||
{{/if}}
|
||||
</td>
|
||||
{{#ifeq perBrowser.browser 'Safari'}}
|
||||
<td class="muted-color">
|
||||
<i class="fa fa-times"></i>
|
||||
</td>
|
||||
{{else}}
|
||||
<td>
|
||||
<input type="checkbox"
|
||||
class="check-enable-for-browser"
|
||||
{{#if perBrowser.kpxc}}checked{{/if}}
|
||||
id="check-enable-kpxc-for-{{perBrowser.browser}}"
|
||||
data-browser="{{perBrowser.browser}}"
|
||||
data-extension="kpxc" />
|
||||
<label for="check-enable-kpxc-for-{{perBrowser.browser}}"></label>
|
||||
{{#if perBrowser.kpxc}}
|
||||
<i class="fa fa-download"></i>
|
||||
{{/if}}
|
||||
</td>
|
||||
{{/ifeq}}
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
{{else}}
|
||||
<p>{{res 'setBrowserIntroWeb'}}</p>
|
||||
<a href="{{extensionDownloadLink}}" target="_blank" rel="noreferrer">
|
||||
KeeWeb Connect {{res 'for'}} {{extensionBrowserFamily}}
|
||||
</a>
|
||||
{{/if}}
|
||||
</div>
|
Loading…
Reference in New Issue