diff options
author | Marius David Wieschollek <passwords.public@mdns.eu> | 2021-01-09 03:39:15 +0300 |
---|---|---|
committer | Marius David Wieschollek <passwords.public@mdns.eu> | 2021-01-09 03:40:08 +0300 |
commit | 5f6f50fda06ab11e7fd09561892ebcf21f29d308 (patch) | |
tree | dbc207777ee7404fb958b3d3a04aabf8f5cdef7b | |
parent | 75694a4f2ec118e613971b26c81916dca8d40a1d (diff) |
[#69] Implement automatic logout option in settings
Signed-off-by: Marius David Wieschollek <passwords.public@mdns.eu>
-rw-r--r-- | src/js/Controller/Server/Create.js | 10 | ||||
-rw-r--r-- | src/js/Controller/Server/Update.js | 3 | ||||
-rw-r--r-- | src/js/Manager/ServerTimeoutManager.js | 15 | ||||
-rw-r--r-- | src/js/Validation/Server.js | 20 | ||||
-rw-r--r-- | src/platform/generic/_locales/de/messages.json | 22 | ||||
-rw-r--r-- | src/platform/generic/_locales/en/messages.json | 22 | ||||
-rw-r--r-- | src/vue/Components/Accounts/Account.vue | 20 | ||||
-rw-r--r-- | src/vue/Components/Accounts/NewAccount.vue | 8 |
8 files changed, 106 insertions, 14 deletions
diff --git a/src/js/Controller/Server/Create.js b/src/js/Controller/Server/Create.js index fa8cf80..ec85ef7 100644 --- a/src/js/Controller/Server/Create.js +++ b/src/js/Controller/Server/Create.js @@ -1,4 +1,3 @@ -import Server from '@js/Models/Server/Server'; import ServerRepository from '@js/Repositories/ServerRepository'; import ServerManager from '@js/Manager/ServerManager'; import ErrorManager from '@js/Manager/ErrorManager'; @@ -24,8 +23,9 @@ export default class Create extends AbstractController { let server = result.server; if(await this._createServer(server, result)) { - ServerManager.addServer(server) - .catch(ErrorManager.catch); + ServerManager + .addServer(server) + .catch(ErrorManager.catchEvt); reply.setType('server.item').setPayload(server); } else { reply.setType('validation.error').setPayload(result); @@ -41,7 +41,9 @@ export default class Create extends AbstractController { */ async _createServer(server, result) { try { - server.setEnabled(true); + server + .setEnabled(true) + .setTimeout(0); await ServerRepository.create(server); return true; } catch(e) { diff --git a/src/js/Controller/Server/Update.js b/src/js/Controller/Server/Update.js index a29fcb3..29ae932 100644 --- a/src/js/Controller/Server/Update.js +++ b/src/js/Controller/Server/Update.js @@ -48,7 +48,8 @@ export default class Update extends AbstractController { .setUser(server.getUser()) .setToken(server.getToken()) .setLabel(server.getLabel()) - .setBaseUrl(server.getBaseUrl()); + .setBaseUrl(server.getBaseUrl()) + .setTimeout(server.getTimeout()); await ServerRepository.update(realServer); return realServer; diff --git a/src/js/Manager/ServerTimeoutManager.js b/src/js/Manager/ServerTimeoutManager.js index 58228ef..e8a0c71 100644 --- a/src/js/Manager/ServerTimeoutManager.js +++ b/src/js/Manager/ServerTimeoutManager.js @@ -1,6 +1,7 @@ import ErrorManager from "@js/Manager/ErrorManager"; import ApiRepository from "@js/Repositories/ApiRepository"; import ServerManager from "@js/Manager/ServerManager"; +import MessageService from "@js/Services/MessageService"; export default class ServerTimeoutManager { @@ -10,6 +11,11 @@ export default class ServerTimeoutManager { .catch(ErrorManager.catchEvt); }, 5 * 60 * 1000); this._lastInteraction = Date.now(); + this._setUpActivityTriggers(); + } + + trigger() { + this._lastInteraction = Date.now(); } /** @@ -42,4 +48,13 @@ export default class ServerTimeoutManager { } } } + + _setUpActivityTriggers() { + MessageService.listen( + ['popup.status.get', 'popup.status.set', 'options.status', 'setting.set', 'setting.get'], + async (message, reply) => { + this.trigger(); + } + ); + } }
\ No newline at end of file diff --git a/src/js/Validation/Server.js b/src/js/Validation/Server.js index 94fc117..c936dcc 100644 --- a/src/js/Validation/Server.js +++ b/src/js/Validation/Server.js @@ -41,6 +41,7 @@ export default class Server { if(!this._validateUser(data, result.errors)) result.ok = false; if(!this._validateBaseUrl(data, result.errors)) result.ok = false; if(!this._validateToken(data, result.errors)) result.ok = false; + if(!this._validateTimeout(data, result.errors)) result.ok = false; if(!result.ok) { result.message = LocalisationService.translate('ValidationFailed'); @@ -131,6 +132,25 @@ export default class Server { /** * + * @param {Object} data + * @param {Object} errors + * @returns {Boolean} + * @private + */ + _validateTimeout(data, errors) { + if(!data.hasOwnProperty('timeout')) data.timeout = 0; + if(typeof data.timeout === 'string') data.timeout = parseInt(data.timeout); + + if([0, 5*60*1000, 10*60*1000, 15*60*1000, 30*60*1000, 60*60*1000].indexOf(data.timeout) === -1) { + errors.timeout = LocalisationService.translate('ValidationInvalidTimeout'); + return false; + } + + return true; + } + + /** + * * @param {String} field * @param {Object} data * @param {Object} errors diff --git a/src/platform/generic/_locales/de/messages.json b/src/platform/generic/_locales/de/messages.json index 353cba0..9002b9f 100644 --- a/src/platform/generic/_locales/de/messages.json +++ b/src/platform/generic/_locales/de/messages.json @@ -167,6 +167,24 @@ "message" : "Token ändern", "description": "Label of the button to change the login token of an existing account in the account details in the extension settings" }, + "ServerTimeout" : { + "message" : "Automatisch abmelden", + "description": "Label of the option to change the automatic logout time of an existing account in the account details in the extension settings" + }, + "ServerTimeoutOptionNever" : { + "message" : "Nie", + "description": "Label of the option for the server timeout to never expire" + }, + "ServerTimeoutOptionMinutes" : { + "message" : "Nach $MINUTES$ Minuten", + "description": "Label of the option for the server timeout to expire after a given amount of minutes", + "placeholders": { + "minutes": { + "content": "$1", + "example": "One of 5, 10, 15 30 or 60" + } + } + }, "TabRelated" : { "message" : "Vorschläge", "description": "Label of the related passwords tab in the extension popup" @@ -253,6 +271,10 @@ "message" : "Das Token muss ein gültiges Nextcloud-Token sein.", "description": "Validation message when the user attempts to save an account but the token does not match the Nextcloud token schema" }, + "ValidationInvalidTimeout" : { + "message" : "Die Abmeldezeit muss eine der vorgegebenen Optionen sein", + "description": "Validation message when the user attempts to save an account but the timeout is not within the predefined range" + }, "ValidationDuplicate" : { "message" : "Es gibt bereits ein Konto für diesen Benutzer von dieser Nextcloud.", "description": "Validation message when the user attempts to save a new account, but a similar account with the same server and same user name already exists" diff --git a/src/platform/generic/_locales/en/messages.json b/src/platform/generic/_locales/en/messages.json index f651084..a141101 100644 --- a/src/platform/generic/_locales/en/messages.json +++ b/src/platform/generic/_locales/en/messages.json @@ -167,6 +167,24 @@ "message" : "Change Token", "description": "Label of the button to change the login token of an existing account in the account details in the extension settings" }, + "ServerTimeout" : { + "message" : "Logout after", + "description": "Label of the option to change the automatic logout time of an existing account in the account details in the extension settings" + }, + "ServerTimeoutOptionNever" : { + "message" : "Never", + "description": "Label of the option for the server timeout to never expire" + }, + "ServerTimeoutOptionMinutes" : { + "message" : "After $MINUTES$ minutes", + "description": "Label of the option for the server timeout to expire after a given amount of minutes", + "placeholders": { + "minutes": { + "content": "$1", + "example": "One of 5, 10, 15 30 or 60" + } + } + }, "TabRelated" : { "message" : "Suggestions", "description": "Label of the related passwords tab in the extension popup" @@ -267,6 +285,10 @@ "message" : "The token must be a valid Nextcloud token.", "description": "Validation message when the user attempts to save an account but the token does not match the Nextcloud token schema" }, + "ValidationInvalidTimeout" : { + "message" : "The logout time must be one of the given options.", + "description": "Validation message when the user attempts to save an account but the timeout is not within the predefined range" + }, "ValidationDuplicate" : { "message" : "There is already an account for this user on this Nextcloud.", "description": "Validation message when the user attempts to save a new account, but a similar account with the same server and same user name already exists" diff --git a/src/vue/Components/Accounts/Account.vue b/src/vue/Components/Accounts/Account.vue index 0b49dbc..e37dd3b 100644 --- a/src/vue/Components/Accounts/Account.vue +++ b/src/vue/Components/Accounts/Account.vue @@ -17,8 +17,8 @@ required pattern="([A-Za-z0-9]{5}-?){5}" placeholder="xxxxx-xxxxx-xxxxx-xxxxx-xxxxx" v-else/> - <input type="text" :id="`${id}-timeout`" v-model="user"/> - <translate tag="label" :for="`${id}-timeout`" say="ServerTimeout" required/> + <translate tag="label" :for="`${id}-timeout`" say="ServerTimeout" required v-if="lockable"/> + <select-field :options="timeoutOptions" :id="`${id}-timeout`" v-model="timeout" v-if="lockable"/> </fieldset> </form> </template> @@ -31,9 +31,10 @@ import ErrorManager from '@js/Manager/ErrorManager'; import Icon from '@vue/Components/Icon'; import LocalisationService from "@js/Services/LocalisationService"; + import SelectField from "@vue/Components/Form/SelectField"; export default { - components: {Icon, Translate}, + components: {SelectField, Icon, Translate}, props: { server: { @@ -47,6 +48,7 @@ label : this.server.getLabel(), url : this.server.getBaseUrl(), user : this.server.getUser(), + lockable : true || this.server.getLockable(), timeout : this.server.getTimeout(), changeLabel: LocalisationService.translate('ServerTokenChange'), token : '', @@ -55,6 +57,18 @@ }; }, + computed: { + timeoutOptions() { + let options = [{id: 0, label: 'ServerTimeoutOptionNever'}]; + + for(let i of [5, 10, 15, 30, 60]) { + options.push({id: i * 60 * 1000, label: ['ServerTimeoutOptionMinutes', i]}); + } + + return options; + } + }, + methods: { async save() { if(!this.$el.reportValidity() || this.submitting) return; diff --git a/src/vue/Components/Accounts/NewAccount.vue b/src/vue/Components/Accounts/NewAccount.vue index e4c7a45..1aa9842 100644 --- a/src/vue/Components/Accounts/NewAccount.vue +++ b/src/vue/Components/Accounts/NewAccount.vue @@ -15,8 +15,6 @@ required pattern="([A-Za-z0-9]{5}-?){5}" placeholder="xxxxx-xxxxx-xxxxx-xxxxx-xxxxx"/> - <translate tag="label" for="new-timeout" say="ServerTimeout"/> - <input type="text" id="new-timeout" v-model="timeout" required/> </fieldset> </form> </template> @@ -35,8 +33,7 @@ label : '', baseUrl : '', user : '', - token : '', - timeout : 0 + token : '' }; }, @@ -52,8 +49,7 @@ label : this.label, baseUrl: this.baseUrl, user : this.user, - token : this.token, - timeout: this.timeout + token : this.token }; try { |