-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #50930 from nextcloud/backport/50910/stable29
- Loading branch information
Showing
19 changed files
with
324 additions
and
172 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,13 @@ | ||
/** | ||
* @copyright Copyright (c) 2023 John Molakvoæ <[email protected]> | ||
* | ||
* @author John Molakvoæ <[email protected]> | ||
* | ||
* @license AGPL-3.0-or-later | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU Affero General Public License as | ||
* published by the Free Software Foundation, either version 3 of the | ||
* License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU Affero General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Affero General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
* | ||
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors | ||
* SPDX-License-Identifier: AGPL-3.0-or-later | ||
*/ | ||
// eslint-disable-next-line n/no-extraneous-import | ||
import type { AxiosResponse } from 'axios' | ||
import type { AxiosResponse } from '@nextcloud/axios' | ||
import type { Node } from '@nextcloud/files' | ||
import type { StorageConfig } from '../services/externalStorage' | ||
|
||
import { addPasswordConfirmationInterceptors, PwdConfirmationMode } from '@nextcloud/password-confirmation' | ||
import { generateUrl } from '@nextcloud/router' | ||
import { showError, showSuccess, spawnDialog } from '@nextcloud/dialogs' | ||
import { translate as t } from '@nextcloud/l10n' | ||
|
@@ -35,14 +19,30 @@ import { FileAction, DefaultType } from '@nextcloud/files' | |
import { STORAGE_STATUS, isMissingAuthConfig } from '../utils/credentialsUtils' | ||
import { isNodeExternalStorage } from '../utils/externalStorageUtils' | ||
|
||
// Add password confirmation interceptors as | ||
// the backend requires the user to confirm their password | ||
addPasswordConfirmationInterceptors(axios) | ||
|
||
type CredentialResponse = { | ||
login?: string, | ||
password?: string, | ||
} | ||
|
||
/** | ||
* Set credentials for external storage | ||
* | ||
* @param node The node for which to set the credentials | ||
* @param login The username | ||
* @param password The password | ||
*/ | ||
async function setCredentials(node: Node, login: string, password: string): Promise<null|true> { | ||
const configResponse = await axios.put(generateUrl('apps/files_external/userglobalstorages/{id}', node.attributes), { | ||
backendOptions: { user: login, password }, | ||
const configResponse = await axios.request({ | ||
method: 'PUT', | ||
url: generateUrl('apps/files_external/userglobalstorages/{id}', { id: node.attributes.id }), | ||
confirmPassword: PwdConfirmationMode.Strict, | ||
data: { | ||
backendOptions: { user: login, password }, | ||
}, | ||
}) as AxiosResponse<StorageConfig> | ||
|
||
const config = configResponse.data | ||
|
@@ -59,8 +59,10 @@ async function setCredentials(node: Node, login: string, password: string): Prom | |
return true | ||
} | ||
|
||
export const ACTION_CREDENTIALS_EXTERNAL_STORAGE = 'credentials-external-storage' | ||
|
||
export const action = new FileAction({ | ||
id: 'credentials-external-storage', | ||
id: ACTION_CREDENTIALS_EXTERNAL_STORAGE, | ||
displayName: () => t('files', 'Enter missing credentials'), | ||
iconSvgInline: () => LoginSvg, | ||
|
||
|
@@ -93,7 +95,14 @@ export const action = new FileAction({ | |
)) | ||
|
||
if (login && password) { | ||
return await setCredentials(node, login, password) | ||
try { | ||
await setCredentials(node, login, password) | ||
showSuccess(t('files_external', 'Credentials successfully set')) | ||
} catch (error) { | ||
showError(t('files_external', 'Error while setting credentials: {error}', { | ||
error: (error as Error).message, | ||
})) | ||
} | ||
} | ||
|
||
return null | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,12 @@ | ||
/** | ||
* @copyright Copyright (c) 2023 John Molakvoæ <[email protected]> | ||
* | ||
* @author John Molakvoæ <[email protected]> | ||
* | ||
* @license AGPL-3.0-or-later | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU Affero General Public License as | ||
* published by the Free Software Foundation, either version 3 of the | ||
* License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU Affero General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Affero General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
* | ||
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors | ||
* SPDX-License-Identifier: AGPL-3.0-or-later | ||
*/ | ||
// eslint-disable-next-line n/no-extraneous-import | ||
import type { AxiosError } from 'axios' | ||
import type { AxiosError } from '@nextcloud/axios' | ||
import type { Node } from '@nextcloud/files' | ||
|
||
import { FileAction } from '@nextcloud/files' | ||
import { showWarning } from '@nextcloud/dialogs' | ||
import { translate as t } from '@nextcloud/l10n' | ||
import AlertSvg from '@mdi/svg/svg/alert-circle.svg?raw' | ||
|
@@ -32,7 +16,6 @@ import '../css/fileEntryStatus.scss' | |
import { getStatus, type StorageConfig } from '../services/externalStorage' | ||
import { isMissingAuthConfig, STORAGE_STATUS } from '../utils/credentialsUtils' | ||
import { isNodeExternalStorage } from '../utils/externalStorageUtils' | ||
import { FileAction } from '@nextcloud/files' | ||
|
||
export const action = new FileAction({ | ||
id: 'check-external-storage', | ||
|
@@ -47,47 +30,55 @@ export const action = new FileAction({ | |
/** | ||
* Use this function to check the storage availability | ||
* We then update the node attributes directly. | ||
* | ||
* @param node The node to render inline | ||
*/ | ||
async renderInline(node: Node) { | ||
let config = null as any as StorageConfig | ||
try { | ||
const response = await getStatus(node.attributes.id, node.attributes.scope === 'system') | ||
config = response.data | ||
Vue.set(node.attributes, 'config', config) | ||
const span = document.createElement('span') | ||
span.className = 'files-list__row-status' | ||
span.innerHTML = t('files_external', 'Checking storage …') | ||
|
||
let config = null as unknown as StorageConfig | ||
getStatus(node.attributes.id, node.attributes.scope === 'system') | ||
.then(response => { | ||
|
||
config = response.data | ||
Vue.set(node.attributes, 'config', config) | ||
|
||
if (config.status !== STORAGE_STATUS.SUCCESS) { | ||
throw new Error(config?.statusMessage || t('files_external', 'There was an error with this external storage.')) | ||
} | ||
|
||
if (config.status !== STORAGE_STATUS.SUCCESS) { | ||
throw new Error(config?.statusMessage || t('files_external', 'There was an error with this external storage.')) | ||
} | ||
span.remove() | ||
}) | ||
.catch(error => { | ||
// If axios failed or if something else prevented | ||
// us from getting the config | ||
if ((error as AxiosError).response && !config) { | ||
showWarning(t('files_external', 'We were unable to check the external storage {basename}', { | ||
basename: node.basename, | ||
})) | ||
} | ||
|
||
return null | ||
} catch (error) { | ||
// If axios failed or if something else prevented | ||
// us from getting the config | ||
if ((error as AxiosError).response && !config) { | ||
showWarning(t('files_external', 'We were unable to check the external storage {basename}', { | ||
basename: node.basename, | ||
})) | ||
return null | ||
} | ||
// Reset inline status | ||
span.innerHTML = '' | ||
|
||
// Checking if we really have an error | ||
const isWarning = isMissingAuthConfig(config) | ||
const overlay = document.createElement('span') | ||
overlay.classList.add(`files-list__row-status--${isWarning ? 'warning' : 'error'}`) | ||
// Checking if we really have an error | ||
const isWarning = !config ? false : isMissingAuthConfig(config) | ||
const overlay = document.createElement('span') | ||
overlay.classList.add(`files-list__row-status--${isWarning ? 'warning' : 'error'}`) | ||
|
||
const span = document.createElement('span') | ||
span.className = 'files-list__row-status' | ||
// Only show an icon for errors, warning like missing credentials | ||
// have a dedicated inline action button | ||
if (!isWarning) { | ||
span.innerHTML = AlertSvg | ||
span.title = (error as Error).message | ||
} | ||
|
||
// Only show an icon for errors, warning like missing credentials | ||
// have a dedicated inline action button | ||
if (!isWarning) { | ||
span.innerHTML = AlertSvg | ||
span.title = (error as Error).message | ||
} | ||
span.prepend(overlay) | ||
}) | ||
|
||
span.prepend(overlay) | ||
return span | ||
} | ||
return span | ||
}, | ||
|
||
order: 10, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.