Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions apps/oauth2/lib/Controller/SettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use OCA\OAuth2\Db\ClientMapper;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\PasswordConfirmationRequired;
use OCP\AppFramework\Http\JSONResponse;
use OCP\Authentication\Token\IProvider as IAuthTokenProvider;
use OCP\IL10N;
Expand Down Expand Up @@ -40,6 +41,7 @@ public function __construct(
parent::__construct($appName, $request);
}

#[PasswordConfirmationRequired(strict: true)]
public function addClient(string $name,
string $redirectUri): JSONResponse {
if (filter_var($redirectUri, FILTER_VALIDATE_URL) === false) {
Expand All @@ -66,6 +68,7 @@ public function addClient(string $name,
return new JSONResponse($result);
}

#[PasswordConfirmationRequired]
public function deleteClient(int $id): JSONResponse {
$client = $this->clientMapper->getByUid($id);

Expand Down
4 changes: 4 additions & 0 deletions apps/oauth2/src/settings-admin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import axios from '@nextcloud/axios'
import { loadState } from '@nextcloud/initial-state'
import { addPasswordConfirmationInterceptors } from '@nextcloud/password-confirmation'
import { createApp } from 'vue'
import AdminSettings from './views/AdminSettings.vue'

import 'vite/modulepreload-polyfill'

addPasswordConfirmationInterceptors(axios)

const clients = loadState('oauth2', 'clients')

const app = createApp(AdminSettings, {
Expand Down
3 changes: 2 additions & 1 deletion apps/oauth2/src/views/AdminSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import axios, { isAxiosError } from '@nextcloud/axios'
import { getCapabilities } from '@nextcloud/capabilities'
import { loadState } from '@nextcloud/initial-state'
import { t } from '@nextcloud/l10n'
import { PwdConfirmationMode } from '@nextcloud/password-confirmation'
import { generateUrl } from '@nextcloud/router'
import { ref } from 'vue'
import NcButton from '@nextcloud/vue/components/NcButton'
Expand Down Expand Up @@ -56,7 +57,7 @@ async function addClient() {
const { data } = await axios.post(generateUrl('apps/oauth2/clients'), {
name: newClient.value.name,
redirectUri: newClient.value.redirectUri,
})
}, { confirmPassword: PwdConfirmationMode.Strict })
clients.value.push(data)
showSecretWarning.value = true

Expand Down
2 changes: 1 addition & 1 deletion apps/provisioning_api/lib/Controller/AppsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public function getAppInfo(string $app): DataResponse {
*
* 200: App enabled successfully
*/
#[PasswordConfirmationRequired]
#[PasswordConfirmationRequired(strict: true)]
public function enable(string $app): DataResponse {
try {
$app = $this->verifyAppId($app);
Expand Down
2 changes: 1 addition & 1 deletion apps/settings/lib/Controller/AppSettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@ public function enableApp(string $appId, array $groups = []): JSONResponse {
* @param array $groups
* @return JSONResponse
*/
#[PasswordConfirmationRequired]
#[PasswordConfirmationRequired(strict: true)]
public function enableApps(array $appIds, array $groups = []): JSONResponse {
try {
$updateRequired = false;
Expand Down
2 changes: 2 additions & 0 deletions apps/settings/lib/Controller/AuthorizedGroupController.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use OCA\Settings\Service\AuthorizedGroupService;
use OCA\Settings\Service\NotFoundException;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\Attribute\PasswordConfirmationRequired;
use OCP\AppFramework\Http\DataResponse;
use OCP\DB\Exception;
use OCP\IRequest;
Expand All @@ -27,6 +28,7 @@ public function __construct(
* @throws NotFoundException
* @throws Exception
*/
#[PasswordConfirmationRequired(strict: true)]
public function saveSettings(array $newGroups, string $class): DataResponse {
$currentGroups = $this->authorizedGroupService->findExistingGroupsForClass($class);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use OC\Authentication\TwoFactorAuth\EnforcementState;
use OC\Authentication\TwoFactorAuth\MandatoryTwoFactor;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\Attribute\PasswordConfirmationRequired;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IRequest;

Expand All @@ -31,6 +32,7 @@ public function index(): JSONResponse {
return new JSONResponse($this->mandatoryTwoFactor->getState());
}

#[PasswordConfirmationRequired(strict: true)]
public function update(bool $enforced, array $enforcedGroups = [], array $excludedGroups = []): JSONResponse {
$this->mandatoryTwoFactor->setState(
new EnforcementState($enforced, $enforcedGroups, $excludedGroups)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<script>
import axios from '@nextcloud/axios'
import { showError } from '@nextcloud/dialogs'
import { PwdConfirmationMode } from '@nextcloud/password-confirmation'
import { generateUrl } from '@nextcloud/router'
import NcSelect from '@nextcloud/vue/components/NcSelect'
import logger from '../../logger.ts'
Expand Down Expand Up @@ -66,7 +67,7 @@ export default {
class: this.setting.class,
}
try {
await axios.post(generateUrl('/apps/settings/') + '/settings/authorizedgroups/saveSettings', data)
await axios.post(generateUrl('/apps/settings/') + '/settings/authorizedgroups/saveSettings', data, { confirmPassword: PwdConfirmationMode.Strict })
} catch (e) {
showError(t('settings', 'Unable to modify setting'))
logger.error('Unable to modify setting', e)
Expand Down
3 changes: 2 additions & 1 deletion apps/settings/src/components/AdminTwoFactor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
<script>
import axios from '@nextcloud/axios'
import { loadState } from '@nextcloud/initial-state'
import { PwdConfirmationMode } from '@nextcloud/password-confirmation'
import { generateOcsUrl, generateUrl } from '@nextcloud/router'
import debounce from 'lodash/debounce.js'
import sortedUniq from 'lodash/sortedUniq.js'
Expand Down Expand Up @@ -170,7 +171,7 @@ export default {
enforcedGroups: this.enforcedGroups,
excludedGroups: this.excludedGroups,
}
axios.put(generateUrl('/settings/api/admin/twofactorauth'), data)
axios.put(generateUrl('/settings/api/admin/twofactorauth'), data, { confirmPassword: PwdConfirmationMode.Strict })
.then((resp) => resp.data)
.then((state) => {
this.state = state
Expand Down
4 changes: 4 additions & 0 deletions apps/settings/src/main-admin-delegation.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import axios from '@nextcloud/axios'
import { addPasswordConfirmationInterceptors } from '@nextcloud/password-confirmation'
import Vue from 'vue'
import App from './components/AdminDelegating.vue'

addPasswordConfirmationInterceptors(axios)

// bind to window
Vue.prototype.OC = OC
Vue.prototype.t = t
Expand Down
6 changes: 5 additions & 1 deletion apps/settings/src/main-admin-security.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { getCSPNonce } from '@nextcloud/auth'
/**
* SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { getCSPNonce } from '@nextcloud/auth'
import axios from '@nextcloud/axios'
import { loadState } from '@nextcloud/initial-state'
import { addPasswordConfirmationInterceptors } from '@nextcloud/password-confirmation'
import Vue from 'vue'
import AdminTwoFactor from './components/AdminTwoFactor.vue'
import EncryptionSettings from './components/Encryption/EncryptionSettings.vue'
import store from './store/admin-security.js'

addPasswordConfirmationInterceptors(axios)

__webpack_nonce__ = getCSPNonce()

Vue.prototype.t = t
Expand Down
4 changes: 4 additions & 0 deletions apps/settings/src/main-apps-users-management.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
*/

import { getCSPNonce } from '@nextcloud/auth'
import axios from '@nextcloud/axios'
import { n, t } from '@nextcloud/l10n'
import { addPasswordConfirmationInterceptors } from '@nextcloud/password-confirmation'
import { createPinia, PiniaVuePlugin } from 'pinia'
import VTooltipPlugin from 'v-tooltip'
import Vue from 'vue'
Expand All @@ -14,6 +16,8 @@ import SettingsApp from './views/SettingsApp.vue'
import router from './router/index.ts'
import { useStore } from './store/index.js'

addPasswordConfirmationInterceptors(axios)

// CSP config for webpack dynamic chunk loading

__webpack_nonce__ = getCSPNonce()
Expand Down
4 changes: 2 additions & 2 deletions apps/settings/src/store/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ export default {
get(url, options) {
return axios.get(sanitize(url), options)
},
post(url, data) {
return axios.post(sanitize(url), data)
post(url, data, options) {
return axios.post(sanitize(url), data, options)
},
patch(url, data) {
return axios.patch(sanitize(url), data)
Expand Down
132 changes: 67 additions & 65 deletions apps/settings/src/store/apps.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import axios from '@nextcloud/axios'
import { showError, showInfo } from '@nextcloud/dialogs'
import { loadState } from '@nextcloud/initial-state'
import { PwdConfirmationMode } from '@nextcloud/password-confirmation'
import { generateUrl } from '@nextcloud/router'
import Vue from 'vue'
import logger from '../logger.ts'
Expand Down Expand Up @@ -180,81 +181,82 @@ const actions = {
} else {
apps = [appId]
}
return api.requireAdmin().then(() => {
context.commit('startLoading', apps)
context.commit('startLoading', 'install')

const previousState = {}
apps.forEach((_appId) => {
const app = context.state.apps.find((app) => app.id === _appId)
if (app) {
previousState[_appId] = {
active: app.active,
groups: [...(app.groups || [])],
}
context.commit('enableApp', { appId: _appId, groups })
context.commit('startLoading', apps)
context.commit('startLoading', 'install')

const previousState = {}
apps.forEach((_appId) => {
const app = context.state.apps.find((app) => app.id === _appId)
if (app) {
previousState[_appId] = {
active: app.active,
groups: [...(app.groups || [])],
}
})

return api.post(generateUrl('settings/apps/enable'), { appIds: apps, groups })
.then((response) => {
context.commit('stopLoading', apps)
context.commit('stopLoading', 'install')

// check for server health
return axios.get(generateUrl('apps/files/'))
.then(() => {
if (response.data.update_required) {
showInfo(
t(
'settings',
'The app has been enabled but needs to be updated. You will be redirected to the update page in 5 seconds.',
),
{
onClick: () => window.location.reload(),
close: false,

},
)
setTimeout(function() {
location.reload()
}, 5000)
}
})
.catch(() => {
if (!Array.isArray(appId)) {
showError(t('settings', 'Error: This app cannot be enabled because it makes the server unstable'))
context.commit('setError', {
appId: apps,
error: t('settings', 'Error: This app cannot be enabled because it makes the server unstable'),
})
context.dispatch('disableApp', { appId })
}
})
})
.catch((error) => {
context.commit('stopLoading', apps)
context.commit('stopLoading', 'install')
context.commit('enableApp', { appId: _appId, groups })
}
})

apps.forEach((_appId) => {
if (previousState[_appId]) {
context.commit('enableApp', {
appId: _appId,
groups: previousState[_appId].groups,
return api.post(generateUrl('settings/apps/enable'), { appIds: apps, groups }, { confirmPassword: PwdConfirmationMode.Strict })
.then((response) => {
context.commit('stopLoading', apps)
context.commit('stopLoading', 'install')

// check for server health
return axios.get(generateUrl('apps/files/'))
.then(() => {
if (response.data.update_required) {
showInfo(
t(
'settings',
'The app has been enabled but needs to be updated. You will be redirected to the update page in 5 seconds.',
),
{
onClick: () => window.location.reload(),
close: false,

},
)
setTimeout(function() {
location.reload()
}, 5000)
}
})
.catch(() => {
if (!Array.isArray(appId)) {
showError(t('settings', 'Error: This app cannot be enabled because it makes the server unstable'))
context.commit('setError', {
appId: apps,
error: t('settings', 'Error: This app cannot be enabled because it makes the server unstable'),
})
if (!previousState[_appId].active) {
context.commit('disableApp', _appId)
}
context.dispatch('disableApp', { appId })
}
})
})
.catch((error) => {
context.commit('stopLoading', apps)
context.commit('stopLoading', 'install')

apps.forEach((_appId) => {
if (previousState[_appId]) {
context.commit('enableApp', {
appId: _appId,
groups: previousState[_appId].groups,
})
if (!previousState[_appId].active) {
context.commit('disableApp', _appId)
}
}
})

const message = error.response?.data?.data?.message
if (message) {
context.commit('setError', {
appId: apps,
error: error.response.data.data.message,
error: message,
})
context.commit('APPS_API_FAILURE', { appId, error })
})
}).catch((error) => context.commit('API_FAILURE', { appId, error }))
}
})
},
forceEnableApp(context, { appId }) {
let apps
Expand Down
3 changes: 3 additions & 0 deletions core/Controller/TwoFactorApiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use OC\Authentication\TwoFactorAuth\ProviderManager;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\ApiRoute;
use OCP\AppFramework\Http\Attribute\PasswordConfirmationRequired;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCSController;
use OCP\Authentication\TwoFactorAuth\IRegistry;
Expand Down Expand Up @@ -60,6 +61,7 @@ public function state(string $user): DataResponse {
* 404: user not found
*/
#[ApiRoute(verb: 'POST', url: '/enable', root: '/twofactor')]
#[PasswordConfirmationRequired]
public function enable(string $user, array $providers = []): DataResponse {
$userObject = $this->userManager->get($user);
if ($userObject !== null) {
Expand All @@ -84,6 +86,7 @@ public function enable(string $user, array $providers = []): DataResponse {
* 404: user not found
*/
#[ApiRoute(verb: 'POST', url: '/disable', root: '/twofactor')]
#[PasswordConfirmationRequired(strict: true)]
public function disable(string $user, array $providers = []): DataResponse {
$userObject = $this->userManager->get($user);
if ($userObject !== null) {
Expand Down
Loading
Loading