Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/marius-wieschollek/passwords-webextension.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src/js
diff options
context:
space:
mode:
authorMarius David Wieschollek <passwords.public@mdns.eu>2021-01-17 17:59:15 +0300
committerMarius David Wieschollek <passwords.public@mdns.eu>2021-01-17 17:59:15 +0300
commitbba69b688e7519c3f6580c67ad00015d7fefa8a1 (patch)
tree6e6465e2ad5bf2cea2f5538fad1bc437d2fd165b /src/js
parent60c01cc5aed8112ae5d4e1203b36d08f21c9a857 (diff)
Add local statistics to improve password recommendations
Signed-off-by: Marius David Wieschollek <passwords.public@mdns.eu>
Diffstat (limited to 'src/js')
-rw-r--r--src/js/App/Background.js2
-rw-r--r--src/js/Controller/Password/Fill.js4
-rw-r--r--src/js/Manager/RecommendationManager.js1
-rw-r--r--src/js/Search/Indexer/PasswordIndexer.js10
-rw-r--r--src/js/Search/Query/Field/AbstractField.js2
-rw-r--r--src/js/Search/Query/Sort/AbstractSort.js2
-rw-r--r--src/js/Services/PasswordStatisticsService.js120
7 files changed, 138 insertions, 3 deletions
diff --git a/src/js/App/Background.js b/src/js/App/Background.js
index cea5277..a4e71d7 100644
--- a/src/js/App/Background.js
+++ b/src/js/App/Background.js
@@ -18,6 +18,7 @@ import ThemeRepository from '@js/Repositories/ThemeRepository';
import SettingsService from '@js/Services/SettingsService';
import MasterSettingsProvider from '@js/Settings/MasterSettingsProvider';
import LocalisationService from "@js/Services/LocalisationService";
+import PasswordStatisticsService from "@js/Services/PasswordStatisticsService";
import PassLinkManager from "@js/Manager/PassLinkManager";
class Background {
@@ -41,6 +42,7 @@ class Background {
BadgeManager.init();
ContextMenuManager.init();
MiningManager.init();
+ await PasswordStatisticsService.init();
await ServerManager.init();
await LocalisationService.init();
} catch(e) {
diff --git a/src/js/Controller/Password/Fill.js b/src/js/Controller/Password/Fill.js
index fcc8aa1..13fc853 100644
--- a/src/js/Controller/Password/Fill.js
+++ b/src/js/Controller/Password/Fill.js
@@ -4,7 +4,7 @@ import AbstractController from '@js/Controller/AbstractController';
import TabManager from '@js/Manager/TabManager';
import SettingsService from '@js/Services/SettingsService';
import ErrorManager from '@js/Manager/ErrorManager';
-import ToastService from "@js/Services/ToastService";
+import PasswordStatisticsService from "@js/Services/PasswordStatisticsService";
import Message from "@js/Models/Message/Message";
export default class Fill extends AbstractController {
@@ -24,6 +24,8 @@ export default class Fill extends AbstractController {
TabManager.set('autofill.ids', ids);
}
+ PasswordStatisticsService.registerUse(password.getId()).catch(ErrorManager.catchEvt)
+
try {
let response = await MessageService.send(
{
diff --git a/src/js/Manager/RecommendationManager.js b/src/js/Manager/RecommendationManager.js
index c64b600..02fef78 100644
--- a/src/js/Manager/RecommendationManager.js
+++ b/src/js/Manager/RecommendationManager.js
@@ -78,6 +78,7 @@ class RecommendationManager {
.score(0.3)
.limit(8)
.sortBy('favorite')
+ .sortBy('uses')
.sortBy('shared')
.sortBy('score')
.sortBy('label');
diff --git a/src/js/Search/Indexer/PasswordIndexer.js b/src/js/Search/Indexer/PasswordIndexer.js
index 57a1bba..cce45e3 100644
--- a/src/js/Search/Indexer/PasswordIndexer.js
+++ b/src/js/Search/Indexer/PasswordIndexer.js
@@ -1,5 +1,7 @@
import Url from 'url-parse';
import AbstractIndexer from '@js/Search/Indexer/AbstractIndexer';
+import PasswordStatisticsService from "@js/Services/PasswordStatisticsService";
+import ErrorManager from "@js/Manager/ErrorManager";
export default class PasswordIndexer extends AbstractIndexer {
@@ -28,6 +30,7 @@ export default class PasswordIndexer extends AbstractIndexer {
id : password.getId(),
type : 'password',
hidden : password.isHidden(),
+ uses : 0,
text : [],
tag : [],
folder : [],
@@ -38,6 +41,13 @@ export default class PasswordIndexer extends AbstractIndexer {
fields : {}
};
+ PasswordStatisticsService
+ .getUses(index.id)
+ .then((uses) => {
+ index.uses = uses;
+ })
+ .catch(ErrorManager.catchEvt)
+
this._indexServer(password, index);
this._indexTextFields(password, index);
this._indexFields(password, index);
diff --git a/src/js/Search/Query/Field/AbstractField.js b/src/js/Search/Query/Field/AbstractField.js
index 539f7fb..4efef4e 100644
--- a/src/js/Search/Query/Field/AbstractField.js
+++ b/src/js/Search/Query/Field/AbstractField.js
@@ -43,7 +43,7 @@ export default class AbstractField {
*/
_getFieldValues(item) {
if(item.hasOwnProperty(this._name)) {
- if(this._name === 'id' || this._name === 'type') {
+ if(this._name === 'id' || this._name === 'type' || this._name === 'hidden' || this._name === 'uses') {
return [item[this._name]];
}
diff --git a/src/js/Search/Query/Sort/AbstractSort.js b/src/js/Search/Query/Sort/AbstractSort.js
index 10e97fb..c906ec1 100644
--- a/src/js/Search/Query/Sort/AbstractSort.js
+++ b/src/js/Search/Query/Sort/AbstractSort.js
@@ -41,7 +41,7 @@ export default class AbstractSort {
_getFieldValue(item) {
let values = [];
if(item.hasOwnProperty(this._field)) {
- if(this._field === 'id' || this._field === 'type' || this._field === 'score') {
+ if(this._field === 'id' || this._field === 'type' || this._field === 'score' || this._field === 'hidden' || this._field === 'uses') {
return item[this._field];
}
diff --git a/src/js/Services/PasswordStatisticsService.js b/src/js/Services/PasswordStatisticsService.js
new file mode 100644
index 0000000..6437f2a
--- /dev/null
+++ b/src/js/Services/PasswordStatisticsService.js
@@ -0,0 +1,120 @@
+import ErrorManager from "@js/Manager/ErrorManager";
+
+export default new class PasswordStatisticsService {
+
+ constructor() {
+ this._db = null;
+ }
+
+ /**
+ * @public
+ * @return {Promise<void>}
+ */
+ async init() {
+ if(!window.indexedDB) return;
+
+ return new Promise((resolve, reject) => {
+ let request = window.indexedDB.open('pwd_stats', 1);
+
+ request.onerror = (event) => {
+ // @TODO use custom error here
+ ErrorManager.logError(new Error('Could not open database'), {event});
+ resolve();
+ };
+
+ request.onupgradeneeded = (event) => {
+ let db = event.target.result;
+ db.createObjectStore('uses', {keyPath: 'id'});
+ };
+
+ request.onsuccess = (event) => {
+ this._db = event.target.result;
+ resolve();
+ };
+ });
+ }
+
+ /**
+ * @public
+ * @param {String} id
+ * @return {Promise<void>}
+ */
+ async registerUse(id) {
+ if(this._db === null) return;
+ let hits = 0;
+ if(await this._entryExists(id)) {
+ hits = await this._readEntry(id);
+ }
+
+ hits++;
+
+ await this._writeEntry(id, hits);
+ }
+
+ /**
+ * @public
+ * @param {String} id
+ * @return {Promise<Number>}
+ */
+ async getUses(id) {
+ if(this._db === null) return 0;
+
+ if(await this._entryExists(id)) {
+ return await this._readEntry(id);
+ }
+
+ return 0;
+ }
+
+ /**
+ * @param {String} id
+ * @return {Promise<Boolean>}
+ * @private
+ */
+ async _entryExists(id) {
+ return new Promise((resolve, reject) => {
+ let transaction = this._db.transaction(['uses'], 'readonly'),
+ count = transaction.objectStore('uses').count(IDBKeyRange.only(id));
+
+ count.onsuccess = (e) => {
+ resolve(e.target.result !== 0);
+ };
+
+ count.onerror = reject;
+ });
+ }
+
+ /**
+ * @param {String} id
+ * @return {Promise<Number>}
+ * @private
+ */
+ async _readEntry(id) {
+ return new Promise((resolve, reject) => {
+ let transaction = this._db.transaction(['uses'], 'readonly'),
+ read = transaction.objectStore('uses').get(id);
+
+ read.onsuccess = (e) => {
+ resolve(e.target.result.value);
+ };
+
+ read.onerror = reject;
+ });
+ }
+
+ /**
+ * @param {String} id
+ * @param {Number} value
+ * @return {Promise<void>}
+ * @private
+ */
+ async _writeEntry(id, value) {
+ return new Promise((resolve, reject) => {
+ let transaction = this._db.transaction(['uses'], 'readwrite'),
+ write = transaction.objectStore('uses').put({id, value});
+
+ write.onsuccess = resolve;
+ write.onerror = reject;
+ });
+ }
+}; \ No newline at end of file