From 2c362c3164cbad18fba6c332047f2ef140e9df0d Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Mon, 6 Oct 2025 16:08:29 +0200 Subject: [PATCH 01/24] feat: initiate remote share notifications Signed-off-by: grnd-alt --- lib/AppInfo/Application.php | 14 ++++++ lib/Controller/BoardController.php | 4 +- lib/Db/Acl.php | 5 +++ lib/Db/BoardMapper.php | 3 ++ lib/Federation/DeckFederationProvider.php | 44 +++++++++++++++++++ .../Version11001Date20251009165313.php | 28 ++++++++++++ lib/Notification/Notifier.php | 10 +++++ lib/Service/BoardService.php | 29 ++++++++++++ src/components/board/SharingTabSidebar.vue | 6 ++- src/services/BoardApi.js | 1 + src/store/main.js | 3 +- 11 files changed, 143 insertions(+), 4 deletions(-) create mode 100644 lib/Federation/DeckFederationProvider.php create mode 100644 lib/Migration/Version11001Date20251009165313.php diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 71c7325222..dae73e7339 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -28,6 +28,7 @@ use OCA\Deck\Event\SessionClosedEvent; use OCA\Deck\Event\SessionCreatedEvent; use OCA\Deck\Listeners\AclCreatedRemovedListener; +use OCA\Deck\Federation\DeckFederationProvider; use OCA\Deck\Listeners\BeforeTemplateRenderedListener; use OCA\Deck\Listeners\CommentEventListener; use OCA\Deck\Listeners\FullTextSearchEventListener; @@ -60,9 +61,11 @@ use OCP\Comments\CommentsEntityEvent; use OCP\Comments\CommentsEvent; use OCP\EventDispatcher\IEventDispatcher; +use OCP\Federation\ICloudFederationProviderManager; use OCP\Group\Events\GroupDeletedEvent; use OCP\IConfig; use OCP\IDBConnection; +use OCP\Server; use OCP\Share\IManager; use OCP\User\Events\UserDeletedEvent; use OCP\Util; @@ -102,6 +105,7 @@ public function boot(IBootContext $context): void { $context->injectFn(function (Listener $listener, IEventDispatcher $eventDispatcher) { $listener->register($eventDispatcher); }); + $context->injectFn($this->registerCloudFederationProvider(...)); } public function register(IRegistrationContext $context): void { @@ -194,4 +198,14 @@ protected function registerCollaborationResources(IProviderManager $resourceMana $resourceManager->registerResourceProvider(ResourceProvider::class); $resourceManager->registerResourceProvider(ResourceProviderCard::class); } + + public function registerCloudFederationProvider( + ICloudFederationProviderManager $manager, + ): void { + $manager->addCloudFederationProvider( + DeckFederationProvider::PROVIDER_ID, + "Deck Federation", + static fn () => Server::get(DeckFederationProvider::class), + ); + } } diff --git a/lib/Controller/BoardController.php b/lib/Controller/BoardController.php index 39739a4e4e..4cabdf6738 100644 --- a/lib/Controller/BoardController.php +++ b/lib/Controller/BoardController.php @@ -83,8 +83,8 @@ public function getUserPermissions(int $boardId): array { * @param $participant */ #[NoAdminRequired] - public function addAcl(int $boardId, int $type, $participant, bool $permissionEdit, bool $permissionShare, bool $permissionManage): Acl { - return $this->boardService->addAcl($boardId, $type, $participant, $permissionEdit, $permissionShare, $permissionManage); + public function addAcl(int $boardId, int $type, $participant, bool $permissionEdit, bool $permissionShare, bool $permissionManage, ?string $remote = null): Acl { + return $this->boardService->addAcl($boardId, $type, $participant, $permissionEdit, $permissionShare, $permissionManage, $remote); } /** diff --git a/lib/Db/Acl.php b/lib/Db/Acl.php index 77c2101691..49fd6b4426 100644 --- a/lib/Db/Acl.php +++ b/lib/Db/Acl.php @@ -19,6 +19,8 @@ * @method void setType(int $type) * @method bool isOwner() * @method void setOwner(int $owner) + * @method void setToken(string $token) + * @method string getToken(string $token) * */ class Acl extends RelationalEntity { @@ -29,6 +31,7 @@ class Acl extends RelationalEntity { public const PERMISSION_TYPE_USER = 0; public const PERMISSION_TYPE_GROUP = 1; + public const PERMISSION_TYPE_REMOTE = 6; public const PERMISSION_TYPE_CIRCLE = 7; protected $participant; @@ -38,6 +41,7 @@ class Acl extends RelationalEntity { protected $permissionShare = false; protected $permissionManage = false; protected $owner = false; + protected $token = null; public function __construct() { $this->addType('id', 'integer'); @@ -47,6 +51,7 @@ public function __construct() { $this->addType('permissionManage', 'boolean'); $this->addType('type', 'integer'); $this->addType('owner', 'boolean'); + $this->addType('token', 'string'); $this->addRelation('owner'); $this->addResolvable('participant'); } diff --git a/lib/Db/BoardMapper.php b/lib/Db/BoardMapper.php index ebf4a672e1..8de4836e7a 100644 --- a/lib/Db/BoardMapper.php +++ b/lib/Db/BoardMapper.php @@ -509,6 +509,9 @@ public function mapAcl(Acl &$acl): void { } return null; } + if ($acl->getType() === Acl::PERMISSION_TYPE_REMOTE) { + return null; + } $this->logger->warning('Unknown permission type for mapping acl ' . $acl->getId()); return null; }); diff --git a/lib/Federation/DeckFederationProvider.php b/lib/Federation/DeckFederationProvider.php new file mode 100644 index 0000000000..bb3c6ab1a1 --- /dev/null +++ b/lib/Federation/DeckFederationProvider.php @@ -0,0 +1,44 @@ +notificationManager->createNotification(); + $notification->setApp('deck'); + $notification->setUser($share->getShareWith()); + $notification->setDateTime(new \DateTime()); + $notification->setObject('remote-board-shared', (string) rand(0,9999999)); + $notification->setSubject('remote-board-shared',[$share->getDescription(), $share->getSharedBy()]); + + $this->notificationManager->notify($notification); + + return 'PLACE_HOLDER_ID'; + } + + public function notificationReceived($notificationType, $providerId, $notification): array { + return []; + } + + public function getSupportedShareTypes(): array { + return ['user']; + } +} diff --git a/lib/Migration/Version11001Date20251009165313.php b/lib/Migration/Version11001Date20251009165313.php new file mode 100644 index 0000000000..9a7de8bfe7 --- /dev/null +++ b/lib/Migration/Version11001Date20251009165313.php @@ -0,0 +1,28 @@ +hasTable($tableName)) { + $table = $schema->getTable($tableName); + if (!$table->hasColumn('token')) { + $table->addColumn('token', 'string', [ + 'notnull' => false, + 'length' => 32, + ]); + } + } + + return $schema; + } +} diff --git a/lib/Notification/Notifier.php b/lib/Notification/Notifier.php index 57ac45f0e2..bebc47e9da 100644 --- a/lib/Notification/Notifier.php +++ b/lib/Notification/Notifier.php @@ -231,6 +231,16 @@ public function prepare(INotification $notification, string $languageCode): INot ); $notification->setLink($this->getBoardUrl($boardId)); break; + case 'remote-board-shared': + $boardId = (int)$notification->getObjectId(); + if (!$boardId) { + throw new AlreadyProcessedException(); + } + $federationOwnerDisplayName = $params[1]; + $notification->setParsedSubject( + $l->t('The remote board %s has been shared with you by %s', [$params[0], $federationOwnerDisplayName]) + ); + break; } return $notification; } diff --git a/lib/Service/BoardService.php b/lib/Service/BoardService.php index 1492ae9b03..7ead753be9 100644 --- a/lib/Service/BoardService.php +++ b/lib/Service/BoardService.php @@ -32,6 +32,7 @@ use OCA\Deck\Event\AclUpdatedEvent; use OCA\Deck\Event\BoardUpdatedEvent; use OCA\Deck\Event\CardCreatedEvent; +use OCA\Deck\Federation\DeckFederationProvider; use OCA\Deck\NoPermissionException; use OCA\Deck\Notification\NotificationHelper; use OCA\Deck\Validators\BoardServiceValidator; @@ -40,12 +41,16 @@ use OCP\AppFramework\Db\MultipleObjectsReturnedException; use OCP\DB\Exception as DbException; use OCP\EventDispatcher\IEventDispatcher; +use OCP\Federation\ICloudFederationProvider; +use OCP\Federation\ICloudFederationProviderManager; +use OCP\Federation\ICloudFederationFactory; use OCP\IConfig; use OCP\IDBConnection; use OCP\IL10N; use OCP\IURLGenerator; use OCP\IUserManager; use OCP\Server; +use OCP\Security\ISecureRandom; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; @@ -66,6 +71,8 @@ public function __construct( private NotificationHelper $notificationHelper, private AssignmentMapper $assignedUsersMapper, private ActivityManager $activityManager, + private readonly ICloudFederationProviderManager $cloudFederationProviderManager, + private readonly ICloudFederationFactory $federationFactory, private IEventDispatcher $eventDispatcher, private ChangeHelper $changeHelper, private IURLGenerator $urlGenerator, @@ -73,6 +80,7 @@ public function __construct( private BoardServiceValidator $boardServiceValidator, private SessionMapper $sessionMapper, private IUserManager $userManager, + private ISecureRandom $random, private ?string $userId, ) { } @@ -364,6 +372,27 @@ public function addAcl(int $boardId, int $type, $participant, bool $edit, bool $ [$edit, $share, $manage] = $this->applyPermissions($boardId, $edit, $share, $manage); $acl = new Acl(); + if ($type === Acl::PERMISSION_TYPE_REMOTE) { + $sharedBy = $this->userManager->get($this->userId); + $board = $this->find($boardId); + $token = $this->random->generate(32); + $cloudShare = $this->federationFactory->getCloudFederationShare( + $participant, // shareWith + $boardId, // name + $board->getTitle(), // description + DeckFederationProvider::PROVIDER_ID, // providerID + $sharedBy->getCloudId(), // owner (this instance) + $sharedBy->getDisplayName(), // ownerDisplayName (this instance) + $sharedBy->getCloudId(), // sharedBy (this instance) + $sharedBy->getDisplayName(), // sharedByDisplayName (this instance) + $token, // sharedSecret + 'user', // shareType + 'deck' // resourceType + ); + $resp = $this->cloudFederationProviderManager->sendCloudShare($cloudShare); + $acl->setToken($token); + } + $acl->setBoardId($boardId); $acl->setType($type); $acl->setParticipant($participant); diff --git a/src/components/board/SharingTabSidebar.vue b/src/components/board/SharingTabSidebar.vue index e583464b8e..d01a1d8bc0 100644 --- a/src/components/board/SharingTabSidebar.vue +++ b/src/components/board/SharingTabSidebar.vue @@ -39,10 +39,12 @@
+
- {{ acl.participant.displayname }} + {{ acl.participant.displayname || acl.participant }} {{ t('deck', '(Group)') }} {{ t('deck', '(Team)') }} + {{ t('deck', '(remote)') }} { const foundIndex = this.board.acl.findIndex((acl) => { return acl.participant.uid === sharee.value.shareWith && acl.participant.type === sharee.value.shareType @@ -191,6 +194,7 @@ export default { loading(false) }, async clickAddAcl() { + console.log(this.addAcl) this.addAclForAPI = { type: this.addAcl.value.shareType, participant: this.addAcl.value.shareWith, diff --git a/src/services/BoardApi.js b/src/services/BoardApi.js index c3bc0584f4..b09ccfbf70 100644 --- a/src/services/BoardApi.js +++ b/src/services/BoardApi.js @@ -319,6 +319,7 @@ export class BoardApi { // Acl API Calls addAcl(acl) { + console.log(acl.participant) return axios.post(this.url(`/boards/${acl.boardId}/acl`), acl) .then( (response) => { diff --git a/src/store/main.js b/src/store/main.js index b9620d87f4..c3796fd724 100644 --- a/src/store/main.js +++ b/src/store/main.js @@ -242,6 +242,7 @@ export default function storeFactory() { state.sharees.push(...shareesUsersAndGroups.users) state.sharees.push(...shareesUsersAndGroups.groups) state.sharees.push(...shareesUsersAndGroups.circles) + state.sharees.push(...shareesUsersAndGroups.remotes) }, setAssignableUsers(state, users) { state.assignableUsers = users @@ -437,7 +438,7 @@ export default function storeFactory() { params.append('search', query) params.append('format', 'json') params.append('perPage', 20) - params.append('itemType', [0, 1, 4, 7]) + params.append('itemType', 'deck') params.append('lookup', false) const response = await axios.get(generateOcsUrl('apps/files_sharing/api/v1/sharees'), { params }) From 9a37762dcb2a60ef35298e19a3f52da8545cb0d0 Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Tue, 14 Oct 2025 16:19:31 +0200 Subject: [PATCH 02/24] wip: show federated shares in navigation Signed-off-by: grnd-alt --- lib/Controller/BoardController.php | 9 +++- lib/Controller/PageController.php | 7 +++- lib/Db/ExternalBoard.php | 32 ++++++++++++++ lib/Db/ExternalBoardMapper.php | 25 +++++++++++ lib/Federation/DeckFederationProvider.php | 12 +++++- .../Version11001Date20251014122010.php | 42 +++++++++++++++++++ lib/Service/BoardService.php | 6 +-- lib/Service/ExternalBoardService.php | 18 ++++++++ src/components/navigation/AppNavigation.vue | 42 +++++++++++++++++++ .../navigation/AppNavigationBoardCategory.vue | 3 ++ src/store/main.js | 5 ++- 11 files changed, 192 insertions(+), 9 deletions(-) create mode 100644 lib/Db/ExternalBoard.php create mode 100644 lib/Db/ExternalBoardMapper.php create mode 100644 lib/Migration/Version11001Date20251014122010.php create mode 100644 lib/Service/ExternalBoardService.php diff --git a/lib/Controller/BoardController.php b/lib/Controller/BoardController.php index 4cabdf6738..fdcd83c806 100644 --- a/lib/Controller/BoardController.php +++ b/lib/Controller/BoardController.php @@ -11,6 +11,7 @@ use OCA\Deck\Db\Board; use OCA\Deck\NoPermissionException; use OCA\Deck\Service\BoardService; +use OCA\Deck\Service\ExternalBoardService; use OCA\Deck\Service\Importer\BoardImportService; use OCA\Deck\Service\PermissionService; use OCP\AppFramework\ApiController; @@ -25,6 +26,7 @@ public function __construct( $appName, IRequest $request, private BoardService $boardService, + private ExternalBoardService $externalBoardService, private PermissionService $permissionService, private BoardImportService $boardImportService, private IL10N $l10n, @@ -35,7 +37,12 @@ public function __construct( #[NoAdminRequired] public function index() { - return $this->boardService->findAll(); + $internalBoards = $this->boardService->findAll(); + $externalBoards = $this->externalBoardService->findAll(); + return [ + 'internal' => $internalBoards, + 'external' => $externalBoards, + ]; } #[NoAdminRequired] diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php index 0f846bdf60..3f420feedb 100644 --- a/lib/Controller/PageController.php +++ b/lib/Controller/PageController.php @@ -10,6 +10,7 @@ use OCA\Deck\Db\Acl; use OCA\Deck\Db\CardMapper; use OCA\Deck\Service\BoardService; +use OCA\Deck\Service\ExternalBoardService; use OCA\Deck\Service\CardService; use OCA\Deck\Service\ConfigService; use OCA\Deck\Service\PermissionService; @@ -36,6 +37,7 @@ public function __construct( private PermissionService $permissionService, private IInitialState $initialState, private BoardService $boardService, + private ExternalBoardService $externalBoardService, private ConfigService $configService, private IEventDispatcher $eventDispatcher, private CardMapper $cardMapper, @@ -53,7 +55,10 @@ public function index(): TemplateResponse { $this->initialState->provideInitialState('canCreate', $this->permissionService->canCreate()); $this->initialState->provideInitialState('config', $this->configService->getAll()); - $this->initialState->provideInitialState('initialBoards', $this->boardService->findAll()); + $this->initialState->provideInitialState('initialBoards', [ + "internal" => $this->boardService->findAll(), + "external" => $this->externalBoardService->findAll(), + ]); $this->eventDispatcher->dispatchTyped(new LoadSidebar()); $this->eventDispatcher->dispatchTyped(new CollaborationResourcesEvent()); diff --git a/lib/Db/ExternalBoard.php b/lib/Db/ExternalBoard.php new file mode 100644 index 0000000000..9d63035826 --- /dev/null +++ b/lib/Db/ExternalBoard.php @@ -0,0 +1,32 @@ +AddType('id', 'integer'); + $this->addType('title', 'string'); + $this->addType('externalId', 'string'); + $this->addType('owner', 'string'); + $this->addResolvable('participant'); + } +} diff --git a/lib/Db/ExternalBoardMapper.php b/lib/Db/ExternalBoardMapper.php new file mode 100644 index 0000000000..d7df1dbdb6 --- /dev/null +++ b/lib/Db/ExternalBoardMapper.php @@ -0,0 +1,25 @@ + */ +class ExternalBoardMapper extends QBMapper{ + public function __construct( + IDBConnection $db, + ) { + parent::__construct($db, 'deck_boards_external', ExternalBoard::class); + } + + public function findAllForUser(string $userId) { + $qb = $this->db->getQueryBuilder(); + $qb->select('*') + ->from('deck_boards_external') + ->where($qb->expr()->eq('participant', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR))) + ->orderBy('id'); + return $this->findEntities($qb); + } +} diff --git a/lib/Federation/DeckFederationProvider.php b/lib/Federation/DeckFederationProvider.php index bb3c6ab1a1..d8042fbb39 100644 --- a/lib/Federation/DeckFederationProvider.php +++ b/lib/Federation/DeckFederationProvider.php @@ -1,7 +1,8 @@ setUser($share->getShareWith()); $notification->setDateTime(new \DateTime()); $notification->setObject('remote-board-shared', (string) rand(0,9999999)); - $notification->setSubject('remote-board-shared',[$share->getDescription(), $share->getSharedBy()]); + $notification->setSubject('remote-board-shared',[$share->getResourceName(), $share->getSharedBy()]); $this->notificationManager->notify($notification); + $externalBoard = new ExternalBoard(); + $externalBoard->setTitle($share->getResourceName()); + $externalBoard->setExternalId($share->getProviderId()); + $externalBoard->setOwner($share->getSharedBy()); + $externalBoard->setParticipant($share->getShareWith()); + $this->externalBoardMapper->insert($externalBoard); return 'PLACE_HOLDER_ID'; } diff --git a/lib/Migration/Version11001Date20251014122010.php b/lib/Migration/Version11001Date20251014122010.php new file mode 100644 index 0000000000..62e3c41cb0 --- /dev/null +++ b/lib/Migration/Version11001Date20251014122010.php @@ -0,0 +1,42 @@ +hasTable($tableName)) { + $table = $schema->createTable($tableName); + $table->addColumn('id', 'integer', [ + 'autoincrement' => true, + 'notnull' => true, + 'length' => 4, + ]); + $table->addColumn('external_id', 'integer', [ + 'notnull' => true, + 'length' => 4, + ]); + $table->addColumn('title', 'string', [ + 'notnull' => true, + 'length' => 100, + ]); + $table->addColumn('owner', 'string', [ + 'notnull' => true, + 'length' => 64, + ]); + $table->addColumn('participant', 'string', [ + 'notnull' => true, + 'length' => 64, + ]); + $table->setPrimaryKey(['id']); + } + return $schema; + } +} diff --git a/lib/Service/BoardService.php b/lib/Service/BoardService.php index 7ead753be9..04327cfb6e 100644 --- a/lib/Service/BoardService.php +++ b/lib/Service/BoardService.php @@ -378,9 +378,9 @@ public function addAcl(int $boardId, int $type, $participant, bool $edit, bool $ $token = $this->random->generate(32); $cloudShare = $this->federationFactory->getCloudFederationShare( $participant, // shareWith - $boardId, // name - $board->getTitle(), // description - DeckFederationProvider::PROVIDER_ID, // providerID + $board->getTitle(), // name + '', // description + $boardId, // providerID $sharedBy->getCloudId(), // owner (this instance) $sharedBy->getDisplayName(), // ownerDisplayName (this instance) $sharedBy->getCloudId(), // sharedBy (this instance) diff --git a/lib/Service/ExternalBoardService.php b/lib/Service/ExternalBoardService.php new file mode 100644 index 0000000000..2f71faf5b8 --- /dev/null +++ b/lib/Service/ExternalBoardService.php @@ -0,0 +1,18 @@ +externalBoardMapper->findAllForUser($this->userId); + } +} diff --git a/src/components/navigation/AppNavigation.vue b/src/components/navigation/AppNavigation.vue index 9999e6bdbc..c66ece2eec 100644 --- a/src/components/navigation/AppNavigation.vue +++ b/src/components/navigation/AppNavigation.vue @@ -43,6 +43,15 @@ + + + @@ -80,6 +89,7 @@ import { subscribe } from '@nextcloud/event-bus' import AppNavigationImportBoard from './AppNavigationImportBoard.vue' import DeckAppSettings from '../DeckAppSettings.vue' import IconCog from 'vue-material-design-icons/CogOutline.vue' +import { mapState } from 'vuex/dist/vuex.common.js' const canCreateState = loadState('deck', 'canCreate') @@ -126,6 +136,38 @@ export default { 'archivedBoards', 'sharedBoards', ]), + ...mapState({ + externalBoards: state => { + return state.externalBoards + }, + }), + isAdmin() { + return !!getCurrentUser()?.isAdmin + }, + cardDetailsInModal: { + get() { + return this.$store.getters.config('cardDetailsInModal') + }, + set(newValue) { + this.$store.dispatch('setConfig', { cardDetailsInModal: newValue }) + }, + }, + cardIdBadge: { + get() { + return this.$store.getters.config('cardIdBadge') + }, + set(newValue) { + this.$store.dispatch('setConfig', { cardIdBadge: newValue }) + }, + }, + configCalendar: { + get() { + return this.$store.getters.config('calendar') + }, + set(newValue) { + this.$store.dispatch('setConfig', { calendar: newValue }) + }, + }, }, mounted() { subscribe('deck:global:toggle-help-dialog', () => { diff --git a/src/components/navigation/AppNavigationBoardCategory.vue b/src/components/navigation/AppNavigationBoardCategory.vue index f0f56433d1..348a3a577b 100644 --- a/src/components/navigation/AppNavigationBoardCategory.vue +++ b/src/components/navigation/AppNavigationBoardCategory.vue @@ -63,6 +63,9 @@ export default { }, computed: { boardsSorted() { + console.log("FROM NAVIGATION") + console.log(this.id) + console.log(this.boards) return [...this.boards].sort((a, b) => a.title.localeCompare(b.title)) }, collapsible() { diff --git a/src/store/main.js b/src/store/main.js index c3796fd724..e30a74ae1c 100644 --- a/src/store/main.js +++ b/src/store/main.js @@ -52,7 +52,8 @@ export default function storeFactory() { currentBoard: null, currentCard: null, hasCardSaveError: false, - boards: loadState('deck', 'initialBoards', []), + boards: loadState('deck', 'initialBoards', {internal:[]}).internal, + externalBoards: loadState('deck', 'initialBoards', {external:[]}).external, sharees: [], assignableUsers: [], boardFilter: BOARD_FILTERS.ALL, @@ -428,7 +429,7 @@ export default function storeFactory() { }, async loadBoards({ commit }) { const boards = await apiClient.loadBoards() - commit('setBoards', boards) + commit('setBoards', boards.internal) }, async loadSharees({ commit }, query) { const params = new URLSearchParams() From 4e485fd7f70438a99480336a0aab0402f4d91e2d Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Tue, 21 Oct 2025 11:14:04 +0200 Subject: [PATCH 03/24] read-only federated boards Signed-off-by: grnd-alt --- appinfo/routes.php | 5 + lib/Controller/BoardController.php | 7 +- lib/Controller/NewBoardController.php | 61 ++++++++ lib/Controller/PageController.php | 3 +- lib/Db/Acl.php | 2 +- lib/Db/AclMapper.php | 2 +- lib/Db/Board.php | 8 + lib/Db/ExternalBoard.php | 32 ---- lib/Db/ExternalBoardMapper.php | 25 ---- lib/Federation/DeckFederationProvider.php | 28 +++- lib/Federation/DeckFederationProxy.php | 140 ++++++++++++++++++ .../Version11001Date20251016122010.php | 24 +++ .../Version11001Date20251020122010.php | 29 ++++ lib/Service/BoardService.php | 10 +- lib/Service/ExternalBoardService.php | 28 +++- lib/Service/PermissionService.php | 53 +++++-- src/components/navigation/AppNavigation.vue | 14 -- .../navigation/AppNavigationBoard.vue | 13 +- src/services/BoardApi.js | 11 +- src/services/StackApi.js | 10 +- src/store/main.js | 53 ++++--- 21 files changed, 411 insertions(+), 147 deletions(-) create mode 100644 lib/Controller/NewBoardController.php delete mode 100644 lib/Db/ExternalBoard.php delete mode 100644 lib/Db/ExternalBoardMapper.php create mode 100644 lib/Federation/DeckFederationProxy.php create mode 100644 lib/Migration/Version11001Date20251016122010.php create mode 100644 lib/Migration/Version11001Date20251020122010.php diff --git a/appinfo/routes.php b/appinfo/routes.php index 45d6555f3b..aef09b3347 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -133,6 +133,11 @@ ['name' => 'board_api#preflighted_cors', 'url' => '/api/v{apiVersion}/{path}','verb' => 'OPTIONS', 'requirements' => ['path' => '.+']], ], 'ocs' => [ + + ['name' => 'new_board#index', 'url' => '/api/v{apiVersion}/boards', 'verb' => 'GET'], + ['name' => 'new_board#read', 'url' => '/api/v{apiVersion}/board/{boardId}', 'verb' => 'GET'], + ['name' => 'new_board#stacks', 'url' => '/api/v{apiVersion}/stacks/{boardId}', 'verb' => 'GET'], + ['name' => 'Config#get', 'url' => '/api/v{apiVersion}/config', 'verb' => 'GET'], ['name' => 'Config#setValue', 'url' => '/api/v{apiVersion}/config/{key}', 'verb' => 'POST'], diff --git a/lib/Controller/BoardController.php b/lib/Controller/BoardController.php index fdcd83c806..be740349be 100644 --- a/lib/Controller/BoardController.php +++ b/lib/Controller/BoardController.php @@ -37,12 +37,7 @@ public function __construct( #[NoAdminRequired] public function index() { - $internalBoards = $this->boardService->findAll(); - $externalBoards = $this->externalBoardService->findAll(); - return [ - 'internal' => $internalBoards, - 'external' => $externalBoards, - ]; + return $this->boardService->findAll(); } #[NoAdminRequired] diff --git a/lib/Controller/NewBoardController.php b/lib/Controller/NewBoardController.php new file mode 100644 index 0000000000..4ff1ab4951 --- /dev/null +++ b/lib/Controller/NewBoardController.php @@ -0,0 +1,61 @@ +boardService->findAll(); + return new DataResponse($internalBoards); + } + + #[NoAdminRequired] + #[PublicPage] + #[NoCSRFRequired] + #[RequestHeader(name: 'x-nextcloud-federation', description: 'Set to 1 when the request is performed by another Nextcloud Server to indicate a federation request', indirect: true)] + public function read(int $boardId): DataResponse { + // Board on this instance -> get it from database + $localBoard = $this->boardService->find($boardId, true, true, $this->request->getParam('accessToken')); + if($localBoard->getExternalId() !== null) { + return $this->externalBoardService->getExternalBoardFromRemote($localBoard); + } + // Board on other instance -> get it from other instance + return new DataResponse($localBoard); + } + + #[NoAdminRequired] + #[PublicPage] + #[NoCSRFRequired] + #[RequestHeader(name: 'x-nextcloud-federation', description: 'Set to 1 when the request is performed by another Nextcloud Server to indicate a federation request', indirect: true)] + public function stacks(int $boardId): DataResponse{ + $localBoard = $this->boardService->find($boardId, true, true, $this->request->getParam('accessToken')); + // Board on other instance -> get it from other instance + if($localBoard->getExternalId() !== null) { + return $this->externalBoardService->getExternalStacksFromRemote($localBoard); + } else { + return new DataResponse($this->stackService->findAll($boardId)); + } + } +} diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php index 3f420feedb..cec7a87ace 100644 --- a/lib/Controller/PageController.php +++ b/lib/Controller/PageController.php @@ -56,8 +56,7 @@ public function index(): TemplateResponse { $this->initialState->provideInitialState('config', $this->configService->getAll()); $this->initialState->provideInitialState('initialBoards', [ - "internal" => $this->boardService->findAll(), - "external" => $this->externalBoardService->findAll(), + $this->boardService->findAll(), ]); $this->eventDispatcher->dispatchTyped(new LoadSidebar()); diff --git a/lib/Db/Acl.php b/lib/Db/Acl.php index 49fd6b4426..04195946b9 100644 --- a/lib/Db/Acl.php +++ b/lib/Db/Acl.php @@ -20,7 +20,7 @@ * @method bool isOwner() * @method void setOwner(int $owner) * @method void setToken(string $token) - * @method string getToken(string $token) + * @method string getToken() * */ class Acl extends RelationalEntity { diff --git a/lib/Db/AclMapper.php b/lib/Db/AclMapper.php index f85d7bf699..bdc1f295ae 100644 --- a/lib/Db/AclMapper.php +++ b/lib/Db/AclMapper.php @@ -24,7 +24,7 @@ public function __construct(IDBConnection $db) { */ public function findAll(int $boardId, ?int $limit = null, ?int $offset = null) { $qb = $this->db->getQueryBuilder(); - $qb->select('id', 'board_id', 'type', 'participant', 'permission_edit', 'permission_share', 'permission_manage') + $qb->select('id', 'board_id', 'type', 'participant', 'permission_edit', 'permission_share', 'permission_manage', 'token') ->from('deck_board_acl') ->where($qb->expr()->eq('board_id', $qb->createNamedParameter($boardId, IQueryBuilder::PARAM_INT))) ->setMaxResults($limit) diff --git a/lib/Db/Board.php b/lib/Db/Board.php index 500eb59b97..1b4018cf7d 100644 --- a/lib/Db/Board.php +++ b/lib/Db/Board.php @@ -24,6 +24,10 @@ * @method void setOwner(string $owner) * @method string getColor() * @method void setColor(string $color) + * @method void setShareToken(string $shareToken) + * @method string getShareToken() + * @method void setExternalId(int $externalId) + * @method int getExternalId() */ class Board extends RelationalEntity { protected $title; @@ -41,6 +45,8 @@ class Board extends RelationalEntity { protected $activeSessions = []; protected $deletedAt = 0; protected $lastModified = 0; + protected $shareToken = null; + protected $externalId = null; protected $settings = []; @@ -50,6 +56,8 @@ public function __construct() { $this->addType('archived', 'boolean'); $this->addType('deletedAt', 'integer'); $this->addType('lastModified', 'integer'); + $this->addType('shareToken', 'string'); + $this->addType('externalId', 'integer'); $this->addRelation('labels'); $this->addRelation('acl'); $this->addRelation('shared'); diff --git a/lib/Db/ExternalBoard.php b/lib/Db/ExternalBoard.php deleted file mode 100644 index 9d63035826..0000000000 --- a/lib/Db/ExternalBoard.php +++ /dev/null @@ -1,32 +0,0 @@ -AddType('id', 'integer'); - $this->addType('title', 'string'); - $this->addType('externalId', 'string'); - $this->addType('owner', 'string'); - $this->addResolvable('participant'); - } -} diff --git a/lib/Db/ExternalBoardMapper.php b/lib/Db/ExternalBoardMapper.php deleted file mode 100644 index d7df1dbdb6..0000000000 --- a/lib/Db/ExternalBoardMapper.php +++ /dev/null @@ -1,25 +0,0 @@ - */ -class ExternalBoardMapper extends QBMapper{ - public function __construct( - IDBConnection $db, - ) { - parent::__construct($db, 'deck_boards_external', ExternalBoard::class); - } - - public function findAllForUser(string $userId) { - $qb = $this->db->getQueryBuilder(); - $qb->select('*') - ->from('deck_boards_external') - ->where($qb->expr()->eq('participant', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR))) - ->orderBy('id'); - return $this->findEntities($qb); - } -} diff --git a/lib/Federation/DeckFederationProvider.php b/lib/Federation/DeckFederationProvider.php index d8042fbb39..a89a3ee3a8 100644 --- a/lib/Federation/DeckFederationProvider.php +++ b/lib/Federation/DeckFederationProvider.php @@ -1,8 +1,11 @@ notificationManager->notify($notification); - $externalBoard = new ExternalBoard(); + $externalBoard = new Board(); $externalBoard->setTitle($share->getResourceName()); $externalBoard->setExternalId($share->getProviderId()); $externalBoard->setOwner($share->getSharedBy()); - $externalBoard->setParticipant($share->getShareWith()); - $this->externalBoardMapper->insert($externalBoard); + $externalBoard->setShareToken($share->getShareSecret()); + $insertedBoard = $this->boardMapper->insert($externalBoard); + + $acl = new Acl(); + $acl->setBoardId($insertedBoard->getId()); + $acl->setType(Acl::PERMISSION_TYPE_USER); + $acl->setParticipant($share->getShareWith()); + $acl->setPermissionEdit(false); + $acl->setPermissionShare(false); + $acl->setPermissionManage(false); + $this->aclMapper->insert($acl); + + $this->changeHelper->boardChanged($insertedBoard->getId()); return 'PLACE_HOLDER_ID'; } diff --git a/lib/Federation/DeckFederationProxy.php b/lib/Federation/DeckFederationProxy.php new file mode 100644 index 0000000000..74afb9f48b --- /dev/null +++ b/lib/Federation/DeckFederationProxy.php @@ -0,0 +1,140 @@ + !$this->config->getSystemValueBool('sharing.federation.allowSelfSignedCertificates'), + 'nextcloud' => [ + 'allow_local_address' => $this->config->getSystemValueBool('allow_local_remote_servers'), + ], + 'headers' => [ + 'Accept' => 'application/json', + 'X-Nextcloud-Federation' => 'true', + 'OCS-APIRequest' => 'true', + 'Accept-Language' => $this->l10nFactory->getUserLanguage($this->userSession->getUser()), + ], + 'cookies' => CookieJar::fromArray([ + 'XDEBUG_SESSION' => 'PHPSTORM' + ], 'nextcloud2.local'), + 'timeout' => 5, + ]; + + if ($cloudId !== null && $accessToken !== null) { + $options['auth'] = [urlencode($cloudId), $accessToken]; + } + + return $options; + } + + protected function prependProtocolIfNotAvailable(string $url): string { + if (!str_starts_with($url, 'http://') && !str_starts_with($url, 'https://')) { + $url = 'https://' . $url; + } + return $url; + } + + /** + * @param 'get'|'post'|'put'|'delete' $verb + * @throws \Exception + */ + protected function request( + string $verb, + ?string $cloudId, + #[SensitiveParameter] + ?string $accessToken, + string $url, + array $parameters, + ): IResponse { + $requestOptions = $this->generateDefaultRequestOptions($cloudId, $accessToken); + if (!empty($parameters)) { + $requestOptions['json'] = $parameters; + } + + try { + return $this->clientService->newClient()->{$verb}( + $this->prependProtocolIfNotAvailable($url), + $requestOptions + ); + } catch (ClientException $e) { + $status = $e->getResponse()->getStatusCode(); + + try { + $body = $e->getResponse()->getBody()->getContents(); + $data = json_decode($body, true, flags: JSON_THROW_ON_ERROR); + $e->getResponse()->getBody()->rewind(); + if (!is_array($data)) { + throw new \RuntimeException('JSON response is not an array'); + } + } catch (\Throwable $e) { + throw new \Exception('Error parsing JSON response', $e->getCode(), $e); + } + + $clientException = new \Exception($e->getMessage(), $status, $e); + $this->logger->debug('Client error from remote', ['exception' => $clientException]); + return new Response($e->getResponse(), false); + } catch (ServerException|\Throwable $e) { + $serverException = new \Exception($e->getMessage(), $e->getCode(), $e); + $this->logger->error('Could not reach remote', ['exception' => $serverException]); + throw $serverException; + } + } + + public function get(string $cloudId, string $shareToken, string $url, array $params = []):IResponse { + return $this->request("get", $cloudId, $shareToken, $url, $params); + } + public function getOCSData(IResponse $response, array $allowedStatusCodes = [Http::STATUS_OK]): array { + if (!in_array($response->getStatusCode(), $allowedStatusCodes, true)) { + $this->logUnexpectedStatusCode(__METHOD__, $response->getStatusCode()); + } + + try { + $content = $response->getBody(); + $responseData = json_decode($content, true, flags: JSON_THROW_ON_ERROR); + if (!is_array($responseData)) { + throw new \RuntimeException('JSON response is not an array'); + } + } catch (\Throwable $e) { + $this->logger->error('Error parsing JSON response: ' . ($content ?? 'no-data'), ['exception' => $e]); + throw new CannotReachRemoteException('Error parsing JSON response', $e->getCode(), $e); + } + + return $responseData['ocs']['data'] ?? []; + } + + /** + * @return Http::STATUS_BAD_REQUEST + */ + public function logUnexpectedStatusCode(string $method, int $statusCode, string $logDetails = ''): int { + if ($this->config->getSystemValueBool('debug')) { + $this->logger->error('Unexpected status code ' . $statusCode . ' returned for ' . $method . ($logDetails !== '' ? "\n" . $logDetails : '')); + } else { + $this->logger->debug('Unexpected status code ' . $statusCode . ' returned for ' . $method . ($logDetails !== '' ? "\n" . $logDetails : '')); + } + return Http::STATUS_BAD_REQUEST; + } +} diff --git a/lib/Migration/Version11001Date20251016122010.php b/lib/Migration/Version11001Date20251016122010.php new file mode 100644 index 0000000000..c189ee5198 --- /dev/null +++ b/lib/Migration/Version11001Date20251016122010.php @@ -0,0 +1,24 @@ +hasTable($tableName)) { + $table = $schema->getTable('deck_boards_external'); + $table->addColumn('share_token', 'string', [ + 'notnull' => true, + 'length' => 32, + ]); + } + return $schema; + } +} diff --git a/lib/Migration/Version11001Date20251020122010.php b/lib/Migration/Version11001Date20251020122010.php new file mode 100644 index 0000000000..11458d0bcf --- /dev/null +++ b/lib/Migration/Version11001Date20251020122010.php @@ -0,0 +1,29 @@ +hasTable($tableName) && $schema->hasTable('deck_boards')) { + $schema->dropTable($tableName); + $table = $schema->getTable('deck_boards'); + $table->addColumn('share_token', 'string', [ + 'notnull' => false, + 'length' => 32, + ]); + $table->addColumn('external_id', 'integer', [ + 'notnull' => false, + 'length' => 4, + ]); + } + return $schema; + } +} diff --git a/lib/Service/BoardService.php b/lib/Service/BoardService.php index 04327cfb6e..bbc862c22b 100644 --- a/lib/Service/BoardService.php +++ b/lib/Service/BoardService.php @@ -115,7 +115,7 @@ public function findAll(int $since = -1, bool $fullDetails = false, bool $includ * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException * @throws BadRequestException */ - public function find(int $boardId, bool $fullDetails = true, bool $allowDeleted = false): Board { + public function find(int $boardId, bool $fullDetails = true, bool $allowDeleted = false, $accessToken = null): Board { $this->boardServiceValidator->check(compact('boardId')); if (isset($this->boardsCacheFull[$boardId]) && $fullDetails) { @@ -126,9 +126,9 @@ public function find(int $boardId, bool $fullDetails = true, bool $allowDeleted return $this->boardsCachePartial[$boardId]; } - $this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ); + $this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ, null, false, $accessToken); $board = $this->boardMapper->find($boardId, true, true, $allowDeleted); - [$board] = $this->enrichBoards([$board], $fullDetails); + [$board] = $this->enrichBoards([$board], $fullDetails, $accessToken); return $board; } @@ -644,7 +644,7 @@ public function export(int $id): Board { * @param Board[] $boards * @return Board[] */ - private function enrichBoards(array $boards, bool $fullDetails = true): array { + private function enrichBoards(array $boards, bool $fullDetails = true, $accessToken = null): array { $result = []; foreach ($boards as $board) { // FIXME The enrichment in here could make use of combined queries @@ -655,7 +655,7 @@ private function enrichBoards(array $boards, bool $fullDetails = true): array { } } - $permissions = $this->permissionService->matchPermissions($board); + $permissions = $this->permissionService->matchPermissions($board, $accessToken); $board->setPermissions([ 'PERMISSION_READ' => $permissions[Acl::PERMISSION_READ] ?? false, 'PERMISSION_EDIT' => $permissions[Acl::PERMISSION_EDIT] ?? false, diff --git a/lib/Service/ExternalBoardService.php b/lib/Service/ExternalBoardService.php index 2f71faf5b8..4d41ea8d60 100644 --- a/lib/Service/ExternalBoardService.php +++ b/lib/Service/ExternalBoardService.php @@ -1,18 +1,36 @@ externalBoardMapper->findAllForUser($this->userId); + public function getExternalBoardFromRemote(Board $localBoard):DataResponse { + $shareToken = $localBoard->getShareToken(); + $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); + $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); + $url = $ownerCloudId->getRemote() . "/ocs/v2.php/apps/deck/api/v1.0/board/".$localBoard->getExternalId()."?accessToken=".urlencode($shareToken); + $resp = $this->proxy->get($participantCloudId->getId(), $shareToken, $url); + return new DataResponse($this->proxy->getOcsData($resp)); + } + public function getExternalStacksFromRemote(Board $localBoard):DataResponse { + $shareToken = $localBoard->getShareToken(); + $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); + $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); + $url = $ownerCloudId->getRemote() . "/ocs/v2.php/apps/deck/api/v1.0/stacks/".$localBoard->getExternalId()."?accessToken=".urlencode($shareToken); + $resp = $this->proxy->get($participantCloudId->getId(), $shareToken, $url); + return new DataResponse($this->proxy->getOcsData($resp)); } } diff --git a/lib/Service/PermissionService.php b/lib/Service/PermissionService.php index 775e7e048f..53f4dade34 100644 --- a/lib/Service/PermissionService.php +++ b/lib/Service/PermissionService.php @@ -54,8 +54,8 @@ public function __construct( * * @return array */ - public function getPermissions(int $boardId, ?string $userId = null, bool $allowDeleted = false): array { - if ($userId === null) { + public function getPermissions(int $boardId, ?string $userId = null, bool $allowDeleted = false, ?string $accessToken = null): array { + if ($userId === null && $accessToken === null) { $userId = $this->userId; } @@ -73,14 +73,23 @@ public function getPermissions(int $boardId, ?string $userId = null, bool $allow $owner = false; $acls = []; } - - $permissions = [ - Acl::PERMISSION_READ => $owner || $this->userCan($acls, Acl::PERMISSION_READ, $userId), - Acl::PERMISSION_EDIT => $owner || $this->userCan($acls, Acl::PERMISSION_EDIT, $userId), - Acl::PERMISSION_MANAGE => $owner || $this->userCan($acls, Acl::PERMISSION_MANAGE, $userId), - Acl::PERMISSION_SHARE => ($owner || $this->userCan($acls, Acl::PERMISSION_SHARE, $userId)) - && (!$this->shareManager->sharingDisabledForUser($userId)) + $permissions = []; + if ($userId !== null) { + $permissions = [ + Acl::PERMISSION_READ => $owner || $this->userCan($acls, Acl::PERMISSION_READ, $userId), + Acl::PERMISSION_EDIT => $owner || $this->userCan($acls, Acl::PERMISSION_EDIT, $userId), + Acl::PERMISSION_MANAGE => $owner || $this->userCan($acls, Acl::PERMISSION_MANAGE, $userId), + Acl::PERMISSION_SHARE => ($owner || $this->userCan($acls, Acl::PERMISSION_SHARE, $userId)) + && (!$this->shareManager->sharingDisabledForUser($userId)) + ]; + } else if ($accessToken !== null ) { + $permissions = [ + Acl::PERMISSION_READ => $owner || $this->externalUserCan($acls, Acl::PERMISSION_READ, $accessToken), + Acl::PERMISSION_EDIT => $owner || $this->externalUserCan($acls, Acl::PERMISSION_EDIT, $accessToken), + Acl::PERMISSION_MANAGE => $owner || $this->externalUserCan($acls, Acl::PERMISSION_MANAGE, $accessToken), + Acl::PERMISSION_SHARE => ($owner || $this->externalUserCan($acls, Acl::PERMISSION_SHARE, $accessToken)) ]; + } $this->permissionCache->set($cacheKey, $permissions); return $permissions; } @@ -92,9 +101,17 @@ public function getPermissions(int $boardId, ?string $userId = null, bool $allow * @return array|bool * @internal param $boardId */ - public function matchPermissions(Board $board) { + public function matchPermissions(Board $board, $accessToken = null) { $owner = $this->userIsBoardOwner($board->getId()); $acls = $board->getAcl() ?? []; + if ($accessToken !== null) { + return [ + Acl::PERMISSION_READ => $owner || $this->externalUserCan($acls, Acl::PERMISSION_READ, $accessToken), + Acl::PERMISSION_EDIT => $owner || $this->externalUserCan($acls, Acl::PERMISSION_EDIT, $accessToken), + Acl::PERMISSION_MANAGE => $owner || $this->externalUserCan($acls, Acl::PERMISSION_MANAGE, $accessToken), + Acl::PERMISSION_SHARE => ($owner || $this->externalUserCan($acls, Acl::PERMISSION_SHARE, $accessToken)) + ]; + } return [ Acl::PERMISSION_READ => $owner || $this->userCan($acls, Acl::PERMISSION_READ), Acl::PERMISSION_EDIT => $owner || $this->userCan($acls, Acl::PERMISSION_EDIT), @@ -109,7 +126,7 @@ public function matchPermissions(Board $board) { * * @throws NoPermissionException */ - public function checkPermission(?IPermissionMapper $mapper, $id, int $permission, $userId = null, bool $allowDeletedCard = false, bool $allowDeletedBoard = false): bool { + public function checkPermission(?IPermissionMapper $mapper, $id, int $permission, $userId = null, bool $allowDeletedCard = false, bool $allowDeletedBoard = false, $accessToken = null): bool { $boardId = (int)$id; if ($mapper instanceof IPermissionMapper && !($mapper instanceof BoardMapper)) { $boardId = $mapper->findBoardId($id); @@ -119,7 +136,7 @@ public function checkPermission(?IPermissionMapper $mapper, $id, int $permission throw new NoPermissionException('Permission denied'); } - $permissions = $this->getPermissions($boardId, $userId, $allowDeletedBoard); + $permissions = $this->getPermissions($boardId, $userId, $allowDeletedBoard, $accessToken); if ($permissions[$permission] === true) { if (!$allowDeletedCard && $mapper instanceof CardMapper) { @@ -167,6 +184,18 @@ private function getBoard(int $boardId, bool $allowDeleted = false): Board { return $this->boardCache[(string)$boardId]; } + + public function externalUserCan(array $acls, $permission, $shareToken = null) { + foreach($acls as $acl) { + if ($acl->getType() === Acl::PERMISSION_TYPE_REMOTE) { + $token = $acl->getToken(); + if ($acl->getToken() === $shareToken) { + return $acl->getPermission($permission); + } + } + } + } + /** * Check if permission matches the acl rules for current user and groups * diff --git a/src/components/navigation/AppNavigation.vue b/src/components/navigation/AppNavigation.vue index c66ece2eec..b1d06e4837 100644 --- a/src/components/navigation/AppNavigation.vue +++ b/src/components/navigation/AppNavigation.vue @@ -43,15 +43,6 @@ - - - @@ -136,11 +127,6 @@ export default { 'archivedBoards', 'sharedBoards', ]), - ...mapState({ - externalBoards: state => { - return state.externalBoards - }, - }), isAdmin() { return !!getCurrentUser()?.isAdmin }, diff --git a/src/components/navigation/AppNavigationBoard.vue b/src/components/navigation/AppNavigationBoard.vue index 515c40288b..b8c462cbae 100644 --- a/src/components/navigation/AppNavigationBoard.vue +++ b/src/components/navigation/AppNavigationBoard.vue @@ -22,9 +22,9 @@ @close="onCloseExportBoard" /> - + - @@ -255,6 +255,9 @@ export default { canLeave() { return this.board.acl?.find((acl) => acl.participant.uid === this.currentUser?.uid && acl.participant.type === 0) !== undefined }, + canLeave() { + return this.board.acl?.find((acl) => acl.participant.uid === this.currentUser?.uid && acl.participant.type === 0) !== undefined + }, dueDateReminderIcon() { if (this.board.settings['notify-due'] === 'all') { return 'icon-sound' diff --git a/src/services/BoardApi.js b/src/services/BoardApi.js index b09ccfbf70..02313fdf7a 100644 --- a/src/services/BoardApi.js +++ b/src/services/BoardApi.js @@ -4,7 +4,7 @@ */ import axios from '@nextcloud/axios' -import { generateUrl } from '@nextcloud/router' +import { generateOcsUrl, generateUrl } from '@nextcloud/router' import '../models/index.js' /** @@ -17,6 +17,11 @@ export class BoardApi { return generateUrl(url) } + ocsUrl(url) { + url = `/apps/deck/api/v1.0${url}` + return generateOcsUrl(url) + } + /** * Updates a board. * @@ -124,10 +129,10 @@ export class BoardApi { } loadById(id) { - return axios.get(this.url(`/boards/${id}`)) + return axios.get(this.ocsUrl(`/board/${id}`)) .then( (response) => { - return Promise.resolve(response.data) + return Promise.resolve(response.data.ocs.data) }, (err) => { return Promise.reject(err) diff --git a/src/services/StackApi.js b/src/services/StackApi.js index 8904743458..977a0445b3 100644 --- a/src/services/StackApi.js +++ b/src/services/StackApi.js @@ -4,7 +4,7 @@ */ import axios from '@nextcloud/axios' -import { generateUrl } from '@nextcloud/router' +import { generateOcsUrl, generateUrl } from '@nextcloud/router' import '../models/index.js' export class StackApi { @@ -13,12 +13,16 @@ export class StackApi { url = `/apps/deck${url}` return generateUrl(url) } + ocsUrl(url) { + url = `/apps/deck/api/v1.0${url}` + return generateOcsUrl(url) + } loadStacks(boardId) { - return axios.get(this.url(`/stacks/${boardId}`)) + return axios.get(this.ocsUrl(`/stacks/${boardId}`)) .then( (response) => { - return Promise.resolve(response.data) + return Promise.resolve(response.data.ocs.data) }, (err) => { return Promise.reject(err) diff --git a/src/store/main.js b/src/store/main.js index e30a74ae1c..9e04cd86c7 100644 --- a/src/store/main.js +++ b/src/store/main.js @@ -52,8 +52,7 @@ export default function storeFactory() { currentBoard: null, currentCard: null, hasCardSaveError: false, - boards: loadState('deck', 'initialBoards', {internal:[]}).internal, - externalBoards: loadState('deck', 'initialBoards', {external:[]}).external, + boards: loadState('deck', 'initialBoards', {}), sharees: [], assignableUsers: [], boardFilter: BOARD_FILTERS.ALL, @@ -416,31 +415,31 @@ export default function storeFactory() { async cloneBoard({ commit }, { boardData, settings }) { const { withCards, withAssignments, withLabels, withDueDate, moveCardsToLeftStack, restoreArchivedCards } = settings - try { - const newBoard = await apiClient.cloneBoard(boardData, withCards, withAssignments, withLabels, withDueDate, moveCardsToLeftStack, restoreArchivedCards) - commit('cloneBoard', newBoard) - return newBoard - } catch (err) { - return err - } - }, - removeBoard({ commit }, board) { - commit('removeBoard', board) - }, - async loadBoards({ commit }) { - const boards = await apiClient.loadBoards() - commit('setBoards', boards.internal) - }, - async loadSharees({ commit }, query) { - const params = new URLSearchParams() - if (typeof query === 'undefined') { - return - } - params.append('search', query) - params.append('format', 'json') - params.append('perPage', 20) - params.append('itemType', 'deck') - params.append('lookup', false) + try { + const newBoard = await apiClient.cloneBoard(boardData, withCards, withAssignments, withLabels, withDueDate, moveCardsToLeftStack, restoreArchivedCards) + commit('cloneBoard', newBoard) + return newBoard + } catch (err) { + return err + } + }, + removeBoard({ commit }, board) { + commit('removeBoard', board) + }, + async loadBoards({ commit }) { + const boards = await apiClient.loadBoards() + commit('setBoards', boards) + }, + async loadSharees({ commit }, query) { + const params = new URLSearchParams() + if (typeof query === 'undefined') { + return + } + params.append('search', query) + params.append('format', 'json') + params.append('perPage', 20) + params.append('itemType', 'deck') + params.append('lookup', false) const response = await axios.get(generateOcsUrl('apps/files_sharing/api/v1/sharees'), { params }) commit('setSharees', response.data.ocs.data) From 972c797f5bf00831df43bb5dbeb591b12d981888 Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Thu, 30 Oct 2025 10:29:00 +0100 Subject: [PATCH 04/24] feat: federated card creation feat: set accessToken from FederationMiddleware Signed-off-by: grnd-alt --- appinfo/routes.php | 3 +- lib/AppInfo/Application.php | 2 + lib/Controller/NewCardController.php | 56 +++++++++++++++ lib/Federation/DeckFederationProvider.php | 2 +- lib/Federation/DeckFederationProxy.php | 29 ++++---- lib/Middleware/FederationMiddleware.php | 23 +++++++ .../Version11001Date20251014122010.php | 42 ------------ .../Version11001Date20251016122010.php | 24 ------- .../Version11001Date20251020122010.php | 4 +- lib/Service/BoardService.php | 10 +-- lib/Service/CardService.php | 2 +- lib/Service/ExternalBoardService.php | 35 +++++++++- lib/Service/PermissionService.php | 68 +++++++++++-------- 13 files changed, 180 insertions(+), 120 deletions(-) create mode 100644 lib/Controller/NewCardController.php create mode 100644 lib/Middleware/FederationMiddleware.php delete mode 100644 lib/Migration/Version11001Date20251014122010.php delete mode 100644 lib/Migration/Version11001Date20251016122010.php diff --git a/appinfo/routes.php b/appinfo/routes.php index aef09b3347..0e303bf093 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -133,11 +133,12 @@ ['name' => 'board_api#preflighted_cors', 'url' => '/api/v{apiVersion}/{path}','verb' => 'OPTIONS', 'requirements' => ['path' => '.+']], ], 'ocs' => [ - ['name' => 'new_board#index', 'url' => '/api/v{apiVersion}/boards', 'verb' => 'GET'], ['name' => 'new_board#read', 'url' => '/api/v{apiVersion}/board/{boardId}', 'verb' => 'GET'], ['name' => 'new_board#stacks', 'url' => '/api/v{apiVersion}/stacks/{boardId}', 'verb' => 'GET'], + ['name' => 'new_card#create', 'url' => '/api/v{apiVersion}/cards', 'verb' => 'POST'], + ['name' => 'Config#get', 'url' => '/api/v{apiVersion}/config', 'verb' => 'GET'], ['name' => 'Config#setValue', 'url' => '/api/v{apiVersion}/config/{key}', 'verb' => 'POST'], diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index dae73e7339..245f0878a5 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -38,6 +38,7 @@ use OCA\Deck\Listeners\ResourceListener; use OCA\Deck\Middleware\DefaultBoardMiddleware; use OCA\Deck\Middleware\ExceptionMiddleware; +use OCA\Deck\Middleware\FederationMiddleware; use OCA\Deck\Notification\Notifier; use OCA\Deck\Reference\BoardReferenceProvider; use OCA\Deck\Reference\CardReferenceProvider; @@ -114,6 +115,7 @@ public function register(IRegistrationContext $context): void { } $context->registerCapability(Capabilities::class); + $context->registerMiddleWare(FederationMiddleware::class); $context->registerMiddleWare(ExceptionMiddleware::class); $context->registerMiddleWare(DefaultBoardMiddleware::class); diff --git a/lib/Controller/NewCardController.php b/lib/Controller/NewCardController.php new file mode 100644 index 0000000000..66f28473d3 --- /dev/null +++ b/lib/Controller/NewCardController.php @@ -0,0 +1,56 @@ +boardService->find($boardId, false); + if ($board->getExternalId()) { + $card = $this->externalBoardService->createCardOnRemote($board, $title, $stackId, $type, $order, $description, $duedate, $users); + return new DataResponse($card); + } + } + $card = $this->cardService->create($title, $stackId, $type, $order, $owner, $description, $duedate); + + // foreach ($labels as $label) { + // $this->assignLabel($card->getId(), $label); + // } + + // foreach ($users as $user) { + // $this->assignmentService->assignUser($card->getId(), $user['id'], $user['type']); + // } + + return new DataResponse($card); + } + +} diff --git a/lib/Federation/DeckFederationProvider.php b/lib/Federation/DeckFederationProvider.php index a89a3ee3a8..e38eee4db8 100644 --- a/lib/Federation/DeckFederationProvider.php +++ b/lib/Federation/DeckFederationProvider.php @@ -49,7 +49,7 @@ public function shareReceived(ICloudFederationShare $share): string { $acl->setBoardId($insertedBoard->getId()); $acl->setType(Acl::PERMISSION_TYPE_USER); $acl->setParticipant($share->getShareWith()); - $acl->setPermissionEdit(false); + $acl->setPermissionEdit(true); $acl->setPermissionShare(false); $acl->setPermissionManage(false); $this->aclMapper->insert($acl); diff --git a/lib/Federation/DeckFederationProxy.php b/lib/Federation/DeckFederationProxy.php index 74afb9f48b..1d80bc9b57 100644 --- a/lib/Federation/DeckFederationProxy.php +++ b/lib/Federation/DeckFederationProxy.php @@ -28,24 +28,22 @@ protected function generateDefaultRequestOptions( ?string $accessToken, ): array { $options = [ - 'verify' => !$this->config->getSystemValueBool('sharing.federation.allowSelfSignedCertificates'), - 'nextcloud' => [ - 'allow_local_address' => $this->config->getSystemValueBool('allow_local_remote_servers'), - ], - 'headers' => [ - 'Accept' => 'application/json', - 'X-Nextcloud-Federation' => 'true', - 'OCS-APIRequest' => 'true', - 'Accept-Language' => $this->l10nFactory->getUserLanguage($this->userSession->getUser()), - ], - 'cookies' => CookieJar::fromArray([ - 'XDEBUG_SESSION' => 'PHPSTORM' - ], 'nextcloud2.local'), + 'verify' => !$this->config->getSystemValueBool('sharing.federation.allowSelfSignedCertificates'), + 'nextcloud' => [ + 'allow_local_address' => $this->config->getSystemValueBool('allow_local_remote_servers'), + ], + 'headers' => [ + 'Cookie' => 'XDEBUG_SESSION=PHPSTORM', + 'Accept' => 'application/json', + 'x-nextcloud-federation' => 'true', + 'OCS-APIRequest' => 'true', + 'Accept-Language' => $this->l10nFactory->getUserLanguage($this->userSession->getUser()), + 'deck-federation-accesstoken' => $accessToken, + ], 'timeout' => 5, ]; if ($cloudId !== null && $accessToken !== null) { - $options['auth'] = [urlencode($cloudId), $accessToken]; } return $options; @@ -107,6 +105,9 @@ protected function request( public function get(string $cloudId, string $shareToken, string $url, array $params = []):IResponse { return $this->request("get", $cloudId, $shareToken, $url, $params); } + public function post(string $cloudId, string $shareToken, string $url, array $params = []):IResponse { + return $this->request("post", $cloudId, $shareToken, $url, $params); + } public function getOCSData(IResponse $response, array $allowedStatusCodes = [Http::STATUS_OK]): array { if (!in_array($response->getStatusCode(), $allowedStatusCodes, true)) { $this->logUnexpectedStatusCode(__METHOD__, $response->getStatusCode()); diff --git a/lib/Middleware/FederationMiddleware.php b/lib/Middleware/FederationMiddleware.php new file mode 100644 index 0000000000..2a7bf4855b --- /dev/null +++ b/lib/Middleware/FederationMiddleware.php @@ -0,0 +1,23 @@ +request->getHeader('deck-federation-accesstoken'); + if ($accessToken) { + $this->permissionService->setAccessToken($accessToken); + } + } +} diff --git a/lib/Migration/Version11001Date20251014122010.php b/lib/Migration/Version11001Date20251014122010.php deleted file mode 100644 index 62e3c41cb0..0000000000 --- a/lib/Migration/Version11001Date20251014122010.php +++ /dev/null @@ -1,42 +0,0 @@ -hasTable($tableName)) { - $table = $schema->createTable($tableName); - $table->addColumn('id', 'integer', [ - 'autoincrement' => true, - 'notnull' => true, - 'length' => 4, - ]); - $table->addColumn('external_id', 'integer', [ - 'notnull' => true, - 'length' => 4, - ]); - $table->addColumn('title', 'string', [ - 'notnull' => true, - 'length' => 100, - ]); - $table->addColumn('owner', 'string', [ - 'notnull' => true, - 'length' => 64, - ]); - $table->addColumn('participant', 'string', [ - 'notnull' => true, - 'length' => 64, - ]); - $table->setPrimaryKey(['id']); - } - return $schema; - } -} diff --git a/lib/Migration/Version11001Date20251016122010.php b/lib/Migration/Version11001Date20251016122010.php deleted file mode 100644 index c189ee5198..0000000000 --- a/lib/Migration/Version11001Date20251016122010.php +++ /dev/null @@ -1,24 +0,0 @@ -hasTable($tableName)) { - $table = $schema->getTable('deck_boards_external'); - $table->addColumn('share_token', 'string', [ - 'notnull' => true, - 'length' => 32, - ]); - } - return $schema; - } -} diff --git a/lib/Migration/Version11001Date20251020122010.php b/lib/Migration/Version11001Date20251020122010.php index 11458d0bcf..d4cbe9d20b 100644 --- a/lib/Migration/Version11001Date20251020122010.php +++ b/lib/Migration/Version11001Date20251020122010.php @@ -11,9 +11,7 @@ class Version11001Date20251020122010 extends SimpleMigrationStep { public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) { $schema = $schemaClosure(); - $tableName = 'deck_boards_external'; - if ($schema->hasTable($tableName) && $schema->hasTable('deck_boards')) { - $schema->dropTable($tableName); + if ($schema->hasTable('deck_boards')) { $table = $schema->getTable('deck_boards'); $table->addColumn('share_token', 'string', [ 'notnull' => false, diff --git a/lib/Service/BoardService.php b/lib/Service/BoardService.php index bbc862c22b..7aaf6bdac3 100644 --- a/lib/Service/BoardService.php +++ b/lib/Service/BoardService.php @@ -115,7 +115,7 @@ public function findAll(int $since = -1, bool $fullDetails = false, bool $includ * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException * @throws BadRequestException */ - public function find(int $boardId, bool $fullDetails = true, bool $allowDeleted = false, $accessToken = null): Board { + public function find(int $boardId, bool $fullDetails = true, bool $allowDeleted = false): Board { $this->boardServiceValidator->check(compact('boardId')); if (isset($this->boardsCacheFull[$boardId]) && $fullDetails) { @@ -126,9 +126,9 @@ public function find(int $boardId, bool $fullDetails = true, bool $allowDeleted return $this->boardsCachePartial[$boardId]; } - $this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ, null, false, $accessToken); + $this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ, null, false); $board = $this->boardMapper->find($boardId, true, true, $allowDeleted); - [$board] = $this->enrichBoards([$board], $fullDetails, $accessToken); + [$board] = $this->enrichBoards([$board], $fullDetails); return $board; } @@ -644,7 +644,7 @@ public function export(int $id): Board { * @param Board[] $boards * @return Board[] */ - private function enrichBoards(array $boards, bool $fullDetails = true, $accessToken = null): array { + private function enrichBoards(array $boards, bool $fullDetails = true): array { $result = []; foreach ($boards as $board) { // FIXME The enrichment in here could make use of combined queries @@ -655,7 +655,7 @@ private function enrichBoards(array $boards, bool $fullDetails = true, $accessTo } } - $permissions = $this->permissionService->matchPermissions($board, $accessToken); + $permissions = $this->permissionService->matchPermissions($board); $board->setPermissions([ 'PERMISSION_READ' => $permissions[Acl::PERMISSION_READ] ?? false, 'PERMISSION_EDIT' => $permissions[Acl::PERMISSION_EDIT] ?? false, diff --git a/lib/Service/CardService.php b/lib/Service/CardService.php index d8ca9adc00..3b9f97d42b 100644 --- a/lib/Service/CardService.php +++ b/lib/Service/CardService.php @@ -193,7 +193,7 @@ public function create(string $title, int $stackId, string $type, int $order, st $card->setDuedate($duedate); $card = $this->cardMapper->insert($card); - $this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $card, ActivityManager::SUBJECT_CARD_CREATE); + $this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $card, ActivityManager::SUBJECT_CARD_CREATE, [], $card->getOwner()); $this->changeHelper->cardChanged($card->getId(), false); $this->eventDispatcher->dispatchTyped(new CardCreatedEvent($card)); diff --git a/lib/Service/ExternalBoardService.php b/lib/Service/ExternalBoardService.php index 4d41ea8d60..ee8757e54e 100644 --- a/lib/Service/ExternalBoardService.php +++ b/lib/Service/ExternalBoardService.php @@ -4,6 +4,7 @@ use OCP\AppFramework\Http\DataResponse; use OCA\Deck\Db\Board; +use OCA\Deck\Db\Card; use OCA\Deck\Federation\DeckFederationProxy; use OCP\Federation\ICloudIdManager; use OCP\IUserManager; @@ -21,7 +22,7 @@ public function getExternalBoardFromRemote(Board $localBoard):DataResponse { $shareToken = $localBoard->getShareToken(); $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); - $url = $ownerCloudId->getRemote() . "/ocs/v2.php/apps/deck/api/v1.0/board/".$localBoard->getExternalId()."?accessToken=".urlencode($shareToken); + $url = $ownerCloudId->getRemote() . "/ocs/v2.php/apps/deck/api/v1.0/board/".$localBoard->getExternalId(); $resp = $this->proxy->get($participantCloudId->getId(), $shareToken, $url); return new DataResponse($this->proxy->getOcsData($resp)); } @@ -29,8 +30,38 @@ public function getExternalStacksFromRemote(Board $localBoard):DataResponse { $shareToken = $localBoard->getShareToken(); $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); - $url = $ownerCloudId->getRemote() . "/ocs/v2.php/apps/deck/api/v1.0/stacks/".$localBoard->getExternalId()."?accessToken=".urlencode($shareToken); + $url = $ownerCloudId->getRemote() . "/ocs/v2.php/apps/deck/api/v1.0/stacks/".$localBoard->getExternalId(); $resp = $this->proxy->get($participantCloudId->getId(), $shareToken, $url); return new DataResponse($this->proxy->getOcsData($resp)); } + + public function createCardOnRemote( + Board $localBoard, + string $title, + int $stackId, + ?string $type = 'plain', + ?int $order = 999, + ?string $description = '', + $duedate = null, + ?array $users = [], + ?int $boardId = null + ): array { + $shareToken = $localBoard->getShareToken(); + $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); + $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); + $url = $ownerCloudId->getRemote() . "/ocs/v2.php/apps/deck/api/v1.0/cards"; + $params = [ + 'title' => $title, + 'stackId' => $stackId, + 'type' => $type, + 'order' => $order, + 'owner' => $participantCloudId->getId(), + 'description' => $description, + 'duedate' => $duedate, + 'users' => $users, + 'boardId' => $localBoard->getExternalId(), + ]; + $resp = $this->proxy->post($participantCloudId->getId(), $shareToken, $url, $params); + return $this->proxy->getOcsData($resp); + } } diff --git a/lib/Service/PermissionService.php b/lib/Service/PermissionService.php index 53f4dade34..a58c055de8 100644 --- a/lib/Service/PermissionService.php +++ b/lib/Service/PermissionService.php @@ -30,6 +30,9 @@ class PermissionService { /** @var array> */ private $users = []; + // accessToken to check permission for federated shares + private ?string $accessToken = null; + private CappedMemoryCache $boardCache; /** @var CappedMemoryCache> */ private CappedMemoryCache $permissionCache; @@ -49,6 +52,13 @@ public function __construct( $this->permissionCache = new CappedMemoryCache(); } + /** + * Set AccessToken for requests from federation shares + */ + public function setAccessToken(string $token) { + $this->accessToken = $token; + } + /** * Get current user permissions for a board by id * @@ -59,37 +69,41 @@ public function getPermissions(int $boardId, ?string $userId = null, bool $allow $userId = $this->userId; } - $cacheKey = $boardId . '-' . $userId; - if ($cached = $this->permissionCache->get($cacheKey)) { - /** @var array $cached */ - return $cached; + // check chache if not a federated request + if ($this->accessToken === null) { + $cacheKey = $boardId . '-' . $userId; + if ($cached = $this->permissionCache->get($cacheKey)) { + /** @var array $cached */ + return $cached; + } + } + $board = $this->getBoard($boardId, $allowDeleted); + if ($this->accessToken !== null) { + $acls = $board->getDeletedAt() === 0 ? $this->aclMapper->findAll($boardId) : []; + $permissions = [ + Acl::PERMISSION_READ => $this->externalUserCan($acls, Acl::PERMISSION_READ, $this->accessToken), + Acl::PERMISSION_EDIT => $this->externalUserCan($acls, Acl::PERMISSION_EDIT, $this->accessToken), + Acl::PERMISSION_MANAGE => $this->externalUserCan($acls, Acl::PERMISSION_MANAGE, $this->accessToken), + Acl::PERMISSION_SHARE => $this->externalUserCan($acls, Acl::PERMISSION_SHARE, $this->accessToken) + ]; + return $permissions; } + try { - $board = $this->getBoard($boardId, $allowDeleted); $owner = $this->userIsBoardOwner($boardId, $userId, $allowDeleted); $acls = $board->getDeletedAt() === 0 ? $this->aclMapper->findAll($boardId) : []; } catch (MultipleObjectsReturnedException|DoesNotExistException $e) { $owner = false; $acls = []; } - $permissions = []; - if ($userId !== null) { - $permissions = [ - Acl::PERMISSION_READ => $owner || $this->userCan($acls, Acl::PERMISSION_READ, $userId), - Acl::PERMISSION_EDIT => $owner || $this->userCan($acls, Acl::PERMISSION_EDIT, $userId), - Acl::PERMISSION_MANAGE => $owner || $this->userCan($acls, Acl::PERMISSION_MANAGE, $userId), - Acl::PERMISSION_SHARE => ($owner || $this->userCan($acls, Acl::PERMISSION_SHARE, $userId)) - && (!$this->shareManager->sharingDisabledForUser($userId)) - ]; - } else if ($accessToken !== null ) { - $permissions = [ - Acl::PERMISSION_READ => $owner || $this->externalUserCan($acls, Acl::PERMISSION_READ, $accessToken), - Acl::PERMISSION_EDIT => $owner || $this->externalUserCan($acls, Acl::PERMISSION_EDIT, $accessToken), - Acl::PERMISSION_MANAGE => $owner || $this->externalUserCan($acls, Acl::PERMISSION_MANAGE, $accessToken), - Acl::PERMISSION_SHARE => ($owner || $this->externalUserCan($acls, Acl::PERMISSION_SHARE, $accessToken)) + $permissions = [ + Acl::PERMISSION_READ => $owner || $this->userCan($acls, Acl::PERMISSION_READ, $userId), + Acl::PERMISSION_EDIT => $owner || $this->userCan($acls, Acl::PERMISSION_EDIT, $userId), + Acl::PERMISSION_MANAGE => $owner || $this->userCan($acls, Acl::PERMISSION_MANAGE, $userId), + Acl::PERMISSION_SHARE => ($owner || $this->userCan($acls, Acl::PERMISSION_SHARE, $userId)) + && (!$this->shareManager->sharingDisabledForUser($userId)) ]; - } $this->permissionCache->set($cacheKey, $permissions); return $permissions; } @@ -101,15 +115,15 @@ public function getPermissions(int $boardId, ?string $userId = null, bool $allow * @return array|bool * @internal param $boardId */ - public function matchPermissions(Board $board, $accessToken = null) { + public function matchPermissions(Board $board) { $owner = $this->userIsBoardOwner($board->getId()); $acls = $board->getAcl() ?? []; - if ($accessToken !== null) { + if ($this->accessToken !== null) { return [ - Acl::PERMISSION_READ => $owner || $this->externalUserCan($acls, Acl::PERMISSION_READ, $accessToken), - Acl::PERMISSION_EDIT => $owner || $this->externalUserCan($acls, Acl::PERMISSION_EDIT, $accessToken), - Acl::PERMISSION_MANAGE => $owner || $this->externalUserCan($acls, Acl::PERMISSION_MANAGE, $accessToken), - Acl::PERMISSION_SHARE => ($owner || $this->externalUserCan($acls, Acl::PERMISSION_SHARE, $accessToken)) + Acl::PERMISSION_READ => $this->externalUserCan($acls, Acl::PERMISSION_READ, $this->accessToken), + Acl::PERMISSION_EDIT => $this->externalUserCan($acls, Acl::PERMISSION_EDIT, $this->accessToken), + Acl::PERMISSION_MANAGE => $this->externalUserCan($acls, Acl::PERMISSION_MANAGE, $this->accessToken), + Acl::PERMISSION_SHARE => $this->externalUserCan($acls, Acl::PERMISSION_SHARE, $this->accessToken) ]; } return [ From 1633bd8b603253cb296d2de8ff31eb404c52d433 Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Thu, 30 Oct 2025 11:33:28 +0100 Subject: [PATCH 05/24] feat: map external boardIds back to internal ones for frontend Signed-off-by: grnd-alt --- lib/Service/ExternalBoardService.php | 75 ++++++++++++++++------------ 1 file changed, 44 insertions(+), 31 deletions(-) diff --git a/lib/Service/ExternalBoardService.php b/lib/Service/ExternalBoardService.php index ee8757e54e..c6197eabbf 100644 --- a/lib/Service/ExternalBoardService.php +++ b/lib/Service/ExternalBoardService.php @@ -24,7 +24,7 @@ public function getExternalBoardFromRemote(Board $localBoard):DataResponse { $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); $url = $ownerCloudId->getRemote() . "/ocs/v2.php/apps/deck/api/v1.0/board/".$localBoard->getExternalId(); $resp = $this->proxy->get($participantCloudId->getId(), $shareToken, $url); - return new DataResponse($this->proxy->getOcsData($resp)); + return new DataResponse($this->LocalizeRemoteBoard($this->proxy->getOcsData($resp), $localBoard)); } public function getExternalStacksFromRemote(Board $localBoard):DataResponse { $shareToken = $localBoard->getShareToken(); @@ -32,36 +32,49 @@ public function getExternalStacksFromRemote(Board $localBoard):DataResponse { $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); $url = $ownerCloudId->getRemote() . "/ocs/v2.php/apps/deck/api/v1.0/stacks/".$localBoard->getExternalId(); $resp = $this->proxy->get($participantCloudId->getId(), $shareToken, $url); - return new DataResponse($this->proxy->getOcsData($resp)); + return new DataResponse($this->LocalizeRemoteStacks($this->proxy->getOcsData($resp), $localBoard)); } - public function createCardOnRemote( - Board $localBoard, - string $title, - int $stackId, - ?string $type = 'plain', - ?int $order = 999, - ?string $description = '', - $duedate = null, - ?array $users = [], - ?int $boardId = null - ): array { - $shareToken = $localBoard->getShareToken(); - $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); - $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); - $url = $ownerCloudId->getRemote() . "/ocs/v2.php/apps/deck/api/v1.0/cards"; - $params = [ - 'title' => $title, - 'stackId' => $stackId, - 'type' => $type, - 'order' => $order, - 'owner' => $participantCloudId->getId(), - 'description' => $description, - 'duedate' => $duedate, - 'users' => $users, - 'boardId' => $localBoard->getExternalId(), - ]; - $resp = $this->proxy->post($participantCloudId->getId(), $shareToken, $url, $params); - return $this->proxy->getOcsData($resp); - } + public function LocalizeRemoteStacks(array $stacks, Board $localBoard) { + foreach ($stacks as $i => $stack) { + $stack['boardId'] = $localBoard->getId(); + $stacks[$i] = $stack; + } + return $stacks; + } + public function LocalizeRemoteBoard(array $remoteBoard, Board $localBoard) { + $remoteBoard['id'] = $localBoard->getId(); + $remoteBoard['stacks'] = $this->LocalizeRemoteStacks($remoteBoard['stacks'], $localBoard); + return $remoteBoard; + } + + public function createCardOnRemote( + Board $localBoard, + string $title, + int $stackId, + ?string $type = 'plain', + ?int $order = 999, + ?string $description = '', + $duedate = null, + ?array $users = [], + ?int $boardId = null + ): array { + $shareToken = $localBoard->getShareToken(); + $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); + $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); + $url = $ownerCloudId->getRemote() . "/ocs/v2.php/apps/deck/api/v1.0/cards"; + $params = [ + 'title' => $title, + 'stackId' => $stackId, + 'type' => $type, + 'order' => $order, + 'owner' => $participantCloudId->getId(), + 'description' => $description, + 'duedate' => $duedate, + 'users' => $users, + 'boardId' => $localBoard->getExternalId(), + ]; + $resp = $this->proxy->post($participantCloudId->getId(), $shareToken, $url, $params); + return $this->proxy->getOcsData($resp); + } } From e398765959a5ec6b3da5947ae0cc905c47635a1a Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Thu, 30 Oct 2025 11:35:32 +0100 Subject: [PATCH 06/24] fix: remote card creation Signed-off-by: grnd-alt --- lib/Controller/NewCardController.php | 6 +++++- lib/Listeners/FullTextSearchEventListener.php | 2 +- src/services/CardApi.js | 9 +++++++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/Controller/NewCardController.php b/lib/Controller/NewCardController.php index 66f28473d3..11b554dc92 100644 --- a/lib/Controller/NewCardController.php +++ b/lib/Controller/NewCardController.php @@ -32,7 +32,7 @@ public function __construct( #[PublicPage] #[NoCSRFRequired] #[RequestHeader(name: 'x-nextcloud-federation', description: 'Set to 1 when the request is performed by another Nextcloud Server to indicate a federation request', indirect: true)] - public function create(string $title, int $stackId, ?string $type = 'plain',?string $owner = null,?int $order = 999, ?string $description = '', $duedate = null, ?array $labels = [], ?array $users = [],?int $boardId=null) { + public function create(string $title, int $stackId, ?int $boardId=null, ?string $type = 'plain',?string $owner = null,?int $order = 999, ?string $description = '', $duedate = null, ?array $labels = [], ?array $users = []) { if ($boardId) { $board = $this->boardService->find($boardId, false); if ($board->getExternalId()) { @@ -40,6 +40,10 @@ public function create(string $title, int $stackId, ?string $type = 'plain',?str return new DataResponse($card); } } + + if (!$owner) { + $owner = $this->userId; + } $card = $this->cardService->create($title, $stackId, $type, $order, $owner, $description, $duedate); // foreach ($labels as $label) { diff --git a/lib/Listeners/FullTextSearchEventListener.php b/lib/Listeners/FullTextSearchEventListener.php index c6d08f4e8f..45263f1d5d 100644 --- a/lib/Listeners/FullTextSearchEventListener.php +++ b/lib/Listeners/FullTextSearchEventListener.php @@ -57,7 +57,7 @@ public function handle(Event $event): void { try { if ($event instanceof CardCreatedEvent) { $this->manager->createIndex( - DeckProvider::DECK_PROVIDER_ID, (string)$event->getCard()->getId(), $this->userId + DeckProvider::DECK_PROVIDER_ID, (string)$event->getCard()->getId(), $event->getCard()->getOwner() ); } if ($event instanceof CardUpdatedEvent) { diff --git a/src/services/CardApi.js b/src/services/CardApi.js index 15031aa1d5..7171d8c731 100644 --- a/src/services/CardApi.js +++ b/src/services/CardApi.js @@ -13,11 +13,16 @@ export class CardApi { return generateUrl(url) } + ocsUrl(url) { + url = `/apps/deck/api/v1.0${url}` + return generateOcsUrl(url) + } + addCard(card) { - return axios.post(this.url('/cards'), card) + return axios.post(this.ocsUrl('/cards'), card) .then( (response) => { - return Promise.resolve(response.data) + return Promise.resolve(response.data.ocs.data) }, (err) => { return Promise.reject(err) From 701ec357c630fab3a251a11f856649bb077aaf10 Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Mon, 3 Nov 2025 11:35:07 +0100 Subject: [PATCH 07/24] feat: create stacks on remote share Signed-off-by: grnd-alt --- appinfo/routes.php | 2 ++ lib/Controller/NewStackController.php | 41 +++++++++++++++++++++++ lib/Db/AclMapper.php | 10 ++++++ lib/Federation/DeckFederationProvider.php | 2 +- lib/Service/ExternalBoardService.php | 19 +++++++++++ lib/Service/PermissionService.php | 4 +++ lib/Service/StackService.php | 2 +- src/services/StackApi.js | 4 +-- 8 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 lib/Controller/NewStackController.php diff --git a/appinfo/routes.php b/appinfo/routes.php index 0e303bf093..68a02a658c 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -139,6 +139,8 @@ ['name' => 'new_card#create', 'url' => '/api/v{apiVersion}/cards', 'verb' => 'POST'], + ['name' => 'new_stack#create', 'url' => '/api/v{apiVersion}/stacks', 'verb' => 'POST'], + ['name' => 'Config#get', 'url' => '/api/v{apiVersion}/config', 'verb' => 'GET'], ['name' => 'Config#setValue', 'url' => '/api/v{apiVersion}/config/{key}', 'verb' => 'POST'], diff --git a/lib/Controller/NewStackController.php b/lib/Controller/NewStackController.php new file mode 100644 index 0000000000..fd262740b0 --- /dev/null +++ b/lib/Controller/NewStackController.php @@ -0,0 +1,41 @@ +boardService->find($boardId, false); + if ($board->getExternalId()) { + $stack = $this->externalBoardService->createStackOnRemote($board, $title, $order); + return new DataResponse($stack); + } else { + $stack = $this->stackService->create($title, $boardId, $order); + return new DataResponse($stack); + }; + } +} diff --git a/lib/Db/AclMapper.php b/lib/Db/AclMapper.php index bdc1f295ae..6cc5307b48 100644 --- a/lib/Db/AclMapper.php +++ b/lib/Db/AclMapper.php @@ -18,6 +18,16 @@ public function __construct(IDBConnection $db) { parent::__construct($db, 'deck_board_acl', Acl::class); } + public function findByAccessToken(string $accessToken){ + $qb = $this->db->getQueryBuilder(); + $qb->select('id', 'board_id', 'type', 'participant', 'permission_edit', 'permission_share', 'permission_manage', 'token') + ->from('deck_board_acl') + ->where($qb->expr()->eq('token', $qb->createNamedParameter($accessToken, IQueryBuilder::PARAM_STR))) + ->setMaxResults(1); + + return $this->findEntity($qb); + } + /** * @return Acl[] * @throws \OCP\DB\Exception diff --git a/lib/Federation/DeckFederationProvider.php b/lib/Federation/DeckFederationProvider.php index e38eee4db8..d3b4a53b94 100644 --- a/lib/Federation/DeckFederationProvider.php +++ b/lib/Federation/DeckFederationProvider.php @@ -51,7 +51,7 @@ public function shareReceived(ICloudFederationShare $share): string { $acl->setParticipant($share->getShareWith()); $acl->setPermissionEdit(true); $acl->setPermissionShare(false); - $acl->setPermissionManage(false); + $acl->setPermissionManage(true); $this->aclMapper->insert($acl); $this->changeHelper->boardChanged($insertedBoard->getId()); diff --git a/lib/Service/ExternalBoardService.php b/lib/Service/ExternalBoardService.php index c6197eabbf..8b7073a79c 100644 --- a/lib/Service/ExternalBoardService.php +++ b/lib/Service/ExternalBoardService.php @@ -77,4 +77,23 @@ public function createCardOnRemote( $resp = $this->proxy->post($participantCloudId->getId(), $shareToken, $url, $params); return $this->proxy->getOcsData($resp); } + + public function createStackOnRemote( + Board $localBoard, + string $title, + int $order = 0, + ): array { + $shareToken = $localBoard->getShareToken(); + $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); + $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); + $url = $ownerCloudId->getRemote() . "/ocs/v2.php/apps/deck/api/v1.0/stacks"; + $params = [ + 'title' => $title, + 'boardId' => $localBoard->getExternalId(), + 'order' => $order, + ]; + $resp = $this->proxy->post($participantCloudId->getId(), $shareToken, $url, $params); + $stack = $this->proxy->getOcsData($resp); + return $this->localizeRemoteStacks([$stack], $localBoard)[0]; + } } diff --git a/lib/Service/PermissionService.php b/lib/Service/PermissionService.php index a58c055de8..8b6729d465 100644 --- a/lib/Service/PermissionService.php +++ b/lib/Service/PermissionService.php @@ -247,6 +247,10 @@ public function userCan(array $acls, $permission, $userId = null) { return $hasGroupPermission; } + public function getUserId() { + return $this->userId || $this->aclMapper->findByAccessToken($this->accessToken)->getParticipant(); + } + /** * Find a list of all users (including the ones from groups) * Required to allow assigning them to cards diff --git a/lib/Service/StackService.php b/lib/Service/StackService.php index 631c4b184e..2a8837e14b 100644 --- a/lib/Service/StackService.php +++ b/lib/Service/StackService.php @@ -202,7 +202,7 @@ public function create(string $title, int $boardId, int $order): Stack { $stack->setOrder($order); $stack = $this->stackMapper->insert($stack); $this->activityManager->triggerEvent( - ActivityManager::DECK_OBJECT_BOARD, $stack, ActivityManager::SUBJECT_STACK_CREATE + ActivityManager::DECK_OBJECT_BOARD, $stack, ActivityManager::SUBJECT_STACK_CREATE, [], $this->permissionService->getUserId() ); $this->changeHelper->boardChanged($boardId); $this->eventDispatcher->dispatchTyped(new BoardUpdatedEvent($boardId)); diff --git a/src/services/StackApi.js b/src/services/StackApi.js index 977a0445b3..e51d0df800 100644 --- a/src/services/StackApi.js +++ b/src/services/StackApi.js @@ -68,10 +68,10 @@ export class StackApi { * @return {Promise} */ createStack(stack) { - return axios.post(this.url('/stacks'), stack) + return axios.post(this.ocsUrl('/stacks'), stack) .then( (response) => { - return Promise.resolve(response.data) + return Promise.resolve(response.data.ocs.data) }, (err) => { return Promise.reject(err) From d70fe58c9ab2eed5a98a770bfad5adc008cc2f11 Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Mon, 3 Nov 2025 12:55:27 +0100 Subject: [PATCH 08/24] feat: delete stacks on remote shares Signed-off-by: grnd-alt --- appinfo/routes.php | 1 + lib/Controller/NewStackController.php | 17 +++++++++++++++++ lib/Federation/DeckFederationProxy.php | 3 +++ lib/Service/ExternalBoardService.php | 9 +++++++++ lib/Service/StackService.php | 2 +- src/services/StackApi.js | 6 +++--- src/store/stack.js | 2 +- 7 files changed, 35 insertions(+), 5 deletions(-) diff --git a/appinfo/routes.php b/appinfo/routes.php index 68a02a658c..fd4380ea29 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -140,6 +140,7 @@ ['name' => 'new_card#create', 'url' => '/api/v{apiVersion}/cards', 'verb' => 'POST'], ['name' => 'new_stack#create', 'url' => '/api/v{apiVersion}/stacks', 'verb' => 'POST'], + ['name' => 'new_stack#delete', 'url' => '/api/v{apiVersion}/stacks/{stackId}/{boardId}', 'verb' => 'DELETE', 'defaults' => ['boardId' => null]], ['name' => 'Config#get', 'url' => '/api/v{apiVersion}/config', 'verb' => 'GET'], ['name' => 'Config#setValue', 'url' => '/api/v{apiVersion}/config/{key}', 'verb' => 'POST'], diff --git a/lib/Controller/NewStackController.php b/lib/Controller/NewStackController.php index fd262740b0..ec247e70c8 100644 --- a/lib/Controller/NewStackController.php +++ b/lib/Controller/NewStackController.php @@ -38,4 +38,21 @@ public function create(string $title, int $boardId, int $order = 0) { return new DataResponse($stack); }; } + + #[NoAdminRequired] + #[PublicPage] + #[NoCSRFRequired] + #[RequestHeader(name: 'x-nextcloud-federation', description: 'Set to 1 when the request is performed by another Nextcloud Server to indicate a federation request', indirect: true)] + public function delete(int $stackId, ?int $boardId = null) { + if ($boardId) { + $board = $this->boardService->find($boardId, false); + if ($board->getExternalId()) { + $result = $this->externalBoardService->deleteStackOnRemote($board, $stackId); + return new DataResponse($result); + } + } + $result = $this->stackService->delete($stackId); + return new DataResponse($result); + } + } diff --git a/lib/Federation/DeckFederationProxy.php b/lib/Federation/DeckFederationProxy.php index 1d80bc9b57..7055cd95a0 100644 --- a/lib/Federation/DeckFederationProxy.php +++ b/lib/Federation/DeckFederationProxy.php @@ -108,6 +108,9 @@ public function get(string $cloudId, string $shareToken, string $url, array $par public function post(string $cloudId, string $shareToken, string $url, array $params = []):IResponse { return $this->request("post", $cloudId, $shareToken, $url, $params); } + public function delete(string $cloudId, string $shareToken, string $url, array $params = []):IResponse { + return $this->request("delete", $cloudId, $shareToken, $url, $params); + } public function getOCSData(IResponse $response, array $allowedStatusCodes = [Http::STATUS_OK]): array { if (!in_array($response->getStatusCode(), $allowedStatusCodes, true)) { $this->logUnexpectedStatusCode(__METHOD__, $response->getStatusCode()); diff --git a/lib/Service/ExternalBoardService.php b/lib/Service/ExternalBoardService.php index 8b7073a79c..570b433db1 100644 --- a/lib/Service/ExternalBoardService.php +++ b/lib/Service/ExternalBoardService.php @@ -96,4 +96,13 @@ public function createStackOnRemote( $stack = $this->proxy->getOcsData($resp); return $this->localizeRemoteStacks([$stack], $localBoard)[0]; } + + public function deleteStackOnRemote(Board $localBoard, int $stackId): array { + $shareToken = $localBoard->getShareToken(); + $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); + $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); + $url = $ownerCloudId->getRemote() . "/ocs/v2.php/apps/deck/api/v1.0/stacks/" . $stackId; + $resp = $this->proxy->delete($participantCloudId->getId(), $shareToken, $url, []); + return $this->proxy->getOcsData($resp); + } } diff --git a/lib/Service/StackService.php b/lib/Service/StackService.php index 2a8837e14b..c2aed66e57 100644 --- a/lib/Service/StackService.php +++ b/lib/Service/StackService.php @@ -225,7 +225,7 @@ public function delete(int $id): Stack { $stack = $this->stackMapper->update($stack); $this->activityManager->triggerEvent( - ActivityManager::DECK_OBJECT_BOARD, $stack, ActivityManager::SUBJECT_STACK_DELETE + ActivityManager::DECK_OBJECT_BOARD, $stack, ActivityManager::SUBJECT_STACK_DELETE, [], $this->permissionService->getUserId() ); $this->changeHelper->boardChanged($stack->getBoardId()); $this->eventDispatcher->dispatchTyped(new BoardUpdatedEvent($stack->getBoardId())); diff --git a/src/services/StackApi.js b/src/services/StackApi.js index e51d0df800..3e09687bca 100644 --- a/src/services/StackApi.js +++ b/src/services/StackApi.js @@ -97,11 +97,11 @@ export class StackApi { }) } - deleteStack(stackId) { - return axios.delete(this.url(`/stacks/${stackId}`)) + deleteStack(stackId, boardId) { + return axios.delete(this.ocsUrl(`/stacks/${stackId}/${boardId}`)) .then( (response) => { - return Promise.resolve(response.data) + return Promise.resolve(response.data.ocs.data) }, (err) => { return Promise.reject(err) diff --git a/src/store/stack.js b/src/store/stack.js index 68cb9ca463..8316317fa9 100644 --- a/src/store/stack.js +++ b/src/store/stack.js @@ -102,7 +102,7 @@ export default function stackModuleFactory() { }) }, deleteStack({ commit }, stack) { - apiClient.deleteStack(stack.id) + apiClient.deleteStack(stack.id, stack.boardId) .then((stack) => { commit('deleteStack', stack) commit('moveStackToTrash', stack) From 62eb09789b4a4eaeff2d25e113265691ed4e1449 Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Wed, 12 Nov 2025 19:56:47 +0100 Subject: [PATCH 09/24] add create to ocs board controller Signed-off-by: grnd-alt --- appinfo/routes.php | 1 + lib/Controller/NewBoardController.php | 7 +++++++ src/services/BoardApi.js | 4 ++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/appinfo/routes.php b/appinfo/routes.php index fd4380ea29..e94d0f9cee 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -136,6 +136,7 @@ ['name' => 'new_board#index', 'url' => '/api/v{apiVersion}/boards', 'verb' => 'GET'], ['name' => 'new_board#read', 'url' => '/api/v{apiVersion}/board/{boardId}', 'verb' => 'GET'], ['name' => 'new_board#stacks', 'url' => '/api/v{apiVersion}/stacks/{boardId}', 'verb' => 'GET'], + ['name' => 'new_board#create', 'url' => '/api/v{apiVersion}/boards', 'verb' => 'POST'], ['name' => 'new_card#create', 'url' => '/api/v{apiVersion}/cards', 'verb' => 'POST'], diff --git a/lib/Controller/NewBoardController.php b/lib/Controller/NewBoardController.php index 4ff1ab4951..556c39e100 100644 --- a/lib/Controller/NewBoardController.php +++ b/lib/Controller/NewBoardController.php @@ -21,6 +21,7 @@ public function __construct( private ExternalBoardService $externalBoardService, private LoggerInterface $logger, private StackService $stackService, + private $userId, ) { parent::__construct($appName, $request); } @@ -45,6 +46,12 @@ public function read(int $boardId): DataResponse { return new DataResponse($localBoard); } + #[NoAdminrequired] + #[NoCSRFRequired] + public function create(string $title, string $color,): DataResponse { + return new DataResponse( $this->boardService->create($title, $this->userId, $color)); + } + #[NoAdminRequired] #[PublicPage] #[NoCSRFRequired] diff --git a/src/services/BoardApi.js b/src/services/BoardApi.js index 02313fdf7a..c5b103ddd0 100644 --- a/src/services/BoardApi.js +++ b/src/services/BoardApi.js @@ -54,10 +54,10 @@ export class BoardApi { * @return {Promise} */ createBoard(boardData) { - return axios.post(this.url('/boards'), boardData) + return axios.post(this.ocsUrl('/boards'), boardData) .then( (response) => { - return Promise.resolve(response.data) + return Promise.resolve(response.data.ocs.data) }, (err) => { return Promise.reject(err) From 51876e930ca6ceaa6e9cee772fb5c51f30a02313 Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Sat, 15 Nov 2025 16:37:04 +0100 Subject: [PATCH 10/24] feat: ocs endpoint for addAcl Signed-off-by: grnd-alt --- appinfo/routes.php | 5 +++-- lib/Controller/NewBoardController.php | 6 ++++++ src/services/BoardApi.js | 4 ++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/appinfo/routes.php b/appinfo/routes.php index e94d0f9cee..bfd6e6c981 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -137,10 +137,11 @@ ['name' => 'new_board#read', 'url' => '/api/v{apiVersion}/board/{boardId}', 'verb' => 'GET'], ['name' => 'new_board#stacks', 'url' => '/api/v{apiVersion}/stacks/{boardId}', 'verb' => 'GET'], ['name' => 'new_board#create', 'url' => '/api/v{apiVersion}/boards', 'verb' => 'POST'], + ['name' => 'new_board#addAcl', 'url' => '/api/v{apiVersion}/boards/{boardId}/acl', 'verb' => 'POST'], - ['name' => 'new_card#create', 'url' => '/api/v{apiVersion}/cards', 'verb' => 'POST'], + ['name' => 'new_card#create', 'url' => '/api/v{apiVersion}/cards', 'verb' => 'POST'], - ['name' => 'new_stack#create', 'url' => '/api/v{apiVersion}/stacks', 'verb' => 'POST'], + ['name' => 'new_stack#create', 'url' => '/api/v{apiVersion}/stacks', 'verb' => 'POST'], ['name' => 'new_stack#delete', 'url' => '/api/v{apiVersion}/stacks/{stackId}/{boardId}', 'verb' => 'DELETE', 'defaults' => ['boardId' => null]], ['name' => 'Config#get', 'url' => '/api/v{apiVersion}/config', 'verb' => 'GET'], diff --git a/lib/Controller/NewBoardController.php b/lib/Controller/NewBoardController.php index 556c39e100..2f69637c09 100644 --- a/lib/Controller/NewBoardController.php +++ b/lib/Controller/NewBoardController.php @@ -65,4 +65,10 @@ public function stacks(int $boardId): DataResponse{ return new DataResponse($this->stackService->findAll($boardId)); } } + + #[NoAdminRequired] + #[NoCSRFRequired] + public function addAcl(int $boardId, int $type, $participant, bool $permissionEdit, bool $permissionShare, bool $permissionManage, ?string $remote = null): DataResponse { + return new DataResponse($this->boardService->addAcl($boardId, $type, $participant, $permissionEdit, $permissionShare, $permissionManage, $remote)); + } } diff --git a/src/services/BoardApi.js b/src/services/BoardApi.js index c5b103ddd0..8806f5b330 100644 --- a/src/services/BoardApi.js +++ b/src/services/BoardApi.js @@ -325,10 +325,10 @@ export class BoardApi { addAcl(acl) { console.log(acl.participant) - return axios.post(this.url(`/boards/${acl.boardId}/acl`), acl) + return axios.post(this.ocsUrl(`/boards/${acl.boardId}/acl`), acl) .then( (response) => { - return Promise.resolve(response.data) + return Promise.resolve(response.data.ocs.data) }, (err) => { return Promise.reject(err) From 2f7ec3d6b7f944cf52d28c74539efe144c95afa6 Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Mon, 5 Jan 2026 18:28:40 +0100 Subject: [PATCH 11/24] feat: register deck resource type Signed-off-by: grnd-alt --- lib/AppInfo/Application.php | 3 ++ .../ResourceTypeRegisterListener.php | 28 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 lib/Listeners/ResourceTypeRegisterListener.php diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 245f0878a5..74d4c9f9ea 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -66,11 +66,13 @@ use OCP\Group\Events\GroupDeletedEvent; use OCP\IConfig; use OCP\IDBConnection; +use OCP\OCM\Events\ResourceTypeRegisterEvent; use OCP\Server; use OCP\Share\IManager; use OCP\User\Events\UserDeletedEvent; use OCP\Util; use Psr\Container\ContainerInterface; +use ResourceTypeRegisterListener; class Application extends App implements IBootstrap { public const APP_ID = 'deck'; @@ -140,6 +142,7 @@ public function register(IRegistrationContext $context): void { $context->registerReferenceProvider(CommentReferenceProvider::class); $context->registerEventListener(BeforeTemplateRenderedEvent::class, BeforeTemplateRenderedListener::class); + $context->registerEventListener(ResourceTypeRegisterEvent::class, ResourceTypeRegisterListener::class); // Event listening to emit UserShareAccessUpdatedEvent for files_sharing $context->registerEventListener(AclCreatedEvent::class, AclCreatedRemovedListener::class); diff --git a/lib/Listeners/ResourceTypeRegisterListener.php b/lib/Listeners/ResourceTypeRegisterListener.php new file mode 100644 index 0000000000..21c9898463 --- /dev/null +++ b/lib/Listeners/ResourceTypeRegisterListener.php @@ -0,0 +1,28 @@ +registerResourceType( + "deck", + ["user"], + [ + 'deck-v1' => '/ocs/v2.php/apps/deck/api/', + ] + ); + } +} + +?> From aa63d05eff3b3ab23d1d3bfdf045ef4ad581625b Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Mon, 2 Feb 2026 11:24:33 +0100 Subject: [PATCH 12/24] feat: introduce config value for federation Signed-off-by: grnd-alt --- lib/Service/ConfigService.php | 10 + package-lock.json | 2198 +++++++++++++++++----------- package.json | 1 + src/components/DeckAppSettings.vue | 19 + 4 files changed, 1350 insertions(+), 878 deletions(-) diff --git a/lib/Service/ConfigService.php b/lib/Service/ConfigService.php index 7b8b031ccc..84bbf2a903 100644 --- a/lib/Service/ConfigService.php +++ b/lib/Service/ConfigService.php @@ -60,6 +60,7 @@ public function getAll(): array { ]; if ($this->groupManager->isAdmin($userId)) { $data['groupLimit'] = $this->get('groupLimit'); + $data['federationEnabled'] = $this->get('federationEnabled'); } return $data; } @@ -76,6 +77,8 @@ public function get(string $key) { throw new NoPermissionException('You must be admin to get the group limit'); } return $this->getGroupLimit(); + case 'federationEnabled': + return (bool) $this->config->getAppValue(Application::APP_ID, 'federationEnabled', false); case 'calendar': if ($this->getUserId() === null) { return false; @@ -150,6 +153,13 @@ public function set($key, $value) { } $result = $this->setGroupLimit($value); break; + case 'federationEnabled': + if (!$this->groupManager->isAdmin($userId)) { + throw new NoPermissionException('You must be admin to set the federation enabled setting'); + } + $this->config->setAppValue(Application::APP_ID, 'federationEnabled', (string)$value); + $result = $value; + break; case 'calendar': $this->config->setUserValue($userId, Application::APP_ID, 'calendar', (string)$value); $result = $value; diff --git a/package-lock.json b/package-lock.json index bb877f092a..7fcef8bf70 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "@nextcloud/l10n": "^3.4.0", "@nextcloud/moment": "^1.3.5", "@nextcloud/notify_push": "^1.3.0", + "@nextcloud/password-confirmation": "^6.0.2", "@nextcloud/router": "^3.0.1", "@nextcloud/vue": "^8.34.0", "blueimp-md5": "^2.19.0", @@ -74,7 +75,6 @@ "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -175,6 +175,7 @@ "integrity": "sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.2", @@ -256,7 +257,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", "dev": true, - "peer": true, "dependencies": { "@babel/types": "^7.22.5" }, @@ -269,7 +269,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", "dev": true, - "peer": true, "dependencies": { "@babel/types": "^7.22.15" }, @@ -323,7 +322,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.5.tgz", "integrity": "sha512-uRc4Cv8UQWnE4NXlYTIIdM7wfFkOqlFztcC/gVXDKohKoVB3OyonfelUBaJzSwpBntZ2KYGF/9S7asCHsXwW6g==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.20", @@ -347,7 +345,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -357,7 +354,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "regexpu-core": "^5.3.1", @@ -375,7 +371,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -385,7 +380,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", @@ -402,7 +396,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, - "peer": true, "engines": { "node": ">=6.9.0" } @@ -412,7 +405,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, - "peer": true, "dependencies": { "@babel/template": "^7.22.15", "@babel/types": "^7.23.0" @@ -426,7 +418,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, - "peer": true, "dependencies": { "@babel/types": "^7.22.5" }, @@ -439,7 +430,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.5.tgz", "integrity": "sha512-4owRteeihKWKamtqg4JmWSsEZU445xpFRXPEwp44HbgbxdWlUV1b4Agg4lkA806Lil5XM/e+FJyS0vj5T6vmcA==", "dev": true, - "peer": true, "dependencies": { "@babel/types": "^7.24.5" }, @@ -484,7 +474,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", "dev": true, - "peer": true, "dependencies": { "@babel/types": "^7.22.5" }, @@ -507,7 +496,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.20", @@ -525,7 +513,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz", "integrity": "sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-member-expression-to-functions": "^7.23.0", @@ -555,7 +542,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", "dev": true, - "peer": true, "dependencies": { "@babel/types": "^7.22.5" }, @@ -568,7 +554,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.5.tgz", "integrity": "sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==", "dev": true, - "peer": true, "dependencies": { "@babel/types": "^7.24.5" }, @@ -586,9 +571,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -609,7 +594,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.5.tgz", "integrity": "sha512-/xxzuNvgRl4/HLNKvnFwdhdgN3cpLxgLROeLDl83Yx0AJ1SGvq1ak0OszTOjDfiB8Vx03eJbeDWh9r+jCCWttw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-function-name": "^7.23.0", "@babel/template": "^7.24.0", @@ -634,12 +618,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", - "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.6.tgz", + "integrity": "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==", "license": "MIT", "dependencies": { - "@babel/types": "^7.28.4" + "@babel/types": "^7.28.6" }, "bin": { "parser": "bin/babel-parser.js" @@ -653,7 +637,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.5.tgz", "integrity": "sha512-LdXRi1wEMTrHVR4Zc9F8OewC3vdm5h4QB6L71zy6StmYeqGi1b3ttIO8UC+BfZKcH9jdr4aI249rBkm+3+YvHw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-plugin-utils": "^7.24.5" @@ -670,7 +653,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.1.tgz", "integrity": "sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0" }, @@ -686,7 +668,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.1.tgz", "integrity": "sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", @@ -704,7 +685,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.1.tgz", "integrity": "sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-plugin-utils": "^7.24.0" @@ -721,7 +701,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", "dev": true, - "peer": true, "engines": { "node": ">=6.9.0" }, @@ -769,7 +748,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -798,7 +776,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.3" }, @@ -811,7 +788,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.1.tgz", "integrity": "sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0" }, @@ -827,7 +803,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.1.tgz", "integrity": "sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0" }, @@ -948,7 +923,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -994,7 +968,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -1011,7 +984,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.1.tgz", "integrity": "sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0" }, @@ -1027,7 +999,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.3.tgz", "integrity": "sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-plugin-utils": "^7.24.0", @@ -1046,7 +1017,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.1.tgz", "integrity": "sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-module-imports": "^7.24.1", "@babel/helper-plugin-utils": "^7.24.0", @@ -1064,7 +1034,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.1.tgz", "integrity": "sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0" }, @@ -1080,7 +1049,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.5.tgz", "integrity": "sha512-sMfBc3OxghjC95BkYrYocHL3NaOplrcaunblzwXhGmlPwpmfsxr4vK+mBBt49r+S240vahmv+kUxkeKgs+haCw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.5" }, @@ -1096,7 +1064,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.1.tgz", "integrity": "sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-create-class-features-plugin": "^7.24.1", "@babel/helper-plugin-utils": "^7.24.0" @@ -1113,7 +1080,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.4.tgz", "integrity": "sha512-B8q7Pz870Hz/q9UgP8InNpY01CSLDSCyqX7zcRuv3FcPl87A2G17lASroHWaCtbdIcbYzOZ7kWmXFKbijMSmFg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-create-class-features-plugin": "^7.24.4", "@babel/helper-plugin-utils": "^7.24.0", @@ -1131,7 +1097,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.5.tgz", "integrity": "sha512-gWkLP25DFj2dwe9Ck8uwMOpko4YsqyfZJrOmqqcegeDYEbp7rmn4U6UQZNj08UF6MaX39XenSpKRCvpDRBtZ7Q==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-compilation-targets": "^7.23.6", @@ -1154,7 +1119,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.1.tgz", "integrity": "sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0", "@babel/template": "^7.24.0" @@ -1171,7 +1135,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.5.tgz", "integrity": "sha512-SZuuLyfxvsm+Ah57I/i1HVjveBENYK9ue8MJ7qkc7ndoNjqquJiElzA7f5yaAXjyW2hKojosOTAQQRX50bPSVg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.5" }, @@ -1187,7 +1150,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.1.tgz", "integrity": "sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.24.0" @@ -1204,7 +1166,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.1.tgz", "integrity": "sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0" }, @@ -1220,7 +1181,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.1.tgz", "integrity": "sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-dynamic-import": "^7.8.3" @@ -1237,7 +1197,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.1.tgz", "integrity": "sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", "@babel/helper-plugin-utils": "^7.24.0" @@ -1254,7 +1213,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.1.tgz", "integrity": "sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" @@ -1271,7 +1229,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.1.tgz", "integrity": "sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" @@ -1288,7 +1245,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.1.tgz", "integrity": "sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-function-name": "^7.23.0", @@ -1306,7 +1262,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.1.tgz", "integrity": "sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-json-strings": "^7.8.3" @@ -1323,7 +1278,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.1.tgz", "integrity": "sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0" }, @@ -1339,7 +1293,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.1.tgz", "integrity": "sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" @@ -1356,7 +1309,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.1.tgz", "integrity": "sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0" }, @@ -1372,7 +1324,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.1.tgz", "integrity": "sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.24.0" @@ -1406,7 +1357,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.1.tgz", "integrity": "sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-module-transforms": "^7.23.3", @@ -1425,7 +1375,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.1.tgz", "integrity": "sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.24.0" @@ -1442,7 +1391,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5" @@ -1459,7 +1407,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.1.tgz", "integrity": "sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0" }, @@ -1475,7 +1422,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.1.tgz", "integrity": "sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" @@ -1492,7 +1438,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.1.tgz", "integrity": "sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-numeric-separator": "^7.10.4" @@ -1509,7 +1454,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.5.tgz", "integrity": "sha512-7EauQHszLGM3ay7a161tTQH7fj+3vVM/gThlz5HpFtnygTxjrlvoeq7MPVA1Vy9Q555OB8SnAOsMkLShNkkrHA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-plugin-utils": "^7.24.5", @@ -1528,7 +1472,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.1.tgz", "integrity": "sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-replace-supers": "^7.24.1" @@ -1545,7 +1488,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.1.tgz", "integrity": "sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" @@ -1562,7 +1504,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.5.tgz", "integrity": "sha512-xWCkmwKT+ihmA6l7SSTpk8e4qQl/274iNbSKRRS8mpqFR32ksy36+a+LWY8OXCCEefF8WFlnOHVsaDI2231wBg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", @@ -1580,7 +1521,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.5.tgz", "integrity": "sha512-9Co00MqZ2aoky+4j2jhofErthm6QVLKbpQrvz20c3CH9KQCLHyNB+t2ya4/UrRpQGR+Wrwjg9foopoeSdnHOkA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.5" }, @@ -1596,7 +1536,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.1.tgz", "integrity": "sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-create-class-features-plugin": "^7.24.1", "@babel/helper-plugin-utils": "^7.24.0" @@ -1613,7 +1552,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.5.tgz", "integrity": "sha512-JM4MHZqnWR04jPMujQDTBVRnqxpLLpx2tkn7iPn+Hmsc0Gnb79yvRWOkvqFOx3Z7P7VxiRIR22c4eGSNj87OBQ==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-create-class-features-plugin": "^7.24.5", @@ -1632,7 +1570,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.1.tgz", "integrity": "sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0" }, @@ -1648,7 +1585,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.1.tgz", "integrity": "sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0", "regenerator-transform": "^0.15.2" @@ -1665,7 +1601,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.1.tgz", "integrity": "sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0" }, @@ -1681,7 +1616,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.1.tgz", "integrity": "sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0" }, @@ -1697,7 +1631,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.1.tgz", "integrity": "sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" @@ -1714,7 +1647,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.1.tgz", "integrity": "sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0" }, @@ -1730,7 +1662,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz", "integrity": "sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0" }, @@ -1746,7 +1677,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.5.tgz", "integrity": "sha512-UTGnhYVZtTAjdwOTzT+sCyXmTn8AhaxOS/MjG9REclZ6ULHWF9KoCZur0HSGU7hk8PdBFKKbYe6+gqdXWz84Jg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.5" }, @@ -1762,7 +1692,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.1.tgz", "integrity": "sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0" }, @@ -1778,7 +1707,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.1.tgz", "integrity": "sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.24.0" @@ -1795,7 +1723,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.1.tgz", "integrity": "sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.24.0" @@ -1812,7 +1739,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.1.tgz", "integrity": "sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.24.0" @@ -1837,7 +1763,6 @@ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.5.tgz", "integrity": "sha512-UGK2ifKtcC8i5AI4cH+sbLLuLc2ktYSFJgBAXorKAsHUZmrQ1q6aQ6i3BvU24wWs2AAKqQB6kq3N9V9Gw1HiMQ==", "dev": true, - "peer": true, "dependencies": { "@babel/compat-data": "^7.24.4", "@babel/helper-compilation-targets": "^7.23.6", @@ -1933,7 +1858,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -1943,7 +1867,6 @@ "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/types": "^7.4.4", @@ -1957,8 +1880,7 @@ "version": "0.8.0", "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@babel/runtime": { "version": "7.27.1", @@ -2004,13 +1926,13 @@ } }, "node_modules/@babel/types": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", - "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz", + "integrity": "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -2144,7 +2066,6 @@ "url": "https://opencollective.com/csstools" } ], - "peer": true, "engines": { "node": "^14 || ^16 || >=18" }, @@ -2168,7 +2089,6 @@ "url": "https://opencollective.com/csstools" } ], - "peer": true, "engines": { "node": "^14 || ^16 || >=18" }, @@ -2176,6 +2096,15 @@ "postcss-selector-parser": "^6.0.13" } }, + "node_modules/@ctrl/tinycolor": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz", + "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/@cypress/request": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.9.tgz", @@ -2261,7 +2190,6 @@ "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=14.17.0" } @@ -2271,7 +2199,6 @@ "resolved": "https://registry.npmjs.org/@dual-bundle/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", "integrity": "sha512-+nxncfwHM5SgAtrVzgpzJOI1ol0PkumhVo469KCf9lUi21IGcY90G98VuHm9VRrUypmAzawAHO9bs6hqeADaVg==", "dev": true, - "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -2282,7 +2209,6 @@ "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.40.1.tgz", "integrity": "sha512-YORCdZSusAlBrFpZ77pJjc5r1bQs5caPWtAu+WWmiSo+8XaUzseapVrfAtiRFbQWnrBxxLLEwF6f6ZG/UgCQCg==", "dev": true, - "peer": true, "dependencies": { "comment-parser": "1.4.0", "esquery": "^1.5.0", @@ -2739,7 +2665,6 @@ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, - "peer": true, "dependencies": { "eslint-visitor-keys": "^3.3.0" }, @@ -2755,7 +2680,6 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "peer": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -2768,7 +2692,6 @@ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true, - "peer": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } @@ -2778,7 +2701,6 @@ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, - "peer": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -2801,15 +2723,13 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, - "peer": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -2826,7 +2746,6 @@ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "argparse": "^2.0.1" }, @@ -2839,7 +2758,6 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, - "peer": true, "engines": { "node": ">=8" }, @@ -2852,7 +2770,6 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, - "peer": true, "engines": { "node": ">=10" }, @@ -2865,7 +2782,6 @@ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, - "peer": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -2962,7 +2878,6 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, - "peer": true, "dependencies": { "@humanwhocodes/object-schema": "^2.0.2", "debug": "^4.3.1", @@ -2977,7 +2892,6 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, - "peer": true, "engines": { "node": ">=12.22" }, @@ -2990,8 +2904,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@isaacs/cliui": { "version": "8.0.2", @@ -3892,11 +3805,9 @@ } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.11", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", - "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", - "license": "MIT", - "peer": true, + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" @@ -3933,7 +3844,6 @@ "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", "dev": true, - "peer": true, "engines": { "node": ">=10.0" }, @@ -3950,7 +3860,6 @@ "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.0.tgz", "integrity": "sha512-zlQONA+msXPPwHWZMKFVS78ewFczIll5lXiVPwFPCZUsrOKdxc2AvxU1HoNBmMRhqDZUR9HkC3UOm+6pME6Xsg==", "dev": true, - "peer": true, "dependencies": { "@jsonjoy.com/base64": "^1.1.1", "@jsonjoy.com/util": "^1.1.2", @@ -3973,7 +3882,6 @@ "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.3.0.tgz", "integrity": "sha512-Cebt4Vk7k1xHy87kHY7KSPLT77A7Ev7IfOblyLZhtYEhrdQ6fX4EoLq3xOQ3O/DRMEh2ok5nyC180E+ABS8Wmw==", "dev": true, - "peer": true, "engines": { "node": ">=10.0" }, @@ -3989,8 +3897,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@linusborg/vue-simple-portal": { "version": "0.1.5", @@ -4479,171 +4386,672 @@ "@nextcloud/event-bus": "^3.3.0" } }, - "node_modules/@nextcloud/paths": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@nextcloud/paths/-/paths-3.0.0.tgz", - "integrity": "sha512-+sTfTkIbVUa2Ue3bkz3R7F1mhddvHPOWUxkSNg7Q5dAsimVFBaTRgiBAJmsAag3JPsxyuS8kUgeb0zdEssRdTA==", - "license": "GPL-3.0-or-later", - "engines": { - "node": "^20.0.0 || ^22.0.0 || ^24.0.0" - } - }, - "node_modules/@nextcloud/router": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@nextcloud/router/-/router-3.1.0.tgz", - "integrity": "sha512-e4dkIaxRSwdZJlZFpn9x03QgBn/Sa2hN1hp/BA7+AbzykmSAlKuWfdmX8j/8ewrLpQwYmZR23IZO9XwpJXq2Uw==", - "license": "GPL-3.0-or-later", + "node_modules/@nextcloud/password-confirmation": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@nextcloud/password-confirmation/-/password-confirmation-6.0.2.tgz", + "integrity": "sha512-EQbGiQl8lBZrFUNE6Xp9NeQEVtQdb/mtxk3VfwTnoVzAxghsI5yTWr9xcS5EKANoNjvVlIKtREN+LG2WWxft5A==", + "license": "MIT", "dependencies": { - "@nextcloud/typings": "^1.10.0" + "@nextcloud/auth": "^2.5.3", + "@nextcloud/axios": "^2.5.2", + "@nextcloud/l10n": "^3.4.0", + "@nextcloud/logger": "^3.0.2", + "@nextcloud/router": "^3.0.1", + "@nextcloud/vue": "^9.1.0", + "vue": "^3.5.22" }, "engines": { "node": "^20.0.0 || ^22.0.0 || ^24.0.0" } }, - "node_modules/@nextcloud/sharing": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@nextcloud/sharing/-/sharing-0.3.0.tgz", - "integrity": "sha512-kV7qeUZvd1fTKeFyH+W5Qq5rNOqG9rLATZM3U9MBxWXHJs3OxMqYQb8UQ3NYONzsX3zDGJmdQECIGHm1ei2sCA==", - "license": "GPL-3.0-or-later", + "node_modules/@nextcloud/password-confirmation/node_modules/@ckpack/vue-color": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@ckpack/vue-color/-/vue-color-1.6.0.tgz", + "integrity": "sha512-b9kFTKhYbNArfgP1lmnaVm0VNsWdZjqIbyHUYry7mZ+E7JeTQclbjq1+2xWn0SE3wzqRYlXmAVjECPOgteWmMQ==", + "license": "MIT", "dependencies": { - "@nextcloud/initial-state": "^3.0.0", - "is-svg": "^6.1.0" + "@ctrl/tinycolor": "^3.6.0", + "material-colors": "^1.2.6" }, "engines": { - "node": "^20.0.0 || ^22.0.0 || ^24.0.0" + "node": ">=12" }, - "optionalDependencies": { - "@nextcloud/files": "^3.12.0" - } - }, - "node_modules/@nextcloud/sharing/node_modules/@nextcloud/initial-state": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@nextcloud/initial-state/-/initial-state-3.0.0.tgz", - "integrity": "sha512-cV+HBdkQJGm8FxkBI5rFT/FbMNWNBvpbj6OPrg4Ae4YOOsQ15CL8InPOAw1t4XkOkQK2NEdUGQLVUz/19wXbdQ==", - "license": "GPL-3.0-or-later", - "engines": { - "node": "^20.0.0 || ^22.0.0 || ^24.0.0" + "peerDependencies": { + "vue": "^3.2.0" } }, - "node_modules/@nextcloud/stylelint-config": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@nextcloud/stylelint-config/-/stylelint-config-3.0.1.tgz", - "integrity": "sha512-xZ9hhyDCK8bMxPchfcyMhGZ8oTG+H+fmzE+vvCIVni0O+SzCVBEKDuvtKWZJDUs3ngmnmNYN1tH5xjbZBBeYyw==", - "dev": true, - "engines": { - "node": "^20.0.0", - "npm": "^10.0.0" - }, - "peerDependencies": { - "stylelint": "^16.2.0", - "stylelint-config-recommended-scss": "^14.0.0", - "stylelint-config-recommended-vue": "^1.5.0" + "node_modules/@nextcloud/password-confirmation/node_modules/@floating-ui/core": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.4.tgz", + "integrity": "sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.10" } }, - "node_modules/@nextcloud/timezones": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@nextcloud/timezones/-/timezones-0.2.0.tgz", - "integrity": "sha512-1mwQ+asTFOgv9rxPoAMEbDF8JfnenIa2EGNS+8MATCyi6WXxYh0Lhkaq1d3l2+xNbUPHgMnk4cRYsvIo319lkA==", - "license": "AGPL-3.0-or-later", + "node_modules/@nextcloud/password-confirmation/node_modules/@floating-ui/dom": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.5.tgz", + "integrity": "sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg==", + "license": "MIT", "dependencies": { - "ical.js": "^2.1.0" - }, - "engines": { - "node": "^20 || ^22" + "@floating-ui/core": "^1.7.4", + "@floating-ui/utils": "^0.2.10" } }, - "node_modules/@nextcloud/typings": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@nextcloud/typings/-/typings-1.10.0.tgz", - "integrity": "sha512-SMC42rDjOH3SspPTLMZRv76ZliHpj2JJkF8pGLP8l1QrVTZxE47Qz5qeKmbj2VL+dRv2e/NgixlAFmzVnxkhqg==", + "node_modules/@nextcloud/password-confirmation/node_modules/@nextcloud/initial-state": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@nextcloud/initial-state/-/initial-state-3.0.0.tgz", + "integrity": "sha512-cV+HBdkQJGm8FxkBI5rFT/FbMNWNBvpbj6OPrg4Ae4YOOsQ15CL8InPOAw1t4XkOkQK2NEdUGQLVUz/19wXbdQ==", "license": "GPL-3.0-or-later", - "dependencies": { - "@types/jquery": "3.5.16" - }, "engines": { "node": "^20.0.0 || ^22.0.0 || ^24.0.0" } }, - "node_modules/@nextcloud/vue": { - "version": "8.35.0", - "resolved": "https://registry.npmjs.org/@nextcloud/vue/-/vue-8.35.0.tgz", - "integrity": "sha512-qPm0aaPbnt7n694WQ97T+EMQTxCa3+RPKDzsBVD6vb01N4uGYwjvrEEOLVmBMlEWqkFy+ks3tpeOjkDPOoJbNA==", + "node_modules/@nextcloud/password-confirmation/node_modules/@nextcloud/vue": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/@nextcloud/vue/-/vue-9.4.0.tgz", + "integrity": "sha512-MoEbaFqFeZfTB+8d/BtgObAfzJMQ+vdidzMP/zKzx9J4cW+vgY5bciDUueY+t3f0uwSJXO3xsqXXWj9x2KihzQ==", "license": "AGPL-3.0-or-later", "dependencies": { + "@ckpack/vue-color": "^1.6.0", "@floating-ui/dom": "^1.7.4", - "@linusborg/vue-simple-portal": "^0.1.5", "@nextcloud/auth": "^2.5.3", "@nextcloud/axios": "^2.5.2", "@nextcloud/browser-storage": "^0.5.0", "@nextcloud/capabilities": "^1.2.1", "@nextcloud/event-bus": "^3.3.3", - "@nextcloud/initial-state": "^2.2.0", + "@nextcloud/initial-state": "^3.0.0", "@nextcloud/l10n": "^3.4.1", - "@nextcloud/logger": "^3.0.2", + "@nextcloud/logger": "^3.0.3", "@nextcloud/router": "^3.1.0", "@nextcloud/sharing": "^0.3.0", - "@nextcloud/timezones": "^0.2.0", - "@nextcloud/vue-select": "^3.26.0", - "@vueuse/components": "^11.0.0", - "@vueuse/core": "^11.0.0", + "@vuepic/vue-datepicker": "^11.0.3", + "@vueuse/components": "^14.1.0", + "@vueuse/core": "^14.0.0", "blurhash": "^2.0.5", "clone": "^2.1.2", - "debounce": "^2.2.0", - "dompurify": "^3.3.0", + "debounce": "^3.0.0", + "dompurify": "^3.3.1", "emoji-mart-vue-fast": "^15.0.5", "escape-html": "^1.0.3", - "floating-vue": "^1.0.0-beta.19", - "focus-trap": "^7.6.6", - "linkify-string": "^4.3.2", - "md5": "^2.3.0", - "p-queue": "^8.1.1", + "floating-vue": "^5.2.2", + "focus-trap": "^7.8.0", + "linkifyjs": "^4.3.2", + "p-queue": "^9.1.0", "rehype-external-links": "^3.0.0", "rehype-highlight": "^7.0.2", - "rehype-react": "^7.1.2", + "rehype-react": "^8.0.0", "remark-breaks": "^4.0.0", "remark-parse": "^11.0.0", - "remark-rehype": "^11.0.0", + "remark-rehype": "^11.1.2", "remark-unlink-protocols": "^1.0.0", - "splitpanes": "^2.4.1", - "string-length": "^5.0.1", + "splitpanes": "^4.0.4", "striptags": "^3.2.0", - "tabbable": "^6.3.0", + "tabbable": "^6.4.0", "tributejs": "^5.1.3", - "unified": "^11.0.1", + "ts-md5": "^2.0.1", + "unified": "^11.0.5", "unist-builder": "^4.0.0", "unist-util-visit": "^5.0.0", - "vue": "^2.7.16", - "vue-color": "^2.8.1", - "vue-frag": "^1.4.3", - "vue-router": "^3.6.5", - "vue2-datepicker": "^3.11.0" + "vue": "^3.5.18", + "vue-router": "^4.6.4", + "vue-select": "^4.0.0-beta.6" }, "engines": { - "node": "^20.0.0 || ^22.0.0 || ^24.0.0" - } - }, - "node_modules/@nextcloud/vue-select": { - "version": "3.26.0", - "resolved": "https://registry.npmjs.org/@nextcloud/vue-select/-/vue-select-3.26.0.tgz", - "integrity": "sha512-UvJExrxzx5pP3lv7j6zrv2yj6B1dXph7sh3lLNPnbJPjPoH/yg58mHNFBcPJrRYMbpy2t3hlC6F7s33KCTr9FA==", - "license": "MIT", - "engines": { - "node": "^20.0.0 || ^22.0.0 || ^24.0.0" - }, - "peerDependencies": { - "vue": "2.x" + "node": "^20.11.0 || ^22 || ^24" } }, - "node_modules/@nextcloud/vue/node_modules/@floating-ui/core": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz", - "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==", + "node_modules/@nextcloud/password-confirmation/node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", "license": "MIT", "dependencies": { - "@floating-ui/utils": "^0.2.10" + "@types/unist": "*" } }, - "node_modules/@nextcloud/vue/node_modules/@floating-ui/dom": { + "node_modules/@nextcloud/password-confirmation/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/@nextcloud/password-confirmation/node_modules/@types/web-bluetooth": { + "version": "0.0.21", + "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz", + "integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==", + "license": "MIT" + }, + "node_modules/@nextcloud/password-confirmation/node_modules/@vue/compiler-core": { + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.27.tgz", + "integrity": "sha512-gnSBQjZA+//qDZen+6a2EdHqJ68Z7uybrMf3SPjEGgG4dicklwDVmMC1AeIHxtLVPT7sn6sH1KOO+tS6gwOUeQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@vue/shared": "3.5.27", + "entities": "^7.0.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/@vue/compiler-dom": { + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.27.tgz", + "integrity": "sha512-oAFea8dZgCtVVVTEC7fv3T5CbZW9BxpFzGGxC79xakTr6ooeEqmRuvQydIiDAkglZEAd09LgVf1RoDnL54fu5w==", + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.27", + "@vue/shared": "3.5.27" + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/@vue/compiler-sfc": { + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.27.tgz", + "integrity": "sha512-sHZu9QyDPeDmN/MRoshhggVOWE5WlGFStKFwu8G52swATgSny27hJRWteKDSUUzUH+wp+bmeNbhJnEAel/auUQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@vue/compiler-core": "3.5.27", + "@vue/compiler-dom": "3.5.27", + "@vue/compiler-ssr": "3.5.27", + "@vue/shared": "3.5.27", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.21", + "postcss": "^8.5.6", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/@vue/compiler-ssr": { + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.27.tgz", + "integrity": "sha512-Sj7h+JHt512fV1cTxKlYhg7qxBvack+BGncSpH+8vnN+KN95iPIcqB5rsbblX40XorP+ilO7VIKlkuu3Xq2vjw==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.27", + "@vue/shared": "3.5.27" + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/@vue/server-renderer": { + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.27.tgz", + "integrity": "sha512-qOz/5thjeP1vAFc4+BY3Nr6wxyLhpeQgAE/8dDtKo6a6xdk+L4W46HDZgNmLOBUDEkFXV3G7pRiUqxjX0/2zWA==", + "license": "MIT", + "dependencies": { + "@vue/compiler-ssr": "3.5.27", + "@vue/shared": "3.5.27" + }, + "peerDependencies": { + "vue": "3.5.27" + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/@vue/shared": { + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.27.tgz", + "integrity": "sha512-dXr/3CgqXsJkZ0n9F3I4elY8wM9jMJpP3pvRG52r6m0tu/MsAFIe6JpXVGeNMd/D9F4hQynWT8Rfuj0bdm9kFQ==", + "license": "MIT" + }, + "node_modules/@nextcloud/password-confirmation/node_modules/@vuepic/vue-datepicker": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@vuepic/vue-datepicker/-/vue-datepicker-11.0.3.tgz", + "integrity": "sha512-sb2adwqwK2PizLQOpxCYps2SwhVT6/ic2HMIOqHJXuYa6iAJZWGL5YVlS7O4aW+sk6ZyxlDURLO7kDZPL4HB/w==", + "license": "MIT", + "dependencies": { + "date-fns": "^4.1.0" + }, + "engines": { + "node": ">=18.12.0" + }, + "peerDependencies": { + "vue": ">=3.3.0" + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/@vueuse/components": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@vueuse/components/-/components-14.1.0.tgz", + "integrity": "sha512-SDRJUAv3H7/PMh+KkYpq0d5KMzpKOfqx4qcV4xyN4mZOLPw8NkiWu+yDcfXwI8h1uCqhRNz2cdeaLa+IuaehFw==", + "license": "MIT", + "dependencies": { + "@vueuse/core": "14.1.0", + "@vueuse/shared": "14.1.0" + }, + "peerDependencies": { + "vue": "^3.5.0" + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/@vueuse/core": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-14.1.0.tgz", + "integrity": "sha512-rgBinKs07hAYyPF834mDTigH7BtPqvZ3Pryuzt1SD/lg5wEcWqvwzXXYGEDb2/cP0Sj5zSvHl3WkmMELr5kfWw==", + "license": "MIT", + "dependencies": { + "@types/web-bluetooth": "^0.0.21", + "@vueuse/metadata": "14.1.0", + "@vueuse/shared": "14.1.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vue": "^3.5.0" + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/@vueuse/metadata": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-14.1.0.tgz", + "integrity": "sha512-7hK4g015rWn2PhKcZ99NyT+ZD9sbwm7SGvp7k+k+rKGWnLjS/oQozoIZzWfCewSUeBmnJkIb+CNr7Zc/EyRnnA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/@vueuse/shared": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-14.1.0.tgz", + "integrity": "sha512-EcKxtYvn6gx1F8z9J5/rsg3+lTQnvOruQd8fUecW99DCK04BkWD7z5KQ/wTAx+DazyoEE9dJt/zV8OIEQbM6kw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vue": "^3.5.0" + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/debounce": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-3.0.0.tgz", + "integrity": "sha512-64byRbF0/AirwbuHqB3/ZpMG9/nckDa6ZA0yd6UnaQNwbbemCOwvz2sL5sjXLHhZHADyiwLm0M5qMhltUUx+TA==", + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT" + }, + "node_modules/@nextcloud/password-confirmation/node_modules/floating-vue": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/floating-vue/-/floating-vue-5.2.2.tgz", + "integrity": "sha512-afW+h2CFafo+7Y9Lvw/xsqjaQlKLdJV7h1fCHfcYQ1C4SVMlu7OAekqWgu5d4SgvkBVU0pVpLlVsrSTBURFRkg==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "~1.1.1", + "vue-resize": "^2.0.0-alpha.1" + }, + "peerDependencies": { + "@nuxt/kit": "^3.2.0", + "vue": "^3.2.0" + }, + "peerDependenciesMeta": { + "@nuxt/kit": { + "optional": true + } + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/floating-vue/node_modules/@floating-ui/dom": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.1.1.tgz", + "integrity": "sha512-TpIO93+DIujg3g7SykEAGZMDtbJRrmnYRCNYSjJlvIbGhBjRSNTLVbNeDQBrzy9qDgUbiWdc7KA0uZHZ2tJmiw==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.1.0" + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/p-queue": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-9.1.0.tgz", + "integrity": "sha512-O/ZPaXuQV29uSLbxWBGGZO1mCQXV2BLIwUr59JUU9SoH76mnYvtms7aafH/isNSNGwuEfP6W/4xD0/TJXxrizw==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^5.0.1", + "p-timeout": "^7.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/p-timeout": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-7.0.1.tgz", + "integrity": "sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==", + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/rehype-react": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/rehype-react/-/rehype-react-8.0.0.tgz", + "integrity": "sha512-vzo0YxYbB2HE+36+9HWXVdxNoNDubx63r5LBzpxBGVWM8s9mdnMdbmuJBAX6TTyuGdZjZix6qU3GcSuKCIWivw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/splitpanes": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/splitpanes/-/splitpanes-4.0.4.tgz", + "integrity": "sha512-RbysugZhjbCw5fgplvk3hOXr41stahQDtZhHVkhnnJI6H4wlGDhM2kIpbehy7v92duy9GnMa8zIhHigIV1TWtg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antoniandre" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/vue": { + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.27.tgz", + "integrity": "sha512-aJ/UtoEyFySPBGarREmN4z6qNKpbEguYHMmXSiOGk69czc+zhs0NF6tEFrY8TZKAl8N/LYAkd4JHVd5E/AsSmw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@vue/compiler-dom": "3.5.27", + "@vue/compiler-sfc": "3.5.27", + "@vue/runtime-dom": "3.5.27", + "@vue/server-renderer": "3.5.27", + "@vue/shared": "3.5.27" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/vue-resize": { + "version": "2.0.0-alpha.1", + "resolved": "https://registry.npmjs.org/vue-resize/-/vue-resize-2.0.0-alpha.1.tgz", + "integrity": "sha512-7+iqOueLU7uc9NrMfrzbG8hwMqchfVfSzpVlCMeJQe4pyibqyoifDNbKTZvwxZKDvGkB+PdFeKvnGZMoEb8esg==", + "license": "MIT", + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/vue-router": { + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.6.4.tgz", + "integrity": "sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.6.4" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "vue": "^3.5.0" + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/vue-select": { + "version": "4.0.0-beta.6", + "resolved": "https://registry.npmjs.org/vue-select/-/vue-select-4.0.0-beta.6.tgz", + "integrity": "sha512-K+zrNBSpwMPhAxYLTCl56gaMrWZGgayoWCLqe5rWwkB8aUbAUh7u6sXjIR7v4ckp2WKC7zEEUY27g6h1MRsIHw==", + "license": "MIT", + "peerDependencies": { + "vue": "3.x" + } + }, + "node_modules/@nextcloud/paths": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@nextcloud/paths/-/paths-3.0.0.tgz", + "integrity": "sha512-+sTfTkIbVUa2Ue3bkz3R7F1mhddvHPOWUxkSNg7Q5dAsimVFBaTRgiBAJmsAag3JPsxyuS8kUgeb0zdEssRdTA==", + "license": "GPL-3.0-or-later", + "engines": { + "node": "^20.0.0 || ^22.0.0 || ^24.0.0" + } + }, + "node_modules/@nextcloud/router": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@nextcloud/router/-/router-3.1.0.tgz", + "integrity": "sha512-e4dkIaxRSwdZJlZFpn9x03QgBn/Sa2hN1hp/BA7+AbzykmSAlKuWfdmX8j/8ewrLpQwYmZR23IZO9XwpJXq2Uw==", + "license": "GPL-3.0-or-later", + "dependencies": { + "@nextcloud/typings": "^1.10.0" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || ^24.0.0" + } + }, + "node_modules/@nextcloud/sharing": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@nextcloud/sharing/-/sharing-0.3.0.tgz", + "integrity": "sha512-kV7qeUZvd1fTKeFyH+W5Qq5rNOqG9rLATZM3U9MBxWXHJs3OxMqYQb8UQ3NYONzsX3zDGJmdQECIGHm1ei2sCA==", + "license": "GPL-3.0-or-later", + "dependencies": { + "@nextcloud/initial-state": "^3.0.0", + "is-svg": "^6.1.0" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || ^24.0.0" + }, + "optionalDependencies": { + "@nextcloud/files": "^3.12.0" + } + }, + "node_modules/@nextcloud/sharing/node_modules/@nextcloud/initial-state": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@nextcloud/initial-state/-/initial-state-3.0.0.tgz", + "integrity": "sha512-cV+HBdkQJGm8FxkBI5rFT/FbMNWNBvpbj6OPrg4Ae4YOOsQ15CL8InPOAw1t4XkOkQK2NEdUGQLVUz/19wXbdQ==", + "license": "GPL-3.0-or-later", + "engines": { + "node": "^20.0.0 || ^22.0.0 || ^24.0.0" + } + }, + "node_modules/@nextcloud/stylelint-config": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@nextcloud/stylelint-config/-/stylelint-config-3.0.1.tgz", + "integrity": "sha512-xZ9hhyDCK8bMxPchfcyMhGZ8oTG+H+fmzE+vvCIVni0O+SzCVBEKDuvtKWZJDUs3ngmnmNYN1tH5xjbZBBeYyw==", + "dev": true, + "engines": { + "node": "^20.0.0", + "npm": "^10.0.0" + }, + "peerDependencies": { + "stylelint": "^16.2.0", + "stylelint-config-recommended-scss": "^14.0.0", + "stylelint-config-recommended-vue": "^1.5.0" + } + }, + "node_modules/@nextcloud/timezones": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@nextcloud/timezones/-/timezones-0.2.0.tgz", + "integrity": "sha512-1mwQ+asTFOgv9rxPoAMEbDF8JfnenIa2EGNS+8MATCyi6WXxYh0Lhkaq1d3l2+xNbUPHgMnk4cRYsvIo319lkA==", + "license": "AGPL-3.0-or-later", + "dependencies": { + "ical.js": "^2.1.0" + }, + "engines": { + "node": "^20 || ^22" + } + }, + "node_modules/@nextcloud/typings": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@nextcloud/typings/-/typings-1.10.0.tgz", + "integrity": "sha512-SMC42rDjOH3SspPTLMZRv76ZliHpj2JJkF8pGLP8l1QrVTZxE47Qz5qeKmbj2VL+dRv2e/NgixlAFmzVnxkhqg==", + "license": "GPL-3.0-or-later", + "dependencies": { + "@types/jquery": "3.5.16" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || ^24.0.0" + } + }, + "node_modules/@nextcloud/vue": { + "version": "8.35.0", + "resolved": "https://registry.npmjs.org/@nextcloud/vue/-/vue-8.35.0.tgz", + "integrity": "sha512-qPm0aaPbnt7n694WQ97T+EMQTxCa3+RPKDzsBVD6vb01N4uGYwjvrEEOLVmBMlEWqkFy+ks3tpeOjkDPOoJbNA==", + "license": "AGPL-3.0-or-later", + "peer": true, + "dependencies": { + "@floating-ui/dom": "^1.7.4", + "@linusborg/vue-simple-portal": "^0.1.5", + "@nextcloud/auth": "^2.5.3", + "@nextcloud/axios": "^2.5.2", + "@nextcloud/browser-storage": "^0.5.0", + "@nextcloud/capabilities": "^1.2.1", + "@nextcloud/event-bus": "^3.3.3", + "@nextcloud/initial-state": "^2.2.0", + "@nextcloud/l10n": "^3.4.1", + "@nextcloud/logger": "^3.0.2", + "@nextcloud/router": "^3.1.0", + "@nextcloud/sharing": "^0.3.0", + "@nextcloud/timezones": "^0.2.0", + "@nextcloud/vue-select": "^3.26.0", + "@vueuse/components": "^11.0.0", + "@vueuse/core": "^11.0.0", + "blurhash": "^2.0.5", + "clone": "^2.1.2", + "debounce": "^2.2.0", + "dompurify": "^3.3.0", + "emoji-mart-vue-fast": "^15.0.5", + "escape-html": "^1.0.3", + "floating-vue": "^1.0.0-beta.19", + "focus-trap": "^7.6.6", + "linkify-string": "^4.3.2", + "md5": "^2.3.0", + "p-queue": "^8.1.1", + "rehype-external-links": "^3.0.0", + "rehype-highlight": "^7.0.2", + "rehype-react": "^7.1.2", + "remark-breaks": "^4.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "remark-unlink-protocols": "^1.0.0", + "splitpanes": "^2.4.1", + "string-length": "^5.0.1", + "striptags": "^3.2.0", + "tabbable": "^6.3.0", + "tributejs": "^5.1.3", + "unified": "^11.0.1", + "unist-builder": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vue": "^2.7.16", + "vue-color": "^2.8.1", + "vue-frag": "^1.4.3", + "vue-router": "^3.6.5", + "vue2-datepicker": "^3.11.0" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || ^24.0.0" + } + }, + "node_modules/@nextcloud/vue-select": { + "version": "3.26.0", + "resolved": "https://registry.npmjs.org/@nextcloud/vue-select/-/vue-select-3.26.0.tgz", + "integrity": "sha512-UvJExrxzx5pP3lv7j6zrv2yj6B1dXph7sh3lLNPnbJPjPoH/yg58mHNFBcPJrRYMbpy2t3hlC6F7s33KCTr9FA==", + "license": "MIT", + "engines": { + "node": "^20.0.0 || ^22.0.0 || ^24.0.0" + }, + "peerDependencies": { + "vue": "2.x" + } + }, + "node_modules/@nextcloud/vue/node_modules/@floating-ui/core": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz", + "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@nextcloud/vue/node_modules/@floating-ui/dom": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz", "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==", @@ -4795,7 +5203,6 @@ "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", "dev": true, - "peer": true, "dependencies": { "eslint-scope": "5.1.1" } @@ -4805,7 +5212,6 @@ "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz", "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -4851,7 +5257,6 @@ "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12.4.0" } @@ -4867,7 +5272,6 @@ "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.4.1.tgz", "integrity": "sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==", "dev": true, - "peer": true, "dependencies": { "detect-libc": "^1.0.3", "is-glob": "^4.0.3", @@ -4908,7 +5312,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -4929,7 +5332,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -4950,7 +5352,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -4971,7 +5372,6 @@ "os": [ "freebsd" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -4992,7 +5392,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -5013,7 +5412,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -5034,7 +5432,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -5055,7 +5452,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -5076,7 +5472,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -5097,7 +5492,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -5118,7 +5512,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -5139,7 +5532,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -5291,6 +5683,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" @@ -5400,7 +5793,6 @@ "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", "dev": true, - "peer": true, "dependencies": { "@types/connect": "*", "@types/node": "*" @@ -5411,7 +5803,6 @@ "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", "dev": true, - "peer": true, "dependencies": { "@types/node": "*" } @@ -5429,7 +5820,6 @@ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "dev": true, - "peer": true, "dependencies": { "@types/node": "*" } @@ -5439,7 +5829,6 @@ "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", "dev": true, - "peer": true, "dependencies": { "@types/express-serve-static-core": "*", "@types/node": "*" @@ -5474,7 +5863,6 @@ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "license": "MIT", - "peer": true, "dependencies": { "@types/eslint": "*", "@types/estree": "*" @@ -5486,12 +5874,20 @@ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "license": "MIT" }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, "node_modules/@types/express": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", "dev": true, - "peer": true, "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -5504,7 +5900,6 @@ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.0.tgz", "integrity": "sha512-AbXMTZGt40T+KON9/Fdxx0B2WK5hsgxcfXJLr5bFpZ7b4JCex2WyQPTEKdXqfHiY5nKKBScZ7yCoO6Pvgxfvnw==", "dev": true, - "peer": true, "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -5517,7 +5912,6 @@ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", "dev": true, - "peer": true, "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -5546,15 +5940,13 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/http-proxy": { "version": "1.17.15", "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", "dev": true, - "peer": true, "dependencies": { "@types/node": "*" } @@ -5601,8 +5993,7 @@ "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/marked": { "version": "4.3.0", @@ -5621,8 +6012,7 @@ "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/ms": { "version": "2.1.0", @@ -5643,7 +6033,6 @@ "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", "dev": true, - "peer": true, "dependencies": { "@types/node": "*" } @@ -5651,22 +6040,19 @@ "node_modules/@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", - "peer": true + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" }, "node_modules/@types/qs": { "version": "6.9.16", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/range-parser": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/react": { "version": "18.0.28", @@ -5683,14 +6069,12 @@ "version": "0.12.2", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/scheduler": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", - "peer": true + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" }, "node_modules/@types/semver": { "version": "7.7.1", @@ -5703,7 +6087,6 @@ "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", "dev": true, - "peer": true, "dependencies": { "@types/mime": "^1", "@types/node": "*" @@ -5714,7 +6097,6 @@ "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", "dev": true, - "peer": true, "dependencies": { "@types/express": "*" } @@ -5724,7 +6106,6 @@ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", "dev": true, - "peer": true, "dependencies": { "@types/http-errors": "*", "@types/node": "*", @@ -5747,7 +6128,6 @@ "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", "dev": true, - "peer": true, "dependencies": { "@types/node": "*" } @@ -5805,7 +6185,6 @@ "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", "dev": true, - "peer": true, "dependencies": { "@types/node": "*" } @@ -5840,7 +6219,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.9.0.tgz", "integrity": "sha512-6e+X0X3sFe/G/54aC3jt0txuMTURqLyekmEHViqyA2VnxhLMpvA6nqmcjIy+Cr9tLDHPssA74BP5Mx9HQIxBEA==", "dev": true, - "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "7.9.0", @@ -5939,7 +6317,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.9.0.tgz", "integrity": "sha512-ZwPK4DeCDxr3GJltRz5iZejPFAAr4Wk3+2WIBaj1L5PYK5RgxExu/Y68FFVclN0y6GGwH8q+KgKRCvaTmFBbgQ==", "dev": true, - "peer": true, "dependencies": { "@typescript-eslint/types": "7.9.0", "@typescript-eslint/visitor-keys": "7.9.0" @@ -5974,7 +6351,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.9.0.tgz", "integrity": "sha512-6Qy8dfut0PFrFRAZsGzuLoM4hre4gjzWJB6sUvdunCYZsYemTkzZNwF1rnGea326PHPT3zn5Lmg32M/xfJfByA==", "dev": true, - "peer": true, "dependencies": { "@typescript-eslint/typescript-estree": "7.9.0", "@typescript-eslint/utils": "7.9.0", @@ -6002,7 +6378,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.9.0.tgz", "integrity": "sha512-oZQD9HEWQanl9UfsbGVcZ2cGaR0YT5476xfWE0oE5kQa2sNK2frxOlkeacLOTh9po4AlUT5rtkGyYM5kew0z5w==", "dev": true, - "peer": true, "engines": { "node": "^18.18.0 || >=20.0.0" }, @@ -6016,7 +6391,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.9.0.tgz", "integrity": "sha512-zBCMCkrb2YjpKV3LA0ZJubtKCDxLttxfdGmwZvTqqWevUPN0FZvSI26FalGFFUZU/9YQK/A4xcQF9o/VVaCKAg==", "dev": true, - "peer": true, "dependencies": { "@typescript-eslint/types": "7.9.0", "@typescript-eslint/visitor-keys": "7.9.0", @@ -6046,7 +6420,6 @@ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -6056,7 +6429,6 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", "dev": true, - "peer": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -6072,7 +6444,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.9.0.tgz", "integrity": "sha512-5KVRQCzZajmT4Ep+NEgjXCvjuypVvYHUW7RHlXzNPuak2oWpVoD1jf5xCP0dPAuNIchjC7uQyvbdaSTFaLqSdA==", "dev": true, - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "7.9.0", @@ -6095,7 +6466,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.9.0.tgz", "integrity": "sha512-iESPx2TNLDNGQLyjKhUvIKprlP49XNEK+MvIf9nIO7ZZaZdbnfWKHnXAgufpxqfA0YryH8XToi4+CjBgVnFTSQ==", "dev": true, - "peer": true, "dependencies": { "@typescript-eslint/types": "7.9.0", "eslint-visitor-keys": "^3.4.3" @@ -6113,7 +6483,6 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "peer": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -6230,6 +6599,12 @@ "node": ">=0.10.0" } }, + "node_modules/@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", + "license": "MIT" + }, "node_modules/@vue/eslint-config-typescript": { "version": "13.0.0", "resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-13.0.0.tgz", @@ -6255,6 +6630,55 @@ } } }, + "node_modules/@vue/reactivity": { + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.27.tgz", + "integrity": "sha512-vvorxn2KXfJ0nBEnj4GYshSgsyMNFnIQah/wczXlsNXt+ijhugmW+PpJ2cNPe4V6jpnBcs0MhCODKllWG+nvoQ==", + "license": "MIT", + "dependencies": { + "@vue/shared": "3.5.27" + } + }, + "node_modules/@vue/reactivity/node_modules/@vue/shared": { + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.27.tgz", + "integrity": "sha512-dXr/3CgqXsJkZ0n9F3I4elY8wM9jMJpP3pvRG52r6m0tu/MsAFIe6JpXVGeNMd/D9F4hQynWT8Rfuj0bdm9kFQ==", + "license": "MIT" + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.27.tgz", + "integrity": "sha512-fxVuX/fzgzeMPn/CLQecWeDIFNt3gQVhxM0rW02Tvp/YmZfXQgcTXlakq7IMutuZ/+Ogbn+K0oct9J3JZfyk3A==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.27", + "@vue/shared": "3.5.27" + } + }, + "node_modules/@vue/runtime-core/node_modules/@vue/shared": { + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.27.tgz", + "integrity": "sha512-dXr/3CgqXsJkZ0n9F3I4elY8wM9jMJpP3pvRG52r6m0tu/MsAFIe6JpXVGeNMd/D9F4hQynWT8Rfuj0bdm9kFQ==", + "license": "MIT" + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.27.tgz", + "integrity": "sha512-/QnLslQgYqSJ5aUmb5F0z0caZPGHRB8LEAQ1s81vHFM5CBfnun63rxhvE/scVb/j3TbBuoZwkJyiLCkBluMpeg==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.27", + "@vue/runtime-core": "3.5.27", + "@vue/shared": "3.5.27", + "csstype": "^3.2.3" + } + }, + "node_modules/@vue/runtime-dom/node_modules/@vue/shared": { + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.27.tgz", + "integrity": "sha512-dXr/3CgqXsJkZ0n9F3I4elY8wM9jMJpP3pvRG52r6m0tu/MsAFIe6JpXVGeNMd/D9F4hQynWT8Rfuj0bdm9kFQ==", + "license": "MIT" + }, "node_modules/@vue/shared": { "version": "3.5.22", "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.22.tgz", @@ -6425,7 +6849,6 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "license": "MIT", - "peer": true, "dependencies": { "@webassemblyjs/helper-numbers": "1.13.2", "@webassemblyjs/helper-wasm-bytecode": "1.13.2" @@ -6435,29 +6858,25 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@webassemblyjs/helper-api-error": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@webassemblyjs/helper-buffer": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "license": "MIT", - "peer": true, "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.13.2", "@webassemblyjs/helper-api-error": "1.13.2", @@ -6468,15 +6887,13 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "license": "MIT", - "peer": true, "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-buffer": "1.14.1", @@ -6489,7 +6906,6 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "license": "MIT", - "peer": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } @@ -6499,7 +6915,6 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "license": "Apache-2.0", - "peer": true, "dependencies": { "@xtuc/long": "4.2.2" } @@ -6508,15 +6923,13 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "license": "MIT", - "peer": true, "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-buffer": "1.14.1", @@ -6533,7 +6946,6 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "license": "MIT", - "peer": true, "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-wasm-bytecode": "1.13.2", @@ -6547,7 +6959,6 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "license": "MIT", - "peer": true, "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-buffer": "1.14.1", @@ -6560,7 +6971,6 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "license": "MIT", - "peer": true, "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-api-error": "1.13.2", @@ -6575,7 +6985,6 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "license": "MIT", - "peer": true, "dependencies": { "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" @@ -6587,7 +6996,6 @@ "integrity": "sha512-u8d0pJ5YFgneF/GuvEiDA61Tf1VDomHHYMjv/wc9XzYj7nopltpG96nXN5dJRstxZhcNpV1g+nT6CydO7pHbjA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=18.12.0" }, @@ -6602,7 +7010,6 @@ "integrity": "sha512-coEmDzc2u/ffMvuW9aCjoRzNSPDl/XLuhPdlFRpT9tZHmJ/039az33CE7uH+8s0uL1j5ZNtfdv0HkfaKRBGJsQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=18.12.0" }, @@ -6617,7 +7024,6 @@ "integrity": "sha512-sbgw03xQaCLiT6gcY/6u3qBDn01CWw/nbaXl3gTdTFuJJ75Gffv3E3DBpgvY2fkkrdS1fpjaXNOmJlnbtKauKg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=18.12.0" }, @@ -6635,15 +7041,12 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "license": "BSD-3-Clause", - "peer": true + "license": "BSD-3-Clause" }, "node_modules/@xtuc/long": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "license": "Apache-2.0", - "peer": true + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" }, "node_modules/abbrev": { "version": "2.0.0", @@ -6659,7 +7062,6 @@ "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", "dev": true, - "peer": true, "dependencies": { "event-target-shim": "^5.0.0" }, @@ -6672,7 +7074,6 @@ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, - "peer": true, "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -6686,6 +7087,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -6698,7 +7100,6 @@ "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=10.13.0" }, @@ -6711,7 +7112,6 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "peer": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -6827,7 +7227,6 @@ "engines": [ "node >= 0.8.0" ], - "peer": true, "bin": { "ansi-html": "bin/ansi-html" } @@ -6897,7 +7296,6 @@ "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", "dev": true, - "peer": true, "engines": { "node": ">=14" } @@ -6935,15 +7333,13 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/array-includes": { "version": "3.1.7", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -6971,7 +7367,6 @@ "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -6991,7 +7386,6 @@ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -7010,7 +7404,6 @@ "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -7029,7 +7422,6 @@ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", "dev": true, - "peer": true, "dependencies": { "array-buffer-byte-length": "^1.0.0", "call-bind": "^1.0.2", @@ -7060,7 +7452,6 @@ "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "dev": true, - "peer": true, "dependencies": { "bn.js": "^4.0.0", "inherits": "^2.0.1", @@ -7071,15 +7462,13 @@ "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/assert": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "is-nan": "^1.3.2", @@ -7188,6 +7577,7 @@ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "dev": true, + "peer": true, "dependencies": { "@jest/transform": "^29.7.0", "@types/babel__core": "^7.1.14", @@ -7328,7 +7718,6 @@ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", "dev": true, - "peer": true, "dependencies": { "@babel/compat-data": "^7.22.6", "@babel/helper-define-polyfill-provider": "^0.6.2", @@ -7343,7 +7732,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -7353,7 +7741,6 @@ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.1", "core-js-compat": "^3.36.1" @@ -7367,7 +7754,6 @@ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.2" }, @@ -7465,8 +7851,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/bcrypt-pbkdf": { "version": "1.0.2", @@ -7491,7 +7876,6 @@ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, - "peer": true, "engines": { "node": ">=8" }, @@ -7562,8 +7946,7 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/body-parser": { "version": "1.20.4", @@ -7571,7 +7954,6 @@ "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "bytes": "~3.1.2", "content-type": "~1.0.5", @@ -7596,7 +7978,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "dependencies": { "ms": "2.0.0" } @@ -7607,7 +7988,6 @@ "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", @@ -7627,8 +8007,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/body-parser/node_modules/statuses": { "version": "2.0.2", @@ -7636,7 +8015,6 @@ "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.8" } @@ -7646,7 +8024,6 @@ "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", "dev": true, - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "multicast-dns": "^7.2.5" @@ -7656,8 +8033,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true, - "peer": true + "dev": true }, "node_modules/brace-expansion": { "version": "1.1.12", @@ -7686,15 +8062,13 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true, - "peer": true + "dev": true }, "node_modules/browserify-aes": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, - "peer": true, "dependencies": { "buffer-xor": "^1.0.3", "cipher-base": "^1.0.0", @@ -7709,7 +8083,6 @@ "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", "dev": true, - "peer": true, "dependencies": { "browserify-aes": "^1.0.4", "browserify-des": "^1.0.0", @@ -7721,7 +8094,6 @@ "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", "dev": true, - "peer": true, "dependencies": { "cipher-base": "^1.0.1", "des.js": "^1.0.0", @@ -7734,7 +8106,6 @@ "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.1.tgz", "integrity": "sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==", "dev": true, - "peer": true, "dependencies": { "bn.js": "^5.2.1", "randombytes": "^2.1.0", @@ -7762,15 +8133,13 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "peer": true + ] }, "node_modules/browserify-sign": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.3.tgz", "integrity": "sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==", "dev": true, - "peer": true, "dependencies": { "bn.js": "^5.2.1", "browserify-rsa": "^4.1.0", @@ -7792,7 +8161,6 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, - "peer": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -7807,8 +8175,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "peer": true + "dev": true }, "node_modules/browserify-sign/node_modules/safe-buffer": { "version": "5.2.1", @@ -7828,15 +8195,13 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "peer": true + ] }, "node_modules/browserify-sign/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, - "peer": true, "dependencies": { "safe-buffer": "~5.1.0" } @@ -7845,15 +8210,13 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "peer": true + "dev": true }, "node_modules/browserify-zlib": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", "dev": true, - "peer": true, "dependencies": { "pako": "~1.0.5" } @@ -7877,6 +8240,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -7919,7 +8283,6 @@ "url": "https://feross.org/support" } ], - "peer": true, "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -7942,8 +8305,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/buildcheck": { "version": "0.0.6", @@ -7960,7 +8322,6 @@ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "dev": true, - "peer": true, "engines": { "node": ">=6" }, @@ -7972,15 +8333,13 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/builtins": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", "dev": true, - "peer": true, "dependencies": { "semver": "^7.0.0" } @@ -7990,7 +8349,6 @@ "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", "dev": true, - "peer": true, "dependencies": { "run-applescript": "^7.0.0" }, @@ -8012,7 +8370,6 @@ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.8" } @@ -8122,6 +8479,16 @@ "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", "dev": true }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -8155,6 +8522,36 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/charenc": { "version": "0.0.2", "license": "BSD-3-Clause", @@ -8176,7 +8573,6 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", "dev": true, - "peer": true, "dependencies": { "readdirp": "^4.0.1" }, @@ -8203,7 +8599,6 @@ "node_modules/chrome-trace-event": { "version": "1.0.3", "license": "MIT", - "peer": true, "engines": { "node": ">=6.0" } @@ -8220,7 +8615,6 @@ "integrity": "sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "inherits": "^2.0.4", "safe-buffer": "^5.2.1", @@ -8249,8 +8643,7 @@ "url": "https://feross.org/support" } ], - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/cjs-module-lexer": { "version": "1.2.3", @@ -8388,7 +8781,6 @@ "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "is-plain-object": "^2.0.4", "kind-of": "^6.0.2", @@ -8404,7 +8796,6 @@ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -8455,8 +8846,7 @@ "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/colorette": { "version": "2.0.16", @@ -8498,7 +8888,6 @@ "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.0.tgz", "integrity": "sha512-QLyTNiZ2KDOibvFPlZ6ZngVsZ/0gYnE6uTXi5aoDg8ed3AkJAz4sEje3Y8a29hQ1s6A99MZXe47fLAXQ1rTqaw==", "dev": true, - "peer": true, "engines": { "node": ">= 12.0.0" } @@ -8517,7 +8906,6 @@ "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "dev": true, - "peer": true, "dependencies": { "mime-db": ">= 1.43.0 < 2" }, @@ -8531,7 +8919,6 @@ "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "bytes": "3.1.2", "compressible": "~2.0.18", @@ -8550,7 +8937,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "dependencies": { "ms": "2.0.0" } @@ -8559,8 +8945,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/compression/node_modules/negotiator": { "version": "0.6.4", @@ -8568,7 +8953,6 @@ "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.6" } @@ -8592,8 +8976,7 @@ "url": "https://feross.org/support" } ], - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", @@ -8639,7 +9022,6 @@ "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", "dev": true, - "peer": true, "engines": { "node": ">=0.8" } @@ -8648,8 +9030,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/console.table": { "version": "0.10.0", @@ -8679,15 +9060,13 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dev": true, - "peer": true, "dependencies": { "safe-buffer": "5.2.1" }, @@ -8713,15 +9092,13 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "peer": true + ] }, "node_modules/content-type": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -8741,7 +9118,6 @@ "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.6" } @@ -8750,8 +9126,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/core-js": { "version": "2.6.9", @@ -8763,7 +9138,6 @@ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", "dev": true, - "peer": true, "dependencies": { "browserslist": "^4.23.0" }, @@ -8842,7 +9216,6 @@ "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", "dev": true, - "peer": true, "dependencies": { "bn.js": "^4.1.0", "elliptic": "^6.5.3" @@ -8852,15 +9225,13 @@ "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/create-hash": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, - "peer": true, "dependencies": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", @@ -8874,7 +9245,6 @@ "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, - "peer": true, "dependencies": { "cipher-base": "^1.0.3", "create-hash": "^1.1.0", @@ -9035,7 +9405,6 @@ "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", "dev": true, - "peer": true, "dependencies": { "browserify-cipher": "^1.0.0", "browserify-sign": "^4.0.0", @@ -9058,7 +9427,6 @@ "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.2.tgz", "integrity": "sha512-c+N0v6wbKVxTu5gOBBFkr9BEdBWaqqjQeiJ8QvSRIJOf+UxlJh930m8e6/WNeODIK0mYLFkoONrnj16i2EcvfQ==", "dev": true, - "peer": true, "engines": { "node": ">=12 || >=16" } @@ -9122,9 +9490,10 @@ } }, "node_modules/csstype": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz", - "integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==" + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "license": "MIT" }, "node_modules/cypress": { "version": "13.17.0", @@ -9132,6 +9501,7 @@ "integrity": "sha512-5xWkaPurwkIljojFidhw8lFScyxhtiFHl/i/3zov+1Z5CmY4t9tjIdvSXfu82Y3w7wt0uR9KkucbhkVvJZLQSA==", "dev": true, "hasInstallScript": true, + "peer": true, "dependencies": { "@cypress/request": "^3.0.6", "@cypress/xvfb": "^1.2.4", @@ -9411,6 +9781,16 @@ "node": ">= 12" } }, + "node_modules/date-fns": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz", + "integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/date-format-parse": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/date-format-parse/-/date-format-parse-0.2.7.tgz", @@ -9525,8 +9905,7 @@ "node_modules/deep-is": { "version": "0.1.3", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/deepmerge": { "version": "4.3.1", @@ -9542,7 +9921,6 @@ "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", "dev": true, - "peer": true, "dependencies": { "bundle-name": "^4.1.0", "default-browser-id": "^5.0.0" @@ -9559,7 +9937,6 @@ "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", "dev": true, - "peer": true, "engines": { "node": ">=18" }, @@ -9614,7 +9991,6 @@ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", "dev": true, - "peer": true, "engines": { "node": ">=12" }, @@ -9652,7 +10028,6 @@ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true, - "peer": true, "engines": { "node": ">= 0.8" } @@ -9699,7 +10074,6 @@ "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", "dev": true, - "peer": true, "dependencies": { "inherits": "^2.0.1", "minimalistic-assert": "^1.0.0" @@ -9710,7 +10084,6 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true, - "peer": true, "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -9721,7 +10094,6 @@ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", "dev": true, - "peer": true, "bin": { "detect-libc": "bin/detect-libc.js" }, @@ -9742,8 +10114,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true, - "peer": true + "dev": true }, "node_modules/detective-amd": { "version": "6.0.1", @@ -10043,7 +10414,6 @@ "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, - "peer": true, "dependencies": { "bn.js": "^4.1.0", "miller-rabin": "^4.0.0", @@ -10054,8 +10424,7 @@ "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/dir-glob": { "version": "3.0.1", @@ -10073,7 +10442,6 @@ "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", "dev": true, - "peer": true, "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" }, @@ -10134,7 +10502,6 @@ "version": "3.0.0", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "esutils": "^2.0.2" }, @@ -10147,7 +10514,6 @@ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dev": true, - "peer": true, "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", @@ -10162,7 +10528,6 @@ "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-5.7.0.tgz", "integrity": "sha512-edTFu0M/7wO1pXY6GDxVNVW086uqwWYIHP98txhcPyV995X21JIH2DtYp33sQJOupYoXKe9RwTw2Ya2vWaquTQ==", "dev": true, - "peer": true, "engines": { "node": ">=4" }, @@ -10180,15 +10545,13 @@ "type": "github", "url": "https://github.com/sponsors/fb55" } - ], - "peer": true + ] }, "node_modules/domhandler": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, - "peer": true, "dependencies": { "domelementtype": "^2.3.0" }, @@ -10200,9 +10563,9 @@ } }, "node_modules/dompurify": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.0.tgz", - "integrity": "sha512-r+f6MYR1gGN1eJv0TVQbhA7if/U7P87cdPl3HN5rikqaBSBxLiCb/b9O+2eG0cxz0ghyU+mU1QkbsOwERMYlWQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.1.tgz", + "integrity": "sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q==", "license": "(MPL-2.0 OR Apache-2.0)", "optionalDependencies": { "@types/trusted-types": "^2.0.7" @@ -10213,7 +10576,6 @@ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "dev": true, - "peer": true, "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", @@ -10356,8 +10718,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true, - "peer": true + "dev": true }, "node_modules/electron-to-chromium": { "version": "1.5.286", @@ -10371,7 +10732,6 @@ "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "bn.js": "^4.11.9", "brorand": "^1.1.0", @@ -10386,8 +10746,7 @@ "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/emittery": { "version": "0.13.1", @@ -10445,7 +10804,6 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "dev": true, - "peer": true, "engines": { "node": ">= 0.8" } @@ -10477,6 +10835,7 @@ "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", "dev": true, + "peer": true, "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" @@ -10525,7 +10884,6 @@ "integrity": "sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "envinfo": "dist/cli.js" }, @@ -10546,7 +10904,6 @@ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.2.tgz", "integrity": "sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA==", "dev": true, - "peer": true, "dependencies": { "array-buffer-byte-length": "^1.0.0", "arraybuffer.prototype.slice": "^1.0.2", @@ -10644,8 +11001,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/es-object-atoms": { "version": "1.1.1", @@ -10679,7 +11035,6 @@ "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", "dev": true, - "peer": true, "dependencies": { "has": "^1.0.3" } @@ -10688,7 +11043,6 @@ "version": "1.2.1", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -10912,7 +11266,6 @@ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, - "peer": true, "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", @@ -10924,7 +11277,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "peer": true, "dependencies": { "ms": "^2.1.1" } @@ -10970,7 +11322,6 @@ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", "dev": true, - "peer": true, "dependencies": { "debug": "^3.2.7" }, @@ -10988,7 +11339,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "peer": true, "dependencies": { "ms": "^2.1.1" } @@ -11038,7 +11388,6 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.2.0.tgz", "integrity": "sha512-9dvv5CcvNjSJPqnS5uZkqb3xmbeqRLnvXKK7iI5+oK/yTusyc46zbBZKENGsOfojm/mKfszyZb+wNqNPAPeGXA==", "dev": true, - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.1.2", "@eslint-community/regexpp": "^4.6.0" @@ -11090,7 +11439,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "peer": true, "dependencies": { "ms": "^2.1.1" } @@ -11100,7 +11448,6 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, - "peer": true, "dependencies": { "esutils": "^2.0.2" }, @@ -11113,7 +11460,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -11123,7 +11469,6 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.8.2.tgz", "integrity": "sha512-5TSnD018f3tUJNne4s4gDWQflbsgOycIKEUBoCLn6XtBMgNHxQFmV8vVxUtiPxAQq8lrX85OaSG/2gnctxw9uQ==", "dev": true, - "peer": true, "dependencies": { "@es-joy/jsdoccomment": "~0.40.1", "are-docs-informative": "^0.0.2", @@ -11147,7 +11492,6 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, - "peer": true, "engines": { "node": ">=10" }, @@ -11227,7 +11571,6 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, - "peer": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -11243,7 +11586,6 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, - "peer": true, "engines": { "node": ">=10" }, @@ -11254,7 +11596,6 @@ "node_modules/eslint-scope": { "version": "5.1.1", "license": "BSD-2-Clause", - "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -11268,7 +11609,6 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true, - "peer": true, "engines": { "node": ">=10" } @@ -11342,14 +11682,12 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "peer": true + "dev": true }, "node_modules/eslint/node_modules/chalk": { "version": "4.1.1", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -11365,7 +11703,6 @@ "version": "4.3.0", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -11380,7 +11717,6 @@ "version": "7.2.0", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -11392,7 +11728,6 @@ "version": "2.0.1", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -11403,15 +11738,13 @@ "node_modules/eslint/node_modules/color-name": { "version": "1.1.4", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/eslint/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, - "peer": true, "engines": { "node": ">=10" }, @@ -11424,7 +11757,6 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, - "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -11441,7 +11773,6 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "peer": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -11454,7 +11785,6 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "peer": true, "engines": { "node": ">=4.0" } @@ -11464,7 +11794,6 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, - "peer": true, "dependencies": { "is-glob": "^4.0.3" }, @@ -11477,7 +11806,6 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, - "peer": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -11492,7 +11820,6 @@ "version": "4.0.0", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -11503,7 +11830,6 @@ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "argparse": "^2.0.1" }, @@ -11516,7 +11842,6 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, - "peer": true, "engines": { "node": ">=10" }, @@ -11529,7 +11854,6 @@ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, - "peer": true, "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -11547,7 +11871,6 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "peer": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -11573,7 +11896,6 @@ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, - "peer": true, "dependencies": { "estraverse": "^5.1.0" }, @@ -11585,7 +11907,6 @@ "version": "5.2.0", "dev": true, "license": "BSD-2-Clause", - "peer": true, "engines": { "node": ">=4.0" } @@ -11594,7 +11915,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "peer": true, "dependencies": { "estraverse": "^5.2.0" }, @@ -11606,7 +11926,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "peer": true, "engines": { "node": ">=4.0" } @@ -11614,16 +11933,24 @@ "node_modules/estraverse": { "version": "4.2.0", "license": "BSD-2-Clause", - "peer": true, "engines": { "node": ">=0.10.0" } }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true, "license": "MIT" }, "node_modules/esutils": { @@ -11638,7 +11965,6 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -11648,7 +11974,6 @@ "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", "dev": true, - "peer": true, "engines": { "node": ">=6" } @@ -11663,13 +11988,11 @@ "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/events": { "version": "3.3.0", "license": "MIT", - "peer": true, "engines": { "node": ">=0.8.x" } @@ -11679,7 +12002,6 @@ "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", "dev": true, - "peer": true, "dependencies": { "md5.js": "^1.3.4", "safe-buffer": "^5.1.1" @@ -11751,7 +12073,6 @@ "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -11798,7 +12119,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "dependencies": { "ms": "2.0.0" } @@ -11807,8 +12127,23 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/express/node_modules/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", "dev": true, - "peer": true + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/express/node_modules/safe-buffer": { "version": "5.2.1", @@ -11828,8 +12163,7 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "peer": true + ] }, "node_modules/extend": { "version": "3.0.2", @@ -11909,8 +12243,7 @@ "node_modules/fast-levenshtein": { "version": "2.0.6", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/fast-shuffle": { "version": "6.1.1", @@ -11961,7 +12294,6 @@ "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", "dev": true, - "peer": true, "engines": { "node": ">= 4.9.1" } @@ -11979,7 +12311,6 @@ "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", "dev": true, - "peer": true, "dependencies": { "websocket-driver": ">=0.5.1" }, @@ -12046,7 +12377,6 @@ "version": "6.0.1", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "flat-cache": "^3.0.4" }, @@ -12122,7 +12452,6 @@ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "dev": true, - "peer": true, "dependencies": { "debug": "2.6.9", "encodeurl": "~2.0.0", @@ -12141,7 +12470,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "dependencies": { "ms": "2.0.0" } @@ -12150,8 +12478,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/find-cypress-specs": { "version": "1.54.6", @@ -12229,7 +12556,6 @@ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -12247,7 +12573,6 @@ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "bin": { "flat": "cli.js" } @@ -12256,7 +12581,6 @@ "version": "3.0.4", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "flatted": "^3.1.0", "rimraf": "^3.0.2" @@ -12285,12 +12609,12 @@ } }, "node_modules/focus-trap": { - "version": "7.6.6", - "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.6.6.tgz", - "integrity": "sha512-v/Z8bvMCajtx4mEXmOo7QEsIzlIOqRXTIwgUfsFOF9gEsespdbD0AkPIka1bSXZ8Y8oZ+2IVDQZePkTfEHZl7Q==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.8.0.tgz", + "integrity": "sha512-/yNdlIkpWbM0ptxno3ONTuf+2g318kh2ez3KSeZN5dZ8YC6AAmgeWz+GasYYiBJPFaYcSAPeu4GfhUaChzIJXA==", "license": "MIT", "dependencies": { - "tabbable": "^6.3.0" + "tabbable": "^6.4.0" } }, "node_modules/follow-redirects": { @@ -12398,7 +12722,6 @@ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "dev": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -12408,7 +12731,6 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -12488,7 +12810,6 @@ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -12611,7 +12932,6 @@ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.1" @@ -12689,9 +13009,7 @@ "node_modules/glob-to-regexp": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "license": "BSD-2-Clause", - "peer": true + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" }, "node_modules/global-dirs": { "version": "3.0.1", @@ -12721,7 +13039,6 @@ "version": "2.0.0", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "global-prefix": "^3.0.0" }, @@ -12733,7 +13050,6 @@ "version": "3.0.0", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ini": "^1.3.5", "kind-of": "^6.0.2", @@ -12747,7 +13063,6 @@ "version": "6.0.3", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -12766,7 +13081,6 @@ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", "dev": true, - "peer": true, "dependencies": { "define-properties": "^1.1.3" }, @@ -12800,8 +13114,7 @@ "node_modules/globjoin": { "version": "0.1.4", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/gonzales-pe": { "version": "4.3.0", @@ -12840,21 +13153,18 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "peer": true + "dev": true }, "node_modules/handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/has": { "version": "1.0.3", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -12896,7 +13206,6 @@ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", "dev": true, - "peer": true, "engines": { "node": ">= 0.4" }, @@ -12936,7 +13245,6 @@ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", "integrity": "sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==", "dev": true, - "peer": true, "dependencies": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -12955,7 +13263,6 @@ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", "dev": true, - "peer": true, "dependencies": { "inherits": "^2.0.3", "minimalistic-assert": "^1.0.1" @@ -13009,6 +13316,98 @@ "@types/unist": "*" } }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", + "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime/node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/hast-util-to-jsx-runtime/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/hast-util-to-jsx-runtime/node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime/node_modules/property-information": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-util-to-jsx-runtime/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime/node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-to-text": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", @@ -13071,7 +13470,6 @@ "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", "dev": true, - "peer": true, "dependencies": { "hash.js": "^1.0.3", "minimalistic-assert": "^1.0.0", @@ -13088,7 +13486,6 @@ "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", "dev": true, - "peer": true, "dependencies": { "inherits": "^2.0.1", "obuf": "^1.0.0", @@ -13101,7 +13498,6 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, - "peer": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -13117,7 +13513,6 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, - "peer": true, "dependencies": { "safe-buffer": "~5.1.0" } @@ -13133,7 +13528,6 @@ "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", "dev": true, - "peer": true, "engines": { "node": ">=8" }, @@ -13153,7 +13547,6 @@ "url": "https://github.com/sponsors/fb55" } ], - "peer": true, "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", @@ -13165,15 +13558,13 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dev": true, - "peer": true, "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -13189,15 +13580,13 @@ "version": "0.5.8", "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", - "dev": true, - "peer": true + "dev": true }, "node_modules/http-proxy": { "version": "1.18.1", "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", "dev": true, - "peer": true, "dependencies": { "eventemitter3": "^4.0.0", "follow-redirects": "^1.0.0", @@ -13213,7 +13602,6 @@ "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/http-proxy": "^1.17.8", "http-proxy": "^1.18.1", @@ -13238,7 +13626,6 @@ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", "dev": true, - "peer": true, "engines": { "node": ">=10" }, @@ -13264,8 +13651,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/human-signals": { "version": "2.1.0", @@ -13291,7 +13677,6 @@ "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", "dev": true, - "peer": true, "engines": { "node": ">=10.18" } @@ -13308,7 +13693,6 @@ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -13320,7 +13704,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "peer": true, "engines": { "node": "^10 || ^12 || >= 14" }, @@ -13361,8 +13744,7 @@ "version": "4.3.7", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/import-fresh": { "version": "3.3.0", @@ -13466,7 +13848,6 @@ "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10.13.0" } @@ -13476,7 +13857,6 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", "dev": true, - "peer": true, "engines": { "node": ">= 10" } @@ -13492,6 +13872,30 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", @@ -13544,7 +13948,6 @@ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, - "peer": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -13577,7 +13980,6 @@ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", "dev": true, - "peer": true, "dependencies": { "builtin-modules": "^3.3.0" }, @@ -13594,7 +13996,6 @@ "integrity": "sha512-DgXeu5UWI0IsMQundYb5UAOzm6G2eVnarJ0byP6Tm55iZNKceD59LNPA2L4VvsScTtHcw0yEkVwSf7PC+QoLSA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "semver": "^7.6.3" } @@ -13644,12 +14045,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-docker": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", "dev": true, - "peer": true, "bin": { "is-docker": "cli.js" }, @@ -13699,7 +14109,6 @@ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", "dev": true, - "peer": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -13722,12 +14131,21 @@ "node": ">=0.10.0" } }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-inside-container": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", "dev": true, - "peer": true, "dependencies": { "is-docker": "^3.0.0" }, @@ -13775,7 +14193,6 @@ "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.0", "define-properties": "^1.1.3" @@ -13792,7 +14209,6 @@ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "dev": true, - "peer": true, "engines": { "node": ">= 0.4" }, @@ -13805,7 +14221,6 @@ "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", "dev": true, - "peer": true, "engines": { "node": ">=16" }, @@ -13873,7 +14288,6 @@ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "isobject": "^3.0.1" }, @@ -14061,7 +14475,6 @@ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2" }, @@ -14099,7 +14512,6 @@ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", "dev": true, - "peer": true, "dependencies": { "is-inside-container": "^1.0.0" }, @@ -14114,8 +14526,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/isexe": { "version": "2.0.0", @@ -14128,7 +14539,6 @@ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -14274,6 +14684,7 @@ "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, + "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -15896,8 +16307,6 @@ "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "license": "MIT", - "peer": true, "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -15911,8 +16320,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -15921,8 +16328,6 @@ "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "license": "MIT", - "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -16055,7 +16460,6 @@ "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", "dev": true, - "peer": true, "engines": { "node": ">=12.0.0" } @@ -16077,8 +16481,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", @@ -16094,14 +16497,12 @@ "node_modules/json-schema-traverse": { "version": "0.4.1", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/json-stringify-safe": { "version": "5.0.1", @@ -16153,7 +16554,6 @@ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, - "peer": true, "dependencies": { "json-buffer": "3.0.1" } @@ -16182,15 +16582,13 @@ "version": "0.30.0", "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.30.0.tgz", "integrity": "sha512-VSWXYUnsPu9+WYKkfmJyLKtIvaRJi1kXUqVmBACORXZQxT5oZDsoZ2vQP+bQFDnWtpI/4eq3MLoRMjI2fnLzTQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/launch-editor": { "version": "2.9.1", "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==", "dev": true, - "peer": true, "dependencies": { "picocolors": "^1.0.0", "shell-quote": "^1.8.1" @@ -16224,7 +16622,6 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, - "peer": true, "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -16294,7 +16691,6 @@ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", "license": "MIT", - "peer": true, "engines": { "node": ">=6.11.5" }, @@ -16335,7 +16731,6 @@ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "p-locate": "^5.0.0" }, @@ -16363,15 +16758,13 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true, - "peer": true + "dev": true }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/lodash.once": { "version": "4.1.1", @@ -16387,8 +16780,7 @@ "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/log-symbols": { "version": "4.1.0", @@ -16548,6 +16940,16 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/lowlight": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-3.3.0.tgz", @@ -16581,10 +16983,9 @@ } }, "node_modules/magic-string": { - "version": "0.30.19", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz", - "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==", - "dev": true, + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" @@ -16672,7 +17073,6 @@ "version": "2.1.3", "dev": true, "license": "MIT", - "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -16693,7 +17093,6 @@ "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", "dev": true, - "peer": true, "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1", @@ -16783,6 +17182,126 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression/node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", + "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx/node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/mdast-util-mdx-jsx/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/mdast-util-mdx-jsx/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx/node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm/node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/mdast-util-newline-to-break": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdast-util-newline-to-break/-/mdast-util-newline-to-break-2.0.0.tgz", @@ -16796,6 +17315,20 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdast-util-to-hast": { "version": "13.2.1", "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", @@ -16869,6 +17402,33 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, "node_modules/mdast-util-to-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", @@ -16898,7 +17458,6 @@ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -16908,7 +17467,6 @@ "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.12.0.tgz", "integrity": "sha512-74wDsex5tQDSClVkeK1vtxqYCAgCoXxx+K4NSHzgU/muYVYByFqa+0RnrPO9NM6naWm1+G9JmZ0p6QHhXmeYfA==", "dev": true, - "peer": true, "dependencies": { "@jsonjoy.com/json-pack": "^1.0.3", "@jsonjoy.com/util": "^1.3.0", @@ -16928,7 +17486,6 @@ "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", "dev": true, - "peer": true, "engines": { "node": ">=18" }, @@ -16941,7 +17498,6 @@ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", "dev": true, - "peer": true, "funding": { "url": "https://github.com/sponsors/sindresorhus" } @@ -16979,7 +17535,6 @@ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "dev": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -17440,7 +17995,6 @@ "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", "dev": true, - "peer": true, "dependencies": { "bn.js": "^4.0.0", "brorand": "^1.0.1" @@ -17453,15 +18007,13 @@ "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true, - "peer": true, "bin": { "mime": "cli.js" }, @@ -17500,15 +18052,13 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/minimalistic-crypto-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/minimatch": { "version": "3.1.2", @@ -17611,7 +18161,6 @@ "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", "dev": true, - "peer": true, "dependencies": { "dns-packet": "^5.2.2", "thunky": "^1.0.2" @@ -17656,15 +18205,13 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true, - "peer": true, "engines": { "node": ">= 0.6" } }, "node_modules/neo-async": { "version": "2.6.2", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/nested-property": { "version": "4.0.0", @@ -17675,8 +18222,7 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/node-domexception": { "version": "1.0.0", @@ -17723,7 +18269,6 @@ "integrity": "sha512-6xKiQ+cph9KImrRh0VsjH2d8/GXA4FIMlgU4B757iI1ApvcyA9VlouP0yZJha01V+huImO+kKMU7ih+2+E14fw==", "dev": true, "license": "(BSD-3-Clause OR GPL-2.0)", - "peer": true, "engines": { "node": ">= 6.13.0" } @@ -17739,7 +18284,6 @@ "resolved": "https://registry.npmjs.org/node-polyfill-webpack-plugin/-/node-polyfill-webpack-plugin-4.0.0.tgz", "integrity": "sha512-WLk77vLpbcpmTekRj6s6vYxk30XoyaY5MDZ4+9g8OaKoG3Ij+TjOqhpQjVUlfDZBPBgpNATDltaQkzuXSnnkwg==", "dev": true, - "peer": true, "dependencies": { "assert": "^2.1.0", "browserify-zlib": "^0.2.0", @@ -17778,7 +18322,6 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dev": true, - "peer": true, "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", @@ -17795,7 +18338,6 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", "dev": true, - "peer": true, "engines": { "node": ">=16" }, @@ -17863,7 +18405,6 @@ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "dev": true, - "peer": true, "dependencies": { "boolbase": "^1.0.0" }, @@ -17931,7 +18472,6 @@ "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -17949,7 +18489,6 @@ "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -17962,7 +18501,6 @@ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -17979,15 +18517,13 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, - "peer": true, "dependencies": { "ee-first": "1.1.1" }, @@ -18001,7 +18537,6 @@ "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.8" } @@ -18033,7 +18568,6 @@ "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", "dev": true, - "peer": true, "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", @@ -18052,7 +18586,6 @@ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, - "peer": true, "dependencies": { "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", @@ -18069,8 +18602,7 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/ospath": { "version": "1.2.2", @@ -18100,7 +18632,6 @@ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "p-limit": "^3.0.2" }, @@ -18152,7 +18683,6 @@ "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.0.tgz", "integrity": "sha512-JA6nkq6hKyWLLasXQXUrO4z8BUZGUt/LjlJxx8Gb2+2ntodU/SS63YZ8b0LUTbQ8ZB9iwOfhEPhg4ykKnn2KsA==", "dev": true, - "peer": true, "dependencies": { "@types/retry": "0.12.2", "is-network-error": "^1.0.0", @@ -18187,8 +18717,7 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/parent-module": { "version": "1.0.1", @@ -18206,7 +18735,6 @@ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz", "integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==", "dev": true, - "peer": true, "dependencies": { "asn1.js": "^4.10.1", "browserify-aes": "^1.2.0", @@ -18237,8 +18765,26 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "peer": true + ] + }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, "node_modules/parse-json": { "version": "5.2.0", @@ -18263,7 +18809,6 @@ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true, - "peer": true, "engines": { "node": ">= 0.8" } @@ -18272,8 +18817,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true, - "peer": true + "dev": true }, "node_modules/path-exists": { "version": "4.0.0", @@ -18342,8 +18886,7 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/path-type": { "version": "4.0.0", @@ -18360,7 +18903,6 @@ "integrity": "sha512-wfRLBZ0feWRhCIkoMB6ete7czJcnNnqRpcoWQBLqatqXXmelSRqfdDK4F3u9T2s2cXas/hQJcryI/4lAL+XTlA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "create-hash": "~1.1.3", "create-hmac": "^1.1.7", @@ -18379,7 +18921,6 @@ "integrity": "sha512-snRpch/kwQhcdlnZKYanNF1m0RDlrCdSKQaH87w1FCFPVPNCQ/Il9QJKAX2jVBZddRdaHBMC+zXa9Gw9tmkNUA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", @@ -18393,7 +18934,6 @@ "integrity": "sha512-0TROgQ1/SxE6KmxWSvXHvRj90/Xo1JvZShofnYF+f6ZsGtR4eES7WfrQzPalmyagfKZCXpVnitiRebZulWsbiw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "inherits": "^2.0.1" } @@ -18404,7 +18944,6 @@ "integrity": "sha512-J7f4wutN8mdbV08MJnXibYpCOPHR+yzy+iQ/AsjMv2j8cLavQ8VGagDFUwwTAdF8FmRKVeNpbTTEwNHCW1g94w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "hash-base": "^2.0.0", "inherits": "^2.0.1" @@ -18429,8 +18968,7 @@ "url": "https://feross.org/support" } ], - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/pcg": { "version": "1.1.0", @@ -18604,6 +19142,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -18618,7 +19157,6 @@ "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.7.0.tgz", "integrity": "sha512-MfcMpSUIaR/nNgeVS8AyvyDugXlADjN9AcV7e5rDfrF1wduIAGSkL4q2+wgrZgA3sHVAHLDO9FuauHhZYW2nBw==", "dev": true, - "peer": true, "dependencies": { "htmlparser2": "^8.0.0", "js-tokens": "^9.0.0", @@ -18633,21 +19171,18 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz", "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/postcss-media-query-parser": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", - "dev": true, - "peer": true + "dev": true }, "node_modules/postcss-modules-extract-imports": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", - "peer": true, "engines": { "node": "^10 || ^12 || >= 14" }, @@ -18659,7 +19194,6 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", - "peer": true, "dependencies": { "icss-utils": "^5.0.0", "postcss-selector-parser": "^6.0.2", @@ -18676,7 +19210,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", - "peer": true, "dependencies": { "postcss-selector-parser": "^6.0.4" }, @@ -18691,7 +19224,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "peer": true, "dependencies": { "icss-utils": "^5.0.0" }, @@ -18704,16 +19236,14 @@ }, "node_modules/postcss-resolve-nested-selector": { "version": "0.1.1", - "dev": true, - "license": "MIT", - "peer": true + "dev": true, + "license": "MIT" }, "node_modules/postcss-safe-parser": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", "dev": true, - "peer": true, "engines": { "node": ">=12.0" }, @@ -18744,7 +19274,6 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, "engines": { "node": ">=12.0" }, @@ -18756,6 +19285,7 @@ "version": "6.0.16", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -18767,8 +19297,7 @@ "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "peer": true + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, "node_modules/postcss-values-parser": { "version": "6.0.2", @@ -18840,7 +19369,6 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, - "peer": true, "engines": { "node": ">= 0.8.0" } @@ -18935,8 +19463,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, - "peer": true + "dev": true }, "node_modules/prompts": { "version": "2.4.2", @@ -18996,7 +19523,6 @@ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dev": true, - "peer": true, "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -19010,7 +19536,6 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true, - "peer": true, "engines": { "node": ">= 0.10" } @@ -19030,7 +19555,6 @@ "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", "dev": true, - "peer": true, "dependencies": { "bn.js": "^4.1.0", "browserify-rsa": "^4.0.0", @@ -19044,8 +19568,7 @@ "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/pump": { "version": "3.0.0", @@ -19095,7 +19618,6 @@ "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { "side-channel": "^1.1.0" }, @@ -19111,7 +19633,6 @@ "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", "dev": true, - "peer": true, "engines": { "node": ">=0.4.x" } @@ -19162,7 +19683,6 @@ "node_modules/randombytes": { "version": "2.1.0", "license": "MIT", - "peer": true, "dependencies": { "safe-buffer": "^5.1.0" } @@ -19172,7 +19692,6 @@ "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", "dev": true, - "peer": true, "dependencies": { "randombytes": "^2.0.5", "safe-buffer": "^5.1.0" @@ -19183,7 +19702,6 @@ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dev": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -19194,7 +19712,6 @@ "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", @@ -19211,7 +19728,6 @@ "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", @@ -19233,7 +19749,6 @@ "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.8" } @@ -19263,7 +19778,6 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", "dev": true, - "peer": true, "engines": { "node": ">= 14.16.0" }, @@ -19278,7 +19792,6 @@ "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "resolve": "^1.20.0" }, @@ -19290,15 +19803,13 @@ "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/regenerate-unicode-properties": { "version": "10.1.1", "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", "dev": true, - "peer": true, "dependencies": { "regenerate": "^1.4.2" }, @@ -19316,7 +19827,6 @@ "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", "dev": true, - "peer": true, "dependencies": { "@babel/runtime": "^7.8.4" } @@ -19343,7 +19853,6 @@ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", "dev": true, - "peer": true, "dependencies": { "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", @@ -19361,7 +19870,6 @@ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", "dev": true, - "peer": true, "dependencies": { "jsesc": "~0.5.0" }, @@ -19374,7 +19882,6 @@ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", "dev": true, - "peer": true, "bin": { "jsesc": "bin/jsesc" } @@ -19660,9 +20167,10 @@ } }, "node_modules/remark-rehype": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.0.tgz", - "integrity": "sha512-z3tJrAs2kIs1AqIIy6pzHmAHlF1hWQ+OdY4/hv+Wxe35EhyLKcajL33iUEn3ScxtFox9nUvRufR/Zre8Q08H/g==", + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", @@ -19823,7 +20331,6 @@ "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.5" } @@ -19947,7 +20454,6 @@ "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", "dev": true, - "peer": true, "engines": { "node": ">= 4" } @@ -19972,7 +20478,6 @@ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, - "peer": true, "dependencies": { "glob": "^7.1.3" }, @@ -19988,7 +20493,6 @@ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", "dev": true, - "peer": true, "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1" @@ -19999,7 +20503,6 @@ "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", "dev": true, - "peer": true, "engines": { "node": ">=18" }, @@ -20044,7 +20547,6 @@ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1", @@ -20062,8 +20564,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/safe-buffer": { "version": "5.1.2", @@ -20074,7 +20575,6 @@ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.3", @@ -20206,6 +20706,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -20239,15 +20740,13 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/selfsigned": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", "dev": true, - "peer": true, "dependencies": { "@types/node-forge": "^1.3.0", "node-forge": "^1" @@ -20273,7 +20772,6 @@ "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "dev": true, - "peer": true, "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -20298,7 +20796,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "dependencies": { "ms": "2.0.0" } @@ -20307,15 +20804,13 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/send/node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true, - "peer": true, "engines": { "node": ">= 0.8" } @@ -20324,8 +20819,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "license": "BSD-3-Clause", - "peer": true, "dependencies": { "randombytes": "^2.1.0" } @@ -20335,7 +20828,6 @@ "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", "dev": true, - "peer": true, "dependencies": { "accepts": "~1.3.4", "batch": "0.6.1", @@ -20354,7 +20846,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "dependencies": { "ms": "2.0.0" } @@ -20364,7 +20855,6 @@ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", "dev": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -20374,7 +20864,6 @@ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", "dev": true, - "peer": true, "dependencies": { "depd": "~1.1.2", "inherits": "2.0.3", @@ -20389,29 +20878,25 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/serve-index/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/serve-index/node_modules/setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/serve-index/node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", "dev": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -20421,7 +20906,6 @@ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "dev": true, - "peer": true, "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", @@ -20467,15 +20951,13 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/sha.js": { "version": "2.4.12", @@ -20483,7 +20965,6 @@ "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", "dev": true, "license": "(MIT AND BSD-3-Clause)", - "peer": true, "dependencies": { "inherits": "^2.0.4", "safe-buffer": "^5.2.1", @@ -20518,8 +20999,7 @@ "url": "https://feross.org/support" } ], - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/shallow-clone": { "version": "3.0.1", @@ -20527,7 +21007,6 @@ "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "kind-of": "^6.0.2" }, @@ -20541,7 +21020,6 @@ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -20551,7 +21029,6 @@ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", "dev": true, - "peer": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -20731,7 +21208,6 @@ "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", "dev": true, - "peer": true, "dependencies": { "faye-websocket": "^0.11.3", "uuid": "^8.3.2", @@ -20760,8 +21236,6 @@ "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "license": "MIT", - "peer": true, "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -20771,8 +21245,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -20789,15 +21261,13 @@ "node_modules/spdx-exceptions": { "version": "2.2.0", "dev": true, - "license": "CC-BY-3.0", - "peer": true + "license": "CC-BY-3.0" }, "node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, - "peer": true, "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" @@ -20806,15 +21276,13 @@ "node_modules/spdx-license-ids": { "version": "3.0.2", "dev": true, - "license": "CC0-1.0", - "peer": true + "license": "CC0-1.0" }, "node_modules/spdy": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", "dev": true, - "peer": true, "dependencies": { "debug": "^4.1.0", "handle-thing": "^2.0.0", @@ -20831,7 +21299,6 @@ "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", "dev": true, - "peer": true, "dependencies": { "debug": "^4.1.0", "detect-node": "^2.0.4", @@ -20935,8 +21402,7 @@ "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.4.tgz", "integrity": "sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/stack-utils": { "version": "2.0.6", @@ -20964,7 +21430,6 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true, - "peer": true, "engines": { "node": ">= 0.8" } @@ -20988,7 +21453,6 @@ "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", "dev": true, - "peer": true, "dependencies": { "inherits": "~2.0.4", "readable-stream": "^3.5.0" @@ -20999,7 +21463,6 @@ "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", "dev": true, - "peer": true, "dependencies": { "builtin-status-codes": "^3.0.0", "inherits": "^2.0.4", @@ -21084,7 +21547,6 @@ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -21102,7 +21564,6 @@ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -21117,7 +21578,6 @@ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -21127,6 +21587,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/stringify-object": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", @@ -21243,6 +21717,30 @@ "webpack": "^5.27.0" } }, + "node_modules/style-to-js": { + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.21.tgz", + "integrity": "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==", + "license": "MIT", + "dependencies": { + "style-to-object": "1.0.14" + } + }, + "node_modules/style-to-js/node_modules/inline-style-parser": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz", + "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", + "license": "MIT" + }, + "node_modules/style-to-js/node_modules/style-to-object": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz", + "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.7" + } + }, "node_modules/style-to-object": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.1.tgz", @@ -21314,7 +21812,6 @@ "resolved": "https://registry.npmjs.org/stylelint-config-html/-/stylelint-config-html-1.1.0.tgz", "integrity": "sha512-IZv4IVESjKLumUGi+HWeb7skgO6/g4VMuAYrJdlqQFndgbj6WJAXPhaysvBiXefX79upBdQVumgYcdd17gCpjQ==", "dev": true, - "peer": true, "engines": { "node": "^12 || >=14" }, @@ -21331,7 +21828,6 @@ "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-14.0.0.tgz", "integrity": "sha512-jSkx290CglS8StmrLp2TxAppIajzIBZKYm3IxT89Kg6fGlxbPiTiyH9PS5YUuVAFwaJLl1ikiXX0QWjI0jmgZQ==", "dev": true, - "peer": true, "engines": { "node": ">=18.12.0" }, @@ -21390,7 +21886,6 @@ "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-6.3.0.tgz", "integrity": "sha512-8OSpiuf1xC7f8kllJsBOFAOYp/mR/C1FXMVeOFjtJPw+AFvEmC93FaklHt7MlOqU4poxuQ1TkYMyfI0V+1SxjA==", "dev": true, - "peer": true, "dependencies": { "known-css-properties": "^0.30.0", "postcss-media-query-parser": "^0.2.3", @@ -21473,7 +21968,6 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, - "peer": true, "engines": { "node": ">=12" }, @@ -21484,15 +21978,13 @@ "node_modules/stylelint/node_modules/balanced-match": { "version": "2.0.0", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/stylelint/node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, - "peer": true, "dependencies": { "flat-cache": "^4.0.0" }, @@ -21505,7 +21997,6 @@ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, - "peer": true, "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" @@ -21519,7 +22010,6 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -21543,7 +22033,6 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, "engines": { "node": ">=18.0" }, @@ -21556,7 +22045,6 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", "dev": true, - "peer": true, "engines": { "node": ">=14" }, @@ -21569,7 +22057,6 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, - "peer": true, "dependencies": { "ansi-regex": "^6.0.1" }, @@ -21585,7 +22072,6 @@ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", "dev": true, - "peer": true, "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^4.0.1" @@ -21646,7 +22132,6 @@ "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", "dev": true, - "peer": true, "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" @@ -21660,7 +22145,6 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -21670,7 +22154,6 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -21692,13 +22175,12 @@ }, "node_modules/svg-tags": { "version": "1.0.0", - "dev": true, - "peer": true + "dev": true }, "node_modules/tabbable": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.3.0.tgz", - "integrity": "sha512-EIHvdY5bPLuWForiR/AN2Bxngzpuwn1is4asboytXtpTgsArc+WmSJKVLlhdh71u7jFcryDqB2A8lQvj78MkyQ==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.4.0.tgz", + "integrity": "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==", "license": "MIT" }, "node_modules/table": { @@ -21706,7 +22188,6 @@ "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", "dev": true, - "peer": true, "dependencies": { "ajv": "^8.0.1", "lodash.truncate": "^4.4.2", @@ -21723,7 +22204,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", "dev": true, - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", @@ -21739,8 +22219,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "peer": true + "dev": true }, "node_modules/tapable": { "version": "2.3.0", @@ -21785,11 +22264,9 @@ } }, "node_modules/terser": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", - "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", - "license": "BSD-2-Clause", - "peer": true, + "version": "5.31.6", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", + "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.15.0", @@ -21808,7 +22285,6 @@ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz", "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==", "license": "MIT", - "peer": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", @@ -21841,9 +22317,7 @@ "node_modules/terser/node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "license": "MIT", - "peer": true + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, "node_modules/test-exclude": { "version": "6.0.0", @@ -21862,15 +22336,13 @@ "node_modules/text-table": { "version": "0.2.0", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/thingies": { "version": "1.21.0", "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", "dev": true, - "peer": true, "engines": { "node": ">=10.18" }, @@ -21894,15 +22366,13 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/timers-browserify": { "version": "2.0.12", "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", "dev": true, - "peer": true, "dependencies": { "setimmediate": "^1.0.4" }, @@ -21955,6 +22425,7 @@ "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -22002,7 +22473,6 @@ "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "isarray": "^2.0.5", "safe-buffer": "^5.2.1", @@ -22017,8 +22487,7 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/to-buffer/node_modules/safe-buffer": { "version": "5.2.1", @@ -22039,8 +22508,7 @@ "url": "https://feross.org/support" } ], - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/to-regex-range": { "version": "5.0.1", @@ -22064,7 +22532,6 @@ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true, - "peer": true, "engines": { "node": ">=0.6" } @@ -22093,7 +22560,6 @@ "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz", "integrity": "sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==", "dev": true, - "peer": true, "engines": { "node": ">=10.0" }, @@ -22141,7 +22607,6 @@ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, - "peer": true, "engines": { "node": ">=16" }, @@ -22154,7 +22619,6 @@ "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.4.tgz", "integrity": "sha512-MLukxDHBl8OJ5Dk3y69IsKVFRA/6MwzEqBgh+OXMPB/OD01KQuWPFd1WAQP8a5PeSCAxfnkhiuWqfmFJzJQt9w==", "dev": true, - "peer": true, "dependencies": { "chalk": "^4.1.0", "enhanced-resolve": "^5.0.0", @@ -22174,7 +22638,6 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "peer": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -22190,7 +22653,6 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -22207,7 +22669,6 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -22219,15 +22680,13 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/ts-loader/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -22237,7 +22696,6 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -22245,6 +22703,15 @@ "node": ">=8" } }, + "node_modules/ts-md5": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ts-md5/-/ts-md5-2.0.1.tgz", + "integrity": "sha512-yF35FCoEOFBzOclSkMNEUbFQZuv89KEQ+5Xz03HrMSGUGB1+r+El+JiGOFwsP4p9RFNzwlrydYoTLvPOuICl9w==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/tsconfig": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz", @@ -22262,7 +22729,6 @@ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", "dev": true, - "peer": true, "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", @@ -22275,7 +22741,6 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, - "peer": true, "dependencies": { "minimist": "^1.2.0" }, @@ -22288,7 +22753,8 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true, - "license": "0BSD" + "license": "0BSD", + "peer": true }, "node_modules/tsx": { "version": "4.20.6", @@ -22314,8 +22780,7 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/tunnel": { "version": "0.0.6", @@ -22350,7 +22815,6 @@ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, - "peer": true, "dependencies": { "prelude-ls": "^1.2.1" }, @@ -22384,7 +22848,6 @@ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dev": true, - "peer": true, "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -22399,7 +22862,6 @@ "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", @@ -22414,7 +22876,6 @@ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "for-each": "^0.3.3", @@ -22433,7 +22894,6 @@ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", "dev": true, - "peer": true, "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", @@ -22453,7 +22913,6 @@ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "for-each": "^0.3.3", @@ -22467,8 +22926,9 @@ "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -22497,7 +22957,6 @@ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -22531,7 +22990,6 @@ "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -22541,7 +22999,6 @@ "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "dev": true, - "peer": true, "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" @@ -22555,7 +23012,6 @@ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -22565,7 +23021,6 @@ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -22744,7 +23199,6 @@ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true, - "peer": true, "engines": { "node": ">= 0.8" } @@ -22801,7 +23255,6 @@ "resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz", "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==", "dev": true, - "peer": true, "dependencies": { "punycode": "^1.4.1", "qs": "^6.12.3" @@ -22836,15 +23289,13 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/util": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", "dev": true, - "peer": true, "dependencies": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", @@ -22862,7 +23313,6 @@ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "dev": true, - "peer": true, "engines": { "node": ">= 0.4.0" } @@ -22895,7 +23345,6 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true, - "peer": true, "engines": { "node": ">= 0.8" } @@ -22968,14 +23417,14 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/vue": { "version": "2.7.16", "resolved": "https://registry.npmjs.org/vue/-/vue-2.7.16.tgz", "integrity": "sha512-4gCtFXaAA3zYZdTp5s4Hl2sozuySsgz4jy1EnpBHNfpMa9dK1ZCG7viqBPCwXtmgc8nHqUsAu3G4gtmXkkY3Sw==", "deprecated": "Vue 2 has reached EOL and is no longer actively maintained. See https://v2.vuejs.org/eol/ for more details.", + "peer": true, "dependencies": { "@vue/compiler-sfc": "2.7.16", "csstype": "^3.1.0" @@ -23027,7 +23476,6 @@ "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz", "integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==", "dev": true, - "peer": true, "dependencies": { "debug": "^4.3.4", "eslint-scope": "^7.1.1", @@ -23052,7 +23500,6 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, - "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -23069,7 +23516,6 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "peer": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -23082,7 +23528,6 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "peer": true, "engines": { "node": ">=4.0" } @@ -23116,6 +23561,7 @@ "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.11.1.tgz", "integrity": "sha512-0iw4VchYLePqJfJu9s62ACWUXeSqM30SQqlIftbYWM3C+jpPcEHKSPUZBLjSF9au4HTHQ/naF6OGnO3Q/qGR3Q==", "license": "MIT", + "peer": true, "dependencies": { "@vue/component-compiler-utils": "^3.1.0", "hash-sum": "^1.0.2", @@ -23159,7 +23605,8 @@ "node_modules/vue-router": { "version": "3.6.5", "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.6.5.tgz", - "integrity": "sha512-VYXZQLtjuvKxxcshuRAwjHnciqZVoXAjTjcqBTz4rKc8qih9g9pI3hbDjmqXaHdgL3v8pV6P8Z335XvHzESxLQ==" + "integrity": "sha512-VYXZQLtjuvKxxcshuRAwjHnciqZVoXAjTjcqBTz4rKc8qih9g9pI3hbDjmqXaHdgL3v8pV6P8Z335XvHzESxLQ==", + "peer": true }, "node_modules/vue-smooth-dnd": { "version": "0.8.1", @@ -23183,6 +23630,7 @@ "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz", "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==", "dev": true, + "peer": true, "dependencies": { "de-indent": "^1.0.2", "he": "^1.2.0" @@ -23207,6 +23655,7 @@ "node_modules/vuex": { "version": "3.6.2", "license": "MIT", + "peer": true, "peerDependencies": { "vue": "^2.0.0" } @@ -23252,7 +23701,6 @@ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", "license": "MIT", - "peer": true, "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -23266,7 +23714,6 @@ "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", "dev": true, - "peer": true, "dependencies": { "minimalistic-assert": "^1.0.0" } @@ -23482,7 +23929,6 @@ "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=18" } @@ -23492,7 +23938,6 @@ "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", "dev": true, - "peer": true, "dependencies": { "colorette": "^2.0.10", "memfs": "^4.6.0", @@ -23523,7 +23968,6 @@ "integrity": "sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/bonjour": "^3.5.13", "@types/connect-history-api-fallback": "^1.5.4", @@ -23582,7 +24026,6 @@ "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -23595,7 +24038,6 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, - "peer": true, "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -23620,7 +24062,6 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, - "peer": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -23634,7 +24075,6 @@ "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "clone-deep": "^4.0.1", "flat": "^5.0.2", @@ -23649,7 +24089,6 @@ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", "license": "MIT", - "peer": true, "engines": { "node": ">=10.13.0" } @@ -23659,7 +24098,6 @@ "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", "dev": true, - "peer": true, "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", @@ -23674,7 +24112,6 @@ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", "dev": true, - "peer": true, "engines": { "node": ">=0.8.0" } @@ -23694,7 +24131,6 @@ "version": "1.3.1", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "isexe": "^2.0.0" }, @@ -23764,8 +24200,7 @@ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/wrap-ansi": { "version": "7.0.0", @@ -23895,7 +24330,6 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "dev": true, - "peer": true, "engines": { "node": ">=10.0.0" }, @@ -23917,7 +24351,6 @@ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", "dev": true, - "peer": true, "engines": { "node": ">=12" } @@ -23927,7 +24360,6 @@ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "dev": true, - "peer": true, "engines": { "node": ">=0.4" } @@ -23993,6 +24425,16 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } } } } diff --git a/package.json b/package.json index f46653ef52..7dfdd8742b 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "@nextcloud/l10n": "^3.4.0", "@nextcloud/moment": "^1.3.5", "@nextcloud/notify_push": "^1.3.0", + "@nextcloud/password-confirmation": "^6.0.2", "@nextcloud/router": "^3.0.1", "@nextcloud/vue": "^8.34.0", "blueimp-md5": "^2.19.0", diff --git a/src/components/DeckAppSettings.vue b/src/components/DeckAppSettings.vue index fca5aacd96..19581c048a 100644 --- a/src/components/DeckAppSettings.vue +++ b/src/components/DeckAppSettings.vue @@ -36,6 +36,11 @@

{{ t('deck', 'Users outside of those groups will not be able to create their own boards, but will still be able to work on boards that have been shared with them.') }}

+ + + @@ -71,6 +76,8 @@ import NcFormBoxSwitch from '@nextcloud/vue/components/NcFormBoxSwitch' import NcHotkeyList from '@nextcloud/vue/components/NcHotkeyList' import NcHotkey from '@nextcloud/vue/components/NcHotkey' import { NcSelect } from '@nextcloud/vue' +import { confirmPassword } from '@nextcloud/password-confirmation' +import '@nextcloud/password-confirmation/style.css' // Required for dialog styles import axios from '@nextcloud/axios' import { generateOcsUrl } from '@nextcloud/router' @@ -121,6 +128,18 @@ export default { this.$store.dispatch('setConfig', { cardIdBadge: newValue }) }, }, + federationEnabled: { + get() { + const value = this.$store.getters.config('federationEnabled') + console.log(value) + return value + }, + set(newValue) { + confirmPassword().then(() => { + this.$store.dispatch('setConfig', { federationEnabled: newValue }) + }) + }, + }, configCalendar: { get() { return this.$store.getters.config('calendar') From 7b0f5909cac8d80bd32111eaaa6171e9a290a869 Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Mon, 9 Feb 2026 14:37:56 +0100 Subject: [PATCH 13/24] feat: feature flag for federation Signed-off-by: grnd-alt --- lib/Controller/NewBoardController.php | 2 +- lib/Db/Board.php | 2 +- .../FederationDisabledException.php | 16 ++++++++++ lib/Federation/DeckFederationProvider.php | 17 +++++----- lib/Federation/DeckFederationProxy.php | 2 +- lib/Listeners/AclCreatedRemovedListener.php | 7 ++++ lib/Middleware/FederationMiddleware.php | 8 ++++- lib/Notification/Notifier.php | 1 + lib/Service/ExternalBoardService.php | 32 +++++++++++++------ lib/Service/PermissionService.php | 8 ++--- 10 files changed, 70 insertions(+), 25 deletions(-) create mode 100644 lib/Exceptions/FederationDisabledException.php diff --git a/lib/Controller/NewBoardController.php b/lib/Controller/NewBoardController.php index 2f69637c09..fd44470aa0 100644 --- a/lib/Controller/NewBoardController.php +++ b/lib/Controller/NewBoardController.php @@ -38,7 +38,7 @@ public function index(): DataResponse { #[RequestHeader(name: 'x-nextcloud-federation', description: 'Set to 1 when the request is performed by another Nextcloud Server to indicate a federation request', indirect: true)] public function read(int $boardId): DataResponse { // Board on this instance -> get it from database - $localBoard = $this->boardService->find($boardId, true, true, $this->request->getParam('accessToken')); + $localBoard = $this->boardService->find($boardId, true, true); if($localBoard->getExternalId() !== null) { return $this->externalBoardService->getExternalBoardFromRemote($localBoard); } diff --git a/lib/Db/Board.php b/lib/Db/Board.php index 1b4018cf7d..a0663dbd3d 100644 --- a/lib/Db/Board.php +++ b/lib/Db/Board.php @@ -27,7 +27,7 @@ * @method void setShareToken(string $shareToken) * @method string getShareToken() * @method void setExternalId(int $externalId) - * @method int getExternalId() + * @method int | null getExternalId() */ class Board extends RelationalEntity { protected $title; diff --git a/lib/Exceptions/FederationDisabledException.php b/lib/Exceptions/FederationDisabledException.php new file mode 100644 index 0000000000..1a25694aef --- /dev/null +++ b/lib/Exceptions/FederationDisabledException.php @@ -0,0 +1,16 @@ +notificationManager->createNotification(); - $notification->setApp('deck'); - $notification->setUser($share->getShareWith()); - $notification->setDateTime(new \DateTime()); - $notification->setObject('remote-board-shared', (string) rand(0,9999999)); - $notification->setSubject('remote-board-shared',[$share->getResourceName(), $share->getSharedBy()]); - - $this->notificationManager->notify($notification); $externalBoard = new Board(); $externalBoard->setTitle($share->getResourceName()); @@ -55,6 +47,15 @@ public function shareReceived(ICloudFederationShare $share): string { $this->aclMapper->insert($acl); $this->changeHelper->boardChanged($insertedBoard->getId()); + + $notification = $this->notificationManager->createNotification(); + $notification->setApp('deck'); + $notification->setUser($share->getShareWith()); + $notification->setDateTime(new \DateTime()); + $notification->setObject('remote-board-shared', $insertedBoard->getId()); + $notification->setSubject('remote-board-shared',[$share->getResourceName(), $share->getSharedBy()]); + + $this->notificationManager->notify($notification); return 'PLACE_HOLDER_ID'; } diff --git a/lib/Federation/DeckFederationProxy.php b/lib/Federation/DeckFederationProxy.php index 7055cd95a0..5f241d1b9e 100644 --- a/lib/Federation/DeckFederationProxy.php +++ b/lib/Federation/DeckFederationProxy.php @@ -124,7 +124,7 @@ public function getOCSData(IResponse $response, array $allowedStatusCodes = [Htt } } catch (\Throwable $e) { $this->logger->error('Error parsing JSON response: ' . ($content ?? 'no-data'), ['exception' => $e]); - throw new CannotReachRemoteException('Error parsing JSON response', $e->getCode(), $e); + throw new \Exception('Error parsing JSON response', $e->getCode(), $e); } return $responseData['ocs']['data'] ?? []; diff --git a/lib/Listeners/AclCreatedRemovedListener.php b/lib/Listeners/AclCreatedRemovedListener.php index dbf9f85e4c..763214f06c 100644 --- a/lib/Listeners/AclCreatedRemovedListener.php +++ b/lib/Listeners/AclCreatedRemovedListener.php @@ -60,6 +60,13 @@ public function handle(Event $event): void { break; default: $user = $this->userManager->get($acl->getParticipant()); + + // for federated participants userManager might return null + // disabling this for now as attachments for federated shares are not supported yet + // @TODO: add event dispatching for federated shares + if (is_null($user)) { + break; + } $this->eventDispatcher->dispatchTyped(new UserShareAccessUpdatedEvent($user)); break; } diff --git a/lib/Middleware/FederationMiddleware.php b/lib/Middleware/FederationMiddleware.php index 2a7bf4855b..850b7ec22a 100644 --- a/lib/Middleware/FederationMiddleware.php +++ b/lib/Middleware/FederationMiddleware.php @@ -2,6 +2,7 @@ namespace OCA\Deck\Middleware; +use OCA\Deck\Service\ConfigService; use OCP\AppFramework\Middleware; use OCP\IRequest; use OCA\Deck\Service\PermissionService; @@ -11,10 +12,15 @@ class FederationMiddleware extends Middleware { public function __construct( private LoggerInterface $logger, private PermissionService $permissionService, - private IRequest $request + private IRequest $request, + private ConfigService $configService, + ) {} public function beforeController($controller, $methodName) { + if(!$this->configService->get("federationEnabled")) { + return; + } $accessToken = $this->request->getHeader('deck-federation-accesstoken'); if ($accessToken) { $this->permissionService->setAccessToken($accessToken); diff --git a/lib/Notification/Notifier.php b/lib/Notification/Notifier.php index bebc47e9da..15c43c8546 100644 --- a/lib/Notification/Notifier.php +++ b/lib/Notification/Notifier.php @@ -240,6 +240,7 @@ public function prepare(INotification $notification, string $languageCode): INot $notification->setParsedSubject( $l->t('The remote board %s has been shared with you by %s', [$params[0], $federationOwnerDisplayName]) ); + $notification->setLink($this->getBoardUrl($boardId)); break; } return $notification; diff --git a/lib/Service/ExternalBoardService.php b/lib/Service/ExternalBoardService.php index 570b433db1..b571a3ed91 100644 --- a/lib/Service/ExternalBoardService.php +++ b/lib/Service/ExternalBoardService.php @@ -2,9 +2,9 @@ namespace OCA\Deck\Service; +use OCA\Deck\Exceptions\FederationDisabledException; use OCP\AppFramework\Http\DataResponse; use OCA\Deck\Db\Board; -use OCA\Deck\Db\Card; use OCA\Deck\Federation\DeckFederationProxy; use OCP\Federation\ICloudIdManager; use OCP\IUserManager; @@ -14,25 +14,36 @@ public function __construct( private IUserManager $userManager, private ICloudIdManager $cloudIdManager, private DeckFederationProxy $proxy, + private ConfigService $configService, private ?string $userId, ) { } + private function ensureFederationEnabled(): void { + if (!$this->configService->get('federationEnabled')) { + throw new FederationDisabledException(); + } + } + public function getExternalBoardFromRemote(Board $localBoard):DataResponse { + $this->ensureFederationEnabled(); $shareToken = $localBoard->getShareToken(); $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); $url = $ownerCloudId->getRemote() . "/ocs/v2.php/apps/deck/api/v1.0/board/".$localBoard->getExternalId(); $resp = $this->proxy->get($participantCloudId->getId(), $shareToken, $url); - return new DataResponse($this->LocalizeRemoteBoard($this->proxy->getOcsData($resp), $localBoard)); + $ocs = $this->proxy->getOCSData($resp); + return new DataResponse($this->LocalizeRemoteBoard($ocs, $localBoard)); } public function getExternalStacksFromRemote(Board $localBoard):DataResponse { + $this->ensureFederationEnabled(); $shareToken = $localBoard->getShareToken(); $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); $url = $ownerCloudId->getRemote() . "/ocs/v2.php/apps/deck/api/v1.0/stacks/".$localBoard->getExternalId(); $resp = $this->proxy->get($participantCloudId->getId(), $shareToken, $url); - return new DataResponse($this->LocalizeRemoteStacks($this->proxy->getOcsData($resp), $localBoard)); + $ocs = $this->proxy->getOCSData($resp); + return new DataResponse($this->LocalizeRemoteStacks($ocs, $localBoard)); } public function LocalizeRemoteStacks(array $stacks, Board $localBoard) { @@ -59,6 +70,7 @@ public function createCardOnRemote( ?array $users = [], ?int $boardId = null ): array { + $this->ensureFederationEnabled(); $shareToken = $localBoard->getShareToken(); $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); @@ -83,6 +95,7 @@ public function createStackOnRemote( string $title, int $order = 0, ): array { + $this->ensureFederationEnabled(); $shareToken = $localBoard->getShareToken(); $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); @@ -98,11 +111,12 @@ public function createStackOnRemote( } public function deleteStackOnRemote(Board $localBoard, int $stackId): array { - $shareToken = $localBoard->getShareToken(); - $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); - $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); - $url = $ownerCloudId->getRemote() . "/ocs/v2.php/apps/deck/api/v1.0/stacks/" . $stackId; - $resp = $this->proxy->delete($participantCloudId->getId(), $shareToken, $url, []); - return $this->proxy->getOcsData($resp); + $this->ensureFederationEnabled(); + $shareToken = $localBoard->getShareToken(); + $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); + $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); + $url = $ownerCloudId->getRemote() . "/ocs/v2.php/apps/deck/api/v1.0/stacks/" . $stackId; + $resp = $this->proxy->delete($participantCloudId->getId(), $shareToken, $url, []); + return $this->proxy->getOcsData($resp); } } diff --git a/lib/Service/PermissionService.php b/lib/Service/PermissionService.php index 8b6729d465..2f4170be5c 100644 --- a/lib/Service/PermissionService.php +++ b/lib/Service/PermissionService.php @@ -64,8 +64,8 @@ public function setAccessToken(string $token) { * * @return array */ - public function getPermissions(int $boardId, ?string $userId = null, bool $allowDeleted = false, ?string $accessToken = null): array { - if ($userId === null && $accessToken === null) { + public function getPermissions(int $boardId, ?string $userId = null, bool $allowDeleted = false): array { + if ($userId === null) { $userId = $this->userId; } @@ -140,7 +140,7 @@ public function matchPermissions(Board $board) { * * @throws NoPermissionException */ - public function checkPermission(?IPermissionMapper $mapper, $id, int $permission, $userId = null, bool $allowDeletedCard = false, bool $allowDeletedBoard = false, $accessToken = null): bool { + public function checkPermission(?IPermissionMapper $mapper, $id, int $permission, $userId = null, bool $allowDeletedCard = false, bool $allowDeletedBoard = false): bool { $boardId = (int)$id; if ($mapper instanceof IPermissionMapper && !($mapper instanceof BoardMapper)) { $boardId = $mapper->findBoardId($id); @@ -150,7 +150,7 @@ public function checkPermission(?IPermissionMapper $mapper, $id, int $permission throw new NoPermissionException('Permission denied'); } - $permissions = $this->getPermissions($boardId, $userId, $allowDeletedBoard, $accessToken); + $permissions = $this->getPermissions($boardId, $userId, $allowDeletedBoard); if ($permissions[$permission] === true) { if (!$allowDeletedCard && $mapper instanceof CardMapper) { From 4de58982647ecc56a799757e3506bcd2b576248e Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Tue, 10 Feb 2026 09:10:40 +0100 Subject: [PATCH 14/24] update acl on federated shares Signed-off-by: grnd-alt --- lib/AppInfo/Application.php | 11 ++++--- lib/Controller/NewBoardController.php | 12 +++++++ lib/Db/BoardMapper.php | 12 +++++++ lib/Federation/DeckFederationProvider.php | 33 ++++++++++++++++++- .../ResourceTypeRegisterListener.php | 1 + lib/Service/BoardService.php | 20 +++++++++++ 6 files changed, 84 insertions(+), 5 deletions(-) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 74d4c9f9ea..ee93331071 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -36,6 +36,7 @@ use OCA\Deck\Listeners\ParticipantCleanupListener; use OCA\Deck\Listeners\ResourceAdditionalScriptsListener; use OCA\Deck\Listeners\ResourceListener; +use OCA\Deck\Listeners\ResourceTypeRegisterListener; use OCA\Deck\Middleware\DefaultBoardMiddleware; use OCA\Deck\Middleware\ExceptionMiddleware; use OCA\Deck\Middleware\FederationMiddleware; @@ -62,6 +63,7 @@ use OCP\Comments\CommentsEntityEvent; use OCP\Comments\CommentsEvent; use OCP\EventDispatcher\IEventDispatcher; +use OCP\Federation\ICloudFederationProvider; use OCP\Federation\ICloudFederationProviderManager; use OCP\Group\Events\GroupDeletedEvent; use OCP\IConfig; @@ -72,7 +74,7 @@ use OCP\User\Events\UserDeletedEvent; use OCP\Util; use Psr\Container\ContainerInterface; -use ResourceTypeRegisterListener; + class Application extends App implements IBootstrap { public const APP_ID = 'deck'; @@ -108,7 +110,7 @@ public function boot(IBootContext $context): void { $context->injectFn(function (Listener $listener, IEventDispatcher $eventDispatcher) { $listener->register($eventDispatcher); }); - $context->injectFn($this->registerCloudFederationProvider(...)); + $context->injectFn([$this, 'registerCloudFederationProviderManager']); } public function register(IRegistrationContext $context): void { @@ -204,13 +206,14 @@ protected function registerCollaborationResources(IProviderManager $resourceMana $resourceManager->registerResourceProvider(ResourceProviderCard::class); } - public function registerCloudFederationProvider( + public function registerCloudFederationProviderManager( + IConfig $config, ICloudFederationProviderManager $manager, ): void { $manager->addCloudFederationProvider( DeckFederationProvider::PROVIDER_ID, "Deck Federation", - static fn () => Server::get(DeckFederationProvider::class), + static fn (): ICloudFederationProvider => Server::get(DeckFederationProvider::class), ); } } diff --git a/lib/Controller/NewBoardController.php b/lib/Controller/NewBoardController.php index fd44470aa0..8782251c32 100644 --- a/lib/Controller/NewBoardController.php +++ b/lib/Controller/NewBoardController.php @@ -71,4 +71,16 @@ public function stacks(int $boardId): DataResponse{ public function addAcl(int $boardId, int $type, $participant, bool $permissionEdit, bool $permissionShare, bool $permissionManage, ?string $remote = null): DataResponse { return new DataResponse($this->boardService->addAcl($boardId, $type, $participant, $permissionEdit, $permissionShare, $permissionManage, $remote)); } + + /** + * @NoAdminRequired + * @param $id + * @param $permissionEdit + * @param $permissionShare + * @param $permissionManage + * @return \OCP\AppFramework\Db\Entity + */ + public function updateAcl($id, $permissionEdit, $permissionShare, $permissionManage) { + return $this->boardService->updateAcl($id, $permissionEdit, $permissionShare, $permissionManage); + } } diff --git a/lib/Db/BoardMapper.php b/lib/Db/BoardMapper.php index 8de4836e7a..a445fd3250 100644 --- a/lib/Db/BoardMapper.php +++ b/lib/Db/BoardMapper.php @@ -127,6 +127,18 @@ public function findBoardIds(string $userId): array { $result->closeCursor(); return array_unique(array_merge($ownerBoards, $sharedBoards)); } + /** + * @param int $externalId + * @return Board[] + */ + public function findByExternalId(int $externalId): array { + $qb = $this->db->getQueryBuilder(); + $qb->select('*') + ->from('deck_boards') + ->where($qb->expr()->eq('external_id', $qb->createNamedParameter($externalId, IQueryBuilder::PARAM_INT))) + ->orderBy('id'); + return $this->findEntities($qb); + } public function findAllForUser(string $userId, ?int $since = null, bool $includeArchived = true, ?int $before = null, ?string $term = null): array { diff --git a/lib/Federation/DeckFederationProvider.php b/lib/Federation/DeckFederationProvider.php index c61fffd335..f9f344e286 100644 --- a/lib/Federation/DeckFederationProvider.php +++ b/lib/Federation/DeckFederationProvider.php @@ -6,6 +6,7 @@ use OCA\Deck\Db\BoardMapper; use OCA\Deck\Db\AclMapper; use OCA\Deck\Db\ChangeHelper; +use OCP\Common\Exception\NotFoundException; use OCP\Federation\ICloudFederationProvider; use OCP\Federation\ICloudFederationShare; use OCP\Federation\ICloudIdManager; @@ -16,7 +17,7 @@ class DeckFederationProvider implements ICloudFederationProvider{ public const PROVIDER_ID = 'deck'; public function __construct( - private readonly ICloudIdmanager $cloudIdManager, + private readonly ICloudIdManager $cloudIdManager, private INotificationManager $notificationManager, private BoardMapper $boardMapper, private AclMapper $aclMapper, @@ -60,6 +61,36 @@ public function shareReceived(ICloudFederationShare $share): string { } public function notificationReceived($notificationType, $providerId, $notification): array { + switch ($notificationType) { + case "update-permissions": + $localBoards = $this->boardMapper->findByExternalId($providerId); + foreach ($localBoards as $board) { + if ($board->getShareToken() === $notification["sharedSecret"]) { + $localBoard = $board; + } + } + if (!isset($localBoard)) { + throw new NotFoundException("Board not found for provider ID: " . $providerId); + } + $localParticipant = $this->cloudIdManager->resolveCloudId($notification[0]["participant"])->getUser(); + $acls = $this->aclMapper->findAll($localBoard->getId()); + foreach ($acls as $acl) { + if ($acl->getParticipant() === $localParticipant) { + $localAcl = $acl; + break; + } + } + if (!isset($localAcl)) { + throw new NotFoundException("ACL entry not found for participant: " . $localParticipant); + } + $acl->setPermissionEdit($notification[0]["permissionEdit"]); + $acl->setPermissionManage($notification[0]["permissionManage"]); + $acl->setPermissionShare($notification[0]["permissionShare"]); + $this->aclMapper->update($acl); + break; + default: + throw new Exception("Unknown notification type: " . $notificationType); + } return []; } diff --git a/lib/Listeners/ResourceTypeRegisterListener.php b/lib/Listeners/ResourceTypeRegisterListener.php index 21c9898463..66de2c1a1f 100644 --- a/lib/Listeners/ResourceTypeRegisterListener.php +++ b/lib/Listeners/ResourceTypeRegisterListener.php @@ -1,4 +1,5 @@ aclMapper->update($acl); $this->changeHelper->boardChanged($acl->getBoardId()); + if($acl->getType() === Acl::PERMISSION_TYPE_REMOTE) { + $notification = $this->federationFactory->getCloudFederationNotification(); + if (!$notification instanceof ICloudFederationNotification) { + throw new \InvalidArgumentException('Invalid notification type'); + } + + $payload = [ + $acl->jsonSerialize(), + "sharedSecret" => $acl->getToken(), + ]; + + $notification->setMessage("update-permissions", "deck", $acl->getBoardId(), $payload); + + $url = $this->cloudIdManager->resolveCloudId($acl->getParticipant()); + $resp = $this->cloudFederationProviderManager->sendCloudNotification($url->getRemote(), $notification); + } + $this->eventDispatcher->dispatchTyped(new AclUpdatedEvent($acl)); return $acl; From fd87c52eec37eb0d51be1b13c44f995c48e011a6 Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Tue, 10 Feb 2026 10:52:48 +0100 Subject: [PATCH 15/24] chore: apply cs:fix Signed-off-by: grnd-alt --- .php-cs-fixer.cache | 1 + appinfo/routes.php | 4 +- lib/AppInfo/Application.php | 5 +- lib/Controller/NewBoardController.php | 18 ++-- lib/Controller/NewCardController.php | 13 ++- lib/Controller/NewStackController.php | 12 +-- lib/Controller/PageController.php | 2 +- lib/Db/AclMapper.php | 2 +- .../FederationDisabledException.php | 2 +- lib/Federation/DeckFederationProvider.php | 31 +++---- lib/Federation/DeckFederationProxy.php | 84 +++++++++---------- .../ResourceTypeRegisterListener.php | 13 ++- lib/Middleware/FederationMiddleware.php | 26 +++--- .../Version11001Date20251009165313.php | 28 +++---- .../Version11001Date20251020122010.php | 2 +- lib/Service/BoardService.php | 16 ++-- lib/Service/ConfigService.php | 2 +- lib/Service/ExternalBoardService.php | 28 +++---- lib/Service/PermissionService.php | 4 +- 19 files changed, 145 insertions(+), 148 deletions(-) create mode 100644 .php-cs-fixer.cache diff --git a/.php-cs-fixer.cache b/.php-cs-fixer.cache new file mode 100644 index 0000000000..2b0df0027d --- /dev/null +++ b/.php-cs-fixer.cache @@ -0,0 +1 @@ +{"php":"8.5.1","version":"3.93.0","indent":"\t","lineEnding":"\n","rules":{"encoding":true,"full_opening_tag":true,"blank_line_after_namespace":true,"braces_position":{"allow_single_line_anonymous_functions":false},"class_definition":true,"constant_case":true,"control_structure_braces":true,"control_structure_continuation_position":true,"elseif":true,"function_declaration":{"closure_function_spacing":"one"},"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":{"on_multiline":"ignore"},"modifier_keywords":{"elements":["method","property"]},"no_break_comment":true,"no_closing_tag":true,"no_multiple_statements_per_line":true,"no_space_around_double_colon":true,"no_spaces_after_function_name":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":true,"single_import_per_statement":true,"single_line_after_imports":true,"single_space_around_construct":{"constructs_followed_by_a_single_space":["abstract","as","case","catch","class","do","else","elseif","final","for","foreach","function","if","interface","namespace","private","protected","public","static","switch","trait","try","use_lambda","while"],"constructs_preceded_by_a_single_space":["as","else","elseif","use_lambda"]},"spaces_inside_parentheses":true,"statement_indentation":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"align_multiline_comment":true,"array_indentation":true,"array_syntax":true,"binary_operator_spaces":{"default":"single_space"},"blank_line_after_opening_tag":true,"cast_spaces":{"space":"none"},"concat_space":{"spacing":"one"},"curly_braces_position":{"classes_opening_brace":"same_line","functions_opening_brace":"same_line"},"list_syntax":true,"lowercase_cast":true,"method_chaining_indentation":true,"no_leading_import_slash":true,"no_short_bool_cast":true,"no_spaces_inside_parenthesis":true,"no_unused_imports":true,"no_whitespace_in_blank_line":true,"nullable_type_declaration_for_default_null_value":true,"nullable_type_declaration":{"syntax":"question_mark"},"operator_linebreak":{"position":"beginning"},"ordered_imports":{"imports_order":["class","function","const"],"sort_algorithm":"alpha"},"phpdoc_align":{"align":"left"},"phpdoc_single_line_var_spacing":true,"phpdoc_var_annotation_correct_order":true,"short_scalar_cast":true,"single_quote":{"strings_containing_single_quote_chars":false},"trailing_comma_in_multiline":{"elements":["parameters"]},"types_spaces":{"space":"none","space_multiple_catch":"none"},"type_declaration_spaces":{"elements":["function","property"]},"visibility_required":{"elements":["property","method","const"]},"yoda_style":{"equal":false,"identical":false,"less_and_greater":false},"PhpCsFixerCustomFixers\/multiline_promoted_properties":true},"ruleCustomisationPolicyVersion":"null-policy","hashes":{"appinfo\/autoload.php":"c9887cd20064590621418f687e8be54e","appinfo\/routes.php":"2b63050ede35d9789d6556fd0ce37fa0","lib\/Activity\/SettingBase.php":"c2d2f5d8e5e27228972cd92f2f75ac7e","lib\/Activity\/SettingChanges.php":"faad9a6994b2a9f84ccf9f4660cddfad","lib\/Activity\/SettingDescription.php":"ab9a2dbb19d2efc490fd5a66ee789a88","lib\/Activity\/ChangeSet.php":"0449998876a513c237d7d2bcddfb9806","lib\/Activity\/DeckProvider.php":"337993875edd981a9cd213362be1231e","lib\/Activity\/ActivityManager.php":"7b3cc029cc1b454c4fb9e26a3df75311","lib\/Activity\/Filter.php":"ed0eeef85d2bf56ea9acea3ea036659a","lib\/Activity\/SettingComment.php":"ac157bc7ca99333bbe635d9d241714a2","lib\/AppInfo\/Application.php":"06f00c88cd6f9a3155aa2eefcb804623","lib\/Cache\/AttachmentCacheHelper.php":"2ef9d1b9cdf7ff6096a08c6b18e12aca","lib\/Collaboration\/Resources\/ResourceProvider.php":"76760e0096dfc6b8df8a8d3372654da8","lib\/Collaboration\/Resources\/ResourceProviderCard.php":"4a7fda5e0cc9c0a4273df9ed9bb45dde","lib\/Command\/BoardImport.php":"9aa00bc87e064636e2706294aa554a34","lib\/Command\/TransferOwnership.php":"0e7fd056889078acea1568914e5c52a2","lib\/Command\/UserExport.php":"8d5b3e3b50cca2b33bc6f11092d75d8b","lib\/Command\/CalendarToggle.php":"073345ab4f3a8ea6044055dc6e43d2cc","lib\/Controller\/AttachmentApiV11Controller.php":"bae1746ee4440ae5ca978d6febc7d535","lib\/Controller\/SessionController.php":"0b12c7648cd7067911bfa6ec0c4083b8","lib\/Controller\/AttachmentApiController.php":"ea82a8566eaba6beecb60cdaad937ff8","lib\/Controller\/AttachmentController.php":"b9f3b343fac1955f40f0204517e2cd55","lib\/Controller\/BoardApiController.php":"3b3d0237e88ade2891628880ed11f36d","lib\/Controller\/BoardImportApiController.php":"375fd366478cb49037525daddefd27e0","lib\/Controller\/CardApiController.php":"36b99ae92d448112a7dcb2f7a19110ef","lib\/Controller\/CardController.php":"5a44d774cd65e8608d4118b19315f39b","lib\/Controller\/CommentsApiController.php":"13e4305002931c1cfa824b9ccc869c04","lib\/Controller\/ConfigController.php":"38e9e3b3131e3660aa810cd7f8e76a96","lib\/Controller\/LabelApiController.php":"f6347352e4dc9c3cb24c18f1236d1643","lib\/Controller\/LabelController.php":"08dd8f96f433b060d8a3b5414a42f359","lib\/Controller\/OverviewApiController.php":"d84e404678551275579ee74d5bd438e9","lib\/Controller\/SearchController.php":"50de19c4ad2f4174299707d743b9424e","lib\/Controller\/StackApiController.php":"a993aae2e4539564bf188c639c0c31fa","lib\/Controller\/StackController.php":"a81231f4ff0155be214c1b82baa6c13b","lib\/Controller\/BoardController.php":"7fed545ed84aa631377e35ff99b53a0e","lib\/Controller\/NewBoardController.php":"d833d2ed02195f6012a5ef3dd4bda86d","lib\/Controller\/NewCardController.php":"0eb4e29be97a17151f8e2f0fbc8c72ba","lib\/Controller\/NewStackController.php":"aa81fde054ea19aa61d425e227df6db2","lib\/Controller\/PageController.php":"326118672c68617f201f119e68096293","lib\/Cron\/CardDescriptionActivity.php":"d8910db39280acaeb6f64297cc4f6bf3","lib\/Cron\/ScheduledNotifications.php":"0266f829a96a39b9a7b1e0ba0f501070","lib\/Cron\/DeleteCron.php":"a3d3037c79354b3eb9f069c4b2344f23","lib\/Cron\/SessionsCleanup.php":"5542e5a486fbb17afb017b7d7fccb8a4","lib\/DAV\/Calendar.php":"d5c4c28c133eb2586a88463f071352ce","lib\/DAV\/CalendarObject.php":"8090769df472f84c3bf5b98a2b28d763","lib\/DAV\/CalendarPlugin.php":"80a8719407a7be88518ad4674f42d247","lib\/DAV\/DeckCalendarBackend.php":"438208533a4d38943f057302f0adabf6","lib\/Dashboard\/DeckWidgetToday.php":"0815fe874acb138b3b15b68974adc790","lib\/Dashboard\/DeckWidgetTomorrow.php":"0b84fbcdd987348e055ec89d57fc22f1","lib\/Dashboard\/DeckWidgetUpcoming.php":"0e2a7c7551ea165c0b7b701fb49c3a11","lib\/Db\/Attachment.php":"17cd484061b53a1e6dac26ad2c4cee9a","lib\/Db\/Circle.php":"47226372be7d955bf40c0fbb665e602d","lib\/Db\/Group.php":"1b90c750ffaed2c053c4b0190fe9734e","lib\/Db\/RelationalObject.php":"dd1a1ae0945e19bd3352197fe6bfb414","lib\/Db\/ChangeHelper.php":"984659676904dcb3fbf05cdf8992e705","lib\/Db\/RelationalEntity.php":"aee95af46f9527e91dd61f755150cb7b","lib\/Db\/Assignment.php":"0625b53e8336dbf962efcac09262d644","lib\/Db\/AssignmentMapper.php":"d54ff3ca8d68ea391d42f95d9faa575d","lib\/Db\/AttachmentMapper.php":"14f387fb7524ea7f5b8bef0ac88388f0","lib\/Db\/Card.php":"7d8be0f616814240efedd293fb46aedf","lib\/Db\/CardMapper.php":"bbb3286dceb204b6cbe5ed71235aeff5","lib\/Db\/DeckMapper.php":"b944ceb9768bd6ea7a1e3d22c459fa95","lib\/Db\/IPermissionMapper.php":"eaf7419e8236dbccc823661532bd628d","lib\/Db\/Label.php":"2c786fd375cbe3e0786115d31c0f785d","lib\/Db\/Session.php":"c0f1c6fbcb83c82983933952b4c4747c","lib\/Db\/Stack.php":"9a6ba2a2c5d66de749d362023ae0a160","lib\/Db\/StackMapper.php":"65c8de410e804c588db2dd5fc77c6e3e","lib\/Db\/User.php":"298d1ddd733711e1e66a3cf22d180a15","lib\/Db\/Acl.php":"ce7cd4ee4340397df19e641caaf34f71","lib\/Db\/AclMapper.php":"6928a9bd36b60cb8d3c3d35505f6e3e6","lib\/Db\/Board.php":"7a0cf0336cce5f7eceb605aed2b715af","lib\/Db\/BoardMapper.php":"864dffa607e73ec693515d7e1f57b0ba","lib\/Db\/LabelMapper.php":"4b473ca4c4686e414582f2863879ee32","lib\/Db\/SessionMapper.php":"090537bd94b18649743bea0dd512d1fd","lib\/Event\/AAclEvent.php":"4ee2811c708009e20532e1183c4dccf7","lib\/Event\/ABoardImportGetAllowedEvent.php":"9764edc27ee52eac04886852cc36c847","lib\/Event\/AclCreatedEvent.php":"80c8dec71734902af22ba3e1081a8a08","lib\/Event\/AclDeletedEvent.php":"60f760f0596a646771ed8dc513f4ffca","lib\/Event\/AclUpdatedEvent.php":"1cc52e39754bcb8190ca6ada6b0f8174","lib\/Event\/BoardImportGetAllowedEvent.php":"ef470b14f40108c09151cd129bec63ed","lib\/Event\/CardCreatedEvent.php":"411acb38a86528c87302ce49541c8b04","lib\/Event\/CardDeletedEvent.php":"978a67335acc5c25a5e500c63498a7bb","lib\/Event\/CardUpdatedEvent.php":"0a3ff12304b822494f69bb953d38b801","lib\/Event\/ACardEvent.php":"0492ee448c3e9b167b806109b5475986","lib\/Event\/BoardUpdatedEvent.php":"55c8911833ceeed09d33e74696a37d31","lib\/Event\/SessionClosedEvent.php":"6405cae8b34bed4bbd667f5fa7078cd1","lib\/Event\/SessionCreatedEvent.php":"e13f0d2234a37ea4d3fb411f3536bc3c","lib\/Exceptions\/ConflictException.php":"554af323e3eeed26ae94ec9522ab555e","lib\/Exceptions\/FederationDisabledException.php":"e75488f00fa500628850a4e0455224d2","lib\/Listeners\/ParticipantCleanupListener.php":"a1f28800657269d3049667369e508ac0","lib\/Listeners\/ResourceAdditionalScriptsListener.php":"75f2c119b90801ade237594d04e8c88b","lib\/Listeners\/BeforeTemplateRenderedListener.php":"3fb2d67b4a095e8aa34fff6f4d54acc3","lib\/Listeners\/ResourceListener.php":"a11490b2d551b06c7fee73697bdd0b73","lib\/Listeners\/AclCreatedRemovedListener.php":"1ffdeafea807e7a7006f5448c59dc040","lib\/Listeners\/CommentEventListener.php":"452b0557762d19c881875a1b7c11ee34","lib\/Listeners\/FullTextSearchEventListener.php":"f01ba7c49df2072e6c8aa6984e3d84a3","lib\/Listeners\/LiveUpdateListener.php":"8bd7c93d9a27a93de05e4732189e9d67","lib\/Listeners\/ResourceTypeRegisterListener.php":"f0f94bf806ad7562b3fdbfad33212c51","lib\/Middleware\/ExceptionMiddleware.php":"03c6190c926896c23c17f0daaeaac778","lib\/Middleware\/DefaultBoardMiddleware.php":"ff162aa6de08c12223be88d914a0bac3","lib\/Middleware\/FederationMiddleware.php":"8ff11eb6086abfa55e5faac6aaaab595","lib\/Migration\/DeletedCircleCleanup.php":"17532a9418c1628c624df5cbda1e2856","lib\/Migration\/Version1000Date20200306161713.php":"82562a9b61c5a31613f59aa208534d12","lib\/Migration\/Version1000Date20200308073933.php":"00bbd47ef753630b72c122ad05e1babc","lib\/Migration\/Version1011Date20230901010840.php":"c0caea1dc1dbc9352c1f76e11b8ce004","lib\/Migration\/Version1011Date20231106160059.php":"fc35eb1e761a591390e004fb55b2cb22","lib\/Migration\/Version10200Date20201111150114.php":"376a20164d1e9d50741c4e3c7bb4a89e","lib\/Migration\/Version10800Date20220422061816.php":"e8ba6f14ef20588edf01b7a07f5aefdf","lib\/Migration\/Version10900Date202206151724222.php":"86343d019bd5a172e4429369d8f4a2e3","lib\/Migration\/Version11000Date20240222115515.php":"41fad9525613b229dab223fc39c1c219","lib\/Migration\/LabelMismatchCleanup.php":"ce4ae70d420fa9c0723718f1ba8baa25","lib\/Migration\/Version11001Date20251009165313.php":"ca413a9b7289287b0d385891b5b2b664","lib\/Migration\/Version11001Date20251020122010.php":"d736b5382d49f29b4772b6974c7fb422","lib\/Model\/OptionalNullableValue.php":"f036eab84eefd745e82202aab17363f4","lib\/Model\/BoardSummary.php":"0e1a838ffed8e83322815e5eb5787c20","lib\/Model\/CardDetails.php":"277e4180484ffbd7b53d7fcf3487fbef","lib\/Notification\/NotificationHelper.php":"a7cb32e5c69ae4b6fef8db5aac477cf5","lib\/Notification\/Notifier.php":"1340393761d067aa182a6ad8b55707f2","lib\/Provider\/DeckProvider.php":"c9233171f9a532634535499d1b56a142","lib\/Reference\/CardReferenceProvider.php":"7c0daed5705113156d078bd7f2d37300","lib\/Reference\/CreateCardReferenceProvider.php":"0a49dc73285a760ce575d9c71eb055ce","lib\/Reference\/BoardReferenceProvider.php":"ed5ca614b07b3ac7e107baf1cda88f98","lib\/Reference\/CommentReferenceProvider.php":"15a93c88f8710758c3ec345141fb0284","lib\/Search\/Query\/DateQueryParameter.php":"f938dfb093010a03301633341378034d","lib\/Search\/Query\/AQueryParameter.php":"323af9216886dc0c19942afd6614ce87","lib\/Search\/Query\/SearchQuery.php":"e54bd541ba56bc6759b6b5d3edd91478","lib\/Search\/Query\/StringQueryParameter.php":"3f9c93fe3b110a732ee8bb715f2c7642","lib\/Search\/CardCommentProvider.php":"fcc3ae2d34ae1e706d65554c50602822","lib\/Search\/CardSearchResultEntry.php":"6780b6189616782626a982fa44f0a4ff","lib\/Search\/CommentSearchResultEntry.php":"681e8bd83005b86daa266ccb0e9f46f8","lib\/Search\/DeckProvider.php":"f46d93de0976defca1eb0ab6cdda3603","lib\/Search\/BoardSearchResultEntry.php":"9605659947b7bfecff4480a04653fb10","lib\/Search\/FilterStringParser.php":"3a49ee9b681903f3c913a362503767f7","lib\/Service\/Importer\/Systems\/DeckJsonService.php":"8bea9ad04928e80e6dc7d93ce6cc5d28","lib\/Service\/Importer\/Systems\/TrelloApiService.php":"685c9fc96ef7dddb4495b545f8b454cf","lib\/Service\/Importer\/Systems\/TrelloJsonService.php":"c6eb3043adcf9c4d083cbbe95433490b","lib\/Service\/Importer\/ABoardImportService.php":"d585d9ae854ef7e2d8f7785da163797f","lib\/Service\/Importer\/BoardImportCommandService.php":"1ee4e2ed1728ce6cff2af3fb0ceaea5b","lib\/Service\/Importer\/BoardImportService.php":"123cd210419fd7d393abeb6769f1daeb","lib\/Service\/FileService.php":"7245f27c159f584bd3b63469306fe0cd","lib\/Service\/IAttachmentService.php":"43e00697aae1b373f8c4743a78dbef76","lib\/Service\/ICustomAttachmentService.php":"bd73412ad67f16033d87923fbcc8218b","lib\/Service\/SearchService.php":"22d5cbd4323c5b06c21cce2666e43670","lib\/Service\/AttachmentService.php":"e1cdabee2e7ae11481d3464e6cd009ed","lib\/Service\/CirclesService.php":"eb642cfdc4ce03580bfe4ce554e0c8a6","lib\/Service\/CommentService.php":"012324dc0ea9b04c89c4a0bb283ab072","lib\/Service\/FullTextSearchService.php":"fa0d4be054ef537531c3f273b15205d4","lib\/Service\/LabelService.php":"44372be0bb9e39c2be057f82d4150202","lib\/Service\/OverviewService.php":"406329da0afebf5e3f46fade9e93a3b3","lib\/Service\/AssignmentService.php":"61b110149f3526a10d5540798aa959a7","lib\/Service\/BoardService.php":"b4c01e3158eb0c0e9f21f6257296ee22","lib\/Service\/CardService.php":"71f92c2b04b8cac8b9c79213b6ac5c7d","lib\/Service\/ConfigService.php":"840a768b3bf8a54d9f72567d0a312af1","lib\/Service\/DefaultBoardService.php":"572ffa1af2238f641b3cd88af73a892d","lib\/Service\/ExternalBoardService.php":"8a141cf80b8a4398516ad6870d4c6a87","lib\/Service\/FilesAppService.php":"ba5688134e5a8247683b1507c4a746fd","lib\/Service\/PermissionService.php":"5b98314a6e9d28a6c22a0ac3869370b5","lib\/Service\/SessionService.php":"e71e3cb0653d78719b2026a295dfcc57","lib\/Service\/StackService.php":"089864b2972b82f3df72dd5eade606ca","lib\/Sharing\/Listener.php":"2c8febc03a61860720e51bc71b0142db","lib\/Sharing\/ShareAPIHelper.php":"a7734c7bcf4bd3040679b86fe6474488","lib\/Sharing\/DeckShareProvider.php":"8303f1ed17723a57d9c6c07fc3d89896","lib\/Validators\/AssignmentServiceValidator.php":"96a432a0375d521830c8a8841f924d8d","lib\/Validators\/AttachmentServiceValidator.php":"82e51705cadf84aa2ef29bf019d2fa79","lib\/Validators\/BoardServiceValidator.php":"224bcb672796fc393a18258f36b089cb","lib\/Validators\/CardServiceValidator.php":"198c8b617e8acc0c5c9865ce348b361a","lib\/Validators\/StackServiceValidator.php":"a99a6366c6ede5e5bc76a33b9657f913","lib\/Validators\/LabelServiceValidator.php":"d6ac86ca3616e37e76077441885d1bfc","lib\/Validators\/BaseValidator.php":"a5f6b6622cea6e7f9cf870e6ae8f9841","lib\/ArchivedItemException.php":"489157f79533a404643034df63074b67","lib\/BadRequestException.php":"8c505f975cafb9ed9cf3c99f22593c33","lib\/Capabilities.php":"1aeb16d382faf4ce8e82a42eeeb7266e","lib\/InvalidAttachmentType.php":"5964ebe6bc8ec08dc523409c4c7f59fc","lib\/NoPermissionException.php":"3812d8f1cfcf46e1c6cf3b8ef815a8bf","lib\/NotFoundException.php":"cc22471994a7acd51b6125265aaf3525","lib\/NotifyPushEvents.php":"b00ce82f3eb95766049605ef5b29965e","lib\/StatusException.php":"1d22687a09c47bbd1cf2fddb123193fb","lib\/Teams\/DeckTeamResourceProvider.php":"0f800de43405827fb9cbfbcb95df347c","lib\/Federation\/DeckFederationProvider.php":"43fece7716b7044ecdd85fdc11b37f7b","lib\/Federation\/DeckFederationProxy.php":"38d0de74614cc62e78e6c79ac318dce9","templates\/main.php":"0ba2f93de5f8c4358fb6ef45f91c3ff9","tests\/integration\/app\/AppTest.php":"d9e45b231b5127720114dc85539c5c68","tests\/integration\/database\/TransferOwnershipTest.php":"83376bf7ebf7ec52073e2e33c22373f2","tests\/integration\/database\/AssignmentMapperTest.php":"12d612fa27b750928bcda17b2ebfe594","tests\/integration\/database\/BoardDatabaseTest.php":"a60798521ce8cc904fadad4b8e23ae4d","tests\/integration\/features\/bootstrap\/AttachmentContext.php":"074e470412e9a5f2aa928e46ac44b05e","tests\/integration\/features\/bootstrap\/BoardContext.php":"3e354f8433d2cc64241708480535dc4f","tests\/integration\/features\/bootstrap\/CommentContext.php":"47b9ee5b1438d4f0506bfed344e5314c","tests\/integration\/features\/bootstrap\/RequestContext.php":"6a7e73090bee3e0503f286b34711d40e","tests\/integration\/features\/bootstrap\/RequestTrait.php":"020fa9411580d6c29099af41af6b3757","tests\/integration\/features\/bootstrap\/SearchContext.php":"5266ce5afa59262754b01f573f2c4b32","tests\/integration\/features\/bootstrap\/ServerContext.php":"e1d7108f84442041e5e2c05e1ef7d6db","tests\/integration\/features\/bootstrap\/SessionContext.php":"4cbcf446b2e39cb76b77fb767de97dce","tests\/integration\/import\/ImportExportTest.php":"957f550aaca9d591e9e98b2e5bb1b457","tests\/unit\/Activity\/ChangeSetTest.php":"b02e6b2b88bedd339a7e1297b855c8b9","tests\/unit\/Activity\/FilterTest.php":"d632c4d32c6ada1e54f45adb31baadbd","tests\/unit\/Activity\/SettingTest.php":"3dd384223e6c8be763c0674427585bef","tests\/unit\/Activity\/ActivityManagerTest.php":"c1475547bd9681b1efa0da0e0d52ac4d","tests\/unit\/Activity\/DeckProviderTest.php":"799fbceb9cfb32c668e6c7473d3275a6","tests\/unit\/Command\/BoardImportTest.php":"891acbba8561b00152427521fe84f2fb","tests\/unit\/Command\/UserExportTest.php":"2a4b48e35e61dbb2c152fcf748e79fe1","tests\/unit\/Cron\/ScheduledNoificationsTest.php":"379e557e4c15ebd1afbcb9e88c0be441","tests\/unit\/Cron\/DeleteCronTest.php":"0690c8fcbadce3cfbc81a0aa814618cb","tests\/unit\/Db\/AclMapperTest.php":"997e432ec096be15c248696c76f8e59e","tests\/unit\/Db\/AclTest.php":"59522cd80027451df59f63c47af0d2f4","tests\/unit\/Db\/AttachmentTest.php":"d4f94a49b089b4725a352c38918acff2","tests\/unit\/Db\/BoardTest.php":"982014b756bb98c8456d90d9fdd7481c","tests\/unit\/Db\/GroupTest.php":"b0de093875faefd9b030dbdec0fb113d","tests\/unit\/Db\/LabelTest.php":"362996963d8f7b01f9ec0392848a0307","tests\/unit\/Db\/StackTest.php":"5e1d85db6d6af930a2e8c4fbf6a31549","tests\/unit\/Db\/UserTest.php":"e1a5994ee6429355029b64ab075c98f2","tests\/unit\/Db\/AttachmentMapperTest.php":"1ac2b9bad049a517268ba3554b14b47f","tests\/unit\/Db\/BoardMapperTest.php":"e6222d4e78f49af0885edd421f3cfed2","tests\/unit\/Db\/CardTest.php":"c3858c4fc36fb89471d56daf0e9d0d77","tests\/unit\/Db\/RelationalEntityTest.php":"1b30a6017ef09252946d08b53e40b16f","tests\/unit\/Middleware\/ExceptionMiddlewareTest.php":"ccf86f5b6bd7d379f882bc4d15598f51","tests\/unit\/Notification\/NotificationHelperTest.php":"7b756aa22a9e658477639abac64ee473","tests\/unit\/Notification\/NotifierTest.php":"479d1d3140c88ea002a767d6f63f255f","tests\/unit\/Reference\/CardReferenceProviderTest.php":"0ad94faba4d90100e1012071cd7c39bd","tests\/unit\/Search\/Query\/AQueryParameterTest.php":"9f331bc9ba60708d87897a990abf042b","tests\/unit\/Search\/FilterStringParserTest.php":"abcc13a720a3452eebabf64764b161fa","tests\/unit\/Service\/Importer\/Systems\/DeckJsonServiceTest.php":"887c13a733807c46f675ef1d31fd655e","tests\/unit\/Service\/Importer\/Systems\/TrelloJsonServiceTest.php":"47f6d071a462c2f28d4f89b569f47753","tests\/unit\/Service\/Importer\/BoardImportServiceTest.php":"0a908f2f4ecf67838d0979da3205e724","tests\/unit\/Service\/AssignmentServiceTest.php":"aa39a881cad189eb72d1b940113ea0f0","tests\/unit\/Service\/PermissionServiceTest.php":"c4340accca124d28575b009607045f81","tests\/unit\/Service\/AttachmentServiceTest.php":"a9aa99e65135fb892d4dcea8c4e99eb9","tests\/unit\/Service\/BoardServiceTest.php":"159d9f5b68543b460a7a311b151e3eb1","tests\/unit\/Service\/CardServiceTest.php":"e3d5d704575902ecb0e95079e50f3657","tests\/unit\/Service\/DefaultBoardServiceTest.php":"c6ae6cebde1b769a22c623301f2fca93","tests\/unit\/Service\/LabelServiceTest.php":"adc8cba39487e3b6208ee60307386b3b","tests\/unit\/Service\/StackServiceTest.php":"8c923675c3e5d0b8d8a058ad8b5fb985","tests\/unit\/Service\/FileServiceTest.php":"3ec1d17487b077d3a5cb259141a2eaf4","tests\/unit\/Service\/FilesAppServiceTest.php":"47907402ea861974fac7a76deb069808","tests\/unit\/Validators\/StackServiceValidatorTest.php":"58262b987f2d9072ff88b0bdb4650d18","tests\/unit\/Validators\/ValidatorTestBase.php":"489d73d6012fc936074a9bbca43bbefa","tests\/unit\/Validators\/BoardServiceValidatorTest.php":"9cc94aba92dd1379f71f24dc19abbb73","tests\/unit\/controller\/BoardApiControllerTest.php":"27030d83f04b851f53eec941847fde8a","tests\/unit\/controller\/LabelApiControllerTest.php":"0b6a521a7d11e5aebbc7bd2c1a6eb910","tests\/unit\/controller\/PageControllerTest.php":"27b9e6b9c5a046d55ce6ee1542d95255","tests\/unit\/controller\/StackApiControllerTest.php":"483459f6905488b4719aaf286e256a59","tests\/unit\/controller\/BoardImportApiControllerTest.php":"303827af15944458dfa954fdaf3a4014","tests\/unit\/controller\/BoardControllerTest.php":"1eb1223535d31bd36f9fb3fcf61d8af7","tests\/unit\/controller\/CardApiControllerTest.php":"5b05f695a22966512a90a2862b4a9fd3","tests\/unit\/controller\/CardControllerTest.php":"59fc813922f96ec9680c475d0953d99e","tests\/unit\/controller\/LabelControllerTest.php":"cd96a6556793611474c9ce745ca9bf3f","tests\/unit\/controller\/StackControllerTest.php":"124d661707a0de9148fbb874303c5580","tests\/unit\/ExceptionsTest.php":"5af6330b5725899c3e8860bf295ea450","tests\/unit\/Listeners\/CommentEventListenerTest.php":"f25c456e4dce4236412c88df7f2bec7e","tests\/bootstrap.php":"53bee9383167d59347d71fd57ee57c1f"}} \ No newline at end of file diff --git a/appinfo/routes.php b/appinfo/routes.php index bfd6e6c981..f01ff5e1ed 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -139,9 +139,9 @@ ['name' => 'new_board#create', 'url' => '/api/v{apiVersion}/boards', 'verb' => 'POST'], ['name' => 'new_board#addAcl', 'url' => '/api/v{apiVersion}/boards/{boardId}/acl', 'verb' => 'POST'], - ['name' => 'new_card#create', 'url' => '/api/v{apiVersion}/cards', 'verb' => 'POST'], + ['name' => 'new_card#create', 'url' => '/api/v{apiVersion}/cards', 'verb' => 'POST'], - ['name' => 'new_stack#create', 'url' => '/api/v{apiVersion}/stacks', 'verb' => 'POST'], + ['name' => 'new_stack#create', 'url' => '/api/v{apiVersion}/stacks', 'verb' => 'POST'], ['name' => 'new_stack#delete', 'url' => '/api/v{apiVersion}/stacks/{stackId}/{boardId}', 'verb' => 'DELETE', 'defaults' => ['boardId' => null]], ['name' => 'Config#get', 'url' => '/api/v{apiVersion}/config', 'verb' => 'GET'], diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index ee93331071..234af609fa 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -27,8 +27,8 @@ use OCA\Deck\Event\CardUpdatedEvent; use OCA\Deck\Event\SessionClosedEvent; use OCA\Deck\Event\SessionCreatedEvent; -use OCA\Deck\Listeners\AclCreatedRemovedListener; use OCA\Deck\Federation\DeckFederationProvider; +use OCA\Deck\Listeners\AclCreatedRemovedListener; use OCA\Deck\Listeners\BeforeTemplateRenderedListener; use OCA\Deck\Listeners\CommentEventListener; use OCA\Deck\Listeners\FullTextSearchEventListener; @@ -75,7 +75,6 @@ use OCP\Util; use Psr\Container\ContainerInterface; - class Application extends App implements IBootstrap { public const APP_ID = 'deck'; @@ -212,7 +211,7 @@ public function registerCloudFederationProviderManager( ): void { $manager->addCloudFederationProvider( DeckFederationProvider::PROVIDER_ID, - "Deck Federation", + 'Deck Federation', static fn (): ICloudFederationProvider => Server::get(DeckFederationProvider::class), ); } diff --git a/lib/Controller/NewBoardController.php b/lib/Controller/NewBoardController.php index 8782251c32..3ab4928c01 100644 --- a/lib/Controller/NewBoardController.php +++ b/lib/Controller/NewBoardController.php @@ -3,17 +3,17 @@ namespace OCA\Deck\Controller; use OCA\Deck\Service\BoardService; -use OCA\Deck\Service\StackService; use OCA\Deck\Service\ExternalBoardService; -use OCP\AppFramework\Http\DataResponse; -use OCP\AppFramework\OCSController; +use OCA\Deck\Service\StackService; use OCP\AppFramework\Http\Attribute\NoAdminRequired; use OCP\AppFramework\Http\Attribute\PublicPage; use OCP\AppFramework\Http\Attribute\RequestHeader; +use OCP\AppFramework\Http\DataResponse; +use OCP\AppFramework\OCSController; use OCP\IRequest; use Psr\Log\LoggerInterface; -class NewBoardController extends OCSController{ +class NewBoardController extends OCSController { public function __construct( string $appName, IRequest $request, @@ -39,7 +39,7 @@ public function index(): DataResponse { public function read(int $boardId): DataResponse { // Board on this instance -> get it from database $localBoard = $this->boardService->find($boardId, true, true); - if($localBoard->getExternalId() !== null) { + if ($localBoard->getExternalId() !== null) { return $this->externalBoardService->getExternalBoardFromRemote($localBoard); } // Board on other instance -> get it from other instance @@ -48,18 +48,18 @@ public function read(int $boardId): DataResponse { #[NoAdminrequired] #[NoCSRFRequired] - public function create(string $title, string $color,): DataResponse { - return new DataResponse( $this->boardService->create($title, $this->userId, $color)); + public function create(string $title, string $color): DataResponse { + return new DataResponse($this->boardService->create($title, $this->userId, $color)); } #[NoAdminRequired] #[PublicPage] #[NoCSRFRequired] #[RequestHeader(name: 'x-nextcloud-federation', description: 'Set to 1 when the request is performed by another Nextcloud Server to indicate a federation request', indirect: true)] - public function stacks(int $boardId): DataResponse{ + public function stacks(int $boardId): DataResponse { $localBoard = $this->boardService->find($boardId, true, true, $this->request->getParam('accessToken')); // Board on other instance -> get it from other instance - if($localBoard->getExternalId() !== null) { + if ($localBoard->getExternalId() !== null) { return $this->externalBoardService->getExternalStacksFromRemote($localBoard); } else { return new DataResponse($this->stackService->findAll($boardId)); diff --git a/lib/Controller/NewCardController.php b/lib/Controller/NewCardController.php index 11b554dc92..c4b12ebbac 100644 --- a/lib/Controller/NewCardController.php +++ b/lib/Controller/NewCardController.php @@ -2,19 +2,18 @@ namespace OCA\Deck\Controller; -use OCP\AppFramework\OCSController; -use OCA\Deck\Service\StackService; -use OCA\Deck\Service\CardService; use OCA\Deck\Service\BoardService; +use OCA\Deck\Service\CardService; use OCA\Deck\Service\ExternalBoardService; -use OCP\AppFramework\Http\DataResponse; +use OCA\Deck\Service\StackService; use OCP\AppFramework\Http\Attribute\NoAdminRequired; +use OCP\AppFramework\Http\Attribute\NoCSRFRequired; use OCP\AppFramework\Http\Attribute\PublicPage; use OCP\AppFramework\Http\Attribute\RequestHeader; -use OCP\AppFramework\Http\Attribute\NoCSRFRequired; +use OCP\AppFramework\Http\DataResponse; +use OCP\AppFramework\OCSController; use OCP\IRequest; - class NewCardController extends OCSController { public function __construct( string $appName, @@ -32,7 +31,7 @@ public function __construct( #[PublicPage] #[NoCSRFRequired] #[RequestHeader(name: 'x-nextcloud-federation', description: 'Set to 1 when the request is performed by another Nextcloud Server to indicate a federation request', indirect: true)] - public function create(string $title, int $stackId, ?int $boardId=null, ?string $type = 'plain',?string $owner = null,?int $order = 999, ?string $description = '', $duedate = null, ?array $labels = [], ?array $users = []) { + public function create(string $title, int $stackId, ?int $boardId = null, ?string $type = 'plain', ?string $owner = null, ?int $order = 999, ?string $description = '', $duedate = null, ?array $labels = [], ?array $users = []) { if ($boardId) { $board = $this->boardService->find($boardId, false); if ($board->getExternalId()) { diff --git a/lib/Controller/NewStackController.php b/lib/Controller/NewStackController.php index ec247e70c8..f3c24ea010 100644 --- a/lib/Controller/NewStackController.php +++ b/lib/Controller/NewStackController.php @@ -1,16 +1,16 @@ db->getQueryBuilder(); $qb->select('id', 'board_id', 'type', 'participant', 'permission_edit', 'permission_share', 'permission_manage', 'token') ->from('deck_board_acl') diff --git a/lib/Exceptions/FederationDisabledException.php b/lib/Exceptions/FederationDisabledException.php index 1a25694aef..f641f443ec 100644 --- a/lib/Exceptions/FederationDisabledException.php +++ b/lib/Exceptions/FederationDisabledException.php @@ -11,6 +11,6 @@ class FederationDisabledException extends BadRequestException { public function __construct() { - parent::__construct("Federation is disabled"); + parent::__construct('Federation is disabled'); } } diff --git a/lib/Federation/DeckFederationProvider.php b/lib/Federation/DeckFederationProvider.php index f9f344e286..a15a57bb0a 100644 --- a/lib/Federation/DeckFederationProvider.php +++ b/lib/Federation/DeckFederationProvider.php @@ -1,19 +1,20 @@ setUser($share->getShareWith()); $notification->setDateTime(new \DateTime()); $notification->setObject('remote-board-shared', $insertedBoard->getId()); - $notification->setSubject('remote-board-shared',[$share->getResourceName(), $share->getSharedBy()]); + $notification->setSubject('remote-board-shared', [$share->getResourceName(), $share->getSharedBy()]); $this->notificationManager->notify($notification); return 'PLACE_HOLDER_ID'; @@ -62,17 +63,17 @@ public function shareReceived(ICloudFederationShare $share): string { public function notificationReceived($notificationType, $providerId, $notification): array { switch ($notificationType) { - case "update-permissions": + case 'update-permissions': $localBoards = $this->boardMapper->findByExternalId($providerId); foreach ($localBoards as $board) { - if ($board->getShareToken() === $notification["sharedSecret"]) { + if ($board->getShareToken() === $notification['sharedSecret']) { $localBoard = $board; } } if (!isset($localBoard)) { - throw new NotFoundException("Board not found for provider ID: " . $providerId); + throw new NotFoundException('Board not found for provider ID: ' . $providerId); } - $localParticipant = $this->cloudIdManager->resolveCloudId($notification[0]["participant"])->getUser(); + $localParticipant = $this->cloudIdManager->resolveCloudId($notification[0]['participant'])->getUser(); $acls = $this->aclMapper->findAll($localBoard->getId()); foreach ($acls as $acl) { if ($acl->getParticipant() === $localParticipant) { @@ -81,15 +82,15 @@ public function notificationReceived($notificationType, $providerId, $notificati } } if (!isset($localAcl)) { - throw new NotFoundException("ACL entry not found for participant: " . $localParticipant); + throw new NotFoundException('ACL entry not found for participant: ' . $localParticipant); } - $acl->setPermissionEdit($notification[0]["permissionEdit"]); - $acl->setPermissionManage($notification[0]["permissionManage"]); - $acl->setPermissionShare($notification[0]["permissionShare"]); + $acl->setPermissionEdit($notification[0]['permissionEdit']); + $acl->setPermissionManage($notification[0]['permissionManage']); + $acl->setPermissionShare($notification[0]['permissionShare']); $this->aclMapper->update($acl); break; default: - throw new Exception("Unknown notification type: " . $notificationType); + throw new Exception('Unknown notification type: ' . $notificationType); } return []; } diff --git a/lib/Federation/DeckFederationProxy.php b/lib/Federation/DeckFederationProxy.php index 5f241d1b9e..76d58150b7 100644 --- a/lib/Federation/DeckFederationProxy.php +++ b/lib/Federation/DeckFederationProxy.php @@ -2,15 +2,14 @@ namespace OCA\Deck\Federation; -use OCP\Http\Client\IClientService; -use OC\Http\Client\Response; -use OCP\Http\Client\IResponse; -use OCP\AppFramework\Http; use GuzzleHttp\Exception\ClientException; -use GuzzleHttp\Cookie\CookieJar; use GuzzleHttp\Exception\ServerException; -use OCP\IUserSession; +use OC\Http\Client\Response; +use OCP\AppFramework\Http; +use OCP\Http\Client\IClientService; +use OCP\Http\Client\IResponse; use OCP\IConfig; +use OCP\IUserSession; use OCP\L10N\IFactory; use Psr\Log\LoggerInterface; @@ -21,27 +20,28 @@ public function __construct( private IConfig $config, private IFactory $l10nFactory, private LoggerInterface $logger, - ){} + ) { + } protected function generateDefaultRequestOptions( ?string $cloudId, #[SensitiveParameter] ?string $accessToken, ): array { - $options = [ - 'verify' => !$this->config->getSystemValueBool('sharing.federation.allowSelfSignedCertificates'), - 'nextcloud' => [ - 'allow_local_address' => $this->config->getSystemValueBool('allow_local_remote_servers'), - ], - 'headers' => [ - 'Cookie' => 'XDEBUG_SESSION=PHPSTORM', - 'Accept' => 'application/json', - 'x-nextcloud-federation' => 'true', - 'OCS-APIRequest' => 'true', - 'Accept-Language' => $this->l10nFactory->getUserLanguage($this->userSession->getUser()), - 'deck-federation-accesstoken' => $accessToken, - ], - 'timeout' => 5, - ]; + $options = [ + 'verify' => !$this->config->getSystemValueBool('sharing.federation.allowSelfSignedCertificates'), + 'nextcloud' => [ + 'allow_local_address' => $this->config->getSystemValueBool('allow_local_remote_servers'), + ], + 'headers' => [ + 'Cookie' => 'XDEBUG_SESSION=PHPSTORM', + 'Accept' => 'application/json', + 'x-nextcloud-federation' => 'true', + 'OCS-APIRequest' => 'true', + 'Accept-Language' => $this->l10nFactory->getUserLanguage($this->userSession->getUser()), + 'deck-federation-accesstoken' => $accessToken, + ], + 'timeout' => 5, + ]; if ($cloudId !== null && $accessToken !== null) { } @@ -81,35 +81,35 @@ protected function request( } catch (ClientException $e) { $status = $e->getResponse()->getStatusCode(); - try { - $body = $e->getResponse()->getBody()->getContents(); - $data = json_decode($body, true, flags: JSON_THROW_ON_ERROR); - $e->getResponse()->getBody()->rewind(); - if (!is_array($data)) { - throw new \RuntimeException('JSON response is not an array'); - } - } catch (\Throwable $e) { - throw new \Exception('Error parsing JSON response', $e->getCode(), $e); - } + try { + $body = $e->getResponse()->getBody()->getContents(); + $data = json_decode($body, true, flags: JSON_THROW_ON_ERROR); + $e->getResponse()->getBody()->rewind(); + if (!is_array($data)) { + throw new \RuntimeException('JSON response is not an array'); + } + } catch (\Throwable $e) { + throw new \Exception('Error parsing JSON response', $e->getCode(), $e); + } - $clientException = new \Exception($e->getMessage(), $status, $e); - $this->logger->debug('Client error from remote', ['exception' => $clientException]); - return new Response($e->getResponse(), false); - } catch (ServerException|\Throwable $e) { - $serverException = new \Exception($e->getMessage(), $e->getCode(), $e); - $this->logger->error('Could not reach remote', ['exception' => $serverException]); - throw $serverException; + $clientException = new \Exception($e->getMessage(), $status, $e); + $this->logger->debug('Client error from remote', ['exception' => $clientException]); + return new Response($e->getResponse(), false); + } catch (ServerException|\Throwable $e) { + $serverException = new \Exception($e->getMessage(), $e->getCode(), $e); + $this->logger->error('Could not reach remote', ['exception' => $serverException]); + throw $serverException; } } public function get(string $cloudId, string $shareToken, string $url, array $params = []):IResponse { - return $this->request("get", $cloudId, $shareToken, $url, $params); + return $this->request('get', $cloudId, $shareToken, $url, $params); } public function post(string $cloudId, string $shareToken, string $url, array $params = []):IResponse { - return $this->request("post", $cloudId, $shareToken, $url, $params); + return $this->request('post', $cloudId, $shareToken, $url, $params); } public function delete(string $cloudId, string $shareToken, string $url, array $params = []):IResponse { - return $this->request("delete", $cloudId, $shareToken, $url, $params); + return $this->request('delete', $cloudId, $shareToken, $url, $params); } public function getOCSData(IResponse $response, array $allowedStatusCodes = [Http::STATUS_OK]): array { if (!in_array($response->getStatusCode(), $allowedStatusCodes, true)) { diff --git a/lib/Listeners/ResourceTypeRegisterListener.php b/lib/Listeners/ResourceTypeRegisterListener.php index 66de2c1a1f..131a72be3b 100644 --- a/lib/Listeners/ResourceTypeRegisterListener.php +++ b/lib/Listeners/ResourceTypeRegisterListener.php @@ -1,14 +1,15 @@ registerResourceType( - "deck", - ["user"], + 'deck', + ['user'], [ 'deck-v1' => '/ocs/v2.php/apps/deck/api/', ] ); } } - -?> diff --git a/lib/Middleware/FederationMiddleware.php b/lib/Middleware/FederationMiddleware.php index 850b7ec22a..7dc2d00467 100644 --- a/lib/Middleware/FederationMiddleware.php +++ b/lib/Middleware/FederationMiddleware.php @@ -3,27 +3,27 @@ namespace OCA\Deck\Middleware; use OCA\Deck\Service\ConfigService; +use OCA\Deck\Service\PermissionService; use OCP\AppFramework\Middleware; use OCP\IRequest; -use OCA\Deck\Service\PermissionService; use Psr\Log\LoggerInterface; class FederationMiddleware extends Middleware { - public function __construct( + public function __construct( private LoggerInterface $logger, - private PermissionService $permissionService, - private IRequest $request, + private PermissionService $permissionService, + private IRequest $request, private ConfigService $configService, + ) { + } - ) {} - - public function beforeController($controller, $methodName) { - if(!$this->configService->get("federationEnabled")) { + public function beforeController($controller, $methodName) { + if (!$this->configService->get('federationEnabled')) { return; } - $accessToken = $this->request->getHeader('deck-federation-accesstoken'); - if ($accessToken) { - $this->permissionService->setAccessToken($accessToken); - } - } + $accessToken = $this->request->getHeader('deck-federation-accesstoken'); + if ($accessToken) { + $this->permissionService->setAccessToken($accessToken); + } + } } diff --git a/lib/Migration/Version11001Date20251009165313.php b/lib/Migration/Version11001Date20251009165313.php index 9a7de8bfe7..35271b43ee 100644 --- a/lib/Migration/Version11001Date20251009165313.php +++ b/lib/Migration/Version11001Date20251009165313.php @@ -9,20 +9,20 @@ use OCP\Migration\SimpleMigrationStep; class Version11001Date20251009165313 extends SimpleMigrationStep { - public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper { - $schema = $schemaClosure(); + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper { + $schema = $schemaClosure(); - $tableName = 'deck_board_acl'; - if ($schema->hasTable($tableName)) { - $table = $schema->getTable($tableName); - if (!$table->hasColumn('token')) { - $table->addColumn('token', 'string', [ - 'notnull' => false, - 'length' => 32, - ]); - } - } + $tableName = 'deck_board_acl'; + if ($schema->hasTable($tableName)) { + $table = $schema->getTable($tableName); + if (!$table->hasColumn('token')) { + $table->addColumn('token', 'string', [ + 'notnull' => false, + 'length' => 32, + ]); + } + } - return $schema; - } + return $schema; + } } diff --git a/lib/Migration/Version11001Date20251020122010.php b/lib/Migration/Version11001Date20251020122010.php index d4cbe9d20b..84bfa9b4cf 100644 --- a/lib/Migration/Version11001Date20251020122010.php +++ b/lib/Migration/Version11001Date20251020122010.php @@ -4,9 +4,9 @@ namespace OCA\Deck\Migration; use Closure; -use OCP\DB\ISchemaWrapper; use OCP\Migration\IOutput; use OCP\Migration\SimpleMigrationStep; + class Version11001Date20251020122010 extends SimpleMigrationStep { public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) { $schema = $schemaClosure(); diff --git a/lib/Service/BoardService.php b/lib/Service/BoardService.php index a5b73bb6c4..1e80b42188 100644 --- a/lib/Service/BoardService.php +++ b/lib/Service/BoardService.php @@ -32,7 +32,6 @@ use OCA\Deck\Event\AclUpdatedEvent; use OCA\Deck\Event\BoardUpdatedEvent; use OCA\Deck\Event\CardCreatedEvent; -use OCA\Deck\Federation\DeckFederationProvider; use OCA\Deck\NoPermissionException; use OCA\Deck\Notification\NotificationHelper; use OCA\Deck\Validators\BoardServiceValidator; @@ -41,18 +40,17 @@ use OCP\AppFramework\Db\MultipleObjectsReturnedException; use OCP\DB\Exception as DbException; use OCP\EventDispatcher\IEventDispatcher; +use OCP\Federation\ICloudFederationFactory; use OCP\Federation\ICloudFederationNotification; -use OCP\Federation\ICloudFederationProvider; use OCP\Federation\ICloudFederationProviderManager; -use OCP\Federation\ICloudFederationFactory; use OCP\Federation\ICloudIdManager; use OCP\IConfig; use OCP\IDBConnection; use OCP\IL10N; use OCP\IURLGenerator; use OCP\IUserManager; -use OCP\Server; use OCP\Security\ISecureRandom; +use OCP\Server; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; @@ -445,18 +443,18 @@ public function updateAcl(int $id, bool $edit, bool $share, bool $manage): Acl { $acl = $this->aclMapper->update($acl); $this->changeHelper->boardChanged($acl->getBoardId()); - if($acl->getType() === Acl::PERMISSION_TYPE_REMOTE) { - $notification = $this->federationFactory->getCloudFederationNotification(); + if ($acl->getType() === Acl::PERMISSION_TYPE_REMOTE) { + $notification = $this->federationFactory->getCloudFederationNotification(); if (!$notification instanceof ICloudFederationNotification) { - throw new \InvalidArgumentException('Invalid notification type'); + throw new \InvalidArgumentException('Invalid notification type'); } $payload = [ $acl->jsonSerialize(), - "sharedSecret" => $acl->getToken(), + 'sharedSecret' => $acl->getToken(), ]; - $notification->setMessage("update-permissions", "deck", $acl->getBoardId(), $payload); + $notification->setMessage('update-permissions', 'deck', $acl->getBoardId(), $payload); $url = $this->cloudIdManager->resolveCloudId($acl->getParticipant()); $resp = $this->cloudFederationProviderManager->sendCloudNotification($url->getRemote(), $notification); diff --git a/lib/Service/ConfigService.php b/lib/Service/ConfigService.php index 84bbf2a903..3618b169a3 100644 --- a/lib/Service/ConfigService.php +++ b/lib/Service/ConfigService.php @@ -78,7 +78,7 @@ public function get(string $key) { } return $this->getGroupLimit(); case 'federationEnabled': - return (bool) $this->config->getAppValue(Application::APP_ID, 'federationEnabled', false); + return (bool)$this->config->getAppValue(Application::APP_ID, 'federationEnabled', false); case 'calendar': if ($this->getUserId() === null) { return false; diff --git a/lib/Service/ExternalBoardService.php b/lib/Service/ExternalBoardService.php index b571a3ed91..561cc6a42c 100644 --- a/lib/Service/ExternalBoardService.php +++ b/lib/Service/ExternalBoardService.php @@ -2,16 +2,16 @@ namespace OCA\Deck\Service; -use OCA\Deck\Exceptions\FederationDisabledException; -use OCP\AppFramework\Http\DataResponse; use OCA\Deck\Db\Board; +use OCA\Deck\Exceptions\FederationDisabledException; use OCA\Deck\Federation\DeckFederationProxy; +use OCP\AppFramework\Http\DataResponse; use OCP\Federation\ICloudIdManager; use OCP\IUserManager; class ExternalBoardService { public function __construct( - private IUserManager $userManager, + private IUserManager $userManager, private ICloudIdManager $cloudIdManager, private DeckFederationProxy $proxy, private ConfigService $configService, @@ -20,9 +20,9 @@ public function __construct( } private function ensureFederationEnabled(): void { - if (!$this->configService->get('federationEnabled')) { - throw new FederationDisabledException(); - } + if (!$this->configService->get('federationEnabled')) { + throw new FederationDisabledException(); + } } public function getExternalBoardFromRemote(Board $localBoard):DataResponse { @@ -30,7 +30,7 @@ public function getExternalBoardFromRemote(Board $localBoard):DataResponse { $shareToken = $localBoard->getShareToken(); $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); - $url = $ownerCloudId->getRemote() . "/ocs/v2.php/apps/deck/api/v1.0/board/".$localBoard->getExternalId(); + $url = $ownerCloudId->getRemote() . '/ocs/v2.php/apps/deck/api/v1.0/board/' . $localBoard->getExternalId(); $resp = $this->proxy->get($participantCloudId->getId(), $shareToken, $url); $ocs = $this->proxy->getOCSData($resp); return new DataResponse($this->LocalizeRemoteBoard($ocs, $localBoard)); @@ -40,7 +40,7 @@ public function getExternalStacksFromRemote(Board $localBoard):DataResponse { $shareToken = $localBoard->getShareToken(); $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); - $url = $ownerCloudId->getRemote() . "/ocs/v2.php/apps/deck/api/v1.0/stacks/".$localBoard->getExternalId(); + $url = $ownerCloudId->getRemote() . '/ocs/v2.php/apps/deck/api/v1.0/stacks/' . $localBoard->getExternalId(); $resp = $this->proxy->get($participantCloudId->getId(), $shareToken, $url); $ocs = $this->proxy->getOCSData($resp); return new DataResponse($this->LocalizeRemoteStacks($ocs, $localBoard)); @@ -68,13 +68,13 @@ public function createCardOnRemote( ?string $description = '', $duedate = null, ?array $users = [], - ?int $boardId = null + ?int $boardId = null, ): array { $this->ensureFederationEnabled(); $shareToken = $localBoard->getShareToken(); $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); - $url = $ownerCloudId->getRemote() . "/ocs/v2.php/apps/deck/api/v1.0/cards"; + $url = $ownerCloudId->getRemote() . '/ocs/v2.php/apps/deck/api/v1.0/cards'; $params = [ 'title' => $title, 'stackId' => $stackId, @@ -99,7 +99,7 @@ public function createStackOnRemote( $shareToken = $localBoard->getShareToken(); $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); - $url = $ownerCloudId->getRemote() . "/ocs/v2.php/apps/deck/api/v1.0/stacks"; + $url = $ownerCloudId->getRemote() . '/ocs/v2.php/apps/deck/api/v1.0/stacks'; $params = [ 'title' => $title, 'boardId' => $localBoard->getExternalId(), @@ -110,13 +110,13 @@ public function createStackOnRemote( return $this->localizeRemoteStacks([$stack], $localBoard)[0]; } - public function deleteStackOnRemote(Board $localBoard, int $stackId): array { + public function deleteStackOnRemote(Board $localBoard, int $stackId): array { $this->ensureFederationEnabled(); $shareToken = $localBoard->getShareToken(); $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); - $url = $ownerCloudId->getRemote() . "/ocs/v2.php/apps/deck/api/v1.0/stacks/" . $stackId; + $url = $ownerCloudId->getRemote() . '/ocs/v2.php/apps/deck/api/v1.0/stacks/' . $stackId; $resp = $this->proxy->delete($participantCloudId->getId(), $shareToken, $url, []); return $this->proxy->getOcsData($resp); - } + } } diff --git a/lib/Service/PermissionService.php b/lib/Service/PermissionService.php index 2f4170be5c..72d2005264 100644 --- a/lib/Service/PermissionService.php +++ b/lib/Service/PermissionService.php @@ -124,7 +124,7 @@ public function matchPermissions(Board $board) { Acl::PERMISSION_EDIT => $this->externalUserCan($acls, Acl::PERMISSION_EDIT, $this->accessToken), Acl::PERMISSION_MANAGE => $this->externalUserCan($acls, Acl::PERMISSION_MANAGE, $this->accessToken), Acl::PERMISSION_SHARE => $this->externalUserCan($acls, Acl::PERMISSION_SHARE, $this->accessToken) - ]; + ]; } return [ Acl::PERMISSION_READ => $owner || $this->userCan($acls, Acl::PERMISSION_READ), @@ -200,7 +200,7 @@ private function getBoard(int $boardId, bool $allowDeleted = false): Board { public function externalUserCan(array $acls, $permission, $shareToken = null) { - foreach($acls as $acl) { + foreach ($acls as $acl) { if ($acl->getType() === Acl::PERMISSION_TYPE_REMOTE) { $token = $acl->getToken(); if ($acl->getToken() === $shareToken) { From a0228f146d58b41789073803b02ea1dc3a3f9638 Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Tue, 10 Feb 2026 13:24:30 +0100 Subject: [PATCH 16/24] feat: resolve federated owners Signed-off-by: grnd-alt --- lib/Controller/NewBoardController.php | 2 +- lib/Db/BoardMapper.php | 12 ++++++++++-- lib/Db/FederatedUser.php | 28 +++++++++++++++++++++++++++ lib/Service/ExternalBoardService.php | 11 +++++++++++ 4 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 lib/Db/FederatedUser.php diff --git a/lib/Controller/NewBoardController.php b/lib/Controller/NewBoardController.php index 3ab4928c01..bb17b6d3cf 100644 --- a/lib/Controller/NewBoardController.php +++ b/lib/Controller/NewBoardController.php @@ -46,7 +46,7 @@ public function read(int $boardId): DataResponse { return new DataResponse($localBoard); } - #[NoAdminrequired] + #[NoAdminRequired] #[NoCSRFRequired] public function create(string $title, string $color): DataResponse { return new DataResponse($this->boardService->create($title, $this->userId, $color)); diff --git a/lib/Db/BoardMapper.php b/lib/Db/BoardMapper.php index a445fd3250..718d2c4fd5 100644 --- a/lib/Db/BoardMapper.php +++ b/lib/Db/BoardMapper.php @@ -12,6 +12,7 @@ use OCP\AppFramework\Db\QBMapper; use OCP\Cache\CappedMemoryCache; use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\Federation\ICloudIdManager; use OCP\IDBConnection; use OCP\IGroupManager; use OCP\IUserManager; @@ -32,6 +33,7 @@ public function __construct( private IUserManager $userManager, private IGroupManager $groupManager, private CirclesService $circlesService, + private ICloudIdManager $cloudIdManager, private LoggerInterface $logger, ) { parent::__construct($db, 'deck_boards', Board::class); @@ -534,8 +536,14 @@ public function mapAcl(Acl &$acl): void { */ public function mapOwner(Board &$board) { $userManager = $this->userManager; - $board->resolveRelation('owner', function ($owner) use (&$userManager) { - if ($this->userManager->userExists($owner)) { + $cloudIdManager = $this->cloudIdManager; + $externalId = $board->getExternalId(); + $board->resolveRelation('owner', function ($owner) use (&$userManager, &$cloudIdManager, $externalId) { + if ($externalId !== null) { + $cloudId = $cloudIdManager->resolveCloudId($owner); + return new FederatedUser($cloudId); + } + if ($userManager->userExists($owner)) { return new User($owner, $userManager); } return null; diff --git a/lib/Db/FederatedUser.php b/lib/Db/FederatedUser.php new file mode 100644 index 0000000000..c48c9eb81a --- /dev/null +++ b/lib/Db/FederatedUser.php @@ -0,0 +1,28 @@ +cloudId = $cloudId; + parent::__construct($cloudId->getId(), $cloudId); + } + + public function getObjectSerialization(): array { + return [ + 'uid' => $this->cloudId->getId(), + 'displayname' => $this->cloudId->getUser(), + 'remote' => $this->cloudId->getRemote(), + 'type' => Acl::PERMISSION_TYPE_REMOTE + ]; + } +} diff --git a/lib/Service/ExternalBoardService.php b/lib/Service/ExternalBoardService.php index 561cc6a42c..1a1c3df6a9 100644 --- a/lib/Service/ExternalBoardService.php +++ b/lib/Service/ExternalBoardService.php @@ -2,7 +2,10 @@ namespace OCA\Deck\Service; +use OCA\Deck\Db\Acl; use OCA\Deck\Db\Board; +use OCA\Deck\Db\BoardMapper; +use OCA\Deck\Db\FederatedUser; use OCA\Deck\Exceptions\FederationDisabledException; use OCA\Deck\Federation\DeckFederationProxy; use OCP\AppFramework\Http\DataResponse; @@ -15,6 +18,9 @@ public function __construct( private ICloudIdManager $cloudIdManager, private DeckFederationProxy $proxy, private ConfigService $configService, + private BoardService $boardService, + private PermissionService $permissionService, + private BoardMapper $boardMapper, private ?string $userId, ) { } @@ -56,6 +62,11 @@ public function LocalizeRemoteStacks(array $stacks, Board $localBoard) { public function LocalizeRemoteBoard(array $remoteBoard, Board $localBoard) { $remoteBoard['id'] = $localBoard->getId(); $remoteBoard['stacks'] = $this->LocalizeRemoteStacks($remoteBoard['stacks'], $localBoard); + + // setting this manually to a federatedUser as $localBoard->getOwner() does not return the resolved owner + $remoteBoard['owner'] = new FederatedUser($this->cloudIdManager->resolveCloudId($localBoard->getOwner())); + $remoteBoard['acl'] = $localBoard->getAcl(); + $remoteBoard['permissions'] = $localBoard->getPermissions(); return $remoteBoard; } From 6d055faa76c96362cace2c9a436a01db8c4e5022 Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Tue, 10 Feb 2026 13:28:01 +0100 Subject: [PATCH 17/24] fix(federation): check permission on local copy of boards Signed-off-by: grnd-alt --- lib/Service/ExternalBoardService.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/Service/ExternalBoardService.php b/lib/Service/ExternalBoardService.php index 1a1c3df6a9..3b06e85518 100644 --- a/lib/Service/ExternalBoardService.php +++ b/lib/Service/ExternalBoardService.php @@ -82,6 +82,7 @@ public function createCardOnRemote( ?int $boardId = null, ): array { $this->ensureFederationEnabled(); + $this->permissionService->checkPermission($this->boardMapper, $localBoard->getId(), Acl::PERMISSION_EDIT, $this->userId, false, false); $shareToken = $localBoard->getShareToken(); $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); @@ -107,6 +108,7 @@ public function createStackOnRemote( int $order = 0, ): array { $this->ensureFederationEnabled(); + $this->permissionService->checkPermission($this->boardMapper, $localBoard->getId(), Acl::PERMISSION_EDIT, $this->userId, false, false); $shareToken = $localBoard->getShareToken(); $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); @@ -123,6 +125,7 @@ public function createStackOnRemote( public function deleteStackOnRemote(Board $localBoard, int $stackId): array { $this->ensureFederationEnabled(); + $this->permissionService->checkPermission($this->boardMapper, $localBoard->getId(), Acl::PERMISSION_EDIT, $this->userId, false, false); $shareToken = $localBoard->getShareToken(); $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); From e6a7bad8fe682ea4ce31abe392af0e1719cca426 Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Mon, 16 Feb 2026 16:57:37 +0100 Subject: [PATCH 18/24] chore: rename new controllers Signed-off-by: grnd-alt --- appinfo/routes.php | 16 ++++++++-------- ...oardController.php => BoardOcsController.php} | 2 +- ...wCardController.php => CardOcsController.php} | 2 +- ...tackController.php => StackOcsController.php} | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) rename lib/Controller/{NewBoardController.php => BoardOcsController.php} (98%) rename lib/Controller/{NewCardController.php => CardOcsController.php} (97%) rename lib/Controller/{NewStackController.php => StackOcsController.php} (97%) diff --git a/appinfo/routes.php b/appinfo/routes.php index f01ff5e1ed..d3b7643ec5 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -133,16 +133,16 @@ ['name' => 'board_api#preflighted_cors', 'url' => '/api/v{apiVersion}/{path}','verb' => 'OPTIONS', 'requirements' => ['path' => '.+']], ], 'ocs' => [ - ['name' => 'new_board#index', 'url' => '/api/v{apiVersion}/boards', 'verb' => 'GET'], - ['name' => 'new_board#read', 'url' => '/api/v{apiVersion}/board/{boardId}', 'verb' => 'GET'], - ['name' => 'new_board#stacks', 'url' => '/api/v{apiVersion}/stacks/{boardId}', 'verb' => 'GET'], - ['name' => 'new_board#create', 'url' => '/api/v{apiVersion}/boards', 'verb' => 'POST'], - ['name' => 'new_board#addAcl', 'url' => '/api/v{apiVersion}/boards/{boardId}/acl', 'verb' => 'POST'], + ['name' => 'board_ocs#index', 'url' => '/api/v{apiVersion}/boards', 'verb' => 'GET'], + ['name' => 'board_ocs#read', 'url' => '/api/v{apiVersion}/board/{boardId}', 'verb' => 'GET'], + ['name' => 'board_ocs#stacks', 'url' => '/api/v{apiVersion}/stacks/{boardId}', 'verb' => 'GET'], + ['name' => 'board_ocs#create', 'url' => '/api/v{apiVersion}/boards', 'verb' => 'POST'], + ['name' => 'board_ocs#addAcl', 'url' => '/api/v{apiVersion}/boards/{boardId}/acl', 'verb' => 'POST'], - ['name' => 'new_card#create', 'url' => '/api/v{apiVersion}/cards', 'verb' => 'POST'], + ['name' => 'card_ocs#create', 'url' => '/api/v{apiVersion}/cards', 'verb' => 'POST'], - ['name' => 'new_stack#create', 'url' => '/api/v{apiVersion}/stacks', 'verb' => 'POST'], - ['name' => 'new_stack#delete', 'url' => '/api/v{apiVersion}/stacks/{stackId}/{boardId}', 'verb' => 'DELETE', 'defaults' => ['boardId' => null]], + ['name' => 'stack_ocs#create', 'url' => '/api/v{apiVersion}/stacks', 'verb' => 'POST'], + ['name' => 'stack_ocs#delete', 'url' => '/api/v{apiVersion}/stacks/{stackId}/{boardId}', 'verb' => 'DELETE', 'defaults' => ['boardId' => null]], ['name' => 'Config#get', 'url' => '/api/v{apiVersion}/config', 'verb' => 'GET'], ['name' => 'Config#setValue', 'url' => '/api/v{apiVersion}/config/{key}', 'verb' => 'POST'], diff --git a/lib/Controller/NewBoardController.php b/lib/Controller/BoardOcsController.php similarity index 98% rename from lib/Controller/NewBoardController.php rename to lib/Controller/BoardOcsController.php index bb17b6d3cf..2e7c57d2c4 100644 --- a/lib/Controller/NewBoardController.php +++ b/lib/Controller/BoardOcsController.php @@ -13,7 +13,7 @@ use OCP\IRequest; use Psr\Log\LoggerInterface; -class NewBoardController extends OCSController { +class BoardOcsController extends OCSController { public function __construct( string $appName, IRequest $request, diff --git a/lib/Controller/NewCardController.php b/lib/Controller/CardOcsController.php similarity index 97% rename from lib/Controller/NewCardController.php rename to lib/Controller/CardOcsController.php index c4b12ebbac..a244ae44f7 100644 --- a/lib/Controller/NewCardController.php +++ b/lib/Controller/CardOcsController.php @@ -14,7 +14,7 @@ use OCP\AppFramework\OCSController; use OCP\IRequest; -class NewCardController extends OCSController { +class CardocsController extends OCSController { public function __construct( string $appName, IRequest $request, diff --git a/lib/Controller/NewStackController.php b/lib/Controller/StackOcsController.php similarity index 97% rename from lib/Controller/NewStackController.php rename to lib/Controller/StackOcsController.php index f3c24ea010..01ee37ccce 100644 --- a/lib/Controller/NewStackController.php +++ b/lib/Controller/StackOcsController.php @@ -13,7 +13,7 @@ use OCP\AppFramework\OCSController; use OCP\IRequest; -class NewStackController extends OCSController { +class StackOcsController extends OCSController { public function __construct( string $appName, IRequest $request, From bc53969e14378955581d4cc5bf4ff801a80359fb Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Mon, 16 Feb 2026 17:33:47 +0100 Subject: [PATCH 19/24] fix: respect admin config values for federation Signed-off-by: grnd-alt --- lib/Federation/DeckFederationProvider.php | 3 +++ lib/Listeners/ResourceTypeRegisterListener.php | 10 ++++++++++ lib/Service/BoardService.php | 3 +++ lib/Service/ConfigService.php | 14 ++++++++++++++ lib/Service/ExternalBoardService.php | 16 +++++----------- lib/Service/PermissionService.php | 2 ++ 6 files changed, 37 insertions(+), 11 deletions(-) diff --git a/lib/Federation/DeckFederationProvider.php b/lib/Federation/DeckFederationProvider.php index a15a57bb0a..cd8b3394ab 100644 --- a/lib/Federation/DeckFederationProvider.php +++ b/lib/Federation/DeckFederationProvider.php @@ -8,6 +8,7 @@ use OCA\Deck\Db\Board; use OCA\Deck\Db\BoardMapper; use OCA\Deck\Db\ChangeHelper; +use OCA\Deck\Service\ConfigService; use OCP\Common\Exception\NotFoundException; use OCP\Federation\ICloudFederationProvider; use OCP\Federation\ICloudFederationShare; @@ -23,6 +24,7 @@ public function __construct( private BoardMapper $boardMapper, private AclMapper $aclMapper, private ChangeHelper $changeHelper, + private ConfigService $configService, ) { } @@ -31,6 +33,7 @@ public function getShareType(): string { } public function shareReceived(ICloudFederationShare $share): string { + $this->configService->ensureFederationEnabled(); $externalBoard = new Board(); $externalBoard->setTitle($share->getResourceName()); diff --git a/lib/Listeners/ResourceTypeRegisterListener.php b/lib/Listeners/ResourceTypeRegisterListener.php index 131a72be3b..0cbcf10d57 100644 --- a/lib/Listeners/ResourceTypeRegisterListener.php +++ b/lib/Listeners/ResourceTypeRegisterListener.php @@ -2,6 +2,8 @@ namespace OCA\Deck\Listeners; +use OCA\Deck\Exceptions\FederationDisabledException; +use OCA\Deck\Service\ConfigService; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use OCP\OCM\Events\ResourceTypeRegisterEvent; @@ -10,6 +12,7 @@ class ResourceTypeRegisterListener implements IEventListener { public function __construct( protected IOCMProvider $provider, + protected ConfigService $configService ) { } @@ -17,6 +20,13 @@ public function handle(Event $event):void { if (!$event instanceof ResourceTypeRegisterEvent) { return; } + + try { + $this->configService->ensureFederationEnabled(); + } catch (FederationDisabledException $e) { + return; + } + $event->registerResourceType( 'deck', ['user'], diff --git a/lib/Service/BoardService.php b/lib/Service/BoardService.php index 1e80b42188..4de9dd9aac 100644 --- a/lib/Service/BoardService.php +++ b/lib/Service/BoardService.php @@ -82,6 +82,7 @@ public function __construct( private SessionMapper $sessionMapper, private IUserManager $userManager, private ISecureRandom $random, + private ConfigService $configService, private ?string $userId, ) { } @@ -374,6 +375,7 @@ public function addAcl(int $boardId, int $type, $participant, bool $edit, bool $ $acl = new Acl(); if ($type === Acl::PERMISSION_TYPE_REMOTE) { + $this->configService->ensureFederationEnabled(); $sharedBy = $this->userManager->get($this->userId); $board = $this->find($boardId); $token = $this->random->generate(32); @@ -444,6 +446,7 @@ public function updateAcl(int $id, bool $edit, bool $share, bool $manage): Acl { $this->changeHelper->boardChanged($acl->getBoardId()); if ($acl->getType() === Acl::PERMISSION_TYPE_REMOTE) { + $this->configService->ensureFederationEnabled(); $notification = $this->federationFactory->getCloudFederationNotification(); if (!$notification instanceof ICloudFederationNotification) { throw new \InvalidArgumentException('Invalid notification type'); diff --git a/lib/Service/ConfigService.php b/lib/Service/ConfigService.php index 3618b169a3..3a70f00f7e 100644 --- a/lib/Service/ConfigService.php +++ b/lib/Service/ConfigService.php @@ -12,6 +12,7 @@ use OCA\Deck\AppInfo\Application; use OCA\Deck\BadRequestException; +use OCA\Deck\Exceptions\FederationDisabledException; use OCA\Deck\NoPermissionException; use OCP\IConfig; use OCP\IGroup; @@ -138,6 +139,19 @@ public function isCardIdBadgeEnabled(): bool { return (bool)$this->config->getUserValue($userId, Application::APP_ID, 'cardIdBadge', $defaultState); } + public function ensureFederationEnabled() { + if (!$this->get('federationEnabled')) { + throw new FederationDisabledException(); + } + // @TODO fine tune these config values to respect incoming and outgoing federation separately + if ($this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'no') !== 'yes') { + throw new FederationDisabledException(); + } + if ($this->config->getAppValue('files_sharing', 'incoming_server2server_share_enabled', 'no') !== 'yes') { + throw new FederationDisabledException(); + } + } + public function set($key, $value) { $userId = $this->getUserId(); if ($userId === null) { diff --git a/lib/Service/ExternalBoardService.php b/lib/Service/ExternalBoardService.php index 3b06e85518..d5e5824b38 100644 --- a/lib/Service/ExternalBoardService.php +++ b/lib/Service/ExternalBoardService.php @@ -25,14 +25,8 @@ public function __construct( ) { } - private function ensureFederationEnabled(): void { - if (!$this->configService->get('federationEnabled')) { - throw new FederationDisabledException(); - } - } - public function getExternalBoardFromRemote(Board $localBoard):DataResponse { - $this->ensureFederationEnabled(); + $this->configService->ensureFederationEnabled(); $shareToken = $localBoard->getShareToken(); $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); @@ -42,7 +36,7 @@ public function getExternalBoardFromRemote(Board $localBoard):DataResponse { return new DataResponse($this->LocalizeRemoteBoard($ocs, $localBoard)); } public function getExternalStacksFromRemote(Board $localBoard):DataResponse { - $this->ensureFederationEnabled(); + $this->configService->ensureFederationEnabled(); $shareToken = $localBoard->getShareToken(); $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); $ownerCloudId = $this->cloudIdManager->resolveCloudId($localBoard->getOwner()); @@ -81,7 +75,7 @@ public function createCardOnRemote( ?array $users = [], ?int $boardId = null, ): array { - $this->ensureFederationEnabled(); + $this->configService->ensureFederationEnabled(); $this->permissionService->checkPermission($this->boardMapper, $localBoard->getId(), Acl::PERMISSION_EDIT, $this->userId, false, false); $shareToken = $localBoard->getShareToken(); $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); @@ -107,7 +101,7 @@ public function createStackOnRemote( string $title, int $order = 0, ): array { - $this->ensureFederationEnabled(); + $this->configService->ensureFederationEnabled(); $this->permissionService->checkPermission($this->boardMapper, $localBoard->getId(), Acl::PERMISSION_EDIT, $this->userId, false, false); $shareToken = $localBoard->getShareToken(); $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); @@ -124,7 +118,7 @@ public function createStackOnRemote( } public function deleteStackOnRemote(Board $localBoard, int $stackId): array { - $this->ensureFederationEnabled(); + $this->configService->ensureFederationEnabled(); $this->permissionService->checkPermission($this->boardMapper, $localBoard->getId(), Acl::PERMISSION_EDIT, $this->userId, false, false); $shareToken = $localBoard->getShareToken(); $participantCloudId = $this->cloudIdManager->getCloudId($this->userId, null); diff --git a/lib/Service/PermissionService.php b/lib/Service/PermissionService.php index 72d2005264..ef3fedad19 100644 --- a/lib/Service/PermissionService.php +++ b/lib/Service/PermissionService.php @@ -43,6 +43,7 @@ public function __construct( private AclMapper $aclMapper, private BoardMapper $boardMapper, private IUserManager $userManager, + private ConfigService $configService, private IGroupManager $groupManager, private IManager $shareManager, private IConfig $config, @@ -200,6 +201,7 @@ private function getBoard(int $boardId, bool $allowDeleted = false): Board { public function externalUserCan(array $acls, $permission, $shareToken = null) { + $this->configService->ensureFederationEnabled(); foreach ($acls as $acl) { if ($acl->getType() === Acl::PERMISSION_TYPE_REMOTE) { $token = $acl->getToken(); From 0e15c1394d67517e338d0a2d812d8417331751e9 Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Mon, 16 Feb 2026 17:42:24 +0100 Subject: [PATCH 20/24] fix: do not add default permissions to federated shares Signed-off-by: grnd-alt --- lib/Federation/DeckFederationProvider.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Federation/DeckFederationProvider.php b/lib/Federation/DeckFederationProvider.php index cd8b3394ab..ed617ac7ff 100644 --- a/lib/Federation/DeckFederationProvider.php +++ b/lib/Federation/DeckFederationProvider.php @@ -46,9 +46,9 @@ public function shareReceived(ICloudFederationShare $share): string { $acl->setBoardId($insertedBoard->getId()); $acl->setType(Acl::PERMISSION_TYPE_USER); $acl->setParticipant($share->getShareWith()); - $acl->setPermissionEdit(true); + $acl->setPermissionEdit(false); $acl->setPermissionShare(false); - $acl->setPermissionManage(true); + $acl->setPermissionManage(false); $this->aclMapper->insert($acl); $this->changeHelper->boardChanged($insertedBoard->getId()); From f91394b0637956429550489075aedb651447dd60 Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Mon, 16 Feb 2026 18:38:03 +0100 Subject: [PATCH 21/24] chore: improve ci Signed-off-by: grnd-alt --- .php-cs-fixer.cache | 1 - cypress/e2e/boardFeatures.js | 2 +- cypress/e2e/cardFeatures.js | 4 +- lib/Controller/BoardController.php | 2 +- lib/Controller/BoardOcsController.php | 21 +++----- lib/Controller/CardOcsController.php | 2 +- lib/Controller/StackOcsController.php | 4 +- lib/Federation/DeckFederationProvider.php | 8 +-- lib/Federation/DeckFederationProxy.php | 11 ++-- .../ResourceTypeRegisterListener.php | 7 ++- lib/Middleware/FederationMiddleware.php | 2 +- lib/Service/BoardService.php | 28 +++++----- lib/Service/ConfigService.php | 2 +- lib/Service/ExternalBoardService.php | 6 +-- lib/Service/PermissionService.php | 14 +++-- psalm.xml | 2 + src/components/DeckAppSettings.vue | 6 +-- src/components/board/SharingTabSidebar.vue | 2 - src/components/navigation/AppNavigation.vue | 2 +- .../navigation/AppNavigationBoard.vue | 9 ++-- .../navigation/AppNavigationBoardCategory.vue | 3 -- src/services/BoardApi.js | 1 - src/services/StackApi.js | 1 + src/store/card.js | 3 ++ src/store/main.js | 53 ++++++++++--------- src/store/stack.js | 3 ++ tests/data/deck.json | 17 ++++-- tests/stub.phpstub | 28 ++++++++++ tests/unit/Db/AclMapperTest.php | 2 + tests/unit/Db/AclTest.php | 9 ++-- tests/unit/Db/BoardMapperTest.php | 2 + tests/unit/Db/BoardTest.php | 8 +++ .../Middleware/ExceptionMiddlewareTest.php | 2 + tests/unit/Service/BoardServiceTest.php | 9 ++++ tests/unit/Service/PermissionServiceTest.php | 1 + tests/unit/controller/BoardControllerTest.php | 2 + tests/unit/controller/PageControllerTest.php | 7 +++ 37 files changed, 176 insertions(+), 110 deletions(-) delete mode 100644 .php-cs-fixer.cache diff --git a/.php-cs-fixer.cache b/.php-cs-fixer.cache deleted file mode 100644 index 2b0df0027d..0000000000 --- a/.php-cs-fixer.cache +++ /dev/null @@ -1 +0,0 @@ -{"php":"8.5.1","version":"3.93.0","indent":"\t","lineEnding":"\n","rules":{"encoding":true,"full_opening_tag":true,"blank_line_after_namespace":true,"braces_position":{"allow_single_line_anonymous_functions":false},"class_definition":true,"constant_case":true,"control_structure_braces":true,"control_structure_continuation_position":true,"elseif":true,"function_declaration":{"closure_function_spacing":"one"},"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":{"on_multiline":"ignore"},"modifier_keywords":{"elements":["method","property"]},"no_break_comment":true,"no_closing_tag":true,"no_multiple_statements_per_line":true,"no_space_around_double_colon":true,"no_spaces_after_function_name":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":true,"single_import_per_statement":true,"single_line_after_imports":true,"single_space_around_construct":{"constructs_followed_by_a_single_space":["abstract","as","case","catch","class","do","else","elseif","final","for","foreach","function","if","interface","namespace","private","protected","public","static","switch","trait","try","use_lambda","while"],"constructs_preceded_by_a_single_space":["as","else","elseif","use_lambda"]},"spaces_inside_parentheses":true,"statement_indentation":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"align_multiline_comment":true,"array_indentation":true,"array_syntax":true,"binary_operator_spaces":{"default":"single_space"},"blank_line_after_opening_tag":true,"cast_spaces":{"space":"none"},"concat_space":{"spacing":"one"},"curly_braces_position":{"classes_opening_brace":"same_line","functions_opening_brace":"same_line"},"list_syntax":true,"lowercase_cast":true,"method_chaining_indentation":true,"no_leading_import_slash":true,"no_short_bool_cast":true,"no_spaces_inside_parenthesis":true,"no_unused_imports":true,"no_whitespace_in_blank_line":true,"nullable_type_declaration_for_default_null_value":true,"nullable_type_declaration":{"syntax":"question_mark"},"operator_linebreak":{"position":"beginning"},"ordered_imports":{"imports_order":["class","function","const"],"sort_algorithm":"alpha"},"phpdoc_align":{"align":"left"},"phpdoc_single_line_var_spacing":true,"phpdoc_var_annotation_correct_order":true,"short_scalar_cast":true,"single_quote":{"strings_containing_single_quote_chars":false},"trailing_comma_in_multiline":{"elements":["parameters"]},"types_spaces":{"space":"none","space_multiple_catch":"none"},"type_declaration_spaces":{"elements":["function","property"]},"visibility_required":{"elements":["property","method","const"]},"yoda_style":{"equal":false,"identical":false,"less_and_greater":false},"PhpCsFixerCustomFixers\/multiline_promoted_properties":true},"ruleCustomisationPolicyVersion":"null-policy","hashes":{"appinfo\/autoload.php":"c9887cd20064590621418f687e8be54e","appinfo\/routes.php":"2b63050ede35d9789d6556fd0ce37fa0","lib\/Activity\/SettingBase.php":"c2d2f5d8e5e27228972cd92f2f75ac7e","lib\/Activity\/SettingChanges.php":"faad9a6994b2a9f84ccf9f4660cddfad","lib\/Activity\/SettingDescription.php":"ab9a2dbb19d2efc490fd5a66ee789a88","lib\/Activity\/ChangeSet.php":"0449998876a513c237d7d2bcddfb9806","lib\/Activity\/DeckProvider.php":"337993875edd981a9cd213362be1231e","lib\/Activity\/ActivityManager.php":"7b3cc029cc1b454c4fb9e26a3df75311","lib\/Activity\/Filter.php":"ed0eeef85d2bf56ea9acea3ea036659a","lib\/Activity\/SettingComment.php":"ac157bc7ca99333bbe635d9d241714a2","lib\/AppInfo\/Application.php":"06f00c88cd6f9a3155aa2eefcb804623","lib\/Cache\/AttachmentCacheHelper.php":"2ef9d1b9cdf7ff6096a08c6b18e12aca","lib\/Collaboration\/Resources\/ResourceProvider.php":"76760e0096dfc6b8df8a8d3372654da8","lib\/Collaboration\/Resources\/ResourceProviderCard.php":"4a7fda5e0cc9c0a4273df9ed9bb45dde","lib\/Command\/BoardImport.php":"9aa00bc87e064636e2706294aa554a34","lib\/Command\/TransferOwnership.php":"0e7fd056889078acea1568914e5c52a2","lib\/Command\/UserExport.php":"8d5b3e3b50cca2b33bc6f11092d75d8b","lib\/Command\/CalendarToggle.php":"073345ab4f3a8ea6044055dc6e43d2cc","lib\/Controller\/AttachmentApiV11Controller.php":"bae1746ee4440ae5ca978d6febc7d535","lib\/Controller\/SessionController.php":"0b12c7648cd7067911bfa6ec0c4083b8","lib\/Controller\/AttachmentApiController.php":"ea82a8566eaba6beecb60cdaad937ff8","lib\/Controller\/AttachmentController.php":"b9f3b343fac1955f40f0204517e2cd55","lib\/Controller\/BoardApiController.php":"3b3d0237e88ade2891628880ed11f36d","lib\/Controller\/BoardImportApiController.php":"375fd366478cb49037525daddefd27e0","lib\/Controller\/CardApiController.php":"36b99ae92d448112a7dcb2f7a19110ef","lib\/Controller\/CardController.php":"5a44d774cd65e8608d4118b19315f39b","lib\/Controller\/CommentsApiController.php":"13e4305002931c1cfa824b9ccc869c04","lib\/Controller\/ConfigController.php":"38e9e3b3131e3660aa810cd7f8e76a96","lib\/Controller\/LabelApiController.php":"f6347352e4dc9c3cb24c18f1236d1643","lib\/Controller\/LabelController.php":"08dd8f96f433b060d8a3b5414a42f359","lib\/Controller\/OverviewApiController.php":"d84e404678551275579ee74d5bd438e9","lib\/Controller\/SearchController.php":"50de19c4ad2f4174299707d743b9424e","lib\/Controller\/StackApiController.php":"a993aae2e4539564bf188c639c0c31fa","lib\/Controller\/StackController.php":"a81231f4ff0155be214c1b82baa6c13b","lib\/Controller\/BoardController.php":"7fed545ed84aa631377e35ff99b53a0e","lib\/Controller\/NewBoardController.php":"d833d2ed02195f6012a5ef3dd4bda86d","lib\/Controller\/NewCardController.php":"0eb4e29be97a17151f8e2f0fbc8c72ba","lib\/Controller\/NewStackController.php":"aa81fde054ea19aa61d425e227df6db2","lib\/Controller\/PageController.php":"326118672c68617f201f119e68096293","lib\/Cron\/CardDescriptionActivity.php":"d8910db39280acaeb6f64297cc4f6bf3","lib\/Cron\/ScheduledNotifications.php":"0266f829a96a39b9a7b1e0ba0f501070","lib\/Cron\/DeleteCron.php":"a3d3037c79354b3eb9f069c4b2344f23","lib\/Cron\/SessionsCleanup.php":"5542e5a486fbb17afb017b7d7fccb8a4","lib\/DAV\/Calendar.php":"d5c4c28c133eb2586a88463f071352ce","lib\/DAV\/CalendarObject.php":"8090769df472f84c3bf5b98a2b28d763","lib\/DAV\/CalendarPlugin.php":"80a8719407a7be88518ad4674f42d247","lib\/DAV\/DeckCalendarBackend.php":"438208533a4d38943f057302f0adabf6","lib\/Dashboard\/DeckWidgetToday.php":"0815fe874acb138b3b15b68974adc790","lib\/Dashboard\/DeckWidgetTomorrow.php":"0b84fbcdd987348e055ec89d57fc22f1","lib\/Dashboard\/DeckWidgetUpcoming.php":"0e2a7c7551ea165c0b7b701fb49c3a11","lib\/Db\/Attachment.php":"17cd484061b53a1e6dac26ad2c4cee9a","lib\/Db\/Circle.php":"47226372be7d955bf40c0fbb665e602d","lib\/Db\/Group.php":"1b90c750ffaed2c053c4b0190fe9734e","lib\/Db\/RelationalObject.php":"dd1a1ae0945e19bd3352197fe6bfb414","lib\/Db\/ChangeHelper.php":"984659676904dcb3fbf05cdf8992e705","lib\/Db\/RelationalEntity.php":"aee95af46f9527e91dd61f755150cb7b","lib\/Db\/Assignment.php":"0625b53e8336dbf962efcac09262d644","lib\/Db\/AssignmentMapper.php":"d54ff3ca8d68ea391d42f95d9faa575d","lib\/Db\/AttachmentMapper.php":"14f387fb7524ea7f5b8bef0ac88388f0","lib\/Db\/Card.php":"7d8be0f616814240efedd293fb46aedf","lib\/Db\/CardMapper.php":"bbb3286dceb204b6cbe5ed71235aeff5","lib\/Db\/DeckMapper.php":"b944ceb9768bd6ea7a1e3d22c459fa95","lib\/Db\/IPermissionMapper.php":"eaf7419e8236dbccc823661532bd628d","lib\/Db\/Label.php":"2c786fd375cbe3e0786115d31c0f785d","lib\/Db\/Session.php":"c0f1c6fbcb83c82983933952b4c4747c","lib\/Db\/Stack.php":"9a6ba2a2c5d66de749d362023ae0a160","lib\/Db\/StackMapper.php":"65c8de410e804c588db2dd5fc77c6e3e","lib\/Db\/User.php":"298d1ddd733711e1e66a3cf22d180a15","lib\/Db\/Acl.php":"ce7cd4ee4340397df19e641caaf34f71","lib\/Db\/AclMapper.php":"6928a9bd36b60cb8d3c3d35505f6e3e6","lib\/Db\/Board.php":"7a0cf0336cce5f7eceb605aed2b715af","lib\/Db\/BoardMapper.php":"864dffa607e73ec693515d7e1f57b0ba","lib\/Db\/LabelMapper.php":"4b473ca4c4686e414582f2863879ee32","lib\/Db\/SessionMapper.php":"090537bd94b18649743bea0dd512d1fd","lib\/Event\/AAclEvent.php":"4ee2811c708009e20532e1183c4dccf7","lib\/Event\/ABoardImportGetAllowedEvent.php":"9764edc27ee52eac04886852cc36c847","lib\/Event\/AclCreatedEvent.php":"80c8dec71734902af22ba3e1081a8a08","lib\/Event\/AclDeletedEvent.php":"60f760f0596a646771ed8dc513f4ffca","lib\/Event\/AclUpdatedEvent.php":"1cc52e39754bcb8190ca6ada6b0f8174","lib\/Event\/BoardImportGetAllowedEvent.php":"ef470b14f40108c09151cd129bec63ed","lib\/Event\/CardCreatedEvent.php":"411acb38a86528c87302ce49541c8b04","lib\/Event\/CardDeletedEvent.php":"978a67335acc5c25a5e500c63498a7bb","lib\/Event\/CardUpdatedEvent.php":"0a3ff12304b822494f69bb953d38b801","lib\/Event\/ACardEvent.php":"0492ee448c3e9b167b806109b5475986","lib\/Event\/BoardUpdatedEvent.php":"55c8911833ceeed09d33e74696a37d31","lib\/Event\/SessionClosedEvent.php":"6405cae8b34bed4bbd667f5fa7078cd1","lib\/Event\/SessionCreatedEvent.php":"e13f0d2234a37ea4d3fb411f3536bc3c","lib\/Exceptions\/ConflictException.php":"554af323e3eeed26ae94ec9522ab555e","lib\/Exceptions\/FederationDisabledException.php":"e75488f00fa500628850a4e0455224d2","lib\/Listeners\/ParticipantCleanupListener.php":"a1f28800657269d3049667369e508ac0","lib\/Listeners\/ResourceAdditionalScriptsListener.php":"75f2c119b90801ade237594d04e8c88b","lib\/Listeners\/BeforeTemplateRenderedListener.php":"3fb2d67b4a095e8aa34fff6f4d54acc3","lib\/Listeners\/ResourceListener.php":"a11490b2d551b06c7fee73697bdd0b73","lib\/Listeners\/AclCreatedRemovedListener.php":"1ffdeafea807e7a7006f5448c59dc040","lib\/Listeners\/CommentEventListener.php":"452b0557762d19c881875a1b7c11ee34","lib\/Listeners\/FullTextSearchEventListener.php":"f01ba7c49df2072e6c8aa6984e3d84a3","lib\/Listeners\/LiveUpdateListener.php":"8bd7c93d9a27a93de05e4732189e9d67","lib\/Listeners\/ResourceTypeRegisterListener.php":"f0f94bf806ad7562b3fdbfad33212c51","lib\/Middleware\/ExceptionMiddleware.php":"03c6190c926896c23c17f0daaeaac778","lib\/Middleware\/DefaultBoardMiddleware.php":"ff162aa6de08c12223be88d914a0bac3","lib\/Middleware\/FederationMiddleware.php":"8ff11eb6086abfa55e5faac6aaaab595","lib\/Migration\/DeletedCircleCleanup.php":"17532a9418c1628c624df5cbda1e2856","lib\/Migration\/Version1000Date20200306161713.php":"82562a9b61c5a31613f59aa208534d12","lib\/Migration\/Version1000Date20200308073933.php":"00bbd47ef753630b72c122ad05e1babc","lib\/Migration\/Version1011Date20230901010840.php":"c0caea1dc1dbc9352c1f76e11b8ce004","lib\/Migration\/Version1011Date20231106160059.php":"fc35eb1e761a591390e004fb55b2cb22","lib\/Migration\/Version10200Date20201111150114.php":"376a20164d1e9d50741c4e3c7bb4a89e","lib\/Migration\/Version10800Date20220422061816.php":"e8ba6f14ef20588edf01b7a07f5aefdf","lib\/Migration\/Version10900Date202206151724222.php":"86343d019bd5a172e4429369d8f4a2e3","lib\/Migration\/Version11000Date20240222115515.php":"41fad9525613b229dab223fc39c1c219","lib\/Migration\/LabelMismatchCleanup.php":"ce4ae70d420fa9c0723718f1ba8baa25","lib\/Migration\/Version11001Date20251009165313.php":"ca413a9b7289287b0d385891b5b2b664","lib\/Migration\/Version11001Date20251020122010.php":"d736b5382d49f29b4772b6974c7fb422","lib\/Model\/OptionalNullableValue.php":"f036eab84eefd745e82202aab17363f4","lib\/Model\/BoardSummary.php":"0e1a838ffed8e83322815e5eb5787c20","lib\/Model\/CardDetails.php":"277e4180484ffbd7b53d7fcf3487fbef","lib\/Notification\/NotificationHelper.php":"a7cb32e5c69ae4b6fef8db5aac477cf5","lib\/Notification\/Notifier.php":"1340393761d067aa182a6ad8b55707f2","lib\/Provider\/DeckProvider.php":"c9233171f9a532634535499d1b56a142","lib\/Reference\/CardReferenceProvider.php":"7c0daed5705113156d078bd7f2d37300","lib\/Reference\/CreateCardReferenceProvider.php":"0a49dc73285a760ce575d9c71eb055ce","lib\/Reference\/BoardReferenceProvider.php":"ed5ca614b07b3ac7e107baf1cda88f98","lib\/Reference\/CommentReferenceProvider.php":"15a93c88f8710758c3ec345141fb0284","lib\/Search\/Query\/DateQueryParameter.php":"f938dfb093010a03301633341378034d","lib\/Search\/Query\/AQueryParameter.php":"323af9216886dc0c19942afd6614ce87","lib\/Search\/Query\/SearchQuery.php":"e54bd541ba56bc6759b6b5d3edd91478","lib\/Search\/Query\/StringQueryParameter.php":"3f9c93fe3b110a732ee8bb715f2c7642","lib\/Search\/CardCommentProvider.php":"fcc3ae2d34ae1e706d65554c50602822","lib\/Search\/CardSearchResultEntry.php":"6780b6189616782626a982fa44f0a4ff","lib\/Search\/CommentSearchResultEntry.php":"681e8bd83005b86daa266ccb0e9f46f8","lib\/Search\/DeckProvider.php":"f46d93de0976defca1eb0ab6cdda3603","lib\/Search\/BoardSearchResultEntry.php":"9605659947b7bfecff4480a04653fb10","lib\/Search\/FilterStringParser.php":"3a49ee9b681903f3c913a362503767f7","lib\/Service\/Importer\/Systems\/DeckJsonService.php":"8bea9ad04928e80e6dc7d93ce6cc5d28","lib\/Service\/Importer\/Systems\/TrelloApiService.php":"685c9fc96ef7dddb4495b545f8b454cf","lib\/Service\/Importer\/Systems\/TrelloJsonService.php":"c6eb3043adcf9c4d083cbbe95433490b","lib\/Service\/Importer\/ABoardImportService.php":"d585d9ae854ef7e2d8f7785da163797f","lib\/Service\/Importer\/BoardImportCommandService.php":"1ee4e2ed1728ce6cff2af3fb0ceaea5b","lib\/Service\/Importer\/BoardImportService.php":"123cd210419fd7d393abeb6769f1daeb","lib\/Service\/FileService.php":"7245f27c159f584bd3b63469306fe0cd","lib\/Service\/IAttachmentService.php":"43e00697aae1b373f8c4743a78dbef76","lib\/Service\/ICustomAttachmentService.php":"bd73412ad67f16033d87923fbcc8218b","lib\/Service\/SearchService.php":"22d5cbd4323c5b06c21cce2666e43670","lib\/Service\/AttachmentService.php":"e1cdabee2e7ae11481d3464e6cd009ed","lib\/Service\/CirclesService.php":"eb642cfdc4ce03580bfe4ce554e0c8a6","lib\/Service\/CommentService.php":"012324dc0ea9b04c89c4a0bb283ab072","lib\/Service\/FullTextSearchService.php":"fa0d4be054ef537531c3f273b15205d4","lib\/Service\/LabelService.php":"44372be0bb9e39c2be057f82d4150202","lib\/Service\/OverviewService.php":"406329da0afebf5e3f46fade9e93a3b3","lib\/Service\/AssignmentService.php":"61b110149f3526a10d5540798aa959a7","lib\/Service\/BoardService.php":"b4c01e3158eb0c0e9f21f6257296ee22","lib\/Service\/CardService.php":"71f92c2b04b8cac8b9c79213b6ac5c7d","lib\/Service\/ConfigService.php":"840a768b3bf8a54d9f72567d0a312af1","lib\/Service\/DefaultBoardService.php":"572ffa1af2238f641b3cd88af73a892d","lib\/Service\/ExternalBoardService.php":"8a141cf80b8a4398516ad6870d4c6a87","lib\/Service\/FilesAppService.php":"ba5688134e5a8247683b1507c4a746fd","lib\/Service\/PermissionService.php":"5b98314a6e9d28a6c22a0ac3869370b5","lib\/Service\/SessionService.php":"e71e3cb0653d78719b2026a295dfcc57","lib\/Service\/StackService.php":"089864b2972b82f3df72dd5eade606ca","lib\/Sharing\/Listener.php":"2c8febc03a61860720e51bc71b0142db","lib\/Sharing\/ShareAPIHelper.php":"a7734c7bcf4bd3040679b86fe6474488","lib\/Sharing\/DeckShareProvider.php":"8303f1ed17723a57d9c6c07fc3d89896","lib\/Validators\/AssignmentServiceValidator.php":"96a432a0375d521830c8a8841f924d8d","lib\/Validators\/AttachmentServiceValidator.php":"82e51705cadf84aa2ef29bf019d2fa79","lib\/Validators\/BoardServiceValidator.php":"224bcb672796fc393a18258f36b089cb","lib\/Validators\/CardServiceValidator.php":"198c8b617e8acc0c5c9865ce348b361a","lib\/Validators\/StackServiceValidator.php":"a99a6366c6ede5e5bc76a33b9657f913","lib\/Validators\/LabelServiceValidator.php":"d6ac86ca3616e37e76077441885d1bfc","lib\/Validators\/BaseValidator.php":"a5f6b6622cea6e7f9cf870e6ae8f9841","lib\/ArchivedItemException.php":"489157f79533a404643034df63074b67","lib\/BadRequestException.php":"8c505f975cafb9ed9cf3c99f22593c33","lib\/Capabilities.php":"1aeb16d382faf4ce8e82a42eeeb7266e","lib\/InvalidAttachmentType.php":"5964ebe6bc8ec08dc523409c4c7f59fc","lib\/NoPermissionException.php":"3812d8f1cfcf46e1c6cf3b8ef815a8bf","lib\/NotFoundException.php":"cc22471994a7acd51b6125265aaf3525","lib\/NotifyPushEvents.php":"b00ce82f3eb95766049605ef5b29965e","lib\/StatusException.php":"1d22687a09c47bbd1cf2fddb123193fb","lib\/Teams\/DeckTeamResourceProvider.php":"0f800de43405827fb9cbfbcb95df347c","lib\/Federation\/DeckFederationProvider.php":"43fece7716b7044ecdd85fdc11b37f7b","lib\/Federation\/DeckFederationProxy.php":"38d0de74614cc62e78e6c79ac318dce9","templates\/main.php":"0ba2f93de5f8c4358fb6ef45f91c3ff9","tests\/integration\/app\/AppTest.php":"d9e45b231b5127720114dc85539c5c68","tests\/integration\/database\/TransferOwnershipTest.php":"83376bf7ebf7ec52073e2e33c22373f2","tests\/integration\/database\/AssignmentMapperTest.php":"12d612fa27b750928bcda17b2ebfe594","tests\/integration\/database\/BoardDatabaseTest.php":"a60798521ce8cc904fadad4b8e23ae4d","tests\/integration\/features\/bootstrap\/AttachmentContext.php":"074e470412e9a5f2aa928e46ac44b05e","tests\/integration\/features\/bootstrap\/BoardContext.php":"3e354f8433d2cc64241708480535dc4f","tests\/integration\/features\/bootstrap\/CommentContext.php":"47b9ee5b1438d4f0506bfed344e5314c","tests\/integration\/features\/bootstrap\/RequestContext.php":"6a7e73090bee3e0503f286b34711d40e","tests\/integration\/features\/bootstrap\/RequestTrait.php":"020fa9411580d6c29099af41af6b3757","tests\/integration\/features\/bootstrap\/SearchContext.php":"5266ce5afa59262754b01f573f2c4b32","tests\/integration\/features\/bootstrap\/ServerContext.php":"e1d7108f84442041e5e2c05e1ef7d6db","tests\/integration\/features\/bootstrap\/SessionContext.php":"4cbcf446b2e39cb76b77fb767de97dce","tests\/integration\/import\/ImportExportTest.php":"957f550aaca9d591e9e98b2e5bb1b457","tests\/unit\/Activity\/ChangeSetTest.php":"b02e6b2b88bedd339a7e1297b855c8b9","tests\/unit\/Activity\/FilterTest.php":"d632c4d32c6ada1e54f45adb31baadbd","tests\/unit\/Activity\/SettingTest.php":"3dd384223e6c8be763c0674427585bef","tests\/unit\/Activity\/ActivityManagerTest.php":"c1475547bd9681b1efa0da0e0d52ac4d","tests\/unit\/Activity\/DeckProviderTest.php":"799fbceb9cfb32c668e6c7473d3275a6","tests\/unit\/Command\/BoardImportTest.php":"891acbba8561b00152427521fe84f2fb","tests\/unit\/Command\/UserExportTest.php":"2a4b48e35e61dbb2c152fcf748e79fe1","tests\/unit\/Cron\/ScheduledNoificationsTest.php":"379e557e4c15ebd1afbcb9e88c0be441","tests\/unit\/Cron\/DeleteCronTest.php":"0690c8fcbadce3cfbc81a0aa814618cb","tests\/unit\/Db\/AclMapperTest.php":"997e432ec096be15c248696c76f8e59e","tests\/unit\/Db\/AclTest.php":"59522cd80027451df59f63c47af0d2f4","tests\/unit\/Db\/AttachmentTest.php":"d4f94a49b089b4725a352c38918acff2","tests\/unit\/Db\/BoardTest.php":"982014b756bb98c8456d90d9fdd7481c","tests\/unit\/Db\/GroupTest.php":"b0de093875faefd9b030dbdec0fb113d","tests\/unit\/Db\/LabelTest.php":"362996963d8f7b01f9ec0392848a0307","tests\/unit\/Db\/StackTest.php":"5e1d85db6d6af930a2e8c4fbf6a31549","tests\/unit\/Db\/UserTest.php":"e1a5994ee6429355029b64ab075c98f2","tests\/unit\/Db\/AttachmentMapperTest.php":"1ac2b9bad049a517268ba3554b14b47f","tests\/unit\/Db\/BoardMapperTest.php":"e6222d4e78f49af0885edd421f3cfed2","tests\/unit\/Db\/CardTest.php":"c3858c4fc36fb89471d56daf0e9d0d77","tests\/unit\/Db\/RelationalEntityTest.php":"1b30a6017ef09252946d08b53e40b16f","tests\/unit\/Middleware\/ExceptionMiddlewareTest.php":"ccf86f5b6bd7d379f882bc4d15598f51","tests\/unit\/Notification\/NotificationHelperTest.php":"7b756aa22a9e658477639abac64ee473","tests\/unit\/Notification\/NotifierTest.php":"479d1d3140c88ea002a767d6f63f255f","tests\/unit\/Reference\/CardReferenceProviderTest.php":"0ad94faba4d90100e1012071cd7c39bd","tests\/unit\/Search\/Query\/AQueryParameterTest.php":"9f331bc9ba60708d87897a990abf042b","tests\/unit\/Search\/FilterStringParserTest.php":"abcc13a720a3452eebabf64764b161fa","tests\/unit\/Service\/Importer\/Systems\/DeckJsonServiceTest.php":"887c13a733807c46f675ef1d31fd655e","tests\/unit\/Service\/Importer\/Systems\/TrelloJsonServiceTest.php":"47f6d071a462c2f28d4f89b569f47753","tests\/unit\/Service\/Importer\/BoardImportServiceTest.php":"0a908f2f4ecf67838d0979da3205e724","tests\/unit\/Service\/AssignmentServiceTest.php":"aa39a881cad189eb72d1b940113ea0f0","tests\/unit\/Service\/PermissionServiceTest.php":"c4340accca124d28575b009607045f81","tests\/unit\/Service\/AttachmentServiceTest.php":"a9aa99e65135fb892d4dcea8c4e99eb9","tests\/unit\/Service\/BoardServiceTest.php":"159d9f5b68543b460a7a311b151e3eb1","tests\/unit\/Service\/CardServiceTest.php":"e3d5d704575902ecb0e95079e50f3657","tests\/unit\/Service\/DefaultBoardServiceTest.php":"c6ae6cebde1b769a22c623301f2fca93","tests\/unit\/Service\/LabelServiceTest.php":"adc8cba39487e3b6208ee60307386b3b","tests\/unit\/Service\/StackServiceTest.php":"8c923675c3e5d0b8d8a058ad8b5fb985","tests\/unit\/Service\/FileServiceTest.php":"3ec1d17487b077d3a5cb259141a2eaf4","tests\/unit\/Service\/FilesAppServiceTest.php":"47907402ea861974fac7a76deb069808","tests\/unit\/Validators\/StackServiceValidatorTest.php":"58262b987f2d9072ff88b0bdb4650d18","tests\/unit\/Validators\/ValidatorTestBase.php":"489d73d6012fc936074a9bbca43bbefa","tests\/unit\/Validators\/BoardServiceValidatorTest.php":"9cc94aba92dd1379f71f24dc19abbb73","tests\/unit\/controller\/BoardApiControllerTest.php":"27030d83f04b851f53eec941847fde8a","tests\/unit\/controller\/LabelApiControllerTest.php":"0b6a521a7d11e5aebbc7bd2c1a6eb910","tests\/unit\/controller\/PageControllerTest.php":"27b9e6b9c5a046d55ce6ee1542d95255","tests\/unit\/controller\/StackApiControllerTest.php":"483459f6905488b4719aaf286e256a59","tests\/unit\/controller\/BoardImportApiControllerTest.php":"303827af15944458dfa954fdaf3a4014","tests\/unit\/controller\/BoardControllerTest.php":"1eb1223535d31bd36f9fb3fcf61d8af7","tests\/unit\/controller\/CardApiControllerTest.php":"5b05f695a22966512a90a2862b4a9fd3","tests\/unit\/controller\/CardControllerTest.php":"59fc813922f96ec9680c475d0953d99e","tests\/unit\/controller\/LabelControllerTest.php":"cd96a6556793611474c9ce745ca9bf3f","tests\/unit\/controller\/StackControllerTest.php":"124d661707a0de9148fbb874303c5580","tests\/unit\/ExceptionsTest.php":"5af6330b5725899c3e8860bf295ea450","tests\/unit\/Listeners\/CommentEventListenerTest.php":"f25c456e4dce4236412c88df7f2bec7e","tests\/bootstrap.php":"53bee9383167d59347d71fd57ee57c1f"}} \ No newline at end of file diff --git a/cypress/e2e/boardFeatures.js b/cypress/e2e/boardFeatures.js index 1343fa361f..adcfb15c1c 100644 --- a/cypress/e2e/boardFeatures.js +++ b/cypress/e2e/boardFeatures.js @@ -24,7 +24,7 @@ describe('Board', function() { cy.intercept({ method: 'POST', - url: '/index.php/apps/deck/boards', + url: '/ocs/v2.php/apps/deck/api/v1.0/boards', }).as('createBoardRequest') // Click "Add board" diff --git a/cypress/e2e/cardFeatures.js b/cypress/e2e/cardFeatures.js index d4497e223d..e04aa9b23e 100644 --- a/cypress/e2e/cardFeatures.js +++ b/cypress/e2e/cardFeatures.js @@ -66,7 +66,7 @@ describe('Card', function () { it('Create card from overview', function () { cy.visit(`/apps/deck/#/`) const newCardTitle = 'Test create from overview' - cy.intercept({ method: 'POST', url: '**/apps/deck/cards' }).as('save') + cy.intercept({ method: 'POST', url: '**/ocs/v2.php/apps/deck/api/v1.0/cards' }).as('save') cy.intercept({ method: 'GET', url: '**/apps/deck/boards/*' }).as('getBoard') cy.get('.button-vue[aria-label*="Add card"]') @@ -213,7 +213,7 @@ describe('Card', function () { it('Smart picker', () => { const newCardTitle = 'Test smart picker' - cy.intercept({ method: 'POST', url: '**/apps/deck/cards' }).as('save') + cy.intercept({ method: 'POST', url: '**/ocs/v2.php/apps/deck/api/v1.0/cards' }).as('save') cy.intercept({ method: 'GET', url: '**/apps/deck/boards/*' }).as('getBoard') cy.get('.card:contains("Hello world")').should('be.visible').click() cy.get('.modal__card').should('be.visible') diff --git a/lib/Controller/BoardController.php b/lib/Controller/BoardController.php index be740349be..5c43ab7b12 100644 --- a/lib/Controller/BoardController.php +++ b/lib/Controller/BoardController.php @@ -86,7 +86,7 @@ public function getUserPermissions(int $boardId): array { */ #[NoAdminRequired] public function addAcl(int $boardId, int $type, $participant, bool $permissionEdit, bool $permissionShare, bool $permissionManage, ?string $remote = null): Acl { - return $this->boardService->addAcl($boardId, $type, $participant, $permissionEdit, $permissionShare, $permissionManage, $remote); + return $this->boardService->addAcl($boardId, $type, $participant, $permissionEdit, $permissionShare, $permissionManage); } /** diff --git a/lib/Controller/BoardOcsController.php b/lib/Controller/BoardOcsController.php index 2e7c57d2c4..64dd9cdfe3 100644 --- a/lib/Controller/BoardOcsController.php +++ b/lib/Controller/BoardOcsController.php @@ -6,6 +6,7 @@ use OCA\Deck\Service\ExternalBoardService; use OCA\Deck\Service\StackService; use OCP\AppFramework\Http\Attribute\NoAdminRequired; +use OCP\AppFramework\Http\Attribute\NoCSRFRequired; use OCP\AppFramework\Http\Attribute\PublicPage; use OCP\AppFramework\Http\Attribute\RequestHeader; use OCP\AppFramework\Http\DataResponse; @@ -57,7 +58,7 @@ public function create(string $title, string $color): DataResponse { #[NoCSRFRequired] #[RequestHeader(name: 'x-nextcloud-federation', description: 'Set to 1 when the request is performed by another Nextcloud Server to indicate a federation request', indirect: true)] public function stacks(int $boardId): DataResponse { - $localBoard = $this->boardService->find($boardId, true, true, $this->request->getParam('accessToken')); + $localBoard = $this->boardService->find($boardId, true, true); // Board on other instance -> get it from other instance if ($localBoard->getExternalId() !== null) { return $this->externalBoardService->getExternalStacksFromRemote($localBoard); @@ -68,19 +69,13 @@ public function stacks(int $boardId): DataResponse { #[NoAdminRequired] #[NoCSRFRequired] - public function addAcl(int $boardId, int $type, $participant, bool $permissionEdit, bool $permissionShare, bool $permissionManage, ?string $remote = null): DataResponse { - return new DataResponse($this->boardService->addAcl($boardId, $type, $participant, $permissionEdit, $permissionShare, $permissionManage, $remote)); + public function addAcl(int $boardId, int $type, string $participant, bool $permissionEdit, bool $permissionShare, bool $permissionManage, ?string $remote = null): DataResponse { + return new DataResponse($this->boardService->addAcl($boardId, $type, $participant, $permissionEdit, $permissionShare, $permissionManage)); } - /** - * @NoAdminRequired - * @param $id - * @param $permissionEdit - * @param $permissionShare - * @param $permissionManage - * @return \OCP\AppFramework\Db\Entity - */ - public function updateAcl($id, $permissionEdit, $permissionShare, $permissionManage) { - return $this->boardService->updateAcl($id, $permissionEdit, $permissionShare, $permissionManage); + #[NoAdminRequired] + #[NoCSRFRequired] + public function updateAcl(int $id, bool $permissionEdit, bool $permissionShare, bool $permissionManage): DataResponse { + return new DataResponse($this->boardService->updateAcl($id, $permissionEdit, $permissionShare, $permissionManage)); } } diff --git a/lib/Controller/CardOcsController.php b/lib/Controller/CardOcsController.php index a244ae44f7..2f0ab5c720 100644 --- a/lib/Controller/CardOcsController.php +++ b/lib/Controller/CardOcsController.php @@ -14,7 +14,7 @@ use OCP\AppFramework\OCSController; use OCP\IRequest; -class CardocsController extends OCSController { +class CardOcsController extends OCSController { public function __construct( string $appName, IRequest $request, diff --git a/lib/Controller/StackOcsController.php b/lib/Controller/StackOcsController.php index 01ee37ccce..04bd6f7864 100644 --- a/lib/Controller/StackOcsController.php +++ b/lib/Controller/StackOcsController.php @@ -28,7 +28,7 @@ public function __construct( #[PublicPage] #[NoCSRFRequired] #[RequestHeader(name: 'x-nextcloud-federation', description: 'Set to 1 when the request is performed by another Nextcloud Server to indicate a federation request', indirect: true)] - public function create(string $title, int $boardId, int $order = 0) { + public function create(string $title, int $boardId, int $order = 0):DataResponse { $board = $this->boardService->find($boardId, false); if ($board->getExternalId()) { $stack = $this->externalBoardService->createStackOnRemote($board, $title, $order); @@ -43,7 +43,7 @@ public function create(string $title, int $boardId, int $order = 0) { #[PublicPage] #[NoCSRFRequired] #[RequestHeader(name: 'x-nextcloud-federation', description: 'Set to 1 when the request is performed by another Nextcloud Server to indicate a federation request', indirect: true)] - public function delete(int $stackId, ?int $boardId = null) { + public function delete(int $stackId, ?int $boardId = null):DataResponse { if ($boardId) { $board = $this->boardService->find($boardId, false); if ($board->getExternalId()) { diff --git a/lib/Federation/DeckFederationProvider.php b/lib/Federation/DeckFederationProvider.php index ed617ac7ff..f61110248f 100644 --- a/lib/Federation/DeckFederationProvider.php +++ b/lib/Federation/DeckFederationProvider.php @@ -37,7 +37,7 @@ public function shareReceived(ICloudFederationShare $share): string { $externalBoard = new Board(); $externalBoard->setTitle($share->getResourceName()); - $externalBoard->setExternalId($share->getProviderId()); + $externalBoard->setExternalId((int)$share->getProviderId()); $externalBoard->setOwner($share->getSharedBy()); $externalBoard->setShareToken($share->getShareSecret()); $insertedBoard = $this->boardMapper->insert($externalBoard); @@ -57,17 +57,17 @@ public function shareReceived(ICloudFederationShare $share): string { $notification->setApp('deck'); $notification->setUser($share->getShareWith()); $notification->setDateTime(new \DateTime()); - $notification->setObject('remote-board-shared', $insertedBoard->getId()); + $notification->setObject('remote-board-shared', (string)$insertedBoard->getId()); $notification->setSubject('remote-board-shared', [$share->getResourceName(), $share->getSharedBy()]); $this->notificationManager->notify($notification); - return 'PLACE_HOLDER_ID'; + return (string)$insertedBoard->getId(); } public function notificationReceived($notificationType, $providerId, $notification): array { switch ($notificationType) { case 'update-permissions': - $localBoards = $this->boardMapper->findByExternalId($providerId); + $localBoards = $this->boardMapper->findByExternalId((int)$providerId); foreach ($localBoards as $board) { if ($board->getShareToken() === $notification['sharedSecret']) { $localBoard = $board; diff --git a/lib/Federation/DeckFederationProxy.php b/lib/Federation/DeckFederationProxy.php index 76d58150b7..aa5f5d8a13 100644 --- a/lib/Federation/DeckFederationProxy.php +++ b/lib/Federation/DeckFederationProxy.php @@ -12,6 +12,7 @@ use OCP\IUserSession; use OCP\L10N\IFactory; use Psr\Log\LoggerInterface; +use SensitiveParameter; class DeckFederationProxy { public function __construct( @@ -33,7 +34,6 @@ protected function generateDefaultRequestOptions( 'allow_local_address' => $this->config->getSystemValueBool('allow_local_remote_servers'), ], 'headers' => [ - 'Cookie' => 'XDEBUG_SESSION=PHPSTORM', 'Accept' => 'application/json', 'x-nextcloud-federation' => 'true', 'OCS-APIRequest' => 'true', @@ -43,9 +43,6 @@ protected function generateDefaultRequestOptions( 'timeout' => 5, ]; - if ($cloudId !== null && $accessToken !== null) { - } - return $options; } @@ -102,13 +99,13 @@ protected function request( } } - public function get(string $cloudId, string $shareToken, string $url, array $params = []):IResponse { + public function get(string $cloudId, string $shareToken, string $url, array $params = []): IResponse { return $this->request('get', $cloudId, $shareToken, $url, $params); } - public function post(string $cloudId, string $shareToken, string $url, array $params = []):IResponse { + public function post(string $cloudId, string $shareToken, string $url, array $params = []): IResponse { return $this->request('post', $cloudId, $shareToken, $url, $params); } - public function delete(string $cloudId, string $shareToken, string $url, array $params = []):IResponse { + public function delete(string $cloudId, string $shareToken, string $url, array $params = []): IResponse { return $this->request('delete', $cloudId, $shareToken, $url, $params); } public function getOCSData(IResponse $response, array $allowedStatusCodes = [Http::STATUS_OK]): array { diff --git a/lib/Listeners/ResourceTypeRegisterListener.php b/lib/Listeners/ResourceTypeRegisterListener.php index 0cbcf10d57..48a0bc7872 100644 --- a/lib/Listeners/ResourceTypeRegisterListener.php +++ b/lib/Listeners/ResourceTypeRegisterListener.php @@ -9,14 +9,17 @@ use OCP\OCM\Events\ResourceTypeRegisterEvent; use OCP\OCM\IOCMProvider; +/** + * @template-implements IEventListener + */ class ResourceTypeRegisterListener implements IEventListener { public function __construct( protected IOCMProvider $provider, - protected ConfigService $configService + protected ConfigService $configService, ) { } - public function handle(Event $event):void { + public function handle(Event $event): void { if (!$event instanceof ResourceTypeRegisterEvent) { return; } diff --git a/lib/Middleware/FederationMiddleware.php b/lib/Middleware/FederationMiddleware.php index 7dc2d00467..83b9b4a58a 100644 --- a/lib/Middleware/FederationMiddleware.php +++ b/lib/Middleware/FederationMiddleware.php @@ -17,7 +17,7 @@ public function __construct( ) { } - public function beforeController($controller, $methodName) { + public function beforeController($controller, $methodName): void { if (!$this->configService->get('federationEnabled')) { return; } diff --git a/lib/Service/BoardService.php b/lib/Service/BoardService.php index 4de9dd9aac..14256bdb3a 100644 --- a/lib/Service/BoardService.php +++ b/lib/Service/BoardService.php @@ -380,19 +380,19 @@ public function addAcl(int $boardId, int $type, $participant, bool $edit, bool $ $board = $this->find($boardId); $token = $this->random->generate(32); $cloudShare = $this->federationFactory->getCloudFederationShare( - $participant, // shareWith - $board->getTitle(), // name - '', // description - $boardId, // providerID - $sharedBy->getCloudId(), // owner (this instance) - $sharedBy->getDisplayName(), // ownerDisplayName (this instance) - $sharedBy->getCloudId(), // sharedBy (this instance) - $sharedBy->getDisplayName(), // sharedByDisplayName (this instance) - $token, // sharedSecret - 'user', // shareType - 'deck' // resourceType + $participant, + $board->getTitle(), + '', + (string)$boardId, + $sharedBy->getCloudId(), + $sharedBy->getDisplayName(), + $sharedBy->getCloudId(), + $sharedBy->getDisplayName(), + $token, + 'user', + 'deck' ); - $resp = $this->cloudFederationProviderManager->sendCloudShare($cloudShare); + $this->cloudFederationProviderManager->sendCloudShare($cloudShare); $acl->setToken($token); } @@ -457,10 +457,10 @@ public function updateAcl(int $id, bool $edit, bool $share, bool $manage): Acl { 'sharedSecret' => $acl->getToken(), ]; - $notification->setMessage('update-permissions', 'deck', $acl->getBoardId(), $payload); + $notification->setMessage('update-permissions', 'deck', (string)$acl->getBoardId(), $payload); $url = $this->cloudIdManager->resolveCloudId($acl->getParticipant()); - $resp = $this->cloudFederationProviderManager->sendCloudNotification($url->getRemote(), $notification); + $this->cloudFederationProviderManager->sendCloudNotification($url->getRemote(), $notification); } $this->eventDispatcher->dispatchTyped(new AclUpdatedEvent($acl)); diff --git a/lib/Service/ConfigService.php b/lib/Service/ConfigService.php index 3a70f00f7e..c63571d2c5 100644 --- a/lib/Service/ConfigService.php +++ b/lib/Service/ConfigService.php @@ -79,7 +79,7 @@ public function get(string $key) { } return $this->getGroupLimit(); case 'federationEnabled': - return (bool)$this->config->getAppValue(Application::APP_ID, 'federationEnabled', false); + return $this->config->getAppValue(Application::APP_ID, 'federationEnabled', 'no') === 'yes'; case 'calendar': if ($this->getUserId() === null) { return false; diff --git a/lib/Service/ExternalBoardService.php b/lib/Service/ExternalBoardService.php index d5e5824b38..bf0f8fe37c 100644 --- a/lib/Service/ExternalBoardService.php +++ b/lib/Service/ExternalBoardService.php @@ -5,8 +5,6 @@ use OCA\Deck\Db\Acl; use OCA\Deck\Db\Board; use OCA\Deck\Db\BoardMapper; -use OCA\Deck\Db\FederatedUser; -use OCA\Deck\Exceptions\FederationDisabledException; use OCA\Deck\Federation\DeckFederationProxy; use OCP\AppFramework\Http\DataResponse; use OCP\Federation\ICloudIdManager; @@ -56,9 +54,7 @@ public function LocalizeRemoteStacks(array $stacks, Board $localBoard) { public function LocalizeRemoteBoard(array $remoteBoard, Board $localBoard) { $remoteBoard['id'] = $localBoard->getId(); $remoteBoard['stacks'] = $this->LocalizeRemoteStacks($remoteBoard['stacks'], $localBoard); - - // setting this manually to a federatedUser as $localBoard->getOwner() does not return the resolved owner - $remoteBoard['owner'] = new FederatedUser($this->cloudIdManager->resolveCloudId($localBoard->getOwner())); + $remoteBoard['owner'] = $localBoard->resolveOwner(); $remoteBoard['acl'] = $localBoard->getAcl(); $remoteBoard['permissions'] = $localBoard->getPermissions(); return $remoteBoard; diff --git a/lib/Service/PermissionService.php b/lib/Service/PermissionService.php index ef3fedad19..ba99ec44ac 100644 --- a/lib/Service/PermissionService.php +++ b/lib/Service/PermissionService.php @@ -146,7 +146,8 @@ public function checkPermission(?IPermissionMapper $mapper, $id, int $permission if ($mapper instanceof IPermissionMapper && !($mapper instanceof BoardMapper)) { $boardId = $mapper->findBoardId($id); } - if ($boardId === null) { + // (int)null === 0 so we have to check if any of these are null + if ($boardId === null || $id === null) { // Throw NoPermission to not leak information about existing entries throw new NoPermissionException('Permission denied'); } @@ -200,16 +201,16 @@ private function getBoard(int $boardId, bool $allowDeleted = false): Board { } - public function externalUserCan(array $acls, $permission, $shareToken = null) { + public function externalUserCan(array $acls, int $permission, string $shareToken):bool { $this->configService->ensureFederationEnabled(); foreach ($acls as $acl) { if ($acl->getType() === Acl::PERMISSION_TYPE_REMOTE) { - $token = $acl->getToken(); if ($acl->getToken() === $shareToken) { return $acl->getPermission($permission); } } } + return false; } /** @@ -249,8 +250,11 @@ public function userCan(array $acls, $permission, $userId = null) { return $hasGroupPermission; } - public function getUserId() { - return $this->userId || $this->aclMapper->findByAccessToken($this->accessToken)->getParticipant(); + public function getUserId(): ?string { + if ($this->userId === null && $this->accessToken === null) { + return null; + } + return $this->userId ?? $this->aclMapper->findByAccessToken($this->accessToken)->getParticipant(); } /** diff --git a/psalm.xml b/psalm.xml index c4a169b7e9..bd7ead736e 100644 --- a/psalm.xml +++ b/psalm.xml @@ -38,6 +38,8 @@ + + diff --git a/src/components/DeckAppSettings.vue b/src/components/DeckAppSettings.vue index 19581c048a..3935dbff5d 100644 --- a/src/components/DeckAppSettings.vue +++ b/src/components/DeckAppSettings.vue @@ -38,8 +38,7 @@

+ :label="t('deck', 'Enable federation')" /> @@ -131,12 +130,11 @@ export default { federationEnabled: { get() { const value = this.$store.getters.config('federationEnabled') - console.log(value) return value }, set(newValue) { confirmPassword().then(() => { - this.$store.dispatch('setConfig', { federationEnabled: newValue }) + this.$store.dispatch('setConfig', { federationEnabled: newValue ? 'yes' : 'no' }) }) }, }, diff --git a/src/components/board/SharingTabSidebar.vue b/src/components/board/SharingTabSidebar.vue index d01a1d8bc0..744453878f 100644 --- a/src/components/board/SharingTabSidebar.vue +++ b/src/components/board/SharingTabSidebar.vue @@ -167,7 +167,6 @@ export default { }).slice(0, 10) }, unallocatedSharees() { - console.log(this.board.acl) return this.sharees.filter((sharee) => { const foundIndex = this.board.acl.findIndex((acl) => { return acl.participant.uid === sharee.value.shareWith && acl.participant.type === sharee.value.shareType @@ -194,7 +193,6 @@ export default { loading(false) }, async clickAddAcl() { - console.log(this.addAcl) this.addAclForAPI = { type: this.addAcl.value.shareType, participant: this.addAcl.value.shareWith, diff --git a/src/components/navigation/AppNavigation.vue b/src/components/navigation/AppNavigation.vue index b1d06e4837..ce9f9b2a09 100644 --- a/src/components/navigation/AppNavigation.vue +++ b/src/components/navigation/AppNavigation.vue @@ -80,7 +80,7 @@ import { subscribe } from '@nextcloud/event-bus' import AppNavigationImportBoard from './AppNavigationImportBoard.vue' import DeckAppSettings from '../DeckAppSettings.vue' import IconCog from 'vue-material-design-icons/CogOutline.vue' -import { mapState } from 'vuex/dist/vuex.common.js' +import { getCurrentUser } from '@nextcloud/auth' const canCreateState = loadState('deck', 'canCreate') diff --git a/src/components/navigation/AppNavigationBoard.vue b/src/components/navigation/AppNavigationBoard.vue index b8c462cbae..740999f9bf 100644 --- a/src/components/navigation/AppNavigationBoard.vue +++ b/src/components/navigation/AppNavigationBoard.vue @@ -22,9 +22,9 @@ @close="onCloseExportBoard" /> - +