aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/base.php17
-rw-r--r--lib/composer/composer/autoload_classmap.php1
-rw-r--r--lib/composer/composer/autoload_static.php1
-rw-r--r--lib/l10n/cs.js1
-rw-r--r--lib/l10n/cs.json1
-rw-r--r--lib/l10n/da.js1
-rw-r--r--lib/l10n/da.json1
-rw-r--r--lib/l10n/de.js1
-rw-r--r--lib/l10n/de.json1
-rw-r--r--lib/l10n/de_DE.js1
-rw-r--r--lib/l10n/de_DE.json1
-rw-r--r--lib/l10n/es.js1
-rw-r--r--lib/l10n/es.json1
-rw-r--r--lib/l10n/et_EE.js11
-rw-r--r--lib/l10n/et_EE.json11
-rw-r--r--lib/l10n/ga.js1
-rw-r--r--lib/l10n/ga.json1
-rw-r--r--lib/l10n/ja.js1
-rw-r--r--lib/l10n/ja.json1
-rw-r--r--lib/l10n/lv.js1
-rw-r--r--lib/l10n/lv.json1
-rw-r--r--lib/l10n/pt_BR.js7
-rw-r--r--lib/l10n/pt_BR.json7
-rw-r--r--lib/l10n/sr.js1
-rw-r--r--lib/l10n/sr.json1
-rw-r--r--lib/l10n/sv.js23
-rw-r--r--lib/l10n/sv.json23
-rw-r--r--lib/l10n/zh_CN.js1
-rw-r--r--lib/l10n/zh_CN.json1
-rw-r--r--lib/l10n/zh_TW.js1
-rw-r--r--lib/l10n/zh_TW.json1
-rw-r--r--lib/private/App/AppManager.php51
-rw-r--r--lib/private/AppFramework/Bootstrap/Coordinator.php4
-rw-r--r--lib/private/AppFramework/Http/Dispatcher.php8
-rw-r--r--lib/private/Federation/CloudIdManager.php5
-rw-r--r--lib/private/Files/ObjectStore/S3ConnectionTrait.php4
-rw-r--r--lib/private/Log/LogDetails.php2
-rw-r--r--lib/private/Mail/EMailTemplate.php4
-rw-r--r--lib/private/Preview/Generator.php48
-rw-r--r--lib/private/PreviewManager.php11
-rw-r--r--lib/private/Profile/ProfileManager.php6
-rw-r--r--lib/private/Profiler/BuiltInProfiler.php95
-rw-r--r--lib/private/Security/Normalizer/IpAddress.php15
-rw-r--r--lib/private/Template/JSConfigHelper.php2
-rw-r--r--lib/private/User/DisplayNameCache.php6
-rw-r--r--lib/private/User/Manager.php19
-rw-r--r--lib/public/AppFramework/Bootstrap/IBootstrap.php2
-rw-r--r--lib/public/IUser.php5
-rw-r--r--lib/public/Profile/IProfileManager.php4
49 files changed, 313 insertions, 101 deletions
diff --git a/lib/base.php b/lib/base.php
index 0ed282eff00..aa463e206a3 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -7,6 +7,7 @@ declare(strict_types=1);
* SPDX-License-Identifier: AGPL-3.0-only
*/
use OC\Encryption\HookManager;
+use OC\Profiler\BuiltInProfiler;
use OC\Share20\GroupDeletedListener;
use OC\Share20\Hooks;
use OC\Share20\UserDeletedListener;
@@ -14,6 +15,7 @@ use OC\Share20\UserRemovedListener;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Group\Events\GroupDeletedEvent;
use OCP\Group\Events\UserRemovedEvent;
+use OCP\IConfig;
use OCP\ILogger;
use OCP\IRequest;
use OCP\IURLGenerator;
@@ -126,7 +128,6 @@ class OC {
}
}
-
if (OC::$CLI) {
OC::$WEBROOT = self::$config->getValue('overwritewebroot', '');
} else {
@@ -522,7 +523,7 @@ class OC {
* We use an additional cookie since we want to protect logout CSRF and
* also we can't directly interfere with PHP's session mechanism.
*/
- private static function performSameSiteCookieProtection(\OCP\IConfig $config): void {
+ private static function performSameSiteCookieProtection(IConfig $config): void {
$request = Server::get(IRequest::class);
// Some user agents are notorious and don't really properly follow HTTP
@@ -635,6 +636,16 @@ class OC {
self::$server = new \OC\Server(\OC::$WEBROOT, self::$config);
self::$server->boot();
+ try {
+ $profiler = new BuiltInProfiler(
+ Server::get(IConfig::class),
+ Server::get(IRequest::class),
+ );
+ $profiler->start();
+ } catch (\Throwable $e) {
+ logger('core')->error('Failed to start profiler: ' . $e->getMessage(), ['app' => 'base']);
+ }
+
if (self::$CLI && in_array('--' . \OCP\Console\ReservedOptions::DEBUG_LOG, $_SERVER['argv'])) {
\OC\Core\Listener\BeforeMessageLoggedEventListener::setup();
}
@@ -654,7 +665,7 @@ class OC {
// initialize intl fallback if necessary
OC_Util::isSetLocaleWorking();
- $config = Server::get(\OCP\IConfig::class);
+ $config = Server::get(IConfig::class);
if (!defined('PHPUNIT_RUN')) {
$errorHandler = new OC\Log\ErrorHandler(
\OCP\Server::get(\Psr\Log\LoggerInterface::class),
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 670a719c9fb..1f3d9d3813b 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -1852,6 +1852,7 @@ return array(
'OC\\Profile\\Actions\\WebsiteAction' => $baseDir . '/lib/private/Profile/Actions/WebsiteAction.php',
'OC\\Profile\\ProfileManager' => $baseDir . '/lib/private/Profile/ProfileManager.php',
'OC\\Profile\\TProfileHelper' => $baseDir . '/lib/private/Profile/TProfileHelper.php',
+ 'OC\\Profiler\\BuiltInProfiler' => $baseDir . '/lib/private/Profiler/BuiltInProfiler.php',
'OC\\Profiler\\FileProfilerStorage' => $baseDir . '/lib/private/Profiler/FileProfilerStorage.php',
'OC\\Profiler\\Profile' => $baseDir . '/lib/private/Profiler/Profile.php',
'OC\\Profiler\\Profiler' => $baseDir . '/lib/private/Profiler/Profiler.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index c15d9d5b53c..8c87d90156d 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -1893,6 +1893,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Profile\\Actions\\WebsiteAction' => __DIR__ . '/../../..' . '/lib/private/Profile/Actions/WebsiteAction.php',
'OC\\Profile\\ProfileManager' => __DIR__ . '/../../..' . '/lib/private/Profile/ProfileManager.php',
'OC\\Profile\\TProfileHelper' => __DIR__ . '/../../..' . '/lib/private/Profile/TProfileHelper.php',
+ 'OC\\Profiler\\BuiltInProfiler' => __DIR__ . '/../../..' . '/lib/private/Profiler/BuiltInProfiler.php',
'OC\\Profiler\\FileProfilerStorage' => __DIR__ . '/../../..' . '/lib/private/Profiler/FileProfilerStorage.php',
'OC\\Profiler\\Profile' => __DIR__ . '/../../..' . '/lib/private/Profiler/Profile.php',
'OC\\Profiler\\Profiler' => __DIR__ . '/../../..' . '/lib/private/Profiler/Profiler.php',
diff --git a/lib/l10n/cs.js b/lib/l10n/cs.js
index 34ca14240eb..06f4631fa3c 100644
--- a/lib/l10n/cs.js
+++ b/lib/l10n/cs.js
@@ -273,6 +273,7 @@ OC.L10N.register(
"A valid Login must be provided" : "Je třeba zadat platné přihlašovací jméno",
"Login contains whitespace at the beginning or at the end" : "Přihlašovací jméno je chybné – na jeho začátku či konci se nachází prázdný znak (mezera, tabulátor, atp.)",
"Login must not consist of dots only" : "Přihlašovací jméno se nemůže skládat pouze ze samých teček",
+ "Login is too long" : "Přihlašovací jméno je příliš dlouhé",
"Login is invalid because files already exist for this user" : "Přihlašovací jméno není platné, protože protože pro tohoto uživatele už existují soubory",
"Account disabled" : "Účet znepřístupněn",
"Login canceled by app" : "Přihlášení zrušeno aplikací",
diff --git a/lib/l10n/cs.json b/lib/l10n/cs.json
index df05f9e91f9..0fd7ca64748 100644
--- a/lib/l10n/cs.json
+++ b/lib/l10n/cs.json
@@ -271,6 +271,7 @@
"A valid Login must be provided" : "Je třeba zadat platné přihlašovací jméno",
"Login contains whitespace at the beginning or at the end" : "Přihlašovací jméno je chybné – na jeho začátku či konci se nachází prázdný znak (mezera, tabulátor, atp.)",
"Login must not consist of dots only" : "Přihlašovací jméno se nemůže skládat pouze ze samých teček",
+ "Login is too long" : "Přihlašovací jméno je příliš dlouhé",
"Login is invalid because files already exist for this user" : "Přihlašovací jméno není platné, protože protože pro tohoto uživatele už existují soubory",
"Account disabled" : "Účet znepřístupněn",
"Login canceled by app" : "Přihlášení zrušeno aplikací",
diff --git a/lib/l10n/da.js b/lib/l10n/da.js
index 6cd7bef6a20..05e77f8d59e 100644
--- a/lib/l10n/da.js
+++ b/lib/l10n/da.js
@@ -273,6 +273,7 @@ OC.L10N.register(
"A valid Login must be provided" : "Et gyldigt login skal angives",
"Login contains whitespace at the beginning or at the end" : "Login indeholder mellemrum i begyndelsen eller slutningen",
"Login must not consist of dots only" : "Login må ikke kun bestå af prikker",
+ "Login is too long" : "Login er for lang",
"Login is invalid because files already exist for this user" : "Login er ugyldigt, fordi filer allerede eksisterer for denne bruger",
"Account disabled" : "Konto deaktiveret",
"Login canceled by app" : "Login annulleret af app",
diff --git a/lib/l10n/da.json b/lib/l10n/da.json
index 7a290e23567..107ff24a9fb 100644
--- a/lib/l10n/da.json
+++ b/lib/l10n/da.json
@@ -271,6 +271,7 @@
"A valid Login must be provided" : "Et gyldigt login skal angives",
"Login contains whitespace at the beginning or at the end" : "Login indeholder mellemrum i begyndelsen eller slutningen",
"Login must not consist of dots only" : "Login må ikke kun bestå af prikker",
+ "Login is too long" : "Login er for lang",
"Login is invalid because files already exist for this user" : "Login er ugyldigt, fordi filer allerede eksisterer for denne bruger",
"Account disabled" : "Konto deaktiveret",
"Login canceled by app" : "Login annulleret af app",
diff --git a/lib/l10n/de.js b/lib/l10n/de.js
index 80ee4b12c26..565432632e8 100644
--- a/lib/l10n/de.js
+++ b/lib/l10n/de.js
@@ -273,6 +273,7 @@ OC.L10N.register(
"A valid Login must be provided" : "Ein gültiger Anmeldename muss eingegeben werden.",
"Login contains whitespace at the beginning or at the end" : "Anmeldename enthält Leerzeichen am Anfang oder am Ende",
"Login must not consist of dots only" : "Der Anmeldename darf nicht nur aus Punkten bestehen",
+ "Login is too long" : "Die Anmeldung dauert zu lange",
"Login is invalid because files already exist for this user" : "Der Anmeldename ist ungültig, da bereits Dateien von diesem Konto existieren",
"Account disabled" : "Konto deaktiviert",
"Login canceled by app" : "Anmeldung durch die App abgebrochen",
diff --git a/lib/l10n/de.json b/lib/l10n/de.json
index 1377f4020cd..f9b01867ab0 100644
--- a/lib/l10n/de.json
+++ b/lib/l10n/de.json
@@ -271,6 +271,7 @@
"A valid Login must be provided" : "Ein gültiger Anmeldename muss eingegeben werden.",
"Login contains whitespace at the beginning or at the end" : "Anmeldename enthält Leerzeichen am Anfang oder am Ende",
"Login must not consist of dots only" : "Der Anmeldename darf nicht nur aus Punkten bestehen",
+ "Login is too long" : "Die Anmeldung dauert zu lange",
"Login is invalid because files already exist for this user" : "Der Anmeldename ist ungültig, da bereits Dateien von diesem Konto existieren",
"Account disabled" : "Konto deaktiviert",
"Login canceled by app" : "Anmeldung durch die App abgebrochen",
diff --git a/lib/l10n/de_DE.js b/lib/l10n/de_DE.js
index 9b074d7053c..d43d052a549 100644
--- a/lib/l10n/de_DE.js
+++ b/lib/l10n/de_DE.js
@@ -273,6 +273,7 @@ OC.L10N.register(
"A valid Login must be provided" : "Ein gültiger Anmeldename muss angegeben werden.",
"Login contains whitespace at the beginning or at the end" : "Anmeldename enthält Leerzeichen am Anfang oder am Ende",
"Login must not consist of dots only" : "Der Anmeldename darf nicht nur aus Punkten bestehen",
+ "Login is too long" : "Die Anmeldung dauert zu lange",
"Login is invalid because files already exist for this user" : "Der Anmeldename ist ungültig, da bereits Dateien von diesem Benutzer existieren",
"Account disabled" : "Konto deaktiviert",
"Login canceled by app" : "Anmeldung durch die App abgebrochen",
diff --git a/lib/l10n/de_DE.json b/lib/l10n/de_DE.json
index 4317c73a212..9e974ad5fac 100644
--- a/lib/l10n/de_DE.json
+++ b/lib/l10n/de_DE.json
@@ -271,6 +271,7 @@
"A valid Login must be provided" : "Ein gültiger Anmeldename muss angegeben werden.",
"Login contains whitespace at the beginning or at the end" : "Anmeldename enthält Leerzeichen am Anfang oder am Ende",
"Login must not consist of dots only" : "Der Anmeldename darf nicht nur aus Punkten bestehen",
+ "Login is too long" : "Die Anmeldung dauert zu lange",
"Login is invalid because files already exist for this user" : "Der Anmeldename ist ungültig, da bereits Dateien von diesem Benutzer existieren",
"Account disabled" : "Konto deaktiviert",
"Login canceled by app" : "Anmeldung durch die App abgebrochen",
diff --git a/lib/l10n/es.js b/lib/l10n/es.js
index 4d7b8700c51..94e52dbc724 100644
--- a/lib/l10n/es.js
+++ b/lib/l10n/es.js
@@ -273,6 +273,7 @@ OC.L10N.register(
"A valid Login must be provided" : "Se debe proporcionar un usuario válido",
"Login contains whitespace at the beginning or at the end" : "El usuario contiene espacios en blanco al inicio o al final",
"Login must not consist of dots only" : "El usuario no debe consistir sólo de puntos",
+ "Login is too long" : "El nombre de inicio de sesión es demasiado largo",
"Login is invalid because files already exist for this user" : "El nombre de inicio de sesión es inválido porque ya existen archivos para este usuario",
"Account disabled" : "Cuenta deshabilitada",
"Login canceled by app" : "Login cancelado por la app",
diff --git a/lib/l10n/es.json b/lib/l10n/es.json
index 3d9f223880a..61f519db2a7 100644
--- a/lib/l10n/es.json
+++ b/lib/l10n/es.json
@@ -271,6 +271,7 @@
"A valid Login must be provided" : "Se debe proporcionar un usuario válido",
"Login contains whitespace at the beginning or at the end" : "El usuario contiene espacios en blanco al inicio o al final",
"Login must not consist of dots only" : "El usuario no debe consistir sólo de puntos",
+ "Login is too long" : "El nombre de inicio de sesión es demasiado largo",
"Login is invalid because files already exist for this user" : "El nombre de inicio de sesión es inválido porque ya existen archivos para este usuario",
"Account disabled" : "Cuenta deshabilitada",
"Login canceled by app" : "Login cancelado por la app",
diff --git a/lib/l10n/et_EE.js b/lib/l10n/et_EE.js
index c75e79941dd..7a32b1cec33 100644
--- a/lib/l10n/et_EE.js
+++ b/lib/l10n/et_EE.js
@@ -153,10 +153,19 @@ OC.L10N.register(
"%1$s shared %2$s with you and wants to add:" : "%1$s jagas sinuga %2$s ning soovib lisada:",
"%1$s shared %2$s with you and wants to add" : "%1$s jagas sinuga %2$s ning soovib lisada",
"%s added a note to a file shared with you" : "%s jagas koos sulle jagatud failiga ka märget",
+ "Share recipient is not a valid user" : "Jaosmeedia vastuvõtja pole korrektne kasutaja",
+ "Share recipient is not a valid group" : "Jaosmeedia vastuvõtja pole korrektne grupp",
+ "Share recipient should be empty" : "Jaosmeedia vastuvõtja peaks jääma tühjaks",
+ "Share recipient should not be empty" : "Jaosmeedia vastuvõtja ei tohi jääda tühjaks",
+ "Share recipient is not a valid circle" : "Jaosmeedia vastuvõtja pole korrektne tiim",
"Unknown share type" : "Tundmatu jagamise tüüp",
+ "Share initiator must be set" : "Jagamise alustaja peab olema määratud",
"Cannot share with yourself" : "Sa ei saa iseendale jagada",
+ "Shared path must be set" : "Jagamise asukoht peab olema teada",
+ "Shared path must be either a file or a folder" : "Jagamise asukoht peab olema kas kaust või fail",
"You cannot share your root folder" : "Sa ei saa juurkausta jagada",
"You are not allowed to share %s" : "Sul pole lubatud %s jagada",
+ "Valid permissions are required for sharing" : "Jagamiseks peavad olema korrektsed õigused",
"File shares cannot have create or delete permissions" : "Jaosfailidel ei saa olla loomis- või kustutamisõigusi",
"Cannot increase permissions of %s" : "Ei saa %s õigusi suurendada",
"Shares need at least read permissions" : "Jaosmeedial peab olema vähemalt lugemisõigus",
@@ -175,6 +184,7 @@ OC.L10N.register(
"Sharing is disabled for you" : "Jagamine pole sinu jaoks kasutusel",
"Cannot share with the share owner" : "Sa ei saa jagada jaosmeedia omanikule",
"Cannot change share type" : "Sa ei saa muuta jaosmeedia tüüpi",
+ "Invalid share recipient" : "Vigane jaosmeedia vastuvõtja",
"Group \"%s\" does not exist" : "„%s“ gruppi pole olemas",
"The requested share does not exist anymore" : "Soovitud jagamist enam ei eksisteeri",
"Could not find category \"%s\"" : "Ei leia kategooriat \"%s\"",
@@ -228,6 +238,7 @@ OC.L10N.register(
"A valid password must be provided" : "Sisesta nõuetele vastav parool",
"The Login is already being used" : "See kasutajanimi on juba kasutusel",
"Could not create account" : "Kasutajakonto loomine ei õnnestunud",
+ "Login is too long" : "Kasutajanimi on liiga pikk",
"Login canceled by app" : "Rakendus katkestas sisselogimise",
"App \"%1$s\" cannot be installed because the following dependencies are not fulfilled: %2$s" : "„%1$s“ rakendust ei saa paigaldada, sest järgnev sõltuvus on puudu: %2$s",
"a safe home for all your data" : "turvaline koht sinu andmetele",
diff --git a/lib/l10n/et_EE.json b/lib/l10n/et_EE.json
index f6f1fcfa660..e8db1891012 100644
--- a/lib/l10n/et_EE.json
+++ b/lib/l10n/et_EE.json
@@ -151,10 +151,19 @@
"%1$s shared %2$s with you and wants to add:" : "%1$s jagas sinuga %2$s ning soovib lisada:",
"%1$s shared %2$s with you and wants to add" : "%1$s jagas sinuga %2$s ning soovib lisada",
"%s added a note to a file shared with you" : "%s jagas koos sulle jagatud failiga ka märget",
+ "Share recipient is not a valid user" : "Jaosmeedia vastuvõtja pole korrektne kasutaja",
+ "Share recipient is not a valid group" : "Jaosmeedia vastuvõtja pole korrektne grupp",
+ "Share recipient should be empty" : "Jaosmeedia vastuvõtja peaks jääma tühjaks",
+ "Share recipient should not be empty" : "Jaosmeedia vastuvõtja ei tohi jääda tühjaks",
+ "Share recipient is not a valid circle" : "Jaosmeedia vastuvõtja pole korrektne tiim",
"Unknown share type" : "Tundmatu jagamise tüüp",
+ "Share initiator must be set" : "Jagamise alustaja peab olema määratud",
"Cannot share with yourself" : "Sa ei saa iseendale jagada",
+ "Shared path must be set" : "Jagamise asukoht peab olema teada",
+ "Shared path must be either a file or a folder" : "Jagamise asukoht peab olema kas kaust või fail",
"You cannot share your root folder" : "Sa ei saa juurkausta jagada",
"You are not allowed to share %s" : "Sul pole lubatud %s jagada",
+ "Valid permissions are required for sharing" : "Jagamiseks peavad olema korrektsed õigused",
"File shares cannot have create or delete permissions" : "Jaosfailidel ei saa olla loomis- või kustutamisõigusi",
"Cannot increase permissions of %s" : "Ei saa %s õigusi suurendada",
"Shares need at least read permissions" : "Jaosmeedial peab olema vähemalt lugemisõigus",
@@ -173,6 +182,7 @@
"Sharing is disabled for you" : "Jagamine pole sinu jaoks kasutusel",
"Cannot share with the share owner" : "Sa ei saa jagada jaosmeedia omanikule",
"Cannot change share type" : "Sa ei saa muuta jaosmeedia tüüpi",
+ "Invalid share recipient" : "Vigane jaosmeedia vastuvõtja",
"Group \"%s\" does not exist" : "„%s“ gruppi pole olemas",
"The requested share does not exist anymore" : "Soovitud jagamist enam ei eksisteeri",
"Could not find category \"%s\"" : "Ei leia kategooriat \"%s\"",
@@ -226,6 +236,7 @@
"A valid password must be provided" : "Sisesta nõuetele vastav parool",
"The Login is already being used" : "See kasutajanimi on juba kasutusel",
"Could not create account" : "Kasutajakonto loomine ei õnnestunud",
+ "Login is too long" : "Kasutajanimi on liiga pikk",
"Login canceled by app" : "Rakendus katkestas sisselogimise",
"App \"%1$s\" cannot be installed because the following dependencies are not fulfilled: %2$s" : "„%1$s“ rakendust ei saa paigaldada, sest järgnev sõltuvus on puudu: %2$s",
"a safe home for all your data" : "turvaline koht sinu andmetele",
diff --git a/lib/l10n/ga.js b/lib/l10n/ga.js
index 0adb89eb57b..4c1832afec9 100644
--- a/lib/l10n/ga.js
+++ b/lib/l10n/ga.js
@@ -273,6 +273,7 @@ OC.L10N.register(
"A valid Login must be provided" : "Ní mór Logáil Isteach bailí a sholáthar",
"Login contains whitespace at the beginning or at the end" : "Tá spás bán sa logáil isteach ag an tús nó ag an deireadh",
"Login must not consist of dots only" : "Níor cheart go gcuimseodh logáil isteach poncanna amháin",
+ "Login is too long" : "Tá logáil isteach ró-fhada",
"Login is invalid because files already exist for this user" : "Tá logáil isteach neamhbhailí toisc go bhfuil comhaid ann cheana don úsáideoir seo",
"Account disabled" : "Díchumasaíodh an cuntas",
"Login canceled by app" : "Cealaíodh logáil isteach ag an aip",
diff --git a/lib/l10n/ga.json b/lib/l10n/ga.json
index 80b707a55d3..9c680309924 100644
--- a/lib/l10n/ga.json
+++ b/lib/l10n/ga.json
@@ -271,6 +271,7 @@
"A valid Login must be provided" : "Ní mór Logáil Isteach bailí a sholáthar",
"Login contains whitespace at the beginning or at the end" : "Tá spás bán sa logáil isteach ag an tús nó ag an deireadh",
"Login must not consist of dots only" : "Níor cheart go gcuimseodh logáil isteach poncanna amháin",
+ "Login is too long" : "Tá logáil isteach ró-fhada",
"Login is invalid because files already exist for this user" : "Tá logáil isteach neamhbhailí toisc go bhfuil comhaid ann cheana don úsáideoir seo",
"Account disabled" : "Díchumasaíodh an cuntas",
"Login canceled by app" : "Cealaíodh logáil isteach ag an aip",
diff --git a/lib/l10n/ja.js b/lib/l10n/ja.js
index e3f2e7ea7cd..c3c82dc9b17 100644
--- a/lib/l10n/ja.js
+++ b/lib/l10n/ja.js
@@ -273,6 +273,7 @@ OC.L10N.register(
"A valid Login must be provided" : "ログイン名を提供する必要があります",
"Login contains whitespace at the beginning or at the end" : "ログイン名の最初か最後に空白が含まれています",
"Login must not consist of dots only" : "ログイン名はドットのみで構成されてはいけません",
+ "Login is too long" : "ログインが長すぎます",
"Login is invalid because files already exist for this user" : "このユーザのファイルが既に存在するため、このログイン名は使用できません",
"Account disabled" : "アカウントは無効",
"Login canceled by app" : "アプリによりログインが中止されました",
diff --git a/lib/l10n/ja.json b/lib/l10n/ja.json
index 5419c0da23d..cd55a7d7703 100644
--- a/lib/l10n/ja.json
+++ b/lib/l10n/ja.json
@@ -271,6 +271,7 @@
"A valid Login must be provided" : "ログイン名を提供する必要があります",
"Login contains whitespace at the beginning or at the end" : "ログイン名の最初か最後に空白が含まれています",
"Login must not consist of dots only" : "ログイン名はドットのみで構成されてはいけません",
+ "Login is too long" : "ログインが長すぎます",
"Login is invalid because files already exist for this user" : "このユーザのファイルが既に存在するため、このログイン名は使用できません",
"Account disabled" : "アカウントは無効",
"Login canceled by app" : "アプリによりログインが中止されました",
diff --git a/lib/l10n/lv.js b/lib/l10n/lv.js
index 4144a89751c..a201c8c6081 100644
--- a/lib/l10n/lv.js
+++ b/lib/l10n/lv.js
@@ -20,6 +20,7 @@ OC.L10N.register(
"%sbit or higher PHP required." : "Nepieciešams %sbit vai jaunāks PHP.",
"The command line tool %s could not be found" : "Komandrindas rīku %s nevarēja atrast",
"The library %s is not available." : "Bibliotēka %s nav pieejama.",
+ "The following platforms are supported: %s" : "Tiek atbalstītas šīs platformas: %s",
"Server version %s or higher is required." : "Ir nepieciešama servera versija %s vai jaunāka.",
"Server version %s or lower is required." : "Ir nepieciešama servera versija %s vai vecāka.",
"Authentication" : "Autentifikācija",
diff --git a/lib/l10n/lv.json b/lib/l10n/lv.json
index ce7a6fcf83d..6ae08bbf873 100644
--- a/lib/l10n/lv.json
+++ b/lib/l10n/lv.json
@@ -18,6 +18,7 @@
"%sbit or higher PHP required." : "Nepieciešams %sbit vai jaunāks PHP.",
"The command line tool %s could not be found" : "Komandrindas rīku %s nevarēja atrast",
"The library %s is not available." : "Bibliotēka %s nav pieejama.",
+ "The following platforms are supported: %s" : "Tiek atbalstītas šīs platformas: %s",
"Server version %s or higher is required." : "Ir nepieciešama servera versija %s vai jaunāka.",
"Server version %s or lower is required." : "Ir nepieciešama servera versija %s vai vecāka.",
"Authentication" : "Autentifikācija",
diff --git a/lib/l10n/pt_BR.js b/lib/l10n/pt_BR.js
index fb3b36789cf..8e242ad9340 100644
--- a/lib/l10n/pt_BR.js
+++ b/lib/l10n/pt_BR.js
@@ -73,15 +73,15 @@ OC.L10N.register(
"next month" : "Mês que vem",
"last month" : "último mês",
"_in %n month_::_in %n months_" : ["em %n mês","em %n meses","em %n meses"],
- "_%n month ago_::_%n months ago_" : ["há %n mês atrás","há %n meses","há %n meses"],
+ "_%n month ago_::_%n months ago_" : ["%n mês atrás","%n meses atrás","%n meses atrás"],
"next year" : "próximo ano",
"last year" : "último ano",
"_in %n year_::_in %n years_" : ["em %n ano","em %n anos","em %n anos"],
"_%n year ago_::_%n years ago_" : ["%n ano atrás","%n anos atrás","%n anos atrás"],
"_in %n hour_::_in %n hours_" : ["em %n hora","em %n horas","em %n horas"],
- "_%n hour ago_::_%n hours ago_" : ["há %n hora atrás","há %n horas","há %n horas"],
+ "_%n hour ago_::_%n hours ago_" : ["%n hora atrás","%n horas atrás","%n horas atrás"],
"_in %n minute_::_in %n minutes_" : ["em %n minuto","em %n minutos","em %n minutos"],
- "_%n minute ago_::_%n minutes ago_" : ["há %n minuto atrás","há %n minutos","há %n minutos"],
+ "_%n minute ago_::_%n minutes ago_" : ["%n minuto atrás","%n minutos atrás","%n minutos atrás"],
"in a few seconds" : "Em alguns segundos",
"seconds ago" : "segundos atrás",
"Empty file" : "Arquivo vazio",
@@ -273,6 +273,7 @@ OC.L10N.register(
"A valid Login must be provided" : "Um Login válido deve ser fornecido",
"Login contains whitespace at the beginning or at the end" : "O login contém espaços em branco no início ou no final",
"Login must not consist of dots only" : "O login não deve consistir apenas de pontos",
+ "Login is too long" : "O login é muito longo",
"Login is invalid because files already exist for this user" : "O login é inválido porque já existem arquivos para este usuário",
"Account disabled" : "Conta desativada",
"Login canceled by app" : "Login cancelado pelo aplicativo",
diff --git a/lib/l10n/pt_BR.json b/lib/l10n/pt_BR.json
index f9be2dc1d1a..6353e34b450 100644
--- a/lib/l10n/pt_BR.json
+++ b/lib/l10n/pt_BR.json
@@ -71,15 +71,15 @@
"next month" : "Mês que vem",
"last month" : "último mês",
"_in %n month_::_in %n months_" : ["em %n mês","em %n meses","em %n meses"],
- "_%n month ago_::_%n months ago_" : ["há %n mês atrás","há %n meses","há %n meses"],
+ "_%n month ago_::_%n months ago_" : ["%n mês atrás","%n meses atrás","%n meses atrás"],
"next year" : "próximo ano",
"last year" : "último ano",
"_in %n year_::_in %n years_" : ["em %n ano","em %n anos","em %n anos"],
"_%n year ago_::_%n years ago_" : ["%n ano atrás","%n anos atrás","%n anos atrás"],
"_in %n hour_::_in %n hours_" : ["em %n hora","em %n horas","em %n horas"],
- "_%n hour ago_::_%n hours ago_" : ["há %n hora atrás","há %n horas","há %n horas"],
+ "_%n hour ago_::_%n hours ago_" : ["%n hora atrás","%n horas atrás","%n horas atrás"],
"_in %n minute_::_in %n minutes_" : ["em %n minuto","em %n minutos","em %n minutos"],
- "_%n minute ago_::_%n minutes ago_" : ["há %n minuto atrás","há %n minutos","há %n minutos"],
+ "_%n minute ago_::_%n minutes ago_" : ["%n minuto atrás","%n minutos atrás","%n minutos atrás"],
"in a few seconds" : "Em alguns segundos",
"seconds ago" : "segundos atrás",
"Empty file" : "Arquivo vazio",
@@ -271,6 +271,7 @@
"A valid Login must be provided" : "Um Login válido deve ser fornecido",
"Login contains whitespace at the beginning or at the end" : "O login contém espaços em branco no início ou no final",
"Login must not consist of dots only" : "O login não deve consistir apenas de pontos",
+ "Login is too long" : "O login é muito longo",
"Login is invalid because files already exist for this user" : "O login é inválido porque já existem arquivos para este usuário",
"Account disabled" : "Conta desativada",
"Login canceled by app" : "Login cancelado pelo aplicativo",
diff --git a/lib/l10n/sr.js b/lib/l10n/sr.js
index 7d9c5dbf19c..187721eeb2a 100644
--- a/lib/l10n/sr.js
+++ b/lib/l10n/sr.js
@@ -273,6 +273,7 @@ OC.L10N.register(
"A valid Login must be provided" : "Морате да унесете исправно име за пријаву",
"Login contains whitespace at the beginning or at the end" : "Име за пријаву садржи белине на почетку или на крају",
"Login must not consist of dots only" : "Име за пријаву не може да се састоји само од тачака",
+ "Login is too long" : "Име за пријаву је сувише дугачко",
"Login is invalid because files already exist for this user" : "Име за пријаву није исправно пошто већ постоје фајлови овог корисника",
"Account disabled" : "Налог је искључен",
"Login canceled by app" : "Пријава отказана од стране апликације",
diff --git a/lib/l10n/sr.json b/lib/l10n/sr.json
index 8ca7ac52409..fc38faab174 100644
--- a/lib/l10n/sr.json
+++ b/lib/l10n/sr.json
@@ -271,6 +271,7 @@
"A valid Login must be provided" : "Морате да унесете исправно име за пријаву",
"Login contains whitespace at the beginning or at the end" : "Име за пријаву садржи белине на почетку или на крају",
"Login must not consist of dots only" : "Име за пријаву не може да се састоји само од тачака",
+ "Login is too long" : "Име за пријаву је сувише дугачко",
"Login is invalid because files already exist for this user" : "Име за пријаву није исправно пошто већ постоје фајлови овог корисника",
"Account disabled" : "Налог је искључен",
"Login canceled by app" : "Пријава отказана од стране апликације",
diff --git a/lib/l10n/sv.js b/lib/l10n/sv.js
index 6e25e5562b5..bc31d5b4acd 100644
--- a/lib/l10n/sv.js
+++ b/lib/l10n/sv.js
@@ -273,6 +273,7 @@ OC.L10N.register(
"A valid Login must be provided" : "En giltig inloggning måste anges",
"Login contains whitespace at the beginning or at the end" : "Inloggningen innehåller blanksteg i början eller slutet",
"Login must not consist of dots only" : "Inloggningen får inte innehålla enbart punkter",
+ "Login is too long" : "Inloggningen är för lång",
"Login is invalid because files already exist for this user" : "Inloggningen är ogiltigt eftersom det redan finns filer för den här användaren",
"Account disabled" : "Konto inaktiverat",
"Login canceled by app" : "Inloggningen avbruten av appen",
@@ -333,8 +334,15 @@ OC.L10N.register(
"Chat message" : "Chattmeddelande",
"A chat message to send to the agent." : "Ett chattmeddelande att skicka till agenten.",
"Confirmation" : "Bekräftelse",
+ "Whether to confirm previously requested actions: 0 for denial and 1 for confirmation." : "Om tidigare begärda åtgärder ska bekräftas: 0 för avslag och 1 för bekräftelse.",
+ "Conversation token" : "Konversationstoken",
+ "A token representing the conversation." : "En token som representerar konversationen.",
"Generated response" : "Genererat svar",
"The response from the chat model." : "Svaret från chattmodellen.",
+ "The new conversation token" : "Den nya konversationstoken",
+ "Send this along with the next interaction." : "Skicka detta tillsammans med nästa interaktion.",
+ "Requested actions by the agent" : "Begärda åtgärder av agenten",
+ "Actions that the agent would like to carry out in JSON format." : "Åtgärder som agenten vill utföra i JSON-format.",
"Context write" : "Kontextuell skrivning",
"Writes text in a given style based on the provided source material." : "Skriver text i en given stil baserat på det tillhandahållna källmaterialet.",
"Writing style" : "Skrivstil",
@@ -365,6 +373,8 @@ OC.L10N.register(
"Change the tone of a piece of text." : "Ändra tonfallet i ett stycke text.",
"Write a text that you want the assistant to rewrite in another tone." : "Skriv text som du vill att assistenten ska omformulera med ett annat tonfall.",
"Desired tone" : "Önskat tonfall",
+ "In which tone should your text be rewritten?" : "I vilken ton ska din text skrivas om?",
+ "The rewritten text in the desired tone, written by the assistant:" : "Den omskrivna texten i önskad ton, skriven av assistenten:",
"Chat" : "Chatt",
"Chat with the assistant" : "Chatta med assistenten",
"System prompt" : "Systemuppmaning",
@@ -373,6 +383,15 @@ OC.L10N.register(
"The history of chat messages before the current message, starting with a message by the user" : "Historiken för chattmeddelanden före det aktuella meddelandet, som börjar med ett meddelande från användaren",
"Response message" : "Svarsmeddelande",
"The generated response as part of the conversation" : "Det genererade svaret som en del av konversationen",
+ "Chat with tools" : "Chatt med verktyg",
+ "Chat with the language model with tool calling support." : "Chatt med språkmodellen med stöd för verktygsanrop.",
+ "Tool message" : "Verktygsmeddelande",
+ "The result of tool calls in the last interaction" : "Resultatet av verktygsanropen i den senaste interaktionen",
+ "Available tools" : "Tillgängliga verktyg",
+ "The available tools in JSON format" : "Tillgängliga verktyg i JSON-format",
+ "The response from the chat model" : "Svaret från chattmodellen",
+ "Tool calls" : "Verktagsanrop",
+ "Tools call instructions from the model in JSON format" : "Verktygsanrop och instruktioner från modellen i JSON-format",
"Formalize text" : "Formalisera text",
"Takes a text and makes it sound more formal" : "Tar en text och får det att låta mer formellt",
"Write a text that you want the assistant to formalize" : "Skriv en text som du vill att assistenten ska formalisera",
@@ -384,7 +403,11 @@ OC.L10N.register(
"The original text to generate a headline for" : "Den ursprungliga texten att skapa en rubrik för",
"The generated headline" : "Den skapade rubriken",
"Proofread" : "Korrekturläs",
+ "Proofreads a text and lists corrections" : "Korrekturläser en text och listar korrigeringar",
"Text" : "Text",
+ "The text to proofread" : "Texten som ska korrekturläsas",
+ "Corrections" : "Korrigeringar",
+ "The corrections that should be made in your text" : "Korrigeringarna som bör göras i din text",
"Reformulate text" : "Omformulera text",
"Takes a text and reformulates it" : "Tar en text och omformulerar den",
"Write a text that you want the assistant to reformulate" : "Skriv en text som du vill att assistenten ska formulera om",
diff --git a/lib/l10n/sv.json b/lib/l10n/sv.json
index 528a325f2f2..cc1b5183b80 100644
--- a/lib/l10n/sv.json
+++ b/lib/l10n/sv.json
@@ -271,6 +271,7 @@
"A valid Login must be provided" : "En giltig inloggning måste anges",
"Login contains whitespace at the beginning or at the end" : "Inloggningen innehåller blanksteg i början eller slutet",
"Login must not consist of dots only" : "Inloggningen får inte innehålla enbart punkter",
+ "Login is too long" : "Inloggningen är för lång",
"Login is invalid because files already exist for this user" : "Inloggningen är ogiltigt eftersom det redan finns filer för den här användaren",
"Account disabled" : "Konto inaktiverat",
"Login canceled by app" : "Inloggningen avbruten av appen",
@@ -331,8 +332,15 @@
"Chat message" : "Chattmeddelande",
"A chat message to send to the agent." : "Ett chattmeddelande att skicka till agenten.",
"Confirmation" : "Bekräftelse",
+ "Whether to confirm previously requested actions: 0 for denial and 1 for confirmation." : "Om tidigare begärda åtgärder ska bekräftas: 0 för avslag och 1 för bekräftelse.",
+ "Conversation token" : "Konversationstoken",
+ "A token representing the conversation." : "En token som representerar konversationen.",
"Generated response" : "Genererat svar",
"The response from the chat model." : "Svaret från chattmodellen.",
+ "The new conversation token" : "Den nya konversationstoken",
+ "Send this along with the next interaction." : "Skicka detta tillsammans med nästa interaktion.",
+ "Requested actions by the agent" : "Begärda åtgärder av agenten",
+ "Actions that the agent would like to carry out in JSON format." : "Åtgärder som agenten vill utföra i JSON-format.",
"Context write" : "Kontextuell skrivning",
"Writes text in a given style based on the provided source material." : "Skriver text i en given stil baserat på det tillhandahållna källmaterialet.",
"Writing style" : "Skrivstil",
@@ -363,6 +371,8 @@
"Change the tone of a piece of text." : "Ändra tonfallet i ett stycke text.",
"Write a text that you want the assistant to rewrite in another tone." : "Skriv text som du vill att assistenten ska omformulera med ett annat tonfall.",
"Desired tone" : "Önskat tonfall",
+ "In which tone should your text be rewritten?" : "I vilken ton ska din text skrivas om?",
+ "The rewritten text in the desired tone, written by the assistant:" : "Den omskrivna texten i önskad ton, skriven av assistenten:",
"Chat" : "Chatt",
"Chat with the assistant" : "Chatta med assistenten",
"System prompt" : "Systemuppmaning",
@@ -371,6 +381,15 @@
"The history of chat messages before the current message, starting with a message by the user" : "Historiken för chattmeddelanden före det aktuella meddelandet, som börjar med ett meddelande från användaren",
"Response message" : "Svarsmeddelande",
"The generated response as part of the conversation" : "Det genererade svaret som en del av konversationen",
+ "Chat with tools" : "Chatt med verktyg",
+ "Chat with the language model with tool calling support." : "Chatt med språkmodellen med stöd för verktygsanrop.",
+ "Tool message" : "Verktygsmeddelande",
+ "The result of tool calls in the last interaction" : "Resultatet av verktygsanropen i den senaste interaktionen",
+ "Available tools" : "Tillgängliga verktyg",
+ "The available tools in JSON format" : "Tillgängliga verktyg i JSON-format",
+ "The response from the chat model" : "Svaret från chattmodellen",
+ "Tool calls" : "Verktagsanrop",
+ "Tools call instructions from the model in JSON format" : "Verktygsanrop och instruktioner från modellen i JSON-format",
"Formalize text" : "Formalisera text",
"Takes a text and makes it sound more formal" : "Tar en text och får det att låta mer formellt",
"Write a text that you want the assistant to formalize" : "Skriv en text som du vill att assistenten ska formalisera",
@@ -382,7 +401,11 @@
"The original text to generate a headline for" : "Den ursprungliga texten att skapa en rubrik för",
"The generated headline" : "Den skapade rubriken",
"Proofread" : "Korrekturläs",
+ "Proofreads a text and lists corrections" : "Korrekturläser en text och listar korrigeringar",
"Text" : "Text",
+ "The text to proofread" : "Texten som ska korrekturläsas",
+ "Corrections" : "Korrigeringar",
+ "The corrections that should be made in your text" : "Korrigeringarna som bör göras i din text",
"Reformulate text" : "Omformulera text",
"Takes a text and reformulates it" : "Tar en text och omformulerar den",
"Write a text that you want the assistant to reformulate" : "Skriv en text som du vill att assistenten ska formulera om",
diff --git a/lib/l10n/zh_CN.js b/lib/l10n/zh_CN.js
index ccfec5d5b3a..818f0fdad18 100644
--- a/lib/l10n/zh_CN.js
+++ b/lib/l10n/zh_CN.js
@@ -273,6 +273,7 @@ OC.L10N.register(
"A valid Login must be provided" : "必须提供有效的登录名",
"Login contains whitespace at the beginning or at the end" : "登录名开头或结尾包含空格",
"Login must not consist of dots only" : "登录名不能仅由点组成",
+ "Login is too long" : "登录名太长",
"Login is invalid because files already exist for this user" : "登录无效,因为此用户的文件已存在",
"Account disabled" : "帐户已禁用",
"Login canceled by app" : "已通过应用取消登录",
diff --git a/lib/l10n/zh_CN.json b/lib/l10n/zh_CN.json
index 14609466bc0..bc3d5081fdc 100644
--- a/lib/l10n/zh_CN.json
+++ b/lib/l10n/zh_CN.json
@@ -271,6 +271,7 @@
"A valid Login must be provided" : "必须提供有效的登录名",
"Login contains whitespace at the beginning or at the end" : "登录名开头或结尾包含空格",
"Login must not consist of dots only" : "登录名不能仅由点组成",
+ "Login is too long" : "登录名太长",
"Login is invalid because files already exist for this user" : "登录无效,因为此用户的文件已存在",
"Account disabled" : "帐户已禁用",
"Login canceled by app" : "已通过应用取消登录",
diff --git a/lib/l10n/zh_TW.js b/lib/l10n/zh_TW.js
index 9e48c3dd6ab..95a20523c8f 100644
--- a/lib/l10n/zh_TW.js
+++ b/lib/l10n/zh_TW.js
@@ -273,6 +273,7 @@ OC.L10N.register(
"A valid Login must be provided" : "必須提供有效帳號",
"Login contains whitespace at the beginning or at the end" : "帳號的開頭或結尾有空白",
"Login must not consist of dots only" : "帳號不能只包含小數點",
+ "Login is too long" : "帳號太長了",
"Login is invalid because files already exist for this user" : "帳號無效,因為使用者的檔案已經存在",
"Account disabled" : "帳號已停用",
"Login canceled by app" : "應用程式取消了登入",
diff --git a/lib/l10n/zh_TW.json b/lib/l10n/zh_TW.json
index 55cad52a465..b9af7705ef9 100644
--- a/lib/l10n/zh_TW.json
+++ b/lib/l10n/zh_TW.json
@@ -271,6 +271,7 @@
"A valid Login must be provided" : "必須提供有效帳號",
"Login contains whitespace at the beginning or at the end" : "帳號的開頭或結尾有空白",
"Login must not consist of dots only" : "帳號不能只包含小數點",
+ "Login is too long" : "帳號太長了",
"Login is invalid because files already exist for this user" : "帳號無效,因為使用者的檔案已經存在",
"Account disabled" : "帳號已停用",
"Login canceled by app" : "應用程式取消了登入",
diff --git a/lib/private/App/AppManager.php b/lib/private/App/AppManager.php
index 740da31770d..f6494fa946d 100644
--- a/lib/private/App/AppManager.php
+++ b/lib/private/App/AppManager.php
@@ -8,7 +8,6 @@ namespace OC\App;
use OC\AppConfig;
use OC\AppFramework\Bootstrap\Coordinator;
-use OC\ServerNotAvailableException;
use OCP\Activity\IManager as IActivityManager;
use OCP\App\AppPathNotFoundException;
use OCP\App\Events\AppDisableEvent;
@@ -251,7 +250,7 @@ class AppManager implements IAppManager {
}
}
- // prevent app.php from printing output
+ // prevent app loading from printing output
ob_start();
foreach ($apps as $app) {
if (!$this->isAppLoaded($app) && ($types === [] || $this->isType($app, $types))) {
@@ -452,43 +451,13 @@ class AppManager implements IAppManager {
// in case someone calls loadApp() directly
\OC_App::registerAutoloading($app, $appPath);
- /** @var Coordinator $coordinator */
- $coordinator = \OC::$server->get(Coordinator::class);
- $isBootable = $coordinator->isBootable($app);
-
- $hasAppPhpFile = is_file($appPath . '/appinfo/app.php');
-
- if ($isBootable && $hasAppPhpFile) {
- $this->logger->error('/appinfo/app.php is not loaded when \OCP\AppFramework\Bootstrap\IBootstrap on the application class is used. Migrate everything from app.php to the Application class.', [
+ if (is_file($appPath . '/appinfo/app.php')) {
+ $this->logger->error('/appinfo/app.php is not supported anymore, use \OCP\AppFramework\Bootstrap\IBootstrap on the application class instead.', [
'app' => $app,
]);
- } elseif ($hasAppPhpFile) {
- $eventLogger->start("bootstrap:load_app:$app:app.php", "Load legacy app.php app $app");
- $this->logger->debug('/appinfo/app.php is deprecated, use \OCP\AppFramework\Bootstrap\IBootstrap on the application class instead.', [
- 'app' => $app,
- ]);
- try {
- self::requireAppFile($appPath);
- } catch (\Throwable $ex) {
- if ($ex instanceof ServerNotAvailableException) {
- throw $ex;
- }
- if (!$this->isShipped($app) && !$this->isType($app, ['authentication'])) {
- $this->logger->error("App $app threw an error during app.php load and will be disabled: " . $ex->getMessage(), [
- 'exception' => $ex,
- ]);
-
- // Only disable apps which are not shipped and that are not authentication apps
- $this->disableApp($app, true);
- } else {
- $this->logger->error("App $app threw an error during app.php load: " . $ex->getMessage(), [
- 'exception' => $ex,
- ]);
- }
- }
- $eventLogger->end("bootstrap:load_app:$app:app.php");
}
+ $coordinator = \OCP\Server::get(Coordinator::class);
$coordinator->bootApp($app);
$eventLogger->start("bootstrap:load_app:$app:info", "Load info.xml for $app and register any services defined in it");
@@ -560,6 +529,7 @@ class AppManager implements IAppManager {
$eventLogger->end("bootstrap:load_app:$app");
}
+
/**
* Check if an app is loaded
* @param string $app app id
@@ -570,17 +540,6 @@ class AppManager implements IAppManager {
}
/**
- * Load app.php from the given app
- *
- * @param string $app app name
- * @throws \Error
- */
- private static function requireAppFile(string $app): void {
- // encapsulated here to avoid variable scope conflicts
- require_once $app . '/appinfo/app.php';
- }
-
- /**
* Enable an app for every user
*
* @param string $appId
diff --git a/lib/private/AppFramework/Bootstrap/Coordinator.php b/lib/private/AppFramework/Bootstrap/Coordinator.php
index 4e78450fa04..2b04d291730 100644
--- a/lib/private/AppFramework/Bootstrap/Coordinator.php
+++ b/lib/private/AppFramework/Bootstrap/Coordinator.php
@@ -30,8 +30,8 @@ class Coordinator {
/** @var RegistrationContext|null */
private $registrationContext;
- /** @var string[] */
- private $bootedApps = [];
+ /** @var array<string,true> */
+ private array $bootedApps = [];
public function __construct(
private IServerContainer $serverContainer,
diff --git a/lib/private/AppFramework/Http/Dispatcher.php b/lib/private/AppFramework/Http/Dispatcher.php
index d63a9108b47..d129a7d770b 100644
--- a/lib/private/AppFramework/Http/Dispatcher.php
+++ b/lib/private/AppFramework/Http/Dispatcher.php
@@ -90,9 +90,11 @@ class Dispatcher {
* @param Controller $controller the controller which will be called
* @param string $methodName the method name which will be called on
* the controller
- * @return array $array[0] contains a string with the http main header,
- * $array[1] contains headers in the form: $key => value, $array[2] contains
- * the response output
+ * @return array $array[0] contains the http status header as a string,
+ * $array[1] contains response headers as an array,
+ * $array[2] contains response cookies as an array,
+ * $array[3] contains the response output as a string,
+ * $array[4] contains the response object
* @throws \Exception
*/
public function dispatch(Controller $controller, string $methodName): array {
diff --git a/lib/private/Federation/CloudIdManager.php b/lib/private/Federation/CloudIdManager.php
index a7d36eda4a0..7e7adda3d39 100644
--- a/lib/private/Federation/CloudIdManager.php
+++ b/lib/private/Federation/CloudIdManager.php
@@ -106,7 +106,10 @@ class CloudIdManager implements ICloudIdManager {
$user = substr($id, 0, $lastValidAtPos);
$remote = substr($id, $lastValidAtPos + 1);
- $this->userManager->validateUserId($user);
+ // We accept slightly more chars when working with federationId than with a local userId.
+ // We remove those eventual chars from the UserId before using
+ // the IUserManager API to confirm its format.
+ $this->userManager->validateUserId(str_replace('=', '-', $user));
if (!empty($user) && !empty($remote)) {
$remote = $this->ensureDefaultProtocol($remote);
diff --git a/lib/private/Files/ObjectStore/S3ConnectionTrait.php b/lib/private/Files/ObjectStore/S3ConnectionTrait.php
index 7ddf2abed1d..b7017583dc2 100644
--- a/lib/private/Files/ObjectStore/S3ConnectionTrait.php
+++ b/lib/private/Files/ObjectStore/S3ConnectionTrait.php
@@ -106,6 +106,10 @@ trait S3ConnectionTrait {
'connect_timeout' => 5
],
'use_aws_shared_config_files' => false,
+ 'retries' => [
+ 'mode' => 'standard',
+ 'max_attempts' => 5,
+ ],
];
if ($this->params['s3-accelerate']) {
diff --git a/lib/private/Log/LogDetails.php b/lib/private/Log/LogDetails.php
index bd18eb983db..b3ae23a3770 100644
--- a/lib/private/Log/LogDetails.php
+++ b/lib/private/Log/LogDetails.php
@@ -37,7 +37,7 @@ abstract class LogDetails {
$url = ($request->getRequestUri() !== '') ? $request->getRequestUri() : '--';
$method = is_string($request->getMethod()) ? $request->getMethod() : '--';
if ($this->config->getValue('installed', false)) {
- $user = \OC_User::getUser() ?? '--';
+ $user = \OC_User::getUser() ?: '--';
} else {
$user = '--';
}
diff --git a/lib/private/Mail/EMailTemplate.php b/lib/private/Mail/EMailTemplate.php
index 2cb222fd137..1d19f00b0a1 100644
--- a/lib/private/Mail/EMailTemplate.php
+++ b/lib/private/Mail/EMailTemplate.php
@@ -523,7 +523,7 @@ EOF;
$this->ensureBodyListClosed();
$color = $this->themingDefaults->getDefaultColorPrimary();
- $textColor = $this->themingDefaults->getTextColorPrimary();
+ $textColor = $this->themingDefaults->getDefaultTextColorPrimary();
$this->htmlBody .= vsprintf($this->buttonGroup, [$color, $color, $urlLeft, $color, $textColor, $textColor, $textLeft, $urlRight, $textRight]);
$this->plainBody .= PHP_EOL . $plainTextLeft . ': ' . $urlLeft . PHP_EOL;
@@ -554,7 +554,7 @@ EOF;
}
$color = $this->themingDefaults->getDefaultColorPrimary();
- $textColor = $this->themingDefaults->getTextColorPrimary();
+ $textColor = $this->themingDefaults->getDefaultTextColorPrimary();
$this->htmlBody .= vsprintf($this->button, [$color, $color, $url, $color, $textColor, $textColor, $text]);
if ($plainText !== false) {
diff --git a/lib/private/Preview/Generator.php b/lib/private/Preview/Generator.php
index ef68c17b896..66069beaecc 100644
--- a/lib/private/Preview/Generator.php
+++ b/lib/private/Preview/Generator.php
@@ -1,4 +1,5 @@
<?php
+
/**
* SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
@@ -20,34 +21,20 @@ use OCP\IStreamImage;
use OCP\Preview\BeforePreviewFetchedEvent;
use OCP\Preview\IProviderV2;
use OCP\Preview\IVersionedPreviewFile;
+use Psr\Log\LoggerInterface;
class Generator {
public const SEMAPHORE_ID_ALL = 0x0a11;
public const SEMAPHORE_ID_NEW = 0x07ea;
- /** @var IPreview */
- private $previewManager;
- /** @var IConfig */
- private $config;
- /** @var IAppData */
- private $appData;
- /** @var GeneratorHelper */
- private $helper;
- /** @var IEventDispatcher */
- private $eventDispatcher;
-
public function __construct(
- IConfig $config,
- IPreview $previewManager,
- IAppData $appData,
- GeneratorHelper $helper,
- IEventDispatcher $eventDispatcher,
+ private IConfig $config,
+ private IPreview $previewManager,
+ private IAppData $appData,
+ private GeneratorHelper $helper,
+ private IEventDispatcher $eventDispatcher,
+ private LoggerInterface $logger,
) {
- $this->config = $config;
- $this->previewManager = $previewManager;
- $this->appData = $appData;
- $this->helper = $helper;
- $this->eventDispatcher = $eventDispatcher;
}
/**
@@ -83,6 +70,16 @@ class Generator {
$mimeType,
));
+ $this->logger->debug('Requesting preview for {path} with width={width}, height={height}, crop={crop}, mode={mode}, mimeType={mimeType}', [
+ 'path' => $file->getPath(),
+ 'width' => $width,
+ 'height' => $height,
+ 'crop' => $crop,
+ 'mode' => $mode,
+ 'mimeType' => $mimeType,
+ ]);
+
+
// since we only ask for one preview, and the generate method return the last one it created, it returns the one we want
return $this->generatePreviews($file, [$specification], $mimeType);
}
@@ -100,6 +97,7 @@ class Generator {
public function generatePreviews(File $file, array $specifications, $mimeType = null) {
//Make sure that we can read the file
if (!$file->isReadable()) {
+ $this->logger->warning('Cannot read file: {path}, skipping preview generation.', ['path' => $file->getPath()]);
throw new NotFoundException('Cannot read file');
}
@@ -121,6 +119,7 @@ class Generator {
$maxPreviewImage = null; // only load the image when we need it
if ($maxPreview->getSize() === 0) {
$maxPreview->delete();
+ $this->logger->error("Max preview generated for file {$file->getPath()} has size 0, deleting and throwing exception.");
throw new NotFoundException('Max preview size 0, invalid!');
}
@@ -167,6 +166,7 @@ class Generator {
$maxPreviewImage = $this->helper->getImage($maxPreview);
}
+ $this->logger->warning('Cached preview not found for file {path}, generating a new preview.', ['path' => $file->getPath()]);
$preview = $this->generatePreview($previewFolder, $maxPreviewImage, $width, $height, $crop, $maxWidth, $maxHeight, $previewVersion);
// New file, augment our array
$previewFiles[] = $preview;
@@ -335,6 +335,11 @@ class Generator {
$previewConcurrency = $this->getNumConcurrentPreviews('preview_concurrency_new');
$sem = self::guardWithSemaphore(self::SEMAPHORE_ID_NEW, $previewConcurrency);
try {
+ $this->logger->debug('Calling preview provider for {mimeType} with width={width}, height={height}', [
+ 'mimeType' => $mimeType,
+ 'width' => $width,
+ 'height' => $height,
+ ]);
$preview = $this->helper->getThumbnail($provider, $file, $width, $height);
} finally {
self::unguardWithSemaphore($sem);
@@ -558,6 +563,7 @@ class Generator {
$path = $this->generatePath($width, $height, $crop, false, $mimeType, $prefix);
foreach ($files as $file) {
if ($file->getName() === $path) {
+ $this->logger->debug('Found cached preview: {path}', ['path' => $path]);
return $file;
}
}
diff --git a/lib/private/PreviewManager.php b/lib/private/PreviewManager.php
index 8417554566e..bc77dcfe483 100644
--- a/lib/private/PreviewManager.php
+++ b/lib/private/PreviewManager.php
@@ -21,8 +21,10 @@ use OCP\Files\SimpleFS\ISimpleFile;
use OCP\IBinaryFinder;
use OCP\IConfig;
use OCP\IPreview;
-use OCP\IServerContainer;
use OCP\Preview\IProviderV2;
+use Psr\Container\ContainerInterface;
+use Psr\Log\LoggerInterface;
+
use function array_key_exists;
class PreviewManager implements IPreview {
@@ -47,7 +49,7 @@ class PreviewManager implements IPreview {
* @psalm-var array<string, null>
*/
private array $loadedBootstrapProviders = [];
- private IServerContainer $container;
+ private ContainerInterface $container;
private IBinaryFinder $binaryFinder;
private IMagickSupport $imagickSupport;
private bool $enablePreviews;
@@ -60,7 +62,7 @@ class PreviewManager implements IPreview {
GeneratorHelper $helper,
?string $userId,
Coordinator $bootstrapCoordinator,
- IServerContainer $container,
+ ContainerInterface $container,
IBinaryFinder $binaryFinder,
IMagickSupport $imagickSupport,
) {
@@ -136,7 +138,8 @@ class PreviewManager implements IPreview {
$this->rootFolder,
$this->config
),
- $this->eventDispatcher
+ $this->eventDispatcher,
+ $this->container->get(LoggerInterface::class),
);
}
return $this->generator;
diff --git a/lib/private/Profile/ProfileManager.php b/lib/private/Profile/ProfileManager.php
index 9d3d94fab21..13860286356 100644
--- a/lib/private/Profile/ProfileManager.php
+++ b/lib/private/Profile/ProfileManager.php
@@ -12,6 +12,7 @@ namespace OC\Profile;
use OC\AppFramework\Bootstrap\Coordinator;
use OC\Core\Db\ProfileConfig;
use OC\Core\Db\ProfileConfigMapper;
+use OC\Core\ResponseDefinitions;
use OC\KnownUser\KnownUserService;
use OC\Profile\Actions\EmailAction;
use OC\Profile\Actions\FediverseAction;
@@ -33,6 +34,9 @@ use Psr\Log\LoggerInterface;
use function array_flip;
use function usort;
+/**
+ * @psalm-import-type CoreProfileFields from ResponseDefinitions
+ */
class ProfileManager implements IProfileManager {
/** @var ILinkAction[] */
private array $actions = [];
@@ -223,7 +227,7 @@ class ProfileManager implements IProfileManager {
/**
* Return the profile parameters of the target user that are visible to the visiting user
* in an associative array
- * @return array{userId: string, address?: string|null, biography?: string|null, displayname?: string|null, headline?: string|null, isUserAvatarVisible?: bool, organisation?: string|null, pronouns?: string|null, role?: string|null, actions: list<array{id: string, icon: string, title: string, target: ?string}>}
+ * @psalm-return CoreProfileFields
*/
public function getProfileFields(IUser $targetUser, ?IUser $visitingUser): array {
$account = $this->accountManager->getAccount($targetUser);
diff --git a/lib/private/Profiler/BuiltInProfiler.php b/lib/private/Profiler/BuiltInProfiler.php
new file mode 100644
index 00000000000..0a62365e901
--- /dev/null
+++ b/lib/private/Profiler/BuiltInProfiler.php
@@ -0,0 +1,95 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+namespace OC\Profiler;
+
+use DateTime;
+use OCP\IConfig;
+use OCP\IRequest;
+
+class BuiltInProfiler {
+ private \ExcimerProfiler $excimer;
+
+ public function __construct(
+ private IConfig $config,
+ private IRequest $request,
+ ) {
+ }
+
+ public function start(): void {
+ if (!extension_loaded('excimer')) {
+ return;
+ }
+
+ $shouldProfileSingleRequest = $this->shouldProfileSingleRequest();
+ $shouldSample = $this->config->getSystemValueBool('profiling.sample') && !$shouldProfileSingleRequest;
+
+
+ if (!$shouldProfileSingleRequest && !$shouldSample) {
+ return;
+ }
+
+ $requestRate = $this->config->getSystemValue('profiling.request.rate', 0.001);
+ $sampleRate = $this->config->getSystemValue('profiling.sample.rate', 1.0);
+ $eventType = $this->config->getSystemValue('profiling.event_type', EXCIMER_REAL);
+
+
+ $this->excimer = new \ExcimerProfiler();
+ $this->excimer->setPeriod($shouldProfileSingleRequest ? $requestRate : $sampleRate);
+ $this->excimer->setEventType($eventType);
+ $this->excimer->setMaxDepth(250);
+
+ if ($shouldSample) {
+ $this->excimer->setFlushCallback([$this, 'handleSampleFlush'], 1);
+ }
+
+ $this->excimer->start();
+ register_shutdown_function([$this, 'handleShutdown']);
+ }
+
+ public function handleSampleFlush(\ExcimerLog $log): void {
+ file_put_contents($this->getSampleFilename(), $log->formatCollapsed(), FILE_APPEND);
+ }
+
+ public function handleShutdown(): void {
+ $this->excimer->stop();
+
+ if (!$this->shouldProfileSingleRequest()) {
+ $this->excimer->flush();
+ return;
+ }
+
+ $request = \OCP\Server::get(IRequest::class);
+ $data = $this->excimer->getLog()->getSpeedscopeData();
+
+ $data['profiles'][0]['name'] = $request->getMethod() . ' ' . $request->getRequestUri() . ' ' . $request->getId();
+
+ file_put_contents($this->getProfileFilename(), json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
+ }
+
+ private function shouldProfileSingleRequest(): bool {
+ $shouldProfileSingleRequest = $this->config->getSystemValueBool('profiling.request', false);
+ $profileSecret = $this->config->getSystemValueString('profiling.secret', '');
+ $secretParam = $this->request->getParam('profile_secret') ?? null;
+ return $shouldProfileSingleRequest || (!empty($profileSecret) && $profileSecret === $secretParam);
+ }
+
+ private function getSampleFilename(): string {
+ $profilePath = $this->config->getSystemValueString('profiling.path', '/tmp');
+ $sampleRotation = $this->config->getSystemValueInt('profiling.sample.rotation', 60);
+ $timestamp = floor(time() / ($sampleRotation * 60)) * ($sampleRotation * 60);
+ $sampleName = date('Y-m-d_Hi', (int)$timestamp);
+ return $profilePath . '/sample-' . $sampleName . '.log';
+ }
+
+ private function getProfileFilename(): string {
+ $profilePath = $this->config->getSystemValueString('profiling.path', '/tmp');
+ $requestId = $this->request->getId();
+ return $profilePath . '/profile-' . (new DateTime)->format('Y-m-d_His_v') . '-' . $requestId . '.json';
+ }
+}
diff --git a/lib/private/Security/Normalizer/IpAddress.php b/lib/private/Security/Normalizer/IpAddress.php
index 6ef8763f6d9..e40dc9ba96b 100644
--- a/lib/private/Security/Normalizer/IpAddress.php
+++ b/lib/private/Security/Normalizer/IpAddress.php
@@ -8,6 +8,8 @@ declare(strict_types=1);
*/
namespace OC\Security\Normalizer;
+use OCP\IConfig;
+
/**
* Class IpAddress is used for normalizing IPv4 and IPv6 addresses in security
* relevant contexts in Nextcloud.
@@ -24,7 +26,8 @@ class IpAddress {
}
/**
- * Return the given subnet for an IPv6 address (48 first bits)
+ * Return the given subnet for an IPv6 address
+ * Rely on security.ipv6_normalized_subnet_size, defaults to 56
*/
private function getIPv6Subnet(string $ip): string {
if ($ip[0] === '[' && $ip[-1] === ']') { // If IP is with brackets, for example [::1]
@@ -35,10 +38,14 @@ class IpAddress {
$ip = substr($ip, 0, $pos - 1);
}
+ $config = \OCP\Server::get(IConfig::class);
+ $maskSize = min(64, $config->getSystemValueInt('security.ipv6_normalized_subnet_size', 56));
+ $maskSize = max(32, $maskSize);
+ $mask = pack('VVP', (1 << 32) - 1, (1 << $maskSize - 32) - 1, 0);
+
$binary = \inet_pton($ip);
- $mask = inet_pton('FFFF:FFFF:FFFF::');
- return inet_ntop($binary & $mask) . '/48';
+ return inet_ntop($binary & $mask) . '/' . $maskSize;
}
/**
@@ -63,7 +70,7 @@ class IpAddress {
/**
- * Gets either the /32 (IPv4) or the /48 (IPv6) subnet of an IP address
+ * Gets either the /32 (IPv4) or the /56 (default for IPv6) subnet of an IP address
*/
public function getSubnet(): string {
if (filter_var($this->ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
diff --git a/lib/private/Template/JSConfigHelper.php b/lib/private/Template/JSConfigHelper.php
index 93f5d7a5866..de9df04ae4b 100644
--- a/lib/private/Template/JSConfigHelper.php
+++ b/lib/private/Template/JSConfigHelper.php
@@ -67,7 +67,7 @@ class JSConfigHelper {
$backend = $this->currentUser->getBackend();
if ($backend instanceof IPasswordConfirmationBackend) {
- $userBackendAllowsPasswordConfirmation = $backend->canConfirmPassword($uid);
+ $userBackendAllowsPasswordConfirmation = $backend->canConfirmPassword($uid) && $this->canUserValidatePassword();
} elseif (isset($this->excludedUserBackEnds[$this->currentUser->getBackendClassName()])) {
$userBackendAllowsPasswordConfirmation = false;
}
diff --git a/lib/private/User/DisplayNameCache.php b/lib/private/User/DisplayNameCache.php
index 34db783de68..40e1c752589 100644
--- a/lib/private/User/DisplayNameCache.php
+++ b/lib/private/User/DisplayNameCache.php
@@ -11,6 +11,7 @@ use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\ICache;
use OCP\ICacheFactory;
+use OCP\IUser;
use OCP\IUserManager;
use OCP\User\Events\UserChangedEvent;
use OCP\User\Events\UserDeletedEvent;
@@ -37,6 +38,11 @@ class DisplayNameCache implements IEventListener {
if (isset($this->cache[$userId])) {
return $this->cache[$userId];
}
+
+ if (strlen($userId) > IUser::MAX_USERID_LENGTH) {
+ return null;
+ }
+
$displayName = $this->memCache->get($userId);
if ($displayName) {
$this->cache[$userId] = $displayName;
diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php
index 1f23a9ae9fd..ca5d90f8c00 100644
--- a/lib/private/User/Manager.php
+++ b/lib/private/User/Manager.php
@@ -118,6 +118,10 @@ class Manager extends PublicEmitter implements IUserManager {
return $this->cachedUsers[$uid];
}
+ if (strlen($uid) > IUser::MAX_USERID_LENGTH) {
+ return null;
+ }
+
$cachedBackend = $this->cache->get(sha1($uid));
if ($cachedBackend !== null && isset($this->backends[$cachedBackend])) {
// Cache has the info of the user backend already, so ask that one directly
@@ -177,6 +181,10 @@ class Manager extends PublicEmitter implements IUserManager {
* @return bool
*/
public function userExists($uid) {
+ if (strlen($uid) > IUser::MAX_USERID_LENGTH) {
+ return false;
+ }
+
$user = $this->get($uid);
return ($user !== null);
}
@@ -692,14 +700,14 @@ class Manager extends PublicEmitter implements IUserManager {
public function validateUserId(string $uid, bool $checkDataDirectory = false): void {
$l = Server::get(IFactory::class)->get('lib');
- // Check the name for bad characters
+ // Check the ID for bad characters
// Allowed are: "a-z", "A-Z", "0-9", spaces and "_.@-'"
if (preg_match('/[^a-zA-Z0-9 _.@\-\']/', $uid)) {
throw new \InvalidArgumentException($l->t('Only the following characters are allowed in an Login:'
. ' "a-z", "A-Z", "0-9", spaces and "_.@-\'"'));
}
- // No empty username
+ // No empty user ID
if (trim($uid) === '') {
throw new \InvalidArgumentException($l->t('A valid Login must be provided'));
}
@@ -709,11 +717,16 @@ class Manager extends PublicEmitter implements IUserManager {
throw new \InvalidArgumentException($l->t('Login contains whitespace at the beginning or at the end'));
}
- // Username only consists of 1 or 2 dots (directory traversal)
+ // User ID only consists of 1 or 2 dots (directory traversal)
if ($uid === '.' || $uid === '..') {
throw new \InvalidArgumentException($l->t('Login must not consist of dots only'));
}
+ // User ID is too long
+ if (strlen($uid) > IUser::MAX_USERID_LENGTH) {
+ throw new \InvalidArgumentException($l->t('Login is too long'));
+ }
+
if (!$this->verifyUid($uid, $checkDataDirectory)) {
throw new \InvalidArgumentException($l->t('Login is invalid because files already exist for this user'));
}
diff --git a/lib/public/AppFramework/Bootstrap/IBootstrap.php b/lib/public/AppFramework/Bootstrap/IBootstrap.php
index 81c34524191..7260d2b77a1 100644
--- a/lib/public/AppFramework/Bootstrap/IBootstrap.php
+++ b/lib/public/AppFramework/Bootstrap/IBootstrap.php
@@ -25,8 +25,6 @@ interface IBootstrap {
* At this stage you can assume that all services are registered and the DI
* container(s) are ready to be queried.
*
- * This is also the state where an optional `appinfo/app.php` was loaded.
- *
* @param IBootContext $context
*
* @since 20.0.0
diff --git a/lib/public/IUser.php b/lib/public/IUser.php
index 227e4f902c7..52f79083dc1 100644
--- a/lib/public/IUser.php
+++ b/lib/public/IUser.php
@@ -16,6 +16,11 @@ use InvalidArgumentException;
*/
interface IUser {
/**
+ * @since 32.0.0
+ */
+ public const MAX_USERID_LENGTH = 64;
+
+ /**
* get the user id
*
* @return string
diff --git a/lib/public/Profile/IProfileManager.php b/lib/public/Profile/IProfileManager.php
index 0a1e6733e58..f4e90e39d12 100644
--- a/lib/public/Profile/IProfileManager.php
+++ b/lib/public/Profile/IProfileManager.php
@@ -9,10 +9,12 @@ declare(strict_types=1);
namespace OCP\Profile;
+use OC\Core\ResponseDefinitions;
use OCP\Accounts\IAccountManager;
use OCP\IUser;
/**
+ * @psalm-import-type CoreProfileFields from ResponseDefinitions
* @since 28.0.0
*/
interface IProfileManager {
@@ -83,7 +85,7 @@ interface IProfileManager {
* Return the profile parameters of the target user that are visible to the visiting user
* in an associative array
*
- * @return array{userId: string, address?: string|null, biography?: string|null, displayname?: string|null, headline?: string|null, isUserAvatarVisible?: bool, organisation?: string|null, pronouns?: string|null, role?: string|null, actions: list<array{id: string, icon: string, title: string, target: ?string}>}
+ * @psalm-return CoreProfileFields
* @since 28.0.0
*/
public function getProfileFields(IUser $targetUser, ?IUser $visitingUser): array;