diff options
Diffstat (limited to 'apps/files_external/src/actions/enterCredentialsAction.ts')
-rw-r--r-- | apps/files_external/src/actions/enterCredentialsAction.ts | 117 |
1 files changed, 61 insertions, 56 deletions
diff --git a/apps/files_external/src/actions/enterCredentialsAction.ts b/apps/files_external/src/actions/enterCredentialsAction.ts index 162a359f488..580f15ad876 100644 --- a/apps/files_external/src/actions/enterCredentialsAction.ts +++ b/apps/files_external/src/actions/enterCredentialsAction.ts @@ -1,56 +1,68 @@ /** - * @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com> - * - * @author John Molakvoæ <skjnldsv@protonmail.com> - * - * @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 { generateOcsUrl, generateUrl } from '@nextcloud/router' -import { showError, showSuccess } from '@nextcloud/dialogs' +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' import axios from '@nextcloud/axios' import LoginSvg from '@mdi/svg/svg/login.svg?raw' -import Vue from 'vue' +import Vue, { defineAsyncComponent } from 'vue' import { FileAction, DefaultType } from '@nextcloud/files' import { STORAGE_STATUS, isMissingAuthConfig } from '../utils/credentialsUtils' import { isNodeExternalStorage } from '../utils/externalStorageUtils' -type OCSAuthResponse = { - ocs: { - meta: { - status: string - statuscode: number - message: string - }, +// 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.request({ + method: 'PUT', + url: generateUrl('apps/files_external/userglobalstorages/{id}', { id: node.attributes.id }), + confirmPassword: PwdConfirmationMode.Strict, data: { - user?: string, - password?: string, - } + backendOptions: { user: login, password }, + }, + }) as AxiosResponse<StorageConfig> + + const config = configResponse.data + if (config.status !== STORAGE_STATUS.SUCCESS) { + showError(t('files_external', 'Unable to update this external storage config. {statusMessage}', { + statusMessage: config?.statusMessage || '', + })) + return null } + + // Success update config attribute + showSuccess(t('files_external', 'New configuration successfully saved')) + Vue.set(node.attributes, 'config', config) + 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, @@ -74,30 +86,23 @@ export const action = new FileAction({ }, async exec(node: Node) { - // always resolve auth request, we'll process the data afterwards - // Using fetch as axios have integrated auth handling and X-Requested-With header - const response = await fetch(generateOcsUrl('/apps/files_external/api/v1/auth'), { - headers: new Headers({ Accept: 'application/json' }), - credentials: 'include', - }) - - const data = (await response?.json() || {}) as OCSAuthResponse - if (data.ocs.data.user && data.ocs.data.password) { - const configResponse = await axios.put(generateUrl('apps/files_external/userglobalstorages/{id}', node.attributes), { - backendOptions: data.ocs.data, - }) as AxiosResponse<StorageConfig> - - const config = configResponse.data - if (config.status !== STORAGE_STATUS.SUCCESS) { - showError(t('files_external', 'Unable to update this external storage config. {statusMessage}', { - statusMessage: config?.statusMessage || '', + const { login, password } = await new Promise<CredentialResponse>(resolve => spawnDialog( + defineAsyncComponent(() => import('../views/CredentialsDialog.vue')), + {}, + (args) => { + resolve(args as CredentialResponse) + }, + )) + + if (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 } - - // Success update config attribute - showSuccess(t('files_external', 'New configuration successfully saved')) - Vue.set(node.attributes, 'config', config) } return null |