Merge branch 'develop'
|
@ -1,13 +0,0 @@
|
|||
# Configuration for probot-no-response - https://github.com/probot/no-response
|
||||
|
||||
# Number of days of inactivity before an Issue is closed for lack of response
|
||||
daysUntilClose: 14
|
||||
# Label requiring a response
|
||||
responseRequiredLabel: need info
|
||||
# Comment to post when closing an Issue for lack of response. Set to `false` to disable
|
||||
closeComment: >
|
||||
This issue has been automatically closed because there has been no response
|
||||
to our request for more information from the original author. With only the
|
||||
information that is currently in the issue, we don't have enough information
|
||||
to take action. Please reach out if you have or find the answers we need so
|
||||
that we can investigate further.
|
|
@ -14,3 +14,4 @@ obj/
|
|||
xcuserdata/
|
||||
*.suo
|
||||
.idea/
|
||||
.vscode
|
After Width: | Height: | Size: 1007 KiB |
After Width: | Height: | Size: 947 KiB |
After Width: | Height: | Size: 1020 KiB |
After Width: | Height: | Size: 1.1 MiB |
After Width: | Height: | Size: 1.5 MiB |
After Width: | Height: | Size: 315 KiB |
After Width: | Height: | Size: 405 KiB |
|
@ -7,15 +7,25 @@
|
|||
<meta name="kw-signature" content="">
|
||||
<meta name="kw-config" content="(no-config)">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<!--<link rel="manifest" href="manifest.json">-->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<meta name="apple-mobile-web-app-title" content="KeeWeb">
|
||||
<meta name="theme-color" content="#6386ec">
|
||||
<meta name="msapplication-config" content="browserconfig.xml">
|
||||
<meta name="msapplication-TileColor" content="#6386ec">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="icons/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="icons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="icons/favicon-16x16.png">
|
||||
<link rel="mask-icon" href="icons/safari-pinned-tab.svg" color="#6386ec">
|
||||
<meta name="msapplication-config" content="browserconfig.xml">
|
||||
<meta name="msapplication-TileColor" content="#6386ec">
|
||||
<meta name="theme-color" content="#6386ec">
|
||||
<link rel="apple-touch-startup-image" href="icons/splash-640x1136.png" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="icons/splash-750x1294.png" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="icons/splash-1242x2148.png" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="icons/splash-1125x2436.png" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="icons/splash-1536x2048.png" media="(min-device-width: 768px) and (max-device-width: 1024px) and (-webkit-min-device-pixel-ratio: 2) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="icons/splash-1668x2224.png" media="(min-device-width: 834px) and (max-device-width: 834px) and (-webkit-min-device-pixel-ratio: 2) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="icons/splash-2048x2732.png" media="(min-device-width: 1024px) and (max-device-width: 1024px) and (-webkit-min-device-pixel-ratio: 2) and (orientation: portrait)">
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<link rel="stylesheet" href="css/main.css?__inline=true" />
|
||||
<script src="js/vendor.js?__inline=true"></script>
|
||||
<script src="js/app.js?__inline=true"></script>
|
||||
|
|
|
@ -27,7 +27,7 @@ const Locale = require('./util/locale');
|
|||
const ready = Launcher && Launcher.ready || $;
|
||||
|
||||
ready(() => {
|
||||
if (FeatureDetector.isPopup && AuthReceiver.receive() || FeatureDetector.isFrame) {
|
||||
if (AuthReceiver.receive() || FeatureDetector.isFrame) {
|
||||
return;
|
||||
}
|
||||
loadMixins();
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
const EntryCollection = require('../collections/entry-collection');
|
||||
const Ranking = require('../util/ranking');
|
||||
|
||||
const urlPartsRegex = /^(\w+:\/\/)?(?:(?:www|wwws|secure)\.)?([^\/]+)\/?(.*)/;
|
||||
|
||||
|
@ -39,7 +40,10 @@ AutoTypeFilter.prototype.prepareFilter = function() {
|
|||
AutoTypeFilter.prototype.getEntryRank = function(entry) {
|
||||
let rank = 0;
|
||||
if (this.titleLower && entry.title) {
|
||||
rank += this.getStringRank(entry.title.toLowerCase(), this.titleLower);
|
||||
rank += Ranking.getStringRank(
|
||||
entry.title.toLowerCase(),
|
||||
this.titleLower
|
||||
);
|
||||
}
|
||||
if (this.urlParts && entry.url) {
|
||||
const entryUrlParts = urlPartsRegex.exec(entry.url.toLowerCase());
|
||||
|
@ -78,22 +82,4 @@ AutoTypeFilter.prototype.getEntryRank = function(entry) {
|
|||
return rank;
|
||||
};
|
||||
|
||||
AutoTypeFilter.prototype.getStringRank = function(s1, s2) {
|
||||
let ix = s1.indexOf(s2);
|
||||
if (ix === 0 && s1.length === s2.length) {
|
||||
return 10;
|
||||
} else if (ix === 0) {
|
||||
return 5;
|
||||
} else if (ix > 0) {
|
||||
return 3;
|
||||
}
|
||||
ix = s2.indexOf(s1);
|
||||
if (ix === 0) {
|
||||
return 5;
|
||||
} else if (ix > 0) {
|
||||
return 3;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
module.exports = AutoTypeFilter;
|
||||
|
|
|
@ -199,7 +199,7 @@ const AutoType = {
|
|||
|
||||
processEventWithFilter(evt) {
|
||||
const entries = evt.filter.getEntries();
|
||||
if (entries.length === 1) {
|
||||
if (entries.length === 1 && AppSettingsModel.instance.get('directAutotype')) {
|
||||
this.hideWindow(() => {
|
||||
this.runAndHandleResult({ entry: entries.at(0) });
|
||||
});
|
||||
|
@ -221,6 +221,14 @@ const AutoType = {
|
|||
}
|
||||
});
|
||||
});
|
||||
this.selectEntryView.on('show-open-files', () => {
|
||||
this.selectEntryView.hide();
|
||||
Backbone.trigger('open-file');
|
||||
Backbone.once('closed-open-view', () => {
|
||||
this.selectEntryView.show();
|
||||
this.selectEntryView.setupKeys();
|
||||
}, this);
|
||||
});
|
||||
},
|
||||
|
||||
resetPendingEvent() {
|
||||
|
|
|
@ -19,17 +19,21 @@ const EntryCollection = Backbone.Collection.extend({
|
|||
'-created': Comparators.dateComparator('created', false),
|
||||
'updated': Comparators.dateComparator('updated', true),
|
||||
'-updated': Comparators.dateComparator('updated', false),
|
||||
'-attachments': function(x, y) { return this.attachmentSortVal(x).localeCompare(this.attachmentSortVal(y)); }
|
||||
'-attachments': function(x, y) { return this.attachmentSortVal(x).localeCompare(this.attachmentSortVal(y)); },
|
||||
'-rank': Comparators.rankComparator()
|
||||
},
|
||||
|
||||
defaultComparator: 'title',
|
||||
|
||||
filter: null,
|
||||
|
||||
initialize: function(models, options) {
|
||||
const comparatorName = options && options.comparator || this.defaultComparator;
|
||||
this.comparator = this.comparators[comparatorName];
|
||||
},
|
||||
|
||||
sortEntries: function(comparator) {
|
||||
sortEntries: function(comparator, filter) {
|
||||
this.filter = filter;
|
||||
this.comparator = this.comparators[comparator] || this.comparators[this.defaultComparator];
|
||||
this.sort();
|
||||
},
|
||||
|
|
|
@ -3,6 +3,9 @@ const Storage = require('../storage');
|
|||
|
||||
const AuthReceiver = {
|
||||
receive: function() {
|
||||
if (!FeatureDetector.isPopup && !FeatureDetector.isStandalone) {
|
||||
return false;
|
||||
}
|
||||
const opener = window.opener || window.parent;
|
||||
const message = this.urlArgsToMessage(window.location.href);
|
||||
const hasKeys = Object.keys(message).filter(key => key !== 'config').length > 0;
|
||||
|
@ -10,7 +13,9 @@ const AuthReceiver = {
|
|||
return false;
|
||||
}
|
||||
if (FeatureDetector.isStandalone) {
|
||||
Storage[sessionStorage.authStorage].handleOAuthReturnMessage(message);
|
||||
if (sessionStorage.authStorage) {
|
||||
Storage[sessionStorage.authStorage].handleOAuthReturnMessage(message);
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
opener.postMessage(message, window.location.origin);
|
||||
|
|
|
@ -3,10 +3,10 @@ const Launcher = require('./launcher');
|
|||
const AppSettingsModel = require('../models/app-settings-model');
|
||||
|
||||
const CopyPaste = {
|
||||
simpleCopy: !!Launcher,
|
||||
simpleCopy: !!(Launcher && Launcher.clipboardSupported),
|
||||
|
||||
copy: function(text) {
|
||||
if (Launcher) {
|
||||
if (this.simpleCopy) {
|
||||
Launcher.setClipboardText(text);
|
||||
const clipboardSeconds = AppSettingsModel.instance.get('clipboardSeconds');
|
||||
if (clipboardSeconds > 0) {
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
/* global FingerprintAuth */
|
||||
|
||||
const Backbone = require('backbone');
|
||||
|
||||
const Launcher = {
|
||||
name: 'cordova',
|
||||
version: '6.0.0',
|
||||
autoTypeSupported: false,
|
||||
thirdPartyStoragesSupported: false,
|
||||
clipboardSupported: false,
|
||||
ready: function(callback) {
|
||||
document.addEventListener('deviceready', callback, false);
|
||||
document.addEventListener('pause', () => {
|
||||
Backbone.trigger('app-minimized');
|
||||
}, false);
|
||||
},
|
||||
platform: function() {
|
||||
return 'cordova';
|
||||
|
@ -40,6 +46,12 @@ const Launcher = {
|
|||
return [...parts].join('/');
|
||||
},
|
||||
writeFile: function(path, data, callback) {
|
||||
const createFile = filePath => {
|
||||
window.resolveLocalFileSystemURL(filePath.dir, dir => {
|
||||
dir.getFile(filePath.file, {create: true}, writeFile);
|
||||
}, callback, callback);
|
||||
};
|
||||
|
||||
const writeFile = fileEntry => {
|
||||
fileEntry.createWriter(fileWriter => {
|
||||
fileWriter.onerror = callback;
|
||||
|
@ -48,7 +60,14 @@ const Launcher = {
|
|||
}, callback);
|
||||
};
|
||||
|
||||
window.resolveLocalFileSystemURL(path, writeFile, callback, callback);
|
||||
if (path.startsWith('cdvfile://')) { // then file exists
|
||||
window.resolveLocalFileSystemURL(path, writeFile, callback, callback);
|
||||
} else { // create file on sd card
|
||||
const filePath = this.parsePath(path);
|
||||
this.mkdir(filePath.dir, () => {
|
||||
createFile(filePath);
|
||||
});
|
||||
}
|
||||
},
|
||||
readFile: function(path, encoding, callback) {
|
||||
window.resolveLocalFileSystemURL(path, fileEntry => {
|
||||
|
@ -109,14 +128,15 @@ const Launcher = {
|
|||
|
||||
return {
|
||||
path: fileName,
|
||||
dir: parts.pop(),
|
||||
file: parts.join('/')
|
||||
file: parts.pop(),
|
||||
dir: parts.join('/')
|
||||
};
|
||||
},
|
||||
createFsWatcher: function(path) {
|
||||
return null; // not in android with content provider
|
||||
},
|
||||
// ensureRunnable: function(path) { },
|
||||
|
||||
preventExit: function(e) {
|
||||
e.returnValue = false;
|
||||
return false;
|
||||
|
@ -124,29 +144,30 @@ const Launcher = {
|
|||
exit: function() {
|
||||
this.hideApp();
|
||||
},
|
||||
|
||||
requestExit: function() { /* skip in cordova */ },
|
||||
requestRestart: function() {
|
||||
window.location.reload();
|
||||
},
|
||||
cancelRestart: function() { /* skip in cordova */ },
|
||||
setClipboardText: function(text) {
|
||||
// TODO
|
||||
},
|
||||
getClipboardText: function() {
|
||||
// TODO
|
||||
},
|
||||
clearClipboardText: function() {
|
||||
// TODO
|
||||
},
|
||||
|
||||
setClipboardText: function(text) {},
|
||||
getClipboardText: function() {},
|
||||
clearClipboardText: function() {},
|
||||
|
||||
minimizeApp: function() {
|
||||
this.hideApp();
|
||||
},
|
||||
canMinimize: function() {
|
||||
return false;
|
||||
},
|
||||
canDetectOsSleep: function() {
|
||||
return false;
|
||||
},
|
||||
updaterEnabled: function() {
|
||||
return false;
|
||||
},
|
||||
|
||||
// getMainWindow: function() { },
|
||||
resolveProxy: function(url, callback) { /* skip in cordova */ },
|
||||
openWindow: function(opts) { /* skip in cordova */ },
|
||||
|
@ -169,6 +190,12 @@ const Launcher = {
|
|||
|
||||
window.cordova.exec(onFileSelected, callback, 'FileChooser', 'choose');
|
||||
},
|
||||
getCookies(callback) {
|
||||
// TODO
|
||||
},
|
||||
setCookies(cookies) {
|
||||
// TODO
|
||||
},
|
||||
|
||||
fingerprints: {
|
||||
config: {
|
||||
|
@ -184,7 +211,7 @@ const Launcher = {
|
|||
|
||||
const encryptConfig = _.extend({}, this.config, {
|
||||
username: fileId,
|
||||
password: password
|
||||
password: password.getText()
|
||||
});
|
||||
|
||||
FingerprintAuth.encrypt(encryptConfig, result => {
|
||||
|
|
|
@ -9,6 +9,7 @@ const Launcher = {
|
|||
version: window.process.versions.electron,
|
||||
autoTypeSupported: true,
|
||||
thirdPartyStoragesSupported: true,
|
||||
clipboardSupported: true,
|
||||
req: window.require,
|
||||
platform: function() {
|
||||
return process.platform;
|
||||
|
@ -27,7 +28,7 @@ const Launcher = {
|
|||
},
|
||||
devTools: true,
|
||||
openDevTools: function() {
|
||||
this.electron().remote.getCurrentWindow().openDevTools();
|
||||
this.electron().remote.getCurrentWindow().openDevTools({ mode: 'bottom' });
|
||||
},
|
||||
getSaveFileName: function(defaultPath, callback) {
|
||||
if (defaultPath) {
|
||||
|
@ -211,6 +212,7 @@ const Launcher = {
|
|||
showMainWindow: function() {
|
||||
const win = this.getMainWindow();
|
||||
win.show();
|
||||
win.focus();
|
||||
win.restore();
|
||||
},
|
||||
spawn: function(config) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
const Backbone = require('backbone');
|
||||
const Locale = require('./../util/locale');
|
||||
const FeatureDetector = require('../util/feature-detector');
|
||||
|
||||
const SettingsManager = {
|
||||
neutralLocale: null,
|
||||
|
@ -28,9 +29,7 @@ const SettingsManager = {
|
|||
if (settings.get('theme')) {
|
||||
this.setTheme(settings.get('theme'));
|
||||
}
|
||||
if (settings.get('fontSize')) {
|
||||
this.setFontSize(settings.get('fontSize'));
|
||||
}
|
||||
this.setFontSize(settings.get('fontSize'));
|
||||
const locale = settings.get('locale');
|
||||
try {
|
||||
if (locale) {
|
||||
|
@ -59,7 +58,8 @@ const SettingsManager = {
|
|||
},
|
||||
|
||||
setFontSize: function(fontSize) {
|
||||
document.documentElement.style.fontSize = fontSize ? (12 + fontSize * 2) + 'px' : '';
|
||||
const defaultFontSize = FeatureDetector.isMobile ? 14 : 12;
|
||||
document.documentElement.style.fontSize = (defaultFontSize + (fontSize || 0) * 2) + 'px';
|
||||
},
|
||||
|
||||
setLocale(loc) {
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
"help": "Help",
|
||||
"settings": "Settings",
|
||||
"plugins": "Plugins",
|
||||
"rank": "rank",
|
||||
|
||||
"cache": "cache",
|
||||
"file": "file",
|
||||
|
@ -146,6 +147,7 @@
|
|||
"searchOptions": "Options",
|
||||
"searchCase": "Match case",
|
||||
"searchRegex": "RegEx",
|
||||
"searchRank": "Rank",
|
||||
|
||||
"openOpen": "Open",
|
||||
"openNew": "New",
|
||||
|
@ -355,6 +357,7 @@
|
|||
"setGenShowSubgroups": "Show entries from all subgroups",
|
||||
"setGenTableView": "Entries list table view",
|
||||
"setGenColorfulIcons": "Colorful custom icons in list",
|
||||
"setGenDirectAutotype": "If only one matching entry is found, select that one automatically for Autotype",
|
||||
"setGenFunction": "Function",
|
||||
"setGenAutoSyncOnClose": "Automatically save and sync on close",
|
||||
"setGenAutoSyncTimer": "Automatically save and sync periodically",
|
||||
|
@ -387,6 +390,7 @@
|
|||
"setGenTryBetaWarning": "Unsaved files",
|
||||
"setGenTryBetaWarningBody": "Please save all files and click this button again",
|
||||
"setGenShowAppLogs": "Show app logs",
|
||||
"setGenReloadApp": "Reload the app",
|
||||
|
||||
"setFilePath": "File path",
|
||||
"setFileStorage": "This file is loaded from {}.",
|
||||
|
|
|
@ -562,6 +562,6 @@
|
|||
"webdavSavePut": "Ecraser le fichier kdbx avec PUT",
|
||||
"launcherSave": "Sauvegarder base des mots de passe",
|
||||
"launcherFileFilter": "Fichiers Keepass",
|
||||
"authPopupRequired": "Les pop-up sont blockés",
|
||||
"authPopupRequired": "Les pop-up sont bloquées",
|
||||
"authPopupRequiredBody": "Merci d'autoriser les popups pour cette appli dans votre navigateur ou essayez à nouveau."
|
||||
}
|
|
@ -240,7 +240,7 @@ const AppModel = Backbone.Model.extend({
|
|||
},
|
||||
|
||||
setFilter: function(filter) {
|
||||
this.filter = filter;
|
||||
this.filter = this.prepareFilter(filter);
|
||||
this.filter.subGroups = this.settings.get('expandGroups');
|
||||
if (!this.filter.advanced && this.advancedSearch) {
|
||||
this.filter.advanced = this.advancedSearch;
|
||||
|
@ -274,7 +274,7 @@ const AppModel = Backbone.Model.extend({
|
|||
|
||||
getEntries: function() {
|
||||
const entries = this.getEntriesByFilter(this.filter);
|
||||
entries.sortEntries(this.sort);
|
||||
entries.sortEntries(this.sort, this.filter);
|
||||
if (this.filter.trash) {
|
||||
this.addTrashGroups(entries);
|
||||
}
|
||||
|
@ -282,7 +282,6 @@ const AppModel = Backbone.Model.extend({
|
|||
},
|
||||
|
||||
getEntriesByFilter: function(filter) {
|
||||
filter = this.prepareFilter(filter);
|
||||
const entries = new EntryCollection();
|
||||
this.files.forEach(file => {
|
||||
file.forEachEntry(filter, entry => entries.push(entry));
|
||||
|
@ -303,12 +302,8 @@ const AppModel = Backbone.Model.extend({
|
|||
|
||||
prepareFilter: function(filter) {
|
||||
filter = _.clone(filter);
|
||||
if (filter.text) {
|
||||
filter.textLower = filter.text.toLowerCase();
|
||||
}
|
||||
if (filter.tag) {
|
||||
filter.tagLower = filter.tag.toLowerCase();
|
||||
}
|
||||
filter.textLower = filter.text ? filter.text.toLowerCase() : '';
|
||||
filter.tagLower = filter.tag ? filter.tag.toLowerCase() : '';
|
||||
return filter;
|
||||
},
|
||||
|
||||
|
@ -1021,12 +1016,12 @@ const AppModel = Backbone.Model.extend({
|
|||
},
|
||||
|
||||
saveFileFingerprint: function(file, password) {
|
||||
if (Launcher && Launcher.fingerprints && password) {
|
||||
if (Launcher && Launcher.fingerprints && !file.has('fingerprint')) {
|
||||
const fileInfo = this.fileInfos.get(file.id);
|
||||
Launcher.fingerprints.register(file.id, this.params.password, token => {
|
||||
Launcher.fingerprints.register(file.id, password, token => {
|
||||
if (token) {
|
||||
fileInfo.set('fingerprint', token);
|
||||
this.model.fileInfos.save();
|
||||
fileInfo.set({ fingerprint: token });
|
||||
this.fileInfos.save();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ const AppSettingsModel = Backbone.Model.extend({
|
|||
minimizeOnClose: false,
|
||||
tableView: false,
|
||||
colorfulIcons: false,
|
||||
directAutotype: true,
|
||||
titlebarStyle: 'default',
|
||||
lockOnMinimize: true,
|
||||
lockOnCopy: false,
|
||||
|
|
|
@ -5,6 +5,7 @@ const Color = require('../util/color');
|
|||
const IconUrl = require('../util/icon-url');
|
||||
const Otp = require('../util/otp');
|
||||
const kdbxweb = require('kdbxweb');
|
||||
const Ranking = require('../util/ranking');
|
||||
|
||||
const EntryModel = Backbone.Model.extend({
|
||||
defaults: {},
|
||||
|
@ -16,9 +17,6 @@ const EntryModel = Backbone.Model.extend({
|
|||
fieldRefFields: ['title', 'password', 'user', 'url', 'notes'],
|
||||
fieldRefIds: { T: 'Title', U: 'UserName', P: 'Password', A: 'URL', N: 'Notes' },
|
||||
|
||||
initialize: function() {
|
||||
},
|
||||
|
||||
setEntry: function(entry, group, file) {
|
||||
this.entry = entry;
|
||||
this.group = group;
|
||||
|
@ -392,6 +390,7 @@ const EntryModel = Backbone.Model.extend({
|
|||
const hasValue = val && (typeof val === 'string' || val.isProtected && val.byteLength);
|
||||
if (hasValue || allowEmpty || this.builtInFields.indexOf(field) >= 0) {
|
||||
this._entryModified();
|
||||
val = this.sanitizeFieldValue(val);
|
||||
this.entry.fields[field] = val;
|
||||
} else if (this.entry.fields.hasOwnProperty(field)) {
|
||||
this._entryModified();
|
||||
|
@ -400,6 +399,15 @@ const EntryModel = Backbone.Model.extend({
|
|||
this._fillByEntry();
|
||||
},
|
||||
|
||||
sanitizeFieldValue: function(val) {
|
||||
if (val && !val.isProtected && val.indexOf('\x1A') >= 0) {
|
||||
// https://github.com/keeweb/keeweb/issues/910
|
||||
// eslint-disable-next-line no-control-regex
|
||||
val = val.replace(/\x1A/g, '');
|
||||
}
|
||||
return val;
|
||||
},
|
||||
|
||||
hasField: function(field) {
|
||||
return this.entry.fields.hasOwnProperty(field);
|
||||
},
|
||||
|
@ -635,6 +643,56 @@ const EntryModel = Backbone.Model.extend({
|
|||
this.entry.times.creationTime = this.entry.times.lastModTime;
|
||||
this.entry.fields.Title = '';
|
||||
this._fillByEntry();
|
||||
},
|
||||
|
||||
getRank: function(searchString) {
|
||||
if (!searchString) {
|
||||
// no search string given, so rank all items the same
|
||||
return 0;
|
||||
}
|
||||
|
||||
let rank = 0;
|
||||
|
||||
const ranking = [
|
||||
{
|
||||
field: 'Title',
|
||||
multiplicator: 10
|
||||
},
|
||||
{
|
||||
field: 'URL',
|
||||
multiplicator: 8
|
||||
},
|
||||
{
|
||||
field: 'UserName',
|
||||
multiplicator: 5
|
||||
},
|
||||
{
|
||||
field: 'Notes',
|
||||
multiplicator: 2
|
||||
}
|
||||
];
|
||||
|
||||
const fieldNames = Object.keys(this.fields);
|
||||
_.forEach(fieldNames, field => {
|
||||
ranking.push(
|
||||
{
|
||||
field: field,
|
||||
multiplicator: 2
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
_.forEach(ranking, rankingEntry => {
|
||||
if (this._getFieldString(rankingEntry.field).toLowerCase() !== '') {
|
||||
const calculatedRank = Ranking.getStringRank(
|
||||
searchString,
|
||||
this._getFieldString(rankingEntry.field).toLowerCase()
|
||||
) * rankingEntry.multiplicator;
|
||||
rank += calculatedRank;
|
||||
}
|
||||
});
|
||||
|
||||
return rank;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -421,11 +421,17 @@ const FileModel = Backbone.Model.extend({
|
|||
syncing: false,
|
||||
syncError: error
|
||||
});
|
||||
|
||||
const shouldResetFingerprint = this.get('passwordChanged') && this.has('fingerprint');
|
||||
if (shouldResetFingerprint && !error) {
|
||||
this.set({ fingerprint: null });
|
||||
}
|
||||
|
||||
if (!this.get('open')) {
|
||||
return;
|
||||
}
|
||||
this.setOpenFile({ passwordLength: this.get('passwordLength') });
|
||||
this.forEachEntry({}, entry => entry.setSaved());
|
||||
this.forEachEntry({ includeDisabled: true }, entry => entry.setSaved());
|
||||
},
|
||||
|
||||
setPassword: function(password) {
|
||||
|
@ -569,10 +575,11 @@ const FileModel = Backbone.Model.extend({
|
|||
this.db.move(group, null);
|
||||
modified = true;
|
||||
}, this);
|
||||
trashGroup.group.entries.forEach(function(entry) {
|
||||
trashGroup.group.entries.slice().forEach(function(entry) {
|
||||
this.db.move(entry, null);
|
||||
modified = true;
|
||||
}, this);
|
||||
trashGroup.get('items').reset();
|
||||
trashGroup.get('entries').reset();
|
||||
if (modified) {
|
||||
this.setModified();
|
||||
|
|
|
@ -38,6 +38,12 @@ _.extend(StorageBase.prototype, {
|
|||
this._oauthProcessReturn(this._oauthReturnMessage);
|
||||
delete this._oauthReturnMessage;
|
||||
delete sessionStorage.authStorage;
|
||||
if (FeatureDetector.isStandalone) {
|
||||
const [url, urlParams] = location.href.split(/[?#]/);
|
||||
if (urlParams) {
|
||||
location.href = url;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const LastChar = String.fromCharCode(0xffffffff);
|
||||
const LastChar = String.fromCharCode(0xfffd);
|
||||
|
||||
const ciCompare = (window.Intl && window.Intl.Collator && !/Edge/.test(navigator.userAgent)) // bugged in Edge: #808
|
||||
? new Intl.Collator(undefined, { sensitivity: 'base' }).compare
|
||||
|
@ -13,6 +13,10 @@ const Comparators = {
|
|||
}
|
||||
},
|
||||
|
||||
rankComparator: function() {
|
||||
return function (x, y) { return y.getRank(this.filter.textLower) - x.getRank(this.filter.textLower); };
|
||||
},
|
||||
|
||||
dateComparator: function(field, asc) {
|
||||
if (asc) {
|
||||
return function (x, y) { return x[field] - y[field]; };
|
||||
|
|
|
@ -47,6 +47,9 @@ const FeatureDetector = {
|
|||
if (window.navigator.userAgent.indexOf('Edge/') > -1) {
|
||||
return 'edge';
|
||||
}
|
||||
if (navigator.standalone) {
|
||||
return 'standalone';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
const Ranking = {
|
||||
getStringRank: function(s1, s2) {
|
||||
let ix = s1.indexOf(s2);
|
||||
if (ix === 0 && s1.length === s2.length) {
|
||||
return 10;
|
||||
} else if (ix === 0) {
|
||||
return 5;
|
||||
} else if (ix > 0) {
|
||||
return 3;
|
||||
}
|
||||
ix = s2.indexOf(s1);
|
||||
if (ix === 0) {
|
||||
return 5;
|
||||
} else if (ix > 0) {
|
||||
return 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = Ranking;
|
|
@ -158,6 +158,9 @@ const AppView = Backbone.View.extend({
|
|||
this.hideKeyChange();
|
||||
this.views.open = new OpenView({ model: this.model });
|
||||
this.views.open.setElement(this.$el.find('.app__body')).render();
|
||||
this.views.open.on('close', () => {
|
||||
Backbone.trigger('closed-open-view');
|
||||
}, this);
|
||||
this.views.open.on('close', this.showEntries, this);
|
||||
},
|
||||
|
||||
|
|
|
@ -26,6 +26,10 @@ const AutoTypePopupView = Backbone.View.extend({
|
|||
this.initScroll();
|
||||
this.listenTo(Backbone, 'main-window-blur', this.mainWindowBlur);
|
||||
this.listenTo(Backbone, 'main-window-will-close', this.mainWindowWillClose);
|
||||
this.setupKeys();
|
||||
},
|
||||
|
||||
setupKeys() {
|
||||
KeyHandler.onKey(Keys.DOM_VK_ESCAPE, this.escPressed, this, false, true);
|
||||
KeyHandler.onKey(Keys.DOM_VK_RETURN, this.enterPressed, this, false, true);
|
||||
KeyHandler.onKey(Keys.DOM_VK_RETURN, this.actionEnterPressed, this, KeyHandler.SHORTCUT_ACTION, true);
|
||||
|
@ -33,10 +37,24 @@ const AutoTypePopupView = Backbone.View.extend({
|
|||
KeyHandler.onKey(Keys.DOM_VK_UP, this.upPressed, this, false, true);
|
||||
KeyHandler.onKey(Keys.DOM_VK_DOWN, this.downPressed, this, false, true);
|
||||
KeyHandler.onKey(Keys.DOM_VK_BACK_SPACE, this.backSpacePressed, this, false, true);
|
||||
KeyHandler.onKey(Keys.DOM_VK_O, this.openKeyPressed, this, KeyHandler.SHORTCUT_ACTION, true);
|
||||
KeyHandler.on('keypress:auto-type', this.keyPressed.bind(this));
|
||||
KeyHandler.setModal('auto-type');
|
||||
},
|
||||
|
||||
removeKeys() {
|
||||
KeyHandler.offKey(Keys.DOM_VK_ESCAPE, this.escPressed, this);
|
||||
KeyHandler.offKey(Keys.DOM_VK_RETURN, this.enterPressed, this);
|
||||
KeyHandler.offKey(Keys.DOM_VK_RETURN, this.actionEnterPressed, this);
|
||||
KeyHandler.offKey(Keys.DOM_VK_RETURN, this.optEnterPressed, this);
|
||||
KeyHandler.offKey(Keys.DOM_VK_UP, this.upPressed, this);
|
||||
KeyHandler.offKey(Keys.DOM_VK_DOWN, this.downPressed, this);
|
||||
KeyHandler.offKey(Keys.DOM_VK_BACK_SPACE, this.backSpacePressed, this);
|
||||
KeyHandler.offKey(Keys.DOM_VK_O, this.openKeyPressed, this);
|
||||
KeyHandler.off('keypress:auto-type');
|
||||
KeyHandler.setModal(null);
|
||||
},
|
||||
|
||||
render() {
|
||||
let topMessage;
|
||||
if (this.model.filter.title || this.model.filter.url) {
|
||||
|
@ -76,13 +94,7 @@ const AutoTypePopupView = Backbone.View.extend({
|
|||
},
|
||||
|
||||
remove() {
|
||||
KeyHandler.offKey(Keys.DOM_VK_ESCAPE, this.escPressed, this);
|
||||
KeyHandler.offKey(Keys.DOM_VK_RETURN, this.enterPressed, this);
|
||||
KeyHandler.offKey(Keys.DOM_VK_UP, this.upPressed, this);
|
||||
KeyHandler.offKey(Keys.DOM_VK_DOWN, this.downPressed, this);
|
||||
KeyHandler.offKey(Keys.DOM_VK_BACK_SPACE, this.backSpacePressed, this);
|
||||
KeyHandler.off('keypress:auto-type');
|
||||
KeyHandler.setModal(null);
|
||||
this.removeKeys();
|
||||
Backbone.View.prototype.remove.apply(this, arguments);
|
||||
},
|
||||
|
||||
|
@ -121,6 +133,11 @@ const AutoTypePopupView = Backbone.View.extend({
|
|||
this.closeWithResult(AutoTypeSequenceType.USERNAME);
|
||||
},
|
||||
|
||||
openKeyPressed() {
|
||||
this.removeKeys();
|
||||
this.trigger('show-open-files');
|
||||
},
|
||||
|
||||
upPressed(e) {
|
||||
e.preventDefault();
|
||||
const activeIndex = this.entries.indexOf(this.result) - 1;
|
||||
|
|
|
@ -74,9 +74,9 @@ const DetailsView = Backbone.View.extend({
|
|||
this.listenTo(Backbone, 'set-locale', this.render);
|
||||
this.listenTo(OtpQrReader, 'qr-read', this.otpCodeRead);
|
||||
this.listenTo(OtpQrReader, 'enter-manually', this.otpEnterManually);
|
||||
KeyHandler.onKey(Keys.DOM_VK_C, this.copyPassword, this, KeyHandler.SHORTCUT_ACTION, false, true);
|
||||
KeyHandler.onKey(Keys.DOM_VK_B, this.copyUserName, this, KeyHandler.SHORTCUT_ACTION, false, true);
|
||||
KeyHandler.onKey(Keys.DOM_VK_U, this.copyUrl, this, KeyHandler.SHORTCUT_ACTION, false, true);
|
||||
KeyHandler.onKey(Keys.DOM_VK_C, this.copyPassword, this, KeyHandler.SHORTCUT_ACTION);
|
||||
KeyHandler.onKey(Keys.DOM_VK_B, this.copyUserName, this, KeyHandler.SHORTCUT_ACTION);
|
||||
KeyHandler.onKey(Keys.DOM_VK_U, this.copyUrl, this, KeyHandler.SHORTCUT_ACTION);
|
||||
if (AutoType.enabled) {
|
||||
KeyHandler.onKey(Keys.DOM_VK_T, this.autoType, this, KeyHandler.SHORTCUT_ACTION);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
const Backbone = require('backbone');
|
||||
const IconMap = require('../const/icon-map');
|
||||
const Launcher = require('../comp/launcher');
|
||||
const Logger = require('../util/logger');
|
||||
|
||||
const logger = new Logger('icon-select-view');
|
||||
|
@ -56,7 +55,7 @@ const IconSelectView = Backbone.View.extend({
|
|||
this.downloadingFavicon = true;
|
||||
this.$el.find('.icon-select__icon-download>i').addClass('fa-spinner fa-spin');
|
||||
this.$el.find('.icon-select__icon-download').removeClass('icon-select__icon--download-error');
|
||||
const url = this.getIconUrl(!Launcher); // inside launcher we can load images without CORS
|
||||
const url = this.getIconUrl(true);
|
||||
const img = document.createElement('img');
|
||||
img.crossOrigin = 'Anonymous';
|
||||
img.src = url;
|
||||
|
|
|
@ -43,7 +43,8 @@ const ListSearchView = Backbone.View.extend({
|
|||
{ value: '-created', icon: 'sort-numeric-desc', loc: () => Locale.searchCreated + ' ' + this.addArrow(Locale.searchNO) },
|
||||
{ value: 'updated', icon: 'sort-numeric-asc', loc: () => Locale.searchUpdated + ' ' + this.addArrow(Locale.searchON) },
|
||||
{ value: '-updated', icon: 'sort-numeric-desc', loc: () => Locale.searchUpdated + ' ' + this.addArrow(Locale.searchNO) },
|
||||
{ value: '-attachments', icon: 'sort-amount-desc', loc: () => Locale.searchAttachments }
|
||||
{ value: '-attachments', icon: 'sort-amount-desc', loc: () => Locale.searchAttachments },
|
||||
{ value: '-rank', icon: 'sort-numeric-desc', loc: () => Locale.searchRank }
|
||||
];
|
||||
this.sortIcons = {};
|
||||
this.sortOptions.forEach(function(opt) {
|
||||
|
@ -55,7 +56,8 @@ const ListSearchView = Backbone.View.extend({
|
|||
url: true, protect: false,
|
||||
notes: true, pass: false,
|
||||
cs: false, regex: false,
|
||||
history: false, title: true
|
||||
history: false, title: true,
|
||||
rank: true
|
||||
};
|
||||
if (this.model.advancedSearch) {
|
||||
this.advancedSearch = _.extend({}, this.model.advancedSearch);
|
||||
|
|
|
@ -15,6 +15,7 @@ const Comparators = require('../util/comparators');
|
|||
const Storage = require('../storage');
|
||||
const Launcher = require('../comp/launcher');
|
||||
const FocusDetector = require('../comp/focus-detector');
|
||||
const FeatureDetector = require('../util/feature-detector');
|
||||
|
||||
const logger = new Logger('open-view');
|
||||
|
||||
|
@ -110,8 +111,8 @@ const OpenView = Backbone.View.extend({
|
|||
this.inputEl.focus();
|
||||
},
|
||||
|
||||
focusInput: function() {
|
||||
if (FocusDetector.hasFocus()) {
|
||||
focusInput: function(focusOnMobile) {
|
||||
if (FocusDetector.hasFocus() && (focusOnMobile || !FeatureDetector.isMobile)) {
|
||||
this.inputEl.focus();
|
||||
}
|
||||
},
|
||||
|
@ -384,21 +385,7 @@ const OpenView = Backbone.View.extend({
|
|||
}
|
||||
|
||||
const fileInfo = this.model.fileInfos.get(id);
|
||||
this.showOpenFileInfo(fileInfo);
|
||||
|
||||
if (fileInfo && Launcher && Launcher.fingerprints) {
|
||||
this.openFileWithFingerprint(fileInfo);
|
||||
}
|
||||
},
|
||||
|
||||
openFileWithFingerprint(fileInfo) {
|
||||
if (fileInfo.get('fingerprint')) {
|
||||
Launcher.fingerprints.auth(fileInfo.id, fileInfo.get('fingerprint'), password => {
|
||||
this.inputEl.val(password);
|
||||
this.inputEl.trigger('input');
|
||||
this.openDb();
|
||||
});
|
||||
}
|
||||
this.showOpenFileInfo(fileInfo, true);
|
||||
},
|
||||
|
||||
removeFile: function(id) {
|
||||
|
@ -507,7 +494,7 @@ const OpenView = Backbone.View.extend({
|
|||
}
|
||||
},
|
||||
|
||||
showOpenFileInfo: function(fileInfo) {
|
||||
showOpenFileInfo: function(fileInfo, fileWasClicked) {
|
||||
if (this.busy || !fileInfo) {
|
||||
return;
|
||||
}
|
||||
|
@ -522,6 +509,12 @@ const OpenView = Backbone.View.extend({
|
|||
this.params.keyFileData = null;
|
||||
this.displayOpenFile();
|
||||
this.displayOpenKeyFile();
|
||||
|
||||
this.openFileWithFingerprint(fileInfo);
|
||||
|
||||
if (fileWasClicked) {
|
||||
this.focusInput(true);
|
||||
}
|
||||
},
|
||||
|
||||
showOpenLocalFile: function(path, keyFilePath) {
|
||||
|
@ -544,6 +537,20 @@ const OpenView = Backbone.View.extend({
|
|||
}
|
||||
},
|
||||
|
||||
openFileWithFingerprint: function(fileInfo) {
|
||||
if (!fileInfo.has('fingerprint')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Launcher && Launcher.fingerprints) {
|
||||
Launcher.fingerprints.auth(fileInfo.id, fileInfo.get('fingerprint'), password => {
|
||||
this.inputEl.val(password);
|
||||
this.inputEl.trigger('input');
|
||||
this.openDb();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
createDemo: function() {
|
||||
if (!this.busy) {
|
||||
this.closeConfig();
|
||||
|
@ -583,7 +590,7 @@ const OpenView = Backbone.View.extend({
|
|||
this.inputEl.removeAttr('disabled').toggleClass('input--error', !!err);
|
||||
if (err) {
|
||||
logger.error('Error opening file', err);
|
||||
this.focusInput();
|
||||
this.focusInput(true);
|
||||
this.inputEl[0].selectionStart = 0;
|
||||
this.inputEl[0].selectionEnd = this.inputEl.val().length;
|
||||
if (err.code === 'InvalidKey') {
|
||||
|
|
|
@ -163,6 +163,7 @@ const SettingsFileView = Backbone.View.extend({
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.appModel.syncFile(this.model, arg);
|
||||
},
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ const SettingsGeneralView = Backbone.View.extend({
|
|||
'change .settings__general-lock-on-os-lock': 'changeLockOnOsLock',
|
||||
'change .settings__general-table-view': 'changeTableView',
|
||||
'change .settings__general-colorful-icons': 'changeColorfulIcons',
|
||||
'change .settings__general-direct-autotype': 'changeDirectAutotype',
|
||||
'change .settings__general-titlebar-style': 'changeTitlebarStyle',
|
||||
'click .settings__general-update-btn': 'checkUpdate',
|
||||
'click .settings__general-restart-btn': 'restartApp',
|
||||
|
@ -46,7 +47,8 @@ const SettingsGeneralView = Backbone.View.extend({
|
|||
'click .settings__general-show-advanced': 'showAdvancedSettings',
|
||||
'click .settings__general-dev-tools-link': 'openDevTools',
|
||||
'click .settings__general-try-beta-link': 'tryBeta',
|
||||
'click .settings__general-show-logs-link': 'showLogs'
|
||||
'click .settings__general-show-logs-link': 'showLogs',
|
||||
'click .settings__general-reload-app-link': 'reloadApp'
|
||||
},
|
||||
|
||||
views: null,
|
||||
|
@ -101,9 +103,11 @@ const SettingsGeneralView = Backbone.View.extend({
|
|||
updateManual: updateManual,
|
||||
releaseNotesLink: Links.ReleaseNotes,
|
||||
colorfulIcons: AppSettingsModel.instance.get('colorfulIcons'),
|
||||
directAutotype: AppSettingsModel.instance.get('directAutotype'),
|
||||
supportsTitleBarStyles: Launcher && FeatureDetector.supportsTitleBarStyles(),
|
||||
titlebarStyle: AppSettingsModel.instance.get('titlebarStyle'),
|
||||
storageProviders: storageProviders
|
||||
storageProviders: storageProviders,
|
||||
showReloadApp: FeatureDetector.isStandalone
|
||||
});
|
||||
this.renderProviderViews(storageProviders);
|
||||
},
|
||||
|
@ -275,6 +279,12 @@ const SettingsGeneralView = Backbone.View.extend({
|
|||
Backbone.trigger('refresh');
|
||||
},
|
||||
|
||||
changeDirectAutotype: function(e) {
|
||||
const directAutotype = e.target.checked || false;
|
||||
AppSettingsModel.instance.set('directAutotype', directAutotype);
|
||||
Backbone.trigger('refresh');
|
||||
},
|
||||
|
||||
restartApp: function() {
|
||||
if (Launcher) {
|
||||
Launcher.requestRestart();
|
||||
|
@ -338,6 +348,10 @@ const SettingsGeneralView = Backbone.View.extend({
|
|||
this.scrollToBottom();
|
||||
},
|
||||
|
||||
reloadApp: function() {
|
||||
location.reload();
|
||||
},
|
||||
|
||||
scrollToBottom: function() {
|
||||
this.$el.closest('.scroller').scrollTop(this.$el.height());
|
||||
}
|
||||
|
|
|
@ -14,7 +14,12 @@
|
|||
cursor: pointer;
|
||||
line-height: $mobile-back-button-height;
|
||||
height: $mobile-back-button-height;
|
||||
>i { margin-right: $base-padding-h; }
|
||||
font-size: 1.2em;
|
||||
>i {
|
||||
margin-right: .3em;
|
||||
font-size: 1.2em;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,6 +46,9 @@
|
|||
@include th {
|
||||
border: 1px solid th(light-border-color);
|
||||
}
|
||||
@include mobile {
|
||||
border-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
input.details__header-title-input {
|
||||
|
@ -52,6 +60,9 @@
|
|||
font-weight: bold;
|
||||
position: relative;
|
||||
top: -2px;
|
||||
@include mobile {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
&-color, &-icon {
|
||||
@include user-select(none);
|
||||
|
@ -86,7 +97,9 @@
|
|||
left: 6px;
|
||||
font-size: $large-header-font-size;
|
||||
&:hover, .details__header-color:hover & {
|
||||
display: block;
|
||||
@include nomobile {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
&-item {
|
||||
padding: 8px 12px;
|
||||
|
@ -147,6 +160,9 @@
|
|||
align-items: stretch;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
@include mobile {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&-after {
|
||||
|
@ -208,15 +224,19 @@
|
|||
.details__field--editable & {
|
||||
border-radius: $base-border-radius;
|
||||
&:hover {
|
||||
transition: border-color $base-duration $base-timing;
|
||||
border: 1px solid;
|
||||
@include th {
|
||||
border-color: th(light-border-color);
|
||||
box-shadow: 0 0 3px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
.details__field-value-add-label {
|
||||
@include th { color: th(muted-color); }
|
||||
transition: color $base-duration $base-timing;
|
||||
@include nomobile {
|
||||
transition: border-color $base-duration $base-timing;
|
||||
border: 1px solid;
|
||||
@include th {
|
||||
border-color: th(light-border-color);
|
||||
box-shadow: 0 0 3px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
.details__field-value-add-label {
|
||||
@include th {
|
||||
color: th(muted-color);
|
||||
}
|
||||
transition: color $base-duration $base-timing;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -250,6 +270,9 @@
|
|||
.details__field--edit[active-mobile-action=cancel] & {
|
||||
@include th { background: th(error-color); border-color: th(error-color); }
|
||||
}
|
||||
@include mobile {
|
||||
border-color: transparent !important;
|
||||
}
|
||||
}
|
||||
>input {
|
||||
.chrome & { padding-bottom: 1px; } // TODO: find a better cross-browser way to do it
|
||||
|
@ -333,6 +356,11 @@
|
|||
@include user-select(none);
|
||||
}
|
||||
}
|
||||
|
||||
@include mobile {
|
||||
@include th { border-bottom: light-border(); }
|
||||
padding-bottom: .5em;
|
||||
}
|
||||
}
|
||||
|
||||
&__attachments {
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
align-items: stretch;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
@include mobile {
|
||||
@include th { background: th(intermediate-background-color); }
|
||||
}
|
||||
|
||||
&__db {
|
||||
flex: 0 0 auto;
|
||||
|
@ -63,6 +66,10 @@
|
|||
flex: 0 0 auto;
|
||||
@include area-selectable(top);
|
||||
padding: $base-padding;
|
||||
.standalone & {
|
||||
padding-top: $base-padding-v;
|
||||
padding-bottom: 1.2em;
|
||||
}
|
||||
font-size: 1.4em;
|
||||
text-align: center;
|
||||
width: 1em;
|
||||
|
|
|
@ -38,6 +38,9 @@
|
|||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
flex-wrap: wrap;
|
||||
@include mobile {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
}
|
||||
&-field-wrap {
|
||||
flex: 1;
|
||||
|
@ -45,6 +48,14 @@
|
|||
}
|
||||
&-field {
|
||||
width: 100%;
|
||||
@include mobile {
|
||||
font-size: 1.05em !important;
|
||||
box-shadow: none !important;
|
||||
border-radius: .6em !important;
|
||||
border: none !important;
|
||||
padding-left: 0.4em;
|
||||
@include th { background-color: th(secondary-background-color) !important; }
|
||||
}
|
||||
}
|
||||
&-icon-search {
|
||||
@include th { color: th(muted-color); }
|
||||
|
@ -55,6 +66,9 @@
|
|||
&:hover {
|
||||
@include th { color: th(medium-color); }
|
||||
}
|
||||
@include mobile {
|
||||
top: .5em;
|
||||
}
|
||||
}
|
||||
&-btn-new {
|
||||
@include icon-btn;
|
||||
|
@ -122,6 +136,13 @@
|
|||
@include area-selected(right);
|
||||
}
|
||||
}
|
||||
@include mobile {
|
||||
margin: 0 $base-padding-h;
|
||||
@include th { border-bottom: light-border(); }
|
||||
&:last-of-type {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.list__item--table) {
|
||||
height: 3rem;
|
||||
|
@ -135,6 +156,9 @@
|
|||
margin-right: 2px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
@include mobile {
|
||||
margin-right: 4px;
|
||||
}
|
||||
&--custom {
|
||||
vertical-align: text-bottom;
|
||||
&.yellow { @include filter(grayscale(1) sepia(1) hue-rotate(20deg) brightness(1.17) saturate(5.7)); }
|
||||
|
|
|
@ -36,10 +36,11 @@
|
|||
}
|
||||
}
|
||||
@include mobile() {
|
||||
&-i, &-svg { font-size: 4.6em; }
|
||||
&-text { font-size: 1.1em; }
|
||||
.open__icons--lower & {
|
||||
margin: 8px;
|
||||
&-i, &-svg { font-size: 2em; }
|
||||
&-text { font-size: .5em; }
|
||||
margin: 14px;
|
||||
&-i, &-svg { font-size: 4.2em; margin-bottom: .1em; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,12 @@
|
|||
line-height: $mobile-back-button-height;
|
||||
height: $mobile-back-button-height;
|
||||
padding-bottom: $base-padding-v;
|
||||
>i { margin-right: $base-padding-h; }
|
||||
font-size: 1.2em;
|
||||
>i {
|
||||
margin-right: .3em;
|
||||
font-size: 1.2em;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
&-pre { display: inline; }
|
||||
}
|
||||
@include nomobile {
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
<h1 class="at-select__header-text">{{res 'autoTypeHeader'}}</h1>
|
||||
<div class="at-select__hint">
|
||||
<div class="at-select__hint-text"><span class="shortcut">{{keyEnter}}</span>: {{selectionHintDefault}}</div>
|
||||
<div class="at-select__hint-text"><span class="shortcut">{{actionSymbol}} {{keyEnter}}</span>: {{selectionHintAction}}</div>
|
||||
<div class="at-select__hint-text"><span class="shortcut">{{altSymbol}} {{keyEnter}}</span>: {{selectionHintOpt}}</div>
|
||||
<div class="at-select__hint-text"><span class="shortcut">{{{actionSymbol}}} {{keyEnter}}</span>: {{selectionHintAction}}</div>
|
||||
<div class="at-select__hint-text"><span class="shortcut">{{{altSymbol}}} {{keyEnter}}</span>: {{selectionHintOpt}}</div>
|
||||
</div>
|
||||
{{#if filterText}}
|
||||
<div class="at-select__header-filter">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div class="details">
|
||||
<div class="details__back-button">
|
||||
<i class="fa fa-chevron-left"></i> {{res 'detBackToList'}}
|
||||
<i class="fa fa-chevron-left"></i>{{res 'detBackToList'}}
|
||||
</div>
|
||||
<div class="details__header">
|
||||
<i class="details__header-color fa fa-bookmark-o" title="{{res 'detSetIconColor'}}" tip-placement="left">
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
{{#if adv.regex}}checked{{/if}}><label for="list__search-adv-check-regex">{{res 'searchRegex'}}</label></div>
|
||||
<div class="list__search-check"><input type="checkbox" id="list__search-adv-check-history" data-id="history"
|
||||
{{#if adv.history}}checked{{/if}}><label for="list__search-adv-check-history">{{Res 'history'}}</label></div>
|
||||
<div class="list__search-check"><input type="checkbox" id="list__search-adv-check-rank" data-id="rank"
|
||||
{{#if adv.rank}}checked{{/if}}><label for="list__search-adv-check-rank">{{Res 'rank'}}</label></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -141,6 +141,13 @@
|
|||
<label for="settings__general-minimize">{{res 'setGenMinInstead'}}</label>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if canAutoType}}
|
||||
<div>
|
||||
<input type="checkbox" class="settings__input input-base settings__general-direct-autotype"
|
||||
id="settings__general-direct-autotype" {{#if directAutotype}}checked{{/if}} />
|
||||
<label for="settings__general-direct-autotype">{{res 'setGenDirectAutotype'}}</label>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<h2>{{res 'setGenLock'}}</h2>
|
||||
<div>
|
||||
|
@ -194,8 +201,11 @@
|
|||
<a class="settings__general-show-advanced">{{res 'setGenShowAdvanced'}}</a>
|
||||
<div class="settings__general-advanced hide">
|
||||
{{#if devTools}}
|
||||
<button class="btn-silent settings__general-dev-tools-link">{{res 'setGenDevTools'}}</button>
|
||||
<button class="btn-silent settings__general-try-beta-link">{{res 'setGenTryBeta'}}</button>
|
||||
<button class="btn-silent settings__general-dev-tools-link">{{res 'setGenDevTools'}}</button>
|
||||
<button class="btn-silent settings__general-try-beta-link">{{res 'setGenTryBeta'}}</button>
|
||||
{{/if}}
|
||||
{{#if showReloadApp}}
|
||||
<button class="btn-silent settings__general-reload-app-link">{{res 'setGenReloadApp'}}</button>
|
||||
{{/if}}
|
||||
<button class="btn-silent settings__general-show-logs-link">{{res 'setGenShowAppLogs'}}</button>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div class="settings">
|
||||
<div class="settings__back-button">
|
||||
<i class="fa fa-chevron-left settings__back-button-pre"></i> {{res 'retToApp'}} <i class="fa fa-external-link-square settings__back-button-post"></i>
|
||||
<i class="fa fa-chevron-left settings__back-button-pre"></i>{{res 'retToApp'}} <i class="fa fa-external-link-square settings__back-button-post"></i>
|
||||
</div>
|
||||
<div class="scroller">
|
||||
</div>
|
||||
|
|
|
@ -163,7 +163,7 @@ function createMainWindow() {
|
|||
setMenu();
|
||||
mainWindow.loadURL(htmlPath);
|
||||
if (showDevToolsOnStart) {
|
||||
mainWindow.openDevTools();
|
||||
mainWindow.openDevTools({ mode: 'bottom' });
|
||||
}
|
||||
mainWindow.once('ready-to-show', () => {
|
||||
mainWindow.show();
|
||||
|
@ -327,7 +327,8 @@ function setMenu() {
|
|||
{
|
||||
label: 'Window',
|
||||
submenu: [
|
||||
{ accelerator: 'CmdOrCtrl+M', role: 'minimize' }
|
||||
{ accelerator: 'CmdOrCtrl+M', role: 'minimize' },
|
||||
{ accelerator: 'Command+W', role: 'close' }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
@ -475,7 +476,7 @@ function hookRequestHeaders() {
|
|||
// partially off-screen or straddling two displays if the user desires that.
|
||||
|
||||
function coerceMainWindowPositionToConnectedDisplay() {
|
||||
const eScreen = require('electron').screen;
|
||||
const eScreen = electron.screen;
|
||||
const displays = eScreen.getAllDisplays();
|
||||
if (!displays || !displays.length) return;
|
||||
const windowBounds = mainWindow.getBounds();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "KeeWeb",
|
||||
"version": "1.7.8",
|
||||
"version": "1.8.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "KeeWeb",
|
||||
"version": "1.7.8",
|
||||
"version": "1.8.0",
|
||||
"description": "Free cross-platform password manager compatible with KeePass",
|
||||
"main": "main.js",
|
||||
"homepage": "https://keeweb.info",
|
||||
|
|
|
@ -1,13 +1,32 @@
|
|||
#!/usr/bin/env bash
|
||||
echo Cloning KeeWeb into $PWD/keeweb...
|
||||
|
||||
SCHEMA=${SCHEMA:-http}
|
||||
|
||||
KEEWEB_GH=git@github.com:keeweb
|
||||
|
||||
if [[ "$SCHEMA" == 'http' ]]; then
|
||||
KEEWEB_GH=https://github.com/keeweb
|
||||
fi
|
||||
|
||||
echo "Cloning KeeWeb ($KEEWEB_GH) into $PWD/keeweb..."
|
||||
|
||||
mkdir keeweb
|
||||
git clone git@github.com:keeweb/favicon-proxy.git keeweb/favicon-proxy
|
||||
git clone git@github.com:keeweb/kdbxweb.git keeweb/kdbxweb
|
||||
git clone git@github.com:keeweb/keeweb.git -b develop keeweb/keeweb
|
||||
git clone git@github.com:keeweb/beta.keeweb.info.git keeweb/keeweb-beta
|
||||
git clone git@github.com:keeweb/keeweb-site.git -b gh-pages keeweb/keeweb-site
|
||||
git clone git@github.com:keeweb/keeweb-plugins.git keeweb/keeweb-plugins
|
||||
git clone git@github.com:keeweb/keeweb.git -b gh-pages --single-branch keeweb/keeweb-dist
|
||||
pushd keeweb >/dev/null
|
||||
|
||||
git clone $KEEWEB_GH/keeweb.git -b develop keeweb
|
||||
|
||||
pushd keeweb >/dev/null
|
||||
git worktree add ../keeweb-dist gh-pages
|
||||
popd >/dev/null
|
||||
|
||||
git clone $KEEWEB_GH/favicon-proxy.git favicon-proxy
|
||||
git clone $KEEWEB_GH/kdbxweb.git kdbxweb
|
||||
git clone $KEEWEB_GH/beta.keeweb.info.git keeweb-beta
|
||||
git clone $KEEWEB_GH/keeweb-site.git -b gh-pages keeweb-site
|
||||
git clone $KEEWEB_GH/keeweb-plugins.git keeweb-plugins
|
||||
popd > /dev/null
|
||||
|
||||
mkdir keeweb/keys
|
||||
echo kdbxweb/ > keeweb/.eslintignore
|
||||
echo Done! KeeWeb is cloned into $PWD/keeweb
|
||||
|
||||
echo "Done! KeeWeb is cloned into $PWD/keeweb"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "keeweb",
|
||||
"version": "1.7.8",
|
||||
"version": "1.8.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
@ -4385,8 +4385,7 @@
|
|||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
||||
"optional": true
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
|
@ -4407,14 +4406,12 @@
|
|||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
||||
"optional": true
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
|
@ -4429,20 +4426,17 @@
|
|||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
||||
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
|
||||
"optional": true
|
||||
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"optional": true
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
|
||||
"optional": true
|
||||
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
|
@ -4559,8 +4553,7 @@
|
|||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
|
||||
"optional": true
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
|
@ -4572,7 +4565,6 @@
|
|||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
||||
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
|
@ -4587,7 +4579,6 @@
|
|||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
|
@ -4595,14 +4586,12 @@
|
|||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
|
||||
"optional": true
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.4.tgz",
|
||||
"integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.1",
|
||||
"yallist": "^3.0.0"
|
||||
|
@ -4621,7 +4610,6 @@
|
|||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
|
@ -4702,8 +4690,7 @@
|
|||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
|
||||
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
|
||||
"optional": true
|
||||
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
|
@ -4715,7 +4702,6 @@
|
|||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
|
@ -4801,8 +4787,7 @@
|
|||
"safe-buffer": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
|
||||
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
|
||||
"optional": true
|
||||
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
|
@ -4838,7 +4823,6 @@
|
|||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
||||
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
|
@ -4858,7 +4842,6 @@
|
|||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
|
@ -4902,14 +4885,12 @@
|
|||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"optional": true
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz",
|
||||
"integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=",
|
||||
"optional": true
|
||||
"integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -5353,7 +5334,7 @@
|
|||
"version": "github:keeweb/grunt-contrib-deb#e9b6e9f6faab0f67512b4168a80b4dfbb0e0b68f",
|
||||
"from": "github:keeweb/grunt-contrib-deb#e9b6e9f",
|
||||
"requires": {
|
||||
"ar-async": "git+https://github.com/JayCanuck/node-ar-async.git",
|
||||
"ar-async": "git+https://github.com/JayCanuck/node-ar-async.git#cd5fa957b30db58d660d3f51bc64f16ab688c162",
|
||||
"async": "^1.5.0",
|
||||
"tar-stream": "^1.3.1"
|
||||
}
|
||||
|
@ -6193,8 +6174,7 @@
|
|||
"imul": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/imul/-/imul-1.0.1.tgz",
|
||||
"integrity": "sha1-nVhnFh6LPelsLDjV3HyxAvNeKsk=",
|
||||
"optional": true
|
||||
"integrity": "sha1-nVhnFh6LPelsLDjV3HyxAvNeKsk="
|
||||
},
|
||||
"imurmurhash": {
|
||||
"version": "0.1.4",
|
||||
|
@ -6610,8 +6590,7 @@
|
|||
"is-property": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
|
||||
"integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=",
|
||||
"optional": true
|
||||
"integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ="
|
||||
},
|
||||
"is-regex": {
|
||||
"version": "1.0.4",
|
||||
|
@ -6815,9 +6794,9 @@
|
|||
"resolved": "https://registry.npmjs.org/kdbxweb/-/kdbxweb-1.2.6.tgz",
|
||||
"integrity": "sha512-9KJlanItY6D2CmR/TN27HINwugSPNATD9yWq4V56JAxVUTY8WHveC5H0llLiyxgPHfr7eejPk8hmj98l/lq7Cw==",
|
||||
"requires": {
|
||||
"pako": "pako@github:keeweb/pako#653c0b00d8941c89d09ed4546d2179001ec44efc",
|
||||
"text-encoding": "text-encoding@github:keeweb/text-encoding#4dfb7cb0954c222852092f8b06ae4f6b4f60bfbb",
|
||||
"xmldom": "xmldom@github:keeweb/xmldom#ec8f61f723e2f403adaf7a1bbf55ced4ff1ea0c6"
|
||||
"pako": "github:keeweb/pako#653c0b00d8941c89d09ed4546d2179001ec44efc",
|
||||
"text-encoding": "github:keeweb/text-encoding#4dfb7cb0954c222852092f8b06ae4f6b4f60bfbb",
|
||||
"xmldom": "github:keeweb/xmldom#ec8f61f723e2f403adaf7a1bbf55ced4ff1ea0c6"
|
||||
},
|
||||
"dependencies": {
|
||||
"abbrev": {
|
||||
|
@ -7544,8 +7523,7 @@
|
|||
"ansi-regex": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz",
|
||||
"integrity": "sha1-xQYbbg74qBd15Q9dZhUb9r83EQc=",
|
||||
"optional": true
|
||||
"integrity": "sha1-xQYbbg74qBd15Q9dZhUb9r83EQc="
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "2.2.1",
|
||||
|
@ -7602,8 +7580,7 @@
|
|||
"balanced-match": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
|
||||
"integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=",
|
||||
"optional": true
|
||||
"integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg="
|
||||
},
|
||||
"bcrypt-pbkdf": {
|
||||
"version": "1.0.0",
|
||||
|
@ -7618,7 +7595,6 @@
|
|||
"version": "0.0.9",
|
||||
"resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
|
||||
"integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"inherits": "~2.0.0"
|
||||
}
|
||||
|
@ -7627,7 +7603,6 @@
|
|||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
|
||||
"integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"hoek": "2.x.x"
|
||||
}
|
||||
|
@ -7636,7 +7611,6 @@
|
|||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz",
|
||||
"integrity": "sha1-cZfX6qm4fmSDkOph/GbIRCdCDfk=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"balanced-match": "^0.4.1",
|
||||
"concat-map": "0.0.1"
|
||||
|
@ -7645,8 +7619,7 @@
|
|||
"buffer-shims": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz",
|
||||
"integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=",
|
||||
"optional": true
|
||||
"integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E="
|
||||
},
|
||||
"caseless": {
|
||||
"version": "0.11.0",
|
||||
|
@ -7678,14 +7651,12 @@
|
|||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
||||
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
|
||||
"optional": true
|
||||
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
|
||||
"integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
|
@ -7702,20 +7673,17 @@
|
|||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"optional": true
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
|
||||
"optional": true
|
||||
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
|
||||
"optional": true
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
},
|
||||
"cryptiles": {
|
||||
"version": "2.0.5",
|
||||
|
@ -7761,8 +7729,7 @@
|
|||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
|
||||
"optional": true
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
|
||||
},
|
||||
"delegates": {
|
||||
"version": "1.0.0",
|
||||
|
@ -7794,8 +7761,7 @@
|
|||
"extsprintf": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz",
|
||||
"integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=",
|
||||
"optional": true
|
||||
"integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA="
|
||||
},
|
||||
"forever-agent": {
|
||||
"version": "0.6.1",
|
||||
|
@ -7817,14 +7783,12 @@
|
|||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"optional": true
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
||||
},
|
||||
"fstream": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.10.tgz",
|
||||
"integrity": "sha1-YE6Kkv4m/9n2+uMDmdSYThqyKCI=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.2",
|
||||
"inherits": "~2.0.0",
|
||||
|
@ -7896,7 +7860,6 @@
|
|||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz",
|
||||
"integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
|
@ -7909,8 +7872,7 @@
|
|||
"graceful-fs": {
|
||||
"version": "4.1.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
|
||||
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
|
||||
"optional": true
|
||||
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
|
||||
},
|
||||
"graceful-readlink": {
|
||||
"version": "1.0.1",
|
||||
|
@ -7960,8 +7922,7 @@
|
|||
"hoek": {
|
||||
"version": "2.16.3",
|
||||
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
|
||||
"integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
|
||||
"optional": true
|
||||
"integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0="
|
||||
},
|
||||
"http-signature": {
|
||||
"version": "1.1.1",
|
||||
|
@ -7978,7 +7939,6 @@
|
|||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
|
@ -7987,8 +7947,7 @@
|
|||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
|
||||
"optional": true
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.4",
|
||||
|
@ -8000,7 +7959,6 @@
|
|||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
||||
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
|
@ -8032,8 +7990,7 @@
|
|||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
|
||||
"optional": true
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"isstream": {
|
||||
"version": "0.1.2",
|
||||
|
@ -8088,14 +8045,12 @@
|
|||
"mime-db": {
|
||||
"version": "1.25.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.25.0.tgz",
|
||||
"integrity": "sha1-wY29fHOl2/b0SgJNwNFloeexw5I=",
|
||||
"optional": true
|
||||
"integrity": "sha1-wY29fHOl2/b0SgJNwNFloeexw5I="
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.13",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.13.tgz",
|
||||
"integrity": "sha1-4HqqnGxrmnyjASxpADrSWjnpKog=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"mime-db": "~1.25.0"
|
||||
}
|
||||
|
@ -8104,7 +8059,6 @@
|
|||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz",
|
||||
"integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.0.0"
|
||||
}
|
||||
|
@ -8112,14 +8066,12 @@
|
|||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
|
||||
"optional": true
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
|
@ -8171,8 +8123,7 @@
|
|||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
|
||||
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
|
||||
"optional": true
|
||||
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.8.2",
|
||||
|
@ -8190,7 +8141,6 @@
|
|||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
|
@ -8198,8 +8148,7 @@
|
|||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"optional": true
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
|
||||
},
|
||||
"pinkie": {
|
||||
"version": "2.0.4",
|
||||
|
@ -8219,8 +8168,7 @@
|
|||
"process-nextick-args": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
|
||||
"integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
|
||||
"optional": true
|
||||
"integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
|
||||
},
|
||||
"punycode": {
|
||||
"version": "1.4.1",
|
||||
|
@ -8301,7 +8249,6 @@
|
|||
"version": "2.5.4",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz",
|
||||
"integrity": "sha1-loAAk8vxoMhr2VtGJUZ1NcKd+gQ=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"glob": "^7.0.5"
|
||||
}
|
||||
|
@ -8362,7 +8309,6 @@
|
|||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
||||
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
|
@ -8372,8 +8318,7 @@
|
|||
"string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
|
||||
"optional": true
|
||||
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
|
||||
},
|
||||
"stringstream": {
|
||||
"version": "0.0.5",
|
||||
|
@ -8385,7 +8330,6 @@
|
|||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
|
@ -8406,7 +8350,6 @@
|
|||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
|
||||
"integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"block-stream": "*",
|
||||
"fstream": "^1.0.2",
|
||||
|
@ -8485,8 +8428,7 @@
|
|||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
|
||||
"optional": true
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
},
|
||||
"uuid": {
|
||||
"version": "3.0.1",
|
||||
|
@ -8515,8 +8457,7 @@
|
|||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"optional": true
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.1",
|
||||
|
@ -11230,8 +11171,7 @@
|
|||
"path-key": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz",
|
||||
"integrity": "sha1-XVPVeAGWRsDWiADbThRua9wqx68=",
|
||||
"optional": true
|
||||
"integrity": "sha1-XVPVeAGWRsDWiADbThRua9wqx68="
|
||||
},
|
||||
"path-parse": {
|
||||
"version": "1.0.6",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "keeweb",
|
||||
"version": "1.7.8",
|
||||
"version": "1.8.0",
|
||||
"description": "Free cross-platform password manager compatible with KeePass",
|
||||
"main": "Gruntfile.js",
|
||||
"private": true,
|
||||
|
@ -87,6 +87,9 @@
|
|||
"email": "antelle.net@gmail.com",
|
||||
"url": "http://antelle.net"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0"
|
||||
},
|
||||
"license": "MIT",
|
||||
"readme": "README.md"
|
||||
}
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
Release notes
|
||||
-------------
|
||||
##### v1.8.0 (2019-03-31)
|
||||
`+` iOS PWA improvements
|
||||
`+` auto-type improvements
|
||||
`*` website icons are downloaded using favicon.keeweb.info
|
||||
|
||||
##### v1.7.8 (2019-03-02)
|
||||
`-` fix #1124: keyboard navigation issues
|
||||
`*` improved link security
|
||||
|
|