diff --git a/docs/plugins.json b/docs/plugins.json index 11ed7b5..f1ce17e 100644 --- a/docs/plugins.json +++ b/docs/plugins.json @@ -668,27 +668,6 @@ "publicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnRq2k3TTx0ewTe6wDr6QVeB5diwiIWzsJD+ApfZu1KNPedcAgslAfjpNsYF1if6cYsPMJH70xJ2np6RQBl1VPdwShOuxkD7m0BD5Hw/Aar8Hdp5cvAdOOMdBO+0DbGeUMy+z66s+oUCJmqVp19T6PkkxbhN08rgtT7v+aFvrbqbO/vlsskbJpH2K2io+e1XmRGPnSr9q4KSqfGbTfe5gLwDIOFd66Z4mb5Utb5wWpsy6Gjh06Yf257AccGD3A1bkTNOyeeX0tqciYBePWMk0icP/aZ6hnErfhnUKf3tOgPLppSHiGcaSKekhChZ2xLUs3U64JwrXSmwHj+TzdO3S0QIDAQAB" } }, - { - "url": "https://plugins.keeweb.info/plugins/haveibeenpwned", - "manifest": { - "version": "0.1.11", - "manifestVersion": "0.1.0", - "name": "haveibeenpwned", - "description": "Check HaveIBeenPwned password database", - "author": { - "name": "Olivier LEVILLAIN", - "email": "olivier.levillain@free.fr", - "url": "https://github.com/leolivier" - }, - "resources": { - "js": "LjFZ6E0K4JagS4VQKjsTNynxv/0hmr7gfJkn9hrtyCjXiibiCJ/cAcxlvS5mia/T1X79NoMt/57+6mklr+BwakVZSVCPVpQ1XQWaN3JNpu3OrWQ8wc2dAui9mdPN91wSrSiOks6ypU6xFHArxUk5M63Md2H1nShBiHpi6McTVv/6/QoYQhhTnztoZJA5CZcZXPVdby9aPzJTwoi24okBggI7fIIfMwE1Hocobq8annyuafGm+/pRMMmVHHG34T3T9+3GSTZ8cRr0q3hOgAN88Eovf3xKQ3/21HUvQtcHPT+YgeWZWWZjM2UvfVMzPU6kF8ks/MfZBZFmLGUc/Zlr5Q==", - "css": "K8gtQONyUe5AMIEa2ozxHvVC4umblP5r6FOdKgX+288Il3m928SquewF9fIqDeeMONtGEQnFpMG60jgP1edEZvBZdjhT3qJySdTUYf7etmjQInY/4/0K18HenixwhW4C6XQm/+M90voHsiKOcZMSY4/uSCmltnI7qaRr3Ag+2+QQXdpMDNQthRCZhgrh3KtO0hHAcGYURRQ2YEfHcfT5JZrl4kpOhJYTTt3Dy0XNnRQaa30qedVY2rCQtAnE870D+MSUpri4BGAGdxz2Wi3BdWUtBPT6wAdoJQWhsIcuRv0f0LIFbjsw1sI52do2oj/dmfJ1lJ3RnEB/ALHDIvx+ew==" - }, - "url": "https://plugins.keeweb.info/plugins/haveibeenpwned", - "publicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnRq2k3TTx0ewTe6wDr6QVeB5diwiIWzsJD+ApfZu1KNPedcAgslAfjpNsYF1if6cYsPMJH70xJ2np6RQBl1VPdwShOuxkD7m0BD5Hw/Aar8Hdp5cvAdOOMdBO+0DbGeUMy+z66s+oUCJmqVp19T6PkkxbhN08rgtT7v+aFvrbqbO/vlsskbJpH2K2io+e1XmRGPnSr9q4KSqfGbTfe5gLwDIOFd66Z4mb5Utb5wWpsy6Gjh06Yf257AccGD3A1bkTNOyeeX0tqciYBePWMk0icP/aZ6hnErfhnUKf3tOgPLppSHiGcaSKekhChZ2xLUs3U64JwrXSmwHj+TzdO3S0QIDAQAB", - "license": "MIT" - } - }, { "url": "https://plugins.keeweb.info/translations/tr", "official": true, @@ -915,4 +894,4 @@ } } ] -} \ No newline at end of file +} diff --git a/docs/plugins/haveibeenpwned/index.html b/docs/plugins/haveibeenpwned/index.html deleted file mode 100644 index 1fcaa60..0000000 --- a/docs/plugins/haveibeenpwned/index.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - KeeWeb Plugin: HaveIBeenPwned - - - - -

KeeWeb Plugin: HaveIBeenPwned

-https://plugins.keeweb.info/plugins/haveibeenpwned -

This plugin checks the HaveIBeenPwned site each time you enter a password to look if it has been pawned in a breach.
- If pawned, it displays a dancing icon looking like this: ';-- near the pawned password
-Note: Passwords is safely checked (only a hash is sent over the network).

-

Since the V3 version of the HaveIBeenPwned API (mid 2019), checking user names is not free anymore -(3.5$/month, see API V3 Key)...
-So user name checking has been disabled in the latest version of this plugin.

-

Freely inspired from the equivalent keepass plugin

- - - diff --git a/docs/plugins/haveibeenpwned/manifest.json b/docs/plugins/haveibeenpwned/manifest.json deleted file mode 100644 index 0b5267c..0000000 --- a/docs/plugins/haveibeenpwned/manifest.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "version": "0.1.11", - "manifestVersion": "0.1.0", - "name": "haveibeenpwned", - "description": "Check HaveIBeenPwned password database", - "author": { - "name": "Olivier LEVILLAIN", - "email": "olivier.levillain@free.fr", - "url": "https://github.com/leolivier" - }, - "resources": { - "js": "LjFZ6E0K4JagS4VQKjsTNynxv/0hmr7gfJkn9hrtyCjXiibiCJ/cAcxlvS5mia/T1X79NoMt/57+6mklr+BwakVZSVCPVpQ1XQWaN3JNpu3OrWQ8wc2dAui9mdPN91wSrSiOks6ypU6xFHArxUk5M63Md2H1nShBiHpi6McTVv/6/QoYQhhTnztoZJA5CZcZXPVdby9aPzJTwoi24okBggI7fIIfMwE1Hocobq8annyuafGm+/pRMMmVHHG34T3T9+3GSTZ8cRr0q3hOgAN88Eovf3xKQ3/21HUvQtcHPT+YgeWZWWZjM2UvfVMzPU6kF8ks/MfZBZFmLGUc/Zlr5Q==", - "css": "K8gtQONyUe5AMIEa2ozxHvVC4umblP5r6FOdKgX+288Il3m928SquewF9fIqDeeMONtGEQnFpMG60jgP1edEZvBZdjhT3qJySdTUYf7etmjQInY/4/0K18HenixwhW4C6XQm/+M90voHsiKOcZMSY4/uSCmltnI7qaRr3Ag+2+QQXdpMDNQthRCZhgrh3KtO0hHAcGYURRQ2YEfHcfT5JZrl4kpOhJYTTt3Dy0XNnRQaa30qedVY2rCQtAnE870D+MSUpri4BGAGdxz2Wi3BdWUtBPT6wAdoJQWhsIcuRv0f0LIFbjsw1sI52do2oj/dmfJ1lJ3RnEB/ALHDIvx+ew==" - }, - "url": "https://plugins.keeweb.info/plugins/haveibeenpwned", - "publicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnRq2k3TTx0ewTe6wDr6QVeB5diwiIWzsJD+ApfZu1KNPedcAgslAfjpNsYF1if6cYsPMJH70xJ2np6RQBl1VPdwShOuxkD7m0BD5Hw/Aar8Hdp5cvAdOOMdBO+0DbGeUMy+z66s+oUCJmqVp19T6PkkxbhN08rgtT7v+aFvrbqbO/vlsskbJpH2K2io+e1XmRGPnSr9q4KSqfGbTfe5gLwDIOFd66Z4mb5Utb5wWpsy6Gjh06Yf257AccGD3A1bkTNOyeeX0tqciYBePWMk0icP/aZ6hnErfhnUKf3tOgPLppSHiGcaSKekhChZ2xLUs3U64JwrXSmwHj+TzdO3S0QIDAQAB", - "license": "MIT" -} diff --git a/docs/plugins/haveibeenpwned/plugin.css b/docs/plugins/haveibeenpwned/plugin.css deleted file mode 100644 index 2d49c90..0000000 --- a/docs/plugins/haveibeenpwned/plugin.css +++ /dev/null @@ -1,20 +0,0 @@ -.hibp-pwned:after{ - content: "';--"; - font: bold 1.2em "Courrier New"; - text-align: center; - background-color: var(--text-color); - background-size:cover; - position: relative; - width:1.5em; - height:1.5em; - animation: hibp-spin 1s linear 0s infinite; - transform-origin: center center; -} -@keyframes hibp-spin { - 0% { transform: rotate(0deg); } - 25% { transform: rotate(10deg); color: var(--error-color); } - 50% { transform: rotate(0deg); } - 75% { transform: rotate(-10deg); color: var(--error-color); } - 100% { transform: rotate(0deg); } -} - diff --git a/docs/plugins/haveibeenpwned/plugin.js b/docs/plugins/haveibeenpwned/plugin.js deleted file mode 100644 index abf88ed..0000000 --- a/docs/plugins/haveibeenpwned/plugin.js +++ /dev/null @@ -1,247 +0,0 @@ -/** - * KeeWeb plugin: haveibeenpwned - * @author Olivier LEVILLAIN - * @license MIT - */ - -const Logger = require('util/logger').Logger; -// change log level here. -const LogLevel = Logger.Level.Info; - -const DetailsView = require('views/details/details-view').DetailsView; -const InputFx = require('util/ui/input-fx').InputFx; -const Kdbxweb = require('kdbxweb'); -const utilFn = require('util/fn'); -const Tip = require('util/ui/tip').Tip; -const detailsViewFieldChanged = DetailsView.prototype.fieldChanged; - -let _seen = []; -class HIBPUtils { - constructor() { - _seen = []; - this.checkPwnedPwd = true; - this.checkPwnedName = true; - this.blockPwnedPwd = false; - this.blockPwnedName = false; - this.logger = new Logger('HaveIBeenPwned'); - this.logger.setLevel(LogLevel); - } - - replacer(key, value) { - if (value != null && typeof value === 'object') { - if (_seen.indexOf(value) >= 0) { - return; - } - _seen.push(value); - } - return value; - } - - stringify(obj) { - const ret = JSON.stringify(obj, this.replacer); - _seen = []; - return ret; - } - - xhrcall(config) { - const xhr = new XMLHttpRequest(); - if (config.responseType) { - xhr.responseType = config.responseType; - } - const statuses = config.statuses || [200]; - xhr.addEventListener('load', () => { - if (statuses.indexOf(xhr.status) >= 0) { - return config.success && config.success(xhr.response, xhr); - } else { - return config.error && config.error('http status ' + xhr.status, xhr); - } - }); - xhr.addEventListener('error', () => { - const err = (xhr.response && xhr.response.error) || new Error('Network error'); - this.logger.error('HaveIBeenPwned API error', 'GET', xhr.status, err); - err.status = xhr.status; - return err; - }); - xhr.addEventListener('timeout', () => { - return config.error && config.error('timeout', xhr); - }); - xhr.open(config.method || 'GET', config.url); - if (config.headers) { - for (const key in config.headers) { - xhr.setRequestHeader(key, config.headers[key]); - } - } - xhr.send(config.data); - } - - hex(buffer) { - const hexCodes = []; - const view = new DataView(buffer); - for (let i = 0; i < view.byteLength; i += 4) { - // Using getUint32 reduces the number of iterations needed (we process 4 bytes each time) - const value = view.getUint32(i); - // toString(16) will give the hex representation of the number without padding - const stringValue = value.toString(16); - // We use concatenation and slice for padding - const padding = '00000000'; - const paddedValue = (padding + stringValue).slice(-padding.length); - hexCodes.push(paddedValue); - } - // Join all the hex strings into one - return hexCodes.join(''); - } - - digest(algo, str) { - const buffer = Kdbxweb.ByteUtils.stringToBytes(str); - const subtle = window.crypto.subtle || window.crypto.webkitSubtle; - const _self = this; - return subtle.digest(algo, buffer).then((hash) => { - return _self.hex(hash); - }); - } - - sha1(str) { - return this.digest('SHA-1', str); - } - - sha256(str) { - return this.digest('SHA-256', str); - } - - alert(el, msg) { - // Alerts.info({ body: msg, title: 'HaveIBeenPwned' }); - el.focus(); - el.addClass('input--error'); - el.addClass('hibp-pwned'); - Tip.createTip(el, { title: msg, placement: 'bottom' }); - InputFx.shake(el); - } - - passed(el, msg) { - hibp.logger.info(msg); - el.removeClass('input--error'); - el.removeClass('hibp-pwned'); - } -} - -const hibp = new HIBPUtils(); - -DetailsView.prototype.checkNamePwned = function (name) { - hibp.logger.info('check hibp name ' + name); - name = encodeURIComponent(name); - const url = `https://haveibeenpwned.com/api/v2/breachedaccount/${name}?truncateResponse=true`; - hibp.logger.debug('url ' + url); - hibp.xhrcall({ - url: url, - method: 'GET', - responseType: 'json', - data: null, - statuses: [200, 404], - success: (data, xhr) => { - if (data && data.length > 0) { - hibp.logger.debug('found breaches ' + JSON.stringify(data)); - let breaches = ''; - data.forEach((breach) => { - breaches += '
  • ' + utilFn.escape(breach.Name) + '
  • \n'; - }); - hibp.alert( - this.userEditView.$el, - `WARNING! This account has been pawned in the following breaches
    \n\n

    Please check on https://haveibeenpwned.com\n` - ); - } else { - hibp.passed(this.userEditView.$el, 'check pwned user name passed...'); - } - } - }); -}; - -DetailsView.prototype.checkPwdPwned = function (passwordHash) { - hibp.logger.info('check hibp pwd (hash) ' + passwordHash); - const prefix = passwordHash.substring(0, 5); - hibp.xhrcall({ - url: `https://api.pwnedpasswords.com/range/${prefix}`, - method: 'GET', - responseType: 'text', - data: null, - statuses: [200, 404], - success: (data) => { - if (data) { - hibp.logger.debug('found breaches ' + JSON.stringify(data)); - data.split('\r\n').forEach((line) => { - const h = line.split(':'); - const suffix = h[0]; - if (prefix + suffix === passwordHash) { - const nb = utilFn.escape(h[1]); - hibp.alert( - this.getFieldView('$Password').$el, - `WARNING: This password is referenced as pawned ${nb} times on https://haveibeenpwned.com!\n` - ); - } - }); - } else { - hibp.passed(this.userEditView.$el, 'check pwned password passed...'); - } - } - }); -}; - -DetailsView.prototype.fieldChanged = function (e) { - detailsViewFieldChanged.apply(this, arguments); - if (e.field) { - hibp.logger.debug('field changed ' + hibp.stringify(e)); - if (e.field === '$Password' && hibp.checkPwnedPwd) { - if (this.getFieldView('$Password').value) { - const pwd = this.getFieldView('$Password').value.getText(); - if (pwd.replace(/\s/, '') !== '' && !pwd.startsWith('{REF:')) { - hibp.sha1(pwd).then((hash) => { - this.checkPwdPwned(hash.toUpperCase()); - }); - } - } - } else if (e.field === '$UserName' && hibp.checkPwnedName) { - this.checkNamePwned(e.val); - } - } -}; - -module.exports.getSettings = function () { - return [ - { - name: 'checkPwnedPwd', - label: 'Check passwords against HaveIBeenPwned list', - type: 'checkbox', - value: hibp.checkPwnedPwd - // disabled since API V3 of HaveIbeenPwned is not free anymore for checking accounts - // }, { - // name: 'checkPwnedName', - // label: 'Check user ids against HaveIBeenPwned list', - // type: 'checkbox', - // value: hibp.checkPwnedName - }, - { - name: 'blockPwnedPwd', - label: 'Block pwned passwords if they are in HaveIBeenPwned list', - type: 'checkbox', - value: hibp.blockPwnedPwd - // }, { - // name: 'blockPwnedName', - // label: 'Block pwned names if they are in HaveIBeenPwned list', - // type: 'checkbox', - // value: hibp.blockPwnedName - } - ]; -}; -// disabled since API V3 of HaveIbeenPwned is not free anymore for checking accounts -hibp.checkPwnedName = false; -hibp.blockPwnedName = false; - -module.exports.setSettings = function (changes) { - for (const field in changes) { - const ccfield = field.substr(0, 1).toLowerCase() + field.substring(1); - hibp[ccfield] = changes[field]; - } -}; - -module.exports.uninstall = function () { - DetailsView.prototype.fieldChanged = detailsViewFieldChanged; -};