mirror of https://github.com/keeweb/keeweb
better eslint
parent
0df1ba97d5
commit
f8395f7f38
34
.eslintrc
34
.eslintrc
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"extends": ["standard", "plugin:prettier/recommended"],
|
||||
"plugins": ["prettier", "import"],
|
||||
"extends": ["standard", "eslint:recommended", "plugin:prettier/recommended"],
|
||||
"rules": {
|
||||
"semi": ["error", "always"],
|
||||
"one-var": "off",
|
||||
|
@ -19,9 +20,36 @@
|
|||
"no-mixed-operators": "off",
|
||||
"prefer-promise-reject-errors": "off",
|
||||
"standard/no-callback-literal": "off",
|
||||
"import/no-webpack-loader-syntax": "off",
|
||||
"object-curly-spacing": "off",
|
||||
"quote-props": "off"
|
||||
"quote-props": "off",
|
||||
"no-new-object": "error",
|
||||
"object-shorthand": "error",
|
||||
"no-array-constructor": "error",
|
||||
"array-callback-return": "error",
|
||||
"no-eval": "error",
|
||||
"no-new-func": "error",
|
||||
"prefer-rest-params": "error",
|
||||
"prefer-spread": "error",
|
||||
"no-useless-constructor": "error",
|
||||
"no-dupe-class-members": "error",
|
||||
"no-duplicate-imports": "error",
|
||||
"eqeqeq": "error",
|
||||
"no-unneeded-ternary": "error",
|
||||
"curly": "error",
|
||||
"prettier/prettier": "error",
|
||||
"no-restricted-syntax": [
|
||||
"error",
|
||||
{
|
||||
"selector": "ExportDefaultDeclaration",
|
||||
"message": "Prefer named exports"
|
||||
}
|
||||
],
|
||||
"no-empty": "off",
|
||||
"import/no-webpack-loader-syntax": "error",
|
||||
"import/no-relative-parent-imports": "error",
|
||||
"import/first": "error",
|
||||
"import/no-namespace": "error",
|
||||
"import/no-default-export": "error"
|
||||
},
|
||||
"parserOptions": {
|
||||
"sourceType": "module",
|
||||
|
|
|
@ -272,7 +272,7 @@ module.exports = function(grunt) {
|
|||
name: 'KeeWeb',
|
||||
dir: 'tmp/desktop/app',
|
||||
out: 'tmp/desktop',
|
||||
electronVersion: electronVersion,
|
||||
electronVersion,
|
||||
overwrite: true,
|
||||
asar: true,
|
||||
appCopyright: `Copyright © ${year} Antelle`,
|
||||
|
@ -387,7 +387,7 @@ module.exports = function(grunt) {
|
|||
options: {
|
||||
vars: {
|
||||
version: pkg.version,
|
||||
rev: function() {
|
||||
rev() {
|
||||
return grunt.config.get('gitinfo.local.branch.current.shortSHA');
|
||||
},
|
||||
homepage: pkg.homepage
|
||||
|
@ -431,7 +431,7 @@ module.exports = function(grunt) {
|
|||
description: pkg.description,
|
||||
author: pkg.author,
|
||||
homepage: pkg.homepage,
|
||||
rev: function() {
|
||||
rev() {
|
||||
return grunt.config.get('gitinfo.local.branch.current.shortSHA');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const Launcher = require('../comp/launcher');
|
||||
|
||||
const AutoTypeEmitterFactory = {
|
||||
create: function(callback) {
|
||||
create(callback) {
|
||||
if (Launcher && Launcher.autoTypeSupported) {
|
||||
const AutoTypeEmitter = require('./emitter/auto-type-emitter-' + Launcher.platform());
|
||||
return new AutoTypeEmitter(callback);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const Launcher = require('../comp/launcher');
|
||||
|
||||
const AutoTypeHelperFactory = {
|
||||
create: function() {
|
||||
create() {
|
||||
if (Launcher && Launcher.autoTypeSupported) {
|
||||
const AutoTypeHelper = require('./helper/auto-type-helper-' + Launcher.platform());
|
||||
return new AutoTypeHelper();
|
||||
|
|
|
@ -110,7 +110,7 @@ AutoTypeObfuscator.prototype.stepReal = function() {
|
|||
break;
|
||||
}
|
||||
}
|
||||
possibleActions.push({ ins: true, ch: this.chars[i], ix: i, from: from, to: to });
|
||||
possibleActions.push({ ins: true, ch: this.chars[i], ix: i, from, to });
|
||||
}
|
||||
}
|
||||
const action = possibleActions[Math.floor(Math.random() * possibleActions.length)];
|
||||
|
@ -158,7 +158,7 @@ AutoTypeObfuscator.prototype.moveRight = function() {
|
|||
AutoTypeObfuscator.prototype.inputChar = function(ch) {
|
||||
logger.debug('inputChar', ch);
|
||||
this.ops.push({ type: 'text', value: ch });
|
||||
this.inputChars.splice(this.inputCursor, this.inputSel, { ch: ch });
|
||||
this.inputChars.splice(this.inputCursor, this.inputSel, { ch });
|
||||
this.inputCursor++;
|
||||
this.inputSel = 0;
|
||||
};
|
||||
|
@ -166,7 +166,7 @@ AutoTypeObfuscator.prototype.inputChar = function(ch) {
|
|||
AutoTypeObfuscator.prototype.copyPaste = function(ch) {
|
||||
logger.debug('copyPaste', ch);
|
||||
this.ops.push({ type: 'cmd', value: 'copyPaste', arg: ch });
|
||||
this.inputChars.splice(this.inputCursor, this.inputSel, { ch: ch });
|
||||
this.inputChars.splice(this.inputCursor, this.inputSel, { ch });
|
||||
this.inputCursor++;
|
||||
this.inputSel = 0;
|
||||
};
|
||||
|
|
|
@ -119,8 +119,8 @@ AutoTypeParser.prototype.addOp = function(op, sep, arg) {
|
|||
type: 'op',
|
||||
value: op,
|
||||
mod: this.resetModifiers(),
|
||||
sep: sep,
|
||||
arg: arg
|
||||
sep,
|
||||
arg
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -71,70 +71,70 @@ AutoTypeRunner.Keys = {
|
|||
};
|
||||
|
||||
AutoTypeRunner.Substitutions = {
|
||||
title: function(runner, op) {
|
||||
title(runner, op) {
|
||||
return runner.getEntryFieldKeys('Title', op);
|
||||
},
|
||||
username: function(runner, op) {
|
||||
username(runner, op) {
|
||||
return runner.getEntryFieldKeys('UserName', op);
|
||||
},
|
||||
url: function(runner, op) {
|
||||
url(runner, op) {
|
||||
return runner.getEntryFieldKeys('URL', op);
|
||||
},
|
||||
password: function(runner, op) {
|
||||
password(runner, op) {
|
||||
return runner.getEntryFieldKeys('Password', op);
|
||||
},
|
||||
notes: function(runner, op) {
|
||||
notes(runner, op) {
|
||||
return runner.getEntryFieldKeys('Notes', op);
|
||||
},
|
||||
group: function(runner) {
|
||||
group(runner) {
|
||||
return runner.getEntryGroupName();
|
||||
},
|
||||
totp: function(runner, op) {
|
||||
totp(runner, op) {
|
||||
return runner.getOtp(op);
|
||||
},
|
||||
s: function(runner, op) {
|
||||
s(runner, op) {
|
||||
return runner.getEntryFieldKeys(op.arg, op);
|
||||
},
|
||||
'dt_simple': function(runner) {
|
||||
'dt_simple'(runner) {
|
||||
return runner.dt('simple');
|
||||
},
|
||||
'dt_year': function(runner) {
|
||||
'dt_year'(runner) {
|
||||
return runner.dt('Y');
|
||||
},
|
||||
'dt_month': function(runner) {
|
||||
'dt_month'(runner) {
|
||||
return runner.dt('M');
|
||||
},
|
||||
'dt_day': function(runner) {
|
||||
'dt_day'(runner) {
|
||||
return runner.dt('D');
|
||||
},
|
||||
'dt_hour': function(runner) {
|
||||
'dt_hour'(runner) {
|
||||
return runner.dt('h');
|
||||
},
|
||||
'dt_minute': function(runner) {
|
||||
'dt_minute'(runner) {
|
||||
return runner.dt('m');
|
||||
},
|
||||
'dt_second': function(runner) {
|
||||
'dt_second'(runner) {
|
||||
return runner.dt('s');
|
||||
},
|
||||
'dt_utc_simple': function(runner) {
|
||||
'dt_utc_simple'(runner) {
|
||||
return runner.udt('simple');
|
||||
},
|
||||
'dt_utc_year': function(runner) {
|
||||
'dt_utc_year'(runner) {
|
||||
return runner.udt('Y');
|
||||
},
|
||||
'dt_utc_month': function(runner) {
|
||||
'dt_utc_month'(runner) {
|
||||
return runner.udt('M');
|
||||
},
|
||||
'dt_utc_day': function(runner) {
|
||||
'dt_utc_day'(runner) {
|
||||
return runner.udt('D');
|
||||
},
|
||||
'dt_utc_hour': function(runner) {
|
||||
'dt_utc_hour'(runner) {
|
||||
return runner.udt('h');
|
||||
},
|
||||
'dt_utc_minute': function(runner) {
|
||||
'dt_utc_minute'(runner) {
|
||||
return runner.udt('m');
|
||||
},
|
||||
'dt_utc_second': function(runner) {
|
||||
'dt_utc_second'(runner) {
|
||||
return runner.udt('s');
|
||||
}
|
||||
};
|
||||
|
@ -412,7 +412,7 @@ AutoTypeRunner.prototype.obfuscateOp = function(op) {
|
|||
}
|
||||
letters = op.value.split('');
|
||||
} else {
|
||||
op.value.forEach(grOp => letters.push.apply(letters, grOp.value.split('')));
|
||||
op.value.forEach(grOp => letters.push(...grOp.value.split('')));
|
||||
}
|
||||
if (letters.length <= 1) {
|
||||
return;
|
||||
|
@ -425,7 +425,7 @@ AutoTypeRunner.prototype.obfuscateOp = function(op) {
|
|||
AutoTypeRunner.prototype.run = function(callback) {
|
||||
this.emitter = AutoTypeEmitterFactory.create(this.emitNext.bind(this));
|
||||
this.emitterState = {
|
||||
callback: callback,
|
||||
callback,
|
||||
stack: [],
|
||||
ops: this.ops,
|
||||
opIx: 0,
|
||||
|
@ -495,7 +495,7 @@ AutoTypeRunner.prototype.emitNext = function(err) {
|
|||
emitterLogger.debug('key', op.value);
|
||||
this.emitter.key(op.value);
|
||||
break;
|
||||
case 'cmd':
|
||||
case 'cmd': {
|
||||
const method = this.emitter[op.value];
|
||||
if (!method) {
|
||||
throw 'Bad cmd: ' + op.value;
|
||||
|
@ -503,6 +503,7 @@ AutoTypeRunner.prototype.emitNext = function(err) {
|
|||
emitterLogger.debug(op.value, op.arg);
|
||||
method.call(this.emitter, op.arg);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw 'Bad op: ' + op.type;
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ AutoTypeEmitter.prototype.text = function(text) {
|
|||
Object.keys(this.mod).forEach(mod => {
|
||||
this.pendingScript.push('keydown ' + ModMap[mod]);
|
||||
});
|
||||
text.split('').map(char => {
|
||||
text.split('').forEach(char => {
|
||||
this.pendingScript.push('key U' + char.charCodeAt(0).toString(16));
|
||||
});
|
||||
Object.keys(this.mod).forEach(mod => {
|
||||
|
|
|
@ -6,7 +6,7 @@ AutoTypeHelper.prototype.getActiveWindowTitle = function(callback) {
|
|||
Launcher.spawn({
|
||||
cmd: 'xdotool',
|
||||
args: ['getactivewindow', 'getwindowname'],
|
||||
complete: function(err, res) {
|
||||
complete(err, res) {
|
||||
return callback(err, res ? res.trim() : undefined);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -7,7 +7,7 @@ AutoTypeHelper.prototype.getActiveWindowTitle = function(callback) {
|
|||
Launcher.spawn({
|
||||
cmd: AutoTypeNativeHelper.getHelperPath(),
|
||||
args: ['--window-info'],
|
||||
complete: function(err, out) {
|
||||
complete(err, out) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ const EntryCollection = Backbone.Collection.extend({
|
|||
'-created': Comparators.dateComparator('created', false),
|
||||
'updated': Comparators.dateComparator('updated', true),
|
||||
'-updated': Comparators.dateComparator('updated', false),
|
||||
'-attachments': function(x, y) {
|
||||
'-attachments'(x, y) {
|
||||
return this.attachmentSortVal(x).localeCompare(this.attachmentSortVal(y));
|
||||
},
|
||||
'-rank': Comparators.rankComparator()
|
||||
|
@ -29,18 +29,18 @@ const EntryCollection = Backbone.Collection.extend({
|
|||
|
||||
filter: null,
|
||||
|
||||
initialize: function(models, options) {
|
||||
initialize(models, options) {
|
||||
const comparatorName = (options && options.comparator) || this.defaultComparator;
|
||||
this.comparator = this.comparators[comparatorName];
|
||||
},
|
||||
|
||||
sortEntries: function(comparator, filter) {
|
||||
sortEntries(comparator, filter) {
|
||||
this.filter = filter;
|
||||
this.comparator = this.comparators[comparator] || this.comparators[this.defaultComparator];
|
||||
this.sort();
|
||||
},
|
||||
|
||||
attachmentSortVal: function(entry) {
|
||||
attachmentSortVal(entry) {
|
||||
const att = entry.attachments;
|
||||
let str = att.length ? String.fromCharCode(64 + att.length) : 'Z';
|
||||
if (att[0]) {
|
||||
|
|
|
@ -4,19 +4,19 @@ const FileModel = require('../models/file-model');
|
|||
const FileCollection = Backbone.Collection.extend({
|
||||
model: FileModel,
|
||||
|
||||
hasOpenFiles: function() {
|
||||
hasOpenFiles() {
|
||||
return this.some(file => file.get('open'));
|
||||
},
|
||||
|
||||
hasUnsavedFiles: function() {
|
||||
hasUnsavedFiles() {
|
||||
return this.some(file => file.get('modified'));
|
||||
},
|
||||
|
||||
hasDirtyFiles: function() {
|
||||
hasDirtyFiles() {
|
||||
return this.some(file => file.get('dirty'));
|
||||
},
|
||||
|
||||
getByName: function(name) {
|
||||
getByName(name) {
|
||||
return this.find(file => file.get('name').toLowerCase() === name.toLowerCase());
|
||||
}
|
||||
});
|
||||
|
|
|
@ -5,9 +5,9 @@ const SettingsStore = require('../comp/settings-store');
|
|||
const FileInfoCollection = Backbone.Collection.extend({
|
||||
model: FileInfoModel,
|
||||
|
||||
initialize: function() {},
|
||||
initialize() {},
|
||||
|
||||
load: function() {
|
||||
load() {
|
||||
return SettingsStore.load('file-info').then(data => {
|
||||
if (data) {
|
||||
this.reset(data, { silent: true });
|
||||
|
@ -15,15 +15,15 @@ const FileInfoCollection = Backbone.Collection.extend({
|
|||
});
|
||||
},
|
||||
|
||||
save: function() {
|
||||
save() {
|
||||
SettingsStore.save('file-info', this.toJSON());
|
||||
},
|
||||
|
||||
getLast: function() {
|
||||
getLast() {
|
||||
return this.first();
|
||||
},
|
||||
|
||||
getMatch: function(storage, name, path) {
|
||||
getMatch(storage, name, path) {
|
||||
return this.find(fi => {
|
||||
return (
|
||||
(fi.get('storage') || '') === (storage || '') &&
|
||||
|
@ -33,7 +33,7 @@ const FileInfoCollection = Backbone.Collection.extend({
|
|||
});
|
||||
},
|
||||
|
||||
getByName: function(name) {
|
||||
getByName(name) {
|
||||
return this.find(file => file.get('name').toLowerCase() === name.toLowerCase());
|
||||
}
|
||||
});
|
||||
|
|
|
@ -31,7 +31,7 @@ const Alerts = {
|
|||
}
|
||||
},
|
||||
|
||||
alert: function(config) {
|
||||
alert(config) {
|
||||
if (config.skipIfAlertDisplayed && Alerts.alertDisplayed) {
|
||||
return null;
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ const Alerts = {
|
|||
return view;
|
||||
},
|
||||
|
||||
notImplemented: function() {
|
||||
notImplemented() {
|
||||
this.alert({
|
||||
header: Locale.notImplemented,
|
||||
body: '',
|
||||
|
@ -65,7 +65,7 @@ const Alerts = {
|
|||
});
|
||||
},
|
||||
|
||||
info: function(config) {
|
||||
info(config) {
|
||||
this.alert(
|
||||
_.extend(
|
||||
{
|
||||
|
@ -82,7 +82,7 @@ const Alerts = {
|
|||
);
|
||||
},
|
||||
|
||||
error: function(config) {
|
||||
error(config) {
|
||||
this.alert(
|
||||
_.extend(
|
||||
{
|
||||
|
@ -99,7 +99,7 @@ const Alerts = {
|
|||
);
|
||||
},
|
||||
|
||||
yesno: function(config) {
|
||||
yesno(config) {
|
||||
this.alert(
|
||||
_.extend(
|
||||
{
|
||||
|
|
|
@ -2,7 +2,7 @@ const FeatureDetector = require('../util/feature-detector');
|
|||
const Storage = require('../storage');
|
||||
|
||||
const AuthReceiver = {
|
||||
receive: function() {
|
||||
receive() {
|
||||
if (!FeatureDetector.isPopup && !FeatureDetector.isStandalone) {
|
||||
return false;
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ const AuthReceiver = {
|
|||
}
|
||||
},
|
||||
|
||||
urlArgsToMessage: function(url) {
|
||||
urlArgsToMessage(url) {
|
||||
const message = {};
|
||||
url.split(/[?#&]/g).forEach(part => {
|
||||
const parts = part.split('=');
|
||||
|
|
|
@ -5,7 +5,7 @@ const AppSettingsModel = require('../models/app-settings-model');
|
|||
const CopyPaste = {
|
||||
simpleCopy: !!(Launcher && Launcher.clipboardSupported),
|
||||
|
||||
copy: function(text) {
|
||||
copy(text) {
|
||||
if (this.simpleCopy) {
|
||||
Launcher.setClipboardText(text);
|
||||
const clipboardSeconds = AppSettingsModel.instance.get('clipboardSeconds');
|
||||
|
@ -32,7 +32,7 @@ const CopyPaste = {
|
|||
}
|
||||
},
|
||||
|
||||
createHiddenInput: function(text) {
|
||||
createHiddenInput(text) {
|
||||
const hiddenInput = $('<input/>')
|
||||
.val(text)
|
||||
.attr({ type: 'text', 'class': 'hide-by-pos' })
|
||||
|
@ -41,10 +41,10 @@ const CopyPaste = {
|
|||
hiddenInput[0].selectionEnd = text.length;
|
||||
hiddenInput.focus();
|
||||
hiddenInput.on({
|
||||
'copy cut paste': function() {
|
||||
'copy cut paste'() {
|
||||
setTimeout(() => hiddenInput.blur(), 0);
|
||||
},
|
||||
blur: function() {
|
||||
blur() {
|
||||
hiddenInput.remove();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -2,13 +2,13 @@ const AppSettingsModel = require('../models/app-settings-model');
|
|||
|
||||
const ExportApi = {
|
||||
settings: {
|
||||
get: function(key) {
|
||||
get(key) {
|
||||
return key ? AppSettingsModel.instance.get(key) : AppSettingsModel.instance.toJSON();
|
||||
},
|
||||
set: function(key, value) {
|
||||
set(key, value) {
|
||||
AppSettingsModel.instance.set(key, value);
|
||||
},
|
||||
del: function(key) {
|
||||
del(key) {
|
||||
AppSettingsModel.instance.unset(key);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -159,7 +159,7 @@ const GeneratorPresets = {
|
|||
this.save(setting);
|
||||
},
|
||||
|
||||
save: function(setting) {
|
||||
save(setting) {
|
||||
AppSettingsModel.instance.unset('generatorPresets', { silent: true });
|
||||
AppSettingsModel.instance.set('generatorPresets', setting);
|
||||
}
|
||||
|
|
|
@ -3,17 +3,17 @@ const AppSettingsModel = require('../models/app-settings-model');
|
|||
|
||||
const IdleTracker = {
|
||||
actionTime: Date.now(),
|
||||
init: function() {
|
||||
init() {
|
||||
setInterval(this.checkIdle.bind(this), 1000 * 60);
|
||||
},
|
||||
checkIdle: function() {
|
||||
checkIdle() {
|
||||
const idleMinutes = (Date.now() - this.actionTime) / 1000 / 60;
|
||||
const maxIdleMinutes = AppSettingsModel.instance.get('idleMinutes');
|
||||
if (maxIdleMinutes && idleMinutes > maxIdleMinutes) {
|
||||
Backbone.trigger('user-idle');
|
||||
}
|
||||
},
|
||||
regUserAction: function() {
|
||||
regUserAction() {
|
||||
this.actionTime = Date.now();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -11,7 +11,7 @@ const KeyHandler = {
|
|||
shortcuts: {},
|
||||
modal: false,
|
||||
|
||||
init: function() {
|
||||
init() {
|
||||
$(document).bind('keypress', this.keypress.bind(this));
|
||||
$(document).bind('keydown', this.keydown.bind(this));
|
||||
|
||||
|
@ -25,33 +25,33 @@ const KeyHandler = {
|
|||
}
|
||||
];
|
||||
},
|
||||
onKey: function(key, handler, thisArg, shortcut, modal, noPrevent) {
|
||||
onKey(key, handler, thisArg, shortcut, modal, noPrevent) {
|
||||
let keyShortcuts = this.shortcuts[key];
|
||||
if (!keyShortcuts) {
|
||||
this.shortcuts[key] = keyShortcuts = [];
|
||||
}
|
||||
keyShortcuts.push({
|
||||
handler: handler,
|
||||
thisArg: thisArg,
|
||||
shortcut: shortcut,
|
||||
modal: modal,
|
||||
noPrevent: noPrevent
|
||||
handler,
|
||||
thisArg,
|
||||
shortcut,
|
||||
modal,
|
||||
noPrevent
|
||||
});
|
||||
},
|
||||
offKey: function(key, handler, thisArg) {
|
||||
offKey(key, handler, thisArg) {
|
||||
if (this.shortcuts[key]) {
|
||||
this.shortcuts[key] = _.reject(this.shortcuts[key], sh => {
|
||||
return sh.handler === handler && sh.thisArg === thisArg;
|
||||
});
|
||||
}
|
||||
},
|
||||
setModal: function(modal) {
|
||||
setModal(modal) {
|
||||
this.modal = modal;
|
||||
},
|
||||
isActionKey: function(e) {
|
||||
isActionKey(e) {
|
||||
return e[shortcutKeyProp];
|
||||
},
|
||||
keydown: function(e) {
|
||||
keydown(e) {
|
||||
IdleTracker.regUserAction();
|
||||
const code = e.keyCode || e.which;
|
||||
const keyShortcuts = this.shortcuts[code];
|
||||
|
@ -94,7 +94,7 @@ const KeyHandler = {
|
|||
}
|
||||
}
|
||||
},
|
||||
keypress: function(e) {
|
||||
keypress(e) {
|
||||
if (
|
||||
!this.modal &&
|
||||
e.charCode !== Keys.DOM_VK_RETURN &&
|
||||
|
@ -109,10 +109,10 @@ const KeyHandler = {
|
|||
this.trigger('keypress:' + this.modal, e);
|
||||
}
|
||||
},
|
||||
reg: function() {
|
||||
reg() {
|
||||
IdleTracker.regUserAction();
|
||||
},
|
||||
handleAKey: function(e) {
|
||||
handleAKey(e) {
|
||||
if (
|
||||
e.target.tagName.toLowerCase() === 'input' &&
|
||||
['password', 'text'].indexOf(e.target.type) >= 0
|
||||
|
|
|
@ -8,7 +8,7 @@ const Launcher = {
|
|||
autoTypeSupported: false,
|
||||
thirdPartyStoragesSupported: false,
|
||||
clipboardSupported: false,
|
||||
ready: function(callback) {
|
||||
ready(callback) {
|
||||
document.addEventListener('deviceready', callback, false);
|
||||
document.addEventListener(
|
||||
'pause',
|
||||
|
@ -18,40 +18,40 @@ const Launcher = {
|
|||
false
|
||||
);
|
||||
},
|
||||
platform: function() {
|
||||
platform() {
|
||||
return 'cordova';
|
||||
},
|
||||
openLink: function(href) {
|
||||
openLink(href) {
|
||||
window.open(href, '_system');
|
||||
},
|
||||
devTools: false,
|
||||
// openDevTools: function() { },
|
||||
getSaveFileName: function(defaultPath, callback) {
|
||||
getSaveFileName(defaultPath, callback) {
|
||||
/* skip in cordova */
|
||||
},
|
||||
getDataPath: function() {
|
||||
getDataPath(...args) {
|
||||
const storagePath = window.cordova.file.externalDataDirectory;
|
||||
return [storagePath].concat(Array.from(arguments)).filter(s => !!s);
|
||||
return [storagePath].concat(Array.from(args)).filter(s => !!s);
|
||||
},
|
||||
getUserDataPath: function(fileName) {
|
||||
getUserDataPath(fileName) {
|
||||
return this.getDataPath('userdata', fileName).join('/');
|
||||
},
|
||||
getTempPath: function(fileName) {
|
||||
getTempPath(fileName) {
|
||||
return this.getDataPath('temp', fileName).join('/');
|
||||
},
|
||||
getDocumentsPath: function(fileName) {
|
||||
getDocumentsPath(fileName) {
|
||||
return this.getDataPath('documents', fileName).join('/');
|
||||
},
|
||||
getAppPath: function(fileName) {
|
||||
getAppPath(fileName) {
|
||||
return this.getDataPath(fileName).join('/');
|
||||
},
|
||||
getWorkDirPath: function(fileName) {
|
||||
getWorkDirPath(fileName) {
|
||||
return this.getDataPath(fileName).join('/');
|
||||
},
|
||||
joinPath: function(...parts) {
|
||||
joinPath(...parts) {
|
||||
return [...parts].join('/');
|
||||
},
|
||||
writeFile: function(path, data, callback) {
|
||||
writeFile(path, data, callback) {
|
||||
const createFile = filePath => {
|
||||
window.resolveLocalFileSystemURL(
|
||||
filePath.dir,
|
||||
|
@ -82,7 +82,7 @@ const Launcher = {
|
|||
});
|
||||
}
|
||||
},
|
||||
readFile: function(path, encoding, callback) {
|
||||
readFile(path, encoding, callback) {
|
||||
window.resolveLocalFileSystemURL(
|
||||
path,
|
||||
fileEntry => {
|
||||
|
@ -104,10 +104,10 @@ const Launcher = {
|
|||
err => callback(undefined, err)
|
||||
);
|
||||
},
|
||||
fileExists: function(path, callback) {
|
||||
fileExists(path, callback) {
|
||||
window.resolveLocalFileSystemURL(path, fileEntry => callback(true), () => callback(false));
|
||||
},
|
||||
deleteFile: function(path, callback) {
|
||||
deleteFile(path, callback) {
|
||||
window.resolveLocalFileSystemURL(
|
||||
path,
|
||||
fileEntry => {
|
||||
|
@ -116,7 +116,7 @@ const Launcher = {
|
|||
callback
|
||||
);
|
||||
},
|
||||
statFile: function(path, callback) {
|
||||
statFile(path, callback) {
|
||||
window.resolveLocalFileSystemURL(
|
||||
path,
|
||||
fileEntry => {
|
||||
|
@ -133,7 +133,7 @@ const Launcher = {
|
|||
err => callback(undefined, err)
|
||||
);
|
||||
},
|
||||
mkdir: function(dir, callback) {
|
||||
mkdir(dir, callback) {
|
||||
const basePath = this.getDataPath().join('/');
|
||||
const createDir = (dirEntry, path, callback) => {
|
||||
const name = path.shift();
|
||||
|
@ -169,7 +169,7 @@ const Launcher = {
|
|||
callback();
|
||||
}
|
||||
},
|
||||
parsePath: function(fileName) {
|
||||
parsePath(fileName) {
|
||||
const parts = fileName.split('/');
|
||||
|
||||
return {
|
||||
|
@ -178,64 +178,64 @@ const Launcher = {
|
|||
dir: parts.join('/')
|
||||
};
|
||||
},
|
||||
createFsWatcher: function(path) {
|
||||
createFsWatcher(path) {
|
||||
return null; // not in android with content provider
|
||||
},
|
||||
// ensureRunnable: function(path) { },
|
||||
|
||||
preventExit: function(e) {
|
||||
preventExit(e) {
|
||||
e.returnValue = false;
|
||||
return false;
|
||||
},
|
||||
exit: function() {
|
||||
exit() {
|
||||
this.hideApp();
|
||||
},
|
||||
|
||||
requestExit: function() {
|
||||
requestExit() {
|
||||
/* skip in cordova */
|
||||
},
|
||||
requestRestart: function() {
|
||||
requestRestart() {
|
||||
window.location.reload();
|
||||
},
|
||||
cancelRestart: function() {
|
||||
cancelRestart() {
|
||||
/* skip in cordova */
|
||||
},
|
||||
|
||||
setClipboardText: function(text) {},
|
||||
getClipboardText: function() {},
|
||||
clearClipboardText: function() {},
|
||||
setClipboardText(text) {},
|
||||
getClipboardText() {},
|
||||
clearClipboardText() {},
|
||||
|
||||
minimizeApp: function() {
|
||||
minimizeApp() {
|
||||
this.hideApp();
|
||||
},
|
||||
canMinimize: function() {
|
||||
canMinimize() {
|
||||
return false;
|
||||
},
|
||||
canDetectOsSleep: function() {
|
||||
canDetectOsSleep() {
|
||||
return false;
|
||||
},
|
||||
updaterEnabled: function() {
|
||||
updaterEnabled() {
|
||||
return false;
|
||||
},
|
||||
|
||||
// getMainWindow: function() { },
|
||||
resolveProxy: function(url, callback) {
|
||||
resolveProxy(url, callback) {
|
||||
/* skip in cordova */
|
||||
},
|
||||
openWindow: function(opts) {
|
||||
openWindow(opts) {
|
||||
/* skip in cordova */
|
||||
},
|
||||
hideApp: function() {
|
||||
hideApp() {
|
||||
/* skip in cordova */
|
||||
},
|
||||
isAppFocused: function() {
|
||||
isAppFocused() {
|
||||
return false; /* skip in cordova */
|
||||
},
|
||||
showMainWindow: function() {
|
||||
showMainWindow() {
|
||||
/* skip in cordova */
|
||||
},
|
||||
// spawn: function(config) { },
|
||||
openFileChooser: function(callback) {
|
||||
openFileChooser(callback) {
|
||||
const onFileSelected = function(selected) {
|
||||
window.resolveLocalFileSystemURL(selected.uri, fileEntry => {
|
||||
fileEntry.file(file => {
|
||||
|
@ -261,7 +261,7 @@ const Launcher = {
|
|||
clientId: 'keeweb'
|
||||
},
|
||||
|
||||
register: function(fileId, password, callback) {
|
||||
register(fileId, password, callback) {
|
||||
FingerprintAuth.isAvailable(result => {
|
||||
if (!result.isAvailable) {
|
||||
return;
|
||||
|
@ -278,14 +278,14 @@ const Launcher = {
|
|||
});
|
||||
},
|
||||
|
||||
auth: function(fileId, token, callback) {
|
||||
auth(fileId, token, callback) {
|
||||
if (!token) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
const decryptConfig = _.extend({}, this.config, {
|
||||
username: fileId,
|
||||
token: token
|
||||
token
|
||||
});
|
||||
|
||||
FingerprintAuth.decrypt(decryptConfig, result => {
|
||||
|
|
|
@ -11,28 +11,28 @@ const Launcher = {
|
|||
thirdPartyStoragesSupported: true,
|
||||
clipboardSupported: true,
|
||||
req: window.require,
|
||||
platform: function() {
|
||||
platform() {
|
||||
return process.platform;
|
||||
},
|
||||
electron: function() {
|
||||
electron() {
|
||||
return this.req('electron');
|
||||
},
|
||||
remoteApp: function() {
|
||||
remoteApp() {
|
||||
return this.electron().remote.app;
|
||||
},
|
||||
remReq: function(mod) {
|
||||
remReq(mod) {
|
||||
return this.electron().remote.require(mod);
|
||||
},
|
||||
openLink: function(href) {
|
||||
openLink(href) {
|
||||
this.electron().shell.openExternal(href);
|
||||
},
|
||||
devTools: true,
|
||||
openDevTools: function() {
|
||||
openDevTools() {
|
||||
this.electron()
|
||||
.remote.getCurrentWindow()
|
||||
.openDevTools({ mode: 'bottom' });
|
||||
},
|
||||
getSaveFileName: function(defaultPath, callback) {
|
||||
getSaveFileName(defaultPath, callback) {
|
||||
if (defaultPath) {
|
||||
const homePath = this.remReq('electron').app.getPath('userDesktop');
|
||||
defaultPath = this.joinPath(homePath, defaultPath);
|
||||
|
@ -40,13 +40,13 @@ const Launcher = {
|
|||
this.remReq('electron').dialog.showSaveDialog(
|
||||
{
|
||||
title: Locale.launcherSave,
|
||||
defaultPath: defaultPath,
|
||||
defaultPath,
|
||||
filters: [{ name: Locale.launcherFileFilter, extensions: ['kdbx'] }]
|
||||
},
|
||||
callback
|
||||
);
|
||||
},
|
||||
getUserDataPath: function(fileName) {
|
||||
getUserDataPath(fileName) {
|
||||
if (!this.userDataPath) {
|
||||
const realUserDataPath = this.remoteApp().getPath('userData');
|
||||
const suffixReplacementRegex = /[\\/]temp[\\/]\d+\.\d+[\\/]?$/;
|
||||
|
@ -54,42 +54,42 @@ const Launcher = {
|
|||
}
|
||||
return this.joinPath(this.userDataPath, fileName || '');
|
||||
},
|
||||
getTempPath: function(fileName) {
|
||||
getTempPath(fileName) {
|
||||
return this.joinPath(this.remoteApp().getPath('temp'), fileName || '');
|
||||
},
|
||||
getDocumentsPath: function(fileName) {
|
||||
getDocumentsPath(fileName) {
|
||||
return this.joinPath(this.remoteApp().getPath('documents'), fileName || '');
|
||||
},
|
||||
getAppPath: function(fileName) {
|
||||
getAppPath(fileName) {
|
||||
const dirname = this.req('path').dirname;
|
||||
const appPath = __dirname.endsWith('app.asar') ? __dirname : this.remoteApp().getAppPath();
|
||||
return this.joinPath(dirname(appPath), fileName || '');
|
||||
},
|
||||
getWorkDirPath: function(fileName) {
|
||||
getWorkDirPath(fileName) {
|
||||
return this.joinPath(process.cwd(), fileName || '');
|
||||
},
|
||||
joinPath: function(...parts) {
|
||||
joinPath(...parts) {
|
||||
return this.req('path').join(...parts);
|
||||
},
|
||||
writeFile: function(path, data, callback) {
|
||||
writeFile(path, data, callback) {
|
||||
this.req('fs').writeFile(path, window.Buffer.from(data), callback);
|
||||
},
|
||||
readFile: function(path, encoding, callback) {
|
||||
readFile(path, encoding, callback) {
|
||||
this.req('fs').readFile(path, encoding, (err, contents) => {
|
||||
const data = typeof contents === 'string' ? contents : new Uint8Array(contents);
|
||||
callback(data, err);
|
||||
});
|
||||
},
|
||||
fileExists: function(path, callback) {
|
||||
fileExists(path, callback) {
|
||||
this.req('fs').exists(path, callback);
|
||||
},
|
||||
deleteFile: function(path, callback) {
|
||||
deleteFile(path, callback) {
|
||||
this.req('fs').unlink(path, callback || _.noop);
|
||||
},
|
||||
statFile: function(path, callback) {
|
||||
statFile(path, callback) {
|
||||
this.req('fs').stat(path, (err, stats) => callback(stats, err));
|
||||
},
|
||||
mkdir: function(dir, callback) {
|
||||
mkdir(dir, callback) {
|
||||
const fs = this.req('fs');
|
||||
const path = this.req('path');
|
||||
const stack = [];
|
||||
|
@ -120,7 +120,7 @@ const Launcher = {
|
|||
|
||||
collect(dir, stack, () => create(stack, callback));
|
||||
},
|
||||
parsePath: function(fileName) {
|
||||
parsePath(fileName) {
|
||||
const path = this.req('path');
|
||||
return {
|
||||
path: fileName,
|
||||
|
@ -128,10 +128,10 @@ const Launcher = {
|
|||
file: path.basename(fileName)
|
||||
};
|
||||
},
|
||||
createFsWatcher: function(path) {
|
||||
createFsWatcher(path) {
|
||||
return this.req('fs').watch(path, { persistent: false });
|
||||
},
|
||||
ensureRunnable: function(path) {
|
||||
ensureRunnable(path) {
|
||||
if (process.platform !== 'win32') {
|
||||
const fs = this.req('fs');
|
||||
const stat = fs.statSync(path);
|
||||
|
@ -142,15 +142,15 @@ const Launcher = {
|
|||
}
|
||||
}
|
||||
},
|
||||
preventExit: function(e) {
|
||||
preventExit(e) {
|
||||
e.returnValue = false;
|
||||
return false;
|
||||
},
|
||||
exit: function() {
|
||||
exit() {
|
||||
this.exitRequested = true;
|
||||
this.requestExit();
|
||||
},
|
||||
requestExit: function() {
|
||||
requestExit() {
|
||||
const app = this.remoteApp();
|
||||
if (this.restartPending) {
|
||||
app.restartApp();
|
||||
|
@ -158,38 +158,38 @@ const Launcher = {
|
|||
app.quit();
|
||||
}
|
||||
},
|
||||
requestRestart: function() {
|
||||
requestRestart() {
|
||||
this.restartPending = true;
|
||||
this.requestExit();
|
||||
},
|
||||
cancelRestart: function() {
|
||||
cancelRestart() {
|
||||
this.restartPending = false;
|
||||
},
|
||||
setClipboardText: function(text) {
|
||||
setClipboardText(text) {
|
||||
return this.electron().clipboard.writeText(text);
|
||||
},
|
||||
getClipboardText: function() {
|
||||
getClipboardText() {
|
||||
return this.electron().clipboard.readText();
|
||||
},
|
||||
clearClipboardText: function() {
|
||||
clearClipboardText() {
|
||||
return this.electron().clipboard.clear();
|
||||
},
|
||||
minimizeApp: function() {
|
||||
minimizeApp() {
|
||||
this.remoteApp().minimizeApp();
|
||||
},
|
||||
canMinimize: function() {
|
||||
canMinimize() {
|
||||
return process.platform !== 'darwin';
|
||||
},
|
||||
canDetectOsSleep: function() {
|
||||
canDetectOsSleep() {
|
||||
return process.platform !== 'linux';
|
||||
},
|
||||
updaterEnabled: function() {
|
||||
updaterEnabled() {
|
||||
return this.electron().remote.process.argv.indexOf('--disable-updater') === -1;
|
||||
},
|
||||
getMainWindow: function() {
|
||||
getMainWindow() {
|
||||
return this.remoteApp().getMainWindow();
|
||||
},
|
||||
resolveProxy: function(url, callback) {
|
||||
resolveProxy(url, callback) {
|
||||
const window = this.getMainWindow();
|
||||
const session = window.webContents.session;
|
||||
session.resolveProxy(url, proxy => {
|
||||
|
@ -198,10 +198,10 @@ const Launcher = {
|
|||
callback(proxy);
|
||||
});
|
||||
},
|
||||
openWindow: function(opts) {
|
||||
openWindow(opts) {
|
||||
return this.remoteApp().openWindow(opts);
|
||||
},
|
||||
hideApp: function() {
|
||||
hideApp() {
|
||||
const app = this.remoteApp();
|
||||
if (this.canMinimize()) {
|
||||
app.minimizeThenHideIfInTray();
|
||||
|
@ -209,16 +209,16 @@ const Launcher = {
|
|||
app.hide();
|
||||
}
|
||||
},
|
||||
isAppFocused: function() {
|
||||
isAppFocused() {
|
||||
return !!this.electron().remote.BrowserWindow.getFocusedWindow();
|
||||
},
|
||||
showMainWindow: function() {
|
||||
showMainWindow() {
|
||||
const win = this.getMainWindow();
|
||||
win.show();
|
||||
win.focus();
|
||||
win.restore();
|
||||
},
|
||||
spawn: function(config) {
|
||||
spawn(config) {
|
||||
const ts = logger.ts();
|
||||
let complete = config.complete;
|
||||
const ps = this.req('child_process').spawn(config.cmd, config.args);
|
||||
|
|
|
@ -13,7 +13,7 @@ const OtpQrReader = {
|
|||
|
||||
fileInput: null,
|
||||
|
||||
read: function() {
|
||||
read() {
|
||||
let screenshotKey = FeatureDetector.screenshotToClipboardShortcut();
|
||||
if (screenshotKey) {
|
||||
screenshotKey = Locale.detSetupOtpAlertBodyWith.replace(
|
||||
|
@ -51,8 +51,8 @@ const OtpQrReader = {
|
|||
esc: '',
|
||||
click: '',
|
||||
enter: '',
|
||||
buttons: buttons,
|
||||
complete: function(res) {
|
||||
buttons,
|
||||
complete(res) {
|
||||
OtpQrReader.alert = null;
|
||||
OtpQrReader.stopListenClipboard();
|
||||
if (res === 'select') {
|
||||
|
@ -68,7 +68,7 @@ const OtpQrReader = {
|
|||
// transparent: true }).show();
|
||||
},
|
||||
|
||||
selectFile: function() {
|
||||
selectFile() {
|
||||
if (!OtpQrReader.fileInput) {
|
||||
const input = document.createElement('input');
|
||||
input.setAttribute('type', 'file');
|
||||
|
@ -81,7 +81,7 @@ const OtpQrReader = {
|
|||
OtpQrReader.fileInput.click();
|
||||
},
|
||||
|
||||
fileSelected: function() {
|
||||
fileSelected() {
|
||||
const file = OtpQrReader.fileInput.files[0];
|
||||
if (!file || file.type.indexOf('image') < 0) {
|
||||
return;
|
||||
|
@ -89,15 +89,15 @@ const OtpQrReader = {
|
|||
OtpQrReader.readFile(file);
|
||||
},
|
||||
|
||||
startListenClipoard: function() {
|
||||
startListenClipoard() {
|
||||
document.addEventListener('paste', OtpQrReader.pasteEvent);
|
||||
},
|
||||
|
||||
stopListenClipboard: function() {
|
||||
stopListenClipboard() {
|
||||
document.removeEventListener('paste', OtpQrReader.pasteEvent);
|
||||
},
|
||||
|
||||
pasteEvent: function(e) {
|
||||
pasteEvent(e) {
|
||||
const item = _.find(
|
||||
e.clipboardData.items,
|
||||
item => item.kind === 'file' && item.type.indexOf('image') !== -1
|
||||
|
@ -115,7 +115,7 @@ const OtpQrReader = {
|
|||
OtpQrReader.readFile(item.getAsFile());
|
||||
},
|
||||
|
||||
readFile: function(file) {
|
||||
readFile(file) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = function() {
|
||||
logger.debug('Image data loaded');
|
||||
|
@ -124,7 +124,7 @@ const OtpQrReader = {
|
|||
reader.readAsDataURL(file);
|
||||
},
|
||||
|
||||
readQr: function(imageData) {
|
||||
readQr(imageData) {
|
||||
const image = new Image();
|
||||
image.onload = function() {
|
||||
logger.debug('Image format loaded');
|
||||
|
@ -167,11 +167,11 @@ const OtpQrReader = {
|
|||
image.src = imageData;
|
||||
},
|
||||
|
||||
enterManually: function() {
|
||||
enterManually() {
|
||||
OtpQrReader.trigger('enter-manually');
|
||||
},
|
||||
|
||||
removeAlert: function() {
|
||||
removeAlert() {
|
||||
if (OtpQrReader.alert) {
|
||||
OtpQrReader.alert.closeImmediate();
|
||||
}
|
||||
|
|
|
@ -10,15 +10,15 @@ const Logger = require('../util/logger');
|
|||
const PopupNotifier = {
|
||||
logger: null,
|
||||
|
||||
init: function() {
|
||||
init() {
|
||||
this.logger = new Logger('popup-notifier');
|
||||
|
||||
if (Launcher) {
|
||||
window.open = this._openLauncherWindow.bind(this);
|
||||
} else {
|
||||
const windowOpen = window.open;
|
||||
window.open = function() {
|
||||
const win = windowOpen.apply(window, arguments);
|
||||
window.open = function(...args) {
|
||||
const win = windowOpen.apply(window, args);
|
||||
if (win) {
|
||||
PopupNotifier.deferCheckClosed(win);
|
||||
Backbone.trigger('popup-opened', win);
|
||||
|
@ -35,7 +35,7 @@ const PopupNotifier = {
|
|||
}
|
||||
},
|
||||
|
||||
_openLauncherWindow: function(url, title, settings) {
|
||||
_openLauncherWindow(url, title, settings) {
|
||||
const opts = {
|
||||
show: false,
|
||||
webPreferences: {
|
||||
|
@ -128,7 +128,7 @@ const PopupNotifier = {
|
|||
);
|
||||
},
|
||||
|
||||
processReturnToApp: function(url) {
|
||||
processReturnToApp(url) {
|
||||
const returnMessage = AuthReceiver.urlArgsToMessage(url);
|
||||
if (Object.keys(returnMessage).length > 0) {
|
||||
const evt = new Event('message');
|
||||
|
@ -137,11 +137,11 @@ const PopupNotifier = {
|
|||
}
|
||||
},
|
||||
|
||||
deferCheckClosed: function(win) {
|
||||
deferCheckClosed(win) {
|
||||
setTimeout(PopupNotifier.checkClosed.bind(PopupNotifier, win), Timeouts.CheckWindowClosed);
|
||||
},
|
||||
|
||||
checkClosed: function(win) {
|
||||
checkClosed(win) {
|
||||