Merge pull request #54020 from nextcloud/feat/42647/hide-app-password-note-without-2fa

feat(files): hide note about app passwords when 2FA not enabled
pull/54068/head
Daniel 2025-07-24 23:52:34 +07:00 committed by GitHub
commit 52a472d7e4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 44 additions and 7 deletions

@ -26,6 +26,7 @@ use OCP\AppFramework\Http\RedirectResponse;
use OCP\AppFramework\Http\Response;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Services\IInitialState;
use OCP\Authentication\TwoFactorAuth\IRegistry;
use OCP\Collaboration\Resources\LoadAdditionalScriptsEvent as ResourcesLoadAdditionalScriptsEvent;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Folder;
@ -60,6 +61,7 @@ class ViewController extends Controller {
private UserConfig $userConfig,
private ViewConfig $viewConfig,
private FilenameValidator $filenameValidator,
private IRegistry $twoFactorRegistry,
) {
parent::__construct($appName, $request);
}
@ -142,7 +144,8 @@ class ViewController extends Controller {
Util::addInitScript('files', 'init');
Util::addScript('files', 'main');
$userId = $this->userSession->getUser()->getUID();
$user = $this->userSession->getUser();
$userId = $user->getUID();
// If the file doesn't exists in the folder and
// exists in only one occurrence, redirect to that file
@ -195,6 +198,15 @@ class ViewController extends Controller {
$this->initialState->provideInitialState('templates_path', $this->templateManager->hasTemplateDirectory() ? $this->templateManager->getTemplatePath() : false);
$this->initialState->provideInitialState('templates', $this->templateManager->listCreators());
$isTwoFactorEnabled = false;
foreach ($this->twoFactorRegistry->getProviderStates($user) as $providerId => $providerState) {
if ($providerId !== 'backup_codes' && $providerState === true) {
$isTwoFactorEnabled = true;
}
}
$this->initialState->provideInitialState('isTwoFactorEnabled', $isTwoFactorEnabled);
$response = new TemplateResponse(
Application::APP_ID,
'index',

@ -93,13 +93,13 @@
:href="webdavDocs"
target="_blank"
rel="noreferrer noopener">
{{ t('files', 'Use this address to access your Files via WebDAV') }}
{{ t('files', 'Use this address to access your Files via WebDAV.') }}
</a>
</em>
<br>
<em>
<em v-if="isTwoFactorEnabled">
<a class="setting-link" :href="appPasswordUrl">
{{ t('files', 'If you have enabled 2FA, you must create and use a new app password by clicking here.') }}
{{ t('files', 'Two-Factor Authentication is enabled for your account, and therefore you need to use an app password to connect an external WebDAV client.') }}
</a>
</em>
</NcAppSettingsSection>
@ -334,6 +334,7 @@ export default {
appPasswordUrl: generateUrl('/settings/user/security#generate-app-token-section'),
webdavUrlCopied: false,
enableGridView: (loadState('core', 'config', [])['enable_non-accessible_features'] ?? true),
isTwoFactorEnabled: (loadState('files', 'isTwoFactorEnabled', false)),
}
},

@ -19,6 +19,7 @@ use OCP\AppFramework\Http\ContentSecurityPolicy;
use OCP\AppFramework\Http\RedirectResponse;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Services\IInitialState;
use OCP\Authentication\TwoFactorAuth\IRegistry;
use OCP\Diagnostics\IEventLogger;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\File;
@ -63,6 +64,7 @@ class ViewControllerTest extends TestCase {
private UserConfig&MockObject $userConfig;
private ViewConfig&MockObject $viewConfig;
private Router $router;
private IRegistry&MockObject $twoFactorRegistry;
private ViewController&MockObject $viewController;
@ -79,6 +81,7 @@ class ViewControllerTest extends TestCase {
$this->userConfig = $this->createMock(UserConfig::class);
$this->userSession = $this->createMock(IUserSession::class);
$this->viewConfig = $this->createMock(ViewConfig::class);
$this->twoFactorRegistry = $this->createMock(IRegistry::class);
$this->user = $this->getMockBuilder(IUser::class)->getMock();
$this->user->expects($this->any())
@ -138,6 +141,7 @@ class ViewControllerTest extends TestCase {
$this->userConfig,
$this->viewConfig,
$filenameValidator,
$this->twoFactorRegistry,
])
->onlyMethods([
'getStorageInfo',
@ -286,4 +290,24 @@ class ViewControllerTest extends TestCase {
$expected = new RedirectResponse('/index.php/apps/files/trashbin/123?dir=/test.d1462861890/sub');
$this->assertEquals($expected, $this->viewController->index('', '', '123'));
}
public function testTwoFactorAuthEnabled(): void {
$this->twoFactorRegistry->method('getProviderStates')
->willReturn([
'totp' => true,
'backup_codes' => true,
]);
$invokedCountProvideInitialState = $this->exactly(9);
$this->initialState->expects($invokedCountProvideInitialState)
->method('provideInitialState')
->willReturnCallback(function ($key, $data) use ($invokedCountProvideInitialState) {
if ($invokedCountProvideInitialState->numberOfInvocations() === 9) {
$this->assertEquals('isTwoFactorEnabled', $key);
$this->assertTrue($data);
}
});
$this->viewController->index('', '', null);
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long