Compare commits

..

2 Commits

Author SHA1 Message Date
Carl Schwan 3caa1467b1 refactor: Improve log message
Co-authored-by: Josh <josh.t.richards@gmail.com>
Signed-off-by: Carl Schwan <carl@carlschwan.eu>
2026-03-02 13:19:08 +01:00
Robin Appelman 2c2335b8b4 fix: improve logging around failed chunked object store uploads
Signed-off-by: Robin Appelman <robin@icewind.nl>
2026-02-27 14:50:49 +01:00
398 changed files with 1232 additions and 1740 deletions
+1 -1
View File
@@ -73,7 +73,7 @@ body:
options:
- "32"
- "33"
- "34 (master)"
- "master"
validations:
required: true
- type: dropdown
-45
View File
@@ -1,45 +0,0 @@
# SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
# SPDX-License-Identifier: AGPL-3.0-or-later
name: Auto-label bug reports
on:
issues:
types: [opened]
jobs:
add-version-label:
if: contains(github.event.issue.title, '[Bug]')
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Extract version number and apply label
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const body = context.payload.issue.body || '';
const normalizedBody = body.replace(/\r\n?/g, '\n');
let label = '';
// Extract Nextcloud Server version number from a block like:
// ### Nextcloud Server version
// 32
const versionMatch = normalizedBody.match(/### Nextcloud Server version\s*\n+([0-9]{1,3})\b/);
let nextcloudVersion = null;
if (versionMatch) {
nextcloudVersion = parseInt(versionMatch[1], 10);
label = nextcloudVersion + '-feedback';
}
if (label) {
try {
await github.rest.issues.addLabels({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: [label]
});
} catch (error) {
core.setFailed(`Failed to add label "${label}": ${error.message || error}`);
}
}
+2 -2
View File
@@ -37,13 +37,13 @@ jobs:
persist-credentials: false
- name: Initialize CodeQL
uses: github/codeql-action/init@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
uses: github/codeql-action/init@45cbd0c69e560cd9e7cd7f8c32362050c9b7ded2 # v4.32.2
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
config-file: ./.github/codeql-config.yml
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
uses: github/codeql-action/analyze@45cbd0c69e560cd9e7cd7f8c32362050c9b7ded2 # v4.32.2
with:
category: "/language:${{matrix.language}}"
+3 -3
View File
@@ -171,7 +171,7 @@ jobs:
run: ./node_modules/cypress/bin/cypress install
- name: Run ${{ matrix.containers == 'component' && 'component' || 'E2E' }} cypress tests
uses: cypress-io/github-action@bc22e01685c56e89e7813fd8e26f33dc47f87e15 # v7.1.5
uses: cypress-io/github-action@84d178e4bbce871e23f2ffa3085898cde0e4f0ec # v7.1.2
with:
# We already installed the dependencies in the init job
install: false
@@ -195,7 +195,7 @@ jobs:
SETUP_TESTING: ${{ matrix.containers == 'setup' && 'true' || '' }}
- name: Upload snapshots and videos
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
if: always()
with:
name: snapshots_${{ matrix.containers }}
@@ -218,7 +218,7 @@ jobs:
run: docker exec nextcloud-e2e-test-server_${{ env.APP_NAME }} tar -cvjf - data > data.tar
- name: Upload data archive
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
if: failure() && matrix.containers != 'component'
with:
name: nc_data_${{ matrix.containers }}
+1 -1
View File
@@ -71,7 +71,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Python
uses: LizardByte/actions/actions/setup_python@70bb8d394d1c92f6113aeec6ae9cc959a5763d15 # v2026.227.200013
uses: LizardByte/actions/actions/setup_python@9bf3ef783775e17fe6b8dde3585d94ec570b93c2 # v2026.212.22356
with:
python-version: '2.7'
+3 -3
View File
@@ -63,7 +63,7 @@ jobs:
ref: ${{ github.event.pull_request.head.ref }}
- name: Run before measurements
uses: nextcloud/profiler@6a74c915048285b35b8e1cd96c0835a635945044
uses: nextcloud/profiler@6801ee10fc80f10b444388fb6ca9b36ad8a2ea83
with:
run: |
curl -s -X PROPFIND -u test:test http://localhost:8080/remote.php/dav/files/test
@@ -85,7 +85,7 @@ jobs:
- name: Run after measurements
id: compare
uses: nextcloud/profiler@6a74c915048285b35b8e1cd96c0835a635945044
uses: nextcloud/profiler@6801ee10fc80f10b444388fb6ca9b36ad8a2ea83
with:
run: |
curl -s -X PROPFIND -u test:test http://localhost:8080/remote.php/dav/files/test
@@ -99,7 +99,7 @@ jobs:
- name: Upload profiles
if: always()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f
with:
name: profiles
path: |
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
issues: write
steps:
- uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v9
- uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v9
with:
repo-token: ${{ secrets.COMMAND_BOT_PAT }}
stale-issue-message: >
+1 -1
View File
@@ -88,7 +88,7 @@ jobs:
- name: Upload Security Analysis results to GitHub
if: always()
uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v3
uses: github/codeql-action/upload-sarif@45cbd0c69e560cd9e7cd7f8c32362050c9b7ded2 # v3
with:
sarif_file: results.sarif
+1 -3
View File
@@ -20,15 +20,13 @@ class Capabilities implements ICapability {
}
/**
* @return array{dav: array{chunking: string, public_shares_chunking: bool, search_supports_creation_time: bool, search_supports_upload_time: bool, bulkupload?: string, absence-supported?: bool, absence-replacement?: bool}}
* @return array{dav: array{chunking: string, public_shares_chunking: bool, bulkupload?: string, absence-supported?: bool, absence-replacement?: bool}}
*/
public function getCapabilities() {
$capabilities = [
'dav' => [
'chunking' => '1.0',
'public_shares_chunking' => true,
'search_supports_creation_time' => true,
'search_supports_upload_time' => true,
]
];
if ($this->config->getSystemValueBool('bulkupload.enabled', true)) {
-5
View File
@@ -86,7 +86,6 @@ class FileSearchBackend implements ISearchBackend {
new SearchPropertyDefinition('{DAV:}displayname', true, true, true),
new SearchPropertyDefinition('{DAV:}getcontenttype', true, true, true),
new SearchPropertyDefinition('{DAV:}getlastmodified', true, true, true, SearchPropertyDefinition::DATATYPE_DATETIME),
new SearchPropertyDefinition('{DAV:}creationdate', true, true, true, SearchPropertyDefinition::DATATYPE_DATETIME),
new SearchPropertyDefinition('{http://nextcloud.org/ns}upload_time', true, true, true, SearchPropertyDefinition::DATATYPE_DATETIME),
new SearchPropertyDefinition(FilesPlugin::SIZE_PROPERTYNAME, true, true, true, SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER),
new SearchPropertyDefinition(TagsPlugin::FAVORITE_PROPERTYNAME, true, true, true, SearchPropertyDefinition::DATATYPE_BOOLEAN),
@@ -300,8 +299,6 @@ class FileSearchBackend implements ISearchBackend {
return $node->getName();
case '{DAV:}getlastmodified':
return $node->getLastModified();
case '{DAV:}creationdate':
return $node->getNode()->getCreationTime();
case '{http://nextcloud.org/ns}upload_time':
return $node->getNode()->getUploadTime();
case FilesPlugin::SIZE_PROPERTYNAME:
@@ -464,8 +461,6 @@ class FileSearchBackend implements ISearchBackend {
return 'mimetype';
case '{DAV:}getlastmodified':
return 'mtime';
case '{DAV:}creationdate':
return 'creation_time';
case '{http://nextcloud.org/ns}upload_time':
return 'upload_time';
case FilesPlugin::SIZE_PROPERTYNAME:
+1 -9
View File
@@ -30,9 +30,7 @@
"type": "object",
"required": [
"chunking",
"public_shares_chunking",
"search_supports_creation_time",
"search_supports_upload_time"
"public_shares_chunking"
],
"properties": {
"chunking": {
@@ -41,12 +39,6 @@
"public_shares_chunking": {
"type": "boolean"
},
"search_supports_creation_time": {
"type": "boolean"
},
"search_supports_upload_time": {
"type": "boolean"
},
"bulkupload": {
"type": "string"
},
-6
View File
@@ -31,8 +31,6 @@ class CapabilitiesTest extends TestCase {
'dav' => [
'chunking' => '1.0',
'public_shares_chunking' => true,
'search_supports_creation_time' => true,
'search_supports_upload_time' => true,
],
];
$this->assertSame($expected, $capabilities->getCapabilities());
@@ -53,8 +51,6 @@ class CapabilitiesTest extends TestCase {
'dav' => [
'chunking' => '1.0',
'public_shares_chunking' => true,
'search_supports_creation_time' => true,
'search_supports_upload_time' => true,
'bulkupload' => '1.0',
],
];
@@ -76,8 +72,6 @@ class CapabilitiesTest extends TestCase {
'dav' => [
'chunking' => '1.0',
'public_shares_chunking' => true,
'search_supports_creation_time' => true,
'search_supports_upload_time' => true,
'absence-supported' => true,
'absence-replacement' => true,
],
+1 -1
View File
@@ -79,7 +79,7 @@ OC.L10N.register(
"Go to the \"{dir}\" directory" : "Vaia ao directorio «{dir}».",
"Current directory path" : "Ruta do directorio actual",
"Share" : "Compartir",
"Reload content" : "Volver cargar o contido",
"Reload content" : "Recargar o contido",
"Your have used your space quota and cannot upload files anymore" : "Vde. usou a súa cota de espazo e xa non pode enviar ningún ficheiro más",
"You do not have permission to upload or create files here." : "Non ten permiso para enviar ou crear ficheiros aquí.",
"Drag and drop files here to upload" : "Arrastre e solte os ficheiros aquí para envialos",
+1 -1
View File
@@ -77,7 +77,7 @@
"Go to the \"{dir}\" directory" : "Vaia ao directorio «{dir}».",
"Current directory path" : "Ruta do directorio actual",
"Share" : "Compartir",
"Reload content" : "Volver cargar o contido",
"Reload content" : "Recargar o contido",
"Your have used your space quota and cannot upload files anymore" : "Vde. usou a súa cota de espazo e xa non pode enviar ningún ficheiro más",
"You do not have permission to upload or create files here." : "Non ten permiso para enviar ou crear ficheiros aquí.",
"Drag and drop files here to upload" : "Arrastre e solte os ficheiros aquí para envialos",
+1 -1
View File
@@ -24,7 +24,7 @@ class ConfigLexicon implements ILexicon {
public const OVERWRITES_HOME_FOLDERS = 'overwrites_home_folders';
public function getStrictness(): Strictness {
return Strictness::IGNORE;
return Strictness::NOTICE;
}
public function getAppConfigs(): array {
@@ -42,11 +42,6 @@
<FavoriteIcon v-once />
</span>
<!-- Recently created icon -->
<span v-else-if="isRecentView && isRecentlyCreated" class="files-list__row-icon-recently-created">
<RecentlyCreatedIcon v-once />
</span>
<component
:is="fileOverlay"
v-if="fileOverlay"
@@ -76,7 +71,6 @@ import PlayCircleIcon from 'vue-material-design-icons/PlayCircle.vue'
import TagIcon from 'vue-material-design-icons/Tag.vue'
import CollectivesIcon from './CollectivesIcon.vue'
import FavoriteIcon from './FavoriteIcon.vue'
import RecentlyCreatedIcon from './RecentlyCreatedIcon.vue'
import { usePreviewImage } from '../../composables/usePreviewImage.ts'
import logger from '../../logger.ts'
import { isLivePhoto } from '../../services/LivePhotos.ts'
@@ -97,7 +91,6 @@ export default defineComponent({
LinkIcon,
NetworkIcon,
TagIcon,
RecentlyCreatedIcon,
},
props: {
@@ -145,21 +138,6 @@ export default defineComponent({
return this.source.attributes.favorite === 1
},
isRecentlyCreated(): boolean {
if (!this.source.crtime) {
return false
}
const oneDayAgo = new Date()
oneDayAgo.setDate(oneDayAgo.getDate() - 1)
return this.source.crtime > oneDayAgo
},
isRecentView(): boolean {
return this.$route?.params?.view === 'recent'
},
userConfig(): UserConfig {
return this.userConfigStore.userConfig
},
@@ -1,71 +0,0 @@
<!--
- SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
- SPDX-License-Identifier: AGPL-3.0-or-later
-->
<template>
<NcIconSvgWrapper class="recently-created-marker-icon" :name="t('files', 'Recently created')" :path="mdiPlus" />
</template>
<script lang="ts">
import { mdiPlus } from '@mdi/js'
import { t } from '@nextcloud/l10n'
import { defineComponent } from 'vue'
import NcIconSvgWrapper from '@nextcloud/vue/components/NcIconSvgWrapper'
/**
* A recently created icon to be used for overlaying recently created entries like the file preview / icon
* It has a stroke around the icon to ensure enough contrast for accessibility.
*
* If the background has a hover state you might want to also apply it to the stroke like this:
* ```scss
* .parent:hover :deep(.recently-created-marker-icon svg path) {
* stroke: var(--color-background-hover);
* }
* ```
*/
export default defineComponent({
name: 'RecentlyCreatedIcon',
components: {
NcIconSvgWrapper,
},
setup() {
return {
mdiPlus,
}
},
methods: {
t,
},
})
</script>
<style lang="scss" scoped>
.recently-created-marker-icon {
color: var(--color-element-success);
// Override NcIconSvgWrapper defaults (clickable area)
min-width: unset !important;
min-height: unset !important;
:deep() {
svg {
// We added a stroke for a11y so we must increase the size to include the stroke
width: 20px !important;
height: 20px !important;
// Override NcIconSvgWrapper defaults of 20px
max-width: unset !important;
max-height: unset !important;
// Show a border around the icon for better contrast
path {
stroke: var(--color-main-background);
stroke-width: 8px;
stroke-linejoin: round;
paint-order: stroke;
}
}
}
}
</style>
+27 -55
View File
@@ -7,18 +7,17 @@ import type { IFileAction } from '@nextcloud/files'
import type { PropType } from 'vue'
import type { FileSource } from '../types.ts'
import { openConflictPicker } from '@nextcloud/dialogs'
import { showError } from '@nextcloud/dialogs'
import { FileType, Folder, File as NcFile, Node, NodeStatus, Permission } from '@nextcloud/files'
import { t } from '@nextcloud/l10n'
import { generateUrl } from '@nextcloud/router'
import { isPublicShare } from '@nextcloud/sharing/public'
import { getConflicts, getUploader } from '@nextcloud/upload'
import { vOnClickOutside } from '@vueuse/components'
import { extname } from 'path'
import Vue, { computed, defineComponent } from 'vue'
import { action as sidebarAction } from '../actions/sidebarAction.ts'
import logger from '../logger.ts'
import { onDropInternalFiles } from '../services/DropService.ts'
import { dataTransferToFileTree, onDropExternalFiles, onDropInternalFiles } from '../services/DropService.ts'
import { getDragAndDropPreview } from '../utils/dragUtils.ts'
import { hashCode } from '../utils/hashUtils.ts'
import { isDownloadable } from '../utils/permissions.ts'
@@ -477,69 +476,42 @@ export default defineComponent({
event.preventDefault()
event.stopPropagation()
// Caching the selection
const selection = this.draggingFiles
const items = [...event.dataTransfer?.items || []] as DataTransferItem[]
// We need to process the dataTransfer ASAP before the
// browser clears it. This is why we cache the items too.
const fileTree = await dataTransferToFileTree(items)
// We might not have the target directory fetched yet
const contents = await this.activeView?.getContents(this.source.path)
const folder = contents?.folder
if (!folder) {
showError(this.t('files', 'Target folder does not exist any more'))
return
}
// If another button is pressed, cancel it. This
// allows cancelling the drag with the right click.
if (!this.canDrop || event.button) {
return
}
// Caching the selection
const selection = this.draggingFiles
const items = Array.from(event.dataTransfer?.items || [])
if (selection.length === 0 && items.some((item) => item.kind === 'file')) {
const uploader = getUploader()
await uploader.batchUpload(
this.source.path,
items.filter((item) => item.kind === 'file')
.map((item) => 'webkitGetAsEntry' in item ? item.webkitGetAsEntry() : item.getAsFile())
.filter(Boolean) as (FileSystemEntry | File)[],
async (nodes, path) => {
try {
const { contents, folder } = await this.activeView!.getContents(path)
const conflicts = getConflicts(nodes, contents)
if (conflicts.length === 0) {
return nodes
}
const result = await openConflictPicker(
folder.displayname,
conflicts,
(contents as Node[]).filter((node) => conflicts.some((conflict) => conflict.name === node.basename)),
{
recursive: true,
},
)
if (result === null) {
return false
}
return [
...nodes.filter((node) => !conflicts.some((conflict) => conflict.name === node.name)),
...result.selected,
...result.renamed,
]
} catch {
return nodes
}
},
)
this.dragover = false
return
}
// We might not have the target directory fetched yet
const cachedContents = this.filesStore.getNodesByPath(this.activeView.id, this.source.path)
const contents = cachedContents.length === 0
? (await this.activeView!.getContents(this.source.path)).contents
: cachedContents
const isCopy = event.ctrlKey
this.dragover = false
logger.debug('Dropped', { event, folder: this.source, selection, fileTree })
logger.debug('Dropped', { event, folder, selection, fileTree })
// Check whether we're uploading files
if (selection.length === 0 && fileTree.contents.length > 0) {
await onDropExternalFiles(fileTree, folder, contents.contents)
return
}
// Else we're moving/copying files
const nodes = selection.map((source) => this.filesStore.getNode(source)) as Node[]
await onDropInternalFiles(nodes, this.source, contents, isCopy)
await onDropInternalFiles(nodes, folder, contents.contents, isCopy)
// Reset selection after we dropped the files
// if the dropped files are within the selection
@@ -743,7 +743,7 @@ export default defineComponent({
& > span {
justify-content: flex-start;
&:not(.files-list__row-icon-favorite):not(.files-list__row-icon-recently-created) svg {
&:not(.files-list__row-icon-favorite) svg {
width: var(--icon-preview-size);
height: var(--icon-preview-size);
}
@@ -791,8 +791,7 @@ export default defineComponent({
}
}
&-favorite,
&-recently-created {
&-favorite {
position: absolute;
top: 0px;
inset-inline-end: -10px;
@@ -994,9 +993,8 @@ export default defineComponent({
}
}
// Icon in the top right
.files-list__row-icon-favorite,
.files-list__row-icon-recently-created {
// Star icon in the top right
.files-list__row-icon-favorite {
position: absolute;
top: 0;
inset-inline-end: 0;
@@ -28,7 +28,7 @@ trait DependencyTrait {
*
* @return MissingDependency[] Unsatisfied required dependencies
*/
public function checkRequiredDependencies(): array {
public function checkRequiredDependencies() {
return array_filter(
$this->checkDependencies(),
fn (MissingDependency $dependency) => !$dependency->isOptional()
@@ -32,23 +32,30 @@ class AmazonS3 extends Common {
private LoggerInterface $logger;
public function needsPartFile(): bool {
return false;
}
/** @var CappedMemoryCache<array|false> */
private CappedMemoryCache $objectCache;
/** @var CappedMemoryCache<bool> */
private CappedMemoryCache $directoryCache;
/** @var CappedMemoryCache<array> */
private CappedMemoryCache $filesCache;
private IMimeTypeDetector $mimeDetector;
private ICache $memCache;
private ?bool $versioningEnabled = null;
private ICache $memCache;
public function __construct(array $parameters) {
parent::__construct($parameters);
$this->parseParams($parameters);
// @todo: using `key` here may be problematic with different authentication methods and/or key rotation...
$this->id = 'amazon::external::' . md5($this->params['hostname'] . ':' . $this->params['bucket'] . ':' . $this->params['key']);
$this->initCaches();
$this->objectCache = new CappedMemoryCache();
$this->directoryCache = new CappedMemoryCache();
$this->filesCache = new CappedMemoryCache();
$this->mimeDetector = Server::get(IMimeTypeDetector::class);
/** @var ICacheFactory $cacheFactory */
$cacheFactory = Server::get(ICacheFactory::class);
@@ -59,7 +66,7 @@ class AmazonS3 extends Common {
private function normalizePath(string $path): string {
$path = trim($path, '/');
if ($path === '') {
if (!$path) {
$path = '.';
}
@@ -77,16 +84,10 @@ class AmazonS3 extends Common {
return $path;
}
private function initCaches(): void {
$this->objectCache = new CappedMemoryCache(2048);
$this->directoryCache = new CappedMemoryCache(8192);
$this->filesCache = new CappedMemoryCache(4096);
}
private function clearCaches(): void {
$this->objectCache->clear();
$this->directoryCache->clear();
$this->filesCache->clear();
private function clearCache(): void {
$this->objectCache = new CappedMemoryCache();
$this->directoryCache = new CappedMemoryCache();
$this->filesCache = new CappedMemoryCache();
}
private function invalidateCache(string $key): void {
@@ -245,7 +246,7 @@ class AmazonS3 extends Common {
}
protected function clearBucket(): bool {
$this->clearCaches();
$this->clearCache();
return $this->batchDelete();
}
@@ -320,9 +321,51 @@ class AmazonS3 extends Common {
return $stat;
}
/**
* Return content length for object
*
* When the information is already present (e.g. opendir has been called before)
* this value is return. Otherwise a headObject is emitted.
*/
private function getContentLength(string $path): int {
if (isset($this->filesCache[$path])) {
return (int)$this->filesCache[$path]['ContentLength'];
}
$result = $this->headObject($path);
if (isset($result['ContentLength'])) {
return (int)$result['ContentLength'];
}
return 0;
}
/**
* Return last modified for object
*
* When the information is already present (e.g. opendir has been called before)
* this value is return. Otherwise a headObject is emitted.
*/
private function getLastModified(string $path): string {
if (isset($this->filesCache[$path])) {
return $this->filesCache[$path]['LastModified'];
}
$result = $this->headObject($path);
if (isset($result['LastModified'])) {
return $result['LastModified'];
}
return 'now';
}
public function is_dir(string $path): bool {
$path = $this->normalizePath($path);
if (isset($this->filesCache[$path])) {
return false;
}
try {
return $this->doesDirectoryExist($path);
} catch (S3Exception $e) {
@@ -345,7 +388,7 @@ class AmazonS3 extends Common {
if (isset($this->directoryCache[$path]) && $this->directoryCache[$path]) {
return 'dir';
}
if ($this->headObject($path)) {
if (isset($this->filesCache[$path]) || $this->headObject($path)) {
return 'file';
}
if ($this->doesDirectoryExist($path)) {
@@ -699,11 +742,6 @@ class AmazonS3 extends Common {
}
}
public function needsPartFile(): bool {
// handled natively by the S3 backend/client integration
return false;
}
public function writeStream(string $path, $stream, ?int $size = null): int {
if ($size === null) {
$size = 0;
@@ -178,7 +178,7 @@ class BackendService {
* @return Backend[]
*/
public function getAvailableBackends() {
return array_filter($this->getBackends(), fn (Backend $backend) => $backend->checkRequiredDependencies() === []);
return array_filter($this->getBackends(), fn (Backend $backend) => !$backend->checkRequiredDependencies());
}
/**
@@ -25,7 +25,7 @@ watch(() => props.configuration, () => {
: ''
}
}
}, { immediate: true })
})
</script>
<template>
+1 -1
View File
@@ -181,7 +181,7 @@ OC.L10N.register(
"Choose a default folder for accepted shares" : "Escolla un cartafol predeterminado para as comparticións aceptadas",
"Invalid path selected" : "Seleccionou unha ruta incorrecta.",
"Unknown error" : "Produciuse un erro descoñecido",
"Set default folder for accepted shares" : "Definir o cartafol predeterminado para as comparticións aceptadas",
"Set default folder for accepted shares" : "Definir o cartafol predeterminado para as s aceptadas",
"Reset" : "Restabelecer",
"Reset folder to system default" : "Restabelecer o cartafol ao predeterminado do sistema",
"Share expiration: {date}" : "Caducidade da compartición: {date}",
+1 -1
View File
@@ -179,7 +179,7 @@
"Choose a default folder for accepted shares" : "Escolla un cartafol predeterminado para as comparticións aceptadas",
"Invalid path selected" : "Seleccionou unha ruta incorrecta.",
"Unknown error" : "Produciuse un erro descoñecido",
"Set default folder for accepted shares" : "Definir o cartafol predeterminado para as comparticións aceptadas",
"Set default folder for accepted shares" : "Definir o cartafol predeterminado para as s aceptadas",
"Reset" : "Restabelecer",
"Reset folder to system default" : "Restabelecer o cartafol ao predeterminado do sistema",
"Share expiration: {date}" : "Caducidade da compartición: {date}",
@@ -93,7 +93,7 @@ async function ocsEntryToNode(ocsEntry: any): Promise<Folder | File | null> {
owner: ocsEntry?.uid_owner,
mime: ocsEntry?.mimetype || 'application/octet-stream',
mtime,
size: ocsEntry?.item_size ?? undefined,
size: ocsEntry?.item_size,
permissions: ocsEntry?.item_permissions || ocsEntry?.permissions,
root: getRootPath(),
attributes: {
@@ -18,7 +18,6 @@ use OCP\Files\Mount\IMountManager;
use OCP\IAppConfig;
use OCP\IConfig;
use OCP\IDateTimeZone;
use OCP\IDBConnection;
use OCP\IGroupManager;
use OCP\IUserManager;
use OCP\IUserSession;
@@ -93,7 +92,6 @@ class CapabilitiesTest extends \Test\TestCase {
$this->createMock(ShareDisableChecker::class),
$this->createMock(IDateTimeZone::class),
$appConfig,
$this->createMock(IDBConnection::class),
);
$cap = new Capabilities($config, $appConfig, $shareManager, $appManager);
-4
View File
@@ -1,15 +1,11 @@
OC.L10N.register(
"profile",
{
"Profile picker" : "Profile picker",
"Profile" : "Profile",
"This application provides the profile" : "This application provides the profile",
"Provides a customisable user profile interface." : "Provides a customisable user profile interface.",
"Searching …" : "Searching …",
"Not found" : "Not found",
"Search for a user profile" : "Search for a user profile",
"Search for a user profile. Start typing" : "Search for a user profile. Start typing",
"Insert selected user profile link" : "Insert selected user profile link",
"Insert" : "Insert",
"You have not added any info yet" : "You have not added any info yet",
"{user} has not added any info yet" : "{user} has not added any info yet",
-4
View File
@@ -1,13 +1,9 @@
{ "translations": {
"Profile picker" : "Profile picker",
"Profile" : "Profile",
"This application provides the profile" : "This application provides the profile",
"Provides a customisable user profile interface." : "Provides a customisable user profile interface.",
"Searching …" : "Searching …",
"Not found" : "Not found",
"Search for a user profile" : "Search for a user profile",
"Search for a user profile. Start typing" : "Search for a user profile. Start typing",
"Insert selected user profile link" : "Insert selected user profile link",
"Insert" : "Insert",
"You have not added any info yet" : "You have not added any info yet",
"{user} has not added any info yet" : "{user} has not added any info yet",
-3
View File
@@ -593,11 +593,8 @@ OC.L10N.register(
"cron.php is registered at a webcron service to call cron.php every 5 minutes over HTTP. Use case: Very small instance (15 accounts depending on the usage)." : "cron.php is registered at a webcron service to call cron.php every 5 minutes over HTTP. Use case: Very small instance (15 accounts depending on the usage).",
"Cron (Recommended)" : "Cron (Recommended)",
"Unable to update profile default setting" : "Unable to update profile default setting",
"Unable to update profile picker setting" : "Unable to update profile picker setting",
"Profile" : "Profile",
"Enable or disable profile by default for new accounts." : "Enable or disable profile by default for new accounts.",
"Enable the profile picker" : "Enable the profile picker",
"Enable or disable the profile picker in the Smart Picker and the profile link previews." : "Enable or disable the profile picker in the Smart Picker and the profile link previews.",
"Password confirmation is required" : "Password confirmation is required",
"Failed to save setting" : "Failed to save setting",
"{app}'s declarative setting field: {name}" : "{app}'s declarative setting field: {name}",
-3
View File
@@ -591,11 +591,8 @@
"cron.php is registered at a webcron service to call cron.php every 5 minutes over HTTP. Use case: Very small instance (15 accounts depending on the usage)." : "cron.php is registered at a webcron service to call cron.php every 5 minutes over HTTP. Use case: Very small instance (15 accounts depending on the usage).",
"Cron (Recommended)" : "Cron (Recommended)",
"Unable to update profile default setting" : "Unable to update profile default setting",
"Unable to update profile picker setting" : "Unable to update profile picker setting",
"Profile" : "Profile",
"Enable or disable profile by default for new accounts." : "Enable or disable profile by default for new accounts.",
"Enable the profile picker" : "Enable the profile picker",
"Enable or disable the profile picker in the Smart Picker and the profile link previews." : "Enable or disable the profile picker in the Smart Picker and the profile link previews.",
"Password confirmation is required" : "Password confirmation is required",
"Failed to save setting" : "Failed to save setting",
"{app}'s declarative setting field: {name}" : "{app}'s declarative setting field: {name}",
-3
View File
@@ -593,11 +593,8 @@ OC.L10N.register(
"cron.php is registered at a webcron service to call cron.php every 5 minutes over HTTP. Use case: Very small instance (15 accounts depending on the usage)." : "Tá cron.php cláraithe ag seirbhís webcron chun cron.php a ghlaoch gach 5 nóiméad thar HTTP. Cás úsáide: Sampla an-bheag (15 chuntas ag brath ar an úsáid).",
"Cron (Recommended)" : "Cron (Molta)",
"Unable to update profile default setting" : "Ní féidir socrú réamhshocraithe na próifíle a nuashonrú",
"Unable to update profile picker setting" : "Ní féidir socruithe roghnóra próifíle a nuashonrú",
"Profile" : "Próifíl",
"Enable or disable profile by default for new accounts." : "Cumasaigh nó díchumasaigh próifíl de réir réamhshocraithe le haghaidh cuntas nua.",
"Enable the profile picker" : "Cumasaigh an roghnóir próifíle",
"Enable or disable the profile picker in the Smart Picker and the profile link previews." : "Cumasaigh nó díchumasaigh an roghnóir próifíle sa Roghnóir Cliste agus réamhamhairc na nasc próifíle.",
"Password confirmation is required" : "Tá deimhniú pasfhocail ag teastáil",
"Failed to save setting" : "Theip ar an socrú a shábháil",
"{app}'s declarative setting field: {name}" : "Réimse socruithe dearbhaithe {app}'s: {name}",
-3
View File
@@ -591,11 +591,8 @@
"cron.php is registered at a webcron service to call cron.php every 5 minutes over HTTP. Use case: Very small instance (15 accounts depending on the usage)." : "Tá cron.php cláraithe ag seirbhís webcron chun cron.php a ghlaoch gach 5 nóiméad thar HTTP. Cás úsáide: Sampla an-bheag (15 chuntas ag brath ar an úsáid).",
"Cron (Recommended)" : "Cron (Molta)",
"Unable to update profile default setting" : "Ní féidir socrú réamhshocraithe na próifíle a nuashonrú",
"Unable to update profile picker setting" : "Ní féidir socruithe roghnóra próifíle a nuashonrú",
"Profile" : "Próifíl",
"Enable or disable profile by default for new accounts." : "Cumasaigh nó díchumasaigh próifíl de réir réamhshocraithe le haghaidh cuntas nua.",
"Enable the profile picker" : "Cumasaigh an roghnóir próifíle",
"Enable or disable the profile picker in the Smart Picker and the profile link previews." : "Cumasaigh nó díchumasaigh an roghnóir próifíle sa Roghnóir Cliste agus réamhamhairc na nasc próifíle.",
"Password confirmation is required" : "Tá deimhniú pasfhocail ag teastáil",
"Failed to save setting" : "Theip ar an socrú a shábháil",
"{app}'s declarative setting field: {name}" : "Réimse socruithe dearbhaithe {app}'s: {name}",
+1 -1
View File
@@ -399,7 +399,7 @@ OC.L10N.register(
"Enforce expiration date for remote shares" : "Aplicar a data de caducidade dos recursos compartidos remotos",
"Default expiration time of remote shares in days" : "Tempo de caducidade predeterminado dos recursos compartidos remotos en días",
"Expire remote shares after x days" : "As comparticións remotas caducan após x días",
"Set default expiration date for shares via link or mail" : "Definir a data de caducidade predeterminada para compartir mediante ligazón ou correo electrónico",
"Set default expiration date for shares via link or mail" : "Definir a data de caducidade predeterminada para as comparticións con outros servidores",
"Enforce expiration date for link or mail shares" : "Aplicar a data de caducidade para as de ligazóns ou correos para compartir",
"Default expiration time of shares in days" : "Tempo de caducidade predeterminado dos recursos compartidos en días",
"Privacy settings for sharing" : "Axustes da privacidade para compartir",
+1 -1
View File
@@ -397,7 +397,7 @@
"Enforce expiration date for remote shares" : "Aplicar a data de caducidade dos recursos compartidos remotos",
"Default expiration time of remote shares in days" : "Tempo de caducidade predeterminado dos recursos compartidos remotos en días",
"Expire remote shares after x days" : "As comparticións remotas caducan após x días",
"Set default expiration date for shares via link or mail" : "Definir a data de caducidade predeterminada para compartir mediante ligazón ou correo electrónico",
"Set default expiration date for shares via link or mail" : "Definir a data de caducidade predeterminada para as comparticións con outros servidores",
"Enforce expiration date for link or mail shares" : "Aplicar a data de caducidade para as de ligazóns ou correos para compartir",
"Default expiration time of shares in days" : "Tempo de caducidade predeterminado dos recursos compartidos en días",
"Privacy settings for sharing" : "Axustes da privacidade para compartir",
-3
View File
@@ -593,11 +593,8 @@ OC.L10N.register(
"cron.php is registered at a webcron service to call cron.php every 5 minutes over HTTP. Use case: Very small instance (15 accounts depending on the usage)." : "cron.php je registriran na webcron usluzi koja poziva cron.php svakih 5 minuta putem HTTP-a. Primjena: vrlo mala instanca (15 računa, ovisno o korištenju).",
"Cron (Recommended)" : "Cron (preporučeno)",
"Unable to update profile default setting" : "Nije moguće ažurirati zadanu postavku profila",
"Unable to update profile picker setting" : "Nije moguće ažurirati postavku odabira profila",
"Profile" : "Profil",
"Enable or disable profile by default for new accounts." : "Omogući ili onemogući profil prema zadanim postavkama za nove račune.",
"Enable the profile picker" : "Omogući odabir profila",
"Enable or disable the profile picker in the Smart Picker and the profile link previews." : "Omogući ili onemogući odabir profila u Pametnom odabiru i pregledima poveznica profila.",
"Password confirmation is required" : "Potrebna je potvrda lozinke",
"Failed to save setting" : "Neuspjelo spremanje postavke",
"{app}'s declarative setting field: {name}" : "Deklarativno polje postavke aplikacije {app}: {name}",
-3
View File
@@ -591,11 +591,8 @@
"cron.php is registered at a webcron service to call cron.php every 5 minutes over HTTP. Use case: Very small instance (15 accounts depending on the usage)." : "cron.php je registriran na webcron usluzi koja poziva cron.php svakih 5 minuta putem HTTP-a. Primjena: vrlo mala instanca (15 računa, ovisno o korištenju).",
"Cron (Recommended)" : "Cron (preporučeno)",
"Unable to update profile default setting" : "Nije moguće ažurirati zadanu postavku profila",
"Unable to update profile picker setting" : "Nije moguće ažurirati postavku odabira profila",
"Profile" : "Profil",
"Enable or disable profile by default for new accounts." : "Omogući ili onemogući profil prema zadanim postavkama za nove račune.",
"Enable the profile picker" : "Omogući odabir profila",
"Enable or disable the profile picker in the Smart Picker and the profile link previews." : "Omogući ili onemogući odabir profila u Pametnom odabiru i pregledima poveznica profila.",
"Password confirmation is required" : "Potrebna je potvrda lozinke",
"Failed to save setting" : "Neuspjelo spremanje postavke",
"{app}'s declarative setting field: {name}" : "Deklarativno polje postavke aplikacije {app}: {name}",
-3
View File
@@ -593,11 +593,8 @@ OC.L10N.register(
"cron.php is registered at a webcron service to call cron.php every 5 minutes over HTTP. Use case: Very small instance (15 accounts depending on the usage)." : "cron.phpは、HTTP越しに5分おきにcron.phpを読み出すWebcronサービスにより登録されています。使用例: 極小なインスタンス(利用率に依存する1〜5アカウント程度)の場合。",
"Cron (Recommended)" : "Cron (推奨)",
"Unable to update profile default setting" : "プロフィールのデフォルト設定を更新できませんでした",
"Unable to update profile picker setting" : "プロフィールピッカーの設定を更新できません",
"Profile" : "プロフィール",
"Enable or disable profile by default for new accounts." : "新しいアカウントの場合、デフォルトでプロフィールを有効または無効にします。",
"Enable the profile picker" : "プロフィールピッカーを有効にする",
"Enable or disable the profile picker in the Smart Picker and the profile link previews." : "スマートピッカーにおけるプロフィールピッカーとプロフィールリンクプレビューの有効化または無効化",
"Password confirmation is required" : "パスワードの確認が必要です",
"Failed to save setting" : "設定の保存に失敗しました",
"{app}'s declarative setting field: {name}" : "{app}の宣言的設定フィールド: {name}",
-3
View File
@@ -591,11 +591,8 @@
"cron.php is registered at a webcron service to call cron.php every 5 minutes over HTTP. Use case: Very small instance (15 accounts depending on the usage)." : "cron.phpは、HTTP越しに5分おきにcron.phpを読み出すWebcronサービスにより登録されています。使用例: 極小なインスタンス(利用率に依存する1〜5アカウント程度)の場合。",
"Cron (Recommended)" : "Cron (推奨)",
"Unable to update profile default setting" : "プロフィールのデフォルト設定を更新できませんでした",
"Unable to update profile picker setting" : "プロフィールピッカーの設定を更新できません",
"Profile" : "プロフィール",
"Enable or disable profile by default for new accounts." : "新しいアカウントの場合、デフォルトでプロフィールを有効または無効にします。",
"Enable the profile picker" : "プロフィールピッカーを有効にする",
"Enable or disable the profile picker in the Smart Picker and the profile link previews." : "スマートピッカーにおけるプロフィールピッカーとプロフィールリンクプレビューの有効化または無効化",
"Password confirmation is required" : "パスワードの確認が必要です",
"Failed to save setting" : "設定の保存に失敗しました",
"{app}'s declarative setting field: {name}" : "{app}の宣言的設定フィールド: {name}",
+1 -1
View File
@@ -815,7 +815,7 @@ OC.L10N.register(
"By member count" : "Üye sayısına göre",
"By name" : "Ada göre",
"Send email" : "E-posta gönder",
"Send welcome email to new accounts" : "Yeni hesaplara karşılama e-postası gönderilsin",
"Send welcome email to new accounts" : "Yeni hesaplara hoş geldiniz e-postası gönderilsin",
"Defaults" : "Varsayılanlar",
"Default quota" : "Varsayılan kota",
"Select default quota" : "Varsayılan kota değerini seçin",
+1 -1
View File
@@ -813,7 +813,7 @@
"By member count" : "Üye sayısına göre",
"By name" : "Ada göre",
"Send email" : "E-posta gönder",
"Send welcome email to new accounts" : "Yeni hesaplara karşılama e-postası gönderilsin",
"Send welcome email to new accounts" : "Yeni hesaplara hoş geldiniz e-postası gönderilsin",
"Defaults" : "Varsayılanlar",
"Default quota" : "Varsayılan kota",
"Select default quota" : "Varsayılan kota değerini seçin",
@@ -16,11 +16,9 @@ use OCP\IConfig;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\Share\IManager;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\MockObject\MockObject;
use Test\TestCase;
#[Group(name: 'DB')]
class SharingTest extends TestCase {
private Sharing $admin;
+3 -2
View File
@@ -144,8 +144,9 @@ class IconBuilder {
$y = $tmp->getImageHeight();
$tmp->destroy();
// set resolution for proper scaling
$res = (int)(72 * $size / max($x, $y));
$appIconFile->setResolution($res, $res);
$resX = (int)(72 * $size / $x);
$resY = (int)(72 * $size / $y);
$appIconFile->setResolution($resX, $resY);
$appIconFile->readImageBlob($svg);
} else {
// handle non-SVG images
+4 -2
View File
@@ -297,9 +297,11 @@ class IconBuilderTest extends TestCase {
$x = $tmp->getImageWidth();
$y = $tmp->getImageHeight();
$tmp->destroy();
$res = (int)(72 * $size / max($x, $y));
// set resolution for proper scaling
$resX = (int)(72 * $size / $x);
$resY = (int)(72 * $size / $y);
$appIconFile->setBackgroundColor(new \ImagickPixel('transparent'));
$appIconFile->setResolution($res, $res);
$appIconFile->setResolution($resX, $resY);
$appIconFile->readImageBlob($svgContent);
} else {
$appIconFile->readImage($filePath);
-7
View File
@@ -128,9 +128,7 @@ OC.L10N.register(
"A connection error to LDAP/AD occurred. Please check host, port and credentials." : "Csatlakozási hiba az LDAP/AD-vel. Ellenőrizd a kiszolgálót, a portot és a hitelesítő adatokat.",
"The \"%uid\" placeholder is missing. It will be replaced with the login name when querying LDAP/AD." : "A(z) „%uid” helykitöltő hiányzik. Ez lesz lecserélve a felhasználónévre az LDAP/AD lekérdezésekor.",
"When logging in, {instanceName} will find the user based on the following attributes:" : "Bejelentkezéskor a(z) {instanceName} a következő attribútumok alapján találja meg a felhasználót:",
"Allows login against the LDAP/AD username, which is either 'uid' or 'sAMAccountName' and will be detected." : "Engedélyezi a bejelentkezést az LDAP/AD felhasználónév alapján, amely vagy 'uid' vagy 'sAMAccountName' és észlelve lesz.",
"LDAP/AD Username:" : "LDAP/AD felhasználónév:",
"Allows login against an email attribute. 'mail' and 'mailPrimaryAddress' allowed." : "Engedélyezi a bejelentkezést egy email attribútum alapján. 'mail' és 'mailPrimaryAddress' megengedett.",
"LDAP/AD Email Address:" : "LDAP/AD e-mail-cím:",
"Other Attributes:" : "Más attribútumok:",
"Defines the filter to apply, when login is attempted. `%%uid` replaces the username in the login action. Example: `uid=%%uid`" : "Meghatározza a belépéskor alkalmazandó szűrőt. A `%%uid` lecseréli a felhasználónevet a bejelentkezési műveletnél. Például: `uid=%%uid`",
@@ -141,7 +139,6 @@ OC.L10N.register(
"More than 1,000 directory entries available." : "Több mint 1000 címtárbejegyzés érhető el.",
"_{ldapTestBase} entry available within the provided Base DN_::_{ldapTestBase} entries available within the provided Base DN_" : ["{ldapTestBase} bejegyzés érhető el a megadott alap DN alatt","{ldapTestBase} bejegyzés érhető el a megadott alap DN alatt"],
"When unchecked, this configuration will be skipped." : "Ha nincs kipipálva, ez a beállítás ki lesz hagyva.",
"Configuration active" : "Konfiguráció aktív",
"Copy current configuration into new directory binding" : "Jelenlegi beállítások másolása egy új címtárkötésbe",
"Copy configuration" : "Konfiguráció másolása",
"Delete configuration" : "Konfiguráció törlése",
@@ -149,11 +146,9 @@ OC.L10N.register(
"Host" : "Kiszolgáló",
"Port" : "Port",
"Detect Port" : "Port észlelése",
"The DN of the client user with which the bind shall be done. For anonymous access, leave DN and Password empty." : "A kliens felhasználó DN-je, amellyel az összeköttetést kívánja. Anonim hozzáféréshez hagyja a DN-t és a jelszavat üresen.",
"User DN" : "Alap DN",
"For anonymous access, leave DN and Password empty." : "Az anonim eléréshez hagyja üresen a DN és Jelszó mezőket.",
"Password" : "Jelszó",
"Save credentials" : "Felhasználóadatok mentése",
"Base DN" : "Alap DN",
"One Base DN per line" : "Soronként egy alap DN",
"You can specify Base DN for users and groups in the Advanced tab" : "A felhasználók és csoportok alap DN-jét a Speciális lapon adhatja meg",
@@ -180,14 +175,12 @@ OC.L10N.register(
"Usernames are used to store and assign metadata. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "A felhasználónevek a metaadatok kezeléséhez és tárolásához vannak felhasználva. Annak érdekében, hogy teljes mértékben azonosítható legyen egy felhasználó, minden LDAP felhasználó kapni fog egy belső felhasználónevet. Ez egy hozzárendelést igényel az eredeti felhasználónév és az LDAP fiók között. A létrejött felhasználónév hozzárendelődik az LDAP fiók UUID értékéhez. Emellett a DN gyorsítótárazott, hogy csökkentse az LDAP interakciók számát, de nincs használva azonosítás céljából. Ha a DN megváltozik, a rendszer észleli ezeket a változásokat. A belső felhasználónév van mindenhol használva a rendszeren belül. A hozzárendelések törlése adattöredékeket hagy maga után. A hozzárendelések ürítése nem beállításfüggő, minden LDAP beállításra hatással van. Soha ne ürítse éles rendszeren a hozzárendeléseket, csak tesztelési vagy kísérleti szakaszban.",
"Clear Username-LDAP User Mapping" : "FelhasználónévLDAP felhasználó hozzárendelés törlése",
"Clear Groupname-LDAP Group Mapping" : "CsoportLDAP csoport hozzárendelés törlése",
"Please renew your password" : "Kérjük, újítsa meg jelszavát",
"An internal error occurred." : "Belső hiba történt.",
"Please try again or contact your administrator." : "Próbálja meg újra, vagy lépjen kapcsolatba a rendszergazdával.",
"Wrong password." : "Hibás jelszó.",
"Current password" : "Jelenlegi jelszó",
"New password" : "Új jelszó",
"Cancel" : "Mégse",
"Renewing…" : "Megújítás folyamatban...",
"Renew password" : "Jelszó megújítása",
"Confirm action" : "Művelet megerősítése",
"Are you sure you want to permanently delete this LDAP configuration? This cannot be undone." : "Biztos, hogy végleg törli ezt az LDAP konfigurációt? Ez nem vonható vissza.",
-7
View File
@@ -126,9 +126,7 @@
"A connection error to LDAP/AD occurred. Please check host, port and credentials." : "Csatlakozási hiba az LDAP/AD-vel. Ellenőrizd a kiszolgálót, a portot és a hitelesítő adatokat.",
"The \"%uid\" placeholder is missing. It will be replaced with the login name when querying LDAP/AD." : "A(z) „%uid” helykitöltő hiányzik. Ez lesz lecserélve a felhasználónévre az LDAP/AD lekérdezésekor.",
"When logging in, {instanceName} will find the user based on the following attributes:" : "Bejelentkezéskor a(z) {instanceName} a következő attribútumok alapján találja meg a felhasználót:",
"Allows login against the LDAP/AD username, which is either 'uid' or 'sAMAccountName' and will be detected." : "Engedélyezi a bejelentkezést az LDAP/AD felhasználónév alapján, amely vagy 'uid' vagy 'sAMAccountName' és észlelve lesz.",
"LDAP/AD Username:" : "LDAP/AD felhasználónév:",
"Allows login against an email attribute. 'mail' and 'mailPrimaryAddress' allowed." : "Engedélyezi a bejelentkezést egy email attribútum alapján. 'mail' és 'mailPrimaryAddress' megengedett.",
"LDAP/AD Email Address:" : "LDAP/AD e-mail-cím:",
"Other Attributes:" : "Más attribútumok:",
"Defines the filter to apply, when login is attempted. `%%uid` replaces the username in the login action. Example: `uid=%%uid`" : "Meghatározza a belépéskor alkalmazandó szűrőt. A `%%uid` lecseréli a felhasználónevet a bejelentkezési műveletnél. Például: `uid=%%uid`",
@@ -139,7 +137,6 @@
"More than 1,000 directory entries available." : "Több mint 1000 címtárbejegyzés érhető el.",
"_{ldapTestBase} entry available within the provided Base DN_::_{ldapTestBase} entries available within the provided Base DN_" : ["{ldapTestBase} bejegyzés érhető el a megadott alap DN alatt","{ldapTestBase} bejegyzés érhető el a megadott alap DN alatt"],
"When unchecked, this configuration will be skipped." : "Ha nincs kipipálva, ez a beállítás ki lesz hagyva.",
"Configuration active" : "Konfiguráció aktív",
"Copy current configuration into new directory binding" : "Jelenlegi beállítások másolása egy új címtárkötésbe",
"Copy configuration" : "Konfiguráció másolása",
"Delete configuration" : "Konfiguráció törlése",
@@ -147,11 +144,9 @@
"Host" : "Kiszolgáló",
"Port" : "Port",
"Detect Port" : "Port észlelése",
"The DN of the client user with which the bind shall be done. For anonymous access, leave DN and Password empty." : "A kliens felhasználó DN-je, amellyel az összeköttetést kívánja. Anonim hozzáféréshez hagyja a DN-t és a jelszavat üresen.",
"User DN" : "Alap DN",
"For anonymous access, leave DN and Password empty." : "Az anonim eléréshez hagyja üresen a DN és Jelszó mezőket.",
"Password" : "Jelszó",
"Save credentials" : "Felhasználóadatok mentése",
"Base DN" : "Alap DN",
"One Base DN per line" : "Soronként egy alap DN",
"You can specify Base DN for users and groups in the Advanced tab" : "A felhasználók és csoportok alap DN-jét a Speciális lapon adhatja meg",
@@ -178,14 +173,12 @@
"Usernames are used to store and assign metadata. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "A felhasználónevek a metaadatok kezeléséhez és tárolásához vannak felhasználva. Annak érdekében, hogy teljes mértékben azonosítható legyen egy felhasználó, minden LDAP felhasználó kapni fog egy belső felhasználónevet. Ez egy hozzárendelést igényel az eredeti felhasználónév és az LDAP fiók között. A létrejött felhasználónév hozzárendelődik az LDAP fiók UUID értékéhez. Emellett a DN gyorsítótárazott, hogy csökkentse az LDAP interakciók számát, de nincs használva azonosítás céljából. Ha a DN megváltozik, a rendszer észleli ezeket a változásokat. A belső felhasználónév van mindenhol használva a rendszeren belül. A hozzárendelések törlése adattöredékeket hagy maga után. A hozzárendelések ürítése nem beállításfüggő, minden LDAP beállításra hatással van. Soha ne ürítse éles rendszeren a hozzárendeléseket, csak tesztelési vagy kísérleti szakaszban.",
"Clear Username-LDAP User Mapping" : "FelhasználónévLDAP felhasználó hozzárendelés törlése",
"Clear Groupname-LDAP Group Mapping" : "CsoportLDAP csoport hozzárendelés törlése",
"Please renew your password" : "Kérjük, újítsa meg jelszavát",
"An internal error occurred." : "Belső hiba történt.",
"Please try again or contact your administrator." : "Próbálja meg újra, vagy lépjen kapcsolatba a rendszergazdával.",
"Wrong password." : "Hibás jelszó.",
"Current password" : "Jelenlegi jelszó",
"New password" : "Új jelszó",
"Cancel" : "Mégse",
"Renewing…" : "Megújítás folyamatban...",
"Renew password" : "Jelszó megújítása",
"Confirm action" : "Művelet megerősítése",
"Are you sure you want to permanently delete this LDAP configuration? This cannot be undone." : "Biztos, hogy végleg törli ezt az LDAP konfigurációt? Ez nem vonható vissza.",
+29 -4
View File
@@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
@@ -10,6 +8,7 @@ namespace OCA\User_LDAP\AppInfo;
use Closure;
use OCA\Files_External\Service\BackendService;
use OCA\User_LDAP\Controller\RenewPasswordController;
use OCA\User_LDAP\Events\GroupBackendRegistered;
use OCA\User_LDAP\Events\UserBackendRegistered;
use OCA\User_LDAP\Group_Proxy;
@@ -31,12 +30,16 @@ use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\AppFramework\IAppContainer;
use OCP\AppFramework\Services\IAppConfig;
use OCP\AppFramework\Services\IInitialState;
use OCP\Config\IUserConfig;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\IAvatarManager;
use OCP\IConfig;
use OCP\IGroupManager;
use OCP\IL10N;
use OCP\Image;
use OCP\IRequest;
use OCP\IURLGenerator;
use OCP\IUserManager;
use OCP\Notification\IManager as INotificationManager;
use OCP\Share\IManager as IShareManager;
@@ -50,11 +53,33 @@ class Application extends App implements IBootstrap {
public function __construct() {
parent::__construct(self::APP_ID);
$container = $this->getContainer();
/**
* Controller
*/
$container->registerService('RenewPasswordController', function (ContainerInterface $appContainer) {
return new RenewPasswordController(
$appContainer->get('AppName'),
$appContainer->get(IRequest::class),
$appContainer->get(IUserManager::class),
$appContainer->get(IConfig::class),
$appContainer->get(IUserConfig::class),
$appContainer->get(IL10N::class),
$appContainer->get('Session'),
$appContainer->get(IURLGenerator::class),
$appContainer->get(IInitialState::class),
);
});
$container->registerService(ILDAPWrapper::class, function (ContainerInterface $appContainer) {
return new LDAP(
$appContainer->get(IConfig::class)->getSystemValueString('ldap_log_file')
);
});
}
public function register(IRegistrationContext $context): void {
$context->registerServiceAlias(ILDAPWrapper::class, LDAP::class);
$context->registerNotifierService(Notifier::class);
$context->registerService(
+7
View File
@@ -8,8 +8,11 @@
namespace OCA\User_LDAP\Command;
use OCA\User_LDAP\Group_Proxy;
use OCA\User_LDAP\Helper;
use OCA\User_LDAP\LDAP;
use OCA\User_LDAP\User_Proxy;
use OCP\IConfig;
use OCP\Server;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
@@ -79,6 +82,10 @@ class Search extends Command {
}
protected function execute(InputInterface $input, OutputInterface $output): int {
$helper = Server::get(Helper::class);
$configPrefixes = $helper->getServerConfigurationPrefixes(true);
$ldapWrapper = new LDAP();
$offset = (int)$input->getOption('offset');
$limit = (int)$input->getOption('limit');
$this->validateOffsetAndLimit($offset, $limit);
+6 -9
View File
@@ -10,19 +10,14 @@ namespace OCA\User_LDAP\Command;
use OCA\User_LDAP\Configuration;
use OCA\User_LDAP\ConnectionFactory;
use OCA\User_LDAP\Helper;
use OCA\User_LDAP\LDAP;
use OCP\Server;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class SetConfig extends Command {
public function __construct(
private readonly Helper $helper,
private readonly ConnectionFactory $connectionFactory,
) {
parent::__construct();
}
protected function configure(): void {
$this
->setName('ldap:set-config')
@@ -46,7 +41,8 @@ class SetConfig extends Command {
}
protected function execute(InputInterface $input, OutputInterface $output): int {
$availableConfigs = $this->helper->getServerConfigurationPrefixes();
$helper = Server::get(Helper::class);
$availableConfigs = $helper->getServerConfigurationPrefixes();
$configID = $input->getArgument('configID');
if (!in_array($configID, $availableConfigs)) {
$output->writeln('Invalid configID');
@@ -69,6 +65,7 @@ class SetConfig extends Command {
$configHolder->$key = $value;
$configHolder->saveConfiguration();
$this->connectionFactory->get($configID)->clearCache();
$connectionFactory = new ConnectionFactory(new LDAP());
$connectionFactory->get($configID)->clearCache();
}
}
+10
View File
@@ -23,6 +23,8 @@ class Sync extends TimedJob {
public const MAX_INTERVAL = 12 * 60 * 60; // 12h
public const MIN_INTERVAL = 30 * 60; // 30min
protected LDAP $ldap;
public function __construct(
ITimeFactory $timeFactory,
private IConfig $config,
@@ -40,6 +42,7 @@ class Sync extends TimedJob {
self::MIN_INTERVAL
)
);
$this->ldap = new LDAP($this->config->getSystemValueString('ldap_log_file'));
}
/**
@@ -250,4 +253,11 @@ class Sync extends TimedJob {
}
return $prefixes[$i];
}
/**
* Only used in tests
*/
public function overwritePropertiesForTest(LDAP $ldapWrapper): void {
$this->ldap = $ldapWrapper;
}
}
+8 -6
View File
@@ -18,21 +18,23 @@ use Psr\Log\LoggerInterface;
class LDAP implements ILDAPWrapper {
protected array $curArgs = [];
protected LoggerInterface $logger;
protected IConfig $config;
private ?LdapDataCollector $dataCollector = null;
protected string $logFile = '';
public function __construct(
IProfiler $profiler,
protected IConfig $config,
protected LoggerInterface $logger,
protected string $logFile = '',
) {
/** @var IProfiler $profiler */
$profiler = Server::get(IProfiler::class);
if ($profiler->isEnabled()) {
$this->dataCollector = new LdapDataCollector();
$profiler->add($this->dataCollector);
}
$this->logFile = $this->config->getSystemValueString('ldap_log_file');
$this->logger = Server::get(LoggerInterface::class);
$this->config = Server::get(IConfig::class);
}
/**
+12 -12
View File
@@ -5,38 +5,38 @@
* SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP;
use OCA\User_LDAP\User\DeletedUsersIndex;
use OCP\GroupInterface;
use OCP\IGroupManager;
use OCP\IUserManager;
use OCP\IServerContainer;
use OCP\LDAP\IDeletionFlagSupport;
use OCP\LDAP\ILDAPProvider;
use OCP\UserInterface;
use Psr\Log\LoggerInterface;
/**
* LDAP provider for public access to the LDAP backend.
*/
class LDAPProvider implements ILDAPProvider, IDeletionFlagSupport {
private IUserLDAP&UserInterface $userBackend;
private IGroupLDAP&GroupInterface $groupBackend;
private $userBackend;
private $groupBackend;
private $logger;
/**
* Create new LDAPProvider
* @param IServerContainer $serverContainer
* @param Helper $helper
* @param DeletedUsersIndex $deletedUsersIndex
* @throws \Exception if user_ldap app was not enabled
*/
public function __construct(
IUserManager $userManager,
IGroupManager $groupManager,
IServerContainer $serverContainer,
private Helper $helper,
private DeletedUsersIndex $deletedUsersIndex,
private LoggerInterface $logger,
) {
$this->logger = $serverContainer->get(LoggerInterface::class);
$userBackendFound = false;
$groupBackendFound = false;
foreach ($userManager->getBackends() as $backend) {
foreach ($serverContainer->getUserManager()->getBackends() as $backend) {
$this->logger->debug('instance ' . get_class($backend) . ' user backend.', ['app' => 'user_ldap']);
if ($backend instanceof IUserLDAP) {
$this->userBackend = $backend;
@@ -44,7 +44,7 @@ class LDAPProvider implements ILDAPProvider, IDeletionFlagSupport {
break;
}
}
foreach ($groupManager->getBackends() as $backend) {
foreach ($serverContainer->getGroupManager()->getBackends() as $backend) {
$this->logger->debug('instance ' . get_class($backend) . ' group backend.', ['app' => 'user_ldap']);
if ($backend instanceof IGroupLDAP) {
$this->groupBackend = $backend;
+3 -5
View File
@@ -1,22 +1,20 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP;
use OCP\IServerContainer;
use OCP\LDAP\ILDAPProvider;
use OCP\LDAP\ILDAPProviderFactory;
use Psr\Container\ContainerInterface;
class LDAPProviderFactory implements ILDAPProviderFactory {
public function __construct(
private ContainerInterface $serverContainer,
/** * @var IServerContainer */
private IServerContainer $serverContainer,
) {
}
+1 -6
View File
@@ -29,7 +29,6 @@ use OCP\IConfig;
use OCP\Image;
use OCP\IUserManager;
use OCP\Notification\IManager as INotificationManager;
use OCP\Profiler\IProfiler;
use OCP\Server;
use OCP\Share\IManager;
use PHPUnit\Framework\MockObject\MockObject;
@@ -243,11 +242,7 @@ class AccessTest extends TestCase {
#[\PHPUnit\Framework\Attributes\DataProvider(methodName: 'dnInputDataProvider')]
public function testStringResemblesDNLDAPmod(string $input, array|bool $interResult, bool $expectedResult): void {
[, $con, $um, $helper] = $this->getConnectorAndLdapMock();
$lw = new LDAP(
$this->createMock(IProfiler::class),
$this->createMock(IConfig::class),
$this->createMock(LoggerInterface::class),
);
$lw = new LDAP();
$access = new Access($lw, $con, $um, $helper, $this->ncUserManager, $this->logger, $this->appConfig, $this->dispatcher);
if (!function_exists('ldap_explode_dn')) {
+2
View File
@@ -76,6 +76,8 @@ class SyncTest extends TestCase {
$this->connectionFactory,
$this->accessFactory,
);
$this->sync->overwritePropertiesForTest($this->ldapWrapper);
}
public static function intervalDataProvider(): array {
+115 -44
View File
@@ -7,6 +7,7 @@ declare(strict_types=1);
*/
namespace OCA\User_LDAP\Tests;
use OC\Config;
use OC\User\Manager;
use OCA\User_LDAP\Access;
use OCA\User_LDAP\Connection;
@@ -15,12 +16,12 @@ use OCA\User_LDAP\Helper;
use OCA\User_LDAP\IGroupLDAP;
use OCA\User_LDAP\ILDAPWrapper;
use OCA\User_LDAP\IUserLDAP;
use OCA\User_LDAP\LDAPProvider;
use OCA\User_LDAP\User\DeletedUsersIndex;
use OCA\User_LDAP\LDAPProviderFactory;
use OCA\User_LDAP\User_LDAP;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\ICacheFactory;
use OCP\IConfig;
use OCP\IServerContainer;
use OCP\Server;
use Psr\Log\LoggerInterface;
@@ -32,6 +33,21 @@ use Psr\Log\LoggerInterface;
*/
#[\PHPUnit\Framework\Attributes\Group(name: 'DB')]
class LDAPProviderTest extends \Test\TestCase {
private function getServerMock(IUserLDAP $userBackend, IGroupLDAP $groupBackend) {
$server = $this->getMockBuilder('OC\Server')
->onlyMethods(['getUserManager', 'getGroupManager'])
->setConstructorArgs(['', new Config(\OC::$configDir)])
->getMock();
$server->expects($this->any())
->method('getUserManager')
->willReturn($this->getUserManagerMock($userBackend));
$server->expects($this->any())
->method('getGroupManager')
->willReturn($this->getGroupManagerMock($groupBackend));
return $server;
}
private function getUserManagerMock(IUserLDAP $userBackend) {
$userManager = $this->getMockBuilder(Manager::class)
->onlyMethods(['getBackends'])
@@ -67,14 +83,9 @@ class LDAPProviderTest extends \Test\TestCase {
return $groupBackend;
}
private function getLDAPProvider(IUserLDAP $userBackend, IGroupLDAP $groupBackend): LDAPProvider {
return new LDAPProvider(
$this->getUserManagerMock($userBackend),
$this->getGroupManagerMock($groupBackend),
Server::get(Helper::class),
Server::get(DeletedUsersIndex::class),
$this->createMock(LoggerInterface::class),
);
private function getLDAPProvider(IServerContainer $serverContainer) {
$factory = new LDAPProviderFactory($serverContainer);
return $factory->getLDAPProvider();
}
@@ -88,7 +99,9 @@ class LDAPProviderTest extends \Test\TestCase {
->getMock();
$userBackend->expects($this->any())->method('userExists')->willReturn(false);
$ldapProvider = $this->getLDAPProvider($userBackend, $this->getDefaultGroupBackendMock());
$server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock());
$ldapProvider = $this->getLDAPProvider($server);
$ldapProvider->getUserDN('nonexisting_user');
}
@@ -112,7 +125,9 @@ class LDAPProviderTest extends \Test\TestCase {
->method('getLDAPAccess')
->willReturn($userAccess);
$ldapProvider = $this->getLDAPProvider($userBackend, $this->getDefaultGroupBackendMock());
$server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock());
$ldapProvider = $this->getLDAPProvider($server);
$this->assertEquals('cn=existing_user,ou=Are Sufficient To,ou=Test,dc=example,dc=org',
$ldapProvider->getUserDN('existing_user'));
}
@@ -130,7 +145,9 @@ class LDAPProviderTest extends \Test\TestCase {
$groupBackend->expects($this->any())->method('groupExists')->willReturn(false);
$ldapProvider = $this->getLDAPProvider($userBackend, $groupBackend);
$server = $this->getServerMock($userBackend, $groupBackend);
$ldapProvider = $this->getLDAPProvider($server);
$ldapProvider->getGroupDN('nonexisting_group');
}
@@ -153,7 +170,9 @@ class LDAPProviderTest extends \Test\TestCase {
->method('getLDAPAccess')
->willReturn($groupAccess);
$ldapProvider = $this->getLDAPProvider($userBackend, $groupBackend);
$server = $this->getServerMock($userBackend, $groupBackend);
$ldapProvider = $this->getLDAPProvider($server);
$this->assertEquals('cn=existing_group,ou=Are Sufficient To,ou=Test,dc=example,dc=org',
$ldapProvider->getGroupDN('existing_group'));
}
@@ -167,7 +186,9 @@ class LDAPProviderTest extends \Test\TestCase {
->method('dn2UserName')
->willReturn('existing_user');
$ldapProvider = $this->getLDAPProvider($userBackend, $this->getDefaultGroupBackendMock());
$server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock());
$ldapProvider = $this->getLDAPProvider($server);
$this->assertEquals('existing_user',
$ldapProvider->getUserName('cn=existing_user,ou=Are Sufficient To,ou=Test,dc=example,dc=org'));
}
@@ -175,9 +196,11 @@ class LDAPProviderTest extends \Test\TestCase {
public function testDNasBaseParameter(): void {
$userBackend = $this->createMock(User_LDAP::class);
$server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock());
$helper = Server::get(Helper::class);
$ldapProvider = $this->getLDAPProvider($userBackend, $this->getDefaultGroupBackendMock());
$ldapProvider = $this->getLDAPProvider($server);
$this->assertEquals(
$helper->DNasBaseParameter('cn=existing_user,ou=Are Sufficient To,ou=Test,dc=example,dc=org'),
$ldapProvider->DNasBaseParameter('cn=existing_user,ou=Are Sufficient To,ou=Test,dc=example,dc=org'));
@@ -186,9 +209,11 @@ class LDAPProviderTest extends \Test\TestCase {
public function testSanitizeDN(): void {
$userBackend = $this->createMock(User_LDAP::class);
$server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock());
$helper = Server::get(Helper::class);
$ldapProvider = $this->getLDAPProvider($userBackend, $this->getDefaultGroupBackendMock());
$ldapProvider = $this->getLDAPProvider($server);
$this->assertEquals(
$helper->sanitizeDN('cn=existing_user,ou=Are Sufficient To,ou=Test,dc=example,dc=org'),
$ldapProvider->sanitizeDN('cn=existing_user,ou=Are Sufficient To,ou=Test,dc=example,dc=org'));
@@ -202,7 +227,9 @@ class LDAPProviderTest extends \Test\TestCase {
$userBackend = $this->createMock(User_LDAP::class);
$userBackend->expects($this->any())->method('userExists')->willReturn(false);
$ldapProvider = $this->getLDAPProvider($userBackend, $this->getDefaultGroupBackendMock());
$server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock());
$ldapProvider = $this->getLDAPProvider($server);
$ldapProvider->getLDAPConnection('nonexisting_user');
}
@@ -219,7 +246,9 @@ class LDAPProviderTest extends \Test\TestCase {
->method('getNewLDAPConnection')
->willReturn($ldapConnection);
$ldapProvider = $this->getLDAPProvider($userBackend, $this->getDefaultGroupBackendMock());
$server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock());
$ldapProvider = $this->getLDAPProvider($server);
$this->assertEquals($ldapConnection, $ldapProvider->getLDAPConnection('existing_user'));
}
@@ -236,7 +265,9 @@ class LDAPProviderTest extends \Test\TestCase {
$groupBackend->expects($this->any())->method('groupExists')->willReturn(false);
$ldapProvider = $this->getLDAPProvider($userBackend, $groupBackend);
$server = $this->getServerMock($userBackend, $groupBackend);
$ldapProvider = $this->getLDAPProvider($server);
$ldapProvider->getGroupLDAPConnection('nonexisting_group');
}
@@ -256,7 +287,9 @@ class LDAPProviderTest extends \Test\TestCase {
->method('getNewLDAPConnection')
->willReturn($ldapConnection);
$ldapProvider = $this->getLDAPProvider($userBackend, $groupBackend);
$server = $this->getServerMock($userBackend, $groupBackend);
$ldapProvider = $this->getLDAPProvider($server);
$this->assertEquals($ldapConnection, $ldapProvider->getGroupLDAPConnection('existing_group'));
}
@@ -271,7 +304,9 @@ class LDAPProviderTest extends \Test\TestCase {
->getMock();
$userBackend->expects($this->any())->method('userExists')->willReturn(false);
$ldapProvider = $this->getLDAPProvider($userBackend, $this->getDefaultGroupBackendMock());
$server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock());
$ldapProvider = $this->getLDAPProvider($server);
$ldapProvider->getLDAPBaseUsers('nonexisting_user');
}
@@ -317,7 +352,9 @@ class LDAPProviderTest extends \Test\TestCase {
->method('getLDAPAccess')
->willReturn($access);
$ldapProvider = $this->getLDAPProvider($userBackend, $this->getDefaultGroupBackendMock());
$server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock());
$ldapProvider = $this->getLDAPProvider($server);
$this->assertEquals($bases[1], $ldapProvider->getLDAPBaseUsers('existing_user'));
}
@@ -332,7 +369,9 @@ class LDAPProviderTest extends \Test\TestCase {
->getMock();
$userBackend->expects($this->any())->method('userExists')->willReturn(false);
$ldapProvider = $this->getLDAPProvider($userBackend, $this->getDefaultGroupBackendMock());
$server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock());
$ldapProvider = $this->getLDAPProvider($server);
$ldapProvider->getLDAPBaseGroups('nonexisting_user');
}
@@ -371,7 +410,9 @@ class LDAPProviderTest extends \Test\TestCase {
->method('getLDAPAccess')
->willReturn($access);
$ldapProvider = $this->getLDAPProvider($userBackend, $this->getDefaultGroupBackendMock());
$server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock());
$ldapProvider = $this->getLDAPProvider($server);
$this->assertEquals($bases[0], $ldapProvider->getLDAPBaseGroups('existing_user'));
}
@@ -386,7 +427,9 @@ class LDAPProviderTest extends \Test\TestCase {
->getMock();
$userBackend->expects($this->any())->method('userExists')->willReturn(false);
$ldapProvider = $this->getLDAPProvider($userBackend, $this->getDefaultGroupBackendMock());
$server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock());
$ldapProvider = $this->getLDAPProvider($server);
$ldapProvider->clearCache('nonexisting_user');
}
@@ -411,7 +454,9 @@ class LDAPProviderTest extends \Test\TestCase {
->method('getLDAPAccess')
->willReturn($access);
$ldapProvider = $this->getLDAPProvider($userBackend, $this->getDefaultGroupBackendMock());
$server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock());
$ldapProvider = $this->getLDAPProvider($server);
$ldapProvider->clearCache('existing_user');
$this->addToAssertionCount(1);
}
@@ -430,7 +475,9 @@ class LDAPProviderTest extends \Test\TestCase {
->getMock();
$groupBackend->expects($this->any())->method('groupExists')->willReturn(false);
$ldapProvider = $this->getLDAPProvider($userBackend, $groupBackend);
$server = $this->getServerMock($userBackend, $groupBackend);
$ldapProvider = $this->getLDAPProvider($server);
$ldapProvider->clearGroupCache('nonexisting_group');
}
@@ -456,7 +503,9 @@ class LDAPProviderTest extends \Test\TestCase {
->method('getLDAPAccess')
->willReturn($access);
$ldapProvider = $this->getLDAPProvider($userBackend, $groupBackend);
$server = $this->getServerMock($userBackend, $groupBackend);
$ldapProvider = $this->getLDAPProvider($server);
$ldapProvider->clearGroupCache('existing_group');
$this->addToAssertionCount(1);
}
@@ -470,22 +519,26 @@ class LDAPProviderTest extends \Test\TestCase {
->method('dn2UserName')
->willReturn('existing_user');
$ldapProvider = $this->getLDAPProvider($userBackend, $this->getDefaultGroupBackendMock());
$server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock());
$ldapProvider = $this->getLDAPProvider($server);
$this->assertTrue($ldapProvider->dnExists('cn=existing_user,ou=Are Sufficient To,ou=Test,dc=example,dc=org'));
}
public function testFlagRecord(): void {
$userBackend = $this->createMock(User_LDAP::class);
$server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock());
$ldapProvider = $this->getLDAPProvider($userBackend, $this->getDefaultGroupBackendMock());
$ldapProvider = $this->getLDAPProvider($server);
$ldapProvider->flagRecord('existing_user');
$this->addToAssertionCount(1);
}
public function testUnflagRecord(): void {
$userBackend = $this->createMock(User_LDAP::class);
$server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock());
$ldapProvider = $this->getLDAPProvider($userBackend, $this->getDefaultGroupBackendMock());
$ldapProvider = $this->getLDAPProvider($server);
$ldapProvider->unflagRecord('existing_user');
$this->addToAssertionCount(1);
}
@@ -501,7 +554,9 @@ class LDAPProviderTest extends \Test\TestCase {
->getMock();
$userBackend->expects($this->any())->method('userExists')->willReturn(false);
$ldapProvider = $this->getLDAPProvider($userBackend, $this->getDefaultGroupBackendMock());
$server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock());
$ldapProvider = $this->getLDAPProvider($server);
$ldapProvider->getLDAPDisplayNameField('nonexisting_user');
}
@@ -526,7 +581,9 @@ class LDAPProviderTest extends \Test\TestCase {
->method('getLDAPAccess')
->willReturn($access);
$ldapProvider = $this->getLDAPProvider($userBackend, $this->getDefaultGroupBackendMock());
$server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock());
$ldapProvider = $this->getLDAPProvider($server);
$this->assertEquals('displayName', $ldapProvider->getLDAPDisplayNameField('existing_user'));
}
@@ -541,7 +598,9 @@ class LDAPProviderTest extends \Test\TestCase {
->getMock();
$userBackend->expects($this->any())->method('userExists')->willReturn(false);
$ldapProvider = $this->getLDAPProvider($userBackend, $this->getDefaultGroupBackendMock());
$server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock());
$ldapProvider = $this->getLDAPProvider($server);
$ldapProvider->getLDAPEmailField('nonexisting_user');
}
@@ -566,7 +625,9 @@ class LDAPProviderTest extends \Test\TestCase {
->method('getLDAPAccess')
->willReturn($access);
$ldapProvider = $this->getLDAPProvider($userBackend, $this->getDefaultGroupBackendMock());
$server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock());
$ldapProvider = $this->getLDAPProvider($server);
$this->assertEquals('mail', $ldapProvider->getLDAPEmailField('existing_user'));
}
@@ -585,7 +646,9 @@ class LDAPProviderTest extends \Test\TestCase {
->method('groupExists')
->willReturn(false);
$ldapProvider = $this->getLDAPProvider($userBackend, $groupBackend);
$server = $this->getServerMock($userBackend, $groupBackend);
$ldapProvider = $this->getLDAPProvider($server);
$ldapProvider->getLDAPGroupMemberAssoc('nonexisting_group');
}
@@ -613,7 +676,9 @@ class LDAPProviderTest extends \Test\TestCase {
->method('getLDAPAccess')
->willReturn($access);
$ldapProvider = $this->getLDAPProvider($userBackend, $groupBackend);
$server = $this->getServerMock($userBackend, $groupBackend);
$ldapProvider = $this->getLDAPProvider($server);
$this->assertEquals('assoc_type', $ldapProvider->getLDAPGroupMemberAssoc('existing_group'));
}
@@ -627,8 +692,9 @@ class LDAPProviderTest extends \Test\TestCase {
->with('admin')
->willReturn(false);
$groupBackend = $this->createMock(Group_LDAP::class);
$server = $this->getServerMock($userBackend, $groupBackend);
$ldapProvider = $this->getLDAPProvider($userBackend, $groupBackend);
$ldapProvider = $this->getLDAPProvider($server);
$ldapProvider->getMultiValueUserAttribute('admin', 'mailAlias');
}
@@ -653,8 +719,9 @@ class LDAPProviderTest extends \Test\TestCase {
->method('getLDAPAccess')
->willReturn($access);
$groupBackend = $this->createMock(Group_LDAP::class);
$server = $this->getServerMock($userBackend, $groupBackend);
$ldapProvider = $this->getLDAPProvider($userBackend, $groupBackend);
$ldapProvider = $this->getLDAPProvider($server);
$ldapProvider->getMultiValueUserAttribute('admin', 'mailAlias');
}
@@ -689,8 +756,9 @@ class LDAPProviderTest extends \Test\TestCase {
$groupBackend = $this->getMockBuilder(Group_LDAP::class)
->disableOriginalConstructor()
->getMock();
$server = $this->getServerMock($userBackend, $groupBackend);
$ldapProvider = $this->getLDAPProvider($userBackend, $groupBackend);
$ldapProvider = $this->getLDAPProvider($server);
$values = $ldapProvider->getMultiValueUserAttribute('admin', 'mailAlias');
self::assertCount(0, $values);
@@ -727,8 +795,9 @@ class LDAPProviderTest extends \Test\TestCase {
$groupBackend = $this->getMockBuilder(Group_LDAP::class)
->disableOriginalConstructor()
->getMock();
$server = $this->getServerMock($userBackend, $groupBackend);
$ldapProvider = $this->getLDAPProvider($userBackend, $groupBackend);
$ldapProvider = $this->getLDAPProvider($server);
$values = $ldapProvider->getMultiValueUserAttribute('admin', 'mailAlias');
self::assertCount(2, $values);
@@ -765,8 +834,9 @@ class LDAPProviderTest extends \Test\TestCase {
$groupBackend = $this->getMockBuilder(Group_LDAP::class)
->disableOriginalConstructor()
->getMock();
$server = $this->getServerMock($userBackend, $groupBackend);
$ldapProvider = $this->getLDAPProvider($userBackend, $groupBackend);
$ldapProvider = $this->getLDAPProvider($server);
$value = $ldapProvider->getUserAttribute('admin', 'mailAlias');
self::assertNull($value);
@@ -803,8 +873,9 @@ class LDAPProviderTest extends \Test\TestCase {
$groupBackend = $this->getMockBuilder(Group_LDAP::class)
->disableOriginalConstructor()
->getMock();
$server = $this->getServerMock($userBackend, $groupBackend);
$ldapProvider = $this->getLDAPProvider($userBackend, $groupBackend);
$ldapProvider = $this->getLDAPProvider($server);
$value = $ldapProvider->getUserAttribute('admin', 'mailAlias');
self::assertEquals('aliasA@test.local', $value);
-8
View File
@@ -8,10 +8,7 @@ declare(strict_types=1);
namespace OCA\User_LDAP\Tests;
use OCA\User_LDAP\LDAP;
use OCP\IConfig;
use OCP\Profiler\IProfiler;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
use Test\TestCase;
class LDAPTest extends TestCase {
@@ -21,11 +18,6 @@ class LDAPTest extends TestCase {
parent::setUp();
$this->ldap = $this->getMockBuilder(LDAP::class)
->onlyMethods(['invokeLDAPMethod'])
->setConstructorArgs([
$this->createMock(IProfiler::class),
$this->createMock(IConfig::class),
$this->createMock(LoggerInterface::class),
])
->getMock();
}
+173 -218
View File
@@ -50,7 +50,7 @@
"focus-trap": "^7.8.0",
"handlebars": "^4.7.8",
"is-svg": "^6.1.0",
"libphonenumber-js": "^1.12.38",
"libphonenumber-js": "^1.12.37",
"lodash": "^4.17.23",
"marked": "^17.0.3",
"moment": "^2.30.1",
@@ -95,7 +95,7 @@
"@vitest/coverage-v8": "^4.0.18",
"@vue/test-utils": "^1.3.5",
"@vue/tsconfig": "~0.5.1",
"babel-loader-exclude-node-modules-except": "^1.2.4",
"babel-loader-exclude-node-modules-except": "^1.2.1",
"babel-plugin-module-resolver": "^5.0.2",
"colord": "^2.9.3",
"exports-loader": "^5.0.0",
@@ -112,7 +112,7 @@
"vitest": "^4.0.18",
"vue-loader": "^15.11.1",
"vue-template-compiler": "^2.7.16",
"webpack": "^5.105.3",
"webpack": "^5.105.2",
"webpack-cli": "^6.0.1",
"webpack-merge": "^6.0.1",
"workbox-webpack-plugin": "^7.4.0"
@@ -2501,6 +2501,29 @@
}
}
},
"node_modules/@isaacs/balanced-match": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz",
"integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": "20 || >=22"
}
},
"node_modules/@isaacs/brace-expansion": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz",
"integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@isaacs/balanced-match": "^4.0.1"
},
"engines": {
"node": "20 || >=22"
}
},
"node_modules/@isaacs/cliui": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
@@ -4736,9 +4759,9 @@
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz",
"integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.3.tgz",
"integrity": "sha512-h6cqHGZ6VdnwliFG1NXvMPTy/9PS3h8oLh7ImwR+kl+oYnQizgjxsONmmPSb2C66RksfkfIxEVtDSEcJiO0tqw==",
"cpu": [
"arm"
],
@@ -4750,9 +4773,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz",
"integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.3.tgz",
"integrity": "sha512-wd+u7SLT/u6knklV/ifG7gr5Qy4GUbH2hMWcDauPFJzmCZUAJ8L2bTkVXC2niOIxp8lk3iH/QX8kSrUxVZrOVw==",
"cpu": [
"arm64"
],
@@ -4764,9 +4787,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz",
"integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.3.tgz",
"integrity": "sha512-lj9ViATR1SsqycwFkJCtYfQTheBdvlWJqzqxwc9f2qrcVrQaF/gCuBRTiTolkRWS6KvNxSk4KHZWG7tDktLgjg==",
"cpu": [
"arm64"
],
@@ -4778,9 +4801,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz",
"integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.3.tgz",
"integrity": "sha512-+Dyo7O1KUmIsbzx1l+4V4tvEVnVQqMOIYtrxK7ncLSknl1xnMHLgn7gddJVrYPNZfEB8CIi3hK8gq8bDhb3h5A==",
"cpu": [
"x64"
],
@@ -4792,9 +4815,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz",
"integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.3.tgz",
"integrity": "sha512-u9Xg2FavYbD30g3DSfNhxgNrxhi6xVG4Y6i9Ur1C7xUuGDW3banRbXj+qgnIrwRN4KeJ396jchwy9bCIzbyBEQ==",
"cpu": [
"arm64"
],
@@ -4806,9 +4829,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz",
"integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.3.tgz",
"integrity": "sha512-5M8kyi/OX96wtD5qJR89a/3x5x8x5inXBZO04JWhkQb2JWavOWfjgkdvUqibGJeNNaz1/Z1PPza5/tAPXICI6A==",
"cpu": [
"x64"
],
@@ -4820,9 +4843,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz",
"integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.3.tgz",
"integrity": "sha512-IoerZJ4l1wRMopEHRKOO16e04iXRDyZFZnNZKrWeNquh5d6bucjezgd+OxG03mOMTnS1x7hilzb3uURPkJ0OfA==",
"cpu": [
"arm"
],
@@ -4834,9 +4857,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz",
"integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.3.tgz",
"integrity": "sha512-ZYdtqgHTDfvrJHSh3W22TvjWxwOgc3ThK/XjgcNGP2DIwFIPeAPNsQxrJO5XqleSlgDux2VAoWQ5iJrtaC1TbA==",
"cpu": [
"arm"
],
@@ -4848,9 +4871,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz",
"integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.3.tgz",
"integrity": "sha512-NcViG7A0YtuFDA6xWSgmFb6iPFzHlf5vcqb2p0lGEbT+gjrEEz8nC/EeDHvx6mnGXnGCC1SeVV+8u+smj0CeGQ==",
"cpu": [
"arm64"
],
@@ -4862,9 +4885,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz",
"integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.3.tgz",
"integrity": "sha512-d3pY7LWno6SYNXRm6Ebsq0DJGoiLXTb83AIPCXl9fmtIQs/rXoS8SJxxUNtFbJ5MiOvs+7y34np77+9l4nfFMw==",
"cpu": [
"arm64"
],
@@ -4876,23 +4899,9 @@
]
},
"node_modules/@rollup/rollup-linux-loong64-gnu": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz",
"integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==",
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-loong64-musl": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz",
"integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.3.tgz",
"integrity": "sha512-3y5GA0JkBuirLqmjwAKwB0keDlI6JfGYduMlJD/Rl7fvb4Ni8iKdQs1eiunMZJhwDWdCvrcqXRY++VEBbvk6Eg==",
"cpu": [
"loong64"
],
@@ -4904,23 +4913,9 @@
]
},
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz",
"integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-ppc64-musl": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz",
"integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.3.tgz",
"integrity": "sha512-AUUH65a0p3Q0Yfm5oD2KVgzTKgwPyp9DSXc3UA7DtxhEb/WSPfbG4wqXeSN62OG5gSo18em4xv6dbfcUGXcagw==",
"cpu": [
"ppc64"
],
@@ -4932,9 +4927,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz",
"integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.3.tgz",
"integrity": "sha512-1makPhFFVBqZE+XFg3Dkq+IkQ7JvmUrwwqaYBL2CE+ZpxPaqkGaiWFEWVGyvTwZace6WLJHwjVh/+CXbKDGPmg==",
"cpu": [
"riscv64"
],
@@ -4946,9 +4941,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-musl": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz",
"integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.3.tgz",
"integrity": "sha512-OOFJa28dxfl8kLOPMUOQBCO6z3X2SAfzIE276fwT52uXDWUS178KWq0pL7d6p1kz7pkzA0yQwtqL0dEPoVcRWg==",
"cpu": [
"riscv64"
],
@@ -4960,9 +4955,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz",
"integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.3.tgz",
"integrity": "sha512-jMdsML2VI5l+V7cKfZx3ak+SLlJ8fKvLJ0Eoa4b9/vCUrzXKgoKxvHqvJ/mkWhFiyp88nCkM5S2v6nIwRtPcgg==",
"cpu": [
"s390x"
],
@@ -4974,9 +4969,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz",
"integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.3.tgz",
"integrity": "sha512-tPgGd6bY2M2LJTA1uGq8fkSPK8ZLYjDjY+ZLK9WHncCnfIz29LIXIqUgzCR0hIefzy6Hpbe8Th5WOSwTM8E7LA==",
"cpu": [
"x64"
],
@@ -4988,9 +4983,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz",
"integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.3.tgz",
"integrity": "sha512-BCFkJjgk+WFzP+tcSMXq77ymAPIxsX9lFJWs+2JzuZTLtksJ2o5hvgTdIcZ5+oKzUDMwI0PfWzRBYAydAHF2Mw==",
"cpu": [
"x64"
],
@@ -5001,24 +4996,10 @@
"linux"
]
},
"node_modules/@rollup/rollup-openbsd-x64": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz",
"integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
]
},
"node_modules/@rollup/rollup-openharmony-arm64": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz",
"integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.3.tgz",
"integrity": "sha512-KTD/EqjZF3yvRaWUJdD1cW+IQBk4fbQaHYJUmP8N4XoKFZilVL8cobFSTDnjTtxWJQ3JYaMgF4nObY/+nYkumA==",
"cpu": [
"arm64"
],
@@ -5030,9 +5011,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz",
"integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.3.tgz",
"integrity": "sha512-+zteHZdoUYLkyYKObGHieibUFLbttX2r+58l27XZauq0tcWYYuKUwY2wjeCN9oK1Um2YgH2ibd6cnX/wFD7DuA==",
"cpu": [
"arm64"
],
@@ -5044,9 +5025,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz",
"integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.3.tgz",
"integrity": "sha512-of1iHkTQSo3kr6dTIRX6t81uj/c/b15HXVsPcEElN5sS859qHrOepM5p9G41Hah+CTqSh2r8Bm56dL2z9UQQ7g==",
"cpu": [
"ia32"
],
@@ -5058,9 +5039,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-gnu": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz",
"integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.3.tgz",
"integrity": "sha512-s0hybmlHb56mWVZQj8ra9048/WZTPLILKxcvcq+8awSZmyiSUZjjem1AhU3Tf4ZKpYhK4mg36HtHDOe8QJS5PQ==",
"cpu": [
"x64"
],
@@ -5072,9 +5053,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz",
"integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.3.tgz",
"integrity": "sha512-zGIbEVVXVtauFgl3MRwGWEN36P5ZGenHRMgNw88X5wEhEBpq0XrMEZwOn07+ICrwM17XO5xfMZqh0OldCH5VTA==",
"cpu": [
"x64"
],
@@ -6502,9 +6483,9 @@
}
},
"node_modules/acorn": {
"version": "8.16.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
"version": "8.15.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
@@ -6930,11 +6911,14 @@
}
},
"node_modules/babel-loader-exclude-node-modules-except": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/babel-loader-exclude-node-modules-except/-/babel-loader-exclude-node-modules-except-1.2.4.tgz",
"integrity": "sha512-rfoi0R9K9tORe4xfFtiqPoBzlMmX/wMxygjSSw5FYHxzoyxmVzxCzASXMTmwfh/3M4VD442TOu67xPNY7m7jEw==",
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/babel-loader-exclude-node-modules-except/-/babel-loader-exclude-node-modules-except-1.2.1.tgz",
"integrity": "sha512-kp/JcdRhhYKprE9fYRquyasqtrdRKXqBj0BVGB9OYxEzdBTpD/8e6w1K1gafyHgntj7f9JxLhi4phOrnCMKD6Q==",
"dev": true,
"license": "MIT"
"license": "MIT",
"dependencies": {
"escape-string-regexp": "2.0.0"
}
},
"node_modules/babel-plugin-module-resolver": {
"version": "5.0.2",
@@ -9220,6 +9204,16 @@
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
"license": "MIT"
},
"node_modules/escape-string-regexp": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
"integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/eslint-scope": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
@@ -9557,22 +9551,10 @@
],
"license": "BSD-3-Clause"
},
"node_modules/fast-xml-builder": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.0.0.tgz",
"integrity": "sha512-fpZuDogrAgnyt9oDDz+5DBz0zgPdPZz6D4IR7iESxRXElrlGTRkHJ9eEt+SACRJwT0FNFrt71DFQIUFBJfX/uQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/NaturalIntelligence"
}
],
"license": "MIT"
},
"node_modules/fast-xml-parser": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.4.1.tgz",
"integrity": "sha512-BQ30U1mKkvXQXXkAGcuyUA/GA26oEB7NzOtsxCDtyu62sjGw5QraKFhx2Em3WQNjPw9PG6MQ9yuIIgkSDfGu5A==",
"version": "5.3.6",
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.6.tgz",
"integrity": "sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA==",
"funding": [
{
"type": "github",
@@ -9581,7 +9563,6 @@
],
"license": "MIT",
"dependencies": {
"fast-xml-builder": "^1.0.0",
"strnum": "^2.1.2"
},
"bin": {
@@ -10141,9 +10122,9 @@
"license": "BSD-2-Clause"
},
"node_modules/glob/node_modules/minimatch": {
"version": "8.0.7",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.7.tgz",
"integrity": "sha512-V+1uQNdzybxa14e/p00HZnQNNcTjnRJjDxg2V8wtkjFctq4M7hXFws4oekyTP0Jebeq7QYtpFyOeBAjc88zvYg==",
"version": "8.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz",
"integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -11840,13 +11821,13 @@
}
},
"node_modules/js-beautify/node_modules/minimatch": {
"version": "9.0.9",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
"integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.2"
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
@@ -12036,9 +12017,9 @@
}
},
"node_modules/libphonenumber-js": {
"version": "1.12.38",
"resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.12.38.tgz",
"integrity": "sha512-vwzxmasAy9hZigxtqTbFEwp8ZdZ975TiqVDwj5bKx5sR+zi5ucUQy9mbVTkKM9GzqdLdxux/hTw2nmN5J7POMA==",
"version": "1.12.37",
"resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.12.37.tgz",
"integrity": "sha512-rDU6bkpuMs8YRt/UpkuYEAsYSoNuDEbrE41I3KNvmXREGH6DGBJ8Wbak4by29wNOQ27zk4g4HL82zf0OGhwRuw==",
"license": "MIT"
},
"node_modules/linkify-string": {
@@ -13112,9 +13093,9 @@
"license": "MIT"
},
"node_modules/minimatch": {
"version": "5.1.9",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz",
"integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==",
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -15647,9 +15628,9 @@
}
},
"node_modules/rollup": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz",
"integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.3.tgz",
"integrity": "sha512-RIDh866U8agLgiIcdpB+COKnlCreHJLfIhWC3LVflku5YHfpnsIKigRZeFfMfCc4dVcqNVfQQ5gO/afOck064A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -15663,31 +15644,28 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.59.0",
"@rollup/rollup-android-arm64": "4.59.0",
"@rollup/rollup-darwin-arm64": "4.59.0",
"@rollup/rollup-darwin-x64": "4.59.0",
"@rollup/rollup-freebsd-arm64": "4.59.0",
"@rollup/rollup-freebsd-x64": "4.59.0",
"@rollup/rollup-linux-arm-gnueabihf": "4.59.0",
"@rollup/rollup-linux-arm-musleabihf": "4.59.0",
"@rollup/rollup-linux-arm64-gnu": "4.59.0",
"@rollup/rollup-linux-arm64-musl": "4.59.0",
"@rollup/rollup-linux-loong64-gnu": "4.59.0",
"@rollup/rollup-linux-loong64-musl": "4.59.0",
"@rollup/rollup-linux-ppc64-gnu": "4.59.0",
"@rollup/rollup-linux-ppc64-musl": "4.59.0",
"@rollup/rollup-linux-riscv64-gnu": "4.59.0",
"@rollup/rollup-linux-riscv64-musl": "4.59.0",
"@rollup/rollup-linux-s390x-gnu": "4.59.0",
"@rollup/rollup-linux-x64-gnu": "4.59.0",
"@rollup/rollup-linux-x64-musl": "4.59.0",
"@rollup/rollup-openbsd-x64": "4.59.0",
"@rollup/rollup-openharmony-arm64": "4.59.0",
"@rollup/rollup-win32-arm64-msvc": "4.59.0",
"@rollup/rollup-win32-ia32-msvc": "4.59.0",
"@rollup/rollup-win32-x64-gnu": "4.59.0",
"@rollup/rollup-win32-x64-msvc": "4.59.0",
"@rollup/rollup-android-arm-eabi": "4.52.3",
"@rollup/rollup-android-arm64": "4.52.3",
"@rollup/rollup-darwin-arm64": "4.52.3",
"@rollup/rollup-darwin-x64": "4.52.3",
"@rollup/rollup-freebsd-arm64": "4.52.3",
"@rollup/rollup-freebsd-x64": "4.52.3",
"@rollup/rollup-linux-arm-gnueabihf": "4.52.3",
"@rollup/rollup-linux-arm-musleabihf": "4.52.3",
"@rollup/rollup-linux-arm64-gnu": "4.52.3",
"@rollup/rollup-linux-arm64-musl": "4.52.3",
"@rollup/rollup-linux-loong64-gnu": "4.52.3",
"@rollup/rollup-linux-ppc64-gnu": "4.52.3",
"@rollup/rollup-linux-riscv64-gnu": "4.52.3",
"@rollup/rollup-linux-riscv64-musl": "4.52.3",
"@rollup/rollup-linux-s390x-gnu": "4.52.3",
"@rollup/rollup-linux-x64-gnu": "4.52.3",
"@rollup/rollup-linux-x64-musl": "4.52.3",
"@rollup/rollup-openharmony-arm64": "4.52.3",
"@rollup/rollup-win32-arm64-msvc": "4.52.3",
"@rollup/rollup-win32-ia32-msvc": "4.52.3",
"@rollup/rollup-win32-x64-gnu": "4.52.3",
"@rollup/rollup-win32-x64-msvc": "4.52.3",
"fsevents": "~2.3.2"
}
},
@@ -18793,12 +18771,12 @@
}
},
"node_modules/webdav/node_modules/minimatch": {
"version": "9.0.9",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
"integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.2"
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
@@ -18815,9 +18793,9 @@
"license": "BSD-2-Clause"
},
"node_modules/webpack": {
"version": "5.105.3",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.3.tgz",
"integrity": "sha512-LLBBA4oLmT7sZdHiYE/PeVuifOxYyE2uL/V+9VQP7YSYdJU7bSf7H8bZRRxW8kEPMkmVjnrXmoR3oejIdX0xbg==",
"version": "5.105.2",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.2.tgz",
"integrity": "sha512-dRXm0a2qcHPUBEzVk8uph0xWSjV/xZxenQQbLwnwP7caQCYpqG1qddwlyEkIDkYn0K8tvmcrZ+bOrzoQ3HxCDw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -18827,7 +18805,7 @@
"@webassemblyjs/ast": "^1.14.1",
"@webassemblyjs/wasm-edit": "^1.14.1",
"@webassemblyjs/wasm-parser": "^1.14.1",
"acorn": "^8.16.0",
"acorn": "^8.15.0",
"acorn-import-phases": "^1.0.3",
"browserslist": "^4.28.1",
"chrome-trace-event": "^1.0.2",
@@ -18845,7 +18823,7 @@
"tapable": "^2.3.0",
"terser-webpack-plugin": "^5.3.16",
"watchpack": "^2.5.1",
"webpack-sources": "^3.3.4"
"webpack-sources": "^3.3.3"
},
"bin": {
"webpack": "bin/webpack.js"
@@ -19169,9 +19147,9 @@
}
},
"node_modules/webpack-sources": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.4.tgz",
"integrity": "sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==",
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz",
"integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -19602,29 +19580,6 @@
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/workbox-build/node_modules/balanced-match": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
"integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
"dev": true,
"license": "MIT",
"engines": {
"node": "18 || 20 || >=22"
}
},
"node_modules/workbox-build/node_modules/brace-expansion": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz",
"integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^4.0.2"
},
"engines": {
"node": "18 || 20 || >=22"
}
},
"node_modules/workbox-build/node_modules/estree-walker": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
@@ -19700,16 +19655,16 @@
}
},
"node_modules/workbox-build/node_modules/minimatch": {
"version": "10.2.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz",
"integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==",
"version": "10.1.1",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz",
"integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"brace-expansion": "^5.0.2"
"@isaacs/brace-expansion": "^5.0.0"
},
"engines": {
"node": "18 || 20 || >=22"
"node": "20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
@@ -19743,9 +19698,9 @@
}
},
"node_modules/workbox-build/node_modules/rollup": {
"version": "2.80.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.80.0.tgz",
"integrity": "sha512-cIFJOD1DESzpjOBl763Kp1AH7UE/0fcdHe6rZXUdQ9c50uvgigvW97u3IcSeBwOkgqL/PXPBktBCh0KEu5L8XQ==",
"version": "2.79.2",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz",
"integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==",
"dev": true,
"license": "MIT",
"bin": {
+3 -3
View File
@@ -66,7 +66,7 @@
"focus-trap": "^7.8.0",
"handlebars": "^4.7.8",
"is-svg": "^6.1.0",
"libphonenumber-js": "^1.12.38",
"libphonenumber-js": "^1.12.37",
"lodash": "^4.17.23",
"marked": "^17.0.3",
"moment": "^2.30.1",
@@ -111,7 +111,7 @@
"@vitest/coverage-v8": "^4.0.18",
"@vue/test-utils": "^1.3.5",
"@vue/tsconfig": "~0.5.1",
"babel-loader-exclude-node-modules-except": "^1.2.4",
"babel-loader-exclude-node-modules-except": "^1.2.1",
"babel-plugin-module-resolver": "^5.0.2",
"colord": "^2.9.3",
"exports-loader": "^5.0.0",
@@ -128,7 +128,7 @@
"vitest": "^4.0.18",
"vue-loader": "^15.11.1",
"vue-template-compiler": "^2.7.16",
"webpack": "^5.105.3",
"webpack": "^5.105.2",
"webpack-cli": "^6.0.1",
"webpack-merge": "^6.0.1",
"workbox-webpack-plugin": "^7.4.0"
+16
View File
@@ -2575,6 +2575,8 @@
'loginName2UserName'
)]]></code>
<code><![CDATA[dispatch]]></code>
<code><![CDATA[registerService]]></code>
<code><![CDATA[registerService]]></code>
</DeprecatedMethod>
</file>
<file src="apps/user_ldap/lib/Configuration.php">
@@ -2615,6 +2617,20 @@
<code><![CDATA[$i]]></code>
</InvalidOperand>
</file>
<file src="apps/user_ldap/lib/LDAPProvider.php">
<DeprecatedInterface>
<code><![CDATA[IServerContainer]]></code>
</DeprecatedInterface>
<DeprecatedMethod>
<code><![CDATA[getGroupManager]]></code>
<code><![CDATA[getUserManager]]></code>
</DeprecatedMethod>
</file>
<file src="apps/user_ldap/lib/LDAPProviderFactory.php">
<DeprecatedInterface>
<code><![CDATA[private]]></code>
</DeprecatedInterface>
</file>
<file src="apps/user_ldap/lib/Mapping/AbstractMapping.php">
<DeprecatedMethod>
<code><![CDATA[getDatabasePlatform]]></code>
+2 -5
View File
@@ -236,11 +236,8 @@ This file is generated from multiple sources. Included packages:
- events
- version: 3.3.0
- license: MIT
- fast-xml-builder
- version: 1.0.0
- license: MIT
- fast-xml-parser
- version: 5.4.1
- version: 5.3.6
- license: MIT
- floating-vue
- version: 1.0.0-beta.19
@@ -450,7 +447,7 @@ This file is generated from multiple sources. Included packages:
- version: 6.0.1
- license: BSD-2-Clause
- minimatch
- version: 9.0.9
- version: 9.0.5
- license: ISC
- webdav
- version: 5.9.0
+2 -5
View File
@@ -236,11 +236,8 @@ This file is generated from multiple sources. Included packages:
- events
- version: 3.3.0
- license: MIT
- fast-xml-builder
- version: 1.0.0
- license: MIT
- fast-xml-parser
- version: 5.4.1
- version: 5.3.6
- license: MIT
- floating-vue
- version: 1.0.0-beta.19
@@ -450,7 +447,7 @@ This file is generated from multiple sources. Included packages:
- version: 6.0.1
- license: BSD-2-Clause
- minimatch
- version: 9.0.9
- version: 9.0.5
- license: ISC
- webdav
- version: 5.9.0
+1 -1
View File
File diff suppressed because one or more lines are too long
+2 -5
View File
@@ -236,11 +236,8 @@ This file is generated from multiple sources. Included packages:
- events
- version: 3.3.0
- license: MIT
- fast-xml-builder
- version: 1.0.0
- license: MIT
- fast-xml-parser
- version: 5.4.1
- version: 5.3.6
- license: MIT
- floating-vue
- version: 1.0.0-beta.19
@@ -450,7 +447,7 @@ This file is generated from multiple sources. Included packages:
- version: 6.0.1
- license: BSD-2-Clause
- minimatch
- version: 9.0.9
- version: 9.0.5
- license: ISC
- webdav
- version: 5.9.0
+2 -5
View File
@@ -236,11 +236,8 @@ This file is generated from multiple sources. Included packages:
- events
- version: 3.3.0
- license: MIT
- fast-xml-builder
- version: 1.0.0
- license: MIT
- fast-xml-parser
- version: 5.4.1
- version: 5.3.6
- license: MIT
- floating-vue
- version: 1.0.0-beta.19
@@ -450,7 +447,7 @@ This file is generated from multiple sources. Included packages:
- version: 6.0.1
- license: BSD-2-Clause
- minimatch
- version: 9.0.9
- version: 9.0.5
- license: ISC
- webdav
- version: 5.9.0
@@ -1,2 +1,2 @@
import{f as y,q as g,u as o,o as n,g as p,I as h,w as v,j as _,t as V,y as k,s as x,c as d,F as M,C as q,E as w,G as K,h as f,r as U}from"./runtime-dom.esm-bundler-DIF-dmiV.chunk.mjs";import{c as j}from"./index-D0gj0nne.chunk.mjs";import{a as C}from"./index-C1xmmKTZ-D5oZDAAj.chunk.mjs";import{t as s}from"./translation-DoG5ZELJ-Bni_xMHF.chunk.mjs";import{g as E}from"./createElementId-DhjFt1I9-DmxdOxki.chunk.mjs";import{N}from"./autolink-U5pBzLgI-DPNCkNxB.chunk.mjs";import{N as S}from"./NcSelect-DLheQ2yp-C6fHgfXd.chunk.mjs";import{N as A}from"./NcCheckboxRadioSwitch-BMsPx74L-CnVoVoz9.chunk.mjs";import{N as L}from"./NcPasswordField-uaMO2pdt-3LVTs_hE.chunk.mjs";import{_ as z}from"./TrashCanOutline-B5JNH7nQ.chunk.mjs";import{C as c,a as b}from"./types-Bi5ljtgu.chunk.mjs";import{l as B}from"./logger-resIultJ.chunk.mjs";const P=y({__name:"ConfigurationEntry",props:k({configKey:{},configOption:{}},{modelValue:{type:[String,Boolean],default:""},modelModifiers:{}}),emits:["update:modelValue"],setup(e){const a=g(e,"modelValue");return(t,i)=>e.configOption.type!==o(c).Boolean?(n(),p(h(e.configOption.type===o(c).Password?o(L):o(z)),{key:0,modelValue:a.value,"onUpdate:modelValue":i[0]||(i[0]=l=>a.value=l),name:e.configKey,required:!(e.configOption.flags&o(b).Optional),label:e.configOption.value,title:e.configOption.tooltip},null,8,["modelValue","name","required","label","title"])):(n(),p(o(A),{key:1,modelValue:a.value,"onUpdate:modelValue":i[1]||(i[1]=l=>a.value=l),type:"switch",title:e.configOption.tooltip},{default:v(()=>[_(V(e.configOption.value),1)]),_:1},8,["modelValue","title"]))}}),R=y({__name:"AuthMechanismRsa",props:k({authMechanism:{}},{modelValue:{required:!0},modelModifiers:{}}),emits:["update:modelValue"],setup(e){const a=g(e,"modelValue"),t=U();x(t,()=>{t.value&&(a.value.private_key="",a.value.public_key="")});async function i(){try{const{data:l}=await j.post(E("/apps/files_external/ajax/public_key.php"),{keyLength:t.value});a.value.private_key=l.data.private_key,a.value.public_key=l.data.public_key}catch(l){B.error("Error generating RSA key pair",{error:l}),C(s("files_external","Error generating key pair"))}}return(l,m)=>(n(),d("div",null,[(n(!0),d(M,null,q(e.authMechanism.configuration,(r,u)=>w((n(),p(P,{key:r.value,modelValue:a.value[u],"onUpdate:modelValue":O=>a.value[u]=O,configKey:u,configOption:r},null,8,["modelValue","onUpdate:modelValue","configKey","configOption"])),[[K,!(r.flags&o(b).Hidden)]])),128)),f(o(S),{modelValue:t.value,"onUpdate:modelValue":m[0]||(m[0]=r=>t.value=r),clearable:!1,inputLabel:o(s)("files_external","Key size"),options:[1024,2048,4096],required:""},null,8,["modelValue","inputLabel"]),f(o(N),{disabled:!t.value,wide:"",onClick:i},{default:v(()=>[_(V(o(s)("files_external","Generate keys")),1)]),_:1},8,["disabled"])]))}}),$=Object.freeze(Object.defineProperty({__proto__:null,default:R},Symbol.toStringTag,{value:"Module"}));export{$ as A,P as _};
//# sourceMappingURL=AuthMechanismRsa-Da474qhT.chunk.mjs.map
import{f as g,q as y,s as v,g as p,u as o,o as n,I as h,w as _,j as V,t as k,v as x,r as M,c as d,h as f,F as q,C as w,E as K,G as U}from"./runtime-dom.esm-bundler-w0tDt7Gi.chunk.mjs";import{c as j}from"./index-2HC-5o-4.chunk.mjs";import{a as C}from"./index-C1xmmKTZ-zpf0CQaW.chunk.mjs";import{t as s}from"./translation-DoG5ZELJ-Bni_xMHF.chunk.mjs";import{g as E}from"./createElementId-DhjFt1I9-B1fq6aa1.chunk.mjs";import{N}from"./autolink-U5pBzLgI-2h5mm9kB.chunk.mjs";import{N as S}from"./NcSelect-DLheQ2yp-dx4VDMCp.chunk.mjs";import{N as A}from"./NcCheckboxRadioSwitch-BMsPx74L-_RgKMJqI.chunk.mjs";import{N as L}from"./NcPasswordField-uaMO2pdt-PEl2ADM3.chunk.mjs";import{_ as z}from"./TrashCanOutline-Big6DF74.chunk.mjs";import{C as c,a as b}from"./types-Cv5PF4zN.chunk.mjs";import{l as B}from"./logger-resIultJ.chunk.mjs";const P=g({__name:"ConfigurationEntry",props:y({configKey:{},configOption:{}},{modelValue:{type:[String,Boolean],default:""},modelModifiers:{}}),emits:["update:modelValue"],setup(e){const a=v(e,"modelValue");return(t,i)=>e.configOption.type!==o(c).Boolean?(n(),p(h(e.configOption.type===o(c).Password?o(L):o(z)),{key:0,modelValue:a.value,"onUpdate:modelValue":i[0]||(i[0]=l=>a.value=l),name:e.configKey,required:!(e.configOption.flags&o(b).Optional),label:e.configOption.value,title:e.configOption.tooltip},null,8,["modelValue","name","required","label","title"])):(n(),p(o(A),{key:1,modelValue:a.value,"onUpdate:modelValue":i[1]||(i[1]=l=>a.value=l),type:"switch",title:e.configOption.tooltip},{default:_(()=>[V(k(e.configOption.value),1)]),_:1},8,["modelValue","title"]))}}),R=g({__name:"AuthMechanismRsa",props:y({authMechanism:{}},{modelValue:{required:!0},modelModifiers:{}}),emits:["update:modelValue"],setup(e){const a=v(e,"modelValue"),t=M();x(t,()=>{t.value&&(a.value.private_key="",a.value.public_key="")});async function i(){try{const{data:l}=await j.post(E("/apps/files_external/ajax/public_key.php"),{keyLength:t.value});a.value.private_key=l.data.private_key,a.value.public_key=l.data.public_key}catch(l){B.error("Error generating RSA key pair",{error:l}),C(s("files_external","Error generating key pair"))}}return(l,m)=>(n(),d("div",null,[(n(!0),d(q,null,w(e.authMechanism.configuration,(r,u)=>K((n(),p(P,{key:r.value,modelValue:a.value[u],"onUpdate:modelValue":O=>a.value[u]=O,configKey:u,configOption:r},null,8,["modelValue","onUpdate:modelValue","configKey","configOption"])),[[U,!(r.flags&o(b).Hidden)]])),128)),f(o(S),{modelValue:t.value,"onUpdate:modelValue":m[0]||(m[0]=r=>t.value=r),clearable:!1,inputLabel:o(s)("files_external","Key size"),options:[1024,2048,4096],required:""},null,8,["modelValue","inputLabel"]),f(o(N),{disabled:!t.value,wide:"",onClick:i},{default:_(()=>[V(k(o(s)("files_external","Generate keys")),1)]),_:1},8,["disabled"])]))}}),$=Object.freeze(Object.defineProperty({__proto__:null,default:R},Symbol.toStringTag,{value:"Module"}));export{$ as A,P as _};
//# sourceMappingURL=AuthMechanismRsa-C4e9bMX8.chunk.mjs.map
File diff suppressed because one or more lines are too long
@@ -1,2 +1,2 @@
import{r as g,B as h,_ as p,a as C}from"./createElementId-DhjFt1I9-DmxdOxki.chunk.mjs";import{f as _,o as i,c as e,b as o,j as y,t as s,u as d,h as H,e as r,n as b,m}from"./runtime-dom.esm-bundler-DIF-dmiV.chunk.mjs";import{a as k}from"./index-Ma7sfat2.chunk.mjs";const A={name:"HelpCircleIcon",emits:["click"],props:{title:{type:String},fillColor:{type:String,default:"currentColor"},size:{type:Number,default:24}}},v=["aria-hidden","aria-label"],V=["fill","width","height"],w={d:"M15.07,11.25L14.17,12.17C13.45,12.89 13,13.5 13,15H11V14.5C11,13.39 11.45,12.39 12.17,11.67L13.41,10.41C13.78,10.05 14,9.55 14,9C14,7.89 13.1,7 12,7A2,2 0 0,0 10,9H8A4,4 0 0,1 12,5A4,4 0 0,1 16,9C16,9.88 15.64,10.67 15.07,11.25M13,19H11V17H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z"},z={key:0};function M(a,l,t,c,f,u){return i(),e("span",m(a.$attrs,{"aria-hidden":t.title?null:"true","aria-label":t.title,class:"material-design-icon help-circle-icon",role:"img",onClick:l[0]||(l[0]=n=>a.$emit("click",n))}),[(i(),e("svg",{fill:t.fillColor,class:"material-design-icon__svg",width:t.size,height:t.size,viewBox:"0 0 24 24"},[o("path",w,[t.title?(i(),e("title",z,s(t.title),1)):r("",!0)])],8,V))],16,v)}const S=p(A,[["render",M]]);g(h);const x={class:"settings-section"},$={class:"settings-section__name"},I=["aria-label","href","title"],N={key:0,class:"settings-section__desc"},B=_({__name:"NcSettingsSection",props:{name:{},description:{default:""},docUrl:{default:""}},setup(a){const l=C("External documentation");return(t,c)=>(i(),e("div",x,[o("h2",$,[y(s(t.name)+" ",1),t.docUrl?(i(),e("a",{key:0,"aria-label":d(l),class:"settings-section__info",href:t.docUrl,rel:"noreferrer nofollow",target:"_blank",title:d(l)},[H(S,{size:20})],8,I)):r("",!0)]),t.description?(i(),e("p",N,s(t.description),1)):r("",!0),b(t.$slots,"default",{},void 0,!0)]))}}),T=p(B,[["__scopeId","data-v-9cedb949"]]),U={name:"ContentCopyIcon",emits:["click"],props:{title:{type:String},fillColor:{type:String,default:"currentColor"},size:{type:Number,default:24}}},L=["aria-hidden","aria-label"],Z=["fill","width","height"],j={d:"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"},E={key:0};function q(a,l,t,c,f,u){return i(),e("span",m(a.$attrs,{"aria-hidden":t.title?null:"true","aria-label":t.title,class:"material-design-icon content-copy-icon",role:"img",onClick:l[0]||(l[0]=n=>a.$emit("click",n))}),[(i(),e("svg",{fill:t.fillColor,class:"material-design-icon__svg",width:t.size,height:t.size,viewBox:"0 0 24 24"},[o("path",j,[t.title?(i(),e("title",E,s(t.title),1)):r("",!0)])],8,Z))],16,L)}const G=k(U,[["render",q]]);export{G as I,T as N};
//# sourceMappingURL=ContentCopy-FlPcmQnb.chunk.mjs.map
import{r as g,B as h,_ as p,a as C}from"./createElementId-DhjFt1I9-B1fq6aa1.chunk.mjs";import{f as _,c as i,o as e,b as o,e as s,n as y,j as H,t as r,u as d,h as b,m}from"./runtime-dom.esm-bundler-w0tDt7Gi.chunk.mjs";import{a as k}from"./index-Ma7sfat2.chunk.mjs";const A={name:"HelpCircleIcon",emits:["click"],props:{title:{type:String},fillColor:{type:String,default:"currentColor"},size:{type:Number,default:24}}},v=["aria-hidden","aria-label"],V=["fill","width","height"],w={d:"M15.07,11.25L14.17,12.17C13.45,12.89 13,13.5 13,15H11V14.5C11,13.39 11.45,12.39 12.17,11.67L13.41,10.41C13.78,10.05 14,9.55 14,9C14,7.89 13.1,7 12,7A2,2 0 0,0 10,9H8A4,4 0 0,1 12,5A4,4 0 0,1 16,9C16,9.88 15.64,10.67 15.07,11.25M13,19H11V17H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z"},z={key:0};function M(a,l,t,c,f,u){return e(),i("span",m(a.$attrs,{"aria-hidden":t.title?null:"true","aria-label":t.title,class:"material-design-icon help-circle-icon",role:"img",onClick:l[0]||(l[0]=n=>a.$emit("click",n))}),[(e(),i("svg",{fill:t.fillColor,class:"material-design-icon__svg",width:t.size,height:t.size,viewBox:"0 0 24 24"},[o("path",w,[t.title?(e(),i("title",z,r(t.title),1)):s("",!0)])],8,V))],16,v)}const S=p(A,[["render",M]]);g(h);const x={class:"settings-section"},$={class:"settings-section__name"},I=["aria-label","href","title"],N={key:0,class:"settings-section__desc"},B=_({__name:"NcSettingsSection",props:{name:{},description:{default:""},docUrl:{default:""}},setup(a){const l=C("External documentation");return(t,c)=>(e(),i("div",x,[o("h2",$,[H(r(t.name)+" ",1),t.docUrl?(e(),i("a",{key:0,"aria-label":d(l),class:"settings-section__info",href:t.docUrl,rel:"noreferrer nofollow",target:"_blank",title:d(l)},[b(S,{size:20})],8,I)):s("",!0)]),t.description?(e(),i("p",N,r(t.description),1)):s("",!0),y(t.$slots,"default",{},void 0,!0)]))}}),T=p(B,[["__scopeId","data-v-9cedb949"]]),U={name:"ContentCopyIcon",emits:["click"],props:{title:{type:String},fillColor:{type:String,default:"currentColor"},size:{type:Number,default:24}}},L=["aria-hidden","aria-label"],Z=["fill","width","height"],j={d:"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"},E={key:0};function q(a,l,t,c,f,u){return e(),i("span",m(a.$attrs,{"aria-hidden":t.title?null:"true","aria-label":t.title,class:"material-design-icon content-copy-icon",role:"img",onClick:l[0]||(l[0]=n=>a.$emit("click",n))}),[(e(),i("svg",{fill:t.fillColor,class:"material-design-icon__svg",width:t.size,height:t.size,viewBox:"0 0 24 24"},[o("path",j,[t.title?(e(),i("title",E,r(t.title),1)):s("",!0)])],8,Z))],16,L)}const G=k(U,[["render",q]]);export{G as I,T as N};
//# sourceMappingURL=ContentCopy-CgZpiJBj.chunk.mjs.map
File diff suppressed because one or more lines are too long
@@ -1,2 +1,2 @@
import{t}from"./translation-DoG5ZELJ-Bni_xMHF.chunk.mjs";import{N as u}from"./index-BIuNq36J.chunk.mjs";import{N as d}from"./mdi-LZKofHvu.chunk.mjs";import{N as p}from"./NcPasswordField-uaMO2pdt-3LVTs_hE.chunk.mjs";import{_ as c}from"./TrashCanOutline-B5JNH7nQ.chunk.mjs";import{f as g,o as h,g as f,w as x,h as s,u as e,r as n}from"./runtime-dom.esm-bundler-DIF-dmiV.chunk.mjs";import"./index-Bndk0DrU.chunk.mjs";import"./NcModal-DHryP_87-DTKTujA6.chunk.mjs";import"./autolink-U5pBzLgI-DPNCkNxB.chunk.mjs";import"./createElementId-DhjFt1I9-DmxdOxki.chunk.mjs";import"./Web-D7kU0XCu.chunk.mjs";import"./index-Ma7sfat2.chunk.mjs";import"./index-D0gj0nne.chunk.mjs";import"./index-sH3U_332.chunk.mjs";import"./NcInputField-o5OFv3z6-vgXJNqqQ.chunk.mjs";const D=g({__name:"CredentialsDialog",emits:["close"],setup(_){const o=n(""),r=n(""),m=[{label:t("files_external","Confirm"),type:"submit",variant:"primary"}];return(i,a)=>(h(),f(e(u),{buttons:m,class:"external-storage-auth",closeOnClickOutside:"","data-cy-external-storage-auth":"",isForm:"",name:e(t)("files_external","Storage credentials"),outTransition:"",onSubmit:a[2]||(a[2]=l=>i.$emit("close",{login:o.value,password:r.value})),"onUpdate:open":a[3]||(a[3]=l=>i.$emit("close"))},{default:x(()=>[s(e(d),{class:"external-storage-auth__header",text:e(t)("files_external","To access the storage, you need to provide the authentication credentials."),type:"info"},null,8,["text"]),s(e(c),{modelValue:o.value,"onUpdate:modelValue":a[0]||(a[0]=l=>o.value=l),autofocus:"",class:"external-storage-auth__login","data-cy-external-storage-auth-dialog-login":"",label:e(t)("files_external","Login"),placeholder:e(t)("files_external","Enter the storage login"),minlength:"2",name:"login",required:""},null,8,["modelValue","label","placeholder"]),s(e(p),{modelValue:r.value,"onUpdate:modelValue":a[1]||(a[1]=l=>r.value=l),class:"external-storage-auth__password","data-cy-external-storage-auth-dialog-password":"",label:e(t)("files_external","Password"),placeholder:e(t)("files_external","Enter the storage password"),name:"password",required:""},null,8,["modelValue","label","placeholder"])]),_:1},8,["name"]))}});export{D as default};
//# sourceMappingURL=CredentialsDialog-s7bWg_Eh.chunk.mjs.map
import{t}from"./translation-DoG5ZELJ-Bni_xMHF.chunk.mjs";import{N as u}from"./index-1X7ElQaR.chunk.mjs";import{N as d}from"./mdi-YPhQfxXZ.chunk.mjs";import{N as p}from"./NcPasswordField-uaMO2pdt-PEl2ADM3.chunk.mjs";import{_ as c}from"./TrashCanOutline-Big6DF74.chunk.mjs";import{f as g,g as h,o as f,w as x,h as s,u as e,r as n}from"./runtime-dom.esm-bundler-w0tDt7Gi.chunk.mjs";import"./index-Bndk0DrU.chunk.mjs";import"./NcModal-DHryP_87-BkYzWFXJ.chunk.mjs";import"./autolink-U5pBzLgI-2h5mm9kB.chunk.mjs";import"./createElementId-DhjFt1I9-B1fq6aa1.chunk.mjs";import"./Web-DzGiDslj.chunk.mjs";import"./index-Ma7sfat2.chunk.mjs";import"./index-2HC-5o-4.chunk.mjs";import"./index-sH3U_332.chunk.mjs";import"./NcInputField-o5OFv3z6-BKcArNCr.chunk.mjs";const D=g({__name:"CredentialsDialog",emits:["close"],setup(_){const o=n(""),r=n(""),m=[{label:t("files_external","Confirm"),type:"submit",variant:"primary"}];return(i,a)=>(f(),h(e(u),{buttons:m,class:"external-storage-auth",closeOnClickOutside:"","data-cy-external-storage-auth":"",isForm:"",name:e(t)("files_external","Storage credentials"),outTransition:"",onSubmit:a[2]||(a[2]=l=>i.$emit("close",{login:o.value,password:r.value})),"onUpdate:open":a[3]||(a[3]=l=>i.$emit("close"))},{default:x(()=>[s(e(d),{class:"external-storage-auth__header",text:e(t)("files_external","To access the storage, you need to provide the authentication credentials."),type:"info"},null,8,["text"]),s(e(c),{modelValue:o.value,"onUpdate:modelValue":a[0]||(a[0]=l=>o.value=l),autofocus:"",class:"external-storage-auth__login","data-cy-external-storage-auth-dialog-login":"",label:e(t)("files_external","Login"),placeholder:e(t)("files_external","Enter the storage login"),minlength:"2",name:"login",required:""},null,8,["modelValue","label","placeholder"]),s(e(p),{modelValue:r.value,"onUpdate:modelValue":a[1]||(a[1]=l=>r.value=l),class:"external-storage-auth__password","data-cy-external-storage-auth-dialog-password":"",label:e(t)("files_external","Password"),placeholder:e(t)("files_external","Enter the storage password"),name:"password",required:""},null,8,["modelValue","label","placeholder"])]),_:1},8,["name"]))}});export{D as default};
//# sourceMappingURL=CredentialsDialog-DThlC5QM.chunk.mjs.map
@@ -1 +1 @@
{"version":3,"file":"CredentialsDialog-s7bWg_Eh.chunk.mjs","sources":["../build/frontend/apps/files_external/src/views/CredentialsDialog.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n-->\n\n<script setup lang=\"ts\">\nimport { t } from '@nextcloud/l10n'\nimport { ref } from 'vue'\nimport NcDialog from '@nextcloud/vue/components/NcDialog'\nimport NcNoteCard from '@nextcloud/vue/components/NcNoteCard'\nimport NcPasswordField from '@nextcloud/vue/components/NcPasswordField'\nimport NcTextField from '@nextcloud/vue/components/NcTextField'\n\ndefineEmits<{\n\tclose: [payload?: { login: string, password: string }]\n}>()\n\nconst login = ref('')\nconst password = ref('')\n\nconst dialogButtons: InstanceType<typeof NcDialog>['buttons'] = [{\n\tlabel: t('files_external', 'Confirm'),\n\ttype: 'submit',\n\tvariant: 'primary',\n}]\n</script>\n\n<template>\n\t<NcDialog\n\t\t:buttons=\"dialogButtons\"\n\t\tclass=\"external-storage-auth\"\n\t\tcloseOnClickOutside\n\t\tdata-cy-external-storage-auth\n\t\tisForm\n\t\t:name=\"t('files_external', 'Storage credentials')\"\n\t\toutTransition\n\t\t@submit=\"$emit('close', { login, password })\"\n\t\t@update:open=\"$emit('close')\">\n\t\t<!-- Header -->\n\t\t<NcNoteCard\n\t\t\tclass=\"external-storage-auth__header\"\n\t\t\t:text=\"t('files_external', 'To access the storage, you need to provide the authentication credentials.')\"\n\t\t\ttype=\"info\" />\n\n\t\t<!-- Login -->\n\t\t<NcTextField\n\t\t\tv-model=\"login\"\n\t\t\tautofocus\n\t\t\tclass=\"external-storage-auth__login\"\n\t\t\tdata-cy-external-storage-auth-dialog-login\n\t\t\t:label=\"t('files_external', 'Login')\"\n\t\t\t:placeholder=\"t('files_external', 'Enter the storage login')\"\n\t\t\tminlength=\"2\"\n\t\t\tname=\"login\"\n\t\t\trequired />\n\n\t\t<!-- Password -->\n\t\t<NcPasswordField\n\t\t\tv-model=\"password\"\n\t\t\tclass=\"external-storage-auth__password\"\n\t\t\tdata-cy-external-storage-auth-dialog-password\n\t\t\t:label=\"t('files_external', 'Password')\"\n\t\t\t:placeholder=\"t('files_external', 'Enter the storage password')\"\n\t\t\tname=\"password\"\n\t\t\trequired />\n\t</NcDialog>\n</template>\n"],"names":["login","ref","password","dialogButtons","t","_createBlock","_unref","NcDialog","_cache","$event","$emit","_createVNode","NcNoteCard","NcTextField","NcPasswordField"],"mappings":"6yBAiBA,MAAMA,EAAQC,EAAI,EAAE,EACdC,EAAWD,EAAI,EAAE,EAEjBE,EAA0D,CAAC,CAChE,MAAOC,EAAE,iBAAkB,SAAS,EACpC,KAAM,SACN,QAAS,SAAA,CACT,oBAIAC,EAqCWC,EAAAC,CAAA,EAAA,CApCT,QAASJ,EACV,MAAM,wBACN,oBAAA,GACA,gCAAA,GACA,OAAA,GACC,KAAMG,EAAAF,CAAA,EAAC,iBAAA,qBAAA,EACR,cAAA,GACC,SAAMI,EAAA,CAAA,IAAAA,EAAA,CAAA,EAAAC,GAAEC,EAAAA,MAAK,QAAA,CAAA,MAAYV,EAAA,eAAOE,EAAA,MAAQ,GACxC,+BAAaQ,EAAAA,MAAK,OAAA,EAAA,aAEnB,IAGe,CAHfC,EAGeL,EAAAM,CAAA,EAAA,CAFd,MAAM,gCACL,KAAMN,EAAAF,CAAA,EAAC,iBAAA,4EAAA,EACR,KAAK,MAAA,mBAGNO,EASYL,EAAAO,CAAA,EAAA,YARFb,EAAA,2CAAAA,EAAK,MAAAS,GACd,UAAA,GACA,MAAM,+BACN,6CAAA,GACC,MAAOH,EAAAF,CAAA,EAAC,iBAAA,OAAA,EACR,YAAaE,EAAAF,CAAA,EAAC,iBAAA,yBAAA,EACf,UAAU,IACV,KAAK,QACL,SAAA,EAAA,+CAGDO,EAOYL,EAAAQ,CAAA,EAAA,YANFZ,EAAA,2CAAAA,EAAQ,MAAAO,GACjB,MAAM,kCACN,gDAAA,GACC,MAAOH,EAAAF,CAAA,EAAC,iBAAA,UAAA,EACR,YAAaE,EAAAF,CAAA,EAAC,iBAAA,4BAAA,EACf,KAAK,WACL,SAAA,EAAA"}
{"version":3,"file":"CredentialsDialog-DThlC5QM.chunk.mjs","sources":["../build/frontend/apps/files_external/src/views/CredentialsDialog.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n-->\n\n<script setup lang=\"ts\">\nimport { t } from '@nextcloud/l10n'\nimport { ref } from 'vue'\nimport NcDialog from '@nextcloud/vue/components/NcDialog'\nimport NcNoteCard from '@nextcloud/vue/components/NcNoteCard'\nimport NcPasswordField from '@nextcloud/vue/components/NcPasswordField'\nimport NcTextField from '@nextcloud/vue/components/NcTextField'\n\ndefineEmits<{\n\tclose: [payload?: { login: string, password: string }]\n}>()\n\nconst login = ref('')\nconst password = ref('')\n\nconst dialogButtons: InstanceType<typeof NcDialog>['buttons'] = [{\n\tlabel: t('files_external', 'Confirm'),\n\ttype: 'submit',\n\tvariant: 'primary',\n}]\n</script>\n\n<template>\n\t<NcDialog\n\t\t:buttons=\"dialogButtons\"\n\t\tclass=\"external-storage-auth\"\n\t\tcloseOnClickOutside\n\t\tdata-cy-external-storage-auth\n\t\tisForm\n\t\t:name=\"t('files_external', 'Storage credentials')\"\n\t\toutTransition\n\t\t@submit=\"$emit('close', { login, password })\"\n\t\t@update:open=\"$emit('close')\">\n\t\t<!-- Header -->\n\t\t<NcNoteCard\n\t\t\tclass=\"external-storage-auth__header\"\n\t\t\t:text=\"t('files_external', 'To access the storage, you need to provide the authentication credentials.')\"\n\t\t\ttype=\"info\" />\n\n\t\t<!-- Login -->\n\t\t<NcTextField\n\t\t\tv-model=\"login\"\n\t\t\tautofocus\n\t\t\tclass=\"external-storage-auth__login\"\n\t\t\tdata-cy-external-storage-auth-dialog-login\n\t\t\t:label=\"t('files_external', 'Login')\"\n\t\t\t:placeholder=\"t('files_external', 'Enter the storage login')\"\n\t\t\tminlength=\"2\"\n\t\t\tname=\"login\"\n\t\t\trequired />\n\n\t\t<!-- Password -->\n\t\t<NcPasswordField\n\t\t\tv-model=\"password\"\n\t\t\tclass=\"external-storage-auth__password\"\n\t\t\tdata-cy-external-storage-auth-dialog-password\n\t\t\t:label=\"t('files_external', 'Password')\"\n\t\t\t:placeholder=\"t('files_external', 'Enter the storage password')\"\n\t\t\tname=\"password\"\n\t\t\trequired />\n\t</NcDialog>\n</template>\n"],"names":["login","ref","password","dialogButtons","t","_createBlock","_unref","NcDialog","_cache","$event","$emit","_createVNode","NcNoteCard","NcTextField","NcPasswordField"],"mappings":"6yBAiBA,MAAMA,EAAQC,EAAI,EAAE,EACdC,EAAWD,EAAI,EAAE,EAEjBE,EAA0D,CAAC,CAChE,MAAOC,EAAE,iBAAkB,SAAS,EACpC,KAAM,SACN,QAAS,SAAA,CACT,oBAIAC,EAqCWC,EAAAC,CAAA,EAAA,CApCT,QAASJ,EACV,MAAM,wBACN,oBAAA,GACA,gCAAA,GACA,OAAA,GACC,KAAMG,EAAAF,CAAA,EAAC,iBAAA,qBAAA,EACR,cAAA,GACC,SAAMI,EAAA,CAAA,IAAAA,EAAA,CAAA,EAAAC,GAAEC,EAAAA,MAAK,QAAA,CAAA,MAAYV,EAAA,eAAOE,EAAA,MAAQ,GACxC,+BAAaQ,EAAAA,MAAK,OAAA,EAAA,aAEnB,IAGe,CAHfC,EAGeL,EAAAM,CAAA,EAAA,CAFd,MAAM,gCACL,KAAMN,EAAAF,CAAA,EAAC,iBAAA,4EAAA,EACR,KAAK,MAAA,mBAGNO,EASYL,EAAAO,CAAA,EAAA,YARFb,EAAA,2CAAAA,EAAK,MAAAS,GACd,UAAA,GACA,MAAM,+BACN,6CAAA,GACC,MAAOH,EAAAF,CAAA,EAAC,iBAAA,OAAA,EACR,YAAaE,EAAAF,CAAA,EAAC,iBAAA,yBAAA,EACf,UAAU,IACV,KAAK,QACL,SAAA,EAAA,+CAGDO,EAOYL,EAAAQ,CAAA,EAAA,YANFZ,EAAA,2CAAAA,EAAQ,MAAAO,GACjB,MAAM,kCACN,gDAAA,GACC,MAAOH,EAAAF,CAAA,EAAC,iBAAA,UAAA,EACR,YAAaE,EAAAF,CAAA,EAAC,iBAAA,4BAAA,EACf,KAAK,WACL,SAAA,EAAA"}
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
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

Some files were not shown because too many files have changed in this diff Show More