aboutsummaryrefslogtreecommitdiffstats
path: root/apps/twofactor_backupcodes
diff options
context:
space:
mode:
Diffstat (limited to 'apps/twofactor_backupcodes')
-rw-r--r--apps/twofactor_backupcodes/.l10nignore3
-rw-r--r--apps/twofactor_backupcodes/.noopenapi0
-rw-r--r--apps/twofactor_backupcodes/appinfo/info.xml34
-rw-r--r--apps/twofactor_backupcodes/appinfo/routes.php19
-rw-r--r--apps/twofactor_backupcodes/composer/autoload.php25
-rw-r--r--apps/twofactor_backupcodes/composer/composer.json13
-rw-r--r--apps/twofactor_backupcodes/composer/composer.lock18
-rw-r--r--apps/twofactor_backupcodes/composer/composer/ClassLoader.php579
-rw-r--r--apps/twofactor_backupcodes/composer/composer/InstalledVersions.php359
-rw-r--r--apps/twofactor_backupcodes/composer/composer/LICENSE21
-rw-r--r--apps/twofactor_backupcodes/composer/composer/autoload_classmap.php34
-rw-r--r--apps/twofactor_backupcodes/composer/composer/autoload_namespaces.php9
-rw-r--r--apps/twofactor_backupcodes/composer/composer/autoload_psr4.php10
-rw-r--r--apps/twofactor_backupcodes/composer/composer/autoload_real.php37
-rw-r--r--apps/twofactor_backupcodes/composer/composer/autoload_static.php60
-rw-r--r--apps/twofactor_backupcodes/composer/composer/installed.json5
-rw-r--r--apps/twofactor_backupcodes/composer/composer/installed.php23
-rw-r--r--apps/twofactor_backupcodes/css/style.css25
-rw-r--r--apps/twofactor_backupcodes/l10n/.gitkeep0
-rw-r--r--apps/twofactor_backupcodes/l10n/af.js17
-rw-r--r--apps/twofactor_backupcodes/l10n/af.json15
-rw-r--r--apps/twofactor_backupcodes/l10n/ar.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/ar.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/ast.js22
-rw-r--r--apps/twofactor_backupcodes/l10n/ast.json20
-rw-r--r--apps/twofactor_backupcodes/l10n/bg.js22
-rw-r--r--apps/twofactor_backupcodes/l10n/bg.json20
-rw-r--r--apps/twofactor_backupcodes/l10n/ca.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/ca.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/cs.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/cs.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/da.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/da.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/de.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/de.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/de_DE.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/de_DE.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/el.js22
-rw-r--r--apps/twofactor_backupcodes/l10n/el.json20
-rw-r--r--apps/twofactor_backupcodes/l10n/en_GB.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/en_GB.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/eo.js22
-rw-r--r--apps/twofactor_backupcodes/l10n/eo.json20
-rw-r--r--apps/twofactor_backupcodes/l10n/es.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/es.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/es_419.js16
-rw-r--r--apps/twofactor_backupcodes/l10n/es_419.json14
-rw-r--r--apps/twofactor_backupcodes/l10n/es_AR.js17
-rw-r--r--apps/twofactor_backupcodes/l10n/es_AR.json15
-rw-r--r--apps/twofactor_backupcodes/l10n/es_CL.js17
-rw-r--r--apps/twofactor_backupcodes/l10n/es_CL.json15
-rw-r--r--apps/twofactor_backupcodes/l10n/es_CO.js17
-rw-r--r--apps/twofactor_backupcodes/l10n/es_CO.json15
-rw-r--r--apps/twofactor_backupcodes/l10n/es_CR.js17
-rw-r--r--apps/twofactor_backupcodes/l10n/es_CR.json15
-rw-r--r--apps/twofactor_backupcodes/l10n/es_DO.js17
-rw-r--r--apps/twofactor_backupcodes/l10n/es_DO.json15
-rw-r--r--apps/twofactor_backupcodes/l10n/es_EC.js22
-rw-r--r--apps/twofactor_backupcodes/l10n/es_EC.json20
-rw-r--r--apps/twofactor_backupcodes/l10n/es_GT.js17
-rw-r--r--apps/twofactor_backupcodes/l10n/es_GT.json15
-rw-r--r--apps/twofactor_backupcodes/l10n/es_HN.js16
-rw-r--r--apps/twofactor_backupcodes/l10n/es_HN.json14
-rw-r--r--apps/twofactor_backupcodes/l10n/es_MX.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/es_MX.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/es_NI.js16
-rw-r--r--apps/twofactor_backupcodes/l10n/es_NI.json14
-rw-r--r--apps/twofactor_backupcodes/l10n/es_PA.js16
-rw-r--r--apps/twofactor_backupcodes/l10n/es_PA.json14
-rw-r--r--apps/twofactor_backupcodes/l10n/es_PE.js16
-rw-r--r--apps/twofactor_backupcodes/l10n/es_PE.json14
-rw-r--r--apps/twofactor_backupcodes/l10n/es_PR.js16
-rw-r--r--apps/twofactor_backupcodes/l10n/es_PR.json14
-rw-r--r--apps/twofactor_backupcodes/l10n/es_PY.js16
-rw-r--r--apps/twofactor_backupcodes/l10n/es_PY.json14
-rw-r--r--apps/twofactor_backupcodes/l10n/es_SV.js17
-rw-r--r--apps/twofactor_backupcodes/l10n/es_SV.json15
-rw-r--r--apps/twofactor_backupcodes/l10n/es_UY.js16
-rw-r--r--apps/twofactor_backupcodes/l10n/es_UY.json14
-rw-r--r--apps/twofactor_backupcodes/l10n/et_EE.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/et_EE.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/eu.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/eu.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/fa.js22
-rw-r--r--apps/twofactor_backupcodes/l10n/fa.json20
-rw-r--r--apps/twofactor_backupcodes/l10n/fi.js18
-rw-r--r--apps/twofactor_backupcodes/l10n/fi.json16
-rw-r--r--apps/twofactor_backupcodes/l10n/fr.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/fr.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/ga.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/ga.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/gl.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/gl.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/he.js19
-rw-r--r--apps/twofactor_backupcodes/l10n/he.json17
-rw-r--r--apps/twofactor_backupcodes/l10n/hr.js22
-rw-r--r--apps/twofactor_backupcodes/l10n/hr.json20
-rw-r--r--apps/twofactor_backupcodes/l10n/hu.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/hu.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/is.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/is.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/it.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/it.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/ja.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/ja.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/ka.js22
-rw-r--r--apps/twofactor_backupcodes/l10n/ka.json20
-rw-r--r--apps/twofactor_backupcodes/l10n/ka_GE.js17
-rw-r--r--apps/twofactor_backupcodes/l10n/ka_GE.json15
-rw-r--r--apps/twofactor_backupcodes/l10n/ko.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/ko.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/lt_LT.js20
-rw-r--r--apps/twofactor_backupcodes/l10n/lt_LT.json18
-rw-r--r--apps/twofactor_backupcodes/l10n/lv.js16
-rw-r--r--apps/twofactor_backupcodes/l10n/lv.json14
-rw-r--r--apps/twofactor_backupcodes/l10n/mk.js22
-rw-r--r--apps/twofactor_backupcodes/l10n/mk.json20
-rw-r--r--apps/twofactor_backupcodes/l10n/mn.js17
-rw-r--r--apps/twofactor_backupcodes/l10n/mn.json15
-rw-r--r--apps/twofactor_backupcodes/l10n/nb.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/nb.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/nl.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/nl.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/pl.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/pl.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/pt_BR.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/pt_BR.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/pt_PT.js15
-rw-r--r--apps/twofactor_backupcodes/l10n/pt_PT.json13
-rw-r--r--apps/twofactor_backupcodes/l10n/ru.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/ru.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/sc.js22
-rw-r--r--apps/twofactor_backupcodes/l10n/sc.json20
-rw-r--r--apps/twofactor_backupcodes/l10n/sk.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/sk.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/sl.js22
-rw-r--r--apps/twofactor_backupcodes/l10n/sl.json20
-rw-r--r--apps/twofactor_backupcodes/l10n/sq.js17
-rw-r--r--apps/twofactor_backupcodes/l10n/sq.json15
-rw-r--r--apps/twofactor_backupcodes/l10n/sr.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/sr.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/sv.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/sv.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/sw.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/sw.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/tr.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/tr.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/ug.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/ug.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/uk.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/uk.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/zh_CN.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/zh_CN.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/zh_HK.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/zh_HK.json21
-rw-r--r--apps/twofactor_backupcodes/l10n/zh_TW.js23
-rw-r--r--apps/twofactor_backupcodes/l10n/zh_TW.json21
-rw-r--r--apps/twofactor_backupcodes/lib/Activity/Provider.php54
-rw-r--r--apps/twofactor_backupcodes/lib/AppInfo/Application.php51
-rw-r--r--apps/twofactor_backupcodes/lib/BackgroundJob/CheckBackupCodes.php49
-rw-r--r--apps/twofactor_backupcodes/lib/BackgroundJob/RememberBackupCodesJob.php77
-rw-r--r--apps/twofactor_backupcodes/lib/Controller/SettingsController.php49
-rw-r--r--apps/twofactor_backupcodes/lib/Db/BackupCode.php31
-rw-r--r--apps/twofactor_backupcodes/lib/Db/BackupCodeMapper.php57
-rw-r--r--apps/twofactor_backupcodes/lib/Event/CodesGenerated.php28
-rw-r--r--apps/twofactor_backupcodes/lib/Listener/ActivityPublisher.php44
-rw-r--r--apps/twofactor_backupcodes/lib/Listener/ClearNotifications.php35
-rw-r--r--apps/twofactor_backupcodes/lib/Listener/ProviderDisabled.php43
-rw-r--r--apps/twofactor_backupcodes/lib/Listener/ProviderEnabled.php40
-rw-r--r--apps/twofactor_backupcodes/lib/Listener/RegistryUpdater.php31
-rw-r--r--apps/twofactor_backupcodes/lib/Listener/UserDeleted.php31
-rw-r--r--apps/twofactor_backupcodes/lib/Migration/CheckBackupCodes.php29
-rw-r--r--apps/twofactor_backupcodes/lib/Migration/Version1002Date20170607104347.php56
-rw-r--r--apps/twofactor_backupcodes/lib/Migration/Version1002Date20170607113030.php88
-rw-r--r--apps/twofactor_backupcodes/lib/Migration/Version1002Date20170919123342.php42
-rw-r--r--apps/twofactor_backupcodes/lib/Migration/Version1002Date20170926101419.php28
-rw-r--r--apps/twofactor_backupcodes/lib/Migration/Version1002Date20180821043638.php34
-rw-r--r--apps/twofactor_backupcodes/lib/Notifications/Notifier.php73
-rw-r--r--apps/twofactor_backupcodes/lib/Provider/BackupCodesProvider.php130
-rw-r--r--apps/twofactor_backupcodes/lib/Service/BackupCodeStorage.php109
-rw-r--r--apps/twofactor_backupcodes/lib/Settings/Personal.php21
-rw-r--r--apps/twofactor_backupcodes/src/service/BackupCodesService.js16
-rw-r--r--apps/twofactor_backupcodes/src/service/PrintService.js16
-rw-r--r--apps/twofactor_backupcodes/src/settings.js20
-rw-r--r--apps/twofactor_backupcodes/src/store.js53
-rw-r--r--apps/twofactor_backupcodes/src/views/PersonalSettings.vue157
-rw-r--r--apps/twofactor_backupcodes/templates/challenge.php20
-rw-r--r--apps/twofactor_backupcodes/templates/personal.php12
-rw-r--r--apps/twofactor_backupcodes/tests/Db/BackupCodeMapperTest.php106
-rw-r--r--apps/twofactor_backupcodes/tests/Service/BackupCodeStorageTest.php90
-rw-r--r--apps/twofactor_backupcodes/tests/Unit/Activity/ProviderTest.php106
-rw-r--r--apps/twofactor_backupcodes/tests/Unit/BackgroundJob/CheckBackupCodeTest.php129
-rw-r--r--apps/twofactor_backupcodes/tests/Unit/BackgroundJob/RememberBackupCodesJobTest.php213
-rw-r--r--apps/twofactor_backupcodes/tests/Unit/Controller/SettingsControllerTest.php60
-rw-r--r--apps/twofactor_backupcodes/tests/Unit/Event/CodesGeneratedTest.php23
-rw-r--r--apps/twofactor_backupcodes/tests/Unit/Listener/ActivityPublisherTest.php72
-rw-r--r--apps/twofactor_backupcodes/tests/Unit/Listener/ClearNotificationsTest.php59
-rw-r--r--apps/twofactor_backupcodes/tests/Unit/Listener/ProviderDisabledTest.php88
-rw-r--r--apps/twofactor_backupcodes/tests/Unit/Listener/ProviderEnabledTest.php86
-rw-r--r--apps/twofactor_backupcodes/tests/Unit/Listener/RegistryUpdaterTest.php54
-rw-r--r--apps/twofactor_backupcodes/tests/Unit/Migration/CheckBackupCodeTest.php41
-rw-r--r--apps/twofactor_backupcodes/tests/Unit/Notification/NotifierTest.php114
-rw-r--r--apps/twofactor_backupcodes/tests/Unit/Provider/BackupCodesProviderTest.php153
-rw-r--r--apps/twofactor_backupcodes/tests/Unit/Service/BackupCodeStorageTest.php220
204 files changed, 7128 insertions, 0 deletions
diff --git a/apps/twofactor_backupcodes/.l10nignore b/apps/twofactor_backupcodes/.l10nignore
new file mode 100644
index 00000000000..cceeb774628
--- /dev/null
+++ b/apps/twofactor_backupcodes/.l10nignore
@@ -0,0 +1,3 @@
+# SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+# SPDX-License-Identifier: AGPL-3.0-or-later
+js/
diff --git a/apps/twofactor_backupcodes/.noopenapi b/apps/twofactor_backupcodes/.noopenapi
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/apps/twofactor_backupcodes/.noopenapi
diff --git a/apps/twofactor_backupcodes/appinfo/info.xml b/apps/twofactor_backupcodes/appinfo/info.xml
new file mode 100644
index 00000000000..48a96e3fa15
--- /dev/null
+++ b/apps/twofactor_backupcodes/appinfo/info.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+ - SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
+-->
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
+ <id>twofactor_backupcodes</id>
+ <name>Two factor backup codes</name>
+ <summary>A two-factor auth backup codes provider</summary>
+ <description>A two-factor auth backup codes provider</description>
+ <version>1.21.0</version>
+ <licence>agpl</licence>
+ <author>Christoph Wurst</author>
+ <namespace>TwoFactorBackupCodes</namespace>
+ <category>integration</category>
+ <category>security</category>
+ <bugs>https://github.com/nextcloud/server/issues</bugs>
+ <dependencies>
+ <nextcloud min-version="32" max-version="32"/>
+ </dependencies>
+
+ <repair-steps>
+ <post-migration>
+ <step>OCA\TwoFactorBackupCodes\Migration\CheckBackupCodes</step>
+ </post-migration>
+ </repair-steps>
+
+ <activity>
+ <providers>
+ <provider>OCA\TwoFactorBackupCodes\Activity\Provider</provider>
+ </providers>
+ </activity>
+</info>
diff --git a/apps/twofactor_backupcodes/appinfo/routes.php b/apps/twofactor_backupcodes/appinfo/routes.php
new file mode 100644
index 00000000000..958e319c49d
--- /dev/null
+++ b/apps/twofactor_backupcodes/appinfo/routes.php
@@ -0,0 +1,19 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+// @codeCoverageIgnoreStart
+return [
+ 'routes' => [
+ [
+ 'name' => 'settings#createCodes',
+ 'url' => '/settings/create',
+ 'verb' => 'POST'
+ ],
+ ]
+];
+// @codeCoverageIgnoreEnd
diff --git a/apps/twofactor_backupcodes/composer/autoload.php b/apps/twofactor_backupcodes/composer/autoload.php
new file mode 100644
index 00000000000..fee47fcf513
--- /dev/null
+++ b/apps/twofactor_backupcodes/composer/autoload.php
@@ -0,0 +1,25 @@
+<?php
+
+// autoload.php @generated by Composer
+
+if (PHP_VERSION_ID < 50600) {
+ if (!headers_sent()) {
+ header('HTTP/1.1 500 Internal Server Error');
+ }
+ $err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
+ if (!ini_get('display_errors')) {
+ if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
+ fwrite(STDERR, $err);
+ } elseif (!headers_sent()) {
+ echo $err;
+ }
+ }
+ trigger_error(
+ $err,
+ E_USER_ERROR
+ );
+}
+
+require_once __DIR__ . '/composer/autoload_real.php';
+
+return ComposerAutoloaderInitTwoFactorBackupCodes::getLoader();
diff --git a/apps/twofactor_backupcodes/composer/composer.json b/apps/twofactor_backupcodes/composer/composer.json
new file mode 100644
index 00000000000..bfa807a8e4f
--- /dev/null
+++ b/apps/twofactor_backupcodes/composer/composer.json
@@ -0,0 +1,13 @@
+{
+ "config" : {
+ "vendor-dir": ".",
+ "optimize-autoloader": true,
+ "classmap-authoritative": true,
+ "autoloader-suffix": "TwoFactorBackupCodes"
+ },
+ "autoload" : {
+ "psr-4": {
+ "OCA\\TwoFactorBackupCodes\\": "../lib/"
+ }
+ }
+}
diff --git a/apps/twofactor_backupcodes/composer/composer.lock b/apps/twofactor_backupcodes/composer/composer.lock
new file mode 100644
index 00000000000..fd0bcbcb753
--- /dev/null
+++ b/apps/twofactor_backupcodes/composer/composer.lock
@@ -0,0 +1,18 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "d751713988987e9331980363e24189ce",
+ "packages": [],
+ "packages-dev": [],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": [],
+ "platform-dev": [],
+ "plugin-api-version": "2.1.0"
+}
diff --git a/apps/twofactor_backupcodes/composer/composer/ClassLoader.php b/apps/twofactor_backupcodes/composer/composer/ClassLoader.php
new file mode 100644
index 00000000000..7824d8f7eaf
--- /dev/null
+++ b/apps/twofactor_backupcodes/composer/composer/ClassLoader.php
@@ -0,0 +1,579 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ * Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Autoload;
+
+/**
+ * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
+ *
+ * $loader = new \Composer\Autoload\ClassLoader();
+ *
+ * // register classes with namespaces
+ * $loader->add('Symfony\Component', __DIR__.'/component');
+ * $loader->add('Symfony', __DIR__.'/framework');
+ *
+ * // activate the autoloader
+ * $loader->register();
+ *
+ * // to enable searching the include path (eg. for PEAR packages)
+ * $loader->setUseIncludePath(true);
+ *
+ * In this example, if you try to use a class in the Symfony\Component
+ * namespace or one of its children (Symfony\Component\Console for instance),
+ * the autoloader will first look for the class under the component/
+ * directory, and it will then fallback to the framework/ directory if not
+ * found before giving up.
+ *
+ * This class is loosely based on the Symfony UniversalClassLoader.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ * @see https://www.php-fig.org/psr/psr-0/
+ * @see https://www.php-fig.org/psr/psr-4/
+ */
+class ClassLoader
+{
+ /** @var \Closure(string):void */
+ private static $includeFile;
+
+ /** @var string|null */
+ private $vendorDir;
+
+ // PSR-4
+ /**
+ * @var array<string, array<string, int>>
+ */
+ private $prefixLengthsPsr4 = array();
+ /**
+ * @var array<string, list<string>>
+ */
+ private $prefixDirsPsr4 = array();
+ /**
+ * @var list<string>
+ */
+ private $fallbackDirsPsr4 = array();
+
+ // PSR-0
+ /**
+ * List of PSR-0 prefixes
+ *
+ * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
+ *
+ * @var array<string, array<string, list<string>>>
+ */
+ private $prefixesPsr0 = array();
+ /**
+ * @var list<string>
+ */
+ private $fallbackDirsPsr0 = array();
+
+ /** @var bool */
+ private $useIncludePath = false;
+
+ /**
+ * @var array<string, string>
+ */
+ private $classMap = array();
+
+ /** @var bool */
+ private $classMapAuthoritative = false;
+
+ /**
+ * @var array<string, bool>
+ */
+ private $missingClasses = array();
+
+ /** @var string|null */
+ private $apcuPrefix;
+
+ /**
+ * @var array<string, self>
+ */
+ private static $registeredLoaders = array();
+
+ /**
+ * @param string|null $vendorDir
+ */
+ public function __construct($vendorDir = null)
+ {
+ $this->vendorDir = $vendorDir;
+ self::initializeIncludeClosure();
+ }
+
+ /**
+ * @return array<string, list<string>>
+ */
+ public function getPrefixes()
+ {
+ if (!empty($this->prefixesPsr0)) {
+ return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
+ }
+
+ return array();
+ }
+
+ /**
+ * @return array<string, list<string>>
+ */
+ public function getPrefixesPsr4()
+ {
+ return $this->prefixDirsPsr4;
+ }
+
+ /**
+ * @return list<string>
+ */
+ public function getFallbackDirs()
+ {
+ return $this->fallbackDirsPsr0;
+ }
+
+ /**
+ * @return list<string>
+ */
+ public function getFallbackDirsPsr4()
+ {
+ return $this->fallbackDirsPsr4;
+ }
+
+ /**
+ * @return array<string, string> Array of classname => path
+ */
+ public function getClassMap()
+ {
+ return $this->classMap;
+ }
+
+ /**
+ * @param array<string, string> $classMap Class to filename map
+ *
+ * @return void
+ */
+ public function addClassMap(array $classMap)
+ {
+ if ($this->classMap) {
+ $this->classMap = array_merge($this->classMap, $classMap);
+ } else {
+ $this->classMap = $classMap;
+ }
+ }
+
+ /**
+ * Registers a set of PSR-0 directories for a given prefix, either
+ * appending or prepending to the ones previously set for this prefix.
+ *
+ * @param string $prefix The prefix
+ * @param list<string>|string $paths The PSR-0 root directories
+ * @param bool $prepend Whether to prepend the directories
+ *
+ * @return void
+ */
+ public function add($prefix, $paths, $prepend = false)
+ {
+ $paths = (array) $paths;
+ if (!$prefix) {
+ if ($prepend) {
+ $this->fallbackDirsPsr0 = array_merge(
+ $paths,
+ $this->fallbackDirsPsr0
+ );
+ } else {
+ $this->fallbackDirsPsr0 = array_merge(
+ $this->fallbackDirsPsr0,
+ $paths
+ );
+ }
+
+ return;
+ }
+
+ $first = $prefix[0];
+ if (!isset($this->prefixesPsr0[$first][$prefix])) {
+ $this->prefixesPsr0[$first][$prefix] = $paths;
+
+ return;
+ }
+ if ($prepend) {
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
+ $paths,
+ $this->prefixesPsr0[$first][$prefix]
+ );
+ } else {
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
+ $this->prefixesPsr0[$first][$prefix],
+ $paths
+ );
+ }
+ }
+
+ /**
+ * Registers a set of PSR-4 directories for a given namespace, either
+ * appending or prepending to the ones previously set for this namespace.
+ *
+ * @param string $prefix The prefix/namespace, with trailing '\\'
+ * @param list<string>|string $paths The PSR-4 base directories
+ * @param bool $prepend Whether to prepend the directories
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @return void
+ */
+ public function addPsr4($prefix, $paths, $prepend = false)
+ {
+ $paths = (array) $paths;
+ if (!$prefix) {
+ // Register directories for the root namespace.
+ if ($prepend) {
+ $this->fallbackDirsPsr4 = array_merge(
+ $paths,
+ $this->fallbackDirsPsr4
+ );
+ } else {
+ $this->fallbackDirsPsr4 = array_merge(
+ $this->fallbackDirsPsr4,
+ $paths
+ );
+ }
+ } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
+ // Register directories for a new namespace.
+ $length = strlen($prefix);
+ if ('\\' !== $prefix[$length - 1]) {
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+ }
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+ $this->prefixDirsPsr4[$prefix] = $paths;
+ } elseif ($prepend) {
+ // Prepend directories for an already registered namespace.
+ $this->prefixDirsPsr4[$prefix] = array_merge(
+ $paths,
+ $this->prefixDirsPsr4[$prefix]
+ );
+ } else {
+ // Append directories for an already registered namespace.
+ $this->prefixDirsPsr4[$prefix] = array_merge(
+ $this->prefixDirsPsr4[$prefix],
+ $paths
+ );
+ }
+ }
+
+ /**
+ * Registers a set of PSR-0 directories for a given prefix,
+ * replacing any others previously set for this prefix.
+ *
+ * @param string $prefix The prefix
+ * @param list<string>|string $paths The PSR-0 base directories
+ *
+ * @return void
+ */
+ public function set($prefix, $paths)
+ {
+ if (!$prefix) {
+ $this->fallbackDirsPsr0 = (array) $paths;
+ } else {
+ $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
+ }
+ }
+
+ /**
+ * Registers a set of PSR-4 directories for a given namespace,
+ * replacing any others previously set for this namespace.
+ *
+ * @param string $prefix The prefix/namespace, with trailing '\\'
+ * @param list<string>|string $paths The PSR-4 base directories
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @return void
+ */
+ public function setPsr4($prefix, $paths)
+ {
+ if (!$prefix) {
+ $this->fallbackDirsPsr4 = (array) $paths;
+ } else {
+ $length = strlen($prefix);
+ if ('\\' !== $prefix[$length - 1]) {
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+ }
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
+ }
+ }
+
+ /**
+ * Turns on searching the include path for class files.
+ *
+ * @param bool $useIncludePath
+ *
+ * @return void
+ */
+ public function setUseIncludePath($useIncludePath)
+ {
+ $this->useIncludePath = $useIncludePath;
+ }
+
+ /**
+ * Can be used to check if the autoloader uses the include path to check
+ * for classes.
+ *
+ * @return bool
+ */
+ public function getUseIncludePath()
+ {
+ return $this->useIncludePath;
+ }
+
+ /**
+ * Turns off searching the prefix and fallback directories for classes
+ * that have not been registered with the class map.
+ *
+ * @param bool $classMapAuthoritative
+ *
+ * @return void
+ */
+ public function setClassMapAuthoritative($classMapAuthoritative)
+ {
+ $this->classMapAuthoritative = $classMapAuthoritative;
+ }
+
+ /**
+ * Should class lookup fail if not found in the current class map?
+ *
+ * @return bool
+ */
+ public function isClassMapAuthoritative()
+ {
+ return $this->classMapAuthoritative;
+ }
+
+ /**
+ * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
+ *
+ * @param string|null $apcuPrefix
+ *
+ * @return void
+ */
+ public function setApcuPrefix($apcuPrefix)
+ {
+ $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
+ }
+
+ /**
+ * The APCu prefix in use, or null if APCu caching is not enabled.
+ *
+ * @return string|null
+ */
+ public function getApcuPrefix()
+ {
+ return $this->apcuPrefix;
+ }
+
+ /**
+ * Registers this instance as an autoloader.
+ *
+ * @param bool $prepend Whether to prepend the autoloader or not
+ *
+ * @return void
+ */
+ public function register($prepend = false)
+ {
+ spl_autoload_register(array($this, 'loadClass'), true, $prepend);
+
+ if (null === $this->vendorDir) {
+ return;
+ }
+
+ if ($prepend) {
+ self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
+ } else {
+ unset(self::$registeredLoaders[$this->vendorDir]);
+ self::$registeredLoaders[$this->vendorDir] = $this;
+ }
+ }
+
+ /**
+ * Unregisters this instance as an autoloader.
+ *
+ * @return void
+ */
+ public function unregister()
+ {
+ spl_autoload_unregister(array($this, 'loadClass'));
+
+ if (null !== $this->vendorDir) {
+ unset(self::$registeredLoaders[$this->vendorDir]);
+ }
+ }
+
+ /**
+ * Loads the given class or interface.
+ *
+ * @param string $class The name of the class
+ * @return true|null True if loaded, null otherwise
+ */
+ public function loadClass($class)
+ {
+ if ($file = $this->findFile($class)) {
+ $includeFile = self::$includeFile;
+ $includeFile($file);
+
+ return true;
+ }
+
+ return null;
+ }
+
+ /**
+ * Finds the path to the file where the class is defined.
+ *
+ * @param string $class The name of the class
+ *
+ * @return string|false The path if found, false otherwise
+ */
+ public function findFile($class)
+ {
+ // class map lookup
+ if (isset($this->classMap[$class])) {
+ return $this->classMap[$class];
+ }
+ if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
+ return false;
+ }
+ if (null !== $this->apcuPrefix) {
+ $file = apcu_fetch($this->apcuPrefix.$class, $hit);
+ if ($hit) {
+ return $file;
+ }
+ }
+
+ $file = $this->findFileWithExtension($class, '.php');
+
+ // Search for Hack files if we are running on HHVM
+ if (false === $file && defined('HHVM_VERSION')) {
+ $file = $this->findFileWithExtension($class, '.hh');
+ }
+
+ if (null !== $this->apcuPrefix) {
+ apcu_add($this->apcuPrefix.$class, $file);
+ }
+
+ if (false === $file) {
+ // Remember that this class does not exist.
+ $this->missingClasses[$class] = true;
+ }
+
+ return $file;
+ }
+
+ /**
+ * Returns the currently registered loaders keyed by their corresponding vendor directories.
+ *
+ * @return array<string, self>
+ */
+ public static function getRegisteredLoaders()
+ {
+ return self::$registeredLoaders;
+ }
+
+ /**
+ * @param string $class
+ * @param string $ext
+ * @return string|false
+ */
+ private function findFileWithExtension($class, $ext)
+ {
+ // PSR-4 lookup
+ $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
+
+ $first = $class[0];
+ if (isset($this->prefixLengthsPsr4[$first])) {
+ $subPath = $class;
+ while (false !== $lastPos = strrpos($subPath, '\\')) {
+ $subPath = substr($subPath, 0, $lastPos);
+ $search = $subPath . '\\';
+ if (isset($this->prefixDirsPsr4[$search])) {
+ $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
+ foreach ($this->prefixDirsPsr4[$search] as $dir) {
+ if (file_exists($file = $dir . $pathEnd)) {
+ return $file;
+ }
+ }
+ }
+ }
+ }
+
+ // PSR-4 fallback dirs
+ foreach ($this->fallbackDirsPsr4 as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
+ return $file;
+ }
+ }
+
+ // PSR-0 lookup
+ if (false !== $pos = strrpos($class, '\\')) {
+ // namespaced class name
+ $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
+ . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
+ } else {
+ // PEAR-like class name
+ $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
+ }
+
+ if (isset($this->prefixesPsr0[$first])) {
+ foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
+ if (0 === strpos($class, $prefix)) {
+ foreach ($dirs as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+ return $file;
+ }
+ }
+ }
+ }
+ }
+
+ // PSR-0 fallback dirs
+ foreach ($this->fallbackDirsPsr0 as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+ return $file;
+ }
+ }
+
+ // PSR-0 include paths.
+ if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
+ return $file;
+ }
+
+ return false;
+ }
+
+ /**
+ * @return void
+ */
+ private static function initializeIncludeClosure()
+ {
+ if (self::$includeFile !== null) {
+ return;
+ }
+
+ /**
+ * Scope isolated include.
+ *
+ * Prevents access to $this/self from included files.
+ *
+ * @param string $file
+ * @return void
+ */
+ self::$includeFile = \Closure::bind(static function($file) {
+ include $file;
+ }, null, null);
+ }
+}
diff --git a/apps/twofactor_backupcodes/composer/composer/InstalledVersions.php b/apps/twofactor_backupcodes/composer/composer/InstalledVersions.php
new file mode 100644
index 00000000000..51e734a774b
--- /dev/null
+++ b/apps/twofactor_backupcodes/composer/composer/InstalledVersions.php
@@ -0,0 +1,359 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ * Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer;
+
+use Composer\Autoload\ClassLoader;
+use Composer\Semver\VersionParser;
+
+/**
+ * This class is copied in every Composer installed project and available to all
+ *
+ * See also https://getcomposer.org/doc/07-runtime.md#installed-versions
+ *
+ * To require its presence, you can require `composer-runtime-api ^2.0`
+ *
+ * @final
+ */
+class InstalledVersions
+{
+ /**
+ * @var mixed[]|null
+ * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
+ */
+ private static $installed;
+
+ /**
+ * @var bool|null
+ */
+ private static $canGetVendors;
+
+ /**
+ * @var array[]
+ * @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
+ */
+ private static $installedByVendor = array();
+
+ /**
+ * Returns a list of all package names which are present, either by being installed, replaced or provided
+ *
+ * @return string[]
+ * @psalm-return list<string>
+ */
+ public static function getInstalledPackages()
+ {
+ $packages = array();
+ foreach (self::getInstalled() as $installed) {
+ $packages[] = array_keys($installed['versions']);
+ }
+
+ if (1 === \count($packages)) {
+ return $packages[0];
+ }
+
+ return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
+ }
+
+ /**
+ * Returns a list of all package names with a specific type e.g. 'library'
+ *
+ * @param string $type
+ * @return string[]
+ * @psalm-return list<string>
+ */
+ public static function getInstalledPackagesByType($type)
+ {
+ $packagesByType = array();
+
+ foreach (self::getInstalled() as $installed) {
+ foreach ($installed['versions'] as $name => $package) {
+ if (isset($package['type']) && $package['type'] === $type) {
+ $packagesByType[] = $name;
+ }
+ }
+ }
+
+ return $packagesByType;
+ }
+
+ /**
+ * Checks whether the given package is installed
+ *
+ * This also returns true if the package name is provided or replaced by another package
+ *
+ * @param string $packageName
+ * @param bool $includeDevRequirements
+ * @return bool
+ */
+ public static function isInstalled($packageName, $includeDevRequirements = true)
+ {
+ foreach (self::getInstalled() as $installed) {
+ if (isset($installed['versions'][$packageName])) {
+ return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Checks whether the given package satisfies a version constraint
+ *
+ * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
+ *
+ * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
+ *
+ * @param VersionParser $parser Install composer/semver to have access to this class and functionality
+ * @param string $packageName
+ * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
+ * @return bool
+ */
+ public static function satisfies(VersionParser $parser, $packageName, $constraint)
+ {
+ $constraint = $parser->parseConstraints((string) $constraint);
+ $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
+
+ return $provided->matches($constraint);
+ }
+
+ /**
+ * Returns a version constraint representing all the range(s) which are installed for a given package
+ *
+ * It is easier to use this via isInstalled() with the $constraint argument if you need to check
+ * whether a given version of a package is installed, and not just whether it exists
+ *
+ * @param string $packageName
+ * @return string Version constraint usable with composer/semver
+ */
+ public static function getVersionRanges($packageName)
+ {
+ foreach (self::getInstalled() as $installed) {
+ if (!isset($installed['versions'][$packageName])) {
+ continue;
+ }
+
+ $ranges = array();
+ if (isset($installed['versions'][$packageName]['pretty_version'])) {
+ $ranges[] = $installed['versions'][$packageName]['pretty_version'];
+ }
+ if (array_key_exists('aliases', $installed['versions'][$packageName])) {
+ $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
+ }
+ if (array_key_exists('replaced', $installed['versions'][$packageName])) {
+ $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
+ }
+ if (array_key_exists('provided', $installed['versions'][$packageName])) {
+ $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
+ }
+
+ return implode(' || ', $ranges);
+ }
+
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+ }
+
+ /**
+ * @param string $packageName
+ * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
+ */
+ public static function getVersion($packageName)
+ {
+ foreach (self::getInstalled() as $installed) {
+ if (!isset($installed['versions'][$packageName])) {
+ continue;
+ }
+
+ if (!isset($installed['versions'][$packageName]['version'])) {
+ return null;
+ }
+
+ return $installed['versions'][$packageName]['version'];
+ }
+
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+ }
+
+ /**
+ * @param string $packageName
+ * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
+ */
+ public static function getPrettyVersion($packageName)
+ {
+ foreach (self::getInstalled() as $installed) {
+ if (!isset($installed['versions'][$packageName])) {
+ continue;
+ }
+
+ if (!isset($installed['versions'][$packageName]['pretty_version'])) {
+ return null;
+ }
+
+ return $installed['versions'][$packageName]['pretty_version'];
+ }
+
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+ }
+
+ /**
+ * @param string $packageName
+ * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
+ */
+ public static function getReference($packageName)
+ {
+ foreach (self::getInstalled() as $installed) {
+ if (!isset($installed['versions'][$packageName])) {
+ continue;
+ }
+
+ if (!isset($installed['versions'][$packageName]['reference'])) {
+ return null;
+ }
+
+ return $installed['versions'][$packageName]['reference'];
+ }
+
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+ }
+
+ /**
+ * @param string $packageName
+ * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
+ */
+ public static function getInstallPath($packageName)
+ {
+ foreach (self::getInstalled() as $installed) {
+ if (!isset($installed['versions'][$packageName])) {
+ continue;
+ }
+
+ return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
+ }
+
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+ }
+
+ /**
+ * @return array
+ * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
+ */
+ public static function getRootPackage()
+ {
+ $installed = self::getInstalled();
+
+ return $installed[0]['root'];
+ }
+
+ /**
+ * Returns the raw installed.php data for custom implementations
+ *
+ * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
+ * @return array[]
+ * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
+ */
+ public static function getRawData()
+ {
+ @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
+
+ if (null === self::$installed) {
+ // only require the installed.php file if this file is loaded from its dumped location,
+ // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
+ if (substr(__DIR__, -8, 1) !== 'C') {
+ self::$installed = include __DIR__ . '/installed.php';
+ } else {
+ self::$installed = array();
+ }
+ }
+
+ return self::$installed;
+ }
+
+ /**
+ * Returns the raw data of all installed.php which are currently loaded for custom implementations
+ *
+ * @return array[]
+ * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
+ */
+ public static function getAllRawData()
+ {
+ return self::getInstalled();
+ }
+
+ /**
+ * Lets you reload the static array from another file
+ *
+ * This is only useful for complex integrations in which a project needs to use
+ * this class but then also needs to execute another project's autoloader in process,
+ * and wants to ensure both projects have access to their version of installed.php.
+ *
+ * A typical case would be PHPUnit, where it would need to make sure it reads all
+ * the data it needs from this class, then call reload() with
+ * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
+ * the project in which it runs can then also use this class safely, without
+ * interference between PHPUnit's dependencies and the project's dependencies.
+ *
+ * @param array[] $data A vendor/composer/installed.php data set
+ * @return void
+ *
+ * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
+ */
+ public static function reload($data)
+ {
+ self::$installed = $data;
+ self::$installedByVendor = array();
+ }
+
+ /**
+ * @return array[]
+ * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
+ */
+ private static function getInstalled()
+ {
+ if (null === self::$canGetVendors) {
+ self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
+ }
+
+ $installed = array();
+
+ if (self::$canGetVendors) {
+ foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
+ if (isset(self::$installedByVendor[$vendorDir])) {
+ $installed[] = self::$installedByVendor[$vendorDir];
+ } elseif (is_file($vendorDir.'/composer/installed.php')) {
+ /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
+ $required = require $vendorDir.'/composer/installed.php';
+ $installed[] = self::$installedByVendor[$vendorDir] = $required;
+ if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
+ self::$installed = $installed[count($installed) - 1];
+ }
+ }
+ }
+ }
+
+ if (null === self::$installed) {
+ // only require the installed.php file if this file is loaded from its dumped location,
+ // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
+ if (substr(__DIR__, -8, 1) !== 'C') {
+ /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
+ $required = require __DIR__ . '/installed.php';
+ self::$installed = $required;
+ } else {
+ self::$installed = array();
+ }
+ }
+
+ if (self::$installed !== array()) {
+ $installed[] = self::$installed;
+ }
+
+ return $installed;
+ }
+}
diff --git a/apps/twofactor_backupcodes/composer/composer/LICENSE b/apps/twofactor_backupcodes/composer/composer/LICENSE
new file mode 100644
index 00000000000..f27399a042d
--- /dev/null
+++ b/apps/twofactor_backupcodes/composer/composer/LICENSE
@@ -0,0 +1,21 @@
+
+Copyright (c) Nils Adermann, Jordi Boggiano
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
diff --git a/apps/twofactor_backupcodes/composer/composer/autoload_classmap.php b/apps/twofactor_backupcodes/composer/composer/autoload_classmap.php
new file mode 100644
index 00000000000..16dda3f615a
--- /dev/null
+++ b/apps/twofactor_backupcodes/composer/composer/autoload_classmap.php
@@ -0,0 +1,34 @@
+<?php
+
+// autoload_classmap.php @generated by Composer
+
+$vendorDir = dirname(__DIR__);
+$baseDir = $vendorDir;
+
+return array(
+ 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
+ 'OCA\\TwoFactorBackupCodes\\Activity\\Provider' => $baseDir . '/../lib/Activity/Provider.php',
+ 'OCA\\TwoFactorBackupCodes\\AppInfo\\Application' => $baseDir . '/../lib/AppInfo/Application.php',
+ 'OCA\\TwoFactorBackupCodes\\BackgroundJob\\CheckBackupCodes' => $baseDir . '/../lib/BackgroundJob/CheckBackupCodes.php',
+ 'OCA\\TwoFactorBackupCodes\\BackgroundJob\\RememberBackupCodesJob' => $baseDir . '/../lib/BackgroundJob/RememberBackupCodesJob.php',
+ 'OCA\\TwoFactorBackupCodes\\Controller\\SettingsController' => $baseDir . '/../lib/Controller/SettingsController.php',
+ 'OCA\\TwoFactorBackupCodes\\Db\\BackupCode' => $baseDir . '/../lib/Db/BackupCode.php',
+ 'OCA\\TwoFactorBackupCodes\\Db\\BackupCodeMapper' => $baseDir . '/../lib/Db/BackupCodeMapper.php',
+ 'OCA\\TwoFactorBackupCodes\\Event\\CodesGenerated' => $baseDir . '/../lib/Event/CodesGenerated.php',
+ 'OCA\\TwoFactorBackupCodes\\Listener\\ActivityPublisher' => $baseDir . '/../lib/Listener/ActivityPublisher.php',
+ 'OCA\\TwoFactorBackupCodes\\Listener\\ClearNotifications' => $baseDir . '/../lib/Listener/ClearNotifications.php',
+ 'OCA\\TwoFactorBackupCodes\\Listener\\ProviderDisabled' => $baseDir . '/../lib/Listener/ProviderDisabled.php',
+ 'OCA\\TwoFactorBackupCodes\\Listener\\ProviderEnabled' => $baseDir . '/../lib/Listener/ProviderEnabled.php',
+ 'OCA\\TwoFactorBackupCodes\\Listener\\RegistryUpdater' => $baseDir . '/../lib/Listener/RegistryUpdater.php',
+ 'OCA\\TwoFactorBackupCodes\\Listener\\UserDeleted' => $baseDir . '/../lib/Listener/UserDeleted.php',
+ 'OCA\\TwoFactorBackupCodes\\Migration\\CheckBackupCodes' => $baseDir . '/../lib/Migration/CheckBackupCodes.php',
+ 'OCA\\TwoFactorBackupCodes\\Migration\\Version1002Date20170607104347' => $baseDir . '/../lib/Migration/Version1002Date20170607104347.php',
+ 'OCA\\TwoFactorBackupCodes\\Migration\\Version1002Date20170607113030' => $baseDir . '/../lib/Migration/Version1002Date20170607113030.php',
+ 'OCA\\TwoFactorBackupCodes\\Migration\\Version1002Date20170919123342' => $baseDir . '/../lib/Migration/Version1002Date20170919123342.php',
+ 'OCA\\TwoFactorBackupCodes\\Migration\\Version1002Date20170926101419' => $baseDir . '/../lib/Migration/Version1002Date20170926101419.php',
+ 'OCA\\TwoFactorBackupCodes\\Migration\\Version1002Date20180821043638' => $baseDir . '/../lib/Migration/Version1002Date20180821043638.php',
+ 'OCA\\TwoFactorBackupCodes\\Notifications\\Notifier' => $baseDir . '/../lib/Notifications/Notifier.php',
+ 'OCA\\TwoFactorBackupCodes\\Provider\\BackupCodesProvider' => $baseDir . '/../lib/Provider/BackupCodesProvider.php',
+ 'OCA\\TwoFactorBackupCodes\\Service\\BackupCodeStorage' => $baseDir . '/../lib/Service/BackupCodeStorage.php',
+ 'OCA\\TwoFactorBackupCodes\\Settings\\Personal' => $baseDir . '/../lib/Settings/Personal.php',
+);
diff --git a/apps/twofactor_backupcodes/composer/composer/autoload_namespaces.php b/apps/twofactor_backupcodes/composer/composer/autoload_namespaces.php
new file mode 100644
index 00000000000..3f5c9296251
--- /dev/null
+++ b/apps/twofactor_backupcodes/composer/composer/autoload_namespaces.php
@@ -0,0 +1,9 @@
+<?php
+
+// autoload_namespaces.php @generated by Composer
+
+$vendorDir = dirname(__DIR__);
+$baseDir = $vendorDir;
+
+return array(
+);
diff --git a/apps/twofactor_backupcodes/composer/composer/autoload_psr4.php b/apps/twofactor_backupcodes/composer/composer/autoload_psr4.php
new file mode 100644
index 00000000000..873cc7acf2f
--- /dev/null
+++ b/apps/twofactor_backupcodes/composer/composer/autoload_psr4.php
@@ -0,0 +1,10 @@
+<?php
+
+// autoload_psr4.php @generated by Composer
+
+$vendorDir = dirname(__DIR__);
+$baseDir = $vendorDir;
+
+return array(
+ 'OCA\\TwoFactorBackupCodes\\' => array($baseDir . '/../lib'),
+);
diff --git a/apps/twofactor_backupcodes/composer/composer/autoload_real.php b/apps/twofactor_backupcodes/composer/composer/autoload_real.php
new file mode 100644
index 00000000000..b063e83100f
--- /dev/null
+++ b/apps/twofactor_backupcodes/composer/composer/autoload_real.php
@@ -0,0 +1,37 @@
+<?php
+
+// autoload_real.php @generated by Composer
+
+class ComposerAutoloaderInitTwoFactorBackupCodes
+{
+ private static $loader;
+
+ public static function loadClassLoader($class)
+ {
+ if ('Composer\Autoload\ClassLoader' === $class) {
+ require __DIR__ . '/ClassLoader.php';
+ }
+ }
+
+ /**
+ * @return \Composer\Autoload\ClassLoader
+ */
+ public static function getLoader()
+ {
+ if (null !== self::$loader) {
+ return self::$loader;
+ }
+
+ spl_autoload_register(array('ComposerAutoloaderInitTwoFactorBackupCodes', 'loadClassLoader'), true, true);
+ self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
+ spl_autoload_unregister(array('ComposerAutoloaderInitTwoFactorBackupCodes', 'loadClassLoader'));
+
+ require __DIR__ . '/autoload_static.php';
+ call_user_func(\Composer\Autoload\ComposerStaticInitTwoFactorBackupCodes::getInitializer($loader));
+
+ $loader->setClassMapAuthoritative(true);
+ $loader->register(true);
+
+ return $loader;
+ }
+}
diff --git a/apps/twofactor_backupcodes/composer/composer/autoload_static.php b/apps/twofactor_backupcodes/composer/composer/autoload_static.php
new file mode 100644
index 00000000000..e72fad72f5f
--- /dev/null
+++ b/apps/twofactor_backupcodes/composer/composer/autoload_static.php
@@ -0,0 +1,60 @@
+<?php
+
+// autoload_static.php @generated by Composer
+
+namespace Composer\Autoload;
+
+class ComposerStaticInitTwoFactorBackupCodes
+{
+ public static $prefixLengthsPsr4 = array (
+ 'O' =>
+ array (
+ 'OCA\\TwoFactorBackupCodes\\' => 25,
+ ),
+ );
+
+ public static $prefixDirsPsr4 = array (
+ 'OCA\\TwoFactorBackupCodes\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/../lib',
+ ),
+ );
+
+ public static $classMap = array (
+ 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
+ 'OCA\\TwoFactorBackupCodes\\Activity\\Provider' => __DIR__ . '/..' . '/../lib/Activity/Provider.php',
+ 'OCA\\TwoFactorBackupCodes\\AppInfo\\Application' => __DIR__ . '/..' . '/../lib/AppInfo/Application.php',
+ 'OCA\\TwoFactorBackupCodes\\BackgroundJob\\CheckBackupCodes' => __DIR__ . '/..' . '/../lib/BackgroundJob/CheckBackupCodes.php',
+ 'OCA\\TwoFactorBackupCodes\\BackgroundJob\\RememberBackupCodesJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/RememberBackupCodesJob.php',
+ 'OCA\\TwoFactorBackupCodes\\Controller\\SettingsController' => __DIR__ . '/..' . '/../lib/Controller/SettingsController.php',
+ 'OCA\\TwoFactorBackupCodes\\Db\\BackupCode' => __DIR__ . '/..' . '/../lib/Db/BackupCode.php',
+ 'OCA\\TwoFactorBackupCodes\\Db\\BackupCodeMapper' => __DIR__ . '/..' . '/../lib/Db/BackupCodeMapper.php',
+ 'OCA\\TwoFactorBackupCodes\\Event\\CodesGenerated' => __DIR__ . '/..' . '/../lib/Event/CodesGenerated.php',
+ 'OCA\\TwoFactorBackupCodes\\Listener\\ActivityPublisher' => __DIR__ . '/..' . '/../lib/Listener/ActivityPublisher.php',
+ 'OCA\\TwoFactorBackupCodes\\Listener\\ClearNotifications' => __DIR__ . '/..' . '/../lib/Listener/ClearNotifications.php',
+ 'OCA\\TwoFactorBackupCodes\\Listener\\ProviderDisabled' => __DIR__ . '/..' . '/../lib/Listener/ProviderDisabled.php',
+ 'OCA\\TwoFactorBackupCodes\\Listener\\ProviderEnabled' => __DIR__ . '/..' . '/../lib/Listener/ProviderEnabled.php',
+ 'OCA\\TwoFactorBackupCodes\\Listener\\RegistryUpdater' => __DIR__ . '/..' . '/../lib/Listener/RegistryUpdater.php',
+ 'OCA\\TwoFactorBackupCodes\\Listener\\UserDeleted' => __DIR__ . '/..' . '/../lib/Listener/UserDeleted.php',
+ 'OCA\\TwoFactorBackupCodes\\Migration\\CheckBackupCodes' => __DIR__ . '/..' . '/../lib/Migration/CheckBackupCodes.php',
+ 'OCA\\TwoFactorBackupCodes\\Migration\\Version1002Date20170607104347' => __DIR__ . '/..' . '/../lib/Migration/Version1002Date20170607104347.php',
+ 'OCA\\TwoFactorBackupCodes\\Migration\\Version1002Date20170607113030' => __DIR__ . '/..' . '/../lib/Migration/Version1002Date20170607113030.php',
+ 'OCA\\TwoFactorBackupCodes\\Migration\\Version1002Date20170919123342' => __DIR__ . '/..' . '/../lib/Migration/Version1002Date20170919123342.php',
+ 'OCA\\TwoFactorBackupCodes\\Migration\\Version1002Date20170926101419' => __DIR__ . '/..' . '/../lib/Migration/Version1002Date20170926101419.php',
+ 'OCA\\TwoFactorBackupCodes\\Migration\\Version1002Date20180821043638' => __DIR__ . '/..' . '/../lib/Migration/Version1002Date20180821043638.php',
+ 'OCA\\TwoFactorBackupCodes\\Notifications\\Notifier' => __DIR__ . '/..' . '/../lib/Notifications/Notifier.php',
+ 'OCA\\TwoFactorBackupCodes\\Provider\\BackupCodesProvider' => __DIR__ . '/..' . '/../lib/Provider/BackupCodesProvider.php',
+ 'OCA\\TwoFactorBackupCodes\\Service\\BackupCodeStorage' => __DIR__ . '/..' . '/../lib/Service/BackupCodeStorage.php',
+ 'OCA\\TwoFactorBackupCodes\\Settings\\Personal' => __DIR__ . '/..' . '/../lib/Settings/Personal.php',
+ );
+
+ public static function getInitializer(ClassLoader $loader)
+ {
+ return \Closure::bind(function () use ($loader) {
+ $loader->prefixLengthsPsr4 = ComposerStaticInitTwoFactorBackupCodes::$prefixLengthsPsr4;
+ $loader->prefixDirsPsr4 = ComposerStaticInitTwoFactorBackupCodes::$prefixDirsPsr4;
+ $loader->classMap = ComposerStaticInitTwoFactorBackupCodes::$classMap;
+
+ }, null, ClassLoader::class);
+ }
+}
diff --git a/apps/twofactor_backupcodes/composer/composer/installed.json b/apps/twofactor_backupcodes/composer/composer/installed.json
new file mode 100644
index 00000000000..f20a6c47c6d
--- /dev/null
+++ b/apps/twofactor_backupcodes/composer/composer/installed.json
@@ -0,0 +1,5 @@
+{
+ "packages": [],
+ "dev": false,
+ "dev-package-names": []
+}
diff --git a/apps/twofactor_backupcodes/composer/composer/installed.php b/apps/twofactor_backupcodes/composer/composer/installed.php
new file mode 100644
index 00000000000..1a66c7f2416
--- /dev/null
+++ b/apps/twofactor_backupcodes/composer/composer/installed.php
@@ -0,0 +1,23 @@
+<?php return array(
+ 'root' => array(
+ 'name' => '__root__',
+ 'pretty_version' => 'dev-master',
+ 'version' => 'dev-master',
+ 'reference' => 'b1797842784b250fb01ed5e3bf130705eb94751b',
+ 'type' => 'library',
+ 'install_path' => __DIR__ . '/../',
+ 'aliases' => array(),
+ 'dev' => false,
+ ),
+ 'versions' => array(
+ '__root__' => array(
+ 'pretty_version' => 'dev-master',
+ 'version' => 'dev-master',
+ 'reference' => 'b1797842784b250fb01ed5e3bf130705eb94751b',
+ 'type' => 'library',
+ 'install_path' => __DIR__ . '/../',
+ 'aliases' => array(),
+ 'dev_requirement' => false,
+ ),
+ ),
+);
diff --git a/apps/twofactor_backupcodes/css/style.css b/apps/twofactor_backupcodes/css/style.css
new file mode 100644
index 00000000000..8df541fe3dc
--- /dev/null
+++ b/apps/twofactor_backupcodes/css/style.css
@@ -0,0 +1,25 @@
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+.challenge-form {
+ margin: 16px auto 1px !important;
+}
+
+.challenge {
+ margin-top: 0 !important;
+ margin-inline-start: 0 !important;
+ box-sizing: border-box !important;
+ width: 100% !important;
+}
+
+.confirm-inline {
+ position: absolute;
+ inset-inline-end: 0;
+ top: 0;
+ margin: 0 !important;
+ padding-inline-end: 25px !important;
+ background-color: transparent !important;
+ border: none !important;
+ opacity: .5;
+}
diff --git a/apps/twofactor_backupcodes/l10n/.gitkeep b/apps/twofactor_backupcodes/l10n/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/.gitkeep
diff --git a/apps/twofactor_backupcodes/l10n/af.js b/apps/twofactor_backupcodes/l10n/af.js
new file mode 100644
index 00000000000..cdd9083fbc7
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/af.js
@@ -0,0 +1,17 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "U het tweefaktorrugsteunkodes vir u rekening geskep",
+ "Second-factor backup codes" : "Tweedefaktorrugsteunkodes",
+ "Generate backup codes" : "Genereer rugsteunkodes",
+ "Backup code" : "Rugsteunkode",
+ "Use backup code" : "Gebruik rugsteunkode",
+ "Two factor backup codes" : "Tweefaktorrugsteunkodes",
+ "An error occurred while generating your backup codes" : "’n fout het voorgekom tydens generering van u rugsteunkodes",
+ "Save backup codes" : "Bewaar rugsteunkodes",
+ "Print backup codes" : "Druk rugsteunkodes",
+ "Regenerate backup codes" : "Hergenereer rugsteunkodes",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Indien u rugsteunkodes hergenereer maak u outomaties die ou kodes ongeldig.",
+ "Submit" : "Dien in"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/twofactor_backupcodes/l10n/af.json b/apps/twofactor_backupcodes/l10n/af.json
new file mode 100644
index 00000000000..c4fc9d35c4c
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/af.json
@@ -0,0 +1,15 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "U het tweefaktorrugsteunkodes vir u rekening geskep",
+ "Second-factor backup codes" : "Tweedefaktorrugsteunkodes",
+ "Generate backup codes" : "Genereer rugsteunkodes",
+ "Backup code" : "Rugsteunkode",
+ "Use backup code" : "Gebruik rugsteunkode",
+ "Two factor backup codes" : "Tweefaktorrugsteunkodes",
+ "An error occurred while generating your backup codes" : "’n fout het voorgekom tydens generering van u rugsteunkodes",
+ "Save backup codes" : "Bewaar rugsteunkodes",
+ "Print backup codes" : "Druk rugsteunkodes",
+ "Regenerate backup codes" : "Hergenereer rugsteunkodes",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Indien u rugsteunkodes hergenereer maak u outomaties die ou kodes ongeldig.",
+ "Submit" : "Dien in"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/ar.js b/apps/twofactor_backupcodes/l10n/ar.js
new file mode 100644
index 00000000000..0c5f32cbf3d
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/ar.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "لقد قمت بتوليد الأكواد الاحتياطية للدخول مع التحقق ثنائي العوامل لحسابك",
+ "Second-factor backup codes" : "الأكواد الاحتياطية للعامل الثاني في الدخول مع التحقق ثنائي العوامل من الهوية",
+ "Generate backup codes" : "توليد رموز الاسترجاع الاحتياطية",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "لقد قمت بتمكين التحقّق المثنى من الهوية لكنك لم تقم بتوليد الأكواد الاحتياطية بعد. ستحتاج هذه الأكواد لاسترجاع حق الدخول لحسابك إذا ما ضاع عاملك الثاني في الدخول.",
+ "Backup code" : "الرمز الاحتياطي",
+ "Use backup code" : "إستخدم الرمز الإحتياطي",
+ "Two factor backup codes" : "الأكواد الاحتياطية للتحقق ثنائي العوامل",
+ "A two-factor auth backup codes provider" : "مزوّد الأكواد الاحتياطية للتحقق ثنائي العوامل من الهويّة",
+ "An error occurred while generating your backup codes" : "حدث خطأ عند توليد أكوادك الاحتياطية",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "تمّ توليد الأكواد الاحتياطية. {used} من {total} تمّ استخدامها.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "هذه هي الرموز الاحتياطية الخاصة بك. يرجى حفظها و/أو طباعتها لأنك لن تتمكن من قراءة الرموز لاحقًا.",
+ "Save backup codes" : "الإحتفاظ بالرموز الإحتياطية",
+ "Print backup codes" : "طباعة الرموز الإحتياطية",
+ "Regenerate backup codes" : "إعادة توليد رموز الإسترجاع الإحتياطية",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "عندما تقوم بتوليد أكواد احتياطية جديدة، فإن الأكواد القديمة تفقد صلاحيتها تلقائيّتاً.",
+ "{name} backup codes" : "{name} أكواد احتياطية",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "استخدم واحداً من الأكواد الاحتياطية التي سبق و أن خزنتها عند تجهيز إعدادات التحقق ثنائي العوامل من الهويّة.",
+ "Submit" : "إرسال "
+},
+"nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;");
diff --git a/apps/twofactor_backupcodes/l10n/ar.json b/apps/twofactor_backupcodes/l10n/ar.json
new file mode 100644
index 00000000000..0e496b1fb71
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/ar.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "لقد قمت بتوليد الأكواد الاحتياطية للدخول مع التحقق ثنائي العوامل لحسابك",
+ "Second-factor backup codes" : "الأكواد الاحتياطية للعامل الثاني في الدخول مع التحقق ثنائي العوامل من الهوية",
+ "Generate backup codes" : "توليد رموز الاسترجاع الاحتياطية",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "لقد قمت بتمكين التحقّق المثنى من الهوية لكنك لم تقم بتوليد الأكواد الاحتياطية بعد. ستحتاج هذه الأكواد لاسترجاع حق الدخول لحسابك إذا ما ضاع عاملك الثاني في الدخول.",
+ "Backup code" : "الرمز الاحتياطي",
+ "Use backup code" : "إستخدم الرمز الإحتياطي",
+ "Two factor backup codes" : "الأكواد الاحتياطية للتحقق ثنائي العوامل",
+ "A two-factor auth backup codes provider" : "مزوّد الأكواد الاحتياطية للتحقق ثنائي العوامل من الهويّة",
+ "An error occurred while generating your backup codes" : "حدث خطأ عند توليد أكوادك الاحتياطية",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "تمّ توليد الأكواد الاحتياطية. {used} من {total} تمّ استخدامها.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "هذه هي الرموز الاحتياطية الخاصة بك. يرجى حفظها و/أو طباعتها لأنك لن تتمكن من قراءة الرموز لاحقًا.",
+ "Save backup codes" : "الإحتفاظ بالرموز الإحتياطية",
+ "Print backup codes" : "طباعة الرموز الإحتياطية",
+ "Regenerate backup codes" : "إعادة توليد رموز الإسترجاع الإحتياطية",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "عندما تقوم بتوليد أكواد احتياطية جديدة، فإن الأكواد القديمة تفقد صلاحيتها تلقائيّتاً.",
+ "{name} backup codes" : "{name} أكواد احتياطية",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "استخدم واحداً من الأكواد الاحتياطية التي سبق و أن خزنتها عند تجهيز إعدادات التحقق ثنائي العوامل من الهويّة.",
+ "Submit" : "إرسال "
+},"pluralForm" :"nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/ast.js b/apps/twofactor_backupcodes/l10n/ast.js
new file mode 100644
index 00000000000..787fc3bf72f
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/ast.js
@@ -0,0 +1,22 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Creesti los códigos de recuperación pa l'autenticación en dos pasos de la to cuenta",
+ "Second-factor backup codes" : "Códigos de recuperación de l'autenticación en dos pasos",
+ "Generate backup codes" : "Xenerar códigos de recuperación",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Activesti l'autenticación en dos pasos mas entá nun xeneresti nengún códigu de recuperación. Estos códigos precísense pa recuperar l'accesu a la to cuenta en casu de perder l'autenticación en dos pasos.",
+ "Backup code" : "Códigu de recuperación",
+ "Use backup code" : "Usar un códigu de recuperación",
+ "Two factor backup codes" : "Códigos de recuperación de l'autenticación en dos pasos",
+ "A two-factor auth backup codes provider" : "Un fornidor de códigos de recuperación pa l'autenticación en dos pasos",
+ "An error occurred while generating your backup codes" : "Prodúxose un error mentanto se xeneraben los códigos de recuperación",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Xeneráronse los códigos de recuperación y usáronse {used} de {total} códigos.",
+ "Save backup codes" : "Guardar los códigos de recuperación",
+ "Print backup codes" : "Imprentar los códigos de recuperación",
+ "Regenerate backup codes" : "Volver xenerar los códigos de recuperación",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si vuelves xenerar los códigos de recuperación, anules automáticamente los antiguos.",
+ "{name} backup codes" : "Códigos de recuperación de: {name}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Usa unu de los códigos de recuperación que guardesti cuando configuresti l'autenticación en dos pasos.",
+ "Submit" : "Unviar"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/twofactor_backupcodes/l10n/ast.json b/apps/twofactor_backupcodes/l10n/ast.json
new file mode 100644
index 00000000000..ff63a8a9cf4
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/ast.json
@@ -0,0 +1,20 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Creesti los códigos de recuperación pa l'autenticación en dos pasos de la to cuenta",
+ "Second-factor backup codes" : "Códigos de recuperación de l'autenticación en dos pasos",
+ "Generate backup codes" : "Xenerar códigos de recuperación",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Activesti l'autenticación en dos pasos mas entá nun xeneresti nengún códigu de recuperación. Estos códigos precísense pa recuperar l'accesu a la to cuenta en casu de perder l'autenticación en dos pasos.",
+ "Backup code" : "Códigu de recuperación",
+ "Use backup code" : "Usar un códigu de recuperación",
+ "Two factor backup codes" : "Códigos de recuperación de l'autenticación en dos pasos",
+ "A two-factor auth backup codes provider" : "Un fornidor de códigos de recuperación pa l'autenticación en dos pasos",
+ "An error occurred while generating your backup codes" : "Prodúxose un error mentanto se xeneraben los códigos de recuperación",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Xeneráronse los códigos de recuperación y usáronse {used} de {total} códigos.",
+ "Save backup codes" : "Guardar los códigos de recuperación",
+ "Print backup codes" : "Imprentar los códigos de recuperación",
+ "Regenerate backup codes" : "Volver xenerar los códigos de recuperación",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si vuelves xenerar los códigos de recuperación, anules automáticamente los antiguos.",
+ "{name} backup codes" : "Códigos de recuperación de: {name}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Usa unu de los códigos de recuperación que guardesti cuando configuresti l'autenticación en dos pasos.",
+ "Submit" : "Unviar"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/bg.js b/apps/twofactor_backupcodes/l10n/bg.js
new file mode 100644
index 00000000000..a690b5d6afe
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/bg.js
@@ -0,0 +1,22 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Създадохте резервен код за двустепенното удостоверяване за вашия профил",
+ "Second-factor backup codes" : "Резервен код за втората стъпка",
+ "Generate backup codes" : "Генериране на резервни кодове",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Активирали сте двустепенно удостоверяване, но все още не сте генерирали резервни кодове. Те са необходими за възстановяване на достъп до вашия профил, в случай че загубите втората си стъпка.",
+ "Backup code" : "Резервен код",
+ "Use backup code" : "Използвай код за възстановяване",
+ "Two factor backup codes" : "Двустепенни резервни кодове",
+ "A two-factor auth backup codes provider" : "Доставчик на двустепенни резервни кодове за удостоверяване",
+ "An error occurred while generating your backup codes" : "Възникна грешка при генерирането на резервния код",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Резервен код е бил генериран. Използвани са {used} от {total} кода.",
+ "Save backup codes" : "Записване на резервния код",
+ "Print backup codes" : "Принтиране на резервния код",
+ "Regenerate backup codes" : "Регенериране на резервния код",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "При регенерирането на резервния код, стария код автоматично бива анулиран.",
+ "{name} backup codes" : "{name} резервни кодове",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Използвайте един от резервните кодове, които сте запазили, когато настройвате двустепенно удостоверяване.",
+ "Submit" : "Изпращане"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/twofactor_backupcodes/l10n/bg.json b/apps/twofactor_backupcodes/l10n/bg.json
new file mode 100644
index 00000000000..8a60d037158
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/bg.json
@@ -0,0 +1,20 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Създадохте резервен код за двустепенното удостоверяване за вашия профил",
+ "Second-factor backup codes" : "Резервен код за втората стъпка",
+ "Generate backup codes" : "Генериране на резервни кодове",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Активирали сте двустепенно удостоверяване, но все още не сте генерирали резервни кодове. Те са необходими за възстановяване на достъп до вашия профил, в случай че загубите втората си стъпка.",
+ "Backup code" : "Резервен код",
+ "Use backup code" : "Използвай код за възстановяване",
+ "Two factor backup codes" : "Двустепенни резервни кодове",
+ "A two-factor auth backup codes provider" : "Доставчик на двустепенни резервни кодове за удостоверяване",
+ "An error occurred while generating your backup codes" : "Възникна грешка при генерирането на резервния код",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Резервен код е бил генериран. Използвани са {used} от {total} кода.",
+ "Save backup codes" : "Записване на резервния код",
+ "Print backup codes" : "Принтиране на резервния код",
+ "Regenerate backup codes" : "Регенериране на резервния код",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "При регенерирането на резервния код, стария код автоматично бива анулиран.",
+ "{name} backup codes" : "{name} резервни кодове",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Използвайте един от резервните кодове, които сте запазили, когато настройвате двустепенно удостоверяване.",
+ "Submit" : "Изпращане"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/ca.js b/apps/twofactor_backupcodes/l10n/ca.js
new file mode 100644
index 00000000000..a530ac84138
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/ca.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Heu creat els codis de reserva de dos factors per al vostre compte",
+ "Second-factor backup codes" : "Codis de reserva de dos factors",
+ "Generate backup codes" : "Genera els codis de reserva",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Heu habilitat l'autenticació de dos factors, però encara no heu generat codis de reserva. Els necessitareu per a restablir l'accés al compte si perdeu el segon factor.",
+ "Backup code" : "Codi de reserva",
+ "Use backup code" : "Utilitza un codi de reserva",
+ "Two factor backup codes" : "Codis de reserva de l'autenticació de dos factors",
+ "A two-factor auth backup codes provider" : "Proveïdor de codis de reserva de l'autenticació de dos factors",
+ "An error occurred while generating your backup codes" : "S'ha produït un error en generar els codis de reserva",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "S'han generat els codis de reserva. Heu utilitzat {used} de {total} codis.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Aquests són els vostres codis de reserva. Deseu-los o imprimiu-los, ja que no podreu tornar-los a consultar més tard.",
+ "Save backup codes" : "Desa els codis de reserva",
+ "Print backup codes" : "Imprimeix els codis de reserva",
+ "Regenerate backup codes" : "Torna a generar els codis de reserva",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si torneu a generar els codis de reserva, anul·lareu automàticament els codis antics.",
+ "{name} backup codes" : "Codis de seguretat per a {name}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Utilitzeu un dels codis de reserva que vau desar en configurar l'autenticació de dos factors.",
+ "Submit" : "Envia"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/twofactor_backupcodes/l10n/ca.json b/apps/twofactor_backupcodes/l10n/ca.json
new file mode 100644
index 00000000000..a57edf504f4
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/ca.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Heu creat els codis de reserva de dos factors per al vostre compte",
+ "Second-factor backup codes" : "Codis de reserva de dos factors",
+ "Generate backup codes" : "Genera els codis de reserva",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Heu habilitat l'autenticació de dos factors, però encara no heu generat codis de reserva. Els necessitareu per a restablir l'accés al compte si perdeu el segon factor.",
+ "Backup code" : "Codi de reserva",
+ "Use backup code" : "Utilitza un codi de reserva",
+ "Two factor backup codes" : "Codis de reserva de l'autenticació de dos factors",
+ "A two-factor auth backup codes provider" : "Proveïdor de codis de reserva de l'autenticació de dos factors",
+ "An error occurred while generating your backup codes" : "S'ha produït un error en generar els codis de reserva",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "S'han generat els codis de reserva. Heu utilitzat {used} de {total} codis.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Aquests són els vostres codis de reserva. Deseu-los o imprimiu-los, ja que no podreu tornar-los a consultar més tard.",
+ "Save backup codes" : "Desa els codis de reserva",
+ "Print backup codes" : "Imprimeix els codis de reserva",
+ "Regenerate backup codes" : "Torna a generar els codis de reserva",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si torneu a generar els codis de reserva, anul·lareu automàticament els codis antics.",
+ "{name} backup codes" : "Codis de seguretat per a {name}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Utilitzeu un dels codis de reserva que vau desar en configurar l'autenticació de dos factors.",
+ "Submit" : "Envia"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/cs.js b/apps/twofactor_backupcodes/l10n/cs.js
new file mode 100644
index 00000000000..cfb0cf59dc3
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/cs.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Vytvořili jste záložní kódy pro dvoufázové ověřování se pro svůj účet",
+ "Second-factor backup codes" : "Záložní kódy pro dvoufázové ověřování",
+ "Generate backup codes" : "Vytvořit záložní kódy",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Zapnuli jste si dvoufázové ověřování, ale doposud nenechali vytvořit záložní kódy. Ty jsou potřebné pro obnovení přístupu k vašemu účtu v případě, že ztratíte druhý faktor.",
+ "Backup code" : "Záložní kód",
+ "Use backup code" : "Použít záložní kód",
+ "Two factor backup codes" : "Záložní kódy pro dvoufázové ověřování",
+ "A two-factor auth backup codes provider" : "Poskytovatel záložních kódů pro dvoufázové ověřování",
+ "An error occurred while generating your backup codes" : "Při pokusu o vytvoření záložních kódů nastala chyba.",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Záložní kódy byly vytvořeny. Využito {used} z {total} kódů.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Zde jsou vaše záložní kódy. Kódy si uložte a/nebo vytiskněte, protože už je nebude možné zobrazit znovu.",
+ "Save backup codes" : "Uložit záložní kódy",
+ "Print backup codes" : "Vytisknout záložní kódy",
+ "Regenerate backup codes" : "Vytvořit nové záložní kódy",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Pokud necháte vytvořit nové záložní kódy, staré budou automaticky zneplatněny.",
+ "{name} backup codes" : "{name} záložní kódy",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Použijte jeden ze svých záložních kódů které jste si uložili při nastavování dvoufázového ověřování.",
+ "Submit" : "Odeslat"
+},
+"nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;");
diff --git a/apps/twofactor_backupcodes/l10n/cs.json b/apps/twofactor_backupcodes/l10n/cs.json
new file mode 100644
index 00000000000..199c42c7e99
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/cs.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Vytvořili jste záložní kódy pro dvoufázové ověřování se pro svůj účet",
+ "Second-factor backup codes" : "Záložní kódy pro dvoufázové ověřování",
+ "Generate backup codes" : "Vytvořit záložní kódy",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Zapnuli jste si dvoufázové ověřování, ale doposud nenechali vytvořit záložní kódy. Ty jsou potřebné pro obnovení přístupu k vašemu účtu v případě, že ztratíte druhý faktor.",
+ "Backup code" : "Záložní kód",
+ "Use backup code" : "Použít záložní kód",
+ "Two factor backup codes" : "Záložní kódy pro dvoufázové ověřování",
+ "A two-factor auth backup codes provider" : "Poskytovatel záložních kódů pro dvoufázové ověřování",
+ "An error occurred while generating your backup codes" : "Při pokusu o vytvoření záložních kódů nastala chyba.",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Záložní kódy byly vytvořeny. Využito {used} z {total} kódů.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Zde jsou vaše záložní kódy. Kódy si uložte a/nebo vytiskněte, protože už je nebude možné zobrazit znovu.",
+ "Save backup codes" : "Uložit záložní kódy",
+ "Print backup codes" : "Vytisknout záložní kódy",
+ "Regenerate backup codes" : "Vytvořit nové záložní kódy",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Pokud necháte vytvořit nové záložní kódy, staré budou automaticky zneplatněny.",
+ "{name} backup codes" : "{name} záložní kódy",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Použijte jeden ze svých záložních kódů které jste si uložili při nastavování dvoufázového ověřování.",
+ "Submit" : "Odeslat"
+},"pluralForm" :"nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/da.js b/apps/twofactor_backupcodes/l10n/da.js
new file mode 100644
index 00000000000..29ba82cb980
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/da.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Du har lavet two-factor backup koder til din konto",
+ "Second-factor backup codes" : "Second-factor backup koder",
+ "Generate backup codes" : "Generer backup koder",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Du har aktiveret to-faktor-godkendelse, men har ikke genereret backup-koder endnu. De er nødvendige for at gendanne adgang til din konto, hvis du mister din anden faktor.",
+ "Backup code" : "Backup-kode",
+ "Use backup code" : "Anvend backup kode",
+ "Two factor backup codes" : "To faktor backup koder",
+ "A two-factor auth backup codes provider" : "En to-faktor udbyder af sikkerhedskopieringskoder",
+ "An error occurred while generating your backup codes" : "Der opstod en fejl under genereringen af dine backup-koder",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Sikkerhedskopieringskoder er blevet genereret. {used} af {total} koder er blevet brugt.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Dette er dine backup-koder. Gem og/eller udskriv dem, da du ikke vil kunne se koderne igen senere.",
+ "Save backup codes" : "Gem backup-koder",
+ "Print backup codes" : "Print backup-koder",
+ "Regenerate backup codes" : "Regenerer backup-koder",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Hvis du genererer nye backupkoder, så vil de gamle koder blive ubrugelige.",
+ "{name} backup codes" : "{name} backup-koder",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Brug en af de backupkoder, du har gemt, når du konfigurerer to-faktor-godkendelse.",
+ "Submit" : "Tilføj"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/twofactor_backupcodes/l10n/da.json b/apps/twofactor_backupcodes/l10n/da.json
new file mode 100644
index 00000000000..21e8083f0f6
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/da.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Du har lavet two-factor backup koder til din konto",
+ "Second-factor backup codes" : "Second-factor backup koder",
+ "Generate backup codes" : "Generer backup koder",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Du har aktiveret to-faktor-godkendelse, men har ikke genereret backup-koder endnu. De er nødvendige for at gendanne adgang til din konto, hvis du mister din anden faktor.",
+ "Backup code" : "Backup-kode",
+ "Use backup code" : "Anvend backup kode",
+ "Two factor backup codes" : "To faktor backup koder",
+ "A two-factor auth backup codes provider" : "En to-faktor udbyder af sikkerhedskopieringskoder",
+ "An error occurred while generating your backup codes" : "Der opstod en fejl under genereringen af dine backup-koder",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Sikkerhedskopieringskoder er blevet genereret. {used} af {total} koder er blevet brugt.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Dette er dine backup-koder. Gem og/eller udskriv dem, da du ikke vil kunne se koderne igen senere.",
+ "Save backup codes" : "Gem backup-koder",
+ "Print backup codes" : "Print backup-koder",
+ "Regenerate backup codes" : "Regenerer backup-koder",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Hvis du genererer nye backupkoder, så vil de gamle koder blive ubrugelige.",
+ "{name} backup codes" : "{name} backup-koder",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Brug en af de backupkoder, du har gemt, når du konfigurerer to-faktor-godkendelse.",
+ "Submit" : "Tilføj"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/de.js b/apps/twofactor_backupcodes/l10n/de.js
new file mode 100644
index 00000000000..a4e7c13ab45
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/de.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Du hast Zwei-Faktor Sicherungs-Codes für dein Konto erstellt",
+ "Second-factor backup codes" : "Zweitfaktor Backup-Codes",
+ "Generate backup codes" : "Backup-Codes erzeugen",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Du hast die Zwei-Faktor-Authentifizierung aktiviert, aber noch keine Backup-Codes erzeugt. Diese werden für den Fall benötigt, dass du den Zugriff auf deinen zweiten Faktor verloren hast.",
+ "Backup code" : "Backup-Code",
+ "Use backup code" : "Verwende Backup-Code",
+ "Two factor backup codes" : "Zwei-Faktor-Backup-Codes",
+ "A two-factor auth backup codes provider" : "Ein Anbieter für Zwei-Faktor-Backup-Codes",
+ "An error occurred while generating your backup codes" : "Es ist ein Fehler beim Erstellen deiner Backup-Codes aufgetreten",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Backup-Codes wurden erzeugt. {used} von {total} Codes wurden benutzt.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Dies sind deine Backup-Codes. Bitte speichere und/oder drucke diese aus, da du die Codes später nicht mehr abrufen kannst.",
+ "Save backup codes" : "Backup-Codes speichern",
+ "Print backup codes" : "Backup-Codes drucken",
+ "Regenerate backup codes" : "Backup-Codes erneuern",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Wenn du Backup-Codes erneuerst, werden alte automatisch ungültig.",
+ "{name} backup codes" : "{name} Backup-Codes",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Verwende einen der Backup-Codes, den du bei der Einrichtung der Zwei-Faktor-Authentifizierung gespeichert hast.",
+ "Submit" : "Übermitteln"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/twofactor_backupcodes/l10n/de.json b/apps/twofactor_backupcodes/l10n/de.json
new file mode 100644
index 00000000000..290f9f47be3
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/de.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Du hast Zwei-Faktor Sicherungs-Codes für dein Konto erstellt",
+ "Second-factor backup codes" : "Zweitfaktor Backup-Codes",
+ "Generate backup codes" : "Backup-Codes erzeugen",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Du hast die Zwei-Faktor-Authentifizierung aktiviert, aber noch keine Backup-Codes erzeugt. Diese werden für den Fall benötigt, dass du den Zugriff auf deinen zweiten Faktor verloren hast.",
+ "Backup code" : "Backup-Code",
+ "Use backup code" : "Verwende Backup-Code",
+ "Two factor backup codes" : "Zwei-Faktor-Backup-Codes",
+ "A two-factor auth backup codes provider" : "Ein Anbieter für Zwei-Faktor-Backup-Codes",
+ "An error occurred while generating your backup codes" : "Es ist ein Fehler beim Erstellen deiner Backup-Codes aufgetreten",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Backup-Codes wurden erzeugt. {used} von {total} Codes wurden benutzt.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Dies sind deine Backup-Codes. Bitte speichere und/oder drucke diese aus, da du die Codes später nicht mehr abrufen kannst.",
+ "Save backup codes" : "Backup-Codes speichern",
+ "Print backup codes" : "Backup-Codes drucken",
+ "Regenerate backup codes" : "Backup-Codes erneuern",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Wenn du Backup-Codes erneuerst, werden alte automatisch ungültig.",
+ "{name} backup codes" : "{name} Backup-Codes",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Verwende einen der Backup-Codes, den du bei der Einrichtung der Zwei-Faktor-Authentifizierung gespeichert hast.",
+ "Submit" : "Übermitteln"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/de_DE.js b/apps/twofactor_backupcodes/l10n/de_DE.js
new file mode 100644
index 00000000000..800e3e112c1
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/de_DE.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Sie haben Zwei-Faktor Sicherungs-Codes für Ihr Konto erstellt",
+ "Second-factor backup codes" : "Backup-Codes für Zweitfaktor",
+ "Generate backup codes" : "Backup-Codes erzeugen",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Sie haben die Zwei-Faktor-Authentifizierung aktiviert, aber noch keine Backup-Codes erzeugt. Diese werden für den Fall benötigt, dass Sie den Zugriff auf Ihren zweiten Faktor verlieren.",
+ "Backup code" : "Backup-Code",
+ "Use backup code" : "Backup-Code verwenden",
+ "Two factor backup codes" : "Zwei-Faktor-Backup-Codes",
+ "A two-factor auth backup codes provider" : "Ein Anbieter für Zwei-Faktor-Backup-Codes",
+ "An error occurred while generating your backup codes" : "Es ist ein Fehler beim Erstellen Ihrer Backup-Codes aufgetreten",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Backup-Codes wurden erzeugt. {used} von {total} Codes wurden benutzt.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Dies sind Ihre Backup-Codes. Bitte speichern und/oder drucken Sie diese aus, da Sie die Codes später nicht mehr abrufen können.",
+ "Save backup codes" : "Backup-Codes speichern",
+ "Print backup codes" : "Backup-Codes drucken",
+ "Regenerate backup codes" : "Backup-Codes erneuern",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Wenn Sie die Backup-Codes erneuern, werden die alten Codes automatisch ungültig.",
+ "{name} backup codes" : "{name} Backup-Codes",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Verwenden Sie einen der Backup-Codes, den Sie bei der Einrichtung der Zwei-Faktor-Authentifizierung gespeichert haben.",
+ "Submit" : "Übermitteln"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/twofactor_backupcodes/l10n/de_DE.json b/apps/twofactor_backupcodes/l10n/de_DE.json
new file mode 100644
index 00000000000..04f73e1e330
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/de_DE.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Sie haben Zwei-Faktor Sicherungs-Codes für Ihr Konto erstellt",
+ "Second-factor backup codes" : "Backup-Codes für Zweitfaktor",
+ "Generate backup codes" : "Backup-Codes erzeugen",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Sie haben die Zwei-Faktor-Authentifizierung aktiviert, aber noch keine Backup-Codes erzeugt. Diese werden für den Fall benötigt, dass Sie den Zugriff auf Ihren zweiten Faktor verlieren.",
+ "Backup code" : "Backup-Code",
+ "Use backup code" : "Backup-Code verwenden",
+ "Two factor backup codes" : "Zwei-Faktor-Backup-Codes",
+ "A two-factor auth backup codes provider" : "Ein Anbieter für Zwei-Faktor-Backup-Codes",
+ "An error occurred while generating your backup codes" : "Es ist ein Fehler beim Erstellen Ihrer Backup-Codes aufgetreten",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Backup-Codes wurden erzeugt. {used} von {total} Codes wurden benutzt.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Dies sind Ihre Backup-Codes. Bitte speichern und/oder drucken Sie diese aus, da Sie die Codes später nicht mehr abrufen können.",
+ "Save backup codes" : "Backup-Codes speichern",
+ "Print backup codes" : "Backup-Codes drucken",
+ "Regenerate backup codes" : "Backup-Codes erneuern",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Wenn Sie die Backup-Codes erneuern, werden die alten Codes automatisch ungültig.",
+ "{name} backup codes" : "{name} Backup-Codes",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Verwenden Sie einen der Backup-Codes, den Sie bei der Einrichtung der Zwei-Faktor-Authentifizierung gespeichert haben.",
+ "Submit" : "Übermitteln"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/el.js b/apps/twofactor_backupcodes/l10n/el.js
new file mode 100644
index 00000000000..cda1c9ba2bb
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/el.js
@@ -0,0 +1,22 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Μπορείτε να δημιουργήσετε τον παράγοντα διπλού ελέγχου ταυτότητας για το λογαριασμό σας ΤΟΤΡ",
+ "Second-factor backup codes" : "Εφεδρικοί κωδικοί δεύτερου-παράγοντα",
+ "Generate backup codes" : "Δημιουργία εφεδρικών κωδικών",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Ενεργοποιήσατε τον έλεγχο ταυτότητας δύο παραγόντων, αλλά δεν δημιουργήθηκαν ακόμη εφεδρικοί κωδικοί. Απαιτούνται για να αποκαταστήσετε την πρόσβαση στο λογαριασμό σας σε περίπτωση που χάσετε τον δεύτερο παράγοντα.",
+ "Backup code" : "Εφεδρικός κωδικός",
+ "Use backup code" : "Χρησιμοποιήστε έναν εφεδρικό κωδικό",
+ "Two factor backup codes" : "Δύο συντελεστές δημιουργίας αντιγράφων",
+ "A two-factor auth backup codes provider" : "Παροχέας εφεδρικών κωδικών δύο-παραγόντων",
+ "An error occurred while generating your backup codes" : "Ένα σφάλμα προέκυψε κατά τη δημιουργία των εφεδρικών κωδικών.",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Δημιουργήθηκαν εφεδρικοί κωδικοί. Χρησιμοποιήθηκαν {used} από {total} κωδικοί.",
+ "Save backup codes" : "Αποθήκευση εφεδρικών κωδικών",
+ "Print backup codes" : "Εκτύπωση εφεδρικών κωδικών",
+ "Regenerate backup codes" : "Δημιουργία εφεδρικών κωδικών",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Εάν αναδημιουργήσετε εφεδρικούς κωδικούς, οι παλιοί κωδικοί ακυρώνονται αυτόματα.",
+ "{name} backup codes" : "{name} εφεδρικοί κωδικοί",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Χρησιμοποιήστε έναν από τους εφεδρικούς κωδικούς που αποθηκεύσατε όταν ρυθμίζετε τον έλεγχο ταυτότητας δύο παραγόντων.",
+ "Submit" : "Υποβολή"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/twofactor_backupcodes/l10n/el.json b/apps/twofactor_backupcodes/l10n/el.json
new file mode 100644
index 00000000000..1f43bf0c068
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/el.json
@@ -0,0 +1,20 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Μπορείτε να δημιουργήσετε τον παράγοντα διπλού ελέγχου ταυτότητας για το λογαριασμό σας ΤΟΤΡ",
+ "Second-factor backup codes" : "Εφεδρικοί κωδικοί δεύτερου-παράγοντα",
+ "Generate backup codes" : "Δημιουργία εφεδρικών κωδικών",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Ενεργοποιήσατε τον έλεγχο ταυτότητας δύο παραγόντων, αλλά δεν δημιουργήθηκαν ακόμη εφεδρικοί κωδικοί. Απαιτούνται για να αποκαταστήσετε την πρόσβαση στο λογαριασμό σας σε περίπτωση που χάσετε τον δεύτερο παράγοντα.",
+ "Backup code" : "Εφεδρικός κωδικός",
+ "Use backup code" : "Χρησιμοποιήστε έναν εφεδρικό κωδικό",
+ "Two factor backup codes" : "Δύο συντελεστές δημιουργίας αντιγράφων",
+ "A two-factor auth backup codes provider" : "Παροχέας εφεδρικών κωδικών δύο-παραγόντων",
+ "An error occurred while generating your backup codes" : "Ένα σφάλμα προέκυψε κατά τη δημιουργία των εφεδρικών κωδικών.",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Δημιουργήθηκαν εφεδρικοί κωδικοί. Χρησιμοποιήθηκαν {used} από {total} κωδικοί.",
+ "Save backup codes" : "Αποθήκευση εφεδρικών κωδικών",
+ "Print backup codes" : "Εκτύπωση εφεδρικών κωδικών",
+ "Regenerate backup codes" : "Δημιουργία εφεδρικών κωδικών",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Εάν αναδημιουργήσετε εφεδρικούς κωδικούς, οι παλιοί κωδικοί ακυρώνονται αυτόματα.",
+ "{name} backup codes" : "{name} εφεδρικοί κωδικοί",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Χρησιμοποιήστε έναν από τους εφεδρικούς κωδικούς που αποθηκεύσατε όταν ρυθμίζετε τον έλεγχο ταυτότητας δύο παραγόντων.",
+ "Submit" : "Υποβολή"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/en_GB.js b/apps/twofactor_backupcodes/l10n/en_GB.js
new file mode 100644
index 00000000000..e2426b031c8
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/en_GB.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "You created two-factor backup codes for your account",
+ "Second-factor backup codes" : "Second-factor backup codes",
+ "Generate backup codes" : "Generate backup codes",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor.",
+ "Backup code" : "Backup code",
+ "Use backup code" : "Use backup code",
+ "Two factor backup codes" : "Two factor backup codes",
+ "A two-factor auth backup codes provider" : "A two-factor auth backup codes provider",
+ "An error occurred while generating your backup codes" : "An error occurred while generating your backup codes",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Backup codes have been generated. {used} of {total} codes have been used.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later.",
+ "Save backup codes" : "Save backup codes",
+ "Print backup codes" : "Print backup codes",
+ "Regenerate backup codes" : "Regenerate backup codes",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "If you regenerate backup codes, you automatically invalidate old codes.",
+ "{name} backup codes" : "{name} backup codes",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Use one of the backup codes you saved when setting up two-factor authentication.",
+ "Submit" : "Submit"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/twofactor_backupcodes/l10n/en_GB.json b/apps/twofactor_backupcodes/l10n/en_GB.json
new file mode 100644
index 00000000000..2b255e97cd7
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/en_GB.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "You created two-factor backup codes for your account",
+ "Second-factor backup codes" : "Second-factor backup codes",
+ "Generate backup codes" : "Generate backup codes",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor.",
+ "Backup code" : "Backup code",
+ "Use backup code" : "Use backup code",
+ "Two factor backup codes" : "Two factor backup codes",
+ "A two-factor auth backup codes provider" : "A two-factor auth backup codes provider",
+ "An error occurred while generating your backup codes" : "An error occurred while generating your backup codes",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Backup codes have been generated. {used} of {total} codes have been used.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later.",
+ "Save backup codes" : "Save backup codes",
+ "Print backup codes" : "Print backup codes",
+ "Regenerate backup codes" : "Regenerate backup codes",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "If you regenerate backup codes, you automatically invalidate old codes.",
+ "{name} backup codes" : "{name} backup codes",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Use one of the backup codes you saved when setting up two-factor authentication.",
+ "Submit" : "Submit"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/eo.js b/apps/twofactor_backupcodes/l10n/eo.js
new file mode 100644
index 00000000000..8cf8ac95ce5
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/eo.js
@@ -0,0 +1,22 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Vi kreis dufazajn rezervkodojn por via konto",
+ "Second-factor backup codes" : "Dufazaj rezervkodoj",
+ "Generate backup codes" : "Generi rezervkodojn",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Vi ŝaltis dufazan aŭtentigon, sed vi ankoraŭ ne generis rezervkodojn. Ĉi tiuj lastaj nepras por restaŭri aliron al via konto okaze de perdo de via dua fazo.",
+ "Backup code" : "Rezervkodo",
+ "Use backup code" : "Uzi rezervkodon",
+ "Two factor backup codes" : "Dufazaj rezervkodoj",
+ "A two-factor auth backup codes provider" : "Provizanto de rezervkodoj por dufaza aŭtentigo",
+ "An error occurred while generating your backup codes" : "Eraro okazis dum generado de viaj rezervkodoj",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Rezervkodoj generiĝis. {used} kodoj el {total} uziĝis.",
+ "Save backup codes" : "Konservi la rezervkodojn",
+ "Print backup codes" : "Presi la rezervkodojn",
+ "Regenerate backup codes" : "Regeneri rezervkodojn",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si vi regeneras rezervkodojn, vi aŭtomate senvalidigas la antaŭajn.",
+ "{name} backup codes" : "{name} rezervkodoj",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Uzu unu el viaj rezervkodoj, kiujn vi konservis dum agordo de dufaza aŭtentigo.",
+ "Submit" : "Sendi"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/twofactor_backupcodes/l10n/eo.json b/apps/twofactor_backupcodes/l10n/eo.json
new file mode 100644
index 00000000000..44cc0c9660f
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/eo.json
@@ -0,0 +1,20 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Vi kreis dufazajn rezervkodojn por via konto",
+ "Second-factor backup codes" : "Dufazaj rezervkodoj",
+ "Generate backup codes" : "Generi rezervkodojn",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Vi ŝaltis dufazan aŭtentigon, sed vi ankoraŭ ne generis rezervkodojn. Ĉi tiuj lastaj nepras por restaŭri aliron al via konto okaze de perdo de via dua fazo.",
+ "Backup code" : "Rezervkodo",
+ "Use backup code" : "Uzi rezervkodon",
+ "Two factor backup codes" : "Dufazaj rezervkodoj",
+ "A two-factor auth backup codes provider" : "Provizanto de rezervkodoj por dufaza aŭtentigo",
+ "An error occurred while generating your backup codes" : "Eraro okazis dum generado de viaj rezervkodoj",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Rezervkodoj generiĝis. {used} kodoj el {total} uziĝis.",
+ "Save backup codes" : "Konservi la rezervkodojn",
+ "Print backup codes" : "Presi la rezervkodojn",
+ "Regenerate backup codes" : "Regeneri rezervkodojn",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si vi regeneras rezervkodojn, vi aŭtomate senvalidigas la antaŭajn.",
+ "{name} backup codes" : "{name} rezervkodoj",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Uzu unu el viaj rezervkodoj, kiujn vi konservis dum agordo de dufaza aŭtentigo.",
+ "Submit" : "Sendi"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/es.js b/apps/twofactor_backupcodes/l10n/es.js
new file mode 100644
index 00000000000..1f0621f4a8c
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Has creado códigos de respaldo para la autenticación de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo para el segundo factor",
+ "Generate backup codes" : "Generar códigos de respaldo",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Ha habilitado la autenticación de dos factores pero no ha generado aún los códigos de respaldo. Estos son necesarios para acceder a su cuenta en caso de pérdida del segundo factor.",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usar código de respaldo",
+ "Two factor backup codes" : "Códigos de respaldo para la verificación de dos factores",
+ "A two-factor auth backup codes provider" : "Un proveedor de códigos respaldo para autenticación de dos factores",
+ "An error occurred while generating your backup codes" : "Ha ocurrido un error mientras se generaban sus códigos de respaldo.",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Se han generado códigos de respaldo. Se han usado {used} de {total} códigos.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Estos son sus códigos de respaldo. Por favor, guárdelos y/o imprima los mismos, ya que no podrá volver a verlos más tarde.",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regenera los códigos de respaldo, automáticamente invalidará los antiguos.",
+ "{name} backup codes" : "Códigos de respaldo {name}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Use uno de los códigos de respaldo que guardó cuando activó la autenticación de dos factores.",
+ "Submit" : "Enviar"
+},
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/twofactor_backupcodes/l10n/es.json b/apps/twofactor_backupcodes/l10n/es.json
new file mode 100644
index 00000000000..bad78f7b72d
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Has creado códigos de respaldo para la autenticación de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo para el segundo factor",
+ "Generate backup codes" : "Generar códigos de respaldo",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Ha habilitado la autenticación de dos factores pero no ha generado aún los códigos de respaldo. Estos son necesarios para acceder a su cuenta en caso de pérdida del segundo factor.",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usar código de respaldo",
+ "Two factor backup codes" : "Códigos de respaldo para la verificación de dos factores",
+ "A two-factor auth backup codes provider" : "Un proveedor de códigos respaldo para autenticación de dos factores",
+ "An error occurred while generating your backup codes" : "Ha ocurrido un error mientras se generaban sus códigos de respaldo.",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Se han generado códigos de respaldo. Se han usado {used} de {total} códigos.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Estos son sus códigos de respaldo. Por favor, guárdelos y/o imprima los mismos, ya que no podrá volver a verlos más tarde.",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regenera los códigos de respaldo, automáticamente invalidará los antiguos.",
+ "{name} backup codes" : "Códigos de respaldo {name}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Use uno de los códigos de respaldo que guardó cuando activó la autenticación de dos factores.",
+ "Submit" : "Enviar"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/es_419.js b/apps/twofactor_backupcodes/l10n/es_419.js
new file mode 100644
index 00000000000..bda75e326ad
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_419.js
@@ -0,0 +1,16 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/twofactor_backupcodes/l10n/es_419.json b/apps/twofactor_backupcodes/l10n/es_419.json
new file mode 100644
index 00000000000..67d4525548f
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_419.json
@@ -0,0 +1,14 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/es_AR.js b/apps/twofactor_backupcodes/l10n/es_AR.js
new file mode 100644
index 00000000000..dac1122e86b
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_AR.js
@@ -0,0 +1,17 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Usted ha creado códigos de respaldo de dos factores para su cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Use el código de respaldo",
+ "Two factor backup codes" : "Códigos de respaldo de dos factores",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar sus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si usted regenera los códigos de respaldo, automáticamente invalidará los anteriores. ",
+ "Submit" : "Enviar"
+},
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/twofactor_backupcodes/l10n/es_AR.json b/apps/twofactor_backupcodes/l10n/es_AR.json
new file mode 100644
index 00000000000..425dd987e3e
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_AR.json
@@ -0,0 +1,15 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Usted ha creado códigos de respaldo de dos factores para su cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Use el código de respaldo",
+ "Two factor backup codes" : "Códigos de respaldo de dos factores",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar sus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si usted regenera los códigos de respaldo, automáticamente invalidará los anteriores. ",
+ "Submit" : "Enviar"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/es_CL.js b/apps/twofactor_backupcodes/l10n/es_CL.js
new file mode 100644
index 00000000000..bd9cbba24a9
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_CL.js
@@ -0,0 +1,17 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "Two factor backup codes" : "Códigos de respaldo de dos factores",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/twofactor_backupcodes/l10n/es_CL.json b/apps/twofactor_backupcodes/l10n/es_CL.json
new file mode 100644
index 00000000000..3798120620d
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_CL.json
@@ -0,0 +1,15 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "Two factor backup codes" : "Códigos de respaldo de dos factores",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/es_CO.js b/apps/twofactor_backupcodes/l10n/es_CO.js
new file mode 100644
index 00000000000..bd9cbba24a9
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_CO.js
@@ -0,0 +1,17 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "Two factor backup codes" : "Códigos de respaldo de dos factores",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/twofactor_backupcodes/l10n/es_CO.json b/apps/twofactor_backupcodes/l10n/es_CO.json
new file mode 100644
index 00000000000..3798120620d
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_CO.json
@@ -0,0 +1,15 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "Two factor backup codes" : "Códigos de respaldo de dos factores",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/es_CR.js b/apps/twofactor_backupcodes/l10n/es_CR.js
new file mode 100644
index 00000000000..bd9cbba24a9
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_CR.js
@@ -0,0 +1,17 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "Two factor backup codes" : "Códigos de respaldo de dos factores",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/twofactor_backupcodes/l10n/es_CR.json b/apps/twofactor_backupcodes/l10n/es_CR.json
new file mode 100644
index 00000000000..3798120620d
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_CR.json
@@ -0,0 +1,15 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "Two factor backup codes" : "Códigos de respaldo de dos factores",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/es_DO.js b/apps/twofactor_backupcodes/l10n/es_DO.js
new file mode 100644
index 00000000000..bd9cbba24a9
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_DO.js
@@ -0,0 +1,17 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "Two factor backup codes" : "Códigos de respaldo de dos factores",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/twofactor_backupcodes/l10n/es_DO.json b/apps/twofactor_backupcodes/l10n/es_DO.json
new file mode 100644
index 00000000000..3798120620d
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_DO.json
@@ -0,0 +1,15 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "Two factor backup codes" : "Códigos de respaldo de dos factores",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/es_EC.js b/apps/twofactor_backupcodes/l10n/es_EC.js
new file mode 100644
index 00000000000..14f349562cd
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_EC.js
@@ -0,0 +1,22 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Has habilitado la autenticación de dos factores pero aún no has generado códigos de respaldo. Estos son necesarios para restaurar el acceso a tu cuenta en caso de que pierdas tu segundo factor.",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "Two factor backup codes" : "Códigos de respaldo de dos factores",
+ "A two-factor auth backup codes provider" : "Un proveedor de códigos de respaldo para autenticación de dos factores.",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Se han generado códigos de respaldo. Se han utilizado {used} de {total} códigos.",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "{name} backup codes" : "Códigos de respaldo de {name}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Utiliza uno de los códigos de respaldo que guardaste al configurar la autenticación de dos factores.",
+ "Submit" : "Enviar"
+},
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/twofactor_backupcodes/l10n/es_EC.json b/apps/twofactor_backupcodes/l10n/es_EC.json
new file mode 100644
index 00000000000..7747d76faa5
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_EC.json
@@ -0,0 +1,20 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Has habilitado la autenticación de dos factores pero aún no has generado códigos de respaldo. Estos son necesarios para restaurar el acceso a tu cuenta en caso de que pierdas tu segundo factor.",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "Two factor backup codes" : "Códigos de respaldo de dos factores",
+ "A two-factor auth backup codes provider" : "Un proveedor de códigos de respaldo para autenticación de dos factores.",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Se han generado códigos de respaldo. Se han utilizado {used} de {total} códigos.",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "{name} backup codes" : "Códigos de respaldo de {name}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Utiliza uno de los códigos de respaldo que guardaste al configurar la autenticación de dos factores.",
+ "Submit" : "Enviar"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/es_GT.js b/apps/twofactor_backupcodes/l10n/es_GT.js
new file mode 100644
index 00000000000..bd9cbba24a9
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_GT.js
@@ -0,0 +1,17 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "Two factor backup codes" : "Códigos de respaldo de dos factores",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/twofactor_backupcodes/l10n/es_GT.json b/apps/twofactor_backupcodes/l10n/es_GT.json
new file mode 100644
index 00000000000..3798120620d
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_GT.json
@@ -0,0 +1,15 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "Two factor backup codes" : "Códigos de respaldo de dos factores",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/es_HN.js b/apps/twofactor_backupcodes/l10n/es_HN.js
new file mode 100644
index 00000000000..bda75e326ad
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_HN.js
@@ -0,0 +1,16 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/twofactor_backupcodes/l10n/es_HN.json b/apps/twofactor_backupcodes/l10n/es_HN.json
new file mode 100644
index 00000000000..67d4525548f
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_HN.json
@@ -0,0 +1,14 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/es_MX.js b/apps/twofactor_backupcodes/l10n/es_MX.js
new file mode 100644
index 00000000000..b6860f03ea7
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_MX.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Habilitó la autentificación de dos factores pero aún no ha generado los códigos de respaldo. Éstos son necesarios para acceder a su cuenta en caso de que pierda del segundo factor.",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "Two factor backup codes" : "Códigos de respaldo de dos factores",
+ "A two-factor auth backup codes provider" : "Un proveedor de códigos de respaldo para autenticación de dos-factores",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Se generaron los códigos de respaldo. Se han utilizado {used} de {total} códigos.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Estos son sus códigos de respaldo. Por favor guárdelos y/o imprímalos ya que no podrá leerlos después.",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "{name} backup codes" : "Códigos de respaldo {name}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Utilice uno de los códigos de respaldo que guardó al configurar la autentificación de dos factores.",
+ "Submit" : "Enviar"
+},
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/twofactor_backupcodes/l10n/es_MX.json b/apps/twofactor_backupcodes/l10n/es_MX.json
new file mode 100644
index 00000000000..5256ae1025a
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_MX.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Habilitó la autentificación de dos factores pero aún no ha generado los códigos de respaldo. Éstos son necesarios para acceder a su cuenta en caso de que pierda del segundo factor.",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "Two factor backup codes" : "Códigos de respaldo de dos factores",
+ "A two-factor auth backup codes provider" : "Un proveedor de códigos de respaldo para autenticación de dos-factores",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Se generaron los códigos de respaldo. Se han utilizado {used} de {total} códigos.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Estos son sus códigos de respaldo. Por favor guárdelos y/o imprímalos ya que no podrá leerlos después.",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "{name} backup codes" : "Códigos de respaldo {name}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Utilice uno de los códigos de respaldo que guardó al configurar la autentificación de dos factores.",
+ "Submit" : "Enviar"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/es_NI.js b/apps/twofactor_backupcodes/l10n/es_NI.js
new file mode 100644
index 00000000000..bda75e326ad
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_NI.js
@@ -0,0 +1,16 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/twofactor_backupcodes/l10n/es_NI.json b/apps/twofactor_backupcodes/l10n/es_NI.json
new file mode 100644
index 00000000000..67d4525548f
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_NI.json
@@ -0,0 +1,14 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/es_PA.js b/apps/twofactor_backupcodes/l10n/es_PA.js
new file mode 100644
index 00000000000..bda75e326ad
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_PA.js
@@ -0,0 +1,16 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/twofactor_backupcodes/l10n/es_PA.json b/apps/twofactor_backupcodes/l10n/es_PA.json
new file mode 100644
index 00000000000..67d4525548f
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_PA.json
@@ -0,0 +1,14 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/es_PE.js b/apps/twofactor_backupcodes/l10n/es_PE.js
new file mode 100644
index 00000000000..bda75e326ad
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_PE.js
@@ -0,0 +1,16 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/twofactor_backupcodes/l10n/es_PE.json b/apps/twofactor_backupcodes/l10n/es_PE.json
new file mode 100644
index 00000000000..67d4525548f
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_PE.json
@@ -0,0 +1,14 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/es_PR.js b/apps/twofactor_backupcodes/l10n/es_PR.js
new file mode 100644
index 00000000000..bda75e326ad
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_PR.js
@@ -0,0 +1,16 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/twofactor_backupcodes/l10n/es_PR.json b/apps/twofactor_backupcodes/l10n/es_PR.json
new file mode 100644
index 00000000000..67d4525548f
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_PR.json
@@ -0,0 +1,14 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/es_PY.js b/apps/twofactor_backupcodes/l10n/es_PY.js
new file mode 100644
index 00000000000..bda75e326ad
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_PY.js
@@ -0,0 +1,16 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/twofactor_backupcodes/l10n/es_PY.json b/apps/twofactor_backupcodes/l10n/es_PY.json
new file mode 100644
index 00000000000..67d4525548f
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_PY.json
@@ -0,0 +1,14 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/es_SV.js b/apps/twofactor_backupcodes/l10n/es_SV.js
new file mode 100644
index 00000000000..bd9cbba24a9
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_SV.js
@@ -0,0 +1,17 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "Two factor backup codes" : "Códigos de respaldo de dos factores",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/twofactor_backupcodes/l10n/es_SV.json b/apps/twofactor_backupcodes/l10n/es_SV.json
new file mode 100644
index 00000000000..3798120620d
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_SV.json
@@ -0,0 +1,15 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "Two factor backup codes" : "Códigos de respaldo de dos factores",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/es_UY.js b/apps/twofactor_backupcodes/l10n/es_UY.js
new file mode 100644
index 00000000000..bda75e326ad
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_UY.js
@@ -0,0 +1,16 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/twofactor_backupcodes/l10n/es_UY.json b/apps/twofactor_backupcodes/l10n/es_UY.json
new file mode 100644
index 00000000000..67d4525548f
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/es_UY.json
@@ -0,0 +1,14 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Creaste códigos de respaldo de dos factores para tu cuenta",
+ "Second-factor backup codes" : "Códigos de respaldo del segundo factor",
+ "Generate backup codes" : "Generar los códigos de respaldo",
+ "Backup code" : "Código de respaldo",
+ "Use backup code" : "Usa el código de respaldo",
+ "An error occurred while generating your backup codes" : "Se presentó un error al generar tus códigos de respaldo. ",
+ "Save backup codes" : "Guardar códigos de respaldo",
+ "Print backup codes" : "Imprimir códigos de respaldo",
+ "Regenerate backup codes" : "Regenerar códigos de respaldo",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si regeneras los códigos de respaldo, automáticamente invalidarás los anteriores. ",
+ "Submit" : "Enviar"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/et_EE.js b/apps/twofactor_backupcodes/l10n/et_EE.js
new file mode 100644
index 00000000000..8f62eea86ee
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/et_EE.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Sa lõid oma konto jaoks kaheastmelise autentimise varukoodid",
+ "Second-factor backup codes" : "Kaheastmelise autentimise varukoodid",
+ "Generate backup codes" : "Genereeri varukoodid",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Sa lülitasid sisse kaheastmelise autentimise, aga pole veel varukoode genereerinud. Neid on vaja kontole ligipääsemiseks, kui peaksid oma teise autentimisfaktori kaotama.",
+ "Backup code" : "Varukood",
+ "Use backup code" : "Kasuta varukoodi",
+ "Two factor backup codes" : "Kaheastmelise autentimise varukoodid",
+ "A two-factor auth backup codes provider" : "Kaheastmelise autentimise varukoodide pakkuja",
+ "An error occurred while generating your backup codes" : "Varukoodide genereerimisel tekkis tõrge",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Varukoodid genereeritud. {used} koodi {total}-st on kasutatud.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Need on su tagavarakoodid. Palun salvesta ja/või prindi need välja kuna sa ei saa neid koode hiljem uuesti lugeda.",
+ "Save backup codes" : "Salvesta varukoodid",
+ "Print backup codes" : "Trüki varukoodid",
+ "Regenerate backup codes" : "Genereeri varukoodid uuesti",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Kui genereerid varukoodid uuesti, muudad vanad koodid automaatselt kehtetuks.",
+ "{name} backup codes" : "{name} varukoodid",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Kasuta üht kaheastmelise autentimise seadistamisel salvestatud varukoodidest.",
+ "Submit" : "Saada"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/twofactor_backupcodes/l10n/et_EE.json b/apps/twofactor_backupcodes/l10n/et_EE.json
new file mode 100644
index 00000000000..9cc7ebced77
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/et_EE.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Sa lõid oma konto jaoks kaheastmelise autentimise varukoodid",
+ "Second-factor backup codes" : "Kaheastmelise autentimise varukoodid",
+ "Generate backup codes" : "Genereeri varukoodid",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Sa lülitasid sisse kaheastmelise autentimise, aga pole veel varukoode genereerinud. Neid on vaja kontole ligipääsemiseks, kui peaksid oma teise autentimisfaktori kaotama.",
+ "Backup code" : "Varukood",
+ "Use backup code" : "Kasuta varukoodi",
+ "Two factor backup codes" : "Kaheastmelise autentimise varukoodid",
+ "A two-factor auth backup codes provider" : "Kaheastmelise autentimise varukoodide pakkuja",
+ "An error occurred while generating your backup codes" : "Varukoodide genereerimisel tekkis tõrge",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Varukoodid genereeritud. {used} koodi {total}-st on kasutatud.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Need on su tagavarakoodid. Palun salvesta ja/või prindi need välja kuna sa ei saa neid koode hiljem uuesti lugeda.",
+ "Save backup codes" : "Salvesta varukoodid",
+ "Print backup codes" : "Trüki varukoodid",
+ "Regenerate backup codes" : "Genereeri varukoodid uuesti",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Kui genereerid varukoodid uuesti, muudad vanad koodid automaatselt kehtetuks.",
+ "{name} backup codes" : "{name} varukoodid",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Kasuta üht kaheastmelise autentimise seadistamisel salvestatud varukoodidest.",
+ "Submit" : "Saada"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/eu.js b/apps/twofactor_backupcodes/l10n/eu.js
new file mode 100644
index 00000000000..51bbef86537
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/eu.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Zure kontuarentzat bai faktoreko segurtasun kodeak sortu dituzu",
+ "Second-factor backup codes" : "Bigarren faktoreko segurtasun kodeak",
+ "Generate backup codes" : "Segurtasun kodeak sortu",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Bi faktoreko autentifikazioa aktibatu duzu baina ez duzu segurtasun koderik sortu oraindik. Bigarren faktorea galtzen baduzu zure kontura sartu ahal izateko beharrezkoak dira segurtasun kode horiek.",
+ "Backup code" : "Babeskopia-kodea",
+ "Use backup code" : "Erabili ordezko kodea",
+ "Two factor backup codes" : "Bigarren faktoreko segurtasun kodeak",
+ "A two-factor auth backup codes provider" : "Bigarren faktoreko segurtasun kodeen hornitzailea",
+ "An error occurred while generating your backup codes" : "Errorea gertatu da segurtasun kodeak sortzean",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Sortu den segurtasun kode kopurua. {used} erabili dira {total} segurtasun kodetik.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Hauexek dira zure segurtasun kodeak. Gorde edo/eta inprimatu itzazu ez baitira berriz agertuko.",
+ "Save backup codes" : "Gorde babeskopia-kodeak",
+ "Print backup codes" : "Segurtasun kodeak inprimatu",
+ "Regenerate backup codes" : "Segurtasun kodeak berriz sortu",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Segurtasun kodeak berriz sortzen badituzu, zaharrak desaktibatu egingo dira.",
+ "{name} backup codes" : "{name} segurtasun kodeak",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Erabili bi faktoreko autentifikazioa aktibatu zenuenean sortutako segurtasun kodeetako bat",
+ "Submit" : "Bidali"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/twofactor_backupcodes/l10n/eu.json b/apps/twofactor_backupcodes/l10n/eu.json
new file mode 100644
index 00000000000..23655c5bbcc
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/eu.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Zure kontuarentzat bai faktoreko segurtasun kodeak sortu dituzu",
+ "Second-factor backup codes" : "Bigarren faktoreko segurtasun kodeak",
+ "Generate backup codes" : "Segurtasun kodeak sortu",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Bi faktoreko autentifikazioa aktibatu duzu baina ez duzu segurtasun koderik sortu oraindik. Bigarren faktorea galtzen baduzu zure kontura sartu ahal izateko beharrezkoak dira segurtasun kode horiek.",
+ "Backup code" : "Babeskopia-kodea",
+ "Use backup code" : "Erabili ordezko kodea",
+ "Two factor backup codes" : "Bigarren faktoreko segurtasun kodeak",
+ "A two-factor auth backup codes provider" : "Bigarren faktoreko segurtasun kodeen hornitzailea",
+ "An error occurred while generating your backup codes" : "Errorea gertatu da segurtasun kodeak sortzean",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Sortu den segurtasun kode kopurua. {used} erabili dira {total} segurtasun kodetik.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Hauexek dira zure segurtasun kodeak. Gorde edo/eta inprimatu itzazu ez baitira berriz agertuko.",
+ "Save backup codes" : "Gorde babeskopia-kodeak",
+ "Print backup codes" : "Segurtasun kodeak inprimatu",
+ "Regenerate backup codes" : "Segurtasun kodeak berriz sortu",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Segurtasun kodeak berriz sortzen badituzu, zaharrak desaktibatu egingo dira.",
+ "{name} backup codes" : "{name} segurtasun kodeak",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Erabili bi faktoreko autentifikazioa aktibatu zenuenean sortutako segurtasun kodeetako bat",
+ "Submit" : "Bidali"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/fa.js b/apps/twofactor_backupcodes/l10n/fa.js
new file mode 100644
index 00000000000..123700613c3
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/fa.js
@@ -0,0 +1,22 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "شما کدهای پشتیبان دو مرحله ای برای حساب خود ایجاد کردید.",
+ "Second-factor backup codes" : "کدهای پشتیبان فاکتور دوم",
+ "Generate backup codes" : "کدهای پشتیبان تولید کنید",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "شما احراز هویت دو مرحله ای را فعال کرده اید اما هنوز کدهای پشتیبان ایجاد نکرده اید. آنها برای بازگرداندن دسترسی به حساب شما در صورت از دست دادن فاکتور دوم مورد نیاز هستند.",
+ "Backup code" : "کد پشتیبان",
+ "Use backup code" : "از کد پشتیبان استفاده شود",
+ "Two factor backup codes" : "کدهای پشتیبان دو عاملی",
+ "A two-factor auth backup codes provider" : "ارائه دهنده کدهای پشتیبان تأیید اعتبار دو مرحله ای",
+ "An error occurred while generating your backup codes" : "هنگام ایجاد کدهای پشتیبان شما خطایی روی داد",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "کدهای پشتیبان ایجاد شده است. {used} از {total} کد استفاده شده است.",
+ "Save backup codes" : "ذخیره کدهای پشتیبان",
+ "Print backup codes" : "چاپ کدهای پشتیبان",
+ "Regenerate backup codes" : "کدهای پشتیبان را دوباره تولید کنید.",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "اگر کدهای پشتیبان را دوباره تولید کنید، به طور خودکار کدهای قدیمی را باطل می کنید.",
+ "{name} backup codes" : "کدهای پشتیبان {نام}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "از یکی از کدهای پشتیبان که هنگام تنظیم احراز هویت دو مرحله ای ذخیره کرده اید استفاده کنید.",
+ "Submit" : "ارسال"
+},
+"nplurals=2; plural=(n > 1);");
diff --git a/apps/twofactor_backupcodes/l10n/fa.json b/apps/twofactor_backupcodes/l10n/fa.json
new file mode 100644
index 00000000000..c1c2d24f30e
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/fa.json
@@ -0,0 +1,20 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "شما کدهای پشتیبان دو مرحله ای برای حساب خود ایجاد کردید.",
+ "Second-factor backup codes" : "کدهای پشتیبان فاکتور دوم",
+ "Generate backup codes" : "کدهای پشتیبان تولید کنید",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "شما احراز هویت دو مرحله ای را فعال کرده اید اما هنوز کدهای پشتیبان ایجاد نکرده اید. آنها برای بازگرداندن دسترسی به حساب شما در صورت از دست دادن فاکتور دوم مورد نیاز هستند.",
+ "Backup code" : "کد پشتیبان",
+ "Use backup code" : "از کد پشتیبان استفاده شود",
+ "Two factor backup codes" : "کدهای پشتیبان دو عاملی",
+ "A two-factor auth backup codes provider" : "ارائه دهنده کدهای پشتیبان تأیید اعتبار دو مرحله ای",
+ "An error occurred while generating your backup codes" : "هنگام ایجاد کدهای پشتیبان شما خطایی روی داد",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "کدهای پشتیبان ایجاد شده است. {used} از {total} کد استفاده شده است.",
+ "Save backup codes" : "ذخیره کدهای پشتیبان",
+ "Print backup codes" : "چاپ کدهای پشتیبان",
+ "Regenerate backup codes" : "کدهای پشتیبان را دوباره تولید کنید.",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "اگر کدهای پشتیبان را دوباره تولید کنید، به طور خودکار کدهای قدیمی را باطل می کنید.",
+ "{name} backup codes" : "کدهای پشتیبان {نام}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "از یکی از کدهای پشتیبان که هنگام تنظیم احراز هویت دو مرحله ای ذخیره کرده اید استفاده کنید.",
+ "Submit" : "ارسال"
+},"pluralForm" :"nplurals=2; plural=(n > 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/fi.js b/apps/twofactor_backupcodes/l10n/fi.js
new file mode 100644
index 00000000000..6a408e16400
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/fi.js
@@ -0,0 +1,18 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Loit kaksivaiheisen tunnistautumisen varakoodit tilillesi",
+ "Second-factor backup codes" : "Kaksivaiheisen tunnistautumisen varakoodit",
+ "Generate backup codes" : "Luo varakoodit",
+ "Backup code" : "Varakoodi",
+ "Use backup code" : "Käytä varakoodia",
+ "Two factor backup codes" : "Kaksivaiheiden tunnistautumisen varakoodit",
+ "An error occurred while generating your backup codes" : "Tapahtui virhe varakoodeja luotaessa",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Varakoodit on luotu. {used}/{total} koodia on käytetty.",
+ "Save backup codes" : "Tallenna varakoodit",
+ "Print backup codes" : "Tulosta varakoodit",
+ "Regenerate backup codes" : "Luo varakoodit uudelleen",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Jos luot varakoodit uudelleen, vanhat koodit poistetaan automaattisesti käytöstä.",
+ "Submit" : "Lähetä"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/twofactor_backupcodes/l10n/fi.json b/apps/twofactor_backupcodes/l10n/fi.json
new file mode 100644
index 00000000000..ce82c32a30f
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/fi.json
@@ -0,0 +1,16 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Loit kaksivaiheisen tunnistautumisen varakoodit tilillesi",
+ "Second-factor backup codes" : "Kaksivaiheisen tunnistautumisen varakoodit",
+ "Generate backup codes" : "Luo varakoodit",
+ "Backup code" : "Varakoodi",
+ "Use backup code" : "Käytä varakoodia",
+ "Two factor backup codes" : "Kaksivaiheiden tunnistautumisen varakoodit",
+ "An error occurred while generating your backup codes" : "Tapahtui virhe varakoodeja luotaessa",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Varakoodit on luotu. {used}/{total} koodia on käytetty.",
+ "Save backup codes" : "Tallenna varakoodit",
+ "Print backup codes" : "Tulosta varakoodit",
+ "Regenerate backup codes" : "Luo varakoodit uudelleen",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Jos luot varakoodit uudelleen, vanhat koodit poistetaan automaattisesti käytöstä.",
+ "Submit" : "Lähetä"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/fr.js b/apps/twofactor_backupcodes/l10n/fr.js
new file mode 100644
index 00000000000..c49e09edc8f
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/fr.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Vous avez créé des codes de secours à deux facteurs pour votre compte",
+ "Second-factor backup codes" : "Codes de récupération pour l’authentification en deux étapes",
+ "Generate backup codes" : "Générer des codes de récupération",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Vous avez activé l'authentification en deux étapes mais vous n'avez pas généré de codes de secours. Ils sont nécessaires pour récupérer l'accès à votre compte en cas de perte de votre autre moyen de connexion.",
+ "Backup code" : "Code de récupération",
+ "Use backup code" : "Utiliser un code de récupération",
+ "Two factor backup codes" : "Code de secours pour l'authentification double facteur.",
+ "A two-factor auth backup codes provider" : "Un fournisseur de codes de récupération d'authentification à deux facteurs",
+ "An error occurred while generating your backup codes" : "Une erreur est survenue lors de la génération de vos codes de récupération",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Les codes de récupération ont été générés. {used} codes sur {total} ont été utilisés.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Ce sont vos codes de secours. Veuillez les enregistrer et/ou les imprimer car vous ne pourrez plus les redemander ultérieurement.",
+ "Save backup codes" : "Sauvegarder les codes de récupération",
+ "Print backup codes" : "Imprimer les codes de récupération",
+ "Regenerate backup codes" : "Régénérer les codes de récupération",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si vous régénérez les codes de récupération, vous invalidez automatiquement les anciens codes.",
+ "{name} backup codes" : "{name} codes de récupération",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Utilisez l'un des codes de récupération que vous avez enregistrés lors de la configuration de l'authentification à deux facteurs.",
+ "Submit" : "Soumettre"
+},
+"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/twofactor_backupcodes/l10n/fr.json b/apps/twofactor_backupcodes/l10n/fr.json
new file mode 100644
index 00000000000..04f04ae2c6e
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/fr.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Vous avez créé des codes de secours à deux facteurs pour votre compte",
+ "Second-factor backup codes" : "Codes de récupération pour l’authentification en deux étapes",
+ "Generate backup codes" : "Générer des codes de récupération",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Vous avez activé l'authentification en deux étapes mais vous n'avez pas généré de codes de secours. Ils sont nécessaires pour récupérer l'accès à votre compte en cas de perte de votre autre moyen de connexion.",
+ "Backup code" : "Code de récupération",
+ "Use backup code" : "Utiliser un code de récupération",
+ "Two factor backup codes" : "Code de secours pour l'authentification double facteur.",
+ "A two-factor auth backup codes provider" : "Un fournisseur de codes de récupération d'authentification à deux facteurs",
+ "An error occurred while generating your backup codes" : "Une erreur est survenue lors de la génération de vos codes de récupération",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Les codes de récupération ont été générés. {used} codes sur {total} ont été utilisés.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Ce sont vos codes de secours. Veuillez les enregistrer et/ou les imprimer car vous ne pourrez plus les redemander ultérieurement.",
+ "Save backup codes" : "Sauvegarder les codes de récupération",
+ "Print backup codes" : "Imprimer les codes de récupération",
+ "Regenerate backup codes" : "Régénérer les codes de récupération",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si vous régénérez les codes de récupération, vous invalidez automatiquement les anciens codes.",
+ "{name} backup codes" : "{name} codes de récupération",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Utilisez l'un des codes de récupération que vous avez enregistrés lors de la configuration de l'authentification à deux facteurs.",
+ "Submit" : "Soumettre"
+},"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/ga.js b/apps/twofactor_backupcodes/l10n/ga.js
new file mode 100644
index 00000000000..92afbed005f
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/ga.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Chruthaigh tú cóid chúltaca dhá-fhachtóir do do chuntas",
+ "Second-factor backup codes" : "Cóid chúltaca dara fachtóir",
+ "Generate backup codes" : "Gin cóid chúltaca",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Chuir tú ar chumas fíordheimhnithe dhá-fhachtóir ach níor ghin tú cóid chúltaca fós. Tá siad ag teastáil chun rochtain ar do chuntas a aischur ar eagla go gcaillfidh tú do dhara fachtóir.",
+ "Backup code" : "Cód cúltaca",
+ "Use backup code" : "Úsáid cód cúltaca",
+ "Two factor backup codes" : "Cóid chúltaca dhá fhachtóir",
+ "A two-factor auth backup codes provider" : "Soláthraí cóid chúltaca údaráis dhá-fhachtóir",
+ "An error occurred while generating your backup codes" : "Tharla earráid agus do chóid chúltaca á nginiúint",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Gineadh cóid chúltaca. Baineadh úsáid as {used} as {total} cóid.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Seo iad do chóid chúltaca. Sábháil agus/nó priontáil iad mar ní bheidh tú in ann na cóid a léamh arís ar ball le do thoil.",
+ "Save backup codes" : "Sábháil cóid chúltaca",
+ "Print backup codes" : "Priontáil cóid chúltaca",
+ "Regenerate backup codes" : "Athghin cóid chúltaca",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Má athghineann tú cóid chúltaca, déanann tú sean-chóid neamhbhailí go huathoibríoch.",
+ "{name} backup codes" : "cóid chúltaca {name}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Bain úsáid as ceann de na cóid chúltaca a shábháil tú agus fíordheimhniú dhá-fhachtóir á socrú agat.",
+ "Submit" : "Cuir isteach"
+},
+"nplurals=5; plural=(n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4);");
diff --git a/apps/twofactor_backupcodes/l10n/ga.json b/apps/twofactor_backupcodes/l10n/ga.json
new file mode 100644
index 00000000000..b610ac4d1b7
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/ga.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Chruthaigh tú cóid chúltaca dhá-fhachtóir do do chuntas",
+ "Second-factor backup codes" : "Cóid chúltaca dara fachtóir",
+ "Generate backup codes" : "Gin cóid chúltaca",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Chuir tú ar chumas fíordheimhnithe dhá-fhachtóir ach níor ghin tú cóid chúltaca fós. Tá siad ag teastáil chun rochtain ar do chuntas a aischur ar eagla go gcaillfidh tú do dhara fachtóir.",
+ "Backup code" : "Cód cúltaca",
+ "Use backup code" : "Úsáid cód cúltaca",
+ "Two factor backup codes" : "Cóid chúltaca dhá fhachtóir",
+ "A two-factor auth backup codes provider" : "Soláthraí cóid chúltaca údaráis dhá-fhachtóir",
+ "An error occurred while generating your backup codes" : "Tharla earráid agus do chóid chúltaca á nginiúint",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Gineadh cóid chúltaca. Baineadh úsáid as {used} as {total} cóid.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Seo iad do chóid chúltaca. Sábháil agus/nó priontáil iad mar ní bheidh tú in ann na cóid a léamh arís ar ball le do thoil.",
+ "Save backup codes" : "Sábháil cóid chúltaca",
+ "Print backup codes" : "Priontáil cóid chúltaca",
+ "Regenerate backup codes" : "Athghin cóid chúltaca",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Má athghineann tú cóid chúltaca, déanann tú sean-chóid neamhbhailí go huathoibríoch.",
+ "{name} backup codes" : "cóid chúltaca {name}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Bain úsáid as ceann de na cóid chúltaca a shábháil tú agus fíordheimhniú dhá-fhachtóir á socrú agat.",
+ "Submit" : "Cuir isteach"
+},"pluralForm" :"nplurals=5; plural=(n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/gl.js b/apps/twofactor_backupcodes/l10n/gl.js
new file mode 100644
index 00000000000..76a82fe9ebc
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/gl.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Creou códigos de recuperación de dous factores para a súa conta",
+ "Second-factor backup codes" : "Códigos de recuperación do segundo factor",
+ "Generate backup codes" : "Xerar códigos de recuperación",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Activou a autenticación de dous factores mais aínda non xerou os códigos de recuperación. Necesítanse para restaurar o acceso á súa conta no caso de perder o segundo factor.",
+ "Backup code" : "Código de recuperación",
+ "Use backup code" : "Usar código de recuperación",
+ "Two factor backup codes" : "Códigos de recuperación de dous factores",
+ "A two-factor auth backup codes provider" : "Un provedor de códigos de recuperación para a autenticación de dous factores",
+ "An error occurred while generating your backup codes" : "Produciuse un erro ao xerar os seus códigos de recuperación",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Xeraronse os códigos de recuperación. Usou {used} códigos de {total}.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Estes son os seus códigos de recuperación. Gárdeos e/ou imprímaos xa que non poderá volver lelos de novo.",
+ "Save backup codes" : "Gardar os códigos de recuperación",
+ "Print backup codes" : "Imprimir os códigos de recuperación",
+ "Regenerate backup codes" : "Volver xerar códigos de recuperación",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Se volve xerar os códigos de recuperación, automaticamente invalidara os antigos códigos.",
+ "{name} backup codes" : "Códigos de recuperación {name} ",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Use un dos códigos de recuperación que gardou cando axustou a autenticación de dous factores.",
+ "Submit" : "Enviar "
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/twofactor_backupcodes/l10n/gl.json b/apps/twofactor_backupcodes/l10n/gl.json
new file mode 100644
index 00000000000..47cc4a174f4
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/gl.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Creou códigos de recuperación de dous factores para a súa conta",
+ "Second-factor backup codes" : "Códigos de recuperación do segundo factor",
+ "Generate backup codes" : "Xerar códigos de recuperación",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Activou a autenticación de dous factores mais aínda non xerou os códigos de recuperación. Necesítanse para restaurar o acceso á súa conta no caso de perder o segundo factor.",
+ "Backup code" : "Código de recuperación",
+ "Use backup code" : "Usar código de recuperación",
+ "Two factor backup codes" : "Códigos de recuperación de dous factores",
+ "A two-factor auth backup codes provider" : "Un provedor de códigos de recuperación para a autenticación de dous factores",
+ "An error occurred while generating your backup codes" : "Produciuse un erro ao xerar os seus códigos de recuperación",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Xeraronse os códigos de recuperación. Usou {used} códigos de {total}.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Estes son os seus códigos de recuperación. Gárdeos e/ou imprímaos xa que non poderá volver lelos de novo.",
+ "Save backup codes" : "Gardar os códigos de recuperación",
+ "Print backup codes" : "Imprimir os códigos de recuperación",
+ "Regenerate backup codes" : "Volver xerar códigos de recuperación",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Se volve xerar os códigos de recuperación, automaticamente invalidara os antigos códigos.",
+ "{name} backup codes" : "Códigos de recuperación {name} ",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Use un dos códigos de recuperación que gardou cando axustou a autenticación de dous factores.",
+ "Submit" : "Enviar "
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/he.js b/apps/twofactor_backupcodes/l10n/he.js
new file mode 100644
index 00000000000..e3d24e14788
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/he.js
@@ -0,0 +1,19 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "יצרת קודים לגיבוי לטובת אימות דו־שלבי עבור החשבון שלך",
+ "Second-factor backup codes" : "קודים לגיבוי עבור אימות דו־שלבי",
+ "Generate backup codes" : "יצירת קודים לגיבוי",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "הפעלת אימות דו־שלבי אך לא ייצאת קודים לגיבוי עדיין. הם נחוצים כדי לשחזר גישה לחשבון שלך במקרה שהגורם השני שלך אבד.",
+ "Backup code" : "קוד גיבוי",
+ "Use backup code" : "שימוש בקוד גיבוי",
+ "Two factor backup codes" : "קודים לגיבוי אימות דו־שלבי",
+ "An error occurred while generating your backup codes" : "אירעה שגיאה ביצירת הקודים שלך לגיבוי",
+ "Save backup codes" : "שמירת קודים לגיבוי",
+ "Print backup codes" : "הדפסת קודים לגיבוי",
+ "Regenerate backup codes" : "יצירת קודים לגיבוי",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "ייצור של קודים חדשים לגיבוי יבטל את תוקף הקודים הישנים.",
+ "{name} backup codes" : "{name} קודים לגיבוי",
+ "Submit" : "שליחה"
+},
+"nplurals=3; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: 2;");
diff --git a/apps/twofactor_backupcodes/l10n/he.json b/apps/twofactor_backupcodes/l10n/he.json
new file mode 100644
index 00000000000..a0528976ea0
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/he.json
@@ -0,0 +1,17 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "יצרת קודים לגיבוי לטובת אימות דו־שלבי עבור החשבון שלך",
+ "Second-factor backup codes" : "קודים לגיבוי עבור אימות דו־שלבי",
+ "Generate backup codes" : "יצירת קודים לגיבוי",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "הפעלת אימות דו־שלבי אך לא ייצאת קודים לגיבוי עדיין. הם נחוצים כדי לשחזר גישה לחשבון שלך במקרה שהגורם השני שלך אבד.",
+ "Backup code" : "קוד גיבוי",
+ "Use backup code" : "שימוש בקוד גיבוי",
+ "Two factor backup codes" : "קודים לגיבוי אימות דו־שלבי",
+ "An error occurred while generating your backup codes" : "אירעה שגיאה ביצירת הקודים שלך לגיבוי",
+ "Save backup codes" : "שמירת קודים לגיבוי",
+ "Print backup codes" : "הדפסת קודים לגיבוי",
+ "Regenerate backup codes" : "יצירת קודים לגיבוי",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "ייצור של קודים חדשים לגיבוי יבטל את תוקף הקודים הישנים.",
+ "{name} backup codes" : "{name} קודים לגיבוי",
+ "Submit" : "שליחה"
+},"pluralForm" :"nplurals=3; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: 2;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/hr.js b/apps/twofactor_backupcodes/l10n/hr.js
new file mode 100644
index 00000000000..8fecb092274
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/hr.js
@@ -0,0 +1,22 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Stvorili ste dvofaktorske pričuvne šifre za svoj račun",
+ "Second-factor backup codes" : "Pričuvne šifre drugog faktora",
+ "Generate backup codes" : "Generiraj pričuvne šifre",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Omogućili ste dvofaktorsku autentifikaciju, ali još niste generirali pričuvne šifre. One su potrebne kako bi vratili pristup svom računu u slučaju da izgubite svoj drugi faktor.",
+ "Backup code" : "Pričuvna šifra",
+ "Use backup code" : "Upotrijebi pričuvnu šifru",
+ "Two factor backup codes" : "Dvofaktorske pričuvne šifre",
+ "A two-factor auth backup codes provider" : "Davatelj pričuvnih šifri za dvofaktorsku autentifikaciju",
+ "An error occurred while generating your backup codes" : "Došlo je do pogreške pri generiranju pričuvnih šifri",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Pričuvne šifre su generirane. Iskorišteno je {used} od {total} šifri.",
+ "Save backup codes" : "Spremi pričuvne šifre",
+ "Print backup codes" : "Ispis pričuvnih šifri",
+ "Regenerate backup codes" : "Ponovno generiranje pričuvnih šifri",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Ako ponovno generirate pričuvne šifre, automatski poništavate stare šifre.",
+ "{name} backup codes" : "{name} pričuvnih šifri",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Upotrijebite jednu od pričuvnih šifri koje ste spremili prilikom postavljanja dvofaktorske autentifikacije.",
+ "Submit" : "Šalji"
+},
+"nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;");
diff --git a/apps/twofactor_backupcodes/l10n/hr.json b/apps/twofactor_backupcodes/l10n/hr.json
new file mode 100644
index 00000000000..049d4a601fa
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/hr.json
@@ -0,0 +1,20 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Stvorili ste dvofaktorske pričuvne šifre za svoj račun",
+ "Second-factor backup codes" : "Pričuvne šifre drugog faktora",
+ "Generate backup codes" : "Generiraj pričuvne šifre",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Omogućili ste dvofaktorsku autentifikaciju, ali još niste generirali pričuvne šifre. One su potrebne kako bi vratili pristup svom računu u slučaju da izgubite svoj drugi faktor.",
+ "Backup code" : "Pričuvna šifra",
+ "Use backup code" : "Upotrijebi pričuvnu šifru",
+ "Two factor backup codes" : "Dvofaktorske pričuvne šifre",
+ "A two-factor auth backup codes provider" : "Davatelj pričuvnih šifri za dvofaktorsku autentifikaciju",
+ "An error occurred while generating your backup codes" : "Došlo je do pogreške pri generiranju pričuvnih šifri",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Pričuvne šifre su generirane. Iskorišteno je {used} od {total} šifri.",
+ "Save backup codes" : "Spremi pričuvne šifre",
+ "Print backup codes" : "Ispis pričuvnih šifri",
+ "Regenerate backup codes" : "Ponovno generiranje pričuvnih šifri",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Ako ponovno generirate pričuvne šifre, automatski poništavate stare šifre.",
+ "{name} backup codes" : "{name} pričuvnih šifri",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Upotrijebite jednu od pričuvnih šifri koje ste spremili prilikom postavljanja dvofaktorske autentifikacije.",
+ "Submit" : "Šalji"
+},"pluralForm" :"nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/hu.js b/apps/twofactor_backupcodes/l10n/hu.js
new file mode 100644
index 00000000000..1ddbcdb4277
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/hu.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Kétfaktoros helyreállítási kódot hozott létre a fiókjához",
+ "Second-factor backup codes" : "Második lépcsős biztonsági kódok",
+ "Generate backup codes" : "Biztonsági kódok előállítása",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Engedélyezte a kétlépcsős hitelesítést, de még nem hozott létre biztonsági kódokat. Ezek ahhoz szükségesek, hogy akkor is hozzáférjen a fiókjához, ha elveszíti a második faktort.",
+ "Backup code" : "Biztonsági kód",
+ "Use backup code" : "Biztonsági kód használata",
+ "Two factor backup codes" : "Kétlépcsős biztonsági mentési kódok",
+ "A two-factor auth backup codes provider" : "Kétlépcsős hitelesítés biztonsági kódjainak szolgáltatója",
+ "An error occurred while generating your backup codes" : "Hiba történt a biztonsági kódok előállítása során",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Létrejöttek a biztonsági kódok. {total} kódból {used} lett felhasználva.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Ezek a biztonsági kódjai. Mentse el vagy nyomtassa ki őket úgy, hogy később is meglegyenek.",
+ "Save backup codes" : "Biztonsági kódok mentése",
+ "Print backup codes" : "Biztonsági kódok nyomtatása",
+ "Regenerate backup codes" : "Biztonsági kódok újbóli előállítása",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Ha újra előállítja a biztonsági kódokat, akkor a régiek automatikusan érvénytelenítve lesznek.",
+ "{name} backup codes" : "{name} biztonsági kódjai",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Használjon egy biztonsági kódot, amikor beállítja a kétlépcsős hitelesítést.",
+ "Submit" : "Küldés"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/twofactor_backupcodes/l10n/hu.json b/apps/twofactor_backupcodes/l10n/hu.json
new file mode 100644
index 00000000000..514b09a7896
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/hu.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Kétfaktoros helyreállítási kódot hozott létre a fiókjához",
+ "Second-factor backup codes" : "Második lépcsős biztonsági kódok",
+ "Generate backup codes" : "Biztonsági kódok előállítása",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Engedélyezte a kétlépcsős hitelesítést, de még nem hozott létre biztonsági kódokat. Ezek ahhoz szükségesek, hogy akkor is hozzáférjen a fiókjához, ha elveszíti a második faktort.",
+ "Backup code" : "Biztonsági kód",
+ "Use backup code" : "Biztonsági kód használata",
+ "Two factor backup codes" : "Kétlépcsős biztonsági mentési kódok",
+ "A two-factor auth backup codes provider" : "Kétlépcsős hitelesítés biztonsági kódjainak szolgáltatója",
+ "An error occurred while generating your backup codes" : "Hiba történt a biztonsági kódok előállítása során",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Létrejöttek a biztonsági kódok. {total} kódból {used} lett felhasználva.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Ezek a biztonsági kódjai. Mentse el vagy nyomtassa ki őket úgy, hogy később is meglegyenek.",
+ "Save backup codes" : "Biztonsági kódok mentése",
+ "Print backup codes" : "Biztonsági kódok nyomtatása",
+ "Regenerate backup codes" : "Biztonsági kódok újbóli előállítása",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Ha újra előállítja a biztonsági kódokat, akkor a régiek automatikusan érvénytelenítve lesznek.",
+ "{name} backup codes" : "{name} biztonsági kódjai",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Használjon egy biztonsági kódot, amikor beállítja a kétlépcsős hitelesítést.",
+ "Submit" : "Küldés"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/is.js b/apps/twofactor_backupcodes/l10n/is.js
new file mode 100644
index 00000000000..c43e3779337
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/is.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Þú útbjóst tveggja-þrepa öryggisafritunarkóða fyrir aðganginn þinn",
+ "Second-factor backup codes" : "Tveggja-þrepa öryggisafritunarkóðar",
+ "Generate backup codes" : "Útbúa öryggisafritunarkóða",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Þú virkjaðir tveggja-þrepa auðkenningu en hefur ekki ennþá útbúið öryggisafritunarkóða. Þeir eru nauðsynlegir til að geta endurheimt aðganginn þinn fari svo að þú tapir seinni þætti auðkenningarinnar.",
+ "Backup code" : "Öryggisafritunarkóði",
+ "Use backup code" : "Nota öryggisafritunarkóða",
+ "Two factor backup codes" : "Tveggja-þrepa öryggisafritunarkóðar",
+ "A two-factor auth backup codes provider" : "Útgefandi tveggja-þrepa öryggisafritunarkóða",
+ "An error occurred while generating your backup codes" : "Villa kom upp við að búa til öryggisafritunarkóðana þína",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Öryggisafritunarkóðar hafa verið útbúnir. {used} af {total} kóðum hafa verið notaðir.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Þetta eru öryggisafritunarkóðarnir þínir. Vistaðu þá og/eða prentaðu þá út, því þú munt ekki geta lesið þá aftur síðar í ferlinu.",
+ "Save backup codes" : "Vista öryggisafritunarkóða",
+ "Print backup codes" : "Prenta öryggisafritunarkóða",
+ "Regenerate backup codes" : "Endurnýja öryggisafritunarkóða",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Ef þú endurnýjar öryggisafritunarkóða, gerir þú sjálfkrafa eldri kóða ógilda.",
+ "{name} backup codes" : "{name} öryggisafritunarkóðar",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Notaðu einn af öryggisafritunarkóðunum sem þú vistaðir þegar þú settir upp tveggja-þátta auðkenningu.",
+ "Submit" : "Senda inn"
+},
+"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);");
diff --git a/apps/twofactor_backupcodes/l10n/is.json b/apps/twofactor_backupcodes/l10n/is.json
new file mode 100644
index 00000000000..2141b6e51bc
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/is.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Þú útbjóst tveggja-þrepa öryggisafritunarkóða fyrir aðganginn þinn",
+ "Second-factor backup codes" : "Tveggja-þrepa öryggisafritunarkóðar",
+ "Generate backup codes" : "Útbúa öryggisafritunarkóða",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Þú virkjaðir tveggja-þrepa auðkenningu en hefur ekki ennþá útbúið öryggisafritunarkóða. Þeir eru nauðsynlegir til að geta endurheimt aðganginn þinn fari svo að þú tapir seinni þætti auðkenningarinnar.",
+ "Backup code" : "Öryggisafritunarkóði",
+ "Use backup code" : "Nota öryggisafritunarkóða",
+ "Two factor backup codes" : "Tveggja-þrepa öryggisafritunarkóðar",
+ "A two-factor auth backup codes provider" : "Útgefandi tveggja-þrepa öryggisafritunarkóða",
+ "An error occurred while generating your backup codes" : "Villa kom upp við að búa til öryggisafritunarkóðana þína",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Öryggisafritunarkóðar hafa verið útbúnir. {used} af {total} kóðum hafa verið notaðir.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Þetta eru öryggisafritunarkóðarnir þínir. Vistaðu þá og/eða prentaðu þá út, því þú munt ekki geta lesið þá aftur síðar í ferlinu.",
+ "Save backup codes" : "Vista öryggisafritunarkóða",
+ "Print backup codes" : "Prenta öryggisafritunarkóða",
+ "Regenerate backup codes" : "Endurnýja öryggisafritunarkóða",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Ef þú endurnýjar öryggisafritunarkóða, gerir þú sjálfkrafa eldri kóða ógilda.",
+ "{name} backup codes" : "{name} öryggisafritunarkóðar",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Notaðu einn af öryggisafritunarkóðunum sem þú vistaðir þegar þú settir upp tveggja-þátta auðkenningu.",
+ "Submit" : "Senda inn"
+},"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/it.js b/apps/twofactor_backupcodes/l10n/it.js
new file mode 100644
index 00000000000..4ccc170b59c
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/it.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Hai creato codici di backup a due fattori per il tuo account",
+ "Second-factor backup codes" : "Codici di backup con secondo fattore",
+ "Generate backup codes" : "Genera i codici di backup",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Hai abilitato l'autenticazione a due fattori, ma non hai ancora generato i codici di backup. Sono necessari per recuperare l'accesso al tuo account nel caso in cui tu perda l'accesso al secondo fattore.",
+ "Backup code" : "Codice di backup",
+ "Use backup code" : "Usa il codice di backup",
+ "Two factor backup codes" : "Codici di backup a due fattori",
+ "A two-factor auth backup codes provider" : "Un fornitore di codici di backup per l'autenticazione a due fattori",
+ "An error occurred while generating your backup codes" : "Si è verificato un errore durante la generazione dei tuoi codici di backup",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "I codici di backup sono stati generali. {used} di {total} codici sono stati utilizzati.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Questi sono i tuoi codici di backup. Salvali e/o stampali poiché non potrai più leggerli successivamente.",
+ "Save backup codes" : "Salva i codici di backup",
+ "Print backup codes" : "Stampa i codici di backup",
+ "Regenerate backup codes" : "Rigenera i codici di backup",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Se rigeneri i codici di backup, invaliderai automaticamente i vecchi codici.",
+ "{name} backup codes" : "Codici di backup di {name}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Usa uno dei codici di backup che hai salvato quando configuri l'autenticazione a due fattori.",
+ "Submit" : "Invia"
+},
+"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/twofactor_backupcodes/l10n/it.json b/apps/twofactor_backupcodes/l10n/it.json
new file mode 100644
index 00000000000..cc13db71619
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/it.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Hai creato codici di backup a due fattori per il tuo account",
+ "Second-factor backup codes" : "Codici di backup con secondo fattore",
+ "Generate backup codes" : "Genera i codici di backup",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Hai abilitato l'autenticazione a due fattori, ma non hai ancora generato i codici di backup. Sono necessari per recuperare l'accesso al tuo account nel caso in cui tu perda l'accesso al secondo fattore.",
+ "Backup code" : "Codice di backup",
+ "Use backup code" : "Usa il codice di backup",
+ "Two factor backup codes" : "Codici di backup a due fattori",
+ "A two-factor auth backup codes provider" : "Un fornitore di codici di backup per l'autenticazione a due fattori",
+ "An error occurred while generating your backup codes" : "Si è verificato un errore durante la generazione dei tuoi codici di backup",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "I codici di backup sono stati generali. {used} di {total} codici sono stati utilizzati.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Questi sono i tuoi codici di backup. Salvali e/o stampali poiché non potrai più leggerli successivamente.",
+ "Save backup codes" : "Salva i codici di backup",
+ "Print backup codes" : "Stampa i codici di backup",
+ "Regenerate backup codes" : "Rigenera i codici di backup",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Se rigeneri i codici di backup, invaliderai automaticamente i vecchi codici.",
+ "{name} backup codes" : "Codici di backup di {name}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Usa uno dei codici di backup che hai salvato quando configuri l'autenticazione a due fattori.",
+ "Submit" : "Invia"
+},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/ja.js b/apps/twofactor_backupcodes/l10n/ja.js
new file mode 100644
index 00000000000..52fd8935dba
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/ja.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "アカウントの二要素認証バックアップコードを作成しました",
+ "Second-factor backup codes" : "第二要素バックアップコード",
+ "Generate backup codes" : "バックアップコードを生成",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "二要素認証を有効にしましたが、まだバックアップコードを生成していません。 2番めの要素を失った際、アカウントへのアクセスを回復するために必要とされます。",
+ "Backup code" : "バックアップコード",
+ "Use backup code" : "バックアップコードを使用する",
+ "Two factor backup codes" : "二要素認証バックアップコード",
+ "A two-factor auth backup codes provider" : "二要素認証バックアップコードプロバイダー",
+ "An error occurred while generating your backup codes" : "バックアップコードの生成中にエラーが発生しました",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "バックアップコードが生成されました。 {total} 個のうち {used} 個のコードが使用されています。",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "これらはバックアップコードです。後でコードを再度読み取ることはできませんので、保存または印刷してください。",
+ "Save backup codes" : "バックアップコードを保存",
+ "Print backup codes" : "バックアップコードを印刷",
+ "Regenerate backup codes" : "バックアップコードを再生成",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "バックアップコードを再生成すると、自動的に古いコードが無効になります。",
+ "{name} backup codes" : "{name} バックアップコード",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "二要素認証を設定するときに保存したバックアップコードのいずれかを使用します。",
+ "Submit" : "了解"
+},
+"nplurals=1; plural=0;");
diff --git a/apps/twofactor_backupcodes/l10n/ja.json b/apps/twofactor_backupcodes/l10n/ja.json
new file mode 100644
index 00000000000..a813c3102ca
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/ja.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "アカウントの二要素認証バックアップコードを作成しました",
+ "Second-factor backup codes" : "第二要素バックアップコード",
+ "Generate backup codes" : "バックアップコードを生成",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "二要素認証を有効にしましたが、まだバックアップコードを生成していません。 2番めの要素を失った際、アカウントへのアクセスを回復するために必要とされます。",
+ "Backup code" : "バックアップコード",
+ "Use backup code" : "バックアップコードを使用する",
+ "Two factor backup codes" : "二要素認証バックアップコード",
+ "A two-factor auth backup codes provider" : "二要素認証バックアップコードプロバイダー",
+ "An error occurred while generating your backup codes" : "バックアップコードの生成中にエラーが発生しました",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "バックアップコードが生成されました。 {total} 個のうち {used} 個のコードが使用されています。",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "これらはバックアップコードです。後でコードを再度読み取ることはできませんので、保存または印刷してください。",
+ "Save backup codes" : "バックアップコードを保存",
+ "Print backup codes" : "バックアップコードを印刷",
+ "Regenerate backup codes" : "バックアップコードを再生成",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "バックアップコードを再生成すると、自動的に古いコードが無効になります。",
+ "{name} backup codes" : "{name} バックアップコード",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "二要素認証を設定するときに保存したバックアップコードのいずれかを使用します。",
+ "Submit" : "了解"
+},"pluralForm" :"nplurals=1; plural=0;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/ka.js b/apps/twofactor_backupcodes/l10n/ka.js
new file mode 100644
index 00000000000..fb9029941b0
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/ka.js
@@ -0,0 +1,22 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "You created two-factor backup codes for your account",
+ "Second-factor backup codes" : "Second-factor backup codes",
+ "Generate backup codes" : "Generate backup codes",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor.",
+ "Backup code" : "Backup code",
+ "Use backup code" : "Use backup code",
+ "Two factor backup codes" : "Two factor backup codes",
+ "A two-factor auth backup codes provider" : "A two-factor auth backup codes provider",
+ "An error occurred while generating your backup codes" : "An error occurred while generating your backup codes",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Backup codes have been generated. {used} of {total} codes have been used.",
+ "Save backup codes" : "Save backup codes",
+ "Print backup codes" : "Print backup codes",
+ "Regenerate backup codes" : "Regenerate backup codes",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "If you regenerate backup codes, you automatically invalidate old codes.",
+ "{name} backup codes" : "{name} backup codes",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Use one of the backup codes you saved when setting up two-factor authentication.",
+ "Submit" : "Submit"
+},
+"nplurals=2; plural=(n!=1);");
diff --git a/apps/twofactor_backupcodes/l10n/ka.json b/apps/twofactor_backupcodes/l10n/ka.json
new file mode 100644
index 00000000000..f663ce8ddff
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/ka.json
@@ -0,0 +1,20 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "You created two-factor backup codes for your account",
+ "Second-factor backup codes" : "Second-factor backup codes",
+ "Generate backup codes" : "Generate backup codes",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor.",
+ "Backup code" : "Backup code",
+ "Use backup code" : "Use backup code",
+ "Two factor backup codes" : "Two factor backup codes",
+ "A two-factor auth backup codes provider" : "A two-factor auth backup codes provider",
+ "An error occurred while generating your backup codes" : "An error occurred while generating your backup codes",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Backup codes have been generated. {used} of {total} codes have been used.",
+ "Save backup codes" : "Save backup codes",
+ "Print backup codes" : "Print backup codes",
+ "Regenerate backup codes" : "Regenerate backup codes",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "If you regenerate backup codes, you automatically invalidate old codes.",
+ "{name} backup codes" : "{name} backup codes",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Use one of the backup codes you saved when setting up two-factor authentication.",
+ "Submit" : "Submit"
+},"pluralForm" :"nplurals=2; plural=(n!=1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/ka_GE.js b/apps/twofactor_backupcodes/l10n/ka_GE.js
new file mode 100644
index 00000000000..2155dcba759
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/ka_GE.js
@@ -0,0 +1,17 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "შექმენით ორ-ფაქტორიანი ბექაფის კოდები თქვენი ანგარიშისთვის",
+ "Second-factor backup codes" : "მეორე-ფაქტორის ბექაფის კოდები",
+ "Generate backup codes" : "გენერირდება ბექაფის კოდები",
+ "Backup code" : "ბექაფის კოდები",
+ "Use backup code" : "ბექაფის კოდების გამოყენება",
+ "Two factor backup codes" : "მეორე-ფაქტორის ბექაფის კოდები",
+ "An error occurred while generating your backup codes" : "ბექაფის კოდების გენერაციისას წარმოიშვა შეცდომა",
+ "Save backup codes" : "ბექაფის კოდების შენახვა",
+ "Print backup codes" : "ბექაფის კოდების ამობეჭდვა",
+ "Regenerate backup codes" : "ბექაფის კოდების გენერაცია",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "ძველი კოდები, ახალი ბექაფის კოდების რეგენერაციისას დაკარგავენ მოქმდების ძალას.",
+ "Submit" : "გაგზავნა"
+},
+"nplurals=2; plural=(n!=1);");
diff --git a/apps/twofactor_backupcodes/l10n/ka_GE.json b/apps/twofactor_backupcodes/l10n/ka_GE.json
new file mode 100644
index 00000000000..bf5bc6ebff3
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/ka_GE.json
@@ -0,0 +1,15 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "შექმენით ორ-ფაქტორიანი ბექაფის კოდები თქვენი ანგარიშისთვის",
+ "Second-factor backup codes" : "მეორე-ფაქტორის ბექაფის კოდები",
+ "Generate backup codes" : "გენერირდება ბექაფის კოდები",
+ "Backup code" : "ბექაფის კოდები",
+ "Use backup code" : "ბექაფის კოდების გამოყენება",
+ "Two factor backup codes" : "მეორე-ფაქტორის ბექაფის კოდები",
+ "An error occurred while generating your backup codes" : "ბექაფის კოდების გენერაციისას წარმოიშვა შეცდომა",
+ "Save backup codes" : "ბექაფის კოდების შენახვა",
+ "Print backup codes" : "ბექაფის კოდების ამობეჭდვა",
+ "Regenerate backup codes" : "ბექაფის კოდების გენერაცია",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "ძველი კოდები, ახალი ბექაფის კოდების რეგენერაციისას დაკარგავენ მოქმდების ძალას.",
+ "Submit" : "გაგზავნა"
+},"pluralForm" :"nplurals=2; plural=(n!=1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/ko.js b/apps/twofactor_backupcodes/l10n/ko.js
new file mode 100644
index 00000000000..d292d78e9a1
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/ko.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "내 계정의 2단계 인증 백업 코드를 생성함",
+ "Second-factor backup codes" : "2단계 인증 백업 코드",
+ "Generate backup codes" : "백업 코드 생성",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "2단계 인증을 활성화했으나 아직 백업 코드를 생성하지 않았습니다. 백업코드는 2단계 인증을 잃어버려 계정을 복구할 때 필요합니다.",
+ "Backup code" : "백업 코드",
+ "Use backup code" : "백업 코드 사용",
+ "Two factor backup codes" : "2단계 인증 백업 코드",
+ "A two-factor auth backup codes provider" : "2단계 인증 백업 코드 공급자",
+ "An error occurred while generating your backup codes" : "백업 코드를 생성하는 중 오류가 발생했습니다.",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "백업 코드가 생성되었습니다. {total}개 중 {used}개의 코드가 사용되었습니다.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "귀하의 백업 코드입니다. 이 코드는 다시 확인할 수 없다는 사실을 염두에 두고, 저장하거나 출력해 두십시오.",
+ "Save backup codes" : "백업 코드 저장",
+ "Print backup codes" : "백업 코드 인쇄",
+ "Regenerate backup codes" : "백업 코드 다시 생성",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "백업 코드를 다시 생성하면 이전 코드는 자동으로 무효화됩니다.",
+ "{name} backup codes" : "{name} 백업 코드",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "2단계 인증을 설정할 때 저장한 백업 코드를 사용하십시오.",
+ "Submit" : "제출"
+},
+"nplurals=1; plural=0;");
diff --git a/apps/twofactor_backupcodes/l10n/ko.json b/apps/twofactor_backupcodes/l10n/ko.json
new file mode 100644
index 00000000000..29ec38258a5
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/ko.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "내 계정의 2단계 인증 백업 코드를 생성함",
+ "Second-factor backup codes" : "2단계 인증 백업 코드",
+ "Generate backup codes" : "백업 코드 생성",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "2단계 인증을 활성화했으나 아직 백업 코드를 생성하지 않았습니다. 백업코드는 2단계 인증을 잃어버려 계정을 복구할 때 필요합니다.",
+ "Backup code" : "백업 코드",
+ "Use backup code" : "백업 코드 사용",
+ "Two factor backup codes" : "2단계 인증 백업 코드",
+ "A two-factor auth backup codes provider" : "2단계 인증 백업 코드 공급자",
+ "An error occurred while generating your backup codes" : "백업 코드를 생성하는 중 오류가 발생했습니다.",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "백업 코드가 생성되었습니다. {total}개 중 {used}개의 코드가 사용되었습니다.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "귀하의 백업 코드입니다. 이 코드는 다시 확인할 수 없다는 사실을 염두에 두고, 저장하거나 출력해 두십시오.",
+ "Save backup codes" : "백업 코드 저장",
+ "Print backup codes" : "백업 코드 인쇄",
+ "Regenerate backup codes" : "백업 코드 다시 생성",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "백업 코드를 다시 생성하면 이전 코드는 자동으로 무효화됩니다.",
+ "{name} backup codes" : "{name} 백업 코드",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "2단계 인증을 설정할 때 저장한 백업 코드를 사용하십시오.",
+ "Submit" : "제출"
+},"pluralForm" :"nplurals=1; plural=0;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/lt_LT.js b/apps/twofactor_backupcodes/l10n/lt_LT.js
new file mode 100644
index 00000000000..206e3dc2ed2
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/lt_LT.js
@@ -0,0 +1,20 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Jūs sukūrėte dviejų faktorių atsarginius kodus savo paskyrai",
+ "Second-factor backup codes" : "Antorojo faktoriaus atsarginiai kodai",
+ "Generate backup codes" : "Generuoti atsarginius kodus",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Jūs įjungėte dviejų faktorių tapatybės nustatymą, tačiau kol kas nesugeneravote atsarginių kodų. Jie yra reikalingi, kad būtų atkurta prieiga prie jūsų paskyros tuo atveju, jei prarasite savo antrąjį faktorių.",
+ "Backup code" : "Atsarginis kodas",
+ "Use backup code" : "Naudoti atsarginį kodą",
+ "Two factor backup codes" : "Dviejų faktorių atsarginiai kodai",
+ "An error occurred while generating your backup codes" : "Generuojant jūsų atsarginius kodus, įvyko klaida",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Atsarginiai kodai sugeneruoti. Panaudota {used} iš {total} kodų.",
+ "Save backup codes" : "Įrašyti atsarginius kodus",
+ "Print backup codes" : "Spausdinti atsarginius kodus",
+ "Regenerate backup codes" : "Iš naujo generuoti atsarginius kodus",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Jeigu iš naujo generuosite atsarginius kodus, automatiškai paversite senuosius kodus nebegaliojančiais.",
+ "{name} backup codes" : "{name} atsarginiai kodai",
+ "Submit" : "Pateikti"
+},
+"nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < 11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 : n % 1 != 0 ? 2: 3);");
diff --git a/apps/twofactor_backupcodes/l10n/lt_LT.json b/apps/twofactor_backupcodes/l10n/lt_LT.json
new file mode 100644
index 00000000000..bb37a06a21b
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/lt_LT.json
@@ -0,0 +1,18 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Jūs sukūrėte dviejų faktorių atsarginius kodus savo paskyrai",
+ "Second-factor backup codes" : "Antorojo faktoriaus atsarginiai kodai",
+ "Generate backup codes" : "Generuoti atsarginius kodus",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Jūs įjungėte dviejų faktorių tapatybės nustatymą, tačiau kol kas nesugeneravote atsarginių kodų. Jie yra reikalingi, kad būtų atkurta prieiga prie jūsų paskyros tuo atveju, jei prarasite savo antrąjį faktorių.",
+ "Backup code" : "Atsarginis kodas",
+ "Use backup code" : "Naudoti atsarginį kodą",
+ "Two factor backup codes" : "Dviejų faktorių atsarginiai kodai",
+ "An error occurred while generating your backup codes" : "Generuojant jūsų atsarginius kodus, įvyko klaida",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Atsarginiai kodai sugeneruoti. Panaudota {used} iš {total} kodų.",
+ "Save backup codes" : "Įrašyti atsarginius kodus",
+ "Print backup codes" : "Spausdinti atsarginius kodus",
+ "Regenerate backup codes" : "Iš naujo generuoti atsarginius kodus",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Jeigu iš naujo generuosite atsarginius kodus, automatiškai paversite senuosius kodus nebegaliojančiais.",
+ "{name} backup codes" : "{name} atsarginiai kodai",
+ "Submit" : "Pateikti"
+},"pluralForm" :"nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < 11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 : n % 1 != 0 ? 2: 3);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/lv.js b/apps/twofactor_backupcodes/l10n/lv.js
new file mode 100644
index 00000000000..7c0eaf63c4b
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/lv.js
@@ -0,0 +1,16 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Tu savam kontam izveidoji divpakāpju rezerves kopiju kodus",
+ "Second-factor backup codes" : "Second-factor dublēšanas kodi",
+ "Generate backup codes" : "Izveidot rezerves kodus",
+ "Backup code" : "Dublēšanas kods",
+ "Use backup code" : "Izmantot rezerves kodu",
+ "An error occurred while generating your backup codes" : "Atgadījās kļūda rezerves kodu izveidošanas laikā",
+ "Save backup codes" : "Saglabāt rezerves kodus",
+ "Print backup codes" : "Drukāt dublējuma kodus",
+ "Regenerate backup codes" : "Atjaunot dublējuma kodus",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Ja atjaunot dublējum kodus, tiek automātiski anulēti vecie kodi.",
+ "Submit" : "Iesniegt"
+},
+"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);");
diff --git a/apps/twofactor_backupcodes/l10n/lv.json b/apps/twofactor_backupcodes/l10n/lv.json
new file mode 100644
index 00000000000..871dee78b2c
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/lv.json
@@ -0,0 +1,14 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Tu savam kontam izveidoji divpakāpju rezerves kopiju kodus",
+ "Second-factor backup codes" : "Second-factor dublēšanas kodi",
+ "Generate backup codes" : "Izveidot rezerves kodus",
+ "Backup code" : "Dublēšanas kods",
+ "Use backup code" : "Izmantot rezerves kodu",
+ "An error occurred while generating your backup codes" : "Atgadījās kļūda rezerves kodu izveidošanas laikā",
+ "Save backup codes" : "Saglabāt rezerves kodus",
+ "Print backup codes" : "Drukāt dublējuma kodus",
+ "Regenerate backup codes" : "Atjaunot dublējuma kodus",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Ja atjaunot dublējum kodus, tiek automātiski anulēti vecie kodi.",
+ "Submit" : "Iesniegt"
+},"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/mk.js b/apps/twofactor_backupcodes/l10n/mk.js
new file mode 100644
index 00000000000..f6447ece31d
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/mk.js
@@ -0,0 +1,22 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Креиравте резервни кодови за двофакторна автентификација на вашата сметка",
+ "Second-factor backup codes" : "Резервни кодови за двофакторна автентификација",
+ "Generate backup codes" : "Генерирај резервни кодови",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Имате активирано двофакторна автентикација но немате генерирано резервни кодови. Тие се потребни за во случај да го изгубите пристапот до вториот фактор.",
+ "Backup code" : "Резервен код",
+ "Use backup code" : "Искористи резервен код",
+ "Two factor backup codes" : "Резервни кодови за двофакторна автентификација",
+ "A two-factor auth backup codes provider" : "Провајдер за резервни кодови за двофакторна автентификација",
+ "An error occurred while generating your backup codes" : "Настана грешка при генерирање на вашите резервни кодови",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Резервни кодови се генерирани. Искористени се {used} од {total} кодови.",
+ "Save backup codes" : "Зачувај ги резервните кодови",
+ "Print backup codes" : "Печати ги резевните кодови",
+ "Regenerate backup codes" : "Генерирај повторно резервни кодови",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Доколку генерирате повторно резервни кодови, старите кодови нема да бидат во употреба.",
+ "{name} backup codes" : "{name} резервни кодови",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Искористи еден од резервните кодови што ги зачувавте кога активиравте двофакторна автентикација.",
+ "Submit" : "Испрати"
+},
+"nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;");
diff --git a/apps/twofactor_backupcodes/l10n/mk.json b/apps/twofactor_backupcodes/l10n/mk.json
new file mode 100644
index 00000000000..8ff2522dd78
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/mk.json
@@ -0,0 +1,20 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Креиравте резервни кодови за двофакторна автентификација на вашата сметка",
+ "Second-factor backup codes" : "Резервни кодови за двофакторна автентификација",
+ "Generate backup codes" : "Генерирај резервни кодови",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Имате активирано двофакторна автентикација но немате генерирано резервни кодови. Тие се потребни за во случај да го изгубите пристапот до вториот фактор.",
+ "Backup code" : "Резервен код",
+ "Use backup code" : "Искористи резервен код",
+ "Two factor backup codes" : "Резервни кодови за двофакторна автентификација",
+ "A two-factor auth backup codes provider" : "Провајдер за резервни кодови за двофакторна автентификација",
+ "An error occurred while generating your backup codes" : "Настана грешка при генерирање на вашите резервни кодови",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Резервни кодови се генерирани. Искористени се {used} од {total} кодови.",
+ "Save backup codes" : "Зачувај ги резервните кодови",
+ "Print backup codes" : "Печати ги резевните кодови",
+ "Regenerate backup codes" : "Генерирај повторно резервни кодови",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Доколку генерирате повторно резервни кодови, старите кодови нема да бидат во употреба.",
+ "{name} backup codes" : "{name} резервни кодови",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Искористи еден од резервните кодови што ги зачувавте кога активиравте двофакторна автентикација.",
+ "Submit" : "Испрати"
+},"pluralForm" :"nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/mn.js b/apps/twofactor_backupcodes/l10n/mn.js
new file mode 100644
index 00000000000..7c6cf17b2eb
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/mn.js
@@ -0,0 +1,17 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Та өөрийн аккаунтад хоёр хүчин зүйлийн нөөц код үүсгэсэн",
+ "Second-factor backup codes" : "нөөц кодын хоёр дахь хүчин зүйл",
+ "Generate backup codes" : "нөөц кодыг үүсгэх",
+ "Backup code" : "Нөөц код",
+ "Use backup code" : "Нөөц кодыг ашиглах",
+ "Two factor backup codes" : "Нөөц кодын хоёр хүчин зүйл",
+ "An error occurred while generating your backup codes" : "Таны нөөц кодыг үүсгэх явцад алдаа гарлаа",
+ "Save backup codes" : "Нөөц кодыг хадгалах",
+ "Print backup codes" : "Нөөц кодыг хэвлэх",
+ "Regenerate backup codes" : "Нөөц кодыг дахин сэргээх",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "хэрвээ нөөц кодыг дахин сэргээх бол, та хуучин кодыг автоматаар хүчингүй болгоно",
+ "Submit" : "мэдэгдэх"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/twofactor_backupcodes/l10n/mn.json b/apps/twofactor_backupcodes/l10n/mn.json
new file mode 100644
index 00000000000..17763574b64
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/mn.json
@@ -0,0 +1,15 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Та өөрийн аккаунтад хоёр хүчин зүйлийн нөөц код үүсгэсэн",
+ "Second-factor backup codes" : "нөөц кодын хоёр дахь хүчин зүйл",
+ "Generate backup codes" : "нөөц кодыг үүсгэх",
+ "Backup code" : "Нөөц код",
+ "Use backup code" : "Нөөц кодыг ашиглах",
+ "Two factor backup codes" : "Нөөц кодын хоёр хүчин зүйл",
+ "An error occurred while generating your backup codes" : "Таны нөөц кодыг үүсгэх явцад алдаа гарлаа",
+ "Save backup codes" : "Нөөц кодыг хадгалах",
+ "Print backup codes" : "Нөөц кодыг хэвлэх",
+ "Regenerate backup codes" : "Нөөц кодыг дахин сэргээх",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "хэрвээ нөөц кодыг дахин сэргээх бол, та хуучин кодыг автоматаар хүчингүй болгоно",
+ "Submit" : "мэдэгдэх"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/nb.js b/apps/twofactor_backupcodes/l10n/nb.js
new file mode 100644
index 00000000000..ff76337d31a
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/nb.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Du opprettet to-faktor sikkerhetskoder for din konto",
+ "Second-factor backup codes" : "Andre-faktor sikkerhetskoder",
+ "Generate backup codes" : "Generer sikkerhetskoder",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Du aktiverte tofaktorautentisering, men har ikke generert sikkerhetskoder ennå. De er nødvendige for å gjenopprette tilgangen til din konto i tilfelle du mister din to-faktor autentisering.",
+ "Backup code" : "Sikkerhetskoder",
+ "Use backup code" : "Bruker sikkerhetskode",
+ "Two factor backup codes" : "Sikkerhetskoder for to-faktor",
+ "A two-factor auth backup codes provider" : "En tilbyder av sikkerhetskoder for to-faktor autentisering",
+ "An error occurred while generating your backup codes" : "En feil oppsto under generering av sikkerhetskodene",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Sikkerhetskoder er generert. {used} av {total} koder er brukt.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Dette er reservekodene dine. Lagre og/eller skriv dem ut, da du ikke vil kunne lese kodene igjen senere.",
+ "Save backup codes" : "Lagre sikkerhetskodene",
+ "Print backup codes" : "Skriv ut sikkerhetskoder",
+ "Regenerate backup codes" : "Lag sikkerhetskoder på nytt",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Hvis du regenererer nye sikkerhetskoder, blir de gamle kodene ugyldige.",
+ "{name} backup codes" : "{name} sikkerhetskoder",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Bruk en av sikkerhetskodene du lagret når du opprettet to-faktor autentisering.",
+ "Submit" : "Send"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/twofactor_backupcodes/l10n/nb.json b/apps/twofactor_backupcodes/l10n/nb.json
new file mode 100644
index 00000000000..739b785fc98
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/nb.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Du opprettet to-faktor sikkerhetskoder for din konto",
+ "Second-factor backup codes" : "Andre-faktor sikkerhetskoder",
+ "Generate backup codes" : "Generer sikkerhetskoder",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Du aktiverte tofaktorautentisering, men har ikke generert sikkerhetskoder ennå. De er nødvendige for å gjenopprette tilgangen til din konto i tilfelle du mister din to-faktor autentisering.",
+ "Backup code" : "Sikkerhetskoder",
+ "Use backup code" : "Bruker sikkerhetskode",
+ "Two factor backup codes" : "Sikkerhetskoder for to-faktor",
+ "A two-factor auth backup codes provider" : "En tilbyder av sikkerhetskoder for to-faktor autentisering",
+ "An error occurred while generating your backup codes" : "En feil oppsto under generering av sikkerhetskodene",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Sikkerhetskoder er generert. {used} av {total} koder er brukt.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Dette er reservekodene dine. Lagre og/eller skriv dem ut, da du ikke vil kunne lese kodene igjen senere.",
+ "Save backup codes" : "Lagre sikkerhetskodene",
+ "Print backup codes" : "Skriv ut sikkerhetskoder",
+ "Regenerate backup codes" : "Lag sikkerhetskoder på nytt",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Hvis du regenererer nye sikkerhetskoder, blir de gamle kodene ugyldige.",
+ "{name} backup codes" : "{name} sikkerhetskoder",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Bruk en av sikkerhetskodene du lagret når du opprettet to-faktor autentisering.",
+ "Submit" : "Send"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/nl.js b/apps/twofactor_backupcodes/l10n/nl.js
new file mode 100644
index 00000000000..641e12060a9
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/nl.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Je creëerde tweefactorauthenticatie back-upcodes voor je account",
+ "Second-factor backup codes" : "Tweefactorauthenticatie back-upcode",
+ "Generate backup codes" : "Genereer back-upcode",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Je hebt tweefactorauthenticatie ingeschakeld, maar nog geen back-upcodes gegenereerd. Die zijn nodig voor het ontgrendelen van je account in het geval dat je je tweede factor (zoals een mobiele telefoon) kwijt bent.",
+ "Backup code" : "Back-upcode",
+ "Use backup code" : "Gebruik back-upcode",
+ "Two factor backup codes" : "Twee-factor back-upcode",
+ "A two-factor auth backup codes provider" : "Een tweefactor authenticatie back-upcodes provider",
+ "An error occurred while generating your backup codes" : "Er trad een fout op bij het genereren van je back-upcodes",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Back-upcodes zijn gegenereerd. {used} van {total} codes zijn gebruikt.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Dit zijn je back-upcodes. Bewaar ze en/of druk ze alsjeblieft af, want je ze kunt niet later nog een keer opvragen.",
+ "Save backup codes" : "Bewaren back-upcode",
+ "Print backup codes" : "Afdrukken back-upcode",
+ "Regenerate backup codes" : "Regenereer back-upcode",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Als je back-upcodes opnieuw genereert, worden oude codes automatisch ongeldig gemaakt.",
+ "{name} backup codes" : "{name} back-upcodes",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Gebruik een van de back-upcodes die je bewaarde bij het inschakelen van de tweefactorauthenticatie.",
+ "Submit" : "Verwerken"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/twofactor_backupcodes/l10n/nl.json b/apps/twofactor_backupcodes/l10n/nl.json
new file mode 100644
index 00000000000..e4638fbb0f9
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/nl.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Je creëerde tweefactorauthenticatie back-upcodes voor je account",
+ "Second-factor backup codes" : "Tweefactorauthenticatie back-upcode",
+ "Generate backup codes" : "Genereer back-upcode",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Je hebt tweefactorauthenticatie ingeschakeld, maar nog geen back-upcodes gegenereerd. Die zijn nodig voor het ontgrendelen van je account in het geval dat je je tweede factor (zoals een mobiele telefoon) kwijt bent.",
+ "Backup code" : "Back-upcode",
+ "Use backup code" : "Gebruik back-upcode",
+ "Two factor backup codes" : "Twee-factor back-upcode",
+ "A two-factor auth backup codes provider" : "Een tweefactor authenticatie back-upcodes provider",
+ "An error occurred while generating your backup codes" : "Er trad een fout op bij het genereren van je back-upcodes",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Back-upcodes zijn gegenereerd. {used} van {total} codes zijn gebruikt.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Dit zijn je back-upcodes. Bewaar ze en/of druk ze alsjeblieft af, want je ze kunt niet later nog een keer opvragen.",
+ "Save backup codes" : "Bewaren back-upcode",
+ "Print backup codes" : "Afdrukken back-upcode",
+ "Regenerate backup codes" : "Regenereer back-upcode",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Als je back-upcodes opnieuw genereert, worden oude codes automatisch ongeldig gemaakt.",
+ "{name} backup codes" : "{name} back-upcodes",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Gebruik een van de back-upcodes die je bewaarde bij het inschakelen van de tweefactorauthenticatie.",
+ "Submit" : "Verwerken"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/pl.js b/apps/twofactor_backupcodes/l10n/pl.js
new file mode 100644
index 00000000000..52840c4641b
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/pl.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Stworzyłeś zapasowe kody uwierzytelnienia dwuskładnikowego swojego konta",
+ "Second-factor backup codes" : "Kody zapasowe uwierzytelnienia dwuskładnikowego",
+ "Generate backup codes" : "Generowanie kodów zapasowych",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Włączyłeś uwierzytelnianie dwuskładnikowe, ale nie wygenerowłeś jeszcze kodów zapasowych. Są one potrzebne do przywrócenia dostępu do Twojego konta w przypadku utraty drugiego składnika.",
+ "Backup code" : "Kody zapasowe",
+ "Use backup code" : "Użyj kodu zapasowego",
+ "Two factor backup codes" : "Kody zapasowe uwierzytelnienia dwuskładnikowego",
+ "A two-factor auth backup codes provider" : "Dostawca dwuskładnikowych kodów zapasowych ",
+ "An error occurred while generating your backup codes" : "Wystąpił błąd podczas generowania kodów zapasowych.",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Wygenerowano kody zapasowe. Użyto {used} z {total} kodów.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "To są kody zapasowe. Zapisz je i/lub wydrukuj, ponieważ nie będziesz mógł ich później odczytać.",
+ "Save backup codes" : "Zapisz kody zapasowe",
+ "Print backup codes" : "Drukuj kody zapasowe",
+ "Regenerate backup codes" : "Ponownie generuj kody zapasowe",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Jeśli generujesz kody zapasowe ponownie, automatycznie unieważniasz stare kody.",
+ "{name} backup codes" : "Kody kopii zapasowej {name}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Użyj jednego z kodów zapasowych zapisanych podczas konfigurowania uwierzytelniania dwuskładnikowego.",
+ "Submit" : "Wyślij"
+},
+"nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);");
diff --git a/apps/twofactor_backupcodes/l10n/pl.json b/apps/twofactor_backupcodes/l10n/pl.json
new file mode 100644
index 00000000000..e8ecbb3a095
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/pl.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Stworzyłeś zapasowe kody uwierzytelnienia dwuskładnikowego swojego konta",
+ "Second-factor backup codes" : "Kody zapasowe uwierzytelnienia dwuskładnikowego",
+ "Generate backup codes" : "Generowanie kodów zapasowych",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Włączyłeś uwierzytelnianie dwuskładnikowe, ale nie wygenerowłeś jeszcze kodów zapasowych. Są one potrzebne do przywrócenia dostępu do Twojego konta w przypadku utraty drugiego składnika.",
+ "Backup code" : "Kody zapasowe",
+ "Use backup code" : "Użyj kodu zapasowego",
+ "Two factor backup codes" : "Kody zapasowe uwierzytelnienia dwuskładnikowego",
+ "A two-factor auth backup codes provider" : "Dostawca dwuskładnikowych kodów zapasowych ",
+ "An error occurred while generating your backup codes" : "Wystąpił błąd podczas generowania kodów zapasowych.",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Wygenerowano kody zapasowe. Użyto {used} z {total} kodów.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "To są kody zapasowe. Zapisz je i/lub wydrukuj, ponieważ nie będziesz mógł ich później odczytać.",
+ "Save backup codes" : "Zapisz kody zapasowe",
+ "Print backup codes" : "Drukuj kody zapasowe",
+ "Regenerate backup codes" : "Ponownie generuj kody zapasowe",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Jeśli generujesz kody zapasowe ponownie, automatycznie unieważniasz stare kody.",
+ "{name} backup codes" : "Kody kopii zapasowej {name}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Użyj jednego z kodów zapasowych zapisanych podczas konfigurowania uwierzytelniania dwuskładnikowego.",
+ "Submit" : "Wyślij"
+},"pluralForm" :"nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/pt_BR.js b/apps/twofactor_backupcodes/l10n/pt_BR.js
new file mode 100644
index 00000000000..c3803a5f156
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/pt_BR.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Você criou os códigos de backup de dois fatores para sua conta.",
+ "Second-factor backup codes" : "Códigos de backup segundo-fator",
+ "Generate backup codes" : "Gerar códigos de backup",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Você ativou a autenticação de dois fatores, mas ainda não gerou códigos de backup. Eles são necessários para restaurar o acesso à sua conta caso você perca seu segundo fator.",
+ "Backup code" : "Código de backup",
+ "Use backup code" : "Usar o código de backup",
+ "Two factor backup codes" : "Códigos de backup de dois fatores",
+ "A two-factor auth backup codes provider" : "Um provedor de códigos de backup de autenticação de dois fatores",
+ "An error occurred while generating your backup codes" : "Ocorreu um erro ao gerar os códigos de backup",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Códigos de backup foram gerados. Foram usados {used} de um total de {total} códigos.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Estes são seus códigos de backup. Salve-os e/ou imprima-os, pois você não conseguirá ler os códigos novamente mais tarde.",
+ "Save backup codes" : "Salvar códigos de backup",
+ "Print backup codes" : "Imprimir códigos de backup",
+ "Regenerate backup codes" : "Regerar códigos de backup",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Se você gerar novamente os códigos de backup, invalidará automaticamente os códigos antigos.",
+ "{name} backup codes" : "Códigos de backup {name}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Use um dos códigos de backup que você salvou ao configurar a autenticação de dois fatores.",
+ "Submit" : "Enviar"
+},
+"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/twofactor_backupcodes/l10n/pt_BR.json b/apps/twofactor_backupcodes/l10n/pt_BR.json
new file mode 100644
index 00000000000..1f7d46bda90
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/pt_BR.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Você criou os códigos de backup de dois fatores para sua conta.",
+ "Second-factor backup codes" : "Códigos de backup segundo-fator",
+ "Generate backup codes" : "Gerar códigos de backup",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Você ativou a autenticação de dois fatores, mas ainda não gerou códigos de backup. Eles são necessários para restaurar o acesso à sua conta caso você perca seu segundo fator.",
+ "Backup code" : "Código de backup",
+ "Use backup code" : "Usar o código de backup",
+ "Two factor backup codes" : "Códigos de backup de dois fatores",
+ "A two-factor auth backup codes provider" : "Um provedor de códigos de backup de autenticação de dois fatores",
+ "An error occurred while generating your backup codes" : "Ocorreu um erro ao gerar os códigos de backup",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Códigos de backup foram gerados. Foram usados {used} de um total de {total} códigos.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Estes são seus códigos de backup. Salve-os e/ou imprima-os, pois você não conseguirá ler os códigos novamente mais tarde.",
+ "Save backup codes" : "Salvar códigos de backup",
+ "Print backup codes" : "Imprimir códigos de backup",
+ "Regenerate backup codes" : "Regerar códigos de backup",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Se você gerar novamente os códigos de backup, invalidará automaticamente os códigos antigos.",
+ "{name} backup codes" : "Códigos de backup {name}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Use um dos códigos de backup que você salvou ao configurar a autenticação de dois fatores.",
+ "Submit" : "Enviar"
+},"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/pt_PT.js b/apps/twofactor_backupcodes/l10n/pt_PT.js
new file mode 100644
index 00000000000..16cc27277b7
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/pt_PT.js
@@ -0,0 +1,15 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "Second-factor backup codes" : "Códigos de segurança de segundo fator",
+ "Generate backup codes" : "Gerar códigos de cópia de segurança",
+ "Backup code" : "Código de segurança",
+ "Use backup code" : "Usar código de cópia de segurança",
+ "An error occurred while generating your backup codes" : "Ocorreu um erro enquanto os códigos de segurança eram gerados",
+ "Save backup codes" : "Guardar códigos de segurança",
+ "Print backup codes" : "Imprimir códigos de segurança",
+ "Regenerate backup codes" : "Voltar a gerar os códigos de segurança",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Se voltar a gerar os códigos de segurança os seus códigos antigos serão automaticamente invalidados.",
+ "Submit" : "Submeter"
+},
+"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/apps/twofactor_backupcodes/l10n/pt_PT.json b/apps/twofactor_backupcodes/l10n/pt_PT.json
new file mode 100644
index 00000000000..7e132a94af5
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/pt_PT.json
@@ -0,0 +1,13 @@
+{ "translations": {
+ "Second-factor backup codes" : "Códigos de segurança de segundo fator",
+ "Generate backup codes" : "Gerar códigos de cópia de segurança",
+ "Backup code" : "Código de segurança",
+ "Use backup code" : "Usar código de cópia de segurança",
+ "An error occurred while generating your backup codes" : "Ocorreu um erro enquanto os códigos de segurança eram gerados",
+ "Save backup codes" : "Guardar códigos de segurança",
+ "Print backup codes" : "Imprimir códigos de segurança",
+ "Regenerate backup codes" : "Voltar a gerar os códigos de segurança",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Se voltar a gerar os códigos de segurança os seus códigos antigos serão automaticamente invalidados.",
+ "Submit" : "Submeter"
+},"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/ru.js b/apps/twofactor_backupcodes/l10n/ru.js
new file mode 100644
index 00000000000..76e1baf9d6d
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/ru.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Вы создали двухфакторные резервные коды для своего аккаунта",
+ "Second-factor backup codes" : "Резервные коды двухфакторной аутентификации",
+ "Generate backup codes" : "Создать резервные коды",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Вы включили двухфакторную аутентификацию, но еще не сгенерировали резервные коды. Они необходимы для восстановления доступа к вашей учетной записи в случае, если вы потеряете свой второй фактор проверки подлинности.",
+ "Backup code" : "Резервный код",
+ "Use backup code" : "Использовать резервный код",
+ "Two factor backup codes" : "Второй фактор — резервные коды",
+ "A two-factor auth backup codes provider" : "Провайдер резервных копий для кодов двухфакторной аутентификации",
+ "An error occurred while generating your backup codes" : "Произошла ошибка при создании резервных кодов",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Использовано {used} из {total} ранее выпущенных резервных кодов.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Это ваши резервные коды. Пожалуйста, сохраните и/или распечатайте их, так как позже вы не сможете прочитать коды снова.",
+ "Save backup codes" : "Сохранить резервные коды",
+ "Print backup codes" : "Распечатать резервные коды",
+ "Regenerate backup codes" : "Перевыпустить резервные коды",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "При перевыпуске резервных кодов, старые автоматически становятся недействительными.",
+ "{name} backup codes" : "Резервные коды {name}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Использовать для двухфакторной аутентификации один из ранее выпущенных резервных кодов.",
+ "Submit" : "Отправить"
+},
+"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);");
diff --git a/apps/twofactor_backupcodes/l10n/ru.json b/apps/twofactor_backupcodes/l10n/ru.json
new file mode 100644
index 00000000000..9202e3136f1
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/ru.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Вы создали двухфакторные резервные коды для своего аккаунта",
+ "Second-factor backup codes" : "Резервные коды двухфакторной аутентификации",
+ "Generate backup codes" : "Создать резервные коды",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Вы включили двухфакторную аутентификацию, но еще не сгенерировали резервные коды. Они необходимы для восстановления доступа к вашей учетной записи в случае, если вы потеряете свой второй фактор проверки подлинности.",
+ "Backup code" : "Резервный код",
+ "Use backup code" : "Использовать резервный код",
+ "Two factor backup codes" : "Второй фактор — резервные коды",
+ "A two-factor auth backup codes provider" : "Провайдер резервных копий для кодов двухфакторной аутентификации",
+ "An error occurred while generating your backup codes" : "Произошла ошибка при создании резервных кодов",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Использовано {used} из {total} ранее выпущенных резервных кодов.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Это ваши резервные коды. Пожалуйста, сохраните и/или распечатайте их, так как позже вы не сможете прочитать коды снова.",
+ "Save backup codes" : "Сохранить резервные коды",
+ "Print backup codes" : "Распечатать резервные коды",
+ "Regenerate backup codes" : "Перевыпустить резервные коды",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "При перевыпуске резервных кодов, старые автоматически становятся недействительными.",
+ "{name} backup codes" : "Резервные коды {name}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Использовать для двухфакторной аутентификации один из ранее выпущенных резервных кодов.",
+ "Submit" : "Отправить"
+},"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/sc.js b/apps/twofactor_backupcodes/l10n/sc.js
new file mode 100644
index 00000000000..850261f3774
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/sc.js
@@ -0,0 +1,22 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "As creadu còdighes de còpia de seguresa a duos fatores pro su contu tuo",
+ "Second-factor backup codes" : "Còdighes de còpia de seguresa a segundu fatore",
+ "Generate backup codes" : "Gènera còdighes de còpia de seguresa",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "As ativadu s'autenticatzione a duos fatores ma no as ancora generadu is còdighes. Sunt netzessàrios pro ripristinare s'atzessu a su contu tuo s'in casu perdes su segundu fatore. ",
+ "Backup code" : "Còdighe de còpia de seguresa",
+ "Use backup code" : "Imprea còdighe de còpia de seguresa",
+ "Two factor backup codes" : "Còdighes còpia de seguresa a duos fatores",
+ "A two-factor auth backup codes provider" : "Unu frunidore de autenticatzione de còdighes de còpia de seguresa a duos fatores",
+ "An error occurred while generating your backup codes" : "Ddoe at àpidu un'errore in sa creatzione de is còdighes de còpia de seguresa",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Is còdighes de còpia de seguresa si sunt generados. {used} de {total} còdighes sunt istados impreados.",
+ "Save backup codes" : "Sarva còdighes de còpia de seguresa",
+ "Print backup codes" : "Imprenta còdighes de còpia de seguresa",
+ "Regenerate backup codes" : "Torra a generare còdighes de còpia de seguresa",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si torras a generare is còdighes de còpia de seguresa, in automàticu is còdighes betzos non sunt prus vàlidos.",
+ "{name} backup codes" : "{name} còdighes de còpia de seguresa",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Imprea unu de is còdighes de còpia de seguresa chi as sarvadu cando cunfiguras s'autenticatzione a duos fatores.",
+ "Submit" : "Imbia"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/twofactor_backupcodes/l10n/sc.json b/apps/twofactor_backupcodes/l10n/sc.json
new file mode 100644
index 00000000000..3d0bc7d37ac
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/sc.json
@@ -0,0 +1,20 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "As creadu còdighes de còpia de seguresa a duos fatores pro su contu tuo",
+ "Second-factor backup codes" : "Còdighes de còpia de seguresa a segundu fatore",
+ "Generate backup codes" : "Gènera còdighes de còpia de seguresa",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "As ativadu s'autenticatzione a duos fatores ma no as ancora generadu is còdighes. Sunt netzessàrios pro ripristinare s'atzessu a su contu tuo s'in casu perdes su segundu fatore. ",
+ "Backup code" : "Còdighe de còpia de seguresa",
+ "Use backup code" : "Imprea còdighe de còpia de seguresa",
+ "Two factor backup codes" : "Còdighes còpia de seguresa a duos fatores",
+ "A two-factor auth backup codes provider" : "Unu frunidore de autenticatzione de còdighes de còpia de seguresa a duos fatores",
+ "An error occurred while generating your backup codes" : "Ddoe at àpidu un'errore in sa creatzione de is còdighes de còpia de seguresa",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Is còdighes de còpia de seguresa si sunt generados. {used} de {total} còdighes sunt istados impreados.",
+ "Save backup codes" : "Sarva còdighes de còpia de seguresa",
+ "Print backup codes" : "Imprenta còdighes de còpia de seguresa",
+ "Regenerate backup codes" : "Torra a generare còdighes de còpia de seguresa",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Si torras a generare is còdighes de còpia de seguresa, in automàticu is còdighes betzos non sunt prus vàlidos.",
+ "{name} backup codes" : "{name} còdighes de còpia de seguresa",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Imprea unu de is còdighes de còpia de seguresa chi as sarvadu cando cunfiguras s'autenticatzione a duos fatores.",
+ "Submit" : "Imbia"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/sk.js b/apps/twofactor_backupcodes/l10n/sk.js
new file mode 100644
index 00000000000..d5d51c5b935
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/sk.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Vytvorili ste záložné kódy dvojfaktorového overovania pre váš účet",
+ "Second-factor backup codes" : "Dvojfaktorové záložné kódy",
+ "Generate backup codes" : "Vytvoriť záložné kódy",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Povolili ste dvojfaktorové overenie totožnosti, zatiaľ ste však nevygenerovali záložné kódy. V prípade straty druhého faktora sú potrebné na obnovenie prístupu k vášmu účtu.",
+ "Backup code" : "Záložný kód",
+ "Use backup code" : "Použiť záložný kód",
+ "Two factor backup codes" : "Záložné kódy pre dvojfaktorové overovanie",
+ "A two-factor auth backup codes provider" : "Poskytovateľ záložných kódov pre dvojfaktorové overovanie",
+ "An error occurred while generating your backup codes" : "Pri vytváraní záložných kódov nastala chyba.",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Boli vygenerované záložné kódy. Boli použité {used} z {total} kódov.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Toto sú vaše záložné kódy. Uložte si ich a/alebo si ich vytlačte, pretože kódy neskôr nebudete môcť znova prečítať.",
+ "Save backup codes" : "Uložiť záložné kódy",
+ "Print backup codes" : "Vytlačiť záložné kódy",
+ "Regenerate backup codes" : "Vytvoriť nové záložné kódy",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Ak vytvoríte nové záložné kódy, staré sa automaticky zneplatnia.",
+ "{name} backup codes" : "{name} záložné kódy",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Pri nastavovaní dvojfaktorového overovania totožnosti použite jeden zo záložných kódov, ktoré ste uložili.",
+ "Submit" : "Odoslať"
+},
+"nplurals=4; plural=(n % 1 == 0 && n == 1 ? 0 : n % 1 == 0 && n >= 2 && n <= 4 ? 1 : n % 1 != 0 ? 2: 3);");
diff --git a/apps/twofactor_backupcodes/l10n/sk.json b/apps/twofactor_backupcodes/l10n/sk.json
new file mode 100644
index 00000000000..cc32c1f9721
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/sk.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Vytvorili ste záložné kódy dvojfaktorového overovania pre váš účet",
+ "Second-factor backup codes" : "Dvojfaktorové záložné kódy",
+ "Generate backup codes" : "Vytvoriť záložné kódy",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Povolili ste dvojfaktorové overenie totožnosti, zatiaľ ste však nevygenerovali záložné kódy. V prípade straty druhého faktora sú potrebné na obnovenie prístupu k vášmu účtu.",
+ "Backup code" : "Záložný kód",
+ "Use backup code" : "Použiť záložný kód",
+ "Two factor backup codes" : "Záložné kódy pre dvojfaktorové overovanie",
+ "A two-factor auth backup codes provider" : "Poskytovateľ záložných kódov pre dvojfaktorové overovanie",
+ "An error occurred while generating your backup codes" : "Pri vytváraní záložných kódov nastala chyba.",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Boli vygenerované záložné kódy. Boli použité {used} z {total} kódov.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Toto sú vaše záložné kódy. Uložte si ich a/alebo si ich vytlačte, pretože kódy neskôr nebudete môcť znova prečítať.",
+ "Save backup codes" : "Uložiť záložné kódy",
+ "Print backup codes" : "Vytlačiť záložné kódy",
+ "Regenerate backup codes" : "Vytvoriť nové záložné kódy",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Ak vytvoríte nové záložné kódy, staré sa automaticky zneplatnia.",
+ "{name} backup codes" : "{name} záložné kódy",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Pri nastavovaní dvojfaktorového overovania totožnosti použite jeden zo záložných kódov, ktoré ste uložili.",
+ "Submit" : "Odoslať"
+},"pluralForm" :"nplurals=4; plural=(n % 1 == 0 && n == 1 ? 0 : n % 1 == 0 && n >= 2 && n <= 4 ? 1 : n % 1 != 0 ? 2: 3);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/sl.js b/apps/twofactor_backupcodes/l10n/sl.js
new file mode 100644
index 00000000000..1d0310064a7
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/sl.js
@@ -0,0 +1,22 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Za račun so uspešno ustvarjene dvo-stopenjske varnostne kode",
+ "Second-factor backup codes" : "Varnostne kode druge stopnje",
+ "Generate backup codes" : "Ustvari rezervne šifre",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Omogočena je dvostopenjska overitev, ni pa še ustvarjenih varnostnih kod. Uporabljajo se za obnovitev dostopa do računa v primeru neveljavnosti kode druge stopnje.",
+ "Backup code" : "Varnostna koda",
+ "Use backup code" : "Uporabi varnostno kodo",
+ "Two factor backup codes" : "Dvostopenjske varnostne kode",
+ "A two-factor auth backup codes provider" : "Ponudnik varnostnih kod za dvostopenjsko overitev",
+ "An error occurred while generating your backup codes" : "Prišlo je do namako med ustvarjanjem varnostnih kok",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Varnostne kode so bile uspešno ustvarjene. Uporabljeno {used} od skupno {total}.",
+ "Save backup codes" : "Shrani varnostne kode",
+ "Print backup codes" : "Natisni varnostne kode",
+ "Regenerate backup codes" : "Osveži varnostne kode",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Z osvežitvijo varnostnih kod bo preklicana veljavnost starih.",
+ "{name} backup codes" : "Varnostne kode {name}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Uporabite eno izmed varnostnih kod, ki ste jo shranili pri nastavljanju dvostopenjske overitve",
+ "Submit" : "Pošlji"
+},
+"nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);");
diff --git a/apps/twofactor_backupcodes/l10n/sl.json b/apps/twofactor_backupcodes/l10n/sl.json
new file mode 100644
index 00000000000..eea353bedc7
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/sl.json
@@ -0,0 +1,20 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Za račun so uspešno ustvarjene dvo-stopenjske varnostne kode",
+ "Second-factor backup codes" : "Varnostne kode druge stopnje",
+ "Generate backup codes" : "Ustvari rezervne šifre",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Omogočena je dvostopenjska overitev, ni pa še ustvarjenih varnostnih kod. Uporabljajo se za obnovitev dostopa do računa v primeru neveljavnosti kode druge stopnje.",
+ "Backup code" : "Varnostna koda",
+ "Use backup code" : "Uporabi varnostno kodo",
+ "Two factor backup codes" : "Dvostopenjske varnostne kode",
+ "A two-factor auth backup codes provider" : "Ponudnik varnostnih kod za dvostopenjsko overitev",
+ "An error occurred while generating your backup codes" : "Prišlo je do namako med ustvarjanjem varnostnih kok",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Varnostne kode so bile uspešno ustvarjene. Uporabljeno {used} od skupno {total}.",
+ "Save backup codes" : "Shrani varnostne kode",
+ "Print backup codes" : "Natisni varnostne kode",
+ "Regenerate backup codes" : "Osveži varnostne kode",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Z osvežitvijo varnostnih kod bo preklicana veljavnost starih.",
+ "{name} backup codes" : "Varnostne kode {name}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Uporabite eno izmed varnostnih kod, ki ste jo shranili pri nastavljanju dvostopenjske overitve",
+ "Submit" : "Pošlji"
+},"pluralForm" :"nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/sq.js b/apps/twofactor_backupcodes/l10n/sq.js
new file mode 100644
index 00000000000..74167ba33e4
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/sq.js
@@ -0,0 +1,17 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Ju krijuat kodet rezervë me dy faktorë për llogarinë tuaj",
+ "Second-factor backup codes" : "Kodet e rezervimit të dytë të faktorëve",
+ "Generate backup codes" : "Gjenero kodet rezerve",
+ "Backup code" : "Kod i kopjuar",
+ "Use backup code" : "Përdorni kodin e kopjimit",
+ "Two factor backup codes" : "Dy kopje rezervë të faktorëve",
+ "An error occurred while generating your backup codes" : "Ndodhi një problem ndërsa ishin duke u prodhuar kodet tuaja rezervë",
+ "Save backup codes" : "Ruaj kodet e kopjuara",
+ "Print backup codes" : "Printo kodet rezervë ",
+ "Regenerate backup codes" : "Gjenero kodet e kopjuara",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Nëse gjeneroni kode rezervë, automaktikisht ju çaktivizoni kodet e vjetra.",
+ "Submit" : "Dërgo"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/twofactor_backupcodes/l10n/sq.json b/apps/twofactor_backupcodes/l10n/sq.json
new file mode 100644
index 00000000000..9448cacbdc4
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/sq.json
@@ -0,0 +1,15 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Ju krijuat kodet rezervë me dy faktorë për llogarinë tuaj",
+ "Second-factor backup codes" : "Kodet e rezervimit të dytë të faktorëve",
+ "Generate backup codes" : "Gjenero kodet rezerve",
+ "Backup code" : "Kod i kopjuar",
+ "Use backup code" : "Përdorni kodin e kopjimit",
+ "Two factor backup codes" : "Dy kopje rezervë të faktorëve",
+ "An error occurred while generating your backup codes" : "Ndodhi një problem ndërsa ishin duke u prodhuar kodet tuaja rezervë",
+ "Save backup codes" : "Ruaj kodet e kopjuara",
+ "Print backup codes" : "Printo kodet rezervë ",
+ "Regenerate backup codes" : "Gjenero kodet e kopjuara",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Nëse gjeneroni kode rezervë, automaktikisht ju çaktivizoni kodet e vjetra.",
+ "Submit" : "Dërgo"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/sr.js b/apps/twofactor_backupcodes/l10n/sr.js
new file mode 100644
index 00000000000..58ba0cfca8d
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/sr.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Направили сте двофакторске резервне кодове за Ваш налог",
+ "Second-factor backup codes" : "Двофакторски резервни кодови",
+ "Generate backup codes" : "Генериши резервне кодове",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Укључили сте двофакторску проверу идентитета, али још нисте генерисали резервне кодове. Они су потребни да вратите приступ Вашем налогу, у случају да изгубите приступ Вашем другом фактору.",
+ "Backup code" : "Резервни код",
+ "Use backup code" : "Искористи резервни код",
+ "Two factor backup codes" : "Двофакторски резервни кодови",
+ "A two-factor auth backup codes provider" : "Провајдер резервних кодова за двофакторску ауторизацију",
+ "An error occurred while generating your backup codes" : "Десила се грешка приликом генерисања резервних кодова",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Резервни кодови су изгенерисани. {used} од {total} кодова је искоришћено.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Ово су ваши резервни кодови. Сачувајте их и/или их одштампајте пошто више нећете моћи поново да их прочитате.",
+ "Save backup codes" : "Сачувај резервне кодове",
+ "Print backup codes" : "Одштампај резервне кодове",
+ "Regenerate backup codes" : "Поново генериши резервне кодове",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Ако поново генеришете резервне кодове, стари аутоматски престају да важе.",
+ "{name} backup codes" : "{name} резервни кодови",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Искористите један од резервних кодова које сте сачували када се подешавали двофакторску проверу идентитета.",
+ "Submit" : "Пошаљи"
+},
+"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);");
diff --git a/apps/twofactor_backupcodes/l10n/sr.json b/apps/twofactor_backupcodes/l10n/sr.json
new file mode 100644
index 00000000000..0a5be0547be
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/sr.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Направили сте двофакторске резервне кодове за Ваш налог",
+ "Second-factor backup codes" : "Двофакторски резервни кодови",
+ "Generate backup codes" : "Генериши резервне кодове",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Укључили сте двофакторску проверу идентитета, али још нисте генерисали резервне кодове. Они су потребни да вратите приступ Вашем налогу, у случају да изгубите приступ Вашем другом фактору.",
+ "Backup code" : "Резервни код",
+ "Use backup code" : "Искористи резервни код",
+ "Two factor backup codes" : "Двофакторски резервни кодови",
+ "A two-factor auth backup codes provider" : "Провајдер резервних кодова за двофакторску ауторизацију",
+ "An error occurred while generating your backup codes" : "Десила се грешка приликом генерисања резервних кодова",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Резервни кодови су изгенерисани. {used} од {total} кодова је искоришћено.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Ово су ваши резервни кодови. Сачувајте их и/или их одштампајте пошто више нећете моћи поново да их прочитате.",
+ "Save backup codes" : "Сачувај резервне кодове",
+ "Print backup codes" : "Одштампај резервне кодове",
+ "Regenerate backup codes" : "Поново генериши резервне кодове",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Ако поново генеришете резервне кодове, стари аутоматски престају да важе.",
+ "{name} backup codes" : "{name} резервни кодови",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Искористите један од резервних кодова које сте сачували када се подешавали двофакторску проверу идентитета.",
+ "Submit" : "Пошаљи"
+},"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/sv.js b/apps/twofactor_backupcodes/l10n/sv.js
new file mode 100644
index 00000000000..4ac01e1d46a
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/sv.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Du skapade återställningsnycklar till tvåfaktorsautentiseringen på ditt användarkonto.",
+ "Second-factor backup codes" : "Tvåfaktorsautentisering",
+ "Generate backup codes" : "Generera återställningsnycklar",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Du har aktiverat tvåfaktorsautentisering men har ännu inte skapat återställningsnycklar. Detta är nödvändigt om du förlorar åtkomst till din andra faktor.",
+ "Backup code" : "Återställningsnyckel",
+ "Use backup code" : "Använd återställningsnyckel",
+ "Two factor backup codes" : "Återställningsnycklar tvåfaktor",
+ "A two-factor auth backup codes provider" : "Återställningsnycklar för tvåfaktorautentisering",
+ "An error occurred while generating your backup codes" : "Ett fel uppstod vid skapandet av nya återställningsnycklar",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Återställningsnycklar har skapats. {used} av {total} nycklar har använts.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Detta är dina reservkoder. Spara och/eller skriv ut dem eftersom du inte kommer att kunna läsa koderna igen senare.",
+ "Save backup codes" : "Spara återställningsnycklar",
+ "Print backup codes" : "Skriv ut återställningsnycklar",
+ "Regenerate backup codes" : "Skapa nya återställningsnycklar",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Om du skapar nya återställningsnycklar så kommer de gamla automatiskt att sluta fungera.",
+ "{name} backup codes" : "{name} återställningsnycklar",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Använd en av återställningsnycklarna du sparade när du konfigurerar tvåfaktorsautentisering.",
+ "Submit" : "Skicka"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/twofactor_backupcodes/l10n/sv.json b/apps/twofactor_backupcodes/l10n/sv.json
new file mode 100644
index 00000000000..f579d7633aa
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/sv.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Du skapade återställningsnycklar till tvåfaktorsautentiseringen på ditt användarkonto.",
+ "Second-factor backup codes" : "Tvåfaktorsautentisering",
+ "Generate backup codes" : "Generera återställningsnycklar",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Du har aktiverat tvåfaktorsautentisering men har ännu inte skapat återställningsnycklar. Detta är nödvändigt om du förlorar åtkomst till din andra faktor.",
+ "Backup code" : "Återställningsnyckel",
+ "Use backup code" : "Använd återställningsnyckel",
+ "Two factor backup codes" : "Återställningsnycklar tvåfaktor",
+ "A two-factor auth backup codes provider" : "Återställningsnycklar för tvåfaktorautentisering",
+ "An error occurred while generating your backup codes" : "Ett fel uppstod vid skapandet av nya återställningsnycklar",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Återställningsnycklar har skapats. {used} av {total} nycklar har använts.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Detta är dina reservkoder. Spara och/eller skriv ut dem eftersom du inte kommer att kunna läsa koderna igen senare.",
+ "Save backup codes" : "Spara återställningsnycklar",
+ "Print backup codes" : "Skriv ut återställningsnycklar",
+ "Regenerate backup codes" : "Skapa nya återställningsnycklar",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Om du skapar nya återställningsnycklar så kommer de gamla automatiskt att sluta fungera.",
+ "{name} backup codes" : "{name} återställningsnycklar",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Använd en av återställningsnycklarna du sparade när du konfigurerar tvåfaktorsautentisering.",
+ "Submit" : "Skicka"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/sw.js b/apps/twofactor_backupcodes/l10n/sw.js
new file mode 100644
index 00000000000..1602df7d1dc
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/sw.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Umeunda misimbo ya usaidizi ya vipengele viwili vya akaunti yako",
+ "Second-factor backup codes" : "Misimbo ya ambari mbadala za kipengele cha pili",
+ "Generate backup codes" : "Tengeneza misimbo mbadala",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Umewasha uthibitishaji wa vipengele viwili lakini bado hukutoa misimbo mbadala. Inahitajika ili kurejesha ufikiaji wa akaunti yako endapo utapoteza kipengele chako cha pili.",
+ "Backup code" : "Msimbo mbadala wa usaidizi",
+ "Use backup code" : "Tumia nambari ya kuthibitisha",
+ "Two factor backup codes" : "Nambari mbili mbadala za misimbo",
+ "A two-factor auth backup codes provider" : "Mtoa huduma wa misimbo ya uthibitishaji wa vipengele viwili",
+ "An error occurred while generating your backup codes" : "Hitilafu ilitokea wakati wa kuunda misimbo yako mbadala",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Misimbo ya hifadhi rudufu imetolewa. {used}kati ya misimbo {total} zimetumika.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Hii ndiyo misimbo yako mbadala. Tafadhali ihifadhi na/au uichapishe kwani hutaweza kusoma misimbo tena baadaye.",
+ "Save backup codes" : "Hifadhi misimbo mbadala ya usaidizi",
+ "Print backup codes" : "Chapisha misimbo mbadala ya usaidizi",
+ "Regenerate backup codes" : "Tengeneza upya misimbo mbadala ya usaidizi",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Ukiunda upya misimbo mbadala, unabatilisha misimbo ya zamani kiotomatiki.",
+ "{name} backup codes" : "{name} misimbo mbadala ya usaidizi",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Tumia mojawapo ya misimbo mbadala uliyohifadhi wakati wa kusanidi uthibitishaji wa vipengele viwili.",
+ "Submit" : "Wasilisha"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/twofactor_backupcodes/l10n/sw.json b/apps/twofactor_backupcodes/l10n/sw.json
new file mode 100644
index 00000000000..b6607a180e5
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/sw.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Umeunda misimbo ya usaidizi ya vipengele viwili vya akaunti yako",
+ "Second-factor backup codes" : "Misimbo ya ambari mbadala za kipengele cha pili",
+ "Generate backup codes" : "Tengeneza misimbo mbadala",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Umewasha uthibitishaji wa vipengele viwili lakini bado hukutoa misimbo mbadala. Inahitajika ili kurejesha ufikiaji wa akaunti yako endapo utapoteza kipengele chako cha pili.",
+ "Backup code" : "Msimbo mbadala wa usaidizi",
+ "Use backup code" : "Tumia nambari ya kuthibitisha",
+ "Two factor backup codes" : "Nambari mbili mbadala za misimbo",
+ "A two-factor auth backup codes provider" : "Mtoa huduma wa misimbo ya uthibitishaji wa vipengele viwili",
+ "An error occurred while generating your backup codes" : "Hitilafu ilitokea wakati wa kuunda misimbo yako mbadala",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Misimbo ya hifadhi rudufu imetolewa. {used}kati ya misimbo {total} zimetumika.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Hii ndiyo misimbo yako mbadala. Tafadhali ihifadhi na/au uichapishe kwani hutaweza kusoma misimbo tena baadaye.",
+ "Save backup codes" : "Hifadhi misimbo mbadala ya usaidizi",
+ "Print backup codes" : "Chapisha misimbo mbadala ya usaidizi",
+ "Regenerate backup codes" : "Tengeneza upya misimbo mbadala ya usaidizi",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Ukiunda upya misimbo mbadala, unabatilisha misimbo ya zamani kiotomatiki.",
+ "{name} backup codes" : "{name} misimbo mbadala ya usaidizi",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Tumia mojawapo ya misimbo mbadala uliyohifadhi wakati wa kusanidi uthibitishaji wa vipengele viwili.",
+ "Submit" : "Wasilisha"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/tr.js b/apps/twofactor_backupcodes/l10n/tr.js
new file mode 100644
index 00000000000..5d2bb802e55
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/tr.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "İki adımlı doğrulama için yedek kodlarınızı oluşturdunuz",
+ "Second-factor backup codes" : "İki adımlı doğrulama yedek kodları",
+ "Generate backup codes" : "Yedek kodları oluştur",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "İki adımlı doğrulamayı kullanıma aldınız ancak henüz yedek kodlarını oluşturmadınız. Bu kodlar herhangi bir nedenle ikinci adımı kullanamadığınızda hesabınıza erişebilmenizi sağlar.",
+ "Backup code" : "Yedek kod",
+ "Use backup code" : "Yedek kodu kullan",
+ "Two factor backup codes" : "İki adımlı doğrulama yedek kodları",
+ "A two-factor auth backup codes provider" : "İki adımlı doğrulama için yedek kodlar sağlayıcısı",
+ "An error occurred while generating your backup codes" : "Yedek kodlar oluşturulurken bir sorun çıktı",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Yedek kodları oluşturuldu. {used} / {total} kod kullanılıyor.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Yedek kodlarınızı burada görebilirsiniz. Kodları daha sonra göremeyeceğiniz için bu kodları kaydedin ya da yazdırın.",
+ "Save backup codes" : "Yedek kodları kaydet",
+ "Print backup codes" : "Yedek kodları yazdır",
+ "Regenerate backup codes" : "Yedek kodlarını yeniden oluştur",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Yedek kodlarını yeniden oluşturursanız, eski kodlar geçersiz olur.",
+ "{name} backup codes" : "{name} yedek kodları",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "İki adımlı doğrulamayı ayarlarken yedek kodlarından birini kullanın.",
+ "Submit" : "Gönder"
+},
+"nplurals=2; plural=(n > 1);");
diff --git a/apps/twofactor_backupcodes/l10n/tr.json b/apps/twofactor_backupcodes/l10n/tr.json
new file mode 100644
index 00000000000..2ad03bb0a87
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/tr.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "İki adımlı doğrulama için yedek kodlarınızı oluşturdunuz",
+ "Second-factor backup codes" : "İki adımlı doğrulama yedek kodları",
+ "Generate backup codes" : "Yedek kodları oluştur",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "İki adımlı doğrulamayı kullanıma aldınız ancak henüz yedek kodlarını oluşturmadınız. Bu kodlar herhangi bir nedenle ikinci adımı kullanamadığınızda hesabınıza erişebilmenizi sağlar.",
+ "Backup code" : "Yedek kod",
+ "Use backup code" : "Yedek kodu kullan",
+ "Two factor backup codes" : "İki adımlı doğrulama yedek kodları",
+ "A two-factor auth backup codes provider" : "İki adımlı doğrulama için yedek kodlar sağlayıcısı",
+ "An error occurred while generating your backup codes" : "Yedek kodlar oluşturulurken bir sorun çıktı",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Yedek kodları oluşturuldu. {used} / {total} kod kullanılıyor.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Yedek kodlarınızı burada görebilirsiniz. Kodları daha sonra göremeyeceğiniz için bu kodları kaydedin ya da yazdırın.",
+ "Save backup codes" : "Yedek kodları kaydet",
+ "Print backup codes" : "Yedek kodları yazdır",
+ "Regenerate backup codes" : "Yedek kodlarını yeniden oluştur",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Yedek kodlarını yeniden oluşturursanız, eski kodlar geçersiz olur.",
+ "{name} backup codes" : "{name} yedek kodları",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "İki adımlı doğrulamayı ayarlarken yedek kodlarından birini kullanın.",
+ "Submit" : "Gönder"
+},"pluralForm" :"nplurals=2; plural=(n > 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/ug.js b/apps/twofactor_backupcodes/l10n/ug.js
new file mode 100644
index 00000000000..351a95adf06
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/ug.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "ھېساباتىڭىزغا ئىككى ئامىللىق زاپاسلاش كودى قۇردىڭىز",
+ "Second-factor backup codes" : "ئىككىنچى ئامىل زاپاسلاش كودى",
+ "Generate backup codes" : "زاپاسلاش كودى ھاسىل قىلىڭ",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "سىز ئىككى ئامىللىق دەلىللەشنى قوزغىدىڭىز ، ئەمما زاپاسلاش كودى ھاسىل قىلمىدىڭىز. ئۇلار ئىككىنچى ئامىلىڭىزنى يوقىتىپ قويسىڭىز ، ھېساباتىڭىزغا كىرىشنى ئەسلىگە كەلتۈرۈشكە موھتاج.",
+ "Backup code" : "زاپاسلاش كودى",
+ "Use backup code" : "زاپاسلاش كودىنى ئىشلىتىڭ",
+ "Two factor backup codes" : "ئىككى ئامىل زاپاسلاش كودى",
+ "A two-factor auth backup codes provider" : "ئىككى ئامىللىق ئاپتوماتىك زاپاسلاش كودى بىلەن تەمىنلىگۈچى",
+ "An error occurred while generating your backup codes" : "زاپاسلاش كودىڭىزنى ھاسىل قىلغاندا خاتالىق كۆرۈلدى",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "زاپاسلاش كودى بارلىققا كەلدى. {used}{total} كودلار ئىشلىتىلگەن.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "بۇلار سىزنىڭ زاپاسلاش كودىڭىز. كېيىن كودلارنى قايتا ئوقۇيالمىغاچقا ساقلىۋېلىڭ ۋە ياكى بېسىڭ.",
+ "Save backup codes" : "زاپاسلاش كودىنى ساقلاڭ",
+ "Print backup codes" : "زاپاسلاش كودىنى بېسىڭ",
+ "Regenerate backup codes" : "زاپاسلاش كودىنى قايتا ھاسىل قىلىڭ",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "زاپاسلاش كودىنى ئەسلىگە كەلتۈرسىڭىز ، كونا كودلارنى ئاپتوماتىك ئىناۋەتسىز قىلىسىز.",
+ "{name} backup codes" : "{name} زاپاسلاش كودى",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "ئىككى ئامىللىق دەلىللەشنى تەڭشىگەندە ساقلىغان زاپاسلاش كودىدىن بىرنى ئىشلىتىڭ.",
+ "Submit" : "يوللاڭ"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/twofactor_backupcodes/l10n/ug.json b/apps/twofactor_backupcodes/l10n/ug.json
new file mode 100644
index 00000000000..be886f61abf
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/ug.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "ھېساباتىڭىزغا ئىككى ئامىللىق زاپاسلاش كودى قۇردىڭىز",
+ "Second-factor backup codes" : "ئىككىنچى ئامىل زاپاسلاش كودى",
+ "Generate backup codes" : "زاپاسلاش كودى ھاسىل قىلىڭ",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "سىز ئىككى ئامىللىق دەلىللەشنى قوزغىدىڭىز ، ئەمما زاپاسلاش كودى ھاسىل قىلمىدىڭىز. ئۇلار ئىككىنچى ئامىلىڭىزنى يوقىتىپ قويسىڭىز ، ھېساباتىڭىزغا كىرىشنى ئەسلىگە كەلتۈرۈشكە موھتاج.",
+ "Backup code" : "زاپاسلاش كودى",
+ "Use backup code" : "زاپاسلاش كودىنى ئىشلىتىڭ",
+ "Two factor backup codes" : "ئىككى ئامىل زاپاسلاش كودى",
+ "A two-factor auth backup codes provider" : "ئىككى ئامىللىق ئاپتوماتىك زاپاسلاش كودى بىلەن تەمىنلىگۈچى",
+ "An error occurred while generating your backup codes" : "زاپاسلاش كودىڭىزنى ھاسىل قىلغاندا خاتالىق كۆرۈلدى",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "زاپاسلاش كودى بارلىققا كەلدى. {used}{total} كودلار ئىشلىتىلگەن.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "بۇلار سىزنىڭ زاپاسلاش كودىڭىز. كېيىن كودلارنى قايتا ئوقۇيالمىغاچقا ساقلىۋېلىڭ ۋە ياكى بېسىڭ.",
+ "Save backup codes" : "زاپاسلاش كودىنى ساقلاڭ",
+ "Print backup codes" : "زاپاسلاش كودىنى بېسىڭ",
+ "Regenerate backup codes" : "زاپاسلاش كودىنى قايتا ھاسىل قىلىڭ",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "زاپاسلاش كودىنى ئەسلىگە كەلتۈرسىڭىز ، كونا كودلارنى ئاپتوماتىك ئىناۋەتسىز قىلىسىز.",
+ "{name} backup codes" : "{name} زاپاسلاش كودى",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "ئىككى ئامىللىق دەلىللەشنى تەڭشىگەندە ساقلىغان زاپاسلاش كودىدىن بىرنى ئىشلىتىڭ.",
+ "Submit" : "يوللاڭ"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/uk.js b/apps/twofactor_backupcodes/l10n/uk.js
new file mode 100644
index 00000000000..6c4f1d63169
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/uk.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "Ви створили резервні коди для двофакторної авторизації у вашому обліковому записі",
+ "Second-factor backup codes" : "Резервні коди другого фактору",
+ "Generate backup codes" : "Створити резервні коди",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Ви увімкнули двофакторну авторизацію, але поки не створили резервні коди. Резервні коди потрібні для відновлення доступу до вашого облікового запису, якщо буде втрачено доступ до другого фактору.",
+ "Backup code" : "Резервні коди",
+ "Use backup code" : "Використати резервний код",
+ "Two factor backup codes" : "Резервні коди двофакторної авторизації",
+ "A two-factor auth backup codes provider" : "Постачальник резервних кодів двофакторної авторизації",
+ "An error occurred while generating your backup codes" : "Помилка під час створення резервних кодів",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Створено резервні коди. Ви вже використали {used} із {total} кодів.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Це резервні коди. Будь ласка, збережіть їх та/або надрукуйте, оскільки вони подалі будуть недоступні.",
+ "Save backup codes" : "Зберегти резервні коди",
+ "Print backup codes" : "Друк резервних кодів",
+ "Regenerate backup codes" : "Перестворити резервні коди",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Після повторного створення резервних кодів попередні автоматично стануть недійсними",
+ "{name} backup codes" : "Резервні коди {name}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Скористайтеся одним з резервних кодів, які ви зберегли під час встановлення двофакторної авторизації.",
+ "Submit" : "Гаразд"
+},
+"nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);");
diff --git a/apps/twofactor_backupcodes/l10n/uk.json b/apps/twofactor_backupcodes/l10n/uk.json
new file mode 100644
index 00000000000..0a05102a3b4
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/uk.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "Ви створили резервні коди для двофакторної авторизації у вашому обліковому записі",
+ "Second-factor backup codes" : "Резервні коди другого фактору",
+ "Generate backup codes" : "Створити резервні коди",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "Ви увімкнули двофакторну авторизацію, але поки не створили резервні коди. Резервні коди потрібні для відновлення доступу до вашого облікового запису, якщо буде втрачено доступ до другого фактору.",
+ "Backup code" : "Резервні коди",
+ "Use backup code" : "Використати резервний код",
+ "Two factor backup codes" : "Резервні коди двофакторної авторизації",
+ "A two-factor auth backup codes provider" : "Постачальник резервних кодів двофакторної авторизації",
+ "An error occurred while generating your backup codes" : "Помилка під час створення резервних кодів",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "Створено резервні коди. Ви вже використали {used} із {total} кодів.",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "Це резервні коди. Будь ласка, збережіть їх та/або надрукуйте, оскільки вони подалі будуть недоступні.",
+ "Save backup codes" : "Зберегти резервні коди",
+ "Print backup codes" : "Друк резервних кодів",
+ "Regenerate backup codes" : "Перестворити резервні коди",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "Після повторного створення резервних кодів попередні автоматично стануть недійсними",
+ "{name} backup codes" : "Резервні коди {name}",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "Скористайтеся одним з резервних кодів, які ви зберегли під час встановлення двофакторної авторизації.",
+ "Submit" : "Гаразд"
+},"pluralForm" :"nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/zh_CN.js b/apps/twofactor_backupcodes/l10n/zh_CN.js
new file mode 100644
index 00000000000..34a772fd64c
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/zh_CN.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "您已经为账号创建了两步验证的备用码",
+ "Second-factor backup codes" : "两步验证备用码",
+ "Generate backup codes" : "生成备用码",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "您已启用两步验证但还没有生成备用码。当您丢失您的第二因素时,备用码能帮助您恢复对您账号的访问。",
+ "Backup code" : "备用码",
+ "Use backup code" : "使用备用码",
+ "Two factor backup codes" : "两步验证备用码",
+ "A two-factor auth backup codes provider" : "一个两步验证备用码提供者",
+ "An error occurred while generating your backup codes" : "生成备用码时出错",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "备用码已生成。备用码 {total} 条中的 {used} 条已被使用。",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "下列是您的备用码。备用码无法重复查看,请将其保存或打印存储。",
+ "Save backup codes" : "保存备用码",
+ "Print backup codes" : "打印备用码",
+ "Regenerate backup codes" : "重新生成备用码",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "如果您重新生成了备用码,旧的代码将自动失效。",
+ "{name} backup codes" : "{name} 备用码",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "在设置两步验证时使用您保存的其中一个备用码",
+ "Submit" : "提交"
+},
+"nplurals=1; plural=0;");
diff --git a/apps/twofactor_backupcodes/l10n/zh_CN.json b/apps/twofactor_backupcodes/l10n/zh_CN.json
new file mode 100644
index 00000000000..d08d943029e
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/zh_CN.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "您已经为账号创建了两步验证的备用码",
+ "Second-factor backup codes" : "两步验证备用码",
+ "Generate backup codes" : "生成备用码",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "您已启用两步验证但还没有生成备用码。当您丢失您的第二因素时,备用码能帮助您恢复对您账号的访问。",
+ "Backup code" : "备用码",
+ "Use backup code" : "使用备用码",
+ "Two factor backup codes" : "两步验证备用码",
+ "A two-factor auth backup codes provider" : "一个两步验证备用码提供者",
+ "An error occurred while generating your backup codes" : "生成备用码时出错",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "备用码已生成。备用码 {total} 条中的 {used} 条已被使用。",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "下列是您的备用码。备用码无法重复查看,请将其保存或打印存储。",
+ "Save backup codes" : "保存备用码",
+ "Print backup codes" : "打印备用码",
+ "Regenerate backup codes" : "重新生成备用码",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "如果您重新生成了备用码,旧的代码将自动失效。",
+ "{name} backup codes" : "{name} 备用码",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "在设置两步验证时使用您保存的其中一个备用码",
+ "Submit" : "提交"
+},"pluralForm" :"nplurals=1; plural=0;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/zh_HK.js b/apps/twofactor_backupcodes/l10n/zh_HK.js
new file mode 100644
index 00000000000..c9de2b58d3b
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/zh_HK.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "你的帳戶已建立雙重認證的備用碼。",
+ "Second-factor backup codes" : "第二階段備用驗證碼",
+ "Generate backup codes" : "產生備用驗證碼",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "你已經啟用了雙重認證但並未産生雙重認證備用碼。若你遺失了你的第二驗證因數,你會需要雙重認證備用碼來復原你帳戶的存取權。",
+ "Backup code" : "備用驗證碼",
+ "Use backup code" : "使用備用驗證碼",
+ "Two factor backup codes" : "雙重備用驗證碼",
+ "A two-factor auth backup codes provider" : "雙重認證備用驗證碼提供者",
+ "An error occurred while generating your backup codes" : "產生備用碼時發生錯誤。",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "備用碼已經建立,共{total}組備用碼中有{used}組已經使用",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "以下是您的備用碼,由於備用碼不會再次顯示,請儲存 並/或 列印。",
+ "Save backup codes" : "儲存備用碼",
+ "Print backup codes" : "列印備用碼",
+ "Regenerate backup codes" : "重新產生備用碼",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "若您重新產生備用碼,原來舊的備用碼將自動失效。",
+ "{name} backup codes" : "{name} 備用驗證碼",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "設定啟用雙重認證時,可輸入其中一個您已儲存的備用碼。",
+ "Submit" : "遞交"
+},
+"nplurals=1; plural=0;");
diff --git a/apps/twofactor_backupcodes/l10n/zh_HK.json b/apps/twofactor_backupcodes/l10n/zh_HK.json
new file mode 100644
index 00000000000..416a88eed9e
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/zh_HK.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "你的帳戶已建立雙重認證的備用碼。",
+ "Second-factor backup codes" : "第二階段備用驗證碼",
+ "Generate backup codes" : "產生備用驗證碼",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "你已經啟用了雙重認證但並未産生雙重認證備用碼。若你遺失了你的第二驗證因數,你會需要雙重認證備用碼來復原你帳戶的存取權。",
+ "Backup code" : "備用驗證碼",
+ "Use backup code" : "使用備用驗證碼",
+ "Two factor backup codes" : "雙重備用驗證碼",
+ "A two-factor auth backup codes provider" : "雙重認證備用驗證碼提供者",
+ "An error occurred while generating your backup codes" : "產生備用碼時發生錯誤。",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "備用碼已經建立,共{total}組備用碼中有{used}組已經使用",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "以下是您的備用碼,由於備用碼不會再次顯示,請儲存 並/或 列印。",
+ "Save backup codes" : "儲存備用碼",
+ "Print backup codes" : "列印備用碼",
+ "Regenerate backup codes" : "重新產生備用碼",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "若您重新產生備用碼,原來舊的備用碼將自動失效。",
+ "{name} backup codes" : "{name} 備用驗證碼",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "設定啟用雙重認證時,可輸入其中一個您已儲存的備用碼。",
+ "Submit" : "遞交"
+},"pluralForm" :"nplurals=1; plural=0;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/zh_TW.js b/apps/twofactor_backupcodes/l10n/zh_TW.js
new file mode 100644
index 00000000000..2c2ae1710a6
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/zh_TW.js
@@ -0,0 +1,23 @@
+OC.L10N.register(
+ "twofactor_backupcodes",
+ {
+ "You created two-factor backup codes for your account" : "您已建立您帳號的雙因子認證的備用碼",
+ "Second-factor backup codes" : "雙因子認證備用碼",
+ "Generate backup codes" : "產生備用碼",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "您已啟用雙因子認證,但尚未產生備用碼。如果您失去第二因素的認證方式,則必須使用備用碼來恢復對您帳號的存取權。",
+ "Backup code" : "備用碼",
+ "Use backup code" : "使用備用碼",
+ "Two factor backup codes" : "雙因子認證備用碼",
+ "A two-factor auth backup codes provider" : "雙因子認證備用碼提供者",
+ "An error occurred while generating your backup codes" : "產生備用碼時發生錯誤",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "備用碼已產生。共 {total} 組備用碼,有 {used} 組已使用。",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "以下是您的備用碼。由於備用碼不會再次顯示,請儲存及/或列印。",
+ "Save backup codes" : "儲存備用碼",
+ "Print backup codes" : "列印備用碼",
+ "Regenerate backup codes" : "重新產生備用碼",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "若您重新產生備用碼,原來舊的備用碼將自動失效。",
+ "{name} backup codes" : "{name} 備用碼",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "設定啟用雙因子認證時,可輸入其中一組您已儲存的備用碼。",
+ "Submit" : "提交"
+},
+"nplurals=1; plural=0;");
diff --git a/apps/twofactor_backupcodes/l10n/zh_TW.json b/apps/twofactor_backupcodes/l10n/zh_TW.json
new file mode 100644
index 00000000000..23d922a1cca
--- /dev/null
+++ b/apps/twofactor_backupcodes/l10n/zh_TW.json
@@ -0,0 +1,21 @@
+{ "translations": {
+ "You created two-factor backup codes for your account" : "您已建立您帳號的雙因子認證的備用碼",
+ "Second-factor backup codes" : "雙因子認證備用碼",
+ "Generate backup codes" : "產生備用碼",
+ "You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor." : "您已啟用雙因子認證,但尚未產生備用碼。如果您失去第二因素的認證方式,則必須使用備用碼來恢復對您帳號的存取權。",
+ "Backup code" : "備用碼",
+ "Use backup code" : "使用備用碼",
+ "Two factor backup codes" : "雙因子認證備用碼",
+ "A two-factor auth backup codes provider" : "雙因子認證備用碼提供者",
+ "An error occurred while generating your backup codes" : "產生備用碼時發生錯誤",
+ "Backup codes have been generated. {used} of {total} codes have been used." : "備用碼已產生。共 {total} 組備用碼,有 {used} 組已使用。",
+ "These are your backup codes. Please save and/or print them as you will not be able to read the codes again later." : "以下是您的備用碼。由於備用碼不會再次顯示,請儲存及/或列印。",
+ "Save backup codes" : "儲存備用碼",
+ "Print backup codes" : "列印備用碼",
+ "Regenerate backup codes" : "重新產生備用碼",
+ "If you regenerate backup codes, you automatically invalidate old codes." : "若您重新產生備用碼,原來舊的備用碼將自動失效。",
+ "{name} backup codes" : "{name} 備用碼",
+ "Use one of the backup codes you saved when setting up two-factor authentication." : "設定啟用雙因子認證時,可輸入其中一組您已儲存的備用碼。",
+ "Submit" : "提交"
+},"pluralForm" :"nplurals=1; plural=0;"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/lib/Activity/Provider.php b/apps/twofactor_backupcodes/lib/Activity/Provider.php
new file mode 100644
index 00000000000..eba38147bd7
--- /dev/null
+++ b/apps/twofactor_backupcodes/lib/Activity/Provider.php
@@ -0,0 +1,54 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Activity;
+
+use OCP\Activity\Exceptions\UnknownActivityException;
+use OCP\Activity\IEvent;
+use OCP\Activity\IManager;
+use OCP\Activity\IProvider;
+use OCP\IURLGenerator;
+use OCP\L10N\IFactory as L10nFactory;
+
+class Provider implements IProvider {
+
+ /**
+ * @param L10nFactory $l10n
+ * @param IURLGenerator $urlGenerator
+ * @param IManager $activityManager
+ */
+ public function __construct(
+ private L10nFactory $l10n,
+ private IURLGenerator $urlGenerator,
+ private IManager $activityManager,
+ ) {
+ }
+
+ public function parse($language, IEvent $event, ?IEvent $previousEvent = null): IEvent {
+ if ($event->getApp() !== 'twofactor_backupcodes') {
+ throw new UnknownActivityException();
+ }
+
+ $l = $this->l10n->get('twofactor_backupcodes', $language);
+
+ switch ($event->getSubject()) {
+ case 'codes_generated':
+ $event->setParsedSubject($l->t('You created two-factor backup codes for your account'));
+
+ if ($this->activityManager->getRequirePNG()) {
+ $event->setIcon($this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'actions/password.png')));
+ } else {
+ $event->setIcon($this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'actions/password.svg')));
+ }
+ break;
+ default:
+ throw new UnknownActivityException();
+ }
+ return $event;
+ }
+}
diff --git a/apps/twofactor_backupcodes/lib/AppInfo/Application.php b/apps/twofactor_backupcodes/lib/AppInfo/Application.php
new file mode 100644
index 00000000000..e9a1ec1c72c
--- /dev/null
+++ b/apps/twofactor_backupcodes/lib/AppInfo/Application.php
@@ -0,0 +1,51 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\AppInfo;
+
+use OCA\TwoFactorBackupCodes\Event\CodesGenerated;
+use OCA\TwoFactorBackupCodes\Listener\ActivityPublisher;
+use OCA\TwoFactorBackupCodes\Listener\ClearNotifications;
+use OCA\TwoFactorBackupCodes\Listener\ProviderDisabled;
+use OCA\TwoFactorBackupCodes\Listener\ProviderEnabled;
+use OCA\TwoFactorBackupCodes\Listener\RegistryUpdater;
+use OCA\TwoFactorBackupCodes\Listener\UserDeleted;
+use OCA\TwoFactorBackupCodes\Notifications\Notifier;
+use OCA\TwoFactorBackupCodes\Provider\BackupCodesProvider;
+use OCP\AppFramework\App;
+use OCP\AppFramework\Bootstrap\IBootContext;
+use OCP\AppFramework\Bootstrap\IBootstrap;
+use OCP\AppFramework\Bootstrap\IRegistrationContext;
+use OCP\Authentication\TwoFactorAuth\TwoFactorProviderForUserRegistered;
+use OCP\Authentication\TwoFactorAuth\TwoFactorProviderForUserUnregistered;
+use OCP\User\Events\UserDeletedEvent;
+
+class Application extends App implements IBootstrap {
+ public const APP_ID = 'twofactor_backupcodes';
+
+ public function __construct() {
+ parent::__construct(self::APP_ID);
+ }
+
+ public function register(IRegistrationContext $context): void {
+ $context->registerNotifierService(Notifier::class);
+
+ $context->registerEventListener(CodesGenerated::class, ActivityPublisher::class);
+ $context->registerEventListener(CodesGenerated::class, RegistryUpdater::class);
+ $context->registerEventListener(CodesGenerated::class, ClearNotifications::class);
+ $context->registerEventListener(TwoFactorProviderForUserRegistered::class, ProviderEnabled::class);
+ $context->registerEventListener(TwoFactorProviderForUserUnregistered::class, ProviderDisabled::class);
+ $context->registerEventListener(UserDeletedEvent::class, UserDeleted::class);
+
+
+ $context->registerTwoFactorProvider(BackupCodesProvider::class);
+ }
+
+ public function boot(IBootContext $context): void {
+ }
+}
diff --git a/apps/twofactor_backupcodes/lib/BackgroundJob/CheckBackupCodes.php b/apps/twofactor_backupcodes/lib/BackgroundJob/CheckBackupCodes.php
new file mode 100644
index 00000000000..bc26cb260f4
--- /dev/null
+++ b/apps/twofactor_backupcodes/lib/BackgroundJob/CheckBackupCodes.php
@@ -0,0 +1,49 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\BackgroundJob;
+
+use OC\Authentication\TwoFactorAuth\Manager;
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\Authentication\TwoFactorAuth\IRegistry;
+use OCP\BackgroundJob\IJobList;
+use OCP\BackgroundJob\QueuedJob;
+use OCP\IUser;
+use OCP\IUserManager;
+
+class CheckBackupCodes extends QueuedJob {
+
+ /** @var Manager */
+ private $twofactorManager;
+
+ public function __construct(
+ ITimeFactory $timeFactory,
+ private IUserManager $userManager,
+ private IJobList $jobList,
+ Manager $twofactorManager,
+ private IRegistry $registry,
+ ) {
+ parent::__construct($timeFactory);
+ $this->twofactorManager = $twofactorManager;
+ }
+
+ protected function run($argument) {
+ $this->userManager->callForSeenUsers(function (IUser $user): void {
+ if (!$user->isEnabled()) {
+ return;
+ }
+
+ $providers = $this->registry->getProviderStates($user);
+ $isTwoFactorAuthenticated = $this->twofactorManager->isTwoFactorAuthenticated($user);
+
+ if ($isTwoFactorAuthenticated && isset($providers['backup_codes']) && $providers['backup_codes'] === false) {
+ $this->jobList->add(RememberBackupCodesJob::class, ['uid' => $user->getUID()]);
+ }
+ });
+ }
+}
diff --git a/apps/twofactor_backupcodes/lib/BackgroundJob/RememberBackupCodesJob.php b/apps/twofactor_backupcodes/lib/BackgroundJob/RememberBackupCodesJob.php
new file mode 100644
index 00000000000..5e853479f0a
--- /dev/null
+++ b/apps/twofactor_backupcodes/lib/BackgroundJob/RememberBackupCodesJob.php
@@ -0,0 +1,77 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\BackgroundJob;
+
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\Authentication\TwoFactorAuth\IRegistry;
+use OCP\BackgroundJob\IJobList;
+use OCP\BackgroundJob\TimedJob;
+use OCP\IUserManager;
+use OCP\Notification\IManager;
+
+class RememberBackupCodesJob extends TimedJob {
+
+ public function __construct(
+ private IRegistry $registry,
+ private IUserManager $userManager,
+ ITimeFactory $timeFactory,
+ private IManager $notificationManager,
+ private IJobList $jobList,
+ ) {
+ parent::__construct($timeFactory);
+ $this->time = $timeFactory;
+
+ $this->setInterval(60 * 60 * 24 * 14);
+ $this->setTimeSensitivity(self::TIME_INSENSITIVE);
+ }
+
+ protected function run($argument) {
+ $uid = $argument['uid'];
+ $user = $this->userManager->get($uid);
+
+ if ($user === null) {
+ // We can't run with an invalid user
+ $this->jobList->remove(self::class, $argument);
+ return;
+ }
+
+ $providers = $this->registry->getProviderStates($user);
+ $state2fa = array_reduce($providers, function (bool $carry, bool $state) {
+ return $carry || $state;
+ }, false);
+
+ /*
+ * If no provider is active or if the backup codes are already generate
+ * we can remove the job
+ */
+ if ($state2fa === false || (isset($providers['backup_codes']) && $providers['backup_codes'] === true)) {
+ // Backup codes already generated lets remove this job
+ $this->jobList->remove(self::class, $argument);
+ return;
+ }
+
+ $date = new \DateTime();
+ $date->setTimestamp($this->time->getTime());
+
+ $notification = $this->notificationManager->createNotification();
+ $notification->setApp('twofactor_backupcodes')
+ ->setUser($user->getUID())
+ ->setObject('create', 'codes')
+ ->setSubject('create_backupcodes');
+ $this->notificationManager->markProcessed($notification);
+
+ if (!$user->isEnabled()) {
+ // Don't recreate a notification for a user that can not read it
+ $this->jobList->remove(self::class, $argument);
+ return;
+ }
+ $notification->setDateTime($date);
+ $this->notificationManager->notify($notification);
+ }
+}
diff --git a/apps/twofactor_backupcodes/lib/Controller/SettingsController.php b/apps/twofactor_backupcodes/lib/Controller/SettingsController.php
new file mode 100644
index 00000000000..effc058e05c
--- /dev/null
+++ b/apps/twofactor_backupcodes/lib/Controller/SettingsController.php
@@ -0,0 +1,49 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Controller;
+
+use OCA\TwoFactorBackupCodes\Service\BackupCodeStorage;
+use OCP\AppFramework\Controller;
+use OCP\AppFramework\Http\Attribute\NoAdminRequired;
+use OCP\AppFramework\Http\Attribute\PasswordConfirmationRequired;
+use OCP\AppFramework\Http\JSONResponse;
+use OCP\IRequest;
+use OCP\IUserSession;
+
+class SettingsController extends Controller {
+
+ /**
+ * @param string $appName
+ * @param IRequest $request
+ * @param BackupCodeStorage $storage
+ * @param IUserSession $userSession
+ */
+ public function __construct(
+ $appName,
+ IRequest $request,
+ private BackupCodeStorage $storage,
+ private IUserSession $userSession,
+ ) {
+ parent::__construct($appName, $request);
+ }
+
+ /**
+ * @return JSONResponse
+ */
+ #[NoAdminRequired]
+ #[PasswordConfirmationRequired]
+ public function createCodes(): JSONResponse {
+ $user = $this->userSession->getUser();
+ $codes = $this->storage->createCodes($user);
+ return new JSONResponse([
+ 'codes' => $codes,
+ 'state' => $this->storage->getBackupCodesState($user),
+ ]);
+ }
+}
diff --git a/apps/twofactor_backupcodes/lib/Db/BackupCode.php b/apps/twofactor_backupcodes/lib/Db/BackupCode.php
new file mode 100644
index 00000000000..252b9b77faa
--- /dev/null
+++ b/apps/twofactor_backupcodes/lib/Db/BackupCode.php
@@ -0,0 +1,31 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Db;
+
+use OCP\AppFramework\Db\Entity;
+
+/**
+ * @method string getUserId()
+ * @method void setUserId(string $userId)
+ * @method string getCode()
+ * @method void setCode(string $code)
+ * @method int getUsed()
+ * @method void setUsed(int $code)
+ */
+class BackupCode extends Entity {
+
+ /** @var string */
+ protected $userId;
+
+ /** @var string */
+ protected $code;
+
+ /** @var int */
+ protected $used;
+}
diff --git a/apps/twofactor_backupcodes/lib/Db/BackupCodeMapper.php b/apps/twofactor_backupcodes/lib/Db/BackupCodeMapper.php
new file mode 100644
index 00000000000..fbbc3d0403c
--- /dev/null
+++ b/apps/twofactor_backupcodes/lib/Db/BackupCodeMapper.php
@@ -0,0 +1,57 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Db;
+
+use OCP\AppFramework\Db\QBMapper;
+use OCP\DB\QueryBuilder\IQueryBuilder;
+use OCP\IDBConnection;
+use OCP\IUser;
+
+/**
+ * @template-extends QBMapper<BackupCode>
+ */
+class BackupCodeMapper extends QBMapper {
+ public function __construct(IDBConnection $db) {
+ parent::__construct($db, 'twofactor_backupcodes');
+ }
+
+ /**
+ * @param IUser $user
+ * @return BackupCode[]
+ */
+ public function getBackupCodes(IUser $user): array {
+ /* @var IQueryBuilder $qb */
+ $qb = $this->db->getQueryBuilder();
+
+ $qb->select('id', 'user_id', 'code', 'used')
+ ->from('twofactor_backupcodes')
+ ->where($qb->expr()->eq('user_id', $qb->createNamedParameter($user->getUID())));
+
+ return self::findEntities($qb);
+ }
+
+ /**
+ * @param IUser $user
+ */
+ public function deleteCodes(IUser $user): void {
+ $this->deleteCodesByUserId($user->getUID());
+ }
+
+ /**
+ * @param string $uid
+ */
+ public function deleteCodesByUserId(string $uid): void {
+ /* @var IQueryBuilder $qb */
+ $qb = $this->db->getQueryBuilder();
+
+ $qb->delete('twofactor_backupcodes')
+ ->where($qb->expr()->eq('user_id', $qb->createNamedParameter($uid)));
+ $qb->execute();
+ }
+}
diff --git a/apps/twofactor_backupcodes/lib/Event/CodesGenerated.php b/apps/twofactor_backupcodes/lib/Event/CodesGenerated.php
new file mode 100644
index 00000000000..90dc6206f71
--- /dev/null
+++ b/apps/twofactor_backupcodes/lib/Event/CodesGenerated.php
@@ -0,0 +1,28 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Event;
+
+use OCP\EventDispatcher\Event;
+use OCP\IUser;
+
+class CodesGenerated extends Event {
+
+ public function __construct(
+ private IUser $user,
+ ) {
+ parent::__construct();
+ }
+
+ /**
+ * @return IUser
+ */
+ public function getUser(): IUser {
+ return $this->user;
+ }
+}
diff --git a/apps/twofactor_backupcodes/lib/Listener/ActivityPublisher.php b/apps/twofactor_backupcodes/lib/Listener/ActivityPublisher.php
new file mode 100644
index 00000000000..b52f1f2c098
--- /dev/null
+++ b/apps/twofactor_backupcodes/lib/Listener/ActivityPublisher.php
@@ -0,0 +1,44 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Listener;
+
+use BadMethodCallException;
+use OCA\TwoFactorBackupCodes\Event\CodesGenerated;
+use OCP\Activity\IManager;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use Psr\Log\LoggerInterface;
+
+/** @template-implements IEventListener<CodesGenerated> */
+class ActivityPublisher implements IEventListener {
+ public function __construct(
+ private IManager $activityManager,
+ private LoggerInterface $logger,
+ ) {
+ }
+
+ /**
+ * Push an event to the user's activity stream
+ */
+ public function handle(Event $event): void {
+ if ($event instanceof CodesGenerated) {
+ $activity = $this->activityManager->generateEvent();
+ $activity->setApp('twofactor_backupcodes')
+ ->setType('security')
+ ->setAuthor($event->getUser()->getUID())
+ ->setAffectedUser($event->getUser()->getUID())
+ ->setSubject('codes_generated');
+ try {
+ $this->activityManager->publish($activity);
+ } catch (BadMethodCallException $e) {
+ $this->logger->error('Could not publish backup code creation activity', ['exception' => $e]);
+ }
+ }
+ }
+}
diff --git a/apps/twofactor_backupcodes/lib/Listener/ClearNotifications.php b/apps/twofactor_backupcodes/lib/Listener/ClearNotifications.php
new file mode 100644
index 00000000000..46bb1583004
--- /dev/null
+++ b/apps/twofactor_backupcodes/lib/Listener/ClearNotifications.php
@@ -0,0 +1,35 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Listener;
+
+use OCA\TwoFactorBackupCodes\Event\CodesGenerated;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\Notification\IManager;
+
+/** @template-implements IEventListener<CodesGenerated> */
+class ClearNotifications implements IEventListener {
+
+ public function __construct(
+ private IManager $manager,
+ ) {
+ }
+
+ public function handle(Event $event): void {
+ if (!($event instanceof CodesGenerated)) {
+ return;
+ }
+
+ $notification = $this->manager->createNotification();
+ $notification->setApp('twofactor_backupcodes')
+ ->setUser($event->getUser()->getUID())
+ ->setObject('create', 'codes');
+ $this->manager->markProcessed($notification);
+ }
+}
diff --git a/apps/twofactor_backupcodes/lib/Listener/ProviderDisabled.php b/apps/twofactor_backupcodes/lib/Listener/ProviderDisabled.php
new file mode 100644
index 00000000000..a8d51e55c1b
--- /dev/null
+++ b/apps/twofactor_backupcodes/lib/Listener/ProviderDisabled.php
@@ -0,0 +1,43 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Listener;
+
+use OCA\TwoFactorBackupCodes\BackgroundJob\RememberBackupCodesJob;
+use OCP\Authentication\TwoFactorAuth\IRegistry;
+use OCP\Authentication\TwoFactorAuth\TwoFactorProviderForUserUnregistered;
+use OCP\BackgroundJob\IJobList;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+
+/** @template-implements IEventListener<TwoFactorProviderForUserUnregistered> */
+class ProviderDisabled implements IEventListener {
+
+ public function __construct(
+ private IRegistry $registry,
+ private IJobList $jobList,
+ ) {
+ }
+
+ public function handle(Event $event): void {
+ if (!($event instanceof TwoFactorProviderForUserUnregistered)) {
+ return;
+ }
+
+ $providers = $this->registry->getProviderStates($event->getUser());
+
+ // Loop over all providers. If all are disabled we remove the job
+ $state = array_reduce($providers, function (bool $carry, bool $enabled) {
+ return $carry || $enabled;
+ }, false);
+
+ if ($state === false) {
+ $this->jobList->remove(RememberBackupCodesJob::class, ['uid' => $event->getUser()->getUID()]);
+ }
+ }
+}
diff --git a/apps/twofactor_backupcodes/lib/Listener/ProviderEnabled.php b/apps/twofactor_backupcodes/lib/Listener/ProviderEnabled.php
new file mode 100644
index 00000000000..4ec510e7194
--- /dev/null
+++ b/apps/twofactor_backupcodes/lib/Listener/ProviderEnabled.php
@@ -0,0 +1,40 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Listener;
+
+use OCA\TwoFactorBackupCodes\BackgroundJob\RememberBackupCodesJob;
+use OCP\Authentication\TwoFactorAuth\IRegistry;
+use OCP\Authentication\TwoFactorAuth\TwoFactorProviderForUserRegistered;
+use OCP\BackgroundJob\IJobList;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+
+/** @template-implements IEventListener<TwoFactorProviderForUserRegistered> */
+class ProviderEnabled implements IEventListener {
+
+ public function __construct(
+ private IRegistry $registry,
+ private IJobList $jobList,
+ ) {
+ }
+
+ public function handle(Event $event): void {
+ if (!($event instanceof TwoFactorProviderForUserRegistered)) {
+ return;
+ }
+
+ $providers = $this->registry->getProviderStates($event->getUser());
+ if (isset($providers['backup_codes']) && $providers['backup_codes'] === true) {
+ // Backup codes already generated nothing to do here
+ return;
+ }
+
+ $this->jobList->add(RememberBackupCodesJob::class, ['uid' => $event->getUser()->getUID()]);
+ }
+}
diff --git a/apps/twofactor_backupcodes/lib/Listener/RegistryUpdater.php b/apps/twofactor_backupcodes/lib/Listener/RegistryUpdater.php
new file mode 100644
index 00000000000..1cb07bd9805
--- /dev/null
+++ b/apps/twofactor_backupcodes/lib/Listener/RegistryUpdater.php
@@ -0,0 +1,31 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Listener;
+
+use OCA\TwoFactorBackupCodes\Event\CodesGenerated;
+use OCA\TwoFactorBackupCodes\Provider\BackupCodesProvider;
+use OCP\Authentication\TwoFactorAuth\IRegistry;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+
+/** @template-implements IEventListener<CodesGenerated> */
+class RegistryUpdater implements IEventListener {
+
+ public function __construct(
+ private IRegistry $registry,
+ private BackupCodesProvider $provider,
+ ) {
+ }
+
+ public function handle(Event $event): void {
+ if ($event instanceof CodesGenerated) {
+ $this->registry->enableProviderFor($this->provider, $event->getUser());
+ }
+ }
+}
diff --git a/apps/twofactor_backupcodes/lib/Listener/UserDeleted.php b/apps/twofactor_backupcodes/lib/Listener/UserDeleted.php
new file mode 100644
index 00000000000..72fd504b338
--- /dev/null
+++ b/apps/twofactor_backupcodes/lib/Listener/UserDeleted.php
@@ -0,0 +1,31 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Listener;
+
+use OCA\TwoFactorBackupCodes\Db\BackupCodeMapper;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\User\Events\UserDeletedEvent;
+
+/** @template-implements IEventListener<UserDeletedEvent> */
+class UserDeleted implements IEventListener {
+
+ public function __construct(
+ private BackupCodeMapper $backupCodeMapper,
+ ) {
+ }
+
+ public function handle(Event $event): void {
+ if (!($event instanceof UserDeletedEvent)) {
+ return;
+ }
+
+ $this->backupCodeMapper->deleteCodes($event->getUser());
+ }
+}
diff --git a/apps/twofactor_backupcodes/lib/Migration/CheckBackupCodes.php b/apps/twofactor_backupcodes/lib/Migration/CheckBackupCodes.php
new file mode 100644
index 00000000000..9c0c676134b
--- /dev/null
+++ b/apps/twofactor_backupcodes/lib/Migration/CheckBackupCodes.php
@@ -0,0 +1,29 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Migration;
+
+use OCP\BackgroundJob\IJobList;
+use OCP\Migration\IOutput;
+use OCP\Migration\IRepairStep;
+
+class CheckBackupCodes implements IRepairStep {
+
+ public function __construct(
+ private IJobList $jobList,
+ ) {
+ }
+
+ public function getName(): string {
+ return 'Add background job to check for backup codes';
+ }
+
+ public function run(IOutput $output) {
+ $this->jobList->add(\OCA\TwoFactorBackupCodes\BackgroundJob\CheckBackupCodes::class);
+ }
+}
diff --git a/apps/twofactor_backupcodes/lib/Migration/Version1002Date20170607104347.php b/apps/twofactor_backupcodes/lib/Migration/Version1002Date20170607104347.php
new file mode 100644
index 00000000000..ce752541bac
--- /dev/null
+++ b/apps/twofactor_backupcodes/lib/Migration/Version1002Date20170607104347.php
@@ -0,0 +1,56 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Migration;
+
+use Doctrine\DBAL\Types\Types;
+use OCP\DB\ISchemaWrapper;
+use OCP\Migration\IOutput;
+use OCP\Migration\SimpleMigrationStep;
+
+class Version1002Date20170607104347 extends SimpleMigrationStep {
+ /**
+ * @param IOutput $output
+ * @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
+ * @param array $options
+ * @return null|ISchemaWrapper
+ * @since 13.0.0
+ */
+ public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) {
+ /** @var ISchemaWrapper $schema */
+ $schema = $schemaClosure();
+
+ if (!$schema->hasTable('twofactor_backupcodes')) {
+ $table = $schema->createTable('twofactor_backupcodes');
+
+ $table->addColumn('id', Types::INTEGER, [
+ 'autoincrement' => true,
+ 'notnull' => true,
+ 'length' => 20,
+ ]);
+ $table->addColumn('user_id', Types::STRING, [
+ 'notnull' => true,
+ 'length' => 64,
+ ]);
+ $table->addColumn('code', Types::STRING, [
+ 'notnull' => true,
+ 'length' => 64,
+ ]);
+ $table->addColumn('used', Types::INTEGER, [
+ 'notnull' => true,
+ 'length' => 1,
+ 'default' => 0,
+ ]);
+
+ $table->setPrimaryKey(['id']);
+ $table->addIndex(['user_id'], 'twofactor_backupcodes_uid');
+ }
+
+ return $schema;
+ }
+}
diff --git a/apps/twofactor_backupcodes/lib/Migration/Version1002Date20170607113030.php b/apps/twofactor_backupcodes/lib/Migration/Version1002Date20170607113030.php
new file mode 100644
index 00000000000..bed733cd413
--- /dev/null
+++ b/apps/twofactor_backupcodes/lib/Migration/Version1002Date20170607113030.php
@@ -0,0 +1,88 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Migration;
+
+use OCP\DB\ISchemaWrapper;
+use OCP\DB\QueryBuilder\IQueryBuilder;
+use OCP\IDBConnection;
+use OCP\Migration\IOutput;
+use OCP\Migration\SimpleMigrationStep;
+
+class Version1002Date20170607113030 extends SimpleMigrationStep {
+
+ /**
+ * @param IDBConnection $connection
+ */
+ public function __construct(
+ protected IDBConnection $connection,
+ ) {
+ }
+
+ /**
+ * @param IOutput $output
+ * @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
+ * @param array $options
+ * @since 13.0.0
+ */
+ public function preSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) {
+ /** @var ISchemaWrapper $schema */
+ $schema = $schemaClosure();
+
+ if (!$schema->hasTable('twofactor_backup_codes')) {
+ // Legacy table does not exist
+ return;
+ }
+
+ $insert = $this->connection->getQueryBuilder();
+ $insert->insert('twofactor_backupcodes')
+ ->values([
+ // Inserting with id might fail: 'id' => $insert->createParameter('id'),
+ 'user_id' => $insert->createParameter('user_id'),
+ 'code' => $insert->createParameter('code'),
+ 'used' => $insert->createParameter('used'),
+ ]);
+
+ $query = $this->connection->getQueryBuilder();
+ $query->select('*')
+ ->from('twofactor_backup_codes')
+ ->orderBy('id', 'ASC');
+ $result = $query->execute();
+
+ $output->startProgress();
+ while ($row = $result->fetch()) {
+ $output->advance();
+
+ $insert
+ // Inserting with id might fail: ->setParameter('id', $row['id'], IQueryBuilder::PARAM_INT)
+ ->setParameter('user_id', $row['user_id'], IQueryBuilder::PARAM_STR)
+ ->setParameter('code', $row['code'], IQueryBuilder::PARAM_STR)
+ ->setParameter('used', $row['used'], IQueryBuilder::PARAM_INT)
+ ->execute();
+ }
+ $output->finishProgress();
+ }
+
+ /**
+ * @param IOutput $output
+ * @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
+ * @param array $options
+ * @return null|ISchemaWrapper
+ * @since 13.0.0
+ */
+ public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) {
+ /** @var ISchemaWrapper $schema */
+ $schema = $schemaClosure();
+
+ if ($schema->hasTable('twofactor_backup_codes')) {
+ $schema->dropTable('twofactor_backup_codes');
+ return $schema;
+ }
+ return null;
+ }
+}
diff --git a/apps/twofactor_backupcodes/lib/Migration/Version1002Date20170919123342.php b/apps/twofactor_backupcodes/lib/Migration/Version1002Date20170919123342.php
new file mode 100644
index 00000000000..2ca390e6edd
--- /dev/null
+++ b/apps/twofactor_backupcodes/lib/Migration/Version1002Date20170919123342.php
@@ -0,0 +1,42 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Migration;
+
+use Doctrine\DBAL\Types\Type;
+use Doctrine\DBAL\Types\Types;
+use OCP\DB\ISchemaWrapper;
+use OCP\Migration\IOutput;
+use OCP\Migration\SimpleMigrationStep;
+
+class Version1002Date20170919123342 extends SimpleMigrationStep {
+
+ /**
+ * @param IOutput $output
+ * @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
+ * @param array $options
+ * @return null|ISchemaWrapper
+ * @since 13.0.0
+ */
+ public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) {
+ /** @var ISchemaWrapper $schema */
+ $schema = $schemaClosure();
+
+ $table = $schema->getTable('twofactor_backupcodes');
+ $column = $table->getColumn('user_id');
+ $column->setDefault('');
+
+ $column = $table->getColumn('used');
+ if ($column->getType()->getName() !== Types::SMALLINT) {
+ $column->setType(Type::getType(Types::SMALLINT));
+ $column->setOptions(['length' => 6]);
+ }
+
+ return $schema;
+ }
+}
diff --git a/apps/twofactor_backupcodes/lib/Migration/Version1002Date20170926101419.php b/apps/twofactor_backupcodes/lib/Migration/Version1002Date20170926101419.php
new file mode 100644
index 00000000000..d19fda49182
--- /dev/null
+++ b/apps/twofactor_backupcodes/lib/Migration/Version1002Date20170926101419.php
@@ -0,0 +1,28 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Migration;
+
+use OCP\Migration\BigIntMigration;
+
+/**
+ * Auto-generated migration step: Please modify to your needs!
+ */
+class Version1002Date20170926101419 extends BigIntMigration {
+
+ /**
+ * @return array Returns an array with the following structure
+ * ['table1' => ['column1', 'column2'], ...]
+ * @since 13.0.0
+ */
+ protected function getColumnsByTable() {
+ return [
+ 'twofactor_backupcodes' => ['id'],
+ ];
+ }
+}
diff --git a/apps/twofactor_backupcodes/lib/Migration/Version1002Date20180821043638.php b/apps/twofactor_backupcodes/lib/Migration/Version1002Date20180821043638.php
new file mode 100644
index 00000000000..04d6d58c783
--- /dev/null
+++ b/apps/twofactor_backupcodes/lib/Migration/Version1002Date20180821043638.php
@@ -0,0 +1,34 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Migration;
+
+use Closure;
+use OCP\DB\ISchemaWrapper;
+use OCP\Migration\IOutput;
+use OCP\Migration\SimpleMigrationStep;
+
+class Version1002Date20180821043638 extends SimpleMigrationStep {
+
+ /**
+ * @param IOutput $output
+ * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
+ * @param array $options
+ *
+ * @return ISchemaWrapper
+ */
+ public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
+ /** @var ISchemaWrapper $schema */
+ $schema = $schemaClosure();
+ $table = $schema->getTable('twofactor_backupcodes');
+
+ $table->getColumn('code')->setLength(128);
+
+ return $schema;
+ }
+}
diff --git a/apps/twofactor_backupcodes/lib/Notifications/Notifier.php b/apps/twofactor_backupcodes/lib/Notifications/Notifier.php
new file mode 100644
index 00000000000..e8144f52a56
--- /dev/null
+++ b/apps/twofactor_backupcodes/lib/Notifications/Notifier.php
@@ -0,0 +1,73 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Notifications;
+
+use OCP\IURLGenerator;
+use OCP\L10N\IFactory;
+use OCP\Notification\INotification;
+use OCP\Notification\INotifier;
+use OCP\Notification\UnknownNotificationException;
+
+class Notifier implements INotifier {
+
+ public function __construct(
+ private IFactory $factory,
+ private IURLGenerator $url,
+ ) {
+ }
+
+ /**
+ * Identifier of the notifier, only use [a-z0-9_]
+ *
+ * @return string
+ * @since 17.0.0
+ */
+ public function getID(): string {
+ return 'twofactor_backupcodes';
+ }
+
+ /**
+ * Human readable name describing the notifier
+ *
+ * @return string
+ * @since 17.0.0
+ */
+ public function getName(): string {
+ return $this->factory->get('twofactor_backupcodes')->t('Second-factor backup codes');
+ }
+
+ public function prepare(INotification $notification, string $languageCode): INotification {
+ if ($notification->getApp() !== 'twofactor_backupcodes') {
+ // Not my app => throw
+ throw new UnknownNotificationException();
+ }
+
+ // Read the language from the notification
+ $l = $this->factory->get('twofactor_backupcodes', $languageCode);
+
+ switch ($notification->getSubject()) {
+ case 'create_backupcodes':
+ $notification->setParsedSubject(
+ $l->t('Generate backup codes')
+ )->setParsedMessage(
+ $l->t('You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor.')
+ );
+
+ $notification->setLink($this->url->linkToRouteAbsolute('settings.PersonalSettings.index', ['section' => 'security']));
+
+ $notification->setIcon($this->url->getAbsoluteURL($this->url->imagePath('core', 'actions/password.svg')));
+
+ return $notification;
+
+ default:
+ // Unknown subject => Unknown notification => throw
+ throw new UnknownNotificationException();
+ }
+ }
+}
diff --git a/apps/twofactor_backupcodes/lib/Provider/BackupCodesProvider.php b/apps/twofactor_backupcodes/lib/Provider/BackupCodesProvider.php
new file mode 100644
index 00000000000..c521329e203
--- /dev/null
+++ b/apps/twofactor_backupcodes/lib/Provider/BackupCodesProvider.php
@@ -0,0 +1,130 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Provider;
+
+use OC\App\AppManager;
+use OCA\TwoFactorBackupCodes\Service\BackupCodeStorage;
+use OCA\TwoFactorBackupCodes\Settings\Personal;
+use OCP\AppFramework\Services\IInitialState;
+use OCP\Authentication\TwoFactorAuth\IDeactivatableByAdmin;
+use OCP\Authentication\TwoFactorAuth\IPersonalProviderSettings;
+use OCP\Authentication\TwoFactorAuth\IProvidesPersonalSettings;
+use OCP\IL10N;
+use OCP\IUser;
+use OCP\Template\ITemplate;
+use OCP\Template\ITemplateManager;
+
+class BackupCodesProvider implements IDeactivatableByAdmin, IProvidesPersonalSettings {
+ public function __construct(
+ private string $appName,
+ private BackupCodeStorage $storage,
+ private IL10N $l10n,
+ private AppManager $appManager,
+ private IInitialState $initialState,
+ private ITemplateManager $templateManager,
+ ) {
+ }
+
+ /**
+ * Get unique identifier of this 2FA provider
+ *
+ * @return string
+ */
+ public function getId(): string {
+ return 'backup_codes';
+ }
+
+ /**
+ * Get the display name for selecting the 2FA provider
+ *
+ * @return string
+ */
+ public function getDisplayName(): string {
+ return $this->l10n->t('Backup code');
+ }
+
+ /**
+ * Get the description for selecting the 2FA provider
+ *
+ * @return string
+ */
+ public function getDescription(): string {
+ return $this->l10n->t('Use backup code');
+ }
+
+ /**
+ * Get the template for rending the 2FA provider view
+ *
+ * @param IUser $user
+ * @return ITemplate
+ */
+ public function getTemplate(IUser $user): ITemplate {
+ return $this->templateManager->getTemplate('twofactor_backupcodes', 'challenge');
+ }
+
+ /**
+ * Verify the given challenge
+ *
+ * @param IUser $user
+ * @param string $challenge
+ * @return bool
+ */
+ public function verifyChallenge(IUser $user, string $challenge): bool {
+ return $this->storage->validateCode($user, $challenge);
+ }
+
+ /**
+ * Decides whether 2FA is enabled for the given user
+ *
+ * @param IUser $user
+ * @return boolean
+ */
+ public function isTwoFactorAuthEnabledForUser(IUser $user): bool {
+ return $this->storage->hasBackupCodes($user);
+ }
+
+ /**
+ * Determine whether backup codes should be active or not
+ *
+ * Backup codes only make sense if at least one 2FA provider is active,
+ * hence this method checks all enabled apps on whether they provide 2FA
+ * functionality or not. If there's at least one app, backup codes are
+ * enabled on the personal settings page.
+ *
+ * @param IUser $user
+ * @return boolean
+ */
+ public function isActive(IUser $user): bool {
+ $appIds = array_filter($this->appManager->getEnabledAppsForUser($user), function ($appId) {
+ return $appId !== $this->appName;
+ });
+ foreach ($appIds as $appId) {
+ $info = $this->appManager->getAppInfo($appId);
+ if (isset($info['two-factor-providers']) && count($info['two-factor-providers']) > 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @param IUser $user
+ *
+ * @return IPersonalProviderSettings
+ */
+ public function getPersonalSettings(IUser $user): IPersonalProviderSettings {
+ $state = $this->storage->getBackupCodesState($user);
+ $this->initialState->provideInitialState('state', $state);
+ return new Personal();
+ }
+
+ public function disableFor(IUser $user): void {
+ $this->storage->deleteCodes($user);
+ }
+}
diff --git a/apps/twofactor_backupcodes/lib/Service/BackupCodeStorage.php b/apps/twofactor_backupcodes/lib/Service/BackupCodeStorage.php
new file mode 100644
index 00000000000..7dd6b3949e2
--- /dev/null
+++ b/apps/twofactor_backupcodes/lib/Service/BackupCodeStorage.php
@@ -0,0 +1,109 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Service;
+
+use OCA\TwoFactorBackupCodes\Db\BackupCode;
+use OCA\TwoFactorBackupCodes\Db\BackupCodeMapper;
+use OCA\TwoFactorBackupCodes\Event\CodesGenerated;
+use OCP\EventDispatcher\IEventDispatcher;
+use OCP\IUser;
+use OCP\Security\IHasher;
+use OCP\Security\ISecureRandom;
+
+class BackupCodeStorage {
+ private static $CODE_LENGTH = 16;
+
+ public function __construct(
+ private BackupCodeMapper $mapper,
+ private ISecureRandom $random,
+ private IHasher $hasher,
+ private IEventDispatcher $eventDispatcher,
+ ) {
+ }
+
+ /**
+ * @param IUser $user
+ * @param int $number
+ * @return string[]
+ */
+ public function createCodes(IUser $user, int $number = 10): array {
+ $result = [];
+
+ // Delete existing ones
+ $this->mapper->deleteCodes($user);
+
+ $uid = $user->getUID();
+ foreach (range(1, min([$number, 20])) as $i) {
+ $code = $this->random->generate(self::$CODE_LENGTH, ISecureRandom::CHAR_HUMAN_READABLE);
+
+ $dbCode = new BackupCode();
+ $dbCode->setUserId($uid);
+ $dbCode->setCode($this->hasher->hash($code));
+ $dbCode->setUsed(0);
+ $this->mapper->insert($dbCode);
+
+ $result[] = $code;
+ }
+
+ $this->eventDispatcher->dispatchTyped(new CodesGenerated($user));
+
+ return $result;
+ }
+
+ /**
+ * @param IUser $user
+ * @return bool
+ */
+ public function hasBackupCodes(IUser $user): bool {
+ $codes = $this->mapper->getBackupCodes($user);
+ return count($codes) > 0;
+ }
+
+ /**
+ * @param IUser $user
+ * @return array
+ */
+ public function getBackupCodesState(IUser $user): array {
+ $codes = $this->mapper->getBackupCodes($user);
+ $total = count($codes);
+ $used = 0;
+ array_walk($codes, function (BackupCode $code) use (&$used): void {
+ if ((int)$code->getUsed() === 1) {
+ $used++;
+ }
+ });
+ return [
+ 'enabled' => $total > 0,
+ 'total' => $total,
+ 'used' => $used,
+ ];
+ }
+
+ /**
+ * @param IUser $user
+ * @param string $code
+ * @return bool
+ */
+ public function validateCode(IUser $user, string $code): bool {
+ $dbCodes = $this->mapper->getBackupCodes($user);
+
+ foreach ($dbCodes as $dbCode) {
+ if ((int)$dbCode->getUsed() === 0 && $this->hasher->verify($code, $dbCode->getCode())) {
+ $dbCode->setUsed(1);
+ $this->mapper->update($dbCode);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public function deleteCodes(IUser $user): void {
+ $this->mapper->deleteCodes($user);
+ }
+}
diff --git a/apps/twofactor_backupcodes/lib/Settings/Personal.php b/apps/twofactor_backupcodes/lib/Settings/Personal.php
new file mode 100644
index 00000000000..e03c3d303db
--- /dev/null
+++ b/apps/twofactor_backupcodes/lib/Settings/Personal.php
@@ -0,0 +1,21 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCA\TwoFactorBackupCodes\Settings;
+
+use OCP\Authentication\TwoFactorAuth\IPersonalProviderSettings;
+use OCP\Server;
+use OCP\Template\ITemplate;
+use OCP\Template\ITemplateManager;
+
+class Personal implements IPersonalProviderSettings {
+ public function getBody(): ITemplate {
+ return Server::get(ITemplateManager::class)->getTemplate('twofactor_backupcodes', 'personal');
+ }
+}
diff --git a/apps/twofactor_backupcodes/src/service/BackupCodesService.js b/apps/twofactor_backupcodes/src/service/BackupCodesService.js
new file mode 100644
index 00000000000..0abf365ccdb
--- /dev/null
+++ b/apps/twofactor_backupcodes/src/service/BackupCodesService.js
@@ -0,0 +1,16 @@
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import Axios from '@nextcloud/axios'
+import { generateUrl } from '@nextcloud/router'
+
+/**
+ *
+ */
+export function generateCodes() {
+ const url = generateUrl('/apps/twofactor_backupcodes/settings/create')
+
+ return Axios.post(url, {}).then(resp => resp.data)
+}
diff --git a/apps/twofactor_backupcodes/src/service/PrintService.js b/apps/twofactor_backupcodes/src/service/PrintService.js
new file mode 100644
index 00000000000..4575628744a
--- /dev/null
+++ b/apps/twofactor_backupcodes/src/service/PrintService.js
@@ -0,0 +1,16 @@
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+/**
+ * @param {any} data -
+ */
+export function print(data) {
+ const name = OC.theme.name || 'Nextcloud'
+ const newTab = window.open('', t('twofactor_backupcodes', '{name} backup codes', { name }))
+ newTab.document.write('<h1>' + t('twofactor_backupcodes', '{name} backup codes', { name }) + '</h1>')
+ newTab.document.write('<pre>' + data + '</pre>')
+ newTab.print()
+ newTab.close()
+}
diff --git a/apps/twofactor_backupcodes/src/settings.js b/apps/twofactor_backupcodes/src/settings.js
new file mode 100644
index 00000000000..53aa7e365af
--- /dev/null
+++ b/apps/twofactor_backupcodes/src/settings.js
@@ -0,0 +1,20 @@
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import { loadState } from '@nextcloud/initial-state'
+import Vue from 'vue'
+
+import PersonalSettings from './views/PersonalSettings.vue'
+import store from './store.js'
+
+Vue.prototype.t = t
+
+const initialState = loadState('twofactor_backupcodes', 'state')
+store.replaceState(initialState)
+
+const View = Vue.extend(PersonalSettings)
+new View({
+ store,
+}).$mount('#twofactor-backupcodes-settings')
diff --git a/apps/twofactor_backupcodes/src/store.js b/apps/twofactor_backupcodes/src/store.js
new file mode 100644
index 00000000000..1d5cdcafc6d
--- /dev/null
+++ b/apps/twofactor_backupcodes/src/store.js
@@ -0,0 +1,53 @@
+/**
+ * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import Vue from 'vue'
+import Vuex, { Store } from 'vuex'
+import { generateCodes } from './service/BackupCodesService.js'
+
+Vue.use(Vuex)
+
+const state = {
+ enabled: false,
+ total: 0,
+ used: 0,
+ codes: [],
+}
+
+const mutations = {
+ setEnabled(state, enabled) {
+ Vue.set(state, 'enabled', enabled)
+ },
+ setTotal(state, total) {
+ Vue.set(state, 'total', total)
+ },
+ setUsed(state, used) {
+ Vue.set(state, 'used', used)
+ },
+ setCodes(state, codes) {
+ Vue.set(state, 'codes', codes)
+ },
+}
+
+const actions = {
+ generate({ commit }) {
+ commit('setEnabled', false)
+
+ return generateCodes().then(({ codes, state }) => {
+ commit('setEnabled', state.enabled)
+ commit('setTotal', state.total)
+ commit('setUsed', state.used)
+ commit('setCodes', codes)
+ return true
+ })
+ },
+}
+
+export default new Store({
+ strict: process.env.NODE_ENV !== 'production',
+ state,
+ mutations,
+ actions,
+})
diff --git a/apps/twofactor_backupcodes/src/views/PersonalSettings.vue b/apps/twofactor_backupcodes/src/views/PersonalSettings.vue
new file mode 100644
index 00000000000..3e17613bb47
--- /dev/null
+++ b/apps/twofactor_backupcodes/src/views/PersonalSettings.vue
@@ -0,0 +1,157 @@
+<!--
+ - SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
+-->
+<template>
+ <div class="backupcodes-settings">
+ <NcButton v-if="!enabled"
+ id="generate-backup-codes"
+ :disabled="generatingCodes"
+ @click="generateBackupCodes">
+ <template #icon>
+ <NcLoadingIcon v-if="generatingCodes" />
+ </template>
+ {{ t('twofactor_backupcodes', 'Generate backup codes') }}
+ </NcButton>
+ <template v-else>
+ <p class="backupcodes-settings__codes">
+ <template v-if="!haveCodes">
+ {{ t('twofactor_backupcodes', 'Backup codes have been generated. {used} of {total} codes have been used.', {used, total}) }}
+ </template>
+ <template v-else>
+ {{ t('twofactor_backupcodes', 'These are your backup codes. Please save and/or print them as you will not be able to read the codes again later.') }}
+ <ul>
+ <li v-for="code in codes"
+ :key="code"
+ class="backupcodes-settings__codes__code">
+ {{ code }}
+ </li>
+ </ul>
+ </template>
+ </p>
+ <p class="backupcodes-settings__actions">
+ <template v-if="haveCodes">
+ <NcButton :href="downloadUrl"
+ :download="downloadFilename"
+ type="primary">
+ {{ t('twofactor_backupcodes', 'Save backup codes') }}
+ </NcButton>
+ <NcButton @click="printCodes">
+ {{ t('twofactor_backupcodes', 'Print backup codes') }}
+ </NcButton>
+ </template>
+ <NcButton id="generate-backup-codes"
+ @click="generateBackupCodes">
+ {{ t('twofactor_backupcodes', 'Regenerate backup codes') }}
+ </NcButton>
+ </p>
+ <p>
+ <em>
+ {{ t('twofactor_backupcodes', 'If you regenerate backup codes, you automatically invalidate old codes.') }}
+ </em>
+ </p>
+ </template>
+ </div>
+</template>
+
+<script>
+import { confirmPassword } from '@nextcloud/password-confirmation'
+import { print } from '../service/PrintService.js'
+import NcButton from '@nextcloud/vue/components/NcButton'
+import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'
+
+import '@nextcloud/password-confirmation/dist/style.css'
+
+export default {
+ name: 'PersonalSettings',
+ components: {
+ NcButton,
+ NcLoadingIcon,
+ },
+ data() {
+ return {
+ generatingCodes: false,
+ }
+ },
+ computed: {
+ downloadUrl() {
+ if (!this.codes) {
+ return ''
+ }
+ return 'data:text/plain,' + encodeURIComponent(this.codes.reduce((prev, code) => {
+ return prev + code + '\r\n'
+ }, ''))
+ },
+ downloadFilename() {
+ const name = OC.theme.name || 'Nextcloud'
+ return name + '-backup-codes.txt'
+ },
+ enabled() {
+ return this.$store.state.enabled
+ },
+ total() {
+ return this.$store.state.total
+ },
+ used() {
+ return this.$store.state.used
+ },
+ codes() {
+ return this.$store.state.codes
+ },
+ name() {
+ return OC.theme.name || 'Nextcloud'
+ },
+ haveCodes() {
+ return this.codes && this.codes.length > 0
+ },
+ },
+ methods: {
+ generateBackupCodes() {
+ confirmPassword().then(() => {
+ // Hide old codes
+ this.generatingCodes = true
+
+ this.$store.dispatch('generate').then(() => {
+ this.generatingCodes = false
+ }).catch(err => {
+ OC.Notification.showTemporary(t('twofactor_backupcodes', 'An error occurred while generating your backup codes'))
+ this.generatingCodes = false
+ throw err
+ })
+ }).catch(console.error.bind(this))
+ },
+
+ getPrintData(codes) {
+ if (!codes) {
+ return ''
+ }
+ return codes.reduce((prev, code) => {
+ return prev + code + '<br>'
+ }, '')
+ },
+
+ printCodes() {
+ print(this.getPrintData(this.codes))
+ },
+ },
+}
+</script>
+
+<style lang="scss" scoped>
+.backupcodes-settings {
+ &__codes {
+ &__code {
+ font-family: monospace;
+ letter-spacing: 0.02em;
+ font-size: 1.2em;
+ }
+ }
+
+ &__actions {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: var(--default-grid-baseline);
+ }
+}
+</style>
diff --git a/apps/twofactor_backupcodes/templates/challenge.php b/apps/twofactor_backupcodes/templates/challenge.php
new file mode 100644
index 00000000000..2dc4eec3973
--- /dev/null
+++ b/apps/twofactor_backupcodes/templates/challenge.php
@@ -0,0 +1,20 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+style('twofactor_backupcodes', 'style');
+?>
+
+<img class="two-factor-icon" src="<?php p(image_path('core', 'actions/more-white.svg')) ?>" alt="" />
+
+<p><?php p($l->t('Use one of the backup codes you saved when setting up two-factor authentication.')) ?></p>
+
+<form method="POST" class="challenge-form">
+ <input type="text" class="challenge" name="challenge" required="required" autofocus autocomplete="off" autocapitalize="off" placeholder="<?php p($l->t('Backup code')) ?>">
+ <button class="two-factor-submit primary" type="submit">
+ <?php p($l->t('Submit')); ?>
+ </button>
+</form>
diff --git a/apps/twofactor_backupcodes/templates/personal.php b/apps/twofactor_backupcodes/templates/personal.php
new file mode 100644
index 00000000000..838e2016777
--- /dev/null
+++ b/apps/twofactor_backupcodes/templates/personal.php
@@ -0,0 +1,12 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+\OCP\Util::addScript('twofactor_backupcodes', 'settings', 'core');
+
+?>
+
+<div id="twofactor-backupcodes-settings"></div>
diff --git a/apps/twofactor_backupcodes/tests/Db/BackupCodeMapperTest.php b/apps/twofactor_backupcodes/tests/Db/BackupCodeMapperTest.php
new file mode 100644
index 00000000000..19cab51969b
--- /dev/null
+++ b/apps/twofactor_backupcodes/tests/Db/BackupCodeMapperTest.php
@@ -0,0 +1,106 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Tests\Db;
+
+use OCA\TwoFactorBackupCodes\Db\BackupCode;
+use OCA\TwoFactorBackupCodes\Db\BackupCodeMapper;
+use OCP\IDBConnection;
+use OCP\IUser;
+use OCP\Server;
+use Test\TestCase;
+
+/**
+ * @group DB
+ */
+class BackupCodeMapperTest extends TestCase {
+ private IDBConnection $db;
+ private BackupCodeMapper $mapper;
+ private string $testUID = 'test123456';
+
+ private function resetDB() {
+ $qb = $this->db->getQueryBuilder();
+ $qb->delete($this->mapper->getTableName())
+ ->where($qb->expr()->eq('user_id', $qb->createNamedParameter($this->testUID)));
+ $qb->execute();
+ }
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->db = Server::get(IDBConnection::class);
+ $this->mapper = Server::get(BackupCodeMapper::class);
+
+ $this->resetDB();
+ }
+
+ protected function tearDown(): void {
+ parent::tearDown();
+
+ $this->resetDB();
+ }
+
+ public function testGetBackupCodes(): void {
+ $code1 = new BackupCode();
+ $code1->setUserId($this->testUID);
+ $code1->setCode('1|$2y$10$Fyo.DkMtkaHapVvRVbQBeeIdi5x/6nmPnxiBzD0GDKa08NMus5xze');
+ $code1->setUsed(1);
+
+ $code2 = new BackupCode();
+ $code2->setUserId($this->testUID);
+ $code2->setCode('1|$2y$10$nj3sZaCqGN8t6.SsnNADt.eX34UCkdX6FPx.r.rIwE6Jj3vi5wyt2');
+ $code2->setUsed(0);
+
+ $this->mapper->insert($code1);
+ $this->mapper->insert($code2);
+
+ $user = $this->getMockBuilder(IUser::class)->getMock();
+ $user->expects($this->once())
+ ->method('getUID')
+ ->willReturn($this->testUID);
+
+ $dbCodes = $this->mapper->getBackupCodes($user);
+
+ $this->assertCount(2, $dbCodes);
+ $this->assertInstanceOf(BackupCode::class, $dbCodes[0]);
+ $this->assertInstanceOf(BackupCode::class, $dbCodes[1]);
+ }
+
+ public function testDeleteCodes(): void {
+ $code = new BackupCode();
+ $code->setUserId($this->testUID);
+ $code->setCode('1|$2y$10$CagG8pEhZL.xDirtCCP/KuuWtnsAasgq60zY9rU46dBK4w8yW0Z/y');
+ $code->setUsed(1);
+ $user = $this->getMockBuilder(IUser::class)->getMock();
+ $user->expects($this->any())
+ ->method('getUID')
+ ->willReturn($this->testUID);
+
+ $this->mapper->insert($code);
+
+ $this->assertCount(1, $this->mapper->getBackupCodes($user));
+
+ $this->mapper->deleteCodes($user);
+
+ $this->assertCount(0, $this->mapper->getBackupCodes($user));
+ }
+
+ public function testInsertArgonEncryptedCodes(): void {
+ $code = new BackupCode();
+ $code->setUserId($this->testUID);
+ $code->setCode('2|$argon2i$v=19$m=1024,t=2,p=2$MjJWUjRFWndtMm5BWGxOag$BusVxLeFyiLLWtaVvX/JRFBiPdZcjRrzpQ/rAhn6vqY');
+ $code->setUsed(1);
+ $user = $this->getMockBuilder(IUser::class)->getMock();
+ $user->expects($this->any())
+ ->method('getUID')
+ ->willReturn($this->testUID);
+
+ $this->mapper->insert($code);
+ $this->assertCount(1, $this->mapper->getBackupCodes($user));
+ }
+}
diff --git a/apps/twofactor_backupcodes/tests/Service/BackupCodeStorageTest.php b/apps/twofactor_backupcodes/tests/Service/BackupCodeStorageTest.php
new file mode 100644
index 00000000000..cfc35e7cb1c
--- /dev/null
+++ b/apps/twofactor_backupcodes/tests/Service/BackupCodeStorageTest.php
@@ -0,0 +1,90 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Tests\Service;
+
+use OCA\TwoFactorBackupCodes\Service\BackupCodeStorage;
+use OCP\IUser;
+use OCP\Notification\IManager;
+use OCP\Notification\INotification;
+use OCP\Server;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+/**
+ * @group DB
+ */
+class BackupCodeStorageTest extends TestCase {
+ private IManager&MockObject $notificationManager;
+ private string $testUID = 'test123456789';
+ private BackupCodeStorage $storage;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->storage = Server::get(BackupCodeStorage::class);
+
+ $this->notificationManager = $this->createMock(IManager::class);
+ $this->notificationManager->method('createNotification')
+ ->willReturn(Server::get(IManager::class)->createNotification());
+ $this->overwriteService(IManager::class, $this->notificationManager);
+ }
+
+ public function testSimpleWorkFlow(): void {
+ $user = $this->getMockBuilder(IUser::class)->getMock();
+ $user->expects($this->any())
+ ->method('getUID')
+ ->willReturn($this->testUID);
+
+ $this->notificationManager->expects($this->once())
+ ->method('markProcessed')
+ ->with($this->callback(function (INotification $notification) {
+ return $notification->getUser() === $this->testUID
+ && $notification->getObjectType() === 'create'
+ && $notification->getObjectId() === 'codes'
+ && $notification->getApp() === 'twofactor_backupcodes';
+ }));
+
+ // Create codes
+ $codes = $this->storage->createCodes($user, 5);
+ $this->assertCount(5, $codes);
+ $this->assertTrue($this->storage->hasBackupCodes($user));
+ $initialState = [
+ 'enabled' => true,
+ 'total' => 5,
+ 'used' => 0,
+ ];
+ $this->assertEquals($initialState, $this->storage->getBackupCodesState($user));
+
+ // Use codes
+ $code = $codes[2];
+ $this->assertTrue($this->storage->validateCode($user, $code));
+ // Code must not be used twice
+ $this->assertFalse($this->storage->validateCode($user, $code));
+ // Invalid codes are invalid
+ $this->assertFalse($this->storage->validateCode($user, 'I DO NOT EXIST'));
+ $stateAfter = [
+ 'enabled' => true,
+ 'total' => 5,
+ 'used' => 1,
+ ];
+ $this->assertEquals($stateAfter, $this->storage->getBackupCodesState($user));
+
+ // Deplete codes
+ $this->assertTrue($this->storage->validateCode($user, $codes[0]));
+ $this->assertTrue($this->storage->validateCode($user, $codes[1]));
+ $this->assertTrue($this->storage->validateCode($user, $codes[3]));
+ $this->assertTrue($this->storage->validateCode($user, $codes[4]));
+ $stateAllUsed = [
+ 'enabled' => true,
+ 'total' => 5,
+ 'used' => 5,
+ ];
+ $this->assertEquals($stateAllUsed, $this->storage->getBackupCodesState($user));
+ }
+}
diff --git a/apps/twofactor_backupcodes/tests/Unit/Activity/ProviderTest.php b/apps/twofactor_backupcodes/tests/Unit/Activity/ProviderTest.php
new file mode 100644
index 00000000000..152ff80194a
--- /dev/null
+++ b/apps/twofactor_backupcodes/tests/Unit/Activity/ProviderTest.php
@@ -0,0 +1,106 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Test\Unit\Activity;
+
+use OCA\TwoFactorBackupCodes\Activity\Provider;
+use OCP\Activity\Exceptions\UnknownActivityException;
+use OCP\Activity\IEvent;
+use OCP\Activity\IManager;
+use OCP\IL10N;
+use OCP\IURLGenerator;
+use OCP\L10N\IFactory;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+class ProviderTest extends TestCase {
+ private IFactory&MockObject $l10n;
+ private IURLGenerator&MockObject $urlGenerator;
+ private IManager&MockObject $activityManager;
+ private Provider $provider;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->l10n = $this->createMock(IFactory::class);
+ $this->urlGenerator = $this->createMock(IURLGenerator::class);
+ $this->activityManager = $this->createMock(IManager::class);
+
+ $this->provider = new Provider($this->l10n, $this->urlGenerator, $this->activityManager);
+ }
+
+ public function testParseUnrelated(): void {
+ $lang = 'ru';
+ $event = $this->createMock(IEvent::class);
+ $event->expects($this->once())
+ ->method('getApp')
+ ->willReturn('comments');
+ $this->expectException(UnknownActivityException::class);
+
+ $this->provider->parse($lang, $event);
+ }
+
+ public static function subjectData(): array {
+ return [
+ ['codes_generated'],
+ ];
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('subjectData')]
+ public function testParse(string $subject): void {
+ $lang = 'ru';
+ $event = $this->createMock(IEvent::class);
+ $l = $this->createMock(IL10N::class);
+
+ $event->expects($this->once())
+ ->method('getApp')
+ ->willReturn('twofactor_backupcodes');
+ $this->l10n->expects($this->once())
+ ->method('get')
+ ->with('twofactor_backupcodes', $lang)
+ ->willReturn($l);
+ $this->urlGenerator->expects($this->once())
+ ->method('imagePath')
+ ->with('core', 'actions/password.svg')
+ ->willReturn('path/to/image');
+ $this->urlGenerator->expects($this->once())
+ ->method('getAbsoluteURL')
+ ->with('path/to/image')
+ ->willReturn('absolute/path/to/image');
+ $event->expects($this->once())
+ ->method('setIcon')
+ ->with('absolute/path/to/image');
+ $event->expects($this->once())
+ ->method('getSubject')
+ ->willReturn($subject);
+ $event->expects($this->once())
+ ->method('setParsedSubject');
+
+ $this->provider->parse($lang, $event);
+ }
+
+ public function testParseInvalidSubject(): void {
+ $lang = 'ru';
+ $l = $this->createMock(IL10N::class);
+ $event = $this->createMock(IEvent::class);
+
+ $event->expects($this->once())
+ ->method('getApp')
+ ->willReturn('twofactor_backupcodes');
+ $this->l10n->expects($this->once())
+ ->method('get')
+ ->with('twofactor_backupcodes', $lang)
+ ->willReturn($l);
+ $event->expects($this->once())
+ ->method('getSubject')
+ ->willReturn('unrelated');
+
+ $this->expectException(UnknownActivityException::class);
+ $this->provider->parse($lang, $event);
+ }
+}
diff --git a/apps/twofactor_backupcodes/tests/Unit/BackgroundJob/CheckBackupCodeTest.php b/apps/twofactor_backupcodes/tests/Unit/BackgroundJob/CheckBackupCodeTest.php
new file mode 100644
index 00000000000..87bc65e4309
--- /dev/null
+++ b/apps/twofactor_backupcodes/tests/Unit/BackgroundJob/CheckBackupCodeTest.php
@@ -0,0 +1,129 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Tests\Unit\BackgroundJob;
+
+use OC\Authentication\TwoFactorAuth\Manager;
+use OCA\TwoFactorBackupCodes\BackgroundJob\CheckBackupCodes;
+use OCA\TwoFactorBackupCodes\BackgroundJob\RememberBackupCodesJob;
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\Authentication\TwoFactorAuth\IRegistry;
+use OCP\BackgroundJob\IJobList;
+use OCP\IUser;
+use OCP\IUserManager;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+class CheckBackupCodeTest extends TestCase {
+ private IUserManager&MockObject $userManager;
+ private IJobList&MockObject $jobList;
+ private IRegistry&MockObject $registry;
+ private Manager&MockObject $manager;
+ private IUser&MockObject $user;
+ private CheckBackupCodes $checkBackupCodes;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->userManager = $this->createMock(IUserManager::class);
+ $this->jobList = $this->createMock(IJobList::class);
+ $this->registry = $this->createMock(IRegistry::class);
+ $this->manager = $this->createMock(Manager::class);
+
+ $this->user = $this->createMock(IUser::class);
+
+ $this->userManager->method('callForSeenUsers')
+ ->willReturnCallback(function (\Closure $e): void {
+ $e($this->user);
+ });
+
+ $this->checkBackupCodes = new CheckBackupCodes(
+ $this->createMock(ITimeFactory::class),
+ $this->userManager,
+ $this->jobList,
+ $this->manager,
+ $this->registry
+ );
+ }
+
+ public function testRunAlreadyGenerated(): void {
+ $this->user->method('isEnabled')
+ ->willReturn(true);
+
+ $this->registry->method('getProviderStates')
+ ->with($this->user)
+ ->willReturn(['backup_codes' => true]);
+ $this->manager->method('isTwoFactorAuthenticated')
+ ->with($this->user)
+ ->willReturn(true);
+ $this->jobList->expects($this->never())
+ ->method($this->anything());
+
+ $this->invokePrivate($this->checkBackupCodes, 'run', [[]]);
+ }
+
+ public function testRun(): void {
+ $this->user->method('getUID')
+ ->willReturn('myUID');
+ $this->user->method('isEnabled')
+ ->willReturn(true);
+
+ $this->registry->expects($this->once())
+ ->method('getProviderStates')
+ ->with($this->user)
+ ->willReturn([
+ 'backup_codes' => false,
+ ]);
+ $this->jobList->expects($this->once())
+ ->method('add')
+ ->with(
+ $this->equalTo(RememberBackupCodesJob::class),
+ ['uid' => 'myUID']
+ );
+ $this->manager->method('isTwoFactorAuthenticated')
+ ->with($this->user)
+ ->willReturn(true);
+
+ $this->invokePrivate($this->checkBackupCodes, 'run', [[]]);
+ }
+
+ public function testRunDisabledUser(): void {
+ $this->user->method('getUID')
+ ->willReturn('myUID');
+ $this->user->method('isEnabled')
+ ->willReturn(false);
+
+ $this->registry->expects($this->never())
+ ->method('getProviderStates')
+ ->with($this->user);
+
+ $this->jobList->expects($this->never())
+ ->method('add');
+
+ $this->invokePrivate($this->checkBackupCodes, 'run', [[]]);
+ }
+
+ public function testRunNoProviders(): void {
+ $this->user->method('isEnabled')
+ ->willReturn(true);
+
+ $this->registry->expects($this->once())
+ ->method('getProviderStates')
+ ->with($this->user)
+ ->willReturn([
+ 'backup_codes' => false,
+ ]);
+ $this->jobList->expects($this->never())
+ ->method($this->anything());
+ $this->manager->method('isTwoFactorAuthenticated')
+ ->with($this->user)
+ ->willReturn(false);
+
+ $this->invokePrivate($this->checkBackupCodes, 'run', [[]]);
+ }
+}
diff --git a/apps/twofactor_backupcodes/tests/Unit/BackgroundJob/RememberBackupCodesJobTest.php b/apps/twofactor_backupcodes/tests/Unit/BackgroundJob/RememberBackupCodesJobTest.php
new file mode 100644
index 00000000000..6b162894258
--- /dev/null
+++ b/apps/twofactor_backupcodes/tests/Unit/BackgroundJob/RememberBackupCodesJobTest.php
@@ -0,0 +1,213 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Tests\Unit\BackgroundJob;
+
+use OCA\TwoFactorBackupCodes\BackgroundJob\RememberBackupCodesJob;
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\Authentication\TwoFactorAuth\IRegistry;
+use OCP\BackgroundJob\IJobList;
+use OCP\IUser;
+use OCP\IUserManager;
+use OCP\Notification\IManager;
+use OCP\Notification\INotification;
+use OCP\Server;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+class RememberBackupCodesJobTest extends TestCase {
+ private IRegistry&MockObject $registry;
+ private IUserManager&MockObject $userManager;
+ private ITimeFactory&MockObject $time;
+ private IManager&MockObject $notificationManager;
+ private IJobList&MockObject $jobList;
+ private RememberBackupCodesJob $job;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->registry = $this->createMock(IRegistry::class);
+ $this->userManager = $this->createMock(IUserManager::class);
+ $this->time = $this->createMock(ITimeFactory::class);
+ $this->time->method('getTime')
+ ->willReturn(10000000);
+ $this->notificationManager = $this->createMock(IManager::class);
+ $this->jobList = $this->createMock(IJobList::class);
+
+ $this->job = new RememberBackupCodesJob(
+ $this->registry,
+ $this->userManager,
+ $this->time,
+ $this->notificationManager,
+ $this->jobList
+ );
+ }
+
+ public function testInvalidUID(): void {
+ $this->userManager->method('get')
+ ->with('invalidUID')
+ ->willReturn(null);
+
+ $this->notificationManager->expects($this->never())
+ ->method($this->anything());
+ $this->jobList->expects($this->once())
+ ->method('remove')
+ ->with(
+ RememberBackupCodesJob::class,
+ ['uid' => 'invalidUID']
+ );
+ $this->jobList->expects($this->never())
+ ->method('add');
+
+ self::invokePrivate($this->job, 'run', [['uid' => 'invalidUID']]);
+ }
+
+ public function testBackupCodesGenerated(): void {
+ $user = $this->createMock(IUser::class);
+ $user->method('getUID')
+ ->willReturn('validUID');
+ $user->method('isEnabled')
+ ->willReturn(true);
+
+ $this->userManager->method('get')
+ ->with('validUID')
+ ->willReturn($user);
+
+ $this->registry->method('getProviderStates')
+ ->with($user)
+ ->willReturn([
+ 'backup_codes' => true
+ ]);
+
+ $this->jobList->expects($this->once())
+ ->method('remove')
+ ->with(
+ RememberBackupCodesJob::class,
+ ['uid' => 'validUID']
+ );
+
+ $this->notificationManager->expects($this->never())
+ ->method($this->anything());
+
+ self::invokePrivate($this->job, 'run', [['uid' => 'validUID']]);
+ }
+
+ public function testNoActiveProvider(): void {
+ $user = $this->createMock(IUser::class);
+ $user->method('getUID')
+ ->willReturn('validUID');
+ $this->userManager->method('get')
+ ->with('validUID')
+ ->willReturn($user);
+
+ $this->registry->method('getProviderStates')
+ ->with($user)
+ ->willReturn([
+ 'backup_codes' => false,
+ 'foo' => false,
+ ]);
+
+ $this->jobList->expects($this->once())
+ ->method('remove')
+ ->with(
+ RememberBackupCodesJob::class,
+ ['uid' => 'validUID']
+ );
+
+ $this->notificationManager->expects($this->never())
+ ->method($this->anything());
+
+ self::invokePrivate($this->job, 'run', [['uid' => 'validUID']]);
+ }
+
+ public function testNotificationSend(): void {
+ $user = $this->createMock(IUser::class);
+ $user->method('getUID')
+ ->willReturn('validUID');
+ $user->method('isEnabled')
+ ->willReturn(true);
+ $this->userManager->method('get')
+ ->with('validUID')
+ ->willReturn($user);
+
+ $this->registry->method('getProviderStates')
+ ->with($user)
+ ->willReturn([
+ 'backup_codes' => false,
+ 'foo' => true,
+ ]);
+
+ $this->jobList->expects($this->never())
+ ->method($this->anything());
+
+ $date = new \DateTime();
+ $date->setTimestamp($this->time->getTime());
+
+ $this->notificationManager->method('createNotification')
+ ->willReturn(Server::get(IManager::class)->createNotification());
+
+ $this->notificationManager->expects($this->once())
+ ->method('notify')
+ ->with($this->callback(function (INotification $n) {
+ return $n->getApp() === 'twofactor_backupcodes'
+ && $n->getUser() === 'validUID'
+ && $n->getDateTime()->getTimestamp() === 10000000
+ && $n->getObjectType() === 'create'
+ && $n->getObjectId() === 'codes'
+ && $n->getSubject() === 'create_backupcodes';
+ }));
+
+ self::invokePrivate($this->job, 'run', [['uid' => 'validUID']]);
+ }
+
+ public function testNotificationNotSendForDisabledUser(): void {
+ $user = $this->createMock(IUser::class);
+ $user->method('getUID')
+ ->willReturn('validUID');
+ $user->method('isEnabled')
+ ->willReturn(false);
+ $this->userManager->method('get')
+ ->with('validUID')
+ ->willReturn($user);
+
+ $this->registry->method('getProviderStates')
+ ->with($user)
+ ->willReturn([
+ 'backup_codes' => false,
+ 'foo' => true,
+ ]);
+
+ $this->jobList->expects($this->once())
+ ->method('remove')
+ ->with(
+ RememberBackupCodesJob::class,
+ ['uid' => 'validUID']
+ );
+
+ $date = new \DateTime();
+ $date->setTimestamp($this->time->getTime());
+
+ $this->notificationManager->method('createNotification')
+ ->willReturn(Server::get(IManager::class)->createNotification());
+
+ $this->notificationManager->expects($this->once())
+ ->method('markProcessed')
+ ->with($this->callback(function (INotification $n) {
+ return $n->getApp() === 'twofactor_backupcodes'
+ && $n->getUser() === 'validUID'
+ && $n->getObjectType() === 'create'
+ && $n->getObjectId() === 'codes'
+ && $n->getSubject() === 'create_backupcodes';
+ }));
+
+ $this->notificationManager->expects($this->never())
+ ->method('notify');
+
+ self::invokePrivate($this->job, 'run', [['uid' => 'validUID']]);
+ }
+}
diff --git a/apps/twofactor_backupcodes/tests/Unit/Controller/SettingsControllerTest.php b/apps/twofactor_backupcodes/tests/Unit/Controller/SettingsControllerTest.php
new file mode 100644
index 00000000000..02c42b65148
--- /dev/null
+++ b/apps/twofactor_backupcodes/tests/Unit/Controller/SettingsControllerTest.php
@@ -0,0 +1,60 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Tests\Unit\Controller;
+
+use OCA\TwoFactorBackupCodes\Controller\SettingsController;
+use OCA\TwoFactorBackupCodes\Service\BackupCodeStorage;
+use OCP\AppFramework\Http\JSONResponse;
+use OCP\IRequest;
+use OCP\IUser;
+use OCP\IUserSession;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+class SettingsControllerTest extends TestCase {
+ private IRequest&MockObject $request;
+ private BackupCodeStorage&MockObject $storage;
+ private IUserSession&MockObject $userSession;
+ private SettingsController $controller;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->request = $this->createMock(IRequest::class);
+ $this->storage = $this->createMock(BackupCodeStorage::class);
+ $this->userSession = $this->createMock(IUserSession::class);
+
+ $this->controller = new SettingsController('twofactor_backupcodes', $this->request, $this->storage, $this->userSession);
+ }
+
+ public function testCreateCodes(): void {
+ $user = $this->createMock(IUser::class);
+
+ $codes = ['a', 'b'];
+ $this->userSession->expects($this->once())
+ ->method('getUser')
+ ->willReturn($user);
+ $this->storage->expects($this->once())
+ ->method('createCodes')
+ ->with($user)
+ ->willReturn($codes);
+ $this->storage->expects($this->once())
+ ->method('getBackupCodesState')
+ ->with($user)
+ ->willReturn(['state']);
+
+ $expected = [
+ 'codes' => $codes,
+ 'state' => ['state'],
+ ];
+ $response = $this->controller->createCodes();
+ $this->assertInstanceOf(JSONResponse::class, $response);
+ $this->assertEquals($expected, $response->getData());
+ }
+}
diff --git a/apps/twofactor_backupcodes/tests/Unit/Event/CodesGeneratedTest.php b/apps/twofactor_backupcodes/tests/Unit/Event/CodesGeneratedTest.php
new file mode 100644
index 00000000000..3f619e387e9
--- /dev/null
+++ b/apps/twofactor_backupcodes/tests/Unit/Event/CodesGeneratedTest.php
@@ -0,0 +1,23 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Tests\Unit\Event;
+
+use OCA\TwoFactorBackupCodes\Event\CodesGenerated;
+use OCP\IUser;
+use Test\TestCase;
+
+class CodesGeneratedTest extends TestCase {
+ public function testCodeGeneratedEvent(): void {
+ $user = $this->createMock(IUser::class);
+
+ $event = new CodesGenerated($user);
+
+ $this->assertSame($user, $event->getUser());
+ }
+}
diff --git a/apps/twofactor_backupcodes/tests/Unit/Listener/ActivityPublisherTest.php b/apps/twofactor_backupcodes/tests/Unit/Listener/ActivityPublisherTest.php
new file mode 100644
index 00000000000..bd944dc2396
--- /dev/null
+++ b/apps/twofactor_backupcodes/tests/Unit/Listener/ActivityPublisherTest.php
@@ -0,0 +1,72 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Tests\Unit\Listener;
+
+use OCA\TwoFactorBackupCodes\Event\CodesGenerated;
+use OCA\TwoFactorBackupCodes\Listener\ActivityPublisher;
+use OCP\Activity\IEvent;
+use OCP\Activity\IManager;
+use OCP\EventDispatcher\Event;
+use OCP\IUser;
+use PHPUnit\Framework\MockObject\MockObject;
+use Psr\Log\LoggerInterface;
+use Test\TestCase;
+
+class ActivityPublisherTest extends TestCase {
+ private IManager&MockObject $activityManager;
+ private LoggerInterface&MockObject $logger;
+ private ActivityPublisher $listener;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->activityManager = $this->createMock(IManager::class);
+ $this->logger = $this->createMock(LoggerInterface::class);
+
+ $this->listener = new ActivityPublisher($this->activityManager, $this->logger);
+ }
+
+ public function testHandleGenericEvent(): void {
+ $event = $this->createMock(Event::class);
+ $this->activityManager->expects($this->never())
+ ->method('publish');
+
+ $this->listener->handle($event);
+ }
+
+ public function testHandleCodesGeneratedEvent(): void {
+ $user = $this->createMock(IUser::class);
+ $user->method('getUID')->willReturn('fritz');
+ $event = new CodesGenerated($user);
+ $activityEvent = $this->createMock(IEvent::class);
+ $this->activityManager->expects($this->once())
+ ->method('generateEvent')
+ ->willReturn($activityEvent);
+ $activityEvent->expects($this->once())
+ ->method('setApp')
+ ->with('twofactor_backupcodes')
+ ->willReturnSelf();
+ $activityEvent->expects($this->once())
+ ->method('setType')
+ ->with('security')
+ ->willReturnSelf();
+ $activityEvent->expects($this->once())
+ ->method('setAuthor')
+ ->with('fritz')
+ ->willReturnSelf();
+ $activityEvent->expects($this->once())
+ ->method('setAffectedUser')
+ ->with('fritz')
+ ->willReturnSelf();
+ $this->activityManager->expects($this->once())
+ ->method('publish');
+
+ $this->listener->handle($event);
+ }
+}
diff --git a/apps/twofactor_backupcodes/tests/Unit/Listener/ClearNotificationsTest.php b/apps/twofactor_backupcodes/tests/Unit/Listener/ClearNotificationsTest.php
new file mode 100644
index 00000000000..229d8df05d3
--- /dev/null
+++ b/apps/twofactor_backupcodes/tests/Unit/Listener/ClearNotificationsTest.php
@@ -0,0 +1,59 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Tests\Unit\Listener;
+
+use OCA\TwoFactorBackupCodes\Event\CodesGenerated;
+use OCA\TwoFactorBackupCodes\Listener\ClearNotifications;
+use OCP\EventDispatcher\Event;
+use OCP\IUser;
+use OCP\Notification\IManager;
+use OCP\Notification\INotification;
+use OCP\Server;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+class ClearNotificationsTest extends TestCase {
+ private IManager&MockObject $notificationManager;
+ private ClearNotifications $listener;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->notificationManager = $this->createMock(IManager::class);
+ $this->notificationManager->method('createNotification')
+ ->willReturn(Server::get(IManager::class)->createNotification());
+
+ $this->listener = new ClearNotifications($this->notificationManager);
+ }
+
+ public function testHandleGenericEvent(): void {
+ $event = $this->createMock(Event::class);
+ $this->notificationManager->expects($this->never())
+ ->method($this->anything());
+
+ $this->listener->handle($event);
+ }
+
+ public function testHandleCodesGeneratedEvent(): void {
+ $user = $this->createMock(IUser::class);
+ $user->method('getUID')->willReturn('fritz');
+ $event = new CodesGenerated($user);
+
+ $this->notificationManager->expects($this->once())
+ ->method('markProcessed')
+ ->with($this->callback(function (INotification $n) {
+ return $n->getUser() === 'fritz'
+ && $n->getApp() === 'twofactor_backupcodes'
+ && $n->getObjectType() === 'create'
+ && $n->getObjectId() === 'codes';
+ }));
+
+ $this->listener->handle($event);
+ }
+}
diff --git a/apps/twofactor_backupcodes/tests/Unit/Listener/ProviderDisabledTest.php b/apps/twofactor_backupcodes/tests/Unit/Listener/ProviderDisabledTest.php
new file mode 100644
index 00000000000..ea4f530cab4
--- /dev/null
+++ b/apps/twofactor_backupcodes/tests/Unit/Listener/ProviderDisabledTest.php
@@ -0,0 +1,88 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Tests\Unit\Listener;
+
+use OCA\TwoFactorBackupCodes\BackgroundJob\RememberBackupCodesJob;
+use OCA\TwoFactorBackupCodes\Listener\ProviderDisabled;
+use OCP\Authentication\TwoFactorAuth\IRegistry;
+use OCP\Authentication\TwoFactorAuth\TwoFactorProviderForUserUnregistered;
+use OCP\BackgroundJob\IJobList;
+use OCP\EventDispatcher\Event;
+use OCP\IUser;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+class ProviderDisabledTest extends TestCase {
+ private IRegistry&MockObject $registy;
+ private IJobList&MockObject $jobList;
+ private ProviderDisabled $listener;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->registy = $this->createMock(IRegistry::class);
+ $this->jobList = $this->createMock(IJobList::class);
+
+ $this->listener = new ProviderDisabled($this->registy, $this->jobList);
+ }
+
+ public function testHandleGenericEvent(): void {
+ $event = $this->createMock(Event::class);
+ $this->jobList->expects($this->never())
+ ->method($this->anything());
+
+ $this->listener->handle($event);
+ }
+
+ public function testHandleStillActiveProvider(): void {
+ $user = $this->createMock(IUser::class);
+ $user->method('getUID')
+ ->willReturn('myUID');
+ $event = $this->createMock(TwoFactorProviderForUserUnregistered::class);
+ $event->method('getUser')
+ ->willReturn($user);
+
+ $this->registy->method('getProviderStates')
+ ->with($user)
+ ->willReturn([
+ 'backup_codes' => false,
+ 'foo' => true,
+ ]);
+
+ $this->jobList->expects($this->never())
+ ->method($this->anything());
+
+ $this->listener->handle($event);
+ }
+
+ public function testHandleNoActiveProvider(): void {
+ $user = $this->createMock(IUser::class);
+ $user->method('getUID')
+ ->willReturn('myUID');
+ $event = $this->createMock(TwoFactorProviderForUserUnregistered::class);
+ $event->method('getUser')
+ ->willReturn($user);
+
+ $this->registy->method('getProviderStates')
+ ->with($user)
+ ->willReturn([
+ 'backup_codes' => false,
+ 'foo' => false,
+ ]);
+
+ $this->jobList->expects($this->once())
+ ->method('remove')
+ ->with(
+ $this->equalTo(RememberBackupCodesJob::class),
+ $this->equalTo(['uid' => 'myUID'])
+ );
+
+ $this->listener->handle($event);
+ }
+}
diff --git a/apps/twofactor_backupcodes/tests/Unit/Listener/ProviderEnabledTest.php b/apps/twofactor_backupcodes/tests/Unit/Listener/ProviderEnabledTest.php
new file mode 100644
index 00000000000..50aac6139c0
--- /dev/null
+++ b/apps/twofactor_backupcodes/tests/Unit/Listener/ProviderEnabledTest.php
@@ -0,0 +1,86 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Tests\Unit\Listener;
+
+use OCA\TwoFactorBackupCodes\BackgroundJob\RememberBackupCodesJob;
+use OCA\TwoFactorBackupCodes\Listener\ProviderEnabled;
+use OCP\Authentication\TwoFactorAuth\IRegistry;
+use OCP\Authentication\TwoFactorAuth\TwoFactorProviderForUserRegistered;
+use OCP\BackgroundJob\IJobList;
+use OCP\EventDispatcher\Event;
+use OCP\IUser;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+class ProviderEnabledTest extends TestCase {
+ private IRegistry&MockObject $registy;
+ private IJobList&MockObject $jobList;
+ private ProviderEnabled $listener;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->registy = $this->createMock(IRegistry::class);
+ $this->jobList = $this->createMock(IJobList::class);
+
+ $this->listener = new ProviderEnabled($this->registy, $this->jobList);
+ }
+
+ public function testHandleGenericEvent(): void {
+ $event = $this->createMock(Event::class);
+ $this->jobList->expects($this->never())
+ ->method($this->anything());
+
+ $this->listener->handle($event);
+ }
+
+ public function testHandleCodesGeneratedEventAlraedyBackupcodes(): void {
+ $user = $this->createMock(IUser::class);
+ $user->method('getUID')
+ ->willReturn('myUID');
+ $event = $this->createMock(TwoFactorProviderForUserRegistered::class);
+ $event->method('getUser')
+ ->willReturn($user);
+
+ $this->registy->method('getProviderStates')
+ ->with($user)
+ ->willReturn([
+ 'backup_codes' => true,
+ ]);
+
+ $this->jobList->expects($this->never())
+ ->method($this->anything());
+
+ $this->listener->handle($event);
+ }
+
+ public function testHandleCodesGeneratedEventNoBackupcodes(): void {
+ $user = $this->createMock(IUser::class);
+ $user->method('getUID')
+ ->willReturn('myUID');
+ $event = $this->createMock(TwoFactorProviderForUserRegistered::class);
+ $event->method('getUser')
+ ->willReturn($user);
+
+ $this->registy->method('getProviderStates')
+ ->with($user)
+ ->willReturn([
+ 'backup_codes' => false,
+ ]);
+
+ $this->jobList->expects($this->once())
+ ->method('add')
+ ->with(
+ $this->equalTo(RememberBackupCodesJob::class),
+ $this->equalTo(['uid' => 'myUID'])
+ );
+
+ $this->listener->handle($event);
+ }
+}
diff --git a/apps/twofactor_backupcodes/tests/Unit/Listener/RegistryUpdaterTest.php b/apps/twofactor_backupcodes/tests/Unit/Listener/RegistryUpdaterTest.php
new file mode 100644
index 00000000000..86d890f0d5e
--- /dev/null
+++ b/apps/twofactor_backupcodes/tests/Unit/Listener/RegistryUpdaterTest.php
@@ -0,0 +1,54 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Tests\Unit\Listener;
+
+use OCA\TwoFactorBackupCodes\Event\CodesGenerated;
+use OCA\TwoFactorBackupCodes\Listener\RegistryUpdater;
+use OCA\TwoFactorBackupCodes\Provider\BackupCodesProvider;
+use OCP\Authentication\TwoFactorAuth\IRegistry;
+use OCP\EventDispatcher\Event;
+use OCP\IUser;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+class RegistryUpdaterTest extends TestCase {
+ private IRegistry&MockObject $registry;
+ private BackupCodesProvider&MockObject $provider;
+ private RegistryUpdater $listener;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->registry = $this->createMock(IRegistry::class);
+ $this->provider = $this->createMock(BackupCodesProvider::class);
+
+ $this->listener = new RegistryUpdater($this->registry, $this->provider);
+ }
+
+ public function testHandleGenericEvent(): void {
+ $event = $this->createMock(Event::class);
+ $this->registry->expects($this->never())
+ ->method('enableProviderFor');
+
+ $this->listener->handle($event);
+ }
+
+ public function testHandleCodesGeneratedEvent(): void {
+ $user = $this->createMock(IUser::class);
+ $event = new CodesGenerated($user);
+ $this->registry->expects($this->once())
+ ->method('enableProviderFor')
+ ->with(
+ $this->provider,
+ $user
+ );
+
+ $this->listener->handle($event);
+ }
+}
diff --git a/apps/twofactor_backupcodes/tests/Unit/Migration/CheckBackupCodeTest.php b/apps/twofactor_backupcodes/tests/Unit/Migration/CheckBackupCodeTest.php
new file mode 100644
index 00000000000..c68ab185116
--- /dev/null
+++ b/apps/twofactor_backupcodes/tests/Unit/Migration/CheckBackupCodeTest.php
@@ -0,0 +1,41 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Tests\Unit\Migration;
+
+use OCA\TwoFactorBackupCodes\Migration\CheckBackupCodes;
+use OCP\BackgroundJob\IJobList;
+use OCP\Migration\IOutput;
+use PHPunit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+class CheckBackupCodeTest extends TestCase {
+ private IJobList&MockObject $jobList;
+ private CheckBackupCodes $checkBackupsCodes;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->jobList = $this->createMock(IJobList::class);
+ $this->checkBackupsCodes = new CheckBackupCodes($this->jobList);
+ }
+
+ public function testGetName(): void {
+ $this->assertSame('Add background job to check for backup codes', $this->checkBackupsCodes->getName());
+ }
+
+ public function testRun(): void {
+ $this->jobList->expects($this->once())
+ ->method('add')
+ ->with(
+ $this->equalTo(\OCA\TwoFactorBackupCodes\BackgroundJob\CheckBackupCodes::class)
+ );
+
+ $this->checkBackupsCodes->run($this->createMock(IOutput::class));
+ }
+}
diff --git a/apps/twofactor_backupcodes/tests/Unit/Notification/NotifierTest.php b/apps/twofactor_backupcodes/tests/Unit/Notification/NotifierTest.php
new file mode 100644
index 00000000000..b091d57dbd2
--- /dev/null
+++ b/apps/twofactor_backupcodes/tests/Unit/Notification/NotifierTest.php
@@ -0,0 +1,114 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Tests\Unit\Notification;
+
+use OCA\TwoFactorBackupCodes\Notifications\Notifier;
+use OCP\IL10N;
+use OCP\IURLGenerator;
+use OCP\L10N\IFactory;
+use OCP\Notification\INotification;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+class NotifierTest extends TestCase {
+ protected IFactory&MockObject $factory;
+ protected IURLGenerator&MockObject $url;
+ protected IL10N&MockObject $l;
+ protected Notifier $notifier;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->l = $this->createMock(IL10N::class);
+ $this->l->expects($this->any())
+ ->method('t')
+ ->willReturnCallback(function ($string, $args) {
+ return vsprintf($string, $args);
+ });
+ $this->factory = $this->createMock(IFactory::class);
+ $this->url = $this->createMock(IURLGenerator::class);
+ $this->factory->expects($this->any())
+ ->method('get')
+ ->willReturn($this->l);
+
+ $this->notifier = new Notifier(
+ $this->factory,
+ $this->url
+ );
+ }
+
+
+ public function testPrepareWrongApp(): void {
+ $this->expectException(\InvalidArgumentException::class);
+
+ /** @var INotification|MockObject $notification */
+ $notification = $this->createMock(INotification::class);
+ $notification->expects($this->once())
+ ->method('getApp')
+ ->willReturn('notifications');
+ $notification->expects($this->never())
+ ->method('getSubject');
+
+ $this->notifier->prepare($notification, 'en');
+ }
+
+
+ public function testPrepareWrongSubject(): void {
+ $this->expectException(\InvalidArgumentException::class);
+
+ /** @var INotification|MockObject $notification */
+ $notification = $this->createMock(INotification::class);
+ $notification->expects($this->once())
+ ->method('getApp')
+ ->willReturn('twofactor_backupcodes');
+ $notification->expects($this->once())
+ ->method('getSubject')
+ ->willReturn('wrong subject');
+
+ $this->notifier->prepare($notification, 'en');
+ }
+
+ public function testPrepare(): void {
+ /** @var INotification&MockObject $notification */
+ $notification = $this->createMock(INotification::class);
+
+ $notification->expects($this->once())
+ ->method('getApp')
+ ->willReturn('twofactor_backupcodes');
+ $notification->expects($this->once())
+ ->method('getSubject')
+ ->willReturn('create_backupcodes');
+
+ $this->factory->expects($this->once())
+ ->method('get')
+ ->with('twofactor_backupcodes', 'nl')
+ ->willReturn($this->l);
+
+ $notification->expects($this->once())
+ ->method('setParsedSubject')
+ ->with('Generate backup codes')
+ ->willReturnSelf();
+ $notification->expects($this->once())
+ ->method('setParsedMessage')
+ ->with('You enabled two-factor authentication but did not generate backup codes yet. They are needed to restore access to your account in case you lose your second factor.')
+ ->willReturnSelf();
+
+ $this->url->expects($this->once())
+ ->method('linkToRouteAbsolute')
+ ->with('settings.PersonalSettings.index', ['section' => 'security'])
+ ->willReturn('linkToRouteAbsolute');
+ $notification->expects($this->once())
+ ->method('setLink')
+ ->with('linkToRouteAbsolute')
+ ->willReturnSelf();
+
+ $return = $this->notifier->prepare($notification, 'nl');
+ $this->assertEquals($notification, $return);
+ }
+}
diff --git a/apps/twofactor_backupcodes/tests/Unit/Provider/BackupCodesProviderTest.php b/apps/twofactor_backupcodes/tests/Unit/Provider/BackupCodesProviderTest.php
new file mode 100644
index 00000000000..512374fca8c
--- /dev/null
+++ b/apps/twofactor_backupcodes/tests/Unit/Provider/BackupCodesProviderTest.php
@@ -0,0 +1,153 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Tests\Unit\Provider;
+
+use OC\App\AppManager;
+use OCA\TwoFactorBackupCodes\Provider\BackupCodesProvider;
+use OCA\TwoFactorBackupCodes\Service\BackupCodeStorage;
+use OCP\AppFramework\Services\IInitialState;
+use OCP\IL10N;
+use OCP\IUser;
+use OCP\Server;
+use OCP\Template\ITemplateManager;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+class BackupCodesProviderTest extends TestCase {
+ private string $appName;
+
+ private BackupCodeStorage&MockObject $storage;
+ private IL10N&MockObject $l10n;
+ private AppManager&MockObject $appManager;
+ private IInitialState&MockObject $initialState;
+
+ private ITemplateManager $templateManager;
+ private BackupCodesProvider $provider;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->appName = 'twofactor_backupcodes';
+ $this->storage = $this->createMock(BackupCodeStorage::class);
+ $this->l10n = $this->createMock(IL10N::class);
+ $this->appManager = $this->createMock(AppManager::class);
+ $this->initialState = $this->createMock(IInitialState::class);
+ $this->templateManager = Server::get(ITemplateManager::class);
+
+ $this->provider = new BackupCodesProvider(
+ $this->appName,
+ $this->storage,
+ $this->l10n,
+ $this->appManager,
+ $this->initialState,
+ $this->templateManager,
+ );
+ }
+
+ public function testGetId(): void {
+ $this->assertEquals('backup_codes', $this->provider->getId());
+ }
+
+ public function testGetDisplayName(): void {
+ $this->l10n->expects($this->once())
+ ->method('t')
+ ->with('Backup code')
+ ->willReturn('l10n backup code');
+ $this->assertSame('l10n backup code', $this->provider->getDisplayName());
+ }
+
+ public function testGetDescription(): void {
+ $this->l10n->expects($this->once())
+ ->method('t')
+ ->with('Use backup code')
+ ->willReturn('l10n use backup code');
+ $this->assertSame('l10n use backup code', $this->provider->getDescription());
+ }
+
+ public function testGetTempalte(): void {
+ $user = $this->getMockBuilder(IUser::class)->getMock();
+ $expected = $this->templateManager->getTemplate('twofactor_backupcodes', 'challenge');
+
+ $this->assertEquals($expected, $this->provider->getTemplate($user));
+ }
+
+ public function testVerfiyChallenge(): void {
+ $user = $this->getMockBuilder(IUser::class)->getMock();
+ $challenge = 'xyz';
+
+ $this->storage->expects($this->once())
+ ->method('validateCode')
+ ->with($user, $challenge)
+ ->willReturn(false);
+
+ $this->assertFalse($this->provider->verifyChallenge($user, $challenge));
+ }
+
+ public function testIsTwoFactorEnabledForUser(): void {
+ $user = $this->getMockBuilder(IUser::class)->getMock();
+
+ $this->storage->expects($this->once())
+ ->method('hasBackupCodes')
+ ->with($user)
+ ->willReturn(true);
+
+ $this->assertTrue($this->provider->isTwoFactorAuthEnabledForUser($user));
+ }
+
+ public function testIsActiveNoProviders(): void {
+ $user = $this->getMockBuilder(IUser::class)->getMock();
+
+ $this->appManager->expects($this->once())
+ ->method('getEnabledAppsForUser')
+ ->with($user)
+ ->willReturn([
+ 'twofactor_backupcodes',
+ 'mail',
+ ]);
+ $this->appManager->expects($this->once())
+ ->method('getAppInfo')
+ ->with('mail')
+ ->willReturn([
+ 'two-factor-providers' => [],
+ ]);
+
+ $this->assertFalse($this->provider->isActive($user));
+ }
+
+ public function testIsActiveWithProviders(): void {
+ $user = $this->getMockBuilder(IUser::class)->getMock();
+
+ $this->appManager->expects($this->once())
+ ->method('getEnabledAppsForUser')
+ ->with($user)
+ ->willReturn([
+ 'twofactor_backupcodes',
+ 'twofactor_u2f',
+ ]);
+ $this->appManager->expects($this->once())
+ ->method('getAppInfo')
+ ->with('twofactor_u2f')
+ ->willReturn([
+ 'two-factor-providers' => [
+ 'OCA\TwoFactorU2F\Provider\U2FProvider',
+ ],
+ ]);
+
+ $this->assertTrue($this->provider->isActive($user));
+ }
+
+ public function testDisable(): void {
+ $user = $this->getMockBuilder(IUser::class)->getMock();
+ $this->storage->expects(self::once())
+ ->method('deleteCodes')
+ ->with($user);
+
+ $this->provider->disableFor($user);
+ }
+}
diff --git a/apps/twofactor_backupcodes/tests/Unit/Service/BackupCodeStorageTest.php b/apps/twofactor_backupcodes/tests/Unit/Service/BackupCodeStorageTest.php
new file mode 100644
index 00000000000..069e50b71fd
--- /dev/null
+++ b/apps/twofactor_backupcodes/tests/Unit/Service/BackupCodeStorageTest.php
@@ -0,0 +1,220 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\TwoFactorBackupCodes\Tests\Unit\Service;
+
+use OCA\TwoFactorBackupCodes\Db\BackupCode;
+use OCA\TwoFactorBackupCodes\Db\BackupCodeMapper;
+use OCA\TwoFactorBackupCodes\Event\CodesGenerated;
+use OCA\TwoFactorBackupCodes\Service\BackupCodeStorage;
+use OCP\EventDispatcher\IEventDispatcher;
+use OCP\IUser;
+use OCP\Security\IHasher;
+use OCP\Security\ISecureRandom;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+class BackupCodeStorageTest extends TestCase {
+ private BackupCodeMapper&MockObject $mapper;
+ private ISecureRandom&MockObject $random;
+ private IHasher&MockObject $hasher;
+ private IEventDispatcher&MockObject $eventDispatcher;
+ private BackupCodeStorage $storage;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->mapper = $this->createMock(BackupCodeMapper::class);
+ $this->random = $this->createMock(ISecureRandom::class);
+ $this->hasher = $this->createMock(IHasher::class);
+ $this->eventDispatcher = $this->createMock(IEventDispatcher::class);
+
+ $this->storage = new BackupCodeStorage($this->mapper, $this->random, $this->hasher, $this->eventDispatcher);
+ }
+
+ public function testCreateCodes(): void {
+ $user = $this->createMock(IUser::class);
+ $number = 5;
+ $user->method('getUID')->willReturn('fritz');
+ $this->random->expects($this->exactly($number))
+ ->method('generate')
+ ->with(16, ISecureRandom::CHAR_HUMAN_READABLE)
+ ->willReturn('CODEABCDEF');
+ $this->hasher->expects($this->exactly($number))
+ ->method('hash')
+ ->with('CODEABCDEF')
+ ->willReturn('HASHEDCODE');
+ $row = new BackupCode();
+ $row->setUserId('fritz');
+ $row->setCode('HASHEDCODE');
+ $row->setUsed(0);
+ $this->mapper->expects($this->exactly($number))
+ ->method('insert')
+ ->with($this->equalTo($row));
+ $this->eventDispatcher->expects($this->once())
+ ->method('dispatchTyped')
+ ->with(
+ $this->equalTo(new CodesGenerated($user))
+ );
+
+ $codes = $this->storage->createCodes($user, $number);
+ $this->assertCount($number, $codes);
+ foreach ($codes as $code) {
+ $this->assertEquals('CODEABCDEF', $code);
+ }
+ }
+
+ public function testHasBackupCodes(): void {
+ $user = $this->createMock(IUser::class);
+ $codes = [
+ new BackupCode(),
+ new BackupCode(),
+ ];
+
+ $this->mapper->expects($this->once())
+ ->method('getBackupCodes')
+ ->with($user)
+ ->willReturn($codes);
+
+ $this->assertTrue($this->storage->hasBackupCodes($user));
+ }
+
+ public function testHasBackupCodesNoCodes(): void {
+ $user = $this->createMock(IUser::class);
+ $codes = [];
+
+ $this->mapper->expects($this->once())
+ ->method('getBackupCodes')
+ ->with($user)
+ ->willReturn($codes);
+
+ $this->assertFalse($this->storage->hasBackupCodes($user));
+ }
+
+ public function testGetBackupCodeState(): void {
+ $user = $this->createMock(IUser::class);
+
+ $code1 = new BackupCode();
+ $code1->setUsed(1);
+ $code2 = new BackupCode();
+ $code2->setUsed('0');
+ $codes = [
+ $code1,
+ $code2,
+ ];
+
+ $this->mapper->expects($this->once())
+ ->method('getBackupCodes')
+ ->with($user)
+ ->willReturn($codes);
+
+ $expected = [
+ 'enabled' => true,
+ 'total' => 2,
+ 'used' => 1,
+ ];
+ $this->assertEquals($expected, $this->storage->getBackupCodesState($user));
+ }
+
+ public function testGetBackupCodeDisabled(): void {
+ $user = $this->createMock(IUser::class);
+
+ $codes = [];
+
+ $this->mapper->expects($this->once())
+ ->method('getBackupCodes')
+ ->with($user)
+ ->willReturn($codes);
+
+ $expected = [
+ 'enabled' => false,
+ 'total' => 0,
+ 'used' => 0,
+ ];
+ $this->assertEquals($expected, $this->storage->getBackupCodesState($user));
+ }
+
+ public function testValidateCode(): void {
+ $user = $this->createMock(IUser::class);
+ $code = new BackupCode();
+ $code->setUsed(0);
+ $code->setCode('HASHEDVALUE');
+ $codes = [
+ $code,
+ ];
+
+ $this->mapper->expects($this->once())
+ ->method('getBackupCodes')
+ ->with($user)
+ ->willReturn($codes);
+ $this->hasher->expects($this->once())
+ ->method('verify')
+ ->with('CHALLENGE', 'HASHEDVALUE', $this->anything())
+ ->willReturn(true);
+ $this->mapper->expects($this->once())
+ ->method('update')
+ ->with($code);
+
+ $this->assertTrue($this->storage->validateCode($user, 'CHALLENGE'));
+
+ $this->assertEquals(1, $code->getUsed());
+ }
+
+ public function testValidateUsedCode(): void {
+ $user = $this->createMock(IUser::class);
+ $code = new BackupCode();
+ $code->setUsed('1');
+ $code->setCode('HASHEDVALUE');
+ $codes = [
+ $code,
+ ];
+
+ $this->mapper->expects($this->once())
+ ->method('getBackupCodes')
+ ->with($user)
+ ->willReturn($codes);
+ $this->hasher->expects($this->never())
+ ->method('verify');
+ $this->mapper->expects($this->never())
+ ->method('update');
+
+ $this->assertFalse($this->storage->validateCode($user, 'CHALLENGE'));
+ }
+
+ public function testValidateCodeWithWrongHash(): void {
+ $user = $this->createMock(IUser::class);
+ $code = new BackupCode();
+ $code->setUsed(0);
+ $code->setCode('HASHEDVALUE');
+ $codes = [
+ $code,
+ ];
+
+ $this->mapper->expects($this->once())
+ ->method('getBackupCodes')
+ ->with($user)
+ ->willReturn($codes);
+ $this->hasher->expects($this->once())
+ ->method('verify')
+ ->with('CHALLENGE', 'HASHEDVALUE')
+ ->willReturn(false);
+ $this->mapper->expects($this->never())
+ ->method('update');
+
+ $this->assertFalse($this->storage->validateCode($user, 'CHALLENGE'));
+ }
+
+ public function testDeleteCodes(): void {
+ $user = $this->createMock(IUser::class);
+ $this->mapper->expects($this->once())
+ ->method('deleteCodes')
+ ->with($user);
+
+ $this->storage->deleteCodes($user);
+ }
+}