From a43988f3cd4ce1cc8e866ed03231f6f5debf4b31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcell=20F=C3=BCl=C3=B6p?= Date: Sun, 12 Jun 2022 12:33:56 +0000 Subject: [PATCH] :construction: Move user processing from widget to mixin plus * some template and style tweaking * improve tooltips * enforce Nextcloud app-password instead of login password --- src/components/Widgets/NextcloudInfo.vue | 86 ++++++++---------------- src/mixins/NextcloudMixin.js | 64 ++++++++++++++---- 2 files changed, 80 insertions(+), 70 deletions(-) diff --git a/src/components/Widgets/NextcloudInfo.vue b/src/components/Widgets/NextcloudInfo.vue index 71f6ae35..6b9c953a 100644 --- a/src/components/Widgets/NextcloudInfo.vue +++ b/src/components/Widgets/NextcloudInfo.vue @@ -11,11 +11,11 @@

{{ branding.name }}

- {{ $t('widgets.nextcloud-info.label-version') }} {{ version.string }} + {{ $t('widgets.nextcloud-info.label-version') }} {{ version.string }}

{{ user.displayName }} ({{ user.id }})

@@ -76,10 +76,10 @@

{{ formatNumber(server.nextcloud.shares.num_shares) }} - {{ $t('shares') }} {{ $t('and') }} + {{ $t('autonomous') }} {{ $t('and') }} - {{ formatNumber(server.nextcloud.shares.num_fed_shares_sent) }} - / {{ formatNumber(server.nextcloud.shares.num_fed_shares_received) }} + {{ formatNumber(server.nextcloud.shares.num_fed_shares_sent + + server.nextcloud.shares.num_fed_shares_received) }} {{ $t('federated shares') }}

@@ -109,7 +109,7 @@ import WidgetMixin from '@/mixins/WidgetMixin'; import NextcloudMixin from '@/mixins/NextcloudMixin'; import { convertBytes } from '@/utils/MiscHelpers'; -// //import { NcdUsr, NcdServer } from '@/utils/ncd'; +// //import { NcdServer } from '@/utils/ncd'; const NextcloudSchema = { branding: { @@ -122,19 +122,6 @@ const NextcloudSchema = { string: null, edition: null, }, - user: { - id: null, - isAdmin: false, - displayName: null, - email: null, - quota: { - relative: null, - total: null, - used: null, - free: null, - quota: null, - }, - }, server: { server: { webserver: null, @@ -213,33 +200,15 @@ export default { }, methods: { async fetchData() { - const promise = this.fetchCapabilities() - .then(() => this.makeRequest(this.endpoint('user'), this.headers)) - // //.then(() => NcdUsr) - .then(this.processUser); - - await promise; - + await this.loadCapabilities(); + await this.loadUser(); if (this.user.isAdmin) { - promise.then(() => this.makeRequest(this.endpoint('serverinfo'), this.headers)) - // //promise.then(() => NcdServer) - .then(this.processServerInfo); + this.processServerInfo( + await this.makeRequest(this.endpoint('serverinfo'), this.headers), + // //NcdServer, + ); } - - promise.finally(() => this.finishLoading()); - }, - processUser(userData) { - const user = userData?.ocs?.data; - if (!user) { - this.error('Invalid response'); - return; - } - this.user.id = user.id; - this.user.email = user.email; - this.user.quota = user.quota; - this.user.displayName = user.displayname; - this.user.lastLogin = user.lastLogin; - this.user.isAdmin = user.groups && user.groups.includes('admin'); + this.finishLoading(); }, processServerInfo(serverData) { const data = serverData?.ocs?.data; @@ -278,10 +247,10 @@ export default { }; }, appUpdatesTooltip() { - const content = 'Updates are available for: ' - + ` ${Object.keys(this.server.nextcloud.system.apps.app_updates).join(', ')}`; + const content = 'Updates are available for:

