diff options
author | Marius David Wieschollek <passwords.public@mdns.eu> | 2022-03-09 21:32:45 +0300 |
---|---|---|
committer | Marius David Wieschollek <passwords.public@mdns.eu> | 2022-03-09 21:32:45 +0300 |
commit | c93d7f4385a1f69097514e42a684a48d47c403f1 (patch) | |
tree | 1d5039292df691c3d80f21709143d726ce13de46 | |
parent | 7a2eb3e4edb8e7b98969398a66538fe9645c3cfc (diff) |
Add warning for soon deprecated versions of passwords
Signed-off-by: Marius David Wieschollek <passwords.public@mdns.eu>
-rw-r--r-- | src/js/Helper/ServerRequirementCheck.js | 87 | ||||
-rw-r--r-- | src/js/Miner/DomMiner.js | 30 | ||||
-rw-r--r-- | src/js/Models/Server/Server.js | 41 | ||||
-rw-r--r-- | src/platform/generic/_locales/en/messages.json | 22 | ||||
-rw-r--r-- | src/vue/Components/Accounts/Account.vue | 25 |
5 files changed, 177 insertions, 28 deletions
diff --git a/src/js/Helper/ServerRequirementCheck.js b/src/js/Helper/ServerRequirementCheck.js index eceef09..1485b8b 100644 --- a/src/js/Helper/ServerRequirementCheck.js +++ b/src/js/Helper/ServerRequirementCheck.js @@ -11,6 +11,10 @@ export default class ServerRequirementCheck { return [2021, 1]; } + get WARNING_APP_VERSION() { + return [2022, 2]; + } + /** * * @param {PasswordsClient} api @@ -34,6 +38,10 @@ export default class ServerRequirementCheck { if(setting.getValue() === null || !this._versionCompare(setting.getValue())) { if(disable) await this._disableServer(setting.getValue()); return false; + } else if(disable && !this._versionCompare(setting.getValue(), this.WARNING_APP_VERSION)) { + await this._markServerAsSoonIncompatible(setting.getValue()); + } else { + this._removeFlags(disable); } } catch(e) { @@ -53,9 +61,54 @@ export default class ServerRequirementCheck { let server = this._api.getServer(); server.setEnabled(false); server.setStatus(server.STATUS_DISABLED); + server.addFlag(server.FLAG_INCOMPATIBLE); await ServerRepository.update(server); let minVersion = this.MINIMUM_APP_VERSION.join('.'); + ErrorManager.error('Disabled account with unsupported api version', {server: server.getLabel(), version: serverVersion, requiredVersion: minVersion}); + this._sendServerDisabledToast(server, minVersion, serverVersion); + } + + /** + * + * @return {Promise<void>} + * @private + */ + async _markServerAsSoonIncompatible(serverVersion) { + let server = this._api.getServer(); + server.addFlag(server.FLAG_SOON_INCOMPATIBLE); + await ServerRepository.update(server); + + this._sendServerWarningToast(server, this.WARNING_APP_VERSION.join('.'), serverVersion); + } + + /** + * + * @return {Promise<void>} + * @private + */ + async _removeFlags(save) { + let server = this._api.getServer(); + if(server.hasFlag(server.FLAG_SOON_INCOMPATIBLE)) { + server.removeFlag(server.FLAG_SOON_INCOMPATIBLE); + if(save) await ServerRepository.update(server); + } + if(server.hasFlag(server.FLAG_INCOMPATIBLE)) { + server.removeFlag(server.FLAG_INCOMPATIBLE); + server.setEnabled(true); + server.setStatus(server.STATUS_UNAUTHORIZED); + if(save) await ServerRepository.update(server); + } + } + + /** + * + * @param {Server} server + * @param {String} minVersion + * @param {String} serverVersion + * @private + */ + _sendServerDisabledToast(server, minVersion, serverVersion) { let toast = new Toast() .setTitle('ToastServerCheckTitle') .setMessage('ToastServerCheckMessage') @@ -65,20 +118,40 @@ export default class ServerRequirementCheck { .setTags([this._api.getServer().getId(), 'server-error']) .setTtl(0); - ErrorManager.error('Disabled account with unsupported api version', {server: server.getLabel(), version: serverVersion, requiredVersion: minVersion}); + ToastService.create(toast) + .then(() => {SystemService.getBrowserApi().tabs.create({active: true, url: server.getBaseUrl()});}) + .catch(ErrorManager.catch); + } + + /** + * + * @param {Server} server + * @param {String} minVersion + * @param {String} serverVersion + * @private + */ + _sendServerWarningToast(server, minVersion, serverVersion) { + let toast = new Toast() + .setTitle('ToastServerCheckTitle') + .setMessage('ToastServerCheckWarning') + .setTitleVars([server.getLabel()]) + .setMessageVars([server.getLabel(), minVersion, serverVersion]) + .setType('warning') + .setTags([this._api.getServer().getId(), 'server-error']) + .setTtl(0); ToastService.create(toast) - .then(() => {SystemService.getBrowserApi().tabs.create({active: true, url: server.getBaseUrl()});}) - .catch(ErrorManager.catch); + .then(() => {SystemService.getBrowserApi().tabs.create({active: true, url: server.getBaseUrl()});}) + .catch(ErrorManager.catch); } /** - * @param version + * @param {String} version + * @param {Array} base * @return {Boolean} */ - _versionCompare(version) { - let base = this.MINIMUM_APP_VERSION, - parts = version.split('.'); + _versionCompare(version, base = this.MINIMUM_APP_VERSION) { + let parts = version.split('.'); for(let i = 0; i < base.length; i++) { if(!parts.hasOwnProperty(i)) return false; diff --git a/src/js/Miner/DomMiner.js b/src/js/Miner/DomMiner.js index bec8a3d..4d72498 100644 --- a/src/js/Miner/DomMiner.js +++ b/src/js/Miner/DomMiner.js @@ -22,7 +22,7 @@ export default class DomMiner { this._addFormsListener(forms); } else { this._addBodyListener(); - } + } } _addFormsListener(forms) { @@ -47,10 +47,10 @@ export default class DomMiner { _addBodyListener() { const bodyObserver = new MutationObserver((mutations) => { - for (const mutation of mutations) { - if (mutation.type === "childList") { - for (const added of mutation.addedNodes) { - if (new FormService().getPasswordFields(added).length > 0) { + for(const mutation of mutations) { + if(mutation.type === "childList") { + for(const added of mutation.addedNodes) { + if(new FormService().getPasswordFields(added).length > 0) { bodyObserver.disconnect(); this._addFormsListener(new FormService().getLoginFields()); } @@ -58,7 +58,7 @@ export default class DomMiner { } } }); - bodyObserver.observe(document.body, { childList: true, subtree: true }); + bodyObserver.observe(document.body, {childList: true, subtree: true}); } _checkForNewPassword() { @@ -73,18 +73,18 @@ export default class DomMiner { let exists = false; this._knownForms.forEach(element => { if((element.pass === form.pass.value) && - (element.user === form.user.value) && - (element.url === this._getUrl())) { + (element.user === form.user.value) && + (element.url === this._getUrl())) { exists = true; - } - }); + } + }); if(exists === false) { this._knownForms.push( - { - pass: form.pass.value, - user: form.user.value, - url: this._getUrl() - }); + { + pass: form.pass.value, + user: form.user.value, + url : this._getUrl() + }); } return exists; } diff --git a/src/js/Models/Server/Server.js b/src/js/Models/Server/Server.js index 53a09dc..148be68 100644 --- a/src/js/Models/Server/Server.js +++ b/src/js/Models/Server/Server.js @@ -15,6 +15,14 @@ export default class Server extends ServerModel { return 'disabled'; } + get FLAG_INCOMPATIBLE() { + return 'flag_incompatible'; + } + + get FLAG_SOON_INCOMPATIBLE() { + return 'flag_soon_incompatible'; + } + constructor(data) { let status; if(data.hasOwnProperty('status')) { @@ -110,6 +118,39 @@ export default class Server extends ServerModel { return this; } + getFlags() { + return this.getProperty('flags'); + } + + setFlags(value) { + return this.setProperty('flags', value); + } + + addFlag(flag) { + if(!this.hasFlag(flag)) { + let flags = this.getFlags(); + if(!flags) flags = []; + flags.push(flag); + this.setFlags(flags); + } + return this; + } + + removeFlag(flag) { + if(this.hasFlag(flag)) { + let flags = this.getFlags(), + index = flags.indexOf(flag); + flags.splice(index, 1); + this.setFlags(flags); + } + return this; + } + + hasFlag(flag) { + let flags = this.getFlags(); + return Array.isArray(flags) && flags.indexOf(flag) !== -1 + } + toJSON() { let object = super.toJSON(); object.status = this._status; diff --git a/src/platform/generic/_locales/en/messages.json b/src/platform/generic/_locales/en/messages.json index a8cb5be..8337125 100644 --- a/src/platform/generic/_locales/en/messages.json +++ b/src/platform/generic/_locales/en/messages.json @@ -629,11 +629,29 @@ }, "minversion": { "content": "$2", - "example": "2020.1" + "example": "2021.12" }, "serverversion": { "content": "$3", - "example": "2020.3" + "example": "2021.11" + } + } + }, + "ToastServerCheckWarning": { + "message": "This extension will soon require passwords $MINVERSION$, but \"$SERVER$\" uses passwords $SERVERVERSION$. Please update the app in order to keep using the account.", + "description": "Text of the toast notification when an account uses a server which will soon be no longer supported because it uses an outdated and unsupported version of the passwords app", + "placeholders": { + "server": { + "content": "$1", + "example": "My Nextcloud" + }, + "minversion": { + "content": "$2", + "example": "2021.12" + }, + "serverversion": { + "content": "$3", + "example": "2021.11" } } }, diff --git a/src/vue/Components/Accounts/Account.vue b/src/vue/Components/Accounts/Account.vue index 8b679cd..0891b89 100644 --- a/src/vue/Components/Accounts/Account.vue +++ b/src/vue/Components/Accounts/Account.vue @@ -1,8 +1,14 @@ <template> <form class="account-form" v-on:submit.prevent="save()"> - <translate tag="div" class="server-warning" say="ServerDisabledWarning" v-if="!server.getEnabled()"> + <translate tag="div" class="server-error" say="ServerIncompatibleError" v-if="server.hasFlag(server.FLAG_INCOMPATIBLE)"> <icon icon="exclamation-triangle" font="solid" slot="before"/> </translate> + <translate tag="div" class="server-warning" say="ServerSoonIncompatibleWarning" v-if="server.hasFlag(server.FLAG_SOON_INCOMPATIBLE)"> + <icon icon="exclamation-triangle" font="solid" slot="before"/> + </translate> + <translate tag="div" class="server-info" say="ServerDisabledWarning" v-if="!server.getEnabled()"> + <icon icon="exclamation-circle" font="solid" slot="before"/> + </translate> <fieldset :disabled="submitting"> <translate tag="label" :for="`${id}-label`" say="ServerLabel" required/> @@ -138,13 +144,24 @@ <style lang="scss"> .account-form { - .server-warning { - background-color : var(--warning-bg-color); - color : var(--warning-fg-color); + .server-info, + .server-warning, + .server-error { + background-color : var(--info-bg-color); + color : var(--info-fg-color); margin : .5rem; border-radius : 3px; padding : 1rem; + &.server-warning { + background-color : var(--warning-bg-color); + color : var(--warning-fg-color); + } + &.server-error { + background-color : var(--error-bg-color); + color : var(--error-fg-color); + } + .icon { margin-right : .5rem; } |