Compare commits
108 Commits
checkValid
...
v23.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0619207f13 | ||
|
|
842e22f882 | ||
|
|
09014ec6d1 | ||
|
|
c853206e8a | ||
|
|
df961fa2f3 | ||
|
|
d5f6547fb8 | ||
|
|
cb74a9af7d | ||
|
|
1441f46bbe | ||
|
|
614cc82d48 | ||
|
|
2b58973533 | ||
|
|
e983376e58 | ||
|
|
9275a9f28a | ||
|
|
ab9282fe26 | ||
|
|
b5e314adf4 | ||
|
|
d03df09879 | ||
|
|
11722dd537 | ||
|
|
3f0cff6667 | ||
|
|
be529b46d9 | ||
|
|
608cf4a592 | ||
|
|
e3de5140b6 | ||
|
|
b1d4efd9f2 | ||
|
|
7f7f21a7b9 | ||
|
|
e6d35b6655 | ||
|
|
4736bba7f6 | ||
|
|
11be6bf4ec | ||
|
|
43e032dd1b | ||
|
|
48e8f5a536 | ||
|
|
29166b6c61 | ||
|
|
3a68a36ee4 | ||
|
|
3d8aa4e038 | ||
|
|
21a1b0cace | ||
|
|
d0385114e1 | ||
|
|
ce69760500 | ||
|
|
7b4c6fe066 | ||
|
|
17db07c50a | ||
|
|
9b0b0fc8d3 | ||
|
|
503be0ef9f | ||
|
|
a08b3b0f00 | ||
|
|
6ffd6b2dee | ||
|
|
e7890cc401 | ||
|
|
e98ee218be | ||
|
|
185da2f25f | ||
|
|
256437d120 | ||
|
|
a33e0a6580 | ||
|
|
2aeb134993 | ||
|
|
83e6007e34 | ||
|
|
78db627d88 | ||
|
|
0afe44c449 | ||
|
|
8fe072e798 | ||
|
|
6debeae0cf | ||
|
|
ba2145ae57 | ||
|
|
38e7d94006 | ||
|
|
6559144834 | ||
|
|
f0661de4e5 | ||
|
|
516b10de33 | ||
|
|
106950d493 | ||
|
|
098cf1f9aa | ||
|
|
d9e25f5f32 | ||
|
|
6c95b46948 | ||
|
|
6c7bc8ac98 | ||
|
|
ea38a798f3 | ||
|
|
7be83b23f4 | ||
|
|
73b8a016a4 | ||
|
|
8ff4870026 | ||
|
|
016482e50c | ||
|
|
2fb31dffc6 | ||
|
|
eecfa3f105 | ||
|
|
b8318c2363 | ||
|
|
acece8f4ba | ||
|
|
5fc031c91f | ||
|
|
d27be604d4 | ||
|
|
df52393d31 | ||
|
|
3b83976c98 | ||
|
|
7e80182e75 | ||
|
|
a80d49a0e7 | ||
|
|
077c45f173 | ||
|
|
b8da11cd62 | ||
|
|
0233cd4edb | ||
|
|
ebfb94fbc0 | ||
|
|
8b0bf9eadf | ||
|
|
1e1ef32cca | ||
|
|
3bd26b630e | ||
|
|
9eac3099d3 | ||
|
|
28376490bf | ||
|
|
f37d550f8a | ||
|
|
ca2e024fb0 | ||
|
|
b1c32d32b1 | ||
|
|
bf5c89bbdd | ||
|
|
49486de8cd | ||
|
|
59cb10c59a | ||
|
|
025951ebf4 | ||
|
|
7a5dcf7e3e | ||
|
|
6db690c3c7 | ||
|
|
fb214c25c6 | ||
|
|
84397254b6 | ||
|
|
22641dfd3f | ||
|
|
cbfb7811a5 | ||
|
|
d67f540d15 | ||
|
|
f0045bf139 | ||
|
|
21f7134fe0 | ||
|
|
35546c034d | ||
|
|
9967198e5a | ||
|
|
36f1714f1d | ||
|
|
dab21ab707 | ||
|
|
ddf6b82112 | ||
|
|
32005be6b2 | ||
|
|
0b72abb7a5 | ||
|
|
2e14d28262 |
@@ -1,5 +1,5 @@
|
||||
codecov:
|
||||
branch: master
|
||||
branch: stable23
|
||||
ci:
|
||||
- drone.nextcloud.com
|
||||
- !scrutinizer-ci.com
|
||||
|
||||
@@ -1403,7 +1403,7 @@ steps:
|
||||
commands:
|
||||
# JavaScript files are not used in integration tests so it is not needed to
|
||||
# build them.
|
||||
- git clone --depth 1 https://github.com/nextcloud/spreed apps/spreed
|
||||
- git clone --depth 1 --branch stable23 https://github.com/nextcloud/spreed apps/spreed
|
||||
- name: integration-sharing-v1-video-verification
|
||||
image: ghcr.io/nextcloud/continuous-integration-integration-php7.3:latest
|
||||
commands:
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
</IfModule>
|
||||
|
||||
# Add cache control for static resources
|
||||
<FilesMatch "\.(css|js|svg|gif|png|jpg|ico)$">
|
||||
<FilesMatch "\.(css|js|svg|gif|png|jpg|ico|wasm|tflite)$">
|
||||
Header set Cache-Control "max-age=15778463"
|
||||
</FilesMatch>
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
|
||||
<IfModule mod_mime.c>
|
||||
AddType image/svg+xml svg svgz
|
||||
AddType application/wasm wasm
|
||||
AddEncoding gzip svgz
|
||||
</IfModule>
|
||||
|
||||
|
||||
2
3rdparty
2
3rdparty
Submodule 3rdparty updated: 217764f87e...747d4ceb41
@@ -1,6 +1,6 @@
|
||||
# Nextcloud Server ☁
|
||||
[](https://scrutinizer-ci.com/g/nextcloud/server/?branch=master)
|
||||
[](https://codecov.io/gh/nextcloud/server)
|
||||
[](https://scrutinizer-ci.com/g/nextcloud/server/?branch=stable23)
|
||||
[](https://codecov.io/gh/nextcloud/server)
|
||||
[](https://bestpractices.coreinfrastructure.org/projects/209)
|
||||
|
||||
**A safe home for all your data.**
|
||||
|
||||
@@ -49,7 +49,7 @@ class CalendarProvider implements ICalendarProvider {
|
||||
public function getCalendars(string $principalUri, array $calendarUris = []): array {
|
||||
$calendarInfos = [];
|
||||
if (empty($calendarUris)) {
|
||||
$calendarInfos[] = $this->calDavBackend->getCalendarsForUser($principalUri);
|
||||
$calendarInfos = $this->calDavBackend->getCalendarsForUser($principalUri);
|
||||
} else {
|
||||
foreach ($calendarUris as $calendarUri) {
|
||||
$calendarInfos[] = $this->calDavBackend->getCalendarByUri($principalUri, $calendarUri);
|
||||
|
||||
@@ -391,12 +391,13 @@ class FilesPlugin extends ServerPlugin {
|
||||
$user->getUID()
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
if ($node instanceof \OCA\DAV\Connector\Sabre\Node) {
|
||||
$propFind->handle(self::DATA_FINGERPRINT_PROPERTYNAME, function () use ($node) {
|
||||
return $this->config->getSystemValue('data-fingerprint', '');
|
||||
});
|
||||
$propFind->handle(self::CREATION_TIME_PROPERTYNAME, function () use ($node) {
|
||||
return $node->getFileInfo()->getCreationTime();
|
||||
});
|
||||
}
|
||||
|
||||
if ($node instanceof \OCA\DAV\Connector\Sabre\File) {
|
||||
@@ -423,10 +424,6 @@ class FilesPlugin extends ServerPlugin {
|
||||
return new ChecksumList($checksum);
|
||||
});
|
||||
|
||||
$propFind->handle(self::CREATION_TIME_PROPERTYNAME, function () use ($node) {
|
||||
return $node->getFileInfo()->getCreationTime();
|
||||
});
|
||||
|
||||
$propFind->handle(self::UPLOAD_TIME_PROPERTYNAME, function () use ($node) {
|
||||
return $node->getFileInfo()->getUploadTime();
|
||||
});
|
||||
|
||||
@@ -105,15 +105,6 @@ class Scan extends Base {
|
||||
);
|
||||
}
|
||||
|
||||
public function checkScanWarning($fullPath, OutputInterface $output) {
|
||||
$normalizedPath = basename(\OC\Files\Filesystem::normalizePath($fullPath));
|
||||
$path = basename($fullPath);
|
||||
|
||||
if ($normalizedPath !== $path) {
|
||||
$output->writeln("\t<error>Entry \"" . $fullPath . '" will not be accessible due to incompatible encoding</error>');
|
||||
}
|
||||
}
|
||||
|
||||
protected function scanFiles($user, $path, OutputInterface $output, $backgroundScan = false, $recursive = true, $homeOnly = false) {
|
||||
$connection = $this->reconnectToDatabase($output);
|
||||
$scanner = new \OC\Files\Utils\Scanner(
|
||||
@@ -141,12 +132,8 @@ class Scan extends Base {
|
||||
$output->writeln('Error while scanning, storage not available (' . $e->getMessage() . ')', OutputInterface::VERBOSITY_VERBOSE);
|
||||
});
|
||||
|
||||
$scanner->listen('\OC\Files\Utils\Scanner', 'scanFile', function ($path) use ($output) {
|
||||
$this->checkScanWarning($path, $output);
|
||||
});
|
||||
|
||||
$scanner->listen('\OC\Files\Utils\Scanner', 'scanFolder', function ($path) use ($output) {
|
||||
$this->checkScanWarning($path, $output);
|
||||
$scanner->listen('\OC\Files\Utils\Scanner', 'normalizedNameMismatch', function ($fullPath) use ($output) {
|
||||
$output->writeln("\t<error>Entry \"" . $fullPath . '" will not be accessible due to incompatible encoding</error>');
|
||||
});
|
||||
|
||||
try {
|
||||
|
||||
@@ -73,15 +73,6 @@ class ScanAppData extends Base {
|
||||
$this->addArgument('folder', InputArgument::OPTIONAL, 'The appdata subfolder to scan', '');
|
||||
}
|
||||
|
||||
public function checkScanWarning($fullPath, OutputInterface $output) {
|
||||
$normalizedPath = basename(\OC\Files\Filesystem::normalizePath($fullPath));
|
||||
$path = basename($fullPath);
|
||||
|
||||
if ($normalizedPath !== $path) {
|
||||
$output->writeln("\t<error>Entry \"" . $fullPath . '" will not be accessible due to incompatible encoding</error>');
|
||||
}
|
||||
}
|
||||
|
||||
protected function scanFiles(OutputInterface $output, string $folder): int {
|
||||
try {
|
||||
$appData = $this->getAppDataFolder();
|
||||
@@ -124,12 +115,8 @@ class ScanAppData extends Base {
|
||||
$output->writeln('Error while scanning, storage not available (' . $e->getMessage() . ')', OutputInterface::VERBOSITY_VERBOSE);
|
||||
});
|
||||
|
||||
$scanner->listen('\OC\Files\Utils\Scanner', 'scanFile', function ($path) use ($output) {
|
||||
$this->checkScanWarning($path, $output);
|
||||
});
|
||||
|
||||
$scanner->listen('\OC\Files\Utils\Scanner', 'scanFolder', function ($path) use ($output) {
|
||||
$this->checkScanWarning($path, $output);
|
||||
$scanner->listen('\OC\Files\Utils\Scanner', 'normalizedNameMismatch', function ($fullPath) use ($output) {
|
||||
$output->writeln("\t<error>Entry \"" . $fullPath . '" will not be accessible due to incompatible encoding</error>');
|
||||
});
|
||||
|
||||
try {
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
#filestable tbody tr.externalDisabledRow {
|
||||
background-color: #CCC;
|
||||
}
|
||||
|
||||
|
||||
#filestable tbody tr.externalErroredRow {
|
||||
background-color: #F2DEDE;
|
||||
}
|
||||
|
||||
@@ -254,8 +254,6 @@ OCA.Files_External.StatusManager = {
|
||||
OCA.Files_External.StatusManager.Utils.changeFolderIcon(elementList);
|
||||
// Save default view
|
||||
OCA.Files_External.StatusManager.Utils.storeDefaultFolderIconAndBgcolor(elementList);
|
||||
// Disable row until check status
|
||||
elementList.addClass('externalDisabledRow');
|
||||
OCA.Files_External.StatusManager.Utils.toggleLink(elementList.find('a.name'), false, false);
|
||||
}
|
||||
}
|
||||
@@ -505,7 +503,6 @@ OCA.Files_External.StatusManager.Utils = {
|
||||
// can't use here FileList.findFileEl(OCA.Files_External.StatusManager.Utils.jqSelEscape(folder)); return incorrect instance of filelist
|
||||
trFolder = $('#fileList tr[data-file=\"' + OCA.Files_External.StatusManager.Utils.jqSelEscape(folder) + '\"]');
|
||||
}
|
||||
trFolder.removeClass('externalErroredRow').removeClass('externalDisabledRow');
|
||||
var tdChilds = trFolder.find("td.filename div.thumbnail");
|
||||
tdChilds.each(function () {
|
||||
var thisElement = $(this);
|
||||
|
||||
@@ -207,7 +207,7 @@ $canCreateMounts = $_['visibilityType'] === BackendService::VISIBILITY_ADMIN ||
|
||||
<form autocomplete="false" action="#"
|
||||
id="global_credentials" method="post">
|
||||
<h2><?php p($l->t('Global credentials')); ?></h2>
|
||||
<p class="settings-hint"><?php p($l->t('Global credentials can be used to authenticate with multiple external storage that have the same credentials.')); ?></p>
|
||||
<p class="settings-hint"><?php p($l->t('Global credentials can be used to authenticate with multiple external storages that have the same credentials.')); ?></p>
|
||||
<input type="text" name="username"
|
||||
autocomplete="false"
|
||||
value="<?php p($_['globalCredentials']['user']); ?>"
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -137,7 +137,9 @@ export default {
|
||||
font-family: var(--font-face);
|
||||
cursor: text;
|
||||
|
||||
&:hover {
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
border-color: var(--color-primary-element) !important;
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
@@ -388,7 +388,9 @@ export default {
|
||||
.email__actions {
|
||||
opacity: 0.4 !important;
|
||||
|
||||
&:hover {
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
opacity: 0.8 !important;
|
||||
}
|
||||
|
||||
|
||||
@@ -88,7 +88,9 @@ a {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
opacity: 0.8;
|
||||
background-color: rgba(127, 127, 127, .25);
|
||||
}
|
||||
|
||||
@@ -105,10 +105,17 @@ export default {
|
||||
font-weight: bold;
|
||||
box-shadow: 0 2px 9px var(--color-box-shadow);
|
||||
|
||||
&:hover {
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
box-shadow: 0 2px 12px var(--color-box-shadow);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: var(--color-main-text) solid 1px;
|
||||
outline-offset: 3px;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
filter: grayscale(1);
|
||||
opacity: 0.5;
|
||||
|
||||
@@ -32,7 +32,11 @@
|
||||
{{ t('settings', 'The more restrictive setting of either visibility or scope is respected on your Profile. For example, if visibility is set to "Show to everyone" and scope is set to "Private", "Private" is respected.') }}
|
||||
</em>
|
||||
|
||||
<div class="visibility-dropdowns">
|
||||
<div
|
||||
class="visibility-dropdowns"
|
||||
:style="{
|
||||
gridTemplateRows: `repeat(${rows}, 44px)`,
|
||||
}">
|
||||
<VisibilityDropdown v-for="param in visibilityParams"
|
||||
:key="param.id"
|
||||
:param-id="param.id"
|
||||
@@ -53,6 +57,16 @@ import { PROFILE_READABLE_ENUM } from '../../../constants/AccountPropertyConstan
|
||||
const { profileConfig } = loadState('settings', 'profileParameters', {})
|
||||
const { profileEnabled } = loadState('settings', 'personalInfoParameters', false)
|
||||
|
||||
const compareParams = (a, b) => {
|
||||
if (a.appId === b.appId || (a.appId !== 'core' && b.appId !== 'core')) {
|
||||
return a.displayId.localeCompare(b.displayId)
|
||||
} else if (a.appId === 'core') {
|
||||
return 1
|
||||
} else {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'ProfileVisibilitySection',
|
||||
|
||||
@@ -67,9 +81,11 @@ export default {
|
||||
profileEnabled,
|
||||
visibilityParams: Object.entries(profileConfig)
|
||||
.map(([paramId, { appId, displayId, visibility }]) => ({ id: paramId, appId, displayId, visibility }))
|
||||
.sort((a, b) => a.appId === b.appId ? a.displayId.localeCompare(b.displayId) : (a.appId !== 'core' ? -1 : 1)),
|
||||
.sort(compareParams),
|
||||
// TODO remove this when not used once the settings layout is updated
|
||||
marginLeft: window.getComputedStyle(document.getElementById('personal-settings-avatar-container')).getPropertyValue('width').trim(),
|
||||
marginLeft: window.matchMedia('(min-width: 1600px)').matches
|
||||
? window.getComputedStyle(document.getElementById('personal-settings-avatar-container')).getPropertyValue('width').trim()
|
||||
: '0px'
|
||||
}
|
||||
},
|
||||
|
||||
@@ -77,13 +93,17 @@ export default {
|
||||
disabled() {
|
||||
return !this.profileEnabled
|
||||
},
|
||||
|
||||
rows() {
|
||||
return Math.ceil(this.visibilityParams.length / 2)
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
subscribe('settings:profile-enabled:updated', this.handleProfileEnabledUpdate)
|
||||
// TODO remove this when not used once the settings layout is updated
|
||||
window.onresize = () => {
|
||||
this.marginLeft = window.matchMedia('(min-width: 1200px)').matches
|
||||
this.marginLeft = window.matchMedia('(min-width: 1600px)').matches
|
||||
? window.getComputedStyle(document.getElementById('personal-settings-avatar-container')).getPropertyValue('width').trim()
|
||||
: '0px'
|
||||
}
|
||||
@@ -125,7 +145,6 @@ section {
|
||||
|
||||
.visibility-dropdowns {
|
||||
display: grid;
|
||||
grid-template-rows: repeat(auto-fit, 44px);
|
||||
gap: 10px 40px;
|
||||
}
|
||||
|
||||
@@ -134,7 +153,6 @@ section {
|
||||
|
||||
.visibility-dropdowns {
|
||||
grid-auto-flow: column;
|
||||
height: 320px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,13 +61,19 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
background-color: rgba(127, 127, 127, .15);
|
||||
}
|
||||
|
||||
&:enabled:hover {
|
||||
background-color: rgba(127, 127, 127, .25);
|
||||
opacity: 0.8 !important;
|
||||
&:enabled {
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
background-color: rgba(127, 127, 127, .25);
|
||||
opacity: 0.8 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -185,7 +185,9 @@ export default {
|
||||
.federation-actions--additional {
|
||||
opacity: 0.4 !important;
|
||||
|
||||
&:hover {
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
opacity: 0.8 !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,5 +67,5 @@
|
||||
<div id="version" class="section">
|
||||
<!-- should be the last part, so Updater can follow if enabled (it has no heading therefore). -->
|
||||
<h2><?php p($l->t('Version'));?></h2>
|
||||
<p><strong><a href="<?php print_unescaped($theme->getBaseUrl()); ?>" rel="noreferrer noopener" target="_blank"><?php p($theme->getTitle()); ?></a> <?php p(OC_Util::getHumanVersion()) ?></strong></p>
|
||||
<p><strong><a href="<?php print_unescaped($theme->getBaseUrl()); ?>" rel="noreferrer noopener" target="_blank"><?php p($theme->getProductName() === 'Nextcloud' ? 'Nextcloud Hub II' : $theme->getProductName()); ?></a> (<?php p(OC_Util::getHumanVersion()) ?>)</strong></p>
|
||||
</div>
|
||||
|
||||
@@ -32,10 +32,10 @@
|
||||
<?php if ($_['sharingAppEnabled'] === false) { ?>
|
||||
<p class="warning"><?php p($l->t('You need to enable the File sharing App.')); ?></p>
|
||||
<?php } else { ?>
|
||||
<div>
|
||||
<a target="_blank" rel="noreferrer noopener" class="icon-info"
|
||||
title="<?php p($l->t('Open documentation'));?>"
|
||||
href="<?php p(link_to_docs('admin-sharing')); ?>"></a>
|
||||
<div>
|
||||
<p class="settings-hint"><?php p($l->t('As admin you can fine-tune the sharing behavior. Please see the documentation for more information.'));?></p>
|
||||
<p id="enable">
|
||||
<input type="checkbox" name="shareapi_enabled" id="shareAPIEnabled" class="checkbox"
|
||||
|
||||
@@ -389,7 +389,7 @@ class ThemingController extends Controller {
|
||||
} else {
|
||||
$startUrl = $this->urlGenerator->getBaseUrl() . '/apps/' . $app . '/';
|
||||
}
|
||||
$description = $info['summary'];
|
||||
$description = $info['summary'] ?? '';
|
||||
}
|
||||
$responseJS = [
|
||||
'name' => $name,
|
||||
|
||||
@@ -379,6 +379,11 @@ abstract class AbstractMapping {
|
||||
DELETE FROM `' . $this->getTableName() . '`
|
||||
WHERE `owncloud_name` = ?');
|
||||
|
||||
$dn = array_search($name, $this->cache);
|
||||
if ($dn !== false) {
|
||||
unset($this->cache[$dn]);
|
||||
}
|
||||
|
||||
return $this->modify($statement, [$name]);
|
||||
}
|
||||
|
||||
|
||||
@@ -127,8 +127,12 @@ abstract class AbstractMappingTest extends \Test\TestCase {
|
||||
[$mapper, $data] = $this->initTest();
|
||||
|
||||
foreach ($data as $entry) {
|
||||
$fdnBefore = $mapper->getDNByName($entry['name']);
|
||||
$result = $mapper->unmap($entry['name']);
|
||||
$fdnAfter = $mapper->getDNByName($entry['name']);
|
||||
$this->assertTrue($result);
|
||||
$this->assertSame($fdnBefore, $entry['dn']);
|
||||
$this->assertFalse($fdnAfter);
|
||||
}
|
||||
|
||||
$result = $mapper->unmap('notAnEntry');
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -87,10 +87,8 @@ class StatusesController extends OCSController {
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
*
|
||||
* @param UserStatus $status
|
||||
* @return array
|
||||
* @return array{userId: string, message: string, icon: string, clearAt: int, status: string}
|
||||
*/
|
||||
private function formatStatus(UserStatus $status): array {
|
||||
$visibleStatus = $status->getStatus();
|
||||
|
||||
@@ -99,6 +99,8 @@ class UserStatusController extends OCSController {
|
||||
public function setStatus(string $statusType): DataResponse {
|
||||
try {
|
||||
$status = $this->service->setStatus($this->userId, $statusType, null, true);
|
||||
|
||||
$this->service->removeBackupUserStatus($this->userId);
|
||||
return new DataResponse($this->formatStatus($status));
|
||||
} catch (InvalidStatusTypeException $ex) {
|
||||
$this->logger->debug('New user-status for "' . $this->userId . '" was rejected due to an invalid status type "' . $statusType . '"');
|
||||
@@ -118,6 +120,7 @@ class UserStatusController extends OCSController {
|
||||
?int $clearAt): DataResponse {
|
||||
try {
|
||||
$status = $this->service->setPredefinedMessage($this->userId, $messageId, $clearAt);
|
||||
$this->service->removeBackupUserStatus($this->userId);
|
||||
return new DataResponse($this->formatStatus($status));
|
||||
} catch (InvalidClearAtException $ex) {
|
||||
$this->logger->debug('New user-status for "' . $this->userId . '" was rejected due to an invalid clearAt value "' . $clearAt . '"');
|
||||
@@ -147,6 +150,7 @@ class UserStatusController extends OCSController {
|
||||
$this->service->clearMessage($this->userId);
|
||||
$status = $this->service->findByUserId($this->userId);
|
||||
}
|
||||
$this->service->removeBackupUserStatus($this->userId);
|
||||
return new DataResponse($this->formatStatus($status));
|
||||
} catch (InvalidClearAtException $ex) {
|
||||
$this->logger->debug('New user-status for "' . $this->userId . '" was rejected due to an invalid clearAt value "' . $clearAt . '"');
|
||||
|
||||
@@ -346,9 +346,21 @@ class StatusService {
|
||||
* @param string $userId
|
||||
* @return bool
|
||||
*/
|
||||
public function removeUserStatus(string $userId, bool $isBackup = false): bool {
|
||||
public function removeUserStatus(string $userId): bool {
|
||||
try {
|
||||
$userStatus = $this->mapper->findByUserId($userId, $isBackup);
|
||||
$userStatus = $this->mapper->findByUserId($userId, false);
|
||||
} catch (DoesNotExistException $ex) {
|
||||
// if there is no status to remove, just return
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->mapper->delete($userStatus);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function removeBackupUserStatus(string $userId): bool {
|
||||
try {
|
||||
$userStatus = $this->mapper->findByUserId($userId, true);
|
||||
} catch (DoesNotExistException $ex) {
|
||||
// if there is no status to remove, just return
|
||||
return false;
|
||||
@@ -448,20 +460,12 @@ class StatusService {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function revertUserStatus(string $userId, string $messageId, string $status): void {
|
||||
public function revertUserStatus(string $userId, ?string $messageId, string $status): void {
|
||||
try {
|
||||
/** @var UserStatus $userStatus */
|
||||
$backupUserStatus = $this->mapper->findByUserId($userId, true);
|
||||
} catch (DoesNotExistException $ex) {
|
||||
// No backup, just move back to available
|
||||
try {
|
||||
$userStatus = $this->mapper->findByUserId($userId);
|
||||
} catch (DoesNotExistException $ex) {
|
||||
// No backup nor current status => ignore
|
||||
return;
|
||||
}
|
||||
$this->cleanStatus($userStatus);
|
||||
$this->cleanStatusMessage($userStatus);
|
||||
// No user status to revert, do nothing
|
||||
return;
|
||||
}
|
||||
try {
|
||||
|
||||
@@ -101,6 +101,7 @@ export default {
|
||||
clearAt: null,
|
||||
icon: null,
|
||||
message: '',
|
||||
messageId: '',
|
||||
isSavingStatus: false,
|
||||
statuses: getAllStatusOptions(),
|
||||
}
|
||||
@@ -191,7 +192,7 @@ export default {
|
||||
try {
|
||||
this.isSavingStatus = true
|
||||
|
||||
if (this.messageId !== null) {
|
||||
if (this.messageId !== undefined && this.messageId !== null) {
|
||||
await this.$store.dispatch('setPredefinedMessage', {
|
||||
messageId: this.messageId,
|
||||
clearAt: this.clearAt,
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~6.5",
|
||||
"behat/behat": "~3.9.0",
|
||||
"behat/behat": "~3.10.0",
|
||||
"guzzlehttp/guzzle": "6.5.2",
|
||||
"jarnaiz/behat-junit-formatter": "^1.3",
|
||||
"sabre/dav": "3.2.3",
|
||||
"sabre/dav": "4.2.0",
|
||||
"symfony/event-dispatcher": "~5.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -458,7 +458,10 @@ trait WebDav {
|
||||
try {
|
||||
$this->response = $this->makeDavRequest($user, "PUT", $destination, [], $file);
|
||||
} catch (\GuzzleHttp\Exception\ServerException $e) {
|
||||
// 4xx and 5xx responses cause an exception
|
||||
// 5xx responses cause a server exception
|
||||
$this->response = $e->getResponse();
|
||||
} catch (\GuzzleHttp\Exception\ClientException $e) {
|
||||
// 4xx responses cause a client exception
|
||||
$this->response = $e->getResponse();
|
||||
}
|
||||
}
|
||||
@@ -487,7 +490,10 @@ trait WebDav {
|
||||
try {
|
||||
$this->response = $this->makeDavRequest($user, "PUT", $destination, [], $file);
|
||||
} catch (\GuzzleHttp\Exception\ServerException $e) {
|
||||
// 4xx and 5xx responses cause an exception
|
||||
// 5xx responses cause a server exception
|
||||
$this->response = $e->getResponse();
|
||||
} catch (\GuzzleHttp\Exception\ClientException $e) {
|
||||
// 4xx responses cause a client exception
|
||||
$this->response = $e->getResponse();
|
||||
}
|
||||
}
|
||||
@@ -502,7 +508,10 @@ trait WebDav {
|
||||
try {
|
||||
$this->response = $this->makeDavRequest($user, 'DELETE', $file, []);
|
||||
} catch (\GuzzleHttp\Exception\ServerException $e) {
|
||||
// 4xx and 5xx responses cause an exception
|
||||
// 5xx responses cause a server exception
|
||||
$this->response = $e->getResponse();
|
||||
} catch (\GuzzleHttp\Exception\ClientException $e) {
|
||||
// 4xx responses cause a client exception
|
||||
$this->response = $e->getResponse();
|
||||
}
|
||||
}
|
||||
@@ -517,7 +526,10 @@ trait WebDav {
|
||||
$destination = '/' . ltrim($destination, '/');
|
||||
$this->response = $this->makeDavRequest($user, "MKCOL", $destination, []);
|
||||
} catch (\GuzzleHttp\Exception\ServerException $e) {
|
||||
// 4xx and 5xx responses cause an exception
|
||||
// 5xx responses cause a server exception
|
||||
$this->response = $e->getResponse();
|
||||
} catch (\GuzzleHttp\Exception\ClientException $e) {
|
||||
// 4xx responses cause a client exception
|
||||
$this->response = $e->getResponse();
|
||||
}
|
||||
}
|
||||
@@ -639,8 +651,12 @@ trait WebDav {
|
||||
public function downloadingFileAs($fileName, $user) {
|
||||
try {
|
||||
$this->response = $this->makeDavRequest($user, 'GET', $fileName, []);
|
||||
} catch (\GuzzleHttp\Exception\ServerException $ex) {
|
||||
$this->response = $ex->getResponse();
|
||||
} catch (\GuzzleHttp\Exception\ServerException $e) {
|
||||
// 5xx responses cause a server exception
|
||||
$this->response = $e->getResponse();
|
||||
} catch (\GuzzleHttp\Exception\ClientException $e) {
|
||||
// 4xx responses cause a client exception
|
||||
$this->response = $e->getResponse();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -619,3 +619,12 @@ Feature: webdav-related
|
||||
And Downloaded content should be "BBBBB"
|
||||
And Downloading file "/C.txt"
|
||||
And Downloaded content should be "CCCCC"
|
||||
|
||||
Scenario: Creating a folder with invalid characters
|
||||
Given using new dav path
|
||||
And As an "admin"
|
||||
And user "user0" exists
|
||||
And user "user1" exists
|
||||
And As an "user1"
|
||||
And user "user1" created a folder "/testshare "
|
||||
Then the HTTP status code should be "400"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#!/bin/bash
|
||||
# Update Nextcloud apps from latest git master
|
||||
# Update Nextcloud apps from latest git stable23
|
||||
# For local development environment
|
||||
# Use from Nextcloud server folder with `./build/update-apps.sh`
|
||||
#
|
||||
# It automatically:
|
||||
# - goes through all apps which are not shipped via server
|
||||
# - shows the app name in bold and uses whitespace for separation
|
||||
# - changes to master and pulls quietly
|
||||
# - changes to stable23 and pulls quietly
|
||||
# - shows the 3 most recent commits for context
|
||||
# - removes branches merged into master
|
||||
# - removes branches merged into stable23
|
||||
# - … could even do the build steps if they are consistent for the apps (like `make`)
|
||||
|
||||
find apps* -maxdepth 2 -name .git -exec sh -c 'cd {}/../ && printf "\n\033[1m${PWD##*/}\033[0m\n" && git checkout master && git pull --quiet -p && git --no-pager log -3 --pretty=format:"%h %Cblue%ar%x09%an %Creset%s" && printf "\n" && git branch --merged master | grep -v "master$" | xargs git branch -d && cd ..' \;
|
||||
find apps* -maxdepth 2 -name .git -exec sh -c 'cd {}/../ && printf "\n\033[1m${PWD##*/}\033[0m\n" && git checkout stable23 && git pull --quiet -p && git --no-pager log -3 --pretty=format:"%h %Cblue%ar%x09%an %Creset%s" && printf "\n" && git branch --merged stable23 | grep -v "stable23$" | xargs git branch -d && cd ..' \;
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
#!/bin/bash
|
||||
# Update Nextcloud server and apps from latest git master
|
||||
# Update Nextcloud server and apps from latest git stable23
|
||||
# For local development environment
|
||||
# Use from Nextcloud server folder with `./build/update.sh`
|
||||
|
||||
# Update server
|
||||
printf "\n\033[1m${PWD##*/}\033[0m\n"
|
||||
git checkout master
|
||||
git checkout stable23
|
||||
git pull --quiet -p
|
||||
git --no-pager log -3 --pretty=format:"%h %Cblue%ar%x09%an %Creset%s"
|
||||
printf "\n"
|
||||
git branch --merged master | grep -v "master$" | xargs git branch -d
|
||||
git branch --merged stable23 | grep -v "stable23$" | xargs git branch -d
|
||||
git submodule update --init
|
||||
|
||||
# Update apps
|
||||
|
||||
@@ -204,15 +204,9 @@ class Upgrade extends Command {
|
||||
$updater->listen('\OC\Updater', 'incompatibleAppDisabled', function ($app) use ($output) {
|
||||
$output->writeln('<comment>Disabled incompatible app: ' . $app . '</comment>');
|
||||
});
|
||||
$updater->listen('\OC\Updater', 'checkAppStoreAppBefore', function ($app) use ($output) {
|
||||
$output->writeln('<info>Checking for update of app ' . $app . ' in appstore</info>');
|
||||
});
|
||||
$updater->listen('\OC\Updater', 'upgradeAppStoreApp', function ($app) use ($output) {
|
||||
$output->writeln('<info>Update app ' . $app . ' from App Store</info>');
|
||||
});
|
||||
$updater->listen('\OC\Updater', 'checkAppStoreApp', function ($app) use ($output) {
|
||||
$output->writeln('<info>Checked for update of app "' . $app . '" in App Store </info>');
|
||||
});
|
||||
$updater->listen('\OC\Updater', 'appSimulateUpdate', function ($app) use ($output) {
|
||||
$output->writeln("<info>Checking whether the database schema for <$app> can be updated (this can take a long time depending on the database size)</info>");
|
||||
});
|
||||
|
||||
@@ -98,6 +98,7 @@ class OCJSController extends Controller {
|
||||
|
||||
/**
|
||||
* @NoCSRFRequired
|
||||
* @NoTwoFactorRequired
|
||||
* @PublicPage
|
||||
*
|
||||
* @return DataDisplayResponse
|
||||
|
||||
@@ -127,13 +127,15 @@ class ProfilePageController extends Controller {
|
||||
}
|
||||
}
|
||||
|
||||
$userStatuses = $this->userStatusManager->getUserStatuses([$targetUserId]);
|
||||
$status = $userStatuses[$targetUserId] ?? null;
|
||||
if ($status !== null) {
|
||||
$this->initialStateService->provideInitialState('status', [
|
||||
'icon' => $status->getIcon(),
|
||||
'message' => $status->getMessage(),
|
||||
]);
|
||||
if ($visitingUser !== null) {
|
||||
$userStatuses = $this->userStatusManager->getUserStatuses([$targetUserId]);
|
||||
$status = $userStatuses[$targetUserId] ?? null;
|
||||
if ($status !== null) {
|
||||
$this->initialStateService->provideInitialState('status', [
|
||||
'icon' => $status->getIcon(),
|
||||
'message' => $status->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->initialStateService->provideInitialState(
|
||||
|
||||
@@ -83,6 +83,12 @@ class TwoFactorMiddleware extends Middleware {
|
||||
* @param string $methodName
|
||||
*/
|
||||
public function beforeController($controller, $methodName) {
|
||||
if ($this->reflector->hasAnnotation('NoTwoFactorRequired')) {
|
||||
// Route handler explicitly marked to work without finished 2FA are
|
||||
// not blocked
|
||||
return;
|
||||
}
|
||||
|
||||
if ($controller instanceof APIController && $methodName === 'poll') {
|
||||
// Allow polling the twofactor nextcloud notifications state
|
||||
return;
|
||||
|
||||
@@ -160,15 +160,9 @@ if (\OCP\Util::needUpgrade()) {
|
||||
$updater->listen('\OC\Updater', 'dbUpgrade', function () use ($eventSource, $l) {
|
||||
$eventSource->send('success', $l->t('Updated database'));
|
||||
});
|
||||
$updater->listen('\OC\Updater', 'checkAppStoreAppBefore', function ($app) use ($eventSource, $l) {
|
||||
$eventSource->send('success', $l->t('Checking for update of app "%s" in App Store', [$app]));
|
||||
});
|
||||
$updater->listen('\OC\Updater', 'upgradeAppStoreApp', function ($app) use ($eventSource, $l) {
|
||||
$eventSource->send('success', $l->t('Update app "%s" from App Store', [$app]));
|
||||
});
|
||||
$updater->listen('\OC\Updater', 'checkAppStoreApp', function ($app) use ($eventSource, $l) {
|
||||
$eventSource->send('success', $l->t('Checked for update of app "%s" in App Store', [$app]));
|
||||
});
|
||||
$updater->listen('\OC\Updater', 'appSimulateUpdate', function ($app) use ($eventSource, $l) {
|
||||
$eventSource->send('success', $l->t('Checking whether the database schema for %s can be updated (this can take a long time depending on the database size)', [$app]));
|
||||
});
|
||||
|
||||
6
core/js/dist/install.js
vendored
6
core/js/dist/install.js
vendored
File diff suppressed because one or more lines are too long
2
core/js/dist/install.js.map
vendored
2
core/js/dist/install.js.map
vendored
File diff suppressed because one or more lines are too long
6
core/js/dist/main.js
vendored
6
core/js/dist/main.js
vendored
File diff suppressed because one or more lines are too long
2
core/js/dist/main.js.map
vendored
2
core/js/dist/main.js.map
vendored
File diff suppressed because one or more lines are too long
16
core/js/dist/profile.js
vendored
16
core/js/dist/profile.js
vendored
File diff suppressed because one or more lines are too long
2
core/js/dist/profile.js.map
vendored
2
core/js/dist/profile.js.map
vendored
File diff suppressed because one or more lines are too long
@@ -96,7 +96,9 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
background-color: var(--color-primary-element-light);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,8 +141,8 @@
|
||||
title=""
|
||||
fill-color="var(--color-text-maxcontrast)"
|
||||
:size="60" />
|
||||
<h3>{{ displayname || userId }} {{ t('core', 'hasn\'t added any info yet') }}</h3>
|
||||
<p>{{ t('core', 'The headline and about section will show up here') }}</p>
|
||||
<h3>{{ emptyProfileMessage }}</h3>
|
||||
<p>{{ t('core', 'The headline and about sections will show up here') }}</p>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
@@ -255,6 +255,12 @@ export default {
|
||||
// For some reason the returned string has prepended whitespace
|
||||
return getComputedStyle(document.body).getPropertyValue('--color-main-background').trim()
|
||||
},
|
||||
|
||||
emptyProfileMessage() {
|
||||
return this.isCurrentUser
|
||||
? t('core', 'You haven\'t added any info yet')
|
||||
: t('core', '{user} hasn\'t added any info yet', { user: (this.displayname || this.userId) })
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
@@ -358,7 +364,9 @@ $content-max-width: 640px;
|
||||
line-height: 44px;
|
||||
font-weight: bold;
|
||||
|
||||
&:hover {
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
color: var(--color-primary-text);
|
||||
background-color: var(--color-primary-element-light);
|
||||
}
|
||||
@@ -374,13 +382,15 @@ $content-max-width: 640px;
|
||||
width: max-content;
|
||||
max-width: $content-max-width;
|
||||
padding: 5px 10px;
|
||||
margin-left: -14px;
|
||||
margin-left: -12px;
|
||||
margin-top: 2px;
|
||||
|
||||
&.interactive {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
background-color: var(--color-main-background);
|
||||
color: var(--color-main-text);
|
||||
border-radius: var(--border-radius-pill);
|
||||
@@ -432,7 +442,9 @@ $content-max-width: 640px;
|
||||
.avatardiv__user-status {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
box-shadow: 0 3px 6px var(--color-box-shadow);
|
||||
}
|
||||
}
|
||||
@@ -506,6 +518,52 @@ $content-max-width: 640px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1024px) {
|
||||
.profile {
|
||||
&__header {
|
||||
height: 250px;
|
||||
position: unset;
|
||||
|
||||
&__container {
|
||||
grid-template-columns: unset;
|
||||
|
||||
&__displayname {
|
||||
margin: 100px 20px 0px;
|
||||
width: unset;
|
||||
display: unset;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&__edit-button {
|
||||
width: fit-content;
|
||||
display: block;
|
||||
margin: 30px auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__content {
|
||||
display: block;
|
||||
}
|
||||
|
||||
&__blocks {
|
||||
width: unset;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 50px 50px 50px;
|
||||
|
||||
&-empty-info {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__sidebar {
|
||||
margin: unset;
|
||||
position: unset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.user-actions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@@ -1161,6 +1161,7 @@ return array(
|
||||
'OC\\Files\\Storage\\Temporary' => $baseDir . '/lib/private/Files/Storage/Temporary.php',
|
||||
'OC\\Files\\Storage\\Wrapper\\Availability' => $baseDir . '/lib/private/Files/Storage/Wrapper/Availability.php',
|
||||
'OC\\Files\\Storage\\Wrapper\\Encoding' => $baseDir . '/lib/private/Files/Storage/Wrapper/Encoding.php',
|
||||
'OC\\Files\\Storage\\Wrapper\\EncodingDirectoryWrapper' => $baseDir . '/lib/private/Files/Storage/Wrapper/EncodingDirectoryWrapper.php',
|
||||
'OC\\Files\\Storage\\Wrapper\\Encryption' => $baseDir . '/lib/private/Files/Storage/Wrapper/Encryption.php',
|
||||
'OC\\Files\\Storage\\Wrapper\\Jail' => $baseDir . '/lib/private/Files/Storage/Wrapper/Jail.php',
|
||||
'OC\\Files\\Storage\\Wrapper\\PermissionsMask' => $baseDir . '/lib/private/Files/Storage/Wrapper/PermissionsMask.php',
|
||||
|
||||
@@ -1190,6 +1190,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
|
||||
'OC\\Files\\Storage\\Temporary' => __DIR__ . '/../../..' . '/lib/private/Files/Storage/Temporary.php',
|
||||
'OC\\Files\\Storage\\Wrapper\\Availability' => __DIR__ . '/../../..' . '/lib/private/Files/Storage/Wrapper/Availability.php',
|
||||
'OC\\Files\\Storage\\Wrapper\\Encoding' => __DIR__ . '/../../..' . '/lib/private/Files/Storage/Wrapper/Encoding.php',
|
||||
'OC\\Files\\Storage\\Wrapper\\EncodingDirectoryWrapper' => __DIR__ . '/../../..' . '/lib/private/Files/Storage/Wrapper/EncodingDirectoryWrapper.php',
|
||||
'OC\\Files\\Storage\\Wrapper\\Encryption' => __DIR__ . '/../../..' . '/lib/private/Files/Storage/Wrapper/Encryption.php',
|
||||
'OC\\Files\\Storage\\Wrapper\\Jail' => __DIR__ . '/../../..' . '/lib/private/Files/Storage/Wrapper/Jail.php',
|
||||
'OC\\Files\\Storage\\Wrapper\\PermissionsMask' => __DIR__ . '/../../..' . '/lib/private/Files/Storage/Wrapper/PermissionsMask.php',
|
||||
|
||||
@@ -343,6 +343,10 @@ class AccountManager implements IAccountManager {
|
||||
}
|
||||
|
||||
public function searchUsers(string $property, array $values): array {
|
||||
// the value col is limited to 255 bytes. It is used for searches only.
|
||||
$values = array_map(function (string $value) {
|
||||
return Util::shortenMultibyteString($value, 255);
|
||||
}, $values);
|
||||
$chunks = array_chunk($values, 500);
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
$query->select('*')
|
||||
@@ -625,8 +629,11 @@ class AccountManager implements IAccountManager {
|
||||
continue;
|
||||
}
|
||||
|
||||
// the value col is limited to 255 bytes. It is used for searches only.
|
||||
$value = $property['value'] ? Util::shortenMultibyteString($property['value'], 255) : '';
|
||||
|
||||
$query->setParameter('name', $property['name'])
|
||||
->setParameter('value', $property['value'] ?? '');
|
||||
->setParameter('value', $value);
|
||||
$query->executeStatement();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,7 +195,7 @@ class AppManager implements IAppManager {
|
||||
if ($values[$appId] === 'yes' || $values[$appId] === 'no') {
|
||||
return [];
|
||||
}
|
||||
return json_decode($values[$appId]);
|
||||
return json_decode($values[$appId], true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -47,8 +47,8 @@ class CalendarQuery implements ICalendarQuery {
|
||||
/** @var int|null */
|
||||
private $limit;
|
||||
|
||||
/** @var array */
|
||||
private $calendarUris;
|
||||
/** @var string[] */
|
||||
private $calendarUris = [];
|
||||
|
||||
public function __construct(string $principalUri) {
|
||||
$this->principalUri = $principalUri;
|
||||
@@ -86,6 +86,9 @@ class CalendarQuery implements ICalendarQuery {
|
||||
$this->calendarUris[] = $calendarUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getCalendarUris(): array {
|
||||
return $this->calendarUris;
|
||||
}
|
||||
|
||||
@@ -189,15 +189,20 @@ class Connection extends \Doctrine\DBAL\Connection {
|
||||
* Prepares an SQL statement.
|
||||
*
|
||||
* @param string $statement The SQL statement to prepare.
|
||||
* @param int $limit
|
||||
* @param int $offset
|
||||
* @param int|null $limit
|
||||
* @param int|null $offset
|
||||
*
|
||||
* @return Statement The prepared statement.
|
||||
* @throws Exception
|
||||
*/
|
||||
public function prepare($statement, $limit = null, $offset = null): Statement {
|
||||
if ($limit === -1) {
|
||||
if ($limit === -1 || $limit === null) {
|
||||
$limit = null;
|
||||
} else {
|
||||
$limit = (int) $limit;
|
||||
}
|
||||
if ($offset !== null) {
|
||||
$offset = (int) $offset;
|
||||
}
|
||||
if (!is_null($limit)) {
|
||||
$platform = $this->getDatabasePlatform();
|
||||
|
||||
@@ -450,12 +450,12 @@ class QueryBuilder implements IQueryBuilder {
|
||||
/**
|
||||
* Sets the position of the first result to retrieve (the "offset").
|
||||
*
|
||||
* @param integer $firstResult The first result to return.
|
||||
* @param int $firstResult The first result to return.
|
||||
*
|
||||
* @return $this This QueryBuilder instance.
|
||||
*/
|
||||
public function setFirstResult($firstResult) {
|
||||
$this->queryBuilder->setFirstResult($firstResult);
|
||||
$this->queryBuilder->setFirstResult((int) $firstResult);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -477,12 +477,16 @@ class QueryBuilder implements IQueryBuilder {
|
||||
* of the databases will just return an empty result set, Oracle will return
|
||||
* all entries.
|
||||
*
|
||||
* @param integer $maxResults The maximum number of results to retrieve.
|
||||
* @param int|null $maxResults The maximum number of results to retrieve.
|
||||
*
|
||||
* @return $this This QueryBuilder instance.
|
||||
*/
|
||||
public function setMaxResults($maxResults) {
|
||||
$this->queryBuilder->setMaxResults($maxResults);
|
||||
if ($maxResults === null) {
|
||||
$this->queryBuilder->setMaxResults($maxResults);
|
||||
} else {
|
||||
$this->queryBuilder->setMaxResults((int) $maxResults);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ namespace OC\Files\Cache;
|
||||
|
||||
use Doctrine\DBAL\Exception;
|
||||
use OC\Files\Filesystem;
|
||||
use OC\Files\Storage\Wrapper\Encoding;
|
||||
use OC\Hooks\BasicEmitter;
|
||||
use OCP\Files\Cache\IScanner;
|
||||
use OCP\Files\ForbiddenException;
|
||||
@@ -419,7 +420,16 @@ class Scanner extends BasicEmitter implements IScanner {
|
||||
if ($permissions === 0) {
|
||||
continue;
|
||||
}
|
||||
$file = $fileMeta['name'];
|
||||
$originalFile = $fileMeta['name'];
|
||||
$file = trim(\OC\Files\Filesystem::normalizePath($originalFile), '/');
|
||||
if (trim($originalFile, '/') !== $file) {
|
||||
// encoding mismatch, might require compatibility wrapper
|
||||
\OC::$server->getLogger()->debug('Scanner: Skipping non-normalized file name "'. $originalFile . '" in path "' . $path . '".', ['app' => 'core']);
|
||||
$this->emit('\OC\Files\Cache\Scanner', 'normalizedNameMismatch', [$path ? $path . '/' . $originalFile : $originalFile]);
|
||||
// skip this entry
|
||||
continue;
|
||||
}
|
||||
|
||||
$newChildNames[] = $file;
|
||||
$child = $path ? $path . '/' . $file : $file;
|
||||
try {
|
||||
|
||||
@@ -554,8 +554,8 @@ abstract class Common implements Storage, ILockingStorage, IWriteStreamStorage {
|
||||
* @throws InvalidPathException
|
||||
*/
|
||||
protected function verifyPosixPath($fileName) {
|
||||
$fileName = trim($fileName);
|
||||
$this->scanForInvalidCharacters($fileName, "\\/");
|
||||
$fileName = trim($fileName);
|
||||
$reservedNames = ['*'];
|
||||
if (in_array($fileName, $reservedNames)) {
|
||||
throw new ReservedWordException();
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
namespace OC\Files\Storage\Wrapper;
|
||||
|
||||
use OC\Cache\CappedMemoryCache;
|
||||
use OC\Files\Filesystem;
|
||||
use OCP\Files\Storage\IStorage;
|
||||
use OCP\ICache;
|
||||
|
||||
@@ -162,7 +163,8 @@ class Encoding extends Wrapper {
|
||||
* @return resource|bool
|
||||
*/
|
||||
public function opendir($path) {
|
||||
return $this->storage->opendir($this->findPathToUse($path));
|
||||
$handle = $this->storage->opendir($this->findPathToUse($path));
|
||||
return EncodingDirectoryWrapper::wrap($handle);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -532,10 +534,16 @@ class Encoding extends Wrapper {
|
||||
}
|
||||
|
||||
public function getMetaData($path) {
|
||||
return $this->storage->getMetaData($this->findPathToUse($path));
|
||||
$entry = $this->storage->getMetaData($this->findPathToUse($path));
|
||||
$entry['name'] = trim(Filesystem::normalizePath($entry['name']), '/');
|
||||
return $entry;
|
||||
}
|
||||
|
||||
public function getDirectoryContent($directory): \Traversable {
|
||||
return $this->storage->getDirectoryContent($this->findPathToUse($directory));
|
||||
$entries = $this->storage->getDirectoryContent($this->findPathToUse($directory));
|
||||
foreach ($entries as $entry) {
|
||||
$entry['name'] = trim(Filesystem::normalizePath($entry['name']), '/');
|
||||
yield $entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2021, Nextcloud GmbH.
|
||||
*
|
||||
* @author Robin Appelman <robin@icewind.nl>
|
||||
* @author Vincent Petry <vincent@nextcloud.com>
|
||||
*
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OC\Files\Storage\Wrapper;
|
||||
|
||||
use Icewind\Streams\DirectoryWrapper;
|
||||
use OC\Files\Filesystem;
|
||||
|
||||
/**
|
||||
* Normalize file names while reading directory entries
|
||||
*/
|
||||
class EncodingDirectoryWrapper extends DirectoryWrapper {
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function dir_readdir() {
|
||||
$file = readdir($this->source);
|
||||
if ($file !== false && $file !== '.' && $file !== '..') {
|
||||
$file = trim(Filesystem::normalizePath($file), '/');
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource $source
|
||||
* @param callable $filter
|
||||
* @return resource|bool
|
||||
*/
|
||||
public static function wrap($source) {
|
||||
return self::wrapSource($source, [
|
||||
'source' => $source,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -145,6 +145,9 @@ class Scanner extends PublicEmitter {
|
||||
$this->emit('\OC\Files\Utils\Scanner', 'postScanFolder', [$mount->getMountPoint() . $path]);
|
||||
$this->dispatcher->dispatchTyped(new FolderScannedEvent($mount->getMountPoint() . $path));
|
||||
});
|
||||
$scanner->listen('\OC\Files\Cache\Scanner', 'normalizedNameMismatch', function ($path) use ($mount) {
|
||||
$this->emit('\OC\Files\Utils\Scanner', 'normalizedNameMismatch', [$path]);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -425,6 +425,7 @@ class ProfileManager {
|
||||
];
|
||||
|
||||
$paramMetadata = array_merge($actionsMetadata, $propertiesMetadata);
|
||||
$configArray = array_intersect_key($configArray, $paramMetadata);
|
||||
|
||||
foreach ($configArray as $paramId => $paramConfig) {
|
||||
if (isset($paramMetadata[$paramId])) {
|
||||
|
||||
@@ -46,7 +46,7 @@ class RedisFactory {
|
||||
}
|
||||
|
||||
private function create() {
|
||||
$isCluster = in_array('redis.cluster', $this->config->getKeys());
|
||||
$isCluster = in_array('redis.cluster', $this->config->getKeys(), true);
|
||||
$config = $isCluster
|
||||
? $this->config->getValue('redis.cluster', [])
|
||||
: $this->config->getValue('redis', []);
|
||||
|
||||
@@ -92,6 +92,38 @@ class IpAddress {
|
||||
return \inet_ntop($binary).'/'.$maskBits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the IPv4 address embedded in an IPv6 if applicable.
|
||||
* The detected format is "::ffff:x.x.x.x" using the binary form.
|
||||
*
|
||||
* @return string|null embedded IPv4 string or null if none was found
|
||||
*/
|
||||
private function getEmbeddedIpv4(string $ipv6): ?string {
|
||||
$binary = inet_pton($ipv6);
|
||||
if (!$binary) {
|
||||
return null;
|
||||
}
|
||||
for ($i = 0; $i <= 9; $i++) {
|
||||
if (unpack('C', $binary[$i])[1] !== 0) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
for ($i = 10; $i <= 11; $i++) {
|
||||
if (unpack('C', $binary[$i])[1] !== 255) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
$binary4 = '';
|
||||
for ($i = 12; $i < 16; $i++) {
|
||||
$binary4 .= $binary[$i];
|
||||
}
|
||||
|
||||
return inet_ntop($binary4);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets either the /32 (IPv4) or the /64 (IPv6) subnet of an IP address
|
||||
*
|
||||
@@ -104,6 +136,15 @@ class IpAddress {
|
||||
32
|
||||
);
|
||||
}
|
||||
|
||||
$ipv4 = $this->getEmbeddedIpv4($this->ip);
|
||||
if ($ipv4 !== null) {
|
||||
return $this->getIPv4Subnet(
|
||||
$ipv4,
|
||||
32
|
||||
);
|
||||
}
|
||||
|
||||
return $this->getIPv6Subnet(
|
||||
$this->ip,
|
||||
64
|
||||
|
||||
@@ -530,7 +530,7 @@ class Setup {
|
||||
$content .= "\n Options -MultiViews";
|
||||
$content .= "\n RewriteRule ^core/js/oc.js$ index.php [PT,E=PATH_INFO:$1]";
|
||||
$content .= "\n RewriteRule ^core/preview.png$ index.php [PT,E=PATH_INFO:$1]";
|
||||
$content .= "\n RewriteCond %{REQUEST_FILENAME} !\\.(css|js|svg|gif|png|html|ttf|woff2?|ico|jpg|jpeg|map|webm|mp4|mp3|ogg|wav)$";
|
||||
$content .= "\n RewriteCond %{REQUEST_FILENAME} !\\.(css|js|svg|gif|png|html|ttf|woff2?|ico|jpg|jpeg|map|webm|mp4|mp3|ogg|wav|wasm|tflite)$";
|
||||
$content .= "\n RewriteCond %{REQUEST_FILENAME} !/core/ajax/update\\.php";
|
||||
$content .= "\n RewriteCond %{REQUEST_FILENAME} !/core/img/(favicon\\.ico|manifest\\.json)$";
|
||||
$content .= "\n RewriteCond %{REQUEST_FILENAME} !/(cron|public|remote|status)\\.php";
|
||||
|
||||
@@ -32,7 +32,6 @@ namespace OC\Template;
|
||||
use OC\AppConfig;
|
||||
use OC\Files\AppData\Factory;
|
||||
use OC\Memcache\NullCache;
|
||||
use OCA\Theming\ThemingDefaults;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\Files\IAppData;
|
||||
use OCP\Files\NotFoundException;
|
||||
@@ -63,7 +62,7 @@ class SCSSCacher {
|
||||
/** @var IConfig */
|
||||
protected $config;
|
||||
|
||||
/** @var ThemingDefaults */
|
||||
/** @var \OC_Defaults */
|
||||
private $defaults;
|
||||
|
||||
/** @var string */
|
||||
@@ -97,7 +96,7 @@ class SCSSCacher {
|
||||
* @param Factory $appDataFactory
|
||||
* @param IURLGenerator $urlGenerator
|
||||
* @param IConfig $config
|
||||
* @param ThemingDefaults $defaults
|
||||
* @param \OC_Defaults $defaults
|
||||
* @param string $serverRoot
|
||||
* @param ICacheFactory $cacheFactory
|
||||
* @param IconsCacher $iconsCacher
|
||||
@@ -107,7 +106,7 @@ class SCSSCacher {
|
||||
Factory $appDataFactory,
|
||||
IURLGenerator $urlGenerator,
|
||||
IConfig $config,
|
||||
ThemingDefaults $defaults,
|
||||
\OC_Defaults $defaults,
|
||||
$serverRoot,
|
||||
ICacheFactory $cacheFactory,
|
||||
IconsCacher $iconsCacher,
|
||||
@@ -407,7 +406,7 @@ class SCSSCacher {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string SCSS code for variables from ThemingDefaults
|
||||
* @return string SCSS code for variables from OC_Defaults
|
||||
*/
|
||||
private function getInjectedVariables(string $cache = ''): string {
|
||||
if ($this->injectedVariables !== null) {
|
||||
|
||||
@@ -418,7 +418,7 @@ class Updater extends BasicEmitter {
|
||||
|
||||
if (!empty($previousEnableStates)) {
|
||||
$ocApp = new \OC_App();
|
||||
if (!empty($previousEnableStates[$app])) {
|
||||
if (!empty($previousEnableStates[$app]) && is_array($previousEnableStates[$app])) {
|
||||
$ocApp->enable($app, $previousEnableStates[$app]);
|
||||
} else {
|
||||
$ocApp->enable($app);
|
||||
@@ -545,13 +545,13 @@ class Updater extends BasicEmitter {
|
||||
$log->info('\OC\Updater::incompatibleAppDisabled: Disabled incompatible app: ' . $app, ['app' => 'updater']);
|
||||
});
|
||||
$this->listen('\OC\Updater', 'checkAppStoreAppBefore', function ($app) use ($log) {
|
||||
$log->info('\OC\Updater::checkAppStoreAppBefore: Checking for update of app "' . $app . '" in appstore', ['app' => 'updater']);
|
||||
$log->debug('\OC\Updater::checkAppStoreAppBefore: Checking for update of app "' . $app . '" in appstore', ['app' => 'updater']);
|
||||
});
|
||||
$this->listen('\OC\Updater', 'upgradeAppStoreApp', function ($app) use ($log) {
|
||||
$log->info('\OC\Updater::upgradeAppStoreApp: Update app "' . $app . '" from appstore', ['app' => 'updater']);
|
||||
});
|
||||
$this->listen('\OC\Updater', 'checkAppStoreApp', function ($app) use ($log) {
|
||||
$log->info('\OC\Updater::checkAppStoreApp: Checked for update of app "' . $app . '" in appstore', ['app' => 'updater']);
|
||||
$log->debug('\OC\Updater::checkAppStoreApp: Checked for update of app "' . $app . '" in appstore', ['app' => 'updater']);
|
||||
});
|
||||
$this->listen('\OC\Updater', 'appSimulateUpdate', function ($app) use ($log) {
|
||||
$log->info('\OC\Updater::appSimulateUpdate: Checking whether the database schema for <' . $app . '> can be updated (this can take a long time depending on the database size)', ['app' => 'updater']);
|
||||
|
||||
@@ -750,6 +750,7 @@ class Session implements IUserSession, Emitter {
|
||||
}
|
||||
|
||||
$dbToken->setLastCheck($now);
|
||||
$this->tokenProvider->updateToken($dbToken);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -767,6 +768,7 @@ class Session implements IUserSession, Emitter {
|
||||
}
|
||||
|
||||
$dbToken->setLastCheck($now);
|
||||
$this->tokenProvider->updateToken($dbToken);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -924,6 +924,10 @@ class OC_Image implements \OCP\IImage {
|
||||
* @return resource|bool|\GdImage
|
||||
*/
|
||||
public function preciseResizeNew(int $width, int $height) {
|
||||
if (!($width > 0) || !($height > 0)) {
|
||||
$this->logger->info(__METHOD__ . '(): Requested image size not bigger than 0', ['app' => 'core']);
|
||||
return false;
|
||||
}
|
||||
if (!$this->valid()) {
|
||||
$this->logger->error(__METHOD__ . '(): No image loaded', ['app' => 'core']);
|
||||
return false;
|
||||
|
||||
@@ -1239,22 +1239,38 @@ class OC_Util {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the setlocal call does not work. This can happen if the right
|
||||
* Check if current locale is non-UTF8
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function isNonUTF8Locale() {
|
||||
if (function_exists('escapeshellcmd')) {
|
||||
return '' === escapeshellcmd('§');
|
||||
} elseif (function_exists('escapeshellarg')) {
|
||||
return '\'\'' === escapeshellarg('§');
|
||||
} else {
|
||||
return 0 === preg_match('/utf-?8/i', setlocale(LC_CTYPE, 0));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the setlocale call does not work. This can happen if the right
|
||||
* local packages are not available on the server.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isSetLocaleWorking() {
|
||||
if ('' === basename('§')) {
|
||||
if (self::isNonUTF8Locale()) {
|
||||
// Borrowed from \Patchwork\Utf8\Bootup::initLocale
|
||||
setlocale(LC_ALL, 'C.UTF-8', 'C');
|
||||
setlocale(LC_CTYPE, 'en_US.UTF-8', 'fr_FR.UTF-8', 'es_ES.UTF-8', 'de_DE.UTF-8', 'ru_RU.UTF-8', 'pt_BR.UTF-8', 'it_IT.UTF-8', 'ja_JP.UTF-8', 'zh_CN.UTF-8', '0');
|
||||
|
||||
// Check again
|
||||
if (self::isNonUTF8Locale()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check again
|
||||
if ('' === basename('§')) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,11 @@ interface ICalendarQuery {
|
||||
/**
|
||||
* Define the property name(s) to search for
|
||||
*
|
||||
* Note: Nextcloud only indexes *some* properties. You can not search for
|
||||
* arbitrary properties.
|
||||
*
|
||||
* @param string $value one of CATEGORIES, COMMENT, DESCRIPTION, LOCATION, RESOURCES, STATUS, SUMMARY, ATTENDEE, CONTACT or ORGANIZER
|
||||
*
|
||||
* @since 23.0.0
|
||||
*/
|
||||
public function addSearchProperty(string $value): void;
|
||||
|
||||
@@ -280,7 +280,7 @@ interface IQueryBuilder {
|
||||
/**
|
||||
* Sets the position of the first result to retrieve (the "offset").
|
||||
*
|
||||
* @param integer $firstResult The first result to return.
|
||||
* @param int $firstResult The first result to return.
|
||||
*
|
||||
* @return $this This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
@@ -299,7 +299,7 @@ interface IQueryBuilder {
|
||||
/**
|
||||
* Sets the maximum number of results to retrieve (the "limit").
|
||||
*
|
||||
* @param integer $maxResults The maximum number of results to retrieve.
|
||||
* @param int|null $maxResults The maximum number of results to retrieve.
|
||||
*
|
||||
* @return $this This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
|
||||
@@ -86,8 +86,8 @@ interface IDBConnection {
|
||||
/**
|
||||
* Used to abstract the ownCloud database access away
|
||||
* @param string $sql the sql query with ? placeholder for params
|
||||
* @param int $limit the maximum number of rows
|
||||
* @param int $offset from which row we want to start
|
||||
* @param int|null $limit the maximum number of rows
|
||||
* @param int|null $offset from which row we want to start
|
||||
* @return IPreparedStatement The prepared statement.
|
||||
* @since 6.0.0
|
||||
* @throws Exception since 21.0.0
|
||||
|
||||
@@ -513,4 +513,28 @@ class Util {
|
||||
}
|
||||
return self::$needUpgradeCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sometimes a string has to be shortened to fit within a certain maximum
|
||||
* data length in bytes. substr() you may break multibyte characters,
|
||||
* because it operates on single byte level. mb_substr() operates on
|
||||
* characters, so does not ensure that the shortend string satisfies the
|
||||
* max length in bytes.
|
||||
*
|
||||
* For example, json_encode is messing with multibyte characters a lot,
|
||||
* replacing them with something along "\u1234".
|
||||
*
|
||||
* This function shortens the string with by $accurancy (-5) from
|
||||
* $dataLength characters, until it fits within $dataLength bytes.
|
||||
*
|
||||
* @since 23.0.0
|
||||
*/
|
||||
public static function shortenMultibyteString(string $subject, int $dataLength, int $accuracy = 5): string {
|
||||
$temp = mb_substr($subject, 0, $dataLength);
|
||||
// json encodes encapsulates the string in double quotes, they need to be substracted
|
||||
while ((strlen(json_encode($temp)) - 2) > $dataLength) {
|
||||
$temp = mb_substr($temp, 0, -$accuracy);
|
||||
}
|
||||
return $temp;
|
||||
}
|
||||
}
|
||||
|
||||
56
package-lock.json
generated
56
package-lock.json
generated
@@ -29,8 +29,8 @@
|
||||
"autosize": "^5.0.1",
|
||||
"backbone": "^1.4.0",
|
||||
"blueimp-md5": "^2.19.0",
|
||||
"bootstrap": "^4.6.0",
|
||||
"camelcase": "^6.2.0",
|
||||
"bootstrap": "^4.6.1",
|
||||
"camelcase": "^6.2.1",
|
||||
"clipboard": "^2.0.8",
|
||||
"core-js": "^3.19.1",
|
||||
"css-vars-ponyfill": "^2.4.7",
|
||||
@@ -47,9 +47,9 @@
|
||||
"jquery-ui-dist": "^1.12.1",
|
||||
"jstimezonedetect": "^1.0.7",
|
||||
"lodash": "^4.17.21",
|
||||
"marked": "^3.0.7",
|
||||
"marked": "^3.0.8",
|
||||
"moment": "^2.29.1",
|
||||
"moment-timezone": "^0.5.33",
|
||||
"moment-timezone": "^0.5.34",
|
||||
"nextcloud-vue-collections": "^0.9.0",
|
||||
"p-limit": "^4.0.0",
|
||||
"p-queue": "^7.1.0",
|
||||
@@ -9209,9 +9209,9 @@
|
||||
"integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ=="
|
||||
},
|
||||
"node_modules/bootstrap": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.0.tgz",
|
||||
"integrity": "sha512-Io55IuQY3kydzHtbGvQya3H+KorS/M9rSNyfCGCg9WZ4pyT/lCxIlpJgG1GXW/PswzC84Tr2fBYi+7+jFVQQBw==",
|
||||
"version": "4.6.1",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.1.tgz",
|
||||
"integrity": "sha512-0dj+VgI9Ecom+rvvpNZ4MUZJz8dcX7WCX+eTID9+/8HgOkv3dsRzi8BGeZJCQU6flWQVYxwTQnEZFrmJSEO7og==",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/bootstrap"
|
||||
@@ -9526,9 +9526,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/camelcase": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz",
|
||||
"integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==",
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz",
|
||||
"integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
@@ -17716,9 +17716,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/marked": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-3.0.7.tgz",
|
||||
"integrity": "sha512-ctKqbnLuNbsHbI26cfMyOlKgXGfl1orOv1AvWWDX7AkgfMOwCWvmuYc+mVLeWhQ9W6hdWVBynOs96VkcscKo0Q==",
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-3.0.8.tgz",
|
||||
"integrity": "sha512-0gVrAjo5m0VZSJb4rpL59K1unJAMb/hm8HRXqasD8VeC8m91ytDPMritgFSlKonfdt+rRYYpP/JfLxgIX8yoSw==",
|
||||
"bin": {
|
||||
"marked": "bin/marked"
|
||||
},
|
||||
@@ -18351,9 +18351,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/moment-timezone": {
|
||||
"version": "0.5.33",
|
||||
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.33.tgz",
|
||||
"integrity": "sha512-PTc2vcT8K9J5/9rDEPe5czSIKgLoGsH8UNpA4qZTVw0Vd/Uz19geE9abbIOQKaAQFcnQ3v5YEXrbSc5BpshH+w==",
|
||||
"version": "0.5.34",
|
||||
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.34.tgz",
|
||||
"integrity": "sha512-3zAEHh2hKUs3EXLESx/wsgw6IQdusOT8Bxm3D9UrHPQR7zlMmzwybC8zHEM1tQ4LJwP7fcxrWr8tuBg05fFCbg==",
|
||||
"dependencies": {
|
||||
"moment": ">= 2.9.0"
|
||||
},
|
||||
@@ -31085,9 +31085,9 @@
|
||||
"integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ=="
|
||||
},
|
||||
"bootstrap": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.0.tgz",
|
||||
"integrity": "sha512-Io55IuQY3kydzHtbGvQya3H+KorS/M9rSNyfCGCg9WZ4pyT/lCxIlpJgG1GXW/PswzC84Tr2fBYi+7+jFVQQBw==",
|
||||
"version": "4.6.1",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.1.tgz",
|
||||
"integrity": "sha512-0dj+VgI9Ecom+rvvpNZ4MUZJz8dcX7WCX+eTID9+/8HgOkv3dsRzi8BGeZJCQU6flWQVYxwTQnEZFrmJSEO7og==",
|
||||
"requires": {}
|
||||
},
|
||||
"brace-expansion": {
|
||||
@@ -31361,9 +31361,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz",
|
||||
"integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg=="
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz",
|
||||
"integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA=="
|
||||
},
|
||||
"camelcase-keys": {
|
||||
"version": "6.2.2",
|
||||
@@ -37614,9 +37614,9 @@
|
||||
}
|
||||
},
|
||||
"marked": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-3.0.7.tgz",
|
||||
"integrity": "sha512-ctKqbnLuNbsHbI26cfMyOlKgXGfl1orOv1AvWWDX7AkgfMOwCWvmuYc+mVLeWhQ9W6hdWVBynOs96VkcscKo0Q=="
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-3.0.8.tgz",
|
||||
"integrity": "sha512-0gVrAjo5m0VZSJb4rpL59K1unJAMb/hm8HRXqasD8VeC8m91ytDPMritgFSlKonfdt+rRYYpP/JfLxgIX8yoSw=="
|
||||
},
|
||||
"material-colors": {
|
||||
"version": "1.2.6",
|
||||
@@ -38112,9 +38112,9 @@
|
||||
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
|
||||
},
|
||||
"moment-timezone": {
|
||||
"version": "0.5.33",
|
||||
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.33.tgz",
|
||||
"integrity": "sha512-PTc2vcT8K9J5/9rDEPe5czSIKgLoGsH8UNpA4qZTVw0Vd/Uz19geE9abbIOQKaAQFcnQ3v5YEXrbSc5BpshH+w==",
|
||||
"version": "0.5.34",
|
||||
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.34.tgz",
|
||||
"integrity": "sha512-3zAEHh2hKUs3EXLESx/wsgw6IQdusOT8Bxm3D9UrHPQR7zlMmzwybC8zHEM1tQ4LJwP7fcxrWr8tuBg05fFCbg==",
|
||||
"requires": {
|
||||
"moment": ">= 2.9.0"
|
||||
}
|
||||
|
||||
@@ -45,8 +45,8 @@
|
||||
"autosize": "^5.0.1",
|
||||
"backbone": "^1.4.0",
|
||||
"blueimp-md5": "^2.19.0",
|
||||
"bootstrap": "^4.6.0",
|
||||
"camelcase": "^6.2.0",
|
||||
"bootstrap": "^4.6.1",
|
||||
"camelcase": "^6.2.1",
|
||||
"clipboard": "^2.0.8",
|
||||
"core-js": "^3.19.1",
|
||||
"css-vars-ponyfill": "^2.4.7",
|
||||
@@ -63,9 +63,9 @@
|
||||
"jquery-ui-dist": "^1.12.1",
|
||||
"jstimezonedetect": "^1.0.7",
|
||||
"lodash": "^4.17.21",
|
||||
"marked": "^3.0.7",
|
||||
"marked": "^3.0.8",
|
||||
"moment": "^2.29.1",
|
||||
"moment-timezone": "^0.5.33",
|
||||
"moment-timezone": "^0.5.34",
|
||||
"nextcloud-vue-collections": "^0.9.0",
|
||||
"p-limit": "^4.0.0",
|
||||
"p-queue": "^7.1.0",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
##
|
||||
## Bundle of CA Root Certificates
|
||||
##
|
||||
## Certificate data from Mozilla as of: Thu Sep 30 03:12:05 2021 GMT
|
||||
## Certificate data from Mozilla as of: Tue Oct 26 03:12:05 2021 GMT
|
||||
##
|
||||
## This is a bundle of X.509 certificates of public Certificate Authorities
|
||||
## (CA). These were automatically extracted from Mozilla's root certificates
|
||||
@@ -14,7 +14,7 @@
|
||||
## Just configure this file as the SSLCACertificateFile.
|
||||
##
|
||||
## Conversion done with mk-ca-bundle.pl version 1.28.
|
||||
## SHA256: c8f6733d1ff4e6a4769c182971a1234f95ae079247a9c439a13423fe8ba5c24f
|
||||
## SHA256: bb36818a81feaa4cca61101e6d6276cd09e972efcb08112dfed846918ca41d7f
|
||||
##
|
||||
|
||||
|
||||
@@ -3152,3 +3152,81 @@ WWRrJ8/vJ8HjJLWG965+Mk2weWjROeiQWMODvA8s1pfrzgzhIMfatz7DP78v3DSk+yshzWePS/Tj
|
||||
OPQD8rv7gmsHINFSH5pkAnuYZttcTVoP0ISVoDwUQwbKytu4QTbaakRnh6+v40URFWkIsr4WOZck
|
||||
bxJF0WddCajJFdr60qZfE2Efv4WstK2tBZQIgx51F9NxO5NQI1mg7TyRVJ12AMXDuDjb
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
TunTrust Root CA
|
||||
================
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQELBQAwYTELMAkG
|
||||
A1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUgQ2VydGlmaWNhdGlvbiBFbGVj
|
||||
dHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJvb3QgQ0EwHhcNMTkwNDI2MDg1NzU2WhcNNDQw
|
||||
NDI2MDg1NzU2WjBhMQswCQYDVQQGEwJUTjE3MDUGA1UECgwuQWdlbmNlIE5hdGlvbmFsZSBkZSBD
|
||||
ZXJ0aWZpY2F0aW9uIEVsZWN0cm9uaXF1ZTEZMBcGA1UEAwwQVHVuVHJ1c3QgUm9vdCBDQTCCAiIw
|
||||
DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPN0/y9BFPdDCA61YguBUtB9YOCfvdZn56eY+hz
|
||||
2vYGqU8ftPkLHzmMmiDQfgbU7DTZhrx1W4eI8NLZ1KMKsmwb60ksPqxd2JQDoOw05TDENX37Jk0b
|
||||
bjBU2PWARZw5rZzJJQRNmpA+TkBuimvNKWfGzC3gdOgFVwpIUPp6Q9p+7FuaDmJ2/uqdHYVy7BG7
|
||||
NegfJ7/Boce7SBbdVtfMTqDhuazb1YMZGoXRlJfXyqNlC/M4+QKu3fZnz8k/9YosRxqZbwUN/dAd
|
||||
gjH8KcwAWJeRTIAAHDOFli/LQcKLEITDCSSJH7UP2dl3RxiSlGBcx5kDPP73lad9UKGAwqmDrViW
|
||||
VSHbhlnUr8a83YFuB9tgYv7sEG7aaAH0gxupPqJbI9dkxt/con3YS7qC0lH4Zr8GRuR5KiY2eY8f
|
||||
Tpkdso8MDhz/yV3A/ZAQprE38806JG60hZC/gLkMjNWb1sjxVj8agIl6qeIbMlEsPvLfe/ZdeikZ
|
||||
juXIvTZxi11Mwh0/rViizz1wTaZQmCXcI/m4WEEIcb9PuISgjwBUFfyRbVinljvrS5YnzWuioYas
|
||||
DXxU5mZMZl+QviGaAkYt5IPCgLnPSz7ofzwB7I9ezX/SKEIBlYrilz0QIX32nRzFNKHsLA4KUiwS
|
||||
VXAkPcvCFDVDXSdOvsC9qnyW5/yeYa1E0wCXAgMBAAGjYzBhMB0GA1UdDgQWBBQGmpsfU33x9aTI
|
||||
04Y+oXNZtPdEITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFAaamx9TffH1pMjThj6hc1m0
|
||||
90QhMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAqgVutt0Vyb+zxiD2BkewhpMl
|
||||
0425yAA/l/VSJ4hxyXT968pk21vvHl26v9Hr7lxpuhbI87mP0zYuQEkHDVneixCwSQXi/5E/S7fd
|
||||
Ao74gShczNxtr18UnH1YeA32gAm56Q6XKRm4t+v4FstVEuTGfbvE7Pi1HE4+Z7/FXxttbUcoqgRY
|
||||
YdZ2vyJ/0Adqp2RT8JeNnYA/u8EH22Wv5psymsNUk8QcCMNE+3tjEUPRahphanltkE8pjkcFwRJp
|
||||
adbGNjHh/PqAulxPxOu3Mqz4dWEX1xAZufHSCe96Qp1bWgvUxpVOKs7/B9dPfhgGiPEZtdmYu65x
|
||||
xBzndFlY7wyJz4sfdZMaBBSSSFCp61cpABbjNhzI+L/wM9VBD8TMPN3pM0MBkRArHtG5Xc0yGYuP
|
||||
jCB31yLEQtyEFpslbei0VXF/sHyz03FJuc9SpAQ/3D2gu68zngowYI7bnV2UqL1g52KAdoGDDIzM
|
||||
MEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQCvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9z
|
||||
ZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZHu/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3r
|
||||
AZ3r2OvEhJn7wAzMMujjd9qDRIueVSjAi1jTkD5OGwDxFa2DK5o=
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
HARICA TLS RSA Root CA 2021
|
||||
===========================
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBsMQswCQYDVQQG
|
||||
EwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u
|
||||
cyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0EgUm9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTUz
|
||||
OFoXDTQ1MDIxMzEwNTUzN1owbDELMAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRl
|
||||
bWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgUlNB
|
||||
IFJvb3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIvC569lmwVnlskN
|
||||
JLnQDmT8zuIkGCyEf3dRywQRNrhe7Wlxp57kJQmXZ8FHws+RFjZiPTgE4VGC/6zStGndLuwRo0Xu
|
||||
a2s7TL+MjaQenRG56Tj5eg4MmOIjHdFOY9TnuEFE+2uva9of08WRiFukiZLRgeaMOVig1mlDqa2Y
|
||||
Ulhu2wr7a89o+uOkXjpFc5gH6l8Cct4MpbOfrqkdtx2z/IpZ525yZa31MJQjB/OCFks1mJxTuy/K
|
||||
5FrZx40d/JiZ+yykgmvwKh+OC19xXFyuQnspiYHLA6OZyoieC0AJQTPb5lh6/a6ZcMBaD9YThnEv
|
||||
dmn8kN3bLW7R8pv1GmuebxWMevBLKKAiOIAkbDakO/IwkfN4E8/BPzWr8R0RI7VDIp4BkrcYAuUR
|
||||
0YLbFQDMYTfBKnya4dC6s1BG7oKsnTH4+yPiAwBIcKMJJnkVU2DzOFytOOqBAGMUuTNe3QvboEUH
|
||||
GjMJ+E20pwKmafTCWQWIZYVWrkvL4N48fS0ayOn7H6NhStYqE613TBoYm5EPWNgGVMWX+Ko/IIqm
|
||||
haZ39qb8HOLubpQzKoNQhArlT4b4UEV4AIHrW2jjJo3Me1xR9BQsQL4aYB16cmEdH2MtiKrOokWQ
|
||||
CPxrvrNQKlr9qEgYRtaQQJKQCoReaDH46+0N0x3GfZkYVVYnZS6NRcUk7M7jAgMBAAGjQjBAMA8G
|
||||
A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFApII6ZgpJIKM+qTW8VX6iVNvRLuMA4GA1UdDwEB/wQE
|
||||
AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAPpBIqm5iFSVmewzVjIuJndftTgfvnNAUX15QvWiWkKQU
|
||||
EapobQk1OUAJ2vQJLDSle1mESSmXdMgHHkdt8s4cUCbjnj1AUz/3f5Z2EMVGpdAgS1D0NTsY9FVq
|
||||
QRtHBmg8uwkIYtlfVUKqrFOFrJVWNlar5AWMxajaH6NpvVMPxP/cyuN+8kyIhkdGGvMA9YCRotxD
|
||||
QpSbIPDRzbLrLFPCU3hKTwSUQZqPJzLB5UkZv/HywouoCjkxKLR9YjYsTewfM7Z+d21+UPCfDtcR
|
||||
j88YxeMn/ibvBZ3PzzfF0HvaO7AWhAw6k9a+F9sPPg4ZeAnHqQJyIkv3N3a6dcSFA1pj1bF1BcK5
|
||||
vZStjBWZp5N99sXzqnTPBIWUmAD04vnKJGW/4GKvyMX6ssmeVkjaef2WdhW+o45WxLM0/L5H9MG0
|
||||
qPzVMIho7suuyWPEdr6sOBjhXlzPrjoiUevRi7PzKzMHVIf6tLITe7pTBGIBnfHAT+7hOtSLIBD6
|
||||
Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79aPib8qXPMThcFarmlwDB31qlpzmq6YR/
|
||||
PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YWxw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnn
|
||||
kf3/W9b3raYvAwtt41dU63ZTGI0RmLo=
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
HARICA TLS ECC Root CA 2021
|
||||
===========================
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQswCQYDVQQGEwJH
|
||||
UjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBD
|
||||
QTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9vdCBDQSAyMDIxMB4XDTIxMDIxOTExMDExMFoX
|
||||
DTQ1MDIxMzExMDEwOVowbDELMAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWlj
|
||||
IGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgRUNDIFJv
|
||||
b3QgQ0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDgI/rGgltJ6rK9JOtDA4MM7KKrxcm1l
|
||||
AEeIhPyaJmuqS7psBAqIXhfyVYf8MLA04jRYVxqEU+kw2anylnTDUR9YSTHMmE5gEYd103KUkE+b
|
||||
ECUqqHgtvpBBWJAVcqeht6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW
|
||||
0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAi
|
||||
rcJRQO9gcS3ujwLEXQNwSaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/Qw
|
||||
CZ61IygNnxS2PFOiTAZpffpskcYqSUXm7LcT4Tps
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
@@ -64,7 +64,7 @@ if [ "$1" = "--acceptance-tests-dir" ]; then
|
||||
fi
|
||||
|
||||
ACCEPTANCE_TESTS_CONFIG_DIR="../../$ACCEPTANCE_TESTS_DIR/config"
|
||||
DEV_BRANCH="master"
|
||||
DEV_BRANCH="stable23"
|
||||
|
||||
# "--timeout-multiplier N" option can be provided to set the timeout multiplier
|
||||
# to be used in ActorContext.
|
||||
|
||||
@@ -32,7 +32,7 @@ class EncodingTest extends \Test\Files\Storage\Storage {
|
||||
|
||||
public function directoryProvider() {
|
||||
$a = parent::directoryProvider();
|
||||
$a[] = [self::NFD_NAME];
|
||||
$a[] = [self::NFC_NAME];
|
||||
return $a;
|
||||
}
|
||||
|
||||
@@ -199,4 +199,46 @@ class EncodingTest extends \Test\Files\Storage\Storage {
|
||||
|
||||
$this->assertEquals('bar', $this->instance->file_get_contents(self::NFC_NAME . '2/test2.txt'));
|
||||
}
|
||||
|
||||
public function testNormalizedDirectoryEntriesOpenDir() {
|
||||
$this->sourceStorage->mkdir('/test');
|
||||
$this->sourceStorage->mkdir('/test/' . self::NFD_NAME);
|
||||
|
||||
$this->assertTrue($this->instance->file_exists('/test/' . self::NFC_NAME));
|
||||
$this->assertTrue($this->instance->file_exists('/test/' . self::NFD_NAME));
|
||||
|
||||
$dh = $this->instance->opendir('/test');
|
||||
$content = [];
|
||||
while ($file = readdir($dh)) {
|
||||
if ($file != '.' and $file != '..') {
|
||||
$content[] = $file;
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertCount(1, $content);
|
||||
$this->assertEquals(self::NFC_NAME, $content[0]);
|
||||
}
|
||||
|
||||
public function testNormalizedDirectoryEntriesGetDirectoryContent() {
|
||||
$this->sourceStorage->mkdir('/test');
|
||||
$this->sourceStorage->mkdir('/test/' . self::NFD_NAME);
|
||||
|
||||
$this->assertTrue($this->instance->file_exists('/test/' . self::NFC_NAME));
|
||||
$this->assertTrue($this->instance->file_exists('/test/' . self::NFD_NAME));
|
||||
|
||||
$content = iterator_to_array($this->instance->getDirectoryContent('/test'));
|
||||
$this->assertCount(1, $content);
|
||||
$this->assertEquals(self::NFC_NAME, $content[0]['name']);
|
||||
}
|
||||
|
||||
public function testNormalizedGetMetaData() {
|
||||
$this->sourceStorage->mkdir('/test');
|
||||
$this->sourceStorage->mkdir('/test/' . self::NFD_NAME);
|
||||
|
||||
$entry = $this->instance->getMetaData('/test/' . self::NFC_NAME);
|
||||
$this->assertEquals(self::NFC_NAME, $entry['name']);
|
||||
|
||||
$entry = $this->instance->getMetaData('/test/' . self::NFD_NAME);
|
||||
$this->assertEquals(self::NFC_NAME, $entry['name']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,18 @@ class IpAddressTest extends TestCase {
|
||||
'192.168.0.123',
|
||||
'192.168.0.123/32',
|
||||
],
|
||||
[
|
||||
'::ffff:192.168.0.123',
|
||||
'192.168.0.123/32',
|
||||
],
|
||||
[
|
||||
'0:0:0:0:0:ffff:192.168.0.123',
|
||||
'192.168.0.123/32',
|
||||
],
|
||||
[
|
||||
'0:0:0:0:0:ffff:c0a8:7b',
|
||||
'192.168.0.123/32',
|
||||
],
|
||||
[
|
||||
'2001:0db8:85a3:0000:0000:8a2e:0370:7334',
|
||||
'2001:db8:85a3::/64',
|
||||
|
||||
@@ -1264,7 +1264,7 @@ class SessionTest extends \Test\TestCase {
|
||||
$mapper->expects($this->any())
|
||||
->method('getToken')
|
||||
->willReturn($token);
|
||||
$mapper->expects($this->once())
|
||||
$mapper->expects($this->exactly(2))
|
||||
->method('update');
|
||||
$request
|
||||
->expects($this->any())
|
||||
@@ -1314,7 +1314,7 @@ class SessionTest extends \Test\TestCase {
|
||||
$mapper->expects($this->any())
|
||||
->method('getToken')
|
||||
->willReturn($token);
|
||||
$mapper->expects($this->never())
|
||||
$mapper->expects($this->once())
|
||||
->method('update');
|
||||
$request
|
||||
->expects($this->any())
|
||||
|
||||
@@ -74,6 +74,18 @@ class UtilTest extends \Test\TestCase {
|
||||
$this->assertEquals("/%C2%A7%23%40test%25%26%5E%C3%A4/-child", $result);
|
||||
}
|
||||
|
||||
public function testIsNonUTF8Locale() {
|
||||
// OC_Util::isNonUTF8Locale() assumes escapeshellcmd('§') returns '' with non-UTF-8 locale.
|
||||
$locale = setlocale(LC_CTYPE, 0);
|
||||
setlocale(LC_CTYPE, 'C');
|
||||
$this->assertEquals('', escapeshellcmd('§'));
|
||||
$this->assertEquals('\'\'', escapeshellarg('§'));
|
||||
setlocale(LC_CTYPE, 'C.UTF-8');
|
||||
$this->assertEquals('§', escapeshellcmd('§'));
|
||||
$this->assertEquals('\'§\'', escapeshellarg('§'));
|
||||
setlocale(LC_CTYPE, $locale);
|
||||
}
|
||||
|
||||
public function testFileInfoLoaded() {
|
||||
$expected = function_exists('finfo_open');
|
||||
$this->assertEquals($expected, \OC_Util::fileInfoLoaded());
|
||||
@@ -298,4 +310,11 @@ class UtilTest extends \Test\TestCase {
|
||||
'myApp/vendor/myFancyCSSFile2',
|
||||
], \OC_Util::$styles);
|
||||
}
|
||||
|
||||
public function testShortenMultibyteString() {
|
||||
$this->assertEquals('Short nuff', \OCP\Util::shortenMultibyteString('Short nuff', 255));
|
||||
$this->assertEquals('ABC', \OCP\Util::shortenMultibyteString('ABCDEF', 3));
|
||||
// each of the characters is 12 bytes
|
||||
$this->assertEquals('🙈', \OCP\Util::shortenMultibyteString('🙈🙊🙉', 16, 2));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,10 +30,10 @@
|
||||
// between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel
|
||||
// when updating major/minor version number.
|
||||
|
||||
$OC_Version = [23, 0, 0, 7];
|
||||
$OC_Version = [23, 0, 0, 10];
|
||||
|
||||
// The human readable string
|
||||
$OC_VersionString = '23.0.0 RC1';
|
||||
$OC_VersionString = '23.0.0';
|
||||
|
||||
$OC_VersionCanBeUpgradedFrom = [
|
||||
'nextcloud' => [
|
||||
|
||||
Reference in New Issue
Block a user