' + + ` ${Object.entries(this.server.nextcloud.system.apps.app_updates).join('
')}`; return { - content, trigger: 'hover focus', delay: 250, classes: 'nc-tooltip', + content, html: true, trigger: 'hover focus', delay: 250, classes: 'nc-tooltip', }; }, storagesTooltip() { @@ -302,7 +271,9 @@ export default { + `${this.server.nextcloud.shares.num_shares_room} chat room
` + `${this.server.nextcloud.shares.num_shares_link} private link
` + `${this.server.nextcloud.shares.num_shares_link_no_password} public link
` - + '
*Federated shares: sent/received'; + + '
Federated shares:

' + + `${this.server.nextcloud.shares.num_fed_shares_sent} sent
` + + `${this.server.nextcloud.shares.num_fed_shares_received} received
`; return { content, html: true, trigger: 'hover focus', delay: 250, classes: 'nc-tooltip', }; @@ -351,6 +322,9 @@ export default { font-size: 105%; margin-left: .25rem; } + small { + opacity: .66; + } hr { color: var(--widget-text-color); border: none; @@ -376,14 +350,13 @@ export default { margin: 0 0 1rem 0; } p.brand { - margin: 0 0 .23rem 0; + margin: 0; font-size: 135%; font-weight: 800; letter-spacing: 3px; } - p.version { - font-size: 80%; - opacity: .66; + p.version small { + font-size: 75%; } p.username { font-size: 110%; @@ -392,17 +365,16 @@ export default { } } p.login { - font-size: 90%; - small { - opacity: .75; - margin-left: .25rem; + span { + font-size: 90%; + margin-right: .25rem; } } } div.server-info { span[data-has-updates] { color: var(--success); - padding-left: .75rem; + margin-left: 0.5rem; } } } diff --git a/src/mixins/NextcloudMixin.js b/src/mixins/NextcloudMixin.js index 6e040afb..a64f1387 100644 --- a/src/mixins/NextcloudMixin.js +++ b/src/mixins/NextcloudMixin.js @@ -1,6 +1,6 @@ import { serviceEndpoints } from '@/utils/defaults'; import { convertBytes, formatNumber, getTimeAgo } from '@/utils/MiscHelpers'; -// //import { NcdCap } from '@/utils/ncd'; +// //import { NcdCap, NcdUsr } from '@/utils/ncd'; /** Reusable mixin for Nextcloud widgets */ export default { @@ -11,6 +11,19 @@ export default { activity: null, }, capabilitiesLastUpdated: 0, + user: { + id: null, + isAdmin: false, + displayName: null, + email: null, + quota: { + relative: null, + total: null, + used: null, + free: null, + quota: null, + }, + }, }; }, computed: { @@ -24,6 +37,9 @@ export default { }, password() { if (!this.options.password) this.error('An app-password is required'); + if (!/^([a-z0-9]{5}-){4}[a-z0-9]{5}$/i.test(this.options.password)) { + this.error('Please use an app-password for this widget, not your login password.'); + } return this.options.password; }, headers() { @@ -33,6 +49,9 @@ export default { Authorization: `Basic ${window.btoa(`${this.username}:${this.password}`)}`, }; }, + capabilitiesTtl() { + return (parseInt(this.options.capabilitiesTtl, 10) || 3600) * 1000; + }, proxyReqEndpoint() { const baseUrl = process.env.VUE_APP_DOMAIN || window.location.origin; return `${baseUrl}${serviceEndpoints.corsProxy}`; @@ -40,21 +59,23 @@ export default { }, methods: { endpoint(id) { - const endpoints = { - capabilities: `${this.hostname}/ocs/v1.php/cloud/capabilities`, - user: `${this.hostname}/ocs/v1.php/cloud/users/${this.username}`, - serverinfo: `${this.hostname}/ocs/v2.php/apps/serverinfo/api/v1/info`, - }; - return endpoints[id]; + switch (id) { + case 'capabilities': + default: + return `${this.hostname}/ocs/v1.php/cloud/capabilities`; + case 'user': + return `${this.hostname}/ocs/v1.php/cloud/users/${this.username}`; + case 'serverinfo': + return `${this.hostname}/ocs/v2.php/apps/serverinfo/api/v1/info`; + } }, - fetchCapabilities() { - const promise = Promise.resolve(); - if ((new Date().getTime()) - this.capabilitiesLastUpdated > 3600000) { - promise.then(() => this.makeRequest(this.endpoint('capabilities'), this.headers)) - // //promise.then(() => NcdCap) + loadCapabilities() { + if ((new Date().getTime()) - this.capabilitiesLastUpdated > this.capabilitiesTtl) { + return this.makeRequest(this.endpoint('capabilities'), this.headers) + // //return Promise.resolve(NcdCap) .then(this.processCapabilities); } - return promise; + return Promise.resolve(); }, processCapabilities(data) { const ocdata = data?.ocs?.data; @@ -69,6 +90,23 @@ export default { this.version.edition = ocdata?.version?.edition; this.capabilitiesLastUpdated = new Date().getTime(); }, + loadUser() { + return this.makeRequest(this.endpoint('user'), this.headers).then(this.processUser); + // //return Promise.resolve(NcdUsr).then(this.processUser); + }, + processUser(userData) { + const user = userData?.ocs?.data; + if (!user) { + this.error('Invalid response'); + return; + } + this.user.id = user.id; + this.user.email = user.email; + this.user.quota = user.quota; + this.user.displayName = user.displayname; + this.user.lastLogin = user.lastLogin; + this.user.isAdmin = user.groups && user.groups.includes('admin'); + }, formatNumber(number) { return formatNumber(number); },