From 701d654d21d6100e882bfe1119a469ff304c068a Mon Sep 17 00:00:00 2001 From: e-five <146029455+e-five256@users.noreply.github.com> Date: Fri, 10 May 2024 19:52:58 -0400 Subject: [PATCH 001/335] Restyle login/register social and action button sections (#706) --- assets/styles/components/_login.scss | 29 +++++++--- assets/styles/layout/_forms.scss | 11 ++++ src/DTO/SettingsDto.php | 5 +- src/Form/SettingsType.php | 1 + src/Service/SettingsManager.php | 3 +- src/Twig/Extension/SettingsExtension.php | 1 + src/Twig/Runtime/SettingsExtensionRuntime.php | 5 ++ templates/admin/settings.html.twig | 4 ++ templates/components/login_socials.html.twig | 57 +++++++++++-------- .../components/user_form_actions.html.twig | 11 ++-- .../resend.html.twig | 10 +++- templates/reset_password/request.html.twig | 3 +- templates/reset_password/reset.html.twig | 3 +- templates/user/login.html.twig | 11 +++- templates/user/register.html.twig | 9 ++- translations/messages.en.yaml | 2 + 16 files changed, 115 insertions(+), 50 deletions(-) diff --git a/assets/styles/components/_login.scss b/assets/styles/components/_login.scss index 7fe9c5a7d..3b20f74ea 100644 --- a/assets/styles/components/_login.scss +++ b/assets/styles/components/_login.scss @@ -15,21 +15,36 @@ font-weight: bold; } + .separator { + display: none; + height: 0; + } + .separator:has(+ div p), .separator.separator-show { + display: block; + border: var(--kbin-section-border); + height: 0; + margin: 20px 30px; + } + .actions { - margin-top: 3rem; + margin-top: 1rem; display: block; } .social { - display: flex; - gap: 2rem; + grid-template-columns: repeat(1, 1fr); + @include media-breakpoint-up(lg) { + &:has(a + a) { + grid-template-columns: repeat(2, 1fr); + } + } + + display: grid; + gap: 0.5rem; justify-content: center; - margin-top: 3rem; a { - align-items: center; - display: inline-flex; - gap: .5rem; + text-align: center; } } } diff --git a/assets/styles/layout/_forms.scss b/assets/styles/layout/_forms.scss index 438442b71..2a45e5afb 100644 --- a/assets/styles/layout/_forms.scss +++ b/assets/styles/layout/_forms.scss @@ -434,6 +434,17 @@ select { } } +.button-flex-hf { + text-align: center; + button { + width: 50%; + + @include media-breakpoint-down(lg) { + width: 100%; + } + } +} + .actions { @include media-breakpoint-down(sm) { text-align: right; diff --git a/src/DTO/SettingsDto.php b/src/DTO/SettingsDto.php index 6c4ccd542..539f75005 100644 --- a/src/DTO/SettingsDto.php +++ b/src/DTO/SettingsDto.php @@ -34,7 +34,8 @@ public function __construct( public bool $KBIN_FEDERATED_SEARCH_ONLY_LOGGEDIN, public bool $MBIN_SIDEBAR_SECTIONS_LOCAL_ONLY, public bool $MBIN_SSO_REGISTRATIONS_ENABLED, - public bool $MBIN_RESTRICT_MAGAZINE_CREATION + public bool $MBIN_RESTRICT_MAGAZINE_CREATION, + public bool $MBIN_SSO_SHOW_FIRST ) { } @@ -64,6 +65,7 @@ public function mergeIntoDto(SettingsDto $dto): SettingsDto $dto->MBIN_SIDEBAR_SECTIONS_LOCAL_ONLY = $this->MBIN_SIDEBAR_SECTIONS_LOCAL_ONLY ?? $dto->MBIN_SIDEBAR_SECTIONS_LOCAL_ONLY; $dto->MBIN_SSO_REGISTRATIONS_ENABLED = $this->MBIN_SSO_REGISTRATIONS_ENABLED ?? $dto->MBIN_SSO_REGISTRATIONS_ENABLED; $dto->MBIN_RESTRICT_MAGAZINE_CREATION = $this->MBIN_RESTRICT_MAGAZINE_CREATION ?? $dto->MBIN_RESTRICT_MAGAZINE_CREATION; + $dto->MBIN_SSO_SHOW_FIRST = $this->MBIN_SSO_SHOW_FIRST ?? $dto->MBIN_SSO_SHOW_FIRST; return $dto; } @@ -95,6 +97,7 @@ public function jsonSerialize(): mixed 'MBIN_SIDEBAR_SECTIONS_LOCAL_ONLY' => $this->MBIN_SIDEBAR_SECTIONS_LOCAL_ONLY, 'MBIN_SSO_REGISTRATIONS_ENABLED' => $this->MBIN_SSO_REGISTRATIONS_ENABLED, 'MBIN_RESTRICT_MAGAZINE_CREATION' => $this->MBIN_RESTRICT_MAGAZINE_CREATION, + 'MBIN_SSO_SHOW_FIRST' => $this->MBIN_SSO_SHOW_FIRST, ]; } } diff --git a/src/Form/SettingsType.php b/src/Form/SettingsType.php index e0cbf609b..a7bef3954 100644 --- a/src/Form/SettingsType.php +++ b/src/Form/SettingsType.php @@ -41,6 +41,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void ->add('KBIN_FEDERATED_SEARCH_ONLY_LOGGEDIN', CheckboxType::class, ['required' => false]) ->add('MBIN_SIDEBAR_SECTIONS_LOCAL_ONLY', CheckboxType::class, ['required' => false]) ->add('MBIN_RESTRICT_MAGAZINE_CREATION', CheckboxType::class, ['required' => false]) + ->add('MBIN_SSO_SHOW_FIRST', CheckboxType::class, ['required' => false]) ->add('submit', SubmitType::class); } diff --git a/src/Service/SettingsManager.php b/src/Service/SettingsManager.php index 60923060e..11ac26645 100644 --- a/src/Service/SettingsManager.php +++ b/src/Service/SettingsManager.php @@ -70,7 +70,8 @@ public function __construct( $this->find($results, 'KBIN_FEDERATED_SEARCH_ONLY_LOGGEDIN', FILTER_VALIDATE_BOOLEAN) ?? true, $this->find($results, 'MBIN_SIDEBAR_SECTIONS_LOCAL_ONLY', FILTER_VALIDATE_BOOLEAN) ?? false, $this->find($results, 'MBIN_SSO_REGISTRATIONS_ENABLED', FILTER_VALIDATE_BOOLEAN) ?? true, - $this->find($results, 'MBIN_RESTRICT_MAGAZINE_CREATION', FILTER_VALIDATE_BOOLEAN) ?? false + $this->find($results, 'MBIN_RESTRICT_MAGAZINE_CREATION', FILTER_VALIDATE_BOOLEAN) ?? false, + $this->find($results, 'MBIN_SSO_SHOW_FIRST', FILTER_VALIDATE_BOOLEAN) ?? false ); } } diff --git a/src/Twig/Extension/SettingsExtension.php b/src/Twig/Extension/SettingsExtension.php index 6573a3244..c3981962e 100644 --- a/src/Twig/Extension/SettingsExtension.php +++ b/src/Twig/Extension/SettingsExtension.php @@ -30,6 +30,7 @@ public function getFunctions(): array new TwigFunction('mbin_current_version', [SettingsExtensionRuntime::class, 'mbinCurrentVersion']), new TwigFunction('mbin_restrict_magazine_creation', [SettingsExtensionRuntime::class, 'mbinRestrictMagazineCreation']), new TwigFunction('mbin_private_instance', [SettingsExtensionRuntime::class, 'mbinPrivateInstance']), + new TwigFunction('mbin_sso_show_first', [SettingsExtensionRuntime::class, 'mbinSsoShowFirst']), ]; } } diff --git a/src/Twig/Runtime/SettingsExtensionRuntime.php b/src/Twig/Runtime/SettingsExtensionRuntime.php index 229f3502d..6f5ce0ea5 100644 --- a/src/Twig/Runtime/SettingsExtensionRuntime.php +++ b/src/Twig/Runtime/SettingsExtensionRuntime.php @@ -113,4 +113,9 @@ public function mbinPrivateInstance(): bool { return $this->settings->get('MBIN_PRIVATE_INSTANCE'); } + + public function mbinSsoShowFirst(): bool + { + return $this->settings->get('MBIN_SSO_SHOW_FIRST'); + } } diff --git a/templates/admin/settings.html.twig b/templates/admin/settings.html.twig index 4588840a4..e2ef8d96a 100644 --- a/templates/admin/settings.html.twig +++ b/templates/admin/settings.html.twig @@ -83,6 +83,10 @@ {{ form_label(form.MBIN_RESTRICT_MAGAZINE_CREATION, 'restrict_magazine_creation') }} {{ form_widget(form.MBIN_RESTRICT_MAGAZINE_CREATION) }} +
+ {{ form_label(form.MBIN_SSO_SHOW_FIRST, 'sso_show_first') }} + {{ form_widget(form.MBIN_SSO_SHOW_FIRST) }} +
{{ form_row(form.submit, {label: 'save', attr: {class: 'btn btn__primary'}}) }}
diff --git a/templates/components/login_socials.html.twig b/templates/components/login_socials.html.twig index 8e744c518..117a89758 100644 --- a/templates/components/login_socials.html.twig +++ b/templates/components/login_socials.html.twig @@ -1,27 +1,36 @@ {# @var this App\Twig\Components\LoginSocialsComponent #} -
- {% if this.googleEnabled %} - - Google +{%- set HAS_ANY_SOCIAL = this.googleEnabled or this.facebookEnabled or this.githubEnabled or this.keycloakEnabled or this.zitadelEnabled or this.azureEnabled -%} +{% if HAS_ANY_SOCIAL %} + {% if not mbin_sso_only_mode() and not mbin_sso_show_first() %} +
{% endif %} - {% if this.facebookEnabled %} - - Facebook +
+ {% if this.googleEnabled %} + + {{ 'continue_with'|trans }} Google + {% endif %} + {% if this.facebookEnabled %} + + {{ 'continue_with'|trans }} Facebook + {% endif %} + {% if this.githubEnabled %} + + {{ 'continue_with'|trans }} GitHub + {% endif %} + {% if this.keycloakEnabled %} + + {{ 'continue_with'|trans }} Keycloak + {% endif %} + {% if this.zitadelEnabled %} + + {{ 'continue_with'|trans }} Zitadel + {% endif %} + {% if this.azureEnabled %} + + {{ 'continue_with'|trans }} Microsoft + {% endif %} +
+ {% if not mbin_sso_only_mode() and mbin_sso_show_first() %} +
{% endif %} - {% if this.githubEnabled %} - - GitHub - {% endif %} - {% if this.keycloakEnabled %} - - Keycloak - {% endif %} - {% if this.zitadelEnabled %} - - Zitadel - {% endif %} - {% if this.azureEnabled %} - - Microsoft - {% endif %} -
+{% endif %} diff --git a/templates/components/user_form_actions.html.twig b/templates/components/user_form_actions.html.twig index e7a923d20..de8ab4cc1 100644 --- a/templates/components/user_form_actions.html.twig +++ b/templates/components/user_form_actions.html.twig @@ -1,18 +1,19 @@ +
{% if showLogin %} -

{{ 'already_have_account'|trans }} +

{{ 'already_have_account'|trans }} {{ 'login'|trans }}

{% endif %} {% if kbin_registrations_enabled() %} {% if showRegister %} -

{{ 'dont_have_account'|trans }} +

{{ 'dont_have_account'|trans }} {{ 'register'|trans }}

- {% endif %} + {% endif %} {% endif %} {% if showPasswordReset %} -

{{ 'you_cant_login'|trans }} +

{{ 'you_cant_login'|trans }} {{ 'reset_password'|trans }}

{% endif %} @@ -21,4 +22,4 @@ {# {{ 'resend_account_activation_email'|trans }}#} {#

#} {# {% endif %}#} -
\ No newline at end of file + diff --git a/templates/resend_verification_email/resend.html.twig b/templates/resend_verification_email/resend.html.twig index fb488f3a8..6f69aef31 100644 --- a/templates/resend_verification_email/resend.html.twig +++ b/templates/resend_verification_email/resend.html.twig @@ -16,9 +16,9 @@

{{ 'resend_account_activation_email'|trans }}

-

{{ 'resend_account_activation_email_description'|trans }}

+

{{ 'resend_account_activation_email_description'|trans }}

- {{ form_start(form) }} + {{ form_start(form) }} {% for flash_error in app.flashes('error') %}
{{ flash_error|trans }}
{% endfor %} @@ -27,7 +27,11 @@ {% endfor %} {{ form_row(form.email) }} - {{ form_row(form.submit) }} + {{ form_row(form.submit, { + row_attr: { + class: 'button-flex-hf' + } + }) }} {{ form_end(form) }} {{ component('user_form_actions', {showRegister: true, showPasswordReset: true, showResendEmail: true}) }} diff --git a/templates/reset_password/request.html.twig b/templates/reset_password/request.html.twig index e0796068f..d4b8c811a 100644 --- a/templates/reset_password/request.html.twig +++ b/templates/reset_password/request.html.twig @@ -24,12 +24,11 @@ label: 'email' }) }} -
+
{{ form_end(form) }} {{ component('user_form_actions', {showLogin: true, showRegister: true, showResendEmail: true}) }} - {{ component('login_socials') }}
{% endblock %} diff --git a/templates/reset_password/reset.html.twig b/templates/reset_password/reset.html.twig index 670b44be4..3582a7074 100644 --- a/templates/reset_password/reset.html.twig +++ b/templates/reset_password/reset.html.twig @@ -22,12 +22,11 @@ {% endfor %} {{ form_row(form.plainPassword) }} -
+
{{ form_end(form) }} {{ component('user_form_actions', {showLogin: true, showRegister: true , showResendEmail: true}) }} - {{ component('login_socials') }}
{% endblock %} diff --git a/templates/user/login.html.twig b/templates/user/login.html.twig index 09bc9a28d..b15fef738 100644 --- a/templates/user/login.html.twig +++ b/templates/user/login.html.twig @@ -17,6 +17,9 @@ {% include 'layout/_flash.html.twig' %}
+ {% if mbin_sso_show_first() %} + {{ component('login_socials') }} + {% endif %} {% if not mbin_sso_only_mode() %}
{% if error %} @@ -42,13 +45,17 @@
-
+
+ {% endif %} + {% if not mbin_sso_show_first() %} + {{ component('login_socials') }} + {% endif %} + {% if not mbin_sso_only_mode() %} {{ component('user_form_actions', {showRegister: true, showPasswordReset: true, showResendEmail: true}) }} {% endif %} - {{ component('login_socials') }}
{% endblock %} diff --git a/templates/user/register.html.twig b/templates/user/register.html.twig index 3b720d441..ae2561e98 100644 --- a/templates/user/register.html.twig +++ b/templates/user/register.html.twig @@ -16,6 +16,9 @@

{{ 'register'|trans }}

+ {% if mbin_sso_registrations_enabled() and mbin_sso_show_first() %} + {{ component('login_socials') }} + {% endif %} {% if kbin_registrations_enabled() %} {{ form_start(form) }} {% for flash_error in app.flashes('verify_email_error') %} @@ -54,17 +57,17 @@ class: 'btn btn__primary' }, row_attr: { - class: 'float-end' + class: 'button-flex-hf' } }) }} {{ form_end(form) }} {% else %}

{{ 'registration_disabled'|trans }}

{% endif %} - {{ component('user_form_actions', {showLogin: true, showPasswordReset: true, showResendEmail: true}) }} - {% if mbin_sso_registrations_enabled() %} + {% if mbin_sso_registrations_enabled() and not mbin_sso_show_first() %} {{ component('login_socials') }} {% endif %} + {{ component('user_form_actions', {showLogin: true, showPasswordReset: true, showResendEmail: true}) }}
{% endblock %} diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml index a66f8b9a5..8d6185de8 100644 --- a/translations/messages.en.yaml +++ b/translations/messages.en.yaml @@ -813,3 +813,5 @@ sso_registrations_enabled.error: New account registrations with third-party iden sso_only_mode: Restrict login and registration to SSO methods only related_entry: Related restrict_magazine_creation: Restrict local magazine creation to admins and global mods +sso_show_first: Show SSO first on login and registration pages +continue_with: Continue with From c6b47b553f59a006d7fb9b276c30fa093b28c2d5 Mon Sep 17 00:00:00 2001 From: asdfzdfj Date: Sat, 11 May 2024 14:20:13 +0700 Subject: [PATCH 002/335] connect mercure endpoint url to noti controller directly (#766) adjusted notification controller to take mercure endpoint url directly as controller values rather than templating the endpoint separately and then extracting them from dom nodes if the endpoint isn't provided then it will not attempt to connect to mercure, effectively disabling them also fix controller related js files according to eslint rules overall functionality should remain the same --- .../controllers/notifications_controller.js | 52 +++++++++++-------- assets/utils/event-source.js | 25 +++++---- templates/base.html.twig | 5 +- 3 files changed, 42 insertions(+), 40 deletions(-) diff --git a/assets/controllers/notifications_controller.js b/assets/controllers/notifications_controller.js index 2b03a8923..eaca58101 100644 --- a/assets/controllers/notifications_controller.js +++ b/assets/controllers/notifications_controller.js @@ -1,9 +1,10 @@ -import {Controller} from '@hotwired/stimulus'; +import { Controller } from '@hotwired/stimulus'; import Subscribe from '../utils/event-source'; /* stimulusFetch: 'lazy' */ export default class extends Controller { static values = { + endpoint: String, user: String, magazine: String, entryId: String, @@ -11,27 +12,26 @@ export default class extends Controller { }; connect() { - this.es(this.getTopics()); + if (this.endpointValue) { + this.connectEs(this.endpointValue, this.getTopics()); - window.onbeforeunload = function (event) { - if (window.es !== undefined) { - window.es.close(); - } - }; + window.addEventListener('pagehide', this.closeEs); + } } - es(topics) { - if (window.es !== undefined) { - window.es.close(); - } + disconnect() { + this.closeEs(); + } + + connectEs(endpoint, topics) { + this.closeEs(); - let self = this; - let cb = function (e) { - let data = JSON.parse(e.data); + const cb = (e) => { + const data = JSON.parse(e.data); - self.dispatch(data.op, {detail: data}); + this.dispatch(data.op, { detail: data }); - self.dispatch('Notification', {detail: data}); + this.dispatch('Notification', { detail: data }); // if (data.op.includes('Create')) { // self.dispatch('CreatedNotification', {detail: data}); @@ -41,17 +41,17 @@ export default class extends Controller { // self.dispatch('MainSubjectCreatedNotification', {detail: data}); // } // - } + }; - const eventSource = Subscribe(topics, cb); + const eventSource = Subscribe(endpoint, topics, cb); if (eventSource) { window.es = eventSource; // firefox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1803431 - if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) { - let resubscribe = (e) => { + if (navigator.userAgent.toLowerCase().includes('firefox')) { + const resubscribe = () => { window.es.close(); setTimeout(() => { - const eventSource = Subscribe(topics, cb); + const eventSource = Subscribe(endpoint, topics, cb); if (eventSource) { window.es = eventSource; window.es.onerror = resubscribe; @@ -63,11 +63,17 @@ export default class extends Controller { } } + closeEs() { + if (window.es instanceof EventSource) { + window.es.close(); + } + } + getTopics() { let pub = true; const topics = [ - 'count' - ] + 'count', + ]; if (this.userValue) { topics.push(`/api/users/${this.userValue}`); diff --git a/assets/utils/event-source.js b/assets/utils/event-source.js index 18970c1d6..b3504c1c1 100644 --- a/assets/utils/event-source.js +++ b/assets/utils/event-source.js @@ -1,17 +1,16 @@ -export default function - subscribe(topics, cb) { - const mercureElem = document.getElementById("mercure-url"); - if (mercureElem) { - const url = new URL(mercureElem.textContent.trim()); +export default function subscribe(endpoint, topics, cb) { + if (!endpoint) { + return null; + } - topics.forEach(topic => { - url.searchParams.append('topic', topic); - }) + const url = new URL(endpoint); - const eventSource = new EventSource(url); - eventSource.onmessage = e => cb(e); + topics.forEach((topic) => { + url.searchParams.append('topic', topic); + }); - return eventSource; - } - return null; + const eventSource = new EventSource(url); + eventSource.onmessage = (e) => cb(e); + + return eventSource; } diff --git a/templates/base.html.twig b/templates/base.html.twig index d4014cd84..56d678998 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -51,10 +51,6 @@ {% block javascripts %} {{ encore_entry_script_tags('app') }} - {% if kbin_mercure_enabled() %} - {# #} - - {% endif %} {% endblock %} Date: Sat, 11 May 2024 14:25:51 +0700 Subject: [PATCH 003/335] webfinger controller event pass request once (#739) pass the webfinger request from controller to WebfingerResponseEvent and its handlers once rather than (implicitly) pulling the request from the stack, also adjusted WebFingerParameters the same way to have it parse the params out of the given request object just to make it clearer what's the required input, rather than magically conjuring them out of thin air on use --- src/Controller/ActivityPub/WebFingerController.php | 2 +- src/Event/ActivityPub/WebfingerResponseEvent.php | 7 +++++-- .../ActivityPub/GroupWebFingerProfileSubscriber.php | 12 +++++------- .../ActivityPub/GroupWebFingerSubscriber.php | 13 ++++++------- .../ActivityPub/UserWebFingerProfileSubscriber.php | 5 +---- .../ActivityPub/UserWebFingerSubscriber.php | 13 ++++++------- .../ActivityPub/Webfinger/WebFingerParameters.php | 11 ++++++----- 7 files changed, 30 insertions(+), 33 deletions(-) diff --git a/src/Controller/ActivityPub/WebFingerController.php b/src/Controller/ActivityPub/WebFingerController.php index f42ff6440..37a3c80d1 100644 --- a/src/Controller/ActivityPub/WebFingerController.php +++ b/src/Controller/ActivityPub/WebFingerController.php @@ -18,7 +18,7 @@ public function __construct(private readonly EventDispatcherInterface $eventDisp public function __invoke(Request $request): JsonResponse { - $event = new WebfingerResponseEvent(new JsonRd()); + $event = new WebfingerResponseEvent(new JsonRd(), $request); $this->eventDispatcher->dispatch($event); if (!empty($event->jsonRd->getLinks())) { diff --git a/src/Event/ActivityPub/WebfingerResponseEvent.php b/src/Event/ActivityPub/WebfingerResponseEvent.php index 73c0a523b..7af331408 100644 --- a/src/Event/ActivityPub/WebfingerResponseEvent.php +++ b/src/Event/ActivityPub/WebfingerResponseEvent.php @@ -5,10 +5,13 @@ namespace App\Event\ActivityPub; use App\ActivityPub\JsonRd; +use Symfony\Component\HttpFoundation\Request; class WebfingerResponseEvent { - public function __construct(public JsonRd $jsonRd) - { + public function __construct( + public JsonRd $jsonRd, + public Request $request, + ) { } } diff --git a/src/EventSubscriber/ActivityPub/GroupWebFingerProfileSubscriber.php b/src/EventSubscriber/ActivityPub/GroupWebFingerProfileSubscriber.php index 116f32f41..ed28e70f1 100644 --- a/src/EventSubscriber/ActivityPub/GroupWebFingerProfileSubscriber.php +++ b/src/EventSubscriber/ActivityPub/GroupWebFingerProfileSubscriber.php @@ -11,13 +11,11 @@ use App\Service\ActivityPub\Webfinger\WebFingerParameters; use JetBrains\PhpStorm\ArrayShape; use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; class GroupWebFingerProfileSubscriber implements EventSubscriberInterface { public function __construct( - private readonly RequestStack $requestStack, private readonly WebFingerParameters $webfingerParameters, private readonly MagazineRepository $magazineRepository, private readonly UrlGeneratorInterface $urlGenerator, @@ -34,13 +32,13 @@ public static function getSubscribedEvents(): array public function buildResponse(WebfingerResponseEvent $event): void { - $request = $this->requestStack->getCurrentRequest(); - $params = $this->webfingerParameters->getParams(); + $params = $this->webfingerParameters->getParams($event->request); $jsonRd = $event->jsonRd; - if (isset($params[WebFingerParameters::ACCOUNT_KEY_NAME]) && $actor = $this->getActor( - $params[WebFingerParameters::ACCOUNT_KEY_NAME] - )) { + if ( + isset($params[WebFingerParameters::ACCOUNT_KEY_NAME]) + && $actor = $this->getActor($params[WebFingerParameters::ACCOUNT_KEY_NAME]) + ) { $accountHref = $this->urlGenerator->generate( 'ap_magazine', ['name' => $actor->name], diff --git a/src/EventSubscriber/ActivityPub/GroupWebFingerSubscriber.php b/src/EventSubscriber/ActivityPub/GroupWebFingerSubscriber.php index ab560c28b..4ca3aff2a 100644 --- a/src/EventSubscriber/ActivityPub/GroupWebFingerSubscriber.php +++ b/src/EventSubscriber/ActivityPub/GroupWebFingerSubscriber.php @@ -11,13 +11,11 @@ use App\Service\ActivityPub\Webfinger\WebFingerParameters; use JetBrains\PhpStorm\ArrayShape; use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; class GroupWebFingerSubscriber implements EventSubscriberInterface { public function __construct( - private readonly RequestStack $requestStack, private readonly WebFingerParameters $webfingerParameters, private readonly MagazineRepository $magazineRepository, private readonly UrlGeneratorInterface $urlGenerator @@ -34,8 +32,8 @@ public static function getSubscribedEvents(): array public function buildResponse(WebfingerResponseEvent $event): void { - $request = $this->requestStack->getCurrentRequest(); - $params = $this->webfingerParameters->getParams(); + $request = $event->request; + $params = $this->webfingerParameters->getParams($request); $jsonRd = $event->jsonRd; $subject = $request->query->get('resource') ?: ''; @@ -43,9 +41,10 @@ public function buildResponse(WebfingerResponseEvent $event): void $jsonRd->setSubject($subject); } - if (isset($params[WebFingerParameters::ACCOUNT_KEY_NAME]) && $actor = $this->getActor( - $params[WebFingerParameters::ACCOUNT_KEY_NAME] - )) { + if ( + isset($params[WebFingerParameters::ACCOUNT_KEY_NAME]) + && $actor = $this->getActor($params[WebFingerParameters::ACCOUNT_KEY_NAME]) + ) { $accountHref = $this->urlGenerator->generate( 'ap_magazine', ['name' => $actor->name], diff --git a/src/EventSubscriber/ActivityPub/UserWebFingerProfileSubscriber.php b/src/EventSubscriber/ActivityPub/UserWebFingerProfileSubscriber.php index aa337342b..7aaf3240f 100644 --- a/src/EventSubscriber/ActivityPub/UserWebFingerProfileSubscriber.php +++ b/src/EventSubscriber/ActivityPub/UserWebFingerProfileSubscriber.php @@ -13,14 +13,12 @@ use JetBrains\PhpStorm\ArrayShape; use Psr\Log\LoggerInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Security\Core\User\UserInterface; class UserWebFingerProfileSubscriber implements EventSubscriberInterface { public function __construct( - private readonly RequestStack $requestStack, private readonly WebFingerParameters $webfingerParameters, private readonly UserRepository $userRepository, private readonly UrlGeneratorInterface $urlGenerator, @@ -40,8 +38,7 @@ public static function getSubscribedEvents(): array public function buildResponse(WebfingerResponseEvent $event): void { - $request = $this->requestStack->getCurrentRequest(); - $params = $this->webfingerParameters->getParams(); + $params = $this->webfingerParameters->getParams($event->request); $jsonRd = $event->jsonRd; if (isset($params[WebFingerParameters::ACCOUNT_KEY_NAME])) { diff --git a/src/EventSubscriber/ActivityPub/UserWebFingerSubscriber.php b/src/EventSubscriber/ActivityPub/UserWebFingerSubscriber.php index f7ac482df..84dc5520b 100644 --- a/src/EventSubscriber/ActivityPub/UserWebFingerSubscriber.php +++ b/src/EventSubscriber/ActivityPub/UserWebFingerSubscriber.php @@ -10,14 +10,12 @@ use App\Service\ActivityPub\Webfinger\WebFingerParameters; use JetBrains\PhpStorm\ArrayShape; use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Security\Core\User\UserInterface; class UserWebFingerSubscriber implements EventSubscriberInterface { public function __construct( - private readonly RequestStack $requestStack, private readonly WebFingerParameters $webfingerParameters, private readonly UserRepository $userRepository, private readonly UrlGeneratorInterface $urlGenerator @@ -34,8 +32,8 @@ public static function getSubscribedEvents(): array public function buildResponse(WebfingerResponseEvent $event): void { - $request = $this->requestStack->getCurrentRequest(); - $params = $this->webfingerParameters->getParams(); + $request = $event->request; + $params = $this->webfingerParameters->getParams($request); $jsonRd = $event->jsonRd; $subject = $request->query->get('resource') ?: ''; @@ -43,9 +41,10 @@ public function buildResponse(WebfingerResponseEvent $event): void $jsonRd->setSubject($subject); } - if (isset($params[WebFingerParameters::ACCOUNT_KEY_NAME]) && $actor = $this->getActor( - $params[WebFingerParameters::ACCOUNT_KEY_NAME] - )) { + if ( + isset($params[WebFingerParameters::ACCOUNT_KEY_NAME]) + && $actor = $this->getActor($params[WebFingerParameters::ACCOUNT_KEY_NAME]) + ) { $accountHref = $this->urlGenerator->generate( 'ap_user', ['username' => $actor->getUserIdentifier()], diff --git a/src/Service/ActivityPub/Webfinger/WebFingerParameters.php b/src/Service/ActivityPub/Webfinger/WebFingerParameters.php index 3cc16562d..b442ae775 100644 --- a/src/Service/ActivityPub/Webfinger/WebFingerParameters.php +++ b/src/Service/ActivityPub/Webfinger/WebFingerParameters.php @@ -4,7 +4,7 @@ namespace App\Service\ActivityPub\Webfinger; -use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\HttpFoundation\Request; class WebFingerParameters { @@ -12,16 +12,17 @@ class WebFingerParameters public const HOST_KEY_NAME = 'host'; public const ACCOUNT_KEY_NAME = 'account'; - public function __construct(private readonly RequestStack $requestStack) + public function __construct() { } - public function getParams(): array + /** + * @return array{acccount?: string, host?: string, rel?: array} + */ + public function getParams(Request $request): array { $params = []; - $request = $this->requestStack->getCurrentRequest(); - if ($resource = $request->query->get('resource')) { $host = $request->server->get('HTTP_HOST'); // @todo From 06d70a0f1d62e45cd03efe8d3b5c30b3a3f6255d Mon Sep 17 00:00:00 2001 From: debounced <35878315+nobodyatroot@users.noreply.github.com> Date: Sun, 12 May 2024 09:22:36 -0500 Subject: [PATCH 004/335] Exclude `node_modules` and `vendor` directories from PHP linter (#775) Co-authored-by: e-five <146029455+e-five256@users.noreply.github.com> --- .php-cs-fixer.dist.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index b79147282..37ecbe83a 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -4,7 +4,12 @@ $finder = (new PhpCsFixer\Finder()) ->in(__DIR__) - ->exclude('var') + ->exclude([ + 'var', + 'node_modules', + 'vendor', + 'docker', + ]) ; return (new PhpCsFixer\Config()) From ffdb5eb2b386b598e32ac8c0aa480d4a31f651eb Mon Sep 17 00:00:00 2001 From: e-five <146029455+e-five256@users.noreply.github.com> Date: Mon, 13 May 2024 10:08:48 -0400 Subject: [PATCH 005/335] Make 2fa input field required to submit form (#774) --- templates/user/2fa.html.twig | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/user/2fa.html.twig b/templates/user/2fa.html.twig index 87115f75b..0af6a4b07 100644 --- a/templates/user/2fa.html.twig +++ b/templates/user/2fa.html.twig @@ -27,6 +27,7 @@ name="{{ authCodeParameterName }}" autocomplete="one-time-code" autofocus + required inputmode="numeric" pattern="[0-9]*"/> From bf9c2055b483c06b05f82d7542c5e6472dfc49c2 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Mon, 13 May 2024 19:08:36 +0200 Subject: [PATCH 006/335] Do not auto-close issues because of stale (#776) --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 1b2a5706a..8bac71e77 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -18,5 +18,5 @@ jobs: exempt-issue-labels: "high priority" days-before-issue-stale: 50 days-before-pr-stale: 40 - days-before-issue-close: 6 + days-before-issue-close: -1 days-before-pr-close: -1 From 2bddbbe6c0e354b7f124796bf63ba6a57c9bc8a4 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Mon, 13 May 2024 19:15:51 +0200 Subject: [PATCH 007/335] Add note to lint docs (#778) --- docs/04-contributing/linting.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/04-contributing/linting.md b/docs/04-contributing/linting.md index 0da3a11ce..ba2e8398c 100644 --- a/docs/04-contributing/linting.md +++ b/docs/04-contributing/linting.md @@ -10,4 +10,6 @@ Try to automatically fix linting errors: ```bash tools/vendor/bin/php-cs-fixer fix -``` \ No newline at end of file +``` + +_Note:_ First time you run the linter, it might take a while. After a hot cache, linting will be much faster. From 24ed9529fc409a32899f9d4920c385f5be699bee Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Tue, 14 May 2024 13:20:46 +0000 Subject: [PATCH 008/335] Rework the tag system (#654) Co-authored-by: debounced <35878315+nobodyatroot@users.noreply.github.com> Co-authored-by: Melroy van den Berg --- assets/styles/app.scss | 1 + assets/styles/components/_tag.scss | 21 ++ config/kbin_routes/tag.yaml | 10 + config/packages/doctrine.yaml | 3 + migrations/Version20240330101300.php | 217 +++++++++++++++ src/Command/MoveEntriesByTagCommand.php | 12 +- src/Command/MovePostsByTagCommand.php | 5 +- src/Command/PostMagazinesUpdateCommand.php | 8 +- .../Update/TagsToJsonbUpdateCommand.php | 52 ---- src/Command/Update/TagsUpdateCommand.php | 10 +- .../ActivityPub/EntryCommentController.php | 9 +- .../ActivityPub/EntryController.php | 9 +- .../ActivityPub/PostCommentController.php | 9 +- src/Controller/ActivityPub/PostController.php | 9 +- src/Controller/Api/BaseApi.php | 19 +- .../Entry/Admin/EntriesChangeMagazineApi.php | 2 +- .../Entry/Comments/EntryCommentsCreateApi.php | 4 +- .../Comments/EntryCommentsFavouriteApi.php | 2 +- .../Entry/Comments/EntryCommentsVoteApi.php | 2 +- .../Moderate/EntryCommentsSetAdultApi.php | 2 +- .../Moderate/EntryCommentsSetLanguageApi.php | 2 +- .../Moderate/EntryCommentsTrashApi.php | 4 +- .../Api/Entry/DomainEntriesRetrieveApi.php | 2 +- src/Controller/Api/Entry/EntriesBaseApi.php | 8 +- .../Api/Entry/EntriesFavouriteApi.php | 2 +- .../Api/Entry/EntriesRetrieveApi.php | 10 +- src/Controller/Api/Entry/EntriesUpdateApi.php | 2 +- src/Controller/Api/Entry/EntriesVoteApi.php | 2 +- .../Api/Entry/MagazineEntriesRetrieveApi.php | 2 +- .../Api/Entry/MagazineEntryCreateApi.php | 8 +- .../Api/Entry/Moderate/EntriesPinApi.php | 2 +- .../Api/Entry/Moderate/EntriesSetAdultApi.php | 2 +- .../Entry/Moderate/EntriesSetLanguageApi.php | 2 +- .../Api/Entry/Moderate/EntriesTrashApi.php | 4 +- .../Api/Entry/UserEntriesRetrieveApi.php | 2 +- .../Api/Notification/NotificationBaseApi.php | 8 +- .../Moderate/PostCommentsSetAdultApi.php | 2 +- .../Moderate/PostCommentsSetLanguageApi.php | 2 +- .../Moderate/PostCommentsTrashApi.php | 4 +- .../Post/Comments/PostCommentsCreateApi.php | 4 +- .../Comments/PostCommentsFavouriteApi.php | 2 +- .../Api/Post/Comments/PostCommentsVoteApi.php | 2 +- .../Api/Post/Moderate/PostsPinApi.php | 2 +- .../Api/Post/Moderate/PostsSetAdultApi.php | 2 +- .../Api/Post/Moderate/PostsSetLanguageApi.php | 2 +- .../Api/Post/Moderate/PostsTrashApi.php | 4 +- src/Controller/Api/Post/PostsBaseApi.php | 8 +- src/Controller/Api/Post/PostsCreateApi.php | 4 +- src/Controller/Api/Post/PostsFavouriteApi.php | 2 +- src/Controller/Api/Post/PostsRetrieveApi.php | 12 +- src/Controller/Api/Post/PostsUpdateApi.php | 2 +- src/Controller/Api/Post/PostsVoteApi.php | 2 +- .../Api/Post/UserPostsRetrieveApi.php | 2 +- .../Entry/EntryCreateController.php | 32 +++ src/Controller/Post/PostCreateController.php | 7 +- src/Controller/Tag/TagBanController.php | 50 ++++ .../Tag/TagCommentFrontController.php | 7 +- .../Tag/TagEntryFrontController.php | 7 +- src/Controller/Tag/TagOverviewController.php | 25 +- .../Tag/TagPeopleFrontController.php | 3 + src/Controller/Tag/TagPostFrontController.php | 10 +- src/DTO/EntryCommentDto.php | 1 - src/DTO/EntryRequestDto.php | 1 - src/DTO/MagazineLogResponseDto.php | 10 +- src/DTO/PostCommentDto.php | 1 - src/DTO/PostDto.php | 1 - src/DoctrineExtensions/DBAL/Types/Citext.php | 26 ++ src/Entity/Contracts/TagInterface.php | 10 - src/Entity/Entry.php | 12 +- src/Entity/EntryComment.php | 12 +- src/Entity/Hashtag.php | 30 +++ src/Entity/HashtagLink.php | 41 +++ src/Entity/Post.php | 12 +- src/Entity/PostComment.php | 7 +- .../Post/PostCreateSubscriber.php | 8 +- src/Exception/TagBannedException.php | 9 + src/Factory/ActivityPub/ActivityFactory.php | 10 +- .../ActivityPub/EntryCommentNoteFactory.php | 3 +- src/Factory/ActivityPub/EntryPageFactory.php | 3 +- .../ActivityPub/PostCommentNoteFactory.php | 3 +- src/Factory/ActivityPub/PostNoteFactory.php | 9 +- src/Factory/EntryCommentFactory.php | 9 +- src/Factory/EntryFactory.php | 8 +- src/Factory/PostCommentFactory.php | 9 +- src/Factory/PostFactory.php | 5 +- src/Factory/ReportFactory.php | 10 +- .../Inbox/ChainActivityHandler.php | 6 + .../ActivityPub/Inbox/CreateHandler.php | 40 ++- src/Pagination/NativeQueryAdapter.php | 62 +++++ src/Pagination/QueryAdapter.php | 2 +- .../ContentPopulationTransformer.php | 47 ++++ .../Transformation/ResultTransformer.php | 10 + .../Transformation/VoidTransformer.php | 13 + .../Contract/TagRepositoryInterface.php | 10 - src/Repository/EntryCommentRepository.php | 30 ++- src/Repository/EntryRepository.php | 43 ++- src/Repository/PostCommentRepository.php | 32 ++- src/Repository/PostRepository.php | 53 ++-- src/Repository/SearchRepository.php | 246 +++++------------- src/Repository/TagLinkRepository.php | 140 ++++++++++ src/Repository/TagRepository.php | 144 +++++----- src/Service/ActivityPub/MarkdownConverter.php | 6 +- src/Service/ActivityPub/Note.php | 13 +- src/Service/ActivityPub/Page.php | 17 +- src/Service/EntryCommentManager.php | 11 +- src/Service/EntryManager.php | 24 +- src/Service/FeedManager.php | 4 +- src/Service/PostCommentManager.php | 23 +- src/Service/PostManager.php | 17 +- src/Service/TagExtractor.php | 81 ++++++ src/Service/TagManager.php | 199 ++++++++++---- src/Twig/Components/TagActionComponent.php | 13 + src/Twig/Extension/AdminExtension.php | 1 + src/Twig/Runtime/AdminExtensionRuntime.php | 24 +- templates/components/tag_actions.html.twig | 2 + templates/entry/_info.html.twig | 6 +- templates/layout/_sidebar.html.twig | 3 + templates/magazine/panel/tags.html.twig | 1 - templates/tag/_list.html.twig | 3 + templates/tag/_options.html.twig | 15 +- templates/tag/_panel.html.twig | 36 +++ templates/tag/overview.html.twig | 20 +- ...agManagerTest.php => TagExtractorTest.php} | 6 +- translations/messages.en.yaml | 9 + 124 files changed, 1669 insertions(+), 660 deletions(-) create mode 100644 assets/styles/components/_tag.scss create mode 100644 migrations/Version20240330101300.php delete mode 100644 src/Command/Update/TagsToJsonbUpdateCommand.php create mode 100644 src/Controller/Tag/TagBanController.php create mode 100644 src/DoctrineExtensions/DBAL/Types/Citext.php delete mode 100644 src/Entity/Contracts/TagInterface.php create mode 100644 src/Entity/Hashtag.php create mode 100644 src/Entity/HashtagLink.php create mode 100644 src/Exception/TagBannedException.php create mode 100644 src/Pagination/NativeQueryAdapter.php create mode 100644 src/Pagination/Transformation/ContentPopulationTransformer.php create mode 100644 src/Pagination/Transformation/ResultTransformer.php create mode 100644 src/Pagination/Transformation/VoidTransformer.php delete mode 100644 src/Repository/Contract/TagRepositoryInterface.php create mode 100644 src/Repository/TagLinkRepository.php create mode 100644 src/Service/TagExtractor.php create mode 100644 src/Twig/Components/TagActionComponent.php create mode 100644 templates/components/tag_actions.html.twig create mode 100644 templates/tag/_list.html.twig create mode 100644 templates/tag/_panel.html.twig rename tests/Unit/Service/{TagManagerTest.php => TagExtractorTest.php} (91%) diff --git a/assets/styles/app.scss b/assets/styles/app.scss index 2c44ebdb0..c849d3343 100644 --- a/assets/styles/app.scss +++ b/assets/styles/app.scss @@ -54,3 +54,4 @@ @import 'themes/default'; @import 'themes/solarized'; @import 'themes/tokyo-night'; +@import 'components/tag'; diff --git a/assets/styles/components/_tag.scss b/assets/styles/components/_tag.scss new file mode 100644 index 000000000..fd97a57ec --- /dev/null +++ b/assets/styles/components/_tag.scss @@ -0,0 +1,21 @@ +.section.tag { + header { + text-align: center; + + h4 { + font-size: 1.2rem; + margin-bottom: 0; + margin-top: .5rem; + } + } + + .tag__actions { + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: center; + margin-top: 1rem; + margin-bottom: 2.5rem; + gap: .25rem; + } +} \ No newline at end of file diff --git a/config/kbin_routes/tag.yaml b/config/kbin_routes/tag.yaml index 577341d38..2165a47aa 100644 --- a/config/kbin_routes/tag.yaml +++ b/config/kbin_routes/tag.yaml @@ -30,3 +30,13 @@ tag_people: path: tag/{name}/people methods: [GET] requirements: { sortBy: "%front_sort_options%" } + +tag_ban: + path: /tag/{name}/ban + methods: [POST] + controller: App\Controller\Tag\TagBanController::ban + +tag_unban: + path: /tag/{name}/unban + methods: [POST] + controller: App\Controller\Tag\TagBanController::unban \ No newline at end of file diff --git a/config/packages/doctrine.yaml b/config/packages/doctrine.yaml index ddbd2c6a7..31320c0ad 100644 --- a/config/packages/doctrine.yaml +++ b/config/packages/doctrine.yaml @@ -1,8 +1,11 @@ doctrine: dbal: url: '%env(resolve:DATABASE_URL)%' + types: + citext: App\DoctrineExtensions\DBAL\Types\Citext mapping_types: user_type: string + citext: citext # IMPORTANT: You MUST configure your server version, # either here or in the DATABASE_URL env var (see .env file) diff --git a/migrations/Version20240330101300.php b/migrations/Version20240330101300.php new file mode 100644 index 000000000..e38d46c10 --- /dev/null +++ b/migrations/Version20240330101300.php @@ -0,0 +1,217 @@ +addSql('CREATE EXTENSION IF NOT EXISTS citext'); + $this->addSql('CREATE SEQUENCE hashtag_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE SEQUENCE hashtag_link_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE TABLE hashtag (id INT NOT NULL, tag citext NOT NULL, banned BOOLEAN DEFAULT false NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE UNIQUE INDEX UNIQ_5AB52A61389B783 ON hashtag (tag)'); + $this->addSql('CREATE TABLE hashtag_link (id INT NOT NULL, hashtag_id INT NOT NULL, entry_id INT DEFAULT NULL, entry_comment_id INT DEFAULT NULL, post_id INT DEFAULT NULL, post_comment_id INT DEFAULT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE INDEX IDX_83957168FB34EF56 ON hashtag_link (hashtag_id)'); + $this->addSql('CREATE INDEX IDX_83957168BA364942 ON hashtag_link (entry_id)'); + $this->addSql('CREATE INDEX IDX_8395716860C33421 ON hashtag_link (entry_comment_id)'); + $this->addSql('CREATE INDEX IDX_839571684B89032C ON hashtag_link (post_id)'); + $this->addSql('CREATE INDEX IDX_83957168DB1174D2 ON hashtag_link (post_comment_id)'); + $this->addSql('ALTER TABLE hashtag_link ADD CONSTRAINT FK_83957168FB34EF56 FOREIGN KEY (hashtag_id) REFERENCES hashtag (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE hashtag_link ADD CONSTRAINT FK_83957168BA364942 FOREIGN KEY (entry_id) REFERENCES entry (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE hashtag_link ADD CONSTRAINT FK_8395716860C33421 FOREIGN KEY (entry_comment_id) REFERENCES entry_comment (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE hashtag_link ADD CONSTRAINT FK_839571684B89032C FOREIGN KEY (post_id) REFERENCES post (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE hashtag_link ADD CONSTRAINT FK_83957168DB1174D2 FOREIGN KEY (post_comment_id) REFERENCES post_comment (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + + // migrate entry tags + $select = "SELECT e.id, e.tags, keys.value::CITEXT as hashtag, e.created_at FROM entry e + JOIN LATERAL (SELECT * FROM jsonb_array_elements_text(e.tags)) as keys ON TRUE + WHERE e.tags IS NOT NULL AND jsonb_typeof(e.tags) = 'array' + UNION ALL + SELECT e.id, e.tags, keys.value::CITEXT as hashtag, e.created_at FROM entry e + JOIN LATERAL (SELECT * FROM jsonb_each_text(e.tags)) as keys ON TRUE + WHERE e.tags IS NOT NULL AND jsonb_typeof(e.tags) = 'object' + ORDER BY created_at DESC"; + $foreachStatement = "IF NOT EXISTS (SELECT id FROM hashtag WHERE hashtag.tag = temprow.hashtag) THEN + INSERT INTO hashtag(id, tag) VALUES(NEXTVAL('hashtag_id_seq'), temprow.hashtag); + END IF; + IF NOT EXISTS (SELECT l.id FROM hashtag_link l + INNER JOIN hashtag def ON def.id=l.hashtag_id + WHERE l.entry_id = temprow.id AND def.tag = temprow.hashtag) + THEN + INSERT INTO hashtag_link (id, entry_id, hashtag_id) VALUES (NEXTVAL('hashtag_link_id_seq'), temprow.id, (SELECT id FROM hashtag WHERE tag = temprow.hashtag)); + END IF;"; + + $this->addSql('DO + $do$ + declare temprow record; + BEGIN + FOR temprow IN + '.$select.' + LOOP + '.$foreachStatement.' + END LOOP; + END + $do$;'); + + // migrate entry comments tags + $select = "SELECT e.id, e.tags, keys.value::CITEXT as hashtag, e.created_at FROM entry_comment e + JOIN LATERAL (SELECT * FROM jsonb_array_elements_text(e.tags)) as keys ON TRUE + WHERE e.tags IS NOT NULL AND jsonb_typeof(e.tags) = 'array' + UNION ALL + SELECT e.id, e.tags, keys.value::CITEXT as hashtag, e.created_at FROM entry_comment e + JOIN LATERAL (SELECT * FROM jsonb_each_text(e.tags)) as keys ON TRUE + WHERE e.tags IS NOT NULL AND jsonb_typeof(e.tags) = 'object' + ORDER BY created_at DESC"; + $foreachStatement = "IF NOT EXISTS (SELECT id FROM hashtag WHERE hashtag.tag = temprow.hashtag) THEN + INSERT INTO hashtag(id, tag) VALUES(NEXTVAL('hashtag_id_seq'), temprow.hashtag); + END IF; + IF NOT EXISTS (SELECT l.id FROM hashtag_link l + INNER JOIN hashtag def ON def.id=l.hashtag_id + WHERE l.entry_comment_id = temprow.id AND def.tag = temprow.hashtag) + THEN + INSERT INTO hashtag_link (id, entry_comment_id, hashtag_id) VALUES (NEXTVAL('hashtag_link_id_seq'), temprow.id, (SELECT id FROM hashtag WHERE tag=temprow.hashtag)); + END IF;"; + + $this->addSql('DO + $do$ + declare temprow record; + BEGIN + FOR temprow IN + '.$select.' + LOOP + '.$foreachStatement.' + END LOOP; + END + $do$;'); + + // migrate post tags + $select = "SELECT e.id, e.tags, keys.value::CITEXT as hashtag, e.created_at FROM post e + JOIN LATERAL (SELECT * FROM jsonb_array_elements_text(e.tags)) as keys ON TRUE + WHERE e.tags IS NOT NULL AND jsonb_typeof(e.tags) = 'array' + UNION ALL + SELECT e.id, e.tags, keys.value::CITEXT as hashtag, e.created_at FROM post e + JOIN LATERAL (SELECT * FROM jsonb_each_text(e.tags)) as keys ON TRUE + WHERE e.tags IS NOT NULL AND jsonb_typeof(e.tags) = 'object' + ORDER BY created_at DESC"; + $foreachStatement = "IF NOT EXISTS (SELECT id FROM hashtag WHERE hashtag.tag = temprow.hashtag) THEN + INSERT INTO hashtag(id, tag) VALUES(NEXTVAL('hashtag_id_seq'), temprow.hashtag); + END IF; + IF NOT EXISTS (SELECT l.id FROM hashtag_link l + INNER JOIN hashtag def ON def.id=l.hashtag_id + WHERE l.post_id = temprow.id AND def.tag = temprow.hashtag) + THEN + INSERT INTO hashtag_link (id, post_id, hashtag_id) VALUES (NEXTVAL('hashtag_link_id_seq'), temprow.id, (SELECT id FROM hashtag WHERE tag=temprow.hashtag)); + END IF;"; + + $this->addSql('DO + $do$ + declare temprow record; + BEGIN + FOR temprow IN + '.$select.' + LOOP + '.$foreachStatement.' + END LOOP; + END + $do$;'); + // migrate post comment tags + $select = "SELECT e.id, e.tags, keys.value::CITEXT as hashtag, e.created_at FROM post_comment e + JOIN LATERAL (SELECT * FROM jsonb_array_elements_text(e.tags)) as keys ON TRUE + WHERE e.tags IS NOT NULL AND jsonb_typeof(e.tags) = 'array' + UNION ALL + SELECT e.id, e.tags, keys.value::CITEXT as hashtag, e.created_at FROM post_comment e + JOIN LATERAL (SELECT * FROM jsonb_each_text(e.tags)) as keys ON TRUE + WHERE e.tags IS NOT NULL AND jsonb_typeof(e.tags) = 'object' + ORDER BY created_at DESC"; + $foreachStatement = "IF NOT EXISTS (SELECT id FROM hashtag WHERE hashtag.tag = temprow.hashtag) THEN + INSERT INTO hashtag(id, tag) VALUES(NEXTVAL('hashtag_id_seq'), temprow.hashtag); + END IF; + IF NOT EXISTS (SELECT l.id FROM hashtag_link l + INNER JOIN hashtag def ON def.id=l.hashtag_id + WHERE l.post_comment_id = temprow.id AND def.tag = temprow.hashtag) + THEN + INSERT INTO hashtag_link (id, post_comment_id, hashtag_id) VALUES (NEXTVAL('hashtag_link_id_seq'), temprow.id, (SELECT id FROM hashtag WHERE tag=temprow.hashtag)); + END IF;"; + + $this->addSql('DO + $do$ + declare temprow record; + BEGIN + FOR temprow IN + '.$select.' + LOOP + '.$foreachStatement.' + END LOOP; + END + $do$;'); + + $this->addSql('ALTER TABLE entry DROP COLUMN tags'); + $this->addSql('ALTER TABLE entry_comment DROP COLUMN tags'); + $this->addSql('ALTER TABLE post DROP COLUMN tags'); + $this->addSql('ALTER TABLE post_comment DROP COLUMN tags'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE entry_comment ADD tags JSONB DEFAULT NULL'); + $this->addSql('ALTER TABLE post_comment ADD tags JSONB DEFAULT NULL'); + $this->addSql('ALTER TABLE post ADD tags JSONB DEFAULT NULL'); + $this->addSql('ALTER TABLE entry ADD tags JSONB DEFAULT NULL'); + + $this->addSql('DO +$do$ + declare temprow record; +BEGIN + FOR temprow IN + SELECT hl.entry_id, hl.entry_comment_id, hl.post_id, hl.post_comment_id, h.tag FROM hashtag_link hl INNER JOIN hashtag h ON h.id = hl.hashtag_id + LOOP + IF temprow.entry_id IS NOT NULL THEN + IF NOT EXISTS (SELECT id FROM entry e WHERE e.id = temprow.entry_id AND e.tags IS NOT NULL) THEN + UPDATE entry SET tags = \'[]\'::jsonb WHERE entry.id = temprow.entry_id; + END IF; + UPDATE entry SET tags = tags || to_jsonb(temprow.tag) WHERE entry.id = temprow.entry_id; + END IF; + IF temprow.entry_comment_id IS NOT NULL THEN + IF NOT EXISTS (SELECT id FROM entry_comment ec WHERE ec.id = temprow.entry_comment_id AND ec.tags IS NOT NULL) THEN + UPDATE entry_comment SET tags = \'[]\'::jsonb WHERE entry_comment.id = temprow.entry_comment_id; + END IF; + UPDATE entry_comment SET tags = tags || to_jsonb(temprow.tag) WHERE entry_comment.id = temprow.entry_comment_id; + END IF; + IF temprow.post_id IS NOT NULL THEN + IF NOT EXISTS (SELECT id FROM post p WHERE p.id = temprow.post_id AND p.tags IS NOT NULL) THEN + UPDATE post SET tags = \'[]\'::jsonb WHERE post.id = temprow.post_id; + END IF; + UPDATE post SET tags = tags || to_jsonb(temprow.tag) WHERE post.id = temprow.post_id; + END IF; + IF temprow.post_comment_id IS NOT NULL THEN + IF NOT EXISTS (SELECT id FROM post_comment pc WHERE pc.id = temprow.post_comment_id AND pc.tags IS NOT NULL) THEN + UPDATE post_comment SET tags = \'[]\'::jsonb WHERE post_comment.id = temprow.post_comment_id; + END IF; + UPDATE post_comment SET tags = tags || to_jsonb(temprow.tag) WHERE post_comment.id = temprow.post_comment_id; + END IF; + END LOOP; +END +$do$;'); + + $this->addSql('DROP SEQUENCE hashtag_id_seq CASCADE'); + $this->addSql('DROP SEQUENCE hashtag_link_id_seq CASCADE'); + $this->addSql('ALTER TABLE hashtag_link DROP CONSTRAINT FK_83957168FB34EF56'); + $this->addSql('ALTER TABLE hashtag_link DROP CONSTRAINT FK_83957168BA364942'); + $this->addSql('ALTER TABLE hashtag_link DROP CONSTRAINT FK_8395716860C33421'); + $this->addSql('ALTER TABLE hashtag_link DROP CONSTRAINT FK_839571684B89032C'); + $this->addSql('ALTER TABLE hashtag_link DROP CONSTRAINT FK_83957168DB1174D2'); + $this->addSql('DROP TABLE hashtag'); + $this->addSql('DROP TABLE hashtag_link'); + } +} diff --git a/src/Command/MoveEntriesByTagCommand.php b/src/Command/MoveEntriesByTagCommand.php index 9e92bc0d7..0702e3bb2 100644 --- a/src/Command/MoveEntriesByTagCommand.php +++ b/src/Command/MoveEntriesByTagCommand.php @@ -54,11 +54,13 @@ protected function execute(InputInterface $input, OutputInterface $output): int return Command::FAILURE; } - $qb = $this->entryRepository->createQueryBuilder('e'); - - $qb->andWhere("JSONB_CONTAINS(e.tags, '\"".$tag."\"') = true"); - - $entries = $qb->getQuery()->getResult(); + $entries = $this->entryRepository->createQueryBuilder('e') + ->where('t.tag = :tag') + ->join('e.hashtags', 'h') + ->join('h.hashtag', 't') + ->setParameter('tag', $tag) + ->getQuery() + ->getResult(); foreach ($entries as $entry) { /* diff --git a/src/Command/MovePostsByTagCommand.php b/src/Command/MovePostsByTagCommand.php index 17a6a92e5..38a32cd95 100644 --- a/src/Command/MovePostsByTagCommand.php +++ b/src/Command/MovePostsByTagCommand.php @@ -54,7 +54,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int $qb = $this->postRepository->createQueryBuilder('p'); - $qb->andWhere("JSONB_CONTAINS(p.tags, '\"".$tag."\"') = true"); + $qb->andWhere('t.tag = :tag') + ->join('p.hashtags', 'h') + ->join('h.hashtag', 't') + ->setParameter('tag', $tag); $posts = $qb->getQuery()->getResult(); diff --git a/src/Command/PostMagazinesUpdateCommand.php b/src/Command/PostMagazinesUpdateCommand.php index d11695840..c1b101961 100644 --- a/src/Command/PostMagazinesUpdateCommand.php +++ b/src/Command/PostMagazinesUpdateCommand.php @@ -7,6 +7,7 @@ use App\Entity\Post; use App\Repository\MagazineRepository; use App\Repository\PostRepository; +use App\Repository\TagLinkRepository; use App\Service\PostManager; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; @@ -22,6 +23,7 @@ class PostMagazinesUpdateCommand extends Command public function __construct( private readonly PostRepository $postRepository, private readonly PostManager $postManager, + private readonly TagLinkRepository $tagLinkRepository, private readonly MagazineRepository $magazineRepository ) { parent::__construct(); @@ -39,12 +41,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int private function handleMagazine(Post $post, OutputInterface $output): void { - if (!$post->tags) { - return; - } + $tags = $this->tagLinkRepository->getTagsOfPost($post); $output->writeln((string) $post->getId()); - foreach ($post->tags as $tag) { + foreach ($tags as $tag) { if ($magazine = $this->magazineRepository->findOneByName($tag)) { $output->writeln($magazine->name); $this->postManager->changeMagazine($post, $magazine); diff --git a/src/Command/Update/TagsToJsonbUpdateCommand.php b/src/Command/Update/TagsToJsonbUpdateCommand.php deleted file mode 100644 index dabe5cff6..000000000 --- a/src/Command/Update/TagsToJsonbUpdateCommand.php +++ /dev/null @@ -1,52 +0,0 @@ -update($this->entityManager->getRepository(Entry::class)); - $this->update($this->entityManager->getRepository(EntryComment::class)); - $this->update($this->entityManager->getRepository(Post::class)); - $this->update($this->entityManager->getRepository(PostComment::class)); - - return Command::SUCCESS; - } - - private function update(TagRepositoryInterface $repository) - { - /** @var TagInterface $entry */ - foreach ($repository->findWithTags() as $entry) { - $entry->tagsTmp = $entry->getTags(); - $this->entityManager->persist($entry); - echo $entry->getId().PHP_EOL; - } - - $this->entityManager->flush(); - } -} diff --git a/src/Command/Update/TagsUpdateCommand.php b/src/Command/Update/TagsUpdateCommand.php index 20ac0ea0f..7cd4e5432 100644 --- a/src/Command/Update/TagsUpdateCommand.php +++ b/src/Command/Update/TagsUpdateCommand.php @@ -7,7 +7,7 @@ use App\Entity\EntryComment; use App\Entity\Post; use App\Entity\PostComment; -use App\Service\TagManager; +use App\Service\TagExtractor; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; @@ -21,7 +21,7 @@ class TagsUpdateCommand extends Command { public function __construct( - private readonly TagManager $tagManager, + private readonly TagExtractor $tagExtractor, private readonly EntityManagerInterface $entityManager ) { parent::__construct(); @@ -31,19 +31,19 @@ protected function execute(InputInterface $input, OutputInterface $output): int { $comments = $this->entityManager->getRepository(EntryComment::class)->findAll(); foreach ($comments as $comment) { - $comment->tags = $this->tagManager->extract($comment->body, $comment->magazine->name); + $comment->tags = $this->tagExtractor->extract($comment->body, $comment->magazine->name); $this->entityManager->persist($comment); } $posts = $this->entityManager->getRepository(Post::class)->findAll(); foreach ($posts as $post) { - $post->tags = $this->tagManager->extract($post->body, $post->magazine->name); + $post->tags = $this->tagExtractor->extract($post->body, $post->magazine->name); $this->entityManager->persist($post); } $comments = $this->entityManager->getRepository(PostComment::class)->findAll(); foreach ($comments as $comment) { - $comment->tags = $this->tagManager->extract($comment->body, $comment->magazine->name); + $comment->tags = $this->tagExtractor->extract($comment->body, $comment->magazine->name); $this->entityManager->persist($comment); } diff --git a/src/Controller/ActivityPub/EntryCommentController.php b/src/Controller/ActivityPub/EntryCommentController.php index d25caea60..506988d2d 100644 --- a/src/Controller/ActivityPub/EntryCommentController.php +++ b/src/Controller/ActivityPub/EntryCommentController.php @@ -10,6 +10,7 @@ use App\Entity\EntryComment; use App\Entity\Magazine; use App\Factory\ActivityPub\EntryCommentNoteFactory; +use App\Repository\TagLinkRepository; use Symfony\Bridge\Doctrine\Attribute\MapEntity; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; @@ -19,8 +20,10 @@ class EntryCommentController extends AbstractController { use PrivateContentTrait; - public function __construct(private readonly EntryCommentNoteFactory $commentNoteFactory) - { + public function __construct( + private readonly EntryCommentNoteFactory $commentNoteFactory, + private readonly TagLinkRepository $tagLinkRepository, + ) { } public function __invoke( @@ -38,7 +41,7 @@ public function __invoke( $this->handlePrivateContent($comment); - $response = new JsonResponse($this->commentNoteFactory->create($comment, true)); + $response = new JsonResponse($this->commentNoteFactory->create($comment, $this->tagLinkRepository->getTagsOfEntryComment($comment), true)); $response->headers->set('Content-Type', 'application/activity+json'); diff --git a/src/Controller/ActivityPub/EntryController.php b/src/Controller/ActivityPub/EntryController.php index a68a25af1..d9f066db6 100644 --- a/src/Controller/ActivityPub/EntryController.php +++ b/src/Controller/ActivityPub/EntryController.php @@ -8,6 +8,7 @@ use App\Entity\Entry; use App\Entity\Magazine; use App\Factory\ActivityPub\EntryPageFactory; +use App\Repository\TagLinkRepository; use Symfony\Bridge\Doctrine\Attribute\MapEntity; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; @@ -15,8 +16,10 @@ class EntryController extends AbstractController { - public function __construct(private readonly EntryPageFactory $pageFactory) - { + public function __construct( + private readonly EntryPageFactory $pageFactory, + private readonly TagLinkRepository $tagLinkRepository, + ) { } public function __invoke( @@ -30,7 +33,7 @@ public function __invoke( return $this->redirect($entry->apId); } - $response = new JsonResponse($this->pageFactory->create($entry, true)); + $response = new JsonResponse($this->pageFactory->create($entry, $this->tagLinkRepository->getTagsOfEntry($entry), true)); $response->headers->set('Content-Type', 'application/activity+json'); diff --git a/src/Controller/ActivityPub/PostCommentController.php b/src/Controller/ActivityPub/PostCommentController.php index 529ad9beb..785dc3f7e 100644 --- a/src/Controller/ActivityPub/PostCommentController.php +++ b/src/Controller/ActivityPub/PostCommentController.php @@ -10,6 +10,7 @@ use App\Entity\Post; use App\Entity\PostComment; use App\Factory\ActivityPub\PostCommentNoteFactory; +use App\Repository\TagLinkRepository; use Symfony\Bridge\Doctrine\Attribute\MapEntity; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; @@ -19,8 +20,10 @@ class PostCommentController extends AbstractController { use PrivateContentTrait; - public function __construct(private readonly PostCommentNoteFactory $commentNoteFactory) - { + public function __construct( + private readonly PostCommentNoteFactory $commentNoteFactory, + private readonly TagLinkRepository $tagLinkRepository, + ) { } public function __invoke( @@ -38,7 +41,7 @@ public function __invoke( $this->handlePrivateContent($post); - $response = new JsonResponse($this->commentNoteFactory->create($comment, true)); + $response = new JsonResponse($this->commentNoteFactory->create($comment, $this->tagLinkRepository->getTagsOfPostComment($comment), true)); $response->headers->set('Content-Type', 'application/activity+json'); diff --git a/src/Controller/ActivityPub/PostController.php b/src/Controller/ActivityPub/PostController.php index 7720f7858..a86b866d4 100644 --- a/src/Controller/ActivityPub/PostController.php +++ b/src/Controller/ActivityPub/PostController.php @@ -8,6 +8,7 @@ use App\Entity\Magazine; use App\Entity\Post; use App\Factory\ActivityPub\PostNoteFactory; +use App\Repository\TagLinkRepository; use Symfony\Bridge\Doctrine\Attribute\MapEntity; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; @@ -15,8 +16,10 @@ class PostController extends AbstractController { - public function __construct(private readonly PostNoteFactory $postNoteFactory) - { + public function __construct( + private readonly PostNoteFactory $postNoteFactory, + private readonly TagLinkRepository $tagLinkRepository, + ) { } public function __invoke( @@ -30,7 +33,7 @@ public function __invoke( return $this->redirect($post->apId); } - $response = new JsonResponse($this->postNoteFactory->create($post, true)); + $response = new JsonResponse($this->postNoteFactory->create($post, $this->tagLinkRepository->getTagsOfPost($post), true)); $response->headers->set('Content-Type', 'application/activity+json'); diff --git a/src/Controller/Api/BaseApi.php b/src/Controller/Api/BaseApi.php index 6b521d5ac..598ebbc88 100644 --- a/src/Controller/Api/BaseApi.php +++ b/src/Controller/Api/BaseApi.php @@ -31,8 +31,13 @@ use App\Factory\PostFactory; use App\Form\Constraint\ImageConstraint; use App\Repository\Criteria; +use App\Repository\EntryCommentRepository; +use App\Repository\EntryRepository; use App\Repository\ImageRepository; use App\Repository\OAuth2ClientAccessRepository; +use App\Repository\PostCommentRepository; +use App\Repository\PostRepository; +use App\Repository\TagLinkRepository; use App\Schema\PaginationSchema; use App\Service\IpResolver; use App\Service\ReportManager; @@ -72,6 +77,11 @@ public function __construct( protected readonly EntryCommentFactory $entryCommentFactory, protected readonly MagazineFactory $magazineFactory, protected readonly RequestStack $request, + protected readonly TagLinkRepository $tagLinkRepository, + protected readonly EntryRepository $entryRepository, + protected readonly EntryCommentRepository $entryCommentRepository, + protected readonly PostRepository $postRepository, + protected readonly PostCommentRepository $postCommentRepository, private readonly ImageRepository $imageRepository, private readonly ReportManager $reportManager, private readonly OAuth2ClientAccessRepository $clientAccessRepository, @@ -163,7 +173,7 @@ public function serializeContentInterface(ContentInterface $content, bool $force /** * @var Entry $content */ - $dto = $this->entryFactory->createResponseDto($content); + $dto = $this->entryFactory->createResponseDto($content, $this->tagLinkRepository->getTagsOfEntry($content)); $dto->visibility = $forceVisible ? VisibilityInterface::VISIBILITY_VISIBLE : $dto->visibility; $toReturn = $dto->jsonSerialize(); $toReturn['itemType'] = 'entry'; @@ -172,7 +182,7 @@ public function serializeContentInterface(ContentInterface $content, bool $force /** * @var EntryComment $content */ - $dto = $this->entryCommentFactory->createResponseDto($content); + $dto = $this->entryCommentFactory->createResponseDto($content, $this->tagLinkRepository->getTagsOfEntryComment($content)); $dto->visibility = $forceVisible ? VisibilityInterface::VISIBILITY_VISIBLE : $dto->visibility; $toReturn = $dto->jsonSerialize(); $toReturn['itemType'] = 'entry_comment'; @@ -181,7 +191,7 @@ public function serializeContentInterface(ContentInterface $content, bool $force /** * @var Post $content */ - $dto = $this->postFactory->createResponseDto($content); + $dto = $this->postFactory->createResponseDto($content, $this->tagLinkRepository->getTagsOfPost($content)); $dto->visibility = $forceVisible ? VisibilityInterface::VISIBILITY_VISIBLE : $dto->visibility; $toReturn = $dto->jsonSerialize(); $toReturn['itemType'] = 'post'; @@ -190,7 +200,7 @@ public function serializeContentInterface(ContentInterface $content, bool $force /** * @var PostComment $content */ - $dto = $this->postCommentFactory->createResponseDto($content); + $dto = $this->postCommentFactory->createResponseDto($content, $this->tagLinkRepository->getTagsOfPostComment($content)); $dto->visibility = $forceVisible ? VisibilityInterface::VISIBILITY_VISIBLE : $dto->visibility; $toReturn = $dto->jsonSerialize(); $toReturn['itemType'] = 'post_comment'; @@ -220,6 +230,7 @@ protected function serializeLogItem(MagazineLog $log): array $this->entryCommentFactory, $this->postFactory, $this->postCommentFactory, + $this->tagLinkRepository, ); if ($response->subject) { diff --git a/src/Controller/Api/Entry/Admin/EntriesChangeMagazineApi.php b/src/Controller/Api/Entry/Admin/EntriesChangeMagazineApi.php index ff1904437..c64961bb2 100644 --- a/src/Controller/Api/Entry/Admin/EntriesChangeMagazineApi.php +++ b/src/Controller/Api/Entry/Admin/EntriesChangeMagazineApi.php @@ -86,7 +86,7 @@ public function __invoke( $manager->changeMagazine($entry, $target); return new JsonResponse( - $this->serializeEntry($factory->createDto($entry)), + $this->serializeEntry($factory->createDto($entry), $this->tagLinkRepository->getTagsOfEntry($entry)), headers: $headers ); } diff --git a/src/Controller/Api/Entry/Comments/EntryCommentsCreateApi.php b/src/Controller/Api/Entry/Comments/EntryCommentsCreateApi.php index c565aa1ea..0b179a8d9 100644 --- a/src/Controller/Api/Entry/Comments/EntryCommentsCreateApi.php +++ b/src/Controller/Api/Entry/Comments/EntryCommentsCreateApi.php @@ -123,7 +123,7 @@ public function __invoke( $dto->parent = $parent; return new JsonResponse( - $this->serializeComment($dto), + $this->serializeComment($dto, $this->tagLinkRepository->getTagsOfEntryComment($comment)), status: 201, headers: $headers ); @@ -237,7 +237,7 @@ public function uploadImage( $dto->parent = $parent; return new JsonResponse( - $this->serializeComment($dto), + $this->serializeComment($dto, $this->tagLinkRepository->getTagsOfEntryComment($comment)), status: 201, headers: $headers ); diff --git a/src/Controller/Api/Entry/Comments/EntryCommentsFavouriteApi.php b/src/Controller/Api/Entry/Comments/EntryCommentsFavouriteApi.php index e1f376f44..ad547668f 100644 --- a/src/Controller/Api/Entry/Comments/EntryCommentsFavouriteApi.php +++ b/src/Controller/Api/Entry/Comments/EntryCommentsFavouriteApi.php @@ -78,7 +78,7 @@ public function __invoke( $manager->toggle($this->getUserOrThrow(), $comment); return new JsonResponse( - $this->serializeComment($factory->createDto($comment)), + $this->serializeComment($factory->createDto($comment), $this->tagLinkRepository->getTagsOfEntryComment($comment)), headers: $headers ); } diff --git a/src/Controller/Api/Entry/Comments/EntryCommentsVoteApi.php b/src/Controller/Api/Entry/Comments/EntryCommentsVoteApi.php index 655b0c662..63cac1e16 100644 --- a/src/Controller/Api/Entry/Comments/EntryCommentsVoteApi.php +++ b/src/Controller/Api/Entry/Comments/EntryCommentsVoteApi.php @@ -91,7 +91,7 @@ public function __invoke( $manager->vote($choice, $comment, $this->getUserOrThrow(), rateLimit: false); return new JsonResponse( - $this->serializeComment($factory->createDto($comment)), + $this->serializeComment($factory->createDto($comment), $this->tagLinkRepository->getTagsOfEntryComment($comment)), headers: $headers ); } diff --git a/src/Controller/Api/Entry/Comments/Moderate/EntryCommentsSetAdultApi.php b/src/Controller/Api/Entry/Comments/Moderate/EntryCommentsSetAdultApi.php index d2069a252..f6421be29 100644 --- a/src/Controller/Api/Entry/Comments/Moderate/EntryCommentsSetAdultApi.php +++ b/src/Controller/Api/Entry/Comments/Moderate/EntryCommentsSetAdultApi.php @@ -86,7 +86,7 @@ public function __invoke( $manager->flush(); return new JsonResponse( - $this->serializeComment($factory->createDto($comment)), + $this->serializeComment($factory->createDto($comment), $this->tagLinkRepository->getTagsOfEntryComment($comment)), headers: $headers ); } diff --git a/src/Controller/Api/Entry/Comments/Moderate/EntryCommentsSetLanguageApi.php b/src/Controller/Api/Entry/Comments/Moderate/EntryCommentsSetLanguageApi.php index c17144c82..08d16ddb2 100644 --- a/src/Controller/Api/Entry/Comments/Moderate/EntryCommentsSetLanguageApi.php +++ b/src/Controller/Api/Entry/Comments/Moderate/EntryCommentsSetLanguageApi.php @@ -100,7 +100,7 @@ public function __invoke( $manager->flush(); return new JsonResponse( - $this->serializeComment($factory->createDto($comment)), + $this->serializeComment($factory->createDto($comment), $this->tagLinkRepository->getTagsOfEntryComment($comment)), headers: $headers ); } diff --git a/src/Controller/Api/Entry/Comments/Moderate/EntryCommentsTrashApi.php b/src/Controller/Api/Entry/Comments/Moderate/EntryCommentsTrashApi.php index ac60f91cc..4ca8a3d02 100644 --- a/src/Controller/Api/Entry/Comments/Moderate/EntryCommentsTrashApi.php +++ b/src/Controller/Api/Entry/Comments/Moderate/EntryCommentsTrashApi.php @@ -82,7 +82,7 @@ public function trash( // Force response to have all fields visible $visibility = $comment->visibility; $comment->visibility = VisibilityInterface::VISIBILITY_VISIBLE; - $response = $this->serializeComment($factory->createDto($comment))->jsonSerialize(); + $response = $this->serializeComment($factory->createDto($comment), $this->tagLinkRepository->getTagsOfEntryComment($comment))->jsonSerialize(); $response['visibility'] = $visibility; return new JsonResponse( @@ -159,7 +159,7 @@ public function restore( } return new JsonResponse( - $this->serializeComment($factory->createDto($comment)), + $this->serializeComment($factory->createDto($comment), $this->tagLinkRepository->getTagsOfEntryComment($comment)), headers: $headers ); } diff --git a/src/Controller/Api/Entry/DomainEntriesRetrieveApi.php b/src/Controller/Api/Entry/DomainEntriesRetrieveApi.php index 0356ff616..dce32dcc5 100644 --- a/src/Controller/Api/Entry/DomainEntriesRetrieveApi.php +++ b/src/Controller/Api/Entry/DomainEntriesRetrieveApi.php @@ -150,7 +150,7 @@ public function __invoke( try { \assert($value instanceof Entry); $this->handlePrivateContent($value); - array_push($dtos, $this->serializeEntry($factory->createDto($value))); + array_push($dtos, $this->serializeEntry($factory->createDto($value), $this->tagLinkRepository->getTagsOfEntry($value))); } catch (\Exception $e) { continue; } diff --git a/src/Controller/Api/Entry/EntriesBaseApi.php b/src/Controller/Api/Entry/EntriesBaseApi.php index ccdf82369..1111086a2 100644 --- a/src/Controller/Api/Entry/EntriesBaseApi.php +++ b/src/Controller/Api/Entry/EntriesBaseApi.php @@ -34,9 +34,9 @@ public function setCommentsFactory(EntryCommentFactory $commentsFactory) /** * Serialize a single entry to JSON. */ - protected function serializeEntry(EntryDto|Entry $dto) + protected function serializeEntry(EntryDto|Entry $dto, array $tags) { - $response = $this->entryFactory->createResponseDto($dto); + $response = $this->entryFactory->createResponseDto($dto, $tags); if ($this->isGranted('ROLE_OAUTH2_ENTRY:VOTE')) { $response->isFavourited = $dto instanceof EntryDto ? $dto->isFavourited : $dto->isFavored($this->getUserOrThrow()); @@ -94,9 +94,9 @@ protected function deserializeEntryFromForm(): EntryRequestDto /** * Serialize a single comment to JSON. */ - protected function serializeComment(EntryCommentDto $comment): EntryCommentResponseDto + protected function serializeComment(EntryCommentDto $comment, array $tags): EntryCommentResponseDto { - $response = $this->entryCommentFactory->createResponseDto($comment); + $response = $this->entryCommentFactory->createResponseDto($comment, $tags); if ($this->isGranted('ROLE_OAUTH2_ENTRY_COMMENT:VOTE')) { $response->isFavourited = $comment->isFavourited; diff --git a/src/Controller/Api/Entry/EntriesFavouriteApi.php b/src/Controller/Api/Entry/EntriesFavouriteApi.php index f63bc1fdd..e050fb504 100644 --- a/src/Controller/Api/Entry/EntriesFavouriteApi.php +++ b/src/Controller/Api/Entry/EntriesFavouriteApi.php @@ -69,7 +69,7 @@ public function __invoke( $manager->toggle($this->getUserOrThrow(), $entry); return new JsonResponse( - $this->serializeEntry($factory->createDto($entry)), + $this->serializeEntry($factory->createDto($entry), $this->tagLinkRepository->getTagsOfEntry($entry)), headers: $headers ); } diff --git a/src/Controller/Api/Entry/EntriesRetrieveApi.php b/src/Controller/Api/Entry/EntriesRetrieveApi.php index 8d0685f87..0201cc63f 100644 --- a/src/Controller/Api/Entry/EntriesRetrieveApi.php +++ b/src/Controller/Api/Entry/EntriesRetrieveApi.php @@ -82,7 +82,7 @@ public function __invoke( $dto = $factory->createDto($entry); return new JsonResponse( - $this->serializeEntry($dto), + $this->serializeEntry($dto, $this->tagLinkRepository->getTagsOfEntry($entry)), headers: $headers ); } @@ -196,7 +196,7 @@ public function collection( try { \assert($value instanceof Entry); $this->handlePrivateContent($value); - array_push($dtos, $this->serializeEntry($factory->createDto($value))); + array_push($dtos, $this->serializeEntry($factory->createDto($value), $this->tagLinkRepository->getTagsOfEntry($value))); } catch (AccessDeniedException $e) { continue; } @@ -302,7 +302,7 @@ public function subscribed( try { \assert($value instanceof Entry); $this->handlePrivateContent($value); - array_push($dtos, $this->serializeEntry($factory->createDto($value))); + array_push($dtos, $this->serializeEntry($factory->createDto($value), $this->tagLinkRepository->getTagsOfEntry($value))); } catch (\Exception $e) { continue; } @@ -408,7 +408,7 @@ public function moderated( try { \assert($value instanceof Entry); $this->handlePrivateContent($value); - array_push($dtos, $this->serializeEntry($factory->createDto($value))); + array_push($dtos, $this->serializeEntry($factory->createDto($value), $this->tagLinkRepository->getTagsOfEntry($value))); } catch (\Exception $e) { continue; } @@ -514,7 +514,7 @@ public function favourited( try { \assert($value instanceof Entry); $this->handlePrivateContent($value); - array_push($dtos, $this->serializeEntry($factory->createDto($value))); + array_push($dtos, $this->serializeEntry($factory->createDto($value), $this->tagLinkRepository->getTagsOfEntry($value))); } catch (\Exception $e) { continue; } diff --git a/src/Controller/Api/Entry/EntriesUpdateApi.php b/src/Controller/Api/Entry/EntriesUpdateApi.php index e112e16c0..51b6d0a7d 100644 --- a/src/Controller/Api/Entry/EntriesUpdateApi.php +++ b/src/Controller/Api/Entry/EntriesUpdateApi.php @@ -96,7 +96,7 @@ public function __invoke( $entry = $manager->edit($entry, $dto); return new JsonResponse( - $this->serializeEntry($entry), + $this->serializeEntry($entry, $this->tagLinkRepository->getTagsOfEntry($entry)), headers: $headers ); } diff --git a/src/Controller/Api/Entry/EntriesVoteApi.php b/src/Controller/Api/Entry/EntriesVoteApi.php index 158e2cbb0..b88cba96c 100644 --- a/src/Controller/Api/Entry/EntriesVoteApi.php +++ b/src/Controller/Api/Entry/EntriesVoteApi.php @@ -90,7 +90,7 @@ public function __invoke( $manager->vote($choice, $entry, $this->getUserOrThrow(), rateLimit: false); return new JsonResponse( - $this->serializeEntry($factory->createDto($entry)), + $this->serializeEntry($factory->createDto($entry), $this->tagLinkRepository->getTagsOfEntry($entry)), headers: $headers ); } diff --git a/src/Controller/Api/Entry/MagazineEntriesRetrieveApi.php b/src/Controller/Api/Entry/MagazineEntriesRetrieveApi.php index 0107e8675..2ee8fbe4c 100644 --- a/src/Controller/Api/Entry/MagazineEntriesRetrieveApi.php +++ b/src/Controller/Api/Entry/MagazineEntriesRetrieveApi.php @@ -151,7 +151,7 @@ public function __invoke( foreach ($entries->getCurrentPageResults() as $value) { try { \assert($value instanceof Entry); - array_push($dtos, $this->serializeEntry($factory->createDto($value))); + array_push($dtos, $this->serializeEntry($factory->createDto($value), $this->tagLinkRepository->getTagsOfEntry($value))); } catch (\Exception $e) { continue; } diff --git a/src/Controller/Api/Entry/MagazineEntryCreateApi.php b/src/Controller/Api/Entry/MagazineEntryCreateApi.php index ab255f570..9c6d08e3f 100644 --- a/src/Controller/Api/Entry/MagazineEntryCreateApi.php +++ b/src/Controller/Api/Entry/MagazineEntryCreateApi.php @@ -101,7 +101,7 @@ public function article( ]); return new JsonResponse( - $this->serializeEntry($manager->createDto($entry)), + $this->serializeEntry($manager->createDto($entry), $this->tagLinkRepository->getTagsOfEntry($entry)), status: 201, headers: $headers ); @@ -179,7 +179,7 @@ public function link( ]); return new JsonResponse( - $this->serializeEntry($manager->createDto($entry)), + $this->serializeEntry($manager->createDto($entry), $this->tagLinkRepository->getTagsOfEntry($entry)), status: 201, headers: $headers ); @@ -252,7 +252,7 @@ public function video( ]); return new JsonResponse( - $this->serializeEntry($manager->createDto($entry)), + $this->serializeEntry($manager->createDto($entry), $this->tagLinkRepository->getTagsOfEntry($entry)), status: 201, headers: $headers ); @@ -363,7 +363,7 @@ public function uploadImage( $entry = $manager->create($dto, $this->getUserOrThrow()); return new JsonResponse( - $this->serializeEntry($manager->createDto($entry)), + $this->serializeEntry($manager->createDto($entry), $this->tagLinkRepository->getTagsOfEntry($entry)), status: 201, headers: $headers ); diff --git a/src/Controller/Api/Entry/Moderate/EntriesPinApi.php b/src/Controller/Api/Entry/Moderate/EntriesPinApi.php index b2e135b20..d74dce7a4 100644 --- a/src/Controller/Api/Entry/Moderate/EntriesPinApi.php +++ b/src/Controller/Api/Entry/Moderate/EntriesPinApi.php @@ -76,7 +76,7 @@ public function __invoke( $manager->pin($entry); return new JsonResponse( - $this->serializeEntry($factory->createDto($entry)), + $this->serializeEntry($factory->createDto($entry), $this->tagLinkRepository->getTagsOfEntry($entry)), headers: $headers ); } diff --git a/src/Controller/Api/Entry/Moderate/EntriesSetAdultApi.php b/src/Controller/Api/Entry/Moderate/EntriesSetAdultApi.php index e55e6c84d..bd909003d 100644 --- a/src/Controller/Api/Entry/Moderate/EntriesSetAdultApi.php +++ b/src/Controller/Api/Entry/Moderate/EntriesSetAdultApi.php @@ -86,7 +86,7 @@ public function __invoke( $manager->flush(); return new JsonResponse( - $this->serializeEntry($factory->createDto($entry)), + $this->serializeEntry($factory->createDto($entry), $this->tagLinkRepository->getTagsOfEntry($entry)), headers: $headers ); } diff --git a/src/Controller/Api/Entry/Moderate/EntriesSetLanguageApi.php b/src/Controller/Api/Entry/Moderate/EntriesSetLanguageApi.php index db734921a..aa410eca8 100644 --- a/src/Controller/Api/Entry/Moderate/EntriesSetLanguageApi.php +++ b/src/Controller/Api/Entry/Moderate/EntriesSetLanguageApi.php @@ -100,7 +100,7 @@ public function __invoke( $manager->flush(); return new JsonResponse( - $this->serializeEntry($factory->createDto($entry)), + $this->serializeEntry($factory->createDto($entry), $this->tagLinkRepository->getTagsOfEntry($entry)), headers: $headers ); } diff --git a/src/Controller/Api/Entry/Moderate/EntriesTrashApi.php b/src/Controller/Api/Entry/Moderate/EntriesTrashApi.php index 8ed8b7449..c24f0ae0f 100644 --- a/src/Controller/Api/Entry/Moderate/EntriesTrashApi.php +++ b/src/Controller/Api/Entry/Moderate/EntriesTrashApi.php @@ -79,7 +79,7 @@ public function trash( $manager->trash($moderator, $entry); - $response = $this->serializeEntry($factory->createDto($entry)); + $response = $this->serializeEntry($factory->createDto($entry), $this->tagLinkRepository->getTagsOfEntry($entry)); // Force response to have all fields visible $visibility = $response->visibility; @@ -161,7 +161,7 @@ public function restore( } return new JsonResponse( - $this->serializeEntry($factory->createDto($entry)), + $this->serializeEntry($factory->createDto($entry), $this->tagLinkRepository->getTagsOfEntry($entry)), headers: $headers ); } diff --git a/src/Controller/Api/Entry/UserEntriesRetrieveApi.php b/src/Controller/Api/Entry/UserEntriesRetrieveApi.php index ad66d95bc..dffdf81ad 100644 --- a/src/Controller/Api/Entry/UserEntriesRetrieveApi.php +++ b/src/Controller/Api/Entry/UserEntriesRetrieveApi.php @@ -151,7 +151,7 @@ public function __invoke( foreach ($entries->getCurrentPageResults() as $value) { try { \assert($value instanceof Entry); - array_push($dtos, $this->serializeEntry($factory->createDto($value))); + array_push($dtos, $this->serializeEntry($factory->createDto($value), $this->tagLinkRepository->getTagsOfEntry($value))); } catch (\Exception $e) { continue; } diff --git a/src/Controller/Api/Notification/NotificationBaseApi.php b/src/Controller/Api/Notification/NotificationBaseApi.php index 7cc734475..c176e7b89 100644 --- a/src/Controller/Api/Notification/NotificationBaseApi.php +++ b/src/Controller/Api/Notification/NotificationBaseApi.php @@ -51,7 +51,7 @@ protected function serializeNotification(Notification $dto) * @var \App\Entity\EntryMentionedNotification $dto */ $entry = $dto->getSubject(); - $toReturn['subject'] = $this->entryFactory->createResponseDto($entry); + $toReturn['subject'] = $this->entryFactory->createResponseDto($entry, $this->tagLinkRepository->getTagsOfEntry($entry)); break; case 'entry_comment_created_notification': case 'entry_comment_edited_notification': @@ -62,7 +62,7 @@ protected function serializeNotification(Notification $dto) * @var \App\Entity\EntryCommentMentionedNotification $dto */ $comment = $dto->getSubject(); - $toReturn['subject'] = $this->entryCommentFactory->createResponseDto($comment); + $toReturn['subject'] = $this->entryCommentFactory->createResponseDto($comment, $this->tagLinkRepository->getTagsOfEntryComment($comment)); break; case 'post_created_notification': case 'post_edited_notification': @@ -72,7 +72,7 @@ protected function serializeNotification(Notification $dto) * @var \App\Entity\PostMentionedNotification $dto */ $post = $dto->getSubject(); - $toReturn['subject'] = $this->postFactory->createResponseDto($post); + $toReturn['subject'] = $this->postFactory->createResponseDto($post, $this->tagLinkRepository->getTagsOfPost($post)); break; case 'post_comment_created_notification': case 'post_comment_edited_notification': @@ -83,7 +83,7 @@ protected function serializeNotification(Notification $dto) * @var \App\Entity\PostCommentMentionedNotification $dto */ $comment = $dto->getSubject(); - $toReturn['subject'] = $this->postCommentFactory->createResponseDto($comment); + $toReturn['subject'] = $this->postCommentFactory->createResponseDto($comment, $this->tagLinkRepository->getTagsOfPostComment($comment)); break; case 'message_notification': if (!$this->isGranted('ROLE_OAUTH2_USER:MESSAGE:READ')) { diff --git a/src/Controller/Api/Post/Comments/Moderate/PostCommentsSetAdultApi.php b/src/Controller/Api/Post/Comments/Moderate/PostCommentsSetAdultApi.php index 718d0d7d1..588ce7378 100644 --- a/src/Controller/Api/Post/Comments/Moderate/PostCommentsSetAdultApi.php +++ b/src/Controller/Api/Post/Comments/Moderate/PostCommentsSetAdultApi.php @@ -86,7 +86,7 @@ public function __invoke( $manager->flush(); return new JsonResponse( - $this->serializePostComment($factory->createDto($comment)), + $this->serializePostComment($factory->createDto($comment), $this->tagLinkRepository->getTagsOfPostComment($comment)), headers: $headers ); } diff --git a/src/Controller/Api/Post/Comments/Moderate/PostCommentsSetLanguageApi.php b/src/Controller/Api/Post/Comments/Moderate/PostCommentsSetLanguageApi.php index ed18fcd94..3104b2208 100644 --- a/src/Controller/Api/Post/Comments/Moderate/PostCommentsSetLanguageApi.php +++ b/src/Controller/Api/Post/Comments/Moderate/PostCommentsSetLanguageApi.php @@ -100,7 +100,7 @@ public function __invoke( $manager->flush(); return new JsonResponse( - $this->serializePostComment($factory->createDto($comment)), + $this->serializePostComment($factory->createDto($comment), $this->tagLinkRepository->getTagsOfPostComment($comment)), headers: $headers ); } diff --git a/src/Controller/Api/Post/Comments/Moderate/PostCommentsTrashApi.php b/src/Controller/Api/Post/Comments/Moderate/PostCommentsTrashApi.php index f98fd7bfd..f84f49f16 100644 --- a/src/Controller/Api/Post/Comments/Moderate/PostCommentsTrashApi.php +++ b/src/Controller/Api/Post/Comments/Moderate/PostCommentsTrashApi.php @@ -82,7 +82,7 @@ public function trash( // Force response to have all fields visible $visibility = $comment->visibility; $comment->visibility = VisibilityInterface::VISIBILITY_VISIBLE; - $response = $this->serializePostComment($factory->createDto($comment))->jsonSerialize(); + $response = $this->serializePostComment($factory->createDto($comment), $this->tagLinkRepository->getTagsOfPostComment($comment))->jsonSerialize(); $response['visibility'] = $visibility; return new JsonResponse( @@ -159,7 +159,7 @@ public function restore( } return new JsonResponse( - $this->serializePostComment($factory->createDto($comment)), + $this->serializePostComment($factory->createDto($comment), $this->tagLinkRepository->getTagsOfPostComment($comment)), headers: $headers ); } diff --git a/src/Controller/Api/Post/Comments/PostCommentsCreateApi.php b/src/Controller/Api/Post/Comments/PostCommentsCreateApi.php index 9cb52704c..5aa81c413 100644 --- a/src/Controller/Api/Post/Comments/PostCommentsCreateApi.php +++ b/src/Controller/Api/Post/Comments/PostCommentsCreateApi.php @@ -121,7 +121,7 @@ public function __invoke( $comment = $manager->create($dto, $this->getUserOrThrow(), rateLimit: false); return new JsonResponse( - $this->serializePostComment($factory->createDto($comment)), + $this->serializePostComment($factory->createDto($comment), $this->tagLinkRepository->getTagsOfPostComment($comment)), status: 201, headers: $headers ); @@ -232,7 +232,7 @@ public function uploadImage( $comment = $manager->create($dto, $this->getUserOrThrow(), rateLimit: false); return new JsonResponse( - $this->serializePostComment($factory->createDto($comment)), + $this->serializePostComment($factory->createDto($comment), $this->tagLinkRepository->getTagsOfPostComment($comment)), status: 201, headers: $headers ); diff --git a/src/Controller/Api/Post/Comments/PostCommentsFavouriteApi.php b/src/Controller/Api/Post/Comments/PostCommentsFavouriteApi.php index 5a9f58d2b..0f35c2c15 100644 --- a/src/Controller/Api/Post/Comments/PostCommentsFavouriteApi.php +++ b/src/Controller/Api/Post/Comments/PostCommentsFavouriteApi.php @@ -78,7 +78,7 @@ public function __invoke( $manager->toggle($this->getUserOrThrow(), $comment); return new JsonResponse( - $this->serializePostComment($factory->createDto($comment)), + $this->serializePostComment($factory->createDto($comment), $this->tagLinkRepository->getTagsOfPostComment($comment)), headers: $headers ); } diff --git a/src/Controller/Api/Post/Comments/PostCommentsVoteApi.php b/src/Controller/Api/Post/Comments/PostCommentsVoteApi.php index b85387a8e..ee626ba7d 100644 --- a/src/Controller/Api/Post/Comments/PostCommentsVoteApi.php +++ b/src/Controller/Api/Post/Comments/PostCommentsVoteApi.php @@ -91,7 +91,7 @@ public function __invoke( $manager->vote($choice, $comment, $this->getUserOrThrow(), rateLimit: false); return new JsonResponse( - $this->serializePostComment($factory->createDto($comment)), + $this->serializePostComment($factory->createDto($comment), $this->tagLinkRepository->getTagsOfPostComment($comment)), headers: $headers ); } diff --git a/src/Controller/Api/Post/Moderate/PostsPinApi.php b/src/Controller/Api/Post/Moderate/PostsPinApi.php index a5e0a1626..a196fd9a7 100644 --- a/src/Controller/Api/Post/Moderate/PostsPinApi.php +++ b/src/Controller/Api/Post/Moderate/PostsPinApi.php @@ -76,7 +76,7 @@ public function __invoke( $manager->pin($post); return new JsonResponse( - $this->serializePost($factory->createDto($post)), + $this->serializePost($factory->createDto($post), $this->tagLinkRepository->getTagsOfPost($post)), headers: $headers ); } diff --git a/src/Controller/Api/Post/Moderate/PostsSetAdultApi.php b/src/Controller/Api/Post/Moderate/PostsSetAdultApi.php index 61742c279..c9d85b5fd 100644 --- a/src/Controller/Api/Post/Moderate/PostsSetAdultApi.php +++ b/src/Controller/Api/Post/Moderate/PostsSetAdultApi.php @@ -86,7 +86,7 @@ public function __invoke( $manager->flush(); return new JsonResponse( - $this->serializePost($factory->createDto($post)), + $this->serializePost($factory->createDto($post), $this->tagLinkRepository->getTagsOfPost($post)), headers: $headers ); } diff --git a/src/Controller/Api/Post/Moderate/PostsSetLanguageApi.php b/src/Controller/Api/Post/Moderate/PostsSetLanguageApi.php index 3002f0106..0976e42b9 100644 --- a/src/Controller/Api/Post/Moderate/PostsSetLanguageApi.php +++ b/src/Controller/Api/Post/Moderate/PostsSetLanguageApi.php @@ -100,7 +100,7 @@ public function __invoke( $manager->flush(); return new JsonResponse( - $this->serializePost($factory->createDto($post)), + $this->serializePost($factory->createDto($post), $this->tagLinkRepository->getTagsOfPost($post)), headers: $headers ); } diff --git a/src/Controller/Api/Post/Moderate/PostsTrashApi.php b/src/Controller/Api/Post/Moderate/PostsTrashApi.php index ea7b17b05..56faf6aff 100644 --- a/src/Controller/Api/Post/Moderate/PostsTrashApi.php +++ b/src/Controller/Api/Post/Moderate/PostsTrashApi.php @@ -82,7 +82,7 @@ public function trash( // Force response to have all fields visible $visibility = $post->visibility; $post->visibility = VisibilityInterface::VISIBILITY_VISIBLE; - $response = $this->serializePost($factory->createDto($post))->jsonSerialize(); + $response = $this->serializePost($factory->createDto($post), $this->tagLinkRepository->getTagsOfPost($post))->jsonSerialize(); $response['visibility'] = $visibility; return new JsonResponse( @@ -159,7 +159,7 @@ public function restore( } return new JsonResponse( - $this->serializePost($factory->createDto($post)), + $this->serializePost($factory->createDto($post), $this->tagLinkRepository->getTagsOfPost($post)), headers: $headers ); } diff --git a/src/Controller/Api/Post/PostsBaseApi.php b/src/Controller/Api/Post/PostsBaseApi.php index 0195f82f7..b45f94000 100644 --- a/src/Controller/Api/Post/PostsBaseApi.php +++ b/src/Controller/Api/Post/PostsBaseApi.php @@ -18,12 +18,12 @@ class PostsBaseApi extends BaseApi /** * Serialize a single post to JSON. */ - protected function serializePost(PostDto $dto): PostResponseDto + protected function serializePost(PostDto $dto, array $tags): PostResponseDto { if (null === $dto) { return []; } - $response = $this->postFactory->createResponseDto($dto); + $response = $this->postFactory->createResponseDto($dto, $tags); if ($this->isGranted('ROLE_OAUTH2_POST:VOTE')) { $response->isFavourited = $dto instanceof PostDto ? $dto->isFavourited : $dto->isFavored($this->getUserOrThrow()); @@ -74,9 +74,9 @@ protected function deserializePostFromForm(PostDto $dto = null): PostDto /** * Serialize a single comment to JSON. */ - protected function serializePostComment(PostCommentDto $comment): PostCommentResponseDto + protected function serializePostComment(PostCommentDto $comment, array $tags): PostCommentResponseDto { - $response = $this->postCommentFactory->createResponseDto($comment); + $response = $this->postCommentFactory->createResponseDto($comment, $tags); if ($this->isGranted('ROLE_OAUTH2_POST_COMMENT:VOTE')) { $response->isFavourited = $comment instanceof PostCommentDto ? $comment->isFavourited : $comment->isFavored($this->getUserOrThrow()); diff --git a/src/Controller/Api/Post/PostsCreateApi.php b/src/Controller/Api/Post/PostsCreateApi.php index c046488df..18028ed4e 100644 --- a/src/Controller/Api/Post/PostsCreateApi.php +++ b/src/Controller/Api/Post/PostsCreateApi.php @@ -105,7 +105,7 @@ public function __invoke( $post = $manager->create($dto, $this->getUserOrThrow(), rateLimit: false); return new JsonResponse( - $this->serializePost($manager->createDto($post)), + $this->serializePost($manager->createDto($post), $this->tagLinkRepository->getTagsOfPost($post)), status: 201, headers: $headers ); @@ -201,7 +201,7 @@ public function uploadImage( $post = $manager->create($dto, $this->getUserOrThrow(), rateLimit: false); return new JsonResponse( - $this->serializePost($manager->createDto($post)), + $this->serializePost($manager->createDto($post), $this->tagLinkRepository->getTagsOfPost($post)), status: 201, headers: $headers ); diff --git a/src/Controller/Api/Post/PostsFavouriteApi.php b/src/Controller/Api/Post/PostsFavouriteApi.php index 9185d1c4a..fd22dd10c 100644 --- a/src/Controller/Api/Post/PostsFavouriteApi.php +++ b/src/Controller/Api/Post/PostsFavouriteApi.php @@ -69,7 +69,7 @@ public function __invoke( $manager->toggle($this->getUserOrThrow(), $post); return new JsonResponse( - $this->serializePost($factory->createDto($post)), + $this->serializePost($factory->createDto($post), $this->tagLinkRepository->getTagsOfPost($post)), headers: $headers ); } diff --git a/src/Controller/Api/Post/PostsRetrieveApi.php b/src/Controller/Api/Post/PostsRetrieveApi.php index 338559966..cfca43d68 100644 --- a/src/Controller/Api/Post/PostsRetrieveApi.php +++ b/src/Controller/Api/Post/PostsRetrieveApi.php @@ -82,7 +82,7 @@ public function __invoke( $dto = $factory->createDto($post); return new JsonResponse( - $this->serializePost($dto), + $this->serializePost($dto, $this->tagLinkRepository->getTagsOfPost($post)), headers: $headers ); } @@ -192,7 +192,7 @@ public function collection( try { \assert($value instanceof Post); $this->handlePrivateContent($value); - array_push($dtos, $this->serializePost($factory->createDto($value))); + array_push($dtos, $this->serializePost($factory->createDto($value), $this->tagLinkRepository->getTagsOfPost($value))); } catch (\Exception $e) { continue; } @@ -312,7 +312,7 @@ public function subscribed( try { \assert($value instanceof Post); $this->handlePrivateContent($value); - array_push($dtos, $this->serializePost($factory->createDto($value))); + array_push($dtos, $this->serializePost($factory->createDto($value), $this->tagLinkRepository->getTagsOfPost($value))); } catch (\Exception $e) { continue; } @@ -418,7 +418,7 @@ public function moderated( try { \assert($value instanceof Post); $this->handlePrivateContent($value); - array_push($dtos, $this->serializePost($factory->createDto($value))); + array_push($dtos, $this->serializePost($factory->createDto($value), $this->tagLinkRepository->getTagsOfPost($value))); } catch (\Exception $e) { continue; } @@ -521,7 +521,7 @@ public function favourited( try { \assert($value instanceof Post); $this->handlePrivateContent($value); - array_push($dtos, $this->serializePost($factory->createDto($value))); + array_push($dtos, $this->serializePost($factory->createDto($value), $this->tagLinkRepository->getTagsOfPost($value))); } catch (\Exception $e) { continue; } @@ -654,7 +654,7 @@ public function byMagazine( try { \assert($value instanceof Post); $this->handlePrivateContent($value); - array_push($dtos, $this->serializePost($factory->createDto($value))); + array_push($dtos, $this->serializePost($factory->createDto($value), $this->tagLinkRepository->getTagsOfPost($value))); } catch (\Exception $e) { continue; } diff --git a/src/Controller/Api/Post/PostsUpdateApi.php b/src/Controller/Api/Post/PostsUpdateApi.php index 8dccdb9cb..8d627f83e 100644 --- a/src/Controller/Api/Post/PostsUpdateApi.php +++ b/src/Controller/Api/Post/PostsUpdateApi.php @@ -99,7 +99,7 @@ public function __invoke( $post = $manager->edit($post, $dto); return new JsonResponse( - $this->serializePost($factory->createDto($post)), + $this->serializePost($factory->createDto($post), $this->tagLinkRepository->getTagsOfPost($post)), headers: $headers ); } diff --git a/src/Controller/Api/Post/PostsVoteApi.php b/src/Controller/Api/Post/PostsVoteApi.php index 26ad13292..fd58b650c 100644 --- a/src/Controller/Api/Post/PostsVoteApi.php +++ b/src/Controller/Api/Post/PostsVoteApi.php @@ -94,7 +94,7 @@ public function __invoke( $manager->vote($choice, $post, $this->getUserOrThrow(), rateLimit: false); return new JsonResponse( - $this->serializePost($factory->createDto($post)), + $this->serializePost($factory->createDto($post), $this->tagLinkRepository->getTagsOfPost($post)), headers: $headers ); } diff --git a/src/Controller/Api/Post/UserPostsRetrieveApi.php b/src/Controller/Api/Post/UserPostsRetrieveApi.php index f235bd7e4..e70118cd3 100644 --- a/src/Controller/Api/Post/UserPostsRetrieveApi.php +++ b/src/Controller/Api/Post/UserPostsRetrieveApi.php @@ -144,7 +144,7 @@ public function __invoke( try { \assert($value instanceof Post); $this->handlePrivateContent($value); - array_push($dtos, $this->serializePost($factory->createDto($value))); + array_push($dtos, $this->serializePost($factory->createDto($value), $this->tagLinkRepository->getTagsOfPost($value))); } catch (\Exception $e) { continue; } diff --git a/src/Controller/Entry/EntryCreateController.php b/src/Controller/Entry/EntryCreateController.php index 20ca2897f..c19e6cd58 100644 --- a/src/Controller/Entry/EntryCreateController.php +++ b/src/Controller/Entry/EntryCreateController.php @@ -7,11 +7,15 @@ use App\Controller\AbstractController; use App\DTO\EntryDto; use App\Entity\Magazine; +use App\Exception\TagBannedException; use App\PageView\EntryPageView; use App\Repository\Criteria; +use App\Repository\TagLinkRepository; +use App\Repository\TagRepository; use App\Service\EntryCommentManager; use App\Service\EntryManager; use App\Service\IpResolver; +use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; @@ -24,6 +28,9 @@ class EntryCreateController extends AbstractController use EntryFormTrait; public function __construct( + private readonly LoggerInterface $logger, + private readonly TagLinkRepository $tagLinkRepository, + private readonly TagRepository $tagRepository, private readonly EntryManager $manager, private readonly EntryCommentManager $commentManager, private readonly ValidatorInterface $validator, @@ -44,6 +51,7 @@ public function __invoke(?Magazine $magazine, ?string $type, Request $request): $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { + /** @var EntryDto $dto */ $dto = $form->getData(); $dto->ip = $this->ipResolver->resolve(); @@ -52,6 +60,15 @@ public function __invoke(?Magazine $magazine, ?string $type, Request $request): } $entry = $this->manager->create($dto, $this->getUserOrThrow()); + foreach ($dto->tags ?? [] as $tag) { + $hashtag = $this->tagRepository->findOneBy(['tag' => $tag]); + if (!$hashtag) { + $hashtag = $this->tagRepository->create($tag); + } elseif ($this->tagLinkRepository->entryHasTag($entry, $hashtag)) { + continue; + } + $this->tagLinkRepository->addTagToEntry($entry, $hashtag); + } $this->addFlash('success', 'flash_thread_new_success'); @@ -70,9 +87,24 @@ public function __invoke(?Magazine $magazine, ?string $type, Request $request): ], new Response(null, $form->isSubmitted() && !$form->isValid() ? 422 : 200) ); + } catch (TagBannedException $e) { + // Show an error to the user + $this->addFlash('error', 'flash_thread_tag_banned_error'); + $this->logger->error($e); + + return $this->render( + $this->getTemplateName((new EntryPageView(1))->resolveType($type)), + [ + 'magazine' => $magazine, + 'user' => $user, + 'form' => $form->createView(), + ], + new Response(null, 422) + ); } catch (\Exception $e) { // Show an error to the user $this->addFlash('error', 'flash_thread_new_error'); + $this->logger->error($e); return $this->render( $this->getTemplateName((new EntryPageView(1))->resolveType($type)), diff --git a/src/Controller/Post/PostCreateController.php b/src/Controller/Post/PostCreateController.php index 33e8a072f..edca962c9 100644 --- a/src/Controller/Post/PostCreateController.php +++ b/src/Controller/Post/PostCreateController.php @@ -9,6 +9,7 @@ use App\Repository\Criteria; use App\Service\IpResolver; use App\Service\PostManager; +use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; @@ -17,6 +18,7 @@ class PostCreateController extends AbstractController { public function __construct( + private readonly LoggerInterface $logger, private readonly PostManager $manager, private readonly IpResolver $ipResolver ) { @@ -26,7 +28,7 @@ public function __construct( public function __invoke(Request $request): Response { $form = $this->createForm(PostType::class); - + $user = $this->getUserOrThrow(); try { // Could thrown an error on event handlers (eg. onPostSubmit if a user upload an incorrect image) $form->handleRequest($request); @@ -39,7 +41,7 @@ public function __invoke(Request $request): Response throw new AccessDeniedHttpException(); } - $this->manager->create($dto, $this->getUserOrThrow()); + $this->manager->create($dto, $user); $this->addFlash('success', 'flash_post_new_success'); @@ -52,6 +54,7 @@ public function __invoke(Request $request): Response ); } } catch (\Exception $e) { + $this->logger->error('{user} tried to create a post, but an exception occurred: {ex} - {message}', ['user' => $user->username, 'ex' => \get_class($e), 'message' => $e->getMessage(), 'stacktrace' => $e->getTrace()]); // Show an error to the user $this->addFlash('error', 'flash_post_new_error'); } diff --git a/src/Controller/Tag/TagBanController.php b/src/Controller/Tag/TagBanController.php new file mode 100644 index 000000000..b6cad5814 --- /dev/null +++ b/src/Controller/Tag/TagBanController.php @@ -0,0 +1,50 @@ +validateCsrf('ban', $request->request->get('token')); + + $hashtag = $this->tagRepository->findOneBy(['tag' => $name]); + if (null === $hashtag) { + $hashtag = $this->tagRepository->create($name); + } + $this->tagManager->ban($hashtag); + + return $this->redirectToRoute('tag_overview', ['name' => $hashtag->tag]); + } + + #[IsGranted('ROLE_ADMIN')] + public function unban(string $name, Request $request): Response + { + $this->validateCsrf('ban', $request->request->get('token')); + + $hashtag = $this->tagRepository->findOneBy(['tag' => $name]); + if ($hashtag) { + $this->tagManager->unban($hashtag); + + return $this->redirectToRoute('tag_overview', ['name' => $hashtag->tag]); + } else { + throw $this->createNotFoundException(); + } + } +} diff --git a/src/Controller/Tag/TagCommentFrontController.php b/src/Controller/Tag/TagCommentFrontController.php index aee8be617..dceed1b09 100644 --- a/src/Controller/Tag/TagCommentFrontController.php +++ b/src/Controller/Tag/TagCommentFrontController.php @@ -7,7 +7,8 @@ use App\Controller\AbstractController; use App\PageView\EntryCommentPageView; use App\Repository\EntryCommentRepository; -use App\Service\TagManager; +use App\Repository\TagRepository; +use App\Service\TagExtractor; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -15,7 +16,8 @@ class TagCommentFrontController extends AbstractController { public function __construct( private readonly EntryCommentRepository $repository, - private readonly TagManager $tagManager + private readonly TagRepository $tagRepository, + private readonly TagExtractor $tagManager ) { } @@ -29,6 +31,7 @@ public function __invoke(string $name, ?string $sortBy, ?string $time, Request $ $params = [ 'comments' => $this->repository->findByCriteria($criteria), 'tag' => $name, + 'counts' => $this->tagRepository->getCounts($name), ]; return $this->render( diff --git a/src/Controller/Tag/TagEntryFrontController.php b/src/Controller/Tag/TagEntryFrontController.php index caf0a1784..1eba97475 100644 --- a/src/Controller/Tag/TagEntryFrontController.php +++ b/src/Controller/Tag/TagEntryFrontController.php @@ -8,7 +8,8 @@ use App\PageView\EntryPageView; use App\Repository\Criteria; use App\Repository\EntryRepository; -use App\Service\TagManager; +use App\Repository\TagRepository; +use App\Service\TagExtractor; use Pagerfanta\PagerfantaInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -17,7 +18,8 @@ class TagEntryFrontController extends AbstractController { public function __construct( private readonly EntryRepository $entryRepository, - private readonly TagManager $tagManager + private readonly TagRepository $tagRepository, + private readonly TagExtractor $tagManager ) { } @@ -36,6 +38,7 @@ public function __invoke(?string $name, ?string $sortBy, ?string $time, ?string [ 'tag' => $name, 'entries' => $listing, + 'counts' => $this->tagRepository->getCounts($name), ] ); } diff --git a/src/Controller/Tag/TagOverviewController.php b/src/Controller/Tag/TagOverviewController.php index aa6e9167d..e37563070 100644 --- a/src/Controller/Tag/TagOverviewController.php +++ b/src/Controller/Tag/TagOverviewController.php @@ -7,14 +7,15 @@ use App\Controller\AbstractController; use App\Repository\TagRepository; use App\Service\SubjectOverviewManager; -use App\Service\TagManager; +use App\Service\TagExtractor; +use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; class TagOverviewController extends AbstractController { public function __construct( - private readonly TagManager $tagManager, + private readonly TagExtractor $tagManager, private readonly TagRepository $tagRepository, private readonly SubjectOverviewManager $overviewManager ) { @@ -27,13 +28,17 @@ public function __invoke(string $name, Request $request): Response $this->tagManager->transliterate(strtolower($name)) ); - return $this->render( - 'tag/overview.html.twig', - [ - 'tag' => $name, - 'results' => $this->overviewManager->buildList($activity), - 'pagination' => $activity, - ] - ); + $params = [ + 'tag' => $name, + 'results' => $this->overviewManager->buildList($activity), + 'pagination' => $activity, + 'counts' => $this->tagRepository->getCounts($name), + ]; + + if ($request->isXmlHttpRequest()) { + return new JsonResponse(['html' => $this->renderView('tag/_list.html.twig', $params)]); + } + + return $this->render('tag/overview.html.twig', $params); } } diff --git a/src/Controller/Tag/TagPeopleFrontController.php b/src/Controller/Tag/TagPeopleFrontController.php index 008fa89b4..7ae50e209 100644 --- a/src/Controller/Tag/TagPeopleFrontController.php +++ b/src/Controller/Tag/TagPeopleFrontController.php @@ -7,6 +7,7 @@ use App\Controller\AbstractController; use App\Repository\MagazineRepository; use App\Repository\PostRepository; +use App\Repository\TagRepository; use App\Service\PeopleManager; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -15,6 +16,7 @@ class TagPeopleFrontController extends AbstractController { public function __construct( private readonly PeopleManager $manager, + private readonly TagRepository $tagRepository, private readonly MagazineRepository $magazineRepository ) { } @@ -35,6 +37,7 @@ public function __invoke( ), 'local' => $this->manager->general(), 'federated' => $this->manager->general(true), + 'counts' => $this->tagRepository->getCounts($name), ] ); } diff --git a/src/Controller/Tag/TagPostFrontController.php b/src/Controller/Tag/TagPostFrontController.php index e45e3e67a..39687f10d 100644 --- a/src/Controller/Tag/TagPostFrontController.php +++ b/src/Controller/Tag/TagPostFrontController.php @@ -7,14 +7,17 @@ use App\Controller\AbstractController; use App\PageView\PostPageView; use App\Repository\PostRepository; -use App\Service\TagManager; +use App\Repository\TagRepository; +use App\Service\TagExtractor; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; class TagPostFrontController extends AbstractController { - public function __construct(private readonly TagManager $tagManager) - { + public function __construct( + private readonly TagExtractor $tagManager, + private readonly TagRepository $tagRepository, + ) { } public function __invoke( @@ -36,6 +39,7 @@ public function __invoke( [ 'tag' => $name, 'posts' => $posts, + 'counts' => $this->tagRepository->getCounts($name), ] ); } diff --git a/src/DTO/EntryCommentDto.php b/src/DTO/EntryCommentDto.php index 57aaca147..787fec59d 100644 --- a/src/DTO/EntryCommentDto.php +++ b/src/DTO/EntryCommentDto.php @@ -39,7 +39,6 @@ class EntryCommentDto public ?string $ip = null; public ?string $apId = null; public ?array $mentions = null; - public ?array $tags = null; public ?\DateTimeImmutable $createdAt = null; public ?\DateTimeImmutable $editedAt = null; public ?\DateTime $lastActive = null; diff --git a/src/DTO/EntryRequestDto.php b/src/DTO/EntryRequestDto.php index 304487b8d..3068fbd45 100644 --- a/src/DTO/EntryRequestDto.php +++ b/src/DTO/EntryRequestDto.php @@ -65,7 +65,6 @@ public function mergeIntoDto(EntryDto $dto): EntryDto { $dto->title = $this->title ?? $dto->title; $dto->body = $this->body ?? $dto->body; - $dto->tags = $this->tags ?? $dto->tags; // TODO: Support for badges when they're implemented // $dto->badges = $this->badges ?? $dto->badges; $dto->isAdult = $this->isAdult ?? $dto->isAdult; diff --git a/src/DTO/MagazineLogResponseDto.php b/src/DTO/MagazineLogResponseDto.php index eca920d64..466116ccb 100644 --- a/src/DTO/MagazineLogResponseDto.php +++ b/src/DTO/MagazineLogResponseDto.php @@ -12,6 +12,7 @@ use App\Factory\EntryFactory; use App\Factory\PostCommentFactory; use App\Factory\PostFactory; +use App\Repository\TagLinkRepository; use Nelmio\ApiDocBundle\Annotation\Model; use OpenApi\Attributes as OA; use Symfony\Component\Serializer\Annotation\Ignore; @@ -75,27 +76,28 @@ public function setSubject( EntryCommentFactory $entryCommentFactory, PostFactory $postFactory, PostCommentFactory $postCommentFactory, + TagLinkRepository $tagLinkRepository, ): void { switch ($this->type) { case 'log_entry_deleted': case 'log_entry_restored': \assert($subject instanceof Entry); - $this->subject = $entryFactory->createResponseDto($subject); + $this->subject = $entryFactory->createResponseDto($subject, tags: $tagLinkRepository->getTagsOfEntry($subject)); break; case 'log_entry_comment_deleted': case 'log_entry_comment_restored': \assert($subject instanceof EntryComment); - $this->subject = $entryCommentFactory->createResponseDto($subject); + $this->subject = $entryCommentFactory->createResponseDto($subject, tags: $tagLinkRepository->getTagsOfEntryComment($subject)); break; case 'log_post_deleted': case 'log_post_restored': \assert($subject instanceof Post); - $this->subject = $postFactory->createResponseDto($subject); + $this->subject = $postFactory->createResponseDto($subject, tags: $tagLinkRepository->getTagsOfPost($subject)); break; case 'log_post_comment_deleted': case 'log_post_comment_restored': \assert($subject instanceof PostComment); - $this->subject = $postCommentFactory->createResponseDto($subject); + $this->subject = $postCommentFactory->createResponseDto($subject, tags: $tagLinkRepository->getTagsOfPostComment($subject)); break; default: break; diff --git a/src/DTO/PostCommentDto.php b/src/DTO/PostCommentDto.php index ed76975f7..9061e4496 100644 --- a/src/DTO/PostCommentDto.php +++ b/src/DTO/PostCommentDto.php @@ -39,7 +39,6 @@ class PostCommentDto implements ContentVisibilityInterface public ?string $ip = null; public ?string $apId = null; public ?array $mentions = null; - public ?array $tags = null; public ?\DateTimeImmutable $createdAt = null; public ?\DateTimeImmutable $editedAt = null; public ?\DateTime $lastActive = null; diff --git a/src/DTO/PostDto.php b/src/DTO/PostDto.php index bc7cecb5d..439541507 100644 --- a/src/DTO/PostDto.php +++ b/src/DTO/PostDto.php @@ -36,7 +36,6 @@ class PostDto implements ContentVisibilityInterface public ?int $userVote = null; public ?string $visibility = VisibilityInterface::VISIBILITY_VISIBLE; public ?string $ip = null; - public ?array $tags = null; public ?array $mentions = null; public ?string $apId = null; public ?\DateTimeImmutable $createdAt = null; diff --git a/src/DoctrineExtensions/DBAL/Types/Citext.php b/src/DoctrineExtensions/DBAL/Types/Citext.php new file mode 100644 index 000000000..d45468563 --- /dev/null +++ b/src/DoctrineExtensions/DBAL/Types/Citext.php @@ -0,0 +1,26 @@ +getDoctrineTypeMapping(self::CITEXT); + } +} diff --git a/src/Entity/Contracts/TagInterface.php b/src/Entity/Contracts/TagInterface.php deleted file mode 100644 index e5a8c9595..000000000 --- a/src/Entity/Contracts/TagInterface.php +++ /dev/null @@ -1,10 +0,0 @@ - true])] - public ?array $tags = null; - #[Column(type: 'json', nullable: true, options: ['jsonb' => true])] public ?array $mentions = null; #[OneToMany(mappedBy: 'entry', targetEntity: EntryComment::class, cascade: ['persist', 'remove'], fetch: 'EXTRA_LAZY', orphanRemoval: true)] public Collection $comments; @@ -128,6 +125,8 @@ class Entry implements VotableInterface, CommentInterface, DomainInterface, Visi public Collection $favourites; #[OneToMany(mappedBy: 'entry', targetEntity: EntryCreatedNotification::class, cascade: ['persist', 'remove'], fetch: 'EXTRA_LAZY', orphanRemoval: true)] public Collection $notifications; + #[OneToMany(mappedBy: 'entry', targetEntity: HashtagLink::class, cascade: ['persist', 'remove'], fetch: 'EXTRA_LAZY', orphanRemoval: true)] + public Collection $hashtags; #[OneToMany(mappedBy: 'entry', targetEntity: EntryBadge::class, cascade: ['remove', 'persist'], fetch: 'EXTRA_LAZY', orphanRemoval: true)] public Collection $badges; public array $children = []; @@ -395,11 +394,6 @@ public function getDescription(): string return ''; // @todo get first author comment } - public function getTags(): array - { - return array_values($this->tags ?? []); - } - public function __sleep() { return []; diff --git a/src/Entity/EntryComment.php b/src/Entity/EntryComment.php index 41311e04b..13c33d0f6 100644 --- a/src/Entity/EntryComment.php +++ b/src/Entity/EntryComment.php @@ -8,7 +8,6 @@ use App\Entity\Contracts\ContentInterface; use App\Entity\Contracts\FavouriteInterface; use App\Entity\Contracts\ReportInterface; -use App\Entity\Contracts\TagInterface; use App\Entity\Contracts\VisibilityInterface; use App\Entity\Contracts\VotableInterface; use App\Entity\Traits\ActivityPubActivityTrait; @@ -36,7 +35,7 @@ #[Index(columns: ['last_active'], name: 'entry_comment_last_active_at_idx')] #[Index(columns: ['created_at'], name: 'entry_comment_created_at_idx')] #[Index(columns: ['body_ts'], name: 'entry_comment_body_ts_idx')] -class EntryComment implements VotableInterface, VisibilityInterface, ReportInterface, FavouriteInterface, TagInterface, ActivityPubActivityInterface +class EntryComment implements VotableInterface, VisibilityInterface, ReportInterface, FavouriteInterface, ActivityPubActivityInterface { use VotableTrait; use VisibilityTrait; @@ -76,8 +75,6 @@ class EntryComment implements VotableInterface, VisibilityInterface, ReportInter public ?\DateTime $lastActive = null; #[Column(type: 'string', nullable: true)] public ?string $ip = null; - #[Column(type: 'json', nullable: true, options: ['jsonb' => true])] - public ?array $tags = null; #[Column(type: 'json', nullable: true)] public ?array $mentions = null; #[OneToMany(mappedBy: 'parent', targetEntity: EntryComment::class, cascade: ['persist', 'remove'], orphanRemoval: true)] @@ -94,6 +91,8 @@ class EntryComment implements VotableInterface, VisibilityInterface, ReportInter public Collection $favourites; #[OneToMany(mappedBy: 'entryComment', targetEntity: EntryCommentCreatedNotification::class, cascade: ['remove'], fetch: 'EXTRA_LAZY', orphanRemoval: true)] public Collection $notifications; + #[OneToMany(mappedBy: 'entryComment', targetEntity: HashtagLink::class, cascade: ['persist', 'remove'], fetch: 'EXTRA_LAZY', orphanRemoval: true)] + public Collection $hashtags; #[Id] #[GeneratedValue] #[Column(type: 'integer')] @@ -235,11 +234,6 @@ public function isFavored(User $user): bool return $this->favourites->matching($criteria)->count() > 0; } - public function getTags(): array - { - return array_values($this->tags ?? []); - } - public function __sleep() { return []; diff --git a/src/Entity/Hashtag.php b/src/Entity/Hashtag.php new file mode 100644 index 000000000..64b4756c4 --- /dev/null +++ b/src/Entity/Hashtag.php @@ -0,0 +1,30 @@ + false])] + public bool $banned = false; + + #[OneToMany(mappedBy: 'hashtag', targetEntity: HashtagLink::class, fetch: 'EXTRA_LAZY', orphanRemoval: true)] + public Collection $linkedPosts; +} diff --git a/src/Entity/HashtagLink.php b/src/Entity/HashtagLink.php new file mode 100644 index 000000000..2df61a73a --- /dev/null +++ b/src/Entity/HashtagLink.php @@ -0,0 +1,41 @@ + true])] - public ?array $tags = null; - #[Column(type: 'json', nullable: true, options: ['jsonb' => true])] public ?array $mentions = null; #[OneToMany(mappedBy: 'post', targetEntity: PostComment::class, cascade: ['persist', 'remove'], orphanRemoval: true)] public Collection $comments; @@ -96,6 +93,8 @@ class Post implements VotableInterface, CommentInterface, VisibilityInterface, R public Collection $favourites; #[OneToMany(mappedBy: 'post', targetEntity: PostCreatedNotification::class, cascade: ['persist', 'remove'], fetch: 'EXTRA_LAZY', orphanRemoval: true)] public Collection $notifications; + #[OneToMany(mappedBy: 'post', targetEntity: HashtagLink::class, cascade: ['persist', 'remove'], fetch: 'EXTRA_LAZY', orphanRemoval: true)] + public Collection $hashtags; public array $children = []; #[Id] #[GeneratedValue] @@ -352,11 +351,6 @@ public function isAdult(): bool return $this->isAdult || $this->magazine->isAdult; } - public function getTags(): array - { - return array_values($this->tags ?? []); - } - public function __sleep() { return []; diff --git a/src/Entity/PostComment.php b/src/Entity/PostComment.php index 05d078044..bd3e92a6a 100644 --- a/src/Entity/PostComment.php +++ b/src/Entity/PostComment.php @@ -8,7 +8,6 @@ use App\Entity\Contracts\ContentInterface; use App\Entity\Contracts\FavouriteInterface; use App\Entity\Contracts\ReportInterface; -use App\Entity\Contracts\TagInterface; use App\Entity\Contracts\VisibilityInterface; use App\Entity\Contracts\VotableInterface; use App\Entity\Traits\ActivityPubActivityTrait; @@ -36,7 +35,7 @@ #[Index(columns: ['last_active'], name: 'post_comment_last_active_at_idx')] #[Index(columns: ['created_at'], name: 'post_comment_created_at_idx')] #[Index(columns: ['body_ts'], name: 'post_comment_body_ts_idx')] -class PostComment implements VotableInterface, VisibilityInterface, ReportInterface, FavouriteInterface, TagInterface, ActivityPubActivityInterface +class PostComment implements VotableInterface, VisibilityInterface, ReportInterface, FavouriteInterface, ActivityPubActivityInterface { use VotableTrait; use VisibilityTrait; @@ -75,8 +74,6 @@ class PostComment implements VotableInterface, VisibilityInterface, ReportInterf #[Column(type: 'string', nullable: true)] public ?string $ip = null; #[Column(type: 'json', nullable: true, options: ['jsonb' => true])] - public ?array $tags = null; - #[Column(type: 'json', nullable: true, options: ['jsonb' => true])] public ?array $mentions = null; #[Column(type: 'boolean', nullable: false)] public bool $isAdult = false; @@ -96,6 +93,8 @@ class PostComment implements VotableInterface, VisibilityInterface, ReportInterf public Collection $favourites; #[OneToMany(mappedBy: 'postComment', targetEntity: PostCommentCreatedNotification::class, cascade: ['remove'], fetch: 'EXTRA_LAZY', orphanRemoval: true)] public Collection $notifications; + #[OneToMany(mappedBy: 'postComment', targetEntity: HashtagLink::class, cascade: ['persist', 'remove'], fetch: 'EXTRA_LAZY', orphanRemoval: true)] + public Collection $hashtags; #[Id] #[GeneratedValue] #[Column(type: 'integer')] diff --git a/src/EventSubscriber/Post/PostCreateSubscriber.php b/src/EventSubscriber/Post/PostCreateSubscriber.php index d940a8bae..5d4ee2a38 100644 --- a/src/EventSubscriber/Post/PostCreateSubscriber.php +++ b/src/EventSubscriber/Post/PostCreateSubscriber.php @@ -11,6 +11,7 @@ use App\Message\Notification\PostCreatedNotificationMessage; use App\Repository\MagazineRepository; use App\Repository\PostRepository; +use App\Repository\TagLinkRepository; use App\Service\PostManager; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -21,6 +22,7 @@ class PostCreateSubscriber implements EventSubscriberInterface public function __construct( private readonly MessageBusInterface $bus, private readonly MagazineRepository $magazineRepository, + private readonly TagLinkRepository $tagLinkRepository, private readonly PostRepository $postRepository, private readonly PostManager $postManager, private readonly EntityManagerInterface $entityManager @@ -54,11 +56,9 @@ public function onPostCreated(PostCreatedEvent $event): void private function handleMagazine(Post $post): void { - if (!$post->tags) { - return; - } + $tags = $this->tagLinkRepository->getTagsOfPost($post); - foreach ($post->tags as $tag) { + foreach ($tags as $tag) { if ($magazine = $this->magazineRepository->findOneByName($tag)) { $this->postManager->changeMagazine($post, $magazine); break; diff --git a/src/Exception/TagBannedException.php b/src/Exception/TagBannedException.php new file mode 100644 index 000000000..36ed71d06 --- /dev/null +++ b/src/Exception/TagBannedException.php @@ -0,0 +1,9 @@ + $this->pageFactory->create($activity, $context), - $activity instanceof EntryComment => $this->entryNoteFactory->create($activity, $context), - $activity instanceof Post => $this->postNoteFactory->create($activity, $context), - $activity instanceof PostComment => $this->postCommentNoteFactory->create($activity, $context), + $activity instanceof Entry => $this->pageFactory->create($activity, $this->tagLinkRepository->getTagsOfEntry($activity), $context), + $activity instanceof EntryComment => $this->entryNoteFactory->create($activity, $this->tagLinkRepository->getTagsOfEntryComment($activity), $context), + $activity instanceof Post => $this->postNoteFactory->create($activity, $this->tagLinkRepository->getTagsOfPost($activity), $context), + $activity instanceof PostComment => $this->postCommentNoteFactory->create($activity, $this->tagLinkRepository->getTagsOfPostComment($activity), $context), default => throw new \LogicException(), }; } diff --git a/src/Factory/ActivityPub/EntryCommentNoteFactory.php b/src/Factory/ActivityPub/EntryCommentNoteFactory.php index 258c568cc..3db222f9f 100644 --- a/src/Factory/ActivityPub/EntryCommentNoteFactory.php +++ b/src/Factory/ActivityPub/EntryCommentNoteFactory.php @@ -34,13 +34,12 @@ public function __construct( ) { } - public function create(EntryComment $comment, bool $context = false): array + public function create(EntryComment $comment, array $tags, bool $context = false): array { if ($context) { $note['@context'] = $this->contextProvider->referencedContexts(); } - $tags = $comment->tags ?? []; if ('random' !== $comment->magazine->name && !$comment->magazine->apId) { // @todo $tags[] = $comment->magazine->name; } diff --git a/src/Factory/ActivityPub/EntryPageFactory.php b/src/Factory/ActivityPub/EntryPageFactory.php index 0cbd4dfb5..e2f6d42a2 100644 --- a/src/Factory/ActivityPub/EntryPageFactory.php +++ b/src/Factory/ActivityPub/EntryPageFactory.php @@ -33,13 +33,12 @@ public function __construct( ) { } - public function create(Entry $entry, bool $context = false): array + public function create(Entry $entry, array $tags, bool $context = false): array { if ($context) { $page['@context'] = $this->contextProvider->referencedContexts(); } - $tags = $entry->tags ?? []; if ('random' !== $entry->magazine->name && !$entry->magazine->apId) { // @todo $tags[] = $entry->magazine->name; } diff --git a/src/Factory/ActivityPub/PostCommentNoteFactory.php b/src/Factory/ActivityPub/PostCommentNoteFactory.php index a01ac695d..1bbe55225 100644 --- a/src/Factory/ActivityPub/PostCommentNoteFactory.php +++ b/src/Factory/ActivityPub/PostCommentNoteFactory.php @@ -34,13 +34,12 @@ public function __construct( ) { } - public function create(PostComment $comment, bool $context = false): array + public function create(PostComment $comment, array $tags, bool $context = false): array { if ($context) { $note['@context'] = $this->contextProvider->referencedContexts(); } - $tags = $comment->tags ?? []; if ('random' !== $comment->magazine->name && !$comment->magazine->apId) { // @todo $tags[] = $comment->magazine->name; } diff --git a/src/Factory/ActivityPub/PostNoteFactory.php b/src/Factory/ActivityPub/PostNoteFactory.php index dcf71f8f3..1c4f5362b 100644 --- a/src/Factory/ActivityPub/PostNoteFactory.php +++ b/src/Factory/ActivityPub/PostNoteFactory.php @@ -15,7 +15,7 @@ use App\Service\ActivityPub\Wrapper\TagsWrapper; use App\Service\ActivityPubManager; use App\Service\MentionManager; -use App\Service\TagManager; +use App\Service\TagExtractor; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; class PostNoteFactory @@ -30,23 +30,22 @@ public function __construct( private readonly ApHttpClient $client, private readonly ActivityPubManager $activityPubManager, private readonly MentionManager $mentionManager, - private readonly TagManager $tagManager, + private readonly TagExtractor $tagExtractor, private readonly MarkdownConverter $markdownConverter ) { } - public function create(Post $post, bool $context = false): array + public function create(Post $post, array $tags, bool $context = false): array { if ($context) { $note['@context'] = $this->contextProvider->referencedContexts(); } - $tags = $post->tags ?? []; if ('random' !== $post->magazine->name && !$post->magazine->apId) { // @todo $tags[] = $post->magazine->name; } - $body = $this->tagManager->joinTagsToBody( + $body = $this->tagExtractor->joinTagsToBody( $post->body, $tags ); diff --git a/src/Factory/EntryCommentFactory.php b/src/Factory/EntryCommentFactory.php index 784ba5ef1..c8d7a66fb 100644 --- a/src/Factory/EntryCommentFactory.php +++ b/src/Factory/EntryCommentFactory.php @@ -8,6 +8,7 @@ use App\DTO\EntryCommentResponseDto; use App\Entity\EntryComment; use App\Entity\User; +use App\Repository\TagLinkRepository; use Symfony\Bundle\SecurityBundle\Security; class EntryCommentFactory @@ -17,6 +18,7 @@ public function __construct( private readonly ImageFactory $imageFactory, private readonly UserFactory $userFactory, private readonly MagazineFactory $magazineFactory, + private readonly TagLinkRepository $tagLinkRepository, ) { } @@ -31,7 +33,7 @@ public function createFromDto(EntryCommentDto $dto, User $user): EntryComment ); } - public function createResponseDto(EntryCommentDto|EntryComment $comment, int $childCount = 0): EntryCommentResponseDto + public function createResponseDto(EntryCommentDto|EntryComment $comment, array $tags, int $childCount = 0): EntryCommentResponseDto { $dto = $comment instanceof EntryComment ? $this->createDto($comment) : $comment; @@ -52,7 +54,7 @@ public function createResponseDto(EntryCommentDto|EntryComment $comment, int $ch $dto->visibility, $dto->apId, $dto->mentions, - $dto->tags, + $tags, $dto->createdAt, $dto->editedAt, $dto->lastActive, @@ -63,7 +65,7 @@ public function createResponseDto(EntryCommentDto|EntryComment $comment, int $ch public function createResponseTree(EntryComment $comment, int $depth = -1): EntryCommentResponseDto { $commentDto = $this->createDto($comment); - $toReturn = $this->createResponseDto($commentDto, array_reduce($comment->children->toArray(), EntryCommentResponseDto::class.'::recursiveChildCount', 0)); + $toReturn = $this->createResponseDto($commentDto, $this->tagLinkRepository->getTagsOfEntryComment($comment), array_reduce($comment->children->toArray(), EntryCommentResponseDto::class.'::recursiveChildCount', 0)); $toReturn->isFavourited = $commentDto->isFavourited; $toReturn->userVote = $commentDto->userVote; @@ -96,7 +98,6 @@ public function createDto(EntryComment $comment): EntryCommentDto $dto->dv = $comment->countDownVotes(); $dto->favouriteCount = $comment->favouriteCount; $dto->mentions = $comment->mentions; - $dto->tags = $comment->tags; $dto->createdAt = $comment->createdAt; $dto->editedAt = $comment->editedAt; $dto->lastActive = $comment->lastActive; diff --git a/src/Factory/EntryFactory.php b/src/Factory/EntryFactory.php index 96f5edfd7..b88e9dc8a 100644 --- a/src/Factory/EntryFactory.php +++ b/src/Factory/EntryFactory.php @@ -9,6 +9,7 @@ use App\Entity\Badge; use App\Entity\Entry; use App\Entity\User; +use App\Repository\TagLinkRepository; use Symfony\Bundle\SecurityBundle\Security; class EntryFactory @@ -20,6 +21,7 @@ public function __construct( private readonly MagazineFactory $magazineFactory, private readonly UserFactory $userFactory, private readonly BadgeFactory $badgeFactory, + private readonly TagLinkRepository $tagLinkRepository, ) { } @@ -38,7 +40,7 @@ public function createFromDto(EntryDto $dto, User $user): Entry ); } - public function createResponseDto(EntryDto|Entry $entry): EntryResponseDto + public function createResponseDto(EntryDto|Entry $entry, array $tags): EntryResponseDto { $dto = $entry instanceof Entry ? $this->createDto($entry) : $entry; $badges = $dto->badges ? array_map(fn (Badge $badge) => $this->badgeFactory->createDto($badge), $dto->badges->toArray()) : null; @@ -53,7 +55,7 @@ public function createResponseDto(EntryDto|Entry $entry): EntryResponseDto $dto->image, $dto->body, $dto->lang, - $dto->tags, + $tags, $badges, $dto->comments, $dto->uv, @@ -95,7 +97,6 @@ public function createDto(Entry $entry): EntryDto $dto->score = $entry->score; $dto->visibility = $entry->visibility; $dto->ip = $entry->ip; - $dto->tags = $entry->tags; $dto->createdAt = $entry->createdAt; $dto->editedAt = $entry->editedAt; $dto->lastActive = $entry->lastActive; @@ -103,6 +104,7 @@ public function createDto(Entry $entry): EntryDto $dto->isPinned = $entry->sticky; $dto->type = $entry->type; $dto->apId = $entry->apId; + $dto->tags = $this->tagLinkRepository->getTagsOfEntry($entry); $currentUser = $this->security->getUser(); // Only return the user's vote if permission to control voting has been given diff --git a/src/Factory/PostCommentFactory.php b/src/Factory/PostCommentFactory.php index 33d847256..81bc0bc8b 100644 --- a/src/Factory/PostCommentFactory.php +++ b/src/Factory/PostCommentFactory.php @@ -9,6 +9,7 @@ use App\Entity\PostComment; use App\Entity\User; use App\Repository\PostRepository; +use App\Repository\TagLinkRepository; use Symfony\Bundle\SecurityBundle\Security; class PostCommentFactory @@ -19,6 +20,7 @@ public function __construct( private readonly MagazineFactory $magazineFactory, private readonly ImageFactory $imageFactory, private readonly PostRepository $postRepository, + private readonly TagLinkRepository $tagLinkRepository, ) { } @@ -33,7 +35,7 @@ public function createFromDto(PostCommentDto $dto, User $user): PostComment ); } - public function createResponseDto(PostCommentDto|PostComment $comment, int $childCount = 0): PostCommentResponseDto + public function createResponseDto(PostCommentDto|PostComment $comment, array $tags, int $childCount = 0): PostCommentResponseDto { $dto = $comment instanceof PostComment ? $this->createDto($comment) : $comment; @@ -54,7 +56,7 @@ public function createResponseDto(PostCommentDto|PostComment $comment, int $chil $dto->visibility, $dto->apId, $dto->mentions, - $dto->tags, + $tags, $dto->createdAt, $dto->editedAt, $dto->lastActive @@ -64,7 +66,7 @@ public function createResponseDto(PostCommentDto|PostComment $comment, int $chil public function createResponseTree(PostComment $comment, int $depth): PostCommentResponseDto { $commentDto = $this->createDto($comment); - $toReturn = $this->createResponseDto($commentDto, array_reduce($comment->children->toArray(), PostCommentResponseDto::class.'::recursiveChildCount', 0)); + $toReturn = $this->createResponseDto($commentDto, $this->tagLinkRepository->getTagsOfPostComment($comment), array_reduce($comment->children->toArray(), PostCommentResponseDto::class.'::recursiveChildCount', 0)); $toReturn->isFavourited = $commentDto->isFavourited; $toReturn->userVote = $commentDto->userVote; @@ -101,7 +103,6 @@ public function createDto(PostComment $comment): PostCommentDto $dto->setId($comment->getId()); $dto->parent = $comment->parent; $dto->mentions = $comment->mentions; - $dto->tags = $comment->tags; $currentUser = $this->security->getUser(); // Only return the user's vote if permission to control voting has been given diff --git a/src/Factory/PostFactory.php b/src/Factory/PostFactory.php index ee61f9c20..6b189c8f5 100644 --- a/src/Factory/PostFactory.php +++ b/src/Factory/PostFactory.php @@ -31,7 +31,7 @@ public function createFromDto(PostDto $dto, User $user): Post ); } - public function createResponseDto(PostDto|Post $post): PostResponseDto + public function createResponseDto(PostDto|Post $post, array $tags): PostResponseDto { $dto = $post instanceof Post ? $this->createDto($post) : $post; @@ -49,7 +49,7 @@ public function createResponseDto(PostDto|Post $post): PostResponseDto $dto->dv, $dto->favouriteCount, $dto->visibility, - $dto->tags, + $tags, $dto->mentions, $dto->apId, $dto->createdAt, @@ -80,7 +80,6 @@ public function createDto(Post $post): PostDto $dto->editedAt = $post->editedAt; $dto->lastActive = $post->lastActive; $dto->ip = $post->ip; - $dto->tags = $post->tags; $dto->mentions = $post->mentions; $dto->apId = $post->apId; $dto->setId($post->getId()); diff --git a/src/Factory/ReportFactory.php b/src/Factory/ReportFactory.php index a87d50e4f..63c8d5f75 100644 --- a/src/Factory/ReportFactory.php +++ b/src/Factory/ReportFactory.php @@ -15,6 +15,7 @@ use App\Entity\PostCommentReport; use App\Entity\PostReport; use App\Entity\Report; +use App\Repository\TagLinkRepository; use Doctrine\ORM\EntityManagerInterface; class ReportFactory @@ -27,6 +28,7 @@ public function __construct( private readonly PostFactory $postFactory, private readonly EntryCommentFactory $entryCommentFactory, private readonly PostCommentFactory $postCommentFactory, + private readonly TagLinkRepository $tagLinkRepository, ) { } @@ -56,19 +58,19 @@ public function createResponseDto(Report $report): ReportResponseDto switch (\get_class($report)) { case EntryReport::class: \assert($subject instanceof Entry); - $toReturn->subject = $this->entryFactory->createResponseDto($subject); + $toReturn->subject = $this->entryFactory->createResponseDto($subject, tags: $this->tagLinkRepository->getTagsOfEntry($subject)); break; case EntryCommentReport::class: \assert($subject instanceof EntryComment); - $toReturn->subject = $this->entryCommentFactory->createResponseDto($subject); + $toReturn->subject = $this->entryCommentFactory->createResponseDto($subject, tags: $this->tagLinkRepository->getTagsOfEntryComment($subject)); break; case PostReport::class: \assert($subject instanceof Post); - $toReturn->subject = $this->postFactory->createResponseDto($subject); + $toReturn->subject = $this->postFactory->createResponseDto($subject, tags: $this->tagLinkRepository->getTagsOfPost($subject)); break; case PostCommentReport::class: \assert($subject instanceof PostComment); - $toReturn->subject = $this->postCommentFactory->createResponseDto($subject); + $toReturn->subject = $this->postCommentFactory->createResponseDto($subject, tags: $this->tagLinkRepository->getTagsOfPostComment($subject)); break; default: throw new \LogicException(); diff --git a/src/MessageHandler/ActivityPub/Inbox/ChainActivityHandler.php b/src/MessageHandler/ActivityPub/Inbox/ChainActivityHandler.php index 228a1093d..13eca0413 100644 --- a/src/MessageHandler/ActivityPub/Inbox/ChainActivityHandler.php +++ b/src/MessageHandler/ActivityPub/Inbox/ChainActivityHandler.php @@ -8,6 +8,8 @@ use App\Entity\EntryComment; use App\Entity\Post; use App\Entity\PostComment; +use App\Exception\TagBannedException; +use App\Exception\UserBannedException; use App\Message\ActivityPub\Inbox\AnnounceMessage; use App\Message\ActivityPub\Inbox\ChainActivityMessage; use App\Message\ActivityPub\Inbox\DislikeMessage; @@ -111,6 +113,10 @@ private function retrieveObject(string $apUrl): Entry|EntryComment|Post|PostComm default: $this->logger->warning('Could not create an object from type {t} on {url}: {o}', ['t' => $object['type'], 'url' => $apUrl, 'o' => $object]); } + } catch (UserBannedException) { + $this->logger->error('the user is banned, url: {url}', ['url' => $apUrl]); + } catch (TagBannedException) { + $this->logger->error('one of the used tags is banned, url: {url}', ['url' => $apUrl]); } catch (\Exception $e) { $this->logger->error('There was an exception while getting {url}: {ex} - {m}. {o}', ['url' => $apUrl, 'ex' => \get_class($e), 'm' => $e->getMessage(), 'o' => $e]); } diff --git a/src/MessageHandler/ActivityPub/Inbox/CreateHandler.php b/src/MessageHandler/ActivityPub/Inbox/CreateHandler.php index da39c549e..5f3038329 100644 --- a/src/MessageHandler/ActivityPub/Inbox/CreateHandler.php +++ b/src/MessageHandler/ActivityPub/Inbox/CreateHandler.php @@ -8,6 +8,8 @@ use App\Entity\EntryComment; use App\Entity\Post; use App\Entity\PostComment; +use App\Exception\TagBannedException; +use App\Exception\UserBannedException; use App\Message\ActivityPub\Inbox\ChainActivityMessage; use App\Message\ActivityPub\Inbox\CreateMessage; use App\Message\ActivityPub\Outbox\AnnounceMessage; @@ -32,25 +34,34 @@ public function __construct( ) { } - public function __invoke(CreateMessage $message) + /** + * @throws \Exception + */ + public function __invoke(CreateMessage $message): void { $this->object = $message->payload; $this->logger->debug('Got a CreateMessage of type {t}', [$message->payload['type'], $message->payload]); - if ('Note' === $this->object['type']) { - $this->handleChain(); - } + try { + if ('Note' === $this->object['type']) { + $this->handleChain(); + } - if ('Page' === $this->object['type']) { - $this->handlePage(); - } + if ('Page' === $this->object['type']) { + $this->handlePage(); + } - if ('Article' === $this->object['type']) { - $this->handlePage(); - } + if ('Article' === $this->object['type']) { + $this->handlePage(); + } - if ('Question' === $this->object['type']) { - $this->handleChain(); + if ('Question' === $this->object['type']) { + $this->handleChain(); + } + } catch (UserBannedException) { + $this->logger->info('Did not create the post, because the user is banned'); + } catch (TagBannedException) { + $this->logger->info('Did not create the post, because one of the used tags is banned'); } } @@ -75,6 +86,11 @@ private function handleChain(): void } } + /** + * @throws \Exception + * @throws UserBannedException + * @throws TagBannedException + */ private function handlePage(): void { $page = $this->page->create($this->object); diff --git a/src/Pagination/NativeQueryAdapter.php b/src/Pagination/NativeQueryAdapter.php new file mode 100644 index 000000000..959d47b60 --- /dev/null +++ b/src/Pagination/NativeQueryAdapter.php @@ -0,0 +1,62 @@ +numOfResults) { + $sql2 = 'SELECT COUNT(*) as cnt FROM ('.$sql.') sub'; + $stmt2 = $this->conn->prepare($sql2); + foreach ($this->parameters as $key => $value) { + $stmt2->bindValue($key, $value); + } + $result = $stmt2->executeQuery()->fetchAllAssociative(); + $this->numOfResults = $result[0]['cnt']; + } + + $this->statement = $this->conn->prepare($sql.' LIMIT :limit OFFSET :offset'); + foreach ($this->parameters as $key => $value) { + $this->statement->bindValue($key, $value); + } + } + + public function getNbResults(): int + { + return $this->numOfResults; + } + + public function getSlice(int $offset, int $length): iterable + { + $this->statement->bindValue('offset', $offset); + $this->statement->bindValue('limit', $length); + + return $this->transformer->transform($this->statement->executeQuery()->fetchAllAssociative()); + } +} diff --git a/src/Pagination/QueryAdapter.php b/src/Pagination/QueryAdapter.php index fba19495c..19d1c6c40 100644 --- a/src/Pagination/QueryAdapter.php +++ b/src/Pagination/QueryAdapter.php @@ -41,7 +41,7 @@ public function __construct( */ public function getNbResults(): int { - return \count($this->paginator); + return $this->paginator->count(); } /** diff --git a/src/Pagination/Transformation/ContentPopulationTransformer.php b/src/Pagination/Transformation/ContentPopulationTransformer.php new file mode 100644 index 000000000..522e98d97 --- /dev/null +++ b/src/Pagination/Transformation/ContentPopulationTransformer.php @@ -0,0 +1,47 @@ +entityManager->getRepository(Entry::class)->findBy( + ['id' => $this->getOverviewIds((array) $input, 'entry')] + ); + $entryComments = $this->entityManager->getRepository(EntryComment::class)->findBy( + ['id' => $this->getOverviewIds((array) $input, 'entry_comment')] + ); + $post = $this->entityManager->getRepository(Post::class)->findBy( + ['id' => $this->getOverviewIds((array) $input, 'post')] + ); + $postComment = $this->entityManager->getRepository(PostComment::class)->findBy( + ['id' => $this->getOverviewIds((array) $input, 'post_comment')] + ); + + $result = array_merge($entries, $entryComments, $post, $postComment); + uasort($result, fn ($a, $b) => $a->getCreatedAt() > $b->getCreatedAt() ? -1 : 1); + + return $result; + } + + private function getOverviewIds(array $result, string $type): array + { + $result = array_filter($result, fn ($subject) => $subject['type'] === $type); + + return array_map(fn ($subject) => $subject['id'], $result); + } +} diff --git a/src/Pagination/Transformation/ResultTransformer.php b/src/Pagination/Transformation/ResultTransformer.php new file mode 100644 index 000000000..56133ee5f --- /dev/null +++ b/src/Pagination/Transformation/ResultTransformer.php @@ -0,0 +1,10 @@ +addTimeClause($qb, $criteria); $this->filter($qb, $criteria); + $this->addBannedHashtagClause($qb); return $qb; } @@ -116,6 +117,18 @@ private function addTimeClause(QueryBuilder $qb, Criteria $criteria): void } } + private function addBannedHashtagClause(QueryBuilder $qb): void + { + $dql = $this->getEntityManager()->createQueryBuilder() + ->select('hl2') + ->from(HashtagLink::class, 'hl2') + ->join('hl2.hashtag', 'h2') + ->where('h2.banned = true') + ->andWhere('hl2.entryComment = c') + ->getDQL(); + $qb->andWhere($qb->expr()->not($qb->expr()->exists($dql))); + } + private function filter(QueryBuilder $qb, Criteria $criteria): QueryBuilder { $user = $this->security->getUser(); @@ -159,7 +172,10 @@ private function filter(QueryBuilder $qb, Criteria $criteria): QueryBuilder } if ($criteria->tag) { - $qb->andWhere("JSONB_CONTAINS(c.tags, '\"".$criteria->tag."\"') = true"); + $qb->andWhere('t.tag = :tag') + ->join('c.hashtags', 'h') + ->join('h.hashtag', 't') + ->setParameter('tag', $criteria->tag); } if ($criteria->subscribed) { @@ -327,12 +343,4 @@ public function findToDelete(User $user, int $limit): array ->getQuery() ->getResult(); } - - public function findWithTags(): array - { - return $this->createQueryBuilder('c') - ->where('c.tags IS NOT NULL') - ->getQuery() - ->getResult(); - } } diff --git a/src/Repository/EntryRepository.php b/src/Repository/EntryRepository.php index 55f330582..7fba4188c 100644 --- a/src/Repository/EntryRepository.php +++ b/src/Repository/EntryRepository.php @@ -13,6 +13,7 @@ use App\Entity\DomainSubscription; use App\Entity\Entry; use App\Entity\EntryFavourite; +use App\Entity\HashtagLink; use App\Entity\Magazine; use App\Entity\MagazineBlock; use App\Entity\MagazineSubscription; @@ -22,7 +23,6 @@ use App\Entity\UserFollow; use App\PageView\EntryPageView; use App\Pagination\AdapterFactory; -use App\Repository\Contract\TagRepositoryInterface; use App\Service\SettingsManager; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\DBAL\ArrayParameterType; @@ -44,7 +44,7 @@ * @method Entry[] findAll() * @method Entry[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ -class EntryRepository extends ServiceEntityRepository implements TagRepositoryInterface +class EntryRepository extends ServiceEntityRepository { public const SORT_DEFAULT = 'hot'; public const TIME_DEFAULT = Criteria::TIME_ALL; @@ -107,6 +107,7 @@ private function getEntryQueryBuilder(EntryPageView $criteria): QueryBuilder $this->addTimeClause($qb, $criteria); $this->addStickyClause($qb, $criteria); $this->filter($qb, $criteria); + $this->addBannedHashtagClause($qb); return $qb; } @@ -132,6 +133,22 @@ private function addStickyClause(QueryBuilder $qb, EntryPageView $criteria): voi } } + private function addBannedHashtagClause(QueryBuilder $qb): void + { + $dql = $this->getEntityManager()->createQueryBuilder() + ->select('hl2') + ->from(HashtagLink::class, 'hl2') + ->join('hl2.hashtag', 'h2') + ->where('h2.banned = true') + ->andWhere('hl2.entry = e') + ->getDQL(); + $qb->andWhere( + $qb->expr()->not( + $qb->expr()->exists($dql) + ) + ); + } + private function filter(QueryBuilder $qb, EntryPageView $criteria): QueryBuilder { $user = $this->security->getUser(); @@ -156,7 +173,10 @@ private function filter(QueryBuilder $qb, EntryPageView $criteria): QueryBuilder } if ($criteria->tag) { - $qb->andWhere("JSONB_CONTAINS(e.tags, '\"".$criteria->tag."\"') = true"); + $qb->andWhere('t.tag = :tag') + ->join('e.hashtags', 'h') + ->join('h.hashtag', 't') + ->setParameter('tag', $criteria->tag); } if ($criteria->domain) { @@ -324,17 +344,22 @@ public function findRelatedByTag(string $tag, ?int $limit = 1): array $qb = $this->createQueryBuilder('e'); return $qb - ->andWhere("JSONB_CONTAINS(e.tags, '\"".$tag."\"') = true") ->andWhere('e.visibility = :visibility') ->andWhere('m.visibility = :visibility') ->andWhere('u.visibility = :visibility') ->andWhere('u.isDeleted = false') ->andWhere('m.isAdult = false') ->andWhere('e.isAdult = false') + ->andWhere('h.tag = :tag') ->join('e.magazine', 'm') ->join('e.user', 'u') + ->join('e.hashtags', 'hl') + ->join('hl.hashtag', 'h') ->orderBy('e.createdAt', 'DESC') - ->setParameters(['visibility' => VisibilityInterface::VISIBILITY_VISIBLE]) + ->setParameters([ + 'visibility' => VisibilityInterface::VISIBILITY_VISIBLE, + 'tag' => $tag, + ]) ->setMaxResults($limit) ->getQuery() ->getResult(); @@ -385,14 +410,6 @@ public function findLast(int $limit): array ->getResult(); } - public function findWithTags(): array - { - return $this->createQueryBuilder('e') - ->where('e.tags IS NOT NULL') - ->getQuery() - ->getResult(); - } - private function countAll(EntryPageView|Criteria $criteria): int { return $this->cache->get( diff --git a/src/Repository/PostCommentRepository.php b/src/Repository/PostCommentRepository.php index 8e2b41499..f33e8801b 100644 --- a/src/Repository/PostCommentRepository.php +++ b/src/Repository/PostCommentRepository.php @@ -9,12 +9,12 @@ namespace App\Repository; use App\Entity\Contracts\VisibilityInterface; +use App\Entity\HashtagLink; use App\Entity\PostComment; use App\Entity\User; use App\Entity\UserBlock; use App\Entity\UserFollow; use App\PageView\PostCommentPageView; -use App\Repository\Contract\TagRepositoryInterface; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\DBAL\ArrayParameterType; use Doctrine\DBAL\Types\Types; @@ -33,7 +33,7 @@ * @method PostComment[] findAll() * @method PostComment[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ -class PostCommentRepository extends ServiceEntityRepository implements TagRepositoryInterface +class PostCommentRepository extends ServiceEntityRepository { public const PER_PAGE = 15; @@ -100,6 +100,7 @@ private function getCommentQueryBuilder(Criteria $criteria): QueryBuilder $this->addTimeClause($qb, $criteria); $this->filter($qb, $criteria); + $this->addBannedHashtagClause($qb); return $qb; } @@ -114,6 +115,18 @@ private function addTimeClause(QueryBuilder $qb, Criteria $criteria): void } } + private function addBannedHashtagClause(QueryBuilder $qb): void + { + $dql = $this->getEntityManager()->createQueryBuilder() + ->select('hl2') + ->from(HashtagLink::class, 'hl2') + ->join('hl2.hashtag', 'h2') + ->where('h2.banned = true') + ->andWhere('hl2.postComment = c') + ->getDQL(); + $qb->andWhere($qb->expr()->not($qb->expr()->exists($dql))); + } + private function filter(QueryBuilder $qb, Criteria $criteria) { if ($criteria->post) { @@ -136,6 +149,13 @@ private function filter(QueryBuilder $qb, Criteria $criteria) ->setParameter('user', $criteria->user); } + if ($criteria->tag) { + $qb->andWhere('t.tag = :tag') + ->join('p.hashtags', 'h') + ->join('h.hashtag', 't') + ->setParameter('tag', $criteria->tag); + } + $user = $this->security->getUser(); if ($user && !$criteria->moderated) { $qb->andWhere( @@ -224,12 +244,4 @@ public function findFederated() ->getQuery() ->getResult(); } - - public function findWithTags(): array - { - return $this->createQueryBuilder('c') - ->where('c.tags IS NOT NULL') - ->getQuery() - ->getResult(); - } } diff --git a/src/Repository/PostRepository.php b/src/Repository/PostRepository.php index 0ff2ae80c..870b20490 100644 --- a/src/Repository/PostRepository.php +++ b/src/Repository/PostRepository.php @@ -9,6 +9,7 @@ namespace App\Repository; use App\Entity\Contracts\VisibilityInterface; +use App\Entity\HashtagLink; use App\Entity\Magazine; use App\Entity\MagazineBlock; use App\Entity\MagazineSubscription; @@ -21,7 +22,6 @@ use App\PageView\EntryPageView; use App\PageView\PostPageView; use App\Pagination\AdapterFactory; -use App\Repository\Contract\TagRepositoryInterface; use App\Service\SettingsManager; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\DBAL\ArrayParameterType; @@ -43,7 +43,7 @@ * @method Post[] findAll() * @method Post[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ -class PostRepository extends ServiceEntityRepository implements TagRepositoryInterface +class PostRepository extends ServiceEntityRepository { public const PER_PAGE = 15; public const SORT_DEFAULT = 'hot'; @@ -89,7 +89,7 @@ private function getEntryQueryBuilder(PostPageView $criteria): QueryBuilder if ($user && VisibilityInterface::VISIBILITY_VISIBLE === $criteria->visibility) { $qb->orWhere( - 'p.user IN (SELECT IDENTITY(puf.following) FROM '.UserFollow::class.' puf WHERE puf.follower = :puf_user AND p.visibility = :puf_visibility)' + 'EXISTS (SELECT IDENTITY(puf.following) FROM '.UserFollow::class.' puf WHERE puf.follower = :puf_user AND p.visibility = :puf_visibility AND puf.following = p.user)' ) ->setParameter('puf_user', $user) ->setParameter('puf_visibility', VisibilityInterface::VISIBILITY_PRIVATE); @@ -103,6 +103,7 @@ private function getEntryQueryBuilder(PostPageView $criteria): QueryBuilder $this->addTimeClause($qb, $criteria); $this->addStickyClause($qb, $criteria); $this->filter($qb, $criteria); + $this->addBannedHashtagClause($qb); return $qb; } @@ -128,6 +129,18 @@ private function addStickyClause(QueryBuilder $qb, PostPageView $criteria): void } } + private function addBannedHashtagClause(QueryBuilder $qb): void + { + $dql = $this->getEntityManager()->createQueryBuilder() + ->select('hl2') + ->from(HashtagLink::class, 'hl2') + ->join('hl2.hashtag', 'h2') + ->where('h2.banned = true') + ->andWhere('hl2.post = p') + ->getDQL(); + $qb->andWhere($qb->expr()->not($qb->expr()->exists($dql))); + } + private function filter(QueryBuilder $qb, Criteria $criteria): QueryBuilder { $user = $this->security->getUser(); @@ -147,14 +160,17 @@ private function filter(QueryBuilder $qb, Criteria $criteria): QueryBuilder } if ($criteria->tag) { - $qb->andWhere("JSONB_CONTAINS(p.tags, '\"".$criteria->tag."\"') = true"); + $qb->andWhere('t.tag = :tag') + ->join('p.hashtags', 'h') + ->join('h.hashtag', 't') + ->setParameter('tag', $criteria->tag); } if ($criteria->subscribed) { $qb->andWhere( - 'p.magazine IN (SELECT IDENTITY(ms.magazine) FROM '.MagazineSubscription::class.' ms WHERE ms.user = :user) + 'EXISTS (SELECT IDENTITY(ms.magazine) FROM '.MagazineSubscription::class.' ms WHERE ms.user = :user AND ms.magazine = p.magazine) OR - p.user IN (SELECT IDENTITY(uf.following) FROM '.UserFollow::class.' uf WHERE uf.follower = :user) + EXISTS (SELECT IDENTITY(uf.following) FROM '.UserFollow::class.' uf WHERE uf.follower = :user AND uf.following = p.user) OR p.user = :user' ); @@ -163,14 +179,14 @@ private function filter(QueryBuilder $qb, Criteria $criteria): QueryBuilder if ($criteria->moderated) { $qb->andWhere( - 'p.magazine IN (SELECT IDENTITY(mm.magazine) FROM '.Moderator::class.' mm WHERE mm.user = :user)' + 'EXISTS (SELECT IDENTITY(mm.magazine) FROM '.Moderator::class.' mm WHERE mm.user = :user AND mm.magazine = p.magazine)' ); $qb->setParameter('user', $this->security->getUser()); } if ($criteria->favourite) { $qb->andWhere( - 'p.id IN (SELECT IDENTITY(pf.post) FROM '.PostFavourite::class.' pf WHERE pf.user = :user)' + 'EXISTS (SELECT IDENTITY(pf.post) FROM '.PostFavourite::class.' pf WHERE pf.user = :user AND pf.post = p)' ); $qb->setParameter('user', $this->security->getUser()); } @@ -182,12 +198,12 @@ private function filter(QueryBuilder $qb, Criteria $criteria): QueryBuilder if ($user && (!$criteria->magazine || !$criteria->magazine->userIsModerator($user)) && !$criteria->moderated) { $qb->andWhere( - 'p.user NOT IN (SELECT IDENTITY(ub.blocked) FROM '.UserBlock::class.' ub WHERE ub.blocker = :blocker)' + 'NOT EXISTS (SELECT IDENTITY(ub.blocked) FROM '.UserBlock::class.' ub WHERE ub.blocker = :blocker AND ub.blocked = p.user)' ); $qb->setParameter('blocker', $user); $qb->andWhere( - 'p.magazine NOT IN (SELECT IDENTITY(mb.magazine) FROM '.MagazineBlock::class.' mb WHERE mb.user = :magazineBlocker)' + 'NOT EXISTS (SELECT IDENTITY(mb.magazine) FROM '.MagazineBlock::class.' mb WHERE mb.user = :magazineBlocker AND mb.magazine = p.magazine)' ); $qb->setParameter('magazineBlocker', $user); } @@ -296,17 +312,22 @@ public function findRelatedByTag(string $tag, ?int $limit = 1): array $qb = $this->createQueryBuilder('p'); return $qb - ->andWhere("JSONB_CONTAINS(p.tags, '\"".$tag."\"') = true") ->andWhere('p.visibility = :visibility') ->andWhere('m.visibility = :visibility') ->andWhere('u.visibility = :visibility') ->andWhere('m.name != :name') ->andWhere('p.isAdult = false') ->andWhere('m.isAdult = false') + ->andWhere('h.tag = :name') ->join('p.magazine', 'm') ->join('p.user', 'u') + ->join('p.hashtags', 'hl') + ->join('hl.hashtag', 'h') ->orderBy('p.createdAt', 'DESC') - ->setParameters(['visibility' => VisibilityInterface::VISIBILITY_VISIBLE, 'name' => $tag]) + ->setParameters([ + 'visibility' => VisibilityInterface::VISIBILITY_VISIBLE, + 'name' => $tag, + ]) ->setMaxResults($limit) ->getQuery() ->getResult(); @@ -406,14 +427,6 @@ public function findUsers(Magazine $magazine, ?bool $federated = false): array ->getResult(); } - public function findWithTags(): array - { - return $this->createQueryBuilder('p') - ->where('p.tags IS NOT NULL') - ->getQuery() - ->getResult(); - } - private function countAll(EntryPageView|Criteria $criteria): int { return $this->cache->get( diff --git a/src/Repository/SearchRepository.php b/src/Repository/SearchRepository.php index a09e0d704..a5d89e5eb 100644 --- a/src/Repository/SearchRepository.php +++ b/src/Repository/SearchRepository.php @@ -5,26 +5,23 @@ namespace App\Repository; use App\Entity\Contracts\VisibilityInterface; -use App\Entity\Entry; -use App\Entity\EntryComment; use App\Entity\Magazine; use App\Entity\Moderator; -use App\Entity\Post; -use App\Entity\PostComment; use App\Entity\User; +use App\Pagination\NativeQueryAdapter; +use App\Pagination\Transformation\ContentPopulationTransformer; use Doctrine\ORM\EntityManagerInterface; -use Pagerfanta\Adapter\ArrayAdapter; -use Pagerfanta\Exception\NotValidCurrentPageException; use Pagerfanta\Pagerfanta; use Pagerfanta\PagerfantaInterface; -use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class SearchRepository { public const PER_PAGE = 25; - public function __construct(private EntityManagerInterface $entityManager) - { + public function __construct( + private readonly EntityManagerInterface $entityManager, + private readonly ContentPopulationTransformer $transformer, + ) { } public function countModerated(User $user): int @@ -42,220 +39,119 @@ public function countModerated(User $user): int public function countBoosts(User $user): int { - // @todo union adapter $conn = $this->entityManager->getConnection(); - $sql = " - (SELECT entry_id as id, created_at, 'entry' AS type FROM entry_vote WHERE user_id = :userId AND choice = 1) - UNION - (SELECT comment_id as id, created_at, 'entry_comment' AS type FROM entry_comment_vote WHERE user_id = :userId AND choice = 1) - UNION - (SELECT post_id as id, created_at, 'post' AS type FROM post_vote WHERE user_id = :userId AND choice = 1) - UNION - (SELECT comment_id as id, created_at, 'post_comment' AS type FROM post_comment_vote WHERE user_id = :userId AND choice = 1) - ORDER BY created_at DESC"; + $sql = "SELECT COUNT(*) as cnt FROM ( + SELECT entry_id as id, created_at, 'entry' AS type FROM entry_vote WHERE user_id = :userId AND choice = 1 + UNION ALL + SELECT comment_id as id, created_at, 'entry_comment' AS type FROM entry_comment_vote WHERE user_id = :userId AND choice = 1 + UNION ALL + SELECT post_id as id, created_at, 'post' AS type FROM post_vote WHERE user_id = :userId AND choice = 1 + UNION ALL + SELECT comment_id as id, created_at, 'post_comment' AS type FROM post_comment_vote WHERE user_id = :userId AND choice = 1 + ) sub"; $stmt = $conn->prepare($sql); $stmt->bindValue('userId', $user->getId()); $stmt = $stmt->executeQuery(); - return $stmt->rowCount(); + return $stmt->fetchAllAssociative()[0]['cnt']; } public function findBoosts(int $page, User $user): PagerfantaInterface { - // @todo union adapter $conn = $this->entityManager->getConnection(); $sql = " - (SELECT entry_id as id, created_at, 'entry' AS type FROM entry_vote WHERE user_id = :userId AND choice = 1) - UNION - (SELECT comment_id as id, created_at, 'entry_comment' AS type FROM entry_comment_vote WHERE user_id = :userId AND choice = 1) - UNION - (SELECT post_id as id, created_at, 'post' AS type FROM post_vote WHERE user_id = :userId AND choice = 1) - UNION - (SELECT comment_id as id, created_at, 'post_comment' AS type FROM post_comment_vote WHERE user_id = :userId AND choice = 1) + SELECT entry_id as id, created_at, 'entry' AS type FROM entry_vote WHERE user_id = :userId AND choice = 1 + UNION ALL + SELECT comment_id as id, created_at, 'entry_comment' AS type FROM entry_comment_vote WHERE user_id = :userId AND choice = 1 + UNION ALL + SELECT post_id as id, created_at, 'post' AS type FROM post_vote WHERE user_id = :userId AND choice = 1 + UNION ALL + SELECT comment_id as id, created_at, 'post_comment' AS type FROM post_comment_vote WHERE user_id = :userId AND choice = 1 ORDER BY created_at DESC"; - $stmt = $conn->prepare($sql); - $stmt->bindValue('userId', $user->getId()); - $stmt = $stmt->executeQuery(); - $stmt->rowCount(); - $pagerfanta = new Pagerfanta( - new ArrayAdapter( - $stmt->fetchAllAssociative() - ) - ); + $pagerfanta = new Pagerfanta(new NativeQueryAdapter($conn, $sql, [ + 'userId' => $user->getId(), + ], transformer: $this->transformer)); - $countAll = $pagerfanta->count(); + $pagerfanta->setCurrentPage($page); - try { - $pagerfanta->setMaxPerPage(2000); - $pagerfanta->setCurrentPage(1); - } catch (NotValidCurrentPageException $e) { - throw new NotFoundHttpException(); - } - - $result = $pagerfanta->getCurrentPageResults(); - - return $this->buildResult($result, $page, $countAll); + return $pagerfanta; } public function search(?User $searchingUser, string $query, int $page = 1): PagerfantaInterface { - // @todo union adapter $conn = $this->entityManager->getConnection(); $sql = "SELECT e.id, e.created_at, e.visibility, 'entry' AS type FROM entry e - INNER JOIN public.user u ON u.id = user_id + INNER JOIN public.user u ON u.id = user_id INNER JOIN magazine m ON e.magazine_id = m.id - WHERE body_ts @@ plainto_tsquery( :query ) = true OR title_ts @@ plainto_tsquery( :query ) = true AND e.visibility = :visibility AND u.is_deleted = false + WHERE (body_ts @@ plainto_tsquery( :query ) = true OR title_ts @@ plainto_tsquery( :query ) = true) + AND e.visibility = :visibility + AND u.is_deleted = false AND NOT EXISTS (SELECT id FROM user_block ub WHERE ub.blocked_id = u.id AND ub.blocker_id = :queryingUser) - AND NOT EXISTS (SELECT id FROM magazine_block mb WHERE mb.magazine_id = m.id AND mb.user_id = :queryingUser) + AND NOT EXISTS (SELECT id FROM magazine_block mb WHERE mb.magazine_id = m.id AND mb.user_id = :queryingUser) + AND NOT EXISTS (SELECT hl.id FROM hashtag_link hl INNER JOIN hashtag h ON h.id = hl.hashtag_id AND h.banned = true WHERE hl.entry_id = e.id) UNION ALL SELECT e.id, e.created_at, e.visibility, 'entry_comment' AS type FROM entry_comment e - INNER JOIN public.user u ON u.id = user_id + INNER JOIN public.user u ON u.id = user_id INNER JOIN magazine m ON e.magazine_id = m.id - WHERE body_ts @@ plainto_tsquery( :query ) = true AND e.visibility = :visibility AND u.is_deleted = false + WHERE body_ts @@ plainto_tsquery( :query ) = true + AND e.visibility = :visibility + AND u.is_deleted = false AND NOT EXISTS (SELECT id FROM user_block ub WHERE ub.blocked_id = u.id AND ub.blocker_id = :queryingUser) - AND NOT EXISTS (SELECT id FROM magazine_block mb WHERE mb.magazine_id = m.id AND mb.user_id = :queryingUser) + AND NOT EXISTS (SELECT id FROM magazine_block mb WHERE mb.magazine_id = m.id AND mb.user_id = :queryingUser) + AND NOT EXISTS (SELECT hl.id FROM hashtag_link hl INNER JOIN hashtag h ON h.id = hl.hashtag_id AND h.banned = true WHERE hl.entry_comment_id = e.id) UNION ALL SELECT e.id, e.created_at, e.visibility, 'post' AS type FROM post e - INNER JOIN public.user u ON u.id = user_id + INNER JOIN public.user u ON u.id = user_id INNER JOIN magazine m ON e.magazine_id = m.id - WHERE body_ts @@ plainto_tsquery( :query ) = true AND e.visibility = :visibility AND u.is_deleted = false + WHERE body_ts @@ plainto_tsquery( :query ) = true + AND e.visibility = :visibility + AND u.is_deleted = false AND NOT EXISTS (SELECT id FROM user_block ub WHERE ub.blocked_id = u.id AND ub.blocker_id = :queryingUser) - AND NOT EXISTS (SELECT id FROM magazine_block mb WHERE mb.magazine_id = m.id AND mb.user_id = :queryingUser) + AND NOT EXISTS (SELECT id FROM magazine_block mb WHERE mb.magazine_id = m.id AND mb.user_id = :queryingUser) + AND NOT EXISTS (SELECT hl.id FROM hashtag_link hl INNER JOIN hashtag h ON h.id = hl.hashtag_id AND h.banned = true WHERE hl.post_id = e.id) UNION ALL SELECT e.id, e.created_at, e.visibility, 'post_comment' AS type FROM post_comment e - INNER JOIN public.user u ON u.id = user_id + INNER JOIN public.user u ON u.id = user_id INNER JOIN magazine m ON e.magazine_id = m.id - WHERE body_ts @@ plainto_tsquery( :query ) = true AND e.visibility = :visibility AND u.is_deleted = false + WHERE body_ts @@ plainto_tsquery( :query ) = true + AND e.visibility = :visibility + AND u.is_deleted = false AND NOT EXISTS (SELECT id FROM user_block ub WHERE ub.blocked_id = u.id AND ub.blocker_id = :queryingUser) - AND NOT EXISTS (SELECT id FROM magazine_block mb WHERE mb.magazine_id = m.id AND mb.user_id = :queryingUser) + AND NOT EXISTS (SELECT id FROM magazine_block mb WHERE mb.magazine_id = m.id AND mb.user_id = :queryingUser) + AND NOT EXISTS (SELECT hl.id FROM hashtag_link hl INNER JOIN hashtag h ON h.id = hl.hashtag_id AND h.banned = true WHERE hl.post_comment_id = e.id) ORDER BY created_at DESC"; - $stmt = $conn->prepare($sql); - $stmt->bindValue('query', $query); - $stmt->bindValue('visibility', VisibilityInterface::VISIBILITY_VISIBLE); - $stmt->bindValue('queryingUser', $searchingUser?->getId() ?? -1); - $stmt = $stmt->executeQuery(); - - $pagerfanta = new Pagerfanta( - new ArrayAdapter( - $stmt->fetchAllAssociative() - ) - ); - - $countAll = $pagerfanta->count(); - - try { - $pagerfanta->setMaxPerPage(20000); - $pagerfanta->setCurrentPage(1); - } catch (NotValidCurrentPageException $e) { - throw new NotFoundHttpException(); - } + $adapter = new NativeQueryAdapter($conn, $sql, [ + 'query' => $query, + 'visibility' => VisibilityInterface::VISIBILITY_VISIBLE, + 'queryingUser' => $searchingUser?->getId() ?? -1, + ], transformer: $this->transformer); - $result = $pagerfanta->getCurrentPageResults(); + $pagerfanta = new Pagerfanta($adapter); + $pagerfanta->setCurrentPage($page); - return $this->buildResult($result, $page, $countAll); + return $pagerfanta; } public function findByApId($url): array { - // @todo union adapter $conn = $this->entityManager->getConnection(); $sql = " - (SELECT id, created_at, 'entry' AS type FROM entry WHERE ap_id ILIKE :url) - UNION - (SELECT id, created_at, 'entry_comment' AS type FROM entry_comment WHERE ap_id ILIKE :url) - UNION - (SELECT id, created_at, 'post' AS type FROM post WHERE ap_id ILIKE :url) - UNION - (SELECT id, created_at, 'post_comment' AS type FROM post_comment WHERE ap_id ILIKE :url) + SELECT id, created_at, 'entry' AS type FROM entry WHERE ap_id ILIKE :url + UNION ALL + SELECT id, created_at, 'entry_comment' AS type FROM entry_comment WHERE ap_id ILIKE :url + UNION ALL + SELECT id, created_at, 'post' AS type FROM post WHERE ap_id ILIKE :url + UNION ALL + SELECT id, created_at, 'post_comment' AS type FROM post_comment WHERE ap_id ILIKE :url ORDER BY created_at DESC "; - $stmt = $conn->prepare($sql); - $stmt->bindValue('url', '%'.$url.'%'); - $stmt = $stmt->executeQuery(); - - $pagerfanta = new Pagerfanta( - new ArrayAdapter( - $stmt->fetchAllAssociative() - ) - ); - - $countAll = $pagerfanta->count(); - - try { - $pagerfanta->setMaxPerPage(1); - $pagerfanta->setCurrentPage(1); - } catch (NotValidCurrentPageException $e) { - throw new NotFoundHttpException(); - } - $result = $pagerfanta->getCurrentPageResults(); + $pagerfanta = new Pagerfanta(new NativeQueryAdapter($conn, $sql, [ + 'url' => "%$url%", + ], transformer: $this->transformer)); - $objects = []; - if ($this->getOverviewIds((array) $result, 'entry')) { - $objects = $this->entityManager->getRepository(Entry::class)->findBy( - ['id' => $this->getOverviewIds((array) $result, 'entry')] - ); - } - if ($this->getOverviewIds((array) $result, 'entry_comment')) { - $objects = $this->entityManager->getRepository(EntryComment::class)->findBy( - ['id' => $this->getOverviewIds((array) $result, 'entry_comment')] - ); - } - if ($this->getOverviewIds((array) $result, 'post')) { - $objects = $this->entityManager->getRepository(Post::class)->findBy( - ['id' => $this->getOverviewIds((array) $result, 'post')] - ); - } - if ($this->getOverviewIds((array) $result, 'post_comment')) { - $objects = $this->entityManager->getRepository(Post::class)->findBy( - ['id' => $this->getOverviewIds((array) $result, 'post_comment')] - ); - } - - return $objects ?? []; - } - - private function getOverviewIds(array $result, string $type): array - { - $result = array_filter($result, fn ($subject) => $subject['type'] === $type); - - return array_map(fn ($subject) => $subject['id'], $result); - } - - private function buildResult(array $result, $page, $countAll) - { - $entries = $this->entityManager->getRepository(Entry::class)->findBy( - ['id' => $this->getOverviewIds((array) $result, 'entry')] - ); - $entryComments = $this->entityManager->getRepository(EntryComment::class)->findBy( - ['id' => $this->getOverviewIds((array) $result, 'entry_comment')] - ); - $post = $this->entityManager->getRepository(Post::class)->findBy( - ['id' => $this->getOverviewIds((array) $result, 'post')] - ); - $postComment = $this->entityManager->getRepository(PostComment::class)->findBy( - ['id' => $this->getOverviewIds((array) $result, 'post_comment')] - ); - - $result = array_merge($entries, $entryComments, $post, $postComment); - uasort($result, fn ($a, $b) => $a->getCreatedAt() > $b->getCreatedAt() ? -1 : 1); - - $pagerfanta = new Pagerfanta( - new ArrayAdapter( - $result - ) - ); - - try { - $pagerfanta->setMaxPerPage(self::PER_PAGE); - $pagerfanta->setCurrentPage($page); - $pagerfanta->setMaxNbPages($countAll > 0 ? ((int) ceil($countAll / self::PER_PAGE)) : 1); - } catch (NotValidCurrentPageException $e) { - throw new NotFoundHttpException(); - } - - return $pagerfanta; + return $pagerfanta->getCurrentPageResults(); } } diff --git a/src/Repository/TagLinkRepository.php b/src/Repository/TagLinkRepository.php new file mode 100644 index 000000000..fbb7bc828 --- /dev/null +++ b/src/Repository/TagLinkRepository.php @@ -0,0 +1,140 @@ +findBy(['entry' => $entry]); + + return array_map(fn ($row) => $row->hashtag->tag, $result); + } + + public function removeTagOfEntry(Entry $entry, Hashtag $tag): void + { + $link = $this->findOneBy(['entry' => $entry, 'hashtag' => $tag]); + $this->entityManager->remove($link); + $this->entityManager->flush(); + } + + public function addTagToEntry(Entry $entry, Hashtag $tag): void + { + $link = new HashtagLink(); + $link->entry = $entry; + $link->hashtag = $tag; + $this->entityManager->persist($link); + $this->entityManager->flush(); + } + + public function entryHasTag(Entry $entry, Hashtag $tag): bool + { + return null !== $this->findOneBy(['entry' => $entry, 'hashtag' => $tag]); + } + + /** + * @return string[] + */ + public function getTagsOfEntryComment(EntryComment $entryComment): array + { + $result = $this->findBy(['entryComment' => $entryComment]); + + return array_map(fn ($row) => $row->hashtag->tag, $result); + } + + public function removeTagOfEntryComment(EntryComment $entryComment, Hashtag $tag): void + { + $link = $this->findOneBy(['entryComment' => $entryComment, 'hashtag' => $tag]); + $this->entityManager->remove($link); + $this->entityManager->flush(); + } + + public function addTagToEntryComment(EntryComment $entryComment, Hashtag $tag): void + { + $link = new HashtagLink(); + $link->entryComment = $entryComment; + $link->hashtag = $tag; + $this->entityManager->persist($link); + $this->entityManager->flush(); + } + + /** + * @return string[] + */ + public function getTagsOfPost(Post $post): array + { + $result = $this->findBy(['post' => $post]); + + return array_map(fn ($row) => $row->hashtag->tag, $result); + } + + public function removeTagOfPost(Post $post, Hashtag $tag): void + { + $link = $this->findOneBy(['post' => $post, 'hashtag' => $tag]); + $this->entityManager->remove($link); + $this->entityManager->flush(); + } + + public function addTagToPost(Post $post, Hashtag $tag): void + { + $link = new HashtagLink(); + $link->post = $post; + $link->hashtag = $tag; + $this->entityManager->persist($link); + $this->entityManager->flush(); + } + + /** + * @return string[] + */ + public function getTagsOfPostComment(PostComment $postComment): array + { + $result = $this->findBy(['postComment' => $postComment]); + + return array_map(fn ($row) => $row->hashtag->tag, $result); + } + + public function removeTagOfPostComment(PostComment $postComment, Hashtag $tag): void + { + $link = $this->findOneBy(['postComment' => $postComment, 'hashtag' => $tag]); + $this->entityManager->remove($link); + $this->entityManager->flush(); + } + + public function addTagToPostComment(PostComment $postComment, Hashtag $tag): void + { + $link = new HashtagLink(); + $link->postComment = $postComment; + $link->hashtag = $tag; + $this->entityManager->persist($link); + $this->entityManager->flush(); + } +} diff --git a/src/Repository/TagRepository.php b/src/Repository/TagRepository.php index f133f1abd..a59d2b926 100644 --- a/src/Repository/TagRepository.php +++ b/src/Repository/TagRepository.php @@ -5,86 +5,78 @@ namespace App\Repository; use App\Entity\Contracts\VisibilityInterface; -use App\Entity\Entry; -use App\Entity\EntryComment; -use App\Entity\Post; -use App\Entity\PostComment; +use App\Entity\Hashtag; +use App\Pagination\NativeQueryAdapter; +use App\Pagination\Transformation\ContentPopulationTransformer; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\ORM\EntityManagerInterface; -use Pagerfanta\Adapter\ArrayAdapter; +use Doctrine\Persistence\ManagerRegistry; +use JetBrains\PhpStorm\ArrayShape; use Pagerfanta\Exception\NotValidCurrentPageException; use Pagerfanta\Pagerfanta; use Pagerfanta\PagerfantaInterface; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; -class TagRepository +/** + * @method Hashtag|null find($id, $lockMode = null, $lockVersion = null) + * @method Hashtag|null findOneBy(array $criteria, array $orderBy = null) + * @method Hashtag[] findAll() + * @method Hashtag[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) + */ +class TagRepository extends ServiceEntityRepository { public const PER_PAGE = 25; - public function __construct(private EntityManagerInterface $entityManager) - { + public function __construct( + ManagerRegistry $registry, + private readonly EntityManagerInterface $entityManager, + private readonly TagLinkRepository $tagLinkRepository, + private readonly ContentPopulationTransformer $populationTransformer + ) { + parent::__construct($registry, Hashtag::class); } public function findOverall(int $page, string $tag): PagerfantaInterface { - // @todo union adapter + $hashtag = $this->findBy(['tag' => $tag]); + $countAll = $this->tagLinkRepository->createQueryBuilder('link') + ->select('count(link.id)') + ->where('link.hashtag = :tag') + ->setParameter(':tag', $hashtag) + ->getQuery() + ->getSingleScalarResult(); + $conn = $this->entityManager->getConnection(); - $sql = " - (SELECT id, created_at, 'entry' AS type FROM entry WHERE tags @> :tag = true AND visibility = :visibility) - UNION - (SELECT id, created_at, 'entry_comment' AS type FROM entry_comment WHERE tags @> :tag = true AND visibility = :visibility) - UNION - (SELECT id, created_at, 'post' AS type FROM post WHERE tags @> :tag = true AND visibility = :visibility) - UNION - (SELECT id, created_at, 'post_comment' AS type FROM post_comment WHERE tags @> :tag = true AND visibility = :visibility) + $sql = "SELECT e.id, e.created_at, 'entry' AS type FROM entry e + INNER JOIN hashtag_link l ON e.id = l.entry_id + INNER JOIN hashtag h ON l.hashtag_id = h.id AND h.tag = :tag + WHERE visibility = :visibility + UNION ALL + SELECT ec.id, ec.created_at, 'entry_comment' AS type FROM entry_comment ec + INNER JOIN hashtag_link l ON ec.id = l.entry_comment_id + INNER JOIN hashtag h ON l.hashtag_id = h.id AND h.tag = :tag + WHERE visibility = :visibility + UNION ALL + SELECT p.id, p.created_at, 'post' AS type FROM post p + INNER JOIN hashtag_link l ON p.id = l.post_id + INNER JOIN hashtag h ON l.hashtag_id = h.id AND h.tag = :tag + WHERE visibility = :visibility + UNION ALL + SELECT pc.id, created_at, 'post_comment' AS type FROM post_comment pc + INNER JOIN hashtag_link l ON pc.id = l.post_comment_id + INNER JOIN hashtag h ON l.hashtag_id = h.id AND h.tag = :tag WHERE visibility = :visibility ORDER BY created_at DESC"; - $stmt = $conn->prepare($sql); - $stmt->bindValue('tag', "\"$tag\""); - $stmt->bindValue('visibility', VisibilityInterface::VISIBILITY_VISIBLE); - $stmt = $stmt->executeQuery(); - $pagerfanta = new Pagerfanta( - new ArrayAdapter( - $stmt->fetchAllAssociative() - ) - ); + $adapter = new NativeQueryAdapter($conn, $sql, [ + 'tag' => $tag, + 'visibility' => VisibilityInterface::VISIBILITY_VISIBLE, + ], $countAll, $this->populationTransformer); - $countAll = $pagerfanta->count(); - - try { - $pagerfanta->setMaxPerPage(20000); - $pagerfanta->setCurrentPage(1); - } catch (NotValidCurrentPageException $e) { - throw new NotFoundHttpException(); - } - - $result = $pagerfanta->getCurrentPageResults(); - - $entries = $this->entityManager->getRepository(Entry::class)->findBy( - ['id' => $this->getOverviewIds((array) $result, 'entry')] - ); - $entryComments = $this->entityManager->getRepository(EntryComment::class)->findBy( - ['id' => $this->getOverviewIds((array) $result, 'entry_comment')] - ); - $post = $this->entityManager->getRepository(Post::class)->findBy( - ['id' => $this->getOverviewIds((array) $result, 'post')] - ); - $postComment = $this->entityManager->getRepository(PostComment::class)->findBy( - ['id' => $this->getOverviewIds((array) $result, 'post_comment')] - ); - - $result = array_merge($entries, $entryComments, $post, $postComment); - uasort($result, fn ($a, $b) => $a->getCreatedAt() > $b->getCreatedAt() ? -1 : 1); - - $pagerfanta = new Pagerfanta( - new ArrayAdapter( - $result - ) - ); + $pagerfanta = new Pagerfanta($adapter); try { $pagerfanta->setMaxPerPage(self::PER_PAGE); $pagerfanta->setCurrentPage($page); - $pagerfanta->setMaxNbPages($countAll > 0 ? ((int) ceil($countAll / self::PER_PAGE)) : 1); } catch (NotValidCurrentPageException $e) { throw new NotFoundHttpException(); } @@ -92,10 +84,38 @@ public function findOverall(int $page, string $tag): PagerfantaInterface return $pagerfanta; } - private function getOverviewIds(array $result, string $type): array + public function create(string $tag): Hashtag + { + $entity = new Hashtag(); + $entity->tag = $tag; + $this->entityManager->persist($entity); + $this->entityManager->flush(); + + return $entity; + } + + #[ArrayShape([ + 'entry' => 'int', + 'entry_comment' => 'int', + 'post' => 'int', + 'post_comment' => 'int', + ])] + public function getCounts(string $tag): ?array { - $result = array_filter($result, fn ($subject) => $subject['type'] === $type); + $conn = $this->entityManager->getConnection(); + $stmt = $conn->prepare('SELECT COUNT(entry_id) as entry, COUNT(entry_comment_id) as entry_comment, COUNT(post_id) as post, COUNT(post_comment_id) as post_comment + FROM hashtag_link INNER JOIN public.hashtag h ON h.id = hashtag_link.hashtag_id AND h.tag = :tag GROUP BY h.tag'); + $stmt->bindValue('tag', $tag); + $result = $stmt->executeQuery()->fetchAllAssociative(); + if (1 === \sizeof($result)) { + return $result[0]; + } - return array_map(fn ($subject) => $subject['id'], $result); + return [ + 'entry' => 0, + 'entry_comment' => 0, + 'post' => 0, + 'post_comment' => 0, + ]; } } diff --git a/src/Service/ActivityPub/MarkdownConverter.php b/src/Service/ActivityPub/MarkdownConverter.php index 3cb3a9c0f..5bd477bba 100644 --- a/src/Service/ActivityPub/MarkdownConverter.php +++ b/src/Service/ActivityPub/MarkdownConverter.php @@ -6,14 +6,14 @@ use App\Service\ActivityPubManager; use App\Service\MentionManager; -use App\Service\TagManager; +use App\Service\TagExtractor; use League\HTMLToMarkdown\Converter\TableConverter; use League\HTMLToMarkdown\HtmlConverter; class MarkdownConverter { public function __construct( - private readonly TagManager $tagManager, + private readonly TagExtractor $tagExtractor, private readonly MentionManager $mentionManager, private readonly ActivityPubManager $activityPubManager ) { @@ -37,7 +37,7 @@ public function convert(string $value): string $value = str_replace($match[0], $replace, $value); } - if ($this->tagManager->extract($match[1])) { + if ($this->tagExtractor->extract($match[1])) { $value = str_replace($match[0], $match[1], $value); } } diff --git a/src/Service/ActivityPub/Note.php b/src/Service/ActivityPub/Note.php index 902c9cda3..af7e973d5 100644 --- a/src/Service/ActivityPub/Note.php +++ b/src/Service/ActivityPub/Note.php @@ -15,6 +15,8 @@ use App\Entity\Post; use App\Entity\PostComment; use App\Entity\User; +use App\Exception\TagBannedException; +use App\Exception\UserBannedException; use App\Factory\ImageFactory; use App\Repository\ApActivityRepository; use App\Service\ActivityPubManager; @@ -35,13 +37,17 @@ public function __construct( private readonly PostCommentManager $postCommentManager, private readonly ActivityPubManager $activityPubManager, private readonly EntityManagerInterface $entityManager, - private readonly MarkdownConverter $markdownConverter, private readonly SettingsManager $settingsManager, private readonly ImageFactory $imageFactory, private readonly ApObjectExtractor $objectExtractor, ) { } + /** + * @throws TagBannedException + * @throws UserBannedException + * @throws \Exception + */ public function create(array $object, array $root = null): EntryComment|PostComment|Post { $current = $this->repository->findByObjectId($object['id']); @@ -90,6 +96,11 @@ public function create(array $object, array $root = null): EntryComment|PostComm return $this->createPost($object); } + /** + * @throws TagBannedException + * @throws UserBannedException + * @throws \Exception + */ private function createEntryComment(array $object, ActivityPubActivityInterface $parent, ActivityPubActivityInterface $root = null): EntryComment { $dto = new EntryCommentDto(); diff --git a/src/Service/ActivityPub/Page.php b/src/Service/ActivityPub/Page.php index da34ef7db..e0c837ab1 100644 --- a/src/Service/ActivityPub/Page.php +++ b/src/Service/ActivityPub/Page.php @@ -12,19 +12,21 @@ use App\Entity\Contracts\VisibilityInterface; use App\Entity\Entry; use App\Entity\User; +use App\Exception\TagBannedException; +use App\Exception\UserBannedException; use App\Factory\ImageFactory; use App\Repository\ApActivityRepository; use App\Service\ActivityPubManager; use App\Service\EntryManager; use App\Service\SettingsManager; use Doctrine\ORM\EntityManagerInterface; +use Exception; use Psr\Log\LoggerInterface; class Page { public function __construct( private readonly ApActivityRepository $repository, - private readonly MarkdownConverter $markdownConverter, private readonly EntryManager $entryManager, private readonly ActivityPubManager $activityPubManager, private readonly EntityManagerInterface $entityManager, @@ -35,12 +37,17 @@ public function __construct( ) { } + /** + * @throws TagBannedException + * @throws UserBannedException + * @throws \Exception if the user could not be found or a sub exception occurred + */ public function create(array $object): Entry { $actor = $this->activityPubManager->findActorOrCreate($object['attributedTo']); if (!empty($actor)) { if ($actor->isBanned) { - throw new \Exception('User is banned.'); + throw new UserBannedException(); } $current = $this->repository->findByObjectId($object['id']); @@ -101,6 +108,9 @@ public function create(array $object): Entry } } + /** + * @throws \Exception + */ private function getVisibility(array $object, User $actor): string { if (!\in_array( @@ -147,6 +157,9 @@ private function handleUrl(EntryDto $dto, ?array $object): void } } + /** + * @throws \Exception + */ private function handleDate(EntryDto $dto, string $date): void { $dto->createdAt = new \DateTimeImmutable($date); diff --git a/src/Service/EntryCommentManager.php b/src/Service/EntryCommentManager.php index d720acbee..380b76db9 100644 --- a/src/Service/EntryCommentManager.php +++ b/src/Service/EntryCommentManager.php @@ -15,6 +15,7 @@ use App\Event\EntryComment\EntryCommentEditedEvent; use App\Event\EntryComment\EntryCommentPurgedEvent; use App\Event\EntryComment\EntryCommentRestoredEvent; +use App\Exception\TagBannedException; use App\Exception\UserBannedException; use App\Factory\EntryCommentFactory; use App\Message\DeleteImageMessage; @@ -31,6 +32,7 @@ class EntryCommentManager implements ContentManagerInterface { public function __construct( private readonly TagManager $tagManager, + private readonly TagExtractor $tagExtractor, private readonly MentionManager $mentionManager, private readonly EntryCommentFactory $factory, private readonly RateLimiterFactory $entryCommentLimiter, @@ -54,6 +56,10 @@ public function create(EntryCommentDto $dto, User $user, $rateLimit = true): Ent throw new UserBannedException(); } + if ($this->tagManager->isAnyTagBanned($this->tagManager->extract($dto->body))) { + throw new TagBannedException(); + } + $comment = $this->factory->createFromDto($dto, $user); $comment->magazine = $dto->entry->magazine; @@ -63,7 +69,6 @@ public function create(EntryCommentDto $dto, User $user, $rateLimit = true): Ent if ($comment->image && !$comment->image->altText) { $comment->image->altText = $dto->imageAlt; } - $comment->tags = $dto->body ? $this->tagManager->extract($dto->body, $comment->magazine->name) : null; $comment->mentions = $dto->body ? array_merge($dto->mentions ?? [], $this->mentionManager->handleChain($comment)) : $dto->mentions; @@ -82,6 +87,8 @@ public function create(EntryCommentDto $dto, User $user, $rateLimit = true): Ent $this->entityManager->persist($comment); $this->entityManager->flush(); + $this->tagManager->updateEntryCommentTags($comment, $this->tagExtractor->extract($comment->body) ?? []); + $this->dispatcher->dispatch(new EntryCommentCreatedEvent($comment)); return $comment; @@ -98,7 +105,7 @@ public function edit(EntryComment $comment, EntryCommentDto $dto): EntryComment if ($dto->image) { $comment->image = $this->imageRepository->find($dto->image->id); } - $comment->tags = $dto->body ? $this->tagManager->extract($dto->body, $comment->magazine->name) : null; + $this->tagManager->updateEntryCommentTags($comment, $this->tagManager->getTagsFromEntryCommentDto($dto)); $comment->mentions = $dto->body ? array_merge($dto->mentions ?? [], $this->mentionManager->handleChain($comment)) : $dto->mentions; diff --git a/src/Service/EntryManager.php b/src/Service/EntryManager.php index e7f44b1ea..d26979cc8 100644 --- a/src/Service/EntryManager.php +++ b/src/Service/EntryManager.php @@ -16,6 +16,7 @@ use App\Event\Entry\EntryEditedEvent; use App\Event\Entry\EntryPinEvent; use App\Event\Entry\EntryRestoredEvent; +use App\Exception\TagBannedException; use App\Exception\UserBannedException; use App\Factory\EntryFactory; use App\Message\DeleteImageMessage; @@ -39,6 +40,7 @@ class EntryManager implements ContentManagerInterface { public function __construct( private readonly LoggerInterface $logger, + private readonly TagExtractor $tagExtractor, private readonly TagManager $tagManager, private readonly MentionManager $mentionManager, private readonly EntryCommentManager $entryCommentManager, @@ -57,6 +59,12 @@ public function __construct( ) { } + /** + * @throws TagBannedException + * @throws UserBannedException + * @throws TooManyRequestsHttpException + * @throws \Exception if title, body and image are empty + */ public function create(EntryDto $dto, User $user, bool $rateLimit = true): Entry { if ($rateLimit) { @@ -70,6 +78,10 @@ public function create(EntryDto $dto, User $user, bool $rateLimit = true): Entry throw new UserBannedException(); } + if ($this->tagManager->isAnyTagBanned($this->tagManager->extract($dto->body))) { + throw new TagBannedException(); + } + $this->logger->debug('creating entry from dto'); $entry = $this->factory->createFromDto($dto, $user); @@ -81,10 +93,6 @@ public function create(EntryDto $dto, User $user, bool $rateLimit = true): Entry if ($entry->image && !$entry->image->altText) { $entry->image->altText = $dto->imageAlt; } - $entry->tags = $dto->tags ? $this->tagManager->extract( - implode(' ', array_map(fn ($tag) => str_starts_with($tag, '#') ? $tag : '#'.$tag, $dto->tags)), - $entry->magazine->name - ) : null; $entry->mentions = $dto->body ? $this->mentionManager->extract($dto->body) : null; $entry->visibility = $dto->visibility; $entry->apId = $dto->apId; @@ -105,6 +113,8 @@ public function create(EntryDto $dto, User $user, bool $rateLimit = true): Entry $this->entityManager->persist($entry); $this->entityManager->flush(); + $this->tagManager->updateEntryTags($entry, $this->tagExtractor->extract($entry->body) ?? []); + $this->dispatcher->dispatch(new EntryCreatedEvent($entry)); return $entry; @@ -154,10 +164,8 @@ public function edit(Entry $entry, EntryDto $dto): Entry if ($dto->image) { $entry->image = $this->imageRepository->find($dto->image->id); } - $entry->tags = $dto->tags ? $this->tagManager->extract( - implode(' ', array_map(fn ($tag) => str_starts_with($tag, '#') ? $tag : '#'.$tag, $dto->tags)), - $entry->magazine->name - ) : null; + $this->tagManager->updateEntryTags($entry, $this->tagManager->getTagsFromEntryDto($dto)); + $entry->mentions = $dto->body ? $this->mentionManager->extract($dto->body) : null; $entry->isOc = $dto->isOc; $entry->lang = $dto->lang; diff --git a/src/Service/FeedManager.php b/src/Service/FeedManager.php index 594a8daef..195656a31 100644 --- a/src/Service/FeedManager.php +++ b/src/Service/FeedManager.php @@ -10,6 +10,7 @@ use App\Repository\Criteria; use App\Repository\EntryRepository; use App\Repository\MagazineRepository; +use App\Repository\TagLinkRepository; use App\Repository\UserRepository; use App\Utils\IriGenerator; use FeedIo\Feed; @@ -27,6 +28,7 @@ public function __construct( private readonly EntryRepository $entryRepository, private readonly MagazineRepository $magazineRepository, private readonly UserRepository $userRepository, + private readonly TagLinkRepository $tagLinkRepository, private readonly RouterInterface $router, private readonly EntryFactory $entryFactory, ) { @@ -111,7 +113,7 @@ public function getEntries(\ArrayIterator $entries): \Generator $item->setPublicId(IriGenerator::getIriFromResource($entry)); $item->setAuthor((new Item\Author())->setName($entry->user->username)); - foreach ($entry->getTags() as $tag) { + foreach ($this->tagLinkRepository->getTagsOfEntry($entry) as $tag) { $category = new Category(); $category->setLabel($tag); diff --git a/src/Service/PostCommentManager.php b/src/Service/PostCommentManager.php index 45e99324a..50d56993d 100644 --- a/src/Service/PostCommentManager.php +++ b/src/Service/PostCommentManager.php @@ -15,6 +15,7 @@ use App\Event\PostComment\PostCommentEditedEvent; use App\Event\PostComment\PostCommentPurgedEvent; use App\Event\PostComment\PostCommentRestoredEvent; +use App\Exception\TagBannedException; use App\Exception\UserBannedException; use App\Factory\PostCommentFactory; use App\Message\DeleteImageMessage; @@ -31,6 +32,7 @@ class PostCommentManager implements ContentManagerInterface { public function __construct( private readonly TagManager $tagManager, + private readonly TagExtractor $tagExtractor, private readonly MentionManager $mentionManager, private readonly PostCommentFactory $factory, private readonly ImageRepository $imageRepository, @@ -41,6 +43,12 @@ public function __construct( ) { } + /** + * @throws TagBannedException + * @throws UserBannedException + * @throws TooManyRequestsHttpException + * @throws \Exception + */ public function create(PostCommentDto $dto, User $user, $rateLimit = true): PostComment { if ($rateLimit) { @@ -54,6 +62,10 @@ public function create(PostCommentDto $dto, User $user, $rateLimit = true): Post throw new UserBannedException(); } + if ($this->tagManager->isAnyTagBanned($this->tagManager->extract($dto->body))) { + throw new TagBannedException(); + } + $comment = $this->factory->createFromDto($dto, $user); $comment->magazine = $dto->post->magazine; @@ -63,7 +75,6 @@ public function create(PostCommentDto $dto, User $user, $rateLimit = true): Post if ($comment->image && !$comment->image->altText) { $comment->image->altText = $dto->imageAlt; } - $comment->tags = $dto->body ? $this->tagManager->extract($dto->body, $comment->magazine->name) : null; $comment->mentions = $dto->body ? array_merge($dto->mentions ?? [], $this->mentionManager->handleChain($comment)) : $dto->mentions; @@ -82,11 +93,16 @@ public function create(PostCommentDto $dto, User $user, $rateLimit = true): Post $this->entityManager->persist($comment); $this->entityManager->flush(); + $this->tagManager->updatePostCommentTags($comment, $this->tagExtractor->extract($comment->body) ?? []); + $this->dispatcher->dispatch(new PostCommentCreatedEvent($comment)); return $comment; } + /** + * @throws \Exception + */ public function edit(PostComment $comment, PostCommentDto $dto): PostComment { Assert::same($comment->post->getId(), $dto->post->getId()); @@ -98,7 +114,7 @@ public function edit(PostComment $comment, PostCommentDto $dto): PostComment if ($dto->image) { $comment->image = $this->imageRepository->find($dto->image->id); } - $comment->tags = $dto->body ? $this->tagManager->extract($dto->body, $comment->magazine->name) : null; + $this->tagManager->updatePostCommentTags($comment, $this->tagExtractor->extract($dto->body) ?? []); $comment->mentions = $dto->body ? array_merge($dto->mentions ?? [], $this->mentionManager->handleChain($comment)) : $dto->mentions; @@ -173,6 +189,9 @@ private function isTrashed(User $user, PostComment $comment): bool return !$comment->isAuthor($user); } + /** + * @throws \Exception + */ public function restore(User $user, PostComment $comment): void { if (VisibilityInterface::VISIBILITY_TRASHED !== $comment->visibility) { diff --git a/src/Service/PostManager.php b/src/Service/PostManager.php index 5af466ac8..6deff08c0 100644 --- a/src/Service/PostManager.php +++ b/src/Service/PostManager.php @@ -15,6 +15,7 @@ use App\Event\Post\PostDeletedEvent; use App\Event\Post\PostEditedEvent; use App\Event\Post\PostRestoredEvent; +use App\Exception\TagBannedException; use App\Exception\UserBannedException; use App\Factory\PostFactory; use App\Message\DeleteImageMessage; @@ -41,6 +42,7 @@ public function __construct( private readonly MentionManager $mentionManager, private readonly PostCommentManager $postCommentManager, private readonly TagManager $tagManager, + private readonly TagExtractor $tagExtractor, private readonly PostFactory $factory, private readonly EventDispatcherInterface $dispatcher, private readonly RateLimiterFactory $postLimiter, @@ -53,6 +55,12 @@ public function __construct( ) { } + /** + * @throws TagBannedException + * @throws UserBannedException + * @throws TooManyRequestsHttpException + * @throws \Exception + */ public function create(PostDto $dto, User $user, $rateLimit = true): Post { if ($rateLimit) { @@ -66,6 +74,10 @@ public function create(PostDto $dto, User $user, $rateLimit = true): Post throw new UserBannedException(); } + if ($this->tagManager->isAnyTagBanned($this->tagManager->extract($dto->body))) { + throw new TagBannedException(); + } + $post = $this->factory->createFromDto($dto, $user); $post->lang = $dto->lang; @@ -76,7 +88,6 @@ public function create(PostDto $dto, User $user, $rateLimit = true): Post if ($post->image && !$post->image->altText) { $post->image->altText = $dto->imageAlt; } - $post->tags = $dto->body ? $this->tagManager->extract($dto->body, $post->magazine->name) : null; $post->mentions = $dto->body ? $this->mentionManager->extract($dto->body) : null; $post->visibility = $dto->visibility; $post->apId = $dto->apId; @@ -91,6 +102,8 @@ public function create(PostDto $dto, User $user, $rateLimit = true): Post $this->entityManager->persist($post); $this->entityManager->flush(); + $this->tagManager->updatePostTags($post, $this->tagExtractor->extract($post->body) ?? []); + $this->dispatcher->dispatch(new PostCreatedEvent($post)); return $post; @@ -108,7 +121,7 @@ public function edit(Post $post, PostDto $dto): Post if ($dto->image) { $post->image = $this->imageRepository->find($dto->image->id); } - $post->tags = $dto->body ? $this->tagManager->extract($dto->body, $post->magazine->name) : null; + $this->tagManager->updatePostTags($post, $this->tagExtractor->extract($dto->body) ?? []); $post->mentions = $dto->body ? $this->mentionManager->extract($dto->body) : null; $post->visibility = $dto->visibility; $post->editedAt = new \DateTimeImmutable('@'.time()); diff --git a/src/Service/TagExtractor.php b/src/Service/TagExtractor.php new file mode 100644 index 000000000..b1140c4ab --- /dev/null +++ b/src/Service/TagExtractor.php @@ -0,0 +1,81 @@ +extract($body) ?? []; + + $join = array_unique(array_merge(array_diff($tags, $current))); + + if (!empty($join)) { + if (!empty($body)) { + $lastTag = end($current); + if (($lastTag && !str_ends_with($body, $lastTag)) || !$lastTag) { + $body = $body.PHP_EOL.PHP_EOL; + } + } + + $body = $body.' #'.implode(' #', $join); + } + + return $body; + } + + public function extract(?string $val, string $magazineName = null): ?array + { + if (null === $val) { + return null; + } + + preg_match_all(RegPatterns::LOCAL_TAG, $val, $matches); + + $result = $matches[1]; + $result = array_map(fn ($tag) => mb_strtolower(trim($tag)), $result); + + $result = array_values($result); + + $result = array_map(fn ($tag) => $this->transliterate($tag), $result); + + if ($magazineName) { + $result = array_diff($result, [$magazineName]); + } + + return \count($result) ? array_unique(array_values($result)) : null; + } + + /** + * transliterate and normalize a hashtag identifier. + * + * mostly recreates Mastodon's hashtag normalization rules, using ICU rules + * - try to transliterate modified latin characters to ASCII regions + * - normalize widths for fullwidth/halfwidth letters + * - strip characters that shouldn't be part of a hashtag + * (borrowed the character set from Mastodon) + * + * @param string $tag input hashtag identifier to normalize + * + * @return string normalized hashtag identifier + * + * @see https://github.com/mastodon/mastodon/blob/main/app/lib/hashtag_normalizer.rb + * @see https://github.com/mastodon/mastodon/blob/main/app/models/tag.rb + */ + public function transliterate(string $tag): string + { + $rules = <<<'ENDRULE' + :: Latin-ASCII; + :: [\uFF00-\uFFEF] NFKC; + :: [^[:alnum:][\u0E47-\u0E4E][_\u00B7\u30FB\u200c]] Remove; + ENDRULE; + + $normalizer = \Transliterator::createFromRules($rules); + + return iconv('UTF-8', 'UTF-8//TRANSLIT', $normalizer->transliterate($tag)); + } +} diff --git a/src/Service/TagManager.php b/src/Service/TagManager.php index 072c029a9..cc7f11385 100644 --- a/src/Service/TagManager.php +++ b/src/Service/TagManager.php @@ -4,74 +4,177 @@ namespace App\Service; -use App\Utils\RegPatterns; +use App\DTO\EntryCommentDto; +use App\DTO\EntryDto; +use App\Entity\Entry; +use App\Entity\EntryComment; +use App\Entity\Hashtag; +use App\Entity\Post; +use App\Entity\PostComment; +use App\Repository\TagLinkRepository; +use App\Repository\TagRepository; +use Doctrine\ORM\EntityManagerInterface; +use JetBrains\PhpStorm\ArrayShape; class TagManager { - public function joinTagsToBody(string $body, array $tags): string - { - $current = $this->extract($body, null, false) ?? []; + public function __construct( + private readonly TagRepository $tagRepository, + private readonly TagLinkRepository $tagLinkRepository, + private readonly EntityManagerInterface $entityManager, + private readonly TagExtractor $tagExtractor, + ) { + } - $join = array_unique(array_merge(array_diff($tags, $current))); + public function extract(?string $val, string $magazineName = null): ?array + { + return $this->tagExtractor->extract($val, $magazineName); + } - if (!empty($join)) { - if (!empty($body)) { - $lastTag = end($current); - if (($lastTag && !str_ends_with($body, $lastTag)) || !$lastTag) { - $body = $body.PHP_EOL.PHP_EOL; - } - } + /** + * @param string[] $newTags + */ + public function updateEntryTags(Entry $entry, array $newTags): void + { + $this->updateTags($newTags, + fn () => $this->tagLinkRepository->getTagsOfEntry($entry), + fn (Hashtag $hashtag) => $this->tagLinkRepository->removeTagOfEntry($entry, $hashtag), + fn (Hashtag $hashtag) => $this->tagLinkRepository->addTagToEntry($entry, $hashtag) + ); + } - $body = $body.' #'.implode(' #', $join); - } + public function getTagsFromEntryDto(EntryDto $dto): array + { + return array_unique( + array_filter( + array_merge( + $dto->tags ?? [], + $this->tagExtractor->extract($dto->body ?? '') ?? [] + ) + ) + ); + } - return $body; + /** + * @param string[] $newTags + */ + public function updateEntryCommentTags(EntryComment $entryComment, array $newTags): void + { + $this->updateTags($newTags, + fn () => $this->tagLinkRepository->getTagsOfEntryComment($entryComment), + fn (Hashtag $hashtag) => $this->tagLinkRepository->removeTagOfEntryComment($entryComment, $hashtag), + fn (Hashtag $hashtag) => $this->tagLinkRepository->addTagToEntryComment($entryComment, $hashtag) + ); } - public function extract(string $val, string $magazineName = null): ?array + public function getTagsFromEntryCommentDto(EntryCommentDto $dto): array { - preg_match_all(RegPatterns::LOCAL_TAG, $val, $matches); + return array_unique( + array_filter( + array_merge( + $dto->tags ?? [], + $this->tagExtractor->extract($dto->body ?? '') ?? [] + ) + ) + ); + } - $result = $matches[1]; - $result = array_map(fn ($tag) => mb_strtolower(trim($tag)), $result); + /** + * @param string[] $newTags + */ + public function updatePostTags(Post $post, array $newTags): void + { + $this->updateTags($newTags, + fn () => $this->tagLinkRepository->getTagsOfPost($post), + fn (Hashtag $hashtag) => $this->tagLinkRepository->removeTagOfPost($post, $hashtag), + fn (Hashtag $hashtag) => $this->tagLinkRepository->addTagToPost($post, $hashtag) + ); + } - $result = array_values($result); + /** + * @param string[] $newTags + */ + public function updatePostCommentTags(PostComment $postComment, array $newTags): void + { + $this->updateTags($newTags, + fn () => $this->tagLinkRepository->getTagsOfPostComment($postComment), + fn (Hashtag $hashtag) => $this->tagLinkRepository->removeTagOfPostComment($postComment, $hashtag), + fn (Hashtag $hashtag) => $this->tagLinkRepository->addTagToPostComment($postComment, $hashtag) + ); + } - $result = array_map(fn ($tag) => $this->transliterate($tag), $result); + /** + * @param string[] $newTags + * @param callable(): string[] $getTags a callable that should return all the tags of the entity as a string array + * @param callable(Hashtag): void $removeTag a callable that gets a string as parameter and should remove the tag + * @param callable(Hashtag): void $addTag + */ + private function updateTags(array $newTags, callable $getTags, callable $removeTag, callable $addTag): void + { + $oldTags = $getTags(); + $actions = $this->intersectOldAndNewTags($oldTags, $newTags); + foreach ($actions['tagsToRemove'] as $tag) { + $removeTag($this->tagRepository->findOneBy(['tag' => $tag])); + } + foreach ($actions['tagsToCreate'] as $tag) { + $tagEntity = $this->tagRepository->findOneBy(['tag' => $tag]); + if (null === $tagEntity) { + $tagEntity = $this->tagRepository->create($tag); + } + $addTag($tagEntity); + } + } - if ($magazineName) { - $result = array_diff($result, [$magazineName]); + #[ArrayShape([ + 'tagsToRemove' => 'string[]', + 'tagsToCreate' => 'string[]', + ])] + private function intersectOldAndNewTags(array $oldTags, array $newTags): array + { + /** @var string[] $tagsToRemove */ + $tagsToRemove = []; + /** @var string[] $tagsToCreate */ + $tagsToCreate = []; + foreach ($oldTags as $tag) { + if (!\in_array($tag, $newTags)) { + $tagsToRemove[] = $tag; + } + } + foreach ($newTags as $tag) { + if (!\in_array($tag, $oldTags)) { + $tagsToCreate[] = $tag; + } } - return \count($result) ? array_unique(array_values($result)) : null; + return [ + 'tagsToCreate' => $tagsToCreate, + 'tagsToRemove' => $tagsToRemove, + ]; } - /** - * transliterate and normalize a hashtag identifier. - * - * mostly recreates Mastodon's hashtag normalization rules, using ICU rules - * - try to transliterate modified latin characters to ASCII regions - * - normalize widths for fullwidth/halfwidth letters - * - strip characters that shouldn't be part of a hashtag - * (borrowed the character set from Mastodon) - * - * @param string $tag input hashtag identifier to normalize - * - * @return normalized hashtag identifier - * - * @see https://github.com/mastodon/mastodon/blob/main/app/lib/hashtag_normalizer.rb - * @see https://github.com/mastodon/mastodon/blob/main/app/models/tag.rb - */ - public function transliterate(string $tag): string + public function ban(Hashtag $hashtag): void { - $rules = <<<'ENDRULE' - :: Latin-ASCII; - :: [\uFF00-\uFFEF] NFKC; - :: [^[:alnum:][\u0E47-\u0E4E][_\u00B7\u30FB\u200c]] Remove; - ENDRULE; + $hashtag->banned = true; + $this->entityManager->persist($hashtag); + $this->entityManager->flush(); + } - $normalizer = \Transliterator::createFromRules($rules); + public function unban(Hashtag $hashtag): void + { + $hashtag->banned = false; + $this->entityManager->persist($hashtag); + $this->entityManager->flush(); + } + + public function isAnyTagBanned(?array $tags): bool + { + if ($tags) { + $result = $this->tagRepository->findBy(['tag' => $tags, 'banned' => true]); + if ($result && 0 !== \sizeof($result)) { + return true; + } + } - return iconv('UTF-8', 'UTF-8//TRANSLIT', $normalizer->transliterate($tag)); + return false; } } diff --git a/src/Twig/Components/TagActionComponent.php b/src/Twig/Components/TagActionComponent.php new file mode 100644 index 000000000..f2d52a9e6 --- /dev/null +++ b/src/Twig/Components/TagActionComponent.php @@ -0,0 +1,13 @@ +security->isGranted('ROLE_ADMIN')) { + throw new AccessDeniedException(); + } + + $hashtag = $this->tagRepository->findOneBy(['tag' => $tag]); + if (null === $hashtag) { + return false; + } + + return $hashtag->banned; + } } diff --git a/templates/components/tag_actions.html.twig b/templates/components/tag_actions.html.twig new file mode 100644 index 000000000..970c841c0 --- /dev/null +++ b/templates/components/tag_actions.html.twig @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/templates/entry/_info.html.twig b/templates/entry/_info.html.twig index 2264936fd..62623a689 100644 --- a/templates/entry/_info.html.twig +++ b/templates/entry/_info.html.twig @@ -23,11 +23,11 @@
  • {{ 'added'|trans }}: {{ component('date', {date: entry.createdAt}) }}
- {% if entry.tags %} + {% if entry.hashtags is not empty %}

{{ 'tags'|trans }}

- {% for tag in entry.tags %} - #{{ tag }} + {% for link in entry.hashtags %} + #{{ link.hashtag.tag }} {% endfor %}
{% endif %} diff --git a/templates/layout/_sidebar.html.twig b/templates/layout/_sidebar.html.twig index 2aa709f8f..0c4401e6f 100644 --- a/templates/layout/_sidebar.html.twig +++ b/templates/layout/_sidebar.html.twig @@ -88,6 +88,9 @@ }) }} {% include 'magazine/_moderators_sidebar.html.twig' %} {% endif %} +{% if tag is defined and tag %} + {% include 'tag/_panel.html.twig' %} +{% endif %} {{ component('related_magazines', {magazine: magazine is defined and magazine ? magazine.name : null, tag: tag is defined and tag ? tag : null}) }} {% if not is_route_name_contains('people') %} {{ component('active_users', {magazine: magazine is defined and magazine ? magazine : null}) }} diff --git a/templates/magazine/panel/tags.html.twig b/templates/magazine/panel/tags.html.twig index 21a68bfd5..b75b8dfdd 100644 --- a/templates/magazine/panel/tags.html.twig +++ b/templates/magazine/panel/tags.html.twig @@ -23,7 +23,6 @@
{{ form_start(form) }} - {{ form_row(form.tags) }}
{{ form_row(form.submit, { 'label': 'save'|trans, attr: {class: 'btn btn__primary'} }) }}
diff --git a/templates/tag/_list.html.twig b/templates/tag/_list.html.twig new file mode 100644 index 000000000..f1b0d4b99 --- /dev/null +++ b/templates/tag/_list.html.twig @@ -0,0 +1,3 @@ +
+ {% include 'layout/_subject_list.html.twig' with {entryCommentAttributes: {showMagazineName: true, showEntryTitle: true}, postCommentAttributes: {withPost: false}} %} +
\ No newline at end of file diff --git a/templates/tag/_options.html.twig b/templates/tag/_options.html.twig index 52a451a9b..9058afa2e 100644 --- a/templates/tag/_options.html.twig +++ b/templates/tag/_options.html.twig @@ -1,16 +1,3 @@ diff --git a/templates/tag/_panel.html.twig b/templates/tag/_panel.html.twig new file mode 100644 index 000000000..4fdb29f24 --- /dev/null +++ b/templates/tag/_panel.html.twig @@ -0,0 +1,36 @@ +
+

{{ 'tag'|trans }}

+ +
+
+

+ + #{{ tag }} + +

+
+
+ + {{ component('tag_actions', {tag: tag}) }} + + {% if false %} + {{ component('magazine_sub', {magazine: magazine}) }} + + {% if showInfo %} +
    +
  • {{ 'subscribers'|trans }}: {{ computed.magazine.subscriptionsCount }}
  • +
+ {% endif %} + {% endif %} + +
    + {{ _self.meta_item('threads'|trans, counts["entry"]) }} + {{ _self.meta_item('comments'|trans, counts["entry_comment"]) }} + {{ _self.meta_item('posts'|trans, counts["post"]) }} + {{ _self.meta_item('replies'|trans, counts["post_comment"]) }} +
+ + {% macro meta_item(name, count) %} +
  • {{ name }}{{ count }}
  • + {% endmacro %} +
    diff --git a/templates/tag/overview.html.twig b/templates/tag/overview.html.twig index 485df4d5e..0c7006e8b 100644 --- a/templates/tag/overview.html.twig +++ b/templates/tag/overview.html.twig @@ -11,6 +11,24 @@ {% endblock %} {% block sidebar_top %} + {% if app.user and app.user.admin %} +
    +

    {{ 'admin_panel'|trans }}

    +
    +
    + + +
    +
    +
    + {% endif %} {% endblock %} {% block body %} @@ -19,6 +37,6 @@ 'show-comment-avatar': app.request.cookies.get(constant('App\\Controller\\User\\ThemeSettingsController::KBIN_COMMENTS_SHOW_USER_AVATAR')) is same as 'true' or not app.request.cookies.has(constant('App\\Controller\\User\\ThemeSettingsController::KBIN_COMMENTS_SHOW_USER_AVATAR')), 'show-post-avatar': app.request.cookies.get(constant('App\\Controller\\User\\ThemeSettingsController::KBIN_POSTS_SHOW_USERS_AVATARS')) is same as 'true' or not app.request.cookies.has(constant('App\\Controller\\User\\ThemeSettingsController::KBIN_POSTS_SHOW_USERS_AVATARS')) }) }}"> - {% include 'layout/_subject_list.html.twig' with {entryCommentAttributes: {showMagazineName: true, showEntryTitle: true}, postCommentAttributes: {withPost: false}} %} + {% include 'tag/_list.html.twig' %}
    {% endblock %} diff --git a/tests/Unit/Service/TagManagerTest.php b/tests/Unit/Service/TagExtractorTest.php similarity index 91% rename from tests/Unit/Service/TagManagerTest.php rename to tests/Unit/Service/TagExtractorTest.php index 0a14a3ada..6716b7fa0 100644 --- a/tests/Unit/Service/TagManagerTest.php +++ b/tests/Unit/Service/TagExtractorTest.php @@ -4,17 +4,17 @@ namespace App\Tests\Unit\Service; -use App\Service\TagManager; +use App\Service\TagExtractor; use PHPUnit\Framework\TestCase; -class TagManagerTest extends TestCase +class TagExtractorTest extends TestCase { /** * @dataProvider provider */ public function testExtract(string $input, ?array $output): void { - $this->assertEquals($output, (new TagManager())->extract($input, 'kbin')); + $this->assertEquals($output, (new TagExtractor())->extract($input, 'kbin')); } public static function provider(): array diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml index 8d6185de8..b78fb8cd2 100644 --- a/translations/messages.en.yaml +++ b/translations/messages.en.yaml @@ -125,6 +125,7 @@ url: URL title: Title body: Body tags: Tags +tag: Tag badges: Badges is_adult: 18+ / NSFW eng: ENG @@ -310,6 +311,13 @@ magazine_panel: Magazine panel reject: Reject approve: Approve ban: Ban +unban: Unban +ban_hashtag_btn: Ban Hashtag +ban_hashtag_description: Banning a hashtag will stop posts with this hashtag from being created, + as well as hiding existing posts with this hashtag. +unban_hashtag_btn: Unban Hashtag +unban_hashtag_description: Unbanning a hashtag will allow creating posts with this hashtag again. + Existing posts with this hashtag are no longer hidden. filters: Filters approved: Approved rejected: Rejected @@ -732,6 +740,7 @@ position_bottom: Bottom position_top: Top pending: Pending flash_thread_new_error: Thread could not be created. Something went wrong. +flash_thread_tag_banned_error: Thread could not be created. The content is not allowed. flash_email_was_sent: Email has been successfully sent. flash_email_failed_to_sent: Email could not be sent. flash_post_new_success: Post has been successfully created. From 60ebebd17e40124b4edd19fec87b56a0cc0651ac Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Tue, 14 May 2024 20:14:35 +0200 Subject: [PATCH 009/335] Extend AI user agent bot ban list (#779) --- public/robots.txt | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/public/robots.txt b/public/robots.txt index 2d1e03d5a..65037c88a 100644 --- a/public/robots.txt +++ b/public/robots.txt @@ -1,10 +1,40 @@ -# Ban ChatGPT from indexing Mbin instances at all, in order to prevent training their [the OpenAI] models on users' data. +# Ban several AI bots from indexing Mbin instances at all, in order to prevent training their models on users' data. + +# OpenAI, ChatGPT User-agent: GPTBot Disallow: / User-agent: ChatGPT-User Disallow: / +# Google AI (Gemini, etc) +User-agent: Google-Extended +Disallow: / + +# Block common crawl +User-agent: CCBot +Disallow: / + +# Facebook +User-agent: FacebookBot +Disallow: / + +# Cohere.ai +User-agent: cohere-ai +Disallow: / + +# Perplexity +User-agent: PerplexityBot +Disallow: / + +# Anthropic +User-agent: anthropic-ai +Disallow: / + +# ...also anthropic +User-agent: ClaudeBot +Disallow: / + # Rest of indexing robots User-agent: * Request-rate: 1/1s From 3e9fb21662ef0a2b3d9386b0cd7926ca96aecb50 Mon Sep 17 00:00:00 2001 From: debounced <35878315+nobodyatroot@users.noreply.github.com> Date: Tue, 14 May 2024 14:12:09 -0500 Subject: [PATCH 010/335] Add SimpleLogin SSO (#762) Co-authored-by: e-five <146029455+e-five256@users.noreply.github.com> --- .env.example | 2 + .env.example_docker | 2 + config/kbin_routes/security.yaml | 10 + config/packages/knpu_oauth2_client.yaml | 7 + config/packages/security.yaml | 1 + config/services.yaml | 3 + migrations/Version20240503224350.php | 29 +++ .../Security/SimpleLoginController.php | 28 +++ src/Entity/User.php | 4 +- src/Provider/SimpleLogin.php | 72 +++++++ src/Provider/SimpleLoginResourceOwner.php | 58 ++++++ src/Security/SimpleLoginAuthenticator.php | 185 ++++++++++++++++++ src/Twig/Components/LoginSocialsComponent.php | 7 + templates/components/login_socials.html.twig | 6 +- 14 files changed, 412 insertions(+), 2 deletions(-) create mode 100644 migrations/Version20240503224350.php create mode 100644 src/Controller/Security/SimpleLoginController.php create mode 100644 src/Provider/SimpleLogin.php create mode 100644 src/Provider/SimpleLoginResourceOwner.php create mode 100644 src/Security/SimpleLoginAuthenticator.php diff --git a/.env.example b/.env.example index a551b36af..a27414961 100644 --- a/.env.example +++ b/.env.example @@ -75,6 +75,8 @@ OAUTH_KEYCLOAK_SECRET= OAUTH_KEYCLOAK_URI= OAUTH_KEYCLOAK_REALM= OAUTH_KEYCLOAK_VERSION= +OAUTH_SIMPLELOGIN_ID= +OAUTH_SIMPLELOGIN_SECRET= OAUTH_ZITADEL_ID= OAUTH_ZITADEL_SECRET= OAUTH_ZITADEL_BASE_URL= diff --git a/.env.example_docker b/.env.example_docker index 337c8a451..635c94f81 100644 --- a/.env.example_docker +++ b/.env.example_docker @@ -72,6 +72,8 @@ OAUTH_KEYCLOAK_SECRET= OAUTH_KEYCLOAK_URI= OAUTH_KEYCLOAK_REALM= OAUTH_KEYCLOAK_VERSION= +OAUTH_SIMPLELOGIN_ID= +OAUTH_SIMPLELOGIN_SECRET= OAUTH_ZITADEL_ID= OAUTH_ZITADEL_SECRET= OAUTH_ZITADEL_BASE_URL= diff --git a/config/kbin_routes/security.yaml b/config/kbin_routes/security.yaml index 11661e39a..897886ff1 100644 --- a/config/kbin_routes/security.yaml +++ b/config/kbin_routes/security.yaml @@ -93,6 +93,16 @@ oauth_keycloak_verify: path: /oauth/keycloak/verify methods: [ GET ] +oauth_simplelogin_connect: + controller: App\Controller\Security\SimpleLoginController::connect + path: /oauth/simplelogin/connect + methods: [ GET ] + +oauth_simplelogin_verify: + controller: App\Controller\Security\SimpleLoginController::verify + path: /oauth/simplelogin/verify + methods: [ GET ] + oauth_zitadel_connect: controller: App\Controller\Security\ZitadelController::connect path: /oauth/zitadel/connect diff --git a/config/packages/knpu_oauth2_client.yaml b/config/packages/knpu_oauth2_client.yaml index d329673bf..bb547e394 100644 --- a/config/packages/knpu_oauth2_client.yaml +++ b/config/packages/knpu_oauth2_client.yaml @@ -35,6 +35,13 @@ knpu_oauth2_client: version: '%oauth_keycloak_version%' redirect_route: oauth_keycloak_verify redirect_params: { } + simplelogin: + type: generic + client_id: '%oauth_simplelogin_id%' + client_secret: '%oauth_simplelogin_secret%' + redirect_route: oauth_simplelogin_verify + redirect_params: { } + provider_class: 'App\Provider\SimpleLogin' zitadel: type: generic client_id: '%oauth_zitadel_id%' diff --git a/config/packages/security.yaml b/config/packages/security.yaml index b11113027..d77cda718 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -38,6 +38,7 @@ security: - App\Security\GoogleAuthenticator - App\Security\GithubAuthenticator - App\Security\KeycloakAuthenticator + - App\Security\SimpleLoginAuthenticator - App\Security\ZitadelAuthenticator logout: enable_csrf: true diff --git a/config/services.yaml b/config/services.yaml index 35a7c8ea1..f610510b3 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -53,6 +53,9 @@ parameters: oauth_keycloak_realm: "%env(OAUTH_KEYCLOAK_REALM)%" oauth_keycloak_version: "%env(OAUTH_KEYCLOAK_VERSION)%" + oauth_simplelogin_id: "%env(default::OAUTH_SIMPLELOGIN_ID)%" + oauth_simplelogin_secret: "%env(OAUTH_SIMPLELOGIN_SECRET)%" + oauth_zitadel_id: "%env(default::OAUTH_ZITADEL_ID)%" oauth_zitadel_secret: "%env(OAUTH_ZITADEL_SECRET)%" oauth_zitadel_base_url: "%env(OAUTH_ZITADEL_BASE_URL)%" diff --git a/migrations/Version20240503224350.php b/migrations/Version20240503224350.php new file mode 100644 index 000000000..9e2404ea0 --- /dev/null +++ b/migrations/Version20240503224350.php @@ -0,0 +1,29 @@ +addSql('ALTER TABLE "user" ADD oauth_simple_login_id VARCHAR(255) DEFAULT NULL'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE "user" DROP oauth_simple_login_id'); + } +} diff --git a/src/Controller/Security/SimpleLoginController.php b/src/Controller/Security/SimpleLoginController.php new file mode 100644 index 000000000..94fb9ae65 --- /dev/null +++ b/src/Controller/Security/SimpleLoginController.php @@ -0,0 +1,28 @@ +getClient('simplelogin') + ->redirect([ + 'openid', + 'email', + 'profile', + ]); + } + + public function verify(Request $request, ClientRegistry $client) + { + } +} diff --git a/src/Entity/User.php b/src/Entity/User.php index 2d8c7674e..71dddb727 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -119,6 +119,8 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface, Visibil #[Column(type: 'string', nullable: true)] public ?string $oauthKeycloakId = null; #[Column(type: 'string', nullable: true)] + public ?string $oauthSimpleLoginId = null; + #[Column(type: 'string', nullable: true)] public ?string $oauthZitadelId = null; #[Column(type: 'boolean', nullable: false, options: ['default' => true])] public bool $hideAdult = true; @@ -755,7 +757,7 @@ public function removeOAuth2UserConsent(OAuth2UserConsent $oAuth2UserConsent): s public function isSsoControlled(): bool { - return $this->oauthAzureId || $this->oauthGithubId || $this->oauthGoogleId || $this->oauthFacebookId || $this->oauthKeycloakId || $this->oauthZitadelId; + return $this->oauthAzureId || $this->oauthGithubId || $this->oauthGoogleId || $this->oauthFacebookId || $this->oauthKeycloakId || $this->oauthSimpleLoginId || $this->oauthZitadelId; } public function getCustomCss(): ?string diff --git a/src/Provider/SimpleLogin.php b/src/Provider/SimpleLogin.php new file mode 100644 index 000000000..09145c51a --- /dev/null +++ b/src/Provider/SimpleLogin.php @@ -0,0 +1,72 @@ +baseUrl, '/').'/'; + } + + protected function getAuthorizationHeaders($token = null) + { + return ['Authorization' => 'Bearer '.$token]; + } + + public function getBaseAuthorizationUrl() + { + return $this->getBaseUrl().'oauth2/authorize'; + } + + public function getBaseAccessTokenUrl(array $params) + { + return $this->getBaseUrl().'oauth2/token'; + } + + public function getResourceOwnerDetailsUrl(AccessToken $token) + { + return $this->getBaseUrl().'oauth2/userinfo'; + } + + protected function getDefaultScopes() + { + return ['openid', 'profile', 'email']; + } + + protected function checkResponse(ResponseInterface $response, $data) + { + if (!empty($data['error'])) { + $error = htmlentities($data['error'], ENT_QUOTES, 'UTF-8'); + $message = htmlentities($data['error_description'], ENT_QUOTES, 'UTF-8'); + throw new IdentityProviderException($message, $response->getStatusCode(), $response); + } + } + + protected function createResourceOwner(array $response, AccessToken $token) + { + return new SimpleLoginResourceOwner($response); + } + + protected function getScopeSeparator() + { + return ' '; + } +} diff --git a/src/Provider/SimpleLoginResourceOwner.php b/src/Provider/SimpleLoginResourceOwner.php new file mode 100644 index 000000000..a899ed6a0 --- /dev/null +++ b/src/Provider/SimpleLoginResourceOwner.php @@ -0,0 +1,58 @@ +response = $response; + } + + public function getId() + { + return $this->getResponseValue('sub'); + } + + public function getName() + { + return $this->getResponseValue('name'); + } + + public function getEmail() + { + return $this->getResponseValue('email'); + } + + public function getPictureUrl() + { + return $this->getResponseValue('avatar_url'); + } + + public function toArray() + { + return $this->response; + } + + protected function getResponseValue($key) + { + $keys = explode('.', $key); + $value = $this->response; + + foreach ($keys as $k) { + if (isset($value[$k])) { + $value = $value[$k]; + } else { + return null; + } + } + + return $value; + } +} diff --git a/src/Security/SimpleLoginAuthenticator.php b/src/Security/SimpleLoginAuthenticator.php new file mode 100644 index 000000000..32229ac79 --- /dev/null +++ b/src/Security/SimpleLoginAuthenticator.php @@ -0,0 +1,185 @@ +attributes->get('_route'); + } + + public function authenticate(Request $request): Passport + { + $client = $this->clientRegistry->getClient('simplelogin'); + $slugger = $this->slugger; + + $provider = $client->getOAuth2Provider(); + + $accessToken = $provider->getAccessToken('authorization_code', [ + 'code' => $request->query->get('code'), + ]); + + $rememberBadge = new RememberMeBadge(); + $rememberBadge = $rememberBadge->enable(); + + return new SelfValidatingPassport( + new UserBadge($accessToken->getToken(), function () use ($accessToken, $client, $slugger) { + /** @var SimpleLoginResourceOwner $simpleloginUser */ + $simpleloginUser = $client->fetchUserFromToken($accessToken); + + $existingUser = $this->entityManager->getRepository(User::class)->findOneBy( + ['oauthSimpleLoginId' => $simpleloginUser->getId()] + ); + + if ($existingUser) { + return $existingUser; + } + + $user = $this->userRepository->findOneBy(['email' => $simpleloginUser->getEmail()]); + + if ($user) { + $user->oauthSimpleLoginId = $simpleloginUser->getId(); + + $this->entityManager->persist($user); + $this->entityManager->flush(); + + return $user; + } + + if (false === $this->settingsManager->get('MBIN_SSO_REGISTRATIONS_ENABLED')) { + throw new CustomUserMessageAuthenticationException('MBIN_SSO_REGISTRATIONS_ENABLED'); + } + + $name = $simpleloginUser->getName(); + $name = preg_replace('/\s+/', '', $name); // remove all whitespace + $name = preg_replace('#[[:punct:]]#', '', $name); // remove all punctuation + + $username = $slugger->slug($name); + + $usernameTaken = $this->entityManager->getRepository(User::class)->findOneBy( + ['username' => $username] + ); + + if ($usernameTaken) { + $username = $username.rand(1, 999); + } + + $dto = (new UserDto())->create( + $username, + $simpleloginUser->getEmail() + ); + + $avatar = $this->getAvatar($simpleloginUser->getPictureUrl()); + + if ($avatar) { + $dto->avatar = $this->imageFactory->createDto($avatar); + } + + $dto->plainPassword = bin2hex(random_bytes(20)); + $dto->ip = $this->ipResolver->resolve(); + + $user = $this->userManager->create($dto, false); + $user->oauthSimpleLoginId = $simpleloginUser->getId(); + $user->avatar = $this->getAvatar($simpleloginUser->getPictureUrl()); + $user->isVerified = true; + + $this->entityManager->persist($user); + $this->entityManager->flush(); + + return $user; + }), + [ + $rememberBadge, + ] + ); + } + + private function getAvatar(?string $pictureUrl): ?Image + { + if (!$pictureUrl) { + return null; + } + + try { + $tempFile = $this->imageManager->download($pictureUrl); + } catch (\Exception $e) { + $tempFile = null; + } + + if ($tempFile) { + $image = $this->imageRepository->findOrCreateFromPath($tempFile); + if ($image) { + $this->entityManager->persist($image); + $this->entityManager->flush(); + } + } + + return $image ?? null; + } + + public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response + { + $targetUrl = $this->router->generate('user_settings_profile'); + + return new RedirectResponse($targetUrl); + } + + public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response + { + $message = strtr($exception->getMessageKey(), $exception->getMessageData()); + + if ('MBIN_SSO_REGISTRATIONS_ENABLED' === $message) { + $session = $request->getSession(); + $session->getFlashBag()->add('error', 'sso_registrations_enabled.error'); + + return new RedirectResponse($this->router->generate('app_login')); + } + + return new Response($message, Response::HTTP_FORBIDDEN); + } +} diff --git a/src/Twig/Components/LoginSocialsComponent.php b/src/Twig/Components/LoginSocialsComponent.php index d9772fc04..9f1979b83 100644 --- a/src/Twig/Components/LoginSocialsComponent.php +++ b/src/Twig/Components/LoginSocialsComponent.php @@ -19,6 +19,8 @@ public function __construct( private readonly ?string $oauthGithubId, #[Autowire('%oauth_keycloak_id%')] private readonly ?string $oauthKeycloakId, + #[Autowire('%oauth_simplelogin_id%')] + private readonly ?string $oauthSimpleLoginId, #[Autowire('%oauth_zitadel_id%')] private readonly ?string $oauthZitadelId, #[Autowire('%oauth_azure_id%')] @@ -46,6 +48,11 @@ public function keycloakEnabled(): bool return !empty($this->oauthKeycloakId); } + public function simpleloginEnabled(): bool + { + return !empty($this->oauthSimpleLoginId); + } + public function zitadelEnabled(): bool { return !empty($this->oauthZitadelId); diff --git a/templates/components/login_socials.html.twig b/templates/components/login_socials.html.twig index 117a89758..116ea6578 100644 --- a/templates/components/login_socials.html.twig +++ b/templates/components/login_socials.html.twig @@ -1,5 +1,5 @@ {# @var this App\Twig\Components\LoginSocialsComponent #} -{%- set HAS_ANY_SOCIAL = this.googleEnabled or this.facebookEnabled or this.githubEnabled or this.keycloakEnabled or this.zitadelEnabled or this.azureEnabled -%} +{%- set HAS_ANY_SOCIAL = this.googleEnabled or this.facebookEnabled or this.githubEnabled or this.keycloakEnabled or this.simpleloginEnabled or this.zitadelEnabled or this.azureEnabled -%} {% if HAS_ANY_SOCIAL %} {% if not mbin_sso_only_mode() and not mbin_sso_show_first() %}
    @@ -21,6 +21,10 @@ {{ 'continue_with'|trans }} Keycloak {% endif %} + {% if this.simpleloginEnabled %} + + {{ 'continue_with'|trans }} SimpleLogin + {% endif %} {% if this.zitadelEnabled %} {{ 'continue_with'|trans }} Zitadel From 0ca9585fc9ebd332d741e53800476803519ad5e3 Mon Sep 17 00:00:00 2001 From: debounced <35878315+nobodyatroot@users.noreply.github.com> Date: Tue, 14 May 2024 20:23:37 -0500 Subject: [PATCH 011/335] Add available simple-icons to SimpleLogin SSO (#781) --- assets/styles/app.scss | 1 + package-lock.json | 11 +++++++++++ package.json | 1 + templates/components/login_socials.html.twig | 2 +- 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/assets/styles/app.scss b/assets/styles/app.scss index c849d3343..7f60d159a 100644 --- a/assets/styles/app.scss +++ b/assets/styles/app.scss @@ -1,6 +1,7 @@ @import '@fortawesome/fontawesome-free/scss/fontawesome'; @import '@fortawesome/fontawesome-free/scss/solid'; @import '@fortawesome/fontawesome-free/scss/brands'; +@import 'simple-icons-font/font/simple-icons'; @import 'glightbox/dist/css/glightbox.min.css'; @import 'mixins/animations'; @import 'mixins/kbin'; diff --git a/package-lock.json b/package-lock.json index e93247403..08ec93b67 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "regenerator-runtime": "^0.14.0", "sass": "^1.69.5", "sass-loader": "^13.3.2", + "simple-icons-font": "^11.12.0", "stimulus-textarea-autogrow": "^4.1.0", "stimulus-use": "^0.52.1", "timeago.js": "^4.0.2", @@ -9689,6 +9690,16 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "node_modules/simple-icons-font": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/simple-icons-font/-/simple-icons-font-11.12.0.tgz", + "integrity": "sha512-JFdVtHwh5513JklPWwCvFp0EpwOPRhQNUy9/Eaudgfhf0FD6CqN26EvFGiS24WCE2dEG28ZwUpliiZK5QID2gQ==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/simple-icons" + } + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", diff --git a/package.json b/package.json index 4e8e03d89..35fe6e716 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "regenerator-runtime": "^0.14.0", "sass": "^1.69.5", "sass-loader": "^13.3.2", + "simple-icons-font": "^11.12.0", "stimulus-textarea-autogrow": "^4.1.0", "stimulus-use": "^0.52.1", "timeago.js": "^4.0.2", diff --git a/templates/components/login_socials.html.twig b/templates/components/login_socials.html.twig index 116ea6578..fd94e4987 100644 --- a/templates/components/login_socials.html.twig +++ b/templates/components/login_socials.html.twig @@ -22,7 +22,7 @@ {{ 'continue_with'|trans }} Keycloak {% endif %} {% if this.simpleloginEnabled %} - + {{ 'continue_with'|trans }} SimpleLogin {% endif %} {% if this.zitadelEnabled %} From 5431dc34bc515a460d787d628ffd6edacec6dc79 Mon Sep 17 00:00:00 2001 From: asdfzdfj Date: Wed, 15 May 2024 11:35:03 +0700 Subject: [PATCH 012/335] front controller path/routing adjustment (#687) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the new filter ui changes also introduces a couple more filtering parameters in the form of controller path params, for threads/entries listing it looks fine and relatively staightforward, but for microblog posts listing, what used to be a simple `/microblog` is now something like `/all/hot/∞/all/all/microblog`, which hinders the user experience on url readability and memorability compared to the previous scheme, for those who still care this changes tries to adjust the path/routing of these front controller especially for the microblog part, to make it more simpler and could omit some default filter parameters if they aren't set, similar to the previous path scheme Co-authored-by: e-five <146029455+e-five256@users.noreply.github.com> --- config/kbin_routes/domain.yaml | 5 +- config/kbin_routes/front.yaml | 77 ++++---- .../Domain/DomainFrontController.php | 11 +- src/Controller/Entry/EntryFrontController.php | 166 ++++++++++++------ src/Repository/Criteria.php | 23 +-- src/Twig/Extension/FrontExtension.php | 19 ++ src/Twig/Runtime/FrontExtensionRuntime.php | 64 +++++++ src/Twig/Runtime/UrlExtensionRuntime.php | 2 +- templates/domain/_options.html.twig | 2 +- templates/entry/_options.html.twig | 50 +++--- templates/layout/_header_nav.html.twig | 8 +- templates/post/_options.html.twig | 50 +++--- 12 files changed, 313 insertions(+), 164 deletions(-) create mode 100644 src/Twig/Extension/FrontExtension.php create mode 100644 src/Twig/Runtime/FrontExtensionRuntime.php diff --git a/config/kbin_routes/domain.yaml b/config/kbin_routes/domain.yaml index d209af86b..6c0631049 100644 --- a/config/kbin_routes/domain.yaml +++ b/config/kbin_routes/domain.yaml @@ -1,12 +1,11 @@ domain_entries: controller: App\Controller\Domain\DomainFrontController - defaults: { sortBy: hot, time: '∞', type: ~ } - path: /d/{name}/{sortBy}/{time}/{type} + defaults: { sortBy: hot, time: '∞'} + path: /d/{name}/{sortBy}/{time} methods: [ GET ] requirements: sortBy: "%default_sort_options%" time: "%default_time_options%" - type: "%default_type_options%" domain_comments: controller: App\Controller\Domain\DomainCommentFrontController diff --git a/config/kbin_routes/front.yaml b/config/kbin_routes/front.yaml index ef14c5b5f..01a28a07d 100644 --- a/config/kbin_routes/front.yaml +++ b/config/kbin_routes/front.yaml @@ -1,45 +1,55 @@ front: controller: App\Controller\Entry\EntryFrontController::front - defaults: { subscription: home, sortBy: hot, time: '∞', type: all, federation: all, content: threads } - path: /{subscription}/{sortBy}/{time}/{type}/{federation}/{content} + defaults: &front_defaults { subscription: home, content: threads, sortBy: hot, time: '∞', federation: all } + path: /{subscription}/{content}/{sortBy}/{time}/{federation} methods: [GET] - requirements: + requirements: &front_requirement subscription: "%default_subscription_options%" sortBy: "%default_sort_options%" time: "%default_time_options%" - type: "%default_type_options%" federation: "%default_federation_options%" content: "%default_content_options%" -front_redirect: - controller: App\Controller\Entry\EntryFrontController::front_redirect - defaults: { sortBy: hot, time: '∞', type: all, federation: all, content: threads } - path: /{sortBy}/{time}/{type}/{federation}/{content} +front_sub: + controller: App\Controller\Entry\EntryFrontController::front + defaults: *front_defaults + path: /{subscription}/{sortBy}/{time}/{federation} methods: [GET] - requirements: - sortBy: "%default_sort_options%" - time: "%default_time_options%" - type: "%default_type_options%" - federation: "%default_federation_options%" - content: "%default_content_options%" + requirements: *front_requirement + +front_content: + controller: App\Controller\Entry\EntryFrontController::front + defaults: *front_defaults + path: /{content}/{sortBy}/{time}/{federation} + methods: [GET] + requirements: *front_requirement + +front_short: + controller: App\Controller\Entry\EntryFrontController::front + defaults: *front_defaults + path: /{sortBy}/{time}/{federation} + methods: [GET] + requirements: *front_requirement front_magazine: controller: App\Controller\Entry\EntryFrontController::magazine - defaults: { sortBy: hot, time: '∞', type: all, federation: all, content: threads } - path: /m/{name}/{sortBy}/{time}/{type}/{federation}/{content} + defaults: &front_magazine_defaults { content: threads, sortBy: hot, time: '∞', federation: all } + path: /m/{name}/{content}/{sortBy}/{time}/{federation} methods: [GET] - requirements: - sortBy: "%default_sort_options%" - time: "%default_time_options%" - type: "%default_type_options%" - federation: "%default_federation_options%" - content: "%default_content_options%" + requirements: *front_requirement + +front_magazine_short: + controller: App\Controller\Entry\EntryFrontController::magazine + defaults: &front_magazine_defaults + path: /m/{name}/{sortBy}/{time}/{federation} + methods: [GET] + requirements: *front_requirement # Microblog compatibility stuff, redirects from the old routes' URLs posts_front: - controller: App\Controller\Entry\EntryFrontController::front_redirect - defaults: { sortBy: hot, time: '∞', type: all, federation: all, content: microblog } + controller: App\Controller\Entry\EntryFrontController::frontRedirect + defaults: { sortBy: hot, time: '∞', federation: all, content: microblog } path: /microblog/{sortBy}/{time} methods: [ GET ] requirements: @@ -47,8 +57,8 @@ posts_front: time: "%default_time_options%" posts_subscribed: - controller: App\Controller\Entry\EntryFrontController::front_redirect - defaults: { sortBy: hot, time: '∞', type: all, federation: all, content: microblog, subscription: 'sub' } + controller: App\Controller\Entry\EntryFrontController::frontRedirect + defaults: { sortBy: hot, time: '∞', federation: all, content: microblog, subscription: 'sub' } path: /sub/microblog/{sortBy}/{time} methods: [ GET ] requirements: @@ -56,8 +66,8 @@ posts_subscribed: time: "%default_time_options%" posts_moderated: - controller: App\Controller\Entry\EntryFrontController::front_redirect - defaults: { sortBy: hot, time: '∞', type: all, federation: all, content: microblog, subscription: 'mod' } + controller: App\Controller\Entry\EntryFrontController::frontRedirect + defaults: { sortBy: hot, time: '∞', federation: all, content: microblog, subscription: 'mod' } path: /mod/microblog/{sortBy}/{time} methods: [ GET ] requirements: @@ -65,8 +75,8 @@ posts_moderated: time: "%default_time_options%" posts_favourite: - controller: App\Controller\Entry\EntryFrontController::front_redirect - defaults: { sortBy: hot, time: '∞', type: all, federation: all, content: microblog, subscription: 'fav' } + controller: App\Controller\Entry\EntryFrontController::frontRedirect + defaults: { sortBy: hot, time: '∞', federation: all, content: microblog, subscription: 'fav' } path: /fav/microblog/{sortBy}/{time} methods: [ GET ] requirements: @@ -74,12 +84,11 @@ posts_favourite: time: "%default_time_options%" magazine_posts: - controller: App\Controller\Entry\EntryFrontController::front_redirect - defaults: { sortBy: hot, time: '∞', type: all, federation: all, content: microblog } - path: /m/{name}/microblog/{sortBy}/{time}/{type}/{federation} + controller: App\Controller\Entry\EntryFrontController::magazineRedirect + defaults: { sortBy: hot, time: '∞', federation: all, content: microblog } + path: /m/{name}/microblog/{sortBy}/{time}/{federation} methods: [ GET ] requirements: sortBy: "%default_sort_options%" time: "%default_time_options%" - type: "%default_type_options%" federation: "%default_federation_options%" diff --git a/src/Controller/Domain/DomainFrontController.php b/src/Controller/Domain/DomainFrontController.php index 54d2b5714..167f336eb 100644 --- a/src/Controller/Domain/DomainFrontController.php +++ b/src/Controller/Domain/DomainFrontController.php @@ -13,6 +13,7 @@ use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Attribute\MapQueryParameter; class DomainFrontController extends AbstractController { @@ -22,8 +23,14 @@ public function __construct( ) { } - public function __invoke(?string $name, ?string $sortBy, ?string $time, ?string $type, Request $request): Response - { + public function __invoke( + ?string $name, + ?string $sortBy, + ?string $time, + #[MapQueryParameter] + ?string $type, + Request $request + ): Response { if (!$domain = $this->domainRepository->findOneBy(['name' => $name])) { throw $this->createNotFoundException(); } diff --git a/src/Controller/Entry/EntryFrontController.php b/src/Controller/Entry/EntryFrontController.php index 6e290e612..d9cf2112a 100644 --- a/src/Controller/Entry/EntryFrontController.php +++ b/src/Controller/Entry/EntryFrontController.php @@ -19,15 +19,26 @@ use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Attribute\MapQueryParameter; class EntryFrontController extends AbstractController { - public function __construct(private readonly EntryRepository $entryRepository, private readonly PostRepository $postRepository) - { + public function __construct( + private readonly EntryRepository $entryRepository, + private readonly PostRepository $postRepository + ) { } - public function front(?string $sortBy, ?string $time, ?string $type, string $subscription, string $federation, string $content, Request $request): Response - { + public function front( + string $subscription, + string $content, + ?string $sortBy, + ?string $time, + string $federation, + #[MapQueryParameter] + ?string $type, + Request $request + ): Response { $user = $this->getUser(); $criteria = $this->createCriteria($content, $request); @@ -39,57 +50,64 @@ public function front(?string $sortBy, ?string $time, ?string $type, string $sub if ('home' === $subscription) { $subscription = $this->subscriptionFor($user); } - $this->handleSubscription($subscription, $user, $criteria); + $this->handleSubscription($subscription, $criteria); $this->setUserPreferences($user, $criteria); - $entities = ('threads' === $content) ? $this->entryRepository->findByCriteria($criteria) : $this->postRepository->findByCriteria($criteria); if ('threads' === $content) { + $entities = $this->entryRepository->findByCriteria($criteria); $entities = $this->handleCrossposts($entities); + $templatePath = 'entry/'; + $dataKey = 'entries'; + } elseif ('microblog' === $content) { + $entities = $this->postRepository->findByCriteria($criteria); + $templatePath = 'post/'; + $dataKey = 'posts'; + } else { + throw new \LogicException("Invalid content filter '{$content}'"); } - $templatePath = ('threads' === $content) ? 'entry/' : 'post/'; - $dataKey = ('threads' === $content) ? 'entries' : 'posts'; - - return $this->renderResponse($request, $content, $criteria, [$dataKey => $entities], $templatePath, $user); + return $this->renderResponse( + $request, + $content, + $criteria, + [$dataKey => $entities], + $templatePath, + $user + ); } - // $name is magazine name, for compatibility - public function front_redirect(?string $sortBy, ?string $time, ?string $type, string $federation, string $content, ?string $name, Request $request): Response - { - $user = $this->getUser(); // Fetch the user - $subscription = $this->subscriptionFor($user); // Determine the subscription filter based on the user - - if ($name) { - return $this->redirectToRoute('front_magazine', [ - 'name' => $name, - 'subscription' => $subscription, - 'sortBy' => $sortBy, - 'time' => $time, - 'type' => $type, - 'federation' => $federation, - 'content' => $content, - ]); - } else { - return $this->redirectToRoute('front', [ - 'subscription' => $subscription, - 'sortBy' => $sortBy, - 'time' => $time, - 'type' => $type, - 'federation' => $federation, - 'content' => $content, - ]); - } + public function frontRedirect( + string $content, + ?string $sortBy, + ?string $time, + string $federation, + #[MapQueryParameter] + ?string $type, + Request $request + ): Response { + $user = $this->getUser(); + $subscription = $this->subscriptionFor($user); + + return $this->redirectToRoute('front', [ + 'subscription' => $subscription, + 'sortBy' => $sortBy, + 'time' => $time, + 'type' => $type, + 'federation' => $federation, + 'content' => $content, + ]); } public function magazine( #[MapEntity(expr: 'repository.findOneByName(name)')] Magazine $magazine, + string $content, ?string $sortBy, ?string $time, - ?string $type, string $federation, - string $content, + #[MapQueryParameter] + ?string $type, Request $request ): Response { $user = $this->getUser(); @@ -106,21 +124,59 @@ public function magazine( $criteria->magazine = $magazine; $criteria->stickiesFirst = true; - $subscription = $request->query->get('subscription'); - if (!$subscription) { - $subscription = 'all'; - } - $this->handleSubscription($subscription, $user, $criteria); + $subscription = $request->query->get('subscription') ?: 'all'; + $this->handleSubscription($subscription, $criteria); $this->setUserPreferences($user, $criteria); - $entities = ('threads' === $content) ? $this->entryRepository->findByCriteria($criteria) : $this->postRepository->findByCriteria($criteria); - // Note no crosspost handling + if ('threads' === $content) { + $entities = $this->entryRepository->findByCriteria($criteria); + // Note no crosspost handling + $templatePath = 'entry/'; + $dataKey = 'entries'; + } elseif ('microblog' === $content) { + $entities = $this->postRepository->findByCriteria($criteria); + $templatePath = 'post/'; + $dataKey = 'posts'; + } else { + throw new \LogicException("Invalid content filter '{$content}'"); + } + + return $this->renderResponse( + $request, + $content, + $criteria, + [$dataKey => $entities, 'magazine' => $magazine], + $templatePath, + $user + ); + } - $templatePath = ('threads' === $content) ? 'entry/' : 'post/'; - $dataKey = ('threads' === $content) ? 'entries' : 'posts'; + /** + * @param string $name magazine name + */ + public function magazineRedirect( + string $name, + string $content, + ?string $sortBy, + ?string $time, + string $federation, + #[MapQueryParameter] + ?string $type, + Request $request + ): Response { + $user = $this->getUser(); // Fetch the user + $subscription = $this->subscriptionFor($user); // Determine the subscription filter based on the user - return $this->renderResponse($request, $content, $criteria, [$dataKey => $entities, 'magazine' => $magazine], $templatePath, $user); + return $this->redirectToRoute('front_magazine', [ + 'name' => $name, + 'subscription' => $subscription, + 'sortBy' => $sortBy, + 'time' => $time, + 'type' => $type, + 'federation' => $federation, + 'content' => $content, + ]); } private function createCriteria(string $content, Request $request) @@ -136,19 +192,18 @@ private function createCriteria(string $content, Request $request) return $criteria->setContent($content); } - private function handleSubscription(string $subscription, $user, &$criteria) + private function handleSubscription(string $subscription, &$criteria) { - if ('sub' === $subscription) { + if (\in_array($subscription, ['sub', 'mod', 'fav'])) { $this->denyAccessUnlessGranted('ROLE_USER'); $this->getUserOrThrow(); + } + + if ('sub' === $subscription) { $criteria->subscribed = true; } elseif ('mod' === $subscription) { - $this->denyAccessUnlessGranted('ROLE_USER'); - $this->getUserOrThrow(); $criteria->moderated = true; } elseif ('fav' === $subscription) { - $this->denyAccessUnlessGranted('ROLE_USER'); - $this->getUserOrThrow(); $criteria->favourite = true; } elseif ($subscription && 'all' !== $subscription) { throw new \LogicException('Invalid subscription filter '.$subscription); @@ -164,7 +219,8 @@ private function setUserPreferences(?User $user, &$criteria) private function renderResponse(Request $request, $content, $criteria, $data, $templatePath, ?User $user) { - $baseData = ['criteria' => $criteria] + $data; + $baseData = array_merge(['criteria' => $criteria], $data); + if ('microblog' === $content) { $dto = new PostDto(); if (isset($data['magazine'])) { diff --git a/src/Repository/Criteria.php b/src/Repository/Criteria.php index c9edd8a94..747eda64c 100644 --- a/src/Repository/Criteria.php +++ b/src/Repository/Criteria.php @@ -230,22 +230,13 @@ public function resolveTime(?string $value, bool $reverse = false): ?string public function resolveType(?string $value): ?string { - // @todo - $routes = [ - 'all' => 'all', - 'article' => Entry::ENTRY_TYPE_ARTICLE, - 'articles' => Entry::ENTRY_TYPE_ARTICLE, - 'link' => Entry::ENTRY_TYPE_LINK, - 'links' => Entry::ENTRY_TYPE_LINK, - 'video' => Entry::ENTRY_TYPE_VIDEO, - 'videos' => Entry::ENTRY_TYPE_VIDEO, - 'photo' => Entry::ENTRY_TYPE_IMAGE, - 'photos' => Entry::ENTRY_TYPE_IMAGE, - 'image' => Entry::ENTRY_TYPE_IMAGE, - 'images' => Entry::ENTRY_TYPE_IMAGE, - ]; - - return $routes[$value] ?? 'all'; + return match ($value) { + 'article', 'articles' => Entry::ENTRY_TYPE_ARTICLE, + 'link', 'links' => Entry::ENTRY_TYPE_LINK, + 'video', 'videos' => Entry::ENTRY_TYPE_VIDEO, + 'photo', 'photos', 'image', 'images' => Entry::ENTRY_TYPE_IMAGE, + default => 'all' + }; } public function translateType(): string diff --git a/src/Twig/Extension/FrontExtension.php b/src/Twig/Extension/FrontExtension.php new file mode 100644 index 000000000..04554e3f9 --- /dev/null +++ b/src/Twig/Extension/FrontExtension.php @@ -0,0 +1,19 @@ +requestStack->getCurrentRequest(); + $attrs = $request->attributes; + $route = $routeName ?? $attrs->get('_route'); + + $params = array_merge($attrs->get('_route_params', []), $request->query->all()); + $params = array_replace($params, $additionalParams); + $params = array_filter($params, fn ($v) => null !== $v); + + $params[$name] = $value; + + if (str_starts_with($route, 'front') && !str_contains($route, '_magazine')) { + $route = $this->getFrontRoute($route, $params); + } + + return $this->urlGenerator->generate($route, $params); + } + + /** + * Upgrades shorter `front_*` routes to a front route that can fit all specified params. + */ + private function getFrontRoute(string $currentRoute, array $params): string + { + $content = $params['content'] ?? null; + $subscription = $params['subscription'] ?? null; + + if (\in_array($currentRoute, ['front_sub', 'front_content']) && $content && $subscription) { + return 'front'; + } elseif ('front_short' === $currentRoute) { + return match (true) { + !empty($content) => 'front_content', + !empty($subscription) => 'front_sub', + default => 'front', + }; + } + + return 'front'; + } +} diff --git a/src/Twig/Runtime/UrlExtensionRuntime.php b/src/Twig/Runtime/UrlExtensionRuntime.php index 54a13661c..46d19859b 100644 --- a/src/Twig/Runtime/UrlExtensionRuntime.php +++ b/src/Twig/Runtime/UrlExtensionRuntime.php @@ -265,7 +265,7 @@ public function postCommentDeleteUrl(PostComment $comment): string // $additionalParams indicates extra parameters to set in addition to [$name] = $value // Set $value to null to indicate deleting a parameter // TODO: It'd be better to have just a single $params which is an associative array - public function optionsUrl(string $name, string $value, string $routeName = null, array $additionalParams = []): string + public function optionsUrl(string $name, ?string $value, string $routeName = null, array $additionalParams = []): string { $route = $routeName ?? $this->requestStack->getCurrentRequest()->attributes->get('_route'); $params = $this->requestStack->getCurrentRequest()->attributes->get('_route_params', []); diff --git a/templates/domain/_options.html.twig b/templates/domain/_options.html.twig index 65bd7c990..c50c3326c 100644 --- a/templates/domain/_options.html.twig +++ b/templates/domain/_options.html.twig @@ -124,7 +124,7 @@
    `; this.containerTarget.innerHTML = failedHtml; this.containerTarget.classList.remove('hidden'); } finally { @@ -86,14 +86,14 @@ export default class extends Controller { } loadScripts(response) { - let tmp = document.createElement("div"); + const tmp = document.createElement('div'); tmp.innerHTML = response; - let el = tmp.getElementsByTagName('script'); + const el = tmp.getElementsByTagName('script'); if (el.length) { - let script = document.createElement("script"); - script.setAttribute("src", el[0].getAttribute('src')); - script.setAttribute("async", "false"); + const script = document.createElement('script'); + script.setAttribute('src', el[0].getAttribute('src')); + script.setAttribute('async', 'false'); // let exists = [...document.head.querySelectorAll('script')] // .filter(value => value.getAttribute('src') >= script.getAttribute('src')); @@ -102,7 +102,7 @@ export default class extends Controller { // return; // } - let head = document.head; + const head = document.head; head.insertBefore(script, head.firstElementChild); } } diff --git a/assets/controllers/rich_textarea_controller.js b/assets/controllers/rich_textarea_controller.js index e6b02d33f..fbde0b483 100644 --- a/assets/controllers/rich_textarea_controller.js +++ b/assets/controllers/rich_textarea_controller.js @@ -1,4 +1,4 @@ -import {Controller} from '@hotwired/stimulus'; +import { Controller } from '@hotwired/stimulus'; /* stimulusFetch: 'lazy' */ export default class extends Controller { @@ -13,30 +13,26 @@ export default class extends Controller { }; handleInput (event) { - let hasSelection = this.element.selectionStart != this.element.selectionEnd; - let key = event.key; + const hasSelection = this.element.selectionStart !== this.element.selectionEnd; + const key = event.key; + + if (event.ctrlKey && 'Enter' === key) { + // ctrl + enter to submit form - // ctrl + enter to submit form - if (event.ctrlKey && key === "Enter") { this.element.form.submit(); - } + } else if (event.ctrlKey && 'b' === key) { + // ctrl + b to toggle bold - // ctrl + b to toggle bold - else if (event.ctrlKey && key === "b") { this.toggleFormattingEnclosure('**'); - } + } else if (event.ctrlKey && 'i' === key) { + // ctrl + i to toggle italic - // ctrl + i to toggle italic - else if (event.ctrlKey && key === "i") { this.toggleFormattingEnclosure('_'); - } + } else if (hasSelection && key in this.enclosureKeys) { + // toggle/cycle wrapping on selection texts - // toggle/cycle wrapping on selection texts - else if (hasSelection && key in this.enclosureKeys) { this.toggleFormattingEnclosure(key, this.enclosureKeys[key] ?? 1); - } - - else { + } else { return; } @@ -67,10 +63,9 @@ export default class extends Controller { this.element.selectionStart = start - finalEnclosure.length; this.element.selectionEnd = end - finalEnclosure.length; - } + } else { + // add a new enclosure - // add a new enclosure - else { document.execCommand('insertText', false, encl + inner + encl); this.element.selectionStart = start + encl.length; diff --git a/assets/controllers/scroll_top_controller.js b/assets/controllers/scroll_top_controller.js index 85384a1e0..e886ea392 100644 --- a/assets/controllers/scroll_top_controller.js +++ b/assets/controllers/scroll_top_controller.js @@ -1,8 +1,8 @@ -import {Controller} from '@hotwired/stimulus'; +import { Controller } from '@hotwired/stimulus'; export default class extends Controller { connect() { - let self = this; + const self = this; window.onscroll = function () { self.scroll(); }; @@ -10,12 +10,12 @@ export default class extends Controller { scroll() { if ( - document.body.scrollTop > 20 || - document.documentElement.scrollTop > 20 + 20 < document.body.scrollTop || + 20 < document.documentElement.scrollTop ) { - this.element.style.display = "block"; + this.element.style.display = 'block'; } else { - this.element.style.display = "none"; + this.element.style.display = 'none'; } } diff --git a/assets/controllers/selection_controller.js b/assets/controllers/selection_controller.js index 1a97349df..72777a6e7 100644 --- a/assets/controllers/selection_controller.js +++ b/assets/controllers/selection_controller.js @@ -1,4 +1,4 @@ -import {Controller} from '@hotwired/stimulus'; +import { Controller } from '@hotwired/stimulus'; /* stimulusFetch: 'lazy' */ export default class extends Controller { diff --git a/assets/controllers/settings_row_enum_controller.js b/assets/controllers/settings_row_enum_controller.js index 92e2762e4..722492950 100644 --- a/assets/controllers/settings_row_enum_controller.js +++ b/assets/controllers/settings_row_enum_controller.js @@ -1,4 +1,4 @@ -import {Controller} from '@hotwired/stimulus'; +import { Controller } from '@hotwired/stimulus'; export default class extends Controller { /** @@ -6,11 +6,11 @@ export default class extends Controller { * @param actionPath {string} - The path to the action to be called * @param reloadRequired {boolean} - Whether the page needs to be reloaded after the action is called */ - change({params: {actionPath, reloadRequired}}) { + change({ params: { actionPath, reloadRequired } }) { return fetch(actionPath).then(() => { if (reloadRequired) { document.querySelector('.settings-list').classList.add('reload-required'); } }); } -} \ No newline at end of file +} diff --git a/assets/controllers/settings_row_switch_controller.js b/assets/controllers/settings_row_switch_controller.js index b1e0258a2..b1e73598b 100644 --- a/assets/controllers/settings_row_switch_controller.js +++ b/assets/controllers/settings_row_switch_controller.js @@ -1,4 +1,4 @@ -import {Controller} from '@hotwired/stimulus'; +import { Controller } from '@hotwired/stimulus'; export default class extends Controller { /** @@ -8,7 +8,7 @@ export default class extends Controller { * @param falsePath {string} - The path to the action to be called when the toggle is unchecked * @param reloadRequired {boolean} - Whether the page needs to be reloaded after the action is called */ - toggle({target, params: {truePath, falsePath, reloadRequired}}) { + toggle({ target, params: { truePath, falsePath, reloadRequired } }) { const path = target.checked ? truePath : falsePath; return fetch(path).then(() => { if (reloadRequired) { @@ -16,4 +16,4 @@ export default class extends Controller { } }); } -} \ No newline at end of file +} diff --git a/assets/controllers/subject_controller.js b/assets/controllers/subject_controller.js index aaeca7624..95331ad07 100644 --- a/assets/controllers/subject_controller.js +++ b/assets/controllers/subject_controller.js @@ -1,22 +1,22 @@ -import {Controller} from '@hotwired/stimulus'; -import {fetch, ok} from "../utils/http"; -import {useIntersection} from 'stimulus-use' -import router from "../utils/routing"; -import getIntIdFromElement, {getLevel, getDepth, getTypeFromNotification} from "../utils/kbin"; +import { fetch, ok } from '../utils/http'; +import getIntIdFromElement, { getDepth, getLevel, getTypeFromNotification } from '../utils/kbin'; +import { Controller } from '@hotwired/stimulus'; import GLightbox from 'glightbox'; +import router from '../utils/routing'; +import { useIntersection } from 'stimulus-use'; /* stimulusFetch: 'lazy' */ export default class extends Controller { static previewInit = false; - static targets = ['loader', 'more', 'container', 'commentsCounter', 'favCounter', 'upvoteCounter', 'downvoteCounter'] + static targets = ['loader', 'more', 'container', 'commentsCounter', 'favCounter', 'upvoteCounter', 'downvoteCounter']; static values = { loading: Boolean, - isExpandedValue: Boolean + isExpandedValue: Boolean, }; static sendBtnLabel = null; connect() { - const params = {selector: '.thumb', openEffect: 'none', closeEffect: 'none', slideEffect: 'none'}; + const params = { selector: '.thumb', openEffect: 'none', closeEffect: 'none', slideEffect: 'none' }; GLightbox(params); const self = this; @@ -32,7 +32,7 @@ export default class extends Controller { } if (this.element.classList.contains('show-preview')) { - useIntersection(this) + useIntersection(this); } this.checkHeight(); @@ -50,7 +50,7 @@ export default class extends Controller { try { this.loadingValue = true; - let response = await fetch(event.target.href, {method: 'GET'}); + let response = await fetch(event.target.href, { method: 'GET' }); response = await ok(response); response = await response.json(); @@ -60,15 +60,15 @@ export default class extends Controller { const textarea = this.containerTarget.querySelector('textarea'); if (textarea) { - if (textarea.value !== "") { - let firstLineEnd = textarea.value.indexOf("\n"); + if ('' !== textarea.value) { + let firstLineEnd = textarea.value.indexOf('\n'); if (-1 === firstLineEnd) { firstLineEnd = textarea.value.length; - textarea.value = textarea.value.slice(0, firstLineEnd) + " " + textarea.value.slice(firstLineEnd); + textarea.value = textarea.value.slice(0, firstLineEnd) + ' ' + textarea.value.slice(firstLineEnd); textarea.selectionStart = firstLineEnd + 1; textarea.selectionEnd = firstLineEnd + 1; } else { - textarea.value = textarea.value.slice(0, firstLineEnd) + " " + textarea.value.slice(firstLineEnd); + textarea.value = textarea.value.slice(0, firstLineEnd) + ' ' + textarea.value.slice(firstLineEnd); textarea.selectionStart = firstLineEnd + 1; textarea.selectionEnd = firstLineEnd + 1; } @@ -98,7 +98,7 @@ export default class extends Controller { let response = await fetch(url, { method: 'POST', - body: new FormData(form) + body: new FormData(form), }); response = await ok(response); @@ -117,11 +117,11 @@ export default class extends Controller { const div = document.createElement('div'); div.innerHTML = response.html; - let level = getLevel(this.element); - let depth = getDepth(this.element); + const level = getLevel(this.element); + const depth = getDepth(this.element); div.firstElementChild.classList.remove('comment-level--1'); - div.firstElementChild.classList.add('comment-level--' + (level >= 10 ? 10 : level + 1)); + div.firstElementChild.classList.add('comment-level--' + (10 <= level ? 10 : level + 1)); div.firstElementChild.dataset.commentCollapseDepthValue = depth + 1; if (this.element.nextElementSibling && this.element.nextElementSibling.classList.contains('comments')) { @@ -161,7 +161,7 @@ export default class extends Controller { let response = await fetch(form.action, { method: 'POST', - body: new FormData(form) + body: new FormData(form), }); response = await ok(response); @@ -185,7 +185,7 @@ export default class extends Controller { let response = await fetch(form.action, { method: 'POST', - body: new FormData(form) + body: new FormData(form), }); response = await ok(response); @@ -282,7 +282,7 @@ export default class extends Controller { try { this.loadingValue = true; - const url = router().generate(`ajax_fetch_${getTypeFromNotification(data)}`, {id: getIntIdFromElement(this.element)}); + const url = router().generate(`ajax_fetch_${getTypeFromNotification(data)}`, { id: getIntIdFromElement(this.element) }); let response = await fetch(url); @@ -303,7 +303,7 @@ export default class extends Controller { updateVotes(data) { this.upvoteCounterTarget.innerText = `(${data.detail.up})`; - if(data.detail.up > 0) { + if (0 < data.detail.up) { this.upvoteCounterTarget.classList.remove('hidden'); } else { this.upvoteCounterTarget.classList.add('hidden'); @@ -336,7 +336,7 @@ export default class extends Controller { try { this.loadingValue = true; - let response = await fetch(event.target.parentNode.formAction, {method: 'POST'}); + let response = await fetch(event.target.parentNode.formAction, { method: 'POST' }); response = await ok(response); response = await response.json(); @@ -368,7 +368,7 @@ export default class extends Controller { this.isExpandedValue = false; const elem = this.element.querySelector('.content'); if (elem) { - elem.style.maxHeight = '25rem' + elem.style.maxHeight = '25rem'; if (elem.scrollHeight - 30 > elem.clientHeight || elem.scrollWidth > elem.clientWidth) { @@ -382,7 +382,7 @@ export default class extends Controller { } createMoreBtn(elem) { - let moreBtn = document.createElement('div') + const moreBtn = document.createElement('div'); moreBtn.innerHTML = ''; moreBtn.classList.add('more'); @@ -392,7 +392,7 @@ export default class extends Controller { } more() { - this.moreBtn.addEventListener('click', e => { + this.moreBtn.addEventListener('click', (e) => { if (e.target.previousSibling.style.maxHeight) { e.target.previousSibling.setAttribute('style', 'margin-bottom: 2rem !important'); e.target.previousSibling.style.maxHeight = null; @@ -405,7 +405,7 @@ export default class extends Controller { e.target.previousSibling.scrollIntoView(); this.isExpandedValue = false; } - }) + }); } expand() { diff --git a/assets/controllers/subject_list_controller.js b/assets/controllers/subject_list_controller.js index bca8085f9..71cfa13da 100644 --- a/assets/controllers/subject_list_controller.js +++ b/assets/controllers/subject_list_controller.js @@ -1,7 +1,7 @@ -import {Controller} from '@hotwired/stimulus'; -import router from "../utils/routing"; -import {fetch, ok} from "../utils/http"; -import {getLevel, getDepth, getTypeFromNotification} from "../utils/kbin"; +import { fetch, ok } from '../utils/http'; +import { getDepth, getLevel, getTypeFromNotification } from '../utils/kbin'; +import { Controller } from '@hotwired/stimulus'; +import router from '../utils/routing'; /* stimulusFetch: 'lazy' */ export default class extends Controller { @@ -15,7 +15,7 @@ export default class extends Controller { async addMainSubject(data) { try { - const url = router().generate(`ajax_fetch_${getTypeFromNotification(data)}`, {id: data.detail.id}); + const url = router().generate(`ajax_fetch_${getTypeFromNotification(data)}`, { id: data.detail.id }); let response = await fetch(url); @@ -35,11 +35,11 @@ export default class extends Controller { const div = document.createElement('div'); div.innerHTML = response.html; - let level = getLevel(parent); - let depth = getDepth(parent); + const level = getLevel(parent); + const depth = getDepth(parent); div.firstElementChild.classList.remove('comment-level--1'); - div.firstElementChild.classList.add('comment-level--' + (level >= 10 ? 10 : level + 1)); + div.firstElementChild.classList.add('comment-level--' + (10 <= level ? 10 : level + 1)); div.firstElementChild.dataset.commentCollapseDepthValue = depth + 1; let current = parent; @@ -47,12 +47,12 @@ export default class extends Controller { if (!current.nextElementSibling) { break; } - if (current.nextElementSibling.dataset.subjectParentValue === 'undefined') { + if ('undefined' === current.nextElementSibling.dataset.subjectParentValue) { break; } if (current.nextElementSibling.dataset.subjectParentValue !== div.firstElementChild.dataset.subjectParentValue && getLevel(current.nextElementSibling) <= level) { - break + break; } current = current.nextElementSibling; @@ -77,7 +77,7 @@ export default class extends Controller { return; } - const url = router().generate(`ajax_fetch_${getTypeFromNotification(data)}`, {id: data.detail.id}); + const url = router().generate(`ajax_fetch_${getTypeFromNotification(data)}`, { id: data.detail.id }); let response = await fetch(url); diff --git a/assets/controllers/subs_controller.js b/assets/controllers/subs_controller.js index 1db898ba2..f344a85a6 100644 --- a/assets/controllers/subs_controller.js +++ b/assets/controllers/subs_controller.js @@ -1,10 +1,10 @@ -import {Controller} from '@hotwired/stimulus'; -import {fetch, ok} from "../utils/http"; +import { fetch, ok } from '../utils/http'; +import { Controller } from '@hotwired/stimulus'; /* stimulusFetch: 'lazy' */ export default class extends Controller { static values = { - loading: Boolean + loading: Boolean, }; async send(event) { @@ -17,7 +17,7 @@ export default class extends Controller { let response = await fetch(form.action, { method: 'POST', - body: new FormData(form) + body: new FormData(form), }); response = await ok(response); @@ -30,4 +30,4 @@ export default class extends Controller { this.loadingValue = false; } } -} \ No newline at end of file +} diff --git a/assets/controllers/subs_panel_controller.js b/assets/controllers/subs_panel_controller.js index 42a737650..5ca485a28 100644 --- a/assets/controllers/subs_panel_controller.js +++ b/assets/controllers/subs_panel_controller.js @@ -1,5 +1,5 @@ import { Controller } from '@hotwired/stimulus'; -import router from "../utils/routing"; +import router from '../utils/routing'; const KBIN_SUBSCRIPTIONS_IN_SEPARATE_SIDEBAR = 'kbin_subscriptions_in_separate_sidebar'; const KBIN_SUBSCRIPTIONS_SIDEBARS_SAME_SIDE = 'kbin_subscriptions_sidebars_same_side'; @@ -16,33 +16,33 @@ export default class extends Controller { async reattach() { await window.fetch( - this.generateSettingsRoute(KBIN_SUBSCRIPTIONS_IN_SEPARATE_SIDEBAR, 'false') + this.generateSettingsRoute(KBIN_SUBSCRIPTIONS_IN_SEPARATE_SIDEBAR, 'false'), ); window.location.reload(); } async popLeft() { await window.fetch( - this.generateSettingsRoute(KBIN_SUBSCRIPTIONS_IN_SEPARATE_SIDEBAR, 'true') + this.generateSettingsRoute(KBIN_SUBSCRIPTIONS_IN_SEPARATE_SIDEBAR, 'true'), ); await window.fetch( this.generateSettingsRoute( KBIN_SUBSCRIPTIONS_SIDEBARS_SAME_SIDE, - ('left' === this.sidebarPositionValue ? 'true' : 'false') - ) + ('left' === this.sidebarPositionValue ? 'true' : 'false'), + ), ); window.location.reload(); } async popRight() { await window.fetch( - this.generateSettingsRoute(KBIN_SUBSCRIPTIONS_IN_SEPARATE_SIDEBAR, 'true') + this.generateSettingsRoute(KBIN_SUBSCRIPTIONS_IN_SEPARATE_SIDEBAR, 'true'), ); await window.fetch( this.generateSettingsRoute( KBIN_SUBSCRIPTIONS_SIDEBARS_SAME_SIDE, - ('left' !== this.sidebarPositionValue ? 'true' : 'false') - ) + ('left' !== this.sidebarPositionValue ? 'true' : 'false'), + ), ); window.location.reload(); } diff --git a/assets/controllers/thumb_controller.js b/assets/controllers/thumb_controller.js index 67df0261b..38669f717 100644 --- a/assets/controllers/thumb_controller.js +++ b/assets/controllers/thumb_controller.js @@ -1,5 +1,4 @@ -import {Controller} from '@hotwired/stimulus'; -import {fetch, ok} from "../utils/http"; +import { Controller } from '@hotwired/stimulus'; /* stimulusFetch: 'lazy' */ export default class extends Controller { @@ -9,7 +8,6 @@ export default class extends Controller { * @returns */ async adult_image_hover(event) { - if (false === event.target.matches(':hover')) { return; } @@ -22,8 +20,6 @@ export default class extends Controller { * @param {*} event */ async adult_image_hover_out(event) { - event.target.style.filter = 'blur(8px)'; - } } diff --git a/assets/controllers/timeago_controller.js b/assets/controllers/timeago_controller.js index fd8bde1db..d8339bbca 100644 --- a/assets/controllers/timeago_controller.js +++ b/assets/controllers/timeago_controller.js @@ -1,9 +1,11 @@ -import {Controller} from '@hotwired/stimulus'; +import { Controller } from '@hotwired/stimulus'; +/* eslint-disable camelcase -- zh_TW is a specific identifier */ +// eslint-disable-next-line -- grouping timeago imports here is more readable than properly sorting import * as timeago from 'timeago.js'; import bg from 'timeago.js/lib/lang/bg'; import de from 'timeago.js/lib/lang/de'; import el from 'timeago.js/lib/lang/el'; -import en from 'timeago.js/lib/lang/en_US' +import en from 'timeago.js/lib/lang/en_US'; import es from 'timeago.js/lib/lang/es'; import fr from 'timeago.js/lib/lang/fr'; import it from 'timeago.js/lib/lang/it'; @@ -13,7 +15,7 @@ import pl from 'timeago.js/lib/lang/pl'; import pt from 'timeago.js/lib/lang/pt_BR'; import ru from 'timeago.js/lib/lang/ru'; import tr from 'timeago.js/lib/lang/tr'; -import uk from 'timeago.js/lib/lang/uk' +import uk from 'timeago.js/lib/lang/uk'; import zh_TW from 'timeago.js/lib/lang/zh_TW'; /* stimulusFetch: 'lazy' */ @@ -35,4 +37,4 @@ export default class extends Controller { timeago.render(elems); } } -} \ No newline at end of file +} diff --git a/assets/email.js b/assets/email.js index a4390799f..87346d8e8 100644 --- a/assets/email.js +++ b/assets/email.js @@ -1 +1 @@ -import './styles/emails.scss'; \ No newline at end of file +import './styles/emails.scss'; diff --git a/assets/utils/http.js b/assets/utils/http.js index a4ab57e5a..1a089fdc8 100644 --- a/assets/utils/http.js +++ b/assets/utils/http.js @@ -2,16 +2,16 @@ * @returns {Promise} */ export async function fetch(url = '', options = {}) { - if (typeof url === 'object' && url !== null) { + if ('object' === typeof url && null !== url) { options = url; url = options.url; } - options = {...options}; + options = { ...options }; options.credentials = options.credentials || 'same-origin'; options.redirect = options.redirect || 'error'; options.headers = { - 'X-Requested-With': 'XMLHttpRequest' + 'X-Requested-With': 'XMLHttpRequest', }; return window.fetch(url, options); diff --git a/assets/utils/kbin.js b/assets/utils/kbin.js index 9adffd022..e1d5be717 100644 --- a/assets/utils/kbin.js +++ b/assets/utils/kbin.js @@ -1,5 +1,5 @@ export default function getIntIdFromElement(element) { - return element.id.substring(element.id.lastIndexOf("-") + 1); + return element.id.substring(element.id.lastIndexOf('-') + 1); } export function getIdPrefixFromNotification(data) { @@ -33,11 +33,11 @@ export function getTypeFromNotification(data) { } export function getLevel(element) { - let level = parseInt(element.className.replace('comment-level--1', '').split('--')[1]); + const level = parseInt(element.className.replace('comment-level--1', '').split('--')[1]); return isNaN(level) ? 1 : level; } export function getDepth(element) { - let depth = parseInt(element.dataset.commentCollapseDepthValue); + const depth = parseInt(element.dataset.commentCollapseDepthValue); return isNaN(depth) ? 1 : depth; } diff --git a/assets/utils/popover.js b/assets/utils/popover.js index 25dc8337e..c58c7f1fa 100644 --- a/assets/utils/popover.js +++ b/assets/utils/popover.js @@ -7,31 +7,40 @@ Util.hasClass = function(el, className) { Util.addClass = function(el, className) { var classList = className.split(' '); el.classList.add(classList[0]); - if (classList.length > 1) Util.addClass(el, classList.slice(1).join(' ')); + if (1 < classList.length) { + Util.addClass(el, classList.slice(1).join(' ')); + } }; Util.removeClass = function(el, className) { var classList = className.split(' '); el.classList.remove(classList[0]); - if (classList.length > 1) Util.removeClass(el, classList.slice(1).join(' ')); + if (1 < classList.length) { + Util.removeClass(el, classList.slice(1).join(' ')); + } }; Util.toggleClass = function(el, className, bool) { - if(bool) Util.addClass(el, className); - else Util.removeClass(el, className); + if (bool) { + Util.addClass(el, className); + } else { + Util.removeClass(el, className); + } }; Util.setAttributes = function(el, attrs) { - for(var key in attrs) { + for (var key in attrs) { el.setAttribute(key, attrs[key]); } }; Util.moveFocus = function (element) { - if( !element ) element = document.getElementsByTagName('body')[0]; + if (!element) { + element = document.getElementsByTagName('body')[0]; + } element.focus(); if (document.activeElement !== element) { - element.setAttribute('tabindex','-1'); + element.setAttribute('tabindex', '-1'); element.focus(); } }; @@ -74,82 +83,90 @@ Util.moveFocus = function (element) { function getPositionTarget(popover) { // position tooltip relative to a specified element - if provided var positionTargetSelector = popover.element.getAttribute('data-position-target'); - if(!positionTargetSelector) return false; + if (!positionTargetSelector) { + return false; + } var positionTarget = document.querySelector(positionTargetSelector); return positionTarget; - }; + } function initPopover(popover) { // reset popover position initPopoverPosition(popover); // init aria-labels - for(var i = 0; i < popover.trigger.length; i++) { - Util.setAttributes(popover.trigger[i], {'aria-expanded': 'false', 'aria-haspopup': 'true'}); + for (var i = 0; i < popover.trigger.length; i++) { + Util.setAttributes(popover.trigger[i], { 'aria-expanded': 'false', 'aria-haspopup': 'true' }); } - }; + } function initPopoverEvents(popover) { - for(var i = 0; i < popover.trigger.length; i++) {(function(i){ - popover.trigger[i].addEventListener('click', function(event){ - event.preventDefault(); - // if the popover had been previously opened by another trigger element -> close it first and reopen in the right position - if(Util.hasClass(popover.element, popover.popoverVisibleClass) && popover.s != popover.trigger[i]) { - togglePopover(popover, false, false); // close menu - } - // toggle popover - popover.selectedTrigger = popover.trigger[i]; - togglePopover(popover, !Util.hasClass(popover.element, popover.popoverVisibleClass), true); - }); - })(i);} + for (var i = 0; i < popover.trigger.length; i++) { + (function(i) { + popover.trigger[i].addEventListener('click', function(event) { + event.preventDefault(); + // if the popover had been previously opened by another trigger element -> close it first and reopen in the right position + if (Util.hasClass(popover.element, popover.popoverVisibleClass) && popover.s != popover.trigger[i]) { + togglePopover(popover, false, false); // close menu + } + // toggle popover + popover.selectedTrigger = popover.trigger[i]; + togglePopover(popover, !Util.hasClass(popover.element, popover.popoverVisibleClass), true); + }); + })(i); + } // trap focus - popover.element.addEventListener('keydown', function(event){ - if( event.keyCode && event.keyCode == 9 || event.key && event.key == 'Tab' ) { + popover.element.addEventListener('keydown', function(event) { + if (event.keyCode && 9 == event.keyCode || event.key && 'Tab' == event.key) { //trap focus inside popover trapFocus(popover, event); } }); // custom events -> open/close popover - popover.element.addEventListener('openPopover', function(event){ + popover.element.addEventListener('openPopover', function(event) { togglePopover(popover, true); }); - popover.element.addEventListener('closePopover', function(event){ + popover.element.addEventListener('closePopover', function(event) { togglePopover(popover, false, event.detail); }); - }; + } function togglePopover(popover, bool, moveFocus) { // toggle popover visibility Util.toggleClass(popover.element, popover.popoverVisibleClass, bool); popover.popoverIsOpen = bool; - if(bool) { + if (bool) { popover.selectedTrigger.setAttribute('aria-expanded', 'true'); getFocusableElements(popover); // move focus focusPopover(popover); - popover.element.addEventListener("transitionend", function(event) {focusPopover(popover);}, {once: true}); + popover.element.addEventListener('transitionend', function(event) { + focusPopover(popover); + }, { once: true }); // position the popover element positionPopover(popover); // add class to popover trigger Util.addClass(popover.selectedTrigger, popover.selectedTriggerClass); - } else if(popover.selectedTrigger) { + } else if (popover.selectedTrigger) { popover.selectedTrigger.setAttribute('aria-expanded', 'false'); - if(moveFocus) Util.moveFocus(popover.selectedTrigger); + if (moveFocus) { + Util.moveFocus(popover.selectedTrigger); + } // remove class from menu trigger Util.removeClass(popover.selectedTrigger, popover.selectedTriggerClass); popover.selectedTrigger = false; } - }; + } function focusPopover(popover) { - if(popover.firstFocusable) { + if (popover.firstFocusable) { popover.firstFocusable.focus(); } else { Util.moveFocus(popover.element); } - }; + } function positionPopover(popover) { // reset popover position @@ -167,14 +184,18 @@ Util.moveFocus = function (element) { ? 'bottom: '+(window.innerHeight - selectedTriggerPosition.top)+'px;' : 'top: '+selectedTriggerPosition.bottom+'px;'; // check right position is correct -> otherwise set left to 0 - if( isRight && (right + popover.element.offsetWidth) > window.innerWidth) horizontal = 'left: '+ parseInt((window.innerWidth - popover.element.offsetWidth)/2)+'px;'; + if (isRight && (right + popover.element.offsetWidth) > window.innerWidth) { + horizontal = 'left: '+ parseInt((window.innerWidth - popover.element.offsetWidth)/2)+'px;'; + } // check if popover needs a max-height (user will scroll inside the popover) var maxHeight = menuOnTop ? selectedTriggerPosition.top - popover.viewportGap : window.innerHeight - selectedTriggerPosition.bottom - popover.viewportGap; var initialStyle = popover.element.getAttribute('style'); - if(!initialStyle) initialStyle = ''; + if (!initialStyle) { + initialStyle = ''; + } popover.element.setAttribute('style', initialStyle + horizontal + vertical +'max-height:'+Math.floor(maxHeight)+'px;'); - }; + } function resetPopoverStyle(popover) { // remove popover inline style before applying new style @@ -183,71 +204,77 @@ Util.moveFocus = function (element) { popover.element.style.bottom = ''; popover.element.style.left = ''; popover.element.style.right = ''; - }; + } function initPopoverPosition(popover) { // make sure the popover does not create any scrollbar popover.element.style.top = '0px'; popover.element.style.left = '0px'; - }; + } function checkPopoverClick(popover, target) { // close popover when clicking outside it - if(!popover.popoverIsOpen) return; - if(!popover.element.contains(target) && !target.closest('[aria-controls="'+popover.elementId+'"]')) togglePopover(popover, false); - }; + if (!popover.popoverIsOpen) { + return; + } + if (!popover.element.contains(target) && !target.closest('[aria-controls="'+popover.elementId+'"]')) { + togglePopover(popover, false); + } + } function checkPopoverFocus(popover) { // on Esc key -> close popover if open and move focus (if focus was inside popover) - if(!popover.popoverIsOpen) return; + if (!popover.popoverIsOpen) { + return; + } var popoverParent = document.activeElement.closest('.js-popover'); togglePopover(popover, false, popoverParent); - }; + } function getFocusableElements(popover) { //get all focusable elements inside the popover var allFocusable = popover.element.querySelectorAll(focusableElString); getFirstVisible(popover, allFocusable); getLastVisible(popover, allFocusable); - }; + } function getFirstVisible(popover, elements) { //get first visible focusable element inside the popover - for(var i = 0; i < elements.length; i++) { - if( isVisible(elements[i]) ) { + for (var i = 0; i < elements.length; i++) { + if (isVisible(elements[i])) { popover.firstFocusable = elements[i]; break; } } - }; + } function getLastVisible(popover, elements) { //get last visible focusable element inside the popover - for(var i = elements.length - 1; i >= 0; i--) { - if( isVisible(elements[i]) ) { + for (var i = elements.length - 1; 0 <= i; i--) { + if (isVisible(elements[i])) { popover.lastFocusable = elements[i]; break; } } - }; + } function trapFocus(popover, event) { - if( popover.firstFocusable == document.activeElement && event.shiftKey) { + if (popover.firstFocusable == document.activeElement && event.shiftKey) { //on Shift+Tab -> focus last focusable element when focus moves out of popover event.preventDefault(); popover.lastFocusable.focus(); } - if( popover.lastFocusable == document.activeElement && !event.shiftKey) { + if (popover.lastFocusable == document.activeElement && !event.shiftKey) { //on Tab -> focus first focusable element when focus moves out of popover event.preventDefault(); popover.firstFocusable.focus(); } - }; + } function isVisible(element) { // check if element is visible return element.offsetWidth || element.offsetHeight || element.getClientRects().length; - }; + } window.Popover = Popover; @@ -256,51 +283,57 @@ Util.moveFocus = function (element) { // generic focusable elements string selector var focusableElString = '[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, [tabindex]:not([tabindex="-1"]), [contenteditable], audio[controls], video[controls], summary'; - if( popovers.length > 0 ) { + if (0 < popovers.length) { var popoversArray = []; var scrollingContainers = []; - for( var i = 0; i < popovers.length; i++) { - (function(i){ + for (var i = 0; i < popovers.length; i++) { + (function(i) { popoversArray.push(new Popover(popovers[i])); var scrollableElement = popovers[i].getAttribute('data-scrollable-element'); - if(scrollableElement && !scrollingContainers.includes(scrollableElement)) scrollingContainers.push(scrollableElement); + if (scrollableElement && !scrollingContainers.includes(scrollableElement)) { + scrollingContainers.push(scrollableElement); + } })(i); } // listen for key events - window.addEventListener('keyup', function(event){ - if( event.keyCode && event.keyCode == 27 || event.key && event.key.toLowerCase() == 'escape' ) { + window.addEventListener('keyup', function(event) { + if (event.keyCode && 27 == event.keyCode || event.key && 'escape' == event.key.toLowerCase()) { // close popover on 'Esc' - popoversArray.forEach(function(element){ + popoversArray.forEach(function(element) { element.checkPopoverFocus(); }); } }); // close popover when clicking outside it - window.addEventListener('click', function(event){ - popoversArray.forEach(function(element){ + window.addEventListener('click', function(event) { + popoversArray.forEach(function(element) { element.checkPopoverClick(event.target); }); }); // on resize -> close all popover elements - window.addEventListener('resize', function(event){ - popoversArray.forEach(function(element){ + window.addEventListener('resize', function(event) { + popoversArray.forEach(function(element) { element.togglePopover(false, false); }); }); // on scroll -> close all popover elements - window.addEventListener('scroll', function(event){ - popoversArray.forEach(function(element){ - if(element.popoverIsOpen) element.togglePopover(false, false); + window.addEventListener('scroll', function(event) { + popoversArray.forEach(function(element) { + if (element.popoverIsOpen) { + element.togglePopover(false, false); + } }); }); // take additional scrollable containers into account - for(var j = 0; j < scrollingContainers.length; j++) { + for (var j = 0; j < scrollingContainers.length; j++) { var scrollingContainer = document.querySelector(scrollingContainers[j]); - if(scrollingContainer) { - scrollingContainer.addEventListener('scroll', function(event){ - popoversArray.forEach(function(element){ - if(element.popoverIsOpen) element.togglePopover(false, false); + if (scrollingContainer) { + scrollingContainer.addEventListener('scroll', function(event) { + popoversArray.forEach(function(element) { + if (element.popoverIsOpen) { + element.togglePopover(false, false); + } }); }); } diff --git a/assets/utils/routing.js b/assets/utils/routing.js index afb544872..2dd852af7 100644 --- a/assets/utils/routing.js +++ b/assets/utils/routing.js @@ -1,6 +1,7 @@ -const routes = require('../../public/js/fos_js_routes.json'); import Routing from '../../vendor/friendsofsymfony/jsrouting-bundle/Resources/public/js/router.min.js'; +const routes = require('../../public/js/fos_js_routes.json'); + export default function router() { Routing.setRoutingData(routes); From 06df5f6526c503e5fea8e58e023db800d471039a Mon Sep 17 00:00:00 2001 From: asdfzdfj Date: Tue, 21 May 2024 12:00:07 +0700 Subject: [PATCH 015/335] slight MentionManager robustness improvement (#787) changed MentionManager::extract() to pass in value to process by function argument rather than shared private property of the service, makes the data flow clearer and prevent accidental state sharing also add unicode flag to mention regex matching in MentionManager to improve robustness when processing unicode text/matches, without this, the matched results may contain invalid unicode, and would result in 'Malformed UTF-8 characters, possibly incorrectly encoded' or similar errors when persisting entries/posts to database --- src/Service/MentionManager.php | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/Service/MentionManager.php b/src/Service/MentionManager.php index d55a5b286..2705e09d2 100644 --- a/src/Service/MentionManager.php +++ b/src/Service/MentionManager.php @@ -16,7 +16,6 @@ class MentionManager public const ALL = 1; public const LOCAL = 2; public const REMOTE = 3; - private string $val; public function __construct( private readonly UserRepository $userRepository, @@ -81,16 +80,14 @@ function ($val) { public function extract(?string $val, $type = self::ALL): ?array { - if (null === $val) { + if (!$val) { return null; } - $this->val = $val; - $result = match ($type) { - self::ALL => array_merge($this->byApPrefix(), $this->byPrefix()), - self::LOCAL => $this->byPrefix(), - self::REMOTE => $this->byApPrefix() + self::ALL => array_merge($this->byApPrefix($val), $this->byPrefix($val)), + self::LOCAL => $this->byPrefix($val), + self::REMOTE => $this->byApPrefix($val) }; $result = array_map(fn ($val) => trim($val), $result); @@ -98,20 +95,20 @@ public function extract(?string $val, $type = self::ALL): ?array return \count($result) ? array_unique($result) : null; } - private function byApPrefix(): array + private function byApPrefix(string $value): array { preg_match_all( - '/(?val, + '/(?val, $matches); + preg_match_all('/(? !str_ends_with($val, '@')); return \count($results) ? array_unique(array_values($results)) : []; From 4d53b842a1bd0d16f83b43a6b6bcfec52dbcd267 Mon Sep 17 00:00:00 2001 From: asdfzdfj Date: Wed, 22 May 2024 20:13:35 +0700 Subject: [PATCH 016/335] added lock when updating actor via UpdateActorHandler (#620) while working on incoming activity, the UpdateActorMessage could be fired more than once per actor, and even with #602 applied there could still be multiple UpdateActorHandler running at the same time updating the same actor, before the added guard could kick in this adds a bit of locking in UpdateActorHandler per actor url to try and ensure that only one handler is actually updating an actor at a time, and discards any following update actor message that comes after added the force parameter to UpdateActorMessage and handler to force actor update regardless of #602 last updated time (still have to get past the lock though) also use symfony rate limiter to throttle auto dispatching the UpdateActorMessage once per 5 minutes, allowing for redispatch recovery if the previously dispatched message+handler falied to update the actor, as it appears that multiple UpdateActorMessage will get dispatched when the actor is eligible for updating e.g. last fetched over an hour ago the `mbin:actor:update` command also got some jank in there fixed as they also used UpdateActorMessage to do its job, and the force parameter is also used here --- config/packages/rate_limiter.yaml | 4 ++ src/Command/ActorUpdateCommand.php | 20 +++++---- .../ActivityPub/UpdateActorMessage.php | 2 +- .../ActivityPub/UpdateActorHandler.php | 41 +++++++++++++++++-- src/Repository/MagazineRepository.php | 1 + src/Repository/UserRepository.php | 1 + src/Service/ActivityPubManager.php | 40 ++++++++++-------- 7 files changed, 78 insertions(+), 31 deletions(-) diff --git a/config/packages/rate_limiter.yaml b/config/packages/rate_limiter.yaml index 7401a8a7a..e5db56ecc 100644 --- a/config/packages/rate_limiter.yaml +++ b/config/packages/rate_limiter.yaml @@ -116,3 +116,7 @@ framework: policy: 'fixed_window' limit: 4 interval: '1 day' + ap_update_actor: + policy: 'sliding_window' + limit: 1 + interval: '5 minutes' diff --git a/src/Command/ActorUpdateCommand.php b/src/Command/ActorUpdateCommand.php index 8f3bb226e..f84c0cfb9 100644 --- a/src/Command/ActorUpdateCommand.php +++ b/src/Command/ActorUpdateCommand.php @@ -18,7 +18,7 @@ #[AsCommand( name: 'mbin:actor:update', - description: 'This command will allow you to update remote user info.', + description: 'This command will allow you to update remote actor (user/magazine) info.', )] class ActorUpdateCommand extends Command { @@ -32,28 +32,30 @@ public function __construct( protected function configure(): void { - $this->addArgument('user', InputArgument::OPTIONAL, 'Argument description') - ->addOption('users', null, InputOption::VALUE_NONE) - ->addOption('magazines', null, InputOption::VALUE_NONE); + $this->addArgument('user', InputArgument::OPTIONAL, 'AP url of the actor to update') + ->addOption('users', null, InputOption::VALUE_NONE, 'update *all* known users that needs updating') + ->addOption('magazines', null, InputOption::VALUE_NONE, 'update *all* known magazines that needs updating') + ->addOption('force', null, InputOption::VALUE_NONE, 'force actor update even if they are recently updated'); } protected function execute(InputInterface $input, OutputInterface $output): int { $io = new SymfonyStyle($input, $output); $userArg = $input->getArgument('user'); + $force = (bool) $input->getOption('force'); - if ($input->getOption('users')) { + if ($userArg) { + $this->bus->dispatch(new UpdateActorMessage($userArg, $force)); + } elseif ($input->getOption('users')) { foreach ($this->repository->findRemoteForUpdate() as $u) { - $this->bus->dispatch(new UpdateActorMessage($u->apProfileId)); + $this->bus->dispatch(new UpdateActorMessage($u->apProfileId, $force)); $io->info($u->username); } } elseif ($input->getOption('magazines')) { foreach ($this->magazineRepository->findRemoteForUpdate() as $u) { - $this->bus->dispatch(new UpdateActorMessage($u->apProfileId)); + $this->bus->dispatch(new UpdateActorMessage($u->apProfileId, $force)); $io->info($u->name); } - } elseif ($userArg) { - $this->bus->dispatch(new UpdateActorMessage($userArg)); } $io->success('Done.'); diff --git a/src/Message/ActivityPub/UpdateActorMessage.php b/src/Message/ActivityPub/UpdateActorMessage.php index b76bc73a1..26c9e5946 100644 --- a/src/Message/ActivityPub/UpdateActorMessage.php +++ b/src/Message/ActivityPub/UpdateActorMessage.php @@ -8,7 +8,7 @@ class UpdateActorMessage implements ActivityPubResolveInterface { - public function __construct(public string $actorUrl) + public function __construct(public string $actorUrl, public bool $force = false) { } } diff --git a/src/MessageHandler/ActivityPub/UpdateActorHandler.php b/src/MessageHandler/ActivityPub/UpdateActorHandler.php index f18cb6000..c13fb530d 100644 --- a/src/MessageHandler/ActivityPub/UpdateActorHandler.php +++ b/src/MessageHandler/ActivityPub/UpdateActorHandler.php @@ -5,18 +5,53 @@ namespace App\MessageHandler\ActivityPub; use App\Message\ActivityPub\UpdateActorMessage; +use App\Repository\MagazineRepository; +use App\Repository\UserRepository; use App\Service\ActivityPubManager; +use Psr\Log\LoggerInterface; +use Symfony\Component\Lock\LockFactory; use Symfony\Component\Messenger\Attribute\AsMessageHandler; #[AsMessageHandler] class UpdateActorHandler { - public function __construct(private readonly ActivityPubManager $manager) - { + public function __construct( + private readonly ActivityPubManager $manager, + private readonly LockFactory $lockFactory, + private readonly UserRepository $userRepository, + private readonly MagazineRepository $magazineRepository, + private readonly LoggerInterface $logger, + ) { } public function __invoke(UpdateActorMessage $message): void { - $this->manager->updateActor($message->actorUrl); + $actorUrl = $message->actorUrl; + $lock = $this->lockFactory->createLock('update_actor_'.hash('sha256', $actorUrl), 60); + + if (!$lock->acquire()) { + $this->logger->debug( + 'not updating actor at {url}: ongoing actor update is already in progress', + ['url' => $actorUrl] + ); + + return; + } + + $actor = $this->userRepository->findOneBy(['apProfileId' => $actorUrl]) + ?? $this->magazineRepository->findOneBy(['apProfileId' => $actorUrl]); + + if ($actor) { + if ($message->force || $actor->apFetchedAt < (new \DateTime())->modify('-1 hour')) { + $this->manager->updateActor($actorUrl); + } else { + $this->logger->debug('not updating actor {url}: last updated is recent: {fetched}', [ + 'url' => $actorUrl, + 'fetched' => $actor->apFetchedAt, + ]); + } + } + + $lock->release(); } } diff --git a/src/Repository/MagazineRepository.php b/src/Repository/MagazineRepository.php index 7c62c4fb2..d2763ff31 100644 --- a/src/Repository/MagazineRepository.php +++ b/src/Repository/MagazineRepository.php @@ -524,6 +524,7 @@ public function findRemoteForUpdate(): array ->andWhere('m.apDomain IS NULL') ->andWhere('m.apDeletedAt IS NULL') ->andWhere('m.apTimeoutAt IS NULL') + ->addOrderBy('m.apFetchedAt', 'ASC') ->setMaxResults(1000) ->getQuery() ->getResult(); diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php index 65f9ceb53..56f7b8e49 100644 --- a/src/Repository/UserRepository.php +++ b/src/Repository/UserRepository.php @@ -349,6 +349,7 @@ public function findRemoteForUpdate(): array ->andWhere('u.apDomain IS NULL') ->andWhere('u.apDeletedAt IS NULL') ->andWhere('u.apTimeoutAt IS NULL') + ->addOrderBy('u.apFetchedAt', 'ASC') ->setMaxResults(1000) ->getQuery() ->getResult(); diff --git a/src/Service/ActivityPubManager.php b/src/Service/ActivityPubManager.php index 91bc49f56..a15eb4495 100644 --- a/src/Service/ActivityPubManager.php +++ b/src/Service/ActivityPubManager.php @@ -37,6 +37,7 @@ use League\HTMLToMarkdown\HtmlConverter; use Psr\Log\LoggerInterface; use Symfony\Component\Messenger\MessageBusInterface; +use Symfony\Component\RateLimiter\RateLimiterFactory; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; class ActivityPubManager @@ -60,6 +61,7 @@ public function __construct( private readonly UrlGeneratorInterface $urlGenerator, private readonly MessageBusInterface $bus, private readonly LoggerInterface $logger, + private readonly RateLimiterFactory $apUpdateActorLimiter, ) { } @@ -133,7 +135,7 @@ public function findActorOrCreate(?string $actorUrlOrHandle): null|User|Magazine $user = $this->userRepository->findOneBy(['username' => ltrim($actorUrl, '@')]); if ($user instanceof User) { if ($user->apId && (!$user->apFetchedAt || $user->apFetchedAt->modify('+1 hour') < (new \DateTime()))) { - $this->bus->dispatch(new UpdateActorMessage($user->apProfileId)); + $this->dispatchUpdateActor($user->apProfileId); } return $user; @@ -166,10 +168,7 @@ public function findActorOrCreate(?string $actorUrlOrHandle): null|User|Magazine $user = $this->createUser($actorUrl); } else { if (!$user->apFetchedAt || $user->apFetchedAt->modify('+1 hour') < (new \DateTime())) { - try { - $this->bus->dispatch(new UpdateActorMessage($user->apProfileId)); - } catch (\Exception $e) { - } + $this->dispatchUpdateActor($user->apProfileId); } } @@ -185,10 +184,7 @@ public function findActorOrCreate(?string $actorUrlOrHandle): null|User|Magazine $magazine = $this->createMagazine($actorUrl); } else { if (!$magazine->apFetchedAt || $magazine->apFetchedAt->modify('+1 hour') < (new \DateTime())) { - try { - $this->bus->dispatch(new UpdateActorMessage($magazine->apProfileId)); - } catch (\Exception $e) { - } + $this->dispatchUpdateActor($magazine->apProfileId); } } @@ -212,6 +208,22 @@ public function findActorOrCreate(?string $actorUrlOrHandle): null|User|Magazine return null; } + public function dispatchUpdateActor(string $actorUrl) + { + $limiter = $this->apUpdateActorLimiter + ->create($actorUrl) + ->consume(1); + + if ($limiter->isAccepted()) { + $this->bus->dispatch(new UpdateActorMessage($actorUrl)); + } else { + $this->logger->debug( + 'not dispatching updating actor for {actor}: one has been dispatched recently', + ['actor' => $actorUrl, 'retry' => $limiter->getRetryAfter()] + ); + } + } + /** * Try to find an existing actor or create a new one if the actor doesn't yet exists. * @@ -291,10 +303,6 @@ public function updateUser(string $actorUrl): ?User $this->logger->info('updating user {name}', ['name' => $actorUrl]); $user = $this->userRepository->findOneBy(['apProfileId' => $actorUrl]); - if ($user instanceof User && $user->apFetchedAt > (new \DateTime())->modify('-1 hour')) { - return $user; - } - $actor = $this->apHttpClient->getActorObject($actorUrl); if (!$actor || !\is_array($actor)) { return null; @@ -426,10 +434,6 @@ public function updateMagazine(string $actorUrl): ?Magazine $this->logger->info('updating magazine "{magName}"', ['magName' => $actorUrl]); $magazine = $this->magazineRepository->findOneBy(['apProfileId' => $actorUrl]); - if ($magazine instanceof Magazine && $magazine->apFetchedAt > (new \DateTime())->modify('-1 hour')) { - return $magazine; - } - $actor = $this->apHttpClient->getActorObject($actorUrl); // Check if actor isn't empty (not set/null/empty array/etc.) @@ -664,7 +668,7 @@ public function findOrCreateMagazineByToAndCC(array $object): Magazine|null $potentialGroups = self::getReceivers($object); $magazine = $this->magazineRepository->findByApGroupProfileId($potentialGroups); if ($magazine and $magazine->apId && (!$magazine->apFetchedAt || $magazine->apFetchedAt->modify('+1 Day') < (new \DateTime()))) { - $this->bus->dispatch(new UpdateActorMessage($magazine->apProfileId)); + $this->dispatchUpdateActor($magazine->apPublicUrl); } if (null === $magazine) { From 78b322c2246738fbc7eb9b2f35c2f2887de4dd89 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Tue, 28 May 2024 14:38:35 +0200 Subject: [PATCH 017/335] Translations update from Hosted Weblate (#794) Co-authored-by: Asmodeus --- translations/messages.pt_BR.yaml | 1 + 1 file changed, 1 insertion(+) create mode 100644 translations/messages.pt_BR.yaml diff --git a/translations/messages.pt_BR.yaml b/translations/messages.pt_BR.yaml new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/translations/messages.pt_BR.yaml @@ -0,0 +1 @@ +{} From 4eb2a55fefa4957910bf341f76a40b3e6e861179 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Tue, 28 May 2024 18:34:51 +0000 Subject: [PATCH 018/335] Include image blur hash in `ImageDto` (#796) --- src/DTO/ImageDto.php | 8 ++++++-- src/Factory/ImageFactory.php | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/DTO/ImageDto.php b/src/DTO/ImageDto.php index 9a04b6a3e..d3c1a9cc6 100644 --- a/src/DTO/ImageDto.php +++ b/src/DTO/ImageDto.php @@ -23,10 +23,12 @@ class ImageDto implements \JsonSerializable public ?int $width = null; #[Groups(['common'])] public ?int $height = null; + #[Groups(['common'])] + public ?string $blurHash = null; #[Ignore] public ?int $id = null; - public static function create(int $id, ?string $filePath, int $width = null, int $height = null, string $altText = null, string $sourceUrl = null, string $storageUrl = null): self + public static function create(int $id, ?string $filePath, int $width = null, int $height = null, string $altText = null, string $sourceUrl = null, string $storageUrl = null, string $blurHash = null): self { $dto = new ImageDto(); $dto->filePath = $filePath; @@ -35,12 +37,13 @@ public static function create(int $id, ?string $filePath, int $width = null, int $dto->height = $height; $dto->sourceUrl = $sourceUrl; $dto->storageUrl = $storageUrl; + $dto->blurHash = $blurHash; $dto->id = $id; return $dto; } - public function jsonSerialize(): mixed + public function jsonSerialize(): array { return [ 'filePath' => $this->filePath, @@ -49,6 +52,7 @@ public function jsonSerialize(): mixed 'altText' => $this->altText, 'width' => $this->width, 'height' => $this->height, + 'blurHash' => $this->blurHash, ]; } } diff --git a/src/Factory/ImageFactory.php b/src/Factory/ImageFactory.php index 3e3a2de93..4b246726a 100644 --- a/src/Factory/ImageFactory.php +++ b/src/Factory/ImageFactory.php @@ -32,6 +32,7 @@ public function createDto(Image $image): ImageDto $image->altText, $image->sourceUrl, $this->imageManager->getUrl($image), + $image->blurhash, ); } } From f2200627363f8a8b4a4fc29dabcf7bfef7f96857 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Tue, 28 May 2024 22:45:27 +0200 Subject: [PATCH 019/335] Update packages (#793) --- composer.lock | 1471 +++++++++--------- package-lock.json | 3673 ++++++++++++++++++++++++++++----------------- symfony.lock | 2 +- 3 files changed, 3018 insertions(+), 2128 deletions(-) diff --git a/composer.lock b/composer.lock index f6e75d139..590efdce9 100644 --- a/composer.lock +++ b/composer.lock @@ -8,16 +8,16 @@ "packages": [ { "name": "aws/aws-crt-php", - "version": "v1.2.4", + "version": "v1.2.5", "source": { "type": "git", "url": "https://github.com/awslabs/aws-crt-php.git", - "reference": "eb0c6e4e142224a10b08f49ebf87f32611d162b2" + "reference": "0ea1f04ec5aa9f049f97e012d1ed63b76834a31b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/eb0c6e4e142224a10b08f49ebf87f32611d162b2", - "reference": "eb0c6e4e142224a10b08f49ebf87f32611d162b2", + "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/0ea1f04ec5aa9f049f97e012d1ed63b76834a31b", + "reference": "0ea1f04ec5aa9f049f97e012d1ed63b76834a31b", "shasum": "" }, "require": { @@ -56,22 +56,22 @@ ], "support": { "issues": "https://github.com/awslabs/aws-crt-php/issues", - "source": "https://github.com/awslabs/aws-crt-php/tree/v1.2.4" + "source": "https://github.com/awslabs/aws-crt-php/tree/v1.2.5" }, - "time": "2023-11-08T00:42:13+00:00" + "time": "2024-04-19T21:30:56+00:00" }, { "name": "aws/aws-sdk-php", - "version": "3.303.4", + "version": "3.308.3", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "9ae5429f7699701cb158780cd287d1549f45ad32" + "reference": "7fa0625056fa1fcf6732f89ba37b3f630d78de59" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/9ae5429f7699701cb158780cd287d1549f45ad32", - "reference": "9ae5429f7699701cb158780cd287d1549f45ad32", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/7fa0625056fa1fcf6732f89ba37b3f630d78de59", + "reference": "7fa0625056fa1fcf6732f89ba37b3f630d78de59", "shasum": "" }, "require": { @@ -151,9 +151,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.303.4" + "source": "https://github.com/aws/aws-sdk-php/tree/3.308.3" }, - "time": "2024-04-05T18:04:15+00:00" + "time": "2024-05-24T18:29:40+00:00" }, { "name": "babdev/pagerfanta-bundle", @@ -858,16 +858,16 @@ }, { "name": "doctrine/collections", - "version": "2.2.1", + "version": "2.2.2", "source": { "type": "git", "url": "https://github.com/doctrine/collections.git", - "reference": "420480fc085bc65f3c956af13abe8e7546f94813" + "reference": "d8af7f248c74f195f7347424600fd9e17b57af59" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/420480fc085bc65f3c956af13abe8e7546f94813", - "reference": "420480fc085bc65f3c956af13abe8e7546f94813", + "url": "https://api.github.com/repos/doctrine/collections/zipball/d8af7f248c74f195f7347424600fd9e17b57af59", + "reference": "d8af7f248c74f195f7347424600fd9e17b57af59", "shasum": "" }, "require": { @@ -924,7 +924,7 @@ ], "support": { "issues": "https://github.com/doctrine/collections/issues", - "source": "https://github.com/doctrine/collections/tree/2.2.1" + "source": "https://github.com/doctrine/collections/tree/2.2.2" }, "funding": [ { @@ -940,20 +940,20 @@ "type": "tidelift" } ], - "time": "2024-03-05T22:28:45+00:00" + "time": "2024-04-18T06:56:21+00:00" }, { "name": "doctrine/common", - "version": "3.4.3", + "version": "3.4.4", "source": { "type": "git", "url": "https://github.com/doctrine/common.git", - "reference": "8b5e5650391f851ed58910b3e3d48a71062eeced" + "reference": "0aad4b7ab7ce8c6602dfbb1e1a24581275fb9d1a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/8b5e5650391f851ed58910b3e3d48a71062eeced", - "reference": "8b5e5650391f851ed58910b3e3d48a71062eeced", + "url": "https://api.github.com/repos/doctrine/common/zipball/0aad4b7ab7ce8c6602dfbb1e1a24581275fb9d1a", + "reference": "0aad4b7ab7ce8c6602dfbb1e1a24581275fb9d1a", "shasum": "" }, "require": { @@ -1015,7 +1015,7 @@ ], "support": { "issues": "https://github.com/doctrine/common/issues", - "source": "https://github.com/doctrine/common/tree/3.4.3" + "source": "https://github.com/doctrine/common/tree/3.4.4" }, "funding": [ { @@ -1031,20 +1031,20 @@ "type": "tidelift" } ], - "time": "2022-10-09T11:47:59+00:00" + "time": "2024-04-16T13:35:33+00:00" }, { "name": "doctrine/dbal", - "version": "3.8.3", + "version": "3.8.4", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "db922ba9436b7b18a23d1653a0b41ff2369ca41c" + "reference": "b05e48a745f722801f55408d0dbd8003b403dbbd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/db922ba9436b7b18a23d1653a0b41ff2369ca41c", - "reference": "db922ba9436b7b18a23d1653a0b41ff2369ca41c", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/b05e48a745f722801f55408d0dbd8003b403dbbd", + "reference": "b05e48a745f722801f55408d0dbd8003b403dbbd", "shasum": "" }, "require": { @@ -1128,7 +1128,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.8.3" + "source": "https://github.com/doctrine/dbal/tree/3.8.4" }, "funding": [ { @@ -1144,7 +1144,7 @@ "type": "tidelift" } ], - "time": "2024-03-03T15:55:06+00:00" + "time": "2024-04-25T07:04:44+00:00" }, { "name": "doctrine/deprecations", @@ -1315,16 +1315,16 @@ }, { "name": "doctrine/doctrine-migrations-bundle", - "version": "3.3.0", + "version": "3.3.1", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineMigrationsBundle.git", - "reference": "1dd42906a5fb9c5960723e2ebb45c68006493835" + "reference": "715b62c31a5894afcb2b2cdbbc6607d7dd0580c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineMigrationsBundle/zipball/1dd42906a5fb9c5960723e2ebb45c68006493835", - "reference": "1dd42906a5fb9c5960723e2ebb45c68006493835", + "url": "https://api.github.com/repos/doctrine/DoctrineMigrationsBundle/zipball/715b62c31a5894afcb2b2cdbbc6607d7dd0580c0", + "reference": "715b62c31a5894afcb2b2cdbbc6607d7dd0580c0", "shasum": "" }, "require": { @@ -1335,6 +1335,7 @@ "symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0" }, "require-dev": { + "composer/semver": "^3.0", "doctrine/coding-standard": "^12", "doctrine/orm": "^2.6 || ^3", "doctrine/persistence": "^2.0 || ^3 ", @@ -1386,7 +1387,7 @@ ], "support": { "issues": "https://github.com/doctrine/DoctrineMigrationsBundle/issues", - "source": "https://github.com/doctrine/DoctrineMigrationsBundle/tree/3.3.0" + "source": "https://github.com/doctrine/DoctrineMigrationsBundle/tree/3.3.1" }, "funding": [ { @@ -1402,20 +1403,20 @@ "type": "tidelift" } ], - "time": "2023-11-13T19:44:41+00:00" + "time": "2024-05-14T20:32:18+00:00" }, { "name": "doctrine/event-manager", - "version": "2.0.0", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/doctrine/event-manager.git", - "reference": "750671534e0241a7c50ea5b43f67e23eb5c96f32" + "reference": "b680156fa328f1dfd874fd48c7026c41570b9c6e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/event-manager/zipball/750671534e0241a7c50ea5b43f67e23eb5c96f32", - "reference": "750671534e0241a7c50ea5b43f67e23eb5c96f32", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/b680156fa328f1dfd874fd48c7026c41570b9c6e", + "reference": "b680156fa328f1dfd874fd48c7026c41570b9c6e", "shasum": "" }, "require": { @@ -1425,10 +1426,10 @@ "doctrine/common": "<2.9" }, "require-dev": { - "doctrine/coding-standard": "^10", + "doctrine/coding-standard": "^12", "phpstan/phpstan": "^1.8.8", - "phpunit/phpunit": "^9.5", - "vimeo/psalm": "^4.28" + "phpunit/phpunit": "^10.5", + "vimeo/psalm": "^5.24" }, "type": "library", "autoload": { @@ -1477,7 +1478,7 @@ ], "support": { "issues": "https://github.com/doctrine/event-manager/issues", - "source": "https://github.com/doctrine/event-manager/tree/2.0.0" + "source": "https://github.com/doctrine/event-manager/tree/2.0.1" }, "funding": [ { @@ -1493,7 +1494,7 @@ "type": "tidelift" } ], - "time": "2022-10-12T20:59:15+00:00" + "time": "2024-05-22T20:47:39+00:00" }, { "name": "doctrine/inflector", @@ -1837,16 +1838,16 @@ }, { "name": "doctrine/orm", - "version": "2.19.3", + "version": "2.19.5", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "1a5a4c674a416b4fdf76833c627c5e7f58bbb890" + "reference": "94986af28452da42a46a4489d1c958a2e5d710e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/1a5a4c674a416b4fdf76833c627c5e7f58bbb890", - "reference": "1a5a4c674a416b4fdf76833c627c5e7f58bbb890", + "url": "https://api.github.com/repos/doctrine/orm/zipball/94986af28452da42a46a4489d1c958a2e5d710e5", + "reference": "94986af28452da42a46a4489d1c958a2e5d710e5", "shasum": "" }, "require": { @@ -1932,9 +1933,9 @@ ], "support": { "issues": "https://github.com/doctrine/orm/issues", - "source": "https://github.com/doctrine/orm/tree/2.19.3" + "source": "https://github.com/doctrine/orm/tree/2.19.5" }, - "time": "2024-03-21T11:01:42+00:00" + "time": "2024-04-30T06:49:54+00:00" }, { "name": "doctrine/persistence", @@ -2036,23 +2037,26 @@ }, { "name": "doctrine/sql-formatter", - "version": "1.2.0", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/doctrine/sql-formatter.git", - "reference": "a321d114e0a18e6497f8a2cd6f890e000cc17ecc" + "reference": "d1ac84aef745c69ea034929eb6d65a6908b675cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/sql-formatter/zipball/a321d114e0a18e6497f8a2cd6f890e000cc17ecc", - "reference": "a321d114e0a18e6497f8a2cd6f890e000cc17ecc", + "url": "https://api.github.com/repos/doctrine/sql-formatter/zipball/d1ac84aef745c69ea034929eb6d65a6908b675cc", + "reference": "d1ac84aef745c69ea034929eb6d65a6908b675cc", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": "^8.1" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.4" + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5", + "vimeo/psalm": "^5.24" }, "bin": [ "bin/sql-formatter" @@ -2082,9 +2086,9 @@ ], "support": { "issues": "https://github.com/doctrine/sql-formatter/issues", - "source": "https://github.com/doctrine/sql-formatter/tree/1.2.0" + "source": "https://github.com/doctrine/sql-formatter/tree/1.4.0" }, - "time": "2023-08-16T21:49:04+00:00" + "time": "2024-05-08T08:12:09+00:00" }, { "name": "egulias/email-validator", @@ -2319,26 +2323,26 @@ }, { "name": "firebase/php-jwt", - "version": "v6.10.0", + "version": "v6.10.1", "source": { "type": "git", "url": "https://github.com/firebase/php-jwt.git", - "reference": "a49db6f0a5033aef5143295342f1c95521b075ff" + "reference": "500501c2ce893c824c801da135d02661199f60c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/a49db6f0a5033aef5143295342f1c95521b075ff", - "reference": "a49db6f0a5033aef5143295342f1c95521b075ff", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/500501c2ce893c824c801da135d02661199f60c5", + "reference": "500501c2ce893c824c801da135d02661199f60c5", "shasum": "" }, "require": { - "php": "^7.4||^8.0" + "php": "^8.0" }, "require-dev": { - "guzzlehttp/guzzle": "^6.5||^7.4", + "guzzlehttp/guzzle": "^7.4", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", - "psr/cache": "^1.0||^2.0", + "psr/cache": "^2.0||^3.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0" }, @@ -2376,9 +2380,9 @@ ], "support": { "issues": "https://github.com/firebase/php-jwt/issues", - "source": "https://github.com/firebase/php-jwt/tree/v6.10.0" + "source": "https://github.com/firebase/php-jwt/tree/v6.10.1" }, - "time": "2023-12-01T16:26:39+00:00" + "time": "2024-05-18T18:05:11+00:00" }, { "name": "friendsofsymfony/jsrouting-bundle", @@ -3394,16 +3398,16 @@ }, { "name": "lcobucci/jwt", - "version": "5.2.0", + "version": "5.3.0", "source": { "type": "git", "url": "https://github.com/lcobucci/jwt.git", - "reference": "0ba88aed12c04bd2ed9924f500673f32b67a6211" + "reference": "08071d8d2c7f4b00222cc4b1fb6aa46990a80f83" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lcobucci/jwt/zipball/0ba88aed12c04bd2ed9924f500673f32b67a6211", - "reference": "0ba88aed12c04bd2ed9924f500673f32b67a6211", + "url": "https://api.github.com/repos/lcobucci/jwt/zipball/08071d8d2c7f4b00222cc4b1fb6aa46990a80f83", + "reference": "08071d8d2c7f4b00222cc4b1fb6aa46990a80f83", "shasum": "" }, "require": { @@ -3451,7 +3455,7 @@ ], "support": { "issues": "https://github.com/lcobucci/jwt/issues", - "source": "https://github.com/lcobucci/jwt/tree/5.2.0" + "source": "https://github.com/lcobucci/jwt/tree/5.3.0" }, "funding": [ { @@ -3463,7 +3467,7 @@ "type": "patreon" } ], - "time": "2023-11-20T21:17:42+00:00" + "time": "2024-04-11T23:07:54+00:00" }, { "name": "league/commonmark", @@ -3709,16 +3713,16 @@ }, { "name": "league/flysystem", - "version": "3.26.0", + "version": "3.28.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "072735c56cc0da00e10716dd90d5a7f7b40b36be" + "reference": "e611adab2b1ae2e3072fa72d62c62f52c2bf1f0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/072735c56cc0da00e10716dd90d5a7f7b40b36be", - "reference": "072735c56cc0da00e10716dd90d5a7f7b40b36be", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/e611adab2b1ae2e3072fa72d62c62f52c2bf1f0c", + "reference": "e611adab2b1ae2e3072fa72d62c62f52c2bf1f0c", "shasum": "" }, "require": { @@ -3742,10 +3746,13 @@ "composer/semver": "^3.0", "ext-fileinfo": "*", "ext-ftp": "*", + "ext-mongodb": "^1.3", "ext-zip": "*", "friendsofphp/php-cs-fixer": "^3.5", "google/cloud-storage": "^1.23", + "guzzlehttp/psr7": "^2.6", "microsoft/azure-storage-blob": "^1.1", + "mongodb/mongodb": "^1.2", "phpseclib/phpseclib": "^3.0.36", "phpstan/phpstan": "^1.10", "phpunit/phpunit": "^9.5.11|^10.0", @@ -3783,32 +3790,22 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/3.26.0" + "source": "https://github.com/thephpleague/flysystem/tree/3.28.0" }, - "funding": [ - { - "url": "https://ecologi.com/frankdejonge", - "type": "custom" - }, - { - "url": "https://github.com/frankdejonge", - "type": "github" - } - ], - "time": "2024-03-25T11:49:53+00:00" + "time": "2024-05-22T10:09:12+00:00" }, { "name": "league/flysystem-aws-s3-v3", - "version": "3.26.0", + "version": "3.28.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem-aws-s3-v3.git", - "reference": "885d0a758c71ae3cd6c503544573a1fdb8dc754f" + "reference": "22071ef1604bc776f5ff2468ac27a752514665c8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/885d0a758c71ae3cd6c503544573a1fdb8dc754f", - "reference": "885d0a758c71ae3cd6c503544573a1fdb8dc754f", + "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/22071ef1604bc776f5ff2468ac27a752514665c8", + "reference": "22071ef1604bc776f5ff2468ac27a752514665c8", "shasum": "" }, "require": { @@ -3848,32 +3845,22 @@ "storage" ], "support": { - "source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/3.26.0" + "source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/3.28.0" }, - "funding": [ - { - "url": "https://ecologi.com/frankdejonge", - "type": "custom" - }, - { - "url": "https://github.com/frankdejonge", - "type": "github" - } - ], - "time": "2024-03-24T21:11:18+00:00" + "time": "2024-05-06T20:05:52+00:00" }, { "name": "league/flysystem-local", - "version": "3.25.1", + "version": "3.28.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem-local.git", - "reference": "61a6a90d6e999e4ddd9ce5adb356de0939060b92" + "reference": "13f22ea8be526ea58c2ddff9e158ef7c296e4f40" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/61a6a90d6e999e4ddd9ce5adb356de0939060b92", - "reference": "61a6a90d6e999e4ddd9ce5adb356de0939060b92", + "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/13f22ea8be526ea58c2ddff9e158ef7c296e4f40", + "reference": "13f22ea8be526ea58c2ddff9e158ef7c296e4f40", "shasum": "" }, "require": { @@ -3907,19 +3894,9 @@ "local" ], "support": { - "source": "https://github.com/thephpleague/flysystem-local/tree/3.25.1" + "source": "https://github.com/thephpleague/flysystem-local/tree/3.28.0" }, - "funding": [ - { - "url": "https://ecologi.com/frankdejonge", - "type": "custom" - }, - { - "url": "https://github.com/frankdejonge", - "type": "github" - } - ], - "time": "2024-03-15T19:58:44+00:00" + "time": "2024-05-06T20:05:52+00:00" }, { "name": "league/html-to-markdown", @@ -4650,16 +4627,16 @@ }, { "name": "liip/imagine-bundle", - "version": "2.12.2", + "version": "2.12.3", "source": { "type": "git", "url": "https://github.com/liip/LiipImagineBundle.git", - "reference": "2ad259dd46ce55f93c6e8d87908d2572bd94796e" + "reference": "fa2baa6262bb74038f01ac746dc3e2a8bc441e09" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/liip/LiipImagineBundle/zipball/2ad259dd46ce55f93c6e8d87908d2572bd94796e", - "reference": "2ad259dd46ce55f93c6e8d87908d2572bd94796e", + "url": "https://api.github.com/repos/liip/LiipImagineBundle/zipball/fa2baa6262bb74038f01ac746dc3e2a8bc441e09", + "reference": "fa2baa6262bb74038f01ac746dc3e2a8bc441e09", "shasum": "" }, "require": { @@ -4747,9 +4724,9 @@ ], "support": { "issues": "https://github.com/liip/LiipImagineBundle/issues", - "source": "https://github.com/liip/LiipImagineBundle/tree/2.12.2" + "source": "https://github.com/liip/LiipImagineBundle/tree/2.12.3" }, - "time": "2024-02-23T21:12:25+00:00" + "time": "2024-05-16T08:51:30+00:00" }, { "name": "meteo-concept/hcaptcha-bundle", @@ -4921,16 +4898,16 @@ }, { "name": "monolog/monolog", - "version": "3.5.0", + "version": "3.6.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "c915e2634718dbc8a4a15c61b0e62e7a44e14448" + "reference": "4b18b21a5527a3d5ffdac2fd35d3ab25a9597654" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/c915e2634718dbc8a4a15c61b0e62e7a44e14448", - "reference": "c915e2634718dbc8a4a15c61b0e62e7a44e14448", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/4b18b21a5527a3d5ffdac2fd35d3ab25a9597654", + "reference": "4b18b21a5527a3d5ffdac2fd35d3ab25a9597654", "shasum": "" }, "require": { @@ -4953,7 +4930,7 @@ "phpstan/phpstan": "^1.9", "phpstan/phpstan-deprecation-rules": "^1.0", "phpstan/phpstan-strict-rules": "^1.4", - "phpunit/phpunit": "^10.1", + "phpunit/phpunit": "^10.5.17", "predis/predis": "^1.1 || ^2", "ruflin/elastica": "^7", "symfony/mailer": "^5.4 || ^6", @@ -5006,7 +4983,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/3.5.0" + "source": "https://github.com/Seldaek/monolog/tree/3.6.0" }, "funding": [ { @@ -5018,7 +4995,7 @@ "type": "tidelift" } ], - "time": "2023-10-27T15:32:31+00:00" + "time": "2024-04-12T21:02:21+00:00" }, { "name": "mtdowling/jmespath.php", @@ -5524,16 +5501,16 @@ }, { "name": "omines/antispam-bundle", - "version": "0.1.6", + "version": "0.1.7", "source": { "type": "git", "url": "https://github.com/omines/antispam-bundle.git", - "reference": "628493dc2d03dc59fab27fa5c5a61395174ed0f0" + "reference": "16a730c6f08e7505b4d2f274fd2337e34103ae7b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/omines/antispam-bundle/zipball/628493dc2d03dc59fab27fa5c5a61395174ed0f0", - "reference": "628493dc2d03dc59fab27fa5c5a61395174ed0f0", + "url": "https://api.github.com/repos/omines/antispam-bundle/zipball/16a730c6f08e7505b4d2f274fd2337e34103ae7b", + "reference": "16a730c6f08e7505b4d2f274fd2337e34103ae7b", "shasum": "" }, "require": { @@ -5549,26 +5526,27 @@ "symfony/yaml": "^6.3|^7.0" }, "conflict": { - "monolog/monolog": "<3" + "monolog/monolog": "<3", + "twig/twig": "<3.1" }, "require-dev": { "ekino/phpstan-banned-code": "^1.0", - "friendsofphp/php-cs-fixer": "^3.38.2", - "infection/infection": "^0.27.8", + "friendsofphp/php-cs-fixer": "^3.54.0", + "infection/infection": "^0.28.1", "phpstan/extension-installer": "^1.3.1", - "phpstan/phpstan": "^1.10.41", - "phpstan/phpstan-phpunit": "^1.3.15", - "phpstan/phpstan-symfony": "^1.3.5", - "phpunit/phpunit": "^10.4.2", - "symfony/browser-kit": "^6.3|^7.0", - "symfony/css-selector": "^6.3|^7.0", - "symfony/debug-bundle": "^6.3|^7.0", - "symfony/dotenv": "^6.3|^7.0", - "symfony/monolog-bundle": "^3.8", - "symfony/routing": "^6.3|^7.0", - "symfony/runtime": "^6.3|^7.0", - "symfony/twig-bundle": "^6.3|^7.0", - "symfony/web-profiler-bundle": "^6.3|^7.0" + "phpstan/phpstan": "^1.10.67", + "phpstan/phpstan-phpunit": "^1.3.16", + "phpstan/phpstan-symfony": "^1.3.12", + "phpunit/phpunit": "^10.5.15 || ^11.1.3", + "symfony/browser-kit": "^6.3|^7.0.3", + "symfony/css-selector": "^6.3|^7.0.3", + "symfony/debug-bundle": "^6.3|^7.0.3", + "symfony/dotenv": "^6.3|^7.0.4", + "symfony/monolog-bundle": "^3.10", + "symfony/routing": "^6.3|^7.0.6", + "symfony/runtime": "^6.3|^7.0.3", + "symfony/twig-bundle": "^6.3|^7.0.4", + "symfony/web-profiler-bundle": "^6.3|^7.0.4" }, "type": "symfony-bundle", "extra": { @@ -5603,7 +5581,7 @@ ], "support": { "issues": "https://github.com/omines/antispam-bundle/issues", - "source": "https://github.com/omines/antispam-bundle/tree/0.1.6" + "source": "https://github.com/omines/antispam-bundle/tree/0.1.7" }, "funding": [ { @@ -5611,20 +5589,20 @@ "type": "github" } ], - "time": "2023-11-27T09:36:34+00:00" + "time": "2024-05-27T11:47:44+00:00" }, { "name": "oneup/flysystem-bundle", - "version": "4.12.0", + "version": "4.12.1", "source": { "type": "git", "url": "https://github.com/1up-lab/OneupFlysystemBundle.git", - "reference": "76949b068d1b3756ffac8abb1ba758fcb979a6a3" + "reference": "625175dcb65f4cdedd52d0a644683a2ebdc688d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/1up-lab/OneupFlysystemBundle/zipball/76949b068d1b3756ffac8abb1ba758fcb979a6a3", - "reference": "76949b068d1b3756ffac8abb1ba758fcb979a6a3", + "url": "https://api.github.com/repos/1up-lab/OneupFlysystemBundle/zipball/625175dcb65f4cdedd52d0a644683a2ebdc688d2", + "reference": "625175dcb65f4cdedd52d0a644683a2ebdc688d2", "shasum": "" }, "require": { @@ -5652,7 +5630,6 @@ "symfony/finder": "^5.4 || ^6.0 || ^7.0", "symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0", "symfony/phpunit-bridge": "^7.0", - "symfony/templating": "^5.4 || ^6.0 || ^7.0", "symfony/translation": "^5.4 || ^6.0 || ^7.0", "symfony/yaml": "^5.4 || ^6.0 || ^7.0" }, @@ -5699,9 +5676,9 @@ ], "support": { "issues": "https://github.com/1up-lab/OneupFlysystemBundle/issues", - "source": "https://github.com/1up-lab/OneupFlysystemBundle/tree/4.12.0" + "source": "https://github.com/1up-lab/OneupFlysystemBundle/tree/4.12.1" }, - "time": "2024-03-14T09:30:06+00:00" + "time": "2024-04-08T13:50:27+00:00" }, { "name": "oscarotero/html-parser", @@ -5803,7 +5780,7 @@ }, { "name": "pagerfanta/doctrine-collections-adapter", - "version": "v4.4.0", + "version": "v4.5.0", "source": { "type": "git", "url": "https://github.com/Pagerfanta/doctrine-collections-adapter.git", @@ -5843,13 +5820,13 @@ "pagerfanta" ], "support": { - "source": "https://github.com/Pagerfanta/doctrine-collections-adapter/tree/v4.4.0" + "source": "https://github.com/Pagerfanta/doctrine-collections-adapter/tree/v4.5.0" }, "time": "2024-03-06T23:51:47+00:00" }, { "name": "pagerfanta/doctrine-dbal-adapter", - "version": "v4.4.0", + "version": "v4.5.0", "source": { "type": "git", "url": "https://github.com/Pagerfanta/doctrine-dbal-adapter.git", @@ -5889,13 +5866,13 @@ "pagerfanta" ], "support": { - "source": "https://github.com/Pagerfanta/doctrine-dbal-adapter/tree/v4.4.0" + "source": "https://github.com/Pagerfanta/doctrine-dbal-adapter/tree/v4.5.0" }, "time": "2024-03-06T23:51:47+00:00" }, { "name": "pagerfanta/doctrine-orm-adapter", - "version": "v4.4.0", + "version": "v4.5.0", "source": { "type": "git", "url": "https://github.com/Pagerfanta/doctrine-orm-adapter.git", @@ -5936,13 +5913,13 @@ "pagerfanta" ], "support": { - "source": "https://github.com/Pagerfanta/doctrine-orm-adapter/tree/v4.4.0" + "source": "https://github.com/Pagerfanta/doctrine-orm-adapter/tree/v4.5.0" }, "time": "2024-03-06T23:51:47+00:00" }, { "name": "pagerfanta/twig", - "version": "v4.4.0", + "version": "v4.5.0", "source": { "type": "git", "url": "https://github.com/Pagerfanta/twig.git", @@ -5980,22 +5957,22 @@ "pagerfanta" ], "support": { - "source": "https://github.com/Pagerfanta/twig/tree/v4.4.0" + "source": "https://github.com/Pagerfanta/twig/tree/v4.5.0" }, "time": "2024-03-06T23:51:47+00:00" }, { "name": "paragonie/constant_time_encoding", - "version": "v2.6.3", + "version": "v2.7.0", "source": { "type": "git", "url": "https://github.com/paragonie/constant_time_encoding.git", - "reference": "58c3f47f650c94ec05a151692652a868995d2938" + "reference": "52a0d99e69f56b9ec27ace92ba56897fe6993105" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/58c3f47f650c94ec05a151692652a868995d2938", - "reference": "58c3f47f650c94ec05a151692652a868995d2938", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/52a0d99e69f56b9ec27ace92ba56897fe6993105", + "reference": "52a0d99e69f56b9ec27ace92ba56897fe6993105", "shasum": "" }, "require": { @@ -6049,7 +6026,7 @@ "issues": "https://github.com/paragonie/constant_time_encoding/issues", "source": "https://github.com/paragonie/constant_time_encoding" }, - "time": "2022-06-14T06:56:20+00:00" + "time": "2024-05-08T12:18:48+00:00" }, { "name": "paragonie/random_compat", @@ -6741,20 +6718,20 @@ }, { "name": "psr/http-factory", - "version": "1.0.2", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/php-fig/http-factory.git", - "reference": "e616d01114759c4c489f93b099585439f795fe35" + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", - "reference": "e616d01114759c4c489f93b099585439f795fe35", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", "shasum": "" }, "require": { - "php": ">=7.0.0", + "php": ">=7.1", "psr/http-message": "^1.0 || ^2.0" }, "type": "library", @@ -6778,7 +6755,7 @@ "homepage": "https://www.php-fig.org/" } ], - "description": "Common interfaces for PSR-7 HTTP message factories", + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", "keywords": [ "factory", "http", @@ -6790,9 +6767,9 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-factory/tree/1.0.2" + "source": "https://github.com/php-fig/http-factory" }, - "time": "2023-04-10T20:10:41+00:00" + "time": "2024-04-15T12:06:14+00:00" }, { "name": "psr/http-message", @@ -6999,7 +6976,7 @@ }, { "name": "scheb/2fa-backup-code", - "version": "v7.2.0", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/scheb/2fa-backup-code.git", @@ -7042,22 +7019,22 @@ "two-step" ], "support": { - "source": "https://github.com/scheb/2fa-backup-code/tree/v7.2.0" + "source": "https://github.com/scheb/2fa-backup-code/tree/v7.3.0" }, "time": "2023-12-03T16:24:13+00:00" }, { "name": "scheb/2fa-bundle", - "version": "v7.2.0", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/scheb/2fa-bundle.git", - "reference": "3eac1a44af1707056426197eda3c7a54a5ac9719" + "reference": "9d5a7b680ce2e6eb15bdfb779c09313b88f365cd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/scheb/2fa-bundle/zipball/3eac1a44af1707056426197eda3c7a54a5ac9719", - "reference": "3eac1a44af1707056426197eda3c7a54a5ac9719", + "url": "https://api.github.com/repos/scheb/2fa-bundle/zipball/9d5a7b680ce2e6eb15bdfb779c09313b88f365cd", + "reference": "9d5a7b680ce2e6eb15bdfb779c09313b88f365cd", "shasum": "" }, "require": { @@ -7109,13 +7086,13 @@ "two-step" ], "support": { - "source": "https://github.com/scheb/2fa-bundle/tree/v7.2.0" + "source": "https://github.com/scheb/2fa-bundle/tree/v7.3.0" }, - "time": "2024-01-26T17:30:55+00:00" + "time": "2024-04-20T14:21:34+00:00" }, { "name": "scheb/2fa-totp", - "version": "v7.2.0", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/scheb/2fa-totp.git", @@ -7159,7 +7136,7 @@ "two-step" ], "support": { - "source": "https://github.com/scheb/2fa-totp/tree/v7.2.0" + "source": "https://github.com/scheb/2fa-totp/tree/v7.3.0" }, "time": "2024-01-18T20:20:03+00:00" }, @@ -7239,16 +7216,16 @@ }, { "name": "spomky-labs/otphp", - "version": "11.2.0", + "version": "11.2.2", "source": { "type": "git", "url": "https://github.com/Spomky-Labs/otphp.git", - "reference": "9a1569038bb1c8e98040b14b8bcbba54f25e7795" + "reference": "b737d1c6330beae7c0bc225d3e848805b352fe42" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Spomky-Labs/otphp/zipball/9a1569038bb1c8e98040b14b8bcbba54f25e7795", - "reference": "9a1569038bb1c8e98040b14b8bcbba54f25e7795", + "url": "https://api.github.com/repos/Spomky-Labs/otphp/zipball/b737d1c6330beae7c0bc225d3e848805b352fe42", + "reference": "b737d1c6330beae7c0bc225d3e848805b352fe42", "shasum": "" }, "require": { @@ -7258,17 +7235,17 @@ }, "require-dev": { "ekino/phpstan-banned-code": "^1.0", - "infection/infection": "^0.26", + "infection/infection": "^0.26|^0.27|^0.28", "php-parallel-lint/php-parallel-lint": "^1.3", "phpstan/phpstan": "^1.0", "phpstan/phpstan-deprecation-rules": "^1.0", "phpstan/phpstan-phpunit": "^1.0", "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/phpunit": "^9.5.26", + "phpunit/phpunit": "^9.5.26|^10.0|^11.0", "qossmic/deptrac-shim": "^1.0", - "rector/rector": "^0.15", - "symfony/phpunit-bridge": "^6.1", - "symplify/easy-coding-standard": "^11.0" + "rector/rector": "1.0", + "symfony/phpunit-bridge": "^6.1|^7.0", + "symplify/easy-coding-standard": "^12.0" }, "type": "library", "autoload": { @@ -7303,7 +7280,7 @@ ], "support": { "issues": "https://github.com/Spomky-Labs/otphp/issues", - "source": "https://github.com/Spomky-Labs/otphp/tree/11.2.0" + "source": "https://github.com/Spomky-Labs/otphp/tree/11.2.2" }, "funding": [ { @@ -7315,7 +7292,7 @@ "type": "patreon" } ], - "time": "2023-03-16T19:16:25+00:00" + "time": "2024-04-15T07:35:15+00:00" }, { "name": "stevenmaguire/oauth2-keycloak", @@ -7380,16 +7357,16 @@ }, { "name": "symfony/amqp-messenger", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/amqp-messenger.git", - "reference": "e65375faa77103493948c5d46b59bebde93aa0b1" + "reference": "65ed12f46fc542d9b855af94ced90563cabbbad7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/amqp-messenger/zipball/e65375faa77103493948c5d46b59bebde93aa0b1", - "reference": "e65375faa77103493948c5d46b59bebde93aa0b1", + "url": "https://api.github.com/repos/symfony/amqp-messenger/zipball/65ed12f46fc542d9b855af94ced90563cabbbad7", + "reference": "65ed12f46fc542d9b855af94ced90563cabbbad7", "shasum": "" }, "require": { @@ -7429,7 +7406,7 @@ "description": "Symfony AMQP extension Messenger Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/amqp-messenger/tree/v7.0.6" + "source": "https://github.com/symfony/amqp-messenger/tree/v7.0.7" }, "funding": [ { @@ -7445,20 +7422,20 @@ "type": "tidelift" } ], - "time": "2024-03-08T07:05:25+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/asset", - "version": "v7.0.3", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/asset.git", - "reference": "3ae493792fc17cc31b84e231f30f2d154575f171" + "reference": "dc7600afc7e6676b3401326ae9c9abfcee4b40c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/asset/zipball/3ae493792fc17cc31b84e231f30f2d154575f171", - "reference": "3ae493792fc17cc31b84e231f30f2d154575f171", + "url": "https://api.github.com/repos/symfony/asset/zipball/dc7600afc7e6676b3401326ae9c9abfcee4b40c5", + "reference": "dc7600afc7e6676b3401326ae9c9abfcee4b40c5", "shasum": "" }, "require": { @@ -7498,7 +7475,7 @@ "description": "Manages URL generation and versioning of web assets such as CSS stylesheets, JavaScript files and image files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/asset/tree/v7.0.3" + "source": "https://github.com/symfony/asset/tree/v7.0.7" }, "funding": [ { @@ -7514,20 +7491,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T15:02:46+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/cache", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "2d0d3f92c74c445410d05374908b03e0a1131e2b" + "reference": "48e3508338987d63b0114a00c208c4cbb76e5303" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/2d0d3f92c74c445410d05374908b03e0a1131e2b", - "reference": "2d0d3f92c74c445410d05374908b03e0a1131e2b", + "url": "https://api.github.com/repos/symfony/cache/zipball/48e3508338987d63b0114a00c208c4cbb76e5303", + "reference": "48e3508338987d63b0114a00c208c4cbb76e5303", "shasum": "" }, "require": { @@ -7594,7 +7571,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v7.0.6" + "source": "https://github.com/symfony/cache/tree/v7.0.7" }, "funding": [ { @@ -7610,20 +7587,20 @@ "type": "tidelift" } ], - "time": "2024-03-27T19:55:25+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/cache-contracts", - "version": "v3.4.2", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/cache-contracts.git", - "reference": "2c9db6509a1b21dad229606897639d3284f54b2a" + "reference": "df6a1a44c890faded49a5fca33c2d5c5fd3c2197" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/2c9db6509a1b21dad229606897639d3284f54b2a", - "reference": "2c9db6509a1b21dad229606897639d3284f54b2a", + "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/df6a1a44c890faded49a5fca33c2d5c5fd3c2197", + "reference": "df6a1a44c890faded49a5fca33c2d5c5fd3c2197", "shasum": "" }, "require": { @@ -7633,7 +7610,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -7670,7 +7647,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/cache-contracts/tree/v3.4.2" + "source": "https://github.com/symfony/cache-contracts/tree/v3.5.0" }, "funding": [ { @@ -7686,20 +7663,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:51:35+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/clock", - "version": "v7.0.5", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/clock.git", - "reference": "8b9d08887353d627d5f6c3bf3373b398b49051c2" + "reference": "2008671acb4a30b01c453de193cf9c80549ebda6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/clock/zipball/8b9d08887353d627d5f6c3bf3373b398b49051c2", - "reference": "8b9d08887353d627d5f6c3bf3373b398b49051c2", + "url": "https://api.github.com/repos/symfony/clock/zipball/2008671acb4a30b01c453de193cf9c80549ebda6", + "reference": "2008671acb4a30b01c453de193cf9c80549ebda6", "shasum": "" }, "require": { @@ -7744,7 +7721,7 @@ "time" ], "support": { - "source": "https://github.com/symfony/clock/tree/v7.0.5" + "source": "https://github.com/symfony/clock/tree/v7.0.7" }, "funding": [ { @@ -7760,20 +7737,20 @@ "type": "tidelift" } ], - "time": "2024-03-02T12:46:12+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/config", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "7fc7e18a73ec8125fd95928c0340470d64760deb" + "reference": "f66f908a975500aa4594258bf454dc66e3939eac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/7fc7e18a73ec8125fd95928c0340470d64760deb", - "reference": "7fc7e18a73ec8125fd95928c0340470d64760deb", + "url": "https://api.github.com/repos/symfony/config/zipball/f66f908a975500aa4594258bf454dc66e3939eac", + "reference": "f66f908a975500aa4594258bf454dc66e3939eac", "shasum": "" }, "require": { @@ -7819,7 +7796,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v7.0.6" + "source": "https://github.com/symfony/config/tree/v7.0.7" }, "funding": [ { @@ -7835,20 +7812,20 @@ "type": "tidelift" } ], - "time": "2024-03-27T19:55:25+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/console", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "fde915cd8e7eb99b3d531d3d5c09531429c3f9e5" + "reference": "c981e0e9380ce9f146416bde3150c79197ce9986" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/fde915cd8e7eb99b3d531d3d5c09531429c3f9e5", - "reference": "fde915cd8e7eb99b3d531d3d5c09531429c3f9e5", + "url": "https://api.github.com/repos/symfony/console/zipball/c981e0e9380ce9f146416bde3150c79197ce9986", + "reference": "c981e0e9380ce9f146416bde3150c79197ce9986", "shasum": "" }, "require": { @@ -7912,7 +7889,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.0.6" + "source": "https://github.com/symfony/console/tree/v7.0.7" }, "funding": [ { @@ -7928,20 +7905,20 @@ "type": "tidelift" } ], - "time": "2024-04-01T11:04:53+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/css-selector", - "version": "v7.0.3", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "ec60a4edf94e63b0556b6a0888548bb400a3a3be" + "reference": "b08a4ad89e84b29cec285b7b1f781a7ae51cf4bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/ec60a4edf94e63b0556b6a0888548bb400a3a3be", - "reference": "ec60a4edf94e63b0556b6a0888548bb400a3a3be", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/b08a4ad89e84b29cec285b7b1f781a7ae51cf4bc", + "reference": "b08a4ad89e84b29cec285b7b1f781a7ae51cf4bc", "shasum": "" }, "require": { @@ -7977,7 +7954,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v7.0.3" + "source": "https://github.com/symfony/css-selector/tree/v7.0.7" }, "funding": [ { @@ -7993,20 +7970,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T15:02:46+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/dependency-injection", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "ff57b5c7d518c39eeb4e69dc0d1ec70723a117b9" + "reference": "4db1314337f4dd864113f88e08c9a7f98b1c1324" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/ff57b5c7d518c39eeb4e69dc0d1ec70723a117b9", - "reference": "ff57b5c7d518c39eeb4e69dc0d1ec70723a117b9", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/4db1314337f4dd864113f88e08c9a7f98b1c1324", + "reference": "4db1314337f4dd864113f88e08c9a7f98b1c1324", "shasum": "" }, "require": { @@ -8057,7 +8034,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v7.0.6" + "source": "https://github.com/symfony/dependency-injection/tree/v7.0.7" }, "funding": [ { @@ -8073,20 +8050,20 @@ "type": "tidelift" } ], - "time": "2024-03-28T09:20:36+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.4.0", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", "shasum": "" }, "require": { @@ -8095,7 +8072,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -8124,7 +8101,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" }, "funding": [ { @@ -8140,20 +8117,20 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/doctrine-bridge", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "929527febf8e134eaba620de1f9396da1db0df85" + "reference": "da605530d1a75162359d494efc00f767f7fcd68a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/929527febf8e134eaba620de1f9396da1db0df85", - "reference": "929527febf8e134eaba620de1f9396da1db0df85", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/da605530d1a75162359d494efc00f767f7fcd68a", + "reference": "da605530d1a75162359d494efc00f767f7fcd68a", "shasum": "" }, "require": { @@ -8230,7 +8207,7 @@ "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/doctrine-bridge/tree/v7.0.6" + "source": "https://github.com/symfony/doctrine-bridge/tree/v7.0.7" }, "funding": [ { @@ -8246,20 +8223,20 @@ "type": "tidelift" } ], - "time": "2024-03-19T09:29:21+00:00" + "time": "2024-04-28T11:44:19+00:00" }, { "name": "symfony/doctrine-messenger", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-messenger.git", - "reference": "227cbb2cda296d724a8e08376ad6db73a0335538" + "reference": "78ec63bf2437187ac70ca13a2db3f2a8e41b3493" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-messenger/zipball/227cbb2cda296d724a8e08376ad6db73a0335538", - "reference": "227cbb2cda296d724a8e08376ad6db73a0335538", + "url": "https://api.github.com/repos/symfony/doctrine-messenger/zipball/78ec63bf2437187ac70ca13a2db3f2a8e41b3493", + "reference": "78ec63bf2437187ac70ca13a2db3f2a8e41b3493", "shasum": "" }, "require": { @@ -8302,7 +8279,7 @@ "description": "Symfony Doctrine Messenger Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/doctrine-messenger/tree/v7.0.6" + "source": "https://github.com/symfony/doctrine-messenger/tree/v7.0.7" }, "funding": [ { @@ -8318,20 +8295,20 @@ "type": "tidelift" } ], - "time": "2024-03-19T09:26:35+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/dotenv", - "version": "v7.0.4", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/dotenv.git", - "reference": "8017ea2f0ff4fbda6ae1bf3f5409d5ecff982067" + "reference": "0fd573c141e1990848702d56329050efd5bf25cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dotenv/zipball/8017ea2f0ff4fbda6ae1bf3f5409d5ecff982067", - "reference": "8017ea2f0ff4fbda6ae1bf3f5409d5ecff982067", + "url": "https://api.github.com/repos/symfony/dotenv/zipball/0fd573c141e1990848702d56329050efd5bf25cc", + "reference": "0fd573c141e1990848702d56329050efd5bf25cc", "shasum": "" }, "require": { @@ -8376,7 +8353,7 @@ "environment" ], "support": { - "source": "https://github.com/symfony/dotenv/tree/v7.0.4" + "source": "https://github.com/symfony/dotenv/tree/v7.0.7" }, "funding": [ { @@ -8392,20 +8369,20 @@ "type": "tidelift" } ], - "time": "2024-02-09T10:53:15+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/error-handler", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "46a4cc138f799886d4bd70477c55c699d3e9dfc8" + "reference": "cf97429887e40480c847bfeb6c3991e1e2c086ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/46a4cc138f799886d4bd70477c55c699d3e9dfc8", - "reference": "46a4cc138f799886d4bd70477c55c699d3e9dfc8", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/cf97429887e40480c847bfeb6c3991e1e2c086ab", + "reference": "cf97429887e40480c847bfeb6c3991e1e2c086ab", "shasum": "" }, "require": { @@ -8451,7 +8428,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v7.0.6" + "source": "https://github.com/symfony/error-handler/tree/v7.0.7" }, "funding": [ { @@ -8467,20 +8444,20 @@ "type": "tidelift" } ], - "time": "2024-03-19T11:57:22+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v7.0.3", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "834c28d533dd0636f910909d01b9ff45cc094b5e" + "reference": "db2a7fab994d67d92356bb39c367db115d9d30f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/834c28d533dd0636f910909d01b9ff45cc094b5e", - "reference": "834c28d533dd0636f910909d01b9ff45cc094b5e", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/db2a7fab994d67d92356bb39c367db115d9d30f9", + "reference": "db2a7fab994d67d92356bb39c367db115d9d30f9", "shasum": "" }, "require": { @@ -8531,7 +8508,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.0.3" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.0.7" }, "funding": [ { @@ -8547,20 +8524,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T15:02:46+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.4.2", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "4e64b49bf370ade88e567de29465762e316e4224" + "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/4e64b49bf370ade88e567de29465762e316e4224", - "reference": "4e64b49bf370ade88e567de29465762e316e4224", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/8f93aec25d41b72493c6ddff14e916177c9efc50", + "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50", "shasum": "" }, "require": { @@ -8570,7 +8547,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -8607,7 +8584,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.2" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.0" }, "funding": [ { @@ -8623,20 +8600,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:51:35+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/expression-language", - "version": "v7.0.3", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/expression-language.git", - "reference": "0877c599cb260c9614f9229c0a2090d6919fd621" + "reference": "b8ec919a6d3d47fc4e7845c256d164413207bf73" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/expression-language/zipball/0877c599cb260c9614f9229c0a2090d6919fd621", - "reference": "0877c599cb260c9614f9229c0a2090d6919fd621", + "url": "https://api.github.com/repos/symfony/expression-language/zipball/b8ec919a6d3d47fc4e7845c256d164413207bf73", + "reference": "b8ec919a6d3d47fc4e7845c256d164413207bf73", "shasum": "" }, "require": { @@ -8670,7 +8647,7 @@ "description": "Provides an engine that can compile and evaluate expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/expression-language/tree/v7.0.3" + "source": "https://github.com/symfony/expression-language/tree/v7.0.7" }, "funding": [ { @@ -8686,26 +8663,27 @@ "type": "tidelift" } ], - "time": "2024-01-23T15:02:46+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/filesystem", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "408105dff4c104454100730bdfd1a9cdd993f04d" + "reference": "cc168be6fbdcdf3401f50ae863ee3818ed4338f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/408105dff4c104454100730bdfd1a9cdd993f04d", - "reference": "408105dff4c104454100730bdfd1a9cdd993f04d", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/cc168be6fbdcdf3401f50ae863ee3818ed4338f5", + "reference": "cc168be6fbdcdf3401f50ae863ee3818ed4338f5", "shasum": "" }, "require": { "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.8" + "symfony/polyfill-mbstring": "~1.8", + "symfony/process": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -8733,7 +8711,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.0.6" + "source": "https://github.com/symfony/filesystem/tree/v7.0.7" }, "funding": [ { @@ -8749,20 +8727,20 @@ "type": "tidelift" } ], - "time": "2024-03-21T19:37:36+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/finder", - "version": "v7.0.0", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "6e5688d69f7cfc4ed4a511e96007e06c2d34ce56" + "reference": "4d58f0f4fe95a30d7b538d71197135483560b97c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/6e5688d69f7cfc4ed4a511e96007e06c2d34ce56", - "reference": "6e5688d69f7cfc4ed4a511e96007e06c2d34ce56", + "url": "https://api.github.com/repos/symfony/finder/zipball/4d58f0f4fe95a30d7b538d71197135483560b97c", + "reference": "4d58f0f4fe95a30d7b538d71197135483560b97c", "shasum": "" }, "require": { @@ -8797,7 +8775,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.0.0" + "source": "https://github.com/symfony/finder/tree/v7.0.7" }, "funding": [ { @@ -8813,7 +8791,7 @@ "type": "tidelift" } ], - "time": "2023-10-31T17:59:56+00:00" + "time": "2024-04-28T11:44:19+00:00" }, { "name": "symfony/flex", @@ -8882,16 +8860,16 @@ }, { "name": "symfony/form", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/form.git", - "reference": "d5db6599775a563792391d0045decc240e7ebd1e" + "reference": "b4df6a399a2b03782a0163807239db342659f54f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/form/zipball/d5db6599775a563792391d0045decc240e7ebd1e", - "reference": "d5db6599775a563792391d0045decc240e7ebd1e", + "url": "https://api.github.com/repos/symfony/form/zipball/b4df6a399a2b03782a0163807239db342659f54f", + "reference": "b4df6a399a2b03782a0163807239db342659f54f", "shasum": "" }, "require": { @@ -8958,7 +8936,7 @@ "description": "Allows to easily create, process and reuse HTML forms", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/form/tree/v7.0.6" + "source": "https://github.com/symfony/form/tree/v7.0.7" }, "funding": [ { @@ -8974,20 +8952,20 @@ "type": "tidelift" } ], - "time": "2024-03-28T09:20:36+00:00" + "time": "2024-04-28T11:44:19+00:00" }, { "name": "symfony/framework-bundle", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/framework-bundle.git", - "reference": "5ebf6771f92d135c2bdbda7133998feb74713658" + "reference": "5d9cee370509056b8b7a5009d7112d045d8f0a64" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/5ebf6771f92d135c2bdbda7133998feb74713658", - "reference": "5ebf6771f92d135c2bdbda7133998feb74713658", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/5d9cee370509056b8b7a5009d7112d045d8f0a64", + "reference": "5d9cee370509056b8b7a5009d7112d045d8f0a64", "shasum": "" }, "require": { @@ -9104,7 +9082,7 @@ "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/framework-bundle/tree/v7.0.6" + "source": "https://github.com/symfony/framework-bundle/tree/v7.0.7" }, "funding": [ { @@ -9120,20 +9098,20 @@ "type": "tidelift" } ], - "time": "2024-03-27T19:55:25+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/http-client", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "6e70473909f46fe5dd3b994a0f1b20ecb6b2f858" + "reference": "6ce3c4c899051b3d7326ea1a1dda3729e29ae6d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/6e70473909f46fe5dd3b994a0f1b20ecb6b2f858", - "reference": "6e70473909f46fe5dd3b994a0f1b20ecb6b2f858", + "url": "https://api.github.com/repos/symfony/http-client/zipball/6ce3c4c899051b3d7326ea1a1dda3729e29ae6d7", + "reference": "6ce3c4c899051b3d7326ea1a1dda3729e29ae6d7", "shasum": "" }, "require": { @@ -9196,7 +9174,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v7.0.6" + "source": "https://github.com/symfony/http-client/tree/v7.0.7" }, "funding": [ { @@ -9212,20 +9190,20 @@ "type": "tidelift" } ], - "time": "2024-04-01T20:49:44+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/http-client-contracts", - "version": "v3.4.2", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "b6b5c876b3a4ed74460e2c5ac53bbce2f12e2a7e" + "reference": "20414d96f391677bf80078aa55baece78b82647d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/b6b5c876b3a4ed74460e2c5ac53bbce2f12e2a7e", - "reference": "b6b5c876b3a4ed74460e2c5ac53bbce2f12e2a7e", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/20414d96f391677bf80078aa55baece78b82647d", + "reference": "20414d96f391677bf80078aa55baece78b82647d", "shasum": "" }, "require": { @@ -9234,7 +9212,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -9274,7 +9252,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v3.4.2" + "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.0" }, "funding": [ { @@ -9290,20 +9268,20 @@ "type": "tidelift" } ], - "time": "2024-04-01T18:51:09+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/http-foundation", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "8789625dcf36e5fbf753014678a1e090f1bc759c" + "reference": "0194e064b8bdc29381462f790bab04e1cac8fdc8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/8789625dcf36e5fbf753014678a1e090f1bc759c", - "reference": "8789625dcf36e5fbf753014678a1e090f1bc759c", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/0194e064b8bdc29381462f790bab04e1cac8fdc8", + "reference": "0194e064b8bdc29381462f790bab04e1cac8fdc8", "shasum": "" }, "require": { @@ -9351,7 +9329,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.0.6" + "source": "https://github.com/symfony/http-foundation/tree/v7.0.7" }, "funding": [ { @@ -9367,20 +9345,20 @@ "type": "tidelift" } ], - "time": "2024-03-19T11:46:48+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/http-kernel", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "34c872391046d59af804af62d4573b829cfe4824" + "reference": "e07bb9bd86e7cd8ba2d3d9c618eec9d1bbe06d25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/34c872391046d59af804af62d4573b829cfe4824", - "reference": "34c872391046d59af804af62d4573b829cfe4824", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/e07bb9bd86e7cd8ba2d3d9c618eec9d1bbe06d25", + "reference": "e07bb9bd86e7cd8ba2d3d9c618eec9d1bbe06d25", "shasum": "" }, "require": { @@ -9434,6 +9412,7 @@ "symfony/translation-contracts": "^2.5|^3", "symfony/uid": "^6.4|^7.0", "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0", "symfony/var-exporter": "^6.4|^7.0", "twig/twig": "^3.0.4" }, @@ -9463,7 +9442,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v7.0.6" + "source": "https://github.com/symfony/http-kernel/tree/v7.0.7" }, "funding": [ { @@ -9479,20 +9458,20 @@ "type": "tidelift" } ], - "time": "2024-04-03T06:12:25+00:00" + "time": "2024-04-29T12:20:25+00:00" }, { "name": "symfony/intl", - "version": "v7.0.3", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/intl.git", - "reference": "295995df4acf6790a35b9ce6ec32b313efb11ff8" + "reference": "dd12042707110995e2e7d80103f8d9928bea8621" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/intl/zipball/295995df4acf6790a35b9ce6ec32b313efb11ff8", - "reference": "295995df4acf6790a35b9ce6ec32b313efb11ff8", + "url": "https://api.github.com/repos/symfony/intl/zipball/dd12042707110995e2e7d80103f8d9928bea8621", + "reference": "dd12042707110995e2e7d80103f8d9928bea8621", "shasum": "" }, "require": { @@ -9509,7 +9488,8 @@ "Symfony\\Component\\Intl\\": "" }, "exclude-from-classmap": [ - "/Tests/" + "/Tests/", + "/Resources/data/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -9545,7 +9525,7 @@ "localization" ], "support": { - "source": "https://github.com/symfony/intl/tree/v7.0.3" + "source": "https://github.com/symfony/intl/tree/v7.0.7" }, "funding": [ { @@ -9561,20 +9541,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T15:02:46+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/lock", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/lock.git", - "reference": "c1fc92e5ba2a4d397751ac0df06689a187059402" + "reference": "9d6546f0223c1f441e2e6517ad3502c226ac0adb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/lock/zipball/c1fc92e5ba2a4d397751ac0df06689a187059402", - "reference": "c1fc92e5ba2a4d397751ac0df06689a187059402", + "url": "https://api.github.com/repos/symfony/lock/zipball/9d6546f0223c1f441e2e6517ad3502c226ac0adb", + "reference": "9d6546f0223c1f441e2e6517ad3502c226ac0adb", "shasum": "" }, "require": { @@ -9623,7 +9603,7 @@ "semaphore" ], "support": { - "source": "https://github.com/symfony/lock/tree/v7.0.6" + "source": "https://github.com/symfony/lock/tree/v7.0.7" }, "funding": [ { @@ -9639,20 +9619,20 @@ "type": "tidelift" } ], - "time": "2024-03-19T09:26:35+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/mailer", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "eb0c3187c7ddfde12d8aa0e1fa5fb29e730a41e0" + "reference": "4ff41a7c7998a88cfdc31b5841ef64d9246fc56a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/eb0c3187c7ddfde12d8aa0e1fa5fb29e730a41e0", - "reference": "eb0c3187c7ddfde12d8aa0e1fa5fb29e730a41e0", + "url": "https://api.github.com/repos/symfony/mailer/zipball/4ff41a7c7998a88cfdc31b5841ef64d9246fc56a", + "reference": "4ff41a7c7998a88cfdc31b5841ef64d9246fc56a", "shasum": "" }, "require": { @@ -9703,7 +9683,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v7.0.6" + "source": "https://github.com/symfony/mailer/tree/v7.0.7" }, "funding": [ { @@ -9719,20 +9699,20 @@ "type": "tidelift" } ], - "time": "2024-03-28T09:20:36+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/mailgun-mailer", - "version": "v7.0.4", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/mailgun-mailer.git", - "reference": "96df0d3815dc72367ecc38c4a82d8021f8bddd4e" + "reference": "e9bb8fdbdd79334a8a88bdd233204315abd992c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/96df0d3815dc72367ecc38c4a82d8021f8bddd4e", - "reference": "96df0d3815dc72367ecc38c4a82d8021f8bddd4e", + "url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/e9bb8fdbdd79334a8a88bdd233204315abd992c5", + "reference": "e9bb8fdbdd79334a8a88bdd233204315abd992c5", "shasum": "" }, "require": { @@ -9772,7 +9752,7 @@ "description": "Symfony Mailgun Mailer Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailgun-mailer/tree/v7.0.4" + "source": "https://github.com/symfony/mailgun-mailer/tree/v7.0.7" }, "funding": [ { @@ -9788,20 +9768,20 @@ "type": "tidelift" } ], - "time": "2024-02-15T11:33:06+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/mercure", - "version": "v0.6.4", + "version": "v0.6.5", "source": { "type": "git", "url": "https://github.com/symfony/mercure.git", - "reference": "8eb2496e0249c4df95a632ce908773bef0b02493" + "reference": "304cf84609ef645d63adc65fc6250292909a461b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mercure/zipball/8eb2496e0249c4df95a632ce908773bef0b02493", - "reference": "8eb2496e0249c4df95a632ce908773bef0b02493", + "url": "https://api.github.com/repos/symfony/mercure/zipball/304cf84609ef645d63adc65fc6250292909a461b", + "reference": "304cf84609ef645d63adc65fc6250292909a461b", "shasum": "" }, "require": { @@ -9818,7 +9798,7 @@ "symfony/http-kernel": "^4.4|^5.0|^6.0|^7.0", "symfony/phpunit-bridge": "^5.2|^6.0|^7.0", "symfony/stopwatch": "^4.4|^5.0|^6.0|^7.0", - "twig/twig": "^2.0|^3.0" + "twig/twig": "^2.0|^3.0|^4.0" }, "suggest": { "symfony/stopwatch": "Integration with the profiler performances" @@ -9862,7 +9842,7 @@ ], "support": { "issues": "https://github.com/symfony/mercure/issues", - "source": "https://github.com/symfony/mercure/tree/v0.6.4" + "source": "https://github.com/symfony/mercure/tree/v0.6.5" }, "funding": [ { @@ -9874,7 +9854,7 @@ "type": "tidelift" } ], - "time": "2023-12-03T22:09:36+00:00" + "time": "2024-04-08T12:51:34+00:00" }, { "name": "symfony/mercure-bundle", @@ -9959,16 +9939,16 @@ }, { "name": "symfony/messenger", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/messenger.git", - "reference": "4e281ef8bf5397be36fe14d64eb665fa12a945ad" + "reference": "90c217478f85d5289aae597551e2a4251e4d08c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/messenger/zipball/4e281ef8bf5397be36fe14d64eb665fa12a945ad", - "reference": "4e281ef8bf5397be36fe14d64eb665fa12a945ad", + "url": "https://api.github.com/repos/symfony/messenger/zipball/90c217478f85d5289aae597551e2a4251e4d08c3", + "reference": "90c217478f85d5289aae597551e2a4251e4d08c3", "shasum": "" }, "require": { @@ -10025,7 +10005,7 @@ "description": "Helps applications send and receive messages to/from other applications or via message queues", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/messenger/tree/v7.0.6" + "source": "https://github.com/symfony/messenger/tree/v7.0.7" }, "funding": [ { @@ -10041,20 +10021,20 @@ "type": "tidelift" } ], - "time": "2024-03-19T11:57:22+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/mime", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "99362408c9abdf8c7cadcf0529b6fc8b16f5ace2" + "reference": "3adbf110c306546f6f00337f421d2edca0e8d3c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/99362408c9abdf8c7cadcf0529b6fc8b16f5ace2", - "reference": "99362408c9abdf8c7cadcf0529b6fc8b16f5ace2", + "url": "https://api.github.com/repos/symfony/mime/zipball/3adbf110c306546f6f00337f421d2edca0e8d3c0", + "reference": "3adbf110c306546f6f00337f421d2edca0e8d3c0", "shasum": "" }, "require": { @@ -10109,7 +10089,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v7.0.6" + "source": "https://github.com/symfony/mime/tree/v7.0.7" }, "funding": [ { @@ -10125,20 +10105,20 @@ "type": "tidelift" } ], - "time": "2024-03-21T19:37:36+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/monolog-bridge", - "version": "v7.0.3", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/monolog-bridge.git", - "reference": "5d4f188e60d1e38a1d9d4bb6fbbbc13111dff2b1" + "reference": "aaa40a0a6512976a6e07d5def7ce9476862ebd65" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/5d4f188e60d1e38a1d9d4bb6fbbbc13111dff2b1", - "reference": "5d4f188e60d1e38a1d9d4bb6fbbbc13111dff2b1", + "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/aaa40a0a6512976a6e07d5def7ce9476862ebd65", + "reference": "aaa40a0a6512976a6e07d5def7ce9476862ebd65", "shasum": "" }, "require": { @@ -10187,7 +10167,7 @@ "description": "Provides integration for Monolog with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/monolog-bridge/tree/v7.0.3" + "source": "https://github.com/symfony/monolog-bridge/tree/v7.0.7" }, "funding": [ { @@ -10203,7 +10183,7 @@ "type": "tidelift" } ], - "time": "2024-01-23T15:02:46+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/monolog-bundle", @@ -10288,16 +10268,16 @@ }, { "name": "symfony/options-resolver", - "version": "v7.0.0", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "700ff4096e346f54cb628ea650767c8130f1001f" + "reference": "23cc173858776ad451e31f053b1c9f47840b2cfa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/700ff4096e346f54cb628ea650767c8130f1001f", - "reference": "700ff4096e346f54cb628ea650767c8130f1001f", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/23cc173858776ad451e31f053b1c9f47840b2cfa", + "reference": "23cc173858776ad451e31f053b1c9f47840b2cfa", "shasum": "" }, "require": { @@ -10335,7 +10315,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v7.0.0" + "source": "https://github.com/symfony/options-resolver/tree/v7.0.7" }, "funding": [ { @@ -10351,20 +10331,20 @@ "type": "tidelift" } ], - "time": "2023-08-08T10:20:21+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/password-hasher", - "version": "v7.0.4", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/password-hasher.git", - "reference": "0eba656c16ecdf5588b3ddd2b2337b06173d839f" + "reference": "5148b049248935f8a7b0a392aece2f22e9a1803d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/password-hasher/zipball/0eba656c16ecdf5588b3ddd2b2337b06173d839f", - "reference": "0eba656c16ecdf5588b3ddd2b2337b06173d839f", + "url": "https://api.github.com/repos/symfony/password-hasher/zipball/5148b049248935f8a7b0a392aece2f22e9a1803d", + "reference": "5148b049248935f8a7b0a392aece2f22e9a1803d", "shasum": "" }, "require": { @@ -10407,7 +10387,7 @@ "password" ], "support": { - "source": "https://github.com/symfony/password-hasher/tree/v7.0.4" + "source": "https://github.com/symfony/password-hasher/tree/v7.0.7" }, "funding": [ { @@ -10423,7 +10403,7 @@ "type": "tidelift" } ], - "time": "2024-02-12T11:15:03+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/polyfill-intl-grapheme", @@ -11146,16 +11126,16 @@ }, { "name": "symfony/process", - "version": "v7.0.4", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "0e7727191c3b71ebec6d529fa0e50a01ca5679e9" + "reference": "3839e56b94dd1dbd13235d27504e66baf23faba0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/0e7727191c3b71ebec6d529fa0e50a01ca5679e9", - "reference": "0e7727191c3b71ebec6d529fa0e50a01ca5679e9", + "url": "https://api.github.com/repos/symfony/process/zipball/3839e56b94dd1dbd13235d27504e66baf23faba0", + "reference": "3839e56b94dd1dbd13235d27504e66baf23faba0", "shasum": "" }, "require": { @@ -11187,7 +11167,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.0.4" + "source": "https://github.com/symfony/process/tree/v7.0.7" }, "funding": [ { @@ -11203,20 +11183,20 @@ "type": "tidelift" } ], - "time": "2024-02-22T20:27:20+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/property-access", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "1c268ba954ccc5e78cf035b391abb67759e24423" + "reference": "8661b861480d2807eb2789ff99d034c0c71ab955" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/1c268ba954ccc5e78cf035b391abb67759e24423", - "reference": "1c268ba954ccc5e78cf035b391abb67759e24423", + "url": "https://api.github.com/repos/symfony/property-access/zipball/8661b861480d2807eb2789ff99d034c0c71ab955", + "reference": "8661b861480d2807eb2789ff99d034c0c71ab955", "shasum": "" }, "require": { @@ -11263,7 +11243,7 @@ "reflection" ], "support": { - "source": "https://github.com/symfony/property-access/tree/v7.0.6" + "source": "https://github.com/symfony/property-access/tree/v7.0.7" }, "funding": [ { @@ -11279,20 +11259,20 @@ "type": "tidelift" } ], - "time": "2024-03-19T11:57:22+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/property-info", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "b8844ddce7d53f78b57ec9be59da80fceddf3167" + "reference": "f0bdb46e19ab308527b324b7ec36161f6880a532" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/b8844ddce7d53f78b57ec9be59da80fceddf3167", - "reference": "b8844ddce7d53f78b57ec9be59da80fceddf3167", + "url": "https://api.github.com/repos/symfony/property-info/zipball/f0bdb46e19ab308527b324b7ec36161f6880a532", + "reference": "f0bdb46e19ab308527b324b7ec36161f6880a532", "shasum": "" }, "require": { @@ -11346,7 +11326,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v7.0.6" + "source": "https://github.com/symfony/property-info/tree/v7.0.7" }, "funding": [ { @@ -11362,20 +11342,20 @@ "type": "tidelift" } ], - "time": "2024-03-28T09:20:36+00:00" + "time": "2024-04-28T11:44:19+00:00" }, { "name": "symfony/psr-http-message-bridge", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/psr-http-message-bridge.git", - "reference": "fbc500cbcb64d3ea7469f019ab7aa717b320ff3f" + "reference": "727befd41438a8feb64066871d3656d8cbdcdbe2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/fbc500cbcb64d3ea7469f019ab7aa717b320ff3f", - "reference": "fbc500cbcb64d3ea7469f019ab7aa717b320ff3f", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/727befd41438a8feb64066871d3656d8cbdcdbe2", + "reference": "727befd41438a8feb64066871d3656d8cbdcdbe2", "shasum": "" }, "require": { @@ -11429,7 +11409,7 @@ "psr-7" ], "support": { - "source": "https://github.com/symfony/psr-http-message-bridge/tree/v7.0.6" + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v7.0.7" }, "funding": [ { @@ -11445,20 +11425,20 @@ "type": "tidelift" } ], - "time": "2024-03-28T09:20:36+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/rate-limiter", - "version": "v7.0.3", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/rate-limiter.git", - "reference": "05ac83ccabdcb6d77e00ab341941577e815fabde" + "reference": "7ba48d83a622ebcd0a804776c505c05898a6f0e9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/rate-limiter/zipball/05ac83ccabdcb6d77e00ab341941577e815fabde", - "reference": "05ac83ccabdcb6d77e00ab341941577e815fabde", + "url": "https://api.github.com/repos/symfony/rate-limiter/zipball/7ba48d83a622ebcd0a804776c505c05898a6f0e9", + "reference": "7ba48d83a622ebcd0a804776c505c05898a6f0e9", "shasum": "" }, "require": { @@ -11499,7 +11479,7 @@ "rate-limiter" ], "support": { - "source": "https://github.com/symfony/rate-limiter/tree/v7.0.3" + "source": "https://github.com/symfony/rate-limiter/tree/v7.0.7" }, "funding": [ { @@ -11515,20 +11495,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T15:02:46+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/redis-messenger", - "version": "v7.0.4", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/redis-messenger.git", - "reference": "0f5fc1c53079fa0028fbbe1491f5c9c9cdf478df" + "reference": "cf673d870c500c3a6d9ffe613b4a9aa68812b722" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/redis-messenger/zipball/0f5fc1c53079fa0028fbbe1491f5c9c9cdf478df", - "reference": "0f5fc1c53079fa0028fbbe1491f5c9c9cdf478df", + "url": "https://api.github.com/repos/symfony/redis-messenger/zipball/cf673d870c500c3a6d9ffe613b4a9aa68812b722", + "reference": "cf673d870c500c3a6d9ffe613b4a9aa68812b722", "shasum": "" }, "require": { @@ -11566,7 +11546,7 @@ "description": "Symfony Redis extension Messenger Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/redis-messenger/tree/v7.0.4" + "source": "https://github.com/symfony/redis-messenger/tree/v7.0.7" }, "funding": [ { @@ -11582,20 +11562,20 @@ "type": "tidelift" } ], - "time": "2024-02-07T14:11:38+00:00" + "time": "2024-04-28T11:44:19+00:00" }, { "name": "symfony/routing", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "cded64e5bbf9f31786f1055fcc76718fdd77519c" + "reference": "9f82bf7766ccc9c22ab7aeb9bebb98351483fa5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/cded64e5bbf9f31786f1055fcc76718fdd77519c", - "reference": "cded64e5bbf9f31786f1055fcc76718fdd77519c", + "url": "https://api.github.com/repos/symfony/routing/zipball/9f82bf7766ccc9c22ab7aeb9bebb98351483fa5b", + "reference": "9f82bf7766ccc9c22ab7aeb9bebb98351483fa5b", "shasum": "" }, "require": { @@ -11647,7 +11627,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v7.0.6" + "source": "https://github.com/symfony/routing/tree/v7.0.7" }, "funding": [ { @@ -11663,20 +11643,20 @@ "type": "tidelift" } ], - "time": "2024-03-28T21:02:11+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/runtime", - "version": "v7.0.3", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/runtime.git", - "reference": "ef2c2fd4b40fb8cd22221154399ad8888e81cdb5" + "reference": "e120730ef206b31bb5521b1a2389c058adbba9c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/runtime/zipball/ef2c2fd4b40fb8cd22221154399ad8888e81cdb5", - "reference": "ef2c2fd4b40fb8cd22221154399ad8888e81cdb5", + "url": "https://api.github.com/repos/symfony/runtime/zipball/e120730ef206b31bb5521b1a2389c058adbba9c7", + "reference": "e120730ef206b31bb5521b1a2389c058adbba9c7", "shasum": "" }, "require": { @@ -11726,7 +11706,7 @@ "runtime" ], "support": { - "source": "https://github.com/symfony/runtime/tree/v7.0.3" + "source": "https://github.com/symfony/runtime/tree/v7.0.7" }, "funding": [ { @@ -11742,20 +11722,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T15:02:46+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/scheduler", - "version": "v7.0.4", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/scheduler.git", - "reference": "626c14645515881d0c11efd985434f44ec2c056e" + "reference": "2522418649397a494dfbd85b913d4423c25cc709" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/scheduler/zipball/626c14645515881d0c11efd985434f44ec2c056e", - "reference": "626c14645515881d0c11efd985434f44ec2c056e", + "url": "https://api.github.com/repos/symfony/scheduler/zipball/2522418649397a494dfbd85b913d4423c25cc709", + "reference": "2522418649397a494dfbd85b913d4423c25cc709", "shasum": "" }, "require": { @@ -11806,7 +11786,7 @@ "scheduler" ], "support": { - "source": "https://github.com/symfony/scheduler/tree/v7.0.4" + "source": "https://github.com/symfony/scheduler/tree/v7.0.7" }, "funding": [ { @@ -11822,20 +11802,20 @@ "type": "tidelift" } ], - "time": "2024-02-15T11:33:06+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/security-bundle", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/security-bundle.git", - "reference": "96a9e4eaf76514674d8ffd6127d8ec1204b72e7f" + "reference": "8d11101574ce8e2147a04245f4b968911a43ffd5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-bundle/zipball/96a9e4eaf76514674d8ffd6127d8ec1204b72e7f", - "reference": "96a9e4eaf76514674d8ffd6127d8ec1204b72e7f", + "url": "https://api.github.com/repos/symfony/security-bundle/zipball/8d11101574ce8e2147a04245f4b968911a43ffd5", + "reference": "8d11101574ce8e2147a04245f4b968911a43ffd5", "shasum": "" }, "require": { @@ -11917,7 +11897,7 @@ "description": "Provides a tight integration of the Security component into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-bundle/tree/v7.0.6" + "source": "https://github.com/symfony/security-bundle/tree/v7.0.7" }, "funding": [ { @@ -11933,20 +11913,20 @@ "type": "tidelift" } ], - "time": "2024-03-15T12:53:12+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/security-core", - "version": "v7.0.3", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/security-core.git", - "reference": "72b9d961a5dcd21e6bc29b99df51a9000a15dde0" + "reference": "6af8ac3b4d9c41a0ce0a4e33d532ba2000b47348" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-core/zipball/72b9d961a5dcd21e6bc29b99df51a9000a15dde0", - "reference": "72b9d961a5dcd21e6bc29b99df51a9000a15dde0", + "url": "https://api.github.com/repos/symfony/security-core/zipball/6af8ac3b4d9c41a0ce0a4e33d532ba2000b47348", + "reference": "6af8ac3b4d9c41a0ce0a4e33d532ba2000b47348", "shasum": "" }, "require": { @@ -12001,7 +11981,7 @@ "description": "Symfony Security Component - Core Library", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-core/tree/v7.0.3" + "source": "https://github.com/symfony/security-core/tree/v7.0.7" }, "funding": [ { @@ -12017,20 +11997,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T15:02:46+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/security-csrf", - "version": "v7.0.3", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/security-csrf.git", - "reference": "f0f724e599f069b768e335e4bdf795726c7dfe8e" + "reference": "671d6736736555309991457dd877e7f6f3317d08" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-csrf/zipball/f0f724e599f069b768e335e4bdf795726c7dfe8e", - "reference": "f0f724e599f069b768e335e4bdf795726c7dfe8e", + "url": "https://api.github.com/repos/symfony/security-csrf/zipball/671d6736736555309991457dd877e7f6f3317d08", + "reference": "671d6736736555309991457dd877e7f6f3317d08", "shasum": "" }, "require": { @@ -12069,7 +12049,7 @@ "description": "Symfony Security Component - CSRF Library", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-csrf/tree/v7.0.3" + "source": "https://github.com/symfony/security-csrf/tree/v7.0.7" }, "funding": [ { @@ -12085,20 +12065,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T15:02:46+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/security-http", - "version": "v7.0.4", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/security-http.git", - "reference": "f3a70a937128f47366821a9f4b5dbfaa0ba9c862" + "reference": "836a338f51cd46d57e77fcba61c6f8c6111a3717" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-http/zipball/f3a70a937128f47366821a9f4b5dbfaa0ba9c862", - "reference": "f3a70a937128f47366821a9f4b5dbfaa0ba9c862", + "url": "https://api.github.com/repos/symfony/security-http/zipball/836a338f51cd46d57e77fcba61c6f8c6111a3717", + "reference": "836a338f51cd46d57e77fcba61c6f8c6111a3717", "shasum": "" }, "require": { @@ -12156,7 +12136,7 @@ "description": "Symfony Security Component - HTTP Integration", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-http/tree/v7.0.4" + "source": "https://github.com/symfony/security-http/tree/v7.0.7" }, "funding": [ { @@ -12172,20 +12152,20 @@ "type": "tidelift" } ], - "time": "2024-02-26T07:52:39+00:00" + "time": "2024-04-19T13:26:52+00:00" }, { "name": "symfony/serializer", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "dbdc0c04c28ac53de1fa35f92fca26e9b1345d98" + "reference": "08f0c517acf4b12dfc0d3963cd12f7b8023aea31" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/dbdc0c04c28ac53de1fa35f92fca26e9b1345d98", - "reference": "dbdc0c04c28ac53de1fa35f92fca26e9b1345d98", + "url": "https://api.github.com/repos/symfony/serializer/zipball/08f0c517acf4b12dfc0d3963cd12f7b8023aea31", + "reference": "08f0c517acf4b12dfc0d3963cd12f7b8023aea31", "shasum": "" }, "require": { @@ -12251,7 +12231,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/serializer/tree/v7.0.6" + "source": "https://github.com/symfony/serializer/tree/v7.0.7" }, "funding": [ { @@ -12267,25 +12247,26 @@ "type": "tidelift" } ], - "time": "2024-03-28T09:20:36+00:00" + "time": "2024-04-28T11:44:19+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.4.2", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "11bbf19a0fb7b36345861e85c5768844c552906e" + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/11bbf19a0fb7b36345861e85c5768844c552906e", - "reference": "11bbf19a0fb7b36345861e85c5768844c552906e", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", "shasum": "" }, "require": { "php": ">=8.1", - "psr/container": "^1.1|^2.0" + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, "conflict": { "ext-psr": "<1.1|>=2" @@ -12293,7 +12274,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -12333,7 +12314,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.4.2" + "source": "https://github.com/symfony/service-contracts/tree/v3.5.0" }, "funding": [ { @@ -12349,20 +12330,20 @@ "type": "tidelift" } ], - "time": "2023-12-19T21:51:00+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/stimulus-bundle", - "version": "v2.16.0", + "version": "v2.17.0", "source": { "type": "git", "url": "https://github.com/symfony/stimulus-bundle.git", - "reference": "6add4bdab1b9df4f2b2532a9dcb7b2f26dbba634" + "reference": "b828a32fe9f75500d26b563cc01874657162c413" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stimulus-bundle/zipball/6add4bdab1b9df4f2b2532a9dcb7b2f26dbba634", - "reference": "6add4bdab1b9df4f2b2532a9dcb7b2f26dbba634", + "url": "https://api.github.com/repos/symfony/stimulus-bundle/zipball/b828a32fe9f75500d26b563cc01874657162c413", + "reference": "b828a32fe9f75500d26b563cc01874657162c413", "shasum": "" }, "require": { @@ -12372,7 +12353,7 @@ "symfony/deprecation-contracts": "^2.0|^3.0", "symfony/finder": "^5.4|^6.0|^7.0", "symfony/http-kernel": "^5.4|^6.0|^7.0", - "twig/twig": "^2.15.3|~3.8.0" + "twig/twig": "^2.15.3|^3.8" }, "require-dev": { "symfony/asset-mapper": "^6.3|^7.0", @@ -12402,7 +12383,7 @@ "symfony-ux" ], "support": { - "source": "https://github.com/symfony/stimulus-bundle/tree/v2.16.0" + "source": "https://github.com/symfony/stimulus-bundle/tree/v2.17.0" }, "funding": [ { @@ -12418,20 +12399,20 @@ "type": "tidelift" } ], - "time": "2024-02-29T16:20:46+00:00" + "time": "2024-04-21T10:23:35+00:00" }, { "name": "symfony/stopwatch", - "version": "v7.0.3", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "983900d6fddf2b0cbaacacbbad07610854bd8112" + "reference": "41a7a24aa1dc82adf46a06bc292d1923acfe6b84" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/983900d6fddf2b0cbaacacbbad07610854bd8112", - "reference": "983900d6fddf2b0cbaacacbbad07610854bd8112", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/41a7a24aa1dc82adf46a06bc292d1923acfe6b84", + "reference": "41a7a24aa1dc82adf46a06bc292d1923acfe6b84", "shasum": "" }, "require": { @@ -12464,7 +12445,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v7.0.3" + "source": "https://github.com/symfony/stopwatch/tree/v7.0.7" }, "funding": [ { @@ -12480,20 +12461,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T15:02:46+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/string", - "version": "v7.0.4", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "f5832521b998b0bec40bee688ad5de98d4cf111b" + "reference": "e405b5424dc2528e02e31ba26b83a79fd4eb8f63" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/f5832521b998b0bec40bee688ad5de98d4cf111b", - "reference": "f5832521b998b0bec40bee688ad5de98d4cf111b", + "url": "https://api.github.com/repos/symfony/string/zipball/e405b5424dc2528e02e31ba26b83a79fd4eb8f63", + "reference": "e405b5424dc2528e02e31ba26b83a79fd4eb8f63", "shasum": "" }, "require": { @@ -12550,7 +12531,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.0.4" + "source": "https://github.com/symfony/string/tree/v7.0.7" }, "funding": [ { @@ -12566,20 +12547,20 @@ "type": "tidelift" } ], - "time": "2024-02-01T13:17:36+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/translation", - "version": "v7.0.4", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "5b75e872f7d135d7abb4613809fadc8d9f3d30a0" + "reference": "1515e03afaa93e6419aba5d5c9d209159317100b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/5b75e872f7d135d7abb4613809fadc8d9f3d30a0", - "reference": "5b75e872f7d135d7abb4613809fadc8d9f3d30a0", + "url": "https://api.github.com/repos/symfony/translation/zipball/1515e03afaa93e6419aba5d5c9d209159317100b", + "reference": "1515e03afaa93e6419aba5d5c9d209159317100b", "shasum": "" }, "require": { @@ -12644,7 +12625,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v7.0.4" + "source": "https://github.com/symfony/translation/tree/v7.0.7" }, "funding": [ { @@ -12660,20 +12641,20 @@ "type": "tidelift" } ], - "time": "2024-02-22T20:27:20+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/translation-contracts", - "version": "v3.4.2", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "43810bdb2ddb5400e5c5e778e27b210a0ca83b6b" + "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/43810bdb2ddb5400e5c5e778e27b210a0ca83b6b", - "reference": "43810bdb2ddb5400e5c5e778e27b210a0ca83b6b", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/b9d2189887bb6b2e0367a9fc7136c5239ab9b05a", + "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a", "shasum": "" }, "require": { @@ -12682,7 +12663,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -12722,7 +12703,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.4.2" + "source": "https://github.com/symfony/translation-contracts/tree/v3.5.0" }, "funding": [ { @@ -12738,20 +12719,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:51:35+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/twig-bridge", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/twig-bridge.git", - "reference": "1d5745dac2e043553177a3b88a76b99c2a2f6c2e" + "reference": "214237f7b3b82eeb430e85ea415c4a2915c304f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/1d5745dac2e043553177a3b88a76b99c2a2f6c2e", - "reference": "1d5745dac2e043553177a3b88a76b99c2a2f6c2e", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/214237f7b3b82eeb430e85ea415c4a2915c304f6", + "reference": "214237f7b3b82eeb430e85ea415c4a2915c304f6", "shasum": "" }, "require": { @@ -12830,7 +12811,7 @@ "description": "Provides integration for Twig with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bridge/tree/v7.0.6" + "source": "https://github.com/symfony/twig-bridge/tree/v7.0.7" }, "funding": [ { @@ -12846,20 +12827,20 @@ "type": "tidelift" } ], - "time": "2024-03-28T21:02:11+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/twig-bundle", - "version": "v7.0.4", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/twig-bundle.git", - "reference": "acab2368f53491e018bf31ef48b39df55a6812ef" + "reference": "4dd8a395b955045d031d9525a7149cfcee8d0b02" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/acab2368f53491e018bf31ef48b39df55a6812ef", - "reference": "acab2368f53491e018bf31ef48b39df55a6812ef", + "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/4dd8a395b955045d031d9525a7149cfcee8d0b02", + "reference": "4dd8a395b955045d031d9525a7149cfcee8d0b02", "shasum": "" }, "require": { @@ -12914,7 +12895,7 @@ "description": "Provides a tight integration of Twig into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bundle/tree/v7.0.4" + "source": "https://github.com/symfony/twig-bundle/tree/v7.0.7" }, "funding": [ { @@ -12930,20 +12911,20 @@ "type": "tidelift" } ], - "time": "2024-02-15T11:33:06+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/uid", - "version": "v7.0.3", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/uid.git", - "reference": "87cedaf3fabd7b733859d4d77aa4ca598259054b" + "reference": "4f3a5d181999e25918586c8369de09e7814e7be2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/uid/zipball/87cedaf3fabd7b733859d4d77aa4ca598259054b", - "reference": "87cedaf3fabd7b733859d4d77aa4ca598259054b", + "url": "https://api.github.com/repos/symfony/uid/zipball/4f3a5d181999e25918586c8369de09e7814e7be2", + "reference": "4f3a5d181999e25918586c8369de09e7814e7be2", "shasum": "" }, "require": { @@ -12988,7 +12969,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/uid/tree/v7.0.3" + "source": "https://github.com/symfony/uid/tree/v7.0.7" }, "funding": [ { @@ -13004,20 +12985,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T15:02:46+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/ux-autocomplete", - "version": "v2.16.0", + "version": "v2.17.0", "source": { "type": "git", "url": "https://github.com/symfony/ux-autocomplete.git", - "reference": "e50ab09c69609cb44a9d5ea987624c49ca0494da" + "reference": "b2c3c4302bc5b0062b3e8891460321fe694c466d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/ux-autocomplete/zipball/e50ab09c69609cb44a9d5ea987624c49ca0494da", - "reference": "e50ab09c69609cb44a9d5ea987624c49ca0494da", + "url": "https://api.github.com/repos/symfony/ux-autocomplete/zipball/b2c3c4302bc5b0062b3e8891460321fe694c466d", + "reference": "b2c3c4302bc5b0062b3e8891460321fe694c466d", "shasum": "" }, "require": { @@ -13050,7 +13031,7 @@ "symfony/uid": "^6.3|^7.0", "twig/twig": "^2.14.7|^3.0.4", "zenstruck/browser": "^1.1", - "zenstruck/foundry": "^1.33" + "zenstruck/foundry": "1.37.*" }, "type": "symfony-bundle", "extra": { @@ -13080,7 +13061,7 @@ "symfony-ux" ], "support": { - "source": "https://github.com/symfony/ux-autocomplete/tree/v2.16.0" + "source": "https://github.com/symfony/ux-autocomplete/tree/v2.17.0" }, "funding": [ { @@ -13096,20 +13077,20 @@ "type": "tidelift" } ], - "time": "2024-02-29T16:20:59+00:00" + "time": "2024-04-19T06:36:45+00:00" }, { "name": "symfony/ux-chartjs", - "version": "v2.16.0", + "version": "v2.17.0", "source": { "type": "git", "url": "https://github.com/symfony/ux-chartjs.git", - "reference": "8cc061e7f8d0bcaae21e71b4cacb46c06a3cad00" + "reference": "962326b44a8c3edf4d8b29e115dc446441bcd662" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/ux-chartjs/zipball/8cc061e7f8d0bcaae21e71b4cacb46c06a3cad00", - "reference": "8cc061e7f8d0bcaae21e71b4cacb46c06a3cad00", + "url": "https://api.github.com/repos/symfony/ux-chartjs/zipball/962326b44a8c3edf4d8b29e115dc446441bcd662", + "reference": "962326b44a8c3edf4d8b29e115dc446441bcd662", "shasum": "" }, "require": { @@ -13160,7 +13141,7 @@ "symfony-ux" ], "support": { - "source": "https://github.com/symfony/ux-chartjs/tree/v2.16.0" + "source": "https://github.com/symfony/ux-chartjs/tree/v2.17.0" }, "funding": [ { @@ -13176,20 +13157,20 @@ "type": "tidelift" } ], - "time": "2024-02-22T12:15:32+00:00" + "time": "2024-04-19T06:36:45+00:00" }, { "name": "symfony/ux-twig-component", - "version": "v2.16.0", + "version": "v2.17.0", "source": { "type": "git", "url": "https://github.com/symfony/ux-twig-component.git", - "reference": "c789f33dd8800949293dd94bf8e7bf01c39559a2" + "reference": "fb3d978b7f19e9a94533a3bf30d68269908ffae1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/ux-twig-component/zipball/c789f33dd8800949293dd94bf8e7bf01c39559a2", - "reference": "c789f33dd8800949293dd94bf8e7bf01c39559a2", + "url": "https://api.github.com/repos/symfony/ux-twig-component/zipball/fb3d978b7f19e9a94533a3bf30d68269908ffae1", + "reference": "fb3d978b7f19e9a94533a3bf30d68269908ffae1", "shasum": "" }, "require": { @@ -13198,7 +13179,7 @@ "symfony/deprecation-contracts": "^2.2|^3.0", "symfony/event-dispatcher": "^5.4|^6.0|^7.0", "symfony/property-access": "^5.4|^6.0|^7.0", - "twig/twig": "~3.8.0" + "twig/twig": "^3.8" }, "conflict": { "symfony/config": "<5.4.0" @@ -13244,7 +13225,7 @@ "twig" ], "support": { - "source": "https://github.com/symfony/ux-twig-component/tree/v2.16.0" + "source": "https://github.com/symfony/ux-twig-component/tree/v2.17.0" }, "funding": [ { @@ -13260,20 +13241,20 @@ "type": "tidelift" } ], - "time": "2024-02-29T16:20:59+00:00" + "time": "2024-04-19T16:14:05+00:00" }, { "name": "symfony/validator", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "a2df2c63b7944a162dee86ab8065f2f91b7d6e36" + "reference": "ab4e75b9d23ba70e78480aecbe4d8da15adf10eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/a2df2c63b7944a162dee86ab8065f2f91b7d6e36", - "reference": "a2df2c63b7944a162dee86ab8065f2f91b7d6e36", + "url": "https://api.github.com/repos/symfony/validator/zipball/ab4e75b9d23ba70e78480aecbe4d8da15adf10eb", + "reference": "ab4e75b9d23ba70e78480aecbe4d8da15adf10eb", "shasum": "" }, "require": { @@ -13338,7 +13319,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/validator/tree/v7.0.6" + "source": "https://github.com/symfony/validator/tree/v7.0.7" }, "funding": [ { @@ -13354,20 +13335,20 @@ "type": "tidelift" } ], - "time": "2024-03-28T09:20:36+00:00" + "time": "2024-04-28T11:44:19+00:00" }, { "name": "symfony/var-dumper", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "66d13dc207d5dab6b4f4c2b5460efe1bea29dbfb" + "reference": "d1627b66fd87c8b4d90cabe5671c29d575690924" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/66d13dc207d5dab6b4f4c2b5460efe1bea29dbfb", - "reference": "66d13dc207d5dab6b4f4c2b5460efe1bea29dbfb", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/d1627b66fd87c8b4d90cabe5671c29d575690924", + "reference": "d1627b66fd87c8b4d90cabe5671c29d575690924", "shasum": "" }, "require": { @@ -13421,7 +13402,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.0.6" + "source": "https://github.com/symfony/var-dumper/tree/v7.0.7" }, "funding": [ { @@ -13437,20 +13418,20 @@ "type": "tidelift" } ], - "time": "2024-03-19T11:57:22+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/var-exporter", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "c74c568d2a15a1d407cf40d61ea82bc2d521e27b" + "reference": "cdecc0022e40e90340ba1a59a3d5ccf069777078" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/c74c568d2a15a1d407cf40d61ea82bc2d521e27b", - "reference": "c74c568d2a15a1d407cf40d61ea82bc2d521e27b", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/cdecc0022e40e90340ba1a59a3d5ccf069777078", + "reference": "cdecc0022e40e90340ba1a59a3d5ccf069777078", "shasum": "" }, "require": { @@ -13497,7 +13478,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v7.0.6" + "source": "https://github.com/symfony/var-exporter/tree/v7.0.7" }, "funding": [ { @@ -13513,20 +13494,20 @@ "type": "tidelift" } ], - "time": "2024-03-20T21:25:22+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/web-link", - "version": "v7.0.3", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/web-link.git", - "reference": "855a347feb2ecfc1d1a379c739aff956d4cbec00" + "reference": "19312f38543e77b09f04f374368b73530bfb9482" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-link/zipball/855a347feb2ecfc1d1a379c739aff956d4cbec00", - "reference": "855a347feb2ecfc1d1a379c739aff956d4cbec00", + "url": "https://api.github.com/repos/symfony/web-link/zipball/19312f38543e77b09f04f374368b73530bfb9482", + "reference": "19312f38543e77b09f04f374368b73530bfb9482", "shasum": "" }, "require": { @@ -13580,7 +13561,7 @@ "push" ], "support": { - "source": "https://github.com/symfony/web-link/tree/v7.0.3" + "source": "https://github.com/symfony/web-link/tree/v7.0.7" }, "funding": [ { @@ -13596,7 +13577,7 @@ "type": "tidelift" } ], - "time": "2024-01-23T15:02:46+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/webpack-encore-bundle", @@ -13671,16 +13652,16 @@ }, { "name": "symfony/workflow", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/workflow.git", - "reference": "6641e5a34f829fbf9bdc3b69c7f93a85f983725e" + "reference": "8b3a8dc022bb6766e04984412c026edcdbe1a020" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/workflow/zipball/6641e5a34f829fbf9bdc3b69c7f93a85f983725e", - "reference": "6641e5a34f829fbf9bdc3b69c7f93a85f983725e", + "url": "https://api.github.com/repos/symfony/workflow/zipball/8b3a8dc022bb6766e04984412c026edcdbe1a020", + "reference": "8b3a8dc022bb6766e04984412c026edcdbe1a020", "shasum": "" }, "require": { @@ -13738,7 +13719,7 @@ "workflow" ], "support": { - "source": "https://github.com/symfony/workflow/tree/v7.0.6" + "source": "https://github.com/symfony/workflow/tree/v7.0.7" }, "funding": [ { @@ -13754,20 +13735,20 @@ "type": "tidelift" } ], - "time": "2024-03-12T08:10:33+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/yaml", - "version": "v7.0.3", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "2d4fca631c00700597e9442a0b2451ce234513d3" + "reference": "0d3916ae69ea28b59d94b60c4f2b50f4e25adb5c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/2d4fca631c00700597e9442a0b2451ce234513d3", - "reference": "2d4fca631c00700597e9442a0b2451ce234513d3", + "url": "https://api.github.com/repos/symfony/yaml/zipball/0d3916ae69ea28b59d94b60c4f2b50f4e25adb5c", + "reference": "0d3916ae69ea28b59d94b60c4f2b50f4e25adb5c", "shasum": "" }, "require": { @@ -13809,7 +13790,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.0.3" + "source": "https://github.com/symfony/yaml/tree/v7.0.7" }, "funding": [ { @@ -13825,7 +13806,7 @@ "type": "tidelift" } ], - "time": "2024-01-23T15:02:46+00:00" + "time": "2024-04-28T11:44:19+00:00" }, { "name": "symfonycasts/reset-password-bundle", @@ -14034,20 +14015,21 @@ }, { "name": "twig/cssinliner-extra", - "version": "v3.8.0", + "version": "v3.10.0", "source": { "type": "git", "url": "https://github.com/twigphp/cssinliner-extra.git", - "reference": "259a4b861732545e0e1ecd43bf25b251494af45b" + "reference": "10e88e9a887b646c58e3d670383208f15295dd22" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/cssinliner-extra/zipball/259a4b861732545e0e1ecd43bf25b251494af45b", - "reference": "259a4b861732545e0e1ecd43bf25b251494af45b", + "url": "https://api.github.com/repos/twigphp/cssinliner-extra/zipball/10e88e9a887b646c58e3d670383208f15295dd22", + "reference": "10e88e9a887b646c58e3d670383208f15295dd22", "shasum": "" }, "require": { "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.5|^3", "tijsverkoyen/css-to-inline-styles": "^2.0", "twig/twig": "^3.0" }, @@ -14056,6 +14038,9 @@ }, "type": "library", "autoload": { + "files": [ + "Resources/functions.php" + ], "psr-4": { "Twig\\Extra\\CssInliner\\": "" }, @@ -14083,7 +14068,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/cssinliner-extra/tree/v3.8.0" + "source": "https://github.com/twigphp/cssinliner-extra/tree/v3.10.0" }, "funding": [ { @@ -14095,38 +14080,38 @@ "type": "tidelift" } ], - "time": "2023-11-21T14:02:01+00:00" + "time": "2024-05-11T07:35:57+00:00" }, { "name": "twig/extra-bundle", - "version": "v3.8.0", + "version": "v3.10.0", "source": { "type": "git", "url": "https://github.com/twigphp/twig-extra-bundle.git", - "reference": "32807183753de0388c8e59f7ac2d13bb47311140" + "reference": "cdc6e23aeb7f4953c1039568c3439aab60c56454" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/twig-extra-bundle/zipball/32807183753de0388c8e59f7ac2d13bb47311140", - "reference": "32807183753de0388c8e59f7ac2d13bb47311140", + "url": "https://api.github.com/repos/twigphp/twig-extra-bundle/zipball/cdc6e23aeb7f4953c1039568c3439aab60c56454", + "reference": "cdc6e23aeb7f4953c1039568c3439aab60c56454", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/framework-bundle": "^5.4|^6.0|^7.0", - "symfony/twig-bundle": "^5.4|^6.0|^7.0", + "symfony/framework-bundle": "^5.4|^6.4|^7.0", + "symfony/twig-bundle": "^5.4|^6.4|^7.0", "twig/twig": "^3.0" }, "require-dev": { "league/commonmark": "^1.0|^2.0", "symfony/phpunit-bridge": "^6.4|^7.0", "twig/cache-extra": "^3.0", - "twig/cssinliner-extra": "^2.12|^3.0", - "twig/html-extra": "^2.12|^3.0", - "twig/inky-extra": "^2.12|^3.0", - "twig/intl-extra": "^2.12|^3.0", - "twig/markdown-extra": "^2.12|^3.0", - "twig/string-extra": "^2.12|^3.0" + "twig/cssinliner-extra": "^3.0", + "twig/html-extra": "^3.0", + "twig/inky-extra": "^3.0", + "twig/intl-extra": "^3.0", + "twig/markdown-extra": "^3.0", + "twig/string-extra": "^3.0" }, "type": "symfony-bundle", "autoload": { @@ -14157,7 +14142,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/twig-extra-bundle/tree/v3.8.0" + "source": "https://github.com/twigphp/twig-extra-bundle/tree/v3.10.0" }, "funding": [ { @@ -14169,25 +14154,26 @@ "type": "tidelift" } ], - "time": "2023-11-21T14:02:01+00:00" + "time": "2024-05-11T07:35:57+00:00" }, { "name": "twig/html-extra", - "version": "v3.8.0", + "version": "v3.10.0", "source": { "type": "git", "url": "https://github.com/twigphp/html-extra.git", - "reference": "c04603bb3b71d8d2ece9e583dbf7bd77811df1f2" + "reference": "1c045fc28ace0dcaf464f8e0d4e2aca6347d5fda" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/html-extra/zipball/c04603bb3b71d8d2ece9e583dbf7bd77811df1f2", - "reference": "c04603bb3b71d8d2ece9e583dbf7bd77811df1f2", + "url": "https://api.github.com/repos/twigphp/html-extra/zipball/1c045fc28ace0dcaf464f8e0d4e2aca6347d5fda", + "reference": "1c045fc28ace0dcaf464f8e0d4e2aca6347d5fda", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/mime": "^5.4|^6.0|^7.0", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/mime": "^5.4|^6.4|^7.0", "twig/twig": "^3.0" }, "require-dev": { @@ -14195,6 +14181,9 @@ }, "type": "library", "autoload": { + "files": [ + "Resources/functions.php" + ], "psr-4": { "Twig\\Extra\\Html\\": "" }, @@ -14221,7 +14210,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/html-extra/tree/v3.8.0" + "source": "https://github.com/twigphp/html-extra/tree/v3.10.0" }, "funding": [ { @@ -14233,26 +14222,26 @@ "type": "tidelift" } ], - "time": "2023-11-21T14:02:01+00:00" + "time": "2024-05-11T07:35:57+00:00" }, { "name": "twig/intl-extra", - "version": "v3.8.0", + "version": "v3.10.0", "source": { "type": "git", "url": "https://github.com/twigphp/intl-extra.git", - "reference": "7b3db67c700735f473a265a97e1adaeba3e6ca0c" + "reference": "693f6beb8ca91fc6323e01b3addf983812f65c93" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/intl-extra/zipball/7b3db67c700735f473a265a97e1adaeba3e6ca0c", - "reference": "7b3db67c700735f473a265a97e1adaeba3e6ca0c", + "url": "https://api.github.com/repos/twigphp/intl-extra/zipball/693f6beb8ca91fc6323e01b3addf983812f65c93", + "reference": "693f6beb8ca91fc6323e01b3addf983812f65c93", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/intl": "^5.4|^6.0|^7.0", - "twig/twig": "^3.0" + "symfony/intl": "^5.4|^6.4|^7.0", + "twig/twig": "^3.10" }, "require-dev": { "symfony/phpunit-bridge": "^6.4|^7.0" @@ -14285,7 +14274,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/intl-extra/tree/v3.8.0" + "source": "https://github.com/twigphp/intl-extra/tree/v3.10.0" }, "funding": [ { @@ -14297,34 +14286,41 @@ "type": "tidelift" } ], - "time": "2023-11-21T17:27:48+00:00" + "time": "2024-05-11T07:35:57+00:00" }, { "name": "twig/twig", - "version": "v3.8.0", + "version": "v3.10.3", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d" + "reference": "67f29781ffafa520b0bbfbd8384674b42db04572" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/9d15f0ac07f44dc4217883ec6ae02fd555c6f71d", - "reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/67f29781ffafa520b0bbfbd8384674b42db04572", + "reference": "67f29781ffafa520b0bbfbd8384674b42db04572", "shasum": "" }, "require": { "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-mbstring": "^1.3", "symfony/polyfill-php80": "^1.22" }, "require-dev": { "psr/container": "^1.0|^2.0", - "symfony/phpunit-bridge": "^5.4.9|^6.3|^7.0" + "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0" }, "type": "library", "autoload": { + "files": [ + "src/Resources/core.php", + "src/Resources/debug.php", + "src/Resources/escaper.php", + "src/Resources/string_loader.php" + ], "psr-4": { "Twig\\": "src/" } @@ -14357,7 +14353,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.8.0" + "source": "https://github.com/twigphp/Twig/tree/v3.10.3" }, "funding": [ { @@ -14369,7 +14365,7 @@ "type": "tidelift" } ], - "time": "2023-11-21T18:54:41+00:00" + "time": "2024-05-16T10:04:27+00:00" }, { "name": "webmozart/assert", @@ -14474,16 +14470,16 @@ }, { "name": "zircote/swagger-php", - "version": "4.8.7", + "version": "4.9.2", "source": { "type": "git", "url": "https://github.com/zircote/swagger-php.git", - "reference": "2357fafbb084be0f9eda7b5c1a659704fed65b28" + "reference": "256d42cb07ba1c2206d66bc7516ee3d3e3e9f0b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zircote/swagger-php/zipball/2357fafbb084be0f9eda7b5c1a659704fed65b28", - "reference": "2357fafbb084be0f9eda7b5c1a659704fed65b28", + "url": "https://api.github.com/repos/zircote/swagger-php/zipball/256d42cb07ba1c2206d66bc7516ee3d3e3e9f0b2", + "reference": "256d42cb07ba1c2206d66bc7516ee3d3e3e9f0b2", "shasum": "" }, "require": { @@ -14549,31 +14545,30 @@ ], "support": { "issues": "https://github.com/zircote/swagger-php/issues", - "source": "https://github.com/zircote/swagger-php/tree/4.8.7" + "source": "https://github.com/zircote/swagger-php/tree/4.9.2" }, - "time": "2024-03-23T06:35:46+00:00" + "time": "2024-05-02T21:36:00+00:00" } ], "packages-dev": [ { "name": "dama/doctrine-test-bundle", - "version": "v8.0.2", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/dmaicher/doctrine-test-bundle.git", - "reference": "f10de294e41570d027a301554a609c394d40e669" + "reference": "21b4dd73546991c7df34ba92ecbf305a1ae5a0ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dmaicher/doctrine-test-bundle/zipball/f10de294e41570d027a301554a609c394d40e669", - "reference": "f10de294e41570d027a301554a609c394d40e669", + "url": "https://api.github.com/repos/dmaicher/doctrine-test-bundle/zipball/21b4dd73546991c7df34ba92ecbf305a1ae5a0ee", + "reference": "21b4dd73546991c7df34ba92ecbf305a1ae5a0ee", "shasum": "" }, "require": { "doctrine/dbal": "^3.3 || ^4.0", "doctrine/doctrine-bundle": "^2.2.2", - "ext-json": "*", - "php": "^7.3 || ^8.0", + "php": "^7.4 || ^8.0", "psr/cache": "^1.0 || ^2.0 || ^3.0", "symfony/cache": "^5.4 || ^6.3 || ^7.0", "symfony/framework-bundle": "^5.4 || ^6.3 || ^7.0" @@ -14582,7 +14577,7 @@ "behat/behat": "^3.0", "friendsofphp/php-cs-fixer": "^3.27", "phpstan/phpstan": "^1.2", - "phpunit/phpunit": "^8.0 || ^9.0 || ^10.0", + "phpunit/phpunit": "^8.0 || ^9.0 || ^10.0 || ^11.0", "symfony/phpunit-bridge": "^6.3", "symfony/process": "^5.4 || ^6.3 || ^7.0", "symfony/yaml": "^5.4 || ^6.3 || ^7.0" @@ -14619,9 +14614,9 @@ ], "support": { "issues": "https://github.com/dmaicher/doctrine-test-bundle/issues", - "source": "https://github.com/dmaicher/doctrine-test-bundle/tree/v8.0.2" + "source": "https://github.com/dmaicher/doctrine-test-bundle/tree/v8.1.0" }, - "time": "2024-02-15T08:28:14+00:00" + "time": "2024-05-21T18:06:21+00:00" }, { "name": "doctrine/data-fixtures", @@ -14709,16 +14704,16 @@ }, { "name": "doctrine/doctrine-fixtures-bundle", - "version": "3.5.1", + "version": "3.6.1", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineFixturesBundle.git", - "reference": "c808a0c85c38c8ee265cc8405b456c1d2b38567d" + "reference": "d13a08ebf244f74c8adb8ff15aa55d01c404e534" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineFixturesBundle/zipball/c808a0c85c38c8ee265cc8405b456c1d2b38567d", - "reference": "c808a0c85c38c8ee265cc8405b456c1d2b38567d", + "url": "https://api.github.com/repos/doctrine/DoctrineFixturesBundle/zipball/d13a08ebf244f74c8adb8ff15aa55d01c404e534", + "reference": "d13a08ebf244f74c8adb8ff15aa55d01c404e534", "shasum": "" }, "require": { @@ -14747,7 +14742,7 @@ "type": "symfony-bundle", "autoload": { "psr-4": { - "Doctrine\\Bundle\\FixturesBundle\\": "" + "Doctrine\\Bundle\\FixturesBundle\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -14776,7 +14771,7 @@ ], "support": { "issues": "https://github.com/doctrine/DoctrineFixturesBundle/issues", - "source": "https://github.com/doctrine/DoctrineFixturesBundle/tree/3.5.1" + "source": "https://github.com/doctrine/DoctrineFixturesBundle/tree/3.6.1" }, "funding": [ { @@ -14792,7 +14787,7 @@ "type": "tidelift" } ], - "time": "2023-11-19T12:48:54+00:00" + "time": "2024-05-07T07:16:35+00:00" }, { "name": "fakerphp/faker", @@ -14862,12 +14857,12 @@ "version": "v5.2.13", "source": { "type": "git", - "url": "https://github.com/justinrainbow/json-schema.git", + "url": "https://github.com/jsonrainbow/json-schema.git", "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/fbbe7e5d79f618997bc3332a6f49246036c45793", + "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/fbbe7e5d79f618997bc3332a6f49246036c45793", "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793", "shasum": "" }, @@ -14922,8 +14917,8 @@ "schema" ], "support": { - "issues": "https://github.com/justinrainbow/json-schema/issues", - "source": "https://github.com/justinrainbow/json-schema/tree/v5.2.13" + "issues": "https://github.com/jsonrainbow/json-schema/issues", + "source": "https://github.com/jsonrainbow/json-schema/tree/v5.2.13" }, "time": "2023-09-26T02:20:38+00:00" }, @@ -15231,16 +15226,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.10.66", + "version": "1.11.2", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "94779c987e4ebd620025d9e5fdd23323903950bd" + "reference": "0d5d4294a70deb7547db655c47685d680e39cfec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/94779c987e4ebd620025d9e5fdd23323903950bd", - "reference": "94779c987e4ebd620025d9e5fdd23323903950bd", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/0d5d4294a70deb7547db655c47685d680e39cfec", + "reference": "0d5d4294a70deb7547db655c47685d680e39cfec", "shasum": "" }, "require": { @@ -15283,13 +15278,9 @@ { "url": "https://github.com/phpstan", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", - "type": "tidelift" } ], - "time": "2024-03-28T16:17:31+00:00" + "time": "2024-05-24T13:23:04+00:00" }, { "name": "phpunit/php-code-coverage", @@ -15614,16 +15605,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.5.17", + "version": "10.5.20", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "c1f736a473d21957ead7e94fcc029f571895abf5" + "reference": "547d314dc24ec1e177720d45c6263fb226cc2ae3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c1f736a473d21957ead7e94fcc029f571895abf5", - "reference": "c1f736a473d21957ead7e94fcc029f571895abf5", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/547d314dc24ec1e177720d45c6263fb226cc2ae3", + "reference": "547d314dc24ec1e177720d45c6263fb226cc2ae3", "shasum": "" }, "require": { @@ -15695,7 +15686,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.17" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.20" }, "funding": [ { @@ -15711,7 +15702,7 @@ "type": "tidelift" } ], - "time": "2024-04-05T04:39:01+00:00" + "time": "2024-04-24T06:32:35+00:00" }, { "name": "sebastian/cli-parser", @@ -16631,16 +16622,16 @@ }, { "name": "symfony/browser-kit", - "version": "v7.0.3", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "725d5b15681685ac17b20b575254c75639722488" + "reference": "0a48e67a7975c07d8cc0661fbbdddce56c58425e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/725d5b15681685ac17b20b575254c75639722488", - "reference": "725d5b15681685ac17b20b575254c75639722488", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/0a48e67a7975c07d8cc0661fbbdddce56c58425e", + "reference": "0a48e67a7975c07d8cc0661fbbdddce56c58425e", "shasum": "" }, "require": { @@ -16679,7 +16670,7 @@ "description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/browser-kit/tree/v7.0.3" + "source": "https://github.com/symfony/browser-kit/tree/v7.0.7" }, "funding": [ { @@ -16695,20 +16686,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T15:02:46+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/debug-bundle", - "version": "v7.0.3", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/debug-bundle.git", - "reference": "b0db5c443883ce5c10c2265c77feb9833c3d9d6d" + "reference": "4b013a2c886cfd0292d90a9a9cebfa29ec7b578c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug-bundle/zipball/b0db5c443883ce5c10c2265c77feb9833c3d9d6d", - "reference": "b0db5c443883ce5c10c2265c77feb9833c3d9d6d", + "url": "https://api.github.com/repos/symfony/debug-bundle/zipball/4b013a2c886cfd0292d90a9a9cebfa29ec7b578c", + "reference": "4b013a2c886cfd0292d90a9a9cebfa29ec7b578c", "shasum": "" }, "require": { @@ -16753,7 +16744,7 @@ "description": "Provides a tight integration of the Symfony VarDumper component and the ServerLogCommand from MonologBridge into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/debug-bundle/tree/v7.0.3" + "source": "https://github.com/symfony/debug-bundle/tree/v7.0.7" }, "funding": [ { @@ -16769,20 +16760,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T15:02:46+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/dom-crawler", - "version": "v7.0.4", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "6cb272cbec4dc7a30a853d2931766b03bea92dda" + "reference": "7cb4ae7166a8a36916be390dbb3819474fb06a29" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/6cb272cbec4dc7a30a853d2931766b03bea92dda", - "reference": "6cb272cbec4dc7a30a853d2931766b03bea92dda", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/7cb4ae7166a8a36916be390dbb3819474fb06a29", + "reference": "7cb4ae7166a8a36916be390dbb3819474fb06a29", "shasum": "" }, "require": { @@ -16820,7 +16811,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v7.0.4" + "source": "https://github.com/symfony/dom-crawler/tree/v7.0.7" }, "funding": [ { @@ -16836,20 +16827,20 @@ "type": "tidelift" } ], - "time": "2024-02-12T11:15:03+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/maker-bundle", - "version": "v1.58.0", + "version": "v1.59.1", "source": { "type": "git", "url": "https://github.com/symfony/maker-bundle.git", - "reference": "c4f8d2c5d55950e1a49e822efc83a8511bee8a36" + "reference": "b87b1b25c607a8a50832395bc751c784946a0350" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/c4f8d2c5d55950e1a49e822efc83a8511bee8a36", - "reference": "c4f8d2c5d55950e1a49e822efc83a8511bee8a36", + "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/b87b1b25c607a8a50832395bc751c784946a0350", + "reference": "b87b1b25c607a8a50832395bc751c784946a0350", "shasum": "" }, "require": { @@ -16912,7 +16903,7 @@ ], "support": { "issues": "https://github.com/symfony/maker-bundle/issues", - "source": "https://github.com/symfony/maker-bundle/tree/v1.58.0" + "source": "https://github.com/symfony/maker-bundle/tree/v1.59.1" }, "funding": [ { @@ -16928,20 +16919,20 @@ "type": "tidelift" } ], - "time": "2024-04-06T15:08:12+00:00" + "time": "2024-05-06T03:59:59+00:00" }, { "name": "symfony/phpunit-bridge", - "version": "v7.0.6", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "a014167aa1f66cb9990675840da65609d3e61612" + "reference": "0a0b90ba08b9a03e09ad49f8d613bdf3eca3a7a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/a014167aa1f66cb9990675840da65609d3e61612", - "reference": "a014167aa1f66cb9990675840da65609d3e61612", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/0a0b90ba08b9a03e09ad49f8d613bdf3eca3a7a9", + "reference": "0a0b90ba08b9a03e09ad49f8d613bdf3eca3a7a9", "shasum": "" }, "require": { @@ -16993,7 +16984,7 @@ "description": "Provides utilities for PHPUnit, especially user deprecation notices management", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/phpunit-bridge/tree/v7.0.6" + "source": "https://github.com/symfony/phpunit-bridge/tree/v7.0.7" }, "funding": [ { @@ -17009,20 +17000,20 @@ "type": "tidelift" } ], - "time": "2024-03-19T11:57:22+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "symfony/web-profiler-bundle", - "version": "v7.0.4", + "version": "v7.0.7", "source": { "type": "git", "url": "https://github.com/symfony/web-profiler-bundle.git", - "reference": "542daea1345fe181cbfd52db00717174a838ea0a" + "reference": "a9a722210b391d7f6d97f140a5f2f7eee604d81a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/542daea1345fe181cbfd52db00717174a838ea0a", - "reference": "542daea1345fe181cbfd52db00717174a838ea0a", + "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/a9a722210b391d7f6d97f140a5f2f7eee604d81a", + "reference": "a9a722210b391d7f6d97f140a5f2f7eee604d81a", "shasum": "" }, "require": { @@ -17074,7 +17065,7 @@ "dev" ], "support": { - "source": "https://github.com/symfony/web-profiler-bundle/tree/v7.0.4" + "source": "https://github.com/symfony/web-profiler-bundle/tree/v7.0.7" }, "funding": [ { @@ -17090,7 +17081,7 @@ "type": "tidelift" } ], - "time": "2024-02-22T20:27:20+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { "name": "theseer/tokenizer", diff --git a/package-lock.json b/package-lock.json index 08ec93b67..df39f70a0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,20 +36,12 @@ "webpack-notifier": "^1.15.0" } }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -59,12 +51,13 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", - "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.6.tgz", + "integrity": "sha512-ZJhac6FkEd1yhG2AHOmfcXG4ceoLltoCVJjN5XsWN9BifBQr+cHJbWi0h68HZuSORq+3WtJ2z0hwF2NG1b5kcA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.2", + "@babel/highlight": "^7.24.6", "picocolors": "^1.0.0" }, "engines": { @@ -72,30 +65,32 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.1.tgz", - "integrity": "sha512-Pc65opHDliVpRHuKfzI+gSA4zcgr65O4cl64fFJIWEEh8JoHIHh0Oez1Eo8Arz8zq/JhgKodQaxEwUPRtZylVA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.6.tgz", + "integrity": "sha512-aC2DGhBq5eEdyXWqrDInSqQjO0k8xtPRf5YylULqx8MCd6jBtzqfta/3ETMRpuKIc5hyswfO80ObyA1MvkCcUQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.3.tgz", - "integrity": "sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.6.tgz", + "integrity": "sha512-qAHSfAdVyFmIvl0VHELib8xar7ONuSHrE2hLnsaWkYNTI68dmi1x8GYDhJjMI/e7XWal9QBlZkwbOnkcw7Z8gQ==", "dev": true, + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.2", - "@babel/generator": "^7.24.1", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.24.1", - "@babel/parser": "^7.24.1", - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.1", - "@babel/types": "^7.24.0", + "@babel/code-frame": "^7.24.6", + "@babel/generator": "^7.24.6", + "@babel/helper-compilation-targets": "^7.24.6", + "@babel/helper-module-transforms": "^7.24.6", + "@babel/helpers": "^7.24.6", + "@babel/parser": "^7.24.6", + "@babel/template": "^7.24.6", + "@babel/traverse": "^7.24.6", + "@babel/types": "^7.24.6", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -111,12 +106,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.1.tgz", - "integrity": "sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.6.tgz", + "integrity": "sha512-S7m4eNa6YAPJRHmKsLHIDJhNAGNKoWNiWefz1MBbpnt8g9lvMDl1hir4P9bo/57bQEmuwEhnRU/AMWsD0G/Fbg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.0", + "@babel/types": "^7.24.6", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -126,37 +122,40 @@ } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.6.tgz", + "integrity": "sha512-DitEzDfOMnd13kZnDqns1ccmftwJTS9DMkyn9pYTxulS7bZxUxpMly3Nf23QQ6NwA4UB8lAqjbqWtyvElEMAkg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.22.15", - "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==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.6.tgz", + "integrity": "sha512-+wnfqc5uHiMYtvRX7qu80Toef8BXeh4HHR1SPeonGb1SKPniNEd4a/nlaJJMv/OIEYvIVavvo0yR7u10Gqz0Iw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.15" + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", - "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.6.tgz", + "integrity": "sha512-VZQ57UsDGlX/5fFA7GkVPplZhHsVc+vuErWgdOiysI9Ksnw0Pbbd6pnPiR/mmJyKHgyIW0c7KT32gmhiF+cirg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-validator-option": "^7.23.5", + "@babel/compat-data": "^7.24.6", + "@babel/helper-validator-option": "^7.24.6", "browserslist": "^4.22.2", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -166,19 +165,20 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.1.tgz", - "integrity": "sha512-1yJa9dX9g//V6fDebXoEfEsxkZHk3Hcbm+zLhyu6qVgYFLvmTALTeV+jNU9e5RnYtioBrGEOdoI2joMSNQ/+aA==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-member-expression-to-functions": "^7.23.0", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.24.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.6.tgz", + "integrity": "sha512-djsosdPJVZE6Vsw3kk7IPRWethP94WHGOhQTc67SNXE0ZzMhHgALw8iGmYS0TD1bbMM0VDROy43od7/hN6WYcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.6", + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-function-name": "^7.24.6", + "@babel/helper-member-expression-to-functions": "^7.24.6", + "@babel/helper-optimise-call-expression": "^7.24.6", + "@babel/helper-replace-supers": "^7.24.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.6", + "@babel/helper-split-export-declaration": "^7.24.6", "semver": "^6.3.1" }, "engines": { @@ -189,12 +189,13 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.22.15", - "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==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.6.tgz", + "integrity": "sha512-C875lFBIWWwyv6MHZUG9HmRrlTDgOsLWZfYR0nW69gaKJNe0/Mpxx5r0EID2ZdHQkdUmQo2t0uNckTL08/1BgA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-annotate-as-pure": "^7.24.6", "regexpu-core": "^5.3.1", "semver": "^6.3.1" }, @@ -206,10 +207,11 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz", - "integrity": "sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==", + "version": "0.6.2", + "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, + "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", @@ -222,74 +224,80 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.6.tgz", + "integrity": "sha512-Y50Cg3k0LKLMjxdPjIl40SdJgMB85iXn27Vk/qbHZCFx/o5XO3PSnpi675h1KEmmDb6OFArfd5SCQEQ5Q4H88g==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.6.tgz", + "integrity": "sha512-xpeLqeeRkbxhnYimfr2PC+iA0Q7ljX/d1eZ9/inYbmfG2jpl8Lu3DyXvpOAnrS5kxkfOWJjioIMQsaMBXFI05w==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" + "@babel/template": "^7.24.6", + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.6.tgz", + "integrity": "sha512-SF/EMrC3OD7dSta1bLJIlrsVxwtd0UpjRJqLno6125epQMJ/kyFmpTT4pbvPbdQHzCHg+biQ7Syo8lnDtbR+uA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", - "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.6.tgz", + "integrity": "sha512-OTsCufZTxDUsv2/eDXanw/mUZHWOxSbEmC3pP8cgjcy5rgeVPWWMStnv274DV60JtHxTk0adT0QrCzC4M9NWGg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.23.0" + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", - "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.6.tgz", + "integrity": "sha512-a26dmxFJBF62rRO9mmpgrfTLsAuyHk4e1hKTUkD/fcMfynt8gvEKwQPQDVxWhca8dHoDck+55DFt42zV0QMw5g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.0" + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.6.tgz", + "integrity": "sha512-Y/YMPm83mV2HJTbX1Qh2sjgjqcacvOlhbzdCCsSlblOKjSYmQqEbO6rUniWQyRo9ncyfjT8hnUjlG06RXDEmcA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-module-imports": "^7.24.6", + "@babel/helper-simple-access": "^7.24.6", + "@babel/helper-split-export-declaration": "^7.24.6", + "@babel/helper-validator-identifier": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -299,35 +307,38 @@ } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", - "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.6.tgz", + "integrity": "sha512-3SFDJRbx7KuPRl8XDUr8O7GAEB8iGyWPjLKJh/ywP/Iy9WOmEfMrsWbaZpvBu2HSYn4KQygIsz0O7m8y10ncMA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", - "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.6.tgz", + "integrity": "sha512-MZG/JcWfxybKwsA9N9PmtF2lOSFSEMVCpIRrbxccZFLJPrJciJdG/UhSh5W96GEteJI2ARqm5UAHxISwRDLSNg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.22.20", - "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==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.6.tgz", + "integrity": "sha512-1Qursq9ArRZPAMOZf/nuzVW8HgJLkTB9y9LfP4lW2MVp4e9WkLJDovfKBxoDcCk6VuzIxyqWHyBoaCtSRP10yg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-wrap-function": "^7.22.20" + "@babel/helper-annotate-as-pure": "^7.24.6", + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-wrap-function": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -337,14 +348,15 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz", - "integrity": "sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.6.tgz", + "integrity": "sha512-mRhfPwDqDpba8o1F8ESxsEkJMQkUF8ZIWrAc0FtWhxnjfextxMWxr22RtFizxxSYLjVHDeMgVsRq8BBZR2ikJQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-member-expression-to-functions": "^7.23.0", - "@babel/helper-optimise-call-expression": "^7.22.5" + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-member-expression-to-functions": "^7.24.6", + "@babel/helper-optimise-call-expression": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -354,103 +366,111 @@ } }, "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.6.tgz", + "integrity": "sha512-nZzcMMD4ZhmB35MOOzQuiGO5RzL6tJbsT37Zx8M5L/i9KSrukGXWTjLe1knIbb/RmxoJE9GON9soq0c0VEMM5g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.22.5", - "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==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.6.tgz", + "integrity": "sha512-jhbbkK3IUKc4T43WadP96a27oYti9gEf1LdyGSP2rHGH77kwLwfhO7TgwnWvxxQVmke0ImmCSS47vcuxEMGD3Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.6.tgz", + "integrity": "sha512-CvLSkwXGWnYlF9+J3iZUvwgAxKiYzK3BWuo+mLzD/MDGOZDj7Gq8+hqaOkMxmJwmlv0iu86uH5fdADd9Hxkymw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", - "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.6.tgz", + "integrity": "sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.6.tgz", + "integrity": "sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.6.tgz", + "integrity": "sha512-Jktc8KkF3zIkePb48QO+IapbXlSapOW9S+ogZZkcO6bABgYAxtZcjZ/O005111YLf+j4M84uEgwYoidDkXbCkQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", - "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.6.tgz", + "integrity": "sha512-f1JLrlw/jbiNfxvdrfBgio/gRBk3yTAEJWirpAkiJG2Hb22E7cEYKHWo0dFPTv/niPovzIdPdEDetrv6tC6gPQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-function-name": "^7.22.5", - "@babel/template": "^7.22.15", - "@babel/types": "^7.22.19" + "@babel/helper-function-name": "^7.24.6", + "@babel/template": "^7.24.6", + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.1.tgz", - "integrity": "sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.6.tgz", + "integrity": "sha512-V2PI+NqnyFu1i0GyTd/O/cTpxzQCYioSkUIRmgo7gFEHKKCg5w46+r/A6WeUR1+P3TeQ49dspGPNd/E3n9AnnA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.1", - "@babel/types": "^7.24.0" + "@babel/template": "^7.24.6", + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", - "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.6.tgz", + "integrity": "sha512-2YnuOp4HAk2BsBrJJvYCbItHx0zWscI1C3zgWkz+wDyD9I7GIVrfnLyrR4Y1VR+7p+chAEcrgRQYZAGIKMV7vQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.6", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" @@ -460,10 +480,11 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz", - "integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.6.tgz", + "integrity": "sha512-eNZXdfU35nJC2h24RznROuOpO94h6x8sg9ju0tT9biNtLZ2vuP8SduLqqV+/8+cebSLV9SJEAN5Z3zQbJG/M+Q==", "dev": true, + "license": "MIT", "bin": { "parser": "bin/babel-parser.js" }, @@ -471,13 +492,31 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.24.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.6.tgz", + "integrity": "sha512-bYndrJ6Ph6Ar+GaB5VAc0JPoP80bQCm4qon6JEzXfRl5QZyQ8Ur1K6k7htxWmPA5z+k7JQvaMUrtXlqclWYzKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.24.1", - "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==", + "version": "7.24.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.6.tgz", + "integrity": "sha512-iVuhb6poq5ikqRq2XWU6OQ+R5o9wF+r/or9CeUyovgptz0UlnK4/seOQ1Istu/XybYjAhQv1FRSSfHHufIku5Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -487,14 +526,15 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.24.1", - "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==", + "version": "7.24.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.6.tgz", + "integrity": "sha512-c8TER5xMDYzzFcGqOEp9l4hvB7dcbhcGjcLVwxWfe4P5DOafdwjsBJZKsmv+o3aXh7NhopvayQIovHrh2zSRUQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.24.1" + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.6", + "@babel/plugin-transform-optional-chaining": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -504,13 +544,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.24.1", - "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==", + "version": "7.24.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.6.tgz", + "integrity": "sha512-z8zEjYmwBUHN/pCF3NuWBhHQjJCrd33qAi8MgANfMrAvn72k2cImT8VjK9LJFu4ysOLJqhfkYYb3MvwANRUNZQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -524,6 +565,7 @@ "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, + "license": "MIT", "engines": { "node": ">=6.9.0" }, @@ -536,6 +578,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -548,6 +591,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, @@ -560,6 +604,7 @@ "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, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -575,6 +620,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -587,6 +633,7 @@ "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, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.3" }, @@ -595,12 +642,13 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.1.tgz", - "integrity": "sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.6.tgz", + "integrity": "sha512-BE6o2BogJKJImTmGpkmOic4V0hlRRxVtzqxiSPa8TIFxyhi4EFjHm08nq1M4STK4RytuLMgnSz0/wfflvGFNOg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -610,12 +658,13 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.1.tgz", - "integrity": "sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.6.tgz", + "integrity": "sha512-D+CfsVZousPXIdudSII7RGy52+dYRtbyKAZcvtQKq/NpsivyMVduepzcLqG5pMBugtMdedxdC8Ramdpcne9ZWQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -629,6 +678,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -641,6 +691,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -653,6 +704,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -665,6 +717,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -677,6 +730,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -689,6 +743,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -701,6 +756,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -713,6 +769,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -725,6 +782,7 @@ "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, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -740,6 +798,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -755,6 +814,7 @@ "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, + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -767,12 +827,13 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.1.tgz", - "integrity": "sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.6.tgz", + "integrity": "sha512-jSSSDt4ZidNMggcLx8SaKsbGNEfIl0PHx/4mFEulorE7bpYLbN0d3pDW3eJ7Y5Z3yPhy3L3NaPCYyTUY7TuugQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -782,14 +843,15 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.24.3", - "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==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.6.tgz", + "integrity": "sha512-VEP2o4iR2DqQU6KPgizTW2mnMx6BG5b5O9iQdrW9HesLkv8GIA8x2daXBQxw1MrsIkFQGA/iJ204CKoQ8UcnAA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-remap-async-to-generator": "^7.22.20", + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-remap-async-to-generator": "^7.24.6", "@babel/plugin-syntax-async-generators": "^7.8.4" }, "engines": { @@ -800,14 +862,15 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.1.tgz", - "integrity": "sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.6.tgz", + "integrity": "sha512-NTBA2SioI3OsHeIn6sQmhvXleSl9T70YY/hostQLveWs0ic+qvbA3fa0kwAwQ0OA/XGaAerNZRQGJyRfhbJK4g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-remap-async-to-generator": "^7.22.20" + "@babel/helper-module-imports": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-remap-async-to-generator": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -817,12 +880,13 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.24.1", - "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==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.6.tgz", + "integrity": "sha512-XNW7jolYHW9CwORrZgA/97tL/k05qe/HL0z/qqJq1mdWhwwCM6D4BJBV7wAz9HgFziN5dTOG31znkVIzwxv+vw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -832,12 +896,13 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.1.tgz", - "integrity": "sha512-h71T2QQvDgM2SmT29UYU6ozjMlAt7s7CSs5Hvy8f8cf/GM/Z4a2zMfN+fjVGaieeCrXR3EdQl6C4gQG+OgmbKw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.6.tgz", + "integrity": "sha512-S/t1Xh4ehW7sGA7c1j/hiOBLnEYCp/c2sEG4ZkL8kI1xX9tW2pqJTCHKtdhe/jHKt8nG0pFCrDHUXd4DvjHS9w==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -847,13 +912,14 @@ } }, "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.1.tgz", - "integrity": "sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.6.tgz", + "integrity": "sha512-j6dZ0Z2Z2slWLR3kt9aOmSIrBvnntWjMDN/TVcMPxhXMLmJVqX605CBRlcGI4b32GMbfifTEsdEjGjiE+j/c3A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-create-class-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -863,13 +929,14 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.1.tgz", - "integrity": "sha512-FUHlKCn6J3ERiu8Dv+4eoz7w8+kFLSyeVG4vDAikwADGjUCoHw/JHokyGtr8OR4UjpwPVivyF+h8Q5iv/JmrtA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.6.tgz", + "integrity": "sha512-1QSRfoPI9RoLRa8Mnakc6v3e0gJxiZQTYrMfLn+mD0sz5+ndSzwymp2hDcYJTyT0MOn0yuWzj8phlIvO72gTHA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-create-class-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-class-static-block": "^7.14.5" }, "engines": { @@ -880,18 +947,19 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.1.tgz", - "integrity": "sha512-ZTIe3W7UejJd3/3R4p7ScyyOoafetUShSf4kCqV0O7F/RiHxVj/wRaRnQlrGwflvcehNA8M42HkAiEDYZu2F1Q==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-replace-supers": "^7.24.1", - "@babel/helper-split-export-declaration": "^7.22.6", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.6.tgz", + "integrity": "sha512-+fN+NO2gh8JtRmDSOB6gaCVo36ha8kfCW1nMq2Gc0DABln0VcHN4PrALDvF5/diLzIRKptC7z/d7Lp64zk92Fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.6", + "@babel/helper-compilation-targets": "^7.24.6", + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-function-name": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-replace-supers": "^7.24.6", + "@babel/helper-split-export-declaration": "^7.24.6", "globals": "^11.1.0" }, "engines": { @@ -902,13 +970,14 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.1.tgz", - "integrity": "sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.6.tgz", + "integrity": "sha512-cRzPobcfRP0ZtuIEkA8QzghoUpSB3X3qSH5W2+FzG+VjWbJXExtx0nbRqwumdBN1x/ot2SlTNQLfBCnPdzp6kg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/template": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/template": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -918,12 +987,13 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.1.tgz", - "integrity": "sha512-ow8jciWqNxR3RYbSNVuF4U2Jx130nwnBnhRw6N6h1bOejNkABmcI5X5oz29K4alWX7vf1C+o6gtKXikzRKkVdw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.6.tgz", + "integrity": "sha512-YLW6AE5LQpk5npNXL7i/O+U9CE4XsBCuRPgyjl1EICZYKmcitV+ayuuUGMJm2lC1WWjXYszeTnIxF/dq/GhIZQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -933,13 +1003,14 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.1.tgz", - "integrity": "sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.6.tgz", + "integrity": "sha512-rCXPnSEKvkm/EjzOtLoGvKseK+dS4kZwx1HexO3BtRtgL0fQ34awHn34aeSHuXtZY2F8a1X8xqBBPRtOxDVmcA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-create-regexp-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -949,12 +1020,13 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.1.tgz", - "integrity": "sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.6.tgz", + "integrity": "sha512-/8Odwp/aVkZwPFJMllSbawhDAO3UJi65foB00HYnK/uXvvCPm0TAXSByjz1mpRmp0q6oX2SIxpkUOpPFHk7FLA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -964,12 +1036,13 @@ } }, "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.24.1", - "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==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.6.tgz", + "integrity": "sha512-vpq8SSLRTBLOHUZHSnBqVo0AKX3PBaoPs2vVzYVWslXDTDIpwAcCDtfhUcHSQQoYoUvcFPTdC8TZYXu9ZnLT/w==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-dynamic-import": "^7.8.3" }, "engines": { @@ -980,13 +1053,14 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.24.1", - "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==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.6.tgz", + "integrity": "sha512-EemYpHtmz0lHE7hxxxYEuTYOOBZ43WkDgZ4arQ4r+VX9QHuNZC+WH3wUWmRNvR8ECpTRne29aZV6XO22qpOtdA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -996,12 +1070,13 @@ } }, "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.24.1", - "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==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.6.tgz", + "integrity": "sha512-inXaTM1SVrIxCkIJ5gqWiozHfFMStuGbGJAxZFBoHcRRdDP0ySLb3jH6JOwmfiinPwyMZqMBX+7NBDCO4z0NSA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "engines": { @@ -1012,13 +1087,14 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.1.tgz", - "integrity": "sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.6.tgz", + "integrity": "sha512-n3Sf72TnqK4nw/jziSqEl1qaWPbCRw2CziHH+jdRYvw4J6yeCzsj4jdw8hIntOEeDGTmHVe2w4MVL44PN0GMzg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1028,14 +1104,15 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.1.tgz", - "integrity": "sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.6.tgz", + "integrity": "sha512-sOajCu6V0P1KPljWHKiDq6ymgqB+vfo3isUS4McqW1DZtvSVU2v/wuMhmRmkg3sFoq6GMaUUf8W4WtoSLkOV/Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-compilation-targets": "^7.24.6", + "@babel/helper-function-name": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1045,12 +1122,13 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.1.tgz", - "integrity": "sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.6.tgz", + "integrity": "sha512-Uvgd9p2gUnzYJxVdBLcU0KurF8aVhkmVyMKW4MIY1/BByvs3EBpv45q01o7pRTVmTvtQq5zDlytP3dcUgm7v9w==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-json-strings": "^7.8.3" }, "engines": { @@ -1061,12 +1139,13 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.1.tgz", - "integrity": "sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.6.tgz", + "integrity": "sha512-f2wHfR2HF6yMj+y+/y07+SLqnOSwRp8KYLpQKOzS58XLVlULhXbiYcygfXQxJlMbhII9+yXDwOUFLf60/TL5tw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1076,12 +1155,13 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.24.1", - "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==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.6.tgz", + "integrity": "sha512-EKaWvnezBCMkRIHxMJSIIylzhqK09YpiJtDbr2wsXTwnO0TxyjMUkaw4RlFIZMIS0iDj0KyIg7H7XCguHu/YDA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" }, "engines": { @@ -1092,12 +1172,13 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.24.1", - "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==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.6.tgz", + "integrity": "sha512-9g8iV146szUo5GWgXpRbq/GALTnY+WnNuRTuRHWWFfWGbP9ukRL0aO/jpu9dmOPikclkxnNsjY8/gsWl6bmZJQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1107,13 +1188,14 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.1.tgz", - "integrity": "sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.6.tgz", + "integrity": "sha512-eAGogjZgcwqAxhyFgqghvoHRr+EYRQPFjUXrTYKBRb5qPnAVxOOglaxc4/byHqjvq/bqO2F3/CGwTHsgKJYHhQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-module-transforms": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1123,14 +1205,15 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz", - "integrity": "sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.6.tgz", + "integrity": "sha512-JEV8l3MHdmmdb7S7Cmx6rbNEjRCgTQMZxllveHO0mx6uiclB0NflCawlQQ6+o5ZrwjUBYPzHm2XoK4wqGVUFuw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-simple-access": "^7.22.5" + "@babel/helper-module-transforms": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-simple-access": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1140,15 +1223,16 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.1.tgz", - "integrity": "sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.6.tgz", + "integrity": "sha512-xg1Z0J5JVYxtpX954XqaaAT6NpAY6LtZXvYFCJmGFJWwtlz2EmJoR8LycFRGNE8dBKizGWkGQZGegtkV8y8s+w==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-validator-identifier": "^7.22.20" + "@babel/helper-hoist-variables": "^7.24.6", + "@babel/helper-module-transforms": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-validator-identifier": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1158,13 +1242,14 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.1.tgz", - "integrity": "sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.6.tgz", + "integrity": "sha512-esRCC/KsSEUvrSjv5rFYnjZI6qv4R1e/iHQrqwbZIoRJqk7xCvEUiN7L1XrmW5QSmQe3n1XD88wbgDTWLbVSyg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-module-transforms": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1174,13 +1259,14 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.22.5", - "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==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.6.tgz", + "integrity": "sha512-6DneiCiu91wm3YiNIGDWZsl6GfTTbspuj/toTEqLh9d4cx50UIzSdg+T96p8DuT7aJOBRhFyaE9ZvTHkXrXr6Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-regexp-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1190,12 +1276,13 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.1.tgz", - "integrity": "sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.6.tgz", + "integrity": "sha512-f8liz9JG2Va8A4J5ZBuaSdwfPqN6axfWRK+y66fjKYbwf9VBLuq4WxtinhJhvp1w6lamKUwLG0slK2RxqFgvHA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1205,12 +1292,13 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.24.1", - "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==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.6.tgz", + "integrity": "sha512-+QlAiZBMsBK5NqrBWFXCYeXyiU1y7BQ/OYaiPAcQJMomn5Tyg+r5WuVtyEuvTbpV7L25ZSLfE+2E9ywj4FD48A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" }, "engines": { @@ -1221,12 +1309,13 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.1.tgz", - "integrity": "sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.6.tgz", + "integrity": "sha512-6voawq8T25Jvvnc4/rXcWZQKKxUNZcKMS8ZNrjxQqoRFernJJKjE3s18Qo6VFaatG5aiX5JV1oPD7DbJhn0a4Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-numeric-separator": "^7.10.4" }, "engines": { @@ -1237,15 +1326,16 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.1.tgz", - "integrity": "sha512-XjD5f0YqOtebto4HGISLNfiNMTTs6tbkFf2TOqJlYKYmbo+mN9Dnpl4SRoofiziuOWMIyq3sZEUqLo3hLITFEA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.6.tgz", + "integrity": "sha512-OKmi5wiMoRW5Smttne7BwHM8s/fb5JFs+bVGNSeHWzwZkWXWValR1M30jyXo1s/RaqgwwhEC62u4rFH/FBcBPg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-compilation-targets": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.24.1" + "@babel/plugin-transform-parameters": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1255,13 +1345,14 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.1.tgz", - "integrity": "sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.6.tgz", + "integrity": "sha512-N/C76ihFKlZgKfdkEYKtaRUtXZAgK7sOY4h2qrbVbVTXPrKGIi8aww5WGe/+Wmg8onn8sr2ut6FXlsbu/j6JHg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-replace-supers": "^7.24.1" + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-replace-supers": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1271,12 +1362,13 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.24.1", - "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==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.6.tgz", + "integrity": "sha512-L5pZ+b3O1mSzJ71HmxSCmTVd03VOT2GXOigug6vDYJzE5awLI7P1g0wFcdmGuwSDSrQ0L2rDOe/hHws8J1rv3w==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" }, "engines": { @@ -1287,13 +1379,14 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.1.tgz", - "integrity": "sha512-n03wmDt+987qXwAgcBlnUUivrZBPZ8z1plL0YvgQalLm+ZE5BMhGm94jhxXtA1wzv1Cu2aaOv1BM9vbVttrzSg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.6.tgz", + "integrity": "sha512-cHbqF6l1QP11OkYTYQ+hhVx1E017O5ZcSPXk9oODpqhcAD1htsWG2NpHrrhthEO2qZomLK0FXS+u7NfrkF5aOQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.6", "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, "engines": { @@ -1304,12 +1397,13 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.1.tgz", - "integrity": "sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.6.tgz", + "integrity": "sha512-ST7guE8vLV+vI70wmAxuZpIKzVjvFX9Qs8bl5w6tN/6gOypPWUmMQL2p7LJz5E63vEGrDhAiYetniJFyBH1RkA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1319,13 +1413,14 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.1.tgz", - "integrity": "sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.6.tgz", + "integrity": "sha512-T9LtDI0BgwXOzyXrvgLTT8DFjCC/XgWLjflczTLXyvxbnSR/gpv0hbmzlHE/kmh9nOvlygbamLKRo6Op4yB6aw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-create-class-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1335,14 +1430,15 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.1.tgz", - "integrity": "sha512-pTHxDVa0BpUbvAgX3Gat+7cSciXqUcY9j2VZKTbSB6+VQGpNgNO9ailxTGHSXlqOnX1Hcx1Enme2+yv7VqP9bg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.6.tgz", + "integrity": "sha512-Qu/ypFxCY5NkAnEhCF86Mvg3NSabKsh/TPpBVswEdkGl7+FbsYHy1ziRqJpwGH4thBdQHh8zx+z7vMYmcJ7iaQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-annotate-as-pure": "^7.24.6", + "@babel/helper-create-class-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { @@ -1353,12 +1449,13 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.1.tgz", - "integrity": "sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.6.tgz", + "integrity": "sha512-oARaglxhRsN18OYsnPTpb8TcKQWDYNsPNmTnx5++WOAsUJ0cSC/FZVlIJCKvPbU4yn/UXsS0551CFKJhN0CaMw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1368,12 +1465,13 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.1.tgz", - "integrity": "sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.6.tgz", + "integrity": "sha512-SMDxO95I8WXRtXhTAc8t/NFQUT7VYbIWwJCJgEli9ml4MhqUMh4S6hxgH6SmAC3eAQNWCDJFxcFeEt9w2sDdXg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.6", "regenerator-transform": "^0.15.2" }, "engines": { @@ -1384,12 +1482,13 @@ } }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.1.tgz", - "integrity": "sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.6.tgz", + "integrity": "sha512-DcrgFXRRlK64dGE0ZFBPD5egM2uM8mgfrvTMOSB2yKzOtjpGegVYkzh3s1zZg1bBck3nkXiaOamJUqK3Syk+4A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1399,12 +1498,13 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.1.tgz", - "integrity": "sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.6.tgz", + "integrity": "sha512-xnEUvHSMr9eOWS5Al2YPfc32ten7CXdH7Zwyyk7IqITg4nX61oHj+GxpNvl+y5JHjfN3KXE2IV55wAWowBYMVw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1414,13 +1514,14 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.1.tgz", - "integrity": "sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.6.tgz", + "integrity": "sha512-h/2j7oIUDjS+ULsIrNZ6/TKG97FgmEk1PXryk/HQq6op4XUUUwif2f69fJrzK0wza2zjCS1xhXmouACaWV5uPA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1430,12 +1531,13 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.1.tgz", - "integrity": "sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.6.tgz", + "integrity": "sha512-fN8OcTLfGmYv7FnDrsjodYBo1DhPL3Pze/9mIIE2MGCT1KgADYIOD7rEglpLHZj8PZlC/JFX5WcD+85FLAQusw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1445,12 +1547,13 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz", - "integrity": "sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.6.tgz", + "integrity": "sha512-BJbEqJIcKwrqUP+KfUIkxz3q8VzXe2R8Wv8TaNgO1cx+nNavxn/2+H8kp9tgFSOL6wYPPEgFvU6IKS4qoGqhmg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1460,12 +1563,13 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.1.tgz", - "integrity": "sha512-CBfU4l/A+KruSUoW+vTQthwcAdwuqbpRNB8HQKlZABwHRhsdHZ9fezp4Sn18PeAlYxTNiLMlx4xUBV3AWfg1BA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.6.tgz", + "integrity": "sha512-IshCXQ+G9JIFJI7bUpxTE/oA2lgVLAIK8q1KdJNoPXOpvRaNjMySGuvLfBw/Xi2/1lLo953uE8hyYSDW3TSYig==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1475,12 +1579,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.1.tgz", - "integrity": "sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.6.tgz", + "integrity": "sha512-bKl3xxcPbkQQo5eX9LjjDpU2xYHeEeNQbOhj0iPvetSzA+Tu9q/o5lujF4Sek60CM6MgYvOS/DJuwGbiEYAnLw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1490,13 +1595,14 @@ } }, "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.24.1", - "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==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.6.tgz", + "integrity": "sha512-8EIgImzVUxy15cZiPii9GvLZwsy7Vxc+8meSlR3cXFmBIl5W5Tn9LGBf7CDKkHj4uVfNXCJB8RsVfnmY61iedA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-create-regexp-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1506,13 +1612,14 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.1.tgz", - "integrity": "sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.6.tgz", + "integrity": "sha512-pssN6ExsvxaKU638qcWb81RrvvgZom3jDgU/r5xFZ7TONkZGFf4MhI2ltMb8OcQWhHyxgIavEU+hgqtbKOmsPA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-create-regexp-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1522,13 +1629,14 @@ } }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.1.tgz", - "integrity": "sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.6.tgz", + "integrity": "sha512-quiMsb28oXWIDK0gXLALOJRXLgICLiulqdZGOaPPd0vRT7fQp74NtdADAVu+D8s00C+0Xs0MxVP0VKF/sZEUgw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-create-regexp-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1538,26 +1646,28 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.3.tgz", - "integrity": "sha512-fSk430k5c2ff8536JcPvPWK4tZDwehWLGlBp0wrsBUjZVdeQV6lePbwKWZaZfK2vnh/1kQX1PzAJWsnBmVgGJA==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.24.1", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.1", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.1", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.1", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.6.tgz", + "integrity": "sha512-CrxEAvN7VxfjOG8JNF2Y/eMqMJbZPZ185amwGUBp8D9USK90xQmv7dLdFSa+VbD7fdIqcy/Mfv7WtzG8+/qxKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.24.6", + "@babel/helper-compilation-targets": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-validator-option": "^7.24.6", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.6", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.6", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.6", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.6", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.24.1", - "@babel/plugin-syntax-import-attributes": "^7.24.1", + "@babel/plugin-syntax-import-assertions": "^7.24.6", + "@babel/plugin-syntax-import-attributes": "^7.24.6", "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", @@ -1569,54 +1679,54 @@ "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.24.1", - "@babel/plugin-transform-async-generator-functions": "^7.24.3", - "@babel/plugin-transform-async-to-generator": "^7.24.1", - "@babel/plugin-transform-block-scoped-functions": "^7.24.1", - "@babel/plugin-transform-block-scoping": "^7.24.1", - "@babel/plugin-transform-class-properties": "^7.24.1", - "@babel/plugin-transform-class-static-block": "^7.24.1", - "@babel/plugin-transform-classes": "^7.24.1", - "@babel/plugin-transform-computed-properties": "^7.24.1", - "@babel/plugin-transform-destructuring": "^7.24.1", - "@babel/plugin-transform-dotall-regex": "^7.24.1", - "@babel/plugin-transform-duplicate-keys": "^7.24.1", - "@babel/plugin-transform-dynamic-import": "^7.24.1", - "@babel/plugin-transform-exponentiation-operator": "^7.24.1", - "@babel/plugin-transform-export-namespace-from": "^7.24.1", - "@babel/plugin-transform-for-of": "^7.24.1", - "@babel/plugin-transform-function-name": "^7.24.1", - "@babel/plugin-transform-json-strings": "^7.24.1", - "@babel/plugin-transform-literals": "^7.24.1", - "@babel/plugin-transform-logical-assignment-operators": "^7.24.1", - "@babel/plugin-transform-member-expression-literals": "^7.24.1", - "@babel/plugin-transform-modules-amd": "^7.24.1", - "@babel/plugin-transform-modules-commonjs": "^7.24.1", - "@babel/plugin-transform-modules-systemjs": "^7.24.1", - "@babel/plugin-transform-modules-umd": "^7.24.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", - "@babel/plugin-transform-new-target": "^7.24.1", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.1", - "@babel/plugin-transform-numeric-separator": "^7.24.1", - "@babel/plugin-transform-object-rest-spread": "^7.24.1", - "@babel/plugin-transform-object-super": "^7.24.1", - "@babel/plugin-transform-optional-catch-binding": "^7.24.1", - "@babel/plugin-transform-optional-chaining": "^7.24.1", - "@babel/plugin-transform-parameters": "^7.24.1", - "@babel/plugin-transform-private-methods": "^7.24.1", - "@babel/plugin-transform-private-property-in-object": "^7.24.1", - "@babel/plugin-transform-property-literals": "^7.24.1", - "@babel/plugin-transform-regenerator": "^7.24.1", - "@babel/plugin-transform-reserved-words": "^7.24.1", - "@babel/plugin-transform-shorthand-properties": "^7.24.1", - "@babel/plugin-transform-spread": "^7.24.1", - "@babel/plugin-transform-sticky-regex": "^7.24.1", - "@babel/plugin-transform-template-literals": "^7.24.1", - "@babel/plugin-transform-typeof-symbol": "^7.24.1", - "@babel/plugin-transform-unicode-escapes": "^7.24.1", - "@babel/plugin-transform-unicode-property-regex": "^7.24.1", - "@babel/plugin-transform-unicode-regex": "^7.24.1", - "@babel/plugin-transform-unicode-sets-regex": "^7.24.1", + "@babel/plugin-transform-arrow-functions": "^7.24.6", + "@babel/plugin-transform-async-generator-functions": "^7.24.6", + "@babel/plugin-transform-async-to-generator": "^7.24.6", + "@babel/plugin-transform-block-scoped-functions": "^7.24.6", + "@babel/plugin-transform-block-scoping": "^7.24.6", + "@babel/plugin-transform-class-properties": "^7.24.6", + "@babel/plugin-transform-class-static-block": "^7.24.6", + "@babel/plugin-transform-classes": "^7.24.6", + "@babel/plugin-transform-computed-properties": "^7.24.6", + "@babel/plugin-transform-destructuring": "^7.24.6", + "@babel/plugin-transform-dotall-regex": "^7.24.6", + "@babel/plugin-transform-duplicate-keys": "^7.24.6", + "@babel/plugin-transform-dynamic-import": "^7.24.6", + "@babel/plugin-transform-exponentiation-operator": "^7.24.6", + "@babel/plugin-transform-export-namespace-from": "^7.24.6", + "@babel/plugin-transform-for-of": "^7.24.6", + "@babel/plugin-transform-function-name": "^7.24.6", + "@babel/plugin-transform-json-strings": "^7.24.6", + "@babel/plugin-transform-literals": "^7.24.6", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.6", + "@babel/plugin-transform-member-expression-literals": "^7.24.6", + "@babel/plugin-transform-modules-amd": "^7.24.6", + "@babel/plugin-transform-modules-commonjs": "^7.24.6", + "@babel/plugin-transform-modules-systemjs": "^7.24.6", + "@babel/plugin-transform-modules-umd": "^7.24.6", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.6", + "@babel/plugin-transform-new-target": "^7.24.6", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.6", + "@babel/plugin-transform-numeric-separator": "^7.24.6", + "@babel/plugin-transform-object-rest-spread": "^7.24.6", + "@babel/plugin-transform-object-super": "^7.24.6", + "@babel/plugin-transform-optional-catch-binding": "^7.24.6", + "@babel/plugin-transform-optional-chaining": "^7.24.6", + "@babel/plugin-transform-parameters": "^7.24.6", + "@babel/plugin-transform-private-methods": "^7.24.6", + "@babel/plugin-transform-private-property-in-object": "^7.24.6", + "@babel/plugin-transform-property-literals": "^7.24.6", + "@babel/plugin-transform-regenerator": "^7.24.6", + "@babel/plugin-transform-reserved-words": "^7.24.6", + "@babel/plugin-transform-shorthand-properties": "^7.24.6", + "@babel/plugin-transform-spread": "^7.24.6", + "@babel/plugin-transform-sticky-regex": "^7.24.6", + "@babel/plugin-transform-template-literals": "^7.24.6", + "@babel/plugin-transform-typeof-symbol": "^7.24.6", + "@babel/plugin-transform-unicode-escapes": "^7.24.6", + "@babel/plugin-transform-unicode-property-regex": "^7.24.6", + "@babel/plugin-transform-unicode-regex": "^7.24.6", + "@babel/plugin-transform-unicode-sets-regex": "^7.24.6", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.10", "babel-plugin-polyfill-corejs3": "^0.10.4", @@ -1636,6 +1746,7 @@ "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, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/types": "^7.4.4", @@ -1649,13 +1760,15 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/@babel/runtime": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.1.tgz", - "integrity": "sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.6.tgz", + "integrity": "sha512-Ja18XcETdEl5mzzACGd+DKgaGJzPTCow7EglgwTmHdwokzDFYh/MHua6lU6DV/hjF2IaOJ4oX2nqnjG7RElKOw==", "dev": true, + "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -1664,33 +1777,35 @@ } }, "node_modules/@babel/template": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", - "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.6.tgz", + "integrity": "sha512-3vgazJlLwNXi9jhrR1ef8qiB65L1RK90+lEQwv4OxveHnqC3BfmnHdgySwRLzf6akhlOYenT+b7AfWq+a//AHw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.24.0", - "@babel/types": "^7.24.0" + "@babel/code-frame": "^7.24.6", + "@babel/parser": "^7.24.6", + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", - "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.24.1", - "@babel/generator": "^7.24.1", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.24.1", - "@babel/types": "^7.24.0", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.6.tgz", + "integrity": "sha512-OsNjaJwT9Zn8ozxcfoBc+RaHdj3gFmCmYoQLUII1o6ZrUwku0BMg80FoOTPx+Gi6XhcQxAYE4xyjPTo4SxEQqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.24.6", + "@babel/generator": "^7.24.6", + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-function-name": "^7.24.6", + "@babel/helper-hoist-variables": "^7.24.6", + "@babel/helper-split-export-declaration": "^7.24.6", + "@babel/parser": "^7.24.6", + "@babel/types": "^7.24.6", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1699,13 +1814,14 @@ } }, "node_modules/@babel/types": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", - "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.6.tgz", + "integrity": "sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-string-parser": "^7.24.6", + "@babel/helper-validator-identifier": "^7.24.6", "to-fast-properties": "^2.0.0" }, "engines": { @@ -1717,6 +1833,7 @@ "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" } @@ -1729,6 +1846,7 @@ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "aix" @@ -1746,6 +1864,7 @@ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -1763,6 +1882,7 @@ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -1780,6 +1900,7 @@ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -1797,6 +1918,7 @@ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -1814,6 +1936,7 @@ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -1831,6 +1954,7 @@ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -1848,6 +1972,7 @@ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -1865,6 +1990,7 @@ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -1882,6 +2008,7 @@ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -1899,6 +2026,7 @@ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -1916,6 +2044,7 @@ "loong64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -1933,6 +2062,7 @@ "mips64el" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -1950,6 +2080,7 @@ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -1967,6 +2098,7 @@ "riscv64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -1984,6 +2116,7 @@ "s390x" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -2001,6 +2134,7 @@ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -2018,6 +2152,7 @@ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "netbsd" @@ -2035,6 +2170,7 @@ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "openbsd" @@ -2052,6 +2188,7 @@ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "sunos" @@ -2069,6 +2206,7 @@ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -2086,6 +2224,7 @@ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -2103,6 +2242,7 @@ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -2117,6 +2257,7 @@ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, + "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.3.0" }, @@ -2132,6 +2273,7 @@ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true, + "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } @@ -2141,6 +2283,7 @@ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -2159,11 +2302,23 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "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, + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -2174,11 +2329,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@eslint/js": { "version": "8.57.0", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -2189,6 +2358,7 @@ "integrity": "sha512-hRILoInAx8GNT5IMkrtIt9blOdrqHOnPBH+k70aWUAqPZPgopb9G5EQJFpaBx/S8zp2fC+mPW349Bziuk1o28Q==", "dev": true, "hasInstallScript": true, + "license": "(CC-BY-4.0 AND OFL-1.1 AND MIT)", "engines": { "node": ">=6" } @@ -2197,19 +2367,22 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/@github/markdown-toolbar-element/-/markdown-toolbar-element-2.2.3.tgz", "integrity": "sha512-AlquKGee+IWiAMYVB0xyHFZRMnu4n3X4HTvJHu79GiVJ1ojTukCWyxMlF5NMsecoLcBKsuBhx3QPv2vkE/zQ0A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@hotwired/stimulus": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/@hotwired/stimulus/-/stimulus-3.2.2.tgz", "integrity": "sha512-eGeIqNOQpXoPAIP7tC1+1Yc1yl1xnwYqg+3mzqxyrbE5pg5YFBZcA6YoTiByJB6DKAEsiWtl6tjTJS4IYtbB7A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@hotwired/stimulus-webpack-helpers": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@hotwired/stimulus-webpack-helpers/-/stimulus-webpack-helpers-1.0.1.tgz", "integrity": "sha512-wa/zupVG0eWxRYJjC1IiPBdt3Lruv0RqGN+/DTMmUWUyMAEB27KXmVY6a8YpUVTM7QwVuaLNGW4EqDgrS2upXQ==", "dev": true, + "license": "MIT", "peerDependencies": { "@hotwired/stimulus": ">= 3.0" } @@ -2219,6 +2392,7 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@humanwhocodes/object-schema": "^2.0.2", "debug": "^4.3.1", @@ -2228,11 +2402,36 @@ "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -2245,13 +2444,15 @@ "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 + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, + "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.27.8" }, @@ -2264,6 +2465,7 @@ "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", @@ -2281,6 +2483,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -2296,6 +2499,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -2312,6 +2516,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -2323,13 +2528,15 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/@jest/types/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, + "license": "MIT", "engines": { "node": ">=8" } @@ -2339,6 +2546,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -2351,6 +2559,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -2365,6 +2574,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -2374,6 +2584,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -2383,6 +2594,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" @@ -2392,13 +2604,15 @@ "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -2408,13 +2622,15 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -2428,6 +2644,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -2437,6 +2654,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -2450,6 +2668,7 @@ "resolved": "https://registry.npmjs.org/@nuxt/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-2.6.0.tgz", "integrity": "sha512-3IZj6MXbzlvUxDncAxgBMLQwGPY/JlNhy2i+AGyOHCAReR5HcBxYjVRBvyaKM9R3s5k4OODYKeHAbrToZH/47w==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^2.4.2", "consola": "^3.2.3", @@ -2469,6 +2688,7 @@ "resolved": "https://registry.npmjs.org/@orchidjs/sifter/-/sifter-1.0.3.tgz", "integrity": "sha512-zCZbwKegHytfsPm8Amcfh7v/4vHqTAaOu6xFswBYcn8nznBOuseu6COB2ON7ez0tFV0mKL0nRNnCiZZA+lU9/g==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@orchidjs/unicode-variants": "^1.0.4" } @@ -2477,16 +2697,18 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/@orchidjs/unicode-variants/-/unicode-variants-1.0.4.tgz", "integrity": "sha512-NvVBRnZNE+dugiXERFsET1JlKZfM5lJDEpSMilKW4bToYJ7pxf0Zne78xyXB2ny2c2aHfJ6WLnz1AaTNHAmQeQ==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.0.tgz", - "integrity": "sha512-jwXtxYbRt1V+CdQSy6Z+uZti7JF5irRKF8hlKfEnF/xJpcNGuuiZMBvuoYM+x9sr9iWGnzrlM0+9hvQ1kgkf1w==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", + "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -2494,13 +2716,14 @@ "peer": true }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.0.tgz", - "integrity": "sha512-fI9nduZhCccjzlsA/OuAwtFGWocxA4gqXGTLvOyiF8d+8o0fZUeSztixkYjcGq1fGZY3Tkq4yRvHPFxU+jdZ9Q==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", + "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -2508,13 +2731,14 @@ "peer": true }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.0.tgz", - "integrity": "sha512-BcnSPRM76/cD2gQC+rQNGBN6GStBs2pl/FpweW8JYuz5J/IEa0Fr4AtrPv766DB/6b2MZ/AfSIOSGw3nEIP8SA==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", + "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -2522,13 +2746,14 @@ "peer": true }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.0.tgz", - "integrity": "sha512-LDyFB9GRolGN7XI6955aFeI3wCdCUszFWumWU0deHA8VpR3nWRrjG6GtGjBrQxQKFevnUTHKCfPR4IvrW3kCgQ==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", + "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -2536,13 +2761,29 @@ "peer": true }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.0.tgz", - "integrity": "sha512-ygrGVhQP47mRh0AAD0zl6QqCbNsf0eTo+vgwkY6LunBcg0f2Jv365GXlDUECIyoXp1kKwL5WW6rsO429DBY/bA==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", + "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", + "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -2550,13 +2791,14 @@ "peer": true }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.0.tgz", - "integrity": "sha512-x+uJ6MAYRlHGe9wi4HQjxpaKHPM3d3JjqqCkeC5gpnnI6OWovLdXTpfa8trjxPLnWKyBsSi5kne+146GAxFt4A==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", + "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -2564,13 +2806,14 @@ "peer": true }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.0.tgz", - "integrity": "sha512-nrRw8ZTQKg6+Lttwqo6a2VxR9tOroa2m91XbdQ2sUUzHoedXlsyvY1fN4xWdqz8PKmf4orDwejxXHjh7YBGUCA==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", + "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -2578,13 +2821,14 @@ "peer": true }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.0.tgz", - "integrity": "sha512-xV0d5jDb4aFu84XKr+lcUJ9y3qpIWhttO3Qev97z8DKLXR62LC3cXT/bMZXrjLF9X+P5oSmJTzAhqwUbY96PnA==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", + "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", "cpu": [ - "ppc64le" + "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -2592,13 +2836,14 @@ "peer": true }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.0.tgz", - "integrity": "sha512-SDDhBQwZX6LPRoPYjAZWyL27LbcBo7WdBFWJi5PI9RPCzU8ijzkQn7tt8NXiXRiFMJCVpkuMkBf4OxSxVMizAw==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", + "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", "cpu": [ "riscv64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -2606,13 +2851,14 @@ "peer": true }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.0.tgz", - "integrity": "sha512-RxB/qez8zIDshNJDufYlTT0ZTVut5eCpAZ3bdXDU9yTxBzui3KhbGjROK2OYTTor7alM7XBhssgoO3CZ0XD3qA==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", + "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", "cpu": [ "s390x" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -2620,13 +2866,14 @@ "peer": true }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.0.tgz", - "integrity": "sha512-C6y6z2eCNCfhZxT9u+jAM2Fup89ZjiG5pIzZIDycs1IwESviLxwkQcFRGLjnDrP+PT+v5i4YFvlcfAs+LnreXg==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", + "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -2634,13 +2881,14 @@ "peer": true }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.0.tgz", - "integrity": "sha512-i0QwbHYfnOMYsBEyjxcwGu5SMIi9sImDVjDg087hpzXqhBSosxkE7gyIYFHgfFl4mr7RrXksIBZ4DoLoP4FhJg==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", + "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -2648,13 +2896,14 @@ "peer": true }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.0.tgz", - "integrity": "sha512-Fq52EYb0riNHLBTAcL0cun+rRwyZ10S9vKzhGKKgeD+XbwunszSY0rVMco5KbOsTlwovP2rTOkiII/fQ4ih/zQ==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", + "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -2662,13 +2911,14 @@ "peer": true }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.0.tgz", - "integrity": "sha512-e/PBHxPdJ00O9p5Ui43+vixSgVf4NlLsmV6QneGERJ3lnjIua/kim6PRFe3iDueT1rQcgSkYP8ZBBXa/h4iPvw==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", + "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -2676,13 +2926,14 @@ "peer": true }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.0.tgz", - "integrity": "sha512-aGg7iToJjdklmxlUlJh/PaPNa4PmqHfyRMLunbL3eaMO0gp656+q1zOKkpJ/CVe9CryJv6tAN1HDoR8cNGzkag==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", + "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -2693,19 +2944,21 @@ "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@stylistic/eslint-plugin": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-1.7.0.tgz", - "integrity": "sha512-ThMUjGIi/jeWYNvOdjZkoLw1EOVs0tEuKXDgWvTn8uWaEz55HuPlajKxjKLpv19C+qRDbKczJfzUODfCdME53A==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-1.8.1.tgz", + "integrity": "sha512-64My6I7uCcmSQ//427Pfg2vjSf9SDzfsGIWohNFgISMLYdC5BzJqDo647iDDJzSxINh3WTC0Ql46ifiKuOoTyA==", "dev": true, + "license": "MIT", "dependencies": { - "@stylistic/eslint-plugin-js": "1.7.0", - "@stylistic/eslint-plugin-jsx": "1.7.0", - "@stylistic/eslint-plugin-plus": "1.7.0", - "@stylistic/eslint-plugin-ts": "1.7.0", - "@types/eslint": "^8.56.2" + "@stylistic/eslint-plugin-js": "1.8.1", + "@stylistic/eslint-plugin-jsx": "1.8.1", + "@stylistic/eslint-plugin-plus": "1.8.1", + "@stylistic/eslint-plugin-ts": "1.8.1", + "@types/eslint": "^8.56.10" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2715,12 +2968,13 @@ } }, "node_modules/@stylistic/eslint-plugin-js": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-1.7.0.tgz", - "integrity": "sha512-PN6On/+or63FGnhhMKSQfYcWutRlzOiYlVdLM6yN7lquoBTqUJHYnl4TA4MHwiAt46X5gRxDr1+xPZ1lOLcL+Q==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-1.8.1.tgz", + "integrity": "sha512-c5c2C8Mos5tTQd+NWpqwEu7VT6SSRooAguFPMj1cp2RkTYl1ynKoXo8MWy3k4rkbzoeYHrqC2UlUzsroAN7wtQ==", "dev": true, + "license": "MIT", "dependencies": { - "@types/eslint": "^8.56.2", + "@types/eslint": "^8.56.10", "acorn": "^8.11.3", "escape-string-regexp": "^4.0.0", "eslint-visitor-keys": "^3.4.3", @@ -2734,15 +2988,16 @@ } }, "node_modules/@stylistic/eslint-plugin-jsx": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-1.7.0.tgz", - "integrity": "sha512-BACdBwXakQvjYIST5N2WWhRbvhRsIxa/F59BiZol+0IH4FSmDXhie7v/yaxDIIA9CbfElzOmIA5nWNYTVXcnwQ==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-1.8.1.tgz", + "integrity": "sha512-k1Eb6rcjMP+mmjvj+vd9y5KUdWn1OBkkPLHXhsrHt5lCDFZxJEs0aVQzE5lpYrtVZVkpc5esTtss/cPJux0lfA==", "dev": true, + "license": "MIT", "dependencies": { - "@stylistic/eslint-plugin-js": "^1.7.0", - "@types/eslint": "^8.56.2", + "@stylistic/eslint-plugin-js": "^1.8.1", + "@types/eslint": "^8.56.10", "estraverse": "^5.3.0", - "picomatch": "^4.0.1" + "picomatch": "^4.0.2" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2751,34 +3006,14 @@ "eslint": ">=8.40.0" } }, - "node_modules/@stylistic/eslint-plugin-jsx/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/@stylistic/eslint-plugin-jsx/node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/@stylistic/eslint-plugin-plus": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-1.7.0.tgz", - "integrity": "sha512-AabDw8sXsc70Ydx3qnbeTlRHZnIwY6UKEenBPURPhY3bfYWX+/pDpZH40HkOu94v8D0DUrocPkeeEUxl4e0JDg==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-1.8.1.tgz", + "integrity": "sha512-4+40H3lHYTN8OWz+US8CamVkO+2hxNLp9+CAjorI7top/lHqemhpJvKA1LD9Uh+WMY9DYWiWpL2+SZ2wAXY9fQ==", "dev": true, + "license": "MIT", "dependencies": { - "@types/eslint": "^8.56.2", + "@types/eslint": "^8.56.10", "@typescript-eslint/utils": "^6.21.0" }, "peerDependencies": { @@ -2786,13 +3021,14 @@ } }, "node_modules/@stylistic/eslint-plugin-ts": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-1.7.0.tgz", - "integrity": "sha512-QsHv98mmW1xaucVYQTyLDgEpybPJ/6jPPxVBrIchntWWwj74xCWKUiw79hu+TpYj/Pbhd9rkqJYLNq3pQGYuyA==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-1.8.1.tgz", + "integrity": "sha512-/q1m+ZuO1JHfiSF16EATFzv7XSJkc5W6DocfvH5o9oB6WWYFMF77fVoBWnKT3wGptPOc2hkRupRKhmeFROdfWA==", "dev": true, + "license": "MIT", "dependencies": { - "@stylistic/eslint-plugin-js": "1.7.0", - "@types/eslint": "^8.56.2", + "@stylistic/eslint-plugin-js": "1.8.1", + "@types/eslint": "^8.56.10", "@typescript-eslint/utils": "^6.21.0" }, "engines": { @@ -2807,6 +3043,7 @@ "resolved": "https://registry.npmjs.org/@symfony/stimulus-bridge/-/stimulus-bridge-3.2.2.tgz", "integrity": "sha512-kIaUEGPXW7g14zsHkIvQWw8cmfCdXSqsEQx18fuHPBb+R0h8nYPyY+e9uVtTuHlE2wHwAjrJoc6YBBK4a7CpKA==", "dev": true, + "license": "MIT", "dependencies": { "@hotwired/stimulus-webpack-helpers": "^1.0.1", "@types/webpack-env": "^1.16.4", @@ -2838,6 +3075,7 @@ "resolved": "https://registry.npmjs.org/@symfony/webpack-encore/-/webpack-encore-4.6.1.tgz", "integrity": "sha512-JbOjy0P6P9pcbgVE3nceFnCCneRO+tbcLUkQh9rpPj/sHtFl12foSjHz6uY93ZGZGAvTyqEslie+4MlD/rUtnQ==", "dev": true, + "license": "MIT", "dependencies": { "@nuxt/friendly-errors-webpack-plugin": "^2.5.1", "assets-webpack-plugin": "7.0.*", @@ -3000,6 +3238,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -3015,6 +3254,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -3031,6 +3271,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -3042,37 +3283,25 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/@symfony/webpack-encore/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, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/@symfony/webpack-encore/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@symfony/webpack-encore/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -3085,6 +3314,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -3092,17 +3322,12 @@ "node": ">=8" } }, - "node_modules/@symfony/webpack-encore/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/@trysound/sax": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", "dev": true, + "license": "ISC", "engines": { "node": ">=10.13.0" } @@ -3112,6 +3337,7 @@ "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", "dev": true, + "license": "MIT", "dependencies": { "@types/connect": "*", "@types/node": "*" @@ -3122,6 +3348,7 @@ "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -3131,6 +3358,7 @@ "resolved": "https://registry.npmjs.org/@types/chart.js/-/chart.js-2.9.41.tgz", "integrity": "sha512-3dvkDvueckY83UyUXtJMalYoH6faOLkWQoaTlJgB4Djde3oORmNP0Jw85HtzTuXyliUHcdp704s0mZFQKio/KQ==", "dev": true, + "license": "MIT", "dependencies": { "moment": "^2.10.2" } @@ -3140,6 +3368,7 @@ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -3149,16 +3378,18 @@ "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", "dev": true, + "license": "MIT", "dependencies": { "@types/express-serve-static-core": "*", "@types/node": "*" } }, "node_modules/@types/eslint": { - "version": "8.56.7", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.7.tgz", - "integrity": "sha512-SjDvI/x3zsZnOkYZ3lCt9lOZWZLB2jIlNKz+LBgCtDurK0JZcwucxYHn1w2BJkD34dgX9Tjnak0txtq4WTggEA==", + "version": "8.56.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", + "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -3169,6 +3400,7 @@ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "dev": true, + "license": "MIT", "dependencies": { "@types/eslint": "*", "@types/estree": "*" @@ -3178,13 +3410,15 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true + "dev": true, + "license": "MIT" }, "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, + "license": "MIT", "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -3193,10 +3427,11 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.43", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz", - "integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.1.tgz", + "integrity": "sha512-ej0phymbFLoCB26dbbq5PGScsf2JAJ4IJHjG10LalgUV36XKTmA4GdA+PVllKvRk0sEKt64X8975qFnkSi0hqA==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -3209,6 +3444,7 @@ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", "dev": true, + "license": "MIT", "dependencies": { "@types/minimatch": "*", "@types/node": "*" @@ -3218,13 +3454,15 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/@types/http-proxy": { "version": "1.17.14", "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -3233,13 +3471,15 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/istanbul-lib-report": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dev": true, + "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "*" } @@ -3249,6 +3489,7 @@ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/istanbul-lib-report": "*" } @@ -3257,25 +3498,29 @@ "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/minimatch": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { - "version": "20.12.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.3.tgz", - "integrity": "sha512-sD+ia2ubTeWrOu+YMF+MTAB7E+O7qsMqAbMfW7DG3K1URwhZ5hN1pLlRVGbf4wDFzSfikL05M17EyorS86jShw==", + "version": "20.12.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", + "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", "dev": true, + "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } @@ -3285,39 +3530,45 @@ "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/qs": { - "version": "6.9.14", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.14.tgz", - "integrity": "sha512-5khscbd3SwWMhFqylJBLQ0zIu7c1K6Vz0uBIt915BI3zV0q1nfjRQD3RqSBcPaO6PHEF4ov/t9y89fSiyThlPA==", - "dev": true + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", + "dev": true, + "license": "MIT" }, "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 + "dev": true, + "license": "MIT" }, "node_modules/@types/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/semver": { "version": "7.5.8", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/send": { "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", "dev": true, + "license": "MIT", "dependencies": { "@types/mime": "^1", "@types/node": "*" @@ -3328,6 +3579,7 @@ "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", "dev": true, + "license": "MIT", "dependencies": { "@types/express": "*" } @@ -3337,6 +3589,7 @@ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", "dev": true, + "license": "MIT", "dependencies": { "@types/http-errors": "*", "@types/node": "*", @@ -3348,21 +3601,24 @@ "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/webpack-env": { - "version": "1.18.4", - "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.18.4.tgz", - "integrity": "sha512-I6e+9+HtWADAWeeJWDFQtdk4EVSAbj6Rtz4q8fJ7mSr1M0jzlFcs8/HZ+Xb5SHzVm1dxH7aUiI+A8kA8Gcrm0A==", - "dev": true + "version": "1.18.5", + "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.18.5.tgz", + "integrity": "sha512-wz7kjjRRj8/Lty4B+Kr0LN6Ypc/3SymeCCGSbaXp2leH0ZVg/PriNiOwNj4bD4uphI7A8NXS4b6Gl373sfO5mA==", + "dev": true, + "license": "MIT" }, "node_modules/@types/ws": { "version": "8.5.10", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -3372,6 +3628,7 @@ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", "dev": true, + "license": "MIT", "dependencies": { "@types/yargs-parser": "*" } @@ -3380,13 +3637,15 @@ "version": "21.0.3", "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@typescript-eslint/scope-manager": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "6.21.0", "@typescript-eslint/visitor-keys": "6.21.0" @@ -3404,6 +3663,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", "dev": true, + "license": "MIT", "engines": { "node": "^16.0.0 || >=18.0.0" }, @@ -3417,6 +3677,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/types": "6.21.0", "@typescript-eslint/visitor-keys": "6.21.0", @@ -3440,79 +3701,12 @@ } } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -3520,17 +3714,12 @@ "node": ">=10" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/@typescript-eslint/utils": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", @@ -3551,26 +3740,12 @@ "eslint": "^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/utils/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -3578,17 +3753,12 @@ "node": ">=10" } }, - "node_modules/@typescript-eslint/utils/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/@typescript-eslint/visitor-keys": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "6.21.0", "eslint-visitor-keys": "^3.4.1" @@ -3605,17 +3775,19 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/@vitest/expect": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.4.0.tgz", - "integrity": "sha512-Jths0sWCJZ8BxjKe+p+eKsoqev1/T8lYcrjavEaz8auEJ4jAVY0GwW3JKmdVU4mmNPLPHixh4GNXP7GFtAiDHA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.0.tgz", + "integrity": "sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "@vitest/spy": "1.4.0", - "@vitest/utils": "1.4.0", + "@vitest/spy": "1.6.0", + "@vitest/utils": "1.6.0", "chai": "^4.3.10" }, "funding": { @@ -3623,13 +3795,14 @@ } }, "node_modules/@vitest/runner": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.4.0.tgz", - "integrity": "sha512-EDYVSmesqlQ4RD2VvWo3hQgTJ7ZrFQ2VSJdfiJiArkCerDAGeyF1i6dHkmySqk573jLp6d/cfqCN+7wUB5tLgg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.0.tgz", + "integrity": "sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "@vitest/utils": "1.4.0", + "@vitest/utils": "1.6.0", "p-limit": "^5.0.0", "pathe": "^1.1.1" }, @@ -3642,6 +3815,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "yocto-queue": "^1.0.0" @@ -3653,11 +3827,26 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@vitest/runner/node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@vitest/snapshot": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.4.0.tgz", - "integrity": "sha512-saAFnt5pPIA5qDGxOHxJ/XxhMFKkUSBJmVt5VgDsAqPTX6JP326r5C/c9UuCMPoXNzuudTPsYDZCoJ5ilpqG2A==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.0.tgz", + "integrity": "sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "magic-string": "^0.30.5", @@ -3669,10 +3858,11 @@ } }, "node_modules/@vitest/spy": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.4.0.tgz", - "integrity": "sha512-Ywau/Qs1DzM/8Uc+yA77CwSegizMlcgTJuYGAi0jujOteJOUf1ujunHThYo243KG9nAyWT3L9ifPYZ5+As/+6Q==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.0.tgz", + "integrity": "sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "tinyspy": "^2.2.0" @@ -3682,10 +3872,11 @@ } }, "node_modules/@vitest/utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.4.0.tgz", - "integrity": "sha512-mx3Yd1/6e2Vt/PUC98DcqTirtfxUyAZ32uK82r8rZzbtBeBo+nqgnjx/LvqQdWsrvNtm14VmurNgcf4nqY5gJg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.0.tgz", + "integrity": "sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "diff-sequences": "^29.6.3", @@ -3702,6 +3893,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6" @@ -3711,25 +3903,29 @@ "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-api-error": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-buffer": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -3740,13 +3936,15 @@ "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-buffer": "1.12.1", @@ -3759,6 +3957,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, + "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" } @@ -3768,6 +3967,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" } @@ -3776,13 +3976,15 @@ "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-buffer": "1.12.1", @@ -3799,6 +4001,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", @@ -3812,6 +4015,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-buffer": "1.12.1", @@ -3824,6 +4028,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-api-error": "1.11.6", @@ -3838,6 +4043,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.12.1", "@xtuc/long": "4.2.2" @@ -3848,6 +4054,7 @@ "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.15.0" }, @@ -3861,6 +4068,7 @@ "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.15.0" }, @@ -3874,6 +4082,7 @@ "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.15.0" }, @@ -3891,19 +4100,22 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true + "dev": 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==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, + "license": "MIT", "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -3917,6 +4129,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -3929,6 +4142,7 @@ "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^8" } @@ -3938,6 +4152,7 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -3947,6 +4162,7 @@ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=0.4.0" @@ -3957,6 +4173,7 @@ "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", "dev": true, + "license": "MIT", "dependencies": { "loader-utils": "^2.0.0", "regex-parser": "^2.2.11" @@ -3970,6 +4187,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -3986,6 +4204,7 @@ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^8.0.0" }, @@ -3999,15 +4218,16 @@ } }, "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.14.0.tgz", + "integrity": "sha512-oYs1UUtO97ZO2lJ4bwnWeQW8/zvOIQLGKcvPTsWmvc2SYgBb+upuNS5NxoLaMU4h8Ju3Nbj6Cq8mD2LQoqVKFA==", "dev": true, + "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "uri-js": "^4.4.1" }, "funding": { "type": "github", @@ -4018,13 +4238,15 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true, + "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" } @@ -4037,6 +4259,7 @@ "engines": [ "node >= 0.8.0" ], + "license": "Apache-2.0", "bin": { "ansi-html": "bin/ansi-html" } @@ -4046,6 +4269,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -4055,6 +4279,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -4067,6 +4292,7 @@ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -4075,28 +4301,41 @@ "node": ">= 8" } }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/argparse": { "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 + "dev": true, + "license": "Python-2.0" }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, - "dependencies": { - "array-uniq": "^1.0.1" - }, + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/array-uniq": { @@ -4104,6 +4343,7 @@ "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -4113,6 +4353,7 @@ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": "*" @@ -4123,6 +4364,7 @@ "resolved": "https://registry.npmjs.org/assets-webpack-plugin/-/assets-webpack-plugin-7.0.0.tgz", "integrity": "sha512-DMZ9r6HFxynWeONRMhSOFTvTrmit5dovdoUKdJgCG03M6CC7XiwNImPH+Ad1jaVrQ2n59e05lBhte52xPt4MSA==", "dev": true, + "license": "MIT", "dependencies": { "camelcase": "^6.0.0", "escape-string-regexp": "^4.0.0", @@ -4140,6 +4382,7 @@ "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", "dev": true, + "license": "MIT", "dependencies": { "find-cache-dir": "^4.0.0", "schema-utils": "^4.0.0" @@ -4153,15 +4396,16 @@ } }, "node_modules/babel-loader/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.14.0.tgz", + "integrity": "sha512-oYs1UUtO97ZO2lJ4bwnWeQW8/zvOIQLGKcvPTsWmvc2SYgBb+upuNS5NxoLaMU4h8Ju3Nbj6Cq8mD2LQoqVKFA==", "dev": true, + "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "uri-js": "^4.4.1" }, "funding": { "type": "github", @@ -4173,6 +4417,7 @@ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3" }, @@ -4184,13 +4429,15 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/babel-loader/node_modules/schema-utils": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -4206,13 +4453,14 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.10.tgz", - "integrity": "sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ==", + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.1", + "@babel/helper-define-polyfill-provider": "^0.6.2", "semver": "^6.3.1" }, "peerDependencies": { @@ -4224,6 +4472,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.1", "core-js-compat": "^3.36.1" @@ -4233,12 +4482,13 @@ } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.1.tgz", - "integrity": "sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.1" + "@babel/helper-define-polyfill-provider": "^0.6.2" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -4248,19 +4498,22 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/batch": { "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 + "dev": true, + "license": "MIT" }, "node_modules/big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", "dev": true, + "license": "MIT", "engines": { "node": "*" } @@ -4270,6 +4523,7 @@ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -4282,6 +4536,7 @@ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dev": true, + "license": "MIT", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -4306,6 +4561,7 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -4315,6 +4571,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -4323,13 +4580,15 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/bonjour-service": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "multicast-dns": "^7.2.5" @@ -4339,25 +4598,27 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -4382,6 +4643,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "caniuse-lite": "^1.0.30001587", "electron-to-chromium": "^1.4.668", @@ -4399,13 +4661,15 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -4415,6 +4679,7 @@ "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=8" @@ -4425,6 +4690,7 @@ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -4444,6 +4710,7 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -4453,6 +4720,7 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4465,6 +4733,7 @@ "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", "dev": true, + "license": "MIT", "dependencies": { "browserslist": "^4.0.0", "caniuse-lite": "^1.0.0", @@ -4473,9 +4742,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001605", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001605.tgz", - "integrity": "sha512-nXwGlFWo34uliI9z3n6Qc0wZaf7zaZWA1CPZ169La5mV3I/gem7bst0vr5XQH5TJXZIMfDeZyOrZnSlVzKxxHQ==", + "version": "1.0.30001624", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001624.tgz", + "integrity": "sha512-0dWnQG87UevOCPYaOR49CBcLBwoZLpws+k6W37nLjWUhumP1Isusj0p2u+3KhjNloRWK9OKMgjBBzPujQHw4nA==", "dev": true, "funding": [ { @@ -4490,13 +4759,15 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/chai": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "assertion-error": "^1.1.0", @@ -4516,6 +4787,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -4530,6 +4802,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } @@ -4538,13 +4811,15 @@ "version": "3.8.2", "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.8.2.tgz", "integrity": "sha512-7rqSlHWMUKFyBDOJvmFGW2lxULtcwaPLegDjX/Nu5j6QybY+GCiQkEY+6cqHw62S5tcwXMD8Y+H5OBGoR7d+ZQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/check-error": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "get-func-name": "^2.0.2" @@ -4558,6 +4833,7 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, + "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -4577,11 +4853,25 @@ "fsevents": "~2.3.2" } }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/chrome-trace-event": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0" } @@ -4597,6 +4887,7 @@ "url": "https://github.com/sponsors/sibiraj-s" } ], + "license": "MIT", "engines": { "node": ">=8" } @@ -4606,6 +4897,7 @@ "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-4.0.0.tgz", "integrity": "sha512-WuWE1nyTNAyW5T7oNyys2EN0cfP2fdRxhxnIQWiAp0bMabPdHhoGxM8A6YL2GhqwgrPnnaemVE7nv5XJ2Fhh2w==", "dev": true, + "license": "MIT", "dependencies": { "del": "^4.1.1" }, @@ -4621,6 +4913,7 @@ "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", "dev": true, + "license": "MIT", "dependencies": { "is-plain-object": "^2.0.4", "kind-of": "^6.0.2", @@ -4635,6 +4928,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "1.1.3" } @@ -4643,25 +4937,29 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/colord": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/colorette": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/commander": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10" } @@ -4670,13 +4968,15 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "dev": true, + "license": "MIT", "dependencies": { "mime-db": ">= 1.43.0 < 2" }, @@ -4689,6 +4989,7 @@ "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", "dev": true, + "license": "MIT", "dependencies": { "accepts": "~1.3.5", "bytes": "3.0.0", @@ -4707,6 +5008,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -4715,25 +5017,37 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/compression/node_modules/safe-buffer": { "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 + "dev": true, + "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/confbox": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz", + "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==", + "dev": true, + "license": "MIT", + "peer": true }, "node_modules/connect-history-api-fallback": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8" } @@ -4743,6 +5057,7 @@ "resolved": "https://registry.npmjs.org/consola/-/consola-3.2.3.tgz", "integrity": "sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==", "dev": true, + "license": "MIT", "engines": { "node": "^14.18.0 || >=16.10.0" } @@ -4752,6 +5067,7 @@ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" }, @@ -4764,6 +5080,7 @@ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -4772,13 +5089,15 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -4787,24 +5106,27 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/core-js": { - "version": "3.36.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.36.1.tgz", - "integrity": "sha512-BTvUrwxVBezj5SZ3f10ImnX2oRByMxql3EimVqMysepbC9EeMUOpLwdy6Eoili2x6E4kf+ZUB5k/+Jv55alPfA==", + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz", + "integrity": "sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" } }, "node_modules/core-js-compat": { - "version": "3.36.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.1.tgz", - "integrity": "sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==", + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", + "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", "dev": true, + "license": "MIT", "dependencies": { "browserslist": "^4.23.0" }, @@ -4817,13 +5139,15 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cross-fetch": { "version": "3.1.8", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", "dev": true, + "license": "MIT", "dependencies": { "node-fetch": "^2.6.12" } @@ -4833,6 +5157,7 @@ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -4847,6 +5172,7 @@ "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", "integrity": "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==", "dev": true, + "license": "ISC", "engines": { "node": "^14 || ^16 || >=18" }, @@ -4855,16 +5181,17 @@ } }, "node_modules/css-loader": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.10.0.tgz", - "integrity": "sha512-LTSA/jWbwdMlk+rhmElbDR2vbtQoTBPr7fkJE+mxrHj+7ru0hUmHafDRzWIjIHTwpitWVaqY2/UWGRca3yUgRw==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", + "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", "dev": true, + "license": "MIT", "dependencies": { "icss-utils": "^5.1.0", "postcss": "^8.4.33", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.4", - "postcss-modules-scope": "^3.1.1", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", "postcss-modules-values": "^4.0.0", "postcss-value-parser": "^4.2.0", "semver": "^7.5.4" @@ -4889,26 +5216,12 @@ } } }, - "node_modules/css-loader/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/css-loader/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -4916,17 +5229,12 @@ "node": ">=10" } }, - "node_modules/css-loader/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/css-minimizer-webpack-plugin": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz", "integrity": "sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.18", "cssnano": "^6.0.1", @@ -4967,15 +5275,16 @@ } }, "node_modules/css-minimizer-webpack-plugin/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.14.0.tgz", + "integrity": "sha512-oYs1UUtO97ZO2lJ4bwnWeQW8/zvOIQLGKcvPTsWmvc2SYgBb+upuNS5NxoLaMU4h8Ju3Nbj6Cq8mD2LQoqVKFA==", "dev": true, + "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "uri-js": "^4.4.1" }, "funding": { "type": "github", @@ -4987,6 +5296,7 @@ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3" }, @@ -4998,13 +5308,15 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/css-minimizer-webpack-plugin/node_modules/schema-utils": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -5024,6 +5336,7 @@ "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.0.1", @@ -5040,6 +5353,7 @@ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", "dev": true, + "license": "MIT", "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" @@ -5053,6 +5367,7 @@ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">= 6" }, @@ -5065,6 +5380,7 @@ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true, + "license": "MIT", "bin": { "cssesc": "bin/cssesc" }, @@ -5076,13 +5392,15 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/cssfontparser/-/cssfontparser-1.2.1.tgz", "integrity": "sha512-6tun4LoZnj7VN6YeegOVb67KBX/7JJsqvj+pv3ZA7F878/eN33AbGa5b/S/wXxS/tcp8nc40xRUrsPlxIyNUPg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cssnano": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", "dev": true, + "license": "MIT", "dependencies": { "cssnano-preset-default": "^6.1.2", "lilconfig": "^3.1.1" @@ -5103,6 +5421,7 @@ "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", "dev": true, + "license": "MIT", "dependencies": { "browserslist": "^4.23.0", "css-declaration-sorter": "^7.2.0", @@ -5147,6 +5466,7 @@ "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", "dev": true, + "license": "MIT", "engines": { "node": "^14 || ^16 || >=18.0" }, @@ -5159,6 +5479,7 @@ "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", "dev": true, + "license": "MIT", "dependencies": { "css-tree": "~2.2.0" }, @@ -5172,6 +5493,7 @@ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", "dev": true, + "license": "MIT", "dependencies": { "mdn-data": "2.0.28", "source-map-js": "^1.0.1" @@ -5185,13 +5507,15 @@ "version": "2.0.28", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", - "dev": true + "dev": true, + "license": "CC0-1.0" }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -5209,6 +5533,7 @@ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "type-detect": "^4.0.0" @@ -5221,13 +5546,15 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/default-gateway": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "execa": "^5.0.0" }, @@ -5240,6 +5567,7 @@ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -5257,6 +5585,7 @@ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5266,6 +5595,7 @@ "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/glob": "^7.1.1", "globby": "^6.1.0", @@ -5279,11 +5609,52 @@ "node": ">=6" } }, + "node_modules/del/node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del/node_modules/globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del/node_modules/globby/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -5293,6 +5664,7 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -5302,13 +5674,15 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/diff-sequences": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -5319,6 +5693,7 @@ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, + "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -5331,6 +5706,7 @@ "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", "dev": true, + "license": "MIT", "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" }, @@ -5343,6 +5719,7 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -5355,6 +5732,7 @@ "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", "dev": true, + "license": "MIT", "dependencies": { "utila": "~0.4" } @@ -5364,6 +5742,7 @@ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", "dev": true, + "license": "MIT", "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", @@ -5383,13 +5762,15 @@ "type": "github", "url": "https://github.com/sponsors/fb55" } - ] + ], + "license": "BSD-2-Clause" }, "node_modules/domhandler": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.2.0" }, @@ -5405,6 +5786,7 @@ "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", @@ -5418,25 +5800,29 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.4.724", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.724.tgz", - "integrity": "sha512-RTRvkmRkGhNBPPpdrgtDKvmOEYTrPlXDfc0J/Nfq5s29tEahAwhiX4mmhNzj6febWMleulxVYPh7QwCSL/EldA==", - "dev": true + "version": "1.4.783", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.783.tgz", + "integrity": "sha512-bT0jEz/Xz1fahQpbZ1D7LgmPYZ3iHVY39NcWWro1+hA2IvjiPeaXtfSqrQ+nXjApMvQRE2ASt1itSLRrebHMRQ==", + "dev": true, + "license": "ISC" }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/emojis-list": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } @@ -5446,15 +5832,17 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/enhanced-resolve": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz", - "integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==", + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.1.tgz", + "integrity": "sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -5468,15 +5856,17 @@ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", "dev": true, + "license": "BSD-2-Clause", "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/envinfo": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.1.tgz", - "integrity": "sha512-8PiZgZNIB4q/Lw4AhOvAfB/ityHAd2bli3lESSWmWSzSsl5dKpy5N1d1Rfkd2teq/g9xN90lc6o98DOjMeYHpg==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", + "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", "dev": true, + "license": "MIT", "bin": { "envinfo": "dist/cli.js" }, @@ -5489,6 +5879,7 @@ "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", "dev": true, + "license": "MIT", "dependencies": { "stackframe": "^1.3.4" } @@ -5498,6 +5889,7 @@ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", "dev": true, + "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.4" }, @@ -5510,15 +5902,17 @@ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/es-module-lexer": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.0.tgz", - "integrity": "sha512-pqrTKmwEIgafsYZAGw9kszYzmagcE/n4dbgwGWLEXg7J4QFJVQRBld8j3Q3GNez79jzxZshq0bcT962QHOghjw==", - "dev": true + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.3.tgz", + "integrity": "sha512-i1gCgmR9dCl6Vil6UKPI/trA69s08g/syhiDK9TG0Nf1RJjjFI+AzoWW7sPufzkgYAn861skuCwJa0pIIHYxvg==", + "dev": true, + "license": "MIT" }, "node_modules/esbuild": { "version": "0.20.2", @@ -5526,6 +5920,7 @@ "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", "dev": true, "hasInstallScript": true, + "license": "MIT", "peer": true, "bin": { "esbuild": "bin/esbuild" @@ -5564,6 +5959,7 @@ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -5572,13 +5968,15 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true + "dev": true, + "license": "MIT" }, "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, + "license": "MIT", "engines": { "node": ">=10" }, @@ -5591,6 +5989,7 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -5642,16 +6041,20 @@ } }, "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "estraverse": "^5.2.0" }, "engines": { - "node": ">=8.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-visitor-keys": { @@ -5659,6 +6062,7 @@ "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, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -5671,6 +6075,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -5681,11 +6086,23 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/eslint/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -5702,6 +6119,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -5713,146 +6131,46 @@ "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 + "dev": true, + "license": "MIT" }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "node_modules/eslint/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, + "license": "MIT", "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "type-fest": "^0.20.2" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=8" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/eslint/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, + "license": "MIT", "engines": { - "node": ">=4.0" + "node": ">=8" } }, - "node_modules/eslint/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/eslint/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, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/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, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" + "brace-expansion": "^1.1.7" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, "engines": { - "node": ">=8" + "node": "*" } }, "node_modules/eslint/node_modules/supports-color": { @@ -5860,6 +6178,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -5867,23 +6186,12 @@ "node": ">=8" } }, - "node_modules/eslint/node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -5901,6 +6209,7 @@ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -5908,20 +6217,12 @@ "node": ">=0.10" } }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -5929,20 +6230,12 @@ "node": ">=4.0" } }, - "node_modules/esrecurse/node_modules/estraverse": { + "node_modules/estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -5952,6 +6245,7 @@ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@types/estree": "^1.0.0" @@ -5962,6 +6256,7 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -5971,6 +6266,7 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -5979,13 +6275,15 @@ "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.x" } @@ -5995,6 +6293,7 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -6018,6 +6317,7 @@ "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dev": true, + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -6060,6 +6360,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -6068,19 +6369,22 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -6092,17 +6396,32 @@ "node": ">=8.6.0" } }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz", "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==", "dev": true, + "license": "MIT", "dependencies": { "fastest-levenshtein": "^1.0.7" } @@ -6112,6 +6431,7 @@ "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4.9.1" } @@ -6121,6 +6441,7 @@ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } @@ -6130,6 +6451,7 @@ "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", "dev": true, + "license": "Apache-2.0", "dependencies": { "websocket-driver": ">=0.5.1" }, @@ -6142,6 +6464,7 @@ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, + "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" }, @@ -6154,6 +6477,7 @@ "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", "dev": true, + "license": "MIT", "dependencies": { "loader-utils": "^2.0.0", "schema-utils": "^3.0.0" @@ -6170,10 +6494,11 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -6186,6 +6511,7 @@ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dev": true, + "license": "MIT", "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", @@ -6204,6 +6530,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -6212,13 +6539,15 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/find-cache-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", "dev": true, + "license": "MIT", "dependencies": { "common-path-prefix": "^3.0.0", "pkg-dir": "^7.0.0" @@ -6231,16 +6560,17 @@ } }, "node_modules/find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -6251,6 +6581,7 @@ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, + "license": "BSD-3-Clause", "bin": { "flat": "cli.js" } @@ -6260,6 +6591,7 @@ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, + "license": "MIT", "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", @@ -6273,7 +6605,9 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -6288,7 +6622,8 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/follow-redirects": { "version": "1.15.6", @@ -6301,6 +6636,7 @@ "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -6315,6 +6651,7 @@ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -6324,21 +6661,24 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/fs-monkey": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", - "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==", - "dev": true + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", + "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==", + "dev": true, + "license": "Unlicense" }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/fsevents": { "version": "2.3.3", @@ -6346,6 +6686,7 @@ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -6359,6 +6700,7 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -6368,6 +6710,7 @@ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -6377,6 +6720,7 @@ "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": "*" @@ -6387,6 +6731,7 @@ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", @@ -6406,6 +6751,7 @@ "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -6415,6 +6761,7 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -6426,13 +6773,16 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/glightbox/-/glightbox-3.3.0.tgz", "integrity": "sha512-SJukatHBZZ/POMOpLUQ6/dhXf/wJTDx1wZ/FwApjseXw2WrRj3Ze9DzNCFYzca0oU7RjXQhi9o02aIZ9SuCz1A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -6449,55 +6799,78 @@ } }, "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { - "is-glob": "^4.0.1" + "is-glob": "^4.0.3" }, "engines": { - "node": ">= 6" + "node": ">=10.13.0" } }, "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==", - "dev": true + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, + "license": "MIT", "dependencies": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/globby/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/gopd": { @@ -6505,6 +6878,7 @@ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, + "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -6516,31 +6890,36 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/growly": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", "integrity": "sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==", - "dev": true + "dev": true, + "license": "MIT" }, "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 + "dev": true, + "license": "MIT" }, "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -6550,6 +6929,7 @@ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" }, @@ -6562,6 +6942,7 @@ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -6574,6 +6955,7 @@ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -6586,6 +6968,7 @@ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -6598,6 +6981,7 @@ "resolved": "https://registry.npmjs.org/hotkeys-js/-/hotkeys-js-3.13.7.tgz", "integrity": "sha512-ygFIdTqqwG4fFP7kkiYlvayZppeIQX2aPpirsngkv1xM1lP0piDY5QEh68nQnIKvz64hfocxhBaD/uK3sSK1yQ==", "dev": true, + "license": "MIT", "peer": true, "funding": { "url": "https://jaywcjlove.github.io/#/sponsor" @@ -6608,6 +6992,7 @@ "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", "dev": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.1", "obuf": "^1.0.0", @@ -6620,6 +7005,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -6634,13 +7020,15 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/hpack.js/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, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -6659,7 +7047,8 @@ "type": "patreon", "url": "https://patreon.com/mdevils" } - ] + ], + "license": "MIT" }, "node_modules/htmlparser2": { "version": "6.1.0", @@ -6673,6 +7062,7 @@ "url": "https://github.com/sponsors/fb55" } ], + "license": "MIT", "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.0.0", @@ -6684,13 +7074,15 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", - "dev": true + "dev": true, + "license": "MIT" }, "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, + "license": "MIT", "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -6706,13 +7098,15 @@ "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 + "dev": true, + "license": "MIT" }, "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, + "license": "MIT", "dependencies": { "eventemitter3": "^4.0.0", "follow-redirects": "^1.0.0", @@ -6727,6 +7121,7 @@ "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", "dev": true, + "license": "MIT", "dependencies": { "@types/http-proxy": "^1.17.8", "http-proxy": "^1.18.1", @@ -6751,6 +7146,7 @@ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=10.17.0" } @@ -6760,6 +7156,7 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -6772,6 +7169,7 @@ "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", "dev": true, + "license": "ISC", "engines": { "node": "^10 || ^12 || >= 14" }, @@ -6784,21 +7182,24 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/immutable": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz", - "integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==", - "dev": true + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.6.tgz", + "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==", + "dev": true, + "license": "MIT" }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -6810,20 +7211,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, + "license": "MIT", "dependencies": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" @@ -6843,6 +7236,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -6856,6 +7250,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -6868,6 +7263,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -6883,6 +7279,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -6890,20 +7287,12 @@ "node": ">=8" } }, - "node_modules/import-local/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/import-local/node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, + "license": "MIT", "dependencies": { "find-up": "^4.0.0" }, @@ -6916,6 +7305,7 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } @@ -6924,7 +7314,9 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -6934,22 +7326,25 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/interpret": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.13.0" } }, "node_modules/ipaddr.js": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", - "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10" } @@ -6959,6 +7354,7 @@ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, + "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -6971,6 +7367,7 @@ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, + "license": "MIT", "dependencies": { "hasown": "^2.0.0" }, @@ -6983,6 +7380,7 @@ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "dev": true, + "license": "MIT", "bin": { "is-docker": "cli.js" }, @@ -6998,6 +7396,7 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -7007,6 +7406,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -7016,6 +7416,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -7028,6 +7429,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -7037,6 +7439,7 @@ "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -7046,6 +7449,7 @@ "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", "dev": true, + "license": "MIT", "dependencies": { "is-path-inside": "^2.1.0" }, @@ -7053,11 +7457,12 @@ "node": ">=6" } }, - "node_modules/is-path-inside": { + "node_modules/is-path-in-cwd/node_modules/is-path-inside": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", "dev": true, + "license": "MIT", "dependencies": { "path-is-inside": "^1.0.2" }, @@ -7065,11 +7470,22 @@ "node": ">=6" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-obj": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -7082,6 +7498,7 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, + "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -7094,6 +7511,7 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -7106,6 +7524,7 @@ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dev": true, + "license": "MIT", "dependencies": { "is-docker": "^2.0.0" }, @@ -7117,19 +7536,22 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -7139,6 +7561,7 @@ "resolved": "https://registry.npmjs.org/jest-canvas-mock/-/jest-canvas-mock-2.5.2.tgz", "integrity": "sha512-vgnpPupjOL6+L5oJXzxTxFrlGEIbHdZqFU+LFNdtLxZ3lRDCl17FlTMM7IatoRQkrcyOTMlDinjUguqmQ6bR2A==", "dev": true, + "license": "MIT", "dependencies": { "cssfontparser": "^1.2.1", "moo-color": "^1.0.2" @@ -7149,6 +7572,7 @@ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", @@ -7166,6 +7590,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -7181,6 +7606,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -7197,6 +7623,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -7208,22 +7635,38 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/jest-util/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, + "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/jest-util/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/jest-util/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -7236,6 +7679,7 @@ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "jest-util": "^29.7.0", @@ -7251,6 +7695,7 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -7260,6 +7705,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -7274,13 +7720,15 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -7293,6 +7741,7 @@ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, @@ -7304,31 +7753,36 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, + "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -7336,18 +7790,12 @@ "node": ">=6" } }, - "node_modules/jsonc-parser": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", - "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", - "dev": true, - "peer": true - }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, + "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } @@ -7357,6 +7805,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -7366,6 +7815,7 @@ "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", "dev": true, + "license": "MIT", "dependencies": { "picocolors": "^1.0.0", "shell-quote": "^1.8.1" @@ -7376,6 +7826,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -7389,6 +7840,7 @@ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=14" }, @@ -7401,6 +7853,7 @@ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.11.5" } @@ -7410,6 +7863,7 @@ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, + "license": "MIT", "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", @@ -7424,6 +7878,7 @@ "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "mlly": "^1.4.2", @@ -7437,15 +7892,16 @@ } }, "node_modules/locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { - "p-locate": "^6.0.0" + "p-locate": "^5.0.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -7455,37 +7911,43 @@ "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true + "dev": true, + "license": "MIT" }, "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 + "dev": true, + "license": "MIT" }, "node_modules/lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/loupe": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "get-func-name": "^2.0.1" @@ -7496,34 +7958,35 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^3.0.2" } }, "node_modules/magic-string": { - "version": "0.30.8", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", - "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" } }, "node_modules/mdn-data": { "version": "2.0.30", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", - "dev": true + "dev": true, + "license": "CC0-1.0" }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -7533,6 +7996,7 @@ "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", "dev": true, + "license": "Unlicense", "dependencies": { "fs-monkey": "^1.0.4" }, @@ -7544,19 +8008,22 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -7566,28 +8033,44 @@ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", "dev": true, + "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" } }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "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, + "license": "MIT", "bin": { "mime": "cli.js" }, @@ -7600,6 +8083,7 @@ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -7609,6 +8093,7 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -7621,15 +8106,17 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/mini-css-extract-plugin": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.8.1.tgz", - "integrity": "sha512-/1HDlyFRxWIZPI1ZpgqlZ8jMw/1Dp/dl3P0L1jtZ+zVcHqwPhGwaJwKL00WVgfnBy6PWCde9W65or7IIETImuA==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.0.tgz", + "integrity": "sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA==", "dev": true, + "license": "MIT", "dependencies": { "schema-utils": "^4.0.0", "tapable": "^2.2.1" @@ -7646,15 +8133,16 @@ } }, "node_modules/mini-css-extract-plugin/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.14.0.tgz", + "integrity": "sha512-oYs1UUtO97ZO2lJ4bwnWeQW8/zvOIQLGKcvPTsWmvc2SYgBb+upuNS5NxoLaMU4h8Ju3Nbj6Cq8mD2LQoqVKFA==", "dev": true, + "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "uri-js": "^4.4.1" }, "funding": { "type": "github", @@ -7666,6 +8154,7 @@ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3" }, @@ -7677,13 +8166,15 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -7702,31 +8193,37 @@ "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 + "dev": true, + "license": "ISC" }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, + "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/mlly": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.6.1.tgz", - "integrity": "sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.0.tgz", + "integrity": "sha512-U9SDaXGEREBYQgfejV97coK0UL1r+qnF2SyO9A3qcI8MzKnsIFKHNVEkrDyNncQTKQQumsasmeq84eNMdBfsNQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "acorn": "^8.11.3", "pathe": "^1.1.2", - "pkg-types": "^1.0.3", - "ufo": "^1.3.2" + "pkg-types": "^1.1.0", + "ufo": "^1.5.3" } }, "node_modules/moment": { @@ -7734,6 +8231,7 @@ "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", "dev": true, + "license": "MIT", "engines": { "node": "*" } @@ -7743,6 +8241,7 @@ "resolved": "https://registry.npmjs.org/moo-color/-/moo-color-1.0.3.tgz", "integrity": "sha512-i/+ZKXMDf6aqYtBhuOcej71YSlbjT3wCO/4H1j8rPvxDJEifdwgg5MaFyu6iYAT8GBZJg2z0dkgK4YMzvURALQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "^1.1.4" } @@ -7751,19 +8250,22 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/multicast-dns": { "version": "7.2.5", "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", "dev": true, + "license": "MIT", "dependencies": { "dns-packet": "^5.2.2", "thunky": "^1.0.2" @@ -7783,6 +8285,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -7794,13 +8297,15 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -7809,13 +8314,15 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dev": true, + "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -7836,6 +8343,7 @@ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", "dev": true, + "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { "node": ">= 6.13.0" } @@ -7845,6 +8353,7 @@ "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-9.0.1.tgz", "integrity": "sha512-fPNFIp2hF/Dq7qLDzSg4vZ0J4e9v60gJR+Qx7RbjbWqzPDdEqeVpEx5CFeDAELIl+A/woaaNn1fQ5nEVerMxJg==", "dev": true, + "license": "MIT", "dependencies": { "growly": "^1.3.0", "is-wsl": "^2.2.0", @@ -7854,26 +8363,12 @@ "which": "^2.0.2" } }, - "node_modules/node-notifier/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/node-notifier/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -7881,23 +8376,19 @@ "node": ">=10" } }, - "node_modules/node-notifier/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/node-releases": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -7907,6 +8398,7 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.0.0" }, @@ -7919,6 +8411,7 @@ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0" }, @@ -7931,6 +8424,7 @@ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -7940,6 +8434,7 @@ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -7948,13 +8443,15 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true + "dev": true, + "license": "MIT" }, "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, + "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, @@ -7967,6 +8464,7 @@ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -7976,6 +8474,7 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, + "license": "ISC", "dependencies": { "wrappy": "1" } @@ -7985,6 +8484,7 @@ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -8000,6 +8500,7 @@ "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, + "license": "MIT", "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", @@ -8013,17 +8514,18 @@ } }, "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" @@ -8033,33 +8535,36 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { - "yocto-queue": "^1.0.0" + "yocto-queue": "^0.1.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { - "p-limit": "^4.0.0" + "p-limit": "^3.0.2" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -8070,6 +8575,7 @@ "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -8079,6 +8585,7 @@ "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/retry": "0.12.0", "retry": "^0.13.1" @@ -8092,6 +8599,7 @@ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -8101,6 +8609,7 @@ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -8113,17 +8622,19 @@ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "license": "MIT", "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=8" } }, "node_modules/path-is-absolute": { @@ -8131,6 +8642,7 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8139,13 +8651,15 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", - "dev": true + "dev": true, + "license": "(WTFPL OR MIT)" }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -8154,19 +8668,22 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -8176,6 +8693,7 @@ "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/pathval": { @@ -8183,24 +8701,27 @@ "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": "*" } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8.6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" @@ -8211,6 +8732,7 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -8220,6 +8742,7 @@ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8229,6 +8752,7 @@ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", "dev": true, + "license": "MIT", "dependencies": { "pinkie": "^2.0.0" }, @@ -8241,6 +8765,7 @@ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", "dev": true, + "license": "MIT", "dependencies": { "find-up": "^6.3.0" }, @@ -8251,16 +8776,105 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/pkg-dir/node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/pkg-types": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz", - "integrity": "sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.1.tgz", + "integrity": "sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "jsonc-parser": "^3.2.0", - "mlly": "^1.2.0", - "pathe": "^1.1.0" + "confbox": "^0.1.7", + "mlly": "^1.7.0", + "pathe": "^1.1.2" } }, "node_modules/pkg-up": { @@ -8268,6 +8882,7 @@ "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", "dev": true, + "license": "MIT", "dependencies": { "find-up": "^3.0.0" }, @@ -8280,6 +8895,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^3.0.0" }, @@ -8292,6 +8908,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" @@ -8305,6 +8922,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -8320,6 +8938,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.0.0" }, @@ -8332,6 +8951,7 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -8355,6 +8975,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.0", @@ -8369,6 +8990,7 @@ "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", "dev": true, + "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.11", "postcss-value-parser": "^4.2.0" @@ -8385,6 +9007,7 @@ "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.1.0.tgz", "integrity": "sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==", "dev": true, + "license": "MIT", "dependencies": { "browserslist": "^4.23.0", "caniuse-api": "^3.0.0", @@ -8403,6 +9026,7 @@ "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz", "integrity": "sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==", "dev": true, + "license": "MIT", "dependencies": { "browserslist": "^4.23.0", "postcss-value-parser": "^4.2.0" @@ -8419,6 +9043,7 @@ "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz", "integrity": "sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==", "dev": true, + "license": "MIT", "engines": { "node": "^14 || ^16 || >=18.0" }, @@ -8431,6 +9056,7 @@ "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz", "integrity": "sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==", "dev": true, + "license": "MIT", "engines": { "node": "^14 || ^16 || >=18.0" }, @@ -8443,6 +9069,7 @@ "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz", "integrity": "sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==", "dev": true, + "license": "MIT", "engines": { "node": "^14 || ^16 || >=18.0" }, @@ -8455,6 +9082,7 @@ "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz", "integrity": "sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==", "dev": true, + "license": "MIT", "engines": { "node": "^14 || ^16 || >=18.0" }, @@ -8467,6 +9095,7 @@ "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz", "integrity": "sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==", "dev": true, + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0", "stylehacks": "^6.1.1" @@ -8483,6 +9112,7 @@ "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz", "integrity": "sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==", "dev": true, + "license": "MIT", "dependencies": { "browserslist": "^4.23.0", "caniuse-api": "^3.0.0", @@ -8501,6 +9131,7 @@ "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz", "integrity": "sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==", "dev": true, + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -8516,6 +9147,7 @@ "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz", "integrity": "sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==", "dev": true, + "license": "MIT", "dependencies": { "colord": "^2.9.3", "cssnano-utils": "^4.0.2", @@ -8533,6 +9165,7 @@ "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz", "integrity": "sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==", "dev": true, + "license": "MIT", "dependencies": { "browserslist": "^4.23.0", "cssnano-utils": "^4.0.2", @@ -8550,6 +9183,7 @@ "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz", "integrity": "sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==", "dev": true, + "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.16" }, @@ -8565,6 +9199,7 @@ "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", "dev": true, + "license": "ISC", "engines": { "node": "^10 || ^12 || >= 14" }, @@ -8577,6 +9212,7 @@ "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", "dev": true, + "license": "MIT", "dependencies": { "icss-utils": "^5.0.0", "postcss-selector-parser": "^6.0.2", @@ -8594,6 +9230,7 @@ "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", "dev": true, + "license": "ISC", "dependencies": { "postcss-selector-parser": "^6.0.4" }, @@ -8609,6 +9246,7 @@ "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", "dev": true, + "license": "ISC", "dependencies": { "icss-utils": "^5.0.0" }, @@ -8624,6 +9262,7 @@ "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz", "integrity": "sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==", "dev": true, + "license": "MIT", "engines": { "node": "^14 || ^16 || >=18.0" }, @@ -8636,6 +9275,7 @@ "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz", "integrity": "sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==", "dev": true, + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -8651,6 +9291,7 @@ "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz", "integrity": "sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==", "dev": true, + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -8666,6 +9307,7 @@ "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz", "integrity": "sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==", "dev": true, + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -8681,6 +9323,7 @@ "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz", "integrity": "sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==", "dev": true, + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -8696,6 +9339,7 @@ "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz", "integrity": "sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==", "dev": true, + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -8711,6 +9355,7 @@ "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz", "integrity": "sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==", "dev": true, + "license": "MIT", "dependencies": { "browserslist": "^4.23.0", "postcss-value-parser": "^4.2.0" @@ -8727,6 +9372,7 @@ "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz", "integrity": "sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==", "dev": true, + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -8742,6 +9388,7 @@ "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz", "integrity": "sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==", "dev": true, + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -8757,6 +9404,7 @@ "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz", "integrity": "sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==", "dev": true, + "license": "MIT", "dependencies": { "cssnano-utils": "^4.0.2", "postcss-value-parser": "^4.2.0" @@ -8773,6 +9421,7 @@ "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz", "integrity": "sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==", "dev": true, + "license": "MIT", "dependencies": { "browserslist": "^4.23.0", "caniuse-api": "^3.0.0" @@ -8789,6 +9438,7 @@ "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz", "integrity": "sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==", "dev": true, + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -8800,10 +9450,11 @@ } }, "node_modules/postcss-selector-parser": { - "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==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", + "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", "dev": true, + "license": "MIT", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -8817,6 +9468,7 @@ "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.3.tgz", "integrity": "sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==", "dev": true, + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0", "svgo": "^3.2.0" @@ -8833,6 +9485,7 @@ "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz", "integrity": "sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==", "dev": true, + "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.16" }, @@ -8847,13 +9500,15 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } @@ -8863,6 +9518,7 @@ "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", "dev": true, + "license": "MIT", "dependencies": { "lodash": "^4.17.20", "renderkid": "^3.0.0" @@ -8873,6 +9529,7 @@ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@jest/schemas": "^29.6.3", @@ -8888,6 +9545,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=10" @@ -8900,13 +9558,15 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dev": true, + "license": "MIT", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -8920,6 +9580,7 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -8929,6 +9590,7 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -8938,6 +9600,7 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.4" }, @@ -8966,13 +9629,15 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } @@ -8982,6 +9647,7 @@ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -8991,6 +9657,7 @@ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dev": true, + "license": "MIT", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -9006,15 +9673,17 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/readable-stream": { @@ -9022,6 +9691,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -9036,6 +9706,7 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, + "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -9043,11 +9714,25 @@ "node": ">=8.10.0" } }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/rechoir": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", "dev": true, + "license": "MIT", "dependencies": { "resolve": "^1.20.0" }, @@ -9059,13 +9744,15 @@ "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 + "dev": true, + "license": "MIT" }, "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, + "license": "MIT", "dependencies": { "regenerate": "^1.4.2" }, @@ -9077,13 +9764,15 @@ "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/regenerator-transform": { "version": "0.15.2", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/runtime": "^7.8.4" } @@ -9092,13 +9781,15 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.3.0.tgz", "integrity": "sha512-TVILVSz2jY5D47F4mA4MppkBrafEaiUWJO/TcZHEIuI13AqoZMkK1WMA4Om1YkYbTx+9Ki1/tSUXbceyr9saRg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/regexpu-core": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", @@ -9116,6 +9807,7 @@ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "jsesc": "~0.5.0" }, @@ -9137,6 +9829,7 @@ "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", "dev": true, + "license": "MIT", "dependencies": { "css-select": "^4.1.3", "dom-converter": "^0.2.0", @@ -9150,6 +9843,7 @@ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -9158,19 +9852,22 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/resize-observer-polyfill": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, + "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -9188,6 +9885,7 @@ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, + "license": "MIT", "dependencies": { "resolve-from": "^5.0.0" }, @@ -9195,20 +9893,32 @@ "node": ">=8" } }, - "node_modules/resolve-from": { + "node_modules/resolve-cwd/node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/resolve-url-loader": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz", "integrity": "sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==", "dev": true, + "license": "MIT", "dependencies": { "adjust-sourcemap-loader": "^4.0.0", "convert-source-map": "^1.7.0", @@ -9224,13 +9934,15 @@ "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/retry": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } @@ -9240,6 +9952,7 @@ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -9249,7 +9962,9 @@ "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -9258,10 +9973,11 @@ } }, "node_modules/rollup": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.0.tgz", - "integrity": "sha512-Qe7w62TyawbDzB4yt32R0+AbIo6m1/sqO7UPzFS8Z/ksL5mrfhA0v4CavfdmFav3D+ub4QeAgsGEe84DoWe/nQ==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", + "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@types/estree": "1.0.5" @@ -9274,21 +9990,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.14.0", - "@rollup/rollup-android-arm64": "4.14.0", - "@rollup/rollup-darwin-arm64": "4.14.0", - "@rollup/rollup-darwin-x64": "4.14.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.14.0", - "@rollup/rollup-linux-arm64-gnu": "4.14.0", - "@rollup/rollup-linux-arm64-musl": "4.14.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.14.0", - "@rollup/rollup-linux-riscv64-gnu": "4.14.0", - "@rollup/rollup-linux-s390x-gnu": "4.14.0", - "@rollup/rollup-linux-x64-gnu": "4.14.0", - "@rollup/rollup-linux-x64-musl": "4.14.0", - "@rollup/rollup-win32-arm64-msvc": "4.14.0", - "@rollup/rollup-win32-ia32-msvc": "4.14.0", - "@rollup/rollup-win32-x64-msvc": "4.14.0", + "@rollup/rollup-android-arm-eabi": "4.18.0", + "@rollup/rollup-android-arm64": "4.18.0", + "@rollup/rollup-darwin-arm64": "4.18.0", + "@rollup/rollup-darwin-x64": "4.18.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", + "@rollup/rollup-linux-arm-musleabihf": "4.18.0", + "@rollup/rollup-linux-arm64-gnu": "4.18.0", + "@rollup/rollup-linux-arm64-musl": "4.18.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", + "@rollup/rollup-linux-riscv64-gnu": "4.18.0", + "@rollup/rollup-linux-s390x-gnu": "4.18.0", + "@rollup/rollup-linux-x64-gnu": "4.18.0", + "@rollup/rollup-linux-x64-musl": "4.18.0", + "@rollup/rollup-win32-arm64-msvc": "4.18.0", + "@rollup/rollup-win32-ia32-msvc": "4.18.0", + "@rollup/rollup-win32-x64-msvc": "4.18.0", "fsevents": "~2.3.2" } }, @@ -9311,6 +10028,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } @@ -9333,19 +10051,22 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/sass": { - "version": "1.72.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.72.0.tgz", - "integrity": "sha512-Gpczt3WA56Ly0Mn8Sl21Vj94s1axi9hDIzDFn9Ph9x3C3p4nNyvsqJoQyVXKou6cBlfFWEgRW4rT8Tb4i3XnVA==", + "version": "1.77.2", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.2.tgz", + "integrity": "sha512-eb4GZt1C3avsX3heBNlrc7I09nyT00IUuo4eFhAbeXWU2fvA7oXI53SxODVAA+zgZCk9aunAZgO+losjR3fAwA==", "dev": true, + "license": "MIT", "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -9363,6 +10084,7 @@ "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.3.3.tgz", "integrity": "sha512-mt5YN2F1MOZr3d/wBRcZxeFgwgkH44wVc2zohO2YF6JiOMkiXe4BYRZpSu2sO1g71mo/j16txzUhsKZlqjVGzA==", "dev": true, + "license": "MIT", "dependencies": { "neo-async": "^2.6.2" }, @@ -9400,6 +10122,7 @@ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -9417,13 +10140,15 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/selfsigned": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", "dev": true, + "license": "MIT", "dependencies": { "@types/node-forge": "^1.3.0", "node-forge": "^1" @@ -9437,6 +10162,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -9446,6 +10172,7 @@ "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "dev": true, + "license": "MIT", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -9470,6 +10197,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -9478,19 +10206,22 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/send/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } @@ -9500,6 +10231,7 @@ "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", "dev": true, + "license": "MIT", "dependencies": { "accepts": "~1.3.4", "batch": "0.6.1", @@ -9518,6 +10250,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -9527,6 +10260,7 @@ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -9536,6 +10270,7 @@ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", "dev": true, + "license": "MIT", "dependencies": { "depd": "~1.1.2", "inherits": "2.0.3", @@ -9550,25 +10285,29 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true + "dev": true, + "license": "ISC" }, "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 + "dev": true, + "license": "MIT" }, "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 + "dev": true, + "license": "ISC" }, "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, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -9578,6 +10317,7 @@ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "dev": true, + "license": "MIT", "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -9593,6 +10333,7 @@ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, + "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -9609,13 +10350,15 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", "dev": true, + "license": "MIT", "dependencies": { "kind-of": "^6.0.2" }, @@ -9628,6 +10371,7 @@ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -9640,6 +10384,7 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -9649,6 +10394,7 @@ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -9657,13 +10403,15 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/side-channel": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -9682,19 +10430,22 @@ "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true, + "license": "ISC", "peer": true }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/simple-icons-font": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/simple-icons-font/-/simple-icons-font-11.12.0.tgz", - "integrity": "sha512-JFdVtHwh5513JklPWwCvFp0EpwOPRhQNUy9/Eaudgfhf0FD6CqN26EvFGiS24WCE2dEG28ZwUpliiZK5QID2gQ==", + "version": "11.15.0", + "resolved": "https://registry.npmjs.org/simple-icons-font/-/simple-icons-font-11.15.0.tgz", + "integrity": "sha512-pNq0z1n2ySIa57j+kTBxYQsC1kW1xeywnsEN5a5sbjKJAoKlwUJM9umrCnDhuzrpHrtAujYDJw3/TEeAFHdwrQ==", "dev": true, + "license": "CC0-1.0", "funding": { "type": "opencollective", "url": "https://opencollective.com/simple-icons" @@ -9705,6 +10456,7 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -9714,6 +10466,7 @@ "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", "dev": true, + "license": "MIT", "dependencies": { "faye-websocket": "^0.11.3", "uuid": "^8.3.2", @@ -9725,6 +10478,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -9734,6 +10488,7 @@ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -9743,6 +10498,7 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -9753,6 +10509,7 @@ "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.1.0", "handle-thing": "^2.0.0", @@ -9769,6 +10526,7 @@ "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.1.0", "detect-node": "^2.0.4", @@ -9783,19 +10541,22 @@ "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/stackframe": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -9805,6 +10566,7 @@ "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/stimulus-textarea-autogrow": { @@ -9812,6 +10574,7 @@ "resolved": "https://registry.npmjs.org/stimulus-textarea-autogrow/-/stimulus-textarea-autogrow-4.1.0.tgz", "integrity": "sha512-hYz+xN3VZiO+eLl+zok4yvhH+mW5WkvOJEExyVP3J97dWQzc/qPDFdAM1EDJvfUIuRzJVq/WJynqqQwiied5iw==", "dev": true, + "license": "MIT", "peerDependencies": { "@hotwired/stimulus": "^3.2.1" } @@ -9821,6 +10584,7 @@ "resolved": "https://registry.npmjs.org/stimulus-use/-/stimulus-use-0.52.2.tgz", "integrity": "sha512-413+tIw9n6Jnb0OFiQE1i3aP01i0hhGgAnPp1P6cNuBbhhqG2IOp8t1O/4s5Tw2lTvSYrFeLNdaY8sYlDaULeg==", "dev": true, + "license": "MIT", "peerDependencies": { "@hotwired/stimulus": ">= 3", "hotkeys-js": ">= 3" @@ -9831,6 +10595,7 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } @@ -9840,6 +10605,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -9854,6 +10620,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -9866,6 +10633,7 @@ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -9875,6 +10643,7 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -9887,6 +10656,7 @@ "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.0.tgz", "integrity": "sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "js-tokens": "^9.0.0" @@ -9900,6 +10670,7 @@ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz", "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/style-loader": { @@ -9907,6 +10678,7 @@ "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 12.13.0" }, @@ -9923,6 +10695,7 @@ "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.1.1.tgz", "integrity": "sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==", "dev": true, + "license": "MIT", "dependencies": { "browserslist": "^4.23.0", "postcss-selector-parser": "^6.0.16" @@ -9939,6 +10712,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -9951,6 +10725,7 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -9959,10 +10734,11 @@ } }, "node_modules/svgo": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.2.0.tgz", - "integrity": "sha512-4PP6CMW/V7l/GmKRKzsLR8xxjdHTV4IMvhTnpuHwwBazSIlw5W/5SmPjN8Dwyt7lKbSJrRDgp4t9ph0HgChFBQ==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", + "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", "dev": true, + "license": "MIT", "dependencies": { "@trysound/sax": "0.2.0", "commander": "^7.2.0", @@ -9988,6 +10764,7 @@ "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", @@ -10004,6 +10781,7 @@ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dev": true, + "license": "MIT", "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", @@ -10018,6 +10796,7 @@ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.3.0" }, @@ -10033,6 +10812,7 @@ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", @@ -10047,6 +10827,7 @@ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.12" }, @@ -10059,6 +10840,7 @@ "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", "dev": true, + "license": "MIT", "dependencies": { "get-port": "^3.1.0" } @@ -10068,15 +10850,17 @@ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/terser": { - "version": "5.30.3", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.30.3.tgz", - "integrity": "sha512-STdUgOUx8rLbMGO9IOwHLpCqolkDITFFQSMYYwKE1N2lY6MVSaeoi10z/EhWxRc6ybqoVmKSkhKYH/XUpl7vSA==", + "version": "5.31.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.0.tgz", + "integrity": "sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -10095,6 +10879,7 @@ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", @@ -10129,6 +10914,7 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -10138,6 +10924,7 @@ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -10152,6 +10939,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -10166,38 +10954,44 @@ "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==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/thunky": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/timeago.js": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/timeago.js/-/timeago.js-4.0.2.tgz", "integrity": "sha512-a7wPxPdVlQL7lqvitHGGRsofhdwtkoSXPGATFuSOA2i1ZNQEPLrGnj68vOp2sOJTCFAQVXPeNMX/GctBaO9L2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/tinybench": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.6.0.tgz", - "integrity": "sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", + "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/tinypool": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.3.tgz", - "integrity": "sha512-Ud7uepAklqRH1bvwy22ynrliC7Dljz7Tm8M/0RBUW+YRa4YHhZ6e4PpgE+fu1zr/WqB1kbeuVrdfeuyIBpy4tw==", + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz", + "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=14.0.0" @@ -10208,6 +11002,7 @@ "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=14.0.0" @@ -10218,6 +11013,7 @@ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.14" } @@ -10227,6 +11023,7 @@ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -10236,6 +11033,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -10248,6 +11046,7 @@ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.6" } @@ -10257,6 +11056,7 @@ "resolved": "https://registry.npmjs.org/tom-select/-/tom-select-2.3.1.tgz", "integrity": "sha512-QS4vnOcB6StNGqX4sGboGXL2fkhBF2gIBB+8Hwv30FZXYPn0CyYO8kkdATRvwfCTThxiR4WcXwKJZ3cOmtI9eg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@orchidjs/sifter": "^1.0.3", "@orchidjs/unicode-variants": "^1.0.4" @@ -10273,13 +11073,15 @@ "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/ts-api-utils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=16" }, @@ -10292,6 +11094,7 @@ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -10304,6 +11107,7 @@ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=4" @@ -10314,6 +11118,7 @@ "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, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -10326,6 +11131,7 @@ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dev": true, + "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -10335,10 +11141,11 @@ } }, "node_modules/typescript": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz", - "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "dev": true, + "license": "Apache-2.0", "peer": true, "bin": { "tsc": "bin/tsc", @@ -10353,19 +11160,22 @@ "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "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, + "license": "MIT", "engines": { "node": ">=4" } @@ -10375,6 +11185,7 @@ "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "dev": true, + "license": "MIT", "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" @@ -10388,6 +11199,7 @@ "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, + "license": "MIT", "engines": { "node": ">=4" } @@ -10397,6 +11209,7 @@ "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, + "license": "MIT", "engines": { "node": ">=4" } @@ -10406,14 +11219,15 @@ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", + "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", "dev": true, "funding": [ { @@ -10429,9 +11243,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -10445,6 +11260,7 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -10453,19 +11269,22 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/utila": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4.0" } @@ -10475,6 +11294,7 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true, + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } @@ -10484,15 +11304,17 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/vite": { - "version": "5.2.8", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.8.tgz", - "integrity": "sha512-OyZR+c1CE8yeHw5V5t59aXsUPPVTHMDjEZz8MgguLL/Q7NblxhZUlTu9xSPqlsUO/y+X7dlU05jdhvyycD55DA==", + "version": "5.2.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz", + "integrity": "sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "esbuild": "^0.20.1", @@ -10545,10 +11367,11 @@ } }, "node_modules/vite-node": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.4.0.tgz", - "integrity": "sha512-VZDAseqjrHgNd4Kh8icYHWzTKSCZMhia7GyHfhtzLW33fZlG9SwsB6CEhgyVOWkJfJ2pFLrp/Gj1FSfAiqH9Lw==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.0.tgz", + "integrity": "sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "cac": "^6.7.14", @@ -10568,17 +11391,18 @@ } }, "node_modules/vitest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.4.0.tgz", - "integrity": "sha512-gujzn0g7fmwf83/WzrDTnncZt2UiXP41mHuFYFrdwaLRVQ6JYQEiME2IfEjU3vcFL3VKa75XhI3lFgn+hfVsQw==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.0.tgz", + "integrity": "sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "@vitest/expect": "1.4.0", - "@vitest/runner": "1.4.0", - "@vitest/snapshot": "1.4.0", - "@vitest/spy": "1.4.0", - "@vitest/utils": "1.4.0", + "@vitest/expect": "1.6.0", + "@vitest/runner": "1.6.0", + "@vitest/snapshot": "1.6.0", + "@vitest/spy": "1.6.0", + "@vitest/utils": "1.6.0", "acorn-walk": "^8.3.2", "chai": "^4.3.10", "debug": "^4.3.4", @@ -10590,9 +11414,9 @@ "std-env": "^3.5.0", "strip-literal": "^2.0.0", "tinybench": "^2.5.1", - "tinypool": "^0.8.2", + "tinypool": "^0.8.3", "vite": "^5.0.0", - "vite-node": "1.4.0", + "vite-node": "1.6.0", "why-is-node-running": "^2.2.2" }, "bin": { @@ -10607,8 +11431,8 @@ "peerDependencies": { "@edge-runtime/vm": "*", "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "1.4.0", - "@vitest/ui": "1.4.0", + "@vitest/browser": "1.6.0", + "@vitest/ui": "1.6.0", "happy-dom": "*", "jsdom": "*" }, @@ -10638,6 +11462,7 @@ "resolved": "https://registry.npmjs.org/vitest-canvas-mock/-/vitest-canvas-mock-0.3.3.tgz", "integrity": "sha512-3P968tYBpqYyzzOaVtqnmYjqbe13576/fkjbDEJSfQAkHtC5/UjuRHOhFEN/ZV5HVZIkaROBUWgazDKJ+Ibw+Q==", "dev": true, + "license": "MIT", "dependencies": { "jest-canvas-mock": "~2.5.2" }, @@ -10650,6 +11475,7 @@ "resolved": "https://registry.npmjs.org/vitest-fetch-mock/-/vitest-fetch-mock-0.2.2.tgz", "integrity": "sha512-XmH6QgTSjCWrqXoPREIdbj40T7i1xnGmAsTAgfckoO75W1IEHKR8hcPCQ7SO16RsdW1t85oUm6pcQRLeBgjVYQ==", "dev": true, + "license": "MIT", "dependencies": { "cross-fetch": "^3.0.6" }, @@ -10665,6 +11491,7 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "cross-spawn": "^7.0.3", @@ -10689,6 +11516,7 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=16" @@ -10702,6 +11530,7 @@ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true, + "license": "Apache-2.0", "peer": true, "engines": { "node": ">=16.17.0" @@ -10712,6 +11541,7 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" @@ -10725,6 +11555,7 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=12" @@ -10738,6 +11569,7 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "path-key": "^4.0.0" @@ -10754,6 +11586,7 @@ "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "mimic-fn": "^4.0.0" @@ -10770,6 +11603,7 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=12" @@ -10783,6 +11617,7 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, + "license": "ISC", "peer": true, "engines": { "node": ">=14" @@ -10796,6 +11631,7 @@ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=12" @@ -10809,6 +11645,7 @@ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", "dev": true, + "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -10822,6 +11659,7 @@ "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", "dev": true, + "license": "MIT", "dependencies": { "minimalistic-assert": "^1.0.0" } @@ -10830,13 +11668,15 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true + "dev": true, + "license": "BSD-2-Clause" }, "node_modules/webpack": { "version": "5.91.0", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz", "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==", "dev": true, + "license": "MIT", "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", @@ -10884,6 +11724,7 @@ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dev": true, + "license": "MIT", "dependencies": { "@discoveryjs/json-ext": "^0.5.0", "@webpack-cli/configtest": "^2.1.1", @@ -10929,6 +11770,7 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", "dev": true, + "license": "MIT", "engines": { "node": ">=14" } @@ -10938,6 +11780,7 @@ "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", "dev": true, + "license": "MIT", "dependencies": { "colorette": "^2.0.10", "memfs": "^3.4.3", @@ -10957,15 +11800,16 @@ } }, "node_modules/webpack-dev-middleware/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.14.0.tgz", + "integrity": "sha512-oYs1UUtO97ZO2lJ4bwnWeQW8/zvOIQLGKcvPTsWmvc2SYgBb+upuNS5NxoLaMU4h8Ju3Nbj6Cq8mD2LQoqVKFA==", "dev": true, + "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "uri-js": "^4.4.1" }, "funding": { "type": "github", @@ -10977,6 +11821,7 @@ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3" }, @@ -10988,13 +11833,15 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/webpack-dev-middleware/node_modules/schema-utils": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -11014,6 +11861,7 @@ "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", "dev": true, + "license": "MIT", "dependencies": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", @@ -11069,15 +11917,16 @@ } }, "node_modules/webpack-dev-server/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.14.0.tgz", + "integrity": "sha512-oYs1UUtO97ZO2lJ4bwnWeQW8/zvOIQLGKcvPTsWmvc2SYgBb+upuNS5NxoLaMU4h8Ju3Nbj6Cq8mD2LQoqVKFA==", "dev": true, + "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "uri-js": "^4.4.1" }, "funding": { "type": "github", @@ -11089,6 +11938,7 @@ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3" }, @@ -11100,13 +11950,16 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/webpack-dev-server/node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -11122,6 +11975,7 @@ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -11141,6 +11995,7 @@ "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", "dev": true, + "license": "MIT", "dependencies": { "clone-deep": "^4.0.1", "flat": "^5.0.2", @@ -11155,6 +12010,7 @@ "resolved": "https://registry.npmjs.org/webpack-notifier/-/webpack-notifier-1.15.0.tgz", "integrity": "sha512-N2V8UMgRB5komdXQRavBsRpw0hPhJq2/SWNOGuhrXpIgRhcMexzkGQysUyGStHLV5hkUlgpRiF7IUXoBqyMmzQ==", "dev": true, + "license": "ISC", "dependencies": { "node-notifier": "^9.0.0", "strip-ansi": "^6.0.0" @@ -11173,15 +12029,41 @@ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.13.0" } }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, "node_modules/websocket-driver": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", @@ -11196,6 +12078,7 @@ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=0.8.0" } @@ -11205,6 +12088,7 @@ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dev": true, + "license": "MIT", "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -11215,6 +12099,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -11230,6 +12115,7 @@ "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "siginfo": "^2.0.0", @@ -11246,19 +12132,32 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/ws": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", - "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz", + "integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -11279,31 +12178,33 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } }, "node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { - "node": ">=12.20" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "vendor/symfony/stimulus-bundle/assets": { - "name": "@symfony/stimulus-bundle", "version": "1.0.0", "dev": true, "license": "MIT", @@ -11313,7 +12214,6 @@ } }, "vendor/symfony/ux-autocomplete/assets": { - "name": "@symfony/ux-autocomplete", "version": "1.0.0", "dev": true, "license": "MIT", @@ -11328,7 +12228,6 @@ } }, "vendor/symfony/ux-chartjs/assets": { - "name": "@symfony/ux-chartjs", "version": "1.1.0", "dev": true, "license": "MIT", diff --git a/symfony.lock b/symfony.lock index 217fd2a71..c1d724d62 100644 --- a/symfony.lock +++ b/symfony.lock @@ -64,7 +64,7 @@ "repo": "github.com/symfony/recipes", "branch": "main", "version": "2.12", - "ref": "32f890075233ac4a1176e848a0f8e932ac6536d6" + "ref": "7b1b0b637b337f6beb895589948cd119da705524" }, "files": [ "config/packages/doctrine.yaml", From 85a90832e2ee6a2315288d0814f0ca8e21bc169d Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Fri, 31 May 2024 11:24:06 +0000 Subject: [PATCH 020/335] Fix/outgoing deletes (#795) Co-authored-by: debounced <35878315+nobodyatroot@users.noreply.github.com> --- migrations/Version20240529115400.php | 25 +++++++++++ .../Magazine/MagazineModeratorsController.php | 4 +- src/Entity/Magazine.php | 11 +++-- .../Entry/EntryBeforeDeleteSubscriber.php | 41 ------------------- .../Entry/EntryDeleteSubscriber.php | 26 ++++++++---- .../EntryCommentBeforeDeleteSubscriber.php | 41 ------------------- .../EntryCommentDeleteSubscriber.php | 31 +++++++++----- .../Post/PostBeforeDeleteSubscriber.php | 41 ------------------- .../Post/PostDeleteSubscriber.php | 26 ++++++++---- .../PostCommentBeforeDeleteSubscriber.php | 41 ------------------- .../PostCommentDeleteSubscriber.php | 31 +++++++++----- src/Factory/MagazineFactory.php | 2 +- .../ActivityPub/Inbox/RemoveHandler.php | 21 ++++++---- src/Repository/MagazineRepository.php | 8 ++-- .../ActivityPub/Wrapper/DeleteWrapper.php | 38 ++++++++++++++++- src/Service/ActivityPubManager.php | 6 +-- src/Service/EntryCommentManager.php | 6 ++- src/Service/EntryManager.php | 4 +- src/Service/MagazineManager.php | 2 +- src/Service/PostCommentManager.php | 6 ++- src/Service/PostManager.php | 4 +- .../magazine/_moderators_sidebar.html.twig | 26 ++++++------ 22 files changed, 191 insertions(+), 250 deletions(-) create mode 100644 migrations/Version20240529115400.php delete mode 100644 src/EventSubscriber/Entry/EntryBeforeDeleteSubscriber.php delete mode 100644 src/EventSubscriber/EntryComment/EntryCommentBeforeDeleteSubscriber.php delete mode 100644 src/EventSubscriber/Post/PostBeforeDeleteSubscriber.php delete mode 100644 src/EventSubscriber/PostComment/PostCommentBeforeDeleteSubscriber.php diff --git a/migrations/Version20240529115400.php b/migrations/Version20240529115400.php new file mode 100644 index 000000000..d397ebf1b --- /dev/null +++ b/migrations/Version20240529115400.php @@ -0,0 +1,25 @@ +addSql('DELETE FROM moderator mod WHERE mod.is_owner = true AND EXISTS (SELECT * FROM magazine m WHERE mod.magazine_id = m.id AND m.ap_id IS NOT NULL);'); + } + + public function down(Schema $schema): void + { + } +} diff --git a/src/Controller/ActivityPub/Magazine/MagazineModeratorsController.php b/src/Controller/ActivityPub/Magazine/MagazineModeratorsController.php index 849ca3a26..4d90548e2 100644 --- a/src/Controller/ActivityPub/Magazine/MagazineModeratorsController.php +++ b/src/Controller/ActivityPub/Magazine/MagazineModeratorsController.php @@ -33,7 +33,7 @@ public function __invoke(Magazine $magazine, Request $request): JsonResponse } #[ArrayShape([ - '@context' => 'string', + '@context' => 'array', 'type' => 'string', 'id' => 'string', 'totalItems' => 'int', @@ -50,7 +50,7 @@ private function getCollectionItems(Magazine $magazine): array } return [ - '@context' => ActivityPubActivityInterface::CONTEXT_URL, + '@context' => [ActivityPubActivityInterface::CONTEXT_URL], 'type' => 'OrderedCollection', 'id' => $this->urlGenerator->generate('ap_magazine_moderators', ['name' => $magazine->name], UrlGeneratorInterface::ABSOLUTE_URL), 'totalItems' => \sizeof($items), diff --git a/src/Entity/Magazine.php b/src/Entity/Magazine.php index 0cfebddb3..ef4d742d9 100644 --- a/src/Entity/Magazine.php +++ b/src/Entity/Magazine.php @@ -110,7 +110,7 @@ class Magazine implements VisibilityInterface, ActivityPubActorInterface, ApiRes public function __construct( string $name, string $title, - User $user, + ?User $user, ?string $description, ?string $rules, bool $isAdult, @@ -131,7 +131,9 @@ public function __construct( $this->badges = new ArrayCollection(); $this->logs = new ArrayCollection(); - $this->addModerator(new Moderator($this, $user, null, true, true)); + if (null !== $user) { + $this->addModerator(new Moderator($this, $user, null, true, true)); + } $this->createdAtTraitConstruct(); } @@ -233,10 +235,7 @@ public function getOwner(): ?User public function getModeratorCount(): int { - $criteria = Criteria::create() - ->where(Criteria::expr()->eq('isOwner', false)); - - return $this->moderators->matching($criteria)->count(); + return $this->moderators->count(); } public function addEntry(Entry $entry): self diff --git a/src/EventSubscriber/Entry/EntryBeforeDeleteSubscriber.php b/src/EventSubscriber/Entry/EntryBeforeDeleteSubscriber.php deleted file mode 100644 index 763aa7850..000000000 --- a/src/EventSubscriber/Entry/EntryBeforeDeleteSubscriber.php +++ /dev/null @@ -1,41 +0,0 @@ - 'onEntryBeforeDeleted', - ]; - } - - public function onEntryBeforeDeleted(EntryBeforeDeletedEvent $event): void - { - if (!$event->entry->apId) { - $this->bus->dispatch( - new DeleteMessage( - $this->deleteWrapper->build($event->entry, Uuid::v4()->toRfc4122()), - $event->entry->user->getId(), - $event->entry->magazine->getId() - ) - ); - } - } -} diff --git a/src/EventSubscriber/Entry/EntryDeleteSubscriber.php b/src/EventSubscriber/Entry/EntryDeleteSubscriber.php index 83ccce928..0c9a3836f 100644 --- a/src/EventSubscriber/Entry/EntryDeleteSubscriber.php +++ b/src/EventSubscriber/Entry/EntryDeleteSubscriber.php @@ -4,6 +4,9 @@ namespace App\EventSubscriber\Entry; +use App\Entity\Entry; +use App\Entity\User; +use App\Event\Entry\EntryBeforeDeletedEvent; use App\Event\Entry\EntryBeforePurgeEvent; use App\Event\Entry\EntryDeletedEvent; use App\Message\ActivityPub\Outbox\DeleteMessage; @@ -28,6 +31,7 @@ public static function getSubscribedEvents(): array return [ EntryDeletedEvent::class => 'onEntryDeleted', EntryBeforePurgeEvent::class => 'onEntryBeforePurge', + EntryBeforeDeletedEvent::class => 'onEntryBeforeDelete', ]; } @@ -41,17 +45,21 @@ public function onEntryBeforePurge(EntryBeforePurgeEvent $event): void $event->entry->magazine->entryCount = $this->entryRepository->countEntriesByMagazine( $event->entry->magazine ) - 1; + $this->onEntryBeforeDeleteImpl($event->user, $event->entry); + } - $this->bus->dispatch(new EntryDeletedNotificationMessage($event->entry->getId())); + public function onEntryBeforeDelete(EntryBeforeDeletedEvent $event): void + { + $this->onEntryBeforeDeleteImpl($event->user, $event->entry); + } + + public function onEntryBeforeDeleteImpl(?User $user, Entry $entry): void + { + $this->bus->dispatch(new EntryDeletedNotificationMessage($entry->getId())); - if (!$event->entry->apId) { - $this->bus->dispatch( - new DeleteMessage( - $this->deleteWrapper->build($event->entry, Uuid::v4()->toRfc4122()), - $event->entry->user->getId(), - $event->entry->magazine->getId() - ) - ); + if (!$entry->apId || !$entry->magazine->apId || (null !== $user && $entry->magazine->userIsModerator($user))) { + $payload = $this->deleteWrapper->adjustDeletePayload($user, $entry, Uuid::v4()->toRfc4122()); + $this->bus->dispatch(new DeleteMessage($payload, $entry->user->getId(), $entry->magazine->getId())); } } } diff --git a/src/EventSubscriber/EntryComment/EntryCommentBeforeDeleteSubscriber.php b/src/EventSubscriber/EntryComment/EntryCommentBeforeDeleteSubscriber.php deleted file mode 100644 index 5f93182eb..000000000 --- a/src/EventSubscriber/EntryComment/EntryCommentBeforeDeleteSubscriber.php +++ /dev/null @@ -1,41 +0,0 @@ - 'onEntryCommentBeforeDelete', - ]; - } - - public function onEntryCommentBeforeDelete(EntryCommentBeforeDeletedEvent $event): void - { - if (!$event->comment->apId) { - $this->bus->dispatch( - new DeleteMessage( - $this->deleteWrapper->build($event->comment, Uuid::v4()->toRfc4122()), - $event->comment->user->getId(), - $event->comment->magazine->getId() - ) - ); - } - } -} diff --git a/src/EventSubscriber/EntryComment/EntryCommentDeleteSubscriber.php b/src/EventSubscriber/EntryComment/EntryCommentDeleteSubscriber.php index dc1c0adf6..2347183ab 100644 --- a/src/EventSubscriber/EntryComment/EntryCommentDeleteSubscriber.php +++ b/src/EventSubscriber/EntryComment/EntryCommentDeleteSubscriber.php @@ -4,6 +4,9 @@ namespace App\EventSubscriber\EntryComment; +use App\Entity\EntryComment; +use App\Entity\User; +use App\Event\EntryComment\EntryCommentBeforeDeletedEvent; use App\Event\EntryComment\EntryCommentBeforePurgeEvent; use App\Event\EntryComment\EntryCommentDeletedEvent; use App\Message\ActivityPub\Outbox\DeleteMessage; @@ -19,7 +22,7 @@ class EntryCommentDeleteSubscriber implements EventSubscriberInterface public function __construct( private readonly CacheInterface $cache, private readonly MessageBusInterface $bus, - private readonly DeleteWrapper $deleteWrapper + private readonly DeleteWrapper $deleteWrapper, ) { } @@ -28,6 +31,7 @@ public static function getSubscribedEvents(): array return [ EntryCommentDeletedEvent::class => 'onEntryCommentDeleted', EntryCommentBeforePurgeEvent::class => 'onEntryCommentBeforePurge', + EntryCommentBeforeDeletedEvent::class => 'onEntryCommentBeforeDelete', ]; } @@ -40,18 +44,23 @@ public function onEntryCommentDeleted(EntryCommentDeletedEvent $event): void public function onEntryCommentBeforePurge(EntryCommentBeforePurgeEvent $event): void { - $this->cache->invalidateTags(['entry_comment_'.$event->comment->root?->getId() ?? $event->comment->getId()]); + $this->onEntryCommentBeforeDeleteImpl($event->user, $event->comment); + } - $this->bus->dispatch(new EntryCommentDeletedNotificationMessage($event->comment->getId())); + public function onEntryCommentBeforeDelete(EntryCommentBeforeDeletedEvent $event): void + { + $this->onEntryCommentBeforeDeleteImpl($event->user, $event->comment); + } + + public function onEntryCommentBeforeDeleteImpl(?User $user, EntryComment $comment): void + { + $this->cache->invalidateTags(['entry_comment_'.$comment->root?->getId() ?? $comment->getId()]); + + $this->bus->dispatch(new EntryCommentDeletedNotificationMessage($comment->getId())); - if (!$event->comment->apId) { - $this->bus->dispatch( - new DeleteMessage( - $this->deleteWrapper->build($event->comment, Uuid::v4()->toRfc4122()), - $event->comment->user->getId(), - $event->comment->magazine->getId() - ) - ); + if (!$comment->apId || !$comment->magazine->apId || (null !== $user && $comment->magazine->userIsModerator($user))) { + $payload = $this->deleteWrapper->adjustDeletePayload($user, $comment, Uuid::v4()->toRfc4122()); + $this->bus->dispatch(new DeleteMessage($payload, $comment->user->getId(), $comment->magazine->getId())); } } } diff --git a/src/EventSubscriber/Post/PostBeforeDeleteSubscriber.php b/src/EventSubscriber/Post/PostBeforeDeleteSubscriber.php deleted file mode 100644 index e481acb65..000000000 --- a/src/EventSubscriber/Post/PostBeforeDeleteSubscriber.php +++ /dev/null @@ -1,41 +0,0 @@ - 'onPostBeforeDelete', - ]; - } - - public function onPostBeforeDelete(PostBeforeDeletedEvent $event): void - { - if (!$event->post->apId) { - $this->bus->dispatch( - new DeleteMessage( - $this->deleteWrapper->build($event->post, Uuid::v4()->toRfc4122()), - $event->post->user->getId(), - $event->post->magazine->getId() - ) - ); - } - } -} diff --git a/src/EventSubscriber/Post/PostDeleteSubscriber.php b/src/EventSubscriber/Post/PostDeleteSubscriber.php index 33c3d2f23..bc76c9d0a 100644 --- a/src/EventSubscriber/Post/PostDeleteSubscriber.php +++ b/src/EventSubscriber/Post/PostDeleteSubscriber.php @@ -4,6 +4,9 @@ namespace App\EventSubscriber\Post; +use App\Entity\Post; +use App\Entity\User; +use App\Event\Post\PostBeforeDeletedEvent; use App\Event\Post\PostBeforePurgeEvent; use App\Event\Post\PostDeletedEvent; use App\Message\ActivityPub\Outbox\DeleteMessage; @@ -28,6 +31,7 @@ public static function getSubscribedEvents(): array return [ PostDeletedEvent::class => 'onPostDeleted', PostBeforePurgeEvent::class => 'onPostBeforePurge', + PostBeforeDeletedEvent::class => 'onPostBeforeDelete', ]; } @@ -39,17 +43,21 @@ public function onPostDeleted(PostDeletedEvent $event) public function onPostBeforePurge(PostBeforePurgeEvent $event): void { $event->post->magazine->postCount = $this->postRepository->countPostsByMagazine($event->post->magazine) - 1; + $this->onPostBeforeDeleteImpl($event->user, $event->post); + } - $this->bus->dispatch(new PostDeletedNotificationMessage($event->post->getId())); + public function onPostBeforeDelete(PostBeforeDeletedEvent $event): void + { + $this->onPostBeforeDeleteImpl($event->user, $event->post); + } + + public function onPostBeforeDeleteImpl(?User $user, Post $post): void + { + $this->bus->dispatch(new PostDeletedNotificationMessage($post->getId())); - if (!$event->post->apId) { - $this->bus->dispatch( - new DeleteMessage( - $this->deleteWrapper->build($event->post, Uuid::v4()->toRfc4122()), - $event->post->user->getId(), - $event->post->magazine->getId() - ) - ); + if (!$post->apId || !$post->magazine->apId || (null !== $user && $post->magazine->userIsModerator($user))) { + $payload = $this->deleteWrapper->adjustDeletePayload($user, $post, Uuid::v4()->toRfc4122()); + $this->bus->dispatch(new DeleteMessage($payload, $post->user->getId(), $post->magazine->getId())); } } } diff --git a/src/EventSubscriber/PostComment/PostCommentBeforeDeleteSubscriber.php b/src/EventSubscriber/PostComment/PostCommentBeforeDeleteSubscriber.php deleted file mode 100644 index 1003b03a2..000000000 --- a/src/EventSubscriber/PostComment/PostCommentBeforeDeleteSubscriber.php +++ /dev/null @@ -1,41 +0,0 @@ - 'onPostBeforeDelete', - ]; - } - - public function onPostBeforeDelete(PostCommentBeforeDeletedEvent $event): void - { - if (!$event->comment->apId) { - $this->bus->dispatch( - new DeleteMessage( - $this->deleteWrapper->build($event->comment, Uuid::v4()->toRfc4122()), - $event->comment->user->getId(), - $event->comment->magazine->getId() - ) - ); - } - } -} diff --git a/src/EventSubscriber/PostComment/PostCommentDeleteSubscriber.php b/src/EventSubscriber/PostComment/PostCommentDeleteSubscriber.php index 3bc14ae83..f8529cc3b 100644 --- a/src/EventSubscriber/PostComment/PostCommentDeleteSubscriber.php +++ b/src/EventSubscriber/PostComment/PostCommentDeleteSubscriber.php @@ -4,6 +4,9 @@ namespace App\EventSubscriber\PostComment; +use App\Entity\PostComment; +use App\Entity\User; +use App\Event\PostComment\PostCommentBeforeDeletedEvent; use App\Event\PostComment\PostCommentBeforePurgeEvent; use App\Event\PostComment\PostCommentDeletedEvent; use App\Message\ActivityPub\Outbox\DeleteMessage; @@ -28,6 +31,7 @@ public static function getSubscribedEvents(): array return [ PostCommentDeletedEvent::class => 'onPostCommentDeleted', PostCommentBeforePurgeEvent::class => 'onPostCommentBeforePurge', + PostCommentBeforeDeletedEvent::class => 'onPostBeforeDelete', ]; } @@ -41,23 +45,28 @@ public function onPostCommentDeleted(PostCommentDeletedEvent $event): void $this->bus->dispatch(new PostCommentDeletedNotificationMessage($event->comment->getId())); } + public function onPostBeforeDelete(PostCommentBeforeDeletedEvent $event): void + { + $this->onPostCommentBeforeDeleteImpl($event->user, $event->comment); + } + public function onPostCommentBeforePurge(PostCommentBeforePurgeEvent $event): void + { + $this->onPostCommentBeforeDeleteImpl($event->user, $event->comment); + } + + public function onPostCommentBeforeDeleteImpl(?User $user, PostComment $comment): void { $this->cache->invalidateTags([ - 'post_'.$event->comment->post->getId(), - 'post_comment_'.$event->comment->root?->getId() ?? $event->comment->getId(), + 'post_'.$comment->post->getId(), + 'post_comment_'.$comment->root?->getId() ?? $comment->getId(), ]); - $this->bus->dispatch(new PostCommentDeletedNotificationMessage($event->comment->getId())); + $this->bus->dispatch(new PostCommentDeletedNotificationMessage($comment->getId())); - if (!$event->comment->apId) { - $this->bus->dispatch( - new DeleteMessage( - $this->deleteWrapper->build($event->comment, Uuid::v4()->toRfc4122()), - $event->comment->user->getId(), - $event->comment->magazine->getId() - ) - ); + if (!$comment->apId || !$comment->magazine->apId || (null !== $user && $comment->magazine->userIsModerator($user))) { + $payload = $this->deleteWrapper->adjustDeletePayload($user, $comment, Uuid::v4()->toRfc4122()); + $this->bus->dispatch(new DeleteMessage($payload, $comment->user->getId(), $comment->magazine->getId())); } } } diff --git a/src/Factory/MagazineFactory.php b/src/Factory/MagazineFactory.php index 1096e311e..6da8db0d5 100644 --- a/src/Factory/MagazineFactory.php +++ b/src/Factory/MagazineFactory.php @@ -32,7 +32,7 @@ public function __construct( ) { } - public function createFromDto(MagazineDto $dto, User $user): Magazine + public function createFromDto(MagazineDto $dto, ?User $user): Magazine { return new Magazine( $dto->name, diff --git a/src/MessageHandler/ActivityPub/Inbox/RemoveHandler.php b/src/MessageHandler/ActivityPub/Inbox/RemoveHandler.php index d56cb5306..cd746626c 100644 --- a/src/MessageHandler/ActivityPub/Inbox/RemoveHandler.php +++ b/src/MessageHandler/ActivityPub/Inbox/RemoveHandler.php @@ -30,23 +30,30 @@ public function __invoke(RemoveMessage $message): void if (!$targetMag) { throw new \LogicException("could not find a magazine with moderators url like: '{$payload['target']}'"); } - if (!$targetMag->userIsModerator($actor) and !$targetMag->hasSameHostAsUser($actor)) { + if (!$targetMag->userIsModerator($actor) && !$targetMag->hasSameHostAsUser($actor)) { throw new \LogicException("the user '$actor->username' ({$actor->getId()}) is not a moderator of $targetMag->name ({$targetMag->getId()}) and is not from the same instance. He can therefore not remove moderators"); } $object = $this->activityPubManager->findUserActorOrCreateOrThrow($payload['object']); $objectMod = $targetMag->getUserAsModeratorOrNull($object); + $loggerParams = [ + 'toRemove' => $object->username, + 'toRemoveId' => $object->getId(), + 'magName' => $targetMag->name, + 'magId' => $targetMag->getId(), + ]; + if (null === $objectMod) { - $this->logger->warning('the user "{toRemove}" ({toRemoveId}) is not a moderator of {magName} ({magId}) and can therefore not be removed as one. Discarding message', [ - 'toRemove' => $object->username, - 'toRemoveId' => $object->getId(), - 'magName' => $targetMag->name, - 'magId' => $targetMag->getId(), - ]); + $this->logger->warning('the user "{toRemove}" ({toRemoveId}) is not a moderator of {magName} ({magId}) and can therefore not be removed as one. Discarding message', $loggerParams); + + return; + } elseif ($objectMod->isOwner) { + $this->logger->warning('the user "{toRemove}" ({toRemoveId}) is the owner of {magName} ({magId}) and can therefore not be removed. Discarding message', $loggerParams); return; } + $this->logger->info(' "{actor}" ({actorId}) removed "{removed}" ({removedId}) as moderator from "{magName}" ({magId})', [ 'actor' => $actor->username, 'actorId' => $actor->getId(), diff --git a/src/Repository/MagazineRepository.php b/src/Repository/MagazineRepository.php index d2763ff31..6c70535c7 100644 --- a/src/Repository/MagazineRepository.php +++ b/src/Repository/MagazineRepository.php @@ -200,11 +200,9 @@ public function findModerators( ?int $page = 1, int $perPage = self::PER_PAGE ): PagerfantaInterface { - $criteria = Criteria::create()->orderBy(['createdAt' => 'ASC']); - - if ($magazine->apId) { - $criteria->where(Criteria::expr()->eq('isOwner', false)); - } + $criteria = Criteria::create() + ->orderBy(['isOwner' => 'DESC']) + ->orderBy(['createdAt' => 'ASC']); $moderators = new Pagerfanta(new SelectableAdapter($magazine->moderators, $criteria)); try { diff --git a/src/Service/ActivityPub/Wrapper/DeleteWrapper.php b/src/Service/ActivityPub/Wrapper/DeleteWrapper.php index 4c85d4a07..3b76b8105 100644 --- a/src/Service/ActivityPub/Wrapper/DeleteWrapper.php +++ b/src/Service/ActivityPub/Wrapper/DeleteWrapper.php @@ -5,6 +5,10 @@ namespace App\Service\ActivityPub\Wrapper; use App\Entity\Contracts\ActivityPubActivityInterface; +use App\Entity\Entry; +use App\Entity\EntryComment; +use App\Entity\Post; +use App\Entity\PostComment; use App\Entity\User; use App\Factory\ActivityPub\ActivityFactory; use JetBrains\PhpStorm\ArrayShape; @@ -15,6 +19,7 @@ class DeleteWrapper { public function __construct( private readonly ActivityFactory $factory, + private readonly AnnounceWrapper $announceWrapper, private readonly UrlGeneratorInterface $urlGenerator ) { } @@ -28,15 +33,26 @@ public function __construct( 'to' => 'mixed', 'cc' => 'mixed', ])] - public function build(ActivityPubActivityInterface $item, string $id): array + public function build(ActivityPubActivityInterface $item, string $id, User $deletingUser = null): array { $item = $this->factory->create($item); + $userUrl = $item['attributedTo']; + + if (null !== $deletingUser) { + // overwrite the actor in the json with the supplied deleting user + if (null !== $deletingUser->apId) { + $userUrl = $deletingUser->apPublicUrl; + } else { + $userUrl = $this->urlGenerator->generate('user_overview', ['username' => $deletingUser->username], UrlGeneratorInterface::ABSOLUTE_URL); + } + } + return [ '@context' => ActivityPubActivityInterface::CONTEXT_URL, 'id' => $this->urlGenerator->generate('ap_object', ['id' => $id], UrlGeneratorInterface::ABSOLUTE_URL), 'type' => 'Delete', - 'actor' => $item['attributedTo'], + 'actor' => $userUrl, 'object' => [ 'id' => $item['id'], 'type' => 'Tombstone', @@ -63,4 +79,22 @@ public function buildForUser(User $user): array 'removeData' => true, ]; } + + public function adjustDeletePayload(?User $actor, Entry|EntryComment|Post|PostComment $content, string $id): array + { + $payload = $this->build($content, $id, $actor); + + if (null !== $actor && $content->user->getId() !== $actor->getId()) { + // if the user is different, then this is a mod action. Lemmy requires a mod action to have a summary + $payload['summary'] = ' '; + } + + if (null !== $actor?->apId) { + // wrap the `Delete` in an `Announce` activity if the deleting user is not a local one + $magazineUrl = $this->urlGenerator->generate('ap_magazine', ['name' => $content->magazine->name], UrlGeneratorInterface::ABSOLUTE_URL); + $payload = $this->announceWrapper->build($magazineUrl, $payload); + } + + return $payload; + } } diff --git a/src/Service/ActivityPubManager.php b/src/Service/ActivityPubManager.php index a15eb4495..fda2ec4cc 100644 --- a/src/Service/ActivityPubManager.php +++ b/src/Service/ActivityPubManager.php @@ -415,7 +415,7 @@ private function createMagazine(string $actorUrl): ?Magazine { $this->magazineManager->create( $this->magazineFactory->createDtoFromAp($actorUrl, $this->buildHandle($actorUrl)), - $this->userRepository->findAdmin(), + null, false ); @@ -504,9 +504,7 @@ public function updateMagazine(string $actorUrl): ?Magazine $moderatorsToRemove = []; /** @var Moderator $mod */ foreach ($magazine->moderators as $mod) { - if (!$mod->isOwner) { - $moderatorsToRemove[] = $mod->user; - } + $moderatorsToRemove[] = $mod->user; } $indexesNotToRemove = []; diff --git a/src/Service/EntryCommentManager.php b/src/Service/EntryCommentManager.php index 380b76db9..4afd81d1e 100644 --- a/src/Service/EntryCommentManager.php +++ b/src/Service/EntryCommentManager.php @@ -23,6 +23,7 @@ use App\Service\Contracts\ContentManagerInterface; use Doctrine\ORM\EntityManagerInterface; use Psr\EventDispatcher\EventDispatcherInterface; +use Psr\Log\LoggerInterface; use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\RateLimiter\RateLimiterFactory; @@ -31,6 +32,7 @@ class EntryCommentManager implements ContentManagerInterface { public function __construct( + private readonly LoggerInterface $logger, private readonly TagManager $tagManager, private readonly TagExtractor $tagExtractor, private readonly MentionManager $mentionManager, @@ -128,7 +130,9 @@ public function edit(EntryComment $comment, EntryCommentDto $dto): EntryComment public function delete(User $user, EntryComment $comment): void { - if ($user->apDomain && $user->apDomain !== parse_url($comment->apId, PHP_URL_HOST)) { + if ($user->apDomain && $user->apDomain !== parse_url($comment->apId ?? '', PHP_URL_HOST) && !$comment->magazine->userIsModerator($user)) { + $this->logger->info('Got a delete activity from user {u}, but they are not from the same instance as the deleted post and they are not a moderator on {m]', ['u' => $user->apId, 'm' => $comment->magazine->apId ?? $comment->magazine->name]); + return; } diff --git a/src/Service/EntryManager.php b/src/Service/EntryManager.php index d26979cc8..cd17948d5 100644 --- a/src/Service/EntryManager.php +++ b/src/Service/EntryManager.php @@ -190,7 +190,9 @@ public function edit(Entry $entry, EntryDto $dto): Entry public function delete(User $user, Entry $entry): void { - if ($user->apDomain && $user->apDomain !== parse_url($entry->apId, PHP_URL_HOST)) { + if ($user->apDomain && $user->apDomain !== parse_url($entry->apId ?? '', PHP_URL_HOST) && !$entry->magazine->userIsModerator($user)) { + $this->logger->info('Got a delete activity from user {u}, but they are not from the same instance as the deleted post and they are not a moderator on {m]', ['u' => $user->apId, 'm' => $entry->magazine->apId ?? $entry->magazine->name]); + return; } diff --git a/src/Service/MagazineManager.php b/src/Service/MagazineManager.php index 914b9eb95..d81d6c63e 100644 --- a/src/Service/MagazineManager.php +++ b/src/Service/MagazineManager.php @@ -56,7 +56,7 @@ public function __construct( ) { } - public function create(MagazineDto $dto, User $user, bool $rateLimit = true): Magazine + public function create(MagazineDto $dto, ?User $user, bool $rateLimit = true): Magazine { if (!$dto->apId && true === $this->settingsManager->get('MBIN_RESTRICT_MAGAZINE_CREATION') && !$user->isAdmin() && !$user->isModerator()) { throw new AccessDeniedException(); diff --git a/src/Service/PostCommentManager.php b/src/Service/PostCommentManager.php index 50d56993d..baaa49792 100644 --- a/src/Service/PostCommentManager.php +++ b/src/Service/PostCommentManager.php @@ -23,6 +23,7 @@ use App\Service\Contracts\ContentManagerInterface; use Doctrine\ORM\EntityManagerInterface; use Psr\EventDispatcher\EventDispatcherInterface; +use Psr\Log\LoggerInterface; use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\RateLimiter\RateLimiterFactory; @@ -31,6 +32,7 @@ class PostCommentManager implements ContentManagerInterface { public function __construct( + private readonly LoggerInterface $logger, private readonly TagManager $tagManager, private readonly TagExtractor $tagExtractor, private readonly MentionManager $mentionManager, @@ -137,7 +139,9 @@ public function edit(PostComment $comment, PostCommentDto $dto): PostComment public function delete(User $user, PostComment $comment): void { - if ($user->apDomain && $user->apDomain !== parse_url($comment->apId, PHP_URL_HOST)) { + if ($user->apDomain && $user->apDomain !== parse_url($comment->apId ?? '', PHP_URL_HOST) && !$comment->magazine->userIsModerator($user)) { + $this->logger->info('Got a delete activity from user {u}, but they are not from the same instance as the deleted post and they are not a moderator on {m]', ['u' => $user->apId, 'm' => $comment->magazine->apId ?? $comment->magazine->name]); + return; } diff --git a/src/Service/PostManager.php b/src/Service/PostManager.php index 6deff08c0..d4dcf26fb 100644 --- a/src/Service/PostManager.php +++ b/src/Service/PostManager.php @@ -142,7 +142,9 @@ public function edit(Post $post, PostDto $dto): Post public function delete(User $user, Post $post): void { - if ($user->apDomain && $user->apDomain !== parse_url($post->apId, PHP_URL_HOST)) { + if ($user->apDomain && $user->apDomain !== parse_url($post->apId ?? '', PHP_URL_HOST) && !$post->magazine->userIsModerator($user)) { + $this->logger->info('Got a delete activity from user {u}, but they are not from the same instance as the deleted post and they are not a moderator on {m]', ['u' => $user->apId, 'm' => $post->magazine->apId ?? $post->magazine->name]); + return; } diff --git a/templates/magazine/_moderators_sidebar.html.twig b/templates/magazine/_moderators_sidebar.html.twig index aab1371fd..81a235ce4 100644 --- a/templates/magazine/_moderators_sidebar.html.twig +++ b/templates/magazine/_moderators_sidebar.html.twig @@ -12,20 +12,18 @@ {% if magazine.moderators|length > 5 %} From 0f04aa583fbfe6e22cc94385c0fac600b58a9239 Mon Sep 17 00:00:00 2001 From: debounced <35878315+nobodyatroot@users.noreply.github.com> Date: Fri, 31 May 2024 06:40:18 -0500 Subject: [PATCH 021/335] version bump in preparation for 1.6.0 release (#789) Co-authored-by: Melroy van den Berg --- config/packages/framework.yaml | 2 +- src/Service/ProjectInfoService.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml index 3a6d30d04..ea6f91c0c 100644 --- a/config/packages/framework.yaml +++ b/config/packages/framework.yaml @@ -17,7 +17,7 @@ framework: http_client: default_options: headers: - 'User-Agent': 'Mbin/1.5.3 (+https://%kbin_domain%/agent)' + 'User-Agent': 'Mbin/1.6.0 (+https://%kbin_domain%/agent)' #esi: true #fragments: true diff --git a/src/Service/ProjectInfoService.php b/src/Service/ProjectInfoService.php index be1614120..dbf2bbefc 100644 --- a/src/Service/ProjectInfoService.php +++ b/src/Service/ProjectInfoService.php @@ -10,7 +10,7 @@ class ProjectInfoService { // If updating version, please also update http client UA in [/config/packages/framework.yaml] - private const VERSION = '1.5.3'; // TODO: Retrieve the version from git tags or getenv()? + private const VERSION = '1.6.0'; // TODO: Retrieve the version from git tags or getenv()? private const NAME = 'mbin'; private const USER_AGENT = 'Mbin'; private const REPOSITORY_URL = 'https://github.com/MbinOrg/mbin'; From af0bd71c822e7b8231a7e783779c9f8409f407b0 Mon Sep 17 00:00:00 2001 From: debounced <35878315+nobodyatroot@users.noreply.github.com> Date: Fri, 31 May 2024 16:01:01 -0500 Subject: [PATCH 022/335] Update Docker caddy builder version (#800) --- docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 75cc37ef4..dfe9729f3 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -36,7 +36,7 @@ RUN chown -R $USER:$GROUP /usr/local/etc/php-fpm.d #################### -FROM caddy:2.7-builder-alpine AS builder-caddy +FROM caddy:2.8.1-builder-alpine AS builder-caddy # Build Caddy with the Mercure and Vulcain and brotil cache modules RUN xcaddy build \ From 3165586ec894d9d545f0b5a75965c939c5a3faa3 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Sat, 1 Jun 2024 02:18:58 +0200 Subject: [PATCH 023/335] Translations update from Hosted Weblate (#798) Co-authored-by: Asmodeus --- translations/messages.pt_BR.yaml | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/translations/messages.pt_BR.yaml b/translations/messages.pt_BR.yaml index 0967ef424..8074f9ea6 100644 --- a/translations/messages.pt_BR.yaml +++ b/translations/messages.pt_BR.yaml @@ -1 +1,28 @@ -{} +type.link: Link +type.article: Fio +type.photo: Foto +type.video: Vídeo +type.smart_contract: Contrato inteligente +type.magazine: Magazine +thread: Fio +threads: Fios +microblog: Microblog +people: Pessoas +events: Eventos +magazine: Magazine +search: Buscar +add: Adicionar +commented: Comentado +change_view: Alterar visualização +filter_by_time: Filtrar por tempo +filter_by_type: Filtrar por tipo +filter_by_subscription: Filtrar por inscrição +magazines: Magazines +select_channel: Selecionar um canal +sort_by: Ordenar por +login: Fazer login +oldest: Mais velho +top: Topo +hot: Popular +active: Ativo +newest: Mais novo From 8849c808230eb636e067db78d87bae0f08a8940d Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Sat, 1 Jun 2024 15:37:48 +0200 Subject: [PATCH 024/335] Translations update from Hosted Weblate (#802) Co-authored-by: Asmodeus --- translations/messages.pt_BR.yaml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/translations/messages.pt_BR.yaml b/translations/messages.pt_BR.yaml index 8074f9ea6..61bc2d6f2 100644 --- a/translations/messages.pt_BR.yaml +++ b/translations/messages.pt_BR.yaml @@ -26,3 +26,23 @@ top: Topo hot: Popular active: Ativo newest: Mais novo +filter_by_federation: Filtrar por status de federação +marked_for_deletion: Marcado para exclusão +marked_for_deletion_at: Marcado para exclusão em %date% +favourites: Favoritos +favourite: Favorito +more: Mais +avatar: Avatar +added: Adicionou +no_comments: Sem comentários +created_at: Criado +owner: Dono +subscribers: Inscritos +online: Online +comments: Comentários +posts: Postagens +replies: Respostas +moderators: Moderadores +mod_log: Registro de moderação +add_comment: Adicionar comentário +add_post: Adicionar postagem From 635c58aaed217e38173a371772089b193ff4756d Mon Sep 17 00:00:00 2001 From: debounced <35878315+nobodyatroot@users.noreply.github.com> Date: Sun, 2 Jun 2024 07:49:21 -0500 Subject: [PATCH 025/335] Add Brazilian Portuguese and Danish language selectors (#801) --- README.md | 2 ++ assets/controllers/timeago_controller.js | 5 +++-- templates/layout/_sidebar.html.twig | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0c73b318e..3a6dba331 100644 --- a/README.md +++ b/README.md @@ -295,6 +295,7 @@ Following languages are currently supported/translated: - Bulgarian - Chinese +- Danish - Dutch - English - Esperanto @@ -305,6 +306,7 @@ Following languages are currently supported/translated: - Japanese - Polish - Portuguese +- Portuguese (Brazil) - Russian - Spanish - Turkish diff --git a/assets/controllers/timeago_controller.js b/assets/controllers/timeago_controller.js index d8339bbca..e5a92a156 100644 --- a/assets/controllers/timeago_controller.js +++ b/assets/controllers/timeago_controller.js @@ -3,6 +3,7 @@ import { Controller } from '@hotwired/stimulus'; // eslint-disable-next-line -- grouping timeago imports here is more readable than properly sorting import * as timeago from 'timeago.js'; import bg from 'timeago.js/lib/lang/bg'; +import da from 'timeago.js/lib/lang/da'; import de from 'timeago.js/lib/lang/de'; import el from 'timeago.js/lib/lang/el'; import en from 'timeago.js/lib/lang/en_US'; @@ -12,7 +13,7 @@ import it from 'timeago.js/lib/lang/it'; import ja from 'timeago.js/lib/lang/ja'; import nl from 'timeago.js/lib/lang/nl'; import pl from 'timeago.js/lib/lang/pl'; -import pt from 'timeago.js/lib/lang/pt_BR'; +import pt_BR from 'timeago.js/lib/lang/pt_BR'; import ru from 'timeago.js/lib/lang/ru'; import tr from 'timeago.js/lib/lang/tr'; import uk from 'timeago.js/lib/lang/uk'; @@ -28,7 +29,7 @@ export default class extends Controller { } const lang = document.documentElement.lang; - const languages = { bg, de, el, en, es, fr, it, ja, nl, pl, pt, ru, tr, uk, zh_TW }; + const languages = { bg, da, de, el, en, es, fr, it, ja, nl, pl, pt_BR, ru, tr, uk, zh_TW }; if (languages[lang]) { timeago.register(lang, languages[lang]); diff --git a/templates/layout/_sidebar.html.twig b/templates/layout/_sidebar.html.twig index 0c4401e6f..36b4a59a9 100644 --- a/templates/layout/_sidebar.html.twig +++ b/templates/layout/_sidebar.html.twig @@ -148,7 +148,7 @@ {% set current = app.request.cookies.get('kbin_lang') ?? header_accept_language ?? kbin_default_lang() %}
  • From 7397c29b45a1800bd908a010cb0ad9cf6a9b701b Mon Sep 17 00:00:00 2001 From: CocoPoops Date: Tue, 4 Jun 2024 01:47:40 +0000 Subject: [PATCH 026/335] change sso authentication success route to front page (#804) --- src/Security/AzureAuthenticator.php | 2 +- src/Security/FacebookAuthenticator.php | 2 +- src/Security/GithubAuthenticator.php | 2 +- src/Security/GoogleAuthenticator.php | 2 +- src/Security/KeycloakAuthenticator.php | 2 +- src/Security/SimpleLoginAuthenticator.php | 2 +- src/Security/ZitadelAuthenticator.php | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Security/AzureAuthenticator.php b/src/Security/AzureAuthenticator.php index acdfbd24a..a82ca063e 100644 --- a/src/Security/AzureAuthenticator.php +++ b/src/Security/AzureAuthenticator.php @@ -119,7 +119,7 @@ public function authenticate(Request $request): Passport public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response { - $targetUrl = $this->router->generate('user_settings_profile'); + $targetUrl = $this->router->generate('front'); return new RedirectResponse($targetUrl); } diff --git a/src/Security/FacebookAuthenticator.php b/src/Security/FacebookAuthenticator.php index f48d35e11..26fe8af6f 100644 --- a/src/Security/FacebookAuthenticator.php +++ b/src/Security/FacebookAuthenticator.php @@ -152,7 +152,7 @@ private function getAvatar(?string $pictureUrl): ?Image public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response { - $targetUrl = $this->router->generate('user_settings_profile'); + $targetUrl = $this->router->generate('front'); return new RedirectResponse($targetUrl); } diff --git a/src/Security/GithubAuthenticator.php b/src/Security/GithubAuthenticator.php index 6574f71ff..68381092e 100644 --- a/src/Security/GithubAuthenticator.php +++ b/src/Security/GithubAuthenticator.php @@ -102,7 +102,7 @@ public function onAuthenticationSuccess( TokenInterface $token, string $firewallName ): ?Response { - $targetUrl = $this->router->generate('user_settings_profile'); + $targetUrl = $this->router->generate('front'); return new RedirectResponse($targetUrl); } diff --git a/src/Security/GoogleAuthenticator.php b/src/Security/GoogleAuthenticator.php index ef913a2d0..80a834ffd 100644 --- a/src/Security/GoogleAuthenticator.php +++ b/src/Security/GoogleAuthenticator.php @@ -158,7 +158,7 @@ public function onAuthenticationSuccess( TokenInterface $token, string $firewallName ): ?Response { - $targetUrl = $this->router->generate('user_settings_profile'); + $targetUrl = $this->router->generate('front'); return new RedirectResponse($targetUrl); } diff --git a/src/Security/KeycloakAuthenticator.php b/src/Security/KeycloakAuthenticator.php index 57587a0dc..733c30e46 100644 --- a/src/Security/KeycloakAuthenticator.php +++ b/src/Security/KeycloakAuthenticator.php @@ -119,7 +119,7 @@ public function authenticate(Request $request): Passport public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response { - $targetUrl = $this->router->generate('user_settings_profile'); + $targetUrl = $this->router->generate('front'); return new RedirectResponse($targetUrl); } diff --git a/src/Security/SimpleLoginAuthenticator.php b/src/Security/SimpleLoginAuthenticator.php index 32229ac79..4a65bddc5 100644 --- a/src/Security/SimpleLoginAuthenticator.php +++ b/src/Security/SimpleLoginAuthenticator.php @@ -164,7 +164,7 @@ private function getAvatar(?string $pictureUrl): ?Image public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response { - $targetUrl = $this->router->generate('user_settings_profile'); + $targetUrl = $this->router->generate('front'); return new RedirectResponse($targetUrl); } diff --git a/src/Security/ZitadelAuthenticator.php b/src/Security/ZitadelAuthenticator.php index 848ea1046..823206ff8 100644 --- a/src/Security/ZitadelAuthenticator.php +++ b/src/Security/ZitadelAuthenticator.php @@ -157,7 +157,7 @@ private function getAvatar(?string $pictureUrl): ?Image public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response { - $targetUrl = $this->router->generate('user_settings_profile'); + $targetUrl = $this->router->generate('front'); return new RedirectResponse($targetUrl); } From d38d2da9f76731eb98935e45d6cf09540923afe7 Mon Sep 17 00:00:00 2001 From: CocoPoops Date: Tue, 4 Jun 2024 02:53:49 +0000 Subject: [PATCH 027/335] Authentik SSO (#806) --- .env.example | 3 + .env.example_docker | 3 + config/kbin_routes/security.yaml | 10 + config/packages/knpu_oauth2_client.yaml | 9 + config/packages/security.yaml | 1 + config/services.yaml | 4 + migrations/Version20240603230734.php | 29 +++ .../Security/AuthentikController.php | 28 +++ src/Entity/User.php | 4 +- src/Provider/Authentik.php | 74 ++++++++ src/Provider/AuthentikResourceOwner.php | 68 +++++++ src/Security/AuthentikAuthenticator.php | 178 ++++++++++++++++++ src/Twig/Components/LoginSocialsComponent.php | 7 + templates/components/login_socials.html.twig | 6 +- 14 files changed, 422 insertions(+), 2 deletions(-) create mode 100644 migrations/Version20240603230734.php create mode 100644 src/Controller/Security/AuthentikController.php create mode 100644 src/Provider/Authentik.php create mode 100644 src/Provider/AuthentikResourceOwner.php create mode 100644 src/Security/AuthentikAuthenticator.php diff --git a/.env.example b/.env.example index a27414961..761d665cc 100644 --- a/.env.example +++ b/.env.example @@ -80,6 +80,9 @@ OAUTH_SIMPLELOGIN_SECRET= OAUTH_ZITADEL_ID= OAUTH_ZITADEL_SECRET= OAUTH_ZITADEL_BASE_URL= +OAUTH_AUTHENTIK_ID= +OAUTH_AUTHENTIK_SECRET= +OAUTH_AUTHENTIK_BASE_URL= # If true, sign ins and sign ups will only be possible through the OAuth providers configured above SSO_ONLY_MODE= diff --git a/.env.example_docker b/.env.example_docker index 635c94f81..9b0bb042b 100644 --- a/.env.example_docker +++ b/.env.example_docker @@ -77,6 +77,9 @@ OAUTH_SIMPLELOGIN_SECRET= OAUTH_ZITADEL_ID= OAUTH_ZITADEL_SECRET= OAUTH_ZITADEL_BASE_URL= +OAUTH_AUTHENTIK_ID= +OAUTH_AUTHENTIK_SECRET= +OAUTH_AUTHENTIK_BASE_URL= # If true, sign ins and sign ups will only be possible through the OAuth providers configured above SSO_ONLY_MODE= diff --git a/config/kbin_routes/security.yaml b/config/kbin_routes/security.yaml index 897886ff1..e3bf45ddd 100644 --- a/config/kbin_routes/security.yaml +++ b/config/kbin_routes/security.yaml @@ -113,6 +113,16 @@ oauth_zitadel_verify: path: /oauth/zitadel/verify methods: [ GET ] +oauth_authentik_connect: + controller: App\Controller\Security\AuthentikController::connect + path: /oauth/authentik/connect + methods: [ GET ] + +oauth_authentik_verify: + controller: App\Controller\Security\AuthentikController::verify + path: /oauth/authentik/verify + methods: [ GET ] + oauth_create_client: controller: App\Controller\Api\OAuth2\CreateClientApi path: /api/client diff --git a/config/packages/knpu_oauth2_client.yaml b/config/packages/knpu_oauth2_client.yaml index bb547e394..91443b918 100644 --- a/config/packages/knpu_oauth2_client.yaml +++ b/config/packages/knpu_oauth2_client.yaml @@ -51,3 +51,12 @@ knpu_oauth2_client: redirect_route: oauth_zitadel_verify redirect_params: { } provider_class: 'App\Provider\Zitadel' + authentik: + type: generic + client_id: '%oauth_authentik_id%' + client_secret: '%oauth_authentik_secret%' + provider_options: + base_url: '%oauth_authentik_base_url%' + redirect_route: oauth_authentik_verify + redirect_params: { } + provider_class: 'App\Provider\Authentik' \ No newline at end of file diff --git a/config/packages/security.yaml b/config/packages/security.yaml index d77cda718..0e6b5a847 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -40,6 +40,7 @@ security: - App\Security\KeycloakAuthenticator - App\Security\SimpleLoginAuthenticator - App\Security\ZitadelAuthenticator + - App\Security\AuthentikAuthenticator logout: enable_csrf: true path: app_logout diff --git a/config/services.yaml b/config/services.yaml index f610510b3..4290f94b6 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -60,6 +60,10 @@ parameters: oauth_zitadel_secret: "%env(OAUTH_ZITADEL_SECRET)%" oauth_zitadel_base_url: "%env(OAUTH_ZITADEL_BASE_URL)%" + oauth_authentik_id: "%env(default::OAUTH_AUTHENTIK_ID)%" + oauth_authentik_secret: "%env(OAUTH_AUTHENTIK_SECRET)%" + oauth_authentik_base_url: "%env(OAUTH_AUTHENTIK_BASE_URL)%" + router.request_context.host: "%env(KBIN_DOMAIN)%" router.request_context.scheme: https diff --git a/migrations/Version20240603230734.php b/migrations/Version20240603230734.php new file mode 100644 index 000000000..b7a73202d --- /dev/null +++ b/migrations/Version20240603230734.php @@ -0,0 +1,29 @@ +addSql('ALTER TABLE "user" ADD oauth_authentik_id VARCHAR(255) DEFAULT NULL'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE "user" DROP oauth_authentik_id'); + } +} diff --git a/src/Controller/Security/AuthentikController.php b/src/Controller/Security/AuthentikController.php new file mode 100644 index 000000000..2152e4709 --- /dev/null +++ b/src/Controller/Security/AuthentikController.php @@ -0,0 +1,28 @@ +getClient('authentik') + ->redirect([ + 'openid', + 'email', + 'profile', + ]); + } + + public function verify(Request $request, ClientRegistry $client) + { + } +} diff --git a/src/Entity/User.php b/src/Entity/User.php index 71dddb727..120912036 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -122,6 +122,8 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface, Visibil public ?string $oauthSimpleLoginId = null; #[Column(type: 'string', nullable: true)] public ?string $oauthZitadelId = null; + #[Column(type: 'string', nullable: true)] + public ?string $oauthAuthentikId = null; #[Column(type: 'boolean', nullable: false, options: ['default' => true])] public bool $hideAdult = true; #[Column(type: 'json', nullable: false, options: ['jsonb' => true, 'default' => '[]'])] @@ -757,7 +759,7 @@ public function removeOAuth2UserConsent(OAuth2UserConsent $oAuth2UserConsent): s public function isSsoControlled(): bool { - return $this->oauthAzureId || $this->oauthGithubId || $this->oauthGoogleId || $this->oauthFacebookId || $this->oauthKeycloakId || $this->oauthSimpleLoginId || $this->oauthZitadelId; + return $this->oauthAzureId || $this->oauthGithubId || $this->oauthGoogleId || $this->oauthFacebookId || $this->oauthKeycloakId || $this->oauthSimpleLoginId || $this->oauthZitadelId || $this->oauthAuthentikId; } public function getCustomCss(): ?string diff --git a/src/Provider/Authentik.php b/src/Provider/Authentik.php new file mode 100644 index 000000000..ab2de54bc --- /dev/null +++ b/src/Provider/Authentik.php @@ -0,0 +1,74 @@ +baseUrl = $options['base_url'] ?? ''; + + parent::__construct($options, $collaborators); + } + + protected function getBaseUrl() + { + return rtrim($this->baseUrl, '/').'/'; + } + + protected function getAuthorizationHeaders($token = null) + { + return ['Authorization' => 'Bearer '.$token]; + } + + public function getBaseAuthorizationUrl() + { + return $this->getBaseUrl().'application/o/authorize/'; + } + + public function getBaseAccessTokenUrl(array $params) + { + return $this->getBaseUrl().'application/o/token/'; + } + + public function getResourceOwnerDetailsUrl(AccessToken $token) + { + return $this->getBaseUrl().'application/o/userinfo/'; + } + + protected function getDefaultScopes() + { + return ['openid', 'profile', 'email']; + } + + protected function checkResponse(ResponseInterface $response, $data) + { + if (!empty($data['error'])) { + $error = htmlentities($data['error'], ENT_QUOTES, 'UTF-8'); + $message = htmlentities($data['error_description'], ENT_QUOTES, 'UTF-8'); + throw new IdentityProviderException($message, $response->getStatusCode(), $response); + } + } + + protected function createResourceOwner(array $response, AccessToken $token) + { + return new AuthentikResourceOwner($response); + } + + protected function getScopeSeparator() + { + return ' '; + } +} diff --git a/src/Provider/AuthentikResourceOwner.php b/src/Provider/AuthentikResourceOwner.php new file mode 100644 index 000000000..9a608ad83 --- /dev/null +++ b/src/Provider/AuthentikResourceOwner.php @@ -0,0 +1,68 @@ +response = $response; + } + + public function getId() + { + return $this->getResponseValue('sub'); + } + + public function getEmail() + { + return $this->getResponseValue('email'); + } + + public function getFamilyName() + { + return $this->getResponseValue('family_name'); + } + + public function getGivenName() + { + return $this->getResponseValue('given_name'); + } + + public function getPreferredUsername() + { + return $this->getResponseValue('preferred_username'); + } + + public function getPictureUrl() + { + return $this->getResponseValue('picture'); + } + + public function toArray() + { + return $this->response; + } + + protected function getResponseValue($key) + { + $keys = explode('.', $key); + $value = $this->response; + + foreach ($keys as $k) { + if (isset($value[$k])) { + $value = $value[$k]; + } else { + return null; + } + } + + return $value; + } +} diff --git a/src/Security/AuthentikAuthenticator.php b/src/Security/AuthentikAuthenticator.php new file mode 100644 index 000000000..828cabbda --- /dev/null +++ b/src/Security/AuthentikAuthenticator.php @@ -0,0 +1,178 @@ +attributes->get('_route'); + } + + public function authenticate(Request $request): Passport + { + $client = $this->clientRegistry->getClient('authentik'); + $slugger = $this->slugger; + + $provider = $client->getOAuth2Provider(); + + $accessToken = $provider->getAccessToken('authorization_code', [ + 'code' => $request->query->get('code'), + ]); + + $rememberBadge = new RememberMeBadge(); + $rememberBadge = $rememberBadge->enable(); + + return new SelfValidatingPassport( + new UserBadge($accessToken->getToken(), function () use ($accessToken, $client, $slugger) { + /** @var AuthentikResourceOwner $authentikUser */ + $authentikUser = $client->fetchUserFromToken($accessToken); + + $existingUser = $this->entityManager->getRepository(User::class)->findOneBy( + ['oauthAuthentikId' => $authentikUser->getId()] + ); + + if ($existingUser) { + return $existingUser; + } + + $user = $this->userRepository->findOneBy(['email' => $authentikUser->getEmail()]); + + if ($user) { + $user->oauthAuthentikId = $authentikUser->getId(); + + $this->entityManager->persist($user); + $this->entityManager->flush(); + + return $user; + } + + if (false === $this->settingsManager->get('MBIN_SSO_REGISTRATIONS_ENABLED')) { + throw new CustomUserMessageAuthenticationException('MBIN_SSO_REGISTRATIONS_ENABLED'); + } + + $email = $authentikUser->toArray()['preferred_username']; + $username = $slugger->slug(substr($email, 0, strrpos($email, '@'))); + + if ($this->userRepository->count(['username' => $username]) > 0) { + $username .= rand(1, 999); + } + + $dto = (new UserDto())->create( + $username, + $authentikUser->getEmail() + ); + + $avatar = $this->getAvatar($authentikUser->getPictureUrl()); + + if ($avatar) { + $dto->avatar = $this->imageFactory->createDto($avatar); + } + + $dto->plainPassword = bin2hex(random_bytes(20)); + $dto->ip = $this->ipResolver->resolve(); + + $user = $this->userManager->create($dto, false); + $user->oauthAuthentikId = $authentikUser->getId(); + $user->avatar = $this->getAvatar($authentikUser->getPictureUrl()); + $user->isVerified = true; + + $this->entityManager->persist($user); + $this->entityManager->flush(); + + return $user; + }), + [ + $rememberBadge, + ] + ); + } + + private function getAvatar(?string $pictureUrl): ?Image + { + if (!$pictureUrl) { + return null; + } + + try { + $tempFile = $this->imageManager->download($pictureUrl); + } catch (\Exception $e) { + $tempFile = null; + } + + if ($tempFile) { + $image = $this->imageRepository->findOrCreateFromPath($tempFile); + if ($image) { + $this->entityManager->persist($image); + $this->entityManager->flush(); + } + } + + return $image ?? null; + } + + public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response + { + $targetUrl = $this->router->generate('front'); + + return new RedirectResponse($targetUrl); + } + + public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response + { + $message = strtr($exception->getMessageKey(), $exception->getMessageData()); + + if ('MBIN_SSO_REGISTRATIONS_ENABLED' === $message) { + $session = $request->getSession(); + $session->getFlashBag()->add('error', 'sso_registrations_enabled.error'); + + return new RedirectResponse($this->router->generate('app_login')); + } + + return new Response($message, Response::HTTP_FORBIDDEN); + } +} diff --git a/src/Twig/Components/LoginSocialsComponent.php b/src/Twig/Components/LoginSocialsComponent.php index 9f1979b83..4b614d578 100644 --- a/src/Twig/Components/LoginSocialsComponent.php +++ b/src/Twig/Components/LoginSocialsComponent.php @@ -23,6 +23,8 @@ public function __construct( private readonly ?string $oauthSimpleLoginId, #[Autowire('%oauth_zitadel_id%')] private readonly ?string $oauthZitadelId, + #[Autowire('%oauth_authentik_id%')] + private readonly ?string $oauthAuthentikId, #[Autowire('%oauth_azure_id%')] private readonly ?string $oauthAzureId, ) { @@ -58,6 +60,11 @@ public function zitadelEnabled(): bool return !empty($this->oauthZitadelId); } + public function authentikEnabled(): bool + { + return !empty($this->oauthAuthentikId); + } + public function azureEnabled(): bool { return !empty($this->oauthAzureId); diff --git a/templates/components/login_socials.html.twig b/templates/components/login_socials.html.twig index fd94e4987..d9ab5bf6d 100644 --- a/templates/components/login_socials.html.twig +++ b/templates/components/login_socials.html.twig @@ -1,5 +1,5 @@ {# @var this App\Twig\Components\LoginSocialsComponent #} -{%- set HAS_ANY_SOCIAL = this.googleEnabled or this.facebookEnabled or this.githubEnabled or this.keycloakEnabled or this.simpleloginEnabled or this.zitadelEnabled or this.azureEnabled -%} +{%- set HAS_ANY_SOCIAL = this.googleEnabled or this.facebookEnabled or this.githubEnabled or this.keycloakEnabled or this.simpleloginEnabled or this.zitadelEnabled or this.authentikEnabled or this.azureEnabled -%} {% if HAS_ANY_SOCIAL %} {% if not mbin_sso_only_mode() and not mbin_sso_show_first() %}
    @@ -29,6 +29,10 @@ {{ 'continue_with'|trans }} Zitadel {% endif %} + {% if this.authentikEnabled %} + + {{ 'continue_with'|trans }} Authentik + {% endif %} {% if this.azureEnabled %} {{ 'continue_with'|trans }} Microsoft From 9389aa2b4e331b5fee6fa9820964995b887a6360 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Thu, 6 Jun 2024 10:30:56 +0000 Subject: [PATCH 028/335] Add moderator updates to the modlog (#799) Co-authored-by: debounced <35878315+nobodyatroot@users.noreply.github.com> --- migrations/Version20240528172429.php | 30 ++++++++++++++ src/Entity/MagazineLog.php | 2 + src/Entity/MagazineLogModeratorAdd.php | 39 +++++++++++++++++++ src/Entity/MagazineLogModeratorRemove.php | 39 +++++++++++++++++++ ...agazineModeratorAddedRemovedSubscriber.php | 10 +++++ templates/modlog/_blocks.html.twig | 8 ++++ translations/messages.en.yaml | 2 + 7 files changed, 130 insertions(+) create mode 100644 migrations/Version20240528172429.php create mode 100644 src/Entity/MagazineLogModeratorAdd.php create mode 100644 src/Entity/MagazineLogModeratorRemove.php diff --git a/migrations/Version20240528172429.php b/migrations/Version20240528172429.php new file mode 100644 index 000000000..e65a73d1e --- /dev/null +++ b/migrations/Version20240528172429.php @@ -0,0 +1,30 @@ +addSql('ALTER TABLE magazine_log ADD acting_user_id INT DEFAULT NULL'); + $this->addSql('ALTER TABLE magazine_log ADD CONSTRAINT FK_87D3D4C53EAD8611 FOREIGN KEY (acting_user_id) REFERENCES "user" (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('CREATE INDEX IDX_87D3D4C53EAD8611 ON magazine_log (acting_user_id)'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE magazine_log DROP CONSTRAINT FK_87D3D4C53EAD8611'); + $this->addSql('DROP INDEX IDX_87D3D4C53EAD8611'); + $this->addSql('ALTER TABLE magazine_log DROP acting_user_id'); + } +} diff --git a/src/Entity/MagazineLog.php b/src/Entity/MagazineLog.php index adbe59875..cc23bfa21 100644 --- a/src/Entity/MagazineLog.php +++ b/src/Entity/MagazineLog.php @@ -30,6 +30,8 @@ 'post_comment_deleted' => MagazineLogPostCommentDeleted::class, 'post_comment_restored' => MagazineLogPostCommentRestored::class, 'ban' => MagazineLogBan::class, + 'moderator_add' => MagazineLogModeratorAdd::class, + 'moderator_remove' => MagazineLogModeratorRemove::class, ])] abstract class MagazineLog { diff --git a/src/Entity/MagazineLogModeratorAdd.php b/src/Entity/MagazineLogModeratorAdd.php new file mode 100644 index 000000000..19724b137 --- /dev/null +++ b/src/Entity/MagazineLogModeratorAdd.php @@ -0,0 +1,39 @@ +actingUser = $actingUser; + } + + public function getSubject(): ContentInterface|null + { + return null; + } + + public function clearSubject(): MagazineLog + { + return $this; + } + + public function getType(): string + { + return 'log_moderator_add'; + } +} diff --git a/src/Entity/MagazineLogModeratorRemove.php b/src/Entity/MagazineLogModeratorRemove.php new file mode 100644 index 000000000..a434d2697 --- /dev/null +++ b/src/Entity/MagazineLogModeratorRemove.php @@ -0,0 +1,39 @@ +actingUser = $actingUser; + } + + public function getSubject(): ContentInterface|null + { + return null; + } + + public function clearSubject(): MagazineLog + { + return $this; + } + + public function getType(): string + { + return 'log_moderator_remove'; + } +} diff --git a/src/EventSubscriber/ActivityPub/MagazineModeratorAddedRemovedSubscriber.php b/src/EventSubscriber/ActivityPub/MagazineModeratorAddedRemovedSubscriber.php index 61ea8cd30..f7fb11a0e 100644 --- a/src/EventSubscriber/ActivityPub/MagazineModeratorAddedRemovedSubscriber.php +++ b/src/EventSubscriber/ActivityPub/MagazineModeratorAddedRemovedSubscriber.php @@ -5,10 +5,13 @@ namespace App\EventSubscriber\ActivityPub; use App\Entity\Magazine; +use App\Entity\MagazineLogModeratorAdd; +use App\Entity\MagazineLogModeratorRemove; use App\Event\Magazine\MagazineModeratorAddedEvent; use App\Event\Magazine\MagazineModeratorRemovedEvent; use App\Message\ActivityPub\Outbox\AddMessage; use App\Message\ActivityPub\Outbox\RemoveMessage; +use Doctrine\ORM\EntityManagerInterface; use Psr\Cache\InvalidArgumentException; use Psr\Log\LoggerInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -21,6 +24,7 @@ public function __construct( private readonly MessageBusInterface $bus, private readonly CacheInterface $cache, private readonly LoggerInterface $logger, + private readonly EntityManagerInterface $entityManager, ) { } @@ -30,6 +34,9 @@ public function onModeratorAdded(MagazineModeratorAddedEvent $event): void if (!$event->magazine->apId or (null !== $event->addedBy and !$event->addedBy->apId)) { $this->bus->dispatch(new AddMessage($event->addedBy->getId(), $event->magazine->getId(), $event->user->getId())); } + $log = new MagazineLogModeratorAdd($event->magazine, $event->user, $event->addedBy); + $this->entityManager->persist($log); + $this->entityManager->flush(); $this->deleteCache($event->magazine); } @@ -39,6 +46,9 @@ public function onModeratorRemoved(MagazineModeratorRemovedEvent $event): void if (!$event->magazine->apId or (null !== $event->removedBy and !$event->removedBy->apId)) { $this->bus->dispatch(new RemoveMessage($event->removedBy->getId(), $event->magazine->getId(), $event->user->getId())); } + $log = new MagazineLogModeratorRemove($event->magazine, $event->user, $event->removedBy); + $this->entityManager->persist($log); + $this->entityManager->flush(); $this->deleteCache($event->magazine); } diff --git a/templates/modlog/_blocks.html.twig b/templates/modlog/_blocks.html.twig index c48e56f48..5e7a21392 100644 --- a/templates/modlog/_blocks.html.twig +++ b/templates/modlog/_blocks.html.twig @@ -42,3 +42,11 @@ {{ component('user_inline', {user: log.user, showAvatar: false}) }} {% if log.meta is same as 'ban' %}{{ 'he_banned'|trans|lower }}{% else %}{{ 'he_unbanned'|trans|lower }}{% endif %} {{ component('user_inline', {user: log.ban.user, showAvatar: false}) }} {% if showMagazine %} {{ 'in'|trans|lower }} {{ component('magazine_inline', {magazine: log.ban.magazine, showIcon: false }) }}{% endif %}{% if log.ban.reason %} - {{ log.ban.reason }}{% endif %} {% endblock %} + +{% block log_moderator_add %} + {{ component('user_inline', {user: log.actingUser}) }} {{ 'magazine_log_mod_added'|trans }}: {{ component('user_inline', {user: log.user}) }} +{% endblock %} + +{% block log_moderator_remove %} + {{ component('user_inline', {user: log.actingUser}) }} {{ 'magazine_log_mod_removed'|trans }}: {{ component('user_inline', {user: log.user}) }} +{% endblock %} diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml index b78fb8cd2..ff6e41092 100644 --- a/translations/messages.en.yaml +++ b/translations/messages.en.yaml @@ -824,3 +824,5 @@ related_entry: Related restrict_magazine_creation: Restrict local magazine creation to admins and global mods sso_show_first: Show SSO first on login and registration pages continue_with: Continue with +magazine_log_mod_added: has added a moderator +magazine_log_mod_removed: has removed a moderator From 2f6b8ffa662770084f7bf81fcc921318f0b620b4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 6 Jun 2024 08:18:24 -0500 Subject: [PATCH 029/335] docs(contributor): contributors readme action update (#808) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: debounced <35878315+nobodyatroot@users.noreply.github.com> --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 3a6dba331..f3384e03a 100644 --- a/README.md +++ b/README.md @@ -189,6 +189,13 @@ For developers: + + + CocoPoops +
    + CocoPoops +
    + garrettw @@ -210,13 +217,6 @@ For developers: Bryson - - - CocoPoops -
    - CocoPoops -
    - vpzomtrrfrt From 38232bb46c96ed59f5613bf1a62df3bf86606290 Mon Sep 17 00:00:00 2001 From: debounced <35878315+nobodyatroot@users.noreply.github.com> Date: Thu, 6 Jun 2024 09:00:20 -0500 Subject: [PATCH 030/335] Docker caddy version bump (#813) --- docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index dfe9729f3..683a45faf 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -36,7 +36,7 @@ RUN chown -R $USER:$GROUP /usr/local/etc/php-fpm.d #################### -FROM caddy:2.8.1-builder-alpine AS builder-caddy +FROM caddy:2.8.4-builder-alpine AS builder-caddy # Build Caddy with the Mercure and Vulcain and brotil cache modules RUN xcaddy build \ From 1e6d471b4396f552c6a1a3613179b75883b79739 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Thu, 6 Jun 2024 14:20:41 +0000 Subject: [PATCH 031/335] fix modlog error when the user adding/removing a moderator is null (#812) --- templates/modlog/_blocks.html.twig | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/templates/modlog/_blocks.html.twig b/templates/modlog/_blocks.html.twig index 5e7a21392..7e64b98d4 100644 --- a/templates/modlog/_blocks.html.twig +++ b/templates/modlog/_blocks.html.twig @@ -44,9 +44,15 @@ {% endblock %} {% block log_moderator_add %} - {{ component('user_inline', {user: log.actingUser}) }} {{ 'magazine_log_mod_added'|trans }}: {{ component('user_inline', {user: log.user}) }} + {% if log.actingUser is not same as null %} + {{ component('user_inline', {user: log.actingUser}) }} + {% endif %} + {{ 'magazine_log_mod_added'|trans }}: {{ component('user_inline', {user: log.user}) }} {% endblock %} {% block log_moderator_remove %} - {{ component('user_inline', {user: log.actingUser}) }} {{ 'magazine_log_mod_removed'|trans }}: {{ component('user_inline', {user: log.user}) }} + {% if log.actingUser is not same as null %} + {{ component('user_inline', {user: log.actingUser}) }} + {% endif %} + {{ 'magazine_log_mod_removed'|trans }}: {{ component('user_inline', {user: log.user}) }} {% endblock %} From 23a9e02ff83b7b876e77d006a49fc5c572d28297 Mon Sep 17 00:00:00 2001 From: debounced <35878315+nobodyatroot@users.noreply.github.com> Date: Tue, 11 Jun 2024 19:55:29 -0500 Subject: [PATCH 032/335] Bump Symfony Framework to 7.0.8 (#816) --- composer.lock | 814 +++++++++++++++++++++++++------------------------- 1 file changed, 409 insertions(+), 405 deletions(-) diff --git a/composer.lock b/composer.lock index 590efdce9..08b796ee4 100644 --- a/composer.lock +++ b/composer.lock @@ -7357,16 +7357,16 @@ }, { "name": "symfony/amqp-messenger", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/amqp-messenger.git", - "reference": "65ed12f46fc542d9b855af94ced90563cabbbad7" + "reference": "4bccb7fa731bf5787f49c51e122e8728ec0f1eef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/amqp-messenger/zipball/65ed12f46fc542d9b855af94ced90563cabbbad7", - "reference": "65ed12f46fc542d9b855af94ced90563cabbbad7", + "url": "https://api.github.com/repos/symfony/amqp-messenger/zipball/4bccb7fa731bf5787f49c51e122e8728ec0f1eef", + "reference": "4bccb7fa731bf5787f49c51e122e8728ec0f1eef", "shasum": "" }, "require": { @@ -7406,7 +7406,7 @@ "description": "Symfony AMQP extension Messenger Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/amqp-messenger/tree/v7.0.7" + "source": "https://github.com/symfony/amqp-messenger/tree/v7.0.8" }, "funding": [ { @@ -7422,20 +7422,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/asset", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/asset.git", - "reference": "dc7600afc7e6676b3401326ae9c9abfcee4b40c5" + "reference": "0f106714bb8d857560edd2ada7f387d2f437c830" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/asset/zipball/dc7600afc7e6676b3401326ae9c9abfcee4b40c5", - "reference": "dc7600afc7e6676b3401326ae9c9abfcee4b40c5", + "url": "https://api.github.com/repos/symfony/asset/zipball/0f106714bb8d857560edd2ada7f387d2f437c830", + "reference": "0f106714bb8d857560edd2ada7f387d2f437c830", "shasum": "" }, "require": { @@ -7475,7 +7475,7 @@ "description": "Manages URL generation and versioning of web assets such as CSS stylesheets, JavaScript files and image files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/asset/tree/v7.0.7" + "source": "https://github.com/symfony/asset/tree/v7.0.8" }, "funding": [ { @@ -7491,20 +7491,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/cache", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "48e3508338987d63b0114a00c208c4cbb76e5303" + "reference": "0070bd599ab52c8dc87fa7b782810cba4fde9d06" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/48e3508338987d63b0114a00c208c4cbb76e5303", - "reference": "48e3508338987d63b0114a00c208c4cbb76e5303", + "url": "https://api.github.com/repos/symfony/cache/zipball/0070bd599ab52c8dc87fa7b782810cba4fde9d06", + "reference": "0070bd599ab52c8dc87fa7b782810cba4fde9d06", "shasum": "" }, "require": { @@ -7571,7 +7571,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v7.0.7" + "source": "https://github.com/symfony/cache/tree/v7.0.8" }, "funding": [ { @@ -7587,7 +7587,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/cache-contracts", @@ -7667,16 +7667,16 @@ }, { "name": "symfony/clock", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/clock.git", - "reference": "2008671acb4a30b01c453de193cf9c80549ebda6" + "reference": "817e27b87908632f647f8684a603b70ec89b75e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/clock/zipball/2008671acb4a30b01c453de193cf9c80549ebda6", - "reference": "2008671acb4a30b01c453de193cf9c80549ebda6", + "url": "https://api.github.com/repos/symfony/clock/zipball/817e27b87908632f647f8684a603b70ec89b75e4", + "reference": "817e27b87908632f647f8684a603b70ec89b75e4", "shasum": "" }, "require": { @@ -7721,7 +7721,7 @@ "time" ], "support": { - "source": "https://github.com/symfony/clock/tree/v7.0.7" + "source": "https://github.com/symfony/clock/tree/v7.0.8" }, "funding": [ { @@ -7737,20 +7737,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/config", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "f66f908a975500aa4594258bf454dc66e3939eac" + "reference": "f8a8fb0c2d0a188a00a2dd5af8a4eb070641ec60" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/f66f908a975500aa4594258bf454dc66e3939eac", - "reference": "f66f908a975500aa4594258bf454dc66e3939eac", + "url": "https://api.github.com/repos/symfony/config/zipball/f8a8fb0c2d0a188a00a2dd5af8a4eb070641ec60", + "reference": "f8a8fb0c2d0a188a00a2dd5af8a4eb070641ec60", "shasum": "" }, "require": { @@ -7796,7 +7796,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v7.0.7" + "source": "https://github.com/symfony/config/tree/v7.0.8" }, "funding": [ { @@ -7812,20 +7812,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/console", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "c981e0e9380ce9f146416bde3150c79197ce9986" + "reference": "725da159ff1e502183b9bf412535a63ebc75fd75" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/c981e0e9380ce9f146416bde3150c79197ce9986", - "reference": "c981e0e9380ce9f146416bde3150c79197ce9986", + "url": "https://api.github.com/repos/symfony/console/zipball/725da159ff1e502183b9bf412535a63ebc75fd75", + "reference": "725da159ff1e502183b9bf412535a63ebc75fd75", "shasum": "" }, "require": { @@ -7889,7 +7889,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.0.7" + "source": "https://github.com/symfony/console/tree/v7.0.8" }, "funding": [ { @@ -7905,20 +7905,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/css-selector", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "b08a4ad89e84b29cec285b7b1f781a7ae51cf4bc" + "reference": "63b9f8c9b3c28c43ad06764c67fe092af2576d17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/b08a4ad89e84b29cec285b7b1f781a7ae51cf4bc", - "reference": "b08a4ad89e84b29cec285b7b1f781a7ae51cf4bc", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/63b9f8c9b3c28c43ad06764c67fe092af2576d17", + "reference": "63b9f8c9b3c28c43ad06764c67fe092af2576d17", "shasum": "" }, "require": { @@ -7954,7 +7954,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v7.0.7" + "source": "https://github.com/symfony/css-selector/tree/v7.0.8" }, "funding": [ { @@ -7970,20 +7970,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/dependency-injection", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "4db1314337f4dd864113f88e08c9a7f98b1c1324" + "reference": "cd4f7774e0d38a8e932922d5afca5681db7004b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/4db1314337f4dd864113f88e08c9a7f98b1c1324", - "reference": "4db1314337f4dd864113f88e08c9a7f98b1c1324", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/cd4f7774e0d38a8e932922d5afca5681db7004b6", + "reference": "cd4f7774e0d38a8e932922d5afca5681db7004b6", "shasum": "" }, "require": { @@ -8034,7 +8034,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v7.0.7" + "source": "https://github.com/symfony/dependency-injection/tree/v7.0.8" }, "funding": [ { @@ -8050,7 +8050,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/deprecation-contracts", @@ -8121,16 +8121,16 @@ }, { "name": "symfony/doctrine-bridge", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "da605530d1a75162359d494efc00f767f7fcd68a" + "reference": "5a5555e4e0e8144edebc55d118cb825a9b8293a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/da605530d1a75162359d494efc00f767f7fcd68a", - "reference": "da605530d1a75162359d494efc00f767f7fcd68a", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/5a5555e4e0e8144edebc55d118cb825a9b8293a0", + "reference": "5a5555e4e0e8144edebc55d118cb825a9b8293a0", "shasum": "" }, "require": { @@ -8207,7 +8207,7 @@ "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/doctrine-bridge/tree/v7.0.7" + "source": "https://github.com/symfony/doctrine-bridge/tree/v7.0.8" }, "funding": [ { @@ -8223,20 +8223,20 @@ "type": "tidelift" } ], - "time": "2024-04-28T11:44:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/doctrine-messenger", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-messenger.git", - "reference": "78ec63bf2437187ac70ca13a2db3f2a8e41b3493" + "reference": "8b86a71fafa47c17cf631a737e76c5220624a2dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-messenger/zipball/78ec63bf2437187ac70ca13a2db3f2a8e41b3493", - "reference": "78ec63bf2437187ac70ca13a2db3f2a8e41b3493", + "url": "https://api.github.com/repos/symfony/doctrine-messenger/zipball/8b86a71fafa47c17cf631a737e76c5220624a2dc", + "reference": "8b86a71fafa47c17cf631a737e76c5220624a2dc", "shasum": "" }, "require": { @@ -8279,7 +8279,7 @@ "description": "Symfony Doctrine Messenger Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/doctrine-messenger/tree/v7.0.7" + "source": "https://github.com/symfony/doctrine-messenger/tree/v7.0.8" }, "funding": [ { @@ -8295,20 +8295,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/dotenv", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/dotenv.git", - "reference": "0fd573c141e1990848702d56329050efd5bf25cc" + "reference": "73ba4287d5b6cd5d67fe5a08987981842a599313" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dotenv/zipball/0fd573c141e1990848702d56329050efd5bf25cc", - "reference": "0fd573c141e1990848702d56329050efd5bf25cc", + "url": "https://api.github.com/repos/symfony/dotenv/zipball/73ba4287d5b6cd5d67fe5a08987981842a599313", + "reference": "73ba4287d5b6cd5d67fe5a08987981842a599313", "shasum": "" }, "require": { @@ -8353,7 +8353,7 @@ "environment" ], "support": { - "source": "https://github.com/symfony/dotenv/tree/v7.0.7" + "source": "https://github.com/symfony/dotenv/tree/v7.0.8" }, "funding": [ { @@ -8369,20 +8369,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/error-handler", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "cf97429887e40480c847bfeb6c3991e1e2c086ab" + "reference": "82eb27b303fe31f1169f86a8d4d5dcc63ff64a31" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/cf97429887e40480c847bfeb6c3991e1e2c086ab", - "reference": "cf97429887e40480c847bfeb6c3991e1e2c086ab", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/82eb27b303fe31f1169f86a8d4d5dcc63ff64a31", + "reference": "82eb27b303fe31f1169f86a8d4d5dcc63ff64a31", "shasum": "" }, "require": { @@ -8428,7 +8428,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v7.0.7" + "source": "https://github.com/symfony/error-handler/tree/v7.0.8" }, "funding": [ { @@ -8444,20 +8444,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "db2a7fab994d67d92356bb39c367db115d9d30f9" + "reference": "5c30c7fc4ccf847e4dd8a18b6158cb1f77702550" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/db2a7fab994d67d92356bb39c367db115d9d30f9", - "reference": "db2a7fab994d67d92356bb39c367db115d9d30f9", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/5c30c7fc4ccf847e4dd8a18b6158cb1f77702550", + "reference": "5c30c7fc4ccf847e4dd8a18b6158cb1f77702550", "shasum": "" }, "require": { @@ -8508,7 +8508,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.0.7" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.0.8" }, "funding": [ { @@ -8524,7 +8524,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -8604,16 +8604,16 @@ }, { "name": "symfony/expression-language", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/expression-language.git", - "reference": "b8ec919a6d3d47fc4e7845c256d164413207bf73" + "reference": "8e64bd4eb4c4dd180fc7de9c72011c49ebbdc822" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/expression-language/zipball/b8ec919a6d3d47fc4e7845c256d164413207bf73", - "reference": "b8ec919a6d3d47fc4e7845c256d164413207bf73", + "url": "https://api.github.com/repos/symfony/expression-language/zipball/8e64bd4eb4c4dd180fc7de9c72011c49ebbdc822", + "reference": "8e64bd4eb4c4dd180fc7de9c72011c49ebbdc822", "shasum": "" }, "require": { @@ -8647,7 +8647,7 @@ "description": "Provides an engine that can compile and evaluate expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/expression-language/tree/v7.0.7" + "source": "https://github.com/symfony/expression-language/tree/v7.0.8" }, "funding": [ { @@ -8663,26 +8663,28 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/filesystem", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "cc168be6fbdcdf3401f50ae863ee3818ed4338f5" + "reference": "a7a171e363186fe78b7c696720a37da4cf052d52" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/cc168be6fbdcdf3401f50ae863ee3818ed4338f5", - "reference": "cc168be6fbdcdf3401f50ae863ee3818ed4338f5", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/a7a171e363186fe78b7c696720a37da4cf052d52", + "reference": "a7a171e363186fe78b7c696720a37da4cf052d52", "shasum": "" }, "require": { "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "require-dev": { "symfony/process": "^6.4|^7.0" }, "type": "library", @@ -8711,7 +8713,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.0.7" + "source": "https://github.com/symfony/filesystem/tree/v7.0.8" }, "funding": [ { @@ -8727,20 +8729,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/finder", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "4d58f0f4fe95a30d7b538d71197135483560b97c" + "reference": "f7f198c76b0b27d6b9d1684dd03d6e6050e35bfb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/4d58f0f4fe95a30d7b538d71197135483560b97c", - "reference": "4d58f0f4fe95a30d7b538d71197135483560b97c", + "url": "https://api.github.com/repos/symfony/finder/zipball/f7f198c76b0b27d6b9d1684dd03d6e6050e35bfb", + "reference": "f7f198c76b0b27d6b9d1684dd03d6e6050e35bfb", "shasum": "" }, "require": { @@ -8775,7 +8777,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.0.7" + "source": "https://github.com/symfony/finder/tree/v7.0.8" }, "funding": [ { @@ -8791,7 +8793,7 @@ "type": "tidelift" } ], - "time": "2024-04-28T11:44:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/flex", @@ -8860,16 +8862,16 @@ }, { "name": "symfony/form", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/form.git", - "reference": "b4df6a399a2b03782a0163807239db342659f54f" + "reference": "1d0128e2f7e80c346ec51fa4d1ce4fec0d435eeb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/form/zipball/b4df6a399a2b03782a0163807239db342659f54f", - "reference": "b4df6a399a2b03782a0163807239db342659f54f", + "url": "https://api.github.com/repos/symfony/form/zipball/1d0128e2f7e80c346ec51fa4d1ce4fec0d435eeb", + "reference": "1d0128e2f7e80c346ec51fa4d1ce4fec0d435eeb", "shasum": "" }, "require": { @@ -8936,7 +8938,7 @@ "description": "Allows to easily create, process and reuse HTML forms", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/form/tree/v7.0.7" + "source": "https://github.com/symfony/form/tree/v7.0.8" }, "funding": [ { @@ -8952,20 +8954,20 @@ "type": "tidelift" } ], - "time": "2024-04-28T11:44:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/framework-bundle", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/framework-bundle.git", - "reference": "5d9cee370509056b8b7a5009d7112d045d8f0a64" + "reference": "f79d0eefe0a1e5a6858ad59f6fef470ec5ae13db" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/5d9cee370509056b8b7a5009d7112d045d8f0a64", - "reference": "5d9cee370509056b8b7a5009d7112d045d8f0a64", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/f79d0eefe0a1e5a6858ad59f6fef470ec5ae13db", + "reference": "f79d0eefe0a1e5a6858ad59f6fef470ec5ae13db", "shasum": "" }, "require": { @@ -9082,7 +9084,7 @@ "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/framework-bundle/tree/v7.0.7" + "source": "https://github.com/symfony/framework-bundle/tree/v7.0.8" }, "funding": [ { @@ -9098,20 +9100,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/http-client", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "6ce3c4c899051b3d7326ea1a1dda3729e29ae6d7" + "reference": "7a05958fd4ecc139e2aa3ae7455f19c2cb4e08af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/6ce3c4c899051b3d7326ea1a1dda3729e29ae6d7", - "reference": "6ce3c4c899051b3d7326ea1a1dda3729e29ae6d7", + "url": "https://api.github.com/repos/symfony/http-client/zipball/7a05958fd4ecc139e2aa3ae7455f19c2cb4e08af", + "reference": "7a05958fd4ecc139e2aa3ae7455f19c2cb4e08af", "shasum": "" }, "require": { @@ -9174,7 +9176,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v7.0.7" + "source": "https://github.com/symfony/http-client/tree/v7.0.8" }, "funding": [ { @@ -9190,7 +9192,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/http-client-contracts", @@ -9272,16 +9274,16 @@ }, { "name": "symfony/http-foundation", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "0194e064b8bdc29381462f790bab04e1cac8fdc8" + "reference": "c7bd24f7a5b50974cbca5d78de2ce5ed73a12628" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/0194e064b8bdc29381462f790bab04e1cac8fdc8", - "reference": "0194e064b8bdc29381462f790bab04e1cac8fdc8", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/c7bd24f7a5b50974cbca5d78de2ce5ed73a12628", + "reference": "c7bd24f7a5b50974cbca5d78de2ce5ed73a12628", "shasum": "" }, "require": { @@ -9329,7 +9331,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.0.7" + "source": "https://github.com/symfony/http-foundation/tree/v7.0.8" }, "funding": [ { @@ -9345,20 +9347,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/http-kernel", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "e07bb9bd86e7cd8ba2d3d9c618eec9d1bbe06d25" + "reference": "2e5adbfaabd29f9c03c3678cfcd858bb2cafa184" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/e07bb9bd86e7cd8ba2d3d9c618eec9d1bbe06d25", - "reference": "e07bb9bd86e7cd8ba2d3d9c618eec9d1bbe06d25", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/2e5adbfaabd29f9c03c3678cfcd858bb2cafa184", + "reference": "2e5adbfaabd29f9c03c3678cfcd858bb2cafa184", "shasum": "" }, "require": { @@ -9442,7 +9444,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v7.0.7" + "source": "https://github.com/symfony/http-kernel/tree/v7.0.8" }, "funding": [ { @@ -9458,20 +9460,20 @@ "type": "tidelift" } ], - "time": "2024-04-29T12:20:25+00:00" + "time": "2024-06-02T16:58:24+00:00" }, { "name": "symfony/intl", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/intl.git", - "reference": "dd12042707110995e2e7d80103f8d9928bea8621" + "reference": "4e4ffbfa65fae8bebb8e53712b3e493c85204612" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/intl/zipball/dd12042707110995e2e7d80103f8d9928bea8621", - "reference": "dd12042707110995e2e7d80103f8d9928bea8621", + "url": "https://api.github.com/repos/symfony/intl/zipball/4e4ffbfa65fae8bebb8e53712b3e493c85204612", + "reference": "4e4ffbfa65fae8bebb8e53712b3e493c85204612", "shasum": "" }, "require": { @@ -9525,7 +9527,7 @@ "localization" ], "support": { - "source": "https://github.com/symfony/intl/tree/v7.0.7" + "source": "https://github.com/symfony/intl/tree/v7.0.8" }, "funding": [ { @@ -9541,20 +9543,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/lock", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/lock.git", - "reference": "9d6546f0223c1f441e2e6517ad3502c226ac0adb" + "reference": "665e2f4c14690d4b974ed59313e50efe18e8bce6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/lock/zipball/9d6546f0223c1f441e2e6517ad3502c226ac0adb", - "reference": "9d6546f0223c1f441e2e6517ad3502c226ac0adb", + "url": "https://api.github.com/repos/symfony/lock/zipball/665e2f4c14690d4b974ed59313e50efe18e8bce6", + "reference": "665e2f4c14690d4b974ed59313e50efe18e8bce6", "shasum": "" }, "require": { @@ -9603,7 +9605,7 @@ "semaphore" ], "support": { - "source": "https://github.com/symfony/lock/tree/v7.0.7" + "source": "https://github.com/symfony/lock/tree/v7.0.8" }, "funding": [ { @@ -9619,20 +9621,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/mailer", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "4ff41a7c7998a88cfdc31b5841ef64d9246fc56a" + "reference": "644c2b5ddd778666298d73c1a8c0949f74ef6649" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/4ff41a7c7998a88cfdc31b5841ef64d9246fc56a", - "reference": "4ff41a7c7998a88cfdc31b5841ef64d9246fc56a", + "url": "https://api.github.com/repos/symfony/mailer/zipball/644c2b5ddd778666298d73c1a8c0949f74ef6649", + "reference": "644c2b5ddd778666298d73c1a8c0949f74ef6649", "shasum": "" }, "require": { @@ -9683,7 +9685,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v7.0.7" + "source": "https://github.com/symfony/mailer/tree/v7.0.8" }, "funding": [ { @@ -9699,20 +9701,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/mailgun-mailer", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/mailgun-mailer.git", - "reference": "e9bb8fdbdd79334a8a88bdd233204315abd992c5" + "reference": "24cdd1dd88b480634d807c1e3f1a9687fa3e7793" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/e9bb8fdbdd79334a8a88bdd233204315abd992c5", - "reference": "e9bb8fdbdd79334a8a88bdd233204315abd992c5", + "url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/24cdd1dd88b480634d807c1e3f1a9687fa3e7793", + "reference": "24cdd1dd88b480634d807c1e3f1a9687fa3e7793", "shasum": "" }, "require": { @@ -9752,7 +9754,7 @@ "description": "Symfony Mailgun Mailer Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailgun-mailer/tree/v7.0.7" + "source": "https://github.com/symfony/mailgun-mailer/tree/v7.0.8" }, "funding": [ { @@ -9768,7 +9770,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/mercure", @@ -9858,16 +9860,16 @@ }, { "name": "symfony/mercure-bundle", - "version": "v0.3.8", + "version": "v0.3.9", "source": { "type": "git", "url": "https://github.com/symfony/mercure-bundle.git", - "reference": "e21ad84694b84c9a3c94bedf4edd82b66728abfc" + "reference": "77435d740b228e9f5f3f065b6db564f85f2cdb64" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mercure-bundle/zipball/e21ad84694b84c9a3c94bedf4edd82b66728abfc", - "reference": "e21ad84694b84c9a3c94bedf4edd82b66728abfc", + "url": "https://api.github.com/repos/symfony/mercure-bundle/zipball/77435d740b228e9f5f3f065b6db564f85f2cdb64", + "reference": "77435d740b228e9f5f3f065b6db564f85f2cdb64", "shasum": "" }, "require": { @@ -9923,7 +9925,7 @@ ], "support": { "issues": "https://github.com/symfony/mercure-bundle/issues", - "source": "https://github.com/symfony/mercure-bundle/tree/v0.3.8" + "source": "https://github.com/symfony/mercure-bundle/tree/v0.3.9" }, "funding": [ { @@ -9935,20 +9937,20 @@ "type": "tidelift" } ], - "time": "2023-12-03T22:26:24+00:00" + "time": "2024-05-31T09:07:18+00:00" }, { "name": "symfony/messenger", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/messenger.git", - "reference": "90c217478f85d5289aae597551e2a4251e4d08c3" + "reference": "ed7bccfe31e7f0bdb5b101f48b6027622a7a48cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/messenger/zipball/90c217478f85d5289aae597551e2a4251e4d08c3", - "reference": "90c217478f85d5289aae597551e2a4251e4d08c3", + "url": "https://api.github.com/repos/symfony/messenger/zipball/ed7bccfe31e7f0bdb5b101f48b6027622a7a48cb", + "reference": "ed7bccfe31e7f0bdb5b101f48b6027622a7a48cb", "shasum": "" }, "require": { @@ -10005,7 +10007,7 @@ "description": "Helps applications send and receive messages to/from other applications or via message queues", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/messenger/tree/v7.0.7" + "source": "https://github.com/symfony/messenger/tree/v7.0.8" }, "funding": [ { @@ -10021,20 +10023,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/mime", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "3adbf110c306546f6f00337f421d2edca0e8d3c0" + "reference": "3426d1e95f432c82ceef57e9943383116800f406" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/3adbf110c306546f6f00337f421d2edca0e8d3c0", - "reference": "3adbf110c306546f6f00337f421d2edca0e8d3c0", + "url": "https://api.github.com/repos/symfony/mime/zipball/3426d1e95f432c82ceef57e9943383116800f406", + "reference": "3426d1e95f432c82ceef57e9943383116800f406", "shasum": "" }, "require": { @@ -10089,7 +10091,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v7.0.7" + "source": "https://github.com/symfony/mime/tree/v7.0.8" }, "funding": [ { @@ -10105,20 +10107,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-06-02T15:49:03+00:00" }, { "name": "symfony/monolog-bridge", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/monolog-bridge.git", - "reference": "aaa40a0a6512976a6e07d5def7ce9476862ebd65" + "reference": "d80b7aeabc539538c6ae8962259ac422632d7796" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/aaa40a0a6512976a6e07d5def7ce9476862ebd65", - "reference": "aaa40a0a6512976a6e07d5def7ce9476862ebd65", + "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/d80b7aeabc539538c6ae8962259ac422632d7796", + "reference": "d80b7aeabc539538c6ae8962259ac422632d7796", "shasum": "" }, "require": { @@ -10167,7 +10169,7 @@ "description": "Provides integration for Monolog with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/monolog-bridge/tree/v7.0.7" + "source": "https://github.com/symfony/monolog-bridge/tree/v7.0.8" }, "funding": [ { @@ -10183,7 +10185,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/monolog-bundle", @@ -10268,16 +10270,16 @@ }, { "name": "symfony/options-resolver", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "23cc173858776ad451e31f053b1c9f47840b2cfa" + "reference": "19eecfc6f1b0e4b093db7f4a71eedc91843e711a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/23cc173858776ad451e31f053b1c9f47840b2cfa", - "reference": "23cc173858776ad451e31f053b1c9f47840b2cfa", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/19eecfc6f1b0e4b093db7f4a71eedc91843e711a", + "reference": "19eecfc6f1b0e4b093db7f4a71eedc91843e711a", "shasum": "" }, "require": { @@ -10315,7 +10317,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v7.0.7" + "source": "https://github.com/symfony/options-resolver/tree/v7.0.8" }, "funding": [ { @@ -10331,20 +10333,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/password-hasher", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/password-hasher.git", - "reference": "5148b049248935f8a7b0a392aece2f22e9a1803d" + "reference": "25c66dba8ca72c9636b16e9a4b33d18554969a3f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/password-hasher/zipball/5148b049248935f8a7b0a392aece2f22e9a1803d", - "reference": "5148b049248935f8a7b0a392aece2f22e9a1803d", + "url": "https://api.github.com/repos/symfony/password-hasher/zipball/25c66dba8ca72c9636b16e9a4b33d18554969a3f", + "reference": "25c66dba8ca72c9636b16e9a4b33d18554969a3f", "shasum": "" }, "require": { @@ -10387,7 +10389,7 @@ "password" ], "support": { - "source": "https://github.com/symfony/password-hasher/tree/v7.0.7" + "source": "https://github.com/symfony/password-hasher/tree/v7.0.8" }, "funding": [ { @@ -10403,7 +10405,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/polyfill-intl-grapheme", @@ -11126,16 +11128,16 @@ }, { "name": "symfony/process", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "3839e56b94dd1dbd13235d27504e66baf23faba0" + "reference": "a358943d5a15277fc6001f47541c08b7d815338f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/3839e56b94dd1dbd13235d27504e66baf23faba0", - "reference": "3839e56b94dd1dbd13235d27504e66baf23faba0", + "url": "https://api.github.com/repos/symfony/process/zipball/a358943d5a15277fc6001f47541c08b7d815338f", + "reference": "a358943d5a15277fc6001f47541c08b7d815338f", "shasum": "" }, "require": { @@ -11167,7 +11169,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.0.7" + "source": "https://github.com/symfony/process/tree/v7.0.8" }, "funding": [ { @@ -11183,20 +11185,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/property-access", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "8661b861480d2807eb2789ff99d034c0c71ab955" + "reference": "ca11e9661ea88664873dba66412525fe301dd744" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/8661b861480d2807eb2789ff99d034c0c71ab955", - "reference": "8661b861480d2807eb2789ff99d034c0c71ab955", + "url": "https://api.github.com/repos/symfony/property-access/zipball/ca11e9661ea88664873dba66412525fe301dd744", + "reference": "ca11e9661ea88664873dba66412525fe301dd744", "shasum": "" }, "require": { @@ -11243,7 +11245,7 @@ "reflection" ], "support": { - "source": "https://github.com/symfony/property-access/tree/v7.0.7" + "source": "https://github.com/symfony/property-access/tree/v7.0.8" }, "funding": [ { @@ -11259,20 +11261,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/property-info", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "f0bdb46e19ab308527b324b7ec36161f6880a532" + "reference": "f03a32b9349352571d5a2b4639dadac461ee94b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/f0bdb46e19ab308527b324b7ec36161f6880a532", - "reference": "f0bdb46e19ab308527b324b7ec36161f6880a532", + "url": "https://api.github.com/repos/symfony/property-info/zipball/f03a32b9349352571d5a2b4639dadac461ee94b5", + "reference": "f03a32b9349352571d5a2b4639dadac461ee94b5", "shasum": "" }, "require": { @@ -11326,7 +11328,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v7.0.7" + "source": "https://github.com/symfony/property-info/tree/v7.0.8" }, "funding": [ { @@ -11342,20 +11344,20 @@ "type": "tidelift" } ], - "time": "2024-04-28T11:44:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/psr-http-message-bridge", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/psr-http-message-bridge.git", - "reference": "727befd41438a8feb64066871d3656d8cbdcdbe2" + "reference": "1f1c2116a08387d4754590af7dd3f1674ebf47a6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/727befd41438a8feb64066871d3656d8cbdcdbe2", - "reference": "727befd41438a8feb64066871d3656d8cbdcdbe2", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/1f1c2116a08387d4754590af7dd3f1674ebf47a6", + "reference": "1f1c2116a08387d4754590af7dd3f1674ebf47a6", "shasum": "" }, "require": { @@ -11409,7 +11411,7 @@ "psr-7" ], "support": { - "source": "https://github.com/symfony/psr-http-message-bridge/tree/v7.0.7" + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v7.0.8" }, "funding": [ { @@ -11425,20 +11427,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/rate-limiter", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/rate-limiter.git", - "reference": "7ba48d83a622ebcd0a804776c505c05898a6f0e9" + "reference": "f3f3d92414ce90c6c20a1c2e3bd5a80321390863" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/rate-limiter/zipball/7ba48d83a622ebcd0a804776c505c05898a6f0e9", - "reference": "7ba48d83a622ebcd0a804776c505c05898a6f0e9", + "url": "https://api.github.com/repos/symfony/rate-limiter/zipball/f3f3d92414ce90c6c20a1c2e3bd5a80321390863", + "reference": "f3f3d92414ce90c6c20a1c2e3bd5a80321390863", "shasum": "" }, "require": { @@ -11479,7 +11481,7 @@ "rate-limiter" ], "support": { - "source": "https://github.com/symfony/rate-limiter/tree/v7.0.7" + "source": "https://github.com/symfony/rate-limiter/tree/v7.0.8" }, "funding": [ { @@ -11495,20 +11497,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/redis-messenger", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/redis-messenger.git", - "reference": "cf673d870c500c3a6d9ffe613b4a9aa68812b722" + "reference": "55171fdc87127e01696b7b251777992f827c73ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/redis-messenger/zipball/cf673d870c500c3a6d9ffe613b4a9aa68812b722", - "reference": "cf673d870c500c3a6d9ffe613b4a9aa68812b722", + "url": "https://api.github.com/repos/symfony/redis-messenger/zipball/55171fdc87127e01696b7b251777992f827c73ac", + "reference": "55171fdc87127e01696b7b251777992f827c73ac", "shasum": "" }, "require": { @@ -11546,7 +11548,7 @@ "description": "Symfony Redis extension Messenger Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/redis-messenger/tree/v7.0.7" + "source": "https://github.com/symfony/redis-messenger/tree/v7.0.8" }, "funding": [ { @@ -11562,20 +11564,20 @@ "type": "tidelift" } ], - "time": "2024-04-28T11:44:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/routing", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "9f82bf7766ccc9c22ab7aeb9bebb98351483fa5b" + "reference": "ceb71bb86a8c4e65eb3b9dd33819df390c11ec67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/9f82bf7766ccc9c22ab7aeb9bebb98351483fa5b", - "reference": "9f82bf7766ccc9c22ab7aeb9bebb98351483fa5b", + "url": "https://api.github.com/repos/symfony/routing/zipball/ceb71bb86a8c4e65eb3b9dd33819df390c11ec67", + "reference": "ceb71bb86a8c4e65eb3b9dd33819df390c11ec67", "shasum": "" }, "require": { @@ -11627,7 +11629,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v7.0.7" + "source": "https://github.com/symfony/routing/tree/v7.0.8" }, "funding": [ { @@ -11643,20 +11645,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/runtime", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/runtime.git", - "reference": "e120730ef206b31bb5521b1a2389c058adbba9c7" + "reference": "ea34522c447dd91a2b31cb330ee4540a56ba53f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/runtime/zipball/e120730ef206b31bb5521b1a2389c058adbba9c7", - "reference": "e120730ef206b31bb5521b1a2389c058adbba9c7", + "url": "https://api.github.com/repos/symfony/runtime/zipball/ea34522c447dd91a2b31cb330ee4540a56ba53f6", + "reference": "ea34522c447dd91a2b31cb330ee4540a56ba53f6", "shasum": "" }, "require": { @@ -11706,7 +11708,7 @@ "runtime" ], "support": { - "source": "https://github.com/symfony/runtime/tree/v7.0.7" + "source": "https://github.com/symfony/runtime/tree/v7.0.8" }, "funding": [ { @@ -11722,20 +11724,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/scheduler", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/scheduler.git", - "reference": "2522418649397a494dfbd85b913d4423c25cc709" + "reference": "91a0c028f2183b111e92e32061bb9db9a9599133" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/scheduler/zipball/2522418649397a494dfbd85b913d4423c25cc709", - "reference": "2522418649397a494dfbd85b913d4423c25cc709", + "url": "https://api.github.com/repos/symfony/scheduler/zipball/91a0c028f2183b111e92e32061bb9db9a9599133", + "reference": "91a0c028f2183b111e92e32061bb9db9a9599133", "shasum": "" }, "require": { @@ -11786,7 +11788,7 @@ "scheduler" ], "support": { - "source": "https://github.com/symfony/scheduler/tree/v7.0.7" + "source": "https://github.com/symfony/scheduler/tree/v7.0.8" }, "funding": [ { @@ -11802,20 +11804,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-06-02T15:49:03+00:00" }, { "name": "symfony/security-bundle", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/security-bundle.git", - "reference": "8d11101574ce8e2147a04245f4b968911a43ffd5" + "reference": "ed017b8ced34fd7381d74ac544fed94c0768f327" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-bundle/zipball/8d11101574ce8e2147a04245f4b968911a43ffd5", - "reference": "8d11101574ce8e2147a04245f4b968911a43ffd5", + "url": "https://api.github.com/repos/symfony/security-bundle/zipball/ed017b8ced34fd7381d74ac544fed94c0768f327", + "reference": "ed017b8ced34fd7381d74ac544fed94c0768f327", "shasum": "" }, "require": { @@ -11897,7 +11899,7 @@ "description": "Provides a tight integration of the Security component into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-bundle/tree/v7.0.7" + "source": "https://github.com/symfony/security-bundle/tree/v7.0.8" }, "funding": [ { @@ -11913,20 +11915,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/security-core", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/security-core.git", - "reference": "6af8ac3b4d9c41a0ce0a4e33d532ba2000b47348" + "reference": "6fec2c1ee2dda57b55988c418b270cf616410b21" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-core/zipball/6af8ac3b4d9c41a0ce0a4e33d532ba2000b47348", - "reference": "6af8ac3b4d9c41a0ce0a4e33d532ba2000b47348", + "url": "https://api.github.com/repos/symfony/security-core/zipball/6fec2c1ee2dda57b55988c418b270cf616410b21", + "reference": "6fec2c1ee2dda57b55988c418b270cf616410b21", "shasum": "" }, "require": { @@ -11981,7 +11983,7 @@ "description": "Symfony Security Component - Core Library", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-core/tree/v7.0.7" + "source": "https://github.com/symfony/security-core/tree/v7.0.8" }, "funding": [ { @@ -11997,20 +11999,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/security-csrf", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/security-csrf.git", - "reference": "671d6736736555309991457dd877e7f6f3317d08" + "reference": "40543b13b35999316d3f79a18d0d4075f30b8d9b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-csrf/zipball/671d6736736555309991457dd877e7f6f3317d08", - "reference": "671d6736736555309991457dd877e7f6f3317d08", + "url": "https://api.github.com/repos/symfony/security-csrf/zipball/40543b13b35999316d3f79a18d0d4075f30b8d9b", + "reference": "40543b13b35999316d3f79a18d0d4075f30b8d9b", "shasum": "" }, "require": { @@ -12049,7 +12051,7 @@ "description": "Symfony Security Component - CSRF Library", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-csrf/tree/v7.0.7" + "source": "https://github.com/symfony/security-csrf/tree/v7.0.8" }, "funding": [ { @@ -12065,20 +12067,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/security-http", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/security-http.git", - "reference": "836a338f51cd46d57e77fcba61c6f8c6111a3717" + "reference": "d1a9b766f1e253b4e2c39a78eddd58cb5b9f2940" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-http/zipball/836a338f51cd46d57e77fcba61c6f8c6111a3717", - "reference": "836a338f51cd46d57e77fcba61c6f8c6111a3717", + "url": "https://api.github.com/repos/symfony/security-http/zipball/d1a9b766f1e253b4e2c39a78eddd58cb5b9f2940", + "reference": "d1a9b766f1e253b4e2c39a78eddd58cb5b9f2940", "shasum": "" }, "require": { @@ -12136,7 +12138,7 @@ "description": "Symfony Security Component - HTTP Integration", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-http/tree/v7.0.7" + "source": "https://github.com/symfony/security-http/tree/v7.0.8" }, "funding": [ { @@ -12152,20 +12154,20 @@ "type": "tidelift" } ], - "time": "2024-04-19T13:26:52+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/serializer", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "08f0c517acf4b12dfc0d3963cd12f7b8023aea31" + "reference": "267299e0f960d1a19f1fa5525100aab0af0e667a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/08f0c517acf4b12dfc0d3963cd12f7b8023aea31", - "reference": "08f0c517acf4b12dfc0d3963cd12f7b8023aea31", + "url": "https://api.github.com/repos/symfony/serializer/zipball/267299e0f960d1a19f1fa5525100aab0af0e667a", + "reference": "267299e0f960d1a19f1fa5525100aab0af0e667a", "shasum": "" }, "require": { @@ -12231,7 +12233,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/serializer/tree/v7.0.7" + "source": "https://github.com/symfony/serializer/tree/v7.0.8" }, "funding": [ { @@ -12247,7 +12249,7 @@ "type": "tidelift" } ], - "time": "2024-04-28T11:44:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/service-contracts", @@ -12334,16 +12336,16 @@ }, { "name": "symfony/stimulus-bundle", - "version": "v2.17.0", + "version": "v2.18.0", "source": { "type": "git", "url": "https://github.com/symfony/stimulus-bundle.git", - "reference": "b828a32fe9f75500d26b563cc01874657162c413" + "reference": "9323437da427e123d8f9b76b19fa9a60a76d45a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stimulus-bundle/zipball/b828a32fe9f75500d26b563cc01874657162c413", - "reference": "b828a32fe9f75500d26b563cc01874657162c413", + "url": "https://api.github.com/repos/symfony/stimulus-bundle/zipball/9323437da427e123d8f9b76b19fa9a60a76d45a0", + "reference": "9323437da427e123d8f9b76b19fa9a60a76d45a0", "shasum": "" }, "require": { @@ -12383,7 +12385,7 @@ "symfony-ux" ], "support": { - "source": "https://github.com/symfony/stimulus-bundle/tree/v2.17.0" + "source": "https://github.com/symfony/stimulus-bundle/tree/v2.18.0" }, "funding": [ { @@ -12399,20 +12401,20 @@ "type": "tidelift" } ], - "time": "2024-04-21T10:23:35+00:00" + "time": "2024-06-01T17:50:20+00:00" }, { "name": "symfony/stopwatch", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "41a7a24aa1dc82adf46a06bc292d1923acfe6b84" + "reference": "e4a0d6fef3dd428ca23172e62d1d863f6f25d541" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/41a7a24aa1dc82adf46a06bc292d1923acfe6b84", - "reference": "41a7a24aa1dc82adf46a06bc292d1923acfe6b84", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/e4a0d6fef3dd428ca23172e62d1d863f6f25d541", + "reference": "e4a0d6fef3dd428ca23172e62d1d863f6f25d541", "shasum": "" }, "require": { @@ -12445,7 +12447,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v7.0.7" + "source": "https://github.com/symfony/stopwatch/tree/v7.0.8" }, "funding": [ { @@ -12461,20 +12463,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/string", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "e405b5424dc2528e02e31ba26b83a79fd4eb8f63" + "reference": "5a6ef5cf9b843d5c4221073350fe615995280a82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/e405b5424dc2528e02e31ba26b83a79fd4eb8f63", - "reference": "e405b5424dc2528e02e31ba26b83a79fd4eb8f63", + "url": "https://api.github.com/repos/symfony/string/zipball/5a6ef5cf9b843d5c4221073350fe615995280a82", + "reference": "5a6ef5cf9b843d5c4221073350fe615995280a82", "shasum": "" }, "require": { @@ -12531,7 +12533,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.0.7" + "source": "https://github.com/symfony/string/tree/v7.0.8" }, "funding": [ { @@ -12547,20 +12549,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/translation", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "1515e03afaa93e6419aba5d5c9d209159317100b" + "reference": "649a646a5aae6e86da1ea119643c53d4080624c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/1515e03afaa93e6419aba5d5c9d209159317100b", - "reference": "1515e03afaa93e6419aba5d5c9d209159317100b", + "url": "https://api.github.com/repos/symfony/translation/zipball/649a646a5aae6e86da1ea119643c53d4080624c2", + "reference": "649a646a5aae6e86da1ea119643c53d4080624c2", "shasum": "" }, "require": { @@ -12625,7 +12627,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v7.0.7" + "source": "https://github.com/symfony/translation/tree/v7.0.8" }, "funding": [ { @@ -12641,7 +12643,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/translation-contracts", @@ -12723,16 +12725,16 @@ }, { "name": "symfony/twig-bridge", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/twig-bridge.git", - "reference": "214237f7b3b82eeb430e85ea415c4a2915c304f6" + "reference": "c8e05d7545962198df715d705c132de0674dc5b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/214237f7b3b82eeb430e85ea415c4a2915c304f6", - "reference": "214237f7b3b82eeb430e85ea415c4a2915c304f6", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/c8e05d7545962198df715d705c132de0674dc5b2", + "reference": "c8e05d7545962198df715d705c132de0674dc5b2", "shasum": "" }, "require": { @@ -12811,7 +12813,7 @@ "description": "Provides integration for Twig with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bridge/tree/v7.0.7" + "source": "https://github.com/symfony/twig-bridge/tree/v7.0.8" }, "funding": [ { @@ -12827,20 +12829,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/twig-bundle", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/twig-bundle.git", - "reference": "4dd8a395b955045d031d9525a7149cfcee8d0b02" + "reference": "a90e474bc260e59bed98a556db63673e6420a0be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/4dd8a395b955045d031d9525a7149cfcee8d0b02", - "reference": "4dd8a395b955045d031d9525a7149cfcee8d0b02", + "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/a90e474bc260e59bed98a556db63673e6420a0be", + "reference": "a90e474bc260e59bed98a556db63673e6420a0be", "shasum": "" }, "require": { @@ -12895,7 +12897,7 @@ "description": "Provides a tight integration of Twig into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bundle/tree/v7.0.7" + "source": "https://github.com/symfony/twig-bundle/tree/v7.0.8" }, "funding": [ { @@ -12911,20 +12913,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/uid", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/uid.git", - "reference": "4f3a5d181999e25918586c8369de09e7814e7be2" + "reference": "82d01607b09ba79f38efe4c213dbf528ff0beeed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/uid/zipball/4f3a5d181999e25918586c8369de09e7814e7be2", - "reference": "4f3a5d181999e25918586c8369de09e7814e7be2", + "url": "https://api.github.com/repos/symfony/uid/zipball/82d01607b09ba79f38efe4c213dbf528ff0beeed", + "reference": "82d01607b09ba79f38efe4c213dbf528ff0beeed", "shasum": "" }, "require": { @@ -12969,7 +12971,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/uid/tree/v7.0.7" + "source": "https://github.com/symfony/uid/tree/v7.0.8" }, "funding": [ { @@ -12985,20 +12987,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/ux-autocomplete", - "version": "v2.17.0", + "version": "v2.18.0", "source": { "type": "git", "url": "https://github.com/symfony/ux-autocomplete.git", - "reference": "b2c3c4302bc5b0062b3e8891460321fe694c466d" + "reference": "aa2e5b1a335f29f1fbd840b1cf52e1c3d3dafc0d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/ux-autocomplete/zipball/b2c3c4302bc5b0062b3e8891460321fe694c466d", - "reference": "b2c3c4302bc5b0062b3e8891460321fe694c466d", + "url": "https://api.github.com/repos/symfony/ux-autocomplete/zipball/aa2e5b1a335f29f1fbd840b1cf52e1c3d3dafc0d", + "reference": "aa2e5b1a335f29f1fbd840b1cf52e1c3d3dafc0d", "shasum": "" }, "require": { @@ -13061,7 +13063,7 @@ "symfony-ux" ], "support": { - "source": "https://github.com/symfony/ux-autocomplete/tree/v2.17.0" + "source": "https://github.com/symfony/ux-autocomplete/tree/v2.18.0" }, "funding": [ { @@ -13077,20 +13079,20 @@ "type": "tidelift" } ], - "time": "2024-04-19T06:36:45+00:00" + "time": "2024-06-01T17:50:20+00:00" }, { "name": "symfony/ux-chartjs", - "version": "v2.17.0", + "version": "v2.18.0", "source": { "type": "git", "url": "https://github.com/symfony/ux-chartjs.git", - "reference": "962326b44a8c3edf4d8b29e115dc446441bcd662" + "reference": "be3e054914217a5c6dc8fed02cebec346d7ed2ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/ux-chartjs/zipball/962326b44a8c3edf4d8b29e115dc446441bcd662", - "reference": "962326b44a8c3edf4d8b29e115dc446441bcd662", + "url": "https://api.github.com/repos/symfony/ux-chartjs/zipball/be3e054914217a5c6dc8fed02cebec346d7ed2ae", + "reference": "be3e054914217a5c6dc8fed02cebec346d7ed2ae", "shasum": "" }, "require": { @@ -13141,7 +13143,7 @@ "symfony-ux" ], "support": { - "source": "https://github.com/symfony/ux-chartjs/tree/v2.17.0" + "source": "https://github.com/symfony/ux-chartjs/tree/v2.18.0" }, "funding": [ { @@ -13157,20 +13159,20 @@ "type": "tidelift" } ], - "time": "2024-04-19T06:36:45+00:00" + "time": "2024-06-01T17:50:16+00:00" }, { "name": "symfony/ux-twig-component", - "version": "v2.17.0", + "version": "v2.18.0", "source": { "type": "git", "url": "https://github.com/symfony/ux-twig-component.git", - "reference": "fb3d978b7f19e9a94533a3bf30d68269908ffae1" + "reference": "a2122be860b9e0010638178eadb4e5ed46d1907c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/ux-twig-component/zipball/fb3d978b7f19e9a94533a3bf30d68269908ffae1", - "reference": "fb3d978b7f19e9a94533a3bf30d68269908ffae1", + "url": "https://api.github.com/repos/symfony/ux-twig-component/zipball/a2122be860b9e0010638178eadb4e5ed46d1907c", + "reference": "a2122be860b9e0010638178eadb4e5ed46d1907c", "shasum": "" }, "require": { @@ -13225,7 +13227,7 @@ "twig" ], "support": { - "source": "https://github.com/symfony/ux-twig-component/tree/v2.17.0" + "source": "https://github.com/symfony/ux-twig-component/tree/v2.18.0" }, "funding": [ { @@ -13241,20 +13243,20 @@ "type": "tidelift" } ], - "time": "2024-04-19T16:14:05+00:00" + "time": "2024-06-06T23:10:35+00:00" }, { "name": "symfony/validator", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "ab4e75b9d23ba70e78480aecbe4d8da15adf10eb" + "reference": "23af65dff1f4dfee9aab3a0123a243e40fa3d9cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/ab4e75b9d23ba70e78480aecbe4d8da15adf10eb", - "reference": "ab4e75b9d23ba70e78480aecbe4d8da15adf10eb", + "url": "https://api.github.com/repos/symfony/validator/zipball/23af65dff1f4dfee9aab3a0123a243e40fa3d9cf", + "reference": "23af65dff1f4dfee9aab3a0123a243e40fa3d9cf", "shasum": "" }, "require": { @@ -13299,7 +13301,8 @@ "Symfony\\Component\\Validator\\": "" }, "exclude-from-classmap": [ - "/Tests/" + "/Tests/", + "/Resources/bin/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -13319,7 +13322,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/validator/tree/v7.0.7" + "source": "https://github.com/symfony/validator/tree/v7.0.8" }, "funding": [ { @@ -13335,20 +13338,20 @@ "type": "tidelift" } ], - "time": "2024-04-28T11:44:19+00:00" + "time": "2024-06-02T15:49:03+00:00" }, { "name": "symfony/var-dumper", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "d1627b66fd87c8b4d90cabe5671c29d575690924" + "reference": "5d2a35f4f1413502c79b20e70d4f6ecd8fc217e9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/d1627b66fd87c8b4d90cabe5671c29d575690924", - "reference": "d1627b66fd87c8b4d90cabe5671c29d575690924", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/5d2a35f4f1413502c79b20e70d4f6ecd8fc217e9", + "reference": "5d2a35f4f1413502c79b20e70d4f6ecd8fc217e9", "shasum": "" }, "require": { @@ -13402,7 +13405,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.0.7" + "source": "https://github.com/symfony/var-dumper/tree/v7.0.8" }, "funding": [ { @@ -13418,20 +13421,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/var-exporter", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "cdecc0022e40e90340ba1a59a3d5ccf069777078" + "reference": "a877941e11ddd19746def2f7fdd003b8d5197b50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/cdecc0022e40e90340ba1a59a3d5ccf069777078", - "reference": "cdecc0022e40e90340ba1a59a3d5ccf069777078", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/a877941e11ddd19746def2f7fdd003b8d5197b50", + "reference": "a877941e11ddd19746def2f7fdd003b8d5197b50", "shasum": "" }, "require": { @@ -13478,7 +13481,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v7.0.7" + "source": "https://github.com/symfony/var-exporter/tree/v7.0.8" }, "funding": [ { @@ -13494,20 +13497,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/web-link", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/web-link.git", - "reference": "19312f38543e77b09f04f374368b73530bfb9482" + "reference": "270f39e3d1c7cc62b5a931fd6e9f2ea4e99ee9cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-link/zipball/19312f38543e77b09f04f374368b73530bfb9482", - "reference": "19312f38543e77b09f04f374368b73530bfb9482", + "url": "https://api.github.com/repos/symfony/web-link/zipball/270f39e3d1c7cc62b5a931fd6e9f2ea4e99ee9cf", + "reference": "270f39e3d1c7cc62b5a931fd6e9f2ea4e99ee9cf", "shasum": "" }, "require": { @@ -13561,7 +13564,7 @@ "push" ], "support": { - "source": "https://github.com/symfony/web-link/tree/v7.0.7" + "source": "https://github.com/symfony/web-link/tree/v7.0.8" }, "funding": [ { @@ -13577,7 +13580,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/webpack-encore-bundle", @@ -13652,16 +13655,16 @@ }, { "name": "symfony/workflow", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/workflow.git", - "reference": "8b3a8dc022bb6766e04984412c026edcdbe1a020" + "reference": "4cfb7fec060bf5bd2c38f14dc0c221a32a19b9eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/workflow/zipball/8b3a8dc022bb6766e04984412c026edcdbe1a020", - "reference": "8b3a8dc022bb6766e04984412c026edcdbe1a020", + "url": "https://api.github.com/repos/symfony/workflow/zipball/4cfb7fec060bf5bd2c38f14dc0c221a32a19b9eb", + "reference": "4cfb7fec060bf5bd2c38f14dc0c221a32a19b9eb", "shasum": "" }, "require": { @@ -13719,7 +13722,7 @@ "workflow" ], "support": { - "source": "https://github.com/symfony/workflow/tree/v7.0.7" + "source": "https://github.com/symfony/workflow/tree/v7.0.8" }, "funding": [ { @@ -13735,20 +13738,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/yaml", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "0d3916ae69ea28b59d94b60c4f2b50f4e25adb5c" + "reference": "89bdddd79e918448ce978be664768ef27b9e5798" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/0d3916ae69ea28b59d94b60c4f2b50f4e25adb5c", - "reference": "0d3916ae69ea28b59d94b60c4f2b50f4e25adb5c", + "url": "https://api.github.com/repos/symfony/yaml/zipball/89bdddd79e918448ce978be664768ef27b9e5798", + "reference": "89bdddd79e918448ce978be664768ef27b9e5798", "shasum": "" }, "require": { @@ -13790,7 +13793,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.0.7" + "source": "https://github.com/symfony/yaml/tree/v7.0.8" }, "funding": [ { @@ -13806,7 +13809,7 @@ "type": "tidelift" } ], - "time": "2024-04-28T11:44:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfonycasts/reset-password-bundle", @@ -16622,16 +16625,16 @@ }, { "name": "symfony/browser-kit", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "0a48e67a7975c07d8cc0661fbbdddce56c58425e" + "reference": "0030d568e9147b853e168117edf72b74f9643e85" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/0a48e67a7975c07d8cc0661fbbdddce56c58425e", - "reference": "0a48e67a7975c07d8cc0661fbbdddce56c58425e", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/0030d568e9147b853e168117edf72b74f9643e85", + "reference": "0030d568e9147b853e168117edf72b74f9643e85", "shasum": "" }, "require": { @@ -16670,7 +16673,7 @@ "description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/browser-kit/tree/v7.0.7" + "source": "https://github.com/symfony/browser-kit/tree/v7.0.8" }, "funding": [ { @@ -16686,20 +16689,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/debug-bundle", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/debug-bundle.git", - "reference": "4b013a2c886cfd0292d90a9a9cebfa29ec7b578c" + "reference": "aa024d28ce7ce0c6a16ee57c066838bece92893f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug-bundle/zipball/4b013a2c886cfd0292d90a9a9cebfa29ec7b578c", - "reference": "4b013a2c886cfd0292d90a9a9cebfa29ec7b578c", + "url": "https://api.github.com/repos/symfony/debug-bundle/zipball/aa024d28ce7ce0c6a16ee57c066838bece92893f", + "reference": "aa024d28ce7ce0c6a16ee57c066838bece92893f", "shasum": "" }, "require": { @@ -16744,7 +16747,7 @@ "description": "Provides a tight integration of the Symfony VarDumper component and the ServerLogCommand from MonologBridge into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/debug-bundle/tree/v7.0.7" + "source": "https://github.com/symfony/debug-bundle/tree/v7.0.8" }, "funding": [ { @@ -16760,20 +16763,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/dom-crawler", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "7cb4ae7166a8a36916be390dbb3819474fb06a29" + "reference": "46cdbb48603db7b9ea55172d3edb6b3e9de58028" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/7cb4ae7166a8a36916be390dbb3819474fb06a29", - "reference": "7cb4ae7166a8a36916be390dbb3819474fb06a29", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/46cdbb48603db7b9ea55172d3edb6b3e9de58028", + "reference": "46cdbb48603db7b9ea55172d3edb6b3e9de58028", "shasum": "" }, "require": { @@ -16811,7 +16814,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v7.0.7" + "source": "https://github.com/symfony/dom-crawler/tree/v7.0.8" }, "funding": [ { @@ -16827,20 +16830,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/maker-bundle", - "version": "v1.59.1", + "version": "v1.60.0", "source": { "type": "git", "url": "https://github.com/symfony/maker-bundle.git", - "reference": "b87b1b25c607a8a50832395bc751c784946a0350" + "reference": "c305a02a22974670f359d4274c9431e1a191f559" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/b87b1b25c607a8a50832395bc751c784946a0350", - "reference": "b87b1b25c607a8a50832395bc751c784946a0350", + "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/c305a02a22974670f359d4274c9431e1a191f559", + "reference": "c305a02a22974670f359d4274c9431e1a191f559", "shasum": "" }, "require": { @@ -16903,7 +16906,7 @@ ], "support": { "issues": "https://github.com/symfony/maker-bundle/issues", - "source": "https://github.com/symfony/maker-bundle/tree/v1.59.1" + "source": "https://github.com/symfony/maker-bundle/tree/v1.60.0" }, "funding": [ { @@ -16919,20 +16922,20 @@ "type": "tidelift" } ], - "time": "2024-05-06T03:59:59+00:00" + "time": "2024-06-10T06:03:18+00:00" }, { "name": "symfony/phpunit-bridge", - "version": "v7.0.7", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "0a0b90ba08b9a03e09ad49f8d613bdf3eca3a7a9" + "reference": "3e1cb8c4dee341cfe96ae9fe29b1acda52a6bb16" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/0a0b90ba08b9a03e09ad49f8d613bdf3eca3a7a9", - "reference": "0a0b90ba08b9a03e09ad49f8d613bdf3eca3a7a9", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/3e1cb8c4dee341cfe96ae9fe29b1acda52a6bb16", + "reference": "3e1cb8c4dee341cfe96ae9fe29b1acda52a6bb16", "shasum": "" }, "require": { @@ -16964,7 +16967,8 @@ "Symfony\\Bridge\\PhpUnit\\": "" }, "exclude-from-classmap": [ - "/Tests/" + "/Tests/", + "/bin/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -16984,7 +16988,7 @@ "description": "Provides utilities for PHPUnit, especially user deprecation notices management", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/phpunit-bridge/tree/v7.0.7" + "source": "https://github.com/symfony/phpunit-bridge/tree/v7.1.1" }, "funding": [ { @@ -17000,20 +17004,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-06-04T06:50:37+00:00" }, { "name": "symfony/web-profiler-bundle", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/web-profiler-bundle.git", - "reference": "a9a722210b391d7f6d97f140a5f2f7eee604d81a" + "reference": "77e2501c9dcc9c280605f9279ec9da85a0a72aa6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/a9a722210b391d7f6d97f140a5f2f7eee604d81a", - "reference": "a9a722210b391d7f6d97f140a5f2f7eee604d81a", + "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/77e2501c9dcc9c280605f9279ec9da85a0a72aa6", + "reference": "77e2501c9dcc9c280605f9279ec9da85a0a72aa6", "shasum": "" }, "require": { @@ -17065,7 +17069,7 @@ "dev" ], "support": { - "source": "https://github.com/symfony/web-profiler-bundle/tree/v7.0.7" + "source": "https://github.com/symfony/web-profiler-bundle/tree/v7.0.8" }, "funding": [ { @@ -17081,7 +17085,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "theseer/tokenizer", From d74b3f13263313acf4055d289d99cb126c0a3534 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 11 Jun 2024 20:19:59 -0500 Subject: [PATCH 033/335] docs(contributor): contributors readme action update (#817) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: nobodyatroot <35878315+nobodyatroot@users.noreply.github.com> --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f3384e03a..d8d500e43 100644 --- a/README.md +++ b/README.md @@ -96,18 +96,18 @@ For developers: - - cooperaj + + nobodyatroot
    - Adam Cooper + debounced
    - - nobodyatroot + + cooperaj
    - debounced + Adam Cooper
    From c153d62af55b5dd7f5c72797c9c06bcbf9def07f Mon Sep 17 00:00:00 2001 From: privacyguard <92675882+privacyguard@users.noreply.github.com> Date: Thu, 13 Jun 2024 01:48:08 +0300 Subject: [PATCH 034/335] Add support for the Privacy Portal OAUTH provider (#818) Co-authored-by: privacyguard --- .env.example | 2 + .env.example_docker | 2 + composer.json | 1 + composer.lock | 219 ++++++++++++------ config/kbin_routes/security.yaml | 10 + config/packages/knpu_oauth2_client.yaml | 7 + config/packages/security.yaml | 1 + config/services.yaml | 3 + docs/01-user/user_guide.md | 2 +- migrations/Version20240612234046.php | 29 +++ .../Security/PrivacyPortalController.php | 28 +++ src/Entity/User.php | 4 +- src/Security/PrivacyPortalAuthenticator.php | 118 ++++++++++ src/Twig/Components/LoginSocialsComponent.php | 7 + symfony.lock | 3 + templates/components/login_socials.html.twig | 6 +- 16 files changed, 363 insertions(+), 79 deletions(-) create mode 100644 migrations/Version20240612234046.php create mode 100644 src/Controller/Security/PrivacyPortalController.php create mode 100644 src/Security/PrivacyPortalAuthenticator.php diff --git a/.env.example b/.env.example index 761d665cc..72b827184 100644 --- a/.env.example +++ b/.env.example @@ -70,6 +70,8 @@ OAUTH_GOOGLE_ID= OAUTH_GOOGLE_SECRET= OAUTH_GITHUB_ID= OAUTH_GITHUB_SECRET= +OAUTH_PRIVACYPORTAL_ID= +OAUTH_PRIVACYPORTAL_SECRET= OAUTH_KEYCLOAK_ID= OAUTH_KEYCLOAK_SECRET= OAUTH_KEYCLOAK_URI= diff --git a/.env.example_docker b/.env.example_docker index 9b0bb042b..25b5d7c87 100644 --- a/.env.example_docker +++ b/.env.example_docker @@ -80,6 +80,8 @@ OAUTH_ZITADEL_BASE_URL= OAUTH_AUTHENTIK_ID= OAUTH_AUTHENTIK_SECRET= OAUTH_AUTHENTIK_BASE_URL= +OAUTH_PRIVACYPORTAL_ID= +OAUTH_PRIVACYPORTAL_SECRET= # If true, sign ins and sign ups will only be possible through the OAuth providers configured above SSO_ONLY_MODE= diff --git a/composer.json b/composer.json index e45cc496c..d54cbd6c8 100644 --- a/composer.json +++ b/composer.json @@ -57,6 +57,7 @@ "phpdocumentor/reflection-docblock": "^5.2", "phpstan/phpdoc-parser": "^0.4.9", "predis/predis": "^2.1", + "privacyportal/oauth2-privacyportal": "^0.1.1", "scheb/2fa-backup-code": "^7.2.0", "scheb/2fa-bundle": "^7.2.0", "scheb/2fa-totp": "^7.2.0", diff --git a/composer.lock b/composer.lock index 08b796ee4..c6d2a4af7 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "090cc34e9abb8db84dae3d7b1bbd21ad", + "content-hash": "d14113edc433c71c25f0a5a19d5e7a54", "packages": [ { "name": "aws/aws-crt-php", @@ -62,16 +62,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.308.3", + "version": "3.313.0", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "7fa0625056fa1fcf6732f89ba37b3f630d78de59" + "reference": "2f5f173300888d6f630ce24751a6ee0f1e6d72e8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/7fa0625056fa1fcf6732f89ba37b3f630d78de59", - "reference": "7fa0625056fa1fcf6732f89ba37b3f630d78de59", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/2f5f173300888d6f630ce24751a6ee0f1e6d72e8", + "reference": "2f5f173300888d6f630ce24751a6ee0f1e6d72e8", "shasum": "" }, "require": { @@ -151,9 +151,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.308.3" + "source": "https://github.com/aws/aws-sdk-php/tree/3.313.0" }, - "time": "2024-05-24T18:29:40+00:00" + "time": "2024-06-11T18:20:58+00:00" }, { "name": "babdev/pagerfanta-bundle", @@ -2159,16 +2159,16 @@ }, { "name": "embed/embed", - "version": "v4.4.10", + "version": "v4.4.11", "source": { "type": "git", "url": "https://github.com/oscarotero/Embed.git", - "reference": "8ac21505d048e8796c6cb9172ec5e81e5d0e0408" + "reference": "09a60be4f14fc60d063a8dba22594f7b43765958" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/oscarotero/Embed/zipball/8ac21505d048e8796c6cb9172ec5e81e5d0e0408", - "reference": "8ac21505d048e8796c6cb9172ec5e81e5d0e0408", + "url": "https://api.github.com/repos/oscarotero/Embed/zipball/09a60be4f14fc60d063a8dba22594f7b43765958", + "reference": "09a60be4f14fc60d063a8dba22594f7b43765958", "shasum": "" }, "require": { @@ -2228,7 +2228,7 @@ "support": { "email": "oom@oscarotero.com", "issues": "https://github.com/oscarotero/Embed/issues", - "source": "https://github.com/oscarotero/Embed/tree/v4.4.10" + "source": "https://github.com/oscarotero/Embed/tree/v4.4.11" }, "funding": [ { @@ -2244,7 +2244,7 @@ "type": "patreon" } ], - "time": "2023-12-10T12:30:47+00:00" + "time": "2024-06-10T16:01:33+00:00" }, { "name": "endroid/qr-code", @@ -3005,16 +3005,16 @@ }, { "name": "knplabs/knp-time-bundle", - "version": "v2.2.0", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/KnpLabs/KnpTimeBundle.git", - "reference": "69cb36a9f22ac8432e8532c9ae84e92d46820d96" + "reference": "93e9528415b28a19872d74b28e816045c0fd217b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/KnpLabs/KnpTimeBundle/zipball/69cb36a9f22ac8432e8532c9ae84e92d46820d96", - "reference": "69cb36a9f22ac8432e8532c9ae84e92d46820d96", + "url": "https://api.github.com/repos/KnpLabs/KnpTimeBundle/zipball/93e9528415b28a19872d74b28e816045c0fd217b", + "reference": "93e9528415b28a19872d74b28e816045c0fd217b", "shasum": "" }, "require": { @@ -3074,9 +3074,9 @@ ], "support": { "issues": "https://github.com/KnpLabs/KnpTimeBundle/issues", - "source": "https://github.com/KnpLabs/KnpTimeBundle/tree/v2.2.0" + "source": "https://github.com/KnpLabs/KnpTimeBundle/tree/v2.4.0" }, - "time": "2023-11-13T19:38:34+00:00" + "time": "2024-06-11T09:38:28+00:00" }, { "name": "knpuniversity/oauth2-client-bundle", @@ -5593,16 +5593,16 @@ }, { "name": "oneup/flysystem-bundle", - "version": "4.12.1", + "version": "4.12.2", "source": { "type": "git", "url": "https://github.com/1up-lab/OneupFlysystemBundle.git", - "reference": "625175dcb65f4cdedd52d0a644683a2ebdc688d2" + "reference": "888cceb2ee641b0d59d5feb31a2447318c311a48" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/1up-lab/OneupFlysystemBundle/zipball/625175dcb65f4cdedd52d0a644683a2ebdc688d2", - "reference": "625175dcb65f4cdedd52d0a644683a2ebdc688d2", + "url": "https://api.github.com/repos/1up-lab/OneupFlysystemBundle/zipball/888cceb2ee641b0d59d5feb31a2447318c311a48", + "reference": "888cceb2ee641b0d59d5feb31a2447318c311a48", "shasum": "" }, "require": { @@ -5676,9 +5676,9 @@ ], "support": { "issues": "https://github.com/1up-lab/OneupFlysystemBundle/issues", - "source": "https://github.com/1up-lab/OneupFlysystemBundle/tree/4.12.1" + "source": "https://github.com/1up-lab/OneupFlysystemBundle/tree/4.12.2" }, - "time": "2024-04-08T13:50:27+00:00" + "time": "2024-06-10T12:55:36+00:00" }, { "name": "oscarotero/html-parser", @@ -5780,7 +5780,7 @@ }, { "name": "pagerfanta/doctrine-collections-adapter", - "version": "v4.5.0", + "version": "v4.6.0", "source": { "type": "git", "url": "https://github.com/Pagerfanta/doctrine-collections-adapter.git", @@ -5820,28 +5820,29 @@ "pagerfanta" ], "support": { - "source": "https://github.com/Pagerfanta/doctrine-collections-adapter/tree/v4.5.0" + "source": "https://github.com/Pagerfanta/doctrine-collections-adapter/tree/v4.6.0" }, "time": "2024-03-06T23:51:47+00:00" }, { "name": "pagerfanta/doctrine-dbal-adapter", - "version": "v4.5.0", + "version": "v4.6.0", "source": { "type": "git", "url": "https://github.com/Pagerfanta/doctrine-dbal-adapter.git", - "reference": "4db40ab3ebcd8dbe150fc94c3b738ebaa2b09aca" + "reference": "4987681d2824a08f9f749c42014f61c972f596d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Pagerfanta/doctrine-dbal-adapter/zipball/4db40ab3ebcd8dbe150fc94c3b738ebaa2b09aca", - "reference": "4db40ab3ebcd8dbe150fc94c3b738ebaa2b09aca", + "url": "https://api.github.com/repos/Pagerfanta/doctrine-dbal-adapter/zipball/4987681d2824a08f9f749c42014f61c972f596d9", + "reference": "4987681d2824a08f9f749c42014f61c972f596d9", "shasum": "" }, "require": { "doctrine/dbal": "^3.5 || ^4.0", "pagerfanta/core": "^3.7 || ^4.0", - "php": "^8.1" + "php": "^8.1", + "symfony/deprecation-contracts": "^2.1 || ^3.0" }, "require-dev": { "phpunit/phpunit": "^10.5" @@ -5866,13 +5867,13 @@ "pagerfanta" ], "support": { - "source": "https://github.com/Pagerfanta/doctrine-dbal-adapter/tree/v4.5.0" + "source": "https://github.com/Pagerfanta/doctrine-dbal-adapter/tree/v4.6.0" }, - "time": "2024-03-06T23:51:47+00:00" + "time": "2024-05-29T22:02:46+00:00" }, { "name": "pagerfanta/doctrine-orm-adapter", - "version": "v4.5.0", + "version": "v4.6.0", "source": { "type": "git", "url": "https://github.com/Pagerfanta/doctrine-orm-adapter.git", @@ -5913,22 +5914,22 @@ "pagerfanta" ], "support": { - "source": "https://github.com/Pagerfanta/doctrine-orm-adapter/tree/v4.5.0" + "source": "https://github.com/Pagerfanta/doctrine-orm-adapter/tree/v4.6.0" }, "time": "2024-03-06T23:51:47+00:00" }, { "name": "pagerfanta/twig", - "version": "v4.5.0", + "version": "v4.6.0", "source": { "type": "git", "url": "https://github.com/Pagerfanta/twig.git", - "reference": "74d43875490442a59ddca66e6e3fc66a9b583dd4" + "reference": "b00b600c4c81bc2e8c001c230b13473584dad16e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Pagerfanta/twig/zipball/74d43875490442a59ddca66e6e3fc66a9b583dd4", - "reference": "74d43875490442a59ddca66e6e3fc66a9b583dd4", + "url": "https://api.github.com/repos/Pagerfanta/twig/zipball/b00b600c4c81bc2e8c001c230b13473584dad16e", + "reference": "b00b600c4c81bc2e8c001c230b13473584dad16e", "shasum": "" }, "require": { @@ -5957,9 +5958,9 @@ "pagerfanta" ], "support": { - "source": "https://github.com/Pagerfanta/twig/tree/v4.5.0" + "source": "https://github.com/Pagerfanta/twig/tree/v4.6.0" }, - "time": "2024-03-06T23:51:47+00:00" + "time": "2024-05-08T00:35:50+00:00" }, { "name": "paragonie/constant_time_encoding", @@ -6464,6 +6465,71 @@ ], "time": "2023-09-13T16:42:03+00:00" }, + { + "name": "privacyportal/oauth2-privacyportal", + "version": "v0.1.1", + "source": { + "type": "git", + "url": "https://github.com/privacyportal/oauth2-privacyportal.git", + "reference": "0522c089262c71dd3fa05ec5e3f49377c6ebaf3b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/privacyportal/oauth2-privacyportal/zipball/0522c089262c71dd3fa05ec5e3f49377c6ebaf3b", + "reference": "0522c089262c71dd3fa05ec5e3f49377c6ebaf3b", + "shasum": "" + }, + "require": { + "ext-json": "*", + "league/oauth2-client": "^2.0", + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.4", + "phpunit/phpunit": "^9.5", + "squizlabs/php_codesniffer": "^3.6" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\OAuth2\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Privacy Portal", + "homepage": "https://github.com/privacyportal" + }, + { + "name": "Steven Maguire", + "email": "stevenmaguire@gmail.com", + "homepage": "https://github.com/stevenmaguire" + }, + { + "name": "Woody Gilk", + "email": "woody.gilk@gmail.com", + "homepage": "https://github.com/shadowhand" + } + ], + "description": "PrivacyPortal OAuth 2.0 Client Provider for The PHP League OAuth2-Client", + "keywords": [ + "authorisation", + "authorization", + "client", + "oauth", + "oauth2", + "privacyportal" + ], + "support": { + "issues": "https://github.com/privacyportal/oauth2-privacyportal/issues", + "source": "https://github.com/privacyportal/oauth2-privacyportal/tree/v0.1.1" + }, + "time": "2023-12-08T01:55:07+00:00" + }, { "name": "psr/cache", "version": "3.0.0", @@ -6976,7 +7042,7 @@ }, { "name": "scheb/2fa-backup-code", - "version": "v7.3.0", + "version": "v7.3.1", "source": { "type": "git", "url": "https://github.com/scheb/2fa-backup-code.git", @@ -7019,22 +7085,22 @@ "two-step" ], "support": { - "source": "https://github.com/scheb/2fa-backup-code/tree/v7.3.0" + "source": "https://github.com/scheb/2fa-backup-code/tree/v7.3.1" }, "time": "2023-12-03T16:24:13+00:00" }, { "name": "scheb/2fa-bundle", - "version": "v7.3.0", + "version": "v7.3.1", "source": { "type": "git", "url": "https://github.com/scheb/2fa-bundle.git", - "reference": "9d5a7b680ce2e6eb15bdfb779c09313b88f365cd" + "reference": "4c8b421b32dffa5b911bbe7d22a7f1f8158773a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/scheb/2fa-bundle/zipball/9d5a7b680ce2e6eb15bdfb779c09313b88f365cd", - "reference": "9d5a7b680ce2e6eb15bdfb779c09313b88f365cd", + "url": "https://api.github.com/repos/scheb/2fa-bundle/zipball/4c8b421b32dffa5b911bbe7d22a7f1f8158773a8", + "reference": "4c8b421b32dffa5b911bbe7d22a7f1f8158773a8", "shasum": "" }, "require": { @@ -7086,13 +7152,13 @@ "two-step" ], "support": { - "source": "https://github.com/scheb/2fa-bundle/tree/v7.3.0" + "source": "https://github.com/scheb/2fa-bundle/tree/v7.3.1" }, - "time": "2024-04-20T14:21:34+00:00" + "time": "2024-06-10T20:47:03+00:00" }, { "name": "scheb/2fa-totp", - "version": "v7.3.0", + "version": "v7.3.1", "source": { "type": "git", "url": "https://github.com/scheb/2fa-totp.git", @@ -7136,7 +7202,7 @@ "two-step" ], "support": { - "source": "https://github.com/scheb/2fa-totp/tree/v7.3.0" + "source": "https://github.com/scheb/2fa-totp/tree/v7.3.1" }, "time": "2024-01-18T20:20:03+00:00" }, @@ -13813,16 +13879,16 @@ }, { "name": "symfonycasts/reset-password-bundle", - "version": "v1.21.0", + "version": "v1.22.0", "source": { "type": "git", "url": "https://github.com/SymfonyCasts/reset-password-bundle.git", - "reference": "598fc74acf0652abf495ac8db1c16234f5d59ded" + "reference": "d9cf4395c0a19a3093bc51b10f508b38f98117f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/SymfonyCasts/reset-password-bundle/zipball/598fc74acf0652abf495ac8db1c16234f5d59ded", - "reference": "598fc74acf0652abf495ac8db1c16234f5d59ded", + "url": "https://api.github.com/repos/SymfonyCasts/reset-password-bundle/zipball/d9cf4395c0a19a3093bc51b10f508b38f98117f5", + "reference": "d9cf4395c0a19a3093bc51b10f508b38f98117f5", "shasum": "" }, "require": { @@ -13837,6 +13903,7 @@ "doctrine/annotations": "^1.0", "doctrine/doctrine-bundle": "^2.8", "doctrine/orm": "^2.13", + "phpstan/phpstan": "^1.11.x-dev", "symfony/framework-bundle": "^5.4 | ^6.0 | ^7.0", "symfony/phpunit-bridge": "^5.4 | ^6.0 | ^7.0" }, @@ -13853,9 +13920,9 @@ "description": "Symfony bundle that adds password reset functionality.", "support": { "issues": "https://github.com/SymfonyCasts/reset-password-bundle/issues", - "source": "https://github.com/SymfonyCasts/reset-password-bundle/tree/v1.21.0" + "source": "https://github.com/SymfonyCasts/reset-password-bundle/tree/v1.22.0" }, - "time": "2024-03-05T20:31:46+00:00" + "time": "2024-06-06T11:59:57+00:00" }, { "name": "symfonycasts/verify-email-bundle", @@ -14473,16 +14540,16 @@ }, { "name": "zircote/swagger-php", - "version": "4.9.2", + "version": "4.10.0", "source": { "type": "git", "url": "https://github.com/zircote/swagger-php.git", - "reference": "256d42cb07ba1c2206d66bc7516ee3d3e3e9f0b2" + "reference": "2d983ce67b9eb7e18403ae7bc5e765f8ce7b8d56" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zircote/swagger-php/zipball/256d42cb07ba1c2206d66bc7516ee3d3e3e9f0b2", - "reference": "256d42cb07ba1c2206d66bc7516ee3d3e3e9f0b2", + "url": "https://api.github.com/repos/zircote/swagger-php/zipball/2d983ce67b9eb7e18403ae7bc5e765f8ce7b8d56", + "reference": "2d983ce67b9eb7e18403ae7bc5e765f8ce7b8d56", "shasum": "" }, "require": { @@ -14548,29 +14615,29 @@ ], "support": { "issues": "https://github.com/zircote/swagger-php/issues", - "source": "https://github.com/zircote/swagger-php/tree/4.9.2" + "source": "https://github.com/zircote/swagger-php/tree/4.10.0" }, - "time": "2024-05-02T21:36:00+00:00" + "time": "2024-06-06T22:42:02+00:00" } ], "packages-dev": [ { "name": "dama/doctrine-test-bundle", - "version": "v8.1.0", + "version": "v8.2.0", "source": { "type": "git", "url": "https://github.com/dmaicher/doctrine-test-bundle.git", - "reference": "21b4dd73546991c7df34ba92ecbf305a1ae5a0ee" + "reference": "1f81a280ea63f049d24e9c8ce00e557b18e0ff2f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dmaicher/doctrine-test-bundle/zipball/21b4dd73546991c7df34ba92ecbf305a1ae5a0ee", - "reference": "21b4dd73546991c7df34ba92ecbf305a1ae5a0ee", + "url": "https://api.github.com/repos/dmaicher/doctrine-test-bundle/zipball/1f81a280ea63f049d24e9c8ce00e557b18e0ff2f", + "reference": "1f81a280ea63f049d24e9c8ce00e557b18e0ff2f", "shasum": "" }, "require": { "doctrine/dbal": "^3.3 || ^4.0", - "doctrine/doctrine-bundle": "^2.2.2", + "doctrine/doctrine-bundle": "^2.11.0", "php": "^7.4 || ^8.0", "psr/cache": "^1.0 || ^2.0 || ^3.0", "symfony/cache": "^5.4 || ^6.3 || ^7.0", @@ -14617,9 +14684,9 @@ ], "support": { "issues": "https://github.com/dmaicher/doctrine-test-bundle/issues", - "source": "https://github.com/dmaicher/doctrine-test-bundle/tree/v8.1.0" + "source": "https://github.com/dmaicher/doctrine-test-bundle/tree/v8.2.0" }, - "time": "2024-05-21T18:06:21+00:00" + "time": "2024-05-28T15:41:06+00:00" }, { "name": "doctrine/data-fixtures", @@ -15229,16 +15296,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.11.2", + "version": "1.11.4", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "0d5d4294a70deb7547db655c47685d680e39cfec" + "reference": "9100a76ce8015b9aa7125b9171ae3a76887b6c82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/0d5d4294a70deb7547db655c47685d680e39cfec", - "reference": "0d5d4294a70deb7547db655c47685d680e39cfec", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/9100a76ce8015b9aa7125b9171ae3a76887b6c82", + "reference": "9100a76ce8015b9aa7125b9171ae3a76887b6c82", "shasum": "" }, "require": { @@ -15283,7 +15350,7 @@ "type": "github" } ], - "time": "2024-05-24T13:23:04+00:00" + "time": "2024-06-06T12:19:22+00:00" }, { "name": "phpunit/php-code-coverage", diff --git a/config/kbin_routes/security.yaml b/config/kbin_routes/security.yaml index e3bf45ddd..3552a4f97 100644 --- a/config/kbin_routes/security.yaml +++ b/config/kbin_routes/security.yaml @@ -83,6 +83,16 @@ oauth_github_verify: path: /oauth/github/verify methods: [ GET ] +oauth_privacyportal_connect: + controller: App\Controller\Security\PrivacyPortalController::connect + path: /oauth/privacyportal/connect + methods: [ GET ] + +oauth_privacyportal_verify: + controller: App\Controller\Security\PrivacyPortalController::verify + path: /oauth/privacyportal/verify + methods: [ GET ] + oauth_keycloak_connect: controller: App\Controller\Security\KeycloakController::connect path: /oauth/keycloak/connect diff --git a/config/packages/knpu_oauth2_client.yaml b/config/packages/knpu_oauth2_client.yaml index 91443b918..470c79a0a 100644 --- a/config/packages/knpu_oauth2_client.yaml +++ b/config/packages/knpu_oauth2_client.yaml @@ -26,6 +26,13 @@ knpu_oauth2_client: client_secret: '%oauth_github_secret%' redirect_route: oauth_github_verify redirect_params: { } + privacyportal: + type: generic + provider_class: League\OAuth2\Client\Provider\PrivacyPortal + client_id: '%oauth_privacyportal_id%' + client_secret: '%oauth_privacyportal_secret%' + redirect_route: oauth_privacyportal_verify + redirect_params: { } keycloak: type: keycloak client_id: '%oauth_keycloak_id%' diff --git a/config/packages/security.yaml b/config/packages/security.yaml index 0e6b5a847..ed1b84e27 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -37,6 +37,7 @@ security: - App\Security\FacebookAuthenticator - App\Security\GoogleAuthenticator - App\Security\GithubAuthenticator + - App\Security\PrivacyPortalAuthenticator - App\Security\KeycloakAuthenticator - App\Security\SimpleLoginAuthenticator - App\Security\ZitadelAuthenticator diff --git a/config/services.yaml b/config/services.yaml index 4290f94b6..7ce177852 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -47,6 +47,9 @@ parameters: oauth_github_id: "%env(default::OAUTH_GITHUB_ID)%" oauth_github_secret: "%env(OAUTH_GITHUB_SECRET)%" + oauth_privacyportal_id: "%env(default::OAUTH_PRIVACYPORTAL_ID)%" + oauth_privacyportal_secret: "%env(OAUTH_PRIVACYPORTAL_SECRET)%" + oauth_keycloak_id: "%env(default::OAUTH_KEYCLOAK_ID)%" oauth_keycloak_secret: "%env(OAUTH_KEYCLOAK_SECRET)%" oauth_keycloak_uri: "%env(OAUTH_KEYCLOAK_URI)%" diff --git a/docs/01-user/user_guide.md b/docs/01-user/user_guide.md index dd0b7ddf1..241fe92df 100644 --- a/docs/01-user/user_guide.md +++ b/docs/01-user/user_guide.md @@ -43,7 +43,7 @@ much you can change the appearance of the platform to suit your preferences. The process of registering for a user account on a platform usually involves providing a username (which will also serve as your identifier in the fediverse), password, and email address to receive an activation link. -Another option is to create an account through social media platforms such as Google, Facebook, or Github. In this case, +Another option is to create an account through social media platforms such as Google, Facebook, Github, or PrivacyPortal. In this case, you can use your social media login credentials to sign up, but you will need to visit your user panel and set up your username before you can take any actions on the platform. However, **you will have only up to an hour after registration ** to set up your default username before this option expires go to (Settings > Profile). diff --git a/migrations/Version20240612234046.php b/migrations/Version20240612234046.php new file mode 100644 index 000000000..98e9f6c83 --- /dev/null +++ b/migrations/Version20240612234046.php @@ -0,0 +1,29 @@ +addSql('ALTER TABLE "user" ADD oauth_privacyportal_id VARCHAR(255) DEFAULT NULL'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE "user" DROP oauth_privacyportal_id'); + } +} diff --git a/src/Controller/Security/PrivacyPortalController.php b/src/Controller/Security/PrivacyPortalController.php new file mode 100644 index 000000000..24bd6a1a8 --- /dev/null +++ b/src/Controller/Security/PrivacyPortalController.php @@ -0,0 +1,28 @@ +getClient('privacyportal') + ->redirect([ + 'openid', + 'name', + 'email', + ]); + } + + public function verify(Request $request, ClientRegistry $client) + { + } +} diff --git a/src/Entity/User.php b/src/Entity/User.php index 120912036..450157fe2 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -116,6 +116,8 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface, Visibil public ?string $oauthGoogleId = null; #[Column(type: 'string', nullable: true)] public ?string $oauthFacebookId = null; + #[Column(name: 'oauth_privacyportal_id', type: 'string', nullable: true)] + public ?string $oauthPrivacyPortalId = null; #[Column(type: 'string', nullable: true)] public ?string $oauthKeycloakId = null; #[Column(type: 'string', nullable: true)] @@ -759,7 +761,7 @@ public function removeOAuth2UserConsent(OAuth2UserConsent $oAuth2UserConsent): s public function isSsoControlled(): bool { - return $this->oauthAzureId || $this->oauthGithubId || $this->oauthGoogleId || $this->oauthFacebookId || $this->oauthKeycloakId || $this->oauthSimpleLoginId || $this->oauthZitadelId || $this->oauthAuthentikId; + return $this->oauthAzureId || $this->oauthGithubId || $this->oauthGoogleId || $this->oauthFacebookId || $this->oauthKeycloakId || $this->oauthSimpleLoginId || $this->oauthZitadelId || $this->oauthAuthentikId || $this->oauthPrivacyPortalId; } public function getCustomCss(): ?string diff --git a/src/Security/PrivacyPortalAuthenticator.php b/src/Security/PrivacyPortalAuthenticator.php new file mode 100644 index 000000000..b69857330 --- /dev/null +++ b/src/Security/PrivacyPortalAuthenticator.php @@ -0,0 +1,118 @@ +attributes->get('_route'); + } + + public function authenticate(Request $request): Passport + { + $client = $this->clientRegistry->getClient('privacyportal'); + $accessToken = $this->fetchAccessToken($client); + $slugger = $this->slugger; + + return new SelfValidatingPassport( + new UserBadge($accessToken->getToken(), function () use ($accessToken, $client, $slugger) { + /** @var PrivacyPortalResourceOwner $privacyPortalUser */ + $privacyPortalUser = $client->fetchUserFromToken($accessToken); + + $existingUser = $this->entityManager->getRepository(User::class)->findOneBy( + ['oauthPrivacyPortalId' => (string) $privacyPortalUser->getId()] + ); + + if ($existingUser) { + return $existingUser; + } + + $user = $this->entityManager->getRepository(User::class)->findOneBy(['email' => $privacyPortalUser->getEmail()] + ); + + if ($user) { + $user->oauthPrivacyPortalId = (string) $privacyPortalUser->getId(); + + $this->entityManager->persist($user); + $this->entityManager->flush(); + + return $user; + } + + if (false === $this->settingsManager->get('MBIN_SSO_REGISTRATIONS_ENABLED')) { + throw new CustomUserMessageAuthenticationException('MBIN_SSO_REGISTRATIONS_ENABLED'); + } + + $username = $slugger->slug($privacyPortalUser->getNickname()); + + if ($this->userRepository->count(['username' => $username]) > 0) { + $username .= rand(1, 9999); + } + + $dto = (new UserDto())->create( + $username, + $privacyPortalUser->getEmail() + ); + + $dto->plainPassword = bin2hex(random_bytes(20)); + $dto->ip = $this->ipResolver->resolve(); + + $user = $this->userManager->create($dto, false); + $user->oauthPrivacyPortalId = (string) $privacyPortalUser->getId(); + $user->isVerified = true; + + $this->entityManager->persist($user); + $this->entityManager->flush(); + + return $user; + }) + ); + } + + public function onAuthenticationSuccess( + Request $request, + TokenInterface $token, + string $firewallName + ): ?Response { + $targetUrl = $this->router->generate('user_settings_profile'); + + return new RedirectResponse($targetUrl); + } + + public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response + { + $message = strtr($exception->getMessageKey(), $exception->getMessageData()); + + return new Response($message, Response::HTTP_FORBIDDEN); + } +} diff --git a/src/Twig/Components/LoginSocialsComponent.php b/src/Twig/Components/LoginSocialsComponent.php index 4b614d578..f6faa29c4 100644 --- a/src/Twig/Components/LoginSocialsComponent.php +++ b/src/Twig/Components/LoginSocialsComponent.php @@ -17,6 +17,8 @@ public function __construct( private readonly ?string $oauthFacebookId, #[Autowire('%oauth_github_id%')] private readonly ?string $oauthGithubId, + #[Autowire('%oauth_privacyportal_id%')] + private readonly ?string $oauthPrivacyPortalId, #[Autowire('%oauth_keycloak_id%')] private readonly ?string $oauthKeycloakId, #[Autowire('%oauth_simplelogin_id%')] @@ -45,6 +47,11 @@ public function githubEnabled(): bool return !empty($this->oauthGithubId); } + public function privacyPortalEnabled(): bool + { + return !empty($this->oauthPrivacyPortalId); + } + public function keycloakEnabled(): bool { return !empty($this->oauthKeycloakId); diff --git a/symfony.lock b/symfony.lock index c1d724d62..2f973ab91 100644 --- a/symfony.lock +++ b/symfony.lock @@ -360,6 +360,9 @@ "tests/bootstrap.php" ] }, + "privacyportal/oauth2-privacyportal": { + "version": "0.1.1" + }, "psr/cache": { "version": "1.0.1" }, diff --git a/templates/components/login_socials.html.twig b/templates/components/login_socials.html.twig index d9ab5bf6d..919b361f5 100644 --- a/templates/components/login_socials.html.twig +++ b/templates/components/login_socials.html.twig @@ -1,5 +1,5 @@ {# @var this App\Twig\Components\LoginSocialsComponent #} -{%- set HAS_ANY_SOCIAL = this.googleEnabled or this.facebookEnabled or this.githubEnabled or this.keycloakEnabled or this.simpleloginEnabled or this.zitadelEnabled or this.authentikEnabled or this.azureEnabled -%} +{%- set HAS_ANY_SOCIAL = this.googleEnabled or this.facebookEnabled or this.githubEnabled or this.keycloakEnabled or this.simpleloginEnabled or this.zitadelEnabled or this.authentikEnabled or this.azureEnabled or this.privacyPortalEnabled -%} {% if HAS_ANY_SOCIAL %} {% if not mbin_sso_only_mode() and not mbin_sso_show_first() %}
    @@ -37,6 +37,10 @@ {{ 'continue_with'|trans }} Microsoft {% endif %} + {% if this.privacyPortalEnabled %} + + {{ 'continue_with'|trans }} Privacy Portal + {% endif %} {% if not mbin_sso_only_mode() and mbin_sso_show_first() %}
    From cca38d821ee0609a56767b8ab54540ad254eb042 Mon Sep 17 00:00:00 2001 From: debounced <35878315+nobodyatroot@users.noreply.github.com> Date: Wed, 12 Jun 2024 18:51:25 -0500 Subject: [PATCH 035/335] Update contrib workflow with new version and permissions (#820) --- .github/workflows/contrib.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/contrib.yaml b/.github/workflows/contrib.yaml index 44953d758..e4326a81c 100644 --- a/.github/workflows/contrib.yaml +++ b/.github/workflows/contrib.yaml @@ -8,8 +8,11 @@ jobs: contrib-readme: runs-on: ubuntu-latest name: Update contrib in README + permissions: + contents: write + pull-requests: write steps: - name: Contribute List - uses: akhilmhdh/contributors-readme-action@v2.3.9 + uses: akhilmhdh/contributors-readme-action@v2.3.10 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From e969601b5369cb168f95d0e014ed4faa61182d6b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 13 Jun 2024 00:44:48 +0000 Subject: [PATCH 036/335] docs(contributor): contributors readme action update (#821) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: nobodyatroot <35878315+nobodyatroot@users.noreply.github.com> --- README.md | 430 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 222 insertions(+), 208 deletions(-) diff --git a/README.md b/README.md index d8d500e43..98fca44d0 100644 --- a/README.md +++ b/README.md @@ -59,214 +59,228 @@ For developers: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    - - ernestwisniewski -
    - Ernest -
    -
    - - melroy89 -
    - Melroy van den Berg -
    -
    - - e-five256 -
    - e-five -
    -
    - - asdfzdfj -
    - asdfzdfj -
    -
    - - SzymonKaminski -
    - SzymonKaminski -
    -
    - - nobodyatroot -
    - debounced -
    -
    - - cooperaj -
    - Adam Cooper -
    -
    - - BentiGorlich -
    - BentiGorlich -
    -
    - - simonrcodrington -
    - Simon Codrington -
    -
    - - weblate -
    - Weblate (bot) -
    -
    - - kkoyung -
    - Kingsley Yung -
    -
    - - TheVillageGuy -
    - TheVillageGuy -
    -
    - - danielpervan -
    - Daniel Pervan -
    -
    - - Ahrotahn -
    - Ahrotahn -
    -
    - - GauthierPLM -
    - Gauthier POGAM--LE MONTAGNER -
    -
    - - thepaperpilot -
    - Anthony Lawn -
    -
    - - chall8908 -
    - Chris Hall -
    -
    - - andrewmoise -
    - andrewmoise -
    -
    - - CocoPoops -
    - CocoPoops -
    -
    - - garrettw -
    - Garrett W. -
    -
    - - piotr-sikora-v -
    - Piotr Sikora -
    -
    - - lilfade -
    - Bryson -
    -
    - - vpzomtrrfrt -
    - vpzomtrrfrt -
    -
    - - cavebob -
    - cavebob -
    -
    - - drupol -
    - Pol Dellaiera -
    -
    - - ryanmonsen -
    - ryanmonsen -
    -
    - - WebVoid -
    - Webvoid -
    -
    - - comradekingu -
    - Allan Nordhøy -
    -
    - - CSDUMMI -
    - CSDUMMI -
    -
    + + ernestwisniewski +
    + Ernest +
    +
    + + melroy89 +
    + Melroy van den Berg +
    +
    + + e-five256 +
    + e-five +
    +
    + + asdfzdfj +
    + asdfzdfj +
    +
    + + SzymonKaminski +
    + SzymonKaminski +
    +
    + + nobodyatroot +
    + debounced +
    +
    + + cooperaj +
    + Adam Cooper +
    +
    + + BentiGorlich +
    + BentiGorlich +
    +
    + + simonrcodrington +
    + Simon Codrington +
    +
    + + weblate +
    + Weblate (bot) +
    +
    + + kkoyung +
    + Kingsley Yung +
    +
    + + TheVillageGuy +
    + TheVillageGuy +
    +
    + + danielpervan +
    + Daniel Pervan +
    +
    + + Ahrotahn +
    + Ahrotahn +
    +
    + + GauthierPLM +
    + Gauthier POGAM--LE MONTAGNER +
    +
    + + CocoPoops +
    + CocoPoops +
    +
    + + andrewmoise +
    + andrewmoise +
    +
    + + chall8908 +
    + Chris Hall +
    +
    + + thepaperpilot +
    + Anthony Lawn +
    +
    + + garrettw +
    + Garrett W. +
    +
    + + piotr-sikora-v +
    + Piotr Sikora +
    +
    + + lilfade +
    + Bryson +
    +
    + + vpzomtrrfrt +
    + vpzomtrrfrt +
    +
    + + cavebob +
    + cavebob +
    +
    + + drupol +
    + Pol Dellaiera +
    +
    + + ryanmonsen +
    + ryanmonsen +
    +
    + + WebVoid +
    + Webvoid +
    +
    + + comradekingu +
    + Allan Nordhøy +
    +
    + + CSDUMMI +
    + CSDUMMI +
    +
    + + privacyguard +
    + privacyguard +
    +
    From 2e9b04cb4bbe06788b436d9b13187043421bc7f3 Mon Sep 17 00:00:00 2001 From: CocoPoops Date: Fri, 14 Jun 2024 00:50:11 +0000 Subject: [PATCH 037/335] Fix Authentik Account Registration (#824) --- src/Security/AuthentikAuthenticator.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Security/AuthentikAuthenticator.php b/src/Security/AuthentikAuthenticator.php index 828cabbda..bac547b92 100644 --- a/src/Security/AuthentikAuthenticator.php +++ b/src/Security/AuthentikAuthenticator.php @@ -95,8 +95,7 @@ public function authenticate(Request $request): Passport throw new CustomUserMessageAuthenticationException('MBIN_SSO_REGISTRATIONS_ENABLED'); } - $email = $authentikUser->toArray()['preferred_username']; - $username = $slugger->slug(substr($email, 0, strrpos($email, '@'))); + $username = $slugger->slug($authentikUser->toArray()['preferred_username']); if ($this->userRepository->count(['username' => $username]) > 0) { $username .= rand(1, 999); From 8afe388dae530d94ee30ebb0e74f3b5a0965b82c Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Fri, 14 Jun 2024 13:04:08 +0000 Subject: [PATCH 038/335] Improve modlog (#828) --- .../User/ThemeSettingsController.php | 4 +++ .../layout/_options_appearance.html.twig | 5 ++++ templates/modlog/_blocks.html.twig | 30 +++++++++++-------- templates/modlog/front.html.twig | 9 +++++- templates/modlog/magazine.html.twig | 9 +++++- translations/messages.en.yaml | 2 ++ 6 files changed, 45 insertions(+), 14 deletions(-) diff --git a/src/Controller/User/ThemeSettingsController.php b/src/Controller/User/ThemeSettingsController.php index de6b6da50..7bb93808d 100644 --- a/src/Controller/User/ThemeSettingsController.php +++ b/src/Controller/User/ThemeSettingsController.php @@ -41,6 +41,8 @@ class ThemeSettingsController extends AbstractController public const KBIN_SUBSCRIPTIONS_SIDEBARS_SAME_SIDE = 'kbin_subscriptions_sidebars_same_side'; public const KBIN_SUBSCRIPTIONS_LARGE_PANEL = 'kbin_subscriptions_large_panel'; public const KBIN_SUBSCRIPTIONS_SHOW_MAGAZINE_ICON = 'kbin_subscriptions_show_magazine_icon'; + public const MBIN_MODERATION_LOG_SHOW_USER_AVATARS = 'mbin_moderation_log_show_user_avatars'; + public const MBIN_MODERATION_LOG_SHOW_MAGAZINE_ICONS = 'mbin_moderation_log_show_magazine_icons'; public const CLASSIC = 'classic'; public const CHAT = 'chat'; @@ -96,6 +98,8 @@ class ThemeSettingsController extends AbstractController self::KBIN_SUBSCRIPTIONS_SIDEBARS_SAME_SIDE, self::KBIN_SUBSCRIPTIONS_LARGE_PANEL, self::KBIN_SUBSCRIPTIONS_SHOW_MAGAZINE_ICON, + self::MBIN_MODERATION_LOG_SHOW_USER_AVATARS, + self::MBIN_MODERATION_LOG_SHOW_MAGAZINE_ICONS, ]; public const VALUES = [ diff --git a/templates/layout/_options_appearance.html.twig b/templates/layout/_options_appearance.html.twig index bd3e92095..481d32dc9 100644 --- a/templates/layout/_options_appearance.html.twig +++ b/templates/layout/_options_appearance.html.twig @@ -51,4 +51,9 @@ {{ component('settings_row_enum', {label: 'comment_reply_position'|trans, help: 'comment_reply_position_help'|trans, settingsKey: 'KBIN_COMMENTS_REPLY_POSITION', values: [ {name: 'position_top'|trans , value: 'TOP'}, {name: 'position_bottom'|trans , value: 'BOTTOM' } ], defaultValue: 'TOP' } ) }} {{ component('settings_row_switch', {label: 'show_avatars_on_comments'|trans, help: 'show_avatars_on_comments_help'|trans, settingsKey: 'KBIN_COMMENTS_SHOW_USER_AVATAR', defaultValue: true}) }} + {{ 'mod_log'|trans }} +
    + {{ component('settings_row_switch', {label: 'show_users_avatars'|trans, settingsKey: 'MBIN_MODERATION_LOG_SHOW_USER_AVATARS', defaultValue: false}) }} + {{ component('settings_row_switch', {label: 'show_magazines_icons'|trans, settingsKey: 'MBIN_MODERATION_LOG_SHOW_MAGAZINE_ICONS', defaultValue: false}) }} +
    diff --git a/templates/modlog/_blocks.html.twig b/templates/modlog/_blocks.html.twig index 7e64b98d4..781abb443 100644 --- a/templates/modlog/_blocks.html.twig +++ b/templates/modlog/_blocks.html.twig @@ -1,58 +1,64 @@ {% block log_entry_deleted %} - {{ component('user_inline', {user: log.user, showAvatar: false}) }} {{ 'removed_thread_by'|trans|lower }} {{ component('user_inline', {user: log.entry.user, showAvatar: false}) }}{% if showMagazine %} {{ 'in'|trans|lower }} {{ component('magazine_inline', {magazine: log.entry.magazine, showIcon: false }) }}{% endif %} - + {{ component('user_inline', {user: log.user, showAvatar: showAvatars}) }} {{ 'removed_thread_by'|trans|lower }} {{ component('user_inline', {user: log.entry.user}) }}{% if showMagazine %} {{ 'in'|trans|lower }} {{ component('magazine_inline', {magazine: log.entry.magazine, showAvatar: showIcons }) }}{% endif %} - {{ log.entry.shortTitle(300) }} {% endblock %} {% block log_entry_restored %} - {{ component('user_inline', {user: log.user, showAvatar: false}) }} {{ 'restored_thread_by'|trans|lower }} {{ component('user_inline', {user: log.entry.user, showAvatar: false}) }}{% if showMagazine %} {{ 'in'|trans|lower }} {{ component('magazine_inline', {magazine: log.entry.magazine, showIcon: false }) }}{% endif %} - + {{ component('user_inline', {user: log.user, showAvatar: showAvatars}) }} {{ 'restored_thread_by'|trans|lower }} {{ component('user_inline', {user: log.entry.user}) }}{% if showMagazine %} {{ 'in'|trans|lower }} {{ component('magazine_inline', {magazine: log.entry.magazine, showAvatar: showIcons }) }}{% endif %} - {{ log.entry.shortTitle(300) }} {% endblock %} {% block log_entry_comment_deleted %} - {{ component('user_inline', {user: log.user, showAvatar: false}) }} {{ 'removed_comment_by'|trans|lower }} {{ component('user_inline', {user: log.comment.user, showAvatar: false}) }}{% if showMagazine %} {{ 'in'|trans|lower }} {{ component('magazine_inline', {magazine: log.comment.magazine, showIcon: false }) }}{% endif %} - + {{ component('user_inline', {user: log.user, showAvatar: showAvatars}) }} {{ 'removed_comment_by'|trans|lower }} {{ component('user_inline', {user: log.comment.user}) }}{% if showMagazine %} {{ 'in'|trans|lower }} {{ component('magazine_inline', {magazine: log.comment.magazine, showAvatar: showIcons }) }}{% endif %} - {{ log.comment.shortTitle(300) }} {% endblock %} {% block log_entry_comment_restored %} - {{ component('user_inline', {user: log.user, showAvatar: false}) }} {{ 'restored_comment_by'|trans|lower }} {{ component('user_inline', {user: log.comment.user, showAvatar: false}) }}{% if showMagazine %} {{ 'in'|trans|lower }} {{ component('magazine_inline', {magazine: log.comment.magazine, showIcon: false }) }}{% endif %} - + {{ component('user_inline', {user: log.user, showAvatar: showAvatars}) }} {{ 'restored_comment_by'|trans|lower }} {{ component('user_inline', {user: log.comment.user}) }}{% if showMagazine %} {{ 'in'|trans|lower }} {{ component('magazine_inline', {magazine: log.comment.magazine, showAvatar: showIcons }) }}{% endif %} - {{ log.comment.shortTitle(300) }} {% endblock %} {% block log_post_deleted %} - {{ component('user_inline', {user: log.user, showAvatar: false}) }} {{ 'removed_post_by'|trans|lower }} {{ component('user_inline', {user: log.post.user, showAvatar: false}) }}{% if showMagazine %} {{ 'in'|trans|lower }} {{ component('magazine_inline', {magazine: log.post.magazine, showIcon: false }) }}{% endif %} - + {{ component('user_inline', {user: log.user, showAvatar: showAvatars}) }} {{ 'removed_post_by'|trans|lower }} {{ component('user_inline', {user: log.post.user}) }}{% if showMagazine %} {{ 'in'|trans|lower }} {{ component('magazine_inline', {magazine: log.post.magazine, showAvatar: showIcons }) }}{% endif %} - {{ log.post.shortTitle(300) }} {% endblock %} {% block log_post_restored %} - {{ component('user_inline', {user: log.user, showAvatar: false}) }} {{ 'restored_post_by'|trans|lower }} {{ component('user_inline', {user: log.post.user, showAvatar: false}) }}{% if showMagazine %} {{ 'in'|trans|lower }} {{ component('magazine_inline', {magazine: log.post.magazine, showIcon: false }) }}{% endif %} - + {{ component('user_inline', {user: log.user, showAvatar: showAvatars}) }} {{ 'restored_post_by'|trans|lower }} {{ component('user_inline', {user: log.post.user}) }}{% if showMagazine %} {{ 'in'|trans|lower }} {{ component('magazine_inline', {magazine: log.post.magazine, showAvatar: showIcons }) }}{% endif %} - {{ log.post.shortTitle(300) }} {% endblock %} {% block log_post_comment_deleted %} - {{ component('user_inline', {user: log.user, showAvatar: false}) }} {{ 'removed_comment_by'|trans|lower }} {{ component('user_inline', {user: log.comment.user, showAvatar: false}) }}{% if showMagazine %} {{ 'in'|trans|lower }} {{ component('magazine_inline', {magazine: log.comment.magazine, showIcon: false }) }}{% endif %} - + {{ component('user_inline', {user: log.user, showAvatar: showAvatars}) }} {{ 'removed_comment_by'|trans|lower }} {{ component('user_inline', {user: log.comment.user}) }}{% if showMagazine %} {{ 'in'|trans|lower }} {{ component('magazine_inline', {magazine: log.comment.magazine, showAvatar: showIcons }) }}{% endif %} - {{ log.comment.shortTitle(300) }} {% endblock %} {% block log_post_comment_restored %} - {{ component('user_inline', {user: log.user, showAvatar: false}) }} {{ 'restored_comment_by'|trans|lower }} {{ component('user_inline', {user: log.comment.user, showAvatar: false}) }}{% if showMagazine %} {{ 'in'|trans|lower }} {{ component('magazine_inline', {magazine: log.comment.magazine, showIcon: false }) }}{% endif %} - + {{ component('user_inline', {user: log.user, showAvatar: showAvatars}) }} {{ 'restored_comment_by'|trans|lower }} {{ component('user_inline', {user: log.comment.user}) }}{% if showMagazine %} {{ 'in'|trans|lower }} {{ component('magazine_inline', {magazine: log.comment.magazine, showAvatar: showIcons }) }}{% endif %} - {{ log.comment.shortTitle(300) }} {% endblock %} {% block log_ban %} - {{ component('user_inline', {user: log.user, showAvatar: false}) }} {% if log.meta is same as 'ban' %}{{ 'he_banned'|trans|lower }}{% else %}{{ 'he_unbanned'|trans|lower }}{% endif %} {{ component('user_inline', {user: log.ban.user, showAvatar: false}) }} - {% if showMagazine %} {{ 'in'|trans|lower }} {{ component('magazine_inline', {magazine: log.ban.magazine, showIcon: false }) }}{% endif %}{% if log.ban.reason %} - {{ log.ban.reason }}{% endif %} + {{ component('user_inline', {user: log.user, showAvatar: showAvatars}) }} {% if log.meta is same as 'ban' %}{{ 'he_banned'|trans|lower }}{% else %}{{ 'he_unbanned'|trans|lower }}{% endif %} {{ component('user_inline', {user: log.ban.user}) }} + {% if showMagazine %} {{ 'in'|trans|lower }} {{ component('magazine_inline', {magazine: log.ban.magazine, showAvatar: showIcons }) }}{% endif %}{% if log.ban.reason %} - {{ log.ban.reason }}{% endif %} {% endblock %} {% block log_moderator_add %} {% if log.actingUser is not same as null %} {{ component('user_inline', {user: log.actingUser}) }} + {% else %} + {{ 'someone'|trans }} {% endif %} - {{ 'magazine_log_mod_added'|trans }}: {{ component('user_inline', {user: log.user}) }} + {{ 'magazine_log_mod_added'|trans -}} + {% if showMagazine %} {{ 'in'|trans|lower }} {{ component('magazine_inline', {magazine: log.magazine, showAvatar: showIcons }) -}}{%- endif -%}: {{ component('user_inline', {user: log.user, showAvatar: showAvatars}) }} {% endblock %} {% block log_moderator_remove %} {% if log.actingUser is not same as null %} {{ component('user_inline', {user: log.actingUser}) }} + {% else %} + {{ 'someone'|trans }} {% endif %} - {{ 'magazine_log_mod_removed'|trans }}: {{ component('user_inline', {user: log.user}) }} + {{ 'magazine_log_mod_removed'|trans -}} + {% if showMagazine %} {{ 'from'|trans|lower }} {{ component('magazine_inline', {magazine: log.magazine, showAvatar: showIcons }) -}}{%- endif -%}: {{ component('user_inline', {user: log.user, showAvatar: showAvatars}) }} {% endblock %} diff --git a/templates/modlog/front.html.twig b/templates/modlog/front.html.twig index 8686d64c8..6bc0864f1 100644 --- a/templates/modlog/front.html.twig +++ b/templates/modlog/front.html.twig @@ -1,4 +1,9 @@ {% extends 'base.html.twig' %} +{% set V_TRUE = constant('App\\Controller\\User\\ThemeSettingsController::TRUE') %} +{% set MBIN_MODERATION_LOG_SHOW_USER_AVATARS = constant('App\\Controller\\User\\ThemeSettingsController::MBIN_MODERATION_LOG_SHOW_USER_AVATARS') %} +{% set showAvatars = app.request.cookies.get(MBIN_MODERATION_LOG_SHOW_USER_AVATARS) is same as V_TRUE %} +{% set MBIN_MODERATION_LOG_SHOW_MAGAZINE_ICONS = constant('App\\Controller\\User\\ThemeSettingsController::MBIN_MODERATION_LOG_SHOW_MAGAZINE_ICONS') %} +{% set showIcons = app.request.cookies.get(MBIN_MODERATION_LOG_SHOW_MAGAZINE_ICONS) is same as V_TRUE %} {% use 'modlog/_blocks.html.twig' %} {%- block title -%} @@ -27,7 +32,9 @@
    {%- with { log: log, - showMagazine: false, + showMagazine: true, + showAvatars: showAvatars, + showIcons: showIcons, } only -%} {{ block(log.type) }} {%- endwith -%} diff --git a/templates/modlog/magazine.html.twig b/templates/modlog/magazine.html.twig index cddfdba5c..a34c84cf0 100644 --- a/templates/modlog/magazine.html.twig +++ b/templates/modlog/magazine.html.twig @@ -1,11 +1,16 @@ {% extends 'base.html.twig' %} +{% set V_TRUE = constant('App\\Controller\\User\\ThemeSettingsController::TRUE') %} +{% set MBIN_MODERATION_LOG_SHOW_USER_AVATARS = constant('App\\Controller\\User\\ThemeSettingsController::MBIN_MODERATION_LOG_SHOW_USER_AVATARS') %} +{% set showAvatars = app.request.cookies.get(MBIN_MODERATION_LOG_SHOW_USER_AVATARS) is same as V_TRUE %} +{% set MBIN_MODERATION_LOG_SHOW_MAGAZINE_ICONS = constant('App\\Controller\\User\\ThemeSettingsController::MBIN_MODERATION_LOG_SHOW_MAGAZINE_ICONS') %} +{% set showIcons = app.request.cookies.get(MBIN_MODERATION_LOG_SHOW_MAGAZINE_ICONS) is same as V_TRUE %} {% use 'modlog/_blocks.html.twig' %} {%- block title -%} {{- 'magazines'|trans }} - {{ parent() -}} {%- endblock -%} -{% block mainClass %}page-magazines{% endblock %} +{% block mainClass %}page-magazines page-modlog{% endblock %} {% block header_nav %} {% endblock %} @@ -24,6 +29,8 @@ {%- with { log: log, showMagazine: false, + showAvatars: showAvatars, + showIcons: showIcons, } only -%} {{ block(log.type) }} {%- endwith -%} diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml index ff6e41092..23bc141f5 100644 --- a/translations/messages.en.yaml +++ b/translations/messages.en.yaml @@ -83,6 +83,7 @@ reset_password: Reset password show_more: Show more to: to in: in +from: from username: Username email: Email repeat_password: Repeat password @@ -824,5 +825,6 @@ related_entry: Related restrict_magazine_creation: Restrict local magazine creation to admins and global mods sso_show_first: Show SSO first on login and registration pages continue_with: Continue with +someone: Someone magazine_log_mod_added: has added a moderator magazine_log_mod_removed: has removed a moderator From 8c30a43e02c33794cef6c9512a9b2573903380e3 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Fri, 14 Jun 2024 13:05:49 +0000 Subject: [PATCH 039/335] expose the `apFetchedAt` field of users and magazines for admins (#826) --- templates/components/magazine_box.html.twig | 5 +++++ templates/user/_info.html.twig | 5 +++++ translations/messages.en.yaml | 1 + 3 files changed, 11 insertions(+) diff --git a/templates/components/magazine_box.html.twig b/templates/components/magazine_box.html.twig index 472bbe205..6e2063d07 100644 --- a/templates/components/magazine_box.html.twig +++ b/templates/components/magazine_box.html.twig @@ -42,6 +42,11 @@
  • {{ 'created_at'|trans }}: {{ component('date', {date: computed.magazine.createdAt}) }}
  • + {% if app.user is defined and app.user is not null and app.user.admin() and computed.magazine.apId is not null %} +
  • + {{ 'last_updated'|trans }}: {{ component('date', {date: computed.magazine.apFetchedAt}) }} +
  • + {% endif %}
  • {{ 'subscribers'|trans }}: {{ computed.magazine.subscriptionsCount }}
  • {% endif %} diff --git a/templates/user/_info.html.twig b/templates/user/_info.html.twig index c6ec88255..72ff6552a 100644 --- a/templates/user/_info.html.twig +++ b/templates/user/_info.html.twig @@ -19,6 +19,11 @@ {% endif %}
    • {{ 'joined'|trans }}: {{ component('date', {date: user.createdAt}) }}
    • + {% if app.user is defined and app.user is not null and app.user.admin() and user.apId is not null %} +
    • + {{ 'last_updated'|trans }}: {{ component('date', {date: user.apFetchedAt}) }} +
    • + {% endif %} {%- set TYPE_ENTRY = constant('App\\Repository\\ReputationRepository::TYPE_ENTRY') -%}
    • {{ 'reputation_points'|trans }}: {{ get_reputation_total(user) }}
    • Date: Fri, 14 Jun 2024 15:07:29 +0200 Subject: [PATCH 040/335] Translations update from Hosted Weblate (#829) Co-authored-by: BentiGorlich --- translations/messages.de.yaml | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/translations/messages.de.yaml b/translations/messages.de.yaml index d6754323a..b056016d9 100644 --- a/translations/messages.de.yaml +++ b/translations/messages.de.yaml @@ -422,8 +422,7 @@ toolbar.ordered_list: Geordnete Liste your_account_is_not_active: Dein Profil wurde noch nicht aktiviert. Bitte prüfe deine E-Mails und klicke den Aktivierungslink um fortzufahren. Falls du keine Mail erhalten hast frage eine neue Aktivierungsmail an. -your_account_has_been_banned: E-Mails für Anweisungen zur Kontoaktivierung oder fordere eine neue E-Mail zur Aktivierung an +your_account_has_been_banned: Dein Konto wurde gesperrt federation_page_enabled: Föderationsseite aktiviert federation_page_disallowed_description: Instanzen mit denen wir nicht föderieren federation_page_allowed_description: Bekannte Instanzen mit denen wir föderieren @@ -469,7 +468,7 @@ subscription_sort: Sortierung unblock: Entblockieren oauth.consent.grant_permissions: Gebe Berechtigungen oauth2.grant.moderate.magazine.ban.delete: Nutzer in deinen moderierten Magazinen - entbannen. + entsperren. subscriptions_in_own_sidebar: In eigener Seitenleiste subscription_sidebar_pop_out_left: Nach links in eigene Seitenleiste verschieben subscription_sidebar_pop_out_right: Nach rechts in eigene Seitenleiste verschieben @@ -854,3 +853,21 @@ restrict_magazine_creation: 'Erstellung lokaler Magazine auf Admins und globale sort_by: 'Sortieren nach' filter_by_subscription: 'Nach Abonnements filtern' related_entry: Zugehörig +tag: Hashtag +unban: Sperre aufheben +ban_hashtag_btn: Hashtag Sperren +unban_hashtag_btn: Hashtag Sperre Aufheben +private_instance: Nutzer zur Anmeldung zwingen um auf Inhalte zugreifen zu können +flash_thread_tag_banned_error: Thema konnte nicht erstellt werden. Der Inhalt ist + nicht erlaubt. +sso_only_mode: Anmeldung und Registrierung auf SSO Methoden beschränken +magazine_log_mod_added: hat einen Moderator hinzugefügt +magazine_log_mod_removed: hat einen Moderator entfernt +ban_hashtag_description: Durch das Sperren eines Hashtags wird verhindert, dass Beiträge + mit diesem Hashtag erstellt werden. Außerdem werden vorhandene Beiträge mit diesem + Hashtag ausgeblendet. +unban_hashtag_description: Wenn Sie eine Hashtag Sperre aufheben, können wieder Beiträge + mit diesem Hashtag erstellt werden. Vorhandene Beiträge mit diesem Hashtag werden + nicht mehr ausgeblendet. +sso_show_first: SSO als erstes auf der Anmeldungs- und Registrierungsseite anzeigen +continue_with: Weiter mit From 88800b183973276a0ffbe228606d884f6487df30 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Fri, 14 Jun 2024 13:28:32 +0000 Subject: [PATCH 041/335] New/cake day (#827) --- src/Service/ActivityPubManager.php | 22 +++++++++++++++++++ src/Service/SettingsManager.php | 9 ++++++++ src/Twig/Extension/SettingsExtension.php | 1 + src/Twig/Runtime/SettingsExtensionRuntime.php | 5 +++++ templates/user/_info.html.twig | 10 ++++++--- templates/user/_user_popover.html.twig | 4 ++++ translations/messages.en.yaml | 1 + 7 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/Service/ActivityPubManager.php b/src/Service/ActivityPubManager.php index fda2ec4cc..bb1b2a60d 100644 --- a/src/Service/ActivityPubManager.php +++ b/src/Service/ActivityPubManager.php @@ -330,6 +330,17 @@ public function updateUser(string $actorUrl): ?User $user->apTimeoutAt = null; $user->apFetchedAt = new \DateTime(); + if (isset($actor['published'])) { + try { + $createdAt = new \DateTimeImmutable($actor['published']); + $now = new \DateTimeImmutable(); + if ($createdAt < $now) { + $user->createdAt = $createdAt; + } + } catch (\Exception) { + } + } + // Only update about when summary is set if (isset($actor['summary'])) { $converter = new HtmlConverter(['strip_tags' => true]); @@ -463,6 +474,17 @@ public function updateMagazine(string $actorUrl): ?Magazine $magazine->title = $actor['preferredUsername']; } + if (isset($actor['published'])) { + try { + $createdAt = new \DateTimeImmutable($actor['published']); + $now = new \DateTimeImmutable(); + if ($createdAt < $now) { + $magazine->createdAt = $createdAt; + } + } catch (\Exception) { + } + } + $magazine->apInboxUrl = $actor['endpoints']['sharedInbox'] ?? $actor['inbox']; $magazine->apDomain = parse_url($actor['id'], PHP_URL_HOST); $magazine->apFollowersUrl = $actor['followers'] ?? null; diff --git a/src/Service/SettingsManager.php b/src/Service/SettingsManager.php index 11ac26645..bcd672951 100644 --- a/src/Service/SettingsManager.php +++ b/src/Service/SettingsManager.php @@ -9,6 +9,7 @@ use App\Repository\SettingsRepository; use Doctrine\ORM\EntityManagerInterface; use JetBrains\PhpStorm\Pure; +use Symfony\Component\HttpFoundation\RequestStack; class SettingsManager { @@ -17,6 +18,7 @@ class SettingsManager public function __construct( private readonly EntityManagerInterface $entityManager, private readonly SettingsRepository $repository, + private readonly RequestStack $requestStack, private readonly string $kbinDomain, private readonly string $kbinTitle, private readonly string $kbinMetaTitle, @@ -153,4 +155,11 @@ public static function getValue(string $name): string { return self::$dto->{$name}; } + + public function getLocale(): string + { + $request = $this->requestStack->getCurrentRequest(); + + return $request->cookies->get('kbin_lang') ?? $request->getLocale() ?? $this->get('KBIN_DEFAULT_LANG'); + } } diff --git a/src/Twig/Extension/SettingsExtension.php b/src/Twig/Extension/SettingsExtension.php index c3981962e..1b966c0c3 100644 --- a/src/Twig/Extension/SettingsExtension.php +++ b/src/Twig/Extension/SettingsExtension.php @@ -31,6 +31,7 @@ public function getFunctions(): array new TwigFunction('mbin_restrict_magazine_creation', [SettingsExtensionRuntime::class, 'mbinRestrictMagazineCreation']), new TwigFunction('mbin_private_instance', [SettingsExtensionRuntime::class, 'mbinPrivateInstance']), new TwigFunction('mbin_sso_show_first', [SettingsExtensionRuntime::class, 'mbinSsoShowFirst']), + new TwigFunction('mbin_lang', [SettingsExtensionRuntime::class, 'mbinLang']), ]; } } diff --git a/src/Twig/Runtime/SettingsExtensionRuntime.php b/src/Twig/Runtime/SettingsExtensionRuntime.php index 6f5ce0ea5..2213d98fc 100644 --- a/src/Twig/Runtime/SettingsExtensionRuntime.php +++ b/src/Twig/Runtime/SettingsExtensionRuntime.php @@ -118,4 +118,9 @@ public function mbinSsoShowFirst(): bool { return $this->settings->get('MBIN_SSO_SHOW_FIRST'); } + + public function mbinLang(): string + { + return $this->settings->getLocale(); + } } diff --git a/templates/user/_info.html.twig b/templates/user/_info.html.twig index 72ff6552a..b86d90eda 100644 --- a/templates/user/_info.html.twig +++ b/templates/user/_info.html.twig @@ -19,6 +19,7 @@ {% endif %}
      • {{ 'joined'|trans }}: {{ component('date', {date: user.createdAt}) }}
      • +
      • {{ 'cake_day'|trans }}: {{ user.createdAt|format_date('short', '', null, 'gregorian', mbin_lang()) }}
      • {% if app.user is defined and app.user is not null and app.user.admin() and user.apId is not null %}
      • {{ 'last_updated'|trans }}: {{ component('date', {date: user.apFetchedAt}) }} @@ -30,9 +31,12 @@ class="stretched-link">{{ 'moderated'|trans }}: {{ count_user_moderated(user) }}
      • {% if app.user is not same as user %} -
      • {{ 'send_message'|trans }}
      • +
      • + + {{ 'send_message'|trans }} + + +
      • {% endif %}
      diff --git a/templates/user/_user_popover.html.twig b/templates/user/_user_popover.html.twig index a4569f9ee..59578f8a3 100644 --- a/templates/user/_user_popover.html.twig +++ b/templates/user/_user_popover.html.twig @@ -21,6 +21,10 @@

      • {{ 'joined'|trans }}: {{ component('date', {date: user.createdAt}) }}
      • +
      • + + {{ user.createdAt|format_date('short', '', null, 'gregorian', mbin_lang()) }} +
      • {%- set TYPE_ENTRY = constant('App\\Repository\\ReputationRepository::TYPE_ENTRY') -%} diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml index 25fae8573..17eb07262 100644 --- a/translations/messages.en.yaml +++ b/translations/messages.en.yaml @@ -825,6 +825,7 @@ related_entry: Related restrict_magazine_creation: Restrict local magazine creation to admins and global mods sso_show_first: Show SSO first on login and registration pages continue_with: Continue with +cake_day: Cake day someone: Someone magazine_log_mod_added: has added a moderator magazine_log_mod_removed: has removed a moderator From 476314c3cd0d04fd401873aeeb59666ee1d3096c Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Tue, 18 Jun 2024 06:44:56 +0000 Subject: [PATCH 042/335] Include content of audience tag in the receivers (#834) --- src/Service/ActivityPub/Note.php | 2 +- src/Service/ActivityPub/Page.php | 2 +- src/Service/ActivityPubManager.php | 16 ++++++++++++++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/Service/ActivityPub/Note.php b/src/Service/ActivityPub/Note.php index af7e973d5..01accc095 100644 --- a/src/Service/ActivityPub/Note.php +++ b/src/Service/ActivityPub/Note.php @@ -187,7 +187,7 @@ private function handleSensitiveMedia(PostDto|PostCommentDto|EntryCommentDto|Ent private function createPost(array $object): Post { $dto = new PostDto(); - $dto->magazine = $this->activityPubManager->findOrCreateMagazineByToAndCC($object); + $dto->magazine = $this->activityPubManager->findOrCreateMagazineByToCCAndAudience($object); $dto->apId = $object['id']; $actor = $this->activityPubManager->findActorOrCreate($object['attributedTo']); diff --git a/src/Service/ActivityPub/Page.php b/src/Service/ActivityPub/Page.php index e0c837ab1..21c982174 100644 --- a/src/Service/ActivityPub/Page.php +++ b/src/Service/ActivityPub/Page.php @@ -65,7 +65,7 @@ public function create(array $object): Entry $object['cc'] = [$object['cc']]; } - $magazine = $this->activityPubManager->findOrCreateMagazineByToAndCC($object); + $magazine = $this->activityPubManager->findOrCreateMagazineByToCCAndAudience($object); $dto = new EntryDto(); $dto->magazine = $magazine; $dto->title = $object['name']; diff --git a/src/Service/ActivityPubManager.php b/src/Service/ActivityPubManager.php index bb1b2a60d..5c6a57ca4 100644 --- a/src/Service/ActivityPubManager.php +++ b/src/Service/ActivityPubManager.php @@ -683,7 +683,7 @@ public function updateActor(string $actorUrl): null|Magazine|User return null; } - public function findOrCreateMagazineByToAndCC(array $object): Magazine|null + public function findOrCreateMagazineByToCCAndAudience(array $object): Magazine|null { $potentialGroups = self::getReceivers($object); $magazine = $this->magazineRepository->findByApGroupProfileId($potentialGroups); @@ -711,8 +711,14 @@ public function findOrCreateMagazineByToAndCC(array $object): Magazine|null public static function getReceivers(array $object): array { $res = []; + if (isset($object['audience']) and \is_array($object['audience'])) { + $res = array_merge($res, $object['audience']); + } elseif (isset($object['audience']) and \is_string($object['audience'])) { + $res[] = $object['audience']; + } + if (isset($object['to']) and \is_array($object['to'])) { - $res = $object['to']; + $res = array_merge($res, $object['to']); } elseif (isset($object['to']) and \is_string($object['to'])) { $res[] = $object['to']; } @@ -724,6 +730,12 @@ public static function getReceivers(array $object): array } if (isset($object['object']) and \is_array($object['object'])) { + if (isset($object['object']['audience']) and \is_array($object['object']['audience'])) { + $res = array_merge($res, $object['object']['audience']); + } elseif (isset($object['object']['audience']) and \is_string($object['object']['audience'])) { + $res[] = $object['object']['audience']; + } + if (isset($object['object']['to']) and \is_array($object['object']['to'])) { $res = array_merge($res, $object['object']['to']); } elseif (isset($object['object']['to']) and \is_string($object['object']['to'])) { From ccb672e4e401687af13befa5dc45a8f466427db1 Mon Sep 17 00:00:00 2001 From: debounced <35878315+nobodyatroot@users.noreply.github.com> Date: Tue, 18 Jun 2024 22:23:46 -0500 Subject: [PATCH 043/335] Remove border radius on autocomplete form to fix letters from getting cutoff at the beginning of the item (#835) --- assets/styles/layout/_forms.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/styles/layout/_forms.scss b/assets/styles/layout/_forms.scss index 2a45e5afb..8d42c269d 100644 --- a/assets/styles/layout/_forms.scss +++ b/assets/styles/layout/_forms.scss @@ -151,6 +151,7 @@ input[type=select-one] { display: block; padding: 1rem .5rem; width: 100%; + text-indent: .1rem !important; } .password-preview { @@ -263,6 +264,7 @@ form { color: var(--kbin-input-text-color); width: auto; min-width: 8rem; + border-radius: 0 !important; } & > * { From 032c917e5bedf525d531637bedcfd534bd793e47 Mon Sep 17 00:00:00 2001 From: e-five <146029455+e-five256@users.noreply.github.com> Date: Wed, 19 Jun 2024 10:54:17 -0400 Subject: [PATCH 044/335] add aria attributes to cake day elements (#841) Co-authored-by: BentiGorlich --- assets/styles/components/_popover.scss | 8 ++++++++ assets/styles/components/_sidebar.scss | 5 +++++ templates/user/_info.html.twig | 2 +- templates/user/_user_popover.html.twig | 6 ++++-- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/assets/styles/components/_popover.scss b/assets/styles/components/_popover.scss index 9b145fbc2..c97cf0cd5 100644 --- a/assets/styles/components/_popover.scss +++ b/assets/styles/components/_popover.scss @@ -63,6 +63,14 @@ font-size: .9rem; list-style: none; padding: 0; + + li { + div { + i { + padding-right: .5rem; + } + } + } } .user__actions { diff --git a/assets/styles/components/_sidebar.scss b/assets/styles/components/_sidebar.scss index 032634854..63fde1872 100644 --- a/assets/styles/components/_sidebar.scss +++ b/assets/styles/components/_sidebar.scss @@ -176,6 +176,11 @@ padding: 0; } + div { + i { + padding-right: .5rem; + } + } } } diff --git a/templates/user/_info.html.twig b/templates/user/_info.html.twig index b86d90eda..7d12355fb 100644 --- a/templates/user/_info.html.twig +++ b/templates/user/_info.html.twig @@ -19,7 +19,7 @@ {% endif %} {% endif %} {% if showMeta %} diff --git a/templates/entry/_info.html.twig b/templates/entry/_info.html.twig index 9fa8082fe..c4af6389e 100644 --- a/templates/entry/_info.html.twig +++ b/templates/entry/_info.html.twig @@ -27,6 +27,9 @@ {{ component('user_actions', {user: entry.user}) }}
        • {{ 'added'|trans }}: {{ component('date', {date: entry.createdAt}) }}
        • + {% if entry.editedAt %} +
        • {{ 'edited'|trans }}: {{ component('date', {date: entry.editedAt}) }}
        • + {% endif %}
        {% if entry.hashtags is not empty %}

        {{ 'tags'|trans }}

        diff --git a/templates/page/federation.html.twig b/templates/page/federation.html.twig index 58a477db6..0218b8307 100644 --- a/templates/page/federation.html.twig +++ b/templates/page/federation.html.twig @@ -14,23 +14,99 @@ {% block body %}

        {{ 'federation'|trans }}

        -
        +
        {% if allowedInstances is not empty %} -

        {{'federation_page_allowed_description'|trans}}

        -
          - {% for instance in allowedInstances %} -
        • {{instance}}
        • - {% endfor %} -
        +

        {{'federation_page_allowed_description'|trans}}

        + + + + + + + {% if app.user is defined and app.user is not same as null and app.user.admin %} + + + {% endif %} + + + + {% for instance in allowedInstances %} + + + + + {% if app.user is defined and app.user is not same as null and app.user.admin %} + + + {% endif %} + + {% endfor %} + +
        {{ 'domain'|trans }}{{ 'server_software'|trans }}{{ 'version'|trans }}{{ 'last_successful_deliver'|trans }}{{ 'last_successful_receive'|trans }}
        {{instance.domain}}{{ instance.software ?? '' }}{{ instance.version ?? '' }} + {% if instance.lastSuccessfulDeliver is not same as null %} + {{ component('date', { date: instance.lastSuccessfulDeliver }) }} + {% endif %} + + {% if instance.lastSuccessfulReceive is not same as null %} + {{ component('date', { date: instance.lastSuccessfulReceive }) }} + {% endif %} +
        {% endif %} + {% if defederatedInstances is not empty %} -

        {{'federation_page_disallowed_description'|trans}}

        -
          - {% for instance in defederatedInstances %} -
        • {{instance}}
        • - {% endfor %} -
        +

        {{'federation_page_disallowed_description'|trans}}

        + + + + + + + + + + {% for instance in defederatedInstances %} + + + + + + {% endfor %} + +
        {{ 'domain'|trans }}{{ 'server_software'|trans }}{{ 'version'|trans }}
        {{instance.domain}}{{ instance.software ?? '' }}{{ instance.version ?? '' }}
        + {% endif %} + + {% if deadInstances is not empty %} +

        {{'federation_page_dead_title'|trans}}

        +

        {{ 'federation_page_dead_description'|trans }}

        + + + + + + + {% if app.user is defined and app.user is not same as null and app.user.admin %} + + {% endif %} + + + + {% for instance in deadInstances %} + + + + + {% if app.user is defined and app.user is not same as null and app.user.admin %} + + {% endif %} + + {% endfor %} + +
        {{ 'domain'|trans }}{{ 'server_software'|trans }}{{ 'version'|trans }}{{ 'last_failed_contact'|trans }}
        {{instance.domain}}{{ instance.software ?? ''}}{{ instance.version ?? '' }} + {% if instance.lastFailedDeliver is not same as null %} + {{ component('date', { date: instance.lastFailedDeliver }) }} + {% endif %} +
        {% endif %}
        {% endblock %} diff --git a/templates/user/_info.html.twig b/templates/user/_info.html.twig index 53bc2186c..d5d64430c 100644 --- a/templates/user/_info.html.twig +++ b/templates/user/_info.html.twig @@ -30,6 +30,12 @@ {{ 'last_updated'|trans }}: {{ component('date', {date: user.apFetchedAt}) }}
      • {% endif %} + + {% set instance = get_instance_of_user(user) %} + {% if instance is not same as null %} +
      • {{ 'server_software'|trans }}:
        {{ instance.software }}{% if instance.version is not same as null and app.user is defined and app.user is not null and app.user.admin() %} v{{ instance.version }}{% endif %}
      • + {% endif %} + {%- set TYPE_ENTRY = constant('App\\Repository\\ReputationRepository::TYPE_ENTRY') -%}
      • {{ 'reputation_points'|trans }}: {{ get_reputation_total(user) }}
      • Date: Tue, 30 Jul 2024 17:56:47 +0200 Subject: [PATCH 132/335] Add Redis page to docs (#953) --- docs/02-admin/01-installation/bare_metal.md | 3 ++ docs/02-admin/02-configuration/redis.md | 50 +++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 docs/02-admin/02-configuration/redis.md diff --git a/docs/02-admin/01-installation/bare_metal.md b/docs/02-admin/01-installation/bare_metal.md index 64cc330e6..0d1862014 100644 --- a/docs/02-admin/01-installation/bare_metal.md +++ b/docs/02-admin/01-installation/bare_metal.md @@ -311,6 +311,9 @@ composer clear-cache You can choose between either Redis or KeyDB. +> [!TIP] +> More Redis/KeyDB fine-tuning settings can be found in the [Redis configuration guide](../02-configuration/redis.md). + #### Redis Edit `redis.conf` file: diff --git a/docs/02-admin/02-configuration/redis.md b/docs/02-admin/02-configuration/redis.md new file mode 100644 index 000000000..90e1b8098 --- /dev/null +++ b/docs/02-admin/02-configuration/redis.md @@ -0,0 +1,50 @@ +# Redis + +This documentation is valid for both Redis as well as KeyDB. KeyDB is a fork of Redis, but should work in the same manner. + +## Configure Redis + +Edit the Redis instance for Mbin: `sudo nano /etc/redis/redis.conf`: + +```conf +# NETWORK +timeout 300 +tcp-keepalive 300 + +# MEMORY MANAGEMENT +maxmemory 1gb +maxmemory-policy volatile-ttl + +# LAZY FREEING +lazyfree-lazy-eviction yes +lazyfree-lazy-expire yes +lazyfree-lazy-server-del yes +replica-lazy-flush yes + +# THREADED I/O +io-threads 4 +io-threads-do-reads yes +``` + +Feel free to adjust the memory settings to your liking. + +> [!WARNING] +> Mbin (more specifically Symfony RedisTagAwareAdapter) only support `noeviction` and `volatile-*` settings for the `maxmemory-policy` Redis setting. + +## Redis as a cache + +_Optionally:_ If you are using this Redis instance only for Mbin as a cache, you can disable snapshots in Redis. Which will no longer dump the database to disk and reduce the amount of disk space used as well the disk I/O. + +First comment out existing "save lines" in the Redis configuration file: + +```conf +#save 900 1 +#save 300 10 +#save 60 10000 +``` + +Then add the following line to disable snapshots fully: + +```conf +save "" +``` From c6b83e8d92629255fbda71d4f9933f857bdf8b56 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Tue, 30 Jul 2024 18:46:10 +0200 Subject: [PATCH 133/335] Improve Redis / KeyDB guide (#956) --- docs/02-admin/02-configuration/redis.md | 29 ++++++++++++++++++------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/docs/02-admin/02-configuration/redis.md b/docs/02-admin/02-configuration/redis.md index 90e1b8098..2950a51c6 100644 --- a/docs/02-admin/02-configuration/redis.md +++ b/docs/02-admin/02-configuration/redis.md @@ -1,12 +1,12 @@ -# Redis +# Redis / KeyDB -This documentation is valid for both Redis as well as KeyDB. KeyDB is a fork of Redis, but should work in the same manner. +This documentation is valid for both Redis as well as KeyDB. KeyDB is a fork of Redis, but should work mostly in the same manner. ## Configure Redis Edit the Redis instance for Mbin: `sudo nano /etc/redis/redis.conf`: -```conf +```ruby # NETWORK timeout 300 tcp-keepalive 300 @@ -20,16 +20,29 @@ lazyfree-lazy-eviction yes lazyfree-lazy-expire yes lazyfree-lazy-server-del yes replica-lazy-flush yes +``` + +Feel free to adjust the memory settings to your liking. + +> [!WARNING] +> Mbin (more specifically Symfony RedisTagAwareAdapter) only support `noeviction` and `volatile-*` settings for the `maxmemory-policy` Redis setting. +## Multithreading + +Configure multiple threads in Redis by setting the following two lines: + +```ruby # THREADED I/O io-threads 4 io-threads-do-reads yes ``` -Feel free to adjust the memory settings to your liking. +However, when using **KeyDB**, you need to update the following line (`io-threads` doesn't exists in KeyDB): -> [!WARNING] -> Mbin (more specifically Symfony RedisTagAwareAdapter) only support `noeviction` and `volatile-*` settings for the `maxmemory-policy` Redis setting. +```ruby +# WORKER THREADS +server-threads 4 +``` ## Redis as a cache @@ -37,7 +50,7 @@ _Optionally:_ If you are using this Redis instance only for Mbin as a cache, you First comment out existing "save lines" in the Redis configuration file: -```conf +```ruby #save 900 1 #save 300 10 #save 60 10000 @@ -45,6 +58,6 @@ First comment out existing "save lines" in the Redis configuration file: Then add the following line to disable snapshots fully: -```conf +```ruby save "" ``` From 4063efdd9624ed4eb2fd80a45337d328d83e2a8a Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Tue, 30 Jul 2024 17:05:12 +0000 Subject: [PATCH 134/335] Fix left over mapping in `OAuth2UserConsent` (#957) --- src/Entity/OAuth2UserConsent.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Entity/OAuth2UserConsent.php b/src/Entity/OAuth2UserConsent.php index 25b7c7bc3..a8a248de2 100644 --- a/src/Entity/OAuth2UserConsent.php +++ b/src/Entity/OAuth2UserConsent.php @@ -12,7 +12,6 @@ use Doctrine\ORM\Mapping\Id; use Doctrine\ORM\Mapping\JoinColumn; use Doctrine\ORM\Mapping\ManyToOne; -use Doctrine\ORM\Mapping\OneToOne; #[ORM\Entity(repositoryClass: OAuth2UserConsentRepository::class)] class OAuth2UserConsent @@ -192,9 +191,6 @@ class OAuth2UserConsent #[Column] private ?string $ipAddress = null; - #[OneToOne(mappedBy: 'userConsent', targetEntity: UserPushSubscription::class, cascade: ['persist', 'remove'], orphanRemoval: true)] - public ?UserPushSubscription $pushSubscription = null; - public function getId(): ?int { return $this->id; From d1676947b96efa939907e8d07184d577d9f97b65 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2024 17:07:55 +0000 Subject: [PATCH 135/335] docs(contributor): contributors readme action update (#958) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 604576c8d..994aea35a 100644 --- a/README.md +++ b/README.md @@ -83,17 +83,17 @@ For developers: - - asdfzdfj + + BentiGorlich
        - asdfzdfj + BentiGorlich
        - - BentiGorlich + + asdfzdfj
        - BentiGorlich + asdfzdfj
        From d90a9f74adf420663c7212bdfded6b16e6e0ec68 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Tue, 30 Jul 2024 21:34:39 +0200 Subject: [PATCH 136/335] Add php8.3 to docs + how to switch (#959) --- docs/02-admin/01-installation/bare_metal.md | 13 +++++++++++-- docs/02-admin/02-configuration/README.md | 12 +++++++++++- docs/02-admin/02-configuration/nginx.md | 7 +++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/docs/02-admin/01-installation/bare_metal.md b/docs/02-admin/01-installation/bare_metal.md index 0d1862014..4e972b64d 100644 --- a/docs/02-admin/01-installation/bare_metal.md +++ b/docs/02-admin/01-installation/bare_metal.md @@ -29,7 +29,7 @@ Install prequirements: sudo apt-get install lsb-release ca-certificates curl wget unzip gnupg apt-transport-https software-properties-common python3-launchpadlib git redis-server postgresql postgresql-contrib nginx acl -y ``` -On **Ubuntu 22.04 LTS** or older, prepare latest PHP package repositoy (8.2) by using a Ubuntu PPA (this step is optional for Ubuntu 23.10 or later) via: +On **Ubuntu 22.04 LTS** or older, prepare latest PHP package repositoy (8.2 or 8.3) by using a Ubuntu PPA (this step is optional for Ubuntu 23.10 or later) via: ```bash sudo add-apt-repository ppa:ondrej/php -y @@ -41,13 +41,22 @@ On **Debian 12** or later, you can install the latest PHP package repository (th sudo sh -c 'echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list' ``` -Install PHP 8.2 with some important PHP extensions: +You can choose between PHP 8.2 or 8.3, but it is recommended to use PHP 8.3. + +Install _PHP 8.2_ with some important PHP extensions: ```bash sudo apt-get update sudo apt-get install php8.2 php8.2-common php8.2-fpm php8.2-cli php8.2-amqp php8.2-bcmath php8.2-pgsql php8.2-gd php8.2-curl php8.2-xml php8.2-redis php8.2-mbstring php8.2-zip php8.2-bz2 php8.2-intl php8.2-bcmath -y ``` +Or install _PHP 8.3_ with PHP extensions: + +```bash +sudo apt-get update +sudo apt-get install php8.3 php8.3-common php8.3-fpm php8.3-cli php8.3-amqp php8.3-bcmath php8.3-pgsql php8.3-gd php8.3-curl php8.3-xml php8.3-redis php8.3-mbstring php8.3-zip php8.3-bz2 php8.3-intl php8.3-bcmath -y +``` + Install Composer: ```bash diff --git a/docs/02-admin/02-configuration/README.md b/docs/02-admin/02-configuration/README.md index af4abbfe2..0710f811d 100644 --- a/docs/02-admin/02-configuration/README.md +++ b/docs/02-admin/02-configuration/README.md @@ -1 +1,11 @@ -# Configuration \ No newline at end of file +# Configuration + +These configuration guides can help you configure specific services in more detail. +Assuming you have already Mbin installed and followed the installation guide. + +Currently, the following configuration guides are provided: + +- [Mbin config](./mbin_config_files.md) +- [Nginx](./nginx.md) +- [Let's Encrypt](./letsencrypt.md) +- [Redis / KeyDB](./redis.md) diff --git a/docs/02-admin/02-configuration/nginx.md b/docs/02-admin/02-configuration/nginx.md index a29a7642b..df2dbef83 100644 --- a/docs/02-admin/02-configuration/nginx.md +++ b/docs/02-admin/02-configuration/nginx.md @@ -195,6 +195,13 @@ server { } ``` +> [!TIP] +> If have multiple PHP versions installed. You can switch the PHP version that Nginx is using (`/var/run/php/php-fpm.sock`) via the the following command: +> `sudo update-alternatives --config php-fpm.sock` +> +> Same is true for the PHP CLI command (`/usr/bin/php`), via the following command: +> `sudo update-alternatives --config php` + > [!WARNING] > If also want to also configure your `www.domain.tld` subdomain; our advise is to use a HTTP 301 redirect from the `www` subdomain towards the root domain. Do _NOT_ try to setup a double instance (you want to _avoid_ that ActivityPub will see `www` as a separate instance). See Nginx example below From 7e9fab59713ce0436456a600c96f7cb1fb1bf000 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Tue, 30 Jul 2024 21:48:28 +0200 Subject: [PATCH 137/335] Edit php 8.3 files (#960) --- docs/02-admin/01-installation/bare_metal.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/02-admin/01-installation/bare_metal.md b/docs/02-admin/01-installation/bare_metal.md index 4e972b64d..e9cae1da5 100644 --- a/docs/02-admin/01-installation/bare_metal.md +++ b/docs/02-admin/01-installation/bare_metal.md @@ -234,10 +234,12 @@ OAUTH_ENCRYPTION_KEY= Edit some PHP settings within your `php.ini` file: ```bash -sudo nano /etc/php/8.2/fpm/php.ini +sudo nano /etc/php/8.3/fpm/php.ini ``` ```ini +; Maximum execution time of each script, in seconds +max_execution_time = 60 ; Both max file size and post body size are personal preferences upload_max_filesize = 8M post_max_size = 8M @@ -268,7 +270,7 @@ More info: [Symfony Performance docs](https://symfony.com/doc/current/performanc Edit your PHP `www.conf` file as well, to increase the amount of PHP child processes (optional): ```bash -sudo nano /etc/php/8.2/fpm/pool.d/www.conf +sudo nano /etc/php/8.3/fpm/pool.d/www.conf ``` With the content (these are personal preferences, adjust to your needs): From 1dd3fb978b53fe587a25cc5220cb5d51eb4bb85b Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Tue, 30 Jul 2024 22:08:18 +0200 Subject: [PATCH 138/335] Fix let's encrypt link in docs (#961) --- docs/02-admin/02-configuration/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/02-admin/02-configuration/README.md b/docs/02-admin/02-configuration/README.md index 0710f811d..6a67dc3ee 100644 --- a/docs/02-admin/02-configuration/README.md +++ b/docs/02-admin/02-configuration/README.md @@ -7,5 +7,5 @@ Currently, the following configuration guides are provided: - [Mbin config](./mbin_config_files.md) - [Nginx](./nginx.md) -- [Let's Encrypt](./letsencrypt.md) +- [Let's Encrypt](./lets_encrypt.md) - [Redis / KeyDB](./redis.md) From 46e48b1b4df8bf678bf62984f11b8474a26d11b3 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Wed, 31 Jul 2024 10:24:43 +0000 Subject: [PATCH 139/335] Implement "posting restricted to mods" (#951) Co-authored-by: debounced <35878315+nobodyatroot@users.noreply.github.com> --- migrations/Version20240729174207.php | 26 +++++++++++++++++++ .../Entry/EntryCreateController.php | 14 ++++++++++ src/DTO/MagazineDto.php | 1 + src/Entity/Magazine.php | 25 ++++++++++++++++++ src/Exception/PostingRestrictedException.php | 22 ++++++++++++++++ src/Factory/ActivityPub/GroupFactory.php | 2 +- src/Factory/MagazineFactory.php | 1 + src/Form/MagazineType.php | 1 + .../ActivityPub/Inbox/CreateHandler.php | 10 +++++++ src/Service/ActivityPub/Page.php | 10 +++++-- src/Service/ActivityPubManager.php | 1 + src/Service/EntryManager.php | 6 +++++ src/Service/MagazineManager.php | 1 + templates/components/magazine_box.html.twig | 13 ++++++++-- .../components/magazine_inline.html.twig | 12 +++++++++ templates/entry/front.html.twig | 1 + templates/magazine/_restricted_info.html.twig | 5 ++++ templates/magazine/panel/general.html.twig | 4 +++ translations/messages.en.yaml | 2 ++ 19 files changed, 152 insertions(+), 5 deletions(-) create mode 100644 migrations/Version20240729174207.php create mode 100644 src/Exception/PostingRestrictedException.php create mode 100644 templates/magazine/_restricted_info.html.twig diff --git a/migrations/Version20240729174207.php b/migrations/Version20240729174207.php new file mode 100644 index 000000000..f8d29d6ba --- /dev/null +++ b/migrations/Version20240729174207.php @@ -0,0 +1,26 @@ +addSql('ALTER TABLE magazine ADD posting_restricted_to_mods BOOLEAN NOT NULL DEFAULT FALSE'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE magazine DROP posting_restricted_to_mods'); + } +} diff --git a/src/Controller/Entry/EntryCreateController.php b/src/Controller/Entry/EntryCreateController.php index c19e6cd58..c114248d0 100644 --- a/src/Controller/Entry/EntryCreateController.php +++ b/src/Controller/Entry/EntryCreateController.php @@ -7,6 +7,7 @@ use App\Controller\AbstractController; use App\DTO\EntryDto; use App\Entity\Magazine; +use App\Exception\PostingRestrictedException; use App\Exception\TagBannedException; use App\PageView\EntryPageView; use App\Repository\Criteria; @@ -92,6 +93,19 @@ public function __invoke(?Magazine $magazine, ?string $type, Request $request): $this->addFlash('error', 'flash_thread_tag_banned_error'); $this->logger->error($e); + return $this->render( + $this->getTemplateName((new EntryPageView(1))->resolveType($type)), + [ + 'magazine' => $magazine, + 'user' => $user, + 'form' => $form->createView(), + ], + new Response(null, 422) + ); + } catch (PostingRestrictedException $e) { + $this->addFlash('error', 'flash_posting_restricted_error'); + $this->logger->error($e); + return $this->render( $this->getTemplateName((new EntryPageView(1))->resolveType($type)), [ diff --git a/src/DTO/MagazineDto.php b/src/DTO/MagazineDto.php index 66006e354..b9336445b 100644 --- a/src/DTO/MagazineDto.php +++ b/src/DTO/MagazineDto.php @@ -38,6 +38,7 @@ class MagazineDto public int $postCount = 0; public int $postCommentCount = 0; public bool $isAdult = false; + public bool $isPostingRestrictedToMods = false; public ?bool $isUserSubscribed = null; public ?bool $isBlockedByUser = null; public ?array $tags = null; diff --git a/src/Entity/Magazine.php b/src/Entity/Magazine.php index ef4d742d9..30286af23 100644 --- a/src/Entity/Magazine.php +++ b/src/Entity/Magazine.php @@ -53,6 +53,8 @@ class Magazine implements VisibilityInterface, ActivityPubActorInterface, ApiRes public ?string $description = null; #[Column(type: 'text', length: self::MAX_RULES_LENGTH, nullable: true)] public ?string $rules = null; + #[Column(type: 'boolean', nullable: false, options: ['default' => false])] + public bool $postingRestrictedToMods = false; #[Column(type: 'integer', nullable: false)] public int $subscriptionsCount = 0; #[Column(type: 'integer', nullable: false)] @@ -476,4 +478,27 @@ public function hasSameHostAsUser(User $actor): bool return false; } + + /** + * @param Magazine|User $actor the actor trying to create an Entry + * + * @return bool false if the user is not restricted, true if the user is restricted + */ + public function isActorPostingRestricted(Magazine|User $actor): bool + { + if (!$this->postingRestrictedToMods) { + return false; + } + if ($actor instanceof User) { + if (null !== $this->apId && $this->apDomain === $actor->apDomain) { + return false; + } + + if (null === $this->apId && ($actor->isAdmin() || $actor->isModerator() || $this->userIsModerator($actor))) { + return false; + } + } + + return true; + } } diff --git a/src/Exception/PostingRestrictedException.php b/src/Exception/PostingRestrictedException.php new file mode 100644 index 000000000..63df6f431 --- /dev/null +++ b/src/Exception/PostingRestrictedException.php @@ -0,0 +1,22 @@ +actor instanceof User) { + $username = $this->actor->getUsername(); + } else { + $username = $this->actor->name; + } + $m = \sprintf('Posting in magazine %s is restricted to mods and %s is not a mod', $this->magazine->apId ?? $this->magazine->name, $username); + parent::__construct($m, 0, null); + } +} diff --git a/src/Factory/ActivityPub/GroupFactory.php b/src/Factory/ActivityPub/GroupFactory.php index 9b64b7ccd..4e75a2c98 100644 --- a/src/Factory/ActivityPub/GroupFactory.php +++ b/src/Factory/ActivityPub/GroupFactory.php @@ -77,7 +77,7 @@ public function create(Magazine $magazine): array ['name' => $magazine->name], UrlGeneratorInterface::ABSOLUTE_URL ), - 'postingRestrictedToMods' => false, + 'postingRestrictedToMods' => $magazine->postingRestrictedToMods, 'endpoints' => [ 'sharedInbox' => $this->urlGenerator->generate( 'ap_shared_inbox', diff --git a/src/Factory/MagazineFactory.php b/src/Factory/MagazineFactory.php index 6c914d0c0..9191c2ed7 100644 --- a/src/Factory/MagazineFactory.php +++ b/src/Factory/MagazineFactory.php @@ -63,6 +63,7 @@ public function createDto(Magazine $magazine): MagazineDto $dto->postCount = $magazine->postCount; $dto->postCommentCount = $magazine->postCommentCount; $dto->isAdult = $magazine->isAdult; + $dto->isPostingRestrictedToMods = $magazine->postingRestrictedToMods; $dto->tags = $magazine->tags; $dto->badges = $magazine->badges; $dto->moderators = $magazine->moderators; diff --git a/src/Form/MagazineType.php b/src/Form/MagazineType.php index d247cdf67..59731d646 100644 --- a/src/Form/MagazineType.php +++ b/src/Form/MagazineType.php @@ -24,6 +24,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void ->add('description', TextareaType::class, ['required' => false]) ->add('rules', TextareaType::class, ['required' => false]) ->add('isAdult', CheckboxType::class, ['required' => false]) + ->add('isPostingRestrictedToMods', CheckboxType::class, ['required' => false]) ->add('submit', SubmitType::class); $builder->addEventSubscriber(new DisableFieldsOnMagazineEdit()); diff --git a/src/MessageHandler/ActivityPub/Inbox/CreateHandler.php b/src/MessageHandler/ActivityPub/Inbox/CreateHandler.php index 95462a07b..7f430c0d3 100644 --- a/src/MessageHandler/ActivityPub/Inbox/CreateHandler.php +++ b/src/MessageHandler/ActivityPub/Inbox/CreateHandler.php @@ -6,6 +6,8 @@ use App\Entity\Entry; use App\Entity\EntryComment; +use App\Entity\User; +use App\Exception\PostingRestrictedException; use App\Exception\TagBannedException; use App\Exception\UserBannedException; use App\Exception\UserDeletedException; @@ -76,6 +78,13 @@ public function doWork(MessageInterface $message): void $this->logger->info('Did not create the post, because the user is deleted'); } catch (TagBannedException) { $this->logger->info('Did not create the post, because one of the used tags is banned'); + } catch (PostingRestrictedException $e) { + if ($e->actor instanceof User) { + $username = $e->actor->getUsername(); + } else { + $username = $e->actor->name; + } + $this->logger->info('Did not create the post, because the magazine {m} restricts posting to mods and {u} is not a mod', ['m' => $e->magazine, 'u' => $username]); } } @@ -110,6 +119,7 @@ private function handleChain(): void * @throws UserBannedException * @throws UserDeletedException * @throws TagBannedException + * @throws PostingRestrictedException */ private function handlePage(): void { diff --git a/src/Service/ActivityPub/Page.php b/src/Service/ActivityPub/Page.php index 15f771816..91ad72acf 100644 --- a/src/Service/ActivityPub/Page.php +++ b/src/Service/ActivityPub/Page.php @@ -13,6 +13,7 @@ use App\Entity\Entry; use App\Entity\User; use App\Exception\EntityNotFoundException; +use App\Exception\PostingRestrictedException; use App\Exception\TagBannedException; use App\Exception\UserBannedException; use App\Exception\UserDeletedException; @@ -42,8 +43,9 @@ public function __construct( * @throws TagBannedException * @throws UserBannedException * @throws UserDeletedException - * @throws EntityNotFoundException if the user could not be found or a sub exception occurred - * @throws \Exception if there was an error + * @throws EntityNotFoundException if the user could not be found or a sub exception occurred + * @throws PostingRestrictedException if the target magazine has Magazine::postingRestrictedToMods = true and the actor is a magazine or a user that is not a mod + * @throws \Exception if there was an error */ public function create(array $object, bool $stickyIt = false): Entry { @@ -73,6 +75,10 @@ public function create(array $object, bool $stickyIt = false): Entry } $magazine = $this->activityPubManager->findOrCreateMagazineByToCCAndAudience($object); + if ($magazine->isActorPostingRestricted($actor)) { + throw new PostingRestrictedException($magazine, $actor); + } + $dto = new EntryDto(); $dto->magazine = $magazine; $dto->title = $object['name']; diff --git a/src/Service/ActivityPubManager.php b/src/Service/ActivityPubManager.php index a1e488354..a4818766a 100644 --- a/src/Service/ActivityPubManager.php +++ b/src/Service/ActivityPubManager.php @@ -524,6 +524,7 @@ public function updateMagazine(string $actorUrl): ?Magazine $magazine->apTimeoutAt = null; $magazine->apFetchedAt = new \DateTime(); $magazine->isAdult = $actor['sensitive'] ?? false; + $magazine->postingRestrictedToMods = filter_var($actor['postingRestrictedToMods'] ?? false, FILTER_VALIDATE_BOOLEAN) ?? false; if (null !== $magazine->apFollowersUrl) { try { diff --git a/src/Service/EntryManager.php b/src/Service/EntryManager.php index ce66f5fab..8658322aa 100644 --- a/src/Service/EntryManager.php +++ b/src/Service/EntryManager.php @@ -18,6 +18,7 @@ use App\Event\Entry\EntryEditedEvent; use App\Event\Entry\EntryPinEvent; use App\Event\Entry\EntryRestoredEvent; +use App\Exception\PostingRestrictedException; use App\Exception\TagBannedException; use App\Exception\UserBannedException; use App\Factory\EntryFactory; @@ -68,6 +69,7 @@ public function __construct( * @throws TagBannedException * @throws UserBannedException * @throws TooManyRequestsHttpException + * @throws PostingRestrictedException * @throws \Exception if title, body and image are empty */ public function create(EntryDto $dto, User $user, bool $rateLimit = true, bool $stickyIt = false): Entry @@ -87,6 +89,10 @@ public function create(EntryDto $dto, User $user, bool $rateLimit = true, bool $ throw new TagBannedException(); } + if ($dto->magazine->isActorPostingRestricted($user)) { + throw new PostingRestrictedException($dto->magazine, $user); + } + $this->logger->debug('creating entry from dto'); $entry = $this->factory->createFromDto($dto, $user); diff --git a/src/Service/MagazineManager.php b/src/Service/MagazineManager.php index f1015de5f..e45a4bc0e 100644 --- a/src/Service/MagazineManager.php +++ b/src/Service/MagazineManager.php @@ -141,6 +141,7 @@ public function edit(Magazine $magazine, MagazineDto $dto): Magazine $magazine->description = $dto->description; $magazine->rules = $dto->rules; $magazine->isAdult = $dto->isAdult; + $magazine->postingRestrictedToMods = $dto->isPostingRestrictedToMods; $this->entityManager->flush(); diff --git a/templates/components/magazine_box.html.twig b/templates/components/magazine_box.html.twig index 9a8abd660..311e9319e 100644 --- a/templates/components/magazine_box.html.twig +++ b/templates/components/magazine_box.html.twig @@ -18,8 +18,17 @@ {% endif %}
        -

        {{ computed.magazine.title }}

        +

        + + {{ computed.magazine.title }} + + {% if magazine.postingRestrictedToMods %} + + {% endif %} +

        {{ ('@'~magazine.name)|username(true) }} {% if magazine.isAdult %}18+{% endif %} {% if magazine.apId %} diff --git a/templates/components/magazine_inline.html.twig b/templates/components/magazine_inline.html.twig index afa310bc2..31bf3e3e5 100644 --- a/templates/components/magazine_inline.html.twig +++ b/templates/components/magazine_inline.html.twig @@ -12,7 +12,19 @@ {% endif %} {% if fullName %} {{ magazine.name }} {% if magazine.isAdult %}18+{% endif %} + {% if magazine.postingRestrictedToMods %} + + {% endif %} {% else %} {{ magazine.title }} + {% if magazine.postingRestrictedToMods %} + + {% endif %} {% endif %} diff --git a/templates/entry/front.html.twig b/templates/entry/front.html.twig index 258089ad6..f2d3c49cc 100644 --- a/templates/entry/front.html.twig +++ b/templates/entry/front.html.twig @@ -52,6 +52,7 @@ {% include 'entry/_options.html.twig' %} {% include 'layout/_flash.html.twig' %} {% if magazine is defined and magazine %} + {% include 'magazine/_restricted_info.html.twig' %} {% include 'magazine/_federated_info.html.twig' %} {% include 'magazine/_visibility_info.html.twig' %} {% endif %} diff --git a/templates/magazine/_restricted_info.html.twig b/templates/magazine/_restricted_info.html.twig new file mode 100644 index 000000000..5af8a6a47 --- /dev/null +++ b/templates/magazine/_restricted_info.html.twig @@ -0,0 +1,5 @@ +{% if magazine.postingRestrictedToMods and (app.user is not defined or app.user is same as null or magazine.isActorPostingRestricted(app.user)) %} +

        + {{ 'magazine_posting_restricted_to_mods_warning'|trans }} +
        +{% endif %} diff --git a/templates/magazine/panel/general.html.twig b/templates/magazine/panel/general.html.twig index 38c0bec21..e0d6ddfb6 100644 --- a/templates/magazine/panel/general.html.twig +++ b/templates/magazine/panel/general.html.twig @@ -40,6 +40,10 @@ {{ form_label(form.isAdult) }} {{ form_widget(form.isAdult) }} +
        + {{ form_label(form.isPostingRestrictedToMods) }} + {{ form_widget(form.isPostingRestrictedToMods) }} +
        {{ form_row(form.submit, { 'label': 'done'|trans, 'attr': {'class': 'btn btn__primary'} }) }}
        diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml index b12463807..5f8e4fec2 100644 --- a/translations/messages.en.yaml +++ b/translations/messages.en.yaml @@ -869,6 +869,8 @@ show_related_entries: Show random threads show_related_posts: Show random posts show_active_users: Show active users notification_title_new_report: A new report was created +magazine_posting_restricted_to_mods_warning: Only mods can create threads in this magazine +flash_posting_restricted_error: Creating threads is restricted to mods in this magazine and you are not one server_software: Server software version: Version last_successful_deliver: Last successful deliver From 9a442030eb173397c4177f51da6f06ed6daa0faf Mon Sep 17 00:00:00 2001 From: debounced <35878315+nobodyatroot@users.noreply.github.com> Date: Wed, 31 Jul 2024 13:25:11 -0500 Subject: [PATCH 140/335] Add missing option to limit thread creation to mods on magazine creation (#962) --- src/Entity/Magazine.php | 2 ++ src/Factory/MagazineFactory.php | 1 + templates/magazine/create.html.twig | 1 + translations/messages.en.yaml | 1 + 4 files changed, 5 insertions(+) diff --git a/src/Entity/Magazine.php b/src/Entity/Magazine.php index 30286af23..77d602a8e 100644 --- a/src/Entity/Magazine.php +++ b/src/Entity/Magazine.php @@ -116,6 +116,7 @@ public function __construct( ?string $description, ?string $rules, bool $isAdult, + bool $postingRestrictedToMods, ?Image $icon ) { $this->name = $name; @@ -123,6 +124,7 @@ public function __construct( $this->description = $description; $this->rules = $rules; $this->isAdult = $isAdult; + $this->postingRestrictedToMods = $postingRestrictedToMods; $this->icon = $icon; $this->moderators = new ArrayCollection(); $this->entries = new ArrayCollection(); diff --git a/src/Factory/MagazineFactory.php b/src/Factory/MagazineFactory.php index 9191c2ed7..c17c3d370 100644 --- a/src/Factory/MagazineFactory.php +++ b/src/Factory/MagazineFactory.php @@ -44,6 +44,7 @@ public function createFromDto(MagazineDto $dto, ?User $user): Magazine $dto->description, $dto->rules, $dto->isAdult, + $dto->isPostingRestrictedToMods, $dto->icon ); } diff --git a/templates/magazine/create.html.twig b/templates/magazine/create.html.twig index 04374dd48..6f1af4d13 100644 --- a/templates/magazine/create.html.twig +++ b/templates/magazine/create.html.twig @@ -47,6 +47,7 @@ 'data-input-length-max-value': constant('App\\Entity\\Magazine::MAX_RULES_LENGTH') }}) }} {{ form_row(form.isAdult, {label:'is_adult', row_attr: {class: 'checkbox'}}) }} + {{ form_row(form.isPostingRestrictedToMods, {label:'magazine_posting_restricted_to_mods',row_attr: {class: 'checkbox'}}) }}
        {{ form_row(form.submit, {label: 'create_new_magazine', attr: {class: 'btn btn__primary'}, row_attr: {class: 'float-end'}}) }}
        diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml index 5f8e4fec2..293166cc3 100644 --- a/translations/messages.en.yaml +++ b/translations/messages.en.yaml @@ -876,3 +876,4 @@ version: Version last_successful_deliver: Last successful deliver last_successful_receive: Last successful receive last_failed_contact: Last failed contact +magazine_posting_restricted_to_mods: Restrict thread creation to moderators \ No newline at end of file From 951bf3c14fdbe2effb88f69038a655f310e033e6 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Wed, 31 Jul 2024 20:28:36 +0200 Subject: [PATCH 141/335] Translations update from Hosted Weblate (#964) Co-authored-by: BentiGorlich --- translations/messages.de.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/translations/messages.de.yaml b/translations/messages.de.yaml index 197686609..130e94cb8 100644 --- a/translations/messages.de.yaml +++ b/translations/messages.de.yaml @@ -912,3 +912,16 @@ show_related_magazines: Zeige zufällige Magazine show_related_entries: Zeige zufällige Themen show_related_posts: Zeige zufällige Beiträge notification_title_new_report: Eine neue Meldung wurde erstellt +federation_page_dead_title: Tote Instanzen +federation_page_dead_description: Instanzen zu denen wir mindestens 10 Aktivitäten + in folge nicht zustellen konnten und bei denen die letzte erfolgreiche Zustellung + mehr als eine Woche zurückliegt +server_software: Server Software +version: Version +magazine_posting_restricted_to_mods_warning: Nur Mods können Themen in diesem Magazin + erstellen +flash_posting_restricted_error: Die Erstellung von Themen ist in diesem Magazin auf + mods eingeschränkt und du bist keiner +last_successful_deliver: Letzte erfolgreiche Zustellung +last_successful_receive: Letzter erfolgreicher Empfang +last_failed_contact: Letzter misslungener Kontakt From e63ac148953fa9e08c105499c339e304856bb104 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 31 Jul 2024 18:30:31 +0000 Subject: [PATCH 142/335] docs(contributor): contributors readme action update (#963) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 994aea35a..d592578ab 100644 --- a/README.md +++ b/README.md @@ -97,19 +97,19 @@ For developers: - - SzymonKaminski + + nobodyatroot
        - SzymonKaminski + debounced
        - - nobodyatroot + + SzymonKaminski
        - debounced + SzymonKaminski
        From 84610aaaace4394489a553341dd5c10988388de4 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Thu, 1 Aug 2024 07:23:50 +0000 Subject: [PATCH 143/335] Send out update activities on actor updates (#954) Co-authored-by: debounced <35878315+nobodyatroot@users.noreply.github.com> --- .../Entry/Comments/EntryCommentsUpdateApi.php | 2 +- src/Controller/Api/Entry/EntriesUpdateApi.php | 2 +- .../Api/Magazine/Admin/MagazineUpdateApi.php | 2 +- .../Post/Comments/PostCommentsUpdateApi.php | 2 +- src/Controller/Api/Post/PostsUpdateApi.php | 5 +- .../Comment/EntryCommentEditController.php | 2 +- src/Controller/Entry/EntryEditController.php | 2 +- .../Magazine/Panel/MagazineEditController.php | 2 +- .../Comment/PostCommentEditController.php | 2 +- src/Controller/Post/PostEditController.php | 2 +- src/Entity/Magazine.php | 9 ++ src/Entity/User.php | 9 ++ src/Event/Entry/EntryEditedEvent.php | 3 +- .../EntryComment/EntryCommentEditedEvent.php | 3 +- src/Event/Magazine/MagazineUpdatedEvent.php | 17 +++ src/Event/Post/PostEditedEvent.php | 3 +- .../PostComment/PostCommentEditedEvent.php | 3 +- src/Event/User/UserEditedEvent.php | 13 ++ .../Entry/EntryEditSubscriber.php | 2 +- .../EntryCommentEditSubscriber.php | 2 +- .../Magazine/MagazineUpdatedSubscriber.php | 40 ++++++ .../Post/PostEditSubscriber.php | 4 +- .../PostComment/PostCommentEditSubscriber.php | 2 +- .../User/UserEditedSubscriber.php | 36 ++++++ src/Factory/ActivityPub/GroupFactory.php | 6 +- .../ActivityPub/Outbox/UpdateMessage.php | 2 +- .../ActivityPub/Inbox/UpdateHandler.php | 87 ++++++++++++- .../ActivityPub/Outbox/UpdateHandler.php | 71 ++++++++--- .../ActivityPub/UpdateActorHandler.php | 5 + src/Repository/ApActivityRepository.php | 4 + src/Service/ActivityPub/ApHttpClient.php | 12 +- .../ActivityPub/Wrapper/UpdateWrapper.php | 116 ++++++++++++++++++ src/Service/ActivityPubManager.php | 14 ++- src/Service/EntryCommentManager.php | 4 +- src/Service/EntryManager.php | 4 +- src/Service/MagazineManager.php | 5 +- src/Service/PostCommentManager.php | 4 +- src/Service/PostManager.php | 4 +- src/Service/UserManager.php | 57 +++++---- 39 files changed, 476 insertions(+), 88 deletions(-) create mode 100644 src/Event/Magazine/MagazineUpdatedEvent.php create mode 100644 src/Event/User/UserEditedEvent.php create mode 100644 src/EventSubscriber/Magazine/MagazineUpdatedSubscriber.php create mode 100644 src/EventSubscriber/User/UserEditedSubscriber.php create mode 100644 src/Service/ActivityPub/Wrapper/UpdateWrapper.php diff --git a/src/Controller/Api/Entry/Comments/EntryCommentsUpdateApi.php b/src/Controller/Api/Entry/Comments/EntryCommentsUpdateApi.php index d4f934ca3..b843f62d3 100644 --- a/src/Controller/Api/Entry/Comments/EntryCommentsUpdateApi.php +++ b/src/Controller/Api/Entry/Comments/EntryCommentsUpdateApi.php @@ -105,7 +105,7 @@ public function __invoke( throw new BadRequestHttpException((string) $errors); } - $comment = $manager->edit($comment, $dto); + $comment = $manager->edit($comment, $dto, $this->getUserOrThrow()); return new JsonResponse( $this->serializeCommentTree($comment), diff --git a/src/Controller/Api/Entry/EntriesUpdateApi.php b/src/Controller/Api/Entry/EntriesUpdateApi.php index 51b6d0a7d..80221433f 100644 --- a/src/Controller/Api/Entry/EntriesUpdateApi.php +++ b/src/Controller/Api/Entry/EntriesUpdateApi.php @@ -93,7 +93,7 @@ public function __invoke( throw new BadRequestHttpException((string) $errors); } - $entry = $manager->edit($entry, $dto); + $entry = $manager->edit($entry, $dto, $this->getUserOrThrow()); return new JsonResponse( $this->serializeEntry($entry, $this->tagLinkRepository->getTagsOfEntry($entry)), diff --git a/src/Controller/Api/Magazine/Admin/MagazineUpdateApi.php b/src/Controller/Api/Magazine/Admin/MagazineUpdateApi.php index 91f576a48..3191fbf3f 100644 --- a/src/Controller/Api/Magazine/Admin/MagazineUpdateApi.php +++ b/src/Controller/Api/Magazine/Admin/MagazineUpdateApi.php @@ -99,7 +99,7 @@ public function __invoke( throw new BadRequestHttpException('Magazine name cannot be edited'); } - $magazine = $manager->edit($magazine, $dto); + $magazine = $manager->edit($magazine, $dto, $this->getUserOrThrow()); return new JsonResponse( $this->serializeMagazine($factory->createDto($magazine)), diff --git a/src/Controller/Api/Post/Comments/PostCommentsUpdateApi.php b/src/Controller/Api/Post/Comments/PostCommentsUpdateApi.php index ae7b2bcd1..7d6696de1 100644 --- a/src/Controller/Api/Post/Comments/PostCommentsUpdateApi.php +++ b/src/Controller/Api/Post/Comments/PostCommentsUpdateApi.php @@ -105,7 +105,7 @@ public function __invoke( throw new BadRequestHttpException((string) $errors); } - $comment = $manager->edit($comment, $dto); + $comment = $manager->edit($comment, $dto, $this->getUserOrThrow()); return new JsonResponse( $this->serializePostCommentTree($comment), diff --git a/src/Controller/Api/Post/PostsUpdateApi.php b/src/Controller/Api/Post/PostsUpdateApi.php index 8d627f83e..3e84581b5 100644 --- a/src/Controller/Api/Post/PostsUpdateApi.php +++ b/src/Controller/Api/Post/PostsUpdateApi.php @@ -85,7 +85,8 @@ public function __invoke( ): JsonResponse { $headers = $this->rateLimit($apiUpdateLimiter); - if ($post->user->getId() !== $this->getUserOrThrow()->getId()) { + $user = $this->getUserOrThrow(); + if ($post->user->getId() !== $user->getId()) { throw new AccessDeniedHttpException(); } @@ -96,7 +97,7 @@ public function __invoke( throw new BadRequestHttpException((string) $errors); } - $post = $manager->edit($post, $dto); + $post = $manager->edit($post, $dto, $user); return new JsonResponse( $this->serializePost($factory->createDto($post), $this->tagLinkRepository->getTagsOfPost($post)), diff --git a/src/Controller/Entry/Comment/EntryCommentEditController.php b/src/Controller/Entry/Comment/EntryCommentEditController.php index 354258af7..4d9c03763 100644 --- a/src/Controller/Entry/Comment/EntryCommentEditController.php +++ b/src/Controller/Entry/Comment/EntryCommentEditController.php @@ -95,7 +95,7 @@ private function getForm(EntryCommentDto $dto, EntryComment $comment): FormInter private function handleValidRequest(EntryCommentDto $dto, EntryComment $comment, Request $request): Response { - $comment = $this->manager->edit($comment, $dto); + $comment = $this->manager->edit($comment, $dto, $this->getUserOrThrow()); if ($request->isXmlHttpRequest()) { return $this->getJsonCommentSuccessResponse($comment); diff --git a/src/Controller/Entry/EntryEditController.php b/src/Controller/Entry/EntryEditController.php index 1fb27cf1e..22829f411 100644 --- a/src/Controller/Entry/EntryEditController.php +++ b/src/Controller/Entry/EntryEditController.php @@ -45,7 +45,7 @@ public function __invoke( throw new AccessDeniedHttpException(); } - $entry = $this->manager->edit($entry, $dto); + $entry = $this->manager->edit($entry, $dto, $this->getUserOrThrow()); $this->addFlash('success', 'flash_thread_edit_success'); diff --git a/src/Controller/Magazine/Panel/MagazineEditController.php b/src/Controller/Magazine/Panel/MagazineEditController.php index 83138f355..2d0028574 100644 --- a/src/Controller/Magazine/Panel/MagazineEditController.php +++ b/src/Controller/Magazine/Panel/MagazineEditController.php @@ -29,7 +29,7 @@ public function __invoke(Magazine $magazine, Request $request): Response $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $this->manager->edit($magazine, $magazineDto); + $this->manager->edit($magazine, $magazineDto, $this->getUserOrThrow()); $this->addFlash('success', 'flash_magazine_edit_success'); diff --git a/src/Controller/Post/Comment/PostCommentEditController.php b/src/Controller/Post/Comment/PostCommentEditController.php index d9a7ea388..b993ae8c6 100644 --- a/src/Controller/Post/Comment/PostCommentEditController.php +++ b/src/Controller/Post/Comment/PostCommentEditController.php @@ -106,7 +106,7 @@ private function getCreateForm(PostCommentDto $dto, PostComment $comment): FormI private function handleValidRequest(PostCommentDto $dto, PostComment $comment, Request $request): Response { - $comment = $this->manager->edit($comment, $dto); + $comment = $this->manager->edit($comment, $dto, $this->getUserOrThrow()); if ($request->isXmlHttpRequest()) { return $this->getPostCommentJsonSuccessResponse($comment); diff --git a/src/Controller/Post/PostEditController.php b/src/Controller/Post/PostEditController.php index c78c406d8..c4e627e5e 100644 --- a/src/Controller/Post/PostEditController.php +++ b/src/Controller/Post/PostEditController.php @@ -46,7 +46,7 @@ public function __invoke( throw new AccessDeniedHttpException(); } - $post = $this->manager->edit($post, $dto); + $post = $this->manager->edit($post, $dto, $this->getUserOrThrow()); if ($request->isXmlHttpRequest()) { return new JsonResponse( diff --git a/src/Entity/Magazine.php b/src/Entity/Magazine.php index 77d602a8e..dfa15993a 100644 --- a/src/Entity/Magazine.php +++ b/src/Entity/Magazine.php @@ -481,6 +481,15 @@ public function hasSameHostAsUser(User $actor): bool return false; } + public function canUpdateMagazine(User $actor): bool + { + if (null === $this->apId) { + return $actor->isAdmin() || $actor->isModerator() || $this->userIsModerator($actor); + } else { + return $this->apDomain === $actor->apDomain || $this->userIsModerator($actor); + } + } + /** * @param Magazine|User $actor the actor trying to create an Entry * diff --git a/src/Entity/User.php b/src/Entity/User.php index 338c9550a..f8bd9271a 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -871,4 +871,13 @@ public function getFollowerUrl(ApHttpClient $client, UrlGeneratorInterface $urlG ); } } + + public function canUpdateUser(User $actor): bool + { + if (null === $this->apId) { + return null === $actor->apId && $actor->isAdmin(); + } else { + return $this->apDomain === $actor->apDomain; + } + } } diff --git a/src/Event/Entry/EntryEditedEvent.php b/src/Event/Entry/EntryEditedEvent.php index b6e3dbc5f..12af1d914 100644 --- a/src/Event/Entry/EntryEditedEvent.php +++ b/src/Event/Entry/EntryEditedEvent.php @@ -5,10 +5,11 @@ namespace App\Event\Entry; use App\Entity\Entry; +use App\Entity\User; class EntryEditedEvent { - public function __construct(public Entry $entry) + public function __construct(public Entry $entry, public ?User $editedBy = null) { } } diff --git a/src/Event/EntryComment/EntryCommentEditedEvent.php b/src/Event/EntryComment/EntryCommentEditedEvent.php index c319fbdfc..7e0e7b475 100644 --- a/src/Event/EntryComment/EntryCommentEditedEvent.php +++ b/src/Event/EntryComment/EntryCommentEditedEvent.php @@ -5,10 +5,11 @@ namespace App\Event\EntryComment; use App\Entity\EntryComment; +use App\Entity\User; class EntryCommentEditedEvent { - public function __construct(public EntryComment $comment) + public function __construct(public EntryComment $comment, public ?User $editedByUser = null) { } } diff --git a/src/Event/Magazine/MagazineUpdatedEvent.php b/src/Event/Magazine/MagazineUpdatedEvent.php new file mode 100644 index 000000000..536c8b85f --- /dev/null +++ b/src/Event/Magazine/MagazineUpdatedEvent.php @@ -0,0 +1,17 @@ +entry->apId) { - $this->bus->dispatch(new UpdateMessage($event->entry->getId(), \get_class($event->entry))); + $this->bus->dispatch(new UpdateMessage($event->entry->getId(), \get_class($event->entry), $event->editedBy->getId())); } } } diff --git a/src/EventSubscriber/EntryComment/EntryCommentEditSubscriber.php b/src/EventSubscriber/EntryComment/EntryCommentEditSubscriber.php index eb0d1bd94..cc29f5e51 100644 --- a/src/EventSubscriber/EntryComment/EntryCommentEditSubscriber.php +++ b/src/EventSubscriber/EntryComment/EntryCommentEditSubscriber.php @@ -35,7 +35,7 @@ public function onEntryCommentEdited(EntryCommentEditedEvent $event): void } if (!$event->comment->apId) { - $this->bus->dispatch(new UpdateMessage($event->comment->getId(), \get_class($event->comment))); + $this->bus->dispatch(new UpdateMessage($event->comment->getId(), \get_class($event->comment), $event->editedByUser->getId())); } } } diff --git a/src/EventSubscriber/Magazine/MagazineUpdatedSubscriber.php b/src/EventSubscriber/Magazine/MagazineUpdatedSubscriber.php new file mode 100644 index 000000000..40e1dfc65 --- /dev/null +++ b/src/EventSubscriber/Magazine/MagazineUpdatedSubscriber.php @@ -0,0 +1,40 @@ + 'onMagazineUpdated', + ]; + } + + public function onMagazineUpdated(MagazineUpdatedEvent $event): void + { + $mag = $event->magazine; + if (null === $mag->apId) { + $activity = $this->updateWrapper->buildForActor($mag, $event->editedBy); + $this->bus->dispatch(new GenericAnnounceMessage($mag->getId(), $activity, $event->editedBy->apDomain)); + } elseif (null !== $event->editedBy && null === $event->editedBy->apId) { + $this->bus->dispatch(new UpdateMessage($mag->getId(), Magazine::class, $event->editedBy->getId())); + } + } +} diff --git a/src/EventSubscriber/Post/PostEditSubscriber.php b/src/EventSubscriber/Post/PostEditSubscriber.php index 0fa631cd8..138874685 100644 --- a/src/EventSubscriber/Post/PostEditSubscriber.php +++ b/src/EventSubscriber/Post/PostEditSubscriber.php @@ -24,7 +24,7 @@ public static function getSubscribedEvents(): array ]; } - public function onPostEdited(PostEditedEvent $event) + public function onPostEdited(PostEditedEvent $event): void { $this->bus->dispatch(new PostEditedNotificationMessage($event->post->getId())); if ($event->post->body) { @@ -32,7 +32,7 @@ public function onPostEdited(PostEditedEvent $event) } if (!$event->post->apId) { - $this->bus->dispatch(new UpdateMessage($event->post->getId(), \get_class($event->post))); + $this->bus->dispatch(new UpdateMessage($event->post->getId(), \get_class($event->post), $event->editedBy->getId())); } } } diff --git a/src/EventSubscriber/PostComment/PostCommentEditSubscriber.php b/src/EventSubscriber/PostComment/PostCommentEditSubscriber.php index abba4be54..caad82c28 100644 --- a/src/EventSubscriber/PostComment/PostCommentEditSubscriber.php +++ b/src/EventSubscriber/PostComment/PostCommentEditSubscriber.php @@ -40,7 +40,7 @@ public function onPostCommentEdited(PostCommentEditedEvent $event) } if (!$event->comment->apId) { - $this->bus->dispatch(new UpdateMessage($event->comment->getId(), \get_class($event->comment))); + $this->bus->dispatch(new UpdateMessage($event->comment->getId(), \get_class($event->comment), $event->editedBy->getId())); } } } diff --git a/src/EventSubscriber/User/UserEditedSubscriber.php b/src/EventSubscriber/User/UserEditedSubscriber.php new file mode 100644 index 000000000..8f8d29d9a --- /dev/null +++ b/src/EventSubscriber/User/UserEditedSubscriber.php @@ -0,0 +1,36 @@ + 'onUserEdited', + ]; + } + + public function onUserEdited(UserEditedEvent $event): void + { + $user = $this->userRepository->findOneBy(['id' => $event->userId]); + if (null === $user->apId) { + $this->bus->dispatch(new UpdateMessage($user->getId(), User::class, $user->getId())); + } + } +} diff --git a/src/Factory/ActivityPub/GroupFactory.php b/src/Factory/ActivityPub/GroupFactory.php index 4e75a2c98..9c50ae160 100644 --- a/src/Factory/ActivityPub/GroupFactory.php +++ b/src/Factory/ActivityPub/GroupFactory.php @@ -21,7 +21,7 @@ public function __construct( ) { } - public function create(Magazine $magazine): array + public function create(Magazine $magazine, bool $includeContext = true): array { $markdownSummary = $magazine->description ?? ''; @@ -98,6 +98,10 @@ public function create(Magazine $magazine): array ]; } + if (!$includeContext) { + unset($group['@context']); + } + return $group; } diff --git a/src/Message/ActivityPub/Outbox/UpdateMessage.php b/src/Message/ActivityPub/Outbox/UpdateMessage.php index 93f60ec4d..2197cb8fa 100644 --- a/src/Message/ActivityPub/Outbox/UpdateMessage.php +++ b/src/Message/ActivityPub/Outbox/UpdateMessage.php @@ -8,7 +8,7 @@ class UpdateMessage implements ActivityPubOutboxInterface { - public function __construct(public int $id, public string $type) + public function __construct(public int $id, public string $type, public ?int $editedByUserId = null) { } } diff --git a/src/MessageHandler/ActivityPub/Inbox/UpdateHandler.php b/src/MessageHandler/ActivityPub/Inbox/UpdateHandler.php index 7b9b6037e..d729ad183 100644 --- a/src/MessageHandler/ActivityPub/Inbox/UpdateHandler.php +++ b/src/MessageHandler/ActivityPub/Inbox/UpdateHandler.php @@ -6,27 +6,34 @@ use App\DTO\EntryCommentDto; use App\DTO\EntryDto; +use App\DTO\MagazineThemeDto; use App\DTO\PostCommentDto; use App\DTO\PostDto; use App\Entity\Entry; use App\Entity\EntryComment; +use App\Entity\Magazine; use App\Entity\Message; use App\Entity\Post; use App\Entity\PostComment; use App\Entity\User; use App\Factory\EntryCommentFactory; use App\Factory\EntryFactory; +use App\Factory\ImageFactory; +use App\Factory\MagazineFactory; use App\Factory\PostCommentFactory; use App\Factory\PostFactory; use App\Message\ActivityPub\Inbox\UpdateMessage; use App\Message\ActivityPub\Outbox\GenericAnnounceMessage; +use App\Message\ActivityPub\UpdateActorMessage; use App\Message\Contracts\MessageInterface; +use App\Message\DeleteImageMessage; use App\MessageHandler\MbinMessageHandler; use App\Repository\ApActivityRepository; use App\Service\ActivityPub\ApObjectExtractor; use App\Service\ActivityPubManager; use App\Service\EntryCommentManager; use App\Service\EntryManager; +use App\Service\MagazineManager; use App\Service\MessageManager; use App\Service\PostCommentManager; use App\Service\PostManager; @@ -56,6 +63,9 @@ public function __construct( private readonly MessageManager $messageManager, private readonly LoggerInterface $logger, private readonly MessageBusInterface $bus, + private readonly MagazineManager $magazineManager, + private readonly MagazineFactory $magazineFactory, + private readonly ImageFactory $imageFactory, ) { parent::__construct($this->entityManager); } @@ -71,6 +81,7 @@ public function doWork(MessageInterface $message): void throw new \LogicException(); } $this->payload = $message->payload; + $this->logger->debug('received Update activity: {json}', ['json' => $this->payload]); try { $actor = $this->activityPubManager->findRemoteActor($message->payload['actor']); @@ -80,10 +91,30 @@ public function doWork(MessageInterface $message): void $object = $this->apActivityRepository->findByObjectId($message->payload['object']['id']); - if (!$object) { + if ($object) { + $this->editActivity($object, $message, $actor); + + return; + } + + $object = $this->activityPubManager->findActorOrCreate($message->payload['object']['id']); + if ($object instanceof User) { + $this->updateUser($object, $actor); + return; } + if ($object instanceof Magazine) { + $this->updateMagazine($object, $actor); + + return; + } + + $this->logger->warning("didn't know what to do with the update activity concerning '{id}'. We don't have a local object that has this id", ['id' => $message->payload['object']['id']]); + } + + private function editActivity(array $object, UpdateMessage $message, User $actor): void + { $object = $this->entityManager->getRepository($object['type'])->find((int) $object['id']); if ($object instanceof Entry) { $this->editEntry($object, $actor); @@ -122,7 +153,7 @@ private function editEntry(Entry $entry, User $user): void $dto->title = $this->payload['object']['name']; $this->extractChanges($dto); - $this->entryManager->edit($entry, $dto); + $this->entryManager->edit($entry, $dto, $user); } private function editEntryComment(EntryComment $comment, User $user): void @@ -136,7 +167,7 @@ private function editEntryComment(EntryComment $comment, User $user): void $this->extractChanges($dto); - $this->entryCommentManager->edit($comment, $dto); + $this->entryCommentManager->edit($comment, $dto, $user); } private function editPost(Post $post, User $user): void @@ -150,7 +181,7 @@ private function editPost(Post $post, User $user): void $this->extractChanges($dto); - $this->postManager->edit($post, $dto); + $this->postManager->edit($post, $dto, $user); } private function editPostComment(PostComment $comment, User $user): void @@ -164,7 +195,7 @@ private function editPostComment(PostComment $comment, User $user): void $this->extractChanges($dto); - $this->postCommentManager->edit($comment, $dto); + $this->postCommentManager->edit($comment, $dto, $user); } private function extractChanges(EntryDto|EntryCommentDto|PostDto|PostCommentDto $dto): void @@ -190,4 +221,50 @@ private function editMessage(Message $message, User $user): void ); } } + + private function updateUser(User $user, User $actor): void + { + if ($user->canUpdateUser($actor)) { + if (null !== $user->apId) { + $this->bus->dispatch(new UpdateActorMessage($user->apProfileId, force: true)); + } + } else { + $this->logger->warning('User {u1} wanted to update user {u2} without being allowed to do so', ['u1' => $actor->apId ?? $actor->username, 'u2' => $user->apId ?? $user->username]); + } + } + + private function updateMagazine(Magazine $magazine, User $actor): void + { + if ($magazine->canUpdateMagazine($actor)) { + $payloadObject = $this->payload['object']; + + $themeDto = new MagazineThemeDto($magazine); + if (isset($payloadObject['icon'])) { + $newImage = $this->activityPubManager->handleImages([$payloadObject['icon']]); + if ($magazine->icon && $newImage !== $magazine->icon) { + $this->bus->dispatch(new DeleteImageMessage($magazine->icon->getId())); + } + $themeDto->icon = $this->imageFactory->createDto($newImage); + } elseif ($magazine->icon) { + $this->magazineManager->detachIcon($magazine); + } + + $this->magazineManager->changeTheme($themeDto); + + $dto = $this->magazineFactory->createDto($magazine); + if ($payloadObject['name']) { + $dto->title = $payloadObject['name']; + } elseif ($payloadObject['preferredUsername']) { + $dto->title = $payloadObject['preferredUsername']; + } + if (isset($payloadObject['summary'])) { + $dto->description = $this->activityPubManager->extractMarkdownSummary($payloadObject); + } + $dto->isAdult = $payloadObject['sensitive'] ?? false; + + $this->magazineManager->edit($magazine, $dto, $actor); + } else { + $this->logger->warning('User {u} wanted to update magazine {m} without being allowed to do so', ['u' => $actor->apId ?? $actor->username, 'm' => $magazine->apId ?? $magazine->name]); + } + } } diff --git a/src/MessageHandler/ActivityPub/Outbox/UpdateHandler.php b/src/MessageHandler/ActivityPub/Outbox/UpdateHandler.php index 2cafad8e7..5bcb70c5e 100644 --- a/src/MessageHandler/ActivityPub/Outbox/UpdateHandler.php +++ b/src/MessageHandler/ActivityPub/Outbox/UpdateHandler.php @@ -4,19 +4,26 @@ namespace App\MessageHandler\ActivityPub\Outbox; +use App\Entity\Contracts\ActivityPubActivityInterface; +use App\Entity\Contracts\ActivityPubActorInterface; +use App\Entity\Entry; +use App\Entity\EntryComment; +use App\Entity\Magazine; +use App\Entity\Message; +use App\Entity\Post; +use App\Entity\PostComment; +use App\Entity\User; use App\Message\ActivityPub\Outbox\UpdateMessage; use App\Message\Contracts\MessageInterface; use App\MessageHandler\MbinMessageHandler; use App\Repository\MagazineRepository; use App\Repository\UserRepository; -use App\Service\ActivityPub\Wrapper\CreateWrapper; +use App\Service\ActivityPub\Wrapper\UpdateWrapper; use App\Service\ActivityPubManager; use App\Service\DeliverManager; use App\Service\SettingsManager; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Messenger\Attribute\AsMessageHandler; -use Symfony\Component\Routing\Generator\UrlGeneratorInterface; -use Symfony\Component\Uid\Uuid; #[AsMessageHandler] class UpdateHandler extends MbinMessageHandler @@ -24,12 +31,11 @@ class UpdateHandler extends MbinMessageHandler public function __construct( private readonly UserRepository $userRepository, private readonly MagazineRepository $magazineRepository, - private readonly CreateWrapper $createWrapper, private readonly EntityManagerInterface $entityManager, private readonly ActivityPubManager $activityPubManager, private readonly SettingsManager $settingsManager, - private readonly UrlGeneratorInterface $urlGenerator, private readonly DeliverManager $deliverManager, + private readonly UpdateWrapper $updateWrapper, ) { parent::__construct($this->entityManager); } @@ -49,23 +55,48 @@ public function doWork(MessageInterface $message): void } $entity = $this->entityManager->getRepository($message->type)->find($message->id); + $editedByUser = null; + if ($message->editedByUserId) { + $editedByUser = $this->userRepository->findOneBy(['id' => $message->editedByUserId]); + } + + if ($entity instanceof ActivityPubActivityInterface) { + $activity = $this->updateWrapper->buildForActivity($entity, $editedByUser); - $activity = $this->createWrapper->build($entity); - $activity['id'] = $this->urlGenerator->generate( - 'ap_object', - ['id' => Uuid::v4()->toRfc4122()], - UrlGeneratorInterface::ABSOLUTE_URL, - ); - $activity['type'] = 'Update'; - $activity['object']['updated'] = $entity->editedAt - ? $entity->editedAt->format(DATE_ATOM) - : (new \DateTime())->format(DATE_ATOM); + if ($entity instanceof Entry || $entity instanceof EntryComment || $entity instanceof Post || $entity instanceof PostComment) { + $inboxes = array_filter(array_unique(array_merge( + $this->userRepository->findAudience($entity->user), + $this->activityPubManager->createInboxesFromCC($activity, $entity->user), + $this->magazineRepository->findAudience($entity->magazine) + ))); + } elseif ($entity instanceof Message) { + if (null === $message->editedByUserId) { + throw new \LogicException('a message has to be edited by someone'); + } + $inboxes = array_unique(array_map(fn (User $u) => $u->apInboxUrl, $entity->thread->getOtherParticipants($message->editedByUserId))); + } else { + throw new \LogicException('unknown activity type: '.\get_class($entity)); + } + } elseif ($entity instanceof ActivityPubActorInterface) { + $activity = $this->updateWrapper->buildForActor($entity, $editedByUser); + if ($entity instanceof User) { + $inboxes = $this->userRepository->findAudience($entity); + } elseif ($entity instanceof Magazine) { + if (null === $entity->apId) { + $inboxes = $this->magazineRepository->findAudience($entity); + if (null !== $editedByUser) { + $inboxes = array_filter($inboxes, fn (string $domain) => $editedByUser->apInboxUrl !== $domain); + } + } else { + $inboxes = [$entity->apInboxUrl]; + } + } else { + throw new \LogicException('Unknown actor type: '.\get_class($entity)); + } + } else { + throw new \LogicException('Unknown activity type: '.\get_class($entity)); + } - $inboxes = array_filter(array_unique(array_merge( - $this->userRepository->findAudience($entity->user), - $this->activityPubManager->createInboxesFromCC($activity, $entity->user), - $this->magazineRepository->findAudience($entity->magazine) - ))); $this->deliverManager->deliver($inboxes, $activity); } } diff --git a/src/MessageHandler/ActivityPub/UpdateActorHandler.php b/src/MessageHandler/ActivityPub/UpdateActorHandler.php index 62081adfd..7f9aa73de 100644 --- a/src/MessageHandler/ActivityPub/UpdateActorHandler.php +++ b/src/MessageHandler/ActivityPub/UpdateActorHandler.php @@ -9,6 +9,7 @@ use App\MessageHandler\MbinMessageHandler; use App\Repository\MagazineRepository; use App\Repository\UserRepository; +use App\Service\ActivityPub\ApHttpClient; use App\Service\ActivityPubManager; use Doctrine\ORM\EntityManagerInterface; use Psr\Log\LoggerInterface; @@ -21,6 +22,7 @@ class UpdateActorHandler extends MbinMessageHandler public function __construct( private readonly EntityManagerInterface $entityManager, private readonly ActivityPubManager $manager, + private readonly ApHttpClient $apHttpClient, private readonly LockFactory $lockFactory, private readonly UserRepository $userRepository, private readonly MagazineRepository $magazineRepository, @@ -55,6 +57,9 @@ public function doWork(MessageInterface $message): void ?? $this->magazineRepository->findOneBy(['apProfileId' => $actorUrl]); if ($actor) { + if ($message->force) { + $this->apHttpClient->invalidateActorObjectCache($actorUrl); + } if ($message->force || $actor->apFetchedAt < (new \DateTime())->modify('-1 hour')) { $this->manager->updateActor($actorUrl); } else { diff --git a/src/Repository/ApActivityRepository.php b/src/Repository/ApActivityRepository.php index 6da0d400c..ff25ec6bf 100644 --- a/src/Repository/ApActivityRepository.php +++ b/src/Repository/ApActivityRepository.php @@ -80,6 +80,10 @@ public function findLocalByApId(string $apId): ?array if ($parsed['host'] === $this->settingsManager->get('KBIN_DOMAIN')) { $exploded = array_filter(explode('/', $parsed['path'])); $id = \intval(end($exploded)); + if (\sizeof($exploded) < 3) { + return null; + } + if ('p' === $exploded[3]) { if (4 === \count($exploded)) { return [ diff --git a/src/Service/ActivityPub/ApHttpClient.php b/src/Service/ActivityPub/ApHttpClient.php index c3a651343..4c4fae66c 100644 --- a/src/Service/ActivityPub/ApHttpClient.php +++ b/src/Service/ActivityPub/ApHttpClient.php @@ -143,6 +143,11 @@ function (ItemInterface $item) use ($url) { return $resp ? json_decode($resp, true) : null; } + private function getActorCacheKey(string $apProfileId): string + { + return 'ap_'.hash('sha256', $apProfileId); + } + /** * Retrieve AP actor object (could be a user or magazine). * @@ -153,7 +158,7 @@ function (ItemInterface $item) use ($url) { public function getActorObject(string $apProfileId): ?array { $resp = $this->cache->get( - 'ap_'.hash('sha256', $apProfileId), + $this->getActorCacheKey($apProfileId), function (ItemInterface $item) use ($apProfileId) { $this->logger->debug("ApHttpClient:getActorObject:url: $apProfileId"); $response = null; @@ -210,6 +215,11 @@ function (ItemInterface $item) use ($apProfileId) { return $resp ? json_decode($resp, true) : null; } + public function invalidateActorObjectCache(string $apProfileId): void + { + $this->cache->delete($this->getActorCacheKey($apProfileId)); + } + public function invalidateCollectionObjectCache(string $apAddress): void { $this->cache->delete('ap_collection'.hash('sha256', $apAddress)); diff --git a/src/Service/ActivityPub/Wrapper/UpdateWrapper.php b/src/Service/ActivityPub/Wrapper/UpdateWrapper.php new file mode 100644 index 000000000..85ebd38b5 --- /dev/null +++ b/src/Service/ActivityPub/Wrapper/UpdateWrapper.php @@ -0,0 +1,116 @@ + 'mixed', + 'id' => 'mixed', + 'type' => 'string', + 'actor' => 'mixed', + 'published' => 'mixed', + 'to' => 'mixed', + 'cc' => 'mixed', + 'object' => 'array', + ])] + public function buildForActivity(ActivityPubActivityInterface $activity, ?User $editedBy = null): array + { + $entity = $this->factory->create($activity, true); + $id = Uuid::v4()->toRfc4122(); + + $context = $entity['@context']; + unset($entity['@context']); + + $entity['object']['updated'] = $activity->editedAt ? $activity->editedAt->format(DATE_ATOM) : (new \DateTime())->format(DATE_ATOM); + + $actorUrl = $entity['attributedTo']; + if (null !== $editedBy) { + $actorUrl = $this->urlGenerator->generate('ap_user', ['username' => $editedBy->username], UrlGeneratorInterface::ABSOLUTE_URL); + } + + return [ + '@context' => $context, + 'id' => $this->urlGenerator->generate('ap_object', ['id' => $id], UrlGeneratorInterface::ABSOLUTE_URL), + 'type' => 'Update', + 'actor' => $actorUrl, + 'published' => $entity['published'], + 'to' => $entity['to'], + 'cc' => $entity['cc'], + 'object' => $entity, + ]; + } + + #[ArrayShape([ + '@context' => 'mixed', + 'id' => 'mixed', + 'type' => 'string', + 'actor' => 'mixed', + 'published' => 'mixed', + 'to' => 'mixed', + 'cc' => 'mixed', + 'object' => 'array', + ])] + public function buildForActor(ActivityPubActorInterface $item, ?User $editedBy = null): array + { + if ($item instanceof User) { + $activity = $this->personFactory->create($item, false); + if (null === $item->apId) { + $cc = [$this->urlGenerator->generate('ap_user_followers', ['username' => $item->username], UrlGeneratorInterface::ABSOLUTE_URL)]; + } else { + $cc = [$item->apFollowersUrl]; + } + } elseif ($item instanceof Magazine) { + $activity = $this->groupFactory->create($item, false); + if (null === $item->apId) { + $cc = [$this->urlGenerator->generate('ap_magazine_followers', ['name' => $item->name], UrlGeneratorInterface::ABSOLUTE_URL)]; + } else { + $cc = [$item->apFollowersUrl]; + } + } else { + throw new \LogicException('Unknown actor type: '.\get_class($item)); + } + $id = Uuid::v4()->toRfc4122(); + + $actorUrl = $activity['id']; + if (null !== $editedBy) { + if (null === $editedBy->apId) { + $actorUrl = $this->urlGenerator->generate('ap_user', ['username' => $editedBy->username], UrlGeneratorInterface::ABSOLUTE_URL); + } else { + $actorUrl = $editedBy->apProfileId; + } + } + + return [ + '@context' => [$this->urlGenerator->generate('ap_contexts', [], UrlGeneratorInterface::ABSOLUTE_URL)], + 'id' => $this->urlGenerator->generate('ap_object', ['id' => $id], UrlGeneratorInterface::ABSOLUTE_URL), + 'type' => 'Update', + 'actor' => $actorUrl, + 'published' => $activity['published'], + 'to' => [ActivityPubActivityInterface::PUBLIC_URL], + 'cc' => $cc, + 'object' => $activity, + ]; + } +} diff --git a/src/Service/ActivityPubManager.php b/src/Service/ActivityPubManager.php index a4818766a..cf9b57288 100644 --- a/src/Service/ActivityPubManager.php +++ b/src/Service/ActivityPubManager.php @@ -387,7 +387,7 @@ public function updateUser(string $actorUrl): ?User $user->apFollowersCount = $followersObj['totalItems']; $user->updateFollowCounts(); } - } catch (InvalidApPostException $ignored) { + } catch (InvalidApPostException|InvalidArgumentException $ignored) { } } @@ -534,16 +534,22 @@ public function updateMagazine(string $actorUrl): ?Magazine $magazine->apFollowersCount = $followersObj['totalItems']; $magazine->updateSubscriptionsCount(); } - } catch (InvalidApPostException $ignored) { + } catch (InvalidApPostException|InvalidArgumentException $ignored) { } } if (null !== $magazine->apAttributedToUrl) { - $this->handleModeratorCollection($actorUrl, $magazine); + try { + $this->handleModeratorCollection($actorUrl, $magazine); + } catch (InvalidArgumentException $ignored) { + } } if (null !== $magazine->apFeaturedUrl) { - $this->handleMagazineFeaturedCollection($actorUrl, $magazine); + try { + $this->handleMagazineFeaturedCollection($actorUrl, $magazine); + } catch (InvalidArgumentException $ignored) { + } } if (null !== $magazine->apId) { diff --git a/src/Service/EntryCommentManager.php b/src/Service/EntryCommentManager.php index 2108c7872..6ca55a853 100644 --- a/src/Service/EntryCommentManager.php +++ b/src/Service/EntryCommentManager.php @@ -112,7 +112,7 @@ public function canUserEditComment(EntryComment $comment, User $user): bool return $entryCommentHost === $userHost || $userHost === $magazineHost || $comment->magazine->userIsModerator($user); } - public function edit(EntryComment $comment, EntryCommentDto $dto): EntryComment + public function edit(EntryComment $comment, EntryCommentDto $dto, ?User $editedByUser = null): EntryComment { Assert::same($comment->entry->getId(), $dto->entry->getId()); @@ -145,7 +145,7 @@ public function edit(EntryComment $comment, EntryCommentDto $dto): EntryComment $this->bus->dispatch(new DeleteImageMessage($oldImage->getId())); } - $this->dispatcher->dispatch(new EntryCommentEditedEvent($comment)); + $this->dispatcher->dispatch(new EntryCommentEditedEvent($comment, $editedByUser)); return $comment; } diff --git a/src/Service/EntryManager.php b/src/Service/EntryManager.php index 8658322aa..8798bc063 100644 --- a/src/Service/EntryManager.php +++ b/src/Service/EntryManager.php @@ -179,7 +179,7 @@ public function canUserEditEntry(Entry $entry, User $user): bool return $entryHost === $userHost || $userHost === $magazineHost || $entry->magazine->userIsModerator($user); } - public function edit(Entry $entry, EntryDto $dto): Entry + public function edit(Entry $entry, EntryDto $dto, User $editedBy): Entry { Assert::same($entry->magazine->getId(), $dto->magazine->getId()); @@ -219,7 +219,7 @@ public function edit(Entry $entry, EntryDto $dto): Entry $this->bus->dispatch(new DeleteImageMessage($oldImage->getId())); } - $this->dispatcher->dispatch(new EntryEditedEvent($entry)); + $this->dispatcher->dispatch(new EntryEditedEvent($entry, $editedBy)); return $entry; } diff --git a/src/Service/MagazineManager.php b/src/Service/MagazineManager.php index e45a4bc0e..82539d9da 100644 --- a/src/Service/MagazineManager.php +++ b/src/Service/MagazineManager.php @@ -19,6 +19,7 @@ use App\Event\Magazine\MagazineModeratorAddedEvent; use App\Event\Magazine\MagazineModeratorRemovedEvent; use App\Event\Magazine\MagazineSubscribedEvent; +use App\Event\Magazine\MagazineUpdatedEvent; use App\Exception\UserCannotBeBanned; use App\Factory\MagazineFactory; use App\Message\DeleteImageMessage; @@ -133,7 +134,7 @@ public function subscribe(Magazine $magazine, User $user, $createRequest = true) $this->dispatcher->dispatch(new MagazineSubscribedEvent($magazine, $user)); } - public function edit(Magazine $magazine, MagazineDto $dto): Magazine + public function edit(Magazine $magazine, MagazineDto $dto, User $editedBy): Magazine { Assert::same($magazine->name, $dto->name); @@ -145,6 +146,8 @@ public function edit(Magazine $magazine, MagazineDto $dto): Magazine $this->entityManager->flush(); + $this->dispatcher->dispatch(new MagazineUpdatedEvent($magazine, $editedBy)); + return $magazine; } diff --git a/src/Service/PostCommentManager.php b/src/Service/PostCommentManager.php index 6ff0df963..517728256 100644 --- a/src/Service/PostCommentManager.php +++ b/src/Service/PostCommentManager.php @@ -120,7 +120,7 @@ public function canUserEditPostComment(PostComment $postComment, User $user): bo /** * @throws \Exception */ - public function edit(PostComment $comment, PostCommentDto $dto): PostComment + public function edit(PostComment $comment, PostCommentDto $dto, ?User $editedBy = null): PostComment { Assert::same($comment->post->getId(), $dto->post->getId()); @@ -153,7 +153,7 @@ public function edit(PostComment $comment, PostCommentDto $dto): PostComment $this->bus->dispatch(new DeleteImageMessage($oldImage->getId())); } - $this->dispatcher->dispatch(new PostCommentEditedEvent($comment)); + $this->dispatcher->dispatch(new PostCommentEditedEvent($comment, $editedBy)); return $comment; } diff --git a/src/Service/PostManager.php b/src/Service/PostManager.php index 81b7e2957..a30898921 100644 --- a/src/Service/PostManager.php +++ b/src/Service/PostManager.php @@ -131,7 +131,7 @@ public function canUserEditPost(Post $post, User $user): bool return $postHost === $userHost || $userHost === $magazineHost || $post->magazine->userIsModerator($user); } - public function edit(Post $post, PostDto $dto): Post + public function edit(Post $post, PostDto $dto, ?User $editedBy = null): Post { Assert::same($post->magazine->getId(), $dto->magazine->getId()); @@ -163,7 +163,7 @@ public function edit(Post $post, PostDto $dto): Post $this->bus->dispatch(new DeleteImageMessage($oldImage->getId())); } - $this->dispatcher->dispatch(new PostEditedEvent($post)); + $this->dispatcher->dispatch(new PostEditedEvent($post, $editedBy)); return $post; } diff --git a/src/Service/UserManager.php b/src/Service/UserManager.php index 0581aca0b..8853248b3 100644 --- a/src/Service/UserManager.php +++ b/src/Service/UserManager.php @@ -9,6 +9,7 @@ use App\Entity\User; use App\Entity\UserFollowRequest; use App\Event\User\UserBlockEvent; +use App\Event\User\UserEditedEvent; use App\Event\User\UserFollowEvent; use App\Exception\UserCannotBeBanned; use App\Factory\UserFactory; @@ -231,6 +232,8 @@ public function edit(User $user, UserDto $dto): User $this->bus->dispatch(new UserUpdatedMessage($user->getId())); } + $this->dispatcher->dispatch(new UserEditedEvent($user->getId())); + return $user; } @@ -459,28 +462,28 @@ public function getAllInboxesOfInteractions(User $user): array SELECT res.ap_inbox_url FROM entry INNER JOIN magazine m on entry.magazine_id = m.id AND m.ap_id IS NULL INNER JOIN magazine_subscription ms ON m.id = ms.magazine_id - INNER JOIN public.user res ON ms.user_id = res.id AND res.ap_id IS NOT NULL + INNER JOIN public.user res ON ms.user_id = res.id AND res.ap_id IS NOT NULL WHERE entry.user_id = :id UNION DISTINCT -- local magazines the user posted thread comments to -> their subscribers SELECT res.ap_inbox_url FROM entry_comment INNER JOIN magazine m on entry_comment.magazine_id = m.id AND m.ap_id IS NULL INNER JOIN magazine_subscription ms ON m.id = ms.magazine_id - INNER JOIN public.user res ON ms.user_id = res.id AND res.ap_id IS NOT NULL + INNER JOIN public.user res ON ms.user_id = res.id AND res.ap_id IS NOT NULL WHERE entry_comment.user_id = :id UNION DISTINCT -- local magazines the user posted microblogs to -> their subscribers SELECT res.ap_inbox_url FROM post INNER JOIN magazine m on post.magazine_id = m.id AND m.ap_id IS NULL INNER JOIN magazine_subscription ms ON m.id = ms.magazine_id - INNER JOIN public.user res ON ms.user_id = res.id AND res.ap_id IS NOT NULL + INNER JOIN public.user res ON ms.user_id = res.id AND res.ap_id IS NOT NULL WHERE post.user_id = :id UNION DISTINCT -- local magazine the user posted microblog comments to -> their subscribers SELECT res.ap_inbox_url FROM post_comment INNER JOIN magazine m on post_comment.magazine_id = m.id AND m.ap_id IS NULL INNER JOIN magazine_subscription ms ON m.id = ms.magazine_id - INNER JOIN public.user res ON ms.user_id = res.id AND res.ap_id IS NOT NULL + INNER JOIN public.user res ON ms.user_id = res.id AND res.ap_id IS NOT NULL WHERE post_comment.user_id = :id UNION DISTINCT -- author of micro blogs the user commented on @@ -506,25 +509,25 @@ public function getAllInboxesOfInteractions(User $user): array INNER JOIN entry_comment ec2 ON ec1.parent_id=ec2.id INNER JOIN public.user res ON ec2.user_id=res.id AND res.ap_id IS NOT NULL WHERE ec1.user_id = :id - + UNION DISTINCT -- author of thread the user voted on SELECT res.ap_inbox_url FROM entry_vote INNER JOIN public.user res on entry_vote.author_id = res.id AND res.ap_id IS NOT NULL WHERE entry_vote.user_id = :id - UNION DISTINCT + UNION DISTINCT -- magazine of thread the user voted on SELECT res.ap_inbox_url FROM entry_vote INNER JOIN entry ON entry_vote.entry_id = entry.id INNER JOIN magazine res ON entry.magazine_id=res.id AND res.ap_id IS NOT NULL WHERE entry_vote.user_id = :id - + UNION DISTINCT -- author of thread comment the user voted on SELECT res.ap_inbox_url FROM entry_comment_vote INNER JOIN public.user res on entry_comment_vote.author_id = res.id AND res.ap_id IS NOT NULL WHERE entry_comment_vote.user_id = :id - UNION DISTINCT + UNION DISTINCT -- magazine of thread comment the user voted on SELECT res.ap_inbox_url FROM entry_comment_vote INNER JOIN entry_comment ON entry_comment_vote.comment_id = entry_comment.id @@ -535,50 +538,50 @@ public function getAllInboxesOfInteractions(User $user): array SELECT res.ap_inbox_url FROM post_vote INNER JOIN public.user res on post_vote.author_id = res.id AND res.ap_id IS NOT NULL WHERE post_vote.user_id = :id - UNION DISTINCT + UNION DISTINCT -- magazine of microblog the user voted on SELECT res.ap_inbox_url FROM post_vote INNER JOIN entry ON post_vote.post_id = entry.id INNER JOIN magazine res ON entry.magazine_id=res.id AND res.ap_id IS NOT NULL WHERE post_vote.user_id = :id - + UNION DISTINCT -- author of microblog comment the user voted on SELECT res.ap_inbox_url FROM post_comment_vote INNER JOIN public.user res on post_comment_vote.author_id = res.id AND res.ap_id IS NOT NULL WHERE post_comment_vote.user_id = :id - UNION DISTINCT + UNION DISTINCT -- magazine of microblog comment the user voted on SELECT res.ap_inbox_url FROM post_comment_vote INNER JOIN post_comment ON post_comment_vote.comment_id = post_comment.id INNER JOIN magazine res ON post_comment.magazine_id=res.id AND res.ap_id IS NOT NULL WHERE post_comment_vote.user_id = :id - - + + UNION DISTINCT -- voters of threads of the user SELECT res.ap_inbox_url FROM entry_vote INNER JOIN public.user res on entry_vote.user_id = res.id AND res.ap_id IS NOT NULL WHERE entry_vote.author_id = :id - + UNION DISTINCT -- voters of thread comments of the user SELECT res.ap_inbox_url FROM entry_comment_vote - INNER JOIN public.user res on entry_comment_vote.user_id = res.id AND res.ap_id IS NOT NULL + INNER JOIN public.user res on entry_comment_vote.user_id = res.id AND res.ap_id IS NOT NULL WHERE entry_comment_vote.author_id = :id - + UNION DISTINCT -- voters of microblog of the user SELECT res.ap_inbox_url FROM post_vote INNER JOIN public.user res on post_vote.user_id = res.id AND res.ap_id IS NOT NULL WHERE post_vote.author_id = :id - + UNION DISTINCT -- voters of microblog comments of the user SELECT res.ap_inbox_url FROM post_comment_vote INNER JOIN public.user res on post_comment_vote.user_id = res.id WHERE post_comment_vote.author_id = :id AND res.ap_id IS NOT NULL - + UNION DISTINCT -- favourites of entries of the user SELECT res.ap_inbox_url FROM favourite f @@ -603,7 +606,7 @@ public function getAllInboxesOfInteractions(User $user): array INNER JOIN public.user res on f.user_id = res.id AND res.ap_id IS NOT NULL INNER JOIN post_comment pc ON f.entry_id = pc.id WHERE pc.user_id = :id - + UNION DISTINCT -- favourites of the user: entries SELECT res.ap_inbox_url FROM favourite f @@ -628,7 +631,7 @@ public function getAllInboxesOfInteractions(User $user): array INNER JOIN public.user u on f.user_id = u.id AND f.user_id = :id INNER JOIN post_comment pc ON f.post_comment_id = pc.id INNER JOIN public.user res ON pc.user_id=res.id AND res.ap_id IS NOT NULL - + UNION DISTINCT -- favourites of the user: entries -> their magazine SELECT res.ap_inbox_url FROM favourite f @@ -675,28 +678,28 @@ public function getAllInboxesOfInteractions(User $user): array public function getAllImageFilePathsOfUser(User $user): array { $sql = ' - SELECT i1.file_path FROM entry e INNER JOIN image i1 ON e.image_id = i1.id + SELECT i1.file_path FROM entry e INNER JOIN image i1 ON e.image_id = i1.id WHERE e.user_id = :userId AND i1.file_path IS NOT NULL AND NOT EXISTS (SELECT id FROM entry e2 WHERE e2.user_id <> :userId AND e2.image_id = i1.id) AND NOT EXISTS (SELECT id FROM post p2 WHERE p2.user_id <> :userId AND p2.image_id = i1.id) AND NOT EXISTS (SELECT id FROM entry_comment ec2 WHERE ec2.user_id <> :userId AND ec2.image_id = i1.id) AND NOT EXISTS (SELECT id FROM post_comment pc2 WHERE pc2.user_id <> :userId AND pc2.image_id = i1.id) - UNION DISTINCT - SELECT i2.file_path FROM post p INNER JOIN image i2 ON p.image_id = i2.id + UNION DISTINCT + SELECT i2.file_path FROM post p INNER JOIN image i2 ON p.image_id = i2.id WHERE p.user_id = :userId AND i2.file_path IS NOT NULL AND NOT EXISTS (SELECT id FROM entry e2 WHERE e2.user_id <> :userId AND e2.image_id = i2.id) AND NOT EXISTS (SELECT id FROM post p2 WHERE p2.user_id <> :userId AND p2.image_id = i2.id) AND NOT EXISTS (SELECT id FROM entry_comment ec2 WHERE ec2.user_id <> :userId AND ec2.image_id = i2.id) AND NOT EXISTS (SELECT id FROM post_comment pc2 WHERE pc2.user_id <> :userId AND pc2.image_id = i2.id) - UNION DISTINCT - SELECT i3.file_path FROM entry_comment ec INNER JOIN image i3 ON ec.image_id = i3.id + UNION DISTINCT + SELECT i3.file_path FROM entry_comment ec INNER JOIN image i3 ON ec.image_id = i3.id WHERE ec.user_id = :userId AND i3.file_path IS NOT NULL AND NOT EXISTS (SELECT id FROM entry e2 WHERE e2.user_id <> :userId AND e2.image_id = i3.id) AND NOT EXISTS (SELECT id FROM post p2 WHERE p2.user_id <> :userId AND p2.image_id = i3.id) AND NOT EXISTS (SELECT id FROM entry_comment ec2 WHERE ec2.user_id <> :userId AND ec2.image_id = i3.id) AND NOT EXISTS (SELECT id FROM post_comment pc2 WHERE pc2.user_id <> :userId AND pc2.image_id = i3.id) - UNION DISTINCT - SELECT i4.file_path FROM post_comment pc INNER JOIN image i4 ON pc.image_id = i4.id + UNION DISTINCT + SELECT i4.file_path FROM post_comment pc INNER JOIN image i4 ON pc.image_id = i4.id WHERE pc.user_id = :userId AND i4.file_path IS NOT NULL AND NOT EXISTS (SELECT id FROM entry e2 WHERE e2.user_id <> :userId AND e2.image_id = i4.id) AND NOT EXISTS (SELECT id FROM post p2 WHERE p2.user_id <> :userId AND p2.image_id = i4.id) From 328857684fc4735cc1819566e93028aba4d22caf Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 1 Aug 2024 08:03:23 -0500 Subject: [PATCH 144/335] docs(contributor): contributors readme action update (#966) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d592578ab..180a0b0bd 100644 --- a/README.md +++ b/README.md @@ -120,17 +120,17 @@ For developers: - - simonrcodrington + + weblate
        - Simon Codrington + Weblate (bot)
        - - weblate + + simonrcodrington
        - Weblate (bot) + Simon Codrington
        From 4e5d59b73bbd7c2382ab1ab9a742939bb4d472d3 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Fri, 2 Aug 2024 08:07:07 +0000 Subject: [PATCH 145/335] Add a leaf icon next to users and magazines if they are new (#969) --- assets/styles/components/_magazine.scss | 4 ++++ assets/styles/components/_sidebar.scss | 4 ++++ assets/styles/components/_user.scss | 4 ++++ src/Entity/Traits/CreatedAtTrait.php | 9 +++++++++ templates/components/magazine_box.html.twig | 4 ++++ templates/components/magazine_inline.html.twig | 4 ++++ templates/components/user_box.html.twig | 8 ++++++++ templates/components/user_inline.html.twig | 4 ++++ templates/entry/_form_image.html.twig | 8 ++++++++ templates/magazine/_moderators_sidebar.html.twig | 15 +++------------ templates/user/_user_popover.html.twig | 4 ++++ translations/messages.en.yaml | 4 +++- 12 files changed, 59 insertions(+), 13 deletions(-) diff --git a/assets/styles/components/_magazine.scss b/assets/styles/components/_magazine.scss index f47b13803..bbdf91a07 100644 --- a/assets/styles/components/_magazine.scss +++ b/assets/styles/components/_magazine.scss @@ -337,3 +337,7 @@ td { } + +.new-magazine-icon { + color: green; +} diff --git a/assets/styles/components/_sidebar.scss b/assets/styles/components/_sidebar.scss index 75d013eae..4c6408cfa 100644 --- a/assets/styles/components/_sidebar.scss +++ b/assets/styles/components/_sidebar.scss @@ -190,6 +190,10 @@ padding: 0; } + li.moderator-item { + height: calc(30px + 1rem); + } + ul li { align-items: center; border-top: var(--kbin-meta-border); diff --git a/assets/styles/components/_user.scss b/assets/styles/components/_user.scss index 4671eda29..42e05f252 100644 --- a/assets/styles/components/_user.scss +++ b/assets/styles/components/_user.scss @@ -333,3 +333,7 @@ td .user__actions { margin-bottom: 1rem; } } + +.new-user-icon { + color: green; +} diff --git a/src/Entity/Traits/CreatedAtTrait.php b/src/Entity/Traits/CreatedAtTrait.php index c5e5ee9cd..38ac38e4e 100644 --- a/src/Entity/Traits/CreatedAtTrait.php +++ b/src/Entity/Traits/CreatedAtTrait.php @@ -8,6 +8,8 @@ trait CreatedAtTrait { + public const NEW_FOR_DAYS = 30; + #[ORM\Column(type: 'datetimetz_immutable')] public \DateTimeImmutable $createdAt; @@ -20,4 +22,11 @@ public function getCreatedAt(): \DateTimeImmutable { return $this->createdAt; } + + public function isNew(): bool + { + $days = self::NEW_FOR_DAYS; + + return $this->getCreatedAt() >= new \DateTime("now -$days days"); + } } diff --git a/templates/components/magazine_box.html.twig b/templates/components/magazine_box.html.twig index 311e9319e..ac426b1bc 100644 --- a/templates/components/magazine_box.html.twig +++ b/templates/components/magazine_box.html.twig @@ -28,6 +28,10 @@ title="{{ 'magazine_posting_restricted_to_mods_warning'|trans }}" aria-describedby="{{ 'magazine_posting_restricted_to_mods_warning'|trans }}"> {% endif %} + {% if magazine.isNew() %} + {% set days = constant('App\\Entity\\Magazine::NEW_FOR_DAYS') %} + + {% endif %}

        {{ ('@'~magazine.name)|username(true) }} {% if magazine.isAdult %}18+{% endif %} diff --git a/templates/components/magazine_inline.html.twig b/templates/components/magazine_inline.html.twig index 31bf3e3e5..6dcf04c0f 100644 --- a/templates/components/magazine_inline.html.twig +++ b/templates/components/magazine_inline.html.twig @@ -27,4 +27,8 @@ aria-describedby="{{ 'magazine_posting_restricted_to_mods_warning'|trans }}"> {% endif %} {% endif %} + {% if magazine.isNew() %} + {% set days = constant('App\\Entity\\Magazine::NEW_FOR_DAYS') %} + + {% endif %} diff --git a/templates/components/user_box.html.twig b/templates/components/user_box.html.twig index 5d614819f..c74c2b07b 100644 --- a/templates/components/user_box.html.twig +++ b/templates/components/user_box.html.twig @@ -38,6 +38,10 @@ {% if (user.type) == "Service" %} {{ 'user_badge_bot'|trans }} {% endif %} + {% if user.isNew() %} + {% set days = constant('App\\Entity\\User::NEW_FOR_DAYS') %} + + {% endif %} {% if user.admin() %} {{ 'user_badge_admin'|trans }} @@ -52,6 +56,10 @@ {% if (user.type) == "Service" %} {{ 'user_badge_bot'|trans }} {% endif %} + {% if user.isNew() %} + {% set days = constant('App\\Entity\\User::NEW_FOR_DAYS') %} + + {% endif %} {% if user.admin() %} {{ 'user_badge_admin'|trans }} diff --git a/templates/components/user_inline.html.twig b/templates/components/user_inline.html.twig index 79a1e1a52..c9def975b 100644 --- a/templates/components/user_inline.html.twig +++ b/templates/components/user_inline.html.twig @@ -11,4 +11,8 @@ alt="{{ user.username ~' '~ 'avatar'|trans|lower }}"> {% endif %} {{ user.apPreferredUsername ?? user.username|username -}} + {% if user.isNew() %} + {% set days = constant('App\\Entity\\User::NEW_FOR_DAYS') %} + + {% endif %} diff --git a/templates/entry/_form_image.html.twig b/templates/entry/_form_image.html.twig index 6c18f211f..6e35de486 100644 --- a/templates/entry/_form_image.html.twig +++ b/templates/entry/_form_image.html.twig @@ -12,6 +12,14 @@ 'data-action' : 'input-length#updateDisplay', 'data-input-length-max-value' : constant('App\\Entity\\Entry::MAX_TITLE_LENGTH') }}) }} + {{ component('editor_toolbar', {id: 'entry_image_body'}) }} + {{ form_row(form.body, { + label: false, attr: { + placeholder: 'body', + 'data-controller': 'rich-textarea input-length autogrow', + 'data-action' : 'input-length#updateDisplay', + 'data-input-length-max-value' : constant('App\\Entity\\Entry::MAX_BODY_LENGTH') + }}) }} {{ form_row(form.magazine, {label: false}) }} {{ form_row(form.tags, {label: 'tags'}) }} {{ form_row(form.badges, {label: 'badges'}) }} diff --git a/templates/magazine/_moderators_sidebar.html.twig b/templates/magazine/_moderators_sidebar.html.twig index 81a235ce4..44ef670e8 100644 --- a/templates/magazine/_moderators_sidebar.html.twig +++ b/templates/magazine/_moderators_sidebar.html.twig @@ -1,5 +1,5 @@

        -

        +

        {{ 'moderators'|trans }} {% if app.user and magazine.apId is same as null and app.user.visibility is same as 'visible' %} @@ -12,17 +12,8 @@

        diff --git a/templates/user/_user_popover.html.twig b/templates/user/_user_popover.html.twig index 18275ac58..c7900044b 100644 --- a/templates/user/_user_popover.html.twig +++ b/templates/user/_user_popover.html.twig @@ -11,6 +11,10 @@

        {{ user.username|username }} + {% if user.isNew() %} + {% set days = constant('App\\Entity\\User::NEW_FOR_DAYS') %} + + {% endif %}

        diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml index 293166cc3..a8ea3523d 100644 --- a/translations/messages.en.yaml +++ b/translations/messages.en.yaml @@ -876,4 +876,6 @@ version: Version last_successful_deliver: Last successful deliver last_successful_receive: Last successful receive last_failed_contact: Last failed contact -magazine_posting_restricted_to_mods: Restrict thread creation to moderators \ No newline at end of file +magazine_posting_restricted_to_mods: Restrict thread creation to moderators +new_user_description: This user is new (active for less than %days% days) +new_magazine_description: This magazine is new (active for less than %days% days) From e3a2b1250b07d00e9330c4522c3f77fc30f36d0d Mon Sep 17 00:00:00 2001 From: debounced <35878315+nobodyatroot@users.noreply.github.com> Date: Fri, 2 Aug 2024 05:17:25 -0500 Subject: [PATCH 146/335] Update composer + npm packages and Symfony 7.1 upgrade (#970) Co-authored-by: BentiGorlich --- composer.json | 211 ++++----- composer.lock | 1099 +++++++++++++++++++++++++-------------------- package-lock.json | 948 +++++++++++++++++++------------------- symfony.lock | 4 +- 4 files changed, 1174 insertions(+), 1088 deletions(-) diff --git a/composer.json b/composer.json index a2cb96aa1..f44a0eb81 100644 --- a/composer.json +++ b/composer.json @@ -17,116 +17,117 @@ "ext-intl": "*", "ext-openssl": "*", "ext-redis": "*", - "aws/aws-sdk-php": "^3.250", - "babdev/pagerfanta-bundle": "^v4.0.0", - "debril/rss-atom-bundle": "^5.1", - "doctrine/annotations": "^2.0", - "doctrine/doctrine-bundle": "^2.2", - "doctrine/doctrine-migrations-bundle": "^3.0", - "doctrine/orm": "^2.8", - "embed/embed": "^4.4", - "endroid/qr-code": "^4.8", - "friendsofsymfony/jsrouting-bundle": "^3.2", - "furqansiddiqui/bip39-mnemonic-php": "^0.1.4", + "aws/aws-sdk-php": "^3.317.0", + "babdev/pagerfanta-bundle": "^v4.4.0", + "debril/rss-atom-bundle": "^5.2.0", + "doctrine/annotations": "^2.0.1", + "doctrine/doctrine-bundle": "^2.12.0", + "doctrine/doctrine-migrations-bundle": "^3.3.1", + "doctrine/orm": "^2.19.6", + "embed/embed": "^4.4.12", + "endroid/qr-code": "^4.8.5", + "friendsofsymfony/jsrouting-bundle": "^3.5.0", + "furqansiddiqui/bip39-mnemonic-php": "^0.1.7", "gmostafa/php-graphql-client": "^1.13", - "gumlet/php-image-resize": "2.0.*", - "knplabs/knp-time-bundle": "^2.2.0", - "knpuniversity/oauth2-client-bundle": "^2.10", - "kornrunner/blurhash": "^1.2", - "laminas/laminas-diactoros": "^2.5", - "landrok/activitypub": "^0.5.6", - "league/commonmark": "^2.4", - "league/flysystem-aws-s3-v3": "^3.10", - "league/html-to-markdown": "^5.1", - "league/oauth2-facebook": "^2.2", - "league/oauth2-github": "^3.0", - "league/oauth2-google": "^4.0", + "gumlet/php-image-resize": "^2.0.4", + "knplabs/knp-time-bundle": "^2.4.0", + "knpuniversity/oauth2-client-bundle": "^2.18.1", + "kornrunner/blurhash": "^1.2.2", + "laminas/laminas-diactoros": "^2.26.0", + "landrok/activitypub": "^0.5.8", + "league/commonmark": "^2.5.1", + "league/flysystem-aws-s3-v3": "^3.28.0", + "league/html-to-markdown": "^5.1.1", + "league/oauth2-facebook": "^2.2.0", + "league/oauth2-github": "^3.1.0", + "league/oauth2-google": "^4.0.1", "league/oauth2-server-bundle": "^0.8.0", - "liip/imagine-bundle": "^2.0", - "meteo-concept/hcaptcha-bundle": "^4.0.1", - "minishlink/web-push": "^9.0", - "neitanod/forceutf8": "^2.0", - "nelmio/api-doc-bundle": "^4.11", - "nelmio/cors-bundle": "^2.1", - "nyholm/psr7": "^1.8", - "omines/antispam-bundle": "^0.1.6", - "oneup/flysystem-bundle": "^4.4", - "pagerfanta/core": "^3.1", - "pagerfanta/doctrine-collections-adapter": "^4.0", - "pagerfanta/doctrine-dbal-adapter": "^4.0", - "pagerfanta/doctrine-orm-adapter": "^4.0", - "pagerfanta/twig": "^4.0", - "phpdocumentor/reflection-docblock": "^5.2", - "phpstan/phpdoc-parser": "^0.4.9", - "predis/predis": "^2.1", + "liip/imagine-bundle": "^2.13.1", + "meteo-concept/hcaptcha-bundle": "^4.1.0", + "minishlink/web-push": "^9.0.1", + "neitanod/forceutf8": "^2.0.4", + "nelmio/api-doc-bundle": "^4.29.0", + "nelmio/cors-bundle": "^2.5.0", + "nyholm/psr7": "^1.8.1", + "omines/antispam-bundle": "^0.1.8", + "oneup/flysystem-bundle": "^4.12.2", + "pagerfanta/core": "^3.8.0", + "pagerfanta/doctrine-collections-adapter": "^4.6.0", + "pagerfanta/doctrine-dbal-adapter": "^4.6.0", + "pagerfanta/doctrine-orm-adapter": "^4.6.0", + "pagerfanta/twig": "^4.6.0", + "phpdocumentor/reflection-docblock": "^5.4.1", + "phpstan/phpdoc-parser": "^1.29.1", + "predis/predis": "^2.2.2", "privacyportal/oauth2-privacyportal": "^0.1.1", - "scheb/2fa-backup-code": "^7.2.0", - "scheb/2fa-bundle": "^7.2.0", - "scheb/2fa-totp": "^7.2.0", - "scienta/doctrine-json-functions": "^5.2", - "stevenmaguire/oauth2-keycloak": "*", - "symfony/amqp-messenger": "7.0.*", - "symfony/asset": "7.0.*", - "symfony/cache": "7.0.*", - "symfony/console": "7.0.*", - "symfony/css-selector": "7.0.*", - "symfony/doctrine-messenger": "7.0.*", - "symfony/dotenv": "7.0.*", - "symfony/expression-language": "7.0.*", - "symfony/flex": "^2.2.2", - "symfony/form": "7.0.*", - "symfony/framework-bundle": "7.0.*", - "symfony/http-client": "7.0.*", - "symfony/lock": "7.0.*", - "symfony/mailer": "7.0.*", - "symfony/mailgun-mailer": "7.0.*", + "scheb/2fa-backup-code": "^7.5.0", + "scheb/2fa-bundle": "^7.5.0", + "scheb/2fa-totp": "^7.5.0", + "scienta/doctrine-json-functions": "^5.5.0", + "stevenmaguire/oauth2-keycloak": "^5.1.0", + "symfony/amqp-messenger": "7.1.*", + "symfony/asset": "7.1.*", + "symfony/cache": "7.1.*", + "symfony/console": "7.1.*", + "symfony/css-selector": "7.1.*", + "symfony/doctrine-messenger": "7.1.*", + "symfony/dotenv": "7.1.*", + "symfony/expression-language": "7.1.*", + "symfony/flex": "^2.4.5", + "symfony/form": "7.1.*", + "symfony/framework-bundle": "7.1.*", + "symfony/http-client": "7.1.*", + "symfony/lock": "7.1.*", + "symfony/mailer": "7.1.*", + "symfony/mailgun-mailer": "7.1.*", "symfony/mercure-bundle": "0.3.*", - "symfony/messenger": "7.0.*", - "symfony/mime": "7.0.*", - "symfony/monolog-bundle": "^3.6", - "symfony/property-access": "7.0.*", - "symfony/property-info": "7.0.*", - "symfony/rate-limiter": "7.0.*", - "symfony/redis-messenger": "7.0.*", - "symfony/runtime": "7.0.*", - "symfony/scheduler": "7.0.*", - "symfony/security-bundle": "7.0.*", - "symfony/serializer": "7.0.*", - "symfony/string": "7.0.*", - "symfony/translation": "7.0.*", - "symfony/twig-bundle": "7.0.*", - "symfony/uid": "7.0.*", - "symfony/ux-autocomplete": "^2.7", - "symfony/ux-chartjs": "^2.7", - "symfony/ux-twig-component": "^2.7", - "symfony/validator": "7.0.*", - "symfony/webpack-encore-bundle": "^2.0", - "symfony/workflow": "7.0.*", - "symfony/yaml": "7.0.*", - "symfonycasts/reset-password-bundle": "^1.13", - "symfonycasts/verify-email-bundle": "^1.2", - "thenetworg/oauth2-azure": "^2.2", - "twig/cssinliner-extra": "^3.7", - "twig/extra-bundle": "^3.7", - "twig/html-extra": "^3.5", - "twig/intl-extra": "^3.2", - "twig/twig": "^2.12 || ^3.0", - "webmozart/assert": "^1.9", - "wohali/oauth2-discord-new": "^1.2" + "symfony/messenger": "7.1.*", + "symfony/mime": "7.1.*", + "symfony/monolog-bundle": "^3.10.0", + "symfony/property-access": "7.1.*", + "symfony/property-info": "7.1.*", + "symfony/rate-limiter": "7.1.*", + "symfony/redis-messenger": "7.1.*", + "symfony/runtime": "7.1.*", + "symfony/scheduler": "7.1.*", + "symfony/security-bundle": "7.1.*", + "symfony/serializer": "7.1.*", + "symfony/string": "7.1.*", + "symfony/translation": "7.1.*", + "symfony/type-info": "7.1.*", + "symfony/twig-bundle": "7.1.*", + "symfony/uid": "7.1.*", + "symfony/ux-autocomplete": "^2.18.0", + "symfony/ux-chartjs": "^2.18.0", + "symfony/ux-twig-component": "^2.18.1", + "symfony/validator": "7.1.*", + "symfony/webpack-encore-bundle": "^2.1.1", + "symfony/workflow": "7.1.*", + "symfony/yaml": "7.1.*", + "symfonycasts/reset-password-bundle": "^1.22.0", + "symfonycasts/verify-email-bundle": "^1.17.0", + "thenetworg/oauth2-azure": "^2.2.2", + "twig/cssinliner-extra": "^3.10.0", + "twig/extra-bundle": "^3.10.0", + "twig/html-extra": "^3.10.0", + "twig/intl-extra": "^3.10.0", + "twig/twig": "^3.10.3", + "webmozart/assert": "^1.11.0", + "wohali/oauth2-discord-new": "^1.2.1" }, "require-dev": { - "dama/doctrine-test-bundle": "^8.0.2", - "doctrine/doctrine-fixtures-bundle": "^3.4", - "fakerphp/faker": "^1.23", - "justinrainbow/json-schema": "^5.2", - "phpstan/phpstan": "^1.9", - "phpunit/phpunit": "^10.0", - "symfony/browser-kit": "7.0.*", - "symfony/debug-bundle": "7.0.*", - "symfony/maker-bundle": "^1.27", - "symfony/phpunit-bridge": "^7.0.6", - "symfony/stopwatch": "^7.0.3", - "symfony/web-profiler-bundle": "^7.0.4" + "dama/doctrine-test-bundle": "^8.2.0", + "doctrine/doctrine-fixtures-bundle": "^3.6.1", + "fakerphp/faker": "^1.23.1", + "justinrainbow/json-schema": "^5.3.0", + "phpstan/phpstan": "^1.11.9", + "phpunit/phpunit": "^10.5.29", + "symfony/browser-kit": "7.1.*", + "symfony/debug-bundle": "7.1.*", + "symfony/maker-bundle": "1.60.0", + "symfony/phpunit-bridge": "7.1.*", + "symfony/stopwatch": "7.1.*", + "symfony/web-profiler-bundle": "7.1.*" }, "replace": { "symfony/polyfill-ctype": "*", @@ -162,7 +163,7 @@ "extra": { "symfony": { "allow-contrib": false, - "require": "7.0.*" + "require": "7.1.*" } }, "scripts": { diff --git a/composer.lock b/composer.lock index f58749553..7e9d47a14 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "837c9eee2acfd4e1cf5235a95b61c417", + "content-hash": "f4d9c1ae81fa4d1f914079c0ac2c53d1", "packages": [ { "name": "aws/aws-crt-php", @@ -62,16 +62,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.316.8", + "version": "3.317.0", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "9aff2e655c3f0139f5abe20195ee235b19fff603" + "reference": "6d46c8e00c22f66349b8a509bd2c5ced72cceff2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/9aff2e655c3f0139f5abe20195ee235b19fff603", - "reference": "9aff2e655c3f0139f5abe20195ee235b19fff603", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/6d46c8e00c22f66349b8a509bd2c5ced72cceff2", + "reference": "6d46c8e00c22f66349b8a509bd2c5ced72cceff2", "shasum": "" }, "require": { @@ -79,9 +79,9 @@ "ext-json": "*", "ext-pcre": "*", "ext-simplexml": "*", - "guzzlehttp/guzzle": "^6.5.8 || ^7.4.5 <7.9.0", + "guzzlehttp/guzzle": "^6.5.8 || ^7.4.5", "guzzlehttp/promises": "^1.4.0 || ^2.0", - "guzzlehttp/psr7": "^1.9.1 || ^2.4.5 <2.7.0", + "guzzlehttp/psr7": "^1.9.1 || ^2.4.5", "mtdowling/jmespath.php": "^2.6", "php": ">=7.2.5", "psr/http-message": "^1.0 || ^2.0" @@ -151,9 +151,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.316.8" + "source": "https://github.com/aws/aws-sdk-php/tree/3.317.0" }, - "time": "2024-07-25T19:29:46+00:00" + "time": "2024-08-01T18:12:34+00:00" }, { "name": "babdev/pagerfanta-bundle", @@ -2677,22 +2677,22 @@ }, { "name": "guzzlehttp/guzzle", - "version": "7.8.2", + "version": "7.9.2", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "f4152d9eb85c445fe1f992001d1748e8bec070d2" + "reference": "d281ed313b989f213357e3be1a179f02196ac99b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f4152d9eb85c445fe1f992001d1748e8bec070d2", - "reference": "f4152d9eb85c445fe1f992001d1748e8bec070d2", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/d281ed313b989f213357e3be1a179f02196ac99b", + "reference": "d281ed313b989f213357e3be1a179f02196ac99b", "shasum": "" }, "require": { "ext-json": "*", "guzzlehttp/promises": "^1.5.3 || ^2.0.3", - "guzzlehttp/psr7": "^1.9.1 || ^2.6.3", + "guzzlehttp/psr7": "^2.7.0", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", "symfony/deprecation-contracts": "^2.2 || ^3.0" @@ -2783,7 +2783,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.8.2" + "source": "https://github.com/guzzle/guzzle/tree/7.9.2" }, "funding": [ { @@ -2799,7 +2799,7 @@ "type": "tidelift" } ], - "time": "2024-07-18T11:12:18+00:00" + "time": "2024-07-24T11:22:20+00:00" }, { "name": "guzzlehttp/promises", @@ -2886,16 +2886,16 @@ }, { "name": "guzzlehttp/psr7", - "version": "2.6.3", + "version": "2.7.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "6de29867b18790c0d2c846af4c13a24cc3ad56f3" + "reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/6de29867b18790c0d2c846af4c13a24cc3ad56f3", - "reference": "6de29867b18790c0d2c846af4c13a24cc3ad56f3", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/a70f5c95fb43bc83f07c9c948baa0dc1829bf201", + "reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201", "shasum": "" }, "require": { @@ -2982,7 +2982,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.6.3" + "source": "https://github.com/guzzle/psr7/tree/2.7.0" }, "funding": [ { @@ -2998,7 +2998,7 @@ "type": "tidelift" } ], - "time": "2024-07-18T09:59:12+00:00" + "time": "2024-07-18T11:15:46+00:00" }, { "name": "imagine/imagine", @@ -4856,16 +4856,16 @@ }, { "name": "minishlink/web-push", - "version": "v9.0.0", + "version": "v9.0.1", "source": { "type": "git", "url": "https://github.com/web-push-libs/web-push-php.git", - "reference": "469b4d923d680a14e79af809907dea0fee73f581" + "reference": "761adf330860aa6cd05e5f6945c427c76a07c420" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/web-push-libs/web-push-php/zipball/469b4d923d680a14e79af809907dea0fee73f581", - "reference": "469b4d923d680a14e79af809907dea0fee73f581", + "url": "https://api.github.com/repos/web-push-libs/web-push-php/zipball/761adf330860aa6cd05e5f6945c427c76a07c420", + "reference": "761adf330860aa6cd05e5f6945c427c76a07c420", "shasum": "" }, "require": { @@ -4915,9 +4915,9 @@ ], "support": { "issues": "https://github.com/web-push-libs/web-push-php/issues", - "source": "https://github.com/web-push-libs/web-push-php/tree/v9.0.0" + "source": "https://github.com/web-push-libs/web-push-php/tree/v9.0.1" }, - "time": "2024-07-08T14:49:43+00:00" + "time": "2024-07-30T12:24:56+00:00" }, { "name": "ml/iri", @@ -5233,61 +5233,70 @@ }, { "name": "nelmio/api-doc-bundle", - "version": "v4.23.1", + "version": "v4.29.0", "source": { "type": "git", "url": "https://github.com/nelmio/NelmioApiDocBundle.git", - "reference": "a15b5923602c669007ea53a1a87991e9e147daab" + "reference": "c9523906023e61351f03dbab8d077173f5ec4883" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nelmio/NelmioApiDocBundle/zipball/a15b5923602c669007ea53a1a87991e9e147daab", - "reference": "a15b5923602c669007ea53a1a87991e9e147daab", + "url": "https://api.github.com/repos/nelmio/NelmioApiDocBundle/zipball/c9523906023e61351f03dbab8d077173f5ec4883", + "reference": "c9523906023e61351f03dbab8d077173f5ec4883", "shasum": "" }, "require": { "ext-json": "*", - "php": ">=7.2", - "phpdocumentor/reflection-docblock": "^3.1|^4.0|^5.0", - "psr/cache": "^1.0|^2.0|^3.0", - "psr/container": "^1.0|^2.0", - "psr/log": "^1.0|^2.0|^3.0", - "symfony/config": "^5.4|^6.0|^7.0", - "symfony/console": "^5.4|^6.0|^7.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/framework-bundle": "^5.4.24|^6.0|^7.0", - "symfony/http-foundation": "^5.4|^6.0|^7.0", - "symfony/http-kernel": "^5.4|^6.0|^7.0", - "symfony/options-resolver": "^5.4|^6.0|^7.0", - "symfony/property-info": "^5.4|^6.0|^7.0", - "symfony/routing": "^5.4|^6.0|^7.0", - "zircote/swagger-php": "^4.2.15" + "php": ">=7.4", + "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0", + "phpdocumentor/type-resolver": "^1.8.2", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "psr/container": "^1.0 || ^2.0", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "symfony/config": "^5.4 || ^6.4 || ^7.0", + "symfony/console": "^5.4 || ^6.4 || ^7.0", + "symfony/dependency-injection": "^5.4 || ^6.4 || ^7.0", + "symfony/deprecation-contracts": "^2.1 || ^3", + "symfony/framework-bundle": "^5.4.24 || ^6.4 || ^7.0", + "symfony/http-foundation": "^5.4 || ^6.4 || ^7.0", + "symfony/http-kernel": "^5.4 || ^6.4 || ^7.0", + "symfony/options-resolver": "^5.4 || ^6.4 || ^7.0", + "symfony/property-info": "^5.4.10 || ^6.4 || ^7.0", + "symfony/routing": "^5.4 || ^6.4 || ^7.0", + "zircote/swagger-php": "^4.6.1" + }, + "conflict": { + "zircote/swagger-php": "4.8.7" }, "require-dev": { - "api-platform/core": "^2.7.0|^3", + "api-platform/core": "^2.7.0 || ^3", "composer/package-versions-deprecated": "1.11.99.1", "doctrine/annotations": "^2.0", - "friendsofsymfony/rest-bundle": "^2.8|^3.0", - "jms/serializer": "^1.14|^3.0", - "jms/serializer-bundle": "^2.3|^3.0|^4.0|^5.0", - "phpunit/phpunit": "^8.5|^9.6", - "sensio/framework-extra-bundle": "^5.4|^6.0", - "symfony/asset": "^5.4|^6.0|^7.0", - "symfony/browser-kit": "^5.4|^6.0|^7.0", - "symfony/cache": "^5.4|^6.0|^7.0", - "symfony/dom-crawler": "^5.4|^6.0|^7.0", - "symfony/expression-language": "^5.4|^6.0|^7.0", - "symfony/form": "^5.4|^6.0|^7.0", + "friendsofphp/php-cs-fixer": "^3.52", + "friendsofsymfony/rest-bundle": "^2.8 || ^3.0", + "jms/serializer": "^1.14 || ^3.0", + "jms/serializer-bundle": "^2.3 || ^3.0 || ^4.0 || ^5.0", + "phpstan/phpstan": "^1.10", + "phpstan/phpstan-phpunit": "^1.3", + "phpstan/phpstan-strict-rules": "^1.5", + "phpstan/phpstan-symfony": "^1.3", + "phpunit/phpunit": "^9.6 || ^10.5", + "symfony/asset": "^5.4 || ^6.4 || ^7.0", + "symfony/browser-kit": "^5.4 || ^6.4 || ^7.0", + "symfony/cache": "^5.4 || ^6.4 || ^7.0", + "symfony/dom-crawler": "^5.4 || ^6.4 || ^7.0", + "symfony/expression-language": "^5.4 || ^6.4 || ^7.0", + "symfony/form": "^5.4 || ^6.4 || ^7.0", "symfony/phpunit-bridge": "^6.4", - "symfony/property-access": "^5.4|^6.0|^7.0", - "symfony/security-csrf": "^5.4|^6.0|^7.0", - "symfony/serializer": "^5.4|^6.0|^7.0", - "symfony/stopwatch": "^5.4|^6.0|^7.0", - "symfony/templating": "^5.4|^6.0|^7.0", - "symfony/twig-bundle": "^5.4|^6.0|^7.0", - "symfony/validator": "^5.4|^6.0|^7.0", - "willdurand/hateoas-bundle": "^1.0|^2.0" + "symfony/property-access": "^5.4 || ^6.4 || ^7.0", + "symfony/security-csrf": "^5.4 || ^6.4 || ^7.0", + "symfony/serializer": "^5.4 || ^6.4 || ^7.0", + "symfony/stopwatch": "^5.4 || ^6.4 || ^7.0", + "symfony/templating": "^5.4 || ^6.4 || ^7.0", + "symfony/twig-bundle": "^5.4 || ^6.4 || ^7.0", + "symfony/uid": "^5.4 || ^6.4 || ^7.0", + "symfony/validator": "^5.4 || ^6.4 || ^7.0", + "willdurand/hateoas-bundle": "^1.0 || ^2.0" }, "suggest": { "api-platform/core": "For using an API oriented framework.", @@ -5325,7 +5334,7 @@ "homepage": "https://github.com/nelmio/NelmioApiDocBundle/contributors" } ], - "description": "Generates documentation for your REST API from annotations", + "description": "Generates documentation for your REST API from annotations and attributes", "keywords": [ "api", "doc", @@ -5334,9 +5343,15 @@ ], "support": { "issues": "https://github.com/nelmio/NelmioApiDocBundle/issues", - "source": "https://github.com/nelmio/NelmioApiDocBundle/tree/v4.23.1" + "source": "https://github.com/nelmio/NelmioApiDocBundle/tree/v4.29.0" }, - "time": "2024-03-07T09:21:17+00:00" + "funding": [ + { + "url": "https://github.com/DjordyKoert", + "type": "github" + } + ], + "time": "2024-07-22T08:40:00+00:00" }, { "name": "nelmio/cors-bundle", @@ -6261,28 +6276,35 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.3.0", + "version": "5.4.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + "reference": "9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c", + "reference": "9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c", "shasum": "" }, "require": { + "doctrine/deprecations": "^1.1", "ext-filter": "*", - "php": "^7.2 || ^8.0", + "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", + "phpdocumentor/type-resolver": "^1.7", + "phpstan/phpdoc-parser": "^1.7", "webmozart/assert": "^1.9.1" }, "require-dev": { - "mockery/mockery": "~1.3.2", - "psalm/phar": "^4.8" + "mockery/mockery": "~1.3.5", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-webmozart-assert": "^1.2", + "phpunit/phpunit": "^9.5", + "vimeo/psalm": "^5.13" }, "type": "library", "extra": { @@ -6306,36 +6328,39 @@ }, { "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" + "email": "opensource@ijaap.nl" } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.4.1" }, - "time": "2021-10-19T17:43:47+00:00" + "time": "2024-05-21T05:55:05+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.6.2", + "version": "1.8.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d" + "reference": "153ae662783729388a584b4361f2545e4d841e3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/48f445a408c131e38cab1c235aa6d2bb7a0bb20d", - "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/153ae662783729388a584b4361f2545e4d841e3c", + "reference": "153ae662783729388a584b4361f2545e4d841e3c", "shasum": "" }, "require": { - "php": "^7.4 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" + "doctrine/deprecations": "^1.0", + "php": "^7.3 || ^8.0", + "phpdocumentor/reflection-common": "^2.0", + "phpstan/phpdoc-parser": "^1.13" }, "require-dev": { "ext-tokenizer": "*", + "phpbench/phpbench": "^1.2", "phpstan/extension-installer": "^1.1", "phpstan/phpstan": "^1.8", "phpstan/phpstan-phpunit": "^1.1", @@ -6367,9 +6392,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.2" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.8.2" }, - "time": "2022-10-14T12:47:21+00:00" + "time": "2024-02-23T11:10:43+00:00" }, { "name": "phpseclib/phpseclib", @@ -6483,36 +6508,33 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "0.4.14", + "version": "1.29.1", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "cf4fc7d2aeca6910fba061901ffd7d107ccfdbcc" + "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/cf4fc7d2aeca6910fba061901ffd7d107ccfdbcc", - "reference": "cf4fc7d2aeca6910fba061901ffd7d107ccfdbcc", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fcaefacf2d5c417e928405b71b400d4ce10daaf4", + "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": "^7.2 || ^8.0" }, "require-dev": { - "phing/phing": "^2.16.3", + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^4.15", "php-parallel-lint/php-parallel-lint": "^1.2", "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^0.12.60", - "phpstan/phpstan-strict-rules": "^0.12.5", - "phpunit/phpunit": "^7.5.20", + "phpstan/phpstan": "^1.5", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5", "symfony/process": "^5.2" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.4-dev" - } - }, "autoload": { "psr-4": { "PHPStan\\PhpDocParser\\": [ @@ -6527,9 +6549,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/0.4.14" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.1" }, - "time": "2021-03-19T10:54:14+00:00" + "time": "2024-05-31T08:52:43+00:00" }, { "name": "predis/predis", @@ -7728,16 +7750,16 @@ }, { "name": "symfony/amqp-messenger", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/amqp-messenger.git", - "reference": "4bccb7fa731bf5787f49c51e122e8728ec0f1eef" + "reference": "60dd57f1083ce81471ad08090e02fa584a612af3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/amqp-messenger/zipball/4bccb7fa731bf5787f49c51e122e8728ec0f1eef", - "reference": "4bccb7fa731bf5787f49c51e122e8728ec0f1eef", + "url": "https://api.github.com/repos/symfony/amqp-messenger/zipball/60dd57f1083ce81471ad08090e02fa584a612af3", + "reference": "60dd57f1083ce81471ad08090e02fa584a612af3", "shasum": "" }, "require": { @@ -7777,7 +7799,7 @@ "description": "Symfony AMQP extension Messenger Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/amqp-messenger/tree/v7.0.8" + "source": "https://github.com/symfony/amqp-messenger/tree/v7.1.1" }, "funding": [ { @@ -7793,20 +7815,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { "name": "symfony/asset", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/asset.git", - "reference": "0f106714bb8d857560edd2ada7f387d2f437c830" + "reference": "8970de4a0cedd34e097c0f5c502a614780b9ca43" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/asset/zipball/0f106714bb8d857560edd2ada7f387d2f437c830", - "reference": "0f106714bb8d857560edd2ada7f387d2f437c830", + "url": "https://api.github.com/repos/symfony/asset/zipball/8970de4a0cedd34e097c0f5c502a614780b9ca43", + "reference": "8970de4a0cedd34e097c0f5c502a614780b9ca43", "shasum": "" }, "require": { @@ -7846,7 +7868,7 @@ "description": "Manages URL generation and versioning of web assets such as CSS stylesheets, JavaScript files and image files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/asset/tree/v7.0.8" + "source": "https://github.com/symfony/asset/tree/v7.1.1" }, "funding": [ { @@ -7862,20 +7884,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { "name": "symfony/cache", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "0ee03f2aa8bb920f7041678f5f46f60998e3a7a8" + "reference": "8ac37acee794372f9732fe8a61a8221f6762148e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/0ee03f2aa8bb920f7041678f5f46f60998e3a7a8", - "reference": "0ee03f2aa8bb920f7041678f5f46f60998e3a7a8", + "url": "https://api.github.com/repos/symfony/cache/zipball/8ac37acee794372f9732fe8a61a8221f6762148e", + "reference": "8ac37acee794372f9732fe8a61a8221f6762148e", "shasum": "" }, "require": { @@ -7883,6 +7905,7 @@ "psr/cache": "^2.0|^3.0", "psr/log": "^1.1|^2|^3", "symfony/cache-contracts": "^2.5|^3", + "symfony/deprecation-contracts": "^2.5|^3.0", "symfony/service-contracts": "^2.5|^3", "symfony/var-exporter": "^6.4|^7.0" }, @@ -7942,7 +7965,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v7.0.10" + "source": "https://github.com/symfony/cache/tree/v7.1.3" }, "funding": [ { @@ -7958,7 +7981,7 @@ "type": "tidelift" } ], - "time": "2024-07-17T06:06:58+00:00" + "time": "2024-07-17T06:10:24+00:00" }, { "name": "symfony/cache-contracts", @@ -8038,16 +8061,16 @@ }, { "name": "symfony/clock", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/clock.git", - "reference": "817e27b87908632f647f8684a603b70ec89b75e4" + "reference": "3dfc8b084853586de51dd1441c6242c76a28cbe7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/clock/zipball/817e27b87908632f647f8684a603b70ec89b75e4", - "reference": "817e27b87908632f647f8684a603b70ec89b75e4", + "url": "https://api.github.com/repos/symfony/clock/zipball/3dfc8b084853586de51dd1441c6242c76a28cbe7", + "reference": "3dfc8b084853586de51dd1441c6242c76a28cbe7", "shasum": "" }, "require": { @@ -8092,7 +8115,7 @@ "time" ], "support": { - "source": "https://github.com/symfony/clock/tree/v7.0.8" + "source": "https://github.com/symfony/clock/tree/v7.1.1" }, "funding": [ { @@ -8108,26 +8131,26 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { "name": "symfony/config", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "f8a8fb0c2d0a188a00a2dd5af8a4eb070641ec60" + "reference": "2210fc99fa42a259eb6c89d1f724ce0c4d62d5d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/f8a8fb0c2d0a188a00a2dd5af8a4eb070641ec60", - "reference": "f8a8fb0c2d0a188a00a2dd5af8a4eb070641ec60", + "url": "https://api.github.com/repos/symfony/config/zipball/2210fc99fa42a259eb6c89d1f724ce0c4d62d5d2", + "reference": "2210fc99fa42a259eb6c89d1f724ce0c4d62d5d2", "shasum": "" }, "require": { "php": ">=8.2", "symfony/deprecation-contracts": "^2.5|^3", - "symfony/filesystem": "^6.4|^7.0", + "symfony/filesystem": "^7.1", "symfony/polyfill-ctype": "~1.8" }, "conflict": { @@ -8167,7 +8190,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v7.0.8" + "source": "https://github.com/symfony/config/tree/v7.1.1" }, "funding": [ { @@ -8183,20 +8206,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { "name": "symfony/console", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "f381ef0bc6675a29796d7055088a7193a9e6edff" + "reference": "cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/f381ef0bc6675a29796d7055088a7193a9e6edff", - "reference": "f381ef0bc6675a29796d7055088a7193a9e6edff", + "url": "https://api.github.com/repos/symfony/console/zipball/cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9", + "reference": "cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9", "shasum": "" }, "require": { @@ -8260,7 +8283,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.0.10" + "source": "https://github.com/symfony/console/tree/v7.1.3" }, "funding": [ { @@ -8276,20 +8299,20 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:31:22+00:00" + "time": "2024-07-26T12:41:01+00:00" }, { "name": "symfony/css-selector", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "63b9f8c9b3c28c43ad06764c67fe092af2576d17" + "reference": "1c7cee86c6f812896af54434f8ce29c8d94f9ff4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/63b9f8c9b3c28c43ad06764c67fe092af2576d17", - "reference": "63b9f8c9b3c28c43ad06764c67fe092af2576d17", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/1c7cee86c6f812896af54434f8ce29c8d94f9ff4", + "reference": "1c7cee86c6f812896af54434f8ce29c8d94f9ff4", "shasum": "" }, "require": { @@ -8325,7 +8348,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v7.0.8" + "source": "https://github.com/symfony/css-selector/tree/v7.1.1" }, "funding": [ { @@ -8341,27 +8364,27 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { "name": "symfony/dependency-injection", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "01dcf140b25aa351383f2d3829acbcedd9784ee9" + "reference": "8126f0be4ff984e4db0140e60917900a53facb49" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/01dcf140b25aa351383f2d3829acbcedd9784ee9", - "reference": "01dcf140b25aa351383f2d3829acbcedd9784ee9", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/8126f0be4ff984e4db0140e60917900a53facb49", + "reference": "8126f0be4ff984e4db0140e60917900a53facb49", "shasum": "" }, "require": { "php": ">=8.2", "psr/container": "^1.1|^2.0", "symfony/deprecation-contracts": "^2.5|^3", - "symfony/service-contracts": "^3.3", + "symfony/service-contracts": "^3.5", "symfony/var-exporter": "^6.4|^7.0" }, "conflict": { @@ -8405,7 +8428,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v7.0.10" + "source": "https://github.com/symfony/dependency-injection/tree/v7.1.3" }, "funding": [ { @@ -8421,7 +8444,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T07:32:22+00:00" + "time": "2024-07-26T07:35:39+00:00" }, { "name": "symfony/deprecation-contracts", @@ -8492,22 +8515,23 @@ }, { "name": "symfony/doctrine-bridge", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "462b41a82739386c1b5c6304c572ce1790c57dd1" + "reference": "b526822483124b62ff3cda14237418408f444e4d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/462b41a82739386c1b5c6304c572ce1790c57dd1", - "reference": "462b41a82739386c1b5c6304c572ce1790c57dd1", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/b526822483124b62ff3cda14237418408f444e4d", + "reference": "b526822483124b62ff3cda14237418408f444e4d", "shasum": "" }, "require": { "doctrine/event-manager": "^2", "doctrine/persistence": "^3.1", "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", "symfony/service-contracts": "^2.5|^3" @@ -8548,6 +8572,7 @@ "symfony/security-core": "^6.4|^7.0", "symfony/stopwatch": "^6.4|^7.0", "symfony/translation": "^6.4|^7.0", + "symfony/type-info": "^7.1", "symfony/uid": "^6.4|^7.0", "symfony/validator": "^6.4|^7.0", "symfony/var-dumper": "^6.4|^7.0" @@ -8578,7 +8603,7 @@ "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/doctrine-bridge/tree/v7.0.10" + "source": "https://github.com/symfony/doctrine-bridge/tree/v7.1.3" }, "funding": [ { @@ -8594,20 +8619,20 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:31:22+00:00" + "time": "2024-07-26T12:41:01+00:00" }, { "name": "symfony/doctrine-messenger", - "version": "v7.0.9", + "version": "v7.1.2", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-messenger.git", - "reference": "2f47c6f2eb35b6a409aef6eeadec093c62e63ea4" + "reference": "64e2195442df86a7a0c85a77162d0247601e9da9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-messenger/zipball/2f47c6f2eb35b6a409aef6eeadec093c62e63ea4", - "reference": "2f47c6f2eb35b6a409aef6eeadec093c62e63ea4", + "url": "https://api.github.com/repos/symfony/doctrine-messenger/zipball/64e2195442df86a7a0c85a77162d0247601e9da9", + "reference": "64e2195442df86a7a0c85a77162d0247601e9da9", "shasum": "" }, "require": { @@ -8650,7 +8675,7 @@ "description": "Symfony Doctrine Messenger Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/doctrine-messenger/tree/v7.0.9" + "source": "https://github.com/symfony/doctrine-messenger/tree/v7.1.2" }, "funding": [ { @@ -8666,20 +8691,20 @@ "type": "tidelift" } ], - "time": "2024-06-20T15:46:52+00:00" + "time": "2024-06-20T15:47:37+00:00" }, { "name": "symfony/dotenv", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/dotenv.git", - "reference": "3a0c9ce95ed71a1ad297604742a46085e808c7a3" + "reference": "a26be30fd61678dab694a18a85084cea7673bbf3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dotenv/zipball/3a0c9ce95ed71a1ad297604742a46085e808c7a3", - "reference": "3a0c9ce95ed71a1ad297604742a46085e808c7a3", + "url": "https://api.github.com/repos/symfony/dotenv/zipball/a26be30fd61678dab694a18a85084cea7673bbf3", + "reference": "a26be30fd61678dab694a18a85084cea7673bbf3", "shasum": "" }, "require": { @@ -8724,7 +8749,7 @@ "environment" ], "support": { - "source": "https://github.com/symfony/dotenv/tree/v7.0.10" + "source": "https://github.com/symfony/dotenv/tree/v7.1.3" }, "funding": [ { @@ -8740,20 +8765,20 @@ "type": "tidelift" } ], - "time": "2024-07-09T18:35:37+00:00" + "time": "2024-07-09T19:36:07+00:00" }, { "name": "symfony/error-handler", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "fd1cc26512b502c8fe8dfe90b67a9d8228bbafa2" + "reference": "432bb369952795c61ca1def65e078c4a80dad13c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/fd1cc26512b502c8fe8dfe90b67a9d8228bbafa2", - "reference": "fd1cc26512b502c8fe8dfe90b67a9d8228bbafa2", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/432bb369952795c61ca1def65e078c4a80dad13c", + "reference": "432bb369952795c61ca1def65e078c4a80dad13c", "shasum": "" }, "require": { @@ -8799,7 +8824,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v7.0.10" + "source": "https://github.com/symfony/error-handler/tree/v7.1.3" }, "funding": [ { @@ -8815,20 +8840,20 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:31:22+00:00" + "time": "2024-07-26T13:02:51+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "5c30c7fc4ccf847e4dd8a18b6158cb1f77702550" + "reference": "9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/5c30c7fc4ccf847e4dd8a18b6158cb1f77702550", - "reference": "5c30c7fc4ccf847e4dd8a18b6158cb1f77702550", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7", + "reference": "9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7", "shasum": "" }, "require": { @@ -8879,7 +8904,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.0.8" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.1.1" }, "funding": [ { @@ -8895,7 +8920,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -8975,21 +9000,22 @@ }, { "name": "symfony/expression-language", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/expression-language.git", - "reference": "8e64bd4eb4c4dd180fc7de9c72011c49ebbdc822" + "reference": "463cb95f80c14136175f4e03f7f6199b01c6b8b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/expression-language/zipball/8e64bd4eb4c4dd180fc7de9c72011c49ebbdc822", - "reference": "8e64bd4eb4c4dd180fc7de9c72011c49ebbdc822", + "url": "https://api.github.com/repos/symfony/expression-language/zipball/463cb95f80c14136175f4e03f7f6199b01c6b8b4", + "reference": "463cb95f80c14136175f4e03f7f6199b01c6b8b4", "shasum": "" }, "require": { "php": ">=8.2", "symfony/cache": "^6.4|^7.0", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/service-contracts": "^2.5|^3" }, "type": "library", @@ -9018,7 +9044,7 @@ "description": "Provides an engine that can compile and evaluate expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/expression-language/tree/v7.0.8" + "source": "https://github.com/symfony/expression-language/tree/v7.1.1" }, "funding": [ { @@ -9034,20 +9060,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { "name": "symfony/filesystem", - "version": "v7.0.9", + "version": "v7.1.2", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "f6b35b0de74a2577196114eef957f2414b5599d5" + "reference": "92a91985250c251de9b947a14bb2c9390b1a562c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/f6b35b0de74a2577196114eef957f2414b5599d5", - "reference": "f6b35b0de74a2577196114eef957f2414b5599d5", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/92a91985250c251de9b947a14bb2c9390b1a562c", + "reference": "92a91985250c251de9b947a14bb2c9390b1a562c", "shasum": "" }, "require": { @@ -9084,7 +9110,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.0.9" + "source": "https://github.com/symfony/filesystem/tree/v7.1.2" }, "funding": [ { @@ -9100,20 +9126,20 @@ "type": "tidelift" } ], - "time": "2024-06-28T09:58:46+00:00" + "time": "2024-06-28T10:03:55+00:00" }, { "name": "symfony/finder", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "25b267662f297a8479bf6cf88fdc92e4b16cf24c" + "reference": "717c6329886f32dc65e27461f80f2a465412fdca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/25b267662f297a8479bf6cf88fdc92e4b16cf24c", - "reference": "25b267662f297a8479bf6cf88fdc92e4b16cf24c", + "url": "https://api.github.com/repos/symfony/finder/zipball/717c6329886f32dc65e27461f80f2a465412fdca", + "reference": "717c6329886f32dc65e27461f80f2a465412fdca", "shasum": "" }, "require": { @@ -9148,7 +9174,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.0.10" + "source": "https://github.com/symfony/finder/tree/v7.1.3" }, "funding": [ { @@ -9164,7 +9190,7 @@ "type": "tidelift" } ], - "time": "2024-07-24T07:06:56+00:00" + "time": "2024-07-24T07:08:44+00:00" }, { "name": "symfony/flex", @@ -9233,20 +9259,21 @@ }, { "name": "symfony/form", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/form.git", - "reference": "2713488dbb290a6c0d043766b0e9d0b02672c935" + "reference": "11df2e2e142161824eb341e96cbb3c56c3bb57dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/form/zipball/2713488dbb290a6c0d043766b0e9d0b02672c935", - "reference": "2713488dbb290a6c0d043766b0e9d0b02672c935", + "url": "https://api.github.com/repos/symfony/form/zipball/11df2e2e142161824eb341e96cbb3c56c3bb57dc", + "reference": "11df2e2e142161824eb341e96cbb3c56c3bb57dc", "shasum": "" }, "require": { "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/event-dispatcher": "^6.4|^7.0", "symfony/options-resolver": "^6.4|^7.0", "symfony/polyfill-ctype": "~1.8", @@ -9309,7 +9336,7 @@ "description": "Allows to easily create, process and reuse HTML forms", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/form/tree/v7.0.10" + "source": "https://github.com/symfony/form/tree/v7.1.3" }, "funding": [ { @@ -9325,20 +9352,20 @@ "type": "tidelift" } ], - "time": "2024-07-19T08:29:37+00:00" + "time": "2024-07-19T08:30:01+00:00" }, { "name": "symfony/framework-bundle", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/framework-bundle.git", - "reference": "07a37173aace78420ccaf5eceaf4a79c7dfab375" + "reference": "a32ec544bd501eb4619eb977860ad3076ee55061" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/07a37173aace78420ccaf5eceaf4a79c7dfab375", - "reference": "07a37173aace78420ccaf5eceaf4a79c7dfab375", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/a32ec544bd501eb4619eb977860ad3076ee55061", + "reference": "a32ec544bd501eb4619eb977860ad3076ee55061", "shasum": "" }, "require": { @@ -9347,11 +9374,11 @@ "php": ">=8.2", "symfony/cache": "^6.4|^7.0", "symfony/config": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", + "symfony/dependency-injection": "^7.1", "symfony/deprecation-contracts": "^2.5|^3", "symfony/error-handler": "^6.4|^7.0", "symfony/event-dispatcher": "^6.4|^7.0", - "symfony/filesystem": "^6.4|^7.0", + "symfony/filesystem": "^7.1", "symfony/finder": "^6.4|^7.0", "symfony/http-foundation": "^6.4|^7.0", "symfony/http-kernel": "^6.4|^7.0", @@ -9422,6 +9449,7 @@ "symfony/string": "^6.4|^7.0", "symfony/translation": "^6.4|^7.0", "symfony/twig-bundle": "^6.4|^7.0", + "symfony/type-info": "^7.1", "symfony/uid": "^6.4|^7.0", "symfony/validator": "^6.4|^7.0", "symfony/web-link": "^6.4|^7.0", @@ -9455,7 +9483,7 @@ "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/framework-bundle/tree/v7.0.10" + "source": "https://github.com/symfony/framework-bundle/tree/v7.1.3" }, "funding": [ { @@ -9471,25 +9499,26 @@ "type": "tidelift" } ], - "time": "2024-07-26T13:24:26+00:00" + "time": "2024-07-26T13:24:34+00:00" }, { "name": "symfony/http-client", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "3ae495c67ba9c3b504fecd070a6c28b4143088cf" + "reference": "b79858aa7a051ea791b0d50269a234a0b50cb231" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/3ae495c67ba9c3b504fecd070a6c28b4143088cf", - "reference": "3ae495c67ba9c3b504fecd070a6c28b4143088cf", + "url": "https://api.github.com/repos/symfony/http-client/zipball/b79858aa7a051ea791b0d50269a234a0b50cb231", + "reference": "b79858aa7a051ea791b0d50269a234a0b50cb231", "shasum": "" }, "require": { "php": ">=8.2", "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/http-client-contracts": "^3.4.1", "symfony/service-contracts": "^2.5|^3" }, @@ -9516,6 +9545,7 @@ "symfony/http-kernel": "^6.4|^7.0", "symfony/messenger": "^6.4|^7.0", "symfony/process": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0", "symfony/stopwatch": "^6.4|^7.0" }, "type": "library", @@ -9547,7 +9577,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v7.0.10" + "source": "https://github.com/symfony/http-client/tree/v7.1.3" }, "funding": [ { @@ -9563,7 +9593,7 @@ "type": "tidelift" } ], - "time": "2024-07-17T06:06:58+00:00" + "time": "2024-07-17T06:10:24+00:00" }, { "name": "symfony/http-client-contracts", @@ -9645,16 +9675,16 @@ }, { "name": "symfony/http-foundation", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "e7bb762b114f2f1e2610322e025709df08211f1d" + "reference": "f602d5c17d1fa02f8019ace2687d9d136b7f4a1a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e7bb762b114f2f1e2610322e025709df08211f1d", - "reference": "e7bb762b114f2f1e2610322e025709df08211f1d", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/f602d5c17d1fa02f8019ace2687d9d136b7f4a1a", + "reference": "f602d5c17d1fa02f8019ace2687d9d136b7f4a1a", "shasum": "" }, "require": { @@ -9702,7 +9732,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.0.10" + "source": "https://github.com/symfony/http-foundation/tree/v7.1.3" }, "funding": [ { @@ -9718,25 +9748,26 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:37:16+00:00" + "time": "2024-07-26T12:41:01+00:00" }, { "name": "symfony/http-kernel", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "31cb30794c8bb944a4e1f6bb6aef95840b3345a7" + "reference": "db9702f3a04cc471ec8c70e881825db26ac5f186" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/31cb30794c8bb944a4e1f6bb6aef95840b3345a7", - "reference": "31cb30794c8bb944a4e1f6bb6aef95840b3345a7", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/db9702f3a04cc471ec8c70e881825db26ac5f186", + "reference": "db9702f3a04cc471ec8c70e881825db26ac5f186", "shasum": "" }, "require": { "php": ">=8.2", "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/error-handler": "^6.4|^7.0", "symfony/event-dispatcher": "^6.4|^7.0", "symfony/http-foundation": "^6.4|^7.0", @@ -9777,9 +9808,9 @@ "symfony/finder": "^6.4|^7.0", "symfony/http-client-contracts": "^2.5|^3", "symfony/process": "^6.4|^7.0", - "symfony/property-access": "^6.4|^7.0", + "symfony/property-access": "^7.1", "symfony/routing": "^6.4|^7.0", - "symfony/serializer": "^6.4.4|^7.0.4", + "symfony/serializer": "^7.1", "symfony/stopwatch": "^6.4|^7.0", "symfony/translation": "^6.4|^7.0", "symfony/translation-contracts": "^2.5|^3", @@ -9815,7 +9846,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v7.0.10" + "source": "https://github.com/symfony/http-kernel/tree/v7.1.3" }, "funding": [ { @@ -9831,28 +9862,31 @@ "type": "tidelift" } ], - "time": "2024-07-26T14:56:00+00:00" + "time": "2024-07-26T14:58:15+00:00" }, { "name": "symfony/intl", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/intl.git", - "reference": "4e4ffbfa65fae8bebb8e53712b3e493c85204612" + "reference": "66c1ecda092b1130ada2cf5f59dacfd5b6e9c99c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/intl/zipball/4e4ffbfa65fae8bebb8e53712b3e493c85204612", - "reference": "4e4ffbfa65fae8bebb8e53712b3e493c85204612", + "url": "https://api.github.com/repos/symfony/intl/zipball/66c1ecda092b1130ada2cf5f59dacfd5b6e9c99c", + "reference": "66c1ecda092b1130ada2cf5f59dacfd5b6e9c99c", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/string": "<7.1" }, "require-dev": { "symfony/filesystem": "^6.4|^7.0", - "symfony/finder": "^6.4|^7.0", "symfony/var-exporter": "^6.4|^7.0" }, "type": "library", @@ -9898,7 +9932,7 @@ "localization" ], "support": { - "source": "https://github.com/symfony/intl/tree/v7.0.8" + "source": "https://github.com/symfony/intl/tree/v7.1.1" }, "funding": [ { @@ -9914,20 +9948,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { "name": "symfony/lock", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/lock.git", - "reference": "665e2f4c14690d4b974ed59313e50efe18e8bce6" + "reference": "1f8c941f1270dee046e09a826bcdd3b2ebada45e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/lock/zipball/665e2f4c14690d4b974ed59313e50efe18e8bce6", - "reference": "665e2f4c14690d4b974ed59313e50efe18e8bce6", + "url": "https://api.github.com/repos/symfony/lock/zipball/1f8c941f1270dee046e09a826bcdd3b2ebada45e", + "reference": "1f8c941f1270dee046e09a826bcdd3b2ebada45e", "shasum": "" }, "require": { @@ -9976,7 +10010,7 @@ "semaphore" ], "support": { - "source": "https://github.com/symfony/lock/tree/v7.0.8" + "source": "https://github.com/symfony/lock/tree/v7.1.1" }, "funding": [ { @@ -9992,20 +10026,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { "name": "symfony/mailer", - "version": "v7.0.9", + "version": "v7.1.2", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "6cf146bc806c6ce8999a91072c1841004c0ecc86" + "reference": "8fcff0af9043c8f8a8e229437cea363e282f9aee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/6cf146bc806c6ce8999a91072c1841004c0ecc86", - "reference": "6cf146bc806c6ce8999a91072c1841004c0ecc86", + "url": "https://api.github.com/repos/symfony/mailer/zipball/8fcff0af9043c8f8a8e229437cea363e282f9aee", + "reference": "8fcff0af9043c8f8a8e229437cea363e282f9aee", "shasum": "" }, "require": { @@ -10056,7 +10090,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v7.0.9" + "source": "https://github.com/symfony/mailer/tree/v7.1.2" }, "funding": [ { @@ -10072,20 +10106,20 @@ "type": "tidelift" } ], - "time": "2024-06-28T07:59:17+00:00" + "time": "2024-06-28T08:00:31+00:00" }, { "name": "symfony/mailgun-mailer", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/mailgun-mailer.git", - "reference": "3dc8e7d6db20d7a25b17f8353d4c26731a633a27" + "reference": "dac02fe68e9306849703025511c56f10701696a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/3dc8e7d6db20d7a25b17f8353d4c26731a633a27", - "reference": "3dc8e7d6db20d7a25b17f8353d4c26731a633a27", + "url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/dac02fe68e9306849703025511c56f10701696a8", + "reference": "dac02fe68e9306849703025511c56f10701696a8", "shasum": "" }, "require": { @@ -10125,7 +10159,7 @@ "description": "Symfony Mailgun Mailer Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailgun-mailer/tree/v7.0.10" + "source": "https://github.com/symfony/mailgun-mailer/tree/v7.1.3" }, "funding": [ { @@ -10141,7 +10175,7 @@ "type": "tidelift" } ], - "time": "2024-07-04T11:17:38+00:00" + "time": "2024-07-04T11:20:59+00:00" }, { "name": "symfony/mercure", @@ -10312,16 +10346,16 @@ }, { "name": "symfony/messenger", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/messenger.git", - "reference": "f3a9d96ac01e46813de63337dddbf9a81c9fad86" + "reference": "604e182a7758ceea35921a8ad5dd492a6e13bae4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/messenger/zipball/f3a9d96ac01e46813de63337dddbf9a81c9fad86", - "reference": "f3a9d96ac01e46813de63337dddbf9a81c9fad86", + "url": "https://api.github.com/repos/symfony/messenger/zipball/604e182a7758ceea35921a8ad5dd492a6e13bae4", + "reference": "604e182a7758ceea35921a8ad5dd492a6e13bae4", "shasum": "" }, "require": { @@ -10378,7 +10412,7 @@ "description": "Helps applications send and receive messages to/from other applications or via message queues", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/messenger/tree/v7.0.10" + "source": "https://github.com/symfony/messenger/tree/v7.1.3" }, "funding": [ { @@ -10394,20 +10428,20 @@ "type": "tidelift" } ], - "time": "2024-07-09T18:35:37+00:00" + "time": "2024-07-09T19:36:07+00:00" }, { "name": "symfony/mime", - "version": "v7.0.9", + "version": "v7.1.2", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "60757ea7d562ae1756c1f430a6f7872156a15f32" + "reference": "26a00b85477e69a4bab63b66c5dce64f18b0cbfc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/60757ea7d562ae1756c1f430a6f7872156a15f32", - "reference": "60757ea7d562ae1756c1f430a6f7872156a15f32", + "url": "https://api.github.com/repos/symfony/mime/zipball/26a00b85477e69a4bab63b66c5dce64f18b0cbfc", + "reference": "26a00b85477e69a4bab63b66c5dce64f18b0cbfc", "shasum": "" }, "require": { @@ -10462,7 +10496,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v7.0.9" + "source": "https://github.com/symfony/mime/tree/v7.1.2" }, "funding": [ { @@ -10478,20 +10512,20 @@ "type": "tidelift" } ], - "time": "2024-06-28T09:58:46+00:00" + "time": "2024-06-28T10:03:55+00:00" }, { "name": "symfony/monolog-bridge", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/monolog-bridge.git", - "reference": "d80b7aeabc539538c6ae8962259ac422632d7796" + "reference": "727be11ae17bb1c5a7f600753b9a1bf0cc0ec3b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/d80b7aeabc539538c6ae8962259ac422632d7796", - "reference": "d80b7aeabc539538c6ae8962259ac422632d7796", + "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/727be11ae17bb1c5a7f600753b9a1bf0cc0ec3b8", + "reference": "727be11ae17bb1c5a7f600753b9a1bf0cc0ec3b8", "shasum": "" }, "require": { @@ -10540,7 +10574,7 @@ "description": "Provides integration for Monolog with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/monolog-bridge/tree/v7.0.8" + "source": "https://github.com/symfony/monolog-bridge/tree/v7.1.1" }, "funding": [ { @@ -10556,7 +10590,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { "name": "symfony/monolog-bundle", @@ -10641,16 +10675,16 @@ }, { "name": "symfony/options-resolver", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "19eecfc6f1b0e4b093db7f4a71eedc91843e711a" + "reference": "47aa818121ed3950acd2b58d1d37d08a94f9bf55" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/19eecfc6f1b0e4b093db7f4a71eedc91843e711a", - "reference": "19eecfc6f1b0e4b093db7f4a71eedc91843e711a", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/47aa818121ed3950acd2b58d1d37d08a94f9bf55", + "reference": "47aa818121ed3950acd2b58d1d37d08a94f9bf55", "shasum": "" }, "require": { @@ -10688,7 +10722,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v7.0.8" + "source": "https://github.com/symfony/options-resolver/tree/v7.1.1" }, "funding": [ { @@ -10704,20 +10738,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { "name": "symfony/password-hasher", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/password-hasher.git", - "reference": "25c66dba8ca72c9636b16e9a4b33d18554969a3f" + "reference": "4ad96eb7cf9e2f8f133ada95f2b8021769061662" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/password-hasher/zipball/25c66dba8ca72c9636b16e9a4b33d18554969a3f", - "reference": "25c66dba8ca72c9636b16e9a4b33d18554969a3f", + "url": "https://api.github.com/repos/symfony/password-hasher/zipball/4ad96eb7cf9e2f8f133ada95f2b8021769061662", + "reference": "4ad96eb7cf9e2f8f133ada95f2b8021769061662", "shasum": "" }, "require": { @@ -10760,7 +10794,7 @@ "password" ], "support": { - "source": "https://github.com/symfony/password-hasher/tree/v7.0.8" + "source": "https://github.com/symfony/password-hasher/tree/v7.1.1" }, "funding": [ { @@ -10776,7 +10810,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { "name": "symfony/polyfill-intl-grapheme", @@ -11498,16 +11532,16 @@ }, { "name": "symfony/process", - "version": "v7.0.8", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "a358943d5a15277fc6001f47541c08b7d815338f" + "reference": "7f2f542c668ad6c313dc4a5e9c3321f733197eca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/a358943d5a15277fc6001f47541c08b7d815338f", - "reference": "a358943d5a15277fc6001f47541c08b7d815338f", + "url": "https://api.github.com/repos/symfony/process/zipball/7f2f542c668ad6c313dc4a5e9c3321f733197eca", + "reference": "7f2f542c668ad6c313dc4a5e9c3321f733197eca", "shasum": "" }, "require": { @@ -11539,7 +11573,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.0.8" + "source": "https://github.com/symfony/process/tree/v7.1.3" }, "funding": [ { @@ -11555,20 +11589,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-07-26T12:44:47+00:00" }, { "name": "symfony/property-access", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "ca11e9661ea88664873dba66412525fe301dd744" + "reference": "74e39e6a6276b8e384f34c6ddbc10a6c9a60193a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/ca11e9661ea88664873dba66412525fe301dd744", - "reference": "ca11e9661ea88664873dba66412525fe301dd744", + "url": "https://api.github.com/repos/symfony/property-access/zipball/74e39e6a6276b8e384f34c6ddbc10a6c9a60193a", + "reference": "74e39e6a6276b8e384f34c6ddbc10a6c9a60193a", "shasum": "" }, "require": { @@ -11615,7 +11649,7 @@ "reflection" ], "support": { - "source": "https://github.com/symfony/property-access/tree/v7.0.8" + "source": "https://github.com/symfony/property-access/tree/v7.1.1" }, "funding": [ { @@ -11631,25 +11665,26 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { "name": "symfony/property-info", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "ee413c259f1af416e306709ef699102afd56c27a" + "reference": "88a279df2db5b7919cac6f35d6a5d1d7147e6a9b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/ee413c259f1af416e306709ef699102afd56c27a", - "reference": "ee413c259f1af416e306709ef699102afd56c27a", + "url": "https://api.github.com/repos/symfony/property-info/zipball/88a279df2db5b7919cac6f35d6a5d1d7147e6a9b", + "reference": "88a279df2db5b7919cac6f35d6a5d1d7147e6a9b", "shasum": "" }, "require": { "php": ">=8.2", - "symfony/string": "^6.4|^7.0" + "symfony/string": "^6.4|^7.0", + "symfony/type-info": "^7.1" }, "conflict": { "phpdocumentor/reflection-docblock": "<5.2", @@ -11698,7 +11733,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v7.0.10" + "source": "https://github.com/symfony/property-info/tree/v7.1.3" }, "funding": [ { @@ -11714,20 +11749,20 @@ "type": "tidelift" } ], - "time": "2024-07-26T07:32:22+00:00" + "time": "2024-07-26T07:36:36+00:00" }, { "name": "symfony/psr-http-message-bridge", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/psr-http-message-bridge.git", - "reference": "d9b90feef625bdaea8bd351c543f9ee020a00c5a" + "reference": "1365d10f5476f74a27cf9c2d1eee70c069019db0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/d9b90feef625bdaea8bd351c543f9ee020a00c5a", - "reference": "d9b90feef625bdaea8bd351c543f9ee020a00c5a", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/1365d10f5476f74a27cf9c2d1eee70c069019db0", + "reference": "1365d10f5476f74a27cf9c2d1eee70c069019db0", "shasum": "" }, "require": { @@ -11781,7 +11816,7 @@ "psr-7" ], "support": { - "source": "https://github.com/symfony/psr-http-message-bridge/tree/v7.0.10" + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v7.1.3" }, "funding": [ { @@ -11797,20 +11832,20 @@ "type": "tidelift" } ], - "time": "2024-07-17T06:06:58+00:00" + "time": "2024-07-17T06:10:24+00:00" }, { "name": "symfony/rate-limiter", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/rate-limiter.git", - "reference": "f3f3d92414ce90c6c20a1c2e3bd5a80321390863" + "reference": "f1fbc60e7fed63f1c77bbf8601170cc80fddd95a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/rate-limiter/zipball/f3f3d92414ce90c6c20a1c2e3bd5a80321390863", - "reference": "f3f3d92414ce90c6c20a1c2e3bd5a80321390863", + "url": "https://api.github.com/repos/symfony/rate-limiter/zipball/f1fbc60e7fed63f1c77bbf8601170cc80fddd95a", + "reference": "f1fbc60e7fed63f1c77bbf8601170cc80fddd95a", "shasum": "" }, "require": { @@ -11851,7 +11886,7 @@ "rate-limiter" ], "support": { - "source": "https://github.com/symfony/rate-limiter/tree/v7.0.8" + "source": "https://github.com/symfony/rate-limiter/tree/v7.1.1" }, "funding": [ { @@ -11867,20 +11902,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { "name": "symfony/redis-messenger", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/redis-messenger.git", - "reference": "c8288d7fd3968a82b9af43bea0cf39d9554c09eb" + "reference": "0e13be260a411afbe14f77df45728a23ffb50e7d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/redis-messenger/zipball/c8288d7fd3968a82b9af43bea0cf39d9554c09eb", - "reference": "c8288d7fd3968a82b9af43bea0cf39d9554c09eb", + "url": "https://api.github.com/repos/symfony/redis-messenger/zipball/0e13be260a411afbe14f77df45728a23ffb50e7d", + "reference": "0e13be260a411afbe14f77df45728a23ffb50e7d", "shasum": "" }, "require": { @@ -11918,7 +11953,7 @@ "description": "Symfony Redis extension Messenger Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/redis-messenger/tree/v7.0.10" + "source": "https://github.com/symfony/redis-messenger/tree/v7.1.3" }, "funding": [ { @@ -11934,20 +11969,20 @@ "type": "tidelift" } ], - "time": "2024-07-17T06:06:58+00:00" + "time": "2024-07-17T06:10:24+00:00" }, { "name": "symfony/routing", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "ed9fe56db2eb080b4fc1ecea9d66277ef6d1fb8a" + "reference": "8a908a3f22d5a1b5d297578c2ceb41b02fa916d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/ed9fe56db2eb080b4fc1ecea9d66277ef6d1fb8a", - "reference": "ed9fe56db2eb080b4fc1ecea9d66277ef6d1fb8a", + "url": "https://api.github.com/repos/symfony/routing/zipball/8a908a3f22d5a1b5d297578c2ceb41b02fa916d0", + "reference": "8a908a3f22d5a1b5d297578c2ceb41b02fa916d0", "shasum": "" }, "require": { @@ -11999,7 +12034,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v7.0.10" + "source": "https://github.com/symfony/routing/tree/v7.1.3" }, "funding": [ { @@ -12015,11 +12050,11 @@ "type": "tidelift" } ], - "time": "2024-07-17T06:06:58+00:00" + "time": "2024-07-17T06:10:24+00:00" }, { "name": "symfony/runtime", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/runtime.git", @@ -12078,7 +12113,7 @@ "runtime" ], "support": { - "source": "https://github.com/symfony/runtime/tree/v7.0.8" + "source": "https://github.com/symfony/runtime/tree/v7.1.1" }, "funding": [ { @@ -12098,16 +12133,16 @@ }, { "name": "symfony/scheduler", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/scheduler.git", - "reference": "91a0c028f2183b111e92e32061bb9db9a9599133" + "reference": "024c63fb700453cb53c2d9f71e6868288b0b6fe9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/scheduler/zipball/91a0c028f2183b111e92e32061bb9db9a9599133", - "reference": "91a0c028f2183b111e92e32061bb9db9a9599133", + "url": "https://api.github.com/repos/symfony/scheduler/zipball/024c63fb700453cb53c2d9f71e6868288b0b6fe9", + "reference": "024c63fb700453cb53c2d9f71e6868288b0b6fe9", "shasum": "" }, "require": { @@ -12158,7 +12193,7 @@ "scheduler" ], "support": { - "source": "https://github.com/symfony/scheduler/tree/v7.0.8" + "source": "https://github.com/symfony/scheduler/tree/v7.1.1" }, "funding": [ { @@ -12174,20 +12209,20 @@ "type": "tidelift" } ], - "time": "2024-06-02T15:49:03+00:00" + "time": "2024-06-02T15:49:12+00:00" }, { "name": "symfony/security-bundle", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/security-bundle.git", - "reference": "c9a134cffcb4ca10bebe22a69f1322b2db3082e1" + "reference": "4f77a89e21c2e700b5fbbf3c1eccd71b9a5d69ad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-bundle/zipball/c9a134cffcb4ca10bebe22a69f1322b2db3082e1", - "reference": "c9a134cffcb4ca10bebe22a69f1322b2db3082e1", + "url": "https://api.github.com/repos/symfony/security-bundle/zipball/4f77a89e21c2e700b5fbbf3c1eccd71b9a5d69ad", + "reference": "4f77a89e21c2e700b5fbbf3c1eccd71b9a5d69ad", "shasum": "" }, "require": { @@ -12203,7 +12238,7 @@ "symfony/password-hasher": "^6.4|^7.0", "symfony/security-core": "^6.4|^7.0", "symfony/security-csrf": "^6.4|^7.0", - "symfony/security-http": "^6.4|^7.0", + "symfony/security-http": "^7.1", "symfony/service-contracts": "^2.5|^3" }, "conflict": { @@ -12236,12 +12271,7 @@ "symfony/validator": "^6.4|^7.0", "symfony/yaml": "^6.4|^7.0", "twig/twig": "^3.0.4", - "web-token/jwt-checker": "^3.1", - "web-token/jwt-signature-algorithm-ecdsa": "^3.1", - "web-token/jwt-signature-algorithm-eddsa": "^3.1", - "web-token/jwt-signature-algorithm-hmac": "^3.1", - "web-token/jwt-signature-algorithm-none": "^3.1", - "web-token/jwt-signature-algorithm-rsa": "^3.1" + "web-token/jwt-library": "^3.3.2|^4.0" }, "type": "symfony-bundle", "autoload": { @@ -12269,7 +12299,7 @@ "description": "Provides a tight integration of the Security component into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-bundle/tree/v7.0.10" + "source": "https://github.com/symfony/security-bundle/tree/v7.1.3" }, "funding": [ { @@ -12285,20 +12315,20 @@ "type": "tidelift" } ], - "time": "2024-07-24T07:06:56+00:00" + "time": "2024-07-26T07:24:20+00:00" }, { "name": "symfony/security-core", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/security-core.git", - "reference": "6048754a72768c43419129d3e1c5b2cf7e349adc" + "reference": "aa4f432586a129017ce0ba34e2b1bfe6babfe8c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-core/zipball/6048754a72768c43419129d3e1c5b2cf7e349adc", - "reference": "6048754a72768c43419129d3e1c5b2cf7e349adc", + "url": "https://api.github.com/repos/symfony/security-core/zipball/aa4f432586a129017ce0ba34e2b1bfe6babfe8c7", + "reference": "aa4f432586a129017ce0ba34e2b1bfe6babfe8c7", "shasum": "" }, "require": { @@ -12308,6 +12338,7 @@ "symfony/service-contracts": "^2.5|^3" }, "conflict": { + "symfony/dependency-injection": "<6.4", "symfony/event-dispatcher": "<6.4", "symfony/http-foundation": "<6.4", "symfony/ldap": "<6.4", @@ -12319,6 +12350,7 @@ "psr/container": "^1.1|^2.0", "psr/log": "^1|^2|^3", "symfony/cache": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", "symfony/event-dispatcher": "^6.4|^7.0", "symfony/expression-language": "^6.4|^7.0", "symfony/http-foundation": "^6.4|^7.0", @@ -12353,7 +12385,7 @@ "description": "Symfony Security Component - Core Library", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-core/tree/v7.0.10" + "source": "https://github.com/symfony/security-core/tree/v7.1.3" }, "funding": [ { @@ -12369,20 +12401,20 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:31:22+00:00" + "time": "2024-07-26T12:41:01+00:00" }, { "name": "symfony/security-csrf", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/security-csrf.git", - "reference": "40543b13b35999316d3f79a18d0d4075f30b8d9b" + "reference": "27cd1bce9d7f3457a152a6ca9790712d6954dd21" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-csrf/zipball/40543b13b35999316d3f79a18d0d4075f30b8d9b", - "reference": "40543b13b35999316d3f79a18d0d4075f30b8d9b", + "url": "https://api.github.com/repos/symfony/security-csrf/zipball/27cd1bce9d7f3457a152a6ca9790712d6954dd21", + "reference": "27cd1bce9d7f3457a152a6ca9790712d6954dd21", "shasum": "" }, "require": { @@ -12421,7 +12453,7 @@ "description": "Symfony Security Component - CSRF Library", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-csrf/tree/v7.0.8" + "source": "https://github.com/symfony/security-csrf/tree/v7.1.1" }, "funding": [ { @@ -12437,24 +12469,25 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { "name": "symfony/security-http", - "version": "v7.0.9", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/security-http.git", - "reference": "828b0ce72c7e178aa56c6694f1ba9593cac531d9" + "reference": "19f07b6530dbb82017c38ee7582b154f5c42b179" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-http/zipball/828b0ce72c7e178aa56c6694f1ba9593cac531d9", - "reference": "828b0ce72c7e178aa56c6694f1ba9593cac531d9", + "url": "https://api.github.com/repos/symfony/security-http/zipball/19f07b6530dbb82017c38ee7582b154f5c42b179", + "reference": "19f07b6530dbb82017c38ee7582b154f5c42b179", "shasum": "" }, "require": { "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/http-foundation": "^6.4|^7.0", "symfony/http-kernel": "^6.4|^7.0", "symfony/polyfill-mbstring": "~1.0", @@ -12474,13 +12507,13 @@ "symfony/cache": "^6.4|^7.0", "symfony/clock": "^6.4|^7.0", "symfony/expression-language": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", "symfony/http-client-contracts": "^3.0", "symfony/rate-limiter": "^6.4|^7.0", "symfony/routing": "^6.4|^7.0", "symfony/security-csrf": "^6.4|^7.0", "symfony/translation": "^6.4|^7.0", - "web-token/jwt-checker": "^3.1", - "web-token/jwt-signature-algorithm-ecdsa": "^3.1" + "web-token/jwt-library": "^3.3.2|^4.0" }, "type": "library", "autoload": { @@ -12508,7 +12541,7 @@ "description": "Symfony Security Component - HTTP Integration", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-http/tree/v7.0.9" + "source": "https://github.com/symfony/security-http/tree/v7.1.3" }, "funding": [ { @@ -12524,24 +12557,25 @@ "type": "tidelift" } ], - "time": "2024-06-22T11:38:48+00:00" + "time": "2024-07-26T07:24:20+00:00" }, { "name": "symfony/serializer", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "79b073ce21280bae2567cf1c48ae078dc3eeb01d" + "reference": "0d5ddac365fbfffc30ca9bc944ad3eb9b3763c09" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/79b073ce21280bae2567cf1c48ae078dc3eeb01d", - "reference": "79b073ce21280bae2567cf1c48ae078dc3eeb01d", + "url": "https://api.github.com/repos/symfony/serializer/zipball/0d5ddac365fbfffc30ca9bc944ad3eb9b3763c09", + "reference": "0d5ddac365fbfffc30ca9bc944ad3eb9b3763c09", "shasum": "" }, "require": { "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "~1.8" }, "conflict": { @@ -12571,6 +12605,7 @@ "symfony/property-access": "^6.4|^7.0", "symfony/property-info": "^6.4|^7.0", "symfony/translation-contracts": "^2.5|^3", + "symfony/type-info": "^7.1", "symfony/uid": "^6.4|^7.0", "symfony/validator": "^6.4|^7.0", "symfony/var-dumper": "^6.4|^7.0", @@ -12603,7 +12638,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/serializer/tree/v7.0.10" + "source": "https://github.com/symfony/serializer/tree/v7.1.3" }, "funding": [ { @@ -12619,7 +12654,7 @@ "type": "tidelift" } ], - "time": "2024-07-17T06:06:58+00:00" + "time": "2024-07-17T06:10:24+00:00" }, { "name": "symfony/service-contracts", @@ -12775,16 +12810,16 @@ }, { "name": "symfony/stopwatch", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "e4a0d6fef3dd428ca23172e62d1d863f6f25d541" + "reference": "5b75bb1ac2ba1b9d05c47fc4b3046a625377d23d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/e4a0d6fef3dd428ca23172e62d1d863f6f25d541", - "reference": "e4a0d6fef3dd428ca23172e62d1d863f6f25d541", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5b75bb1ac2ba1b9d05c47fc4b3046a625377d23d", + "reference": "5b75bb1ac2ba1b9d05c47fc4b3046a625377d23d", "shasum": "" }, "require": { @@ -12817,7 +12852,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v7.0.8" + "source": "https://github.com/symfony/stopwatch/tree/v7.1.1" }, "funding": [ { @@ -12833,20 +12868,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { "name": "symfony/string", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "a1ac40b358a5e45c2b6c32ec9b183828c1dcf5d6" + "reference": "ea272a882be7f20cad58d5d78c215001617b7f07" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/a1ac40b358a5e45c2b6c32ec9b183828c1dcf5d6", - "reference": "a1ac40b358a5e45c2b6c32ec9b183828c1dcf5d6", + "url": "https://api.github.com/repos/symfony/string/zipball/ea272a882be7f20cad58d5d78c215001617b7f07", + "reference": "ea272a882be7f20cad58d5d78c215001617b7f07", "shasum": "" }, "require": { @@ -12860,6 +12895,7 @@ "symfony/translation-contracts": "<2.5" }, "require-dev": { + "symfony/emoji": "^7.1", "symfony/error-handler": "^6.4|^7.0", "symfony/http-client": "^6.4|^7.0", "symfony/intl": "^6.4|^7.0", @@ -12903,7 +12939,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.0.10" + "source": "https://github.com/symfony/string/tree/v7.1.3" }, "funding": [ { @@ -12919,20 +12955,20 @@ "type": "tidelift" } ], - "time": "2024-07-22T10:25:05+00:00" + "time": "2024-07-22T10:25:37+00:00" }, { "name": "symfony/translation", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "480fc1b9f44d9104239eb36de1e1151814c8a8d8" + "reference": "8d5e50c813ba2859a6dfc99a0765c550507934a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/480fc1b9f44d9104239eb36de1e1151814c8a8d8", - "reference": "480fc1b9f44d9104239eb36de1e1151814c8a8d8", + "url": "https://api.github.com/repos/symfony/translation/zipball/8d5e50c813ba2859a6dfc99a0765c550507934a1", + "reference": "8d5e50c813ba2859a6dfc99a0765c550507934a1", "shasum": "" }, "require": { @@ -12997,7 +13033,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v7.0.10" + "source": "https://github.com/symfony/translation/tree/v7.1.3" }, "funding": [ { @@ -13013,7 +13049,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:31:22+00:00" + "time": "2024-07-26T12:41:01+00:00" }, { "name": "symfony/translation-contracts", @@ -13095,22 +13131,22 @@ }, { "name": "symfony/twig-bridge", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/twig-bridge.git", - "reference": "c8e05d7545962198df715d705c132de0674dc5b2" + "reference": "96e6e12a63db80bcedefc012042d2cb2d1a015f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/c8e05d7545962198df715d705c132de0674dc5b2", - "reference": "c8e05d7545962198df715d705c132de0674dc5b2", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/96e6e12a63db80bcedefc012042d2cb2d1a015f8", + "reference": "96e6e12a63db80bcedefc012042d2cb2d1a015f8", "shasum": "" }, "require": { "php": ">=8.2", "symfony/translation-contracts": "^2.5|^3", - "twig/twig": "^3.0.4" + "twig/twig": "^3.9" }, "conflict": { "phpdocumentor/reflection-docblock": "<3.2.2", @@ -13132,6 +13168,7 @@ "symfony/asset-mapper": "^6.4|^7.0", "symfony/console": "^6.4|^7.0", "symfony/dependency-injection": "^6.4|^7.0", + "symfony/emoji": "^7.1", "symfony/expression-language": "^6.4|^7.0", "symfony/finder": "^6.4|^7.0", "symfony/form": "^6.4|^7.0", @@ -13183,7 +13220,7 @@ "description": "Provides integration for Twig with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bridge/tree/v7.0.8" + "source": "https://github.com/symfony/twig-bridge/tree/v7.1.1" }, "funding": [ { @@ -13199,20 +13236,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { "name": "symfony/twig-bundle", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/twig-bundle.git", - "reference": "a90e474bc260e59bed98a556db63673e6420a0be" + "reference": "d48c2f08c2f315e749f0e18fc4945b7be8afe1e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/a90e474bc260e59bed98a556db63673e6420a0be", - "reference": "a90e474bc260e59bed98a556db63673e6420a0be", + "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/d48c2f08c2f315e749f0e18fc4945b7be8afe1e5", + "reference": "d48c2f08c2f315e749f0e18fc4945b7be8afe1e5", "shasum": "" }, "require": { @@ -13267,7 +13304,7 @@ "description": "Provides a tight integration of Twig into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bundle/tree/v7.0.8" + "source": "https://github.com/symfony/twig-bundle/tree/v7.1.1" }, "funding": [ { @@ -13283,20 +13320,102 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-05-31T14:57:53+00:00" + }, + { + "name": "symfony/type-info", + "version": "v7.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/type-info.git", + "reference": "60b28eb733f1453287f1263ed305b96091e0d1dc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/type-info/zipball/60b28eb733f1453287f1263ed305b96091e0d1dc", + "reference": "60b28eb733f1453287f1263ed305b96091e0d1dc", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/container": "^1.1|^2.0" + }, + "conflict": { + "phpstan/phpdoc-parser": "<1.0", + "symfony/dependency-injection": "<6.4", + "symfony/property-info": "<6.4" + }, + "require-dev": { + "phpstan/phpdoc-parser": "^1.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\TypeInfo\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mathias Arlaud", + "email": "mathias.arlaud@gmail.com" + }, + { + "name": "Baptiste LEDUC", + "email": "baptiste.leduc@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Extracts PHP types information.", + "homepage": "https://symfony.com", + "keywords": [ + "PHPStan", + "phpdoc", + "symfony", + "type" + ], + "support": { + "source": "https://github.com/symfony/type-info/tree/v7.1.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-05-31T14:59:31+00:00" }, { "name": "symfony/uid", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/uid.git", - "reference": "82d01607b09ba79f38efe4c213dbf528ff0beeed" + "reference": "bb59febeecc81528ff672fad5dab7f06db8c8277" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/uid/zipball/82d01607b09ba79f38efe4c213dbf528ff0beeed", - "reference": "82d01607b09ba79f38efe4c213dbf528ff0beeed", + "url": "https://api.github.com/repos/symfony/uid/zipball/bb59febeecc81528ff672fad5dab7f06db8c8277", + "reference": "bb59febeecc81528ff672fad5dab7f06db8c8277", "shasum": "" }, "require": { @@ -13341,7 +13460,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/uid/tree/v7.0.8" + "source": "https://github.com/symfony/uid/tree/v7.1.1" }, "funding": [ { @@ -13357,7 +13476,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { "name": "symfony/ux-autocomplete", @@ -13617,20 +13736,21 @@ }, { "name": "symfony/validator", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "b3e4d838cdae9f2882402c2ad8018a27d469c075" + "reference": "ba711a6cfc008544dad059abb3c1d997f1472237" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/b3e4d838cdae9f2882402c2ad8018a27d469c075", - "reference": "b3e4d838cdae9f2882402c2ad8018a27d469c075", + "url": "https://api.github.com/repos/symfony/validator/zipball/ba711a6cfc008544dad059abb3c1d997f1472237", + "reference": "ba711a6cfc008544dad059abb3c1d997f1472237", "shasum": "" }, "require": { "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php83": "^1.27", @@ -13663,6 +13783,7 @@ "symfony/property-access": "^6.4|^7.0", "symfony/property-info": "^6.4|^7.0", "symfony/translation": "^6.4.3|^7.0.3", + "symfony/type-info": "^7.1", "symfony/yaml": "^6.4|^7.0" }, "type": "library", @@ -13692,7 +13813,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/validator/tree/v7.0.10" + "source": "https://github.com/symfony/validator/tree/v7.1.3" }, "funding": [ { @@ -13708,20 +13829,20 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:31:22+00:00" + "time": "2024-07-26T12:41:01+00:00" }, { "name": "symfony/var-dumper", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "3b5bed54f7c541aa0bf4cb0d3eb63b9e422ccb8b" + "reference": "86af4617cca75a6e28598f49ae0690f3b9d4591f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/3b5bed54f7c541aa0bf4cb0d3eb63b9e422ccb8b", - "reference": "3b5bed54f7c541aa0bf4cb0d3eb63b9e422ccb8b", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/86af4617cca75a6e28598f49ae0690f3b9d4591f", + "reference": "86af4617cca75a6e28598f49ae0690f3b9d4591f", "shasum": "" }, "require": { @@ -13775,7 +13896,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.0.10" + "source": "https://github.com/symfony/var-dumper/tree/v7.1.3" }, "funding": [ { @@ -13791,20 +13912,20 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:31:22+00:00" + "time": "2024-07-26T12:41:01+00:00" }, { "name": "symfony/var-exporter", - "version": "v7.0.9", + "version": "v7.1.2", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "18053b0e249c7303f9461f78d15cceae69c83b02" + "reference": "b80a669a2264609f07f1667f891dbfca25eba44c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/18053b0e249c7303f9461f78d15cceae69c83b02", - "reference": "18053b0e249c7303f9461f78d15cceae69c83b02", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/b80a669a2264609f07f1667f891dbfca25eba44c", + "reference": "b80a669a2264609f07f1667f891dbfca25eba44c", "shasum": "" }, "require": { @@ -13851,7 +13972,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v7.0.9" + "source": "https://github.com/symfony/var-exporter/tree/v7.1.2" }, "funding": [ { @@ -13867,20 +13988,20 @@ "type": "tidelift" } ], - "time": "2024-06-28T07:59:17+00:00" + "time": "2024-06-28T08:00:31+00:00" }, { "name": "symfony/web-link", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/web-link.git", - "reference": "270f39e3d1c7cc62b5a931fd6e9f2ea4e99ee9cf" + "reference": "63f90aa0054bfd9a091d2f5cf465958f1030638f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-link/zipball/270f39e3d1c7cc62b5a931fd6e9f2ea4e99ee9cf", - "reference": "270f39e3d1c7cc62b5a931fd6e9f2ea4e99ee9cf", + "url": "https://api.github.com/repos/symfony/web-link/zipball/63f90aa0054bfd9a091d2f5cf465958f1030638f", + "reference": "63f90aa0054bfd9a091d2f5cf465958f1030638f", "shasum": "" }, "require": { @@ -13934,7 +14055,7 @@ "push" ], "support": { - "source": "https://github.com/symfony/web-link/tree/v7.0.8" + "source": "https://github.com/symfony/web-link/tree/v7.1.1" }, "funding": [ { @@ -13950,7 +14071,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { "name": "symfony/webpack-encore-bundle", @@ -14025,16 +14146,16 @@ }, { "name": "symfony/workflow", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/workflow.git", - "reference": "4cfb7fec060bf5bd2c38f14dc0c221a32a19b9eb" + "reference": "bc9a36fdd6a6fab9f630bd73b428aa06917e17e8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/workflow/zipball/4cfb7fec060bf5bd2c38f14dc0c221a32a19b9eb", - "reference": "4cfb7fec060bf5bd2c38f14dc0c221a32a19b9eb", + "url": "https://api.github.com/repos/symfony/workflow/zipball/bc9a36fdd6a6fab9f630bd73b428aa06917e17e8", + "reference": "bc9a36fdd6a6fab9f630bd73b428aa06917e17e8", "shasum": "" }, "require": { @@ -14092,7 +14213,7 @@ "workflow" ], "support": { - "source": "https://github.com/symfony/workflow/tree/v7.0.8" + "source": "https://github.com/symfony/workflow/tree/v7.1.1" }, "funding": [ { @@ -14108,20 +14229,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { "name": "symfony/yaml", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "89bdddd79e918448ce978be664768ef27b9e5798" + "reference": "fa34c77015aa6720469db7003567b9f772492bf2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/89bdddd79e918448ce978be664768ef27b9e5798", - "reference": "89bdddd79e918448ce978be664768ef27b9e5798", + "url": "https://api.github.com/repos/symfony/yaml/zipball/fa34c77015aa6720469db7003567b9f772492bf2", + "reference": "fa34c77015aa6720469db7003567b9f772492bf2", "shasum": "" }, "require": { @@ -14163,7 +14284,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.0.8" + "source": "https://github.com/symfony/yaml/tree/v7.1.1" }, "funding": [ { @@ -14179,7 +14300,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { "name": "symfonycasts/reset-password-bundle", @@ -15751,16 +15872,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.11.8", + "version": "1.11.9", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "6adbd118e6c0515dd2f36b06cde1d6da40f1b8ec" + "reference": "e370bcddadaede0c1716338b262346f40d296f82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/6adbd118e6c0515dd2f36b06cde1d6da40f1b8ec", - "reference": "6adbd118e6c0515dd2f36b06cde1d6da40f1b8ec", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e370bcddadaede0c1716338b262346f40d296f82", + "reference": "e370bcddadaede0c1716338b262346f40d296f82", "shasum": "" }, "require": { @@ -15805,7 +15926,7 @@ "type": "github" } ], - "time": "2024-07-24T07:01:22+00:00" + "time": "2024-08-01T16:25:18+00:00" }, { "name": "phpunit/php-code-coverage", @@ -16130,16 +16251,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.5.28", + "version": "10.5.29", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "ff7fb85cdf88131b83e721fb2a327b664dbed275" + "reference": "8e9e80872b4e8064401788ee8a32d40b4455318f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ff7fb85cdf88131b83e721fb2a327b664dbed275", - "reference": "ff7fb85cdf88131b83e721fb2a327b664dbed275", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/8e9e80872b4e8064401788ee8a32d40b4455318f", + "reference": "8e9e80872b4e8064401788ee8a32d40b4455318f", "shasum": "" }, "require": { @@ -16211,7 +16332,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.28" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.29" }, "funding": [ { @@ -16227,7 +16348,7 @@ "type": "tidelift" } ], - "time": "2024-07-18T14:54:16+00:00" + "time": "2024-07-30T11:08:00+00:00" }, { "name": "sebastian/cli-parser", @@ -17147,16 +17268,16 @@ }, { "name": "symfony/browser-kit", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "0030d568e9147b853e168117edf72b74f9643e85" + "reference": "9c13742e3175b5815e272b981876ae329bec2040" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/0030d568e9147b853e168117edf72b74f9643e85", - "reference": "0030d568e9147b853e168117edf72b74f9643e85", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/9c13742e3175b5815e272b981876ae329bec2040", + "reference": "9c13742e3175b5815e272b981876ae329bec2040", "shasum": "" }, "require": { @@ -17195,7 +17316,7 @@ "description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/browser-kit/tree/v7.0.8" + "source": "https://github.com/symfony/browser-kit/tree/v7.1.1" }, "funding": [ { @@ -17211,11 +17332,11 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { "name": "symfony/debug-bundle", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/debug-bundle.git", @@ -17269,7 +17390,7 @@ "description": "Provides a tight integration of the Symfony VarDumper component and the ServerLogCommand from MonologBridge into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/debug-bundle/tree/v7.0.8" + "source": "https://github.com/symfony/debug-bundle/tree/v7.1.1" }, "funding": [ { @@ -17289,16 +17410,16 @@ }, { "name": "symfony/dom-crawler", - "version": "v7.0.8", + "version": "v7.1.1", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "46cdbb48603db7b9ea55172d3edb6b3e9de58028" + "reference": "01ce8174447f1f1dd33a5854b01beef79061d9fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/46cdbb48603db7b9ea55172d3edb6b3e9de58028", - "reference": "46cdbb48603db7b9ea55172d3edb6b3e9de58028", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/01ce8174447f1f1dd33a5854b01beef79061d9fa", + "reference": "01ce8174447f1f1dd33a5854b01beef79061d9fa", "shasum": "" }, "require": { @@ -17336,7 +17457,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v7.0.8" + "source": "https://github.com/symfony/dom-crawler/tree/v7.1.1" }, "funding": [ { @@ -17352,7 +17473,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { "name": "symfony/maker-bundle", @@ -17530,16 +17651,16 @@ }, { "name": "symfony/web-profiler-bundle", - "version": "v7.0.10", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/web-profiler-bundle.git", - "reference": "884ed0470bd703ec40a78dfec94fe971ca55cad6" + "reference": "b9357f73d2c14dcd36783a67386f510654828668" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/884ed0470bd703ec40a78dfec94fe971ca55cad6", - "reference": "884ed0470bd703ec40a78dfec94fe971ca55cad6", + "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/b9357f73d2c14dcd36783a67386f510654828668", + "reference": "b9357f73d2c14dcd36783a67386f510654828668", "shasum": "" }, "require": { @@ -17549,7 +17670,7 @@ "symfony/http-kernel": "^6.4|^7.0", "symfony/routing": "^6.4|^7.0", "symfony/twig-bundle": "^6.4|^7.0", - "twig/twig": "^3.0.4" + "twig/twig": "^3.10" }, "conflict": { "symfony/form": "<6.4", @@ -17591,7 +17712,7 @@ "dev" ], "support": { - "source": "https://github.com/symfony/web-profiler-bundle/tree/v7.0.10" + "source": "https://github.com/symfony/web-profiler-bundle/tree/v7.1.3" }, "funding": [ { @@ -17607,7 +17728,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:31:22+00:00" + "time": "2024-07-26T12:41:01+00:00" }, { "name": "theseer/tokenizer", diff --git a/package-lock.json b/package-lock.json index 50d6c531a..f32c45562 100644 --- a/package-lock.json +++ b/package-lock.json @@ -65,9 +65,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.8.tgz", - "integrity": "sha512-c4IM7OTg6k1Q+AJ153e2mc2QVTezTwnb4VzquwcyiEzGnW0Kedv4do/TrkU98qPeC5LNiMt/QXwIjzYXLBpyZg==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.2.tgz", + "integrity": "sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==", "dev": true, "license": "MIT", "engines": { @@ -75,22 +75,22 @@ } }, "node_modules/@babel/core": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.8.tgz", - "integrity": "sha512-6AWcmZC/MZCO0yKys4uhg5NlxL0ESF3K6IAaoQ+xSXvPyPyxNWRafP+GDbI88Oh68O7QkJgmEtedWPM9U0pZNg==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", + "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.8", - "@babel/helper-compilation-targets": "^7.24.8", - "@babel/helper-module-transforms": "^7.24.8", - "@babel/helpers": "^7.24.8", - "@babel/parser": "^7.24.8", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.8", - "@babel/types": "^7.24.8", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -106,13 +106,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.8.tgz", - "integrity": "sha512-47DG+6F5SzOi0uEvK4wMShmn5yY0mVjVJoWTphdY2B4Rx9wHgjK7Yhtr0ru6nE+sn0v38mzrWOlah0p/YlHHOQ==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz", + "integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.24.8", + "@babel/types": "^7.25.0", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -149,13 +149,13 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.8.tgz", - "integrity": "sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", + "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.24.8", + "@babel/compat-data": "^7.25.2", "@babel/helper-validator-option": "^7.24.8", "browserslist": "^4.23.1", "lru-cache": "^5.1.1", @@ -166,20 +166,18 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.8.tgz", - "integrity": "sha512-4f6Oqnmyp2PP3olgUMmOwC3akxSm5aBYraQ6YDdKy7NcAMkDECHWG0DEnV6M2UAkERgIBhYt8S27rURPg7SxWA==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.0.tgz", + "integrity": "sha512-GYM6BxeQsETc9mnct+nIIpf63SAyzvyYN7UB/IlTyd+MBg06afFGp0mIeUqGyWgS2mxad6vqbMrHVlaL3m70sQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", "@babel/helper-member-expression-to-functions": "^7.24.8", "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7", + "@babel/helper-replace-supers": "^7.25.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/traverse": "^7.25.0", "semver": "^6.3.1" }, "engines": { @@ -190,9 +188,9 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.7.tgz", - "integrity": "sha512-03TCmXy2FtXJEZfbXDTSqq1fRJArk7lX9DOFC/47VthYcxyIOx+eXQmdo6DOQvrbpIix+KfXwvuXdFDZHxt+rA==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.2.tgz", + "integrity": "sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g==", "dev": true, "license": "MIT", "dependencies": { @@ -224,46 +222,6 @@ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", - "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", - "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", - "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-member-expression-to-functions": { "version": "7.24.8", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz", @@ -293,17 +251,16 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.8.tgz", - "integrity": "sha512-m4vWKVqvkVAWLXfHCCfff2luJj86U+J0/x+0N3ArG/tP0Fq7zky2dYwMbtPmkc/oulkkbjdL3uWzuoBwQ8R00Q==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", + "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", "@babel/helper-module-imports": "^7.24.7", "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.2" }, "engines": { "node": ">=6.9.0" @@ -336,15 +293,15 @@ } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.7.tgz", - "integrity": "sha512-9pKLcTlZ92hNZMQfGCHImUpDOlAgkkpqalWEeftW5FBya75k8Li2ilerxkM/uBEj01iBZXcCIB/bwvDYgWyibA==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.0.tgz", + "integrity": "sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-wrap-function": "^7.24.7" + "@babel/helper-wrap-function": "^7.25.0", + "@babel/traverse": "^7.25.0" }, "engines": { "node": ">=6.9.0" @@ -354,15 +311,15 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz", - "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz", + "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.7", - "@babel/helper-optimise-call-expression": "^7.24.7" + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/traverse": "^7.25.0" }, "engines": { "node": ">=6.9.0" @@ -399,19 +356,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-string-parser": { "version": "7.24.8", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", @@ -443,30 +387,29 @@ } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.7.tgz", - "integrity": "sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.0.tgz", + "integrity": "sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-function-name": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.8.tgz", - "integrity": "sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.0.tgz", + "integrity": "sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.8" + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" @@ -489,11 +432,14 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz", - "integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==", + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.3.tgz", + "integrity": "sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==", "dev": true, "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.2" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -502,14 +448,30 @@ } }, "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.7.tgz", - "integrity": "sha512-TiT1ss81W80eQsN+722OaeQMY/G4yTb4G9JrqeiDADs3N8lbPMGldWi9x8tyqCW5NLx1Jh2AvkE6r6QvEltMMQ==", + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.3.tgz", + "integrity": "sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.0.tgz", + "integrity": "sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -519,13 +481,13 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.24.7", - "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.7.tgz", - "integrity": "sha512-unaQgZ/iRu/By6tsjMZzpeBZjChYfLYry6HrEXPoz3KmfF0sVBQ1l8zKMQ4xRGLWVsjuvB8nQfjNP/DcfEOCsg==", + "version": "7.25.0", + "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.25.0.tgz", + "integrity": "sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -553,14 +515,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.7.tgz", - "integrity": "sha512-utA4HuR6F4Vvcr+o4DnjL8fCOlgRFGbeeBEGNg3ZTrLFw6VWG5XmUrvcQ0FjIYMU2ST4XcR2Wsp7t9qOAPnxMg==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.0.tgz", + "integrity": "sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.0" }, "engines": { "node": ">=6.9.0" @@ -852,16 +814,16 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.7.tgz", - "integrity": "sha512-o+iF77e3u7ZS4AoAuJvapz9Fm001PuD2V3Lp6OSE4FYQke+cSewYtnek+THqGRWyQloRCyvWL1OkyfNEl9vr/g==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.0.tgz", + "integrity": "sha512-uaIi2FdqzjpAMvVqvB51S42oC2JEVgh0LDsGfZVDysWE8LrJtQC2jvKmOqEYThKyB7bDEb7BP1GYWDm7tABA0Q==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-remap-async-to-generator": "^7.24.7", - "@babel/plugin-syntax-async-generators": "^7.8.4" + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-remap-async-to-generator": "^7.25.0", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/traverse": "^7.25.0" }, "engines": { "node": ">=6.9.0" @@ -905,13 +867,13 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.7.tgz", - "integrity": "sha512-Nd5CvgMbWc+oWzBsuaMcbwjJWAcp5qzrbg69SZdHSP7AMY0AbWFqFO0WTFCA1jxhMCwodRwvRec8k0QUbZk7RQ==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.0.tgz", + "integrity": "sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -956,19 +918,17 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.8.tgz", - "integrity": "sha512-VXy91c47uujj758ud9wx+OMgheXm4qJfyhj1P18YvlrQkNOSrwsteHk+EFS3OMGfhMhpZa0A+81eE7G4QC+3CA==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.0.tgz", + "integrity": "sha512-xyi6qjr/fYU304fiRwFbekzkqVJZ6A7hOjWZd+89FVcBqPV3S9Wuozz82xdpLspckeaafntbzglaW4pqpzvtSw==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.24.7", "@babel/helper-compilation-targets": "^7.24.8", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-replace-supers": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-replace-supers": "^7.25.0", + "@babel/traverse": "^7.25.0", "globals": "^11.1.0" }, "engines": { @@ -1044,6 +1004,23 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.0.tgz", + "integrity": "sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@babel/plugin-transform-dynamic-import": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", @@ -1113,15 +1090,15 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.7.tgz", - "integrity": "sha512-U9FcnA821YoILngSmYkW6FjyQe2TyZD5pHt4EVIhmcTkrJw/3KqcrRSxuOo5tFZJi7TE19iDyI1u+weTI7bn2w==", + "version": "7.25.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.1.tgz", + "integrity": "sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.1" }, "engines": { "node": ">=6.9.0" @@ -1148,13 +1125,13 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.7.tgz", - "integrity": "sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.2.tgz", + "integrity": "sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1232,16 +1209,16 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.7.tgz", - "integrity": "sha512-GYQE0tW7YoaN13qFh3O1NCY4MPkUiAH3fiF7UcV/I3ajmDKEdG3l+UOcbAm4zUE3gnvUU+Eni7XrVKo9eO9auw==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.0.tgz", + "integrity": "sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" + "@babel/helper-module-transforms": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.0" }, "engines": { "node": ">=6.9.0" @@ -1655,20 +1632,21 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.8.tgz", - "integrity": "sha512-vObvMZB6hNWuDxhSaEPTKCwcqkAIuDtE+bQGn4XMXne1DSLzFVY8Vmj1bm+mUQXYNN8NmaQEO+r8MMbzPr1jBQ==", + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.3.tgz", + "integrity": "sha512-QsYW7UeAaXvLPX9tdVliMJE7MD7M6MLYVTovRTIwhoYQVFHR1rM4wO8wqAezYi3/BpSD+NzVCZ69R6smWiIi8g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.24.8", - "@babel/helper-compilation-targets": "^7.24.8", + "@babel/compat-data": "^7.25.2", + "@babel/helper-compilation-targets": "^7.25.2", "@babel/helper-plugin-utils": "^7.24.8", "@babel/helper-validator-option": "^7.24.8", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.7", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.7", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.3", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.0", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.0", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.7", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.0", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", @@ -1689,29 +1667,30 @@ "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.24.7", - "@babel/plugin-transform-async-generator-functions": "^7.24.7", + "@babel/plugin-transform-async-generator-functions": "^7.25.0", "@babel/plugin-transform-async-to-generator": "^7.24.7", "@babel/plugin-transform-block-scoped-functions": "^7.24.7", - "@babel/plugin-transform-block-scoping": "^7.24.7", + "@babel/plugin-transform-block-scoping": "^7.25.0", "@babel/plugin-transform-class-properties": "^7.24.7", "@babel/plugin-transform-class-static-block": "^7.24.7", - "@babel/plugin-transform-classes": "^7.24.8", + "@babel/plugin-transform-classes": "^7.25.0", "@babel/plugin-transform-computed-properties": "^7.24.7", "@babel/plugin-transform-destructuring": "^7.24.8", "@babel/plugin-transform-dotall-regex": "^7.24.7", "@babel/plugin-transform-duplicate-keys": "^7.24.7", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.0", "@babel/plugin-transform-dynamic-import": "^7.24.7", "@babel/plugin-transform-exponentiation-operator": "^7.24.7", "@babel/plugin-transform-export-namespace-from": "^7.24.7", "@babel/plugin-transform-for-of": "^7.24.7", - "@babel/plugin-transform-function-name": "^7.24.7", + "@babel/plugin-transform-function-name": "^7.25.1", "@babel/plugin-transform-json-strings": "^7.24.7", - "@babel/plugin-transform-literals": "^7.24.7", + "@babel/plugin-transform-literals": "^7.25.2", "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", "@babel/plugin-transform-member-expression-literals": "^7.24.7", "@babel/plugin-transform-modules-amd": "^7.24.7", "@babel/plugin-transform-modules-commonjs": "^7.24.8", - "@babel/plugin-transform-modules-systemjs": "^7.24.7", + "@babel/plugin-transform-modules-systemjs": "^7.25.0", "@babel/plugin-transform-modules-umd": "^7.24.7", "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", "@babel/plugin-transform-new-target": "^7.24.7", @@ -1773,9 +1752,9 @@ "license": "MIT" }, "node_modules/@babel/runtime": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz", - "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", + "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", "dev": true, "license": "MIT", "dependencies": { @@ -1786,35 +1765,32 @@ } }, "node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.8.tgz", - "integrity": "sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==", + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.3.tgz", + "integrity": "sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.8", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.8", - "@babel/types": "^7.24.8", + "@babel/generator": "^7.25.0", + "@babel/parser": "^7.25.3", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.2", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1823,9 +1799,9 @@ } }, "node_modules/@babel/types": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.8.tgz", - "integrity": "sha512-SkSBEHwwJRU52QEVZBmMBnE5Ux2/6WU1grdYyOhpbCNxbmJrDuDCphBzKZSO3taf0zztp+qkWlymE5tVL5l0TA==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.2.tgz", + "integrity": "sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==", "dev": true, "license": "MIT", "dependencies": { @@ -2406,11 +2382,10 @@ } }, "node_modules/@fortawesome/fontawesome-free": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.5.2.tgz", - "integrity": "sha512-hRILoInAx8GNT5IMkrtIt9blOdrqHOnPBH+k70aWUAqPZPgopb9G5EQJFpaBx/S8zp2fC+mPW349Bziuk1o28Q==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.6.0.tgz", + "integrity": "sha512-60G28ke/sXdtS9KZCpZSHHkCbdsOGEhIUGlwq6yhY74UpTiToIh8np7A8yphhM4BWsvNFtIvLpi4co+h9Mr9Ow==", "dev": true, - "hasInstallScript": true, "license": "(CC-BY-4.0 AND OFL-1.1 AND MIT)", "engines": { "node": ">=6" @@ -2756,9 +2731,9 @@ "license": "Apache-2.0" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.1.tgz", - "integrity": "sha512-lncuC4aHicncmbORnx+dUaAgzee9cm/PbIqgWz1PpXuwc+sa1Ct83tnqUDy/GFKleLiN7ZIeytM6KJ4cAn1SxA==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.19.2.tgz", + "integrity": "sha512-OHflWINKtoCFSpm/WmuQaWW4jeX+3Qt3XQDepkkiFTsoxFc5BpF3Z5aDxFZgBqRjO6ATP5+b1iilp4kGIZVWlA==", "cpu": [ "arm" ], @@ -2771,9 +2746,9 @@ "peer": true }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.1.tgz", - "integrity": "sha512-F/tkdw0WSs4ojqz5Ovrw5r9odqzFjb5LIgHdHZG65dFI1lWTWRVy32KDJLKRISHgJvqUeUhdIvy43fX41znyDg==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.19.2.tgz", + "integrity": "sha512-k0OC/b14rNzMLDOE6QMBCjDRm3fQOHAL8Ldc9bxEWvMo4Ty9RY6rWmGetNTWhPo+/+FNd1lsQYRd0/1OSix36A==", "cpu": [ "arm64" ], @@ -2786,9 +2761,9 @@ "peer": true }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.1.tgz", - "integrity": "sha512-vk+ma8iC1ebje/ahpxpnrfVQJibTMyHdWpOGZ3JpQ7Mgn/3QNHmPq7YwjZbIE7km73dH5M1e6MRRsnEBW7v5CQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.19.2.tgz", + "integrity": "sha512-IIARRgWCNWMTeQH+kr/gFTHJccKzwEaI0YSvtqkEBPj7AshElFq89TyreKNFAGh5frLfDCbodnq+Ye3dqGKPBw==", "cpu": [ "arm64" ], @@ -2801,9 +2776,9 @@ "peer": true }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.1.tgz", - "integrity": "sha512-IgpzXKauRe1Tafcej9STjSSuG0Ghu/xGYH+qG6JwsAUxXrnkvNHcq/NL6nz1+jzvWAnQkuAJ4uIwGB48K9OCGA==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.19.2.tgz", + "integrity": "sha512-52udDMFDv54BTAdnw+KXNF45QCvcJOcYGl3vQkp4vARyrcdI/cXH8VXTEv/8QWfd6Fru8QQuw1b2uNersXOL0g==", "cpu": [ "x64" ], @@ -2816,9 +2791,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.1.tgz", - "integrity": "sha512-P9bSiAUnSSM7EmyRK+e5wgpqai86QOSv8BwvkGjLwYuOpaeomiZWifEos517CwbG+aZl1T4clSE1YqqH2JRs+g==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.19.2.tgz", + "integrity": "sha512-r+SI2t8srMPYZeoa1w0o/AfoVt9akI1ihgazGYPQGRilVAkuzMGiTtexNZkrPkQsyFrvqq/ni8f3zOnHw4hUbA==", "cpu": [ "arm" ], @@ -2831,9 +2806,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.1.tgz", - "integrity": "sha512-5RnjpACoxtS+aWOI1dURKno11d7krfpGDEn19jI8BuWmSBbUC4ytIADfROM1FZrFhQPSoP+KEa3NlEScznBTyQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.19.2.tgz", + "integrity": "sha512-+tYiL4QVjtI3KliKBGtUU7yhw0GMcJJuB9mLTCEauHEsqfk49gtUBXGtGP3h1LW8MbaTY6rSFIQV1XOBps1gBA==", "cpu": [ "arm" ], @@ -2846,9 +2821,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.1.tgz", - "integrity": "sha512-8mwmGD668m8WaGbthrEYZ9CBmPug2QPGWxhJxh/vCgBjro5o96gL04WLlg5BA233OCWLqERy4YUzX3bJGXaJgQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.19.2.tgz", + "integrity": "sha512-OR5DcvZiYN75mXDNQQxlQPTv4D+uNCUsmSCSY2FolLf9W5I4DSoJyg7z9Ea3TjKfhPSGgMJiey1aWvlWuBzMtg==", "cpu": [ "arm64" ], @@ -2861,9 +2836,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.1.tgz", - "integrity": "sha512-dJX9u4r4bqInMGOAQoGYdwDP8lQiisWb9et+T84l2WXk41yEej8v2iGKodmdKimT8cTAYt0jFb+UEBxnPkbXEQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.19.2.tgz", + "integrity": "sha512-Hw3jSfWdUSauEYFBSFIte6I8m6jOj+3vifLg8EU3lreWulAUpch4JBjDMtlKosrBzkr0kwKgL9iCfjA8L3geoA==", "cpu": [ "arm64" ], @@ -2876,9 +2851,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.1.tgz", - "integrity": "sha512-V72cXdTl4EI0x6FNmho4D502sy7ed+LuVW6Ym8aI6DRQ9hQZdp5sj0a2usYOlqvFBNKQnLQGwmYnujo2HvjCxQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.19.2.tgz", + "integrity": "sha512-rhjvoPBhBwVnJRq/+hi2Q3EMiVF538/o9dBuj9TVLclo9DuONqt5xfWSaE6MYiFKpo/lFPJ/iSI72rYWw5Hc7w==", "cpu": [ "ppc64" ], @@ -2891,9 +2866,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.1.tgz", - "integrity": "sha512-f+pJih7sxoKmbjghrM2RkWo2WHUW8UbfxIQiWo5yeCaCM0TveMEuAzKJte4QskBp1TIinpnRcxkquY+4WuY/tg==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.19.2.tgz", + "integrity": "sha512-EAz6vjPwHHs2qOCnpQkw4xs14XJq84I81sDRGPEjKPFVPBw7fwvtwhVjcZR6SLydCv8zNK8YGFblKWd/vRmP8g==", "cpu": [ "riscv64" ], @@ -2906,9 +2881,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.1.tgz", - "integrity": "sha512-qb1hMMT3Fr/Qz1OKovCuUM11MUNLUuHeBC2DPPAWUYYUAOFWaxInaTwTQmc7Fl5La7DShTEpmYwgdt2hG+4TEg==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.19.2.tgz", + "integrity": "sha512-IJSUX1xb8k/zN9j2I7B5Re6B0NNJDJ1+soezjNojhT8DEVeDNptq2jgycCOpRhyGj0+xBn7Cq+PK7Q+nd2hxLA==", "cpu": [ "s390x" ], @@ -2921,9 +2896,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.1.tgz", - "integrity": "sha512-7O5u/p6oKUFYjRbZkL2FLbwsyoJAjyeXHCU3O4ndvzg2OFO2GinFPSJFGbiwFDaCFc+k7gs9CF243PwdPQFh5g==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.19.2.tgz", + "integrity": "sha512-OgaToJ8jSxTpgGkZSkwKE+JQGihdcaqnyHEFOSAU45utQ+yLruE1dkonB2SDI8t375wOKgNn8pQvaWY9kPzxDQ==", "cpu": [ "x64" ], @@ -2936,9 +2911,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.1.tgz", - "integrity": "sha512-pDLkYITdYrH/9Cv/Vlj8HppDuLMDUBmgsM0+N+xLtFd18aXgM9Nyqupb/Uw+HeidhfYg2lD6CXvz6CjoVOaKjQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.19.2.tgz", + "integrity": "sha512-5V3mPpWkB066XZZBgSd1lwozBk7tmOkKtquyCJ6T4LN3mzKENXyBwWNQn8d0Ci81hvlBw5RoFgleVpL6aScLYg==", "cpu": [ "x64" ], @@ -2951,9 +2926,9 @@ "peer": true }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.1.tgz", - "integrity": "sha512-W2ZNI323O/8pJdBGil1oCauuCzmVd9lDmWBBqxYZcOqWD6aWqJtVBQ1dFrF4dYpZPks6F+xCZHfzG5hYlSHZ6g==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.19.2.tgz", + "integrity": "sha512-ayVstadfLeeXI9zUPiKRVT8qF55hm7hKa+0N1V6Vj+OTNFfKSoUxyZvzVvgtBxqSb5URQ8sK6fhwxr9/MLmxdA==", "cpu": [ "arm64" ], @@ -2966,9 +2941,9 @@ "peer": true }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.1.tgz", - "integrity": "sha512-ELfEX1/+eGZYMaCIbK4jqLxO1gyTSOIlZr6pbC4SRYFaSIDVKOnZNMdoZ+ON0mrFDp4+H5MhwNC1H/AhE3zQLg==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.19.2.tgz", + "integrity": "sha512-Mda7iG4fOLHNsPqjWSjANvNZYoW034yxgrndof0DwCy0D3FvTjeNo+HGE6oGWgvcLZNLlcp0hLEFcRs+UGsMLg==", "cpu": [ "ia32" ], @@ -2981,9 +2956,9 @@ "peer": true }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.1.tgz", - "integrity": "sha512-yjk2MAkQmoaPYCSu35RLJ62+dz358nE83VfTePJRp8CG7aMg25mEJYpXFiD+NcevhX8LxD5OP5tktPXnXN7GDw==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.19.2.tgz", + "integrity": "sha512-DPi0ubYhSow/00YqmG1jWm3qt1F8aXziHc/UNy8bo9cpCacqhuWu+iSq/fp2SyEQK7iYTZ60fBU9cat3MXTjIQ==", "cpu": [ "x64" ], @@ -3003,17 +2978,17 @@ "license": "MIT" }, "node_modules/@stylistic/eslint-plugin": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-2.3.0.tgz", - "integrity": "sha512-rtiz6u5gRyyEZp36FcF1/gHJbsbT3qAgXZ1qkad6Nr/xJ9wrSJkiSFFQhpYVTIZ7FJNRJurEcumZDCwN9dEI4g==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-2.6.1.tgz", + "integrity": "sha512-UT0f4t+3sQ/GKW7875NiIIjZJ1Bh4gd7JNfoIkwIQyWqO7wGd0Pqzu0Ho30Ka8MNF5lm++SkVeqAk26vGxoUpg==", "dev": true, "license": "MIT", "dependencies": { - "@stylistic/eslint-plugin-js": "2.3.0", - "@stylistic/eslint-plugin-jsx": "2.3.0", - "@stylistic/eslint-plugin-plus": "2.3.0", - "@stylistic/eslint-plugin-ts": "2.3.0", - "@types/eslint": "^8.56.10" + "@stylistic/eslint-plugin-js": "2.6.1", + "@stylistic/eslint-plugin-jsx": "2.6.1", + "@stylistic/eslint-plugin-plus": "2.6.1", + "@stylistic/eslint-plugin-ts": "2.6.1", + "@types/eslint": "^9.6.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3023,16 +2998,16 @@ } }, "node_modules/@stylistic/eslint-plugin-js": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-2.3.0.tgz", - "integrity": "sha512-lQwoiYb0Fs6Yc5QS3uT8+T9CPKK2Eoxc3H8EnYJgM26v/DgtW+1lvy2WNgyBflU+ThShZaHm3a6CdD9QeKx23w==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-2.6.1.tgz", + "integrity": "sha512-iLOiVzcvqzDGD9U0EuVOX680v+XOPiPAjkxWj+Q6iV2GLOM5NB27tKVOpJY7AzBhidwpRbaLTgg3T4UzYx09jw==", "dev": true, "license": "MIT", "dependencies": { - "@types/eslint": "^8.56.10", - "acorn": "^8.11.3", + "@types/eslint": "^9.6.0", + "acorn": "^8.12.1", "eslint-visitor-keys": "^4.0.0", - "espree": "^10.0.1" + "espree": "^10.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3042,14 +3017,14 @@ } }, "node_modules/@stylistic/eslint-plugin-jsx": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-2.3.0.tgz", - "integrity": "sha512-tsQ0IEKB195H6X9A4iUSgLLLKBc8gUBWkBIU8tp1/3g2l8stu+PtMQVV/VmK1+3bem5FJCyvfcZIQ/WF1fsizA==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-2.6.1.tgz", + "integrity": "sha512-5qHLXqxfY6jubAQfDqrifv41fx7gaqA9svDaChxMI6JiHpEBfh+PXxmm3g+B8gJCYVBTC62Rjl0Ny5QabK58bw==", "dev": true, "license": "MIT", "dependencies": { - "@stylistic/eslint-plugin-js": "^2.3.0", - "@types/eslint": "^8.56.10", + "@stylistic/eslint-plugin-js": "^2.6.1", + "@types/eslint": "^9.6.0", "estraverse": "^5.3.0", "picomatch": "^4.0.2" }, @@ -3061,29 +3036,29 @@ } }, "node_modules/@stylistic/eslint-plugin-plus": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-2.3.0.tgz", - "integrity": "sha512-xboPWGUU5yaPlR+WR57GwXEuY4PSlPqA0C3IdNA/+1o2MuBi95XgDJcZiJ9N+aXsqBXAPIpFFb+WQ7QEHo4f7g==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-2.6.1.tgz", + "integrity": "sha512-z/IYu/q8ipApzNam5utSU+BrXg4pK/Gv9xNbr4eWv/bZppvTWJU62xCO4nw/6r2dHNPnqc7uCHEC7GMlBnPY0A==", "dev": true, "license": "MIT", "dependencies": { - "@types/eslint": "^8.56.10", - "@typescript-eslint/utils": "^7.12.0" + "@types/eslint": "^9.6.0", + "@typescript-eslint/utils": "^8.0.0" }, "peerDependencies": { "eslint": "*" } }, "node_modules/@stylistic/eslint-plugin-ts": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-2.3.0.tgz", - "integrity": "sha512-wqOR38/uz/0XPnHX68ftp8sNMSAqnYGjovOTN7w00xnjS6Lxr3Sk7q6AaxWWqbMvOj7V2fQiMC5HWAbTruJsCg==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-2.6.1.tgz", + "integrity": "sha512-Mxl1VMorEG1Hc6oBYPD0+KIJOWkjEF1R0liL7wWgKfwpqOkgmnh5lVdZBrYyfRKOE4RlGcwEFTNai1IW6orgVg==", "dev": true, "license": "MIT", "dependencies": { - "@stylistic/eslint-plugin-js": "2.3.0", - "@types/eslint": "^8.56.10", - "@typescript-eslint/utils": "^7.12.0" + "@stylistic/eslint-plugin-js": "2.6.1", + "@types/eslint": "^9.6.0", + "@typescript-eslint/utils": "^8.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3351,9 +3326,9 @@ } }, "node_modules/@symfony/webpack-encore/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "license": "ISC", "bin": { @@ -3407,16 +3382,6 @@ "@types/node": "*" } }, - "node_modules/@types/chart.js": { - "version": "2.9.41", - "resolved": "https://registry.npmjs.org/@types/chart.js/-/chart.js-2.9.41.tgz", - "integrity": "sha512-3dvkDvueckY83UyUXtJMalYoH6faOLkWQoaTlJgB4Djde3oORmNP0Jw85HtzTuXyliUHcdp704s0mZFQKio/KQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "moment": "^2.10.2" - } - }, "node_modules/@types/connect": { "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", @@ -3439,9 +3404,9 @@ } }, "node_modules/@types/eslint": { - "version": "8.56.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", - "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.0.tgz", + "integrity": "sha512-gi6WQJ7cHRgZxtkQEoyHMppPjq9Kxo5Tjn2prSKDSmZrCz8TZ3jSRCeTJm+WoM+oB0WG37bRqLzaaU3q7JypGg==", "dev": true, "license": "MIT", "dependencies": { @@ -3570,13 +3535,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.14.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", - "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", + "version": "22.0.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.0.2.tgz", + "integrity": "sha512-yPL6DyFwY5PiMVEwymNeqUTKsDczQBJ/5T7W/46RwLU/VH+AA8aT5TZkvBviLKLbbm0hlfftEkGrNzfRk/fofQ==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.11.1" } }, "node_modules/@types/node-forge": { @@ -3661,9 +3626,9 @@ "license": "MIT" }, "node_modules/@types/ws": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "version": "8.5.12", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", + "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3688,17 +3653,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.0.tgz", - "integrity": "sha512-8gVv3kW6n01Q6TrI1cmTZ9YMFi3ucDT7i7aI5lEikk2ebk1AEjrwX8MDTdaX5D7fPXMBLvnsaa0IFTAu+jcfOw==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.0.0.tgz", + "integrity": "sha512-V0aa9Csx/ZWWv2IPgTfY7T4agYwJyILESu/PVqFtTFz9RIS823mAze+NbnBI8xiwdX3iqeQbcTYlvB04G9wyQw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0" + "@typescript-eslint/types": "8.0.0", + "@typescript-eslint/visitor-keys": "8.0.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -3706,13 +3671,13 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.0.tgz", - "integrity": "sha512-fecuH15Y+TzlUutvUl9Cc2XJxqdLr7+93SQIbcZfd4XRGGKoxyljK27b+kxKamjRkU7FYC6RrbSCg0ALcZn/xw==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.0.0.tgz", + "integrity": "sha512-wgdSGs9BTMWQ7ooeHtu5quddKKs5Z5dS+fHLbrQI+ID0XWJLODGMHRfhwImiHoeO2S5Wir2yXuadJN6/l4JRxw==", "dev": true, "license": "MIT", "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -3720,14 +3685,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.0.tgz", - "integrity": "sha512-a5NTvk51ZndFuOLCh5OaJBELYc2O3Zqxfl3Js78VFE1zE46J2AaVuW+rEbVkQznjkmlzWsUI15BG5tQMixzZLw==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.0.0.tgz", + "integrity": "sha512-5b97WpKMX+Y43YKi4zVcCVLtK5F98dFls3Oxui8LbnmRsseKenbbDinmvxrWegKDMmlkIq/XHuyy0UGLtpCDKg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0", + "@typescript-eslint/types": "8.0.0", + "@typescript-eslint/visitor-keys": "8.0.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -3736,7 +3701,7 @@ "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -3749,9 +3714,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "license": "ISC", "bin": { @@ -3762,40 +3727,40 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.0.tgz", - "integrity": "sha512-PqP4kP3hb4r7Jav+NiRCntlVzhxBNWq6ZQ+zQwII1y/G/1gdIPeYDCKr2+dH6049yJQsWZiHU6RlwvIFBXXGNA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.0.0.tgz", + "integrity": "sha512-k/oS/A/3QeGLRvOWCg6/9rATJL5rec7/5s1YmdS0ZU6LHveJyGFwBvLhSRBv6i9xaj7etmosp+l+ViN1I9Aj/Q==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.16.0", - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/typescript-estree": "7.16.0" + "@typescript-eslint/scope-manager": "8.0.0", + "@typescript-eslint/types": "8.0.0", + "@typescript-eslint/typescript-estree": "8.0.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" + "eslint": "^8.57.0 || ^9.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.0.tgz", - "integrity": "sha512-rMo01uPy9C7XxG7AFsxa8zLnWXTF8N3PYclekWSrurvhwiw1eW88mrKiAYe6s53AUY57nTRz8dJsuuXdkAhzCg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.0.0.tgz", + "integrity": "sha512-oN0K4nkHuOyF3PVMyETbpP5zp6wfyOvm7tWhTMfoqxSSsPmJIh6JNASuZDlODE8eE+0EB9uar+6+vxr9DBTYOA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.16.0", + "@typescript-eslint/types": "8.0.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -3823,15 +3788,15 @@ "license": "ISC" }, "node_modules/@vitest/expect": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.2.tgz", - "integrity": "sha512-nKAvxBYqcDugYZ4nJvnm5OR8eDJdgWjk4XM9owQKUjzW70q0icGV2HVnQOyYsp906xJaBDUXw0+9EHw2T8e0mQ==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.5.tgz", + "integrity": "sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@vitest/spy": "2.0.2", - "@vitest/utils": "2.0.2", + "@vitest/spy": "2.0.5", + "@vitest/utils": "2.0.5", "chai": "^5.1.1", "tinyrainbow": "^1.2.0" }, @@ -3840,9 +3805,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.2.tgz", - "integrity": "sha512-SBCyOXfGVvddRd9r2PwoVR0fonQjh9BMIcBMlSzbcNwFfGr6ZhOhvBzurjvi2F4ryut2HcqiFhNeDVGwru8tLg==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.5.tgz", + "integrity": "sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==", "dev": true, "license": "MIT", "peer": true, @@ -3854,14 +3819,14 @@ } }, "node_modules/@vitest/runner": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.0.2.tgz", - "integrity": "sha512-OCh437Vi8Wdbif1e0OvQcbfM3sW4s2lpmOjAE7qfLrpzJX2M7J1IQlNvEcb/fu6kaIB9n9n35wS0G2Q3en5kHg==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.0.5.tgz", + "integrity": "sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@vitest/utils": "2.0.2", + "@vitest/utils": "2.0.5", "pathe": "^1.1.2" }, "funding": { @@ -3869,14 +3834,14 @@ } }, "node_modules/@vitest/snapshot": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.0.2.tgz", - "integrity": "sha512-Yc2ewhhZhx+0f9cSUdfzPRcsM6PhIb+S43wxE7OG0kTxqgqzo8tHkXFuFlndXeDMp09G3sY/X5OAo/RfYydf1g==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.0.5.tgz", + "integrity": "sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@vitest/pretty-format": "2.0.2", + "@vitest/pretty-format": "2.0.5", "magic-string": "^0.30.10", "pathe": "^1.1.2" }, @@ -3885,9 +3850,9 @@ } }, "node_modules/@vitest/spy": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.2.tgz", - "integrity": "sha512-MgwJ4AZtCgqyp2d7WcQVE8aNG5vQ9zu9qMPYQHjsld/QVsrvg78beNrXdO4HYkP0lDahCO3P4F27aagIag+SGQ==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.5.tgz", + "integrity": "sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==", "dev": true, "license": "MIT", "peer": true, @@ -3899,14 +3864,14 @@ } }, "node_modules/@vitest/utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.2.tgz", - "integrity": "sha512-pxCY1v7kmOCWYWjzc0zfjGTA3Wmn8PKnlPvSrsA643P1NHl1fOyXj2Q9SaNlrlFE+ivCsxM80Ov3AR82RmHCWQ==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.5.tgz", + "integrity": "sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@vitest/pretty-format": "2.0.2", + "@vitest/pretty-format": "2.0.5", "estree-walker": "^3.0.3", "loupe": "^3.1.1", "tinyrainbow": "^1.2.0" @@ -4234,16 +4199,16 @@ } }, "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -4412,16 +4377,16 @@ } }, "node_modules/babel-loader/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -4758,9 +4723,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001641", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001641.tgz", - "integrity": "sha512-Phv5thgl67bHYo1TtMY/MurjkHhV4EDaCosezRXgZ8jzA/Ub+wjxAvbGvjoFENStinwi5kCyOYV3mi5tOGykwA==", + "version": "1.0.30001646", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001646.tgz", + "integrity": "sha512-dRg00gudiBDDTmUhClSdv3hqRfpbOnU28IpI1T6PBTLWa+kOj0681C8uML3PifYfREuBrVjDGhL3adYpBT6spw==", "dev": true, "funding": [ { @@ -5220,9 +5185,9 @@ } }, "node_modules/css-loader/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "license": "ISC", "bin": { @@ -5278,16 +5243,16 @@ } }, "node_modules/css-minimizer-webpack-plugin/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -5514,9 +5479,9 @@ "license": "CC0-1.0" }, "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", "dev": true, "license": "MIT", "dependencies": { @@ -5793,9 +5758,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.4.825", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.825.tgz", - "integrity": "sha512-OCcF+LwdgFGcsYPYC5keEEFC2XT0gBhrYbeGzHCx7i9qRFbzO/AqTmc/C/1xNhJj+JA7rzlN7mpBuStshh96Cg==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.4.tgz", + "integrity": "sha512-orzA81VqLyIGUEA77YkVA1D+N+nNfl2isJVjjmOyrlxuooZ19ynb+dOlaDTqd/idKRS9lDCSBmtzM+kyCsMnkA==", "dev": true, "license": "ISC" }, @@ -5827,9 +5792,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", - "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "dev": true, "license": "MIT", "dependencies": { @@ -6446,6 +6411,13 @@ "fastest-levenshtein": "^1.0.7" } }, + "node_modules/fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", + "dev": true, + "license": "MIT" + }, "node_modules/fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", @@ -7208,9 +7180,9 @@ } }, "node_modules/immutable": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.6.tgz", - "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", + "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", "dev": true, "license": "MIT" }, @@ -7232,9 +7204,9 @@ } }, "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", "dev": true, "license": "MIT", "dependencies": { @@ -7383,9 +7355,9 @@ } }, "node_modules/is-core-module": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", - "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", + "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", "dev": true, "license": "MIT", "dependencies": { @@ -7969,14 +7941,14 @@ } }, "node_modules/magic-string": { - "version": "0.30.10", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", - "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "version": "0.30.11", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", + "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, "node_modules/mdn-data": { @@ -8138,16 +8110,16 @@ } }, "node_modules/mini-css-extract-plugin/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -8217,16 +8189,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/moment": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", - "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/moo-color": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/moo-color/-/moo-color-1.0.3.tgz", @@ -8355,9 +8317,9 @@ } }, "node_modules/node-notifier/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "license": "ISC", "bin": { @@ -8368,9 +8330,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "dev": true, "license": "MIT" }, @@ -8938,9 +8900,9 @@ } }, "node_modules/postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "version": "8.4.40", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.40.tgz", + "integrity": "sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==", "dev": true, "funding": [ { @@ -9431,9 +9393,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", - "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz", + "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==", "dev": true, "license": "MIT", "dependencies": { @@ -9916,9 +9878,9 @@ } }, "node_modules/rollup": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.1.tgz", - "integrity": "sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.19.2.tgz", + "integrity": "sha512-6/jgnN1svF9PjNYJ4ya3l+cqutg49vOZ4rVgsDKxdl+5gpGPnByFXWGyfH9YGx9i3nfBwSu1Iyu6vGwFFA0BdQ==", "dev": true, "license": "MIT", "peer": true, @@ -9933,22 +9895,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.18.1", - "@rollup/rollup-android-arm64": "4.18.1", - "@rollup/rollup-darwin-arm64": "4.18.1", - "@rollup/rollup-darwin-x64": "4.18.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.18.1", - "@rollup/rollup-linux-arm-musleabihf": "4.18.1", - "@rollup/rollup-linux-arm64-gnu": "4.18.1", - "@rollup/rollup-linux-arm64-musl": "4.18.1", - "@rollup/rollup-linux-powerpc64le-gnu": "4.18.1", - "@rollup/rollup-linux-riscv64-gnu": "4.18.1", - "@rollup/rollup-linux-s390x-gnu": "4.18.1", - "@rollup/rollup-linux-x64-gnu": "4.18.1", - "@rollup/rollup-linux-x64-musl": "4.18.1", - "@rollup/rollup-win32-arm64-msvc": "4.18.1", - "@rollup/rollup-win32-ia32-msvc": "4.18.1", - "@rollup/rollup-win32-x64-msvc": "4.18.1", + "@rollup/rollup-android-arm-eabi": "4.19.2", + "@rollup/rollup-android-arm64": "4.19.2", + "@rollup/rollup-darwin-arm64": "4.19.2", + "@rollup/rollup-darwin-x64": "4.19.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.19.2", + "@rollup/rollup-linux-arm-musleabihf": "4.19.2", + "@rollup/rollup-linux-arm64-gnu": "4.19.2", + "@rollup/rollup-linux-arm64-musl": "4.19.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.19.2", + "@rollup/rollup-linux-riscv64-gnu": "4.19.2", + "@rollup/rollup-linux-s390x-gnu": "4.19.2", + "@rollup/rollup-linux-x64-gnu": "4.19.2", + "@rollup/rollup-linux-x64-musl": "4.19.2", + "@rollup/rollup-win32-arm64-msvc": "4.19.2", + "@rollup/rollup-win32-ia32-msvc": "4.19.2", + "@rollup/rollup-win32-x64-msvc": "4.19.2", "fsevents": "~2.3.2" } }, @@ -10005,9 +9967,9 @@ "license": "MIT" }, "node_modules/sass": { - "version": "1.77.7", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.7.tgz", - "integrity": "sha512-9ywH75cO+rLjbrZ6en3Gp8qAMwPGBapFtlsMJoDTkcMU/bSe5a6cjKVUn5Jr4Gzg5GbP3HE8cm+02pLCgcoMow==", + "version": "1.77.8", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.8.tgz", + "integrity": "sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==", "dev": true, "license": "MIT", "dependencies": { @@ -10780,9 +10742,9 @@ } }, "node_modules/terser": { - "version": "5.31.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.2.tgz", - "integrity": "sha512-LGyRZVFm/QElZHy/CPr/O4eNZOZIzsrQ92y4v9UJe/pFJjypje2yI3C2FmPtvUEnhadlSbmG2nXtdcjHOjCfxw==", + "version": "5.31.3", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.3.tgz", + "integrity": "sha512-pAfYn3NIZLyZpa83ZKigvj6Rn9c/vd5KfYGX7cN1mnzqgDcxWvrU5ZtAfIKhEXz9nRecw4z3LXkjaq96/qZqAA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -11065,9 +11027,9 @@ } }, "node_modules/typescript": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", - "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, "license": "Apache-2.0", "peer": true, @@ -11080,9 +11042,9 @@ } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.11.1.tgz", + "integrity": "sha512-mIDEX2ek50x0OlRgxryxsenE5XaQD4on5U2inY7RApK3SOJpofyw7uW2AyfMKkhAxXIceo2DeWGVGwyvng1GNQ==", "dev": true, "license": "MIT" }, @@ -11226,9 +11188,9 @@ } }, "node_modules/vite": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.3.tgz", - "integrity": "sha512-NPQdeCU0Dv2z5fu+ULotpuq5yfCS1BzKUIPhNbP3YBfAMGJXbt2nS+sbTFu+qchaqWTD+H3JK++nRwr6XIcp6A==", + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.5.tgz", + "integrity": "sha512-MdjglKR6AQXQb9JGiS7Rc2wC6uMjcm7Go/NHNO63EwiJXfuk9PgqiP/n5IDJCziMkfw9n4Ubp7lttNwz+8ZVKA==", "dev": true, "license": "MIT", "peer": true, @@ -11283,9 +11245,9 @@ } }, "node_modules/vite-node": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.0.2.tgz", - "integrity": "sha512-w4vkSz1Wo+NIQg8pjlEn0jQbcM/0D+xVaYjhw3cvarTanLLBh54oNiRbsT8PNK5GfuST0IlVXjsNRoNlqvY/fw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.0.5.tgz", + "integrity": "sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q==", "dev": true, "license": "MIT", "peer": true, @@ -11307,20 +11269,20 @@ } }, "node_modules/vitest": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.0.2.tgz", - "integrity": "sha512-WlpZ9neRIjNBIOQwBYfBSr0+of5ZCbxT2TVGKW4Lv0c8+srCFIiRdsP7U009t8mMn821HQ4XKgkx5dVWpyoyLw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.0.5.tgz", + "integrity": "sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { "@ampproject/remapping": "^2.3.0", - "@vitest/expect": "2.0.2", - "@vitest/pretty-format": "^2.0.2", - "@vitest/runner": "2.0.2", - "@vitest/snapshot": "2.0.2", - "@vitest/spy": "2.0.2", - "@vitest/utils": "2.0.2", + "@vitest/expect": "2.0.5", + "@vitest/pretty-format": "^2.0.5", + "@vitest/runner": "2.0.5", + "@vitest/snapshot": "2.0.5", + "@vitest/spy": "2.0.5", + "@vitest/utils": "2.0.5", "chai": "^5.1.1", "debug": "^4.3.5", "execa": "^8.0.1", @@ -11331,8 +11293,8 @@ "tinypool": "^1.0.0", "tinyrainbow": "^1.2.0", "vite": "^5.0.0", - "vite-node": "2.0.2", - "why-is-node-running": "^2.2.2" + "vite-node": "2.0.5", + "why-is-node-running": "^2.3.0" }, "bin": { "vitest": "vitest.mjs" @@ -11346,8 +11308,8 @@ "peerDependencies": { "@edge-runtime/vm": "*", "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "2.0.2", - "@vitest/ui": "2.0.2", + "@vitest/browser": "2.0.5", + "@vitest/ui": "2.0.5", "happy-dom": "*", "jsdom": "*" }, @@ -11715,16 +11677,16 @@ } }, "node_modules/webpack-dev-middleware/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -11832,16 +11794,16 @@ } }, "node_modules/webpack-dev-server/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -12120,6 +12082,7 @@ } }, "vendor/symfony/stimulus-bundle/assets": { + "name": "@symfony/stimulus-bundle", "version": "1.0.0", "dev": true, "license": "MIT", @@ -12129,6 +12092,7 @@ } }, "vendor/symfony/ux-autocomplete/assets": { + "name": "@symfony/ux-autocomplete", "version": "1.0.0", "dev": true, "license": "MIT", @@ -12143,12 +12107,12 @@ } }, "vendor/symfony/ux-chartjs/assets": { + "name": "@symfony/ux-chartjs", "version": "1.1.0", "dev": true, "license": "MIT", "devDependencies": { "@hotwired/stimulus": "^3.0.0", - "@types/chart.js": "^2.9.34", "chart.js": "^3.4.1 || ^4.0", "resize-observer-polyfill": "^1.5.1", "vitest-canvas-mock": "^0.3.3" diff --git a/symfony.lock b/symfony.lock index 2f973ab91..10d6e0485 100644 --- a/symfony.lock +++ b/symfony.lock @@ -64,7 +64,7 @@ "repo": "github.com/symfony/recipes", "branch": "main", "version": "2.12", - "ref": "7b1b0b637b337f6beb895589948cd119da705524" + "ref": "7266981c201efbbe02ae53c87f8bb378e3f825ae" }, "files": [ "config/packages/doctrine.yaml", @@ -578,7 +578,7 @@ "repo": "github.com/symfony/recipes", "branch": "main", "version": "0.3", - "ref": "d097c114aae82c5bc88d48ac164fe523f1003292" + "ref": "528285147494380298f8f991ee8c47abebaf79db" }, "files": [ "config/packages/mercure.yaml" From 2fea8e6835c0414cb116806b2c951827f1d98302 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Fri, 2 Aug 2024 12:19:33 +0200 Subject: [PATCH 147/335] Translations update from Hosted Weblate (#972) Co-authored-by: BentiGorlich --- translations/messages.de.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/translations/messages.de.yaml b/translations/messages.de.yaml index 130e94cb8..efd9bf785 100644 --- a/translations/messages.de.yaml +++ b/translations/messages.de.yaml @@ -925,3 +925,6 @@ flash_posting_restricted_error: Die Erstellung von Themen ist in diesem Magazin last_successful_deliver: Letzte erfolgreiche Zustellung last_successful_receive: Letzter erfolgreicher Empfang last_failed_contact: Letzter misslungener Kontakt +magazine_posting_restricted_to_mods: Erstellung von Themen auf Moderatoren beschränken +new_user_description: Dieser Nutzer ist neu (seit weniger als %days% Tagen aktiv) +new_magazine_description: Dieses Magazin ist neu (seit weniger als %days% Tagen aktiv) From 09f66d4dd1f6bf4ec3e347ad3b18830c32826163 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Fri, 2 Aug 2024 10:22:25 +0000 Subject: [PATCH 148/335] Bump version for v1.7.0-rc (#973) --- config/packages/framework.yaml | 2 +- src/Service/ProjectInfoService.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml index 789d808b2..9e5c80db6 100644 --- a/config/packages/framework.yaml +++ b/config/packages/framework.yaml @@ -17,7 +17,7 @@ framework: http_client: default_options: headers: - 'User-Agent': 'Mbin/1.6.0 (+https://%kbin_domain%/agent)' + 'User-Agent': 'Mbin/1.7.0-rc1 (+https://%kbin_domain%/agent)' #esi: true #fragments: true diff --git a/src/Service/ProjectInfoService.php b/src/Service/ProjectInfoService.php index dbf2bbefc..a549a63b7 100644 --- a/src/Service/ProjectInfoService.php +++ b/src/Service/ProjectInfoService.php @@ -10,7 +10,7 @@ class ProjectInfoService { // If updating version, please also update http client UA in [/config/packages/framework.yaml] - private const VERSION = '1.6.0'; // TODO: Retrieve the version from git tags or getenv()? + private const VERSION = '1.7.0-rc1'; // TODO: Retrieve the version from git tags or getenv()? private const NAME = 'mbin'; private const USER_AGENT = 'Mbin'; private const REPOSITORY_URL = 'https://github.com/MbinOrg/mbin'; From 3e123c244301ed9a523a20d6635154f48d2e5a79 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Fri, 2 Aug 2024 14:29:50 +0200 Subject: [PATCH 149/335] Translations update from Hosted Weblate (#974) Co-authored-by: Melroy van den Berg --- translations/messages.en.yaml | 44 +++++++++++++++++-------------- translations/messages.nl.yaml | 49 +++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 19 deletions(-) diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml index a8ea3523d..b0f49f6ad 100644 --- a/translations/messages.en.yaml +++ b/translations/messages.en.yaml @@ -61,7 +61,8 @@ cover: Cover related_posts: Related posts random_posts: Random posts federated_magazine_info: This magazine is from a federated server and may be incomplete. -disconnected_magazine_info: This magazine is not receiving updates (last activity %days% day(s) ago). +disconnected_magazine_info: This magazine is not receiving updates (last activity + %days% day(s) ago). always_disconnected_magazine_info: This magazine is not receiving updates. subscribe_for_updates: Subscribe to start receiving updates. federated_user_info: This profile is from a federated server and may be incomplete. @@ -314,11 +315,11 @@ approve: Approve ban: Ban unban: Unban ban_hashtag_btn: Ban Hashtag -ban_hashtag_description: Banning a hashtag will stop posts with this hashtag from being created, - as well as hiding existing posts with this hashtag. +ban_hashtag_description: Banning a hashtag will stop posts with this hashtag from + being created, as well as hiding existing posts with this hashtag. unban_hashtag_btn: Unban Hashtag -unban_hashtag_description: Unbanning a hashtag will allow creating posts with this hashtag again. - Existing posts with this hashtag are no longer hidden. +unban_hashtag_description: Unbanning a hashtag will allow creating posts with this + hashtag again. Existing posts with this hashtag are no longer hidden. filters: Filters approved: Approved rejected: Rejected @@ -449,13 +450,14 @@ federation_page_enabled: Federation page enabled federation_page_allowed_description: Known instances we federate with federation_page_disallowed_description: Instances we do not federate with federation_page_dead_title: Dead instances -federation_page_dead_description: Instances that we could not deliver at least 10 activities in a row and where the last successful deliver was more than a week ago +federation_page_dead_description: Instances that we could not deliver at least 10 + activities in a row and where the last successful deliver was more than a week ago federated_search_only_loggedin: Federated search limited if not logged in sidebar_sections_local_only: Restrict "Random X" and "Active People" sections to local only account_deletion_title: Account deletion -account_deletion_description: Your account will be deleted in 30 days unless you choose to delete the account immediately. - The account cannot be restored once deleted. +account_deletion_description: Your account will be deleted in 30 days unless you choose + to delete the account immediately. The account cannot be restored once deleted. account_deletion_button: Delete Account account_deletion_immediate: Delete immediately more_from_domain: More from domain @@ -689,14 +691,14 @@ delete_content_desc: Delete the user's content while leaving the responses of ot users in the created threads, posts and comments. purge_content_desc: Completely purge the user's content, including deleting the responses of other users in created threads, posts and comments. -delete_account_desc: Delete the account, including the responses - of other users in created threads, posts and comments. +delete_account_desc: Delete the account, including the responses of other users in + created threads, posts and comments. schedule_delete_account: Schedule Deletion -schedule_delete_account_desc: Schedule the deletion of this account in 30 days. - This will hide the user and their content as well as prevent the user from logging in. +schedule_delete_account_desc: Schedule the deletion of this account in 30 days. This + will hide the user and their content as well as prevent the user from logging in. remove_schedule_delete_account: Remove Scheduled Deletion -remove_schedule_delete_account_desc: Remove the scheduled deletion. - All the content will be available again and the user will be able to login. +remove_schedule_delete_account_desc: Remove the scheduled deletion. All the content + will be available again and the user will be able to login. two_factor_authentication: Two-factor authentication two_factor_backup: Two-factor authentication backup codes 2fa.authentication_code.label: Authentication Code @@ -821,10 +823,12 @@ show: Show hide: Hide edited: edited sso_registrations_enabled: SSO registrations enabled -sso_registrations_enabled.error: New account registrations with third-party identity managers are currently disabled. +sso_registrations_enabled.error: New account registrations with third-party identity + managers are currently disabled. sso_only_mode: Restrict login and registration to SSO methods only related_entry: Related -restrict_magazine_creation: Restrict local magazine creation to admins and global mods +restrict_magazine_creation: Restrict local magazine creation to admins and global + mods sso_show_first: Show SSO first on login and registration pages continue_with: Continue with reported_user: Reported user @@ -869,11 +873,13 @@ show_related_entries: Show random threads show_related_posts: Show random posts show_active_users: Show active users notification_title_new_report: A new report was created -magazine_posting_restricted_to_mods_warning: Only mods can create threads in this magazine -flash_posting_restricted_error: Creating threads is restricted to mods in this magazine and you are not one +magazine_posting_restricted_to_mods_warning: Only mods can create threads in this + magazine +flash_posting_restricted_error: Creating threads is restricted to mods in this magazine + and you are not one server_software: Server software version: Version -last_successful_deliver: Last successful deliver +last_successful_deliver: Last successful delivery last_successful_receive: Last successful receive last_failed_contact: Last failed contact magazine_posting_restricted_to_mods: Restrict thread creation to moderators diff --git a/translations/messages.nl.yaml b/translations/messages.nl.yaml index 823363f92..5ef4b3785 100644 --- a/translations/messages.nl.yaml +++ b/translations/messages.nl.yaml @@ -871,3 +871,52 @@ sso_show_first: Toon SSO (Single-Sign-On) als eerste op de inlog-en registratiep continue_with: Daargaan met magazine_log_entry_pinned: vastgezette gesprek magazine_log_entry_unpinned: verwijderde vastgezette gesprek +own_content_reported_accepted: Een melding over uw inhoud was geaccepteerd. +open_report: open melding +report_accepted: Een melding was geaccepteerd +show_related_entries: Toon willekeurige gesprekken +show_related_magazines: Toon willekeurige tijdschriften +show_related_posts: Toon willekeurige berichten +show_active_users: Toon actieve gebruikers +federation_page_dead_title: Dode instanties +federation_page_dead_description: Instanties waarin we niet minimaal 10 activiteiten + achter elkaar konden leveren en waarbij de laatste succesvolle levering meer dan + een week geleden was +reporting_user: Rapporterende gebruiker +reported: gerapporteerd +report_subject: Onderwerp +own_report_rejected: Uw melding was afgewezen +own_report_accepted: Uw rapport is geaccepteerd +manually_approves_followers: Volgers handmatig goedkeuren +register_push_notifications_button: Registreer voor Pushmeldingen +unregister_push_notifications_button: Verwijder Push registratie +test_push_notifications_button: Test pushmeldingen +test_push_message: Hallo Wereld! +notification_title_new_comment: New commentaar +notification_title_mention: Je werd genoemd +notification_title_new_reply: Nieuw Antwoord +notification_title_new_thread: Nieuw gesprek +notification_title_new_report: Een nieuwe melding is aangemaakt +flash_posting_restricted_error: Het maken van gesprekken is beperkt tot moderators + van dit tijdschrift en jij bent er geen van +server_software: Server software +version: Versie +reported_user: Gerapporteerde gebruiker +notification_title_removed_comment: Een opmerking is verwijderd +notification_title_ban: Je bent verbannen +notification_title_removed_post: Een bericht is verwijderd +notification_title_removed_thread: Een gesprek is verwijderd +notification_title_message: Nieuw direct bericht +notification_title_edited_comment: Een opmerking is gewijzigd +notification_title_new_post: Nieuw Bericht +notification_title_edited_thread: Een gesprek is gewijzgd +notification_title_edited_post: Een bericht is gewijzigd +magazine_posting_restricted_to_mods_warning: Enkel moderators kunnen een nieuw gesprek + aanmaken in dit tijdschrift +last_successful_deliver: Laatste succesvolle levering +last_successful_receive: Laatste succesvolle ontvangst +last_failed_contact: Laatste mislukte contact +magazine_posting_restricted_to_mods: Beperk het aanmaken van gesprekken tot moderators +new_user_description: Deze gebruiker is nieuw (actief voor minder dan %days% dagen) +new_magazine_description: Dit tijdschrift is nieuw (actief voor minder dan %days% + dagen) From de7aeed2692fcb97b4da04d7d23840c3a5acc87f Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Fri, 2 Aug 2024 12:49:40 +0000 Subject: [PATCH 150/335] Remove the newly introduced jitter (#975) --- config/packages/messenger.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/config/packages/messenger.yaml b/config/packages/messenger.yaml index a4e7c109b..fdf5a31d4 100644 --- a/config/packages/messenger.yaml +++ b/config/packages/messenger.yaml @@ -21,6 +21,7 @@ framework: delay: 300000 multiplier: 4 max_delay: 86400000 + jitter: 0 serializer: messenger.transport.symfony_serializer inbox: dsn: "%env(MESSENGER_TRANSPORT_DSN)%" @@ -37,6 +38,7 @@ framework: delay: 300000 multiplier: 4 max_delay: 86400000 + jitter: 0 serializer: messenger.transport.symfony_serializer receive: dsn: "%env(MESSENGER_TRANSPORT_DSN)%" @@ -53,6 +55,7 @@ framework: delay: 300000 multiplier: 4 max_delay: 86400000 + jitter: 0 serializer: messenger.transport.symfony_serializer deliver: dsn: "%env(MESSENGER_TRANSPORT_DSN)%" @@ -69,6 +72,7 @@ framework: delay: 300000 multiplier: 4 max_delay: 86400000 + jitter: 0 serializer: messenger.transport.symfony_serializer outbox: dsn: "%env(MESSENGER_TRANSPORT_DSN)%" @@ -85,6 +89,7 @@ framework: delay: 300000 multiplier: 4 max_delay: 86400000 + jitter: 0 serializer: messenger.transport.symfony_serializer resolve: dsn: "%env(MESSENGER_TRANSPORT_DSN)%" @@ -101,6 +106,7 @@ framework: delay: 300000 multiplier: 4 max_delay: 86400000 + jitter: 0 serializer: messenger.transport.symfony_serializer old: dsn: "%env(MESSENGER_TRANSPORT_DSN)%" @@ -112,6 +118,7 @@ framework: delay: 300000 multiplier: 4 max_delay: 86400000 + jitter: 0 serializer: messenger.transport.symfony_serializer failed: failure_transport: dead @@ -119,6 +126,7 @@ framework: max_retries: 3 delay: 1800000 multiplier: 2 + jitter: 0 dsn: "doctrine://default?queue_name=failed" serializer: messenger.transport.symfony_serializer dead: From 974f9e16a86007e78a2915151e66c6623650e5f4 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Fri, 2 Aug 2024 13:05:16 +0000 Subject: [PATCH 151/335] Revert accidental change (#976) --- templates/entry/_form_image.html.twig | 8 -------- 1 file changed, 8 deletions(-) diff --git a/templates/entry/_form_image.html.twig b/templates/entry/_form_image.html.twig index 6e35de486..6c18f211f 100644 --- a/templates/entry/_form_image.html.twig +++ b/templates/entry/_form_image.html.twig @@ -12,14 +12,6 @@ 'data-action' : 'input-length#updateDisplay', 'data-input-length-max-value' : constant('App\\Entity\\Entry::MAX_TITLE_LENGTH') }}) }} - {{ component('editor_toolbar', {id: 'entry_image_body'}) }} - {{ form_row(form.body, { - label: false, attr: { - placeholder: 'body', - 'data-controller': 'rich-textarea input-length autogrow', - 'data-action' : 'input-length#updateDisplay', - 'data-input-length-max-value' : constant('App\\Entity\\Entry::MAX_BODY_LENGTH') - }}) }} {{ form_row(form.magazine, {label: false}) }} {{ form_row(form.tags, {label: 'tags'}) }} {{ form_row(form.badges, {label: 'badges'}) }} From 6ece14c48b9798c2105b3555f326f53af5789995 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Fri, 2 Aug 2024 14:12:02 +0000 Subject: [PATCH 152/335] Docs: Move mercure supervisor config, add media reverse proxy (#968) --- docs/02-admin/01-installation/bare_metal.md | 42 ++++++---------- docs/02-admin/02-configuration/nginx.md | 48 +++++++++++++++++++ docs/02-admin/03-optional-features/mercure.md | 33 ++++++++++++- 3 files changed, 95 insertions(+), 28 deletions(-) diff --git a/docs/02-admin/01-installation/bare_metal.md b/docs/02-admin/01-installation/bare_metal.md index e9cae1da5..97c4c4e03 100644 --- a/docs/02-admin/01-installation/bare_metal.md +++ b/docs/02-admin/01-installation/bare_metal.md @@ -159,13 +159,24 @@ sudo setfacl -R -m u:"$HTTPDUSER":rwX -m u:$(whoami):rwX var ### The dot env file -Make a copy of the `.env.example` the and edit the `.env` configure file: +The `.env` file holds a lot of environment variables and is the main point for configuring mbin. +We suggest you place your variables in the `.env.local` file and have a 'clean' default one as the `.env` file. +Each time this documentation talks about the `.env` file be sure to edit the `.env.local` file if you decided to use that. + +> In all environments, the following files are loaded if they exist, the latter taking precedence over the former: +> - .env contains default values for the environment variables needed by the app +> - .env.local uncommitted file with local overrides + +Make a copy of the `.env.example` to `.env` and `.env.local` and edit the `.env.local` file: ```bash cp .env.example .env -nano .env +cp .env.example .env.local +nano .env.local ``` +#### Service Passwords + Make sure you have substituted all the passwords and configured the basic services in `.env` file. > [!NOTE] @@ -179,7 +190,7 @@ RABBITMQ_PASSWORD="{!SECRET!!KEY!-16_2-!}" MERCURE_JWT_SECRET="{!SECRET!!KEY!-32_3-!}" ``` -Other important `.env` configs: +#### Other important `.env` configs: ```ini # Configure your media URL correctly: @@ -200,7 +211,7 @@ MAILER_DSN=smtp://username:password@smtpserver.tld:587?encryption=tls&auth_mode= MAILER_DSN=smtp://username:password@smtpserver.tld:465?encryption=ssl&auth_mode=log ``` -OAuth2 keys for API credential grants: +#### OAuth2 keys for API credential grants 1. Create an RSA key pair using OpenSSL: @@ -539,29 +550,6 @@ Save and close the file. Note: you can increase the number of running messenger jobs if your queue is building up (i.e. more messages are coming in than your messengers can handle) -We also use supervisor for running Mercure job: - -```bash -sudo nano /etc/supervisor/conf.d/mercure.conf -``` - -With the following content: - -```ini -[program:mercure] -command=/usr/local/bin/mercure run --config /var/www/mbin/metal/caddy/Caddyfile -process_name=%(program_name)s_%(process_num)s -numprocs=1 -environment=MERCURE_PUBLISHER_JWT_KEY="{!SECRET!!KEY!-32_3-!}",MERCURE_SUBSCRIBER_JWT_KEY="{!SECRET!!KEY!-32_3-!}",SERVER_NAME=":3000",HTTP_PORT="3000" -directory=/var/www/mbin/metal/caddy -autostart=true -autorestart=true -startsecs=5 -startretries=10 -user=www-data -redirect_stderr=false -stdout_syslog=true -``` Save and close the file. Restart supervisor jobs: diff --git a/docs/02-admin/02-configuration/nginx.md b/docs/02-admin/02-configuration/nginx.md index df2dbef83..c108b160f 100644 --- a/docs/02-admin/02-configuration/nginx.md +++ b/docs/02-admin/02-configuration/nginx.md @@ -242,3 +242,51 @@ Restart (or reload) NGINX: ```bash sudo systemctl restart nginx ``` + +## Media reverse proxy + +we suggest that you do not use this configuration: +```dotenv +KBIN_STORAGE_URL=https://mbin.domain.tld/media +``` + +Instead we suggest to use a subdomain for serving your media files: +```dotenv +KBIN_STORAGE_URL=https://media.mbin.domain.tld +``` + +That way you can let nginx cache media assets and seamlessly switch to an object storage provider later. + +```bash +sudo nano /etc/nginx/sites-available/mbin-media.conf +``` + +```nginx +proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=CACHE:10m inactive=7d max_size=10g; + +server { + server_name media.mbin.domain.tld; + root /var/www/mbin/public/media; + + listen 80; +} +``` + +Be sure that the `root /path` is correct (maybe you use `/var/www/kbin/public`). + +Enable the NGINX site, using a symlink: + +```bash +sudo ln -s /etc/nginx/sites-available/mbin-media.conf /etc/nginx/sites-enabled/ +``` + +> [!TIP] +> before reloading nginx in a production environment you can run `nginx -t` to test your configuration. +> If your configuration is faulty and you run `systemctl reload nginx` it will crash the webserver. + +Run `systemctl reload nginx` so the site is loaded. +For it to be a usable https site you have to run `certbot --nginx` and select the media domain or supply your certificates manually. + +> [!TIP] +> don't forget to enable http2 by adding `http2 on;` after certbot ran (underneath the `listen 443 ssl;` line) + diff --git a/docs/02-admin/03-optional-features/mercure.md b/docs/02-admin/03-optional-features/mercure.md index 9b9de00ec..490f32d58 100644 --- a/docs/02-admin/03-optional-features/mercure.md +++ b/docs/02-admin/03-optional-features/mercure.md @@ -2,6 +2,8 @@ More info: [Mercure Website](https://mercure.rocks/), Mercure is used in Mbin for real-time communication between the server and the clients. +### Caddybundle + Download and install Mercure (we are using [Caddyserver.com](https://caddyserver.com/download?package=github.com%2Fdunglas%2Fmercure) mirror to download Mercure): ```bash @@ -89,4 +91,33 @@ Ensure not random formatting errors in the Caddyfile mercure fmt metal/caddy/Caddyfile --overwrite ``` -Mercure will be configured further in the next section (Supervisor). +### Supervisor Job + +We use supervisor for running the Mercure job: + +```bash +sudo nano /etc/supervisor/conf.d/mercure.conf +``` + +With the following content: + +```ini +[program:mercure] +command=/usr/local/bin/mercure run --config /var/www/mbin/metal/caddy/Caddyfile +process_name=%(program_name)s_%(process_num)s +numprocs=1 +environment=MERCURE_PUBLISHER_JWT_KEY="{!SECRET!!KEY!-32_3-!}",MERCURE_SUBSCRIBER_JWT_KEY="{!SECRET!!KEY!-32_3-!}",SERVER_NAME=":3000",HTTP_PORT="3000" +directory=/var/www/mbin/metal/caddy +autostart=true +autorestart=true +startsecs=5 +startretries=10 +user=www-data +redirect_stderr=false +stdout_syslog=true +``` + +Afterwards let supervisor reread the configuration and update the processing groups: +```bash +sudo supervisorctl reread && sudo supervisorctl update && sudo supervisorctl start all +``` From ec138cf9d0375bbb69874dd9c429054ddf89a206 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Fri, 2 Aug 2024 14:15:53 +0000 Subject: [PATCH 153/335] Docs: add s3 reverse proxy and migration to docs (#967) --- .../03-optional-features/s3_storage.md | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/docs/02-admin/03-optional-features/s3_storage.md b/docs/02-admin/03-optional-features/s3_storage.md index 7423ffc0a..39104f3ee 100644 --- a/docs/02-admin/03-optional-features/s3_storage.md +++ b/docs/02-admin/03-optional-features/s3_storage.md @@ -1,5 +1,17 @@ # S3 Images storage +## Migrating the media files + +If you're starting a new instance, you can skip this part. + +To migrate to s3 storage we have to sync the media files located at `/var/www/mbin/public/media` into our s3 bucket. +We suggest running the sync once while your instance is still up and using the local storage for media, then shutting mbin down, +configure it to use the s3 storage and do another sync to get all the files created during the initial sync. + +To actually do the file sync you can use different tools, like `aws-cli`, `rclone` and others, +just search for it and you will find plenty tutorials on how to do that + +## Configuring mbin Edit your `.env` file: ```ini @@ -36,3 +48,73 @@ oneup_flysystem: adapter: kbin.s3_adapter alias: League\Flysystem\Filesystem ``` + +## NGINX reverse proxy + +If you are using an object storage provider, we strongly advise you to use a media reverse proxy. +That way media URLs will not change and break links on remote instances when you decide to switch providers +and it hides your s3 endpoint from users of your instance. + +This replaces the media reverse proxy from [NGINX](../02-configuration/nginx.md). + +If you already had a reverse proxy for your media, then you only have to change the NGINX config, +otherwise please follow the steps in our [media-reverse-proxy](../02-configuration/nginx.md) docs + +This config is heavily inspired by [mastodons nginx config](https://docs.joinmastodon.org/admin/optional/object-storage-proxy/) + +```nginx +proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=CACHE:10m inactive=7d max_size=10g; + +server { + server_name https://media.mbin.domain.tld; + + location / { + try_files $uri @s3; + } + + set $s3_backend 'https://your.s3.endpoint.tld'; + + location @s3 { + limit_except GET { + deny all; + } + + resolver 1.1.1.1; + + proxy_set_header Accept 'image/*'; + proxy_set_header Connection ''; + proxy_set_header Authorization ''; + proxy_hide_header Set-Cookie; + proxy_hide_header 'Access-Control-Allow-Origin'; + proxy_hide_header 'Access-Control-Allow-Methods'; + proxy_hide_header 'Access-Control-Allow-Headers'; + proxy_hide_header x-amz-id-2; + proxy_hide_header x-amz-request-id; + proxy_hide_header x-amz-meta-server-side-encryption; + proxy_hide_header x-amz-server-side-encryption; + proxy_hide_header x-amz-bucket-region; + proxy_hide_header x-amzn-requestid; + proxy_ignore_headers Set-Cookie; + proxy_pass $s3_backend$uri; + proxy_intercept_errors off; + + proxy_cache CACHE; + proxy_cache_valid 200 48h; + proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; + proxy_cache_lock on; + + expires 1y; + add_header Cache-Control public; + add_header 'Access-Control-Allow-Origin' '*'; + add_header X-Cache-Status $upstream_cache_status; + add_header X-Content-Type-Options nosniff; + add_header Content-Security-Policy "default-src 'none'; form-action 'none'"; + } + listen 80; +} +``` + +For it to be a usable https site you have to run certbot or supply your certificates manually. + +> [!TIP] +> don't forget to enable http2 by adding `http2 on;` after certbot ran From bb4d7e25bb4cda8bb4a7db2e6919fe2dc7c2af51 Mon Sep 17 00:00:00 2001 From: debounced <35878315+nobodyatroot@users.noreply.github.com> Date: Sat, 3 Aug 2024 07:27:16 -0500 Subject: [PATCH 154/335] Clean up doctrine deprecation warnings (#977) --- config/packages/doctrine.yaml | 4 +--- src/Kernel.php | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/config/packages/doctrine.yaml b/config/packages/doctrine.yaml index 31320c0ad..a5126459e 100644 --- a/config/packages/doctrine.yaml +++ b/config/packages/doctrine.yaml @@ -19,9 +19,7 @@ doctrine: JSONB_CONTAINS: Scienta\DoctrineJsonFunctions\Query\AST\Functions\Postgresql\JsonbContains auto_generate_proxy_classes: true enable_lazy_ghost_objects: true - # This option needs to be set to 'false', otherwise PHP class inheritance will fail with - # a separate sequence number generator table in PostgreSQL for each child class - report_fields_where_declared: false + report_fields_where_declared: true validate_xml_mapping: true naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware auto_mapping: true diff --git a/src/Kernel.php b/src/Kernel.php index 2d0398083..05e84dd6f 100644 --- a/src/Kernel.php +++ b/src/Kernel.php @@ -4,7 +4,11 @@ namespace App; +use Doctrine\DBAL\Platforms\PostgreSQLPlatform; +use Doctrine\ORM\Mapping\ClassMetadata; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Kernel as BaseKernel; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; @@ -27,4 +31,23 @@ protected function configureRoutes(RoutingConfigurator $routes): void $routes->import($projectDir.'/config/{routes}.php'); } } + + #[Override] + protected function build(ContainerBuilder $container): void + { + $container->addCompilerPass(new class() implements CompilerPassInterface { + public function process(ContainerBuilder $container): void + { + $container->getDefinition('doctrine.orm.default_configuration') + ->addMethodCall( + 'setIdentityGenerationPreferences', + [ + [ + PostgreSQLPlatform::class => ClassMetadata::GENERATOR_TYPE_SEQUENCE, + ], + ] + ); + } + }); + } } From fe6a948b825dd62e5c88d7addb73f52a9d908bfb Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Sat, 3 Aug 2024 13:32:46 +0000 Subject: [PATCH 155/335] When editing an entry only use one type (#971) Co-authored-by: debounced <35878315+nobodyatroot@users.noreply.github.com> --- .../entry_link_create_controller.js | 28 ++++-- src/Controller/Entry/EntryEditController.php | 12 ++- src/Controller/Entry/EntryFormTrait.php | 2 +- src/Form/EntryEditType.php | 99 +++++++++++++++++++ .../DisableFieldsOnEntryEdit.php | 13 --- src/Service/EntryManager.php | 6 ++ templates/entry/_form_edit.html.twig | 73 ++++++++++++++ ...article.html.twig => edit_entry.html.twig} | 6 +- templates/entry/edit_image.html.twig | 25 ----- templates/entry/edit_link.html.twig | 28 ------ translations/messages.en.yaml | 4 +- 11 files changed, 210 insertions(+), 86 deletions(-) create mode 100644 src/Form/EntryEditType.php create mode 100644 templates/entry/_form_edit.html.twig rename templates/entry/{edit_article.html.twig => edit_entry.html.twig} (75%) delete mode 100644 templates/entry/edit_image.html.twig delete mode 100644 templates/entry/edit_link.html.twig diff --git a/assets/controllers/entry_link_create_controller.js b/assets/controllers/entry_link_create_controller.js index a4a2b62d8..c869e9a39 100644 --- a/assets/controllers/entry_link_create_controller.js +++ b/assets/controllers/entry_link_create_controller.js @@ -10,6 +10,8 @@ export default class extends ApplicationController { loading: Boolean, }; + timeoutId = null; + connect() { useThrottle(this, { wait: 1000, @@ -23,20 +25,28 @@ export default class extends ApplicationController { } } - async fetchLink(event) { + fetchLink(event) { if (!event.target.value) { return; } - try { - this.loadingValue = true; - - await this.fetchTitleAndDescription(event); - - this.loadingValue = false; - } catch (e) { - this.loadingValue = false; + if (this.timeoutId) { + window.clearTimeout(this.timeoutId); + this.timeoutId = null; } + + this.timeoutId = window.setTimeout(() => { + this.loadingValue = true; + this.fetchTitleAndDescription(event) + .then(() => { + this.loadingValue = false; + this.timeoutId = null; + }) + .catch(() => { + this.loadingValue = false; + this.timeoutId = null; + }) + }, 1000) } loadingValueChanged(val) { diff --git a/src/Controller/Entry/EntryEditController.php b/src/Controller/Entry/EntryEditController.php index 22829f411..d54357a9b 100644 --- a/src/Controller/Entry/EntryEditController.php +++ b/src/Controller/Entry/EntryEditController.php @@ -5,10 +5,12 @@ namespace App\Controller\Entry; use App\Controller\AbstractController; +use App\DTO\EntryDto; use App\Entity\Entry; use App\Entity\Magazine; -use App\PageView\EntryPageView; +use App\Form\EntryEditType; use App\Service\EntryManager; +use Psr\Log\LoggerInterface; use Symfony\Bridge\Doctrine\Attribute\MapEntity; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -18,10 +20,10 @@ class EntryEditController extends AbstractController { use EntryTemplateTrait; - use EntryFormTrait; public function __construct( private readonly EntryManager $manager, + private readonly LoggerInterface $logger, ) { } @@ -36,7 +38,7 @@ public function __invoke( ): Response { $dto = $this->manager->createDto($entry); - $form = $this->createFormByType((new EntryPageView(1))->resolveType($entry->type), $dto); + $form = $this->createForm(EntryEditType::class, $dto); try { $form->handleRequest($request); @@ -44,6 +46,8 @@ public function __invoke( if (!$this->isGranted('create_content', $dto->magazine)) { throw new AccessDeniedHttpException(); } + /** @var EntryDto $dto */ + $dto = $form->getData(); $entry = $this->manager->edit($entry, $dto, $this->getUserOrThrow()); @@ -57,7 +61,7 @@ public function __invoke( } return $this->render( - $this->getTemplateName((new EntryPageView(1))->resolveType($entry->type), true), + 'entry/edit_entry.html.twig', [ 'magazine' => $magazine, 'entry' => $entry, diff --git a/src/Controller/Entry/EntryFormTrait.php b/src/Controller/Entry/EntryFormTrait.php index a46b1a06f..400e47224 100644 --- a/src/Controller/Entry/EntryFormTrait.php +++ b/src/Controller/Entry/EntryFormTrait.php @@ -12,7 +12,7 @@ use Symfony\Component\Form\FormInterface; /** - * @method createForm(string $class) + * @method FormInterface createForm(string $class, mixed $data = null, array $options = []) */ trait EntryFormTrait { diff --git a/src/Form/EntryEditType.php b/src/Form/EntryEditType.php new file mode 100644 index 000000000..1747be892 --- /dev/null +++ b/src/Form/EntryEditType.php @@ -0,0 +1,99 @@ +add('url', UrlType::class, ['required' => false]) + ->add('title', TextareaType::class) + ->add('body', TextareaType::class) + ->add('magazine', MagazineAutocompleteType::class) + ->add('tags', TextType::class, [ + 'required' => false, + 'autocomplete' => true, + 'tom_select_options' => [ + 'create' => true, + 'createOnBlur' => true, + 'delimiter' => ' ', + ], + ]) + ->add( + 'badges', + BadgesType::class, + [ + 'required' => false, + ] + ) + ->add( + 'image', + FileType::class, + [ + 'constraints' => ImageConstraint::default(), + 'mapped' => false, + 'required' => false, + ] + ) + ->add('imageUrl', UrlType::class, [ + 'required' => false, + ]) + ->add('imageAlt', TextType::class, [ + 'required' => false, + ]) + ->add('isAdult', CheckboxType::class, [ + 'required' => false, + ]) + ->add('lang', LanguageType::class) + ->add('isOc', CheckboxType::class, [ + 'required' => false, + ]) + ->add('submit', SubmitType::class); + + $builder->get('tags')->addModelTransformer( + new TagTransformer() + ); + + $builder->addEventSubscriber($this->defaultLanguage); + $builder->addEventSubscriber($this->disableFieldsOnEntryEdit); + $builder->addEventSubscriber($this->imageListener); + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults( + [ + 'data_class' => EntryDto::class, + ] + ); + } +} diff --git a/src/Form/EventListener/DisableFieldsOnEntryEdit.php b/src/Form/EventListener/DisableFieldsOnEntryEdit.php index a5c8e2122..188980d5d 100644 --- a/src/Form/EventListener/DisableFieldsOnEntryEdit.php +++ b/src/Form/EventListener/DisableFieldsOnEntryEdit.php @@ -34,18 +34,5 @@ public function preSetData(FormEvent $event): void \get_class($field->getConfig()->getType()->getInnerType()), $attrs ); - - if ($form->has('url')) { - $field = $form->get('url'); - $attrs = $field->getConfig()->getOptions(); - $attrs['disabled'] = 'disabled'; - - $form->remove($field->getName()); - $form->add( - $field->getName(), - \get_class($field->getConfig()->getType()->getInnerType()), - $attrs - ); - } } } diff --git a/src/Service/EntryManager.php b/src/Service/EntryManager.php index 8798bc063..e176e28d1 100644 --- a/src/Service/EntryManager.php +++ b/src/Service/EntryManager.php @@ -23,6 +23,7 @@ use App\Exception\UserBannedException; use App\Factory\EntryFactory; use App\Message\DeleteImageMessage; +use App\Message\EntryEmbedMessage; use App\Repository\EntryRepository; use App\Repository\ImageRepository; use App\Service\ActivityPub\ApHttpClient; @@ -184,6 +185,7 @@ public function edit(Entry $entry, EntryDto $dto, User $editedBy): Entry Assert::same($entry->magazine->getId(), $dto->magazine->getId()); $entry->title = $dto->title; + $oldUrl = $entry->url; $entry->url = $dto->url; $entry->body = $dto->body; $entry->lang = $dto->lang; @@ -219,6 +221,10 @@ public function edit(Entry $entry, EntryDto $dto, User $editedBy): Entry $this->bus->dispatch(new DeleteImageMessage($oldImage->getId())); } + if ($entry->url !== $oldUrl) { + $this->bus->dispatch(new EntryEmbedMessage($entry->getId())); + } + $this->dispatcher->dispatch(new EntryEditedEvent($entry, $editedBy)); return $entry; diff --git a/templates/entry/_form_edit.html.twig b/templates/entry/_form_edit.html.twig new file mode 100644 index 000000000..9034a2acc --- /dev/null +++ b/templates/entry/_form_edit.html.twig @@ -0,0 +1,73 @@ +{% form_theme form.lang 'form/lang_select.html.twig' %} + +{{ form_start(form, {attr: {class: 'entry_edit'}}) }} + +

        + {% set label %} + URL +
        + Loading... +
        + {% endset %} + {{ form_label(form.url, label, {'label_html': true}) }} + {{ form_widget(form.url, {attr: {'data-action': 'entry-link-create#fetchLink', 'data-entry-link-create-target': 'url'}}) }} +
        + + {{ form_row(form.title, { + label: 'title', attr: { + 'data-controller' : "input-length autogrow", + 'data-entry-link-create-target': 'title', + 'data-action' : 'input-length#updateDisplay', + 'data-input-length-max-value' : constant('App\\Entity\\Entry::MAX_TITLE_LENGTH') + }}) }} + {{ component('editor_toolbar', {id: 'entry_article_body'}) }} + {{ form_row(form.body, { + label: false, attr: { + placeholder: 'body', + 'data-controller': 'rich-textarea input-length autogrow', + 'data-entry-link-create-target': 'description', + 'data-action' : 'input-length#updateDisplay', + 'data-input-length-max-value' : constant('App\\Entity\\Entry::MAX_BODY_LENGTH') + }}) }} + {{ form_row(form.magazine, {label: false}) }} + {{ form_row(form.tags, {label: 'tags'}) }} + {{ form_row(form.badges, {label: 'badges'}) }} +
        + {{ form_row(form.isAdult, {label: 'is_adult', row_attr: {class: 'checkbox'}}) }} + {{ form_row(form.isOc, {label: 'oc', row_attr: {class: 'checkbox'}}) }} +
        +
        +
          + {% if entry.image is not same as null %} + {{ entry.image.altText }} + + {% endif %} +
        • + + +
        • +
        • + {{ form_row(form.lang, {label: false}) }} +
        • +
        • + {{ form_row(form.submit, {label: 'edit_entry', attr: {class: 'btn btn__primary'}}) }} +
        • +
        +
        +{{ form_end(form) }} diff --git a/templates/entry/edit_article.html.twig b/templates/entry/edit_entry.html.twig similarity index 75% rename from templates/entry/edit_article.html.twig rename to templates/entry/edit_entry.html.twig index ec7330b2b..f1626172f 100644 --- a/templates/entry/edit_article.html.twig +++ b/templates/entry/edit_entry.html.twig @@ -18,11 +18,11 @@ class: 'section--top' }) }} -

        {{ 'edit_article'|trans }}

        +

        {{ 'edit_entry'|trans }}

        {% include 'layout/_flash.html.twig' %}
        -
        - {% include 'entry/_form_article.html.twig' with {edit: true} %} +
        + {% include 'entry/_form_edit.html.twig' %}
        {% endblock %} diff --git a/templates/entry/edit_image.html.twig b/templates/entry/edit_image.html.twig deleted file mode 100644 index a2d4dc7cc..000000000 --- a/templates/entry/edit_image.html.twig +++ /dev/null @@ -1,25 +0,0 @@ -{% extends 'base.html.twig' %} - -{%- block title -%} - {{- 'edit_photo'|trans }} - {{ parent() -}} -{%- endblock -%} - -{% block mainClass %}page-entry-create page-entry-edit-image{% endblock %} - -{% block header_nav %} -{% endblock %} - -{% block sidebar_top %} -{% endblock %} - -{% block body %} - {{ component('entry', {entry: entry, class: 'section--top'}) }} - -

        {{ 'edit_photo'|trans }}

        - {% include 'layout/_flash.html.twig' %} -
        -
        - {% include 'entry/_form_image.html.twig' with {edit: true} %} -
        -
        -{% endblock %} diff --git a/templates/entry/edit_link.html.twig b/templates/entry/edit_link.html.twig deleted file mode 100644 index c8914d0dc..000000000 --- a/templates/entry/edit_link.html.twig +++ /dev/null @@ -1,28 +0,0 @@ -{% extends 'base.html.twig' %} - -{%- block title -%} - {{- 'edit_link'|trans }} - {{ parent() -}} -{%- endblock -%} - -{% block mainClass %}page-entry-create page-entry-edit-link{% endblock %} - -{% block header_nav %} -{% endblock %} - -{% block sidebar_top %} -{% endblock %} - -{% block body %} - {{ component('entry', { - entry: entry, - class: 'section--top' - }) }} - -

        {{ 'edit_link'|trans }}

        - {% include 'layout/_flash.html.twig' %} -
        -
        - {% include 'entry/_form_link.html.twig' with {edit: true} %} -
        -
        -{% endblock %} diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml index b0f49f6ad..111a48c84 100644 --- a/translations/messages.en.yaml +++ b/translations/messages.en.yaml @@ -183,9 +183,7 @@ edit: Edit are_you_sure: Are you sure? moderate: Moderate reason: Reason -edit_link: Edit link -edit_article: Edit thread -edit_photo: Edit photo +edit_entry: Edit thread delete: Delete edit_post: Edit post edit_comment: Save changes From c0c0c20c4d7f87ab922afe7212535c4f90191019 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Sat, 3 Aug 2024 15:35:15 +0200 Subject: [PATCH 156/335] Translations update from Hosted Weblate (#979) --- translations/messages.bg.yaml | 3 --- translations/messages.de.yaml | 3 --- translations/messages.el.yaml | 3 --- translations/messages.eo.yaml | 3 --- translations/messages.es.yaml | 3 --- translations/messages.fr.yaml | 3 --- translations/messages.gl.yaml | 3 --- translations/messages.it.yaml | 3 --- translations/messages.ja.yaml | 3 --- translations/messages.nl.yaml | 3 --- translations/messages.pl.yaml | 3 --- translations/messages.pt.yaml | 3 --- translations/messages.ru.yaml | 3 --- translations/messages.tr.yaml | 3 --- translations/messages.uk.yaml | 3 --- translations/messages.zh_TW.yaml | 3 --- 16 files changed, 48 deletions(-) diff --git a/translations/messages.bg.yaml b/translations/messages.bg.yaml index 0b6c6ec7d..b93c4af48 100644 --- a/translations/messages.bg.yaml +++ b/translations/messages.bg.yaml @@ -141,7 +141,6 @@ remember_me: Запомни ме description: Описание current_password: Текуща парола add_moderator: Добавяне на модератор -edit_photo: Редактиране на снимката off: Изкл. compact_view: Компактен изглед block: Блокиране @@ -197,7 +196,6 @@ joined: Присъединяване removed: Премахнато от модератор domain: Домейн go_to_original_instance: Разгледай на отдалечената инстанция -edit_link: Редактиране на връзката change_my_avatar: Промяна на моя лик domains: Домейни overview: Обзор @@ -344,7 +342,6 @@ auto_preview: Автоматичен преглед на мултимедият wrote_message: Написа съобщение mod_deleted_your_comment: Модератор изтри твой коментар toolbar.mention: Споменаване -edit_article: Редактиране на нишката email_confirm_title: Потвърди своя адрес на ел. поща. added_new_thread: Добави нова нишка two_factor_backup: Резервни кодове за двуфакторно удостоверяване diff --git a/translations/messages.de.yaml b/translations/messages.de.yaml index efd9bf785..244098f3c 100644 --- a/translations/messages.de.yaml +++ b/translations/messages.de.yaml @@ -60,8 +60,6 @@ add_new_video: Neues Video hinzufügen privacy_policy: Datenschutzbestimmungen useful: Nützlich edit: Bearbeiten -edit_article: Thema bearbeiten -edit_photo: Bild bearbeiten delete: Löschen edit_post: Beitrag bearbeiten edit_comment: Änderungen speichern @@ -70,7 +68,6 @@ font_size: Schriftgröße no: Nein show_all: Alle anzeigen already_have_account: Hast du bereits ein Konto? -edit_link: Link bearbeiten new_password: Neues Passwort yes: Ja online: Online diff --git a/translations/messages.el.yaml b/translations/messages.el.yaml index cbf171537..e4ac8835e 100644 --- a/translations/messages.el.yaml +++ b/translations/messages.el.yaml @@ -146,8 +146,6 @@ copy_url_to_fediverse: Αντιγραφή πρωτότυπου URL share_on_fediverse: Κοινοποίηση στο Fediverse are_you_sure: Είσαι σίγουρος; reason: Αιτιολογία -edit_link: Επεξεργασία συνδέσμου -edit_photo: Επεξεργασία φωτογραφίας delete: Διαγραφή edit_post: Επεξεργασία ανάρτησης edit_comment: Αποθήκευση αλλαγών @@ -287,7 +285,6 @@ return: Επιστροφή boost: Ενίσχυση 1d: 1 ημέρα edit: Επεξεργασία -edit_article: Επεξεργασία νήματος notify_on_new_entry_reply: Ειδοποίησέ με για σχόλια στα νήματά μου 1y: 1 έτος general: Γενικά diff --git a/translations/messages.eo.yaml b/translations/messages.eo.yaml index 3e6f8162b..4e54f0936 100644 --- a/translations/messages.eo.yaml +++ b/translations/messages.eo.yaml @@ -164,10 +164,8 @@ chat_view: Babilo aspekto tree_view: Arba aspekto moderate: Kontroli reason: Kialo -edit_article: Redakti fadenon delete: Forigi edit_post: Redakti afiŝon -edit_photo: Redakti foton settings: Agordoj general: Ĝenerala reports: Raportoj @@ -233,7 +231,6 @@ removed_thread_by: forigis fadenon de too_many_requests: Limo superita, bonvolu provi denove poste. set_magazines_bar_empty_desc: se la kampo estas malplena, aktivaj revuoj estas montrataj sur la breto. -edit_link: Redakti ligilon edit_comment: Konservi ŝanĝojn profile: Profilo mod_log: Kontrol-protokolo diff --git a/translations/messages.es.yaml b/translations/messages.es.yaml index d54c02869..319e64548 100644 --- a/translations/messages.es.yaml +++ b/translations/messages.es.yaml @@ -170,9 +170,6 @@ edit: Editar are_you_sure: ¿Estás segura/o? moderate: Moderar reason: Motivo -edit_link: Editar enlace -edit_article: Editar hilo -edit_photo: Editar foto delete: Borrar edit_post: Editar publicación show_users_avatars: Mostrar el avatar del/a usuario/a diff --git a/translations/messages.fr.yaml b/translations/messages.fr.yaml index bf75e4280..b8d7eb234 100644 --- a/translations/messages.fr.yaml +++ b/translations/messages.fr.yaml @@ -148,8 +148,6 @@ moderate: Modérer reason: Motif copy_url_to_fediverse: Copier l'URL d'origine share_on_fediverse: Partager sur le Fédivers -edit_link: Modifier le lien -edit_photo: Modifier la photo delete: Supprimer edit_post: Modifier le message edit_comment: Enregistrer les modifications @@ -181,7 +179,6 @@ edit: Modifier go_to_search: Aller à la recherche privacy_policy: Politique de confidentialité subscriptions: Abonnements -edit_article: Modifier le fil type.smart_contract: Contrat intelligent hot: Dernière minute agree_terms: Consentir aux %terms_link_start%conditions d’utilisation%terms_link_end% diff --git a/translations/messages.gl.yaml b/translations/messages.gl.yaml index 6e8e59134..e82f4a645 100644 --- a/translations/messages.gl.yaml +++ b/translations/messages.gl.yaml @@ -601,14 +601,11 @@ copy_url_to_fediverse: Copiar URL orixinal share_on_fediverse: Comparte no Fediverso edit: Editar are_you_sure: Tes a certeza? -edit_article: Editar conversa -edit_photo: Editar foto delete: Eliminar edit_post: Editar publicación edit_comment: Gardar cambios moderate: Moderar reason: Razón -edit_link: Editar ligazón blocked: Bloqueado reports: Denuncias notifications: Notificacións diff --git a/translations/messages.it.yaml b/translations/messages.it.yaml index eb2d8bba4..7b968662d 100644 --- a/translations/messages.it.yaml +++ b/translations/messages.it.yaml @@ -209,8 +209,6 @@ share_on_fediverse: Condividi sul Fediverso edit: Modifica are_you_sure: Confermi? reason: Motivo -edit_article: Modifica thread -edit_photo: Modifica foto delete: Cancella edit_post: Modifica il post edit_comment: Modifica il commento @@ -265,7 +263,6 @@ joined: Iscritto go_to_filters: Vai ai filtri table_view: Vista a tabella videos: Video -edit_link: Modifica collegamento notifications: Notifiche theme: Tema show_users_avatars: Mostra gli avatar degli utenti diff --git a/translations/messages.ja.yaml b/translations/messages.ja.yaml index 3def46f62..6d07ae2f5 100644 --- a/translations/messages.ja.yaml +++ b/translations/messages.ja.yaml @@ -147,8 +147,6 @@ edit: 編集 are_you_sure: よろしいですか? moderate: モデレートする reason: 理由 -edit_article: スレッドを編集する -edit_photo: 画像を編集する delete: 削除する edit_post: 投稿を編集する settings: 設定 @@ -180,7 +178,6 @@ repeat_password: パスワードを再入力 classic_view: クラシック表示 table_view: テーブル表示 copy_url: MbinのURLをコピー -edit_link: リンクを編集する edit_comment: 上書き保存 general: 全般 hide_adult: R-18・NSFWを非表示する diff --git a/translations/messages.nl.yaml b/translations/messages.nl.yaml index 5ef4b3785..e53ede01e 100644 --- a/translations/messages.nl.yaml +++ b/translations/messages.nl.yaml @@ -157,9 +157,6 @@ share_on_fediverse: Delen op fediverse edit: Bewerken moderate: Modereren reason: Reden -edit_link: Link bewerken -edit_article: Artikel bewerken -edit_photo: Foto bewerken delete: Verwijderen edit_post: Bericht bewerken show_profile_followings: Gevolgde gebruikers tonen diff --git a/translations/messages.pl.yaml b/translations/messages.pl.yaml index ac89914c2..947694c82 100644 --- a/translations/messages.pl.yaml +++ b/translations/messages.pl.yaml @@ -250,9 +250,6 @@ edit: Edytuj are_you_sure: Jesteś pewien? moderate: Moderuj reason: Powód -edit_link: Edytuj link -edit_article: Edytuj wątek -edit_photo: Edytuj obraz delete: Usuń edit_post: Edytuj post settings: Ustawienia diff --git a/translations/messages.pt.yaml b/translations/messages.pt.yaml index f95213529..4f89c780f 100644 --- a/translations/messages.pt.yaml +++ b/translations/messages.pt.yaml @@ -120,8 +120,6 @@ edit: Editar are_you_sure: Tem a certeza? moderate: Moderar reason: Motivo -edit_link: Editar link -edit_article: Editar artigo delete: Apagar edit_post: Editar postagem edit_comment: Editar comentário @@ -280,7 +278,6 @@ mod_log_alert: No Modlog pode encontrar conteúdo removido drasticamente por mod sticky_navbar: Barra de navegação fixa copy_url: Copiar url de Mbin off: Desligado -edit_photo: Editar foto rejected: Rejeitado appearance: Aparência done: Feito diff --git a/translations/messages.ru.yaml b/translations/messages.ru.yaml index 88bf3f1d1..5ed7b3b36 100644 --- a/translations/messages.ru.yaml +++ b/translations/messages.ru.yaml @@ -169,9 +169,6 @@ edit: Редактировать are_you_sure: Вы уверены? moderate: Модерация reason: Причина -edit_link: Изменить ссылку -edit_article: Изменить ветку -edit_photo: Изменить фото delete: Удалить edit_post: Редактировать пост edit_comment: Сохранить изменения diff --git a/translations/messages.tr.yaml b/translations/messages.tr.yaml index a1b1f9c0e..8a0aed377 100644 --- a/translations/messages.tr.yaml +++ b/translations/messages.tr.yaml @@ -143,7 +143,6 @@ edit: Düzenle are_you_sure: Emin misin? moderate: Yönet reason: Sebep -edit_photo: Fotoğrafı düzenle delete: Sil edit_post: Gönderiyi düzenle edit_comment: Yorumu düzenle @@ -273,7 +272,6 @@ cards_view: Kart görünümü approved: Onaylanmış copy_url: Mbin bağlantıyı kopyala ban_expired: Yasak süresi doldu -edit_link: Bağlantıyı düzenle wrote_message: Mesaj yazdı mod_deleted_your_comment: Bir yönetici sizin yorumunuzu sildi appearance: Görünüm @@ -317,7 +315,6 @@ add_new_article: Yeni başlık ekle domain: Alan joined: Katılanlar people_federated: Birleştirilmiş -edit_article: Başlığı düzenle notify_on_new_entry_reply: Başlıklarımdaki bütün yorumlar notify_on_new_entry_comment_reply: Herhangi bir başlıkta yorumlarıma gelen yanıtlar notify_on_new_entry: Abone olduğum magazinlerdeki yeni başlıklar (bağlantılar veya diff --git a/translations/messages.uk.yaml b/translations/messages.uk.yaml index 075f27296..720dcf843 100644 --- a/translations/messages.uk.yaml +++ b/translations/messages.uk.yaml @@ -283,7 +283,6 @@ add_moderator: Додати модератора oauth2.grant.moderate.entry.change_language: Змінювати мову гілок у ваших модерованих спільнотах. username: Імʼя користувача -edit_photo: Редагувати зображення password_confirm_header: Необхідно підтвердити запит на зміну пароля. off: Вимк. light: Світла @@ -495,7 +494,6 @@ flash_comment_edit_success: Коментар успішно оновлено. resend_account_activation_email_description: Введіть адресу е-пошти, повʼязану з вашим обліковим записом. Ми надішлемо вам іншого електронного листа для активації. reload_to_apply: Перезавантажте сторінку, щоб застосувати зміни -edit_article: Редагувати гілку notify_on_new_post_reply: Відповіді будь-якого рівня на ваші дописи oauth2.grant.entry.delete: Видаляти ваші наявні гілки. he_unbanned: допускає @@ -547,7 +545,6 @@ removed: Видалено модератором domain: Домен search: Шукати go_to_original_instance: Переглянути на оригінальному інстансі. -edit_link: Редагувати посилання oauth2.grant.moderate.entry.set_adult: Позначати гілки як «Делікатне» у ваших модерованих спільнотах. oauth2.grant.delete.general: Видаляти будь-які ваші гілки, дописи чи коментарі. diff --git a/translations/messages.zh_TW.yaml b/translations/messages.zh_TW.yaml index e88c9f756..9c912357b 100644 --- a/translations/messages.zh_TW.yaml +++ b/translations/messages.zh_TW.yaml @@ -128,8 +128,6 @@ report: 回報 edit: 編輯 moderate: 管理 reason: 理由 -edit_link: 編輯連結 -edit_photo: 編輯圖片 edit_post: 編輯鋪文 edit_comment: 編輯留言 settings: 設定 @@ -192,7 +190,6 @@ copy_url_to_fediverse: 複製聯邦網址 share_on_fediverse: 分享至聯邦宇宙 are_you_sure: 您確定嗎? articles: 帖子 -edit_article: 編輯帖子 notify_on_new_entry_reply: 有人回覆我的帖子時 notify_on_new_entry_comment_reply: 有人在帖子回覆我的留言時 notify_on_new_entry: 訂閱的刊版有新帖子時 From e75e780e2e193e1fef09db25339b07c1328ec646 Mon Sep 17 00:00:00 2001 From: debounced <35878315+nobodyatroot@users.noreply.github.com> Date: Sat, 3 Aug 2024 09:31:27 -0500 Subject: [PATCH 157/335] Recommend new installs use php8.3 (#981) --- docs/02-admin/01-installation/bare_metal.md | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/docs/02-admin/01-installation/bare_metal.md b/docs/02-admin/01-installation/bare_metal.md index 97c4c4e03..d07ca4c72 100644 --- a/docs/02-admin/01-installation/bare_metal.md +++ b/docs/02-admin/01-installation/bare_metal.md @@ -29,7 +29,7 @@ Install prequirements: sudo apt-get install lsb-release ca-certificates curl wget unzip gnupg apt-transport-https software-properties-common python3-launchpadlib git redis-server postgresql postgresql-contrib nginx acl -y ``` -On **Ubuntu 22.04 LTS** or older, prepare latest PHP package repositoy (8.2 or 8.3) by using a Ubuntu PPA (this step is optional for Ubuntu 23.10 or later) via: +On **Ubuntu 22.04 LTS** or older, prepare latest PHP package repositoy (8.3) by using a Ubuntu PPA (this step is optional for Ubuntu 23.10 or later) via: ```bash sudo add-apt-repository ppa:ondrej/php -y @@ -41,22 +41,16 @@ On **Debian 12** or later, you can install the latest PHP package repository (th sudo sh -c 'echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list' ``` -You can choose between PHP 8.2 or 8.3, but it is recommended to use PHP 8.3. - -Install _PHP 8.2_ with some important PHP extensions: - -```bash -sudo apt-get update -sudo apt-get install php8.2 php8.2-common php8.2-fpm php8.2-cli php8.2-amqp php8.2-bcmath php8.2-pgsql php8.2-gd php8.2-curl php8.2-xml php8.2-redis php8.2-mbstring php8.2-zip php8.2-bz2 php8.2-intl php8.2-bcmath -y -``` - -Or install _PHP 8.3_ with PHP extensions: +Install _PHP 8.3_ with PHP extensions: ```bash sudo apt-get update sudo apt-get install php8.3 php8.3-common php8.3-fpm php8.3-cli php8.3-amqp php8.3-bcmath php8.3-pgsql php8.3-gd php8.3-curl php8.3-xml php8.3-redis php8.3-mbstring php8.3-zip php8.3-bz2 php8.3-intl php8.3-bcmath -y ``` +> [!NOTE] +> If you are upgrading to PHP 8.3 from an older version, please re-review the [PHP configuration](#php) section of this guide as existing `ini` settings are NOT copied to new versions. + Install Composer: ```bash @@ -297,7 +291,7 @@ pm.max_spare_servers = 10 Be sure to restart (or reload) the PHP-FPM service after you applied any changing to the `php.ini` file: ```bash -sudo systemctl restart php8.2-fpm.service +sudo systemctl restart php8.3-fpm.service ``` ### Composer From 00bf67943d999c5c0a8b1cf25548aae07de917aa Mon Sep 17 00:00:00 2001 From: debounced <35878315+nobodyatroot@users.noreply.github.com> Date: Sat, 3 Aug 2024 09:33:12 -0500 Subject: [PATCH 158/335] Bump docker php to 8.3 and rabbitmq versions (#980) Co-authored-by: Melroy van den Berg --- docker/Dockerfile | 2 +- docker/compose.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index a0ceed962..b48dbaa63 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM php:8.2-fpm-alpine as base +FROM php:8.3-fpm-alpine as base # Install php extensions, by docker-php-extension-installer COPY --from=mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/local/bin/ diff --git a/docker/compose.yml b/docker/compose.yml index db359a9fb..bc6bf334c 100644 --- a/docker/compose.yml +++ b/docker/compose.yml @@ -118,7 +118,7 @@ services: - POSTGRES_USER=kbin rabbitmq: - image: rabbitmq:3.13.0-management-alpine + image: rabbitmq:3.13.6-management-alpine container_name: mbin-rabbitmq restart: unless-stopped networks: From 6e4daceced81a11c49f7596ad7a162b8b9f51513 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Sat, 3 Aug 2024 14:34:59 +0000 Subject: [PATCH 159/335] Bump version to 1.7.0-rc2 (#982) --- config/packages/framework.yaml | 2 +- src/Service/ProjectInfoService.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml index 9e5c80db6..64393b069 100644 --- a/config/packages/framework.yaml +++ b/config/packages/framework.yaml @@ -17,7 +17,7 @@ framework: http_client: default_options: headers: - 'User-Agent': 'Mbin/1.7.0-rc1 (+https://%kbin_domain%/agent)' + 'User-Agent': 'Mbin/1.7.0-rc2 (+https://%kbin_domain%/agent)' #esi: true #fragments: true diff --git a/src/Service/ProjectInfoService.php b/src/Service/ProjectInfoService.php index a549a63b7..e455671c0 100644 --- a/src/Service/ProjectInfoService.php +++ b/src/Service/ProjectInfoService.php @@ -10,7 +10,7 @@ class ProjectInfoService { // If updating version, please also update http client UA in [/config/packages/framework.yaml] - private const VERSION = '1.7.0-rc1'; // TODO: Retrieve the version from git tags or getenv()? + private const VERSION = '1.7.0-rc2'; // TODO: Retrieve the version from git tags or getenv()? private const NAME = 'mbin'; private const USER_AGENT = 'Mbin'; private const REPOSITORY_URL = 'https://github.com/MbinOrg/mbin'; From 78c64639ef952d200d6c699d85d259f5bed061f5 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Sat, 3 Aug 2024 16:38:04 +0200 Subject: [PATCH 160/335] Add joinmbin.org list of instance (#983) --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 180a0b0bd..c454b567b 100644 --- a/README.md +++ b/README.md @@ -38,8 +38,9 @@ For developers: ## Instances -- [List of instances](https://fedidb.org/software/mbin) -- [Alternative listing of instances](https://mbin.fediverse.observer/list) +- [List of instances](https://joinmbin.org/servers) +- [Alternative list of instances at fedidb.org](https://fedidb.org/software/mbin) +- [Alternative list of instances at fediverse.observer](https://mbin.fediverse.observer/list) ![Mbin logo](docs/images/mbin.png) From 1de960ae07f363e75ced9a24a621d40620225f28 Mon Sep 17 00:00:00 2001 From: debounced <35878315+nobodyatroot@users.noreply.github.com> Date: Sat, 3 Aug 2024 09:44:02 -0500 Subject: [PATCH 161/335] Additional details/notes on php migrations (#984) --- docs/02-admin/01-installation/bare_metal.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/02-admin/01-installation/bare_metal.md b/docs/02-admin/01-installation/bare_metal.md index d07ca4c72..5d2a2b2a2 100644 --- a/docs/02-admin/01-installation/bare_metal.md +++ b/docs/02-admin/01-installation/bare_metal.md @@ -49,7 +49,7 @@ sudo apt-get install php8.3 php8.3-common php8.3-fpm php8.3-cli php8.3-amqp php8 ``` > [!NOTE] -> If you are upgrading to PHP 8.3 from an older version, please re-review the [PHP configuration](#php) section of this guide as existing `ini` settings are NOT copied to new versions. +> If you are upgrading to PHP 8.3 from an older version, please re-review the [PHP configuration](#php) section of this guide as existing `ini` settings are NOT automatically copied to new versions. Additionally review which php-fpm version is configured in your nginx site. Install Composer: From e4e5f87096059954f7f16e4d3efbbeb62e762aa2 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Sat, 3 Aug 2024 18:17:14 +0000 Subject: [PATCH 162/335] Fix updating actor icons in specific cases (#985) --- src/Service/ActivityPubManager.php | 32 +++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/Service/ActivityPubManager.php b/src/Service/ActivityPubManager.php index cf9b57288..c2eb61c0f 100644 --- a/src/Service/ActivityPubManager.php +++ b/src/Service/ActivityPubManager.php @@ -364,7 +364,10 @@ public function updateUser(string $actorUrl): ?User // Only update avatar if icon is set if (isset($actor['icon'])) { - $newImage = $this->handleImages([$actor['icon']]); + // we only have to wrap the property in an array if it is not already an array, though that is not that easy to determine + // because each json object is an associative array -> each image has to have a 'type' property so use that to check it + $icon = !\array_key_exists('type', $actor['icon']) ? $actor['icon'] : [$actor['icon']]; + $newImage = $this->handleImages($icon); if ($user->avatar && $newImage !== $user->avatar) { $this->bus->dispatch(new DeleteImageMessage($user->avatar->getId())); } @@ -373,7 +376,10 @@ public function updateUser(string $actorUrl): ?User // Only update cover if image is set if (isset($actor['image'])) { - $newImage = $this->handleImages([$actor['image']]); + // we only have to wrap the property in an array if it is not already an array, though that is not that easy to determine + // because each json object is an associative array -> each image has to have a 'type' property so use that to check it + $cover = !\array_key_exists('type', $actor['image']) ? $actor['image'] : [$actor['image']]; + $newImage = $this->handleImages($cover); if ($user->cover && $newImage !== $user->cover) { $this->bus->dispatch(new DeleteImageMessage($user->cover->getId())); } @@ -419,11 +425,20 @@ public function handleImages(array $attachment): ?Image if (\count($images)) { try { - if ($tempFile = $this->imageManager->download($images[0]['url'])) { + $imageObject = $images[0]; + if (isset($imageObject['height'])) { + // determine the highest resolution image + foreach ($images as $i) { + if (isset($i['height']) && $i['height'] ?? 0 > $imageObject['height'] ?? 0) { + $imageObject = $i; + } + } + } + if ($tempFile = $this->imageManager->download($imageObject['url'])) { $image = $this->imageRepository->findOrCreateFromPath($tempFile); - $image->sourceUrl = $images[0]['url']; - if ($image && isset($images[0]['name'])) { - $image->altText = $images[0]['name']; + $image->sourceUrl = $imageObject['url']; + if ($image && isset($imageObject['name'])) { + $image->altText = $imageObject['name']; } $this->entityManager->persist($image); $this->entityManager->flush(); @@ -488,7 +503,10 @@ public function updateMagazine(string $actorUrl): ?Magazine } if (isset($actor['icon'])) { - $newImage = $this->handleImages([$actor['icon']]); + // we only have to wrap the property in an array if it is not already an array, though that is not that easy to determine + // because each json object is an associative array -> each image has to have a 'type' property so use that to check it + $icon = !\array_key_exists('type', $actor['icon']) ? $actor['icon'] : [$actor['icon']]; + $newImage = $this->handleImages($icon); if ($magazine->icon && $newImage !== $magazine->icon) { $this->bus->dispatch(new DeleteImageMessage($magazine->icon->getId())); } From ef7f57ea120994c42a601893b3647a037889bc1b Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Sat, 3 Aug 2024 18:53:00 +0000 Subject: [PATCH 163/335] Add a section for setting up push notifications (#986) --- docs/02-admin/04-running-mbin/first_setup.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/02-admin/04-running-mbin/first_setup.md b/docs/02-admin/04-running-mbin/first_setup.md index 5972399e4..4772504a9 100644 --- a/docs/02-admin/04-running-mbin/first_setup.md +++ b/docs/02-admin/04-running-mbin/first_setup.md @@ -41,3 +41,10 @@ npm run build # Builds frontend ``` Make sure you have substituted all the passwords and configured the basic services. + +### Push Notification setup + +The push notification system needs encryption keys to work. They have to be generated only once, by running +```bash +php bin/console mbin:push:keys:update +``` From e522dbba7a906a6016a3168058a3469ad22a99af Mon Sep 17 00:00:00 2001 From: asdfzdfj Date: Sun, 4 Aug 2024 17:14:20 +0700 Subject: [PATCH 164/335] fix some oddities about nodeinfo fetching/handling (#988) these can unintentionally break incoming federation - make nodeinfo deserializer accepts nullable usage.users.active{Month,Halfyear} as some software doesn't disclose these numbers by making them null (seems to affect misskey in particular) - use `application/json` when fetching nodeinfo endpoint from instances in ApHttpClient, as some software would return HTTP 406 for such requests because it was using default `Accept: application/activity+json` (seems to affect pleroma/akkoma family) --- src/Payloads/NodeInfo/NodeInfoUsageUsers.php | 4 +-- src/Service/ActivityPub/ApHttpClient.php | 37 +++++++++++++------- src/Service/RemoteInstanceManager.php | 4 +++ 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/Payloads/NodeInfo/NodeInfoUsageUsers.php b/src/Payloads/NodeInfo/NodeInfoUsageUsers.php index 90487e269..0dc5a1d5e 100644 --- a/src/Payloads/NodeInfo/NodeInfoUsageUsers.php +++ b/src/Payloads/NodeInfo/NodeInfoUsageUsers.php @@ -7,6 +7,6 @@ class NodeInfoUsageUsers { public int $total; - public int $activeHalfYear; - public int $activeMonth; + public ?int $activeHalfYear = 0; + public ?int $activeMonth = 0; } diff --git a/src/Service/ActivityPub/ApHttpClient.php b/src/Service/ActivityPub/ApHttpClient.php index 4c4fae66c..5b8c567bb 100644 --- a/src/Service/ActivityPub/ApHttpClient.php +++ b/src/Service/ActivityPub/ApHttpClient.php @@ -32,6 +32,7 @@ enum ApRequestType { case ActivityPub; case WebFinger; + case NodeInfo; } class ApHttpClient @@ -313,7 +314,7 @@ public function fetchInstanceNodeInfoEndpoints(string $domain, bool $decoded = t $resp = $this->cache->get('nodeinfo_endpoints_'.hash('sha256', $url), function (ItemInterface $item) use ($url) { $item->expiresAt(new \DateTime('+1 day')); - return $this->generalFetch($url); + return $this->generalFetch($url, ApRequestType::NodeInfo); }); if (!$resp) { @@ -328,7 +329,7 @@ public function fetchInstanceNodeInfo(string $url, bool $decoded = true): array| $resp = $this->cache->get('nodeinfo_'.hash('sha256', $url), function (ItemInterface $item) use ($url) { $item->expiresAt(new \DateTime('+1 day')); - return $this->generalFetch($url); + return $this->generalFetch($url, ApRequestType::NodeInfo); }); if (!$resp) { @@ -338,19 +339,37 @@ public function fetchInstanceNodeInfo(string $url, bool $decoded = true): array| return $decoded ? json_decode($resp, true) : $resp; } - private function generalFetch(string $url): string + private function generalFetch(string $url, ApRequestType $requestType = ApRequestType::ActivityPub): string { $client = new CurlHttpClient(); - $this->logger->debug("ApHttpClient:fetchInstanceNodeInfo:url: $url"); + $this->logger->debug("ApHttpClient:generalFetch:url: $url"); $r = $client->request('GET', $url, [ 'max_duration' => self::TIMEOUT, 'timeout' => self::TIMEOUT, - 'headers' => $this->getInstanceHeaders($url), + 'headers' => $this->getInstanceHeaders($url, requestType: $requestType), ]); return $r->getContent(); } + private function getFetchAcceptHeaders(ApRequestType $requestType): array + { + return match ($requestType) { + ApRequestType::WebFinger => [ + 'Accept' => 'application/jrd+json', + 'Content-Type' => 'application/jrd+json', + ], + ApRequestType::ActivityPub => [ + 'Accept' => 'application/activity+json', + 'Content-Type' => 'application/activity+json', + ], + ApRequestType::NodeInfo => [ + 'Accept' => 'application/json', + 'Content-Type' => 'application/json', + ], + }; + } + private static function headersToCurlArray($headers): array { return array_map(function ($k, $v) { @@ -395,13 +414,7 @@ private function getInstanceHeaders(string $url, ?array $body = null, string $me unset($headers['(request-target)']); $headers['Signature'] = $signatureHeader; $headers['User-Agent'] = $this->projectInfo->getUserAgent().'/'.$this->projectInfo->getVersion().' (+https://'.$this->kbinDomain.'/agent)'; - if (ApRequestType::WebFinger === $requestType) { - $headers['Accept'] = 'application/jrd+json'; - $headers['Content-Type'] = 'application/jrd+json'; - } else { - $headers['Accept'] = 'application/activity+json'; - $headers['Content-Type'] = 'application/activity+json'; - } + $headers = array_merge($headers, $this->getFetchAcceptHeaders($requestType)); return $headers; } diff --git a/src/Service/RemoteInstanceManager.php b/src/Service/RemoteInstanceManager.php index c7a8deb24..ec750002c 100644 --- a/src/Service/RemoteInstanceManager.php +++ b/src/Service/RemoteInstanceManager.php @@ -35,11 +35,14 @@ public function updateInstance(Instance $instance, bool $force = false): bool if ($instance->getUpdatedAt() < new \DateTime('now - 1day') || $force) { $nodeInfoEndpointsRaw = $this->client->fetchInstanceNodeInfoEndpoints($instance->domain, false); $serializer = $this->getSerializer(); + /** @var WellKnownNodeInfo */ $nodeInfoEndpoints = $serializer->deserialize($nodeInfoEndpointsRaw, WellKnownNodeInfo::class, 'json'); + $linkToUse = null; foreach ($nodeInfoEndpoints->links as $link) { if (NodeInfoController::NODE_REL_v21 === $link->rel) { $linkToUse = $link; + break; } elseif (null === $linkToUse && NodeInfoController::NODE_REL_v20 === $link->rel) { $linkToUse = $link; } @@ -54,6 +57,7 @@ public function updateInstance(Instance $instance, bool $force = false): bool $nodeInfoRaw = $this->client->fetchInstanceNodeInfo($linkToUse->href, false); $this->logger->debug('got raw nodeinfo for url {url}: {raw}', ['raw' => $nodeInfoRaw, 'url' => $linkToUse]); + /** @var NodeInfo */ $nodeInfo = $serializer->deserialize($nodeInfoRaw, NodeInfo::class, 'json'); $instance->software = $nodeInfo?->software?->name; From 9b4ae2204cfb4cf742457a0723be9f6cf66940f2 Mon Sep 17 00:00:00 2001 From: asdfzdfj Date: Sun, 4 Aug 2024 17:17:10 +0700 Subject: [PATCH 165/335] preview controller memoize response (#989) adjusted preview controller to clear its content on close, but at the same time also memoize the embed response from the server the should help in dealing with e.g. youtube embed preview where simply hiding the preview container would not make it stop, and there's no good way to universally stop embed media players other than to erase them out entirely, while not making extra requests to the server when the preview is being repeatedly shown/hidden in the same page session --- assets/controllers/preview_controller.js | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/assets/controllers/preview_controller.js b/assets/controllers/preview_controller.js index 0da34e6cb..286323c4b 100644 --- a/assets/controllers/preview_controller.js +++ b/assets/controllers/preview_controller.js @@ -12,6 +12,9 @@ export default class extends Controller { static targets = ['container']; static throttles = ['show']; + /** memoization of fetched embed response */ + fetchedResponse = {}; + connect() { useThrottle(this, { wait: 1000 }); @@ -43,6 +46,21 @@ export default class extends Controller { await this.show(event); } + async fetchEmbed(url) { + if (this.fetchedResponse[url]) { + return this.fetchedResponse[url]; + } + + let response = await fetch(router().generate('ajax_fetch_embed', { url }), { method: 'GET' }); + + response = await ok(response); + response = await response.json(); + + this.fetchedResponse[url] = response; + + return response; + } + async show(event) { event.preventDefault(); @@ -55,10 +73,7 @@ export default class extends Controller { try { this.loadingValue = true; - let response = await fetch(router().generate('ajax_fetch_embed', { url: event.params.url }), { method: 'GET' }); - - response = await ok(response); - response = await response.json(); + const response = await this.fetchEmbed(event.params.url); this.containerTarget.innerHTML = response.html; this.containerTarget.classList.remove('hidden'); From 88440e06780deefb1bfd665d036e81eca83ab612 Mon Sep 17 00:00:00 2001 From: debounced <35878315+nobodyatroot@users.noreply.github.com> Date: Sun, 4 Aug 2024 07:12:06 -0500 Subject: [PATCH 166/335] Replace MAX_IMAGE_BYTES constant in `ImageManager.php` with admin configurable environmental variable (#987) --- .env.example | 4 ++++ .env.example_docker | 4 ++++ config/services.yaml | 4 ++++ src/DTO/SettingsDto.php | 5 ++++- src/Service/ImageManager.php | 6 +++--- src/Service/SettingsManager.php | 4 +++- 6 files changed, 22 insertions(+), 5 deletions(-) diff --git a/.env.example b/.env.example index ae67b5191..c76c6ccd8 100644 --- a/.env.example +++ b/.env.example @@ -32,6 +32,10 @@ KBIN_HEADER_LOGO=false KBIN_FEDERATION_PAGE_ENABLED=true MBIN_DEFAULT_THEME=default +# Max image filesize (in bytes) +# This should be set to <= `upload_max_filesize` and `post_max_size` in the server's php.ini file +MAX_IMAGE_BYTES=6000000 + # Captcha (also enable in admin panel/settings) KBIN_CAPTCHA_ENABLED=false ###> meteo-concept/hcaptcha-bundle ### diff --git a/.env.example_docker b/.env.example_docker index 85e3a3647..36f0b811b 100644 --- a/.env.example_docker +++ b/.env.example_docker @@ -32,6 +32,10 @@ KBIN_HEADER_LOGO=false KBIN_FEDERATION_PAGE_ENABLED=true MBIN_DEFAULT_THEME=default +# Max image filesize (in bytes) +# This should be set to <= `upload_max_filesize` and `post_max_size` in the server's php.ini file +MAX_IMAGE_BYTES=6000000 + # Captcha (also enable in admin panel/settings) KBIN_CAPTCHA_ENABLED=false diff --git a/config/services.yaml b/config/services.yaml index 7b4a95b2f..f03437b71 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -107,6 +107,9 @@ parameters: exif_exiftool_path: '%env(default::EXIF_EXIFTOOL_PATH)%' exif_exiftool_timeout: '%env(int:default::EXIF_EXIFTOOL_TIMEOUT)%' + max_image_bytes: "%env(int:default:max_image_bytes_default:MAX_IMAGE_BYTES)%" + max_image_bytes_default: 6000000 + services: # default configuration for services in *this* file _defaults: @@ -174,6 +177,7 @@ services: $kbinFederationPageEnabled: "%env(bool:KBIN_FEDERATION_PAGE_ENABLED)%" $kbinAdminOnlyOauthClients: "%env(bool:KBIN_ADMIN_ONLY_OAUTH_CLIENTS)%" $mbinSsoOnlyMode: "%sso_only_mode%" + $maxImageBytes: "%max_image_bytes%" # Markdown App\Markdown\Factory\EnvironmentFactory: diff --git a/src/DTO/SettingsDto.php b/src/DTO/SettingsDto.php index 539f75005..684a22f88 100644 --- a/src/DTO/SettingsDto.php +++ b/src/DTO/SettingsDto.php @@ -35,7 +35,8 @@ public function __construct( public bool $MBIN_SIDEBAR_SECTIONS_LOCAL_ONLY, public bool $MBIN_SSO_REGISTRATIONS_ENABLED, public bool $MBIN_RESTRICT_MAGAZINE_CREATION, - public bool $MBIN_SSO_SHOW_FIRST + public bool $MBIN_SSO_SHOW_FIRST, + public int $MAX_IMAGE_BYTES ) { } @@ -66,6 +67,7 @@ public function mergeIntoDto(SettingsDto $dto): SettingsDto $dto->MBIN_SSO_REGISTRATIONS_ENABLED = $this->MBIN_SSO_REGISTRATIONS_ENABLED ?? $dto->MBIN_SSO_REGISTRATIONS_ENABLED; $dto->MBIN_RESTRICT_MAGAZINE_CREATION = $this->MBIN_RESTRICT_MAGAZINE_CREATION ?? $dto->MBIN_RESTRICT_MAGAZINE_CREATION; $dto->MBIN_SSO_SHOW_FIRST = $this->MBIN_SSO_SHOW_FIRST ?? $dto->MBIN_SSO_SHOW_FIRST; + $dto->MAX_IMAGE_BYTES = $this->MAX_IMAGE_BYTES ?? $dto->MAX_IMAGE_BYTES; return $dto; } @@ -98,6 +100,7 @@ public function jsonSerialize(): mixed 'MBIN_SSO_REGISTRATIONS_ENABLED' => $this->MBIN_SSO_REGISTRATIONS_ENABLED, 'MBIN_RESTRICT_MAGAZINE_CREATION' => $this->MBIN_RESTRICT_MAGAZINE_CREATION, 'MBIN_SSO_SHOW_FIRST' => $this->MBIN_SSO_SHOW_FIRST, + 'MAX_IMAGE_BYTES' => $this->MAX_IMAGE_BYTES, ]; } } diff --git a/src/Service/ImageManager.php b/src/Service/ImageManager.php index d03abc892..4c26b3a3f 100644 --- a/src/Service/ImageManager.php +++ b/src/Service/ImageManager.php @@ -22,7 +22,6 @@ class ImageManager 'image/webp', 'image/avif', ]; public const IMAGE_MIMETYPE_STR = 'image/jpeg, image/jpg, image/gif, image/png, image/jxl, image/heic, image/heif, image/webp, image/avif'; - public const MAX_IMAGE_BYTES = 6000000; public function __construct( private readonly string $storageUrl, @@ -31,6 +30,7 @@ public function __construct( private readonly MimeTypesInterface $mimeTypeGuesser, private readonly ValidatorInterface $validator, private readonly LoggerInterface $logger, + private readonly SettingsManager $settings, ) { } @@ -56,8 +56,8 @@ public function store(string $source, string $filePath): bool $fh = fopen($source, 'rb'); try { - if (filesize($source) > self::MAX_IMAGE_BYTES) { - throw new ImageDownloadTooLargeException('the image is too large, max size is '.self::MAX_IMAGE_BYTES); + if (filesize($source) > $this->settings->get('MAX_IMAGE_BYTES')) { + throw new ImageDownloadTooLargeException('the image is too large, max size is '.$this->settings->get('MAX_IMAGE_BYTES')); } $this->validate($source); diff --git a/src/Service/SettingsManager.php b/src/Service/SettingsManager.php index 48f44df8c..49871337c 100644 --- a/src/Service/SettingsManager.php +++ b/src/Service/SettingsManager.php @@ -36,6 +36,7 @@ public function __construct( private readonly bool $kbinFederationPageEnabled, private readonly bool $kbinAdminOnlyOauthClients, private readonly bool $mbinSsoOnlyMode, + private readonly int $maxImageBytes ) { if (!self::$dto) { $results = $this->repository->findAll(); @@ -73,7 +74,8 @@ public function __construct( $this->find($results, 'MBIN_SIDEBAR_SECTIONS_LOCAL_ONLY', FILTER_VALIDATE_BOOLEAN) ?? false, $this->find($results, 'MBIN_SSO_REGISTRATIONS_ENABLED', FILTER_VALIDATE_BOOLEAN) ?? true, $this->find($results, 'MBIN_RESTRICT_MAGAZINE_CREATION', FILTER_VALIDATE_BOOLEAN) ?? false, - $this->find($results, 'MBIN_SSO_SHOW_FIRST', FILTER_VALIDATE_BOOLEAN) ?? false + $this->find($results, 'MBIN_SSO_SHOW_FIRST', FILTER_VALIDATE_BOOLEAN) ?? false, + $this->find($results, 'MAX_IMAGE_BYTES', FILTER_VALIDATE_INT) ?? $this->maxImageBytes ); } } From 373f096af9f3a4a868067b9453e39192af852fc2 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Sun, 4 Aug 2024 17:23:24 +0200 Subject: [PATCH 167/335] Translations update from Hosted Weblate (#990) Co-authored-by: BentiGorlich --- translations/messages.de.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/translations/messages.de.yaml b/translations/messages.de.yaml index 244098f3c..363ecbece 100644 --- a/translations/messages.de.yaml +++ b/translations/messages.de.yaml @@ -925,3 +925,4 @@ last_failed_contact: Letzter misslungener Kontakt magazine_posting_restricted_to_mods: Erstellung von Themen auf Moderatoren beschränken new_user_description: Dieser Nutzer ist neu (seit weniger als %days% Tagen aktiv) new_magazine_description: Dieses Magazin ist neu (seit weniger als %days% Tagen aktiv) +edit_entry: Thema bearbeiten From 93c4baf49d2c0abdde341febe72214be2a7e61f4 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Sun, 4 Aug 2024 17:54:54 +0000 Subject: [PATCH 168/335] Bump version to v1.7.0 (#991) --- config/packages/framework.yaml | 2 +- src/Service/ProjectInfoService.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml index 64393b069..6a4cbd2b9 100644 --- a/config/packages/framework.yaml +++ b/config/packages/framework.yaml @@ -17,7 +17,7 @@ framework: http_client: default_options: headers: - 'User-Agent': 'Mbin/1.7.0-rc2 (+https://%kbin_domain%/agent)' + 'User-Agent': 'Mbin/1.7.0 (+https://%kbin_domain%/agent)' #esi: true #fragments: true diff --git a/src/Service/ProjectInfoService.php b/src/Service/ProjectInfoService.php index e455671c0..c7f83eef8 100644 --- a/src/Service/ProjectInfoService.php +++ b/src/Service/ProjectInfoService.php @@ -10,7 +10,7 @@ class ProjectInfoService { // If updating version, please also update http client UA in [/config/packages/framework.yaml] - private const VERSION = '1.7.0-rc2'; // TODO: Retrieve the version from git tags or getenv()? + private const VERSION = '1.7.0'; // TODO: Retrieve the version from git tags or getenv()? private const NAME = 'mbin'; private const USER_AGENT = 'Mbin'; private const REPOSITORY_URL = 'https://github.com/MbinOrg/mbin'; From 72698919202d5229e1b0ffd063d18579ca27484d Mon Sep 17 00:00:00 2001 From: John Wesley <47087725+jwr1@users.noreply.github.com> Date: Sun, 4 Aug 2024 16:29:10 -0400 Subject: [PATCH 169/335] Update docker php config to match bare metal guide (#992) --- docker/php/conf.d/app.ini | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/docker/php/conf.d/app.ini b/docker/php/conf.d/app.ini index bed9b5b68..2a5158501 100644 --- a/docker/php/conf.d/app.ini +++ b/docker/php/conf.d/app.ini @@ -5,13 +5,16 @@ session.use_strict_mode = 1 zend.detect_unicode = 0 ; https://symfony.com/doc/current/performance.html +max_execution_time = 60 +upload_max_filesize = 8M +post_max_size = 8M +memory_limit = 512M realpath_cache_size = 4096K realpath_cache_ttl = 600 -opcache.interned_strings_buffer = 16 -opcache.max_accelerated_files = 20000 -opcache.memory_consumption = 256 -opcache.enable_file_override = 1 -upload_max_filesize = 12M -post_max_size = 12M -memory_limit = 512M +opcache.enable=1 +opcache.enable_cli=1 +opcache.memory_consumption=512 +opcache.interned_strings_buffer=128 +opcache.max_accelerated_files=100000 +opcache.jit_buffer_size=500M From 6dc36cf3e05617682497ba4e6f58e1cdfaad0846 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 4 Aug 2024 20:31:52 +0000 Subject: [PATCH 170/335] docs(contributor): contributors readme action update (#993) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index c454b567b..4b1c9c4a9 100644 --- a/README.md +++ b/README.md @@ -266,6 +266,13 @@ For developers: CSDUMMI + + + jwr1 +
        + John Wesley +
        + DismalShadowX @@ -273,6 +280,8 @@ For developers: Nathan Sparrow + + privacyguard From 04c5adf19b54001f191461314bb8c5a8f1745d7a Mon Sep 17 00:00:00 2001 From: debounced <35878315+nobodyatroot@users.noreply.github.com> Date: Sun, 4 Aug 2024 15:53:49 -0500 Subject: [PATCH 171/335] Update docker ini files to be a little more consistent with docs (#994) --- docker/php/conf.d/app.dev.ini | 2 ++ docker/php/conf.d/app.ini | 11 +---------- docker/php/conf.d/app.prod.ini | 13 +++++++++++-- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/docker/php/conf.d/app.dev.ini b/docker/php/conf.d/app.dev.ini index c1b638142..2f486a94d 100644 --- a/docker/php/conf.d/app.dev.ini +++ b/docker/php/conf.d/app.dev.ini @@ -3,3 +3,5 @@ ; The `client_host` below may optionally be replaced with `discover_client_host=yes` ; Add `start_with_request=yes` to start debug session on each request xdebug.client_host = 'host.docker.internal' + +max_execution_time = 120 diff --git a/docker/php/conf.d/app.ini b/docker/php/conf.d/app.ini index 2a5158501..8498edf93 100644 --- a/docker/php/conf.d/app.ini +++ b/docker/php/conf.d/app.ini @@ -5,16 +5,7 @@ session.use_strict_mode = 1 zend.detect_unicode = 0 ; https://symfony.com/doc/current/performance.html -max_execution_time = 60 + upload_max_filesize = 8M post_max_size = 8M memory_limit = 512M -realpath_cache_size = 4096K -realpath_cache_ttl = 600 - -opcache.enable=1 -opcache.enable_cli=1 -opcache.memory_consumption=512 -opcache.interned_strings_buffer=128 -opcache.max_accelerated_files=100000 -opcache.jit_buffer_size=500M diff --git a/docker/php/conf.d/app.prod.ini b/docker/php/conf.d/app.prod.ini index 5911fa54c..fe7eacc4f 100644 --- a/docker/php/conf.d/app.prod.ini +++ b/docker/php/conf.d/app.prod.ini @@ -1,2 +1,11 @@ -opcache.preload = /var/www/mbin/config/preload.php -opcache.preload_user = www-data +max_execution_time = 60 + +realpath_cache_size = 4096K +realpath_cache_ttl = 600 + +opcache.enable=1 +opcache.enable_cli=1 +opcache.memory_consumption=512 +opcache.interned_strings_buffer=128 +opcache.max_accelerated_files=100000 +opcache.jit_buffer_size=500M \ No newline at end of file From aa9db5b79f4402fd60a39e7b7f419cfd8b6d4121 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Mon, 5 Aug 2024 16:57:51 +0000 Subject: [PATCH 172/335] Fix the error when saving the admin settings (#997) --- src/Service/SettingsManager.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Service/SettingsManager.php b/src/Service/SettingsManager.php index 49871337c..c510dd146 100644 --- a/src/Service/SettingsManager.php +++ b/src/Service/SettingsManager.php @@ -75,7 +75,7 @@ public function __construct( $this->find($results, 'MBIN_SSO_REGISTRATIONS_ENABLED', FILTER_VALIDATE_BOOLEAN) ?? true, $this->find($results, 'MBIN_RESTRICT_MAGAZINE_CREATION', FILTER_VALIDATE_BOOLEAN) ?? false, $this->find($results, 'MBIN_SSO_SHOW_FIRST', FILTER_VALIDATE_BOOLEAN) ?? false, - $this->find($results, 'MAX_IMAGE_BYTES', FILTER_VALIDATE_INT) ?? $this->maxImageBytes + \intval($this->find($results, 'MAX_IMAGE_BYTES', FILTER_VALIDATE_INT)) ?? $this->maxImageBytes ); } } @@ -111,6 +111,10 @@ public function save(SettingsDto $dto): void $value = $value ? 'true' : 'false'; } + if (!\is_string($value) && !\is_array($value)) { + $value = \strval($value); + } + if (!$s) { $s = new Settings($name, $value); } From 9f0f1a83501c77cdd62741db695f2970182aaa8f Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Mon, 5 Aug 2024 20:26:09 +0000 Subject: [PATCH 173/335] Add posting restricted to mods to the API (#998) --- src/Controller/Api/Magazine/MagazineBaseApi.php | 6 ++---- src/DTO/MagazineRequestDto.php | 2 ++ src/DTO/MagazineResponseDto.php | 4 ++++ src/DTO/MagazineUpdateRequestDto.php | 2 ++ src/Factory/MagazineFactory.php | 1 + 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Controller/Api/Magazine/MagazineBaseApi.php b/src/Controller/Api/Magazine/MagazineBaseApi.php index 9462b049b..4c77ae128 100644 --- a/src/Controller/Api/Magazine/MagazineBaseApi.php +++ b/src/Controller/Api/Magazine/MagazineBaseApi.php @@ -50,13 +50,11 @@ protected function serializeReport(Report $report) */ protected function deserializeMagazine(?MagazineDto $dto = null): MagazineDto { - $dto = $dto ? $dto : new MagazineDto(); + $dto = $dto ?? new MagazineDto(); $deserialized = $this->serializer->deserialize($this->request->getCurrentRequest()->getContent(), MagazineRequestDto::class, 'json'); \assert($deserialized instanceof MagazineRequestDto); - $dto = $deserialized->mergeIntoDto($dto); - - return $dto; + return $deserialized->mergeIntoDto($dto); } protected function deserializeThemeFromForm(MagazineThemeDto $dto): MagazineThemeDto diff --git a/src/DTO/MagazineRequestDto.php b/src/DTO/MagazineRequestDto.php index 4acb4723c..c9683184b 100644 --- a/src/DTO/MagazineRequestDto.php +++ b/src/DTO/MagazineRequestDto.php @@ -14,6 +14,7 @@ class MagazineRequestDto public ?string $description = null; public ?string $rules = null; public ?bool $isAdult = null; + public ?bool $isPostingRestrictedToMods = null; public function mergeIntoDto(MagazineDto $dto): MagazineDto { @@ -22,6 +23,7 @@ public function mergeIntoDto(MagazineDto $dto): MagazineDto $dto->description = $this->description ?? $dto->description; $dto->rules = $this->rules ?? $dto->rules; $dto->isAdult = null !== $this->isAdult ? $this->isAdult : $dto->isAdult; + $dto->isPostingRestrictedToMods = $this->isPostingRestrictedToMods ?? false; return $dto; } diff --git a/src/DTO/MagazineResponseDto.php b/src/DTO/MagazineResponseDto.php index 4395803ec..340baf474 100644 --- a/src/DTO/MagazineResponseDto.php +++ b/src/DTO/MagazineResponseDto.php @@ -35,6 +35,7 @@ class MagazineResponseDto implements \JsonSerializable public ?int $magazineId = null; public ?string $serverSoftware = null; public ?string $serverSoftwareVersion = null; + public bool $isPostingRestrictedToMods = false; public static function create( ?ModeratorResponseDto $owner = null, @@ -59,6 +60,7 @@ public static function create( ?int $magazineId = null, ?string $serverSoftware = null, ?string $serverSoftwareVersion = null, + bool $isPostingRestrictedToMods = false, ): self { $dto = new MagazineResponseDto(); $dto->owner = $owner; @@ -83,6 +85,7 @@ public static function create( $dto->magazineId = $magazineId; $dto->serverSoftware = $serverSoftware; $dto->serverSoftwareVersion = $serverSoftwareVersion; + $dto->isPostingRestrictedToMods = $isPostingRestrictedToMods; return $dto; } @@ -112,6 +115,7 @@ public function jsonSerialize(): mixed 'apProfileId' => $this->apProfileId, 'serverSoftware' => $this->serverSoftware, 'serverSoftwareVersion' => $this->serverSoftwareVersion, + 'isPostingRestrictedToMods' => $this->isPostingRestrictedToMods, ]; } } diff --git a/src/DTO/MagazineUpdateRequestDto.php b/src/DTO/MagazineUpdateRequestDto.php index ca824cd97..7be6b370a 100644 --- a/src/DTO/MagazineUpdateRequestDto.php +++ b/src/DTO/MagazineUpdateRequestDto.php @@ -15,6 +15,7 @@ class MagazineUpdateRequestDto public ?string $description = null; public ?string $rules = null; public ?bool $isAdult = null; + public ?bool $isPostingRestrictedToMods = null; public function mergeIntoDto(MagazineDto $dto, ImageRepository $imageRepository): MagazineDto { @@ -23,6 +24,7 @@ public function mergeIntoDto(MagazineDto $dto, ImageRepository $imageRepository) $dto->description = $this->description ?? $dto->description; $dto->rules = $this->rules ?? $dto->rules; $dto->isAdult = null === $this->isAdult ? $this->isAdult : $dto->isAdult; + $dto->isPostingRestrictedToMods = $this->isPostingRestrictedToMods ?? false; return $dto; } diff --git a/src/Factory/MagazineFactory.php b/src/Factory/MagazineFactory.php index c17c3d370..b8e5e0577 100644 --- a/src/Factory/MagazineFactory.php +++ b/src/Factory/MagazineFactory.php @@ -159,6 +159,7 @@ public function createResponseDto(MagazineDto|Magazine $magazine): MagazineRespo $dto->getId(), $dto->serverSoftware, $dto->serverSoftwareVersion, + $dto->isPostingRestrictedToMods, ); } From 4e7ea2f394fe5608d62418dc1fc9ca401a1abff7 Mon Sep 17 00:00:00 2001 From: debounced <35878315+nobodyatroot@users.noreply.github.com> Date: Mon, 5 Aug 2024 15:28:37 -0500 Subject: [PATCH 174/335] Add user ban and suspension lists to admin panel (#995) --- config/kbin_routes/admin.yaml | 23 ++++- src/Controller/Admin/AdminUserController.php | 32 ------ src/Controller/Admin/AdminUsersController.php | 75 ++++++++++++++ src/Repository/UserRepository.php | 97 ++++++++++++++++++- templates/admin/_options.html.twig | 4 +- templates/admin/users.html.twig | 53 ++++++++-- translations/messages.en.yaml | 5 +- 7 files changed, 240 insertions(+), 49 deletions(-) delete mode 100644 src/Controller/Admin/AdminUserController.php create mode 100644 src/Controller/Admin/AdminUsersController.php diff --git a/config/kbin_routes/admin.yaml b/config/kbin_routes/admin.yaml index bb70652f0..0c6dcd6c6 100644 --- a/config/kbin_routes/admin.yaml +++ b/config/kbin_routes/admin.yaml @@ -1,7 +1,24 @@ -admin_users: - controller: App\Controller\Admin\AdminUserController +admin_users_active: + controller: App\Controller\Admin\AdminUsersController::active defaults: { withFederated: false } - path: /admin/users/{withFederated} + path: /admin/users/active/{withFederated} + methods: [GET] + +admin_users_inactive: + controller: App\Controller\Admin\AdminUsersController::inactive + path: /admin/users/inactive + methods: [GET] + +admin_users_suspended: + controller: App\Controller\Admin\AdminUsersController::suspended + defaults: { withFederated: false } + path: /admin/users/suspended/{withFederated} + methods: [GET] + +admin_users_banned: + controller: App\Controller\Admin\AdminUsersController::banned + defaults: { withFederated: false } + path: /admin/users/banned/{withFederated} methods: [GET] admin_reports: diff --git a/src/Controller/Admin/AdminUserController.php b/src/Controller/Admin/AdminUserController.php deleted file mode 100644 index 10fecd767..000000000 --- a/src/Controller/Admin/AdminUserController.php +++ /dev/null @@ -1,32 +0,0 @@ -render( - 'admin/users.html.twig', - [ - 'users' => $this->repository->findAllPaginated( - (int) $this->request->getCurrentRequest()->get('p', 1), - !($withFederated ?? false) - ), - 'withFederated' => $withFederated, - ] - ); - } -} diff --git a/src/Controller/Admin/AdminUsersController.php b/src/Controller/Admin/AdminUsersController.php new file mode 100644 index 000000000..6d57f9596 --- /dev/null +++ b/src/Controller/Admin/AdminUsersController.php @@ -0,0 +1,75 @@ +render( + 'admin/users.html.twig', + [ + 'users' => $this->repository->findAllActivePaginated( + (int) $this->request->getCurrentRequest()->get('p', 1), + !($withFederated ?? false) + ), + 'withFederated' => $withFederated, + ] + ); + } + + #[IsGranted('ROLE_ADMIN')] + public function inactive() + { + return $this->render( + 'admin/users.html.twig', + [ + 'users' => $this->repository->findAllInactivePaginated( + (int) $this->request->getCurrentRequest()->get('p', 1) + ), + ] + ); + } + + #[IsGranted('ROLE_ADMIN')] + public function suspended(?bool $withFederated = null) + { + return $this->render( + 'admin/users.html.twig', + [ + 'users' => $this->repository->findAllSuspendedPaginated( + (int) $this->request->getCurrentRequest()->get('p', 1), + !($withFederated ?? false) + ), + 'withFederated' => $withFederated, + ] + ); + } + + #[IsGranted('ROLE_ADMIN')] + public function banned(?bool $withFederated = null) + { + return $this->render( + 'admin/users.html.twig', + [ + 'users' => $this->repository->findAllBannedPaginated( + (int) $this->request->getCurrentRequest()->get('p', 1), + !($withFederated ?? false) + ), + 'withFederated' => $withFederated, + ] + ); + } +} diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php index baa1c1cb9..2c7c91dda 100644 --- a/src/Repository/UserRepository.php +++ b/src/Repository/UserRepository.php @@ -239,7 +239,69 @@ public function findBlockedUsers(int $page, User $user, int $perPage = self::PER return $pagerfanta; } - public function findAllPaginated(int $page, bool $onlyLocal = false): PagerfantaInterface + public function findAllActivePaginated(int $page, bool $onlyLocal = false): PagerfantaInterface + { + $builder = $this->createQueryBuilder('u'); + if ($onlyLocal) { + $builder->where('u.apId IS NULL') + ->andWhere('u.isVerified = true'); + } else { + $builder->where('u.apId IS NOT NULL'); + } + $query = $builder + ->andWhere('u.visibility = :visibility') + ->andWhere('u.isDeleted = false') + ->andWhere('u.isBanned = false') + ->setParameter('visibility', VisibilityInterface::VISIBILITY_VISIBLE) + ->orderBy('u.createdAt', 'ASC') + ->getQuery(); + + $pagerfanta = new Pagerfanta( + new QueryAdapter( + $query + ) + ); + + try { + $pagerfanta->setMaxPerPage(self::PER_PAGE); + $pagerfanta->setCurrentPage($page); + } catch (NotValidCurrentPageException $e) { + throw new NotFoundHttpException(); + } + + return $pagerfanta; + } + + public function findAllInactivePaginated(int $page): PagerfantaInterface + { + $builder = $this->createQueryBuilder('u'); + + $query = $builder->where('u.apId IS NULL') + ->andWhere('u.visibility = :visibility') + ->andWhere('u.isVerified = false') + ->andWhere('u.isDeleted = false') + ->andWhere('u.isBanned = false') + ->setParameter('visibility', VisibilityInterface::VISIBILITY_VISIBLE) + ->orderBy('u.createdAt', 'ASC') + ->getQuery(); + + $pagerfanta = new Pagerfanta( + new QueryAdapter( + $query + ) + ); + + try { + $pagerfanta->setMaxPerPage(self::PER_PAGE); + $pagerfanta->setCurrentPage($page); + } catch (NotValidCurrentPageException $e) { + throw new NotFoundHttpException(); + } + + return $pagerfanta; + } + + public function findAllBannedPaginated(int $page, bool $onlyLocal = false): PagerfantaInterface { $builder = $this->createQueryBuilder('u'); if ($onlyLocal) { @@ -248,6 +310,39 @@ public function findAllPaginated(int $page, bool $onlyLocal = false): Pagerfanta $builder->where('u.apId IS NOT NULL'); } $query = $builder + ->andWhere('u.isBanned = true') + ->andWhere('u.isDeleted = false') + ->orderBy('u.createdAt', 'ASC') + ->getQuery(); + + $pagerfanta = new Pagerfanta( + new QueryAdapter( + $query + ) + ); + + try { + $pagerfanta->setMaxPerPage(self::PER_PAGE); + $pagerfanta->setCurrentPage($page); + } catch (NotValidCurrentPageException $e) { + throw new NotFoundHttpException(); + } + + return $pagerfanta; + } + + public function findAllSuspendedPaginated(int $page, bool $onlyLocal = false): PagerfantaInterface + { + $builder = $this->createQueryBuilder('u'); + if ($onlyLocal) { + $builder->where('u.apId IS NULL'); + } else { + $builder->where('u.apId IS NOT NULL'); + } + $query = $builder + ->andWhere('u.visibility = :visibility') + ->andWhere('u.isDeleted = false') + ->setParameter('visibility', VisibilityInterface::VISIBILITY_TRASHED) ->orderBy('u.createdAt', 'ASC') ->getQuery(); diff --git a/templates/admin/_options.html.twig b/templates/admin/_options.html.twig index 075a0821d..29fdb21b6 100644 --- a/templates/admin/_options.html.twig +++ b/templates/admin/_options.html.twig @@ -18,8 +18,8 @@
      • - + {{ 'users'|trans }}
      • diff --git a/templates/admin/users.html.twig b/templates/admin/users.html.twig index 9513c0707..9949452bd 100644 --- a/templates/admin/users.html.twig +++ b/templates/admin/users.html.twig @@ -14,10 +14,41 @@ {% block body %} {% include 'admin/_options.html.twig' %} + + + {% if(users.haveToPaginate is defined and users.haveToPaginate) %} {{ pagerfanta(users, null, {'pageParameter':'[p]'}) }} {% endif %}
        + {% if withFederated is defined %}
        + {% endif %} + + {% if not users|length %} + + + {% else %} + @@ -33,29 +73,22 @@ - {% for user in users %} - {% if not user.isDeleted %} - - {% endif %} {% endfor %}
        {{ 'email'|trans }} {{ 'created_at'|trans }} {{ 'last_active'|trans }}
        {{ component('user_inline', {user: user}) }} {{ user.apId ? '-' : user.email }} {{ component('date', {date: user.createdAt}) }} {{ component('date', {date: user.lastActive}) }} - - - {% if user.isTotpAuthenticationEnabled %} - - {% endif %} -
        + + {% endif %} +
        {% if(users.haveToPaginate is defined and users.haveToPaginate) %} {{ pagerfanta(users, null, {'pageParameter':'[p]'}) }} diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml index 111a48c84..1210b3fa6 100644 --- a/translations/messages.en.yaml +++ b/translations/messages.en.yaml @@ -361,7 +361,6 @@ meta: Meta instance: Instance pages: Pages FAQ: FAQ -inactive: Inactive type_search_term: Type search term federation_enabled: Federation enabled registrations_enabled: Registration enabled @@ -883,3 +882,7 @@ last_failed_contact: Last failed contact magazine_posting_restricted_to_mods: Restrict thread creation to moderators new_user_description: This user is new (active for less than %days% days) new_magazine_description: This magazine is new (active for less than %days% days) +admin_users_active: Active +admin_users_inactive: Inactive +admin_users_suspended: Suspended +admin_users_banned: Banned From 872d062fd90c0aeb82ed06b91b496e7794ba0503 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Mon, 5 Aug 2024 22:30:51 +0200 Subject: [PATCH 175/335] Translations update from Hosted Weblate (#999) --- translations/messages.de.yaml | 1 - translations/messages.el.yaml | 1 - translations/messages.eo.yaml | 1 - translations/messages.es.yaml | 1 - translations/messages.fil.yaml | 1 - translations/messages.fr.yaml | 1 - translations/messages.gl.yaml | 1 - translations/messages.it.yaml | 1 - translations/messages.ja.yaml | 1 - translations/messages.nl.yaml | 1 - translations/messages.pl.yaml | 1 - translations/messages.ru.yaml | 1 - translations/messages.tr.yaml | 1 - translations/messages.uk.yaml | 1 - translations/messages.zh_TW.yaml | 1 - 15 files changed, 15 deletions(-) diff --git a/translations/messages.de.yaml b/translations/messages.de.yaml index 363ecbece..2b8ee2f2b 100644 --- a/translations/messages.de.yaml +++ b/translations/messages.de.yaml @@ -321,7 +321,6 @@ random_entries: Zufällige Themen related_entries: Verwandte Themen delete_account: Konto löschen auto_preview: Automatische Medienvorschau -inactive: Inaktiv mod_remove_your_thread: Ein Moderator hat dein Thema entfernt mod_log_alert: WARNUNG - Der Modlog kann unangenehme oder verstörende Inhalte enthalten, welche von Moderatoren entfernt wurden. Bitte bedenke was du tust. diff --git a/translations/messages.el.yaml b/translations/messages.el.yaml index e4ac8835e..c89f504f2 100644 --- a/translations/messages.el.yaml +++ b/translations/messages.el.yaml @@ -261,7 +261,6 @@ admin_panel: Πίνακας Διαχειριστή dashboard: Ταμπλό contact_email: Email επικοινωνίας pages: Σελίδες -inactive: Ανενεργό type_search_term: Πληκτρολογήστε τον όρο αναζήτησης registrations_enabled: Οι εγγραφές ενεργοποιήθηκαν registration_disabled: Οι εγγραφές απενεργοποιήθηκαν diff --git a/translations/messages.eo.yaml b/translations/messages.eo.yaml index 4e54f0936..213a7d234 100644 --- a/translations/messages.eo.yaml +++ b/translations/messages.eo.yaml @@ -279,7 +279,6 @@ article: Fadeno reputation: Reputacio month: Monato instance: Nodo -inactive: Neaktiva Password is invalid: Pasvorto nevalidas. Your account has been banned: Via konto estis forbarita. send: Sendi diff --git a/translations/messages.es.yaml b/translations/messages.es.yaml index 319e64548..99a04dbcd 100644 --- a/translations/messages.es.yaml +++ b/translations/messages.es.yaml @@ -336,7 +336,6 @@ instance: Instancia registrations_enabled: Registro activado pages: Páginas FAQ: FAQ -inactive: Inactivo type_search_term: Escribir término de búsqueda federation_enabled: Federación activada registration_disabled: Inscripciones desactivadas diff --git a/translations/messages.fil.yaml b/translations/messages.fil.yaml index 696a313e1..295c6a5a9 100644 --- a/translations/messages.fil.yaml +++ b/translations/messages.fil.yaml @@ -176,7 +176,6 @@ status: Katayuan change_language: Baguhin ang wika change_magazine: baguhin ang magasin mark_as_adult: Markahin bilang NSFW -inactive: Hindi aktibo registrations_enabled: Pinagana ang pagrehistro registration_disabled: Nakapatay ang pagrehistro report_issue: Iulat ang isyu diff --git a/translations/messages.fr.yaml b/translations/messages.fr.yaml index b8d7eb234..f1f1adcc3 100644 --- a/translations/messages.fr.yaml +++ b/translations/messages.fr.yaml @@ -367,7 +367,6 @@ add_mentions_entries: Ajouter des étiquettes dans le contenu add_mentions_posts: Ajouter des étiquettes dans les messages Password is invalid: Le mot de passe n'est pas valide. Your account is not active: Votre compte n'est pas actif. -inactive: Inactif purge_account: Purger le compte magazine_panel_tags_info: Fournissez seulement si vous voulez inclure du contenu du Fédivers dans ce magazine, d'après ces étiquettes diff --git a/translations/messages.gl.yaml b/translations/messages.gl.yaml index e82f4a645..3b2c8b5dc 100644 --- a/translations/messages.gl.yaml +++ b/translations/messages.gl.yaml @@ -725,7 +725,6 @@ local: Local admin_panel: Panel Admin pages: Páxinas FAQ: PMF -inactive: Inactivo type_search_term: Escribe termo a buscar federation_enabled: A federación está activada registrations_enabled: Permítese a creación de contas diff --git a/translations/messages.it.yaml b/translations/messages.it.yaml index 7b968662d..c676798e5 100644 --- a/translations/messages.it.yaml +++ b/translations/messages.it.yaml @@ -344,7 +344,6 @@ meta: Meta instance: Istanza pages: Pagine FAQ: FAQ -inactive: Inattivo federation_enabled: Federazione abilitata registrations_enabled: Registrazioni abilitate registration_disabled: Registrazioni disabilitate diff --git a/translations/messages.ja.yaml b/translations/messages.ja.yaml index 6d07ae2f5..2570c308a 100644 --- a/translations/messages.ja.yaml +++ b/translations/messages.ja.yaml @@ -360,7 +360,6 @@ magazine_panel_tags_info: 連合するサーバーからマガジンへ特定の kbin_intro_desc: はフェディバースネットワーク内で動作する、コンテンツの集約とミニブログのための分散型プラットフォームです。 browsing_one_thread: 現在ディスカッション内の一つのスレッドだけを見ています!すべてのコメントは投稿ページから見られます。 boost: ブースト -inactive: 非アクティブ mercure_enabled: Mercureが有効 report_issue: バグを報告 tokyo_night: 東京ナイト diff --git a/translations/messages.nl.yaml b/translations/messages.nl.yaml index e53ede01e..839ed79f8 100644 --- a/translations/messages.nl.yaml +++ b/translations/messages.nl.yaml @@ -341,7 +341,6 @@ meta: Meta instance: Instantie pages: Pagina's FAQ: Veelgestelde vragen -inactive: Inactief federation_enabled: Verspreiding is ingeschakeld registrations_enabled: Registratie zijn ingeschakeld registration_disabled: Registraties zijn uitgeschakeld diff --git a/translations/messages.pl.yaml b/translations/messages.pl.yaml index 947694c82..69f5e04fd 100644 --- a/translations/messages.pl.yaml +++ b/translations/messages.pl.yaml @@ -340,7 +340,6 @@ mod_log_alert: W modlogu możesz trafić na drastyczne treści usunięte przez m mod_remove_your_post: Moderator usunął twój post ban_expired: Ban wygasa change_magazine: Zmień magazyn -inactive: Nieaktywne registration_disabled: Rejestracja wyłączona Your account is not active: Twoje konto nie jest aktywne. send: Wyślij diff --git a/translations/messages.ru.yaml b/translations/messages.ru.yaml index 5ed7b3b36..4e999b992 100644 --- a/translations/messages.ru.yaml +++ b/translations/messages.ru.yaml @@ -337,7 +337,6 @@ meta: Meta instance: Инстанс pages: Страницы FAQ: Часто задаваемые вопросы -inactive: Неактивный type_search_term: Напишите вопрос federation_enabled: Федерация включена registrations_enabled: Регистрация включена diff --git a/translations/messages.tr.yaml b/translations/messages.tr.yaml index 8a0aed377..0f119fc6c 100644 --- a/translations/messages.tr.yaml +++ b/translations/messages.tr.yaml @@ -199,7 +199,6 @@ added_new_comment: Yeri yorum ekledi registration_disabled: Kayıt devre dışı registrations_enabled: Kayıt etkinleştirildi type_search_term: Arama terimini yaz -inactive: İnaktif FAQ: SSS pages: Sayfalar instance: Örnek diff --git a/translations/messages.uk.yaml b/translations/messages.uk.yaml index 720dcf843..12f657248 100644 --- a/translations/messages.uk.yaml +++ b/translations/messages.uk.yaml @@ -168,7 +168,6 @@ oauth2.grant.moderate.magazine.ban.create: Забороняти користув спільнотах. firstname: Імʼя sidebar_position: Положення бічної панелі -inactive: Неактивні oauth2.grant.admin.user.delete: Видаляти користувачів з вашого інстансу. oauth.consent.app_requesting_permissions: хоче виконати наступні дії від вашого імені no: Ні diff --git a/translations/messages.zh_TW.yaml b/translations/messages.zh_TW.yaml index 9c912357b..00ae1e496 100644 --- a/translations/messages.zh_TW.yaml +++ b/translations/messages.zh_TW.yaml @@ -322,7 +322,6 @@ send: 傳送 contact_email: 聯絡用電子郵件 meta: Meta instance: 實體 -inactive: 不活躍 unpin: 取消訂選 registrations_enabled: 已開放註冊 federation_enabled: 已連邦 From 79b66953d6377ab0d08b7c4714a0527ff9ddaf52 Mon Sep 17 00:00:00 2001 From: debounced <35878315+nobodyatroot@users.noreply.github.com> Date: Tue, 6 Aug 2024 09:21:29 -0500 Subject: [PATCH 176/335] Add user password set/reset command to `bin/console` (#1002) --- src/Command/UserPasswordCommand.php | 68 +++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/Command/UserPasswordCommand.php diff --git a/src/Command/UserPasswordCommand.php b/src/Command/UserPasswordCommand.php new file mode 100644 index 000000000..a974b60d9 --- /dev/null +++ b/src/Command/UserPasswordCommand.php @@ -0,0 +1,68 @@ +addArgument('username', InputArgument::REQUIRED) + ->addArgument('password', InputArgument::REQUIRED); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $io = new SymfonyStyle($input, $output); + $password = $input->getArgument('password'); + $user = $this->repository->findOneByUsername($input->getArgument('username')); + + if (!$user) { + $io->error('User does not exist!'); + + return Command::FAILURE; + } + + if ($user->apId) { + $io->error('The specified account is not a local user!'); + + return Command::FAILURE; + } + + // Encode(hash) the plain password, and set it. + $encodedPassword = $this->userPasswordHasher->hashPassword( + $user, + $password + ); + + $user->setPassword($encodedPassword); + $this->entityManager->flush(); + + return Command::SUCCESS; + } +} From 6c8e54186efcd85dfcd340623d4be01145b3c2aa Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Tue, 6 Aug 2024 15:09:34 +0000 Subject: [PATCH 177/335] Fix remove moderator api throwing error (#1003) --- .../Api/Magazine/Admin/MagazineRemoveModeratorsApi.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controller/Api/Magazine/Admin/MagazineRemoveModeratorsApi.php b/src/Controller/Api/Magazine/Admin/MagazineRemoveModeratorsApi.php index a97a48d9e..c66d848dc 100644 --- a/src/Controller/Api/Magazine/Admin/MagazineRemoveModeratorsApi.php +++ b/src/Controller/Api/Magazine/Admin/MagazineRemoveModeratorsApi.php @@ -98,7 +98,7 @@ public function __invoke( throw new BadRequestHttpException('Given user is not a moderator of this magazine'); } - $manager->removeModerator($moderator); + $manager->removeModerator($moderator, $this->getUserOrThrow()); return new JsonResponse( $this->serializeMagazine($factory->createDto($magazine)), From d1c4e343064c919d03db6cd1b21d24dcb533532f Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Wed, 7 Aug 2024 11:50:03 +0000 Subject: [PATCH 178/335] Fix `ActivityHandler` errors regarding the payload (#1004) --- .../ActivityPub/Inbox/ActivityHandler.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/MessageHandler/ActivityPub/Inbox/ActivityHandler.php b/src/MessageHandler/ActivityPub/Inbox/ActivityHandler.php index 4692069a3..45431417d 100644 --- a/src/MessageHandler/ActivityPub/Inbox/ActivityHandler.php +++ b/src/MessageHandler/ActivityPub/Inbox/ActivityHandler.php @@ -31,6 +31,7 @@ use Doctrine\ORM\EntityManagerInterface; use Psr\Log\LoggerInterface; use Symfony\Component\Messenger\Attribute\AsMessageHandler; +use Symfony\Component\Messenger\Exception\UnrecoverableMessageHandlingException; use Symfony\Component\Messenger\MessageBusInterface; #[AsMessageHandler] @@ -60,8 +61,14 @@ public function doWork(MessageInterface $message): void if (!($message instanceof ActivityMessage)) { throw new \LogicException(); } + $payload = @json_decode($message->payload, true); + if (null === $payload) { + $this->logger->warning('activity message from was empty: {json}, ignoring it', ['json' => json_encode($message->payload)]); + throw new UnrecoverableMessageHandlingException('activity message from was empty'); + } + if ($message->request && $message->headers) { try { $this->signatureValidator->validate($message->request, $message->headers, $message->payload); @@ -78,6 +85,11 @@ public function doWork(MessageInterface $message): void } } + if (null === $payload['id']) { + $this->logger->warning('activity message has no id field which is required: {json}', ['json' => json_encode($message->payload)]); + throw new UnrecoverableMessageHandlingException('activity message has no id field'); + } + $idHost = parse_url($payload['id'], PHP_URL_HOST); if ($idHost) { $instance = $this->instanceRepository->findOneBy(['domain' => $idHost]); From 710755d5fc61ca0236a5e151e6b0a795b2502663 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Wed, 7 Aug 2024 11:51:45 +0000 Subject: [PATCH 179/335] Fix the managers checking wrong fields for editing permissions (#1005) --- src/Service/EntryCommentManager.php | 4 ++-- src/Service/EntryManager.php | 4 ++-- src/Service/PostCommentManager.php | 4 ++-- src/Service/PostManager.php | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Service/EntryCommentManager.php b/src/Service/EntryCommentManager.php index 6ca55a853..adaa6a4ed 100644 --- a/src/Service/EntryCommentManager.php +++ b/src/Service/EntryCommentManager.php @@ -106,8 +106,8 @@ public function create(EntryCommentDto $dto, User $user, $rateLimit = true): Ent public function canUserEditComment(EntryComment $comment, User $user): bool { $entryCommentHost = null !== $comment->apId ? parse_url($comment->apId, PHP_URL_HOST) : $this->settingsManager->get('KBIN_DOMAIN'); - $userHost = null !== $user->apId ? parse_url($user->apId, PHP_URL_HOST) : $this->settingsManager->get('KBIN_DOMAIN'); - $magazineHost = null !== $comment->magazine->apId ? parse_url($comment->magazine->apId, PHP_URL_HOST) : $this->settingsManager->get('KBIN_DOMAIN'); + $userHost = null !== $user->apId ? parse_url($user->apProfileId, PHP_URL_HOST) : $this->settingsManager->get('KBIN_DOMAIN'); + $magazineHost = null !== $comment->magazine->apId ? parse_url($comment->magazine->apProfileId, PHP_URL_HOST) : $this->settingsManager->get('KBIN_DOMAIN'); return $entryCommentHost === $userHost || $userHost === $magazineHost || $comment->magazine->userIsModerator($user); } diff --git a/src/Service/EntryManager.php b/src/Service/EntryManager.php index e176e28d1..0d600a1f9 100644 --- a/src/Service/EntryManager.php +++ b/src/Service/EntryManager.php @@ -174,8 +174,8 @@ private function setType(EntryDto $dto, Entry $entry): Entry public function canUserEditEntry(Entry $entry, User $user): bool { $entryHost = null !== $entry->apId ? parse_url($entry->apId, PHP_URL_HOST) : $this->settingsManager->get('KBIN_DOMAIN'); - $userHost = null !== $user->apId ? parse_url($user->apId, PHP_URL_HOST) : $this->settingsManager->get('KBIN_DOMAIN'); - $magazineHost = null !== $entry->magazine->apId ? parse_url($entry->magazine->apId, PHP_URL_HOST) : $this->settingsManager->get('KBIN_DOMAIN'); + $userHost = null !== $user->apId ? parse_url($user->apProfileId, PHP_URL_HOST) : $this->settingsManager->get('KBIN_DOMAIN'); + $magazineHost = null !== $entry->magazine->apId ? parse_url($entry->magazine->apProfileId, PHP_URL_HOST) : $this->settingsManager->get('KBIN_DOMAIN'); return $entryHost === $userHost || $userHost === $magazineHost || $entry->magazine->userIsModerator($user); } diff --git a/src/Service/PostCommentManager.php b/src/Service/PostCommentManager.php index 517728256..2b57336fb 100644 --- a/src/Service/PostCommentManager.php +++ b/src/Service/PostCommentManager.php @@ -111,8 +111,8 @@ public function create(PostCommentDto $dto, User $user, $rateLimit = true): Post public function canUserEditPostComment(PostComment $postComment, User $user): bool { $postCommentHost = null !== $postComment->apId ? parse_url($postComment->apId, PHP_URL_HOST) : $this->settingsManager->get('KBIN_DOMAIN'); - $userHost = null !== $user->apId ? parse_url($user->apId, PHP_URL_HOST) : $this->settingsManager->get('KBIN_DOMAIN'); - $magazineHost = null !== $postComment->magazine->apId ? parse_url($postComment->magazine->apId, PHP_URL_HOST) : $this->settingsManager->get('KBIN_DOMAIN'); + $userHost = null !== $user->apId ? parse_url($user->apProfileId, PHP_URL_HOST) : $this->settingsManager->get('KBIN_DOMAIN'); + $magazineHost = null !== $postComment->magazine->apId ? parse_url($postComment->magazine->apProfileId, PHP_URL_HOST) : $this->settingsManager->get('KBIN_DOMAIN'); return $postCommentHost === $userHost || $userHost === $magazineHost || $postComment->magazine->userIsModerator($user); } diff --git a/src/Service/PostManager.php b/src/Service/PostManager.php index a30898921..9e3b7dccf 100644 --- a/src/Service/PostManager.php +++ b/src/Service/PostManager.php @@ -125,8 +125,8 @@ public function create(PostDto $dto, User $user, $rateLimit = true, bool $sticky public function canUserEditPost(Post $post, User $user): bool { $postHost = null !== $post->apId ? parse_url($post->apId, PHP_URL_HOST) : $this->settingsManager->get('KBIN_DOMAIN'); - $userHost = null !== $user->apId ? parse_url($user->apId, PHP_URL_HOST) : $this->settingsManager->get('KBIN_DOMAIN'); - $magazineHost = null !== $post->magazine->apId ? parse_url($post->magazine->apId, PHP_URL_HOST) : $this->settingsManager->get('KBIN_DOMAIN'); + $userHost = null !== $user->apId ? parse_url($user->apProfileId, PHP_URL_HOST) : $this->settingsManager->get('KBIN_DOMAIN'); + $magazineHost = null !== $post->magazine->apId ? parse_url($post->magazine->apProfileId, PHP_URL_HOST) : $this->settingsManager->get('KBIN_DOMAIN'); return $postHost === $userHost || $userHost === $magazineHost || $post->magazine->userIsModerator($user); } From 4c7182f79712b699a282675953516bc9bfe4481e Mon Sep 17 00:00:00 2001 From: debounced <35878315+nobodyatroot@users.noreply.github.com> Date: Thu, 8 Aug 2024 11:55:28 -0500 Subject: [PATCH 180/335] Allow admins to activate/verify accounts manually using the admin user panel (#1000) --- config/kbin_routes/user.yaml | 5 +++ .../User/Profile/UserVerifyController.php | 39 +++++++++++++++++++ src/Service/UserManager.php | 8 ++++ templates/user/overview.html.twig | 13 ++++++- translations/messages.en.yaml | 1 + 5 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 src/Controller/User/Profile/UserVerifyController.php diff --git a/config/kbin_routes/user.yaml b/config/kbin_routes/user.yaml index fbedd178a..6cc4f782e 100644 --- a/config/kbin_routes/user.yaml +++ b/config/kbin_routes/user.yaml @@ -119,6 +119,11 @@ user_note: path: /u/{username}/note methods: [POST] +user_verify: + controller: App\Controller\User\Profile\UserVerifyController + path: /u/{username}/verify + methods: [POST] + user_remove_following: controller: App\Controller\User\UserRemoveFollowing path: /u/{username}/remove_following diff --git a/src/Controller/User/Profile/UserVerifyController.php b/src/Controller/User/Profile/UserVerifyController.php new file mode 100644 index 000000000..ecfb784a8 --- /dev/null +++ b/src/Controller/User/Profile/UserVerifyController.php @@ -0,0 +1,39 @@ +validateCsrf('user_verify', $request->request->get('token')); + + $this->manager->adminUserVerify($user); + + if ($request->isXmlHttpRequest()) { + return new JsonResponse( + [ + 'isVerified' => true, + ] + ); + } + + return $this->redirectToRefererOrHome($request); + } +} diff --git a/src/Service/UserManager.php b/src/Service/UserManager.php index 8853248b3..922441972 100644 --- a/src/Service/UserManager.php +++ b/src/Service/UserManager.php @@ -252,6 +252,14 @@ public function verify(Request $request, User $user): void $this->verifier->handleEmailConfirmation($request, $user); } + public function adminUserVerify(User $user): void + { + $user->isVerified = true; + + $this->entityManager->persist($user); + $this->entityManager->flush(); + } + public function toggleTheme(User $user): void { $user->toggleTheme(); diff --git a/templates/user/overview.html.twig b/templates/user/overview.html.twig index cc57f1dfe..ca0c59ee7 100644 --- a/templates/user/overview.html.twig +++ b/templates/user/overview.html.twig @@ -15,6 +15,17 @@

        {{ 'admin_panel'|trans }}

        + {% if user.apId is same as null and not user.isVerified and is_granted('ROLE_ADMIN') %} +
        + + +
        +
        + {% endif %} {% if user.isTotpAuthenticationEnabled and is_granted('ROLE_ADMIN') %}
        diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml index 1210b3fa6..9aba3aa3a 100644 --- a/translations/messages.en.yaml +++ b/translations/messages.en.yaml @@ -886,3 +886,4 @@ admin_users_active: Active admin_users_inactive: Inactive admin_users_suspended: Suspended admin_users_banned: Banned +user_verify: Activate account From 8949499dd7474f830bd92823a85dc9513d3ee5f6 Mon Sep 17 00:00:00 2001 From: debounced <35878315+nobodyatroot@users.noreply.github.com> Date: Thu, 8 Aug 2024 16:24:01 -0500 Subject: [PATCH 181/335] Stop banned or suspended users from notification creation on posts and entries (#1007) --- src/Entity/User.php | 10 ++++++++++ .../Notification/EntryCommentNotificationManager.php | 4 ++++ src/Service/Notification/EntryNotificationManager.php | 4 ++++ .../Notification/PostCommentNotificationManager.php | 4 ++++ src/Service/Notification/PostNotificationManager.php | 4 ++++ 5 files changed, 26 insertions(+) diff --git a/src/Entity/User.php b/src/Entity/User.php index f8bd9271a..dcf2d5af9 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -828,11 +828,21 @@ public function softDelete(): void $this->visibility = self::VISIBILITY_SOFT_DELETED; } + public function isSoftDeleted(): bool + { + return self::VISIBILITY_SOFT_DELETED === $this->visibility; + } + public function trash(): void { $this->visibility = self::VISIBILITY_TRASHED; } + public function isTrashed(): bool + { + return self::VISIBILITY_TRASHED === $this->visibility; + } + public function restore(): void { $this->visibility = VisibilityInterface::VISIBILITY_VISIBLE; diff --git a/src/Service/Notification/EntryCommentNotificationManager.php b/src/Service/Notification/EntryCommentNotificationManager.php index 82a024cc4..017e71321 100644 --- a/src/Service/Notification/EntryCommentNotificationManager.php +++ b/src/Service/Notification/EntryCommentNotificationManager.php @@ -56,6 +56,10 @@ public function __construct( // @todo check if author is on the block list public function sendCreated(ContentInterface $subject): void { + if ($subject->user->isBanned || $subject->user->isDeleted || $subject->user->isTrashed() || $subject->user->isSoftDeleted()) { + return; + } + /** * @var EntryComment $subject */ diff --git a/src/Service/Notification/EntryNotificationManager.php b/src/Service/Notification/EntryNotificationManager.php index fd3da855e..722aa8adc 100644 --- a/src/Service/Notification/EntryNotificationManager.php +++ b/src/Service/Notification/EntryNotificationManager.php @@ -54,6 +54,10 @@ public function __construct( // @todo check if author is on the block list public function sendCreated(ContentInterface $subject): void { + if ($subject->user->isBanned || $subject->user->isDeleted || $subject->user->isTrashed() || $subject->user->isSoftDeleted()) { + return; + } + /* * @var Entry $subject */ diff --git a/src/Service/Notification/PostCommentNotificationManager.php b/src/Service/Notification/PostCommentNotificationManager.php index 3b5a2ceca..25b2674b8 100644 --- a/src/Service/Notification/PostCommentNotificationManager.php +++ b/src/Service/Notification/PostCommentNotificationManager.php @@ -56,6 +56,10 @@ public function __construct( // @todo check if author is on the block list public function sendCreated(ContentInterface $subject): void { + if ($subject->user->isBanned || $subject->user->isDeleted || $subject->user->isTrashed() || $subject->user->isSoftDeleted()) { + return; + } + /** * @var PostComment $subject */ diff --git a/src/Service/Notification/PostNotificationManager.php b/src/Service/Notification/PostNotificationManager.php index 3d6bfad8e..7661adebe 100644 --- a/src/Service/Notification/PostNotificationManager.php +++ b/src/Service/Notification/PostNotificationManager.php @@ -53,6 +53,10 @@ public function __construct( // @todo check if author is on the block list public function sendCreated(ContentInterface $subject): void { + if ($subject->user->isBanned || $subject->user->isDeleted || $subject->user->isTrashed() || $subject->user->isSoftDeleted()) { + return; + } + /* * @var Post $subject */ From 0199619fd90d12049fe24302cc2cc01c50ada28f Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Thu, 8 Aug 2024 21:44:00 +0000 Subject: [PATCH 182/335] Invalidate collection cache before getting collection for likes, dislikes and shares (#1008) --- src/Service/ActivityPubManager.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Service/ActivityPubManager.php b/src/Service/ActivityPubManager.php index c2eb61c0f..cc00ed3cc 100644 --- a/src/Service/ActivityPubManager.php +++ b/src/Service/ActivityPubManager.php @@ -1082,6 +1082,7 @@ public function extractRemoteLikeCount(array $apObject): ?int { if (!empty($apObject['likes'])) { if (false !== filter_var($apObject['likes'], FILTER_VALIDATE_URL)) { + $this->apHttpClient->invalidateCollectionObjectCache($apObject['likes']); $collection = $this->apHttpClient->getCollectionObject($apObject['likes']); if (isset($collection['totalItems']) && \is_int($collection['totalItems'])) { return $collection['totalItems']; @@ -1096,6 +1097,7 @@ public function extractRemoteDislikeCount(array $apObject): ?int { if (!empty($apObject['dislikes'])) { if (false !== filter_var($apObject['dislikes'], FILTER_VALIDATE_URL)) { + $this->apHttpClient->invalidateCollectionObjectCache($apObject['dislikes']); $collection = $this->apHttpClient->getCollectionObject($apObject['dislikes']); if (isset($collection['totalItems']) && \is_int($collection['totalItems'])) { return $collection['totalItems']; @@ -1110,6 +1112,7 @@ public function extractRemoteShareCount(array $apObject): ?int { if (!empty($apObject['shares'])) { if (false !== filter_var($apObject['shares'], FILTER_VALIDATE_URL)) { + $this->apHttpClient->invalidateCollectionObjectCache($apObject['shares']); $collection = $this->apHttpClient->getCollectionObject($apObject['shares']); if (isset($collection['totalItems']) && \is_int($collection['totalItems'])) { return $collection['totalItems']; From 27abb8074001004047e16a1556d35fe4740f5f51 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Fri, 9 Aug 2024 14:55:15 +0000 Subject: [PATCH 183/335] Bump version to 1.7.1-rc1 (#1010) --- config/packages/framework.yaml | 2 +- src/Service/ProjectInfoService.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml index 6a4cbd2b9..1123ce187 100644 --- a/config/packages/framework.yaml +++ b/config/packages/framework.yaml @@ -17,7 +17,7 @@ framework: http_client: default_options: headers: - 'User-Agent': 'Mbin/1.7.0 (+https://%kbin_domain%/agent)' + 'User-Agent': 'Mbin/1.7.1-rc1 (+https://%kbin_domain%/agent)' #esi: true #fragments: true diff --git a/src/Service/ProjectInfoService.php b/src/Service/ProjectInfoService.php index c7f83eef8..10bf0683e 100644 --- a/src/Service/ProjectInfoService.php +++ b/src/Service/ProjectInfoService.php @@ -10,7 +10,7 @@ class ProjectInfoService { // If updating version, please also update http client UA in [/config/packages/framework.yaml] - private const VERSION = '1.7.0'; // TODO: Retrieve the version from git tags or getenv()? + private const VERSION = '1.7.1-rc1'; // TODO: Retrieve the version from git tags or getenv()? private const NAME = 'mbin'; private const USER_AGENT = 'Mbin'; private const REPOSITORY_URL = 'https://github.com/MbinOrg/mbin'; From c46b9c3fe2fa3367cffb819a5e5761e50834a35d Mon Sep 17 00:00:00 2001 From: asdfzdfj Date: Fri, 9 Aug 2024 23:40:15 +0700 Subject: [PATCH 184/335] add default null to Instance entity nullables field (#1006) add default values of null to DB nullable properties to prevent access before initialization problems on php side currently observed the error with the field `Instance::$lastSuccessfulReceive` but added null default to all nullable fields just in case "Handling "App\Message\ActivityPub\Inbox\ActivityMessage" failed: Typed property App\Entity\Instance::$lastSuccessfulReceive must not be accessed before initialization" --- src/Entity/Instance.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Entity/Instance.php b/src/Entity/Instance.php index b2dd4d0b3..270d9fddd 100644 --- a/src/Entity/Instance.php +++ b/src/Entity/Instance.php @@ -27,22 +27,22 @@ public static function getDateBeforeDead(): \DateTimeImmutable } #[Column(nullable: true)] - public ?string $software; + public ?string $software = null; #[Column(nullable: true)] - public ?string $version; + public ?string $version = null; #[Column(unique: true)] public string $domain; #[Column(type: 'datetimetz_immutable', nullable: true)] - private ?\DateTimeImmutable $lastSuccessfulDeliver; + private ?\DateTimeImmutable $lastSuccessfulDeliver = null; #[Column(type: 'datetimetz_immutable', nullable: true)] - private ?\DateTimeImmutable $lastFailedDeliver; + private ?\DateTimeImmutable $lastFailedDeliver = null; #[Column(type: 'datetimetz_immutable', nullable: true)] - private ?\DateTimeImmutable $lastSuccessfulReceive; + private ?\DateTimeImmutable $lastSuccessfulReceive = null; #[Column] private int $failedDelivers = 0; From aa954bc54668d610225265ae6f885c44cd4ca899 Mon Sep 17 00:00:00 2001 From: debounced <35878315+nobodyatroot@users.noreply.github.com> Date: Fri, 9 Aug 2024 14:16:41 -0500 Subject: [PATCH 185/335] Remove `\intval` around `MAX_IMAGE_BYTES` in `src/Service/SettingsManager.php`, breaks settings name resolution (#1011) --- src/Service/SettingsManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Service/SettingsManager.php b/src/Service/SettingsManager.php index c510dd146..f05e30ca4 100644 --- a/src/Service/SettingsManager.php +++ b/src/Service/SettingsManager.php @@ -75,7 +75,7 @@ public function __construct( $this->find($results, 'MBIN_SSO_REGISTRATIONS_ENABLED', FILTER_VALIDATE_BOOLEAN) ?? true, $this->find($results, 'MBIN_RESTRICT_MAGAZINE_CREATION', FILTER_VALIDATE_BOOLEAN) ?? false, $this->find($results, 'MBIN_SSO_SHOW_FIRST', FILTER_VALIDATE_BOOLEAN) ?? false, - \intval($this->find($results, 'MAX_IMAGE_BYTES', FILTER_VALIDATE_INT)) ?? $this->maxImageBytes + $this->find($results, 'MAX_IMAGE_BYTES', FILTER_VALIDATE_INT) ?? $this->maxImageBytes ); } } From fb97be2694159e633cda4d41287da996de025242 Mon Sep 17 00:00:00 2001 From: debounced <35878315+nobodyatroot@users.noreply.github.com> Date: Sat, 10 Aug 2024 10:33:47 -0500 Subject: [PATCH 186/335] Add trusted proxy config to framework configuration (#1012) --- .env.example | 5 +++++ .env.example_docker | 5 +++++ config/packages/framework.yaml | 2 ++ 3 files changed, 12 insertions(+) diff --git a/.env.example b/.env.example index c76c6ccd8..7aa3d6a92 100644 --- a/.env.example +++ b/.env.example @@ -32,6 +32,11 @@ KBIN_HEADER_LOGO=false KBIN_FEDERATION_PAGE_ENABLED=true MBIN_DEFAULT_THEME=default +# If you are running Mbin behind a reverse proxy, uncomment the line below and adjust the proxy address/range below +# to your server's IP address if it does not already fall within the private IP spaces specified. +#TRUSTED_PROXIES=::1,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 +TRUSTED_PROXIES= + # Max image filesize (in bytes) # This should be set to <= `upload_max_filesize` and `post_max_size` in the server's php.ini file MAX_IMAGE_BYTES=6000000 diff --git a/.env.example_docker b/.env.example_docker index 36f0b811b..94d692b03 100644 --- a/.env.example_docker +++ b/.env.example_docker @@ -32,6 +32,11 @@ KBIN_HEADER_LOGO=false KBIN_FEDERATION_PAGE_ENABLED=true MBIN_DEFAULT_THEME=default +# If you are running Mbin behind a reverse proxy, uncomment the line below and adjust the proxy address/range below +# to your server's IP address if it does not already fall within the private IP spaces specified. +TRUSTED_PROXIES=::1,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 +#TRUSTED_PROXIES= + # Max image filesize (in bytes) # This should be set to <= `upload_max_filesize` and `post_max_size` in the server's php.ini file MAX_IMAGE_BYTES=6000000 diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml index 1123ce187..b58ae0a6b 100644 --- a/config/packages/framework.yaml +++ b/config/packages/framework.yaml @@ -4,6 +4,8 @@ framework: annotations: false #no longer supported http_method_override: false handle_all_throwables: true + trusted_proxies: '%env(string:default::TRUSTED_PROXIES)%' + trusted_headers: ['x-forwarded-for', 'x-forwarded-proto', 'x-forwarded-port', 'x-forwarded-prefix'] # Enables session support. Note that the session will ONLY be started if you read or write from it. # Remove or comment this section to explicitly disable session support. From 69438cda7d3db360a24655824f38bd7a1bdfe90e Mon Sep 17 00:00:00 2001 From: debounced <35878315+nobodyatroot@users.noreply.github.com> Date: Sun, 11 Aug 2024 16:19:53 -0500 Subject: [PATCH 187/335] Version bump for 1.7.1-rc2 (#1015) --- config/packages/framework.yaml | 2 +- src/Service/ProjectInfoService.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml index b58ae0a6b..4ee3aadcc 100644 --- a/config/packages/framework.yaml +++ b/config/packages/framework.yaml @@ -19,7 +19,7 @@ framework: http_client: default_options: headers: - 'User-Agent': 'Mbin/1.7.1-rc1 (+https://%kbin_domain%/agent)' + 'User-Agent': 'Mbin/1.7.1-rc2 (+https://%kbin_domain%/agent)' #esi: true #fragments: true diff --git a/src/Service/ProjectInfoService.php b/src/Service/ProjectInfoService.php index 10bf0683e..50103727a 100644 --- a/src/Service/ProjectInfoService.php +++ b/src/Service/ProjectInfoService.php @@ -10,7 +10,7 @@ class ProjectInfoService { // If updating version, please also update http client UA in [/config/packages/framework.yaml] - private const VERSION = '1.7.1-rc1'; // TODO: Retrieve the version from git tags or getenv()? + private const VERSION = '1.7.1-rc2'; // TODO: Retrieve the version from git tags or getenv()? private const NAME = 'mbin'; private const USER_AGENT = 'Mbin'; private const REPOSITORY_URL = 'https://github.com/MbinOrg/mbin'; From eb65fe9fb28fd9574dc35243fe2fe6e536dac392 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Mon, 12 Aug 2024 14:53:36 +0200 Subject: [PATCH 188/335] Translations update from Hosted Weblate (#1017) Co-authored-by: hankskyjames777 --- translations/messages.fil.yaml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/translations/messages.fil.yaml b/translations/messages.fil.yaml index 295c6a5a9..ca25953ab 100644 --- a/translations/messages.fil.yaml +++ b/translations/messages.fil.yaml @@ -196,7 +196,7 @@ position_top: Itaas pending: Nakabinbin close: Isara direct_message: Direktang mensahe -top: Itaas +top: Pinakamahusay edited_post: Binago ang post edited_comment: Binago ang puna last_active: Huling Aktibo @@ -219,3 +219,11 @@ own_report_accepted: Natanggap ang iyong ulat own_report_rejected: Naitanggi ang iyong ulat reported_user: Iniulat na tagagamit reporting_user: Paguulat sa tagagamit +last_successful_receive: Huling matagumpay na pagtanggap +notification_title_message: Bagong direktang mensahe +hide: Itago +show: Ipakita +purge_magazine: Purgahin ang magasin +sensitive_hide: Pindutin upang itago +sensitive_show: Pindutin upang ipakita +sensitive_warning: Sensitibong nilalaman From 55944427433b755f56e94f091fe8103158ef06d0 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Mon, 12 Aug 2024 17:29:54 +0000 Subject: [PATCH 189/335] Make the API return the server public key and add a dedicated route for it (#1018) --- config/kbin_routes/notification_api.yaml | 6 +++ .../Api/Notification/NotificationPushApi.php | 52 ++++++++++++++++++- src/DTO/ServerPublicKeyDto.php | 13 +++++ 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 src/DTO/ServerPublicKeyDto.php diff --git a/config/kbin_routes/notification_api.yaml b/config/kbin_routes/notification_api.yaml index f18cadf28..bf1537e4d 100644 --- a/config/kbin_routes/notification_api.yaml +++ b/config/kbin_routes/notification_api.yaml @@ -47,6 +47,12 @@ api_notification_retrieve: methods: [ GET ] format: json +api_notification_push_get_public_key: + controller: App\Controller\Api\Notification\NotificationPushApi::GetServerPublicPushKey + path: /api/notification/push/publicKey + methods: [ GET ] + format: json + api_notification_push_register: controller: App\Controller\Api\Notification\NotificationPushApi::createSubscription path: /api/notification/push diff --git a/src/Controller/Api/Notification/NotificationPushApi.php b/src/Controller/Api/Notification/NotificationPushApi.php index 86a5c8d17..46dccb1c8 100644 --- a/src/Controller/Api/Notification/NotificationPushApi.php +++ b/src/Controller/Api/Notification/NotificationPushApi.php @@ -6,8 +6,10 @@ use App\Controller\Traits\PrivateContentTrait; use App\DTO\NotificationPushSubscriptionRequestDto; +use App\DTO\ServerPublicKeyDto; use App\Entity\UserPushSubscription; use App\Payloads\PushNotification; +use App\Repository\SiteRepository; use App\Repository\UserPushSubscriptionRepository; use App\Schema\Errors\ForbiddenErrorSchema; use App\Schema\Errors\NotFoundErrorSchema; @@ -29,6 +31,53 @@ class NotificationPushApi extends NotificationBaseApi { use PrivateContentTrait; + #[OA\Response( + response: 200, + description: '', + headers: [ + new OA\Header(header: 'X-RateLimit-Remaining', description: 'Number of requests left until you will be rate limited', schema: new OA\Schema(type: 'integer')), + new OA\Header(header: 'X-RateLimit-Retry-After', description: 'Unix timestamp to retry the request after', schema: new OA\Schema(type: 'integer')), + new OA\Header(header: 'X-RateLimit-Limit', description: 'Number of requests available', schema: new OA\Schema(type: 'integer')), + ], + content: new OA\JsonContent(ref: new Model(type: ServerPublicKeyDto::class)) + )] + #[OA\Response( + response: 401, + description: 'Permission denied due to missing or expired token', + content: new OA\JsonContent(ref: new Model(type: UnauthorizedErrorSchema::class)) + )] + #[OA\Response( + response: 403, + description: 'You are not allowed to get the public push key', + content: new OA\JsonContent(ref: new Model(type: ForbiddenErrorSchema::class)) + )] + #[OA\Response( + response: 429, + description: 'You are being rate limited', + headers: [ + new OA\Header(header: 'X-RateLimit-Remaining', description: 'Number of requests left until you will be rate limited', schema: new OA\Schema(type: 'integer')), + new OA\Header(header: 'X-RateLimit-Retry-After', description: 'Unix timestamp to retry the request after', schema: new OA\Schema(type: 'integer')), + new OA\Header(header: 'X-RateLimit-Limit', description: 'Number of requests available', schema: new OA\Schema(type: 'integer')), + ], + content: new OA\JsonContent(ref: new Model(type: TooManyRequestsErrorSchema::class)) + )] + #[OA\RequestBody(content: new Model(type: NotificationPushSubscriptionRequestDto::class))] + #[OA\Tag(name: 'notification')] + #[Security(name: 'oauth2', scopes: ['user:notification:read'])] + #[IsGranted('ROLE_OAUTH2_USER:NOTIFICATION:READ')] + /** + * Get the public push key of the server. + */ + public function GetServerPublicPushKey( + RateLimiterFactory $apiNotificationLimiter, + SiteRepository $siteRepository, + ): JsonResponse { + $headers = $this->rateLimit($apiNotificationLimiter); + $user = $this->getUserOrThrow(); + + return new JsonResponse(new ServerPublicKeyDto($siteRepository->findAll()[0]->pushPublicKey), headers: $headers); + } + #[OA\Response( response: 200, description: 'Created a new push subscription. If there already is a push subscription for this client it will be overwritten. a test notification will be sent right away', @@ -71,6 +120,7 @@ public function createSubscription( SettingsManager $settingsManager, UserPushSubscriptionManager $pushSubscriptionManager, TranslatorInterface $translator, + SiteRepository $siteRepository, #[MapRequestPayload] NotificationPushSubscriptionRequestDto $payload ): JsonResponse { $headers = $this->rateLimit($apiNotificationLimiter); @@ -95,7 +145,7 @@ public function createSubscription( $testNotification = new PushNotification('', $translator->trans('test_push_message', locale: $pushSubscription->locale)); $pushSubscriptionManager->sendTextToUser($user, $testNotification, specificToken: $apiToken); - return new JsonResponse(headers: $headers); + return new JsonResponse(new ServerPublicKeyDto($siteRepository->findAll()[0]->pushPublicKey), headers: $headers); } catch (\ErrorException $e) { $this->logger->error('There was an exception while deleting a UserPushSubscription: {e} - {m}. {o}', [ 'e' => \get_class($e), diff --git a/src/DTO/ServerPublicKeyDto.php b/src/DTO/ServerPublicKeyDto.php new file mode 100644 index 000000000..65ac9256b --- /dev/null +++ b/src/DTO/ServerPublicKeyDto.php @@ -0,0 +1,13 @@ + Date: Mon, 12 Aug 2024 19:07:22 +0000 Subject: [PATCH 190/335] Use the default when the value is zero (#1020) --- src/Service/SettingsManager.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Service/SettingsManager.php b/src/Service/SettingsManager.php index f05e30ca4..edd3ad812 100644 --- a/src/Service/SettingsManager.php +++ b/src/Service/SettingsManager.php @@ -41,6 +41,11 @@ public function __construct( if (!self::$dto) { $results = $this->repository->findAll(); + $maxImageBytesEdited = $this->find($results, 'MAX_IMAGE_BYTES', FILTER_VALIDATE_INT); + if (null === $maxImageBytesEdited || 0 === $maxImageBytesEdited) { + $maxImageBytesEdited = $this->maxImageBytes; + } + self::$dto = new SettingsDto( $this->kbinDomain, $this->find($results, 'KBIN_TITLE') ?? $this->kbinTitle, @@ -75,7 +80,7 @@ public function __construct( $this->find($results, 'MBIN_SSO_REGISTRATIONS_ENABLED', FILTER_VALIDATE_BOOLEAN) ?? true, $this->find($results, 'MBIN_RESTRICT_MAGAZINE_CREATION', FILTER_VALIDATE_BOOLEAN) ?? false, $this->find($results, 'MBIN_SSO_SHOW_FIRST', FILTER_VALIDATE_BOOLEAN) ?? false, - $this->find($results, 'MAX_IMAGE_BYTES', FILTER_VALIDATE_INT) ?? $this->maxImageBytes + $maxImageBytesEdited ); } } @@ -168,4 +173,11 @@ public function getLocale(): string return $request->cookies->get('kbin_lang') ?? $request->getLocale() ?? $this->get('KBIN_DEFAULT_LANG'); } + + public function getMaxImageByteString(): string + { + $megaBytes = round($this->maxImageBytes / 1024 / 1024, 2); + + return $megaBytes.'MB'; + } } From e4f1139e9ab51fac5c32f3ddb75246d87c3393bd Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Mon, 12 Aug 2024 19:08:59 +0000 Subject: [PATCH 191/335] Add an image too large error (#1019) --- .../Entry/EntryCreateController.php | 24 +++++++++++++++++++ src/Controller/Entry/EntryEditController.php | 4 ++++ src/Repository/ImageRepository.php | 16 ++++++++----- templates/layout/_form_media.html.twig | 3 +++ translations/messages.en.yaml | 2 ++ 5 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/Controller/Entry/EntryCreateController.php b/src/Controller/Entry/EntryCreateController.php index c114248d0..a9fa41b86 100644 --- a/src/Controller/Entry/EntryCreateController.php +++ b/src/Controller/Entry/EntryCreateController.php @@ -7,6 +7,7 @@ use App\Controller\AbstractController; use App\DTO\EntryDto; use App\Entity\Magazine; +use App\Exception\ImageDownloadTooLargeException; use App\Exception\PostingRestrictedException; use App\Exception\TagBannedException; use App\PageView\EntryPageView; @@ -16,12 +17,14 @@ use App\Service\EntryCommentManager; use App\Service\EntryManager; use App\Service\IpResolver; +use App\Service\SettingsManager; use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\Security\Http\Attribute\IsGranted; use Symfony\Component\Validator\Validator\ValidatorInterface; +use Symfony\Contracts\Translation\TranslatorInterface; class EntryCreateController extends AbstractController { @@ -29,6 +32,8 @@ class EntryCreateController extends AbstractController use EntryFormTrait; public function __construct( + private readonly TranslatorInterface $translator, + private readonly SettingsManager $settingsManager, private readonly LoggerInterface $logger, private readonly TagLinkRepository $tagLinkRepository, private readonly TagRepository $tagRepository, @@ -45,6 +50,7 @@ public function __invoke(?Magazine $magazine, ?string $type, Request $request): $dto = new EntryDto(); $dto->magazine = $magazine; $user = $this->getUserOrThrow(); + $maxBytes = $this->settingsManager->getMaxImageByteString(); $form = $this->createFormByType((new EntryPageView(1))->resolveType($type), $dto); try { @@ -85,6 +91,7 @@ public function __invoke(?Magazine $magazine, ?string $type, Request $request): 'magazine' => $magazine, 'user' => $user, 'form' => $form->createView(), + 'maxSize' => $maxBytes, ], new Response(null, $form->isSubmitted() && !$form->isValid() ? 422 : 200) ); @@ -99,6 +106,7 @@ public function __invoke(?Magazine $magazine, ?string $type, Request $request): 'magazine' => $magazine, 'user' => $user, 'form' => $form->createView(), + 'maxSize' => $maxBytes, ], new Response(null, 422) ); @@ -112,6 +120,21 @@ public function __invoke(?Magazine $magazine, ?string $type, Request $request): 'magazine' => $magazine, 'user' => $user, 'form' => $form->createView(), + 'maxSize' => $maxBytes, + ], + new Response(null, 422) + ); + } catch (ImageDownloadTooLargeException $e) { + $this->addFlash('error', $this->translator->trans('flash_image_download_too_large_error', ['%bytes%' => $maxBytes])); + $this->logger->error($e); + + return $this->render( + $this->getTemplateName((new EntryPageView(1))->resolveType($type)), + [ + 'magazine' => $magazine, + 'user' => $user, + 'form' => $form->createView(), + 'maxSize' => $maxBytes, ], new Response(null, 422) ); @@ -126,6 +149,7 @@ public function __invoke(?Magazine $magazine, ?string $type, Request $request): 'magazine' => $magazine, 'user' => $user, 'form' => $form->createView(), + 'maxSize' => $maxBytes, ], new Response(null, 422) ); diff --git a/src/Controller/Entry/EntryEditController.php b/src/Controller/Entry/EntryEditController.php index d54357a9b..0db5f481c 100644 --- a/src/Controller/Entry/EntryEditController.php +++ b/src/Controller/Entry/EntryEditController.php @@ -10,6 +10,7 @@ use App\Entity\Magazine; use App\Form\EntryEditType; use App\Service\EntryManager; +use App\Service\SettingsManager; use Psr\Log\LoggerInterface; use Symfony\Bridge\Doctrine\Attribute\MapEntity; use Symfony\Component\HttpFoundation\Request; @@ -24,6 +25,7 @@ class EntryEditController extends AbstractController public function __construct( private readonly EntryManager $manager, private readonly LoggerInterface $logger, + private readonly SettingsManager $settingsManager, ) { } @@ -37,6 +39,7 @@ public function __invoke( Request $request ): Response { $dto = $this->manager->createDto($entry); + $maxBytes = $this->settingsManager->getMaxImageByteString(); $form = $this->createForm(EntryEditType::class, $dto); try { @@ -66,6 +69,7 @@ public function __invoke( 'magazine' => $magazine, 'entry' => $entry, 'form' => $form->createView(), + 'maxSize' => $maxBytes, ], new Response(null, $form->isSubmitted() && !$form->isValid() ? 422 : 200) ); diff --git a/src/Repository/ImageRepository.php b/src/Repository/ImageRepository.php index 0efe372bc..cca289459 100644 --- a/src/Repository/ImageRepository.php +++ b/src/Repository/ImageRepository.php @@ -37,9 +37,9 @@ public function __construct( /** * Process and store an uploaded image. * - * @param upload file path of uploaded image + * @param $upload UploadedFile file path of uploaded image * - * @throws RuntimeException if image type can't be identified + * @throws \RuntimeException if image type can't be identified */ public function findOrCreateFromUpload(UploadedFile $upload): ?Image { @@ -49,9 +49,10 @@ public function findOrCreateFromUpload(UploadedFile $upload): ?Image /** * Process and store an image from source path. * - * @param source file path of the image + * @param $source string file path of the image * - * @throws RuntimeException if image type can't be identified + * @throws \RuntimeException if image type can't be identified + * @throws ImageDownloadTooLargeException */ public function findOrCreateFromPath(string $source): ?Image { @@ -63,6 +64,8 @@ public function findOrCreateFromPath(string $source): ?Image * * @param string $source file path of the image * @param ImageOrigin $origin where the image comes from + * + * @throws ImageDownloadTooLargeException */ private function findOrCreateFromSource(string $source, ImageOrigin $origin): ?Image { @@ -108,9 +111,10 @@ private function findOrCreateFromSource(string $source, ImageOrigin $origin): ?I return $image; } else { $this->logger->error( - 'findOrCreateFromSource: failed to store image file, because it is too big', - ['origin' => $origin, 'type' => \gettype($e)], + 'findOrCreateFromSource: failed to store image file, because it is too big - {msg}', + ['origin' => $origin, 'type' => \gettype($e), 'msg' => $e->getMessage()], ); + throw $e; } } catch (\Exception $e) { $this->logger->error( diff --git a/templates/layout/_form_media.html.twig b/templates/layout/_form_media.html.twig index c28426819..7f655d0c3 100644 --- a/templates/layout/_form_media.html.twig +++ b/templates/layout/_form_media.html.twig @@ -7,6 +7,9 @@ {% if form.image is defined %} {{ form_row(form.image, {label: 'image', attr: {class: 'image-input'}}) }} {% endif %} + {% if maxSize is defined %} +
        {{ 'max_image_size'|trans }}: {{ maxSize }}
        + {% endif %} diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml index 9aba3aa3a..bd14e750d 100644 --- a/translations/messages.en.yaml +++ b/translations/messages.en.yaml @@ -743,6 +743,7 @@ position_top: Top pending: Pending flash_thread_new_error: Thread could not be created. Something went wrong. flash_thread_tag_banned_error: Thread could not be created. The content is not allowed. +flash_image_download_too_large_error: Image could not be created, it is too big (max size %bytes%) flash_email_was_sent: Email has been successfully sent. flash_email_failed_to_sent: Email could not be sent. flash_post_new_success: Post has been successfully created. @@ -887,3 +888,4 @@ admin_users_inactive: Inactive admin_users_suspended: Suspended admin_users_banned: Banned user_verify: Activate account +max_image_size: Maximum file size From 8b528286f99e64e7a2514b96a36764aa20b43d91 Mon Sep 17 00:00:00 2001 From: John Wesley <47087725+jwr1@users.noreply.github.com> Date: Wed, 14 Aug 2024 14:02:51 -0400 Subject: [PATCH 192/335] Revert "Make the API return the server public key and add a dedicated route for it" (#1024) --- config/kbin_routes/notification_api.yaml | 6 --- .../Api/Notification/NotificationPushApi.php | 52 +------------------ src/DTO/ServerPublicKeyDto.php | 13 ----- 3 files changed, 1 insertion(+), 70 deletions(-) delete mode 100644 src/DTO/ServerPublicKeyDto.php diff --git a/config/kbin_routes/notification_api.yaml b/config/kbin_routes/notification_api.yaml index bf1537e4d..f18cadf28 100644 --- a/config/kbin_routes/notification_api.yaml +++ b/config/kbin_routes/notification_api.yaml @@ -47,12 +47,6 @@ api_notification_retrieve: methods: [ GET ] format: json -api_notification_push_get_public_key: - controller: App\Controller\Api\Notification\NotificationPushApi::GetServerPublicPushKey - path: /api/notification/push/publicKey - methods: [ GET ] - format: json - api_notification_push_register: controller: App\Controller\Api\Notification\NotificationPushApi::createSubscription path: /api/notification/push diff --git a/src/Controller/Api/Notification/NotificationPushApi.php b/src/Controller/Api/Notification/NotificationPushApi.php index 46dccb1c8..86a5c8d17 100644 --- a/src/Controller/Api/Notification/NotificationPushApi.php +++ b/src/Controller/Api/Notification/NotificationPushApi.php @@ -6,10 +6,8 @@ use App\Controller\Traits\PrivateContentTrait; use App\DTO\NotificationPushSubscriptionRequestDto; -use App\DTO\ServerPublicKeyDto; use App\Entity\UserPushSubscription; use App\Payloads\PushNotification; -use App\Repository\SiteRepository; use App\Repository\UserPushSubscriptionRepository; use App\Schema\Errors\ForbiddenErrorSchema; use App\Schema\Errors\NotFoundErrorSchema; @@ -31,53 +29,6 @@ class NotificationPushApi extends NotificationBaseApi { use PrivateContentTrait; - #[OA\Response( - response: 200, - description: '', - headers: [ - new OA\Header(header: 'X-RateLimit-Remaining', description: 'Number of requests left until you will be rate limited', schema: new OA\Schema(type: 'integer')), - new OA\Header(header: 'X-RateLimit-Retry-After', description: 'Unix timestamp to retry the request after', schema: new OA\Schema(type: 'integer')), - new OA\Header(header: 'X-RateLimit-Limit', description: 'Number of requests available', schema: new OA\Schema(type: 'integer')), - ], - content: new OA\JsonContent(ref: new Model(type: ServerPublicKeyDto::class)) - )] - #[OA\Response( - response: 401, - description: 'Permission denied due to missing or expired token', - content: new OA\JsonContent(ref: new Model(type: UnauthorizedErrorSchema::class)) - )] - #[OA\Response( - response: 403, - description: 'You are not allowed to get the public push key', - content: new OA\JsonContent(ref: new Model(type: ForbiddenErrorSchema::class)) - )] - #[OA\Response( - response: 429, - description: 'You are being rate limited', - headers: [ - new OA\Header(header: 'X-RateLimit-Remaining', description: 'Number of requests left until you will be rate limited', schema: new OA\Schema(type: 'integer')), - new OA\Header(header: 'X-RateLimit-Retry-After', description: 'Unix timestamp to retry the request after', schema: new OA\Schema(type: 'integer')), - new OA\Header(header: 'X-RateLimit-Limit', description: 'Number of requests available', schema: new OA\Schema(type: 'integer')), - ], - content: new OA\JsonContent(ref: new Model(type: TooManyRequestsErrorSchema::class)) - )] - #[OA\RequestBody(content: new Model(type: NotificationPushSubscriptionRequestDto::class))] - #[OA\Tag(name: 'notification')] - #[Security(name: 'oauth2', scopes: ['user:notification:read'])] - #[IsGranted('ROLE_OAUTH2_USER:NOTIFICATION:READ')] - /** - * Get the public push key of the server. - */ - public function GetServerPublicPushKey( - RateLimiterFactory $apiNotificationLimiter, - SiteRepository $siteRepository, - ): JsonResponse { - $headers = $this->rateLimit($apiNotificationLimiter); - $user = $this->getUserOrThrow(); - - return new JsonResponse(new ServerPublicKeyDto($siteRepository->findAll()[0]->pushPublicKey), headers: $headers); - } - #[OA\Response( response: 200, description: 'Created a new push subscription. If there already is a push subscription for this client it will be overwritten. a test notification will be sent right away', @@ -120,7 +71,6 @@ public function createSubscription( SettingsManager $settingsManager, UserPushSubscriptionManager $pushSubscriptionManager, TranslatorInterface $translator, - SiteRepository $siteRepository, #[MapRequestPayload] NotificationPushSubscriptionRequestDto $payload ): JsonResponse { $headers = $this->rateLimit($apiNotificationLimiter); @@ -145,7 +95,7 @@ public function createSubscription( $testNotification = new PushNotification('', $translator->trans('test_push_message', locale: $pushSubscription->locale)); $pushSubscriptionManager->sendTextToUser($user, $testNotification, specificToken: $apiToken); - return new JsonResponse(new ServerPublicKeyDto($siteRepository->findAll()[0]->pushPublicKey), headers: $headers); + return new JsonResponse(headers: $headers); } catch (\ErrorException $e) { $this->logger->error('There was an exception while deleting a UserPushSubscription: {e} - {m}. {o}', [ 'e' => \get_class($e), diff --git a/src/DTO/ServerPublicKeyDto.php b/src/DTO/ServerPublicKeyDto.php deleted file mode 100644 index 65ac9256b..000000000 --- a/src/DTO/ServerPublicKeyDto.php +++ /dev/null @@ -1,13 +0,0 @@ - Date: Thu, 15 Aug 2024 20:16:31 +0200 Subject: [PATCH 193/335] Fix user getting deleted when unregistering push (#1029) --- .../Api/Notification/NotificationPushApi.php | 19 ++++++++++++------- src/Entity/User.php | 2 +- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/Controller/Api/Notification/NotificationPushApi.php b/src/Controller/Api/Notification/NotificationPushApi.php index 86a5c8d17..b210c9436 100644 --- a/src/Controller/Api/Notification/NotificationPushApi.php +++ b/src/Controller/Api/Notification/NotificationPushApi.php @@ -149,21 +149,26 @@ public function createSubscription( */ public function deleteSubscription( RateLimiterFactory $apiNotificationLimiter, - UserPushSubscriptionRepository $repository, ): JsonResponse { $headers = $this->rateLimit($apiNotificationLimiter); $user = $this->getUserOrThrow(); $token = $this->getOAuthToken(); $apiToken = $this->getAccessToken($token); - $sub = $repository->findOneBy(['user' => $user, 'apiToken' => $apiToken]); - if ($sub) { - $this->entityManager->remove($sub); - $this->entityManager->flush(); + try { + $conn = $this->entityManager->getConnection(); + $stmt = $conn->prepare('DELETE FROM user_push_subscription WHERE user_id = :user AND api_token = :token'); + $stmt->executeQuery(['user' => $user, 'token' => $apiToken]); return new JsonResponse(headers: $headers); - } else { - throw new BadRequestException(message: 'PushSubscription not found', statusCode: 404); + } catch (\Exception $e) { + $this->logger->error('There was an exception while deleting a UserPushSubscription: {e} - {m}. {o}', [ + 'e' => \get_class($e), + 'm' => $e->getMessage(), + 'o' => json_encode($e), + ]); + + return new JsonResponse(status: 500, headers: $headers); } } diff --git a/src/Entity/User.php b/src/Entity/User.php index dcf2d5af9..dd57a071e 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -221,7 +221,7 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface, Visibil #[OneToMany(mappedBy: 'user', targetEntity: Notification::class, cascade: ['persist', 'remove'], fetch: 'EXTRA_LAZY', orphanRemoval: true)] #[OrderBy(['createdAt' => 'DESC'])] public Collection $notifications; - #[OneToMany(mappedBy: 'user', targetEntity: UserPushSubscription::class, cascade: ['persist', 'remove'], fetch: 'EXTRA_LAZY', orphanRemoval: true)] + #[OneToMany(mappedBy: 'user', targetEntity: UserPushSubscription::class, fetch: 'EXTRA_LAZY')] public Collection $pushSubscriptions; #[Id] #[GeneratedValue] From 7c4c8f0cddbf1bab251f218665118d084b49f478 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Thu, 15 Aug 2024 20:18:10 +0200 Subject: [PATCH 194/335] Fix `getAccessToken` always returning null (#1030) --- src/Controller/Api/BaseApi.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controller/Api/BaseApi.php b/src/Controller/Api/BaseApi.php index d43062b4f..470391322 100644 --- a/src/Controller/Api/BaseApi.php +++ b/src/Controller/Api/BaseApi.php @@ -180,7 +180,7 @@ public function getOAuthToken(): ?OAuth2Token public function getAccessToken(?OAuth2Token $oAuth2Token): ?AccessToken { - if ($oAuth2Token) { + if (!$oAuth2Token) { return null; } From dc69144932c73764d76c6e0d76eaf5b2f44d63f5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 18:21:11 +0000 Subject: [PATCH 195/335] docs(contributor): contributors readme action update (#1031) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: BentiGorlich --- README.md | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 4b1c9c4a9..93d9294a7 100644 --- a/README.md +++ b/README.md @@ -97,15 +97,6 @@ For developers: asdfzdfj - - - nobodyatroot -
        - debounced -
        - - - SzymonKaminski @@ -113,6 +104,8 @@ For developers: SzymonKaminski + + cooperaj @@ -148,8 +141,6 @@ For developers: TheVillageGuy - - danielpervan @@ -157,6 +148,8 @@ For developers: Daniel Pervan + + Ahrotahn @@ -192,8 +185,6 @@ For developers: Chris Hall - - andrewmoise @@ -201,6 +192,8 @@ For developers: andrewmoise + + garrettw @@ -235,6 +228,13 @@ For developers:
        cavebob
        + + + + jwr1 +
        + John Wesley +
        @@ -266,13 +266,6 @@ For developers: CSDUMMI - - - jwr1 -
        - John Wesley -
        - DismalShadowX @@ -280,8 +273,6 @@ For developers: Nathan Sparrow - - privacyguard From 8c9b74adce01df8d9c158ac3f1e04f5dde6ea97c Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Thu, 15 Aug 2024 21:02:26 +0200 Subject: [PATCH 196/335] Fix UserPushSubscriptionManager using wrong AccessToken type (#1033) --- src/Controller/Api/Notification/NotificationPushApi.php | 2 +- src/Service/Notification/UserPushSubscriptionManager.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Controller/Api/Notification/NotificationPushApi.php b/src/Controller/Api/Notification/NotificationPushApi.php index b210c9436..56c4ceab6 100644 --- a/src/Controller/Api/Notification/NotificationPushApi.php +++ b/src/Controller/Api/Notification/NotificationPushApi.php @@ -158,7 +158,7 @@ public function deleteSubscription( try { $conn = $this->entityManager->getConnection(); $stmt = $conn->prepare('DELETE FROM user_push_subscription WHERE user_id = :user AND api_token = :token'); - $stmt->executeQuery(['user' => $user, 'token' => $apiToken]); + $stmt->executeQuery(['user' => $user->getId(), 'token' => $apiToken]); return new JsonResponse(headers: $headers); } catch (\Exception $e) { diff --git a/src/Service/Notification/UserPushSubscriptionManager.php b/src/Service/Notification/UserPushSubscriptionManager.php index 5d39a9926..d77f2da18 100644 --- a/src/Service/Notification/UserPushSubscriptionManager.php +++ b/src/Service/Notification/UserPushSubscriptionManager.php @@ -10,7 +10,7 @@ use App\Repository\SiteRepository; use App\Repository\UserPushSubscriptionRepository; use App\Service\SettingsManager; -use League\Bundle\OAuth2ServerBundle\Entity\AccessToken; +use League\Bundle\OAuth2ServerBundle\Model\AccessToken; use Minishlink\WebPush\MessageSentReport; use Minishlink\WebPush\Subscription; use Minishlink\WebPush\WebPush; From 53b909de2ee2a8fc3714a21faf8f76418bca9854 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Thu, 15 Aug 2024 21:09:55 +0200 Subject: [PATCH 197/335] Bump version to 1.7.1-rc3 (#1027) --- config/packages/framework.yaml | 2 +- src/Service/ProjectInfoService.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml index 4ee3aadcc..da0529816 100644 --- a/config/packages/framework.yaml +++ b/config/packages/framework.yaml @@ -19,7 +19,7 @@ framework: http_client: default_options: headers: - 'User-Agent': 'Mbin/1.7.1-rc2 (+https://%kbin_domain%/agent)' + 'User-Agent': 'Mbin/1.7.1-rc3 (+https://%kbin_domain%/agent)' #esi: true #fragments: true diff --git a/src/Service/ProjectInfoService.php b/src/Service/ProjectInfoService.php index 50103727a..700fc9014 100644 --- a/src/Service/ProjectInfoService.php +++ b/src/Service/ProjectInfoService.php @@ -10,7 +10,7 @@ class ProjectInfoService { // If updating version, please also update http client UA in [/config/packages/framework.yaml] - private const VERSION = '1.7.1-rc2'; // TODO: Retrieve the version from git tags or getenv()? + private const VERSION = '1.7.1-rc3'; // TODO: Retrieve the version from git tags or getenv()? private const NAME = 'mbin'; private const USER_AGENT = 'Mbin'; private const REPOSITORY_URL = 'https://github.com/MbinOrg/mbin'; From 8cd1d662ba90cfc616c837ad882c5bf15d0c8095 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Sat, 17 Aug 2024 20:19:43 +0200 Subject: [PATCH 198/335] Fix 500 error when a thread is empty (#1034) --- src/Entity/MessageThread.php | 6 ++- src/Repository/MessageThreadRepository.php | 6 ++- templates/messages/front.html.twig | 55 ++++++++++------------ 3 files changed, 35 insertions(+), 32 deletions(-) diff --git a/src/Entity/MessageThread.php b/src/Entity/MessageThread.php index 8b90c86ad..8db3d3366 100644 --- a/src/Entity/MessageThread.php +++ b/src/Entity/MessageThread.php @@ -104,8 +104,12 @@ public function removeMessage(Message $message): void $this->messages->removeElement($message); } - public function getLastMessage(): Message + public function getLastMessage(): ?Message { + if (0 === $this->messages->count()) { + return null; + } + return $this->messages[$this->messages->count() - 1]; } diff --git a/src/Repository/MessageThreadRepository.php b/src/Repository/MessageThreadRepository.php index 1e3b3ee94..d19a3e061 100644 --- a/src/Repository/MessageThreadRepository.php +++ b/src/Repository/MessageThreadRepository.php @@ -4,6 +4,7 @@ namespace App\Repository; +use App\Entity\Message; use App\Entity\MessageThread; use App\Entity\User; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; @@ -33,8 +34,9 @@ public function __construct(ManagerRegistry $registry, private readonly LoggerIn public function findUserMessages(?User $user, int $page, int $perPage = self::PER_PAGE) { - $qb = $this->createQueryBuilder('mt') - ->where(':user MEMBER OF mt.participants') + $qb = $this->createQueryBuilder('mt'); + $qb->where(':user MEMBER OF mt.participants') + ->andWhere($qb->expr()->exists('SELECT m FROM '.Message::class.' m WHERE m.thread = mt')) ->orderBy('mt.updatedAt', 'DESC') ->setParameter(':user', $user); diff --git a/templates/messages/front.html.twig b/templates/messages/front.html.twig index 514b59c43..dbb198e14 100644 --- a/templates/messages/front.html.twig +++ b/templates/messages/front.html.twig @@ -15,33 +15,35 @@ {% block body %}

        {{ 'messages'|trans }}

        {% for thread in threads %} -
        -
        + {% set lastMessage = thread.getLastMessage() %} + {% if lastMessage is not same as null %} +
        - - {% set i = 0 %} - {% set participants = thread.participants|filter(p => p is not same as app.user) %} - {% for user in participants %} - {% if i > 0 and i is same as (participants|length - 1) %} - {{ 'and'|trans }} - {% elseif i > 0 %} - , - {% endif %} - {{ component('user_inline', {user: user, showAvatar: false}) }} - {% set i = i + 1 %} - {% endfor %} - -
        -
        - {% set lastMessage = thread.getLastMessage() %} - {{ component('user_inline', {user: lastMessage.sender, showAvatar: true}) -}}: - - {{ lastMessage.getTitle() }} - +
        + + {% set i = 0 %} + {% set participants = thread.participants|filter(p => p is not same as app.user) %} + {% for user in participants %} + {% if i > 0 and i is same as (participants|length - 1) %} + {{ 'and'|trans }} + {% elseif i > 0 %} + , + {% endif %} + {{ component('user_inline', {user: user, showAvatar: false}) }} + {% set i = i + 1 %} + {% endfor %} + +
        +
        + {{ component('user_inline', {user: lastMessage.sender, showAvatar: true}) -}}: + + {{ lastMessage.getTitle() }} + +
        + {{ component('date', {date: thread.updatedAt}) }}
        - {{ component('date', {date: thread.updatedAt}) }} -
        + {% endif %} {% endfor %} {% if threads|length == 0 %}
        -
        +
        {% if form.image is defined %} {{ form_row(form.image, {label: 'image', attr: {class: 'image-input'}}) }} {% endif %} @@ -13,14 +13,6 @@ -
        - - -
        {{ form_row(form.imageAlt, {label: 'image_alt'}) }}
        From bd3c332bc3187877854bd10234f321218f024dfa Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 27 Aug 2024 20:52:59 +0000 Subject: [PATCH 222/335] docs(contributor): contributors readme action update (#1067) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 93d9294a7..c22538175 100644 --- a/README.md +++ b/README.md @@ -77,17 +77,17 @@ For developers: - - e-five256 + + BentiGorlich
        - e-five + BentiGorlich
        - - BentiGorlich + + e-five256
        - BentiGorlich + e-five
        From 2b8c41f3e234537b17646bd039c04d2d3795ceb8 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Wed, 28 Aug 2024 22:05:36 +0000 Subject: [PATCH 223/335] Fix some leftover magazine undefined errors in the nav (#1069) --- templates/layout/_header_nav.html.twig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/layout/_header_nav.html.twig b/templates/layout/_header_nav.html.twig index 51c120540..6c41c1018 100644 --- a/templates/layout/_header_nav.html.twig +++ b/templates/layout/_header_nav.html.twig @@ -18,12 +18,12 @@ {% if header_nav is empty %}
      • - + {{ 'threads'|trans }} {% if magazine is defined and magazine %}({{ magazine.entryCount }}){% endif %}
      • - + {{ 'microblog'|trans }} {% if magazine is defined and magazine %}({{ magazine.postCount }}){% endif %}
      • From d9ec2127a1668a5f0e6cda923bb7269601c82821 Mon Sep 17 00:00:00 2001 From: LoveIsGrief Date: Mon, 2 Sep 2024 10:27:38 +0000 Subject: [PATCH 224/335] chore: Create PR template (#1059) Co-authored-by: Melroy van den Berg --- .../pull_request_template.md | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE/pull_request_template.md diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md new file mode 100644 index 000000000..ba6ce0bb0 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md @@ -0,0 +1,56 @@ + + +# Summary + + + +## Checklist + + + + - [ ] Marked as draft PR while still working on PR + - [ ] Marked as "ready for review" once not in progress + - [ ] Added tests (for code changes) + - [ ] Provided screenshots (for visual changes) + + +# Additional information + + + +# Related issues + + From cf3c39494fd51ec1d9d436ef066b27f9bb8bf384 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Mon, 2 Sep 2024 15:52:03 +0200 Subject: [PATCH 225/335] Add installation filler (#1074) --- docs/02-admin/01-installation/README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/02-admin/01-installation/README.md b/docs/02-admin/01-installation/README.md index f34d65bd7..cc92c2f98 100644 --- a/docs/02-admin/01-installation/README.md +++ b/docs/02-admin/01-installation/README.md @@ -1 +1,9 @@ -# Installation \ No newline at end of file +# Installation + +You can choose between: + +- [Bare metal/VM installation](./bare_metal.md) + +Or: + +- [Docker installation](./docker.md) From c9abb39c5ad0eac59d8c1f6c2abc258717cd483d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 17:50:15 +0200 Subject: [PATCH 226/335] docs(contributor): contributors readme action update (#1075) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- README.md | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index c22538175..312fa71a9 100644 --- a/README.md +++ b/README.md @@ -209,47 +209,47 @@ For developers: - - lilfade + + ryanmonsen
        - Bryson + ryanmonsen
        - - vpzomtrrfrt + + drupol
        - vpzomtrrfrt + Pol Dellaiera
        - - cavebob + + jwr1
        - cavebob + John Wesley
        - - jwr1 + + cavebob
        - John Wesley + cavebob
        - - drupol + + vpzomtrrfrt
        - Pol Dellaiera + vpzomtrrfrt
        - - ryanmonsen + + lilfade
        - ryanmonsen + Bryson
        @@ -266,6 +266,13 @@ For developers: CSDUMMI + + + LoveIsGrief +
        + LoveIsGrief +
        + DismalShadowX @@ -273,6 +280,8 @@ For developers: Nathan Sparrow + + privacyguard From 21de6ea0f1db71ff4907d76e175c784c8bb3554c Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Mon, 2 Sep 2024 18:13:49 +0200 Subject: [PATCH 227/335] Translations update from Hosted Weblate (#1076) Co-authored-by: Melroy van den Berg --- translations/messages.nl.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translations/messages.nl.yaml b/translations/messages.nl.yaml index 0f1b4ceec..b15444e84 100644 --- a/translations/messages.nl.yaml +++ b/translations/messages.nl.yaml @@ -87,7 +87,7 @@ add_new_post: Bericht toevoegen add_new_video: Video toevoegen contact: Contact faq: Veelgestelde vragen -rss: Rss +rss: RSS change_theme: Thema wijzigen useful: Nuttig help: Hulp From ff3f5db44a0075fcb4bdd2cd5e423b4ffcdbd2b9 Mon Sep 17 00:00:00 2001 From: TheVillageGuy <47496248+TheVillageGuy@users.noreply.github.com> Date: Mon, 2 Sep 2024 23:02:31 +0200 Subject: [PATCH 228/335] Update theme-dark.scss (#1062) Yes, https://webaim.org/resources/contrastchecker/?fcolor=FFFFFF&bcolor=AB1C28 --- assets/styles/mixins/theme-dark.scss | 6 +++--- assets/styles/mixins/theme-solarized-dark.scss | 4 ++-- assets/styles/themes/_kbin.scss | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/assets/styles/mixins/theme-dark.scss b/assets/styles/mixins/theme-dark.scss index e25f7af4b..ae29a2fe1 100644 --- a/assets/styles/mixins/theme-dark.scss +++ b/assets/styles/mixins/theme-dark.scss @@ -110,12 +110,12 @@ // alerts --kbin-alert-info-bg: rgba(153,116,4,0.15); - --kbin-alert-info-border: 1px solid rgba(153,116,4,0.4); + --kbin-alert-info-border: 1px solid rgba(153,116,4, 0.04); --kbin-alert-info-text-color: #997404; --kbin-alert-info-link-color: #997404; - --kbin-alert-danger-bg: rgba(220, 47, 63, 0.15); - --kbin-alert-danger-border: 1px solid rgba(220, 47, 63, 0.4); + --kbin-alert-danger-bg: rgba(171, 28, 40, 0.9); + --kbin-alert-danger-border: 1px solid rgba(171, 28, 40, 1); --kbin-alert-danger-text-color: var(--kbin-danger-color); --kbin-alert-danger-link-color: var(--kbin-danger-color); diff --git a/assets/styles/mixins/theme-solarized-dark.scss b/assets/styles/mixins/theme-solarized-dark.scss index 86da1adda..f563e08d0 100644 --- a/assets/styles/mixins/theme-solarized-dark.scss +++ b/assets/styles/mixins/theme-solarized-dark.scss @@ -132,8 +132,8 @@ $green: #859900; --kbin-alert-info-text-color: #997404; --kbin-alert-info-link-color: #997404; - --kbin-alert-danger-bg: rgba(220, 47, 63, 0.15); - --kbin-alert-danger-border: 1px solid rgba(220, 47, 63, 0.4); + --kbin-alert-danger-bg: rgba(171, 28, 40, 0.9); + --kbin-alert-danger-border: 1px solid rgba(171, 28, 40, 1); --kbin-alert-danger-text-color: var(--kbin-danger-color); --kbin-alert-danger-link-color: var(--kbin-danger-color); diff --git a/assets/styles/themes/_kbin.scss b/assets/styles/themes/_kbin.scss index a2196f87c..a0c3afcd5 100644 --- a/assets/styles/themes/_kbin.scss +++ b/assets/styles/themes/_kbin.scss @@ -112,8 +112,8 @@ --kbin-alert-info-text-color: #997404; --kbin-alert-info-link-color: #997404; - --kbin-alert-danger-bg: rgba(220, 47, 63, 0.15); - --kbin-alert-danger-border: 1px solid rgba(220, 47, 63, 0.4); + --kbin-alert-danger-bg: rgba(171, 28, 40, 0.9); + --kbin-alert-danger-border: 1px solid rgba(171, 28, 40, 1); --kbin-alert-danger-text-color: var(--kbin-danger-color); --kbin-alert-danger-link-color: var(--kbin-danger-color); From bd351f289e45aead7daaccaa74d9ec29bbb9813e Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Mon, 2 Sep 2024 23:12:19 +0200 Subject: [PATCH 229/335] Fix messenger deadlocks caused by cache locks (#1066) --- src/Service/ActivityPub/ApHttpClient.php | 370 ++++++++++++++--------- 1 file changed, 224 insertions(+), 146 deletions(-) diff --git a/src/Service/ActivityPub/ApHttpClient.php b/src/Service/ActivityPub/ApHttpClient.php index a5bd35d30..38800a710 100644 --- a/src/Service/ActivityPub/ApHttpClient.php +++ b/src/Service/ActivityPub/ApHttpClient.php @@ -18,6 +18,7 @@ use JetBrains\PhpStorm\ArrayShape; use Psr\Cache\InvalidArgumentException; use Psr\Log\LoggerInterface; +use Symfony\Component\Cache\CacheItem; use Symfony\Component\HttpClient\CurlHttpClient; use Symfony\Contracts\Cache\CacheInterface; use Symfony\Contracts\Cache\ItemInterface; @@ -25,6 +26,7 @@ use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; /* * source: @@ -60,10 +62,36 @@ public function __construct( public function getActivityObject(string $url, bool $decoded = true): array|string|null { - $resp = $this->cache->get($this->getActivityObjectCacheKey($url), function (ItemInterface $item) use ($url) { - $this->logger->debug("ApHttpClient:getActivityObject:url: $url"); + $key = $this->getActivityObjectCacheKey($url); + if ($this->cache->hasItem($key)) { + /** @var CacheItem $item */ + $item = $this->cache->getItem($key); + $resp = $item->get(); - $client = new CurlHttpClient(); + return $decoded ? json_decode($resp, true) : $resp; + } + + $resp = $this->getActivityObjectImpl($url); + + if (!$resp) { + return null; + } + + /** @var CacheItem $item */ + $item = $this->cache->getItem($key); + $item->expiresAt(new \DateTime('+1 hour')); + $item->set($resp); + $this->cache->save($item); + + return $decoded ? json_decode($resp, true) : $resp; + } + + private function getActivityObjectImpl(string $url): ?string + { + $this->logger->debug("ApHttpClient:getActivityObject:url: $url"); + + $client = new CurlHttpClient(); + try { $r = $client->request('GET', $url, [ 'max_duration' => self::MAX_DURATION, 'timeout' => self::TIMEOUT, @@ -76,20 +104,14 @@ public function getActivityObject(string $url, bool $decoded = true): array|stri throw new InvalidApPostException("Invalid status code while getting: $url : $statusCode, ".substr($r->getContent(false), 0, 1000)); } - $item->expiresAt(new \DateTime('+1 hour')); - // Read also non-OK responses (like 410) by passing 'false' $content = $r->getContent(false); $this->logger->debug('ApHttpClient:getActivityObject:url: {url} - content: {content}', ['url' => $url, 'content' => $content]); - - return $content; - }); - - if (!$resp) { - return null; + } catch (\Exception $e) { + $this->logRequestException($r, $url, 'ApHttpClient:getActivityObject', $e); } - return $decoded ? json_decode($resp, true) : $resp; + return $content; } public function getActivityObjectCacheKey(string $url): string @@ -125,35 +147,44 @@ public function getInboxUrl(string $apProfileId): string */ public function getWebfingerObject(string $url): ?array { - $resp = $this->cache->get( - 'wf_'.hash('sha256', $url), - function (ItemInterface $item) use ($url) { - $this->logger->debug("ApHttpClient:getWebfingerObject:url: $url"); - $r = null; - try { - $client = new CurlHttpClient(); - $r = $client->request('GET', $url, [ - 'max_duration' => self::MAX_DURATION, - 'timeout' => self::TIMEOUT, - 'headers' => $this->getInstanceHeaders($url, null, 'get', ApRequestType::WebFinger), - ]); - } catch (\Exception $e) { - $msg = "WebFinger Get fail: $url, ex: ".\get_class($e).": {$e->getMessage()}"; - if (null !== $r) { - $msg .= ', '.$r->getContent(false); - } - throw new InvalidWebfingerException($msg); - } + $key = 'wf_'.hash('sha256', $url); + if ($this->cache->hasItem($key)) { + /** @var CacheItem $item */ + $item = $this->cache->getItem($key); + $resp = $item->get(); - $item->expiresAt(new \DateTime('+1 hour')); + return $resp ? json_decode($resp, true) : null; + } - return $r->getContent(); - } - ); + $resp = $this->getWebfingerObjectImpl($url); + + /** @var CacheItem $item */ + $item = $this->cache->getItem($key); + $item->expiresAt(new \DateTime('+1 hour')); + $item->set($resp); + $this->cache->save($item); return $resp ? json_decode($resp, true) : null; } + private function getWebfingerObjectImpl(string $url): ?string + { + $this->logger->debug("ApHttpClient:getWebfingerObject:url: $url"); + $r = null; + try { + $client = new CurlHttpClient(); + $r = $client->request('GET', $url, [ + 'max_duration' => self::MAX_DURATION, + 'timeout' => self::TIMEOUT, + 'headers' => $this->getInstanceHeaders($url, null, 'get', ApRequestType::WebFinger), + ]); + } catch (\Exception $e) { + $this->logRequestException($r, $url, 'ApHttpClient:getWebfingerObject', $e); + } + + return $r->getContent(); + } + private function getActorCacheKey(string $apProfileId): string { return 'ap_'.hash('sha256', $apProfileId); @@ -168,64 +199,72 @@ private function getActorCacheKey(string $apProfileId): string */ public function getActorObject(string $apProfileId): ?array { - $resp = $this->cache->get( - $this->getActorCacheKey($apProfileId), - function (ItemInterface $item) use ($apProfileId) { - $this->logger->debug("ApHttpClient:getActorObject:url: $apProfileId"); - $response = null; - try { - // Set-up request - $client = new CurlHttpClient(); - $response = $client->request('GET', $apProfileId, [ - 'max_duration' => self::MAX_DURATION, - 'timeout' => self::TIMEOUT, - 'headers' => $this->getInstanceHeaders($apProfileId, null, 'get', ApRequestType::ActivityPub), - ]); - // If 4xx error response, try to find the actor locally - if (str_starts_with((string) $response->getStatusCode(), '4')) { - if ($user = $this->userRepository->findOneByApProfileId($apProfileId)) { - $user->apDeletedAt = new \DateTime(); - $this->userRepository->save($user, true); - } - if ($magazine = $this->magazineRepository->findOneByApProfileId($apProfileId)) { - $magazine->apDeletedAt = new \DateTime(); - $this->magazineRepository->save($magazine, true); - } - } - } catch (\Exception $e) { - // If an exception occurred, try to find the actor locally - if ($user = $this->userRepository->findOneByApProfileId($apProfileId)) { - $user->apTimeoutAt = new \DateTime(); - $this->userRepository->save($user, true); - } - if ($magazine = $this->magazineRepository->findOneByApProfileId($apProfileId)) { - $magazine->apTimeoutAt = new \DateTime(); - $this->magazineRepository->save($magazine, true); - } - - $msg = "AP Get fail: $apProfileId, ex: ".\get_class($e).": {$e->getMessage()}"; - if (null !== $response) { - $msg .= ', '.$response->getContent(false); - } - throw new InvalidApPostException($msg); - } + $key = $this->getActorCacheKey($apProfileId); + if ($this->cache->hasItem($key)) { + /** @var CacheItem $item */ + $item = $this->cache->getItem($key); + $resp = $item->get(); - $item->expiresAt(new \DateTime('+1 hour')); + return $resp ? json_decode($resp, true) : null; + } - if (404 === $response->getStatusCode()) { - // treat a 404 error the same as a tombstone, since we think there was an actor, but it isn't there anymore - return json_encode($this->tombstoneFactory->create($apProfileId)); - } + $resp = $this->getActorObjectImpl($apProfileId); - // Return the content. - // Pass the 'false' option to getContent so it doesn't throw errors on "non-OK" respones (eg. 410 status codes). - return $response->getContent(false); - } - ); + /** @var CacheItem $item */ + $item = $this->cache->getItem($key); + $item->expiresAt(new \DateTime('+1 hour')); + $item->set($resp); + $this->cache->save($item); return $resp ? json_decode($resp, true) : null; } + private function getActorObjectImpl(string $apProfileId): ?string + { + $this->logger->debug("ApHttpClient:getActorObject:url: $apProfileId"); + $response = null; + try { + // Set-up request + $client = new CurlHttpClient(); + $response = $client->request('GET', $apProfileId, [ + 'max_duration' => self::MAX_DURATION, + 'timeout' => self::TIMEOUT, + 'headers' => $this->getInstanceHeaders($apProfileId, null, 'get', ApRequestType::ActivityPub), + ]); + // If 4xx error response, try to find the actor locally + if (str_starts_with((string) $response->getStatusCode(), '4')) { + if ($user = $this->userRepository->findOneByApProfileId($apProfileId)) { + $user->apDeletedAt = new \DateTime(); + $this->userRepository->save($user, true); + } + if ($magazine = $this->magazineRepository->findOneByApProfileId($apProfileId)) { + $magazine->apDeletedAt = new \DateTime(); + $this->magazineRepository->save($magazine, true); + } + } + } catch (\Exception|TransportExceptionInterface $e) { + // If an exception occurred, try to find the actor locally + if ($user = $this->userRepository->findOneByApProfileId($apProfileId)) { + $user->apTimeoutAt = new \DateTime(); + $this->userRepository->save($user, true); + } + if ($magazine = $this->magazineRepository->findOneByApProfileId($apProfileId)) { + $magazine->apTimeoutAt = new \DateTime(); + $this->magazineRepository->save($magazine, true); + } + $this->logRequestException($response, $apProfileId, 'ApHttpClient:getActorObject', $e); + } + + if (404 === $response->getStatusCode()) { + // treat a 404 error the same as a tombstone, since we think there was an actor, but it isn't there anymore + return json_encode($this->tombstoneFactory->create($apProfileId)); + } + + // Return the content. + // Pass the 'false' option to getContent so it doesn't throw errors on "non-OK" respones (eg. 410 status codes). + return $response->getContent(false); + } + public function invalidateActorObjectCache(string $apProfileId): void { $this->cache->delete($this->getActorCacheKey($apProfileId)); @@ -241,43 +280,73 @@ public function invalidateCollectionObjectCache(string $apAddress): void */ public function getCollectionObject(string $apAddress): ?array { - $resp = $this->cache->get( - 'ap_collection'.hash('sha256', $apAddress), - function (ItemInterface $item) use ($apAddress) { - $this->logger->debug("ApHttpClient:getCollectionObject:url: $apAddress"); - $response = null; - try { - // Set-up request - $client = new CurlHttpClient(); - $response = $client->request('GET', $apAddress, [ - 'max_duration' => self::MAX_DURATION, - 'timeout' => self::TIMEOUT, - 'headers' => $this->getInstanceHeaders($apAddress, null, 'get', ApRequestType::ActivityPub), - ]); - - $statusCode = $response->getStatusCode(); - // Accepted status code are 2xx or 410 (used Tombstone types) - if (!str_starts_with((string) $statusCode, '2') && 410 !== $statusCode) { - throw new InvalidApPostException("Invalid status code while getting: $apAddress : $statusCode, ".substr($response->getContent(false), 0, 1000)); - } - } catch (\Exception $e) { - $msg = "AP Get fail: $apAddress, ex: ".\get_class($e).": {$e->getMessage()}"; - if (null !== $response) { - $msg .= ', '.$response->getContent(false); - } - throw new InvalidApPostException($msg); - } + $key = 'ap_collection'.hash('sha256', $apAddress); + if ($this->cache->hasItem($key)) { + /** @var CacheItem $item */ + $item = $this->cache->getItem($key); + $resp = $item->get(); - $item->expiresAt(new \DateTime('+24 hour')); + return $resp ? json_decode($resp, true) : null; + } - // When everything goes OK, return the data - return $response->getContent(); - } - ); + $resp = $this->getCollectionObjectImpl($apAddress); + + /** @var CacheItem $item */ + $item = $this->cache->getItem($key); + $item->expiresAt(new \DateTime('+24 hour')); + $item->set($resp); + $this->cache->save($item); return $resp ? json_decode($resp, true) : null; } + private function getCollectionObjectImpl(string $apAddress): ?string + { + $this->logger->debug("ApHttpClient:getCollectionObject:url: $apAddress"); + $response = null; + try { + // Set-up request + $client = new CurlHttpClient(); + $response = $client->request('GET', $apAddress, [ + 'max_duration' => self::MAX_DURATION, + 'timeout' => self::TIMEOUT, + 'headers' => $this->getInstanceHeaders($apAddress, null, 'get', ApRequestType::ActivityPub), + ]); + + $statusCode = $response->getStatusCode(); + // Accepted status code are 2xx or 410 (used Tombstone types) + if (!str_starts_with((string) $statusCode, '2') && 410 !== $statusCode) { + throw new InvalidApPostException("Invalid status code while getting: $apAddress : $statusCode, ".substr($response->getContent(false), 0, 1000)); + } + } catch (\Exception $e) { + $this->logRequestException($response, $apAddress, 'ApHttpClient:getCollectionObject', $e); + } + + // When everything goes OK, return the data + return $response->getContent(); + } + + private function logRequestException(?ResponseInterface $response, string $requestUrl, string $requestType, \Exception $e): void + { + if (null !== $response) { + try { + $content = $response->getContent(false); + } catch (ClientExceptionInterface|RedirectionExceptionInterface|ServerExceptionInterface|TransportExceptionInterface $e) { + $class = \get_class($e); + $content = "there was an exception while getting the content, $class: {$e->getMessage()}"; + } + } + + $this->logger->error('{type} get fail: {address}, ex: {e}: {msg} - {content}', [ + 'type' => $requestType, + 'address' => $requestUrl, + 'e' => \get_class($e), + 'msg' => $e->getMessage(), + 'content' => $content ?? 'no content provided', + ]); + throw $e; + } + /** * Sends a POST request to the specified URL with optional request body and caching mechanism. * @@ -326,20 +395,8 @@ public function post(string $url, User|Magazine $actor, ?array $body = null): vo public function fetchInstanceNodeInfoEndpoints(string $domain, bool $decoded = true): array|string|null { $url = "https://$domain/.well-known/nodeinfo"; - $resp = $this->cache->get('nodeinfo_endpoints_'.hash('sha256', $url), function (ItemInterface $item) use ($url) { - $item->expiresAt(new \DateTime('+1 day')); - try { - return $this->generalFetch($url, ApRequestType::NodeInfo); - } catch (\Exception $e) { - $this->logger->warning('There was an exception fetching nodeinfo endpoints from {url}: {e} - {msg}', [ - 'url' => $url, - 'e' => \get_class($e), - 'msg' => $e->getMessage(), - ]); - - return null; - } - }); + + $resp = $this->generalFetchCached('nodeinfo_endpoints_', 'nodeinfo endpoints', $url, ApRequestType::NodeInfo); if (!$resp) { return null; @@ -350,21 +407,7 @@ public function fetchInstanceNodeInfoEndpoints(string $domain, bool $decoded = t public function fetchInstanceNodeInfo(string $url, bool $decoded = true): array|string|null { - $resp = $this->cache->get('nodeinfo_'.hash('sha256', $url), function (ItemInterface $item) use ($url) { - $item->expiresAt(new \DateTime('+1 day')); - - try { - return $this->generalFetch($url, ApRequestType::NodeInfo); - } catch (\Exception $e) { - $this->logger->warning('There was an exception fetching the nodeinfo from {url}: {e} - {msg}', [ - 'url' => $url, - 'e' => \get_class($e), - 'msg' => $e->getMessage(), - ]); - - return null; - } - }); + $resp = $this->generalFetchCached('nodeinfo_', 'nodeinfo', $url, ApRequestType::NodeInfo); if (!$resp) { return null; @@ -392,6 +435,41 @@ private function generalFetch(string $url, ApRequestType $requestType = ApReques return $r->getContent(); } + private function generalFetchCached(string $cachePrefix, string $fetchType, string $url, ApRequestType $requestType = ApRequestType::ActivityPub): ?string + { + $key = $cachePrefix.hash('sha256', $url); + + if ($this->cache->hasItem($key)) { + /** @var CacheItem $item */ + $item = $this->cache->getItem($key); + + return $item->get(); + } + + try { + $resp = $this->generalFetch($url, $requestType); + } catch (\Exception $e) { + $this->logger->warning('There was an exception fetching {type} from {url}: {e} - {msg}', [ + 'type' => $fetchType, + 'url' => $url, + 'e' => \get_class($e), + 'msg' => $e->getMessage(), + ]); + $resp = null; + } + + if (!$resp) { + return null; + } + + $item = $this->cache->getItem($key); + $item->set($resp); + $item->expiresAt(new \DateTime('+1 day')); + $this->cache->save($item); + + return $resp; + } + private function getFetchAcceptHeaders(ApRequestType $requestType): array { return match ($requestType) { From 58aeacd4c58bb23b2c5e24f37f628437fa46a0e8 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Tue, 3 Sep 2024 12:28:48 +0200 Subject: [PATCH 230/335] Fix the regex, so FF is no longer complaining (#1077) --- src/Utils/RegPatterns.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utils/RegPatterns.php b/src/Utils/RegPatterns.php index 9a506756a..b32495082 100644 --- a/src/Utils/RegPatterns.php +++ b/src/Utils/RegPatterns.php @@ -7,7 +7,7 @@ class RegPatterns { public const MAGAZINE_NAME = '/^[a-zA-Z0-9_]{2,25}$/'; - public const USERNAME = '/^[a-zA-Z0-9_-]{1,30}$/'; + public const USERNAME = '/^[a-zA-Z0-9_\-]{1,30}$/'; public const LOCAL_MAGAZINE = '/^@\w{2,25}\b/'; public const LOCAL_USER = '/^@[a-zA-Z0-9_-]{1,30}\b/'; public const AP_MAGAZINE = '/^(!\w{2,25})(@)(([a-z0-9|-]+\.)*[a-z0-9|-]+\.[a-z]+)/'; From 0f8edfd73d5fe02a9a22c53709692aa3ccf1c2e3 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Tue, 3 Sep 2024 12:41:26 +0200 Subject: [PATCH 231/335] Use the latest pipeline docker image (#1078) --- .github/workflows/action.yaml | 8 ++++---- ci/Dockerfile | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/action.yaml b/.github/workflows/action.yaml index 5762fff17..fe2fd6454 100644 --- a/.github/workflows/action.yaml +++ b/.github/workflows/action.yaml @@ -14,7 +14,7 @@ jobs: build: runs-on: ubuntu-latest container: - image: danger89/mbin-pipeline:1.1.0 + image: danger89/mbin-pipeline:1.2.0 steps: - uses: actions/checkout@v4 @@ -63,7 +63,7 @@ jobs: unit-test: runs-on: ubuntu-latest container: - image: danger89/mbin-pipeline:1.1.0 + image: danger89/mbin-pipeline:1.2.0 steps: - uses: actions/checkout@v4 @@ -96,7 +96,7 @@ jobs: security-check: runs-on: ubuntu-latest container: - image: danger89/mbin-pipeline:1.1.0 + image: danger89/mbin-pipeline:1.2.0 steps: - uses: actions/checkout@v4 @@ -106,7 +106,7 @@ jobs: fixer-dry-run: runs-on: ubuntu-latest container: - image: danger89/mbin-pipeline:1.1.0 + image: danger89/mbin-pipeline:1.2.0 steps: - uses: actions/checkout@v4 diff --git a/ci/Dockerfile b/ci/Dockerfile index cff1e67e7..fcab4a06a 100644 --- a/ci/Dockerfile +++ b/ci/Dockerfile @@ -1,7 +1,7 @@ FROM php:8.3 # Add composer -COPY --from=composer:2.7.7 /usr/bin/composer /usr/bin/composer +COPY --from=composer:2.7.8 /usr/bin/composer /usr/bin/composer # Add NodeJS RUN apt-get update && apt-get install -y nodejs npm @@ -15,7 +15,7 @@ RUN curl -sSLf \ https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions RUN chmod +x /usr/local/bin/install-php-extensions -RUN install-php-extensions amqp intl redis gd zip bcmath +RUN install-php-extensions amqp intl redis gd zip bcmath xsl # Install local-php-security-checker (same as used by "symfony security:check") RUN curl -sSLf \ From ef042f237f940ac523db0339ee1ccad107bbf89e Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Tue, 3 Sep 2024 14:33:26 +0200 Subject: [PATCH 232/335] Use attribute twig method + is defined on report notification objects (#1080) --- templates/notifications/_blocks.html.twig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/templates/notifications/_blocks.html.twig b/templates/notifications/_blocks.html.twig index 7a09420c1..47c616867 100644 --- a/templates/notifications/_blocks.html.twig +++ b/templates/notifications/_blocks.html.twig @@ -101,22 +101,22 @@ {% endblock magazine_ban_notification %} {% block reportlink %} - {% if notification.report.entry is not same as null %} + {% if notification.report.entry is defined and notification.report.entry is not same as null %} {% set entry = notification.report.entry %} {{ entry.title }} - {% elseif notification.report.entryComment is not same as null %} + {% elseif notification.report.entryComment is defined and notification.report.entryComment is not same as null %} {% set entryComment = notification.report.entryComment %} {{ entryComment.getShortTitle() }} - {% elseif notification.report.post is not same as null %} + {% elseif notification.report.post is defined and notification.report.post is not same as null %} {% set post = notification.report.post %} {{ post.getShortTitle() }} - {% elseif notification.report.postComment is not same as null %} + {% elseif notification.report.postComment is defined and notification.report.postComment is not same as null %} {% set postComment = notification.report.postComment %} {{ post.getShortTitle() }} From a50b9242f5f1e882fcac029580f57ddde2c913c1 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Tue, 3 Sep 2024 14:51:47 +0200 Subject: [PATCH 233/335] Bump the version to 1.7.1-rc5 (#1079) --- config/packages/framework.yaml | 2 +- src/Service/ProjectInfoService.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml index 178bf1e87..067dc3f2a 100644 --- a/config/packages/framework.yaml +++ b/config/packages/framework.yaml @@ -19,7 +19,7 @@ framework: http_client: default_options: headers: - 'User-Agent': 'Mbin/1.7.1-rc4 (+https://%kbin_domain%/agent)' + 'User-Agent': 'Mbin/1.7.1-rc5 (+https://%kbin_domain%/agent)' #esi: true #fragments: true diff --git a/src/Service/ProjectInfoService.php b/src/Service/ProjectInfoService.php index 257658bf9..5ca786b85 100644 --- a/src/Service/ProjectInfoService.php +++ b/src/Service/ProjectInfoService.php @@ -10,7 +10,7 @@ class ProjectInfoService { // If updating version, please also update http client UA in [/config/packages/framework.yaml] - private const VERSION = '1.7.1-rc4'; // TODO: Retrieve the version from git tags or getenv()? + private const VERSION = '1.7.1-rc5'; // TODO: Retrieve the version from git tags or getenv()? private const NAME = 'mbin'; private const CANONICAL_NAME = 'Mbin'; private const REPOSITORY_URL = 'https://github.com/MbinOrg/mbin'; From ab956e9198559569ec18d8d6aeed9d906ad5e5e1 Mon Sep 17 00:00:00 2001 From: asdfzdfj Date: Tue, 3 Sep 2024 21:27:08 +0700 Subject: [PATCH 234/335] move private vars out of some services/handlers (#1070) refactored some services/handlers that pass extra data by means of private variables to pass them all as function arguments in an ideal scenario this should not be a problem, but after what's happened with embed thumbnails, the assumption that all services/handlers will starts with a clean slate is no longer reliable functionality should remain the same, if anything it'd be more troubling if something's changed --- .../ActivityPub/Inbox/CreateHandler.php | 37 ++++----- .../ActivityPub/Inbox/UpdateHandler.php | 77 +++++++++---------- src/MessageHandler/DeleteUserHandler.php | 41 +++++----- 3 files changed, 75 insertions(+), 80 deletions(-) diff --git a/src/MessageHandler/ActivityPub/Inbox/CreateHandler.php b/src/MessageHandler/ActivityPub/Inbox/CreateHandler.php index ddcb02fca..7493899aa 100644 --- a/src/MessageHandler/ActivityPub/Inbox/CreateHandler.php +++ b/src/MessageHandler/ActivityPub/Inbox/CreateHandler.php @@ -32,9 +32,6 @@ #[AsMessageHandler] class CreateHandler extends MbinMessageHandler { - private array $object; - private bool $stickyIt; - public function __construct( private readonly EntityManagerInterface $entityManager, private readonly Note $note, @@ -61,19 +58,19 @@ public function doWork(MessageInterface $message): void if (!($message instanceof CreateMessage)) { throw new \LogicException(); } - $this->object = $message->payload; - $this->stickyIt = $message->stickyIt; + $object = $message->payload; + $stickyIt = $message->stickyIt; $this->logger->debug('Got a CreateMessage of type {t}, {m}', ['t' => $message->payload['type'], 'm' => $message->payload]); $entryTypes = ['Page', 'Article', 'Video']; $postTypes = ['Question', 'Note']; try { - if ('ChatMessage' === $this->object['type']) { - $this->handlePrivateMessage(); - } elseif (\in_array($this->object['type'], $postTypes)) { - $this->handleChain(); - } elseif (\in_array($this->object['type'], $entryTypes)) { - $this->handlePage(); + if ('ChatMessage' === $object['type']) { + $this->handlePrivateMessage($object); + } elseif (\in_array($object['type'], $postTypes)) { + $this->handleChain($object, $stickyIt); + } elseif (\in_array($object['type'], $entryTypes)) { + $this->handlePage($object, $stickyIt); } } catch (UserBannedException) { $this->logger->info('Did not create the post, because the user is banned'); @@ -99,18 +96,18 @@ public function doWork(MessageInterface $message): void * @throws UserDeletedException * @throws InstanceBannedException */ - private function handleChain(): void + private function handleChain(array $object, bool $stickyIt): void { - if (isset($this->object['inReplyTo']) && $this->object['inReplyTo']) { - $existed = $this->repository->findByObjectId($this->object['inReplyTo']); + if (isset($object['inReplyTo']) && $object['inReplyTo']) { + $existed = $this->repository->findByObjectId($object['inReplyTo']); if (!$existed) { - $this->bus->dispatch(new ChainActivityMessage([$this->object])); + $this->bus->dispatch(new ChainActivityMessage([$object])); return; } } - $note = $this->note->create($this->object, stickyIt: $this->stickyIt); + $note = $this->note->create($object, stickyIt: $stickyIt); if ($note instanceof EntryComment || $note instanceof Post || $note instanceof PostComment) { if (null !== $note->apId and null === $note->magazine->apId and 'random' !== $note->magazine->name) { // local magazine, but remote post. Random magazine is ignored, as it should not be federated at all @@ -127,9 +124,9 @@ private function handleChain(): void * @throws PostingRestrictedException * @throws InstanceBannedException */ - private function handlePage(): void + private function handlePage(array $object, bool $stickyIt): void { - $page = $this->page->create($this->object, stickyIt: $this->stickyIt); + $page = $this->page->create($object, stickyIt: $stickyIt); if ($page instanceof Entry) { if (null !== $page->apId and null === $page->magazine->apId and 'random' !== $page->magazine->name) { // local magazine, but remote post. Random magazine is ignored, as it should not be federated at all @@ -138,9 +135,9 @@ private function handlePage(): void } } - private function handlePrivateMessage(): void + private function handlePrivateMessage(array $object): void { - $this->messageManager->createMessage($this->object); + $this->messageManager->createMessage($object); } private function handlePrivateMentions(): void diff --git a/src/MessageHandler/ActivityPub/Inbox/UpdateHandler.php b/src/MessageHandler/ActivityPub/Inbox/UpdateHandler.php index d729ad183..fdb26e4af 100644 --- a/src/MessageHandler/ActivityPub/Inbox/UpdateHandler.php +++ b/src/MessageHandler/ActivityPub/Inbox/UpdateHandler.php @@ -45,8 +45,6 @@ #[AsMessageHandler] class UpdateHandler extends MbinMessageHandler { - private array $payload; - public function __construct( private readonly ActivityPubManager $activityPubManager, private readonly ApActivityRepository $apActivityRepository, @@ -80,24 +78,24 @@ public function doWork(MessageInterface $message): void if (!($message instanceof UpdateMessage)) { throw new \LogicException(); } - $this->payload = $message->payload; - $this->logger->debug('received Update activity: {json}', ['json' => $this->payload]); + $payload = $message->payload; + $this->logger->debug('received Update activity: {json}', ['json' => $payload]); try { - $actor = $this->activityPubManager->findRemoteActor($message->payload['actor']); + $actor = $this->activityPubManager->findRemoteActor($payload['actor']); } catch (\Exception) { return; } - $object = $this->apActivityRepository->findByObjectId($message->payload['object']['id']); + $object = $this->apActivityRepository->findByObjectId($payload['object']['id']); if ($object) { - $this->editActivity($object, $message, $actor); + $this->editActivity($object, $actor, $payload); return; } - $object = $this->activityPubManager->findActorOrCreate($message->payload['object']['id']); + $object = $this->activityPubManager->findActorOrCreate($payload['object']['id']); if ($object instanceof User) { $this->updateUser($object, $actor); @@ -105,43 +103,44 @@ public function doWork(MessageInterface $message): void } if ($object instanceof Magazine) { - $this->updateMagazine($object, $actor); + $this->updateMagazine($object, $actor, $payload); return; } - $this->logger->warning("didn't know what to do with the update activity concerning '{id}'. We don't have a local object that has this id", ['id' => $message->payload['object']['id']]); + $this->logger->warning("didn't know what to do with the update activity concerning '{id}'. We don't have a local object that has this id", ['id' => $payload['object']['id']]); } - private function editActivity(array $object, UpdateMessage $message, User $actor): void + private function editActivity(array $object, User $actor, array $payload): void { $object = $this->entityManager->getRepository($object['type'])->find((int) $object['id']); + if ($object instanceof Entry) { - $this->editEntry($object, $actor); + $this->editEntry($object, $actor, $payload); if (null === $object->magazine->apId) { - $this->bus->dispatch(new GenericAnnounceMessage($object->magazine->getId(), $message->payload, $actor->apInboxUrl)); + $this->bus->dispatch(new GenericAnnounceMessage($object->magazine->getId(), $payload, $actor->apInboxUrl)); } } elseif ($object instanceof EntryComment) { - $this->editEntryComment($object, $actor); + $this->editEntryComment($object, $actor, $payload); if (null === $object->magazine->apId) { - $this->bus->dispatch(new GenericAnnounceMessage($object->magazine->getId(), $message->payload, $actor->apInboxUrl)); + $this->bus->dispatch(new GenericAnnounceMessage($object->magazine->getId(), $payload, $actor->apInboxUrl)); } } elseif ($object instanceof Post) { - $this->editPost($object, $actor); + $this->editPost($object, $actor, $payload); if (null === $object->magazine->apId) { - $this->bus->dispatch(new GenericAnnounceMessage($object->magazine->getId(), $message->payload, $actor->apInboxUrl)); + $this->bus->dispatch(new GenericAnnounceMessage($object->magazine->getId(), $payload, $actor->apInboxUrl)); } } elseif ($object instanceof PostComment) { - $this->editPostComment($object, $actor); + $this->editPostComment($object, $actor, $payload); if (null === $object->magazine->apId) { - $this->bus->dispatch(new GenericAnnounceMessage($object->magazine->getId(), $message->payload, $actor->apInboxUrl)); + $this->bus->dispatch(new GenericAnnounceMessage($object->magazine->getId(), $payload, $actor->apInboxUrl)); } } elseif ($object instanceof Message) { - $this->editMessage($object, $actor); + $this->editMessage($object, $actor, $payload); } } - private function editEntry(Entry $entry, User $user): void + private function editEntry(Entry $entry, User $user, array $payload): void { if (!$this->entryManager->canUserEditEntry($entry, $user)) { $this->logger->warning('User {u} tried to edit entry {et} ({eId}), but is not allowed to', ['u' => $user->apId ?? $user->username, 'et' => $entry->title, 'eId' => $entry->getId()]); @@ -150,13 +149,13 @@ private function editEntry(Entry $entry, User $user): void } $dto = $this->entryFactory->createDto($entry); - $dto->title = $this->payload['object']['name']; + $dto->title = $payload['object']['name']; - $this->extractChanges($dto); + $this->extractChanges($dto, $payload); $this->entryManager->edit($entry, $dto, $user); } - private function editEntryComment(EntryComment $comment, User $user): void + private function editEntryComment(EntryComment $comment, User $user, array $payload): void { if (!$this->entryCommentManager->canUserEditComment($comment, $user)) { $this->logger->warning('User {u} tried to edit entry comment {et} ({eId}), but is not allowed to', ['u' => $user->apId ?? $user->username, 'et' => $comment->getShortTitle(), 'eId' => $comment->getId()]); @@ -165,12 +164,12 @@ private function editEntryComment(EntryComment $comment, User $user): void } $dto = $this->entryCommentFactory->createDto($comment); - $this->extractChanges($dto); + $this->extractChanges($dto, $payload); $this->entryCommentManager->edit($comment, $dto, $user); } - private function editPost(Post $post, User $user): void + private function editPost(Post $post, User $user, array $payload): void { if (!$this->postManager->canUserEditPost($post, $user)) { $this->logger->warning('User {u} tried to edit post {pt} ({pId}), but is not allowed to', ['u' => $user->apId ?? $user->username, 'pt' => $post->getShortTitle(), 'pId' => $post->getId()]); @@ -179,12 +178,12 @@ private function editPost(Post $post, User $user): void } $dto = $this->postFactory->createDto($post); - $this->extractChanges($dto); + $this->extractChanges($dto, $payload); $this->postManager->edit($post, $dto, $user); } - private function editPostComment(PostComment $comment, User $user): void + private function editPostComment(PostComment $comment, User $user, array $payload): void { if (!$this->postCommentManager->canUserEditPostComment($comment, $user)) { $this->logger->warning('User {u} tried to edit post comment {pt} ({pId}), but is not allowed to', ['u' => $user->apId ?? $user->username, 'pt' => $comment->getShortTitle(), 'pId' => $comment->getId()]); @@ -193,27 +192,27 @@ private function editPostComment(PostComment $comment, User $user): void } $dto = $this->postCommentFactory->createDto($comment); - $this->extractChanges($dto); + $this->extractChanges($dto, $payload); $this->postCommentManager->edit($comment, $dto, $user); } - private function extractChanges(EntryDto|EntryCommentDto|PostDto|PostCommentDto $dto): void + private function extractChanges(EntryDto|EntryCommentDto|PostDto|PostCommentDto $dto, array $payload): void { - if (!empty($this->payload['object']['content'])) { - $dto->body = $this->objectExtractor->getMarkdownBody($this->payload['object']); + if (!empty($payload['object']['content'])) { + $dto->body = $this->objectExtractor->getMarkdownBody($payload['object']); } else { $dto->body = null; } - $dto->apLikeCount = $this->activityPubManager->extractRemoteLikeCount($this->payload['object']); - $dto->apDislikeCount = $this->activityPubManager->extractRemoteDislikeCount($this->payload['object']); - $dto->apShareCount = $this->activityPubManager->extractRemoteShareCount($this->payload['object']); + $dto->apLikeCount = $this->activityPubManager->extractRemoteLikeCount($payload['object']); + $dto->apDislikeCount = $this->activityPubManager->extractRemoteDislikeCount($payload['object']); + $dto->apShareCount = $this->activityPubManager->extractRemoteShareCount($payload['object']); } - private function editMessage(Message $message, User $user): void + private function editMessage(Message $message, User $user, array $payload): void { if ($this->messageManager->canUserEditMessage($message, $user)) { - $this->messageManager->editMessage($message, $this->payload['object']); + $this->messageManager->editMessage($message, $payload['object']); } else { $this->logger->warning( 'Got an update message from a user that is not allowed to edit it. Update actor: {ua}. Original Author: {oa}', @@ -233,10 +232,10 @@ private function updateUser(User $user, User $actor): void } } - private function updateMagazine(Magazine $magazine, User $actor): void + private function updateMagazine(Magazine $magazine, User $actor, array $payload): void { if ($magazine->canUpdateMagazine($actor)) { - $payloadObject = $this->payload['object']; + $payloadObject = $payload['object']; $themeDto = new MagazineThemeDto($magazine); if (isset($payloadObject['icon'])) { diff --git a/src/MessageHandler/DeleteUserHandler.php b/src/MessageHandler/DeleteUserHandler.php index 0fc22529b..c949a3027 100644 --- a/src/MessageHandler/DeleteUserHandler.php +++ b/src/MessageHandler/DeleteUserHandler.php @@ -21,8 +21,6 @@ #[AsMessageHandler] class DeleteUserHandler extends MbinMessageHandler { - private ?User $user; - public function __construct( private readonly LoggerInterface $logger, private readonly ImageManager $imageManager, @@ -44,54 +42,55 @@ public function doWork(MessageInterface $message): void if (!($message instanceof DeleteUserMessage)) { throw new \LogicException(); } - $this->user = $this->entityManager + /** @var ?User $user */ + $user = $this->entityManager ->getRepository(User::class) ->find($message->id); - if (!$this->user) { + if (!$user) { throw new UnrecoverableMessageHandlingException('User not found'); - } elseif ($this->user->isDeleted && null === $this->user->markedForDeletionAt) { + } elseif ($user->isDeleted && null === $user->markedForDeletionAt) { throw new UnrecoverableMessageHandlingException('User already deleted'); } - $isLocal = null === $this->user->apId; + $isLocal = null === $user->apId; - $privateKey = $this->user->getPrivateKey(); - $publicKey = $this->user->getPublicKey(); + $privateKey = $user->getPrivateKey(); + $publicKey = $user->getPublicKey(); - $inboxes = $this->getInboxes(); + $inboxes = $this->getInboxes($user); // note: email cannot be null. For remote accounts email is set to their 'handle@domain.tld' who knows why... - $userDto = UserDto::create($this->user->username, email: $this->user->username, createdAt: $this->user->createdAt); + $userDto = UserDto::create($user->username, email: $user->username, createdAt: $user->createdAt); $userDto->plainPassword = ''.time(); if (!$isLocal) { - $userDto->apId = $this->user->apId; - $userDto->apProfileId = $this->user->apProfileId; + $userDto->apId = $user->apId; + $userDto->apProfileId = $user->apProfileId; } try { - $this->userManager->detachAvatar($this->user); + $this->userManager->detachAvatar($user); } catch (\Exception|\Error $e) { - $this->logger->error("couldn't delete the avatar of {user} at '{path}': {message}", ['user' => $this->user->username, 'path' => $this->user->avatar?->filePath, 'message' => \get_class($e).': '.$e->getMessage()]); + $this->logger->error("couldn't delete the avatar of {user} at '{path}': {message}", ['user' => $user->username, 'path' => $user->avatar?->filePath, 'message' => \get_class($e).': '.$e->getMessage()]); } try { - $this->userManager->detachCover($this->user); + $this->userManager->detachCover($user); } catch (\Exception|\Error $e) { - $this->logger->error("couldn't delete the cover of {user} at '{path}': {message}", ['user' => $this->user->username, 'path' => $this->user->cover?->filePath, 'message' => \get_class($e).': '.$e->getMessage()]); + $this->logger->error("couldn't delete the cover of {user} at '{path}': {message}", ['user' => $user->username, 'path' => $user->cover?->filePath, 'message' => \get_class($e).': '.$e->getMessage()]); } - $filePathsOfUser = $this->userManager->getAllImageFilePathsOfUser($this->user); + $filePathsOfUser = $this->userManager->getAllImageFilePathsOfUser($user); foreach ($filePathsOfUser as $path) { try { $this->imageManager->remove($path); } catch (\Exception|\Error $e) { - $this->logger->error("couldn't delete image of {user} at '{path}': {message}", ['user' => $this->user->username, 'path' => $path, 'message' => \get_class($e).': '.$e->getMessage()]); + $this->logger->error("couldn't delete image of {user} at '{path}': {message}", ['user' => $user->username, 'path' => $path, 'message' => \get_class($e).': '.$e->getMessage()]); } } $this->entityManager->beginTransaction(); // delete the original user, so all the content is cascade deleted - $this->entityManager->remove($this->user); + $this->entityManager->remove($user); $this->entityManager->flush(); // recreate a user with the same name, so this handle is blocked @@ -115,9 +114,9 @@ public function doWork(MessageInterface $message): void $this->entityManager->commit(); } - private function getInboxes(): array + private function getInboxes(?User $user): array { - return array_unique(array_filter($this->userManager->getAllInboxesOfInteractions($this->user))); + return array_unique(array_filter($this->userManager->getAllInboxesOfInteractions($user))); } private function sendDeleteMessages(array $targetInboxes, User $deletedUser): void From 9bf9708fef60875266d2c357b597c1906c14b900 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Wed, 4 Sep 2024 11:22:21 +0200 Subject: [PATCH 235/335] Add warning message to logger in case of invalid reg form submission (#1082) --- src/Controller/Security/RegisterController.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Controller/Security/RegisterController.php b/src/Controller/Security/RegisterController.php index 71a411efe..0e69971bb 100644 --- a/src/Controller/Security/RegisterController.php +++ b/src/Controller/Security/RegisterController.php @@ -9,6 +9,7 @@ use App\Service\IpResolver; use App\Service\SettingsManager; use App\Service\UserManager; +use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -18,6 +19,7 @@ public function __construct( private readonly UserManager $manager, private readonly IpResolver $ipResolver, private readonly SettingsManager $settingsManager, + private readonly LoggerInterface $logger, ) { } @@ -48,6 +50,10 @@ public function __invoke(Request $request): Response ); return $this->redirectToRoute('front'); + } elseif ($form->isSubmitted() && !$form->isValid()) { + $this->logger->error('Registration form submission was invalid.', [ + 'errors' => $form->getErrors(true, false), + ]); } return $this->render( From a95eb3ab77163ae92bce612d96c4a7a0615c1bbb Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Wed, 4 Sep 2024 11:24:39 +0200 Subject: [PATCH 236/335] Translations update from Hosted Weblate (#1081) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Λευτέρης Τ Co-authored-by: ButterflyOfFire Co-authored-by: BentiGorlich --- translations/messages.de.yaml | 4 +-- translations/messages.el.yaml | 10 ++++++- translations/messages.fr.yaml | 56 +++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 3 deletions(-) diff --git a/translations/messages.de.yaml b/translations/messages.de.yaml index e0930d369..c5c9703ab 100644 --- a/translations/messages.de.yaml +++ b/translations/messages.de.yaml @@ -823,8 +823,8 @@ sidebar_sections_local_only: Beschränke "Zufällige X" und "Aktive Nutzer" Absc auf lokale Inhalte account_deletion_title: Kontolöschung account_deletion_description: Dein Konto wird in 30 Tagen gelöscht außer du entscheidest - dich dein Konto sofort zu löschen. Das Konto kann nicht wiederhergestellt werden - sobald es gelöscht ist. + dich dein Konto sofort zu löschen. Um das Konto wiederherzustellen, logge dich in + den nächsten 30 Tagen mit deinen Zugangsdaten ein oder kontaktiere einen Administrator. account_deletion_button: Lösche Konto account_deletion_immediate: Sofort Löschen remove_schedule_delete_account: Entferne geplante Löschung diff --git a/translations/messages.el.yaml b/translations/messages.el.yaml index c89f504f2..f5ccf3674 100644 --- a/translations/messages.el.yaml +++ b/translations/messages.el.yaml @@ -332,7 +332,7 @@ type.smart_contract: Έξυπνο συμβόλαιο up_votes: Ενισχύσεις enter_your_comment: Εισαγάγετε το σχόλιό σας enter_your_post: Εισαγάγετε την ανάρτησή σας -comments_count: '{0}σχόλια|{1}σχόλιο|]1,Inf[ σχόλια' +comments_count: '{0}Σχόλια|{1}Σχόλιο|]1,Inf[ Σχόλια' empty: Κενό unfollow: Κατάργηση ακολούθησης down_votes: Μειώσεις @@ -404,3 +404,11 @@ toolbar.link: Σύνδεσμος toolbar.image: Εικόνα toolbar.mention: Αναφορά password_confirm_header: Επιβεβαιώστε το αίτημα αλλαγής κωδικού πρόσβασης. +filter_by_subscription: Φιλτράρισμα βάσει εγγραφής +filter_by_federation: Φιλτράρισμα βάσει κατάστασης ομοσπονδίας +sort_by: Ταξινόμηση βάσει +subscribers_count: '{0}Εγγεγραμμένοι|{1}Εγγεγραμμένος|]1,Inf[ Εγγεγραμμένοι' +followers_count: '{0}Ακόλουθοι|{1}Ακόλουθος|]1,Inf[ Ακόλουθοι' +marked_for_deletion: Επισημάνθηκε για διαγραφή +marked_for_deletion_at: Επισημάνθηκε για διαγραφή στις %date% +remove_media: Αφαίρεση πολυμέσων diff --git a/translations/messages.fr.yaml b/translations/messages.fr.yaml index f1f1adcc3..e5b62a993 100644 --- a/translations/messages.fr.yaml +++ b/translations/messages.fr.yaml @@ -686,3 +686,59 @@ oauth2.grant.moderate.magazine_admin.badges: Créer ou supprimer des badges des qui vous appartiennent. oauth2.grant.moderate.post.pin: Épinglez des publications en haut de vos magazines modérés. +user_badge_bot: Robot +suspend_account: Suspendre le compte +user_badge_op: OP +user_badge_admin: Admin +announcement: Annonce +show: Afficher +hide: Masquer +back: Retour +version: Version +admin_users_active: Actifs +2fa.authentication_code.label: Code d'authentification +related_entry: Connexes +and: et +edited: édité +auto: Auto +delete_magazine: Supprimer le magazine +purge_magazine: Purger le magazine +purge_content: Purger le contenu +delete_content: Supprimer le contenu +subscription_panel_large: Grand panneau +page_width: Largeur de la page +page_width_max: Max +restore_magazine: Restaurer le magazine +deletion: Suppression +accept: Accepter +action: Action +keywords: Mots-clés +details: Détails +sensitive_warning: Contenu sensible +from: de +tag: Étiquette +someone: Quelqu'un +default_theme: Thème par défaut +2fa.remove: Supprimer 2FA +menu: Menu +abandoned: Abandonné +cancel_request: Annuler la demande +show_subscriptions: Afficher les abonnements +alphabetically: Alphabétiquement +page_width_auto: Auto +page_width_fixed: Fixe +user_badge_moderator: Mod +reported: signalé +report_subject: Sujet +unsuspend_account: Annuler la suspension du compte +sort_by: Trier par +filter_by_subscription: Filtrer par abonnement +filter_by_federation: Filtrer par statut de fédération +close: Fermer +pending: En attente +position_bottom: En bas +position_top: En haut +two_factor_authentication: Authentification à deux facteurs +admin_users_suspended: Suspendus +admin_users_banned: Bannis +admin_users_inactive: Inactifs From bdc3570797cc535c8048541a4f8fb663e9b7a967 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 4 Sep 2024 11:27:16 +0200 Subject: [PATCH 237/335] docs(contributor): contributors readme action update (#1084) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- README.md | 45 ++++++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 312fa71a9..c22538175 100644 --- a/README.md +++ b/README.md @@ -209,47 +209,47 @@ For developers: - - ryanmonsen + + lilfade
        - ryanmonsen + Bryson
        - - drupol + + vpzomtrrfrt
        - Pol Dellaiera + vpzomtrrfrt
        - - jwr1 + + cavebob
        - John Wesley + cavebob
        - - cavebob + + jwr1
        - cavebob + John Wesley
        - - vpzomtrrfrt + + drupol
        - vpzomtrrfrt + Pol Dellaiera
        - - lilfade + + ryanmonsen
        - Bryson + ryanmonsen
        @@ -266,13 +266,6 @@ For developers: CSDUMMI - - - LoveIsGrief -
        - LoveIsGrief -
        - DismalShadowX @@ -280,8 +273,6 @@ For developers: Nathan Sparrow - - privacyguard From 2510c1b9c770ed539934e900bed8a39aab264870 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Thu, 5 Sep 2024 20:00:43 +0200 Subject: [PATCH 238/335] Do not stealth anti-spam error messages in log (#1087) --- config/packages/antispam.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/packages/antispam.yaml b/config/packages/antispam.yaml index a0b51e291..f7d8855a7 100644 --- a/config/packages/antispam.yaml +++ b/config/packages/antispam.yaml @@ -7,8 +7,12 @@ # For more details on the options available visit https://omines.github.io/antispam-bundle/configuration/ # antispam: + stealth: false + profiles: default: + stealth: false + # Insert a honeypot called "email_address" on all forms to lure bots into filling it in honeypot: email_address From 6ebaa3044c5f08d4396d135150d735fafa259c74 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Thu, 5 Sep 2024 20:02:14 +0200 Subject: [PATCH 239/335] Translations update from Hosted Weblate (#1088) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Λευτέρης Τ --- translations/messages.el.yaml | 46 ++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/translations/messages.el.yaml b/translations/messages.el.yaml index f5ccf3674..bfb822efa 100644 --- a/translations/messages.el.yaml +++ b/translations/messages.el.yaml @@ -108,8 +108,8 @@ reset_check_email_desc: Αν υπάρχει ήδη λογαριασμός με email που θα περιέχει σύνδεσμο ώστε να επαναφέρετε τον κωδικό σας. Ο σύνδεσμος θα λήξει σε %expire%. random_posts: Τυχαίες αναρτήσεις -email_confirm_content: 'Έτοιμος να ενεργοποιήσεις τον λογαριασμό σου στο /kbin; Πάτησε - στον παρακάτω σύνδεσμο:' +email_confirm_content: 'Θες να ενεργοποιήσεις τον λογαριασμό σου στο Μbin; Πάτα στον + παρακάτω σύνδεσμο:' federated_user_info: Αυτό το προφίλ είναι από έναν συνενωμένο server και μπορεί να είναι ελλιπές. email_confirm_expire: Λάβετε υπόψη ότι ο σύνδεσμος θα λήξει σε μία ώρα. @@ -141,7 +141,7 @@ articles: Νήματα photos: Φωτογραφίες videos: Βίντεο report: Αναφορά -copy_url: Αντιγραφή /kbin URL +copy_url: Αντιγραφή Mbin URL copy_url_to_fediverse: Αντιγραφή πρωτότυπου URL share_on_fediverse: Κοινοποίηση στο Fediverse are_you_sure: Είσαι σίγουρος; @@ -160,7 +160,7 @@ hide_adult: Απόκρυψη περιεχομένου για ενήλικες (N privacy: Ιδιωτικότητα show_profile_subscriptions: Εμφάνιση συνδρομών σε περιοδικά notify_on_new_entry_comment_reply: Απαντήσεις στα σχόλια μου σε οποιοδήποτε νήμα -notify_on_new_post_reply: Ειδοποίησέ με για απαντήσεις στις αναρτήσεις μου +notify_on_new_post_reply: Απαντήσεις οποιοδήποτε επιπέδου σε αναρτήσεις που εξουσιοδότησα notify_on_new_entry: Νέα νήματα (σύνδεσμοι ή άρθρα) σε οποιοδήποτε περιοδικό στο οποίο έχω εγγραφεί save: Αποθήκευση @@ -217,7 +217,7 @@ wrote_message: Έγραψε ένα μήνυμα mentioned_you: Σε ανέφερε comment: Σχόλιο post: Ανάρτηση -send_message: Αποστολή μηνύματος +send_message: Αποστολή άμεσου μηνύματος message: Μήνυμα infinite_scroll: Άπειρη κύλιση sticky_navbar: Καρφιτσωμένη μπάρα πλοήγησης @@ -262,7 +262,7 @@ dashboard: Ταμπλό contact_email: Email επικοινωνίας pages: Σελίδες type_search_term: Πληκτρολογήστε τον όρο αναζήτησης -registrations_enabled: Οι εγγραφές ενεργοποιήθηκαν +registrations_enabled: Εγγραφή ενεργή registration_disabled: Οι εγγραφές απενεργοποιήθηκαν restore: Επαναφορά add_mentions_posts: Προσθήκη ετικετών αναφοράς σε αναρτήσεις @@ -284,7 +284,7 @@ return: Επιστροφή boost: Ενίσχυση 1d: 1 ημέρα edit: Επεξεργασία -notify_on_new_entry_reply: Ειδοποίησέ με για σχόλια στα νήματά μου +notify_on_new_entry_reply: Σχόλια οποιουδήποτε επιπέδου σε νήματα που εξουσιοδότησα 1y: 1 έτος general: Γενικά solarized_dark: Solarized Σκοτεινό @@ -338,7 +338,7 @@ unfollow: Κατάργηση ακολούθησης down_votes: Μειώσεις federated_magazine_info: Αυτό το περιοδικό είναι από έναν συνενωμένο server και ενδέχεται να είναι ελλιπές. -go_to_original_instance: Περιηγηθείτε περισσότερο στο πρωτότυπο instance. +go_to_original_instance: Προβολή σε απομακρυσμένη εντότητα. login_or_email: Όνομα χρήστη ή email in: στο up_vote: Ενίσχυση @@ -356,11 +356,11 @@ flash_register_success: Καλώς ήρθες, ο λογαριασμός σου set_magazines_bar: Μπάρα περιοδικών banned: Σε απαγόρευσε ban_expired: Η απαγόρευση έληξε -ban: Απαγόρευση +ban: Αποκλεισμός bans: Απαγορεύσεις add_ban: Προσθήκη απαγόρευσης federation: Ομοσπονδία -instances: Instances +instances: Οντότητες meta: Meta federated: Ομοσπονδιακός instance: Instance @@ -396,7 +396,7 @@ your_account_is_not_active: Ο λογαριασμός σας δεν έχει ε το email σας και κάντε κλικ στον σύνδεσμο ενεργοποίησης για να συνεχίσετε your_account_has_been_banned: Ο λογαριασμός σας έχει αποκλειστεί filter.origin.label: Επιλογή προέλευσης -kbin_bot: /kbin Bot +kbin_bot: Πράκτορας Mbin toolbar.header: Επικεφαλίδα toolbar.quote: Παράθεση toolbar.code: Κώδικας @@ -412,3 +412,27 @@ followers_count: '{0}Ακόλουθοι|{1}Ακόλουθος|]1,Inf[ Ακόλο marked_for_deletion: Επισημάνθηκε για διαγραφή marked_for_deletion_at: Επισημάνθηκε για διαγραφή στις %date% remove_media: Αφαίρεση πολυμέσων +edit_entry: Επεξεργασία νήματος +default_theme_auto: Ανοιχτό/Σκοτεινό (Αυτόματος Εντοπισμός) +unban: Άρση αποκλεισμού +ban_hashtag_btn: Αποκλεισμός Ετικέτας +ban_hashtag_description: Αποκλείοντας μία ετικέτα θα αποτρέπει τη δημιουργία αναρτήσεων + μ' αυτή την ετικέτα, αλλά και θα αποκρύπτει υπάρχουσες μ' αυτή την ετικέτα. +unban_hashtag_description: Αφαιρόντας τον αποκλεισμό μιας ετικέτας θα επιτρέπεται + η δημιουργία αναρτήσεων μ' αυτή την ετικέτα ξανά. Υπάρχουσες αναρτήσεις μ' αυτή + δεν θα κρύβονται. +mark_as_adult: Επισήμανση ως NSFW +unmark_as_adult: Άρση επισήμανσης ως NSFW +tag: Ετικέτα +from: από +default_theme: Προεπιλεγμένο θέμα +solarized_auto: Solarized (Αυτόματος Εντοπισμός) +local_and_federated: Τοπική και σε ομοσπονδία +menu: Μενού +flash_mark_as_adult_success: Αυτή η ανάρτηση έχει επισημανθεί επιτυχώς ως NSFW. +flash_unmark_as_adult_success: Αυτή η ανάρτηση δεν είναι πλέον επισημασμένη ως NSFW. +disconnected_magazine_info: Αυτό το περιοδικό δεν λαμβάνει ενημερώσεις (τελευταία + δραστηριότητα %days% ημέρα/-ες πριν). +always_disconnected_magazine_info: Αυτό το περιοδικό δεν λαμβάνει ενημερώσεις. +subscribe_for_updates: Κάνε εγγραφή για να λαμβάνεις ενημερώσεις. +unban_hashtag_btn: Άρση αποκλεισμού Ετικέτας From b09197e0b20a270ecd23c6be1b217cfb32811c5b Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Thu, 5 Sep 2024 20:07:10 +0200 Subject: [PATCH 240/335] Translations update from Hosted Weblate (#1089) Co-authored-by: Melroy van den Berg --- translations/messages.it.yaml | 2 +- translations/messages.uk.yaml | 6 +++--- translations/messages.zh_TW.yaml | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/translations/messages.it.yaml b/translations/messages.it.yaml index c676798e5..f0ba2b11a 100644 --- a/translations/messages.it.yaml +++ b/translations/messages.it.yaml @@ -55,7 +55,7 @@ password: Password remember_me: Ricordami reset_password: Reimposta password show_more: Mostra di più -email_confirm_content: 'Sei pronto ad attivare il tuo account Kbin? Clicca sul link +email_confirm_content: 'Sei pronto ad attivare il tuo account Mbin? Clicca sul link sottostante:' reset_check_email_desc2: Se non vedi alcuna e-mail, controlla nella cartella della posta indesiderata. diff --git a/translations/messages.uk.yaml b/translations/messages.uk.yaml index 12f657248..4869354ee 100644 --- a/translations/messages.uk.yaml +++ b/translations/messages.uk.yaml @@ -9,7 +9,7 @@ oauth2.grant.moderate.post.trash: Видаляти або відновлюват moderation.report.approve_report_title: Прийняти скаргу preview: Попередній перегляд moderation.report.reject_report_title: Відхилити скаргу -kbin_bot: /kbin Бот +kbin_bot: Mbin Бот dashboard: Панель керування added_new_reply: Додає нову відповідь bans: Заборонені @@ -162,7 +162,7 @@ magazine_theme_appearance_icon: Власний значок для спільн toolbar.ordered_list: Упорядкований список kbin_intro_title: Досліджуйте Федіверс microblog: Мікроблог -email_confirm_content: 'Готові активувати свій обліковий запис /kbin? Натисніть на +email_confirm_content: 'Готові активувати свій обліковий запис Mbin? Натисніть на посилання нижче:' oauth2.grant.moderate.magazine.ban.create: Забороняти користувачів у ваших модерованих спільнотах. @@ -523,7 +523,7 @@ edit_post: Редагувати допис no_comments: Немає коментарів federation_page_disallowed_description: Інстанси, з якими ми не федеруємо bot_body_content: "Ласкаво просимо до /kbin Бота! Цей бот відіграє вирішальну роль - в активації функціональності ActivityPub у /kbin. Він забезпечує /kbin спілкування + в активації функціональності ActivityPub у Mbin. Він забезпечує Mbin спілкування та федерацію з іншими інстансами у Федіверсі.\n\nActivityPub — це мережевий протокол відкритого стандарту. Він дозволяє децентралізованим платформам соціальних мереж спілкуватися та взаємодіяти одна з одною. Це дозволяє користувачам на різних інстансах diff --git a/translations/messages.zh_TW.yaml b/translations/messages.zh_TW.yaml index 00ae1e496..2fc9f5822 100644 --- a/translations/messages.zh_TW.yaml +++ b/translations/messages.zh_TW.yaml @@ -234,7 +234,7 @@ agree_terms: email_verify: 確認電子郵件地址 email_confirm_expire: 請注意,此連結於一小時後失效。 image_alt: 替代文字 -email_confirm_content: 準備好啟用你的 /kbin 帳號了嗎?點擊下方的連結: +email_confirm_content: 準備好啟用你的 Mbin 帳號了嗎?點擊下方的連結: homepage: 首頁 notify_on_new_post_comment_reply: 有人在任何鋪文回覆我的留言時 notify_on_new_posts: 訂閱的刊版有新鋪文時 @@ -360,10 +360,10 @@ filter.origin.label: 選擇來源 filter.adult.label: 選擇是否顯示成人內容 filter.fields.only_names: 只有名字 filter.fields.names_and_descriptions: 名字和描述 -kbin_bot: /kbin 機器人 +kbin_bot: Mbin 機器人 preferred_languages: 過濾帖子和鋪文的語言 magazine_panel_tags_info: 不建議使用,除非你想要來自其他聯邦宇宙的內容透過標籤(hashtags) 能被引進到這個刊版 -bot_body_content: "歡迎使用 /kbin 機器人!這個機器人在讓 /kbin 啟用 ActivityPub 的功能中有很重要的作用。它能確保 /kbin +bot_body_content: "歡迎使用 Mbin 機器人!這個機器人在讓 Mbin 啟用 ActivityPub 的功能中有很重要的作用。它能確保 /kbin 可以聯繫並並與其他聯邦宇宙的實體組成聯邦。\n\nActivityPub 是一個開放、標準的傳輸協定,能夠讓去中心化的社交網路平台可以互相構通和交流。讓用戶能在不同實體(也就是伺服器)在聯邦的社交網路中-又稱為聯邦宇宙-去追蹤、交流、並分享內容。 提供一個標準,讓用戶可以推出新內容、追蹤其他用戶、進行像是按讚、分享、在刊版或鋪文留言等等的社交活動。" auto_preview_help: 自動展開媒體預覽。 From 2e014e52ca65b8f800f2b8a653b8fdecb0af8165 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Sat, 7 Sep 2024 12:27:40 +0200 Subject: [PATCH 241/335] Translations update from Hosted Weblate (#1090) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Λευτέρης Τ --- translations/messages.el.yaml | 210 +++++++++++++++++++++++----------- 1 file changed, 141 insertions(+), 69 deletions(-) diff --git a/translations/messages.el.yaml b/translations/messages.el.yaml index bfb822efa..e03d51cc0 100644 --- a/translations/messages.el.yaml +++ b/translations/messages.el.yaml @@ -5,7 +5,7 @@ type.video: Βίντεο type.magazine: Περιοδικό thread: Νήμα threads: Νήματα -microblog: Microblog +microblog: Μικροϊστολόγιο events: Γεγονότα magazine: Περιοδικό magazines: Περιοδικά @@ -17,8 +17,8 @@ active: Ενεργά newest: Νεότερα oldest: Παλαιότερα commented: Με σχόλια -filter_by_time: Φιλτράρισμα κατά χρόνο -filter_by_type: φιλτράρισμα κατά τύπο +filter_by_time: Φιλτράρισμα βάσει χρόνου +filter_by_type: φιλτράρισμα βάσει τύπου favourites: Αγαπημένα favourite: Αγαπημένο avatar: Άβαταρ @@ -33,7 +33,7 @@ replies: Απαντήσεις moderators: Διαχειριστές add_post: Προσθήκη ανάρτησης add_media: Προσθήκη πολυμέσων -markdown_howto: Πώς λειτουργεί ο επεξεργαστής κειμένου; +markdown_howto: Πώς λειτουργεί ο συντάκτης; activity: Δραστηριότητα cover: Εξώφυλλο related_posts: Σχετικές αναρτήσεις @@ -67,8 +67,8 @@ rss: RSS change_theme: Αλλαγή θέματος useful: Χρήσιμα help: Βοήθεια -check_email: Ελέγξτε το email σας -reset_check_email_desc2: Αν δεν λάβατε email παρακαλώ τσέκαρετε το φάκελο με τα ανεπιθύμητα. +check_email: "'Ελεγξε το email σου" +reset_check_email_desc2: Αν δεν έλαβες το email παρακαλώ κοίτα το φάκελο με τα ανεπιθύμητα. try_again: Προσπάθησε ξανά email_confirm_header: Γεια! Επιβεβαίωσε την διεύθυνση email σου. email_verify: Επιβεβαίωσε την διεύθυνση email @@ -92,7 +92,7 @@ columns: Στήλες user: Χρήστης joined: Έγινε μέλος people_local: Τοπικά -hot: Τρέχοντα +hot: Σε τάση dont_have_account: Δεν έχεις λογαριασμό; change_view: Αλλαγή όψης username: Όνομα χρήστη @@ -101,17 +101,17 @@ agree_terms: Δέχομαι τους %terms_link_start%Όρους και Προ και την %policy_link_start%Πολιτική Απορρήτου%policy_link_end% owner: Ιδιοκτήτης create_new_magazine: Δημιουργία νέου περιοδικού -mod_log: Ιστορικό συντονιστών +mod_log: Καταγραφές συντονισμού faq: Συχνές ερωτήσεις (FAQ) add_comment: Προσθήκη σχολίου -reset_check_email_desc: Αν υπάρχει ήδη λογαριασμός με το email σας, σύντομα θα λάβετε - email που θα περιέχει σύνδεσμο ώστε να επαναφέρετε τον κωδικό σας. Ο σύνδεσμος θα - λήξει σε %expire%. +reset_check_email_desc: Αν υπάρχει ήδη λογαριασμός με το email σου, σύντομα θα λάβεις + ένα email που θα περιέχει σύνδεσμο ώστε να επαναφέρεις τον κωδικό σου. Ο σύνδεσμος + θα λήξει σε %expire%. random_posts: Τυχαίες αναρτήσεις email_confirm_content: 'Θες να ενεργοποιήσεις τον λογαριασμό σου στο Μbin; Πάτα στον παρακάτω σύνδεσμο:' -federated_user_info: Αυτό το προφίλ είναι από έναν συνενωμένο server και μπορεί να - είναι ελλιπές. +federated_user_info: Αυτό το προφίλ είναι από έναν συνενωμένο διακομιστή και μπορεί + να είναι ελλιπές. email_confirm_expire: Λάβετε υπόψη ότι ο σύνδεσμος θα λήξει σε μία ώρα. description: Περιγραφή people: Άτομα @@ -131,11 +131,11 @@ chat_view: Προβολή συνομιλίας tree_view: Προβολή δέντρου table_view: Προβολή πίνακα cards_view: Προβολή καρτών -3h: 3 ώρες -6h: 6 ώρες -12h: 12 ώρες -1w: 1 εβδομάδα -1m: 1 μήνας +3h: 3ώ +6h: 6ώ +12h: 12ώ +1w: 1εβδ +1m: 1μ links: Σύνδεσμοι articles: Νήματα photos: Φωτογραφίες @@ -144,7 +144,7 @@ report: Αναφορά copy_url: Αντιγραφή Mbin URL copy_url_to_fediverse: Αντιγραφή πρωτότυπου URL share_on_fediverse: Κοινοποίηση στο Fediverse -are_you_sure: Είσαι σίγουρος; +are_you_sure: Σίγουρα; reason: Αιτιολογία delete: Διαγραφή edit_post: Επεξεργασία ανάρτησης @@ -156,9 +156,9 @@ reports: Αναφορές notifications: Ειδοποιήσεις messages: Μηνύματα appearance: Εμφάνιση -hide_adult: Απόκρυψη περιεχομένου για ενήλικες (NSFW) +hide_adult: Απόκρυψη περιεχομένου NSFW privacy: Ιδιωτικότητα -show_profile_subscriptions: Εμφάνιση συνδρομών σε περιοδικά +show_profile_subscriptions: Εμφάνιση εγγραφών σε περιοδικά notify_on_new_entry_comment_reply: Απαντήσεις στα σχόλια μου σε οποιοδήποτε νήμα notify_on_new_post_reply: Απαντήσεις οποιοδήποτε επιπέδου σε αναρτήσεις που εξουσιοδότησα notify_on_new_entry: Νέα νήματα (σύνδεσμοι ή άρθρα) σε οποιοδήποτε περιοδικό στο οποίο @@ -173,7 +173,7 @@ new_password: Νέος κωδικός πρόσβασης change_email: Αλλαγή email change_password: Αλλαγή κωδικού πρόσβασης expand: Ανάπτυξη -collapse: Αναδίπλωση +collapse: Σύμπτυξη domains: Τομείς error: Σφάλμα votes: Ψήφοι @@ -193,8 +193,8 @@ removed_thread_by: έχει αφαιρέσει ένα νήμα από removed_comment_by: έχει αφαιρέσει ένα σχόλιο από restored_comment_by: έχει επαναφέρει το σχόλιο από restored_post_by: έχει επαναφέρει την ανάρτηση από -he_banned: ban -he_unbanned: unban +he_banned: αποκλεισμός +he_unbanned: άρση αποκλεισμού read_all: Ανάγνωση όλων show_all: Εμφάνιση όλων flash_thread_edit_success: Το νήμα επεξεργάστηκε επιτυχώς. @@ -203,7 +203,7 @@ flash_thread_pin_success: Το νήμα καρφιτσώθηκε επιτυχώ flash_thread_unpin_success: Το νήμα ξεκαρφιτσώθηκε επιτυχώς. flash_magazine_edit_success: Το περιοδικό έχει επεξεργαστεί επιτυχώς. too_many_requests: Υπέρβαση του ορίου, δοκιμάστε ξανά αργότερα. -set_magazines_bar_desc: προσθέστε τα ονόματα των περιοδικών μετά το κόμμα +set_magazines_bar_desc: πρόσθεσε τα ονόματα των περιοδικών μετά το κόμμα added_new_thread: Πρόσθεσε νέο νήμα edited_thread: Επεξεργάστηκε ένα νήμα mod_remove_your_thread: Ένας συντονιστής αφαίρεσε το νήμα σου @@ -261,13 +261,13 @@ admin_panel: Πίνακας Διαχειριστή dashboard: Ταμπλό contact_email: Email επικοινωνίας pages: Σελίδες -type_search_term: Πληκτρολογήστε τον όρο αναζήτησης +type_search_term: Πληκτρολόγησε τον όρο αναζήτησης registrations_enabled: Εγγραφή ενεργή -registration_disabled: Οι εγγραφές απενεργοποιήθηκαν +registration_disabled: Εγγραφή ανενεργή restore: Επαναφορά add_mentions_posts: Προσθήκη ετικετών αναφοράς σε αναρτήσεις Password is invalid: Ο κωδικός είναι μη έγκυρος. -Your account has been banned: Ο λογαριασμός σας έχει αποκλειστεί. +Your account has been banned: Ο λογαριασμός σου έχει αποκλειστεί. firstname: Όνομα send: Αποστολή active_users: Ενεργοί χρήστες @@ -282,16 +282,16 @@ dynamic_lists: Δυναμικές λίστες captcha_enabled: Το Captcha ενεργοποιήθηκε return: Επιστροφή boost: Ενίσχυση -1d: 1 ημέρα +1d: 1η edit: Επεξεργασία notify_on_new_entry_reply: Σχόλια οποιουδήποτε επιπέδου σε νήματα που εξουσιοδότησα -1y: 1 έτος +1y: 1χρ general: Γενικά solarized_dark: Solarized Σκοτεινό share: Κοινοποίηση homepage: Αρχική notify_on_new_post_comment_reply: Απαντήσεις στα σχόλια μου σε οποιεσδήποτε αναρτήσεις -featured_magazines: Επίλεκτα περιοδικά +featured_magazines: Παρεχόμενα περιοδικά notify_on_new_posts: Νέες αναρτήσεις σε οποιοδήποτε περιοδικό στο οποίο έχω εγγραφεί show_magazines_icons: Εμφάνιση εικονιδίων περιοδικών restored_thread_by: έχει επαναφέρει ένα νήμα από @@ -311,35 +311,35 @@ note: Σημείωση local: Τοπικά FAQ: Συχνές ερωτήσεις (FAQ) related_entries: Σχετικά νήματα -header_logo: Λογότυπο επικεφαλίδας +header_logo: Λογότυπο κεφαλίδας set_magazines_bar_empty_desc: εάν το πεδίο είναι κενό, τα ενεργά περιοδικά εμφανίζονται στη γραμμή. edited_post: Επεξεργάστηκε μια ανάρτηση sidebar_position: Θέση πλευρικής γραμμής add_badge: Προσθήκη σήματος add_mentions_entries: Προσθήκη ετικετών αναφοράς σε νήματα -unban_account: Κατάργηση αποκλεισμού λογαριασμού -browsing_one_thread: Περιηγείστε μόνο ένα νήμα στη συζήτηση! Όλα τα σχόλια είναι διαθέσιμα - στη σελίδα ανάρτησης. -Your account is not active: Ο λογαριασμός σας δεν είναι ενεργός. +unban_account: Άρση αποκλεισμού λογαριασμού +browsing_one_thread: Περιηγήσαι σε μόνο ένα νήμα στη συζήτηση! Όλα τα σχόλια είναι + διαθέσιμα στη σελίδα ανάρτησης. +Your account is not active: Ο λογαριασμός σου δεν είναι ενεργός. random_magazines: Τυχαία περιοδικά removed: Αφαιρέθηκε από συντονιστή -deleted: Διαγράφηκε από τον συγγραφέα +deleted: Διαγράφηκε από τον συντάκτη mod_log_alert: ΠΡΟΕΙΔΟΠΟΙΗΣΗ - Το αρχείο καταγραφής του συντονιστή μπορεί να περιέχει δυσάρεστο ή ενοχλητικό περιεχόμενο που έχει αφαιρεθεί από τους συντονιστές. Παρακαλούμε - να είστε προσεκτικοί. + δώσε προσοχή. type.smart_contract: Έξυπνο συμβόλαιο up_votes: Ενισχύσεις -enter_your_comment: Εισαγάγετε το σχόλιό σας -enter_your_post: Εισαγάγετε την ανάρτησή σας +enter_your_comment: Εισήγαγε το σχόλιό σου +enter_your_post: Εισήγαγε την ανάρτησή σου comments_count: '{0}Σχόλια|{1}Σχόλιο|]1,Inf[ Σχόλια' empty: Κενό unfollow: Κατάργηση ακολούθησης down_votes: Μειώσεις -federated_magazine_info: Αυτό το περιοδικό είναι από έναν συνενωμένο server και ενδέχεται - να είναι ελλιπές. -go_to_original_instance: Προβολή σε απομακρυσμένη εντότητα. -login_or_email: Όνομα χρήστη ή email +federated_magazine_info: Αυτό το περιοδικό είναι από έναν συνενωμένο διακομιστή και + ενδέχεται να είναι ελλιπές. +go_to_original_instance: Προβολή σε απομακρυσμένη οντότητα +login_or_email: Σύνδεση ή email in: στο up_vote: Ενίσχυση down_vote: Μείωση @@ -352,58 +352,59 @@ moderate: Συντόνισε show_profile_followings: Εμφάνιση χρηστών που ακολουθούνται flash_register_success: Καλώς ήρθες, ο λογαριασμός σου είναι πλέον εγγεγραμμένος. Ένα τελευταίο βήμα! - Στα εισερχόμενά σου θα βρεις έναν σύνδεσμο ενεργοποίησης ώστε - να ενεργοποιήσεις τον λογαριασμό σου. + να δώσεις ζωή στον λογαριασμό σου. set_magazines_bar: Μπάρα περιοδικών -banned: Σε απαγόρευσε -ban_expired: Η απαγόρευση έληξε +banned: Σε απέκλεισε +ban_expired: Ο αποκλεισμός έληξε ban: Αποκλεισμός -bans: Απαγορεύσεις -add_ban: Προσθήκη απαγόρευσης +bans: Αποκλεισμοί +add_ban: Προσθήκη αποκλεισμού federation: Ομοσπονδία instances: Οντότητες meta: Meta federated: Ομοσπονδιακός -instance: Instance +instance: Οντότητα federation_enabled: Ενεργοποιήθηκε η ομοσπονδία -magazine_panel_tags_info: Παρέχετε μόνο εάν θέλετε περιεχόμενο από το fediverse να - περιλαμβάνεται σε αυτό το περιοδικό με βάση ετικέτες -banned_instances: Instances σε απαγόρευση -kbin_intro_title: Εξερευνήστε το Fediverse +magazine_panel_tags_info: Παροχή μόνο εάν θες περιεχόμενο από το fediverse να περιλαμβάνεται + σε αυτό το περιοδικό με βάση ετικέτες +banned_instances: Οντότητες σε αποκλεισμό +kbin_intro_title: Εξερεύνησε το Fediverse kbin_intro_desc: είναι μια αποκεντρωμένη πλατφόρμα για συγκέντρωση περιεχομένου και - microblogging που λειτουργεί εντός του δικτύου Fediverse. -kbin_promo_title: Δημιουργήστε το δικό σας instance -kbin_promo_desc: '%link_start%Αντιγραφή clone repo%link_end% και ανάπτυξη fediverse' + μικροϊστολόγια που λειτουργεί εντός του δικτύου Fediverse. +kbin_promo_title: Δημιούργησε τη δική σου οντότητα +kbin_promo_desc: '%link_start%Κλωνοποίηση αποθετηρίου%link_end% και ανάπτυξη fediverse' to: σε report_issue: Αναφορά προβλήματος -tokyo_night: Tokyo Night -mercure_enabled: Το Mercure είναι ενεργοποιημένο +tokyo_night: Τόκυο Νύχτα +mercure_enabled: Το Mercure είναι ενεργό preferred_languages: Φιλτράρισμα γλωσσών των νημάτων και των αναρτήσεων infinite_scroll_help: Φόρτωσε αυτόματα περισσότερο περιεχόμενο όταν φτάσεις το τέλος της σελίδας. sticky_navbar_help: Η γραμμή πλοήγησης θα καρφιτσωθεί στην κορυφή της σελίδας όταν - κάνετε κύλιση προς τα κάτω. + κάνεις κύλιση προς τα κάτω. auto_preview_help: Αυτόματη επέκταση των προεπισκοπήσεων πολυμέσων. reload_to_apply: Ανανέωση σελίδας για να εφαρμοστούν οι αλλαγές filter.fields.label: Επιλογή πεδίων για αναζήτηση filter.fields.only_names: Μόνο ονόματα filter.fields.names_and_descriptions: Ονόματα και περιγραφές -filter.adult.hide: Απόκρυψη περιεχομένου για ενήλικες (NSFW) -filter.adult.show: Εμφάνιση περιεχομένου για ενήλικες (NSFW) -filter.adult.label: Επιλογή εμφάνισης περιεχομένου για ενήλικες (NSFW) -filter.adult.only: Μόνο περιεχόμενο για ενήλικες (NSFW) +filter.adult.hide: Απόκρυψη NSFW +filter.adult.show: Εμφάνιση NSFW +filter.adult.label: Επιλογή εμφάνισης περιεχομένου NSFW +filter.adult.only: Μόνο NSFW toolbar.bold: Έντονα -your_account_is_not_active: Ο λογαριασμός σας δεν έχει ενεργοποιηθεί. Παρακαλώ ελέγξτε - το email σας και κάντε κλικ στον σύνδεσμο ενεργοποίησης για να συνεχίσετε -your_account_has_been_banned: Ο λογαριασμός σας έχει αποκλειστεί +your_account_is_not_active: Ο λογαριασμός σου δεν έχει ενεργοποιηθεί. Παρακαλώ έλεγξε + το email σου για οδηγίες περί ενεργοποίησης λογαριασμού ή + αιτήσου ένα νέο email ενεργοποιήσης λογαριασμού. +your_account_has_been_banned: Ο λογαριασμός σου έχει αποκλειστεί filter.origin.label: Επιλογή προέλευσης kbin_bot: Πράκτορας Mbin -toolbar.header: Επικεφαλίδα +toolbar.header: Κεφαλίδα toolbar.quote: Παράθεση toolbar.code: Κώδικας toolbar.link: Σύνδεσμος toolbar.image: Εικόνα toolbar.mention: Αναφορά -password_confirm_header: Επιβεβαιώστε το αίτημα αλλαγής κωδικού πρόσβασης. +password_confirm_header: Επιβεβαίωσε το αίτημα αλλαγής κωδικού πρόσβασης. filter_by_subscription: Φιλτράρισμα βάσει εγγραφής filter_by_federation: Φιλτράρισμα βάσει κατάστασης ομοσπονδίας sort_by: Ταξινόμηση βάσει @@ -436,3 +437,74 @@ disconnected_magazine_info: Αυτό το περιοδικό δεν λαμβάν always_disconnected_magazine_info: Αυτό το περιοδικό δεν λαμβάνει ενημερώσεις. subscribe_for_updates: Κάνε εγγραφή για να λαμβάνεις ενημερώσεις. unban_hashtag_btn: Άρση αποκλεισμού Ετικέτας +resend_account_activation_email_question: Ανενεργός λογαριασμός; +federated_search_only_loggedin: Η αναζήτηση σε οποσπονδία είναι περιορισμένη αν δεν + έχεις συνδεθεί +oauth.consent.to_allow_access: Για να επιτρεπεί αυτή η πρόσβαση, κάνε κλικ στο κουμπί + "Επιτρέπεται" παρακάτω +toolbar.unordered_list: Μη τακτοποιημένη λίστα +federation_page_allowed_description: Γνωστές οντότητες με τις οποίες έχουμε συνενωθεί +federation_page_disallowed_description: Οντότητες με τις οποίες δε συνενωνόμαστε +account_deletion_title: Διαγραφή λογαριασμού +account_deletion_button: Διαγραφή Λογαριασμού +errors.server404.title: 404 Δε βρέθηκε +sidebar_sections_local_only: Περιορισμός των κατηγοριών "Τυχαίο Χ" και "Ενεργά Άτομα" + σε μόνο για τοπική +errors.server500.title: 500 Εσωτερικό Σφάλμα Διακομιστή +email_confirm_link_help: Εναλλακτικά μπορείς να κάνεις αντιγραφή επικόλληση στον περιηγητή + σου το ακόλουθο +bot_body_content: "Καλώς ήρθατε στον Πράκτορα του Mbin! Αυτός ο πράπτορας έχει καθοριστικό + ρόλο στην διατήρηση της λειτουργικότητας του ActivityPub εντός του Mbin. Εξασφαλίζει + ότι το Mbin μπορεί να επικοινωνεί και να συνενώνεται με άλλες οντότητες στο fediverse.\n + \nΤο ActivityPub είναι ένα ανοιχτό πρωτόκολλο που επιτρέπει στις αποκεντρωμένες + πλατφόρμες κοινωνικής δικτύωσης να επικοινωνούν και να αλληλεπιδρούν μεταξύ τους. + Επιτρέπει στους χρήστες σε διαφορετικές οντότητες (διακομιστές) να ακολουθούν, να + αλληλεπιδρούν και να μοιράζονται περιεχόμενο μέσω του ομοσπονδιακού κοινωνικού δικτύου + που είναι γνωστό ως fediverse. Παρέχει έναν τυποποιημένο τρόπο στους χρήστες να + δημοσιεύουν περιεχόμενο, να ακολουθούν άλλους χρήστες και να συμμετέχουν σε κοινωνικές + αλληλεπιδράσεις όπως να τους αρέσει, να μοιράζονται και να σχολιάζουν νήματα ή αναρτήσεις." +toolbar.strikethrough: Γραμμή διαγραφής +toolbar.ordered_list: Τακτοποιημένη Λίστα +federation_page_enabled: Σελίδα ομοσπονδίας ενεργή +resend_account_activation_email_error: Υπήρξε ένα ζήτημα κατοχύρωσης αυτού του αιτήματος. + Μπορεί να μην υπάρχει λογαριασμός που να σχετίζεται μ' αυτό το email ή ίσως έχει + ήδη ενεργοποιηθεί. +block: Αποκλεισμός +toolbar.italic: Πλάγια +federation_page_dead_title: Νεκρές οντότητες +errors.server429.title: 429 Υπερβολικά Πολλές Αιτήσεις +account_deletion_description: Ο λογαριασμός σου θα διαγραφεί σε 30 ημέρες εκτός αν + επιλέξεις να τον διαγράψεις αμέσως. Για να τον επαναφέρεις εντός 30 ημέρων, συνδέσου + με τα ίδια στοιχεία σύνδεσης χρήστη ή επικοινώνησε με έναν διαχειριστή. +account_deletion_immediate: Άμεση διαγραφή +more_from_domain: Περισσότερα απ' τον τομέα +oauth.consent.app_requesting_permissions: θα 'θελε να πραγματοποιήσει τις ακόλουθες + ενέργειες εκ μέρους σου +oauth.consent.allow: Επιτρέπεται +resend_account_activation_email_description: Εισήγαγε τη διεύθυνση email που σχετίζεται + με τον λογαριασμό σου. Θα σου στείλουμε άλλο ένα email ενεργοποίησης. +oauth.consent.app_has_permissions: μπορεί ήδη να πραγματοποιήσει τις ακόλουθες ενέργειες +custom_css: Προσαρμοσμένη CSS +federation_page_dead_description: Οντότητες στις οποίες δε μπορούσαμε να παραδώσουμε + 10 δραστηριότητες στη σειρά και όπου η τελευταία παράδοση ήταν μια εβδομάδα πριν +errors.server500.description: Συγγνώμη, κάτι πήγε στραβά από τη πλευρά μας. Αν συνεχίζεις + να βλέπεις αυτό το σφάλμα, δοκίμασε να επικοινωνήσεις με τον ιδιοκτήτη της οντότητας. + Αν η οντότητα δε δουλεύει καθόλου, ρίξε μια ματιά εντωμεταξύ, σε %link_start%άλλες + οντότητες του Mbin%link_end% μέχρι να επιλυθεί το πρόβλημα. +errors.server403.title: 403 Απαγορευμένο +email_confirm_button_text: Επιβεβαίωσε την αίτηση για αλλαγή κωδικού +email.delete.title: Αίτημα διαγραφής λογαριασμού χρήστη +email.delete.description: Ο ακόλουθος χρήστης αιτήθηκε διαγραφής του λογαριασμού του +resend_account_activation_email: Επαναποστολή email ενεργοποίησης λογαριασμού +resend_account_activation_email_success: Αν υπάρχει λογαριασμός που συσχετίζεται μ' + αυτό το email, θα στείλουμε νέο email ενεργοποίησης. +ignore_magazines_custom_css: Αγνόηση προσαρμοσμένης CSS περιοδικών +oauth.consent.title: Φόρμα Συναίνεσης OAuth2 +oauth.consent.grant_permissions: Αποδοχή Δικαιωμάτων +oauth.consent.deny: Απόρριψη +oauth.client_identifier.invalid: Μη Έγκυρο ID Πελάτη OAuth! +oauth.client_not_granted_message_read_permission: Αυτή η εφαρμογή δεν έχει το δικαίωμα + να διαβάζει τα μηνύματά σου. +restrict_oauth_clients: Περιορισμός δημιουργίας Πελάτη OAuth2 για τους Διαχειριστές +private_instance: Υποχρέωσε τους χρήστες να συνδεθούν πριν μπορούν να έχουν πρόσβαση + σε περιεχόμενο From 6ec8e1ea181abaccbfd1c62417c49a45ce835e7d Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Sat, 7 Sep 2024 12:42:33 +0200 Subject: [PATCH 242/335] Add trusted proxies to docs (#1086) --- docs/02-admin/02-configuration/nginx.md | 41 +++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/docs/02-admin/02-configuration/nginx.md b/docs/02-admin/02-configuration/nginx.md index c108b160f..34f98c903 100644 --- a/docs/02-admin/02-configuration/nginx.md +++ b/docs/02-admin/02-configuration/nginx.md @@ -243,19 +243,57 @@ Restart (or reload) NGINX: sudo systemctl restart nginx ``` +## Trusted Proxies + +If you are using a reverse proxy, you need to configure your trusted proxies to use the `X-Forwarded-For` header. Mbin configured the following trusted headers for you already: `x-forwarded-for`, `x-forwarded-proto`, `x-forwarded-port` and `x-forwarded-prefix`. + +Trusted proxies can be configured in the `.env` file (or your `.env.local` file): + +```sh +nano /var/www/mbin/.env +``` + +You can configure a single IP address and/or a range of IP addresses (this configuration should be sufficient if you are running Nginx yourself): + +```dotenv +# Change the IP range if needed, this is just an example +TRUSTED_PROXIES=127.0.0.1,192.168.1.0/24 +``` + +Or if the IP address is dynamic, you can set the `REMOTE_ADDR` string which will be replaced at runtime by `$_SERVER['REMOTE_ADDR']`: + +```dotenv +TRUSTED_PROXIES=127.0.0.1,REMOTE_ADDR +``` + +> [!WARNING] +> In this last example be sure that you configure the web server to _not_ +> respond to traffic from _any_ clients other than your trusted load balancers +> (eg. within AWS this can be achieved via security groups). + +Finally run the `post-upgrade` script to dump the `.env` to the `.env.local.php` and clear any cache: + +```sh +./bin/post-upgrade +``` + +More detailed info can be found at: [Symfony Trusted Proxies docs](https://symfony.com/doc/current/deployment/proxies.html) + ## Media reverse proxy we suggest that you do not use this configuration: + ```dotenv KBIN_STORAGE_URL=https://mbin.domain.tld/media ``` Instead we suggest to use a subdomain for serving your media files: + ```dotenv KBIN_STORAGE_URL=https://media.mbin.domain.tld ``` -That way you can let nginx cache media assets and seamlessly switch to an object storage provider later. +That way you can let nginx cache media assets and seamlessly switch to an object storage provider later. ```bash sudo nano /etc/nginx/sites-available/mbin-media.conf @@ -289,4 +327,3 @@ For it to be a usable https site you have to run `certbot --nginx` and select th > [!TIP] > don't forget to enable http2 by adding `http2 on;` after certbot ran (underneath the `listen 443 ssl;` line) - From 80036771e5e5252a9131e98cbf553e696728a0e6 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Sat, 7 Sep 2024 13:41:04 +0200 Subject: [PATCH 243/335] Add missing link to C4.md (#1094) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c22538175..3eaef62eb 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ For developers: - GitHub Security advisories, vulnerability reporting, [Dependabot](https://github.com/features/security) and [Advanced code scanning](https://docs.github.com/en/code-security/code-scanning/introduction-to-code-scanning/about-code-scanning) enabled. And we run [`local-php-security-checker`](https://github.com/fabpot/local-php-security-checker). - Improved **code documentation** - **Tight integration** with [Mbin Weblate project](https://hosted.weblate.org/engage/mbin/) for translations (Two way sync) -- Last but not least, a **community-focus project embracing the Collective Code Construction Contract** (C4). No single maintainer. +- Last but not least, a **community-focus project embracing the [Collective Code Construction Contract](./C4.md)** (C4). No single maintainer. ## Instances From 4cd208383616a68b5f84d12526c69b02d5a12313 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Sat, 7 Sep 2024 16:13:22 +0200 Subject: [PATCH 244/335] Update minor versions NPM packages (#1092) --- package-lock.json | 866 +++++++++++++++++----------------------------- 1 file changed, 316 insertions(+), 550 deletions(-) diff --git a/package-lock.json b/package-lock.json index f32c45562..7761d8f0d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -65,9 +65,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.2.tgz", - "integrity": "sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz", + "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==", "dev": true, "license": "MIT", "engines": { @@ -106,13 +106,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz", - "integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", + "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.25.0", + "@babel/types": "^7.25.6", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -166,9 +166,9 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.0.tgz", - "integrity": "sha512-GYM6BxeQsETc9mnct+nIIpf63SAyzvyYN7UB/IlTyd+MBg06afFGp0mIeUqGyWgS2mxad6vqbMrHVlaL3m70sQ==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz", + "integrity": "sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==", "dev": true, "license": "MIT", "dependencies": { @@ -177,7 +177,7 @@ "@babel/helper-optimise-call-expression": "^7.24.7", "@babel/helper-replace-supers": "^7.25.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/traverse": "^7.25.0", + "@babel/traverse": "^7.25.4", "semver": "^6.3.1" }, "engines": { @@ -402,14 +402,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.0.tgz", - "integrity": "sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz", + "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==", "dev": true, "license": "MIT", "dependencies": { "@babel/template": "^7.25.0", - "@babel/types": "^7.25.0" + "@babel/types": "^7.25.6" }, "engines": { "node": ">=6.9.0" @@ -432,13 +432,13 @@ } }, "node_modules/@babel/parser": { - "version": "7.25.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.3.tgz", - "integrity": "sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.25.2" + "@babel/types": "^7.25.6" }, "bin": { "parser": "bin/babel-parser.js" @@ -613,13 +613,13 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz", - "integrity": "sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.6.tgz", + "integrity": "sha512-aABl0jHw9bZ2karQ/uUD6XP4u0SG22SJrOHFoL6XB1R7dTovOP4TzTlsxOYC5yQ1pdscVK2JTUnF6QL3ARoAiQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -629,13 +629,13 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", - "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.6.tgz", + "integrity": "sha512-sXaDXaJN9SNLymBdlWFA+bjzBhFD617ZaFiY13dGt7TVslVvVgA6fkZOP7Ki3IGElC45lwHdOTrCtKZGVAWeLQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -814,16 +814,16 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.0.tgz", - "integrity": "sha512-uaIi2FdqzjpAMvVqvB51S42oC2JEVgh0LDsGfZVDysWE8LrJtQC2jvKmOqEYThKyB7bDEb7BP1GYWDm7tABA0Q==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.4.tgz", + "integrity": "sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.8", "@babel/helper-remap-async-to-generator": "^7.25.0", "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/traverse": "^7.25.0" + "@babel/traverse": "^7.25.4" }, "engines": { "node": ">=6.9.0" @@ -883,14 +883,14 @@ } }, "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz", - "integrity": "sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.4.tgz", + "integrity": "sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-class-features-plugin": "^7.25.4", + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -918,17 +918,17 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.0.tgz", - "integrity": "sha512-xyi6qjr/fYU304fiRwFbekzkqVJZ6A7hOjWZd+89FVcBqPV3S9Wuozz82xdpLspckeaafntbzglaW4pqpzvtSw==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.4.tgz", + "integrity": "sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-compilation-targets": "^7.25.2", "@babel/helper-plugin-utils": "^7.24.8", "@babel/helper-replace-supers": "^7.25.0", - "@babel/traverse": "^7.25.0", + "@babel/traverse": "^7.25.4", "globals": "^11.1.0" }, "engines": { @@ -1399,14 +1399,14 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz", - "integrity": "sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.4.tgz", + "integrity": "sha512-ao8BG7E2b/URaUQGqN3Tlsg+M3KlHY6rJ1O1gXAEUnZoyNQnvKyH87Kfg+FoxSeyWUB8ISZZsC91C44ZuBFytw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-class-features-plugin": "^7.25.4", + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1615,14 +1615,14 @@ } }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.7.tgz", - "integrity": "sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.4.tgz", + "integrity": "sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.2", + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1632,13 +1632,13 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.25.3", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.3.tgz", - "integrity": "sha512-QsYW7UeAaXvLPX9tdVliMJE7MD7M6MLYVTovRTIwhoYQVFHR1rM4wO8wqAezYi3/BpSD+NzVCZ69R6smWiIi8g==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.4.tgz", + "integrity": "sha512-W9Gyo+KmcxjGahtt3t9fb14vFRWvPpu5pT6GBlovAK6BTBcxgjfVMSQCfJl4oi35ODrxP6xx2Wr8LNST57Mraw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.25.2", + "@babel/compat-data": "^7.25.4", "@babel/helper-compilation-targets": "^7.25.2", "@babel/helper-plugin-utils": "^7.24.8", "@babel/helper-validator-option": "^7.24.8", @@ -1667,13 +1667,13 @@ "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.24.7", - "@babel/plugin-transform-async-generator-functions": "^7.25.0", + "@babel/plugin-transform-async-generator-functions": "^7.25.4", "@babel/plugin-transform-async-to-generator": "^7.24.7", "@babel/plugin-transform-block-scoped-functions": "^7.24.7", "@babel/plugin-transform-block-scoping": "^7.25.0", - "@babel/plugin-transform-class-properties": "^7.24.7", + "@babel/plugin-transform-class-properties": "^7.25.4", "@babel/plugin-transform-class-static-block": "^7.24.7", - "@babel/plugin-transform-classes": "^7.25.0", + "@babel/plugin-transform-classes": "^7.25.4", "@babel/plugin-transform-computed-properties": "^7.24.7", "@babel/plugin-transform-destructuring": "^7.24.8", "@babel/plugin-transform-dotall-regex": "^7.24.7", @@ -1701,7 +1701,7 @@ "@babel/plugin-transform-optional-catch-binding": "^7.24.7", "@babel/plugin-transform-optional-chaining": "^7.24.8", "@babel/plugin-transform-parameters": "^7.24.7", - "@babel/plugin-transform-private-methods": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.25.4", "@babel/plugin-transform-private-property-in-object": "^7.24.7", "@babel/plugin-transform-property-literals": "^7.24.7", "@babel/plugin-transform-regenerator": "^7.24.7", @@ -1714,10 +1714,10 @@ "@babel/plugin-transform-unicode-escapes": "^7.24.7", "@babel/plugin-transform-unicode-property-regex": "^7.24.7", "@babel/plugin-transform-unicode-regex": "^7.24.7", - "@babel/plugin-transform-unicode-sets-regex": "^7.24.7", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.4", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.4", + "babel-plugin-polyfill-corejs3": "^0.10.6", "babel-plugin-polyfill-regenerator": "^0.6.1", "core-js-compat": "^3.37.1", "semver": "^6.3.1" @@ -1752,9 +1752,9 @@ "license": "MIT" }, "node_modules/@babel/runtime": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", - "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", + "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1780,17 +1780,17 @@ } }, "node_modules/@babel/traverse": { - "version": "7.25.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.3.tgz", - "integrity": "sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", + "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.0", - "@babel/parser": "^7.25.3", + "@babel/generator": "^7.25.6", + "@babel/parser": "^7.25.6", "@babel/template": "^7.25.0", - "@babel/types": "^7.25.2", + "@babel/types": "^7.25.6", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1799,9 +1799,9 @@ } }, "node_modules/@babel/types": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.2.tgz", - "integrity": "sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", "dev": true, "license": "MIT", "dependencies": { @@ -2731,9 +2731,9 @@ "license": "Apache-2.0" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.19.2.tgz", - "integrity": "sha512-OHflWINKtoCFSpm/WmuQaWW4jeX+3Qt3XQDepkkiFTsoxFc5BpF3Z5aDxFZgBqRjO6ATP5+b1iilp4kGIZVWlA==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.2.tgz", + "integrity": "sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==", "cpu": [ "arm" ], @@ -2746,9 +2746,9 @@ "peer": true }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.19.2.tgz", - "integrity": "sha512-k0OC/b14rNzMLDOE6QMBCjDRm3fQOHAL8Ldc9bxEWvMo4Ty9RY6rWmGetNTWhPo+/+FNd1lsQYRd0/1OSix36A==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.2.tgz", + "integrity": "sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==", "cpu": [ "arm64" ], @@ -2761,9 +2761,9 @@ "peer": true }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.19.2.tgz", - "integrity": "sha512-IIARRgWCNWMTeQH+kr/gFTHJccKzwEaI0YSvtqkEBPj7AshElFq89TyreKNFAGh5frLfDCbodnq+Ye3dqGKPBw==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.2.tgz", + "integrity": "sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==", "cpu": [ "arm64" ], @@ -2776,9 +2776,9 @@ "peer": true }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.19.2.tgz", - "integrity": "sha512-52udDMFDv54BTAdnw+KXNF45QCvcJOcYGl3vQkp4vARyrcdI/cXH8VXTEv/8QWfd6Fru8QQuw1b2uNersXOL0g==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.2.tgz", + "integrity": "sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==", "cpu": [ "x64" ], @@ -2791,9 +2791,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.19.2.tgz", - "integrity": "sha512-r+SI2t8srMPYZeoa1w0o/AfoVt9akI1ihgazGYPQGRilVAkuzMGiTtexNZkrPkQsyFrvqq/ni8f3zOnHw4hUbA==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.2.tgz", + "integrity": "sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==", "cpu": [ "arm" ], @@ -2806,9 +2806,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.19.2.tgz", - "integrity": "sha512-+tYiL4QVjtI3KliKBGtUU7yhw0GMcJJuB9mLTCEauHEsqfk49gtUBXGtGP3h1LW8MbaTY6rSFIQV1XOBps1gBA==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.2.tgz", + "integrity": "sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==", "cpu": [ "arm" ], @@ -2821,9 +2821,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.19.2.tgz", - "integrity": "sha512-OR5DcvZiYN75mXDNQQxlQPTv4D+uNCUsmSCSY2FolLf9W5I4DSoJyg7z9Ea3TjKfhPSGgMJiey1aWvlWuBzMtg==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.2.tgz", + "integrity": "sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==", "cpu": [ "arm64" ], @@ -2836,9 +2836,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.19.2.tgz", - "integrity": "sha512-Hw3jSfWdUSauEYFBSFIte6I8m6jOj+3vifLg8EU3lreWulAUpch4JBjDMtlKosrBzkr0kwKgL9iCfjA8L3geoA==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.2.tgz", + "integrity": "sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==", "cpu": [ "arm64" ], @@ -2851,9 +2851,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.19.2.tgz", - "integrity": "sha512-rhjvoPBhBwVnJRq/+hi2Q3EMiVF538/o9dBuj9TVLclo9DuONqt5xfWSaE6MYiFKpo/lFPJ/iSI72rYWw5Hc7w==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.2.tgz", + "integrity": "sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==", "cpu": [ "ppc64" ], @@ -2866,9 +2866,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.19.2.tgz", - "integrity": "sha512-EAz6vjPwHHs2qOCnpQkw4xs14XJq84I81sDRGPEjKPFVPBw7fwvtwhVjcZR6SLydCv8zNK8YGFblKWd/vRmP8g==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.2.tgz", + "integrity": "sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==", "cpu": [ "riscv64" ], @@ -2881,9 +2881,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.19.2.tgz", - "integrity": "sha512-IJSUX1xb8k/zN9j2I7B5Re6B0NNJDJ1+soezjNojhT8DEVeDNptq2jgycCOpRhyGj0+xBn7Cq+PK7Q+nd2hxLA==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.2.tgz", + "integrity": "sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==", "cpu": [ "s390x" ], @@ -2896,9 +2896,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.19.2.tgz", - "integrity": "sha512-OgaToJ8jSxTpgGkZSkwKE+JQGihdcaqnyHEFOSAU45utQ+yLruE1dkonB2SDI8t375wOKgNn8pQvaWY9kPzxDQ==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.2.tgz", + "integrity": "sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==", "cpu": [ "x64" ], @@ -2911,9 +2911,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.19.2.tgz", - "integrity": "sha512-5V3mPpWkB066XZZBgSd1lwozBk7tmOkKtquyCJ6T4LN3mzKENXyBwWNQn8d0Ci81hvlBw5RoFgleVpL6aScLYg==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.2.tgz", + "integrity": "sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==", "cpu": [ "x64" ], @@ -2926,9 +2926,9 @@ "peer": true }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.19.2.tgz", - "integrity": "sha512-ayVstadfLeeXI9zUPiKRVT8qF55hm7hKa+0N1V6Vj+OTNFfKSoUxyZvzVvgtBxqSb5URQ8sK6fhwxr9/MLmxdA==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.2.tgz", + "integrity": "sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==", "cpu": [ "arm64" ], @@ -2941,9 +2941,9 @@ "peer": true }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.19.2.tgz", - "integrity": "sha512-Mda7iG4fOLHNsPqjWSjANvNZYoW034yxgrndof0DwCy0D3FvTjeNo+HGE6oGWgvcLZNLlcp0hLEFcRs+UGsMLg==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.2.tgz", + "integrity": "sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==", "cpu": [ "ia32" ], @@ -2956,9 +2956,9 @@ "peer": true }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.19.2.tgz", - "integrity": "sha512-DPi0ubYhSow/00YqmG1jWm3qt1F8aXziHc/UNy8bo9cpCacqhuWu+iSq/fp2SyEQK7iYTZ60fBU9cat3MXTjIQ==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.2.tgz", + "integrity": "sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==", "cpu": [ "x64" ], @@ -2978,53 +2978,16 @@ "license": "MIT" }, "node_modules/@stylistic/eslint-plugin": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-2.6.1.tgz", - "integrity": "sha512-UT0f4t+3sQ/GKW7875NiIIjZJ1Bh4gd7JNfoIkwIQyWqO7wGd0Pqzu0Ho30Ka8MNF5lm++SkVeqAk26vGxoUpg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@stylistic/eslint-plugin-js": "2.6.1", - "@stylistic/eslint-plugin-jsx": "2.6.1", - "@stylistic/eslint-plugin-plus": "2.6.1", - "@stylistic/eslint-plugin-ts": "2.6.1", - "@types/eslint": "^9.6.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "peerDependencies": { - "eslint": ">=8.40.0" - } - }, - "node_modules/@stylistic/eslint-plugin-js": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-2.6.1.tgz", - "integrity": "sha512-iLOiVzcvqzDGD9U0EuVOX680v+XOPiPAjkxWj+Q6iV2GLOM5NB27tKVOpJY7AzBhidwpRbaLTgg3T4UzYx09jw==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-2.7.2.tgz", + "integrity": "sha512-3DVLU5HEuk2pQoBmXJlzvrxbKNpu2mJ0SRqz5O/CJjyNCr12ZiPcYMEtuArTyPOk5i7bsAU44nywh1rGfe3gKQ==", "dev": true, "license": "MIT", "dependencies": { - "@types/eslint": "^9.6.0", - "acorn": "^8.12.1", + "@types/eslint": "^9.6.1", + "@typescript-eslint/utils": "^8.3.0", "eslint-visitor-keys": "^4.0.0", - "espree": "^10.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "peerDependencies": { - "eslint": ">=8.40.0" - } - }, - "node_modules/@stylistic/eslint-plugin-jsx": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-2.6.1.tgz", - "integrity": "sha512-5qHLXqxfY6jubAQfDqrifv41fx7gaqA9svDaChxMI6JiHpEBfh+PXxmm3g+B8gJCYVBTC62Rjl0Ny5QabK58bw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@stylistic/eslint-plugin-js": "^2.6.1", - "@types/eslint": "^9.6.0", + "espree": "^10.1.0", "estraverse": "^5.3.0", "picomatch": "^4.0.2" }, @@ -3035,38 +2998,6 @@ "eslint": ">=8.40.0" } }, - "node_modules/@stylistic/eslint-plugin-plus": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-2.6.1.tgz", - "integrity": "sha512-z/IYu/q8ipApzNam5utSU+BrXg4pK/Gv9xNbr4eWv/bZppvTWJU62xCO4nw/6r2dHNPnqc7uCHEC7GMlBnPY0A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/eslint": "^9.6.0", - "@typescript-eslint/utils": "^8.0.0" - }, - "peerDependencies": { - "eslint": "*" - } - }, - "node_modules/@stylistic/eslint-plugin-ts": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-2.6.1.tgz", - "integrity": "sha512-Mxl1VMorEG1Hc6oBYPD0+KIJOWkjEF1R0liL7wWgKfwpqOkgmnh5lVdZBrYyfRKOE4RlGcwEFTNai1IW6orgVg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@stylistic/eslint-plugin-js": "2.6.1", - "@types/eslint": "^9.6.0", - "@typescript-eslint/utils": "^8.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "peerDependencies": { - "eslint": ">=8.40.0" - } - }, "node_modules/@symfony/stimulus-bridge": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/@symfony/stimulus-bridge/-/stimulus-bridge-3.2.2.tgz", @@ -3100,9 +3031,9 @@ "link": true }, "node_modules/@symfony/webpack-encore": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/@symfony/webpack-encore/-/webpack-encore-4.6.1.tgz", - "integrity": "sha512-JbOjy0P6P9pcbgVE3nceFnCCneRO+tbcLUkQh9rpPj/sHtFl12foSjHz6uY93ZGZGAvTyqEslie+4MlD/rUtnQ==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@symfony/webpack-encore/-/webpack-encore-4.7.0.tgz", + "integrity": "sha512-vlvg1mYLVSaujTEUmkd/ucwK7LG7+89PHfOwfz/sJ53n2IFGtuAXyPyXL0igJ0tMcKvDuCShiWTX1nfnzT/Srw==", "dev": true, "license": "MIT", "dependencies": { @@ -3113,9 +3044,8 @@ "clean-webpack-plugin": "^4.0.0", "css-loader": "^6.7.0", "css-minimizer-webpack-plugin": "^5.0.0", - "fast-levenshtein": "^3.0.0", + "fastest-levenshtein": "^1.0.16", "mini-css-extract-plugin": "^2.6.0", - "pkg-up": "^3.1.0", "pretty-error": "^4.0.0", "resolve-url-loader": "^5.0.0", "semver": "^7.3.2", @@ -3141,6 +3071,7 @@ "@babel/preset-typescript": "^7.0.0", "@symfony/stimulus-bridge": "^3.0.0", "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0", + "@vue/babel-plugin-jsx": "^1.0.0", "@vue/babel-preset-jsx": "^1.0.0", "@vue/compiler-sfc": "^2.6 || ^3.0.2", "eslint": "^8.0.0", @@ -3150,13 +3081,13 @@ "handlebars": "^4.7.7", "handlebars-loader": "^1.7.0", "less": "^4.0.0", - "less-loader": "^11.0.0", + "less-loader": "^11.0.0 || ^12.2.0", "postcss": "^8.3.0", - "postcss-loader": "^7.0.0", + "postcss-loader": "^7.0.0 || ^8.1.0", "sass": "^1.17.0", "sass-loader": "^13.0.0 || ^14.0.0", "stylus": "^0.58.1", - "stylus-loader": "^7.0.0", + "stylus-loader": "^7.0.0 || ^8.1.0", "ts-loader": "^9.0.0", "typescript": "^4.2.2 || ^5.0.0", "vue": "^2.6 || ^3.2.14", @@ -3188,6 +3119,9 @@ "@vue/babel-helper-vue-jsx-merge-props": { "optional": true }, + "@vue/babel-plugin-jsx": { + "optional": true + }, "@vue/babel-preset-jsx": { "optional": true }, @@ -3404,9 +3338,9 @@ } }, "node_modules/@types/eslint": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.0.tgz", - "integrity": "sha512-gi6WQJ7cHRgZxtkQEoyHMppPjq9Kxo5Tjn2prSKDSmZrCz8TZ3jSRCeTJm+WoM+oB0WG37bRqLzaaU3q7JypGg==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", "dev": true, "license": "MIT", "dependencies": { @@ -3414,17 +3348,6 @@ "@types/json-schema": "*" } }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", @@ -3477,9 +3400,9 @@ "license": "MIT" }, "node_modules/@types/http-proxy": { - "version": "1.17.14", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", - "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", + "version": "1.17.15", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", + "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3535,13 +3458,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.0.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.0.2.tgz", - "integrity": "sha512-yPL6DyFwY5PiMVEwymNeqUTKsDczQBJ/5T7W/46RwLU/VH+AA8aT5TZkvBviLKLbbm0hlfftEkGrNzfRk/fofQ==", + "version": "22.5.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz", + "integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~6.11.1" + "undici-types": "~6.19.2" } }, "node_modules/@types/node-forge": { @@ -3636,9 +3559,9 @@ } }, "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", "dev": true, "license": "MIT", "dependencies": { @@ -3653,14 +3576,14 @@ "license": "MIT" }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.0.0.tgz", - "integrity": "sha512-V0aa9Csx/ZWWv2IPgTfY7T4agYwJyILESu/PVqFtTFz9RIS823mAze+NbnBI8xiwdX3iqeQbcTYlvB04G9wyQw==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.4.0.tgz", + "integrity": "sha512-n2jFxLeY0JmKfUqy3P70rs6vdoPjHK8P/w+zJcV3fk0b0BwRXC/zxRTEnAsgYT7MwdQDt/ZEbtdzdVC+hcpF0A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.0.0", - "@typescript-eslint/visitor-keys": "8.0.0" + "@typescript-eslint/types": "8.4.0", + "@typescript-eslint/visitor-keys": "8.4.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3671,9 +3594,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.0.0.tgz", - "integrity": "sha512-wgdSGs9BTMWQ7ooeHtu5quddKKs5Z5dS+fHLbrQI+ID0XWJLODGMHRfhwImiHoeO2S5Wir2yXuadJN6/l4JRxw==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.4.0.tgz", + "integrity": "sha512-T1RB3KQdskh9t3v/qv7niK6P8yvn7ja1mS7QK7XfRVL6wtZ8/mFs/FHf4fKvTA0rKnqnYxl/uHFNbnEt0phgbw==", "dev": true, "license": "MIT", "engines": { @@ -3685,16 +3608,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.0.0.tgz", - "integrity": "sha512-5b97WpKMX+Y43YKi4zVcCVLtK5F98dFls3Oxui8LbnmRsseKenbbDinmvxrWegKDMmlkIq/XHuyy0UGLtpCDKg==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.4.0.tgz", + "integrity": "sha512-kJ2OIP4dQw5gdI4uXsaxUZHRwWAGpREJ9Zq6D5L0BweyOrWsL6Sz0YcAZGWhvKnH7fm1J5YFE1JrQL0c9dd53A==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "8.0.0", - "@typescript-eslint/visitor-keys": "8.0.0", + "@typescript-eslint/types": "8.4.0", + "@typescript-eslint/visitor-keys": "8.4.0", "debug": "^4.3.4", - "globby": "^11.1.0", + "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", @@ -3727,16 +3650,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.0.0.tgz", - "integrity": "sha512-k/oS/A/3QeGLRvOWCg6/9rATJL5rec7/5s1YmdS0ZU6LHveJyGFwBvLhSRBv6i9xaj7etmosp+l+ViN1I9Aj/Q==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.4.0.tgz", + "integrity": "sha512-swULW8n1IKLjRAgciCkTCafyTHHfwVQFt8DovmaF69sKbOxTSFMmIZaSHjqO9i/RV0wIblaawhzvtva8Nmm7lQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.0.0", - "@typescript-eslint/types": "8.0.0", - "@typescript-eslint/typescript-estree": "8.0.0" + "@typescript-eslint/scope-manager": "8.4.0", + "@typescript-eslint/types": "8.4.0", + "@typescript-eslint/typescript-estree": "8.4.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3750,13 +3673,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.0.0.tgz", - "integrity": "sha512-oN0K4nkHuOyF3PVMyETbpP5zp6wfyOvm7tWhTMfoqxSSsPmJIh6JNASuZDlODE8eE+0EB9uar+6+vxr9DBTYOA==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.4.0.tgz", + "integrity": "sha512-zTQD6WLNTre1hj5wp09nBIDiOc2U5r/qmzo7wxPn4ZgAjHql09EofqhF9WF+fZHzL5aCyaIpPcT2hyxl73kr9A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.0.0", + "@typescript-eslint/types": "8.4.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -4310,13 +4233,16 @@ "license": "MIT" }, "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", "dev": true, "license": "MIT", + "dependencies": { + "array-uniq": "^1.0.1" + }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, "node_modules/array-uniq": { @@ -4449,14 +4375,14 @@ } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", - "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.1", - "core-js-compat": "^3.36.1" + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -4606,9 +4532,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", - "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", + "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", "dev": true, "funding": [ { @@ -4626,9 +4552,9 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001640", - "electron-to-chromium": "^1.4.820", - "node-releases": "^2.0.14", + "caniuse-lite": "^1.0.30001646", + "electron-to-chromium": "^1.5.4", + "node-releases": "^2.0.18", "update-browserslist-db": "^1.1.0" }, "bin": { @@ -4723,9 +4649,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001646", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001646.tgz", - "integrity": "sha512-dRg00gudiBDDTmUhClSdv3hqRfpbOnU28IpI1T6PBTLWa+kOj0681C8uML3PifYfREuBrVjDGhL3adYpBT6spw==", + "version": "1.0.30001658", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001658.tgz", + "integrity": "sha512-N2YVqWbJELVdrnsW5p+apoQyYt51aBMSsBZki1XZEfeBCexcM/sf4xiAHcXQBkuOwJBXtWF7aW1sYX6tKebPHw==", "dev": true, "funding": [ { @@ -5078,9 +5004,9 @@ "license": "MIT" }, "node_modules/core-js": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz", - "integrity": "sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==", + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.38.1.tgz", + "integrity": "sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -5090,13 +5016,13 @@ } }, "node_modules/core-js-compat": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", - "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz", + "integrity": "sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==", "dev": true, "license": "MIT", "dependencies": { - "browserslist": "^4.23.0" + "browserslist": "^4.23.3" }, "funding": { "type": "opencollective", @@ -5479,13 +5405,13 @@ "license": "CC0-1.0" }, "node_modules/debug": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", - "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -5574,46 +5500,6 @@ "node": ">=6" } }, - "node_modules/del/node_modules/array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-uniq": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/del/node_modules/globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/del/node_modules/globby/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -5642,19 +5528,6 @@ "dev": true, "license": "MIT" }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/dns-packet": { "version": "5.6.1", "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", @@ -5758,9 +5631,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.4.tgz", - "integrity": "sha512-orzA81VqLyIGUEA77YkVA1D+N+nNfl2isJVjjmOyrlxuooZ19ynb+dOlaDTqd/idKRS9lDCSBmtzM+kyCsMnkA==", + "version": "1.5.18", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.18.tgz", + "integrity": "sha512-1OfuVACu+zKlmjsNdcJuVQuVE61sZOLbNM4JAQ1Rvh6EOj0/EUKhMJjRH73InPlXSh8HIJk1cVZ8pyOV/FMdUQ==", "dev": true, "license": "ISC" }, @@ -5909,9 +5782,9 @@ } }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "license": "MIT", "engines": { @@ -6402,14 +6275,11 @@ "license": "MIT" }, "node_modules/fast-levenshtein": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz", - "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true, - "license": "MIT", - "dependencies": { - "fastest-levenshtein": "^1.0.7" - } + "license": "MIT" }, "node_modules/fast-uri": { "version": "3.0.1", @@ -6618,9 +6488,9 @@ "license": "ISC" }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "dev": true, "funding": [ { @@ -6845,24 +6715,30 @@ } }, "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", "dev": true, "license": "MIT", "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.10.0" + } + }, + "node_modules/globby/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, "node_modules/gopd": { @@ -7170,9 +7046,9 @@ } }, "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", "engines": { @@ -7355,9 +7231,9 @@ } }, "node_modules/is-core-module": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", - "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", "dev": true, "license": "MIT", "dependencies": { @@ -7806,9 +7682,9 @@ } }, "node_modules/launch-editor": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.0.tgz", - "integrity": "sha512-vJranOAJrI/llyWGRQqiDM+adrw+k83fvmmx3+nV47g3+36xM15jE+zyZ6Ffel02+xSvuM0b2GDRosXZkbb6wA==", + "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, "license": "MIT", "dependencies": { @@ -8016,9 +7892,9 @@ } }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", "dependencies": { @@ -8089,9 +7965,9 @@ } }, "node_modules/mini-css-extract-plugin": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.0.tgz", - "integrity": "sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.1.tgz", + "integrity": "sha512-+Vyi+GCCOHnrJ2VPS+6aPoXN2k2jgUzDRhTFLjjTBn23qyXJXkjUWQgTL+mXpF5/A8ixLdCc6kWsoeOjKGejKQ==", "dev": true, "license": "MIT", "dependencies": { @@ -8207,9 +8083,9 @@ "license": "MIT" }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true, "license": "MIT" }, @@ -8487,13 +8363,6 @@ "node": ">= 0.8.0" } }, - "node_modules/optionator/node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "license": "MIT" - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -8634,16 +8503,6 @@ "dev": true, "license": "MIT" }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/pathe": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", @@ -8664,9 +8523,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", "dev": true, "license": "ISC" }, @@ -8820,89 +8679,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-up/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-up/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/postcss": { - "version": "8.4.40", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.40.tgz", - "integrity": "sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==", + "version": "8.4.45", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.45.tgz", + "integrity": "sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==", "dev": true, "funding": [ { @@ -9393,9 +9173,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz", - "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", "dev": true, "license": "MIT", "dependencies": { @@ -9878,9 +9658,9 @@ } }, "node_modules/rollup": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.19.2.tgz", - "integrity": "sha512-6/jgnN1svF9PjNYJ4ya3l+cqutg49vOZ4rVgsDKxdl+5gpGPnByFXWGyfH9YGx9i3nfBwSu1Iyu6vGwFFA0BdQ==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.2.tgz", + "integrity": "sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==", "dev": true, "license": "MIT", "peer": true, @@ -9895,22 +9675,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.19.2", - "@rollup/rollup-android-arm64": "4.19.2", - "@rollup/rollup-darwin-arm64": "4.19.2", - "@rollup/rollup-darwin-x64": "4.19.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.19.2", - "@rollup/rollup-linux-arm-musleabihf": "4.19.2", - "@rollup/rollup-linux-arm64-gnu": "4.19.2", - "@rollup/rollup-linux-arm64-musl": "4.19.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.19.2", - "@rollup/rollup-linux-riscv64-gnu": "4.19.2", - "@rollup/rollup-linux-s390x-gnu": "4.19.2", - "@rollup/rollup-linux-x64-gnu": "4.19.2", - "@rollup/rollup-linux-x64-musl": "4.19.2", - "@rollup/rollup-win32-arm64-msvc": "4.19.2", - "@rollup/rollup-win32-ia32-msvc": "4.19.2", - "@rollup/rollup-win32-x64-msvc": "4.19.2", + "@rollup/rollup-android-arm-eabi": "4.21.2", + "@rollup/rollup-android-arm64": "4.21.2", + "@rollup/rollup-darwin-arm64": "4.21.2", + "@rollup/rollup-darwin-x64": "4.21.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.21.2", + "@rollup/rollup-linux-arm-musleabihf": "4.21.2", + "@rollup/rollup-linux-arm64-gnu": "4.21.2", + "@rollup/rollup-linux-arm64-musl": "4.21.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.21.2", + "@rollup/rollup-linux-riscv64-gnu": "4.21.2", + "@rollup/rollup-linux-s390x-gnu": "4.21.2", + "@rollup/rollup-linux-x64-gnu": "4.21.2", + "@rollup/rollup-linux-x64-musl": "4.21.2", + "@rollup/rollup-win32-arm64-msvc": "4.21.2", + "@rollup/rollup-win32-ia32-msvc": "4.21.2", + "@rollup/rollup-win32-x64-msvc": "4.21.2", "fsevents": "~2.3.2" } }, @@ -9967,9 +9747,9 @@ "license": "MIT" }, "node_modules/sass": { - "version": "1.77.8", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.8.tgz", - "integrity": "sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==", + "version": "1.78.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.78.0.tgz", + "integrity": "sha512-AaIqGSrjo5lA2Yg7RvFZrlXDBCp3nV4XP73GrLGvdRWWwk+8H3l0SDvq/5bA4eF+0RFPLuWUk3E+P1U/YqnpsQ==", "dev": true, "license": "MIT", "dependencies": { @@ -10117,13 +9897,6 @@ "dev": true, "license": "MIT" }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, "node_modules/serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", @@ -10359,16 +10132,6 @@ "url": "https://opencollective.com/simple-icons" } }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -10742,9 +10505,9 @@ } }, "node_modules/terser": { - "version": "5.31.3", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.3.tgz", - "integrity": "sha512-pAfYn3NIZLyZpa83ZKigvj6Rn9c/vd5KfYGX7cN1mnzqgDcxWvrU5ZtAfIKhEXz9nRecw4z3LXkjaq96/qZqAA==", + "version": "5.31.6", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", + "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -10865,17 +10628,17 @@ "license": "MIT" }, "node_modules/tinybench": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", - "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", "dev": true, "license": "MIT", "peer": true }, "node_modules/tinypool": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.0.tgz", - "integrity": "sha512-KIKExllK7jp3uvrNtvRBYBWBOAXSX8ZvoaD8T+7KB/QHIuoJW3Pmr60zucywjAlMb5TeXUkcs/MWeWLu0qvuAQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.1.tgz", + "integrity": "sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==", "dev": true, "license": "MIT", "peer": true, @@ -11042,9 +10805,9 @@ } }, "node_modules/undici-types": { - "version": "6.11.1", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.11.1.tgz", - "integrity": "sha512-mIDEX2ek50x0OlRgxryxsenE5XaQD4on5U2inY7RApK3SOJpofyw7uW2AyfMKkhAxXIceo2DeWGVGwyvng1GNQ==", + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "dev": true, "license": "MIT" }, @@ -11188,16 +10951,16 @@ } }, "node_modules/vite": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.5.tgz", - "integrity": "sha512-MdjglKR6AQXQb9JGiS7Rc2wC6uMjcm7Go/NHNO63EwiJXfuk9PgqiP/n5IDJCziMkfw9n4Ubp7lttNwz+8ZVKA==", + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.3.tgz", + "integrity": "sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==", "dev": true, "license": "MIT", "peer": true, "dependencies": { "esbuild": "^0.21.3", - "postcss": "^8.4.39", - "rollup": "^4.13.0" + "postcss": "^8.4.43", + "rollup": "^4.20.0" }, "bin": { "vite": "bin/vite.js" @@ -11216,6 +10979,7 @@ "less": "*", "lightningcss": "^1.21.0", "sass": "*", + "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" @@ -11233,6 +10997,9 @@ "sass": { "optional": true }, + "sass-embedded": { + "optional": true + }, "stylus": { "optional": true }, @@ -11518,9 +11285,9 @@ } }, "node_modules/watchpack": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", - "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", "dev": true, "license": "MIT", "dependencies": { @@ -11549,13 +11316,12 @@ "license": "BSD-2-Clause" }, "node_modules/webpack": { - "version": "5.93.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz", - "integrity": "sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==", + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", "dev": true, "license": "MIT", "dependencies": { - "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", "@webassemblyjs/ast": "^1.12.1", "@webassemblyjs/wasm-edit": "^1.12.1", @@ -11564,7 +11330,7 @@ "acorn-import-attributes": "^1.9.5", "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.0", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", From 9755508061a615baeb6c17c2803177755c8317d0 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Sun, 8 Sep 2024 13:07:08 +0200 Subject: [PATCH 245/335] Improve anti-spam config a little (#1091) --- config/packages/antispam.yaml | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/config/packages/antispam.yaml b/config/packages/antispam.yaml index f7d8855a7..c80704be8 100644 --- a/config/packages/antispam.yaml +++ b/config/packages/antispam.yaml @@ -12,16 +12,15 @@ antispam: profiles: default: stealth: false - - # Insert a honeypot called "email_address" on all forms to lure bots into filling it in - honeypot: email_address - # Reject all forms that have been submitted either within 3 seconds, or after more than an hour + # Insert a honeypot called "full_name" on all forms to lure bots into filling it in + honeypot: full_name + + # Reject all forms that have been submitted either within 6 seconds, or after more than 30 minutes timer: - min: 3 - max: 3600 + min: 6 + max: 1800 - # # The measures above should already have notable effect on the amount of spam that gets through # your forms. Still getting annoying amounts? Analyze the patterns of uncaught spam, then # consider uncommenting and modifying some of the examples below after careful consideration @@ -29,17 +28,17 @@ antispam: # # Reject text fields that contain (lame attempts at) HTML or BBCode -# banned_markup: true + banned_markup: true # Reject text fields that consist for more than 40% of Cyrillic (Russian) characters -# banned_scripts: -# scripts: [ cyrillic ] -# max_percentage: 40 + # banned_scripts: + # scripts: [ cyrillic ] + # max_percentage: 40 # Reject fields that contain more than 3 URLs, or repeat a single URL more than once -# url_count: -# max: 3 -# max_identical: 1 + # url_count: + # max: 3 + # max_identical: 1 when@test: antispam: From 891e1c00e4250c8565658a87a92bbbd03984c33d Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Sun, 8 Sep 2024 16:37:39 +0200 Subject: [PATCH 246/335] Remove dead kbin.run link in README (#1096) --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 3eaef62eb..7c1b09588 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,6 @@ For developers: - [Official repository on GitHub](https://github.com/MbinOrg/mbin) - [Matrix Space for discussions](https://matrix.to/#/#mbin:melroy.org) -- [Unofficial magazine for discussions within the fediverse](https://kbin.run/m/Mdev) - [Translations](https://hosted.weblate.org/engage/mbin/) - [Contribution guidelines](CONTRIBUTING.md) - please read first, including before opening an issue! From 2eefb0d90f4d06d3a8c77255d69f51be2713220a Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Sun, 8 Sep 2024 17:54:07 +0200 Subject: [PATCH 247/335] Preparing for new release: remove rc5 label (#1093) --- config/packages/framework.yaml | 10 ++++++++-- src/Service/ProjectInfoService.php | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml index 067dc3f2a..91ee2939b 100644 --- a/config/packages/framework.yaml +++ b/config/packages/framework.yaml @@ -5,7 +5,13 @@ framework: http_method_override: false handle_all_throwables: true trusted_proxies: '%env(string:default::TRUSTED_PROXIES)%' - trusted_headers: ['x-forwarded-for', 'x-forwarded-proto', 'x-forwarded-port', 'x-forwarded-prefix'] + trusted_headers: + [ + 'x-forwarded-for', + 'x-forwarded-proto', + 'x-forwarded-port', + 'x-forwarded-prefix', + ] # Enables session support. Note that the session will ONLY be started if you read or write from it. # Remove or comment this section to explicitly disable session support. @@ -19,7 +25,7 @@ framework: http_client: default_options: headers: - 'User-Agent': 'Mbin/1.7.1-rc5 (+https://%kbin_domain%/agent)' + 'User-Agent': 'Mbin/1.7.1 (+https://%kbin_domain%/agent)' #esi: true #fragments: true diff --git a/src/Service/ProjectInfoService.php b/src/Service/ProjectInfoService.php index 5ca786b85..e27ce0192 100644 --- a/src/Service/ProjectInfoService.php +++ b/src/Service/ProjectInfoService.php @@ -10,7 +10,7 @@ class ProjectInfoService { // If updating version, please also update http client UA in [/config/packages/framework.yaml] - private const VERSION = '1.7.1-rc5'; // TODO: Retrieve the version from git tags or getenv()? + private const VERSION = '1.7.1'; // TODO: Retrieve the version from git tags or getenv()? private const NAME = 'mbin'; private const CANONICAL_NAME = 'Mbin'; private const REPOSITORY_URL = 'https://github.com/MbinOrg/mbin'; From 0f9604e2a042a37bffa83be2185c833495414295 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Sun, 8 Sep 2024 18:26:06 +0200 Subject: [PATCH 248/335] Add unofficial magazines (#1097) --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 7c1b09588..48a6693ab 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,14 @@ For developers: - [Translations](https://hosted.weblate.org/engage/mbin/) - [Contribution guidelines](CONTRIBUTING.md) - please read first, including before opening an issue! +## Magazines + +Unofficial magazines: + +- [@mbinmeta@gehirneimer.de](https://gehirneimer.de/m/mbinmeta) +- [@updates@kbin.melroy.org](https://kbin.melroy.org/m/updates) +- [@AskMbin@fedia.io](https://fedia.io/m/AskMbin) + ## Contributors From 2069352e6ed8d75eb654440941020bc2ef51a32c Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Mon, 9 Sep 2024 20:18:16 +0200 Subject: [PATCH 249/335] Translations update from Hosted Weblate (#1099) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Λευτέρης Τ --- translations/messages.el.yaml | 61 +++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/translations/messages.el.yaml b/translations/messages.el.yaml index e03d51cc0..9267acca1 100644 --- a/translations/messages.el.yaml +++ b/translations/messages.el.yaml @@ -508,3 +508,64 @@ oauth.client_not_granted_message_read_permission: Αυτή η εφαρμογή restrict_oauth_clients: Περιορισμός δημιουργίας Πελάτη OAuth2 για τους Διαχειριστές private_instance: Υποχρέωσε τους χρήστες να συνδεθούν πριν μπορούν να έχουν πρόσβαση σε περιεχόμενο +oauth2.grant.entry.vote: Ψήφισε θετικά ή αρνητικά, ενίσχυσε οποιοδήποτε νήμα. +oauth2.grant.entry.report: Ανέφερε οποιοδήποτε νήμα. +oauth2.grant.entry_comment.create: Δημιούργησε νέα σχόλια σε νήματα. +oauth2.grant.domain.block: Απέκλεισε τομείς ή αίρε τον αποκλεισμό και δες τους τομείς + που έχεις αποκλείσει. +oauth2.grant.subscribe.general: Κάνε εγγραφή ή ακολούθησε οποιοδήποτε περιοδικό, τομέα + ή χρήστη και δες τα περιοδικά, τους τομείς και τους χρήστες που εγγράφεσαι. +oauth2.grant.moderate.magazine.reports.all: Διαχειρίσου αναφορές στα περιοδικά που + συντονίζεις. +oauth2.grant.domain.all: Εγγράψου σε τομείς ή απέκλεισέ τους και δες τους τομείς στους + οποίους έχεις εγγραφεί ή αποκλείσει. +oauth2.grant.domain.subscribe: Εγγράψου ή κάνε απεγγραφή σε τομείς και δες τους τομείς + στους οποίους έχεις εγγραφεί. +oauth2.grant.entry.edit: Επεξεργάσου τα υπάρχοντα σου νήματα. +oauth2.grant.moderate.magazine_admin.stats: Δες το περιεχόμενο, τις ψήφους και τα + στατιστικά προβολής των ιδιόκτητων περιοδικών σου. +oauth2.grant.entry_comment.edit: Επεξεργάσου τα υπάρχοντα σχόλιά σου σε νήματα. +oauth2.grant.moderate.magazine_admin.delete: Διέγραψε κάποιο απ' τα ιδιότητα περιοδικά + σου. +oauth2.grant.moderate.magazine.trash.read: Προβολή περιεχομένου απορριμάτων στα περιοδικά + που συντονίζεις. +oauth2.grant.moderate.magazine_admin.edit_theme: Επεξεργάσου την προσαρμοσμένη CSS + οποιωνδήποτε από τα ιδιόκτητα περιοδικά σου. +oauth2.grant.moderate.magazine_admin.moderators: Πρόσθεσε ή αφαίρεσε συντονιστές από + οποιοδήποτε από τα ιδιόκτητα περιοδικά σου. +oauth2.grant.entry_comment.delete: Διέγραψε τα υπάρχοντα σχόλιά σου σε νήματα. +oauth2.grant.entry.create: Δημιούργησε νέα νήματα. +unblock: Άρση αποκλεισμού +oauth2.grant.moderate.magazine.ban.delete: Άρση αποκλεισμού χρηστών σε περιοδικά που + συντονίζεις. +oauth2.grant.moderate.magazine.list: Διάβασε μια λίστα με τα περιοδικά που συντονίζεις. +oauth2.grant.moderate.magazine.reports.read: Διάβασε αναφορές στα περιοδικά που συντονίζεις. +oauth2.grant.moderate.magazine.reports.action: Αποδέξου ή απέρριψε αναφορές στα περιοδικά + που συντονίζεις. +oauth2.grant.moderate.magazine_admin.create: Δημιούργησε νέα περιοδικά. +oauth2.grant.moderate.magazine_admin.update: Επεξεργάσου οποιονδήποτε από τους κανόνες, + την περιγραφή, τη κατάσταση NSFW ή το εικονίδιο των ιδιόκτητων περιοδικών σου. +oauth2.grant.moderate.magazine_admin.all: Δημιούργησε, επεξεργάσου ή διέγραψε τα ιδιόκτητα + περιοδικά σου. +oauth2.grant.moderate.magazine_admin.badges: Δημιούργησε ή αφαίρεσε τα σήματα από + τα ιδιόκτητα περιοδικά σου. +oauth2.grant.moderate.magazine_admin.tags: Δημιούργησε ή αφαίρεσε ετικέτες από τα + ιδιόκτητα περιοδικά σου. +oauth2.grant.admin.all: Εκτέλεσε οποιαδήποτε ενέργεια διαχειριστή στην οντότητά σου. +oauth2.grant.admin.entry.purge: Διέγραψε πλήρως οποιοδήποτε νήμα από την οντότητά + σου. +oauth2.grant.read.general: Διάβασε όλο το περιεχόμενο στο οποίο έχεις πρόσβαση. +oauth2.grant.write.general: Δημιούργησε ή επεξεργάσου οποιοδήποτε από τα νήματα, αναρτήσεις + ή σχόλια σου. +oauth2.grant.delete.general: Διάγραψε οποιοδήποτε από τα νήματα, αναρτήσεις ή σχόλια + σου. +oauth2.grant.report.general: Ανάφερε νήματα, αναρτήσεις ή σχόλια. +oauth2.grant.vote.general: Δώσε θετική, αρνητική ψήφο ή ενίσχυσε νήματα, αναρτήσεις + ή σχόλια. +oauth2.grant.block.general: Απέκλεισε ή αίρε τον αποκλεισμό οποιουδήποτε περιοδικού, + τομέα ή χρήστη και δες τα περιοδικά, τους τομείς και τους χρήστες που έχεις αποκλείσει. +oauth2.grant.entry.all: Δημιούργησε, επεξεργάσου ή διάγραψε τα νήματα σου και ψήφισε, + ενίσχυσε ή ανέφερε οποιοδήποτε νήμα. +oauth2.grant.entry.delete: Διάγραψε τα υπάρχοντα σου νήματα. +oauth2.grant.entry_comment.all: Δημιούργησε, επεξεργάσου ή διάγραψε τα σχόλιά σου + σε νήματα και ψήφισε, ενίσχυσε ή ανέφερε οποιοδήποτε σχόλιο σε ένα νήμα. From 26bc1c8cc8f5c091c3b0f136dd9bae87614d0ac3 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Mon, 9 Sep 2024 20:19:53 +0200 Subject: [PATCH 250/335] Fix update actor failing because of a serializer error (#1098) --- src/Service/RemoteInstanceManager.php | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/Service/RemoteInstanceManager.php b/src/Service/RemoteInstanceManager.php index 354a819dc..b7f0f353c 100644 --- a/src/Service/RemoteInstanceManager.php +++ b/src/Service/RemoteInstanceManager.php @@ -57,11 +57,18 @@ public function updateInstance(Instance $instance, bool $force = false): bool $nodeInfoRaw = $this->client->fetchInstanceNodeInfo($linkToUse->href, false); $this->logger->debug('got raw nodeinfo for url {url}: {raw}', ['raw' => $nodeInfoRaw, 'url' => $linkToUse]); - /** @var NodeInfo $nodeInfo */ - $nodeInfo = $serializer->deserialize($nodeInfoRaw, NodeInfo::class, 'json'); - - $instance->software = $nodeInfo?->software?->name; - $instance->version = $nodeInfo?->software?->version; + try { + /** @var NodeInfo $nodeInfo */ + $nodeInfo = $serializer->deserialize($nodeInfoRaw, NodeInfo::class, 'json'); + $instance->software = $nodeInfo?->software?->name; + $instance->version = $nodeInfo?->software?->version; + } catch (\Error|\Exception $e) { + $this->logger->warning('There as an exception decoding the nodeinfo from {url}: {e} - {m}', [ + 'url' => $instance->domain, + 'e' => \get_class($e), + 'm' => $e->getMessage(), + ]); + } $instance->setUpdatedAt(); $this->entityManager->persist($instance); From 76dbd6976e225f5031b3013bf309e568e3ef493e Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Mon, 9 Sep 2024 22:20:09 +0200 Subject: [PATCH 251/335] Check whether the author is blocked before notifying (#1100) --- .../MagazineSubscriptionRepository.php | 8 +++- .../EntryCommentNotificationManager.php | 18 ++++---- .../Notification/EntryNotificationManager.php | 31 ++++++++----- .../Notification/NotificationTrait.php | 8 ++++ .../PostCommentNotificationManager.php | 19 ++++---- .../Notification/PostNotificationManager.php | 43 +++++++++++-------- 6 files changed, 77 insertions(+), 50 deletions(-) diff --git a/src/Repository/MagazineSubscriptionRepository.php b/src/Repository/MagazineSubscriptionRepository.php index b34436567..0e9064110 100644 --- a/src/Repository/MagazineSubscriptionRepository.php +++ b/src/Repository/MagazineSubscriptionRepository.php @@ -31,6 +31,9 @@ public function __construct(ManagerRegistry $registry) parent::__construct($registry, MagazineSubscription::class); } + /** + * @return MagazineSubscription[] + */ public function findNewEntrySubscribers(Entry $entry): array { return $this->createQueryBuilder('ms') @@ -46,7 +49,10 @@ public function findNewEntrySubscribers(Entry $entry): array ->getResult(); } - public function findNewPostSubscribers(Post $post) + /** + * @return MagazineSubscription[] + */ + public function findNewPostSubscribers(Post $post): array { return $this->createQueryBuilder('ms') ->addSelect('u') diff --git a/src/Service/Notification/EntryCommentNotificationManager.php b/src/Service/Notification/EntryCommentNotificationManager.php index 017e71321..55ca0b736 100644 --- a/src/Service/Notification/EntryCommentNotificationManager.php +++ b/src/Service/Notification/EntryCommentNotificationManager.php @@ -59,10 +59,10 @@ public function sendCreated(ContentInterface $subject): void if ($subject->user->isBanned || $subject->user->isDeleted || $subject->user->isTrashed() || $subject->user->isSoftDeleted()) { return; } + if (!$subject instanceof EntryComment) { + throw new \LogicException(); + } - /** - * @var EntryComment $subject - */ $users = $this->sendMentionedNotification($subject); $users = $this->sendUserReplyNotification($subject, $users); $this->sendMagazineSubscribersNotification($subject, $users); @@ -223,17 +223,17 @@ private function notifyMagazine(Notification $notification): void public function sendEdited(ContentInterface $subject): void { - /* - * @var EntryComment $subject - */ + if (!$subject instanceof EntryComment) { + throw new \LogicException(); + } $this->notifyMagazine(new EntryCommentEditedNotification($subject->user, $subject)); } public function sendDeleted(ContentInterface $subject): void { - /* - * @var EntryComment $subject - */ + if (!$subject instanceof EntryComment) { + throw new \LogicException(); + } $this->notifyMagazine($notification = new EntryCommentDeletedNotification($subject->user, $subject)); } diff --git a/src/Service/Notification/EntryNotificationManager.php b/src/Service/Notification/EntryNotificationManager.php index 722aa8adc..a7f97bb24 100644 --- a/src/Service/Notification/EntryNotificationManager.php +++ b/src/Service/Notification/EntryNotificationManager.php @@ -12,6 +12,7 @@ use App\Entity\EntryMentionedNotification; use App\Entity\Magazine; use App\Entity\Notification; +use App\Entity\User; use App\Event\NotificationCreatedEvent; use App\Factory\MagazineFactory; use App\Repository\MagazineLogRepository; @@ -22,6 +23,7 @@ use App\Service\ImageManager; use App\Service\MentionManager; use App\Service\SettingsManager; +use App\Service\UserManager; use App\Utils\IriGenerator; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; @@ -47,17 +49,21 @@ public function __construct( private readonly EntityManagerInterface $entityManager, private readonly ImageManager $imageManager, private readonly GenerateHtmlClassService $classService, + private readonly UserManager $userManager, private readonly SettingsManager $settingsManager ) { } - // @todo check if author is on the block list public function sendCreated(ContentInterface $subject): void { if ($subject->user->isBanned || $subject->user->isDeleted || $subject->user->isTrashed() || $subject->user->isSoftDeleted()) { return; } + if (!$subject instanceof Entry) { + throw new \LogicException(); + } + /* * @var Entry $subject */ @@ -66,7 +72,7 @@ public function sendCreated(ContentInterface $subject): void // Notify mentioned $mentions = MentionManager::clearLocal($this->mentionManager->extract($subject->body)); foreach ($this->mentionManager->getUsersFromArray($mentions) as $user) { - if (!$user->apId) { + if (!$user->apId && !$user->isBlocked($subject->user)) { $notification = new EntryMentionedNotification($user, $subject); $this->entityManager->persist($notification); $this->eventDispatcher->dispatch(new NotificationCreatedEvent($notification)); @@ -74,6 +80,7 @@ public function sendCreated(ContentInterface $subject): void } // Notify subscribers + /** @var User[] $subscribers */ $subscribers = $this->merge( $this->getUsersToNotify($this->magazineRepository->findNewEntrySubscribers($subject)), [] // @todo user followers @@ -82,9 +89,11 @@ public function sendCreated(ContentInterface $subject): void $subscribers = array_filter($subscribers, fn ($s) => !\in_array($s->username, $mentions ?? [])); foreach ($subscribers as $subscriber) { - $notification = new EntryCreatedNotification($subscriber, $subject); - $this->entityManager->persist($notification); - $this->eventDispatcher->dispatch(new NotificationCreatedEvent($notification)); + if (!$subscriber->isBlocked($subject->user)) { + $notification = new EntryCreatedNotification($subscriber, $subject); + $this->entityManager->persist($notification); + $this->eventDispatcher->dispatch(new NotificationCreatedEvent($notification)); + } } $this->entityManager->flush(); @@ -144,17 +153,17 @@ private function getResponse(Notification $notification): string public function sendEdited(ContentInterface $subject): void { - /* - * @var Entry $subject - */ + if (!$subject instanceof Entry) { + throw new \LogicException(); + } $this->notifyMagazine(new EntryEditedNotification($subject->user, $subject)); } public function sendDeleted(ContentInterface $subject): void { - /* - * @var Entry $subject - */ + if (!$subject instanceof Entry) { + throw new \LogicException(); + } $this->notifyMagazine($notification = new EntryDeletedNotification($subject->user, $subject)); } diff --git a/src/Service/Notification/NotificationTrait.php b/src/Service/Notification/NotificationTrait.php index 4ccfebc46..33347f9bd 100644 --- a/src/Service/Notification/NotificationTrait.php +++ b/src/Service/Notification/NotificationTrait.php @@ -4,8 +4,16 @@ namespace App\Service\Notification; +use App\Entity\MagazineSubscription; +use App\Entity\User; + trait NotificationTrait { + /** + * @param MagazineSubscription[] $subscriptions + * + * @return User[] + */ private function getUsersToNotify(array $subscriptions): array { return array_map(fn ($sub) => $sub->user, $subscriptions); diff --git a/src/Service/Notification/PostCommentNotificationManager.php b/src/Service/Notification/PostCommentNotificationManager.php index 25b2674b8..d7a8241a1 100644 --- a/src/Service/Notification/PostCommentNotificationManager.php +++ b/src/Service/Notification/PostCommentNotificationManager.php @@ -53,16 +53,15 @@ public function __construct( ) { } - // @todo check if author is on the block list public function sendCreated(ContentInterface $subject): void { if ($subject->user->isBanned || $subject->user->isDeleted || $subject->user->isTrashed() || $subject->user->isSoftDeleted()) { return; } + if (!$subject instanceof PostComment) { + throw new \LogicException(); + } - /** - * @var PostComment $subject - */ $users = $this->sendMentionedNotification($subject); $users = $this->sendUserReplyNotification($subject, $users); $this->sendMagazineSubscribersNotification($subject, $users); @@ -222,17 +221,17 @@ private function notifyMagazine(Notification $notification): void public function sendEdited(ContentInterface $subject): void { - /* - * @var PostComment $subject - */ + if (!$subject instanceof PostComment) { + throw new \LogicException(); + } $this->notifyMagazine(new PostCommentEditedNotification($subject->user, $subject)); } public function sendDeleted(ContentInterface $subject): void { - /* - * @var PostComment $subject - */ + if (!$subject instanceof PostComment) { + throw new \LogicException(); + } $this->notifyMagazine($notification = new PostCommentDeletedNotification($subject->user, $subject)); } diff --git a/src/Service/Notification/PostNotificationManager.php b/src/Service/Notification/PostNotificationManager.php index 7661adebe..662e569c3 100644 --- a/src/Service/Notification/PostNotificationManager.php +++ b/src/Service/Notification/PostNotificationManager.php @@ -11,6 +11,7 @@ use App\Entity\PostDeletedNotification; use App\Entity\PostEditedNotification; use App\Entity\PostMentionedNotification; +use App\Entity\User; use App\Event\NotificationCreatedEvent; use App\Factory\MagazineFactory; use App\Repository\MagazineLogRepository; @@ -50,27 +51,29 @@ public function __construct( ) { } - // @todo check if author is on the block list public function sendCreated(ContentInterface $subject): void { if ($subject->user->isBanned || $subject->user->isDeleted || $subject->user->isTrashed() || $subject->user->isSoftDeleted()) { return; } + if (!$subject instanceof Post) { + throw new \LogicException(); + } - /* - * @var Post $subject - */ $this->notifyMagazine(new PostCreatedNotification($subject->user, $subject)); // Notify mentioned $mentions = MentionManager::clearLocal($this->mentionManager->extract($subject->body)); foreach ($this->mentionManager->getUsersFromArray($mentions) as $user) { - $notification = new PostMentionedNotification($user, $subject); - $this->entityManager->persist($notification); - $this->eventDispatcher->dispatch(new NotificationCreatedEvent($notification)); + if (!$user->isBlocked($subject->user)) { + $notification = new PostMentionedNotification($user, $subject); + $this->entityManager->persist($notification); + $this->eventDispatcher->dispatch(new NotificationCreatedEvent($notification)); + } } // Notify subscribers + /** @var User[] $subscribers */ $subscribers = $this->merge( $this->getUsersToNotify($this->magazineRepository->findNewPostSubscribers($subject)), [] // @todo user followers @@ -79,15 +82,17 @@ public function sendCreated(ContentInterface $subject): void $subscribers = array_filter($subscribers, fn ($s) => !\in_array($s->username, $mentions ?? [])); foreach ($subscribers as $subscriber) { - $notification2 = new PostCreatedNotification($subscriber, $subject); - $this->entityManager->persist($notification2); - $this->eventDispatcher->dispatch(new NotificationCreatedEvent($notification2)); + if (!$subscriber->isBlocked($subject->user)) { + $notification2 = new PostCreatedNotification($subscriber, $subject); + $this->entityManager->persist($notification2); + $this->eventDispatcher->dispatch(new NotificationCreatedEvent($notification2)); + } } $this->entityManager->flush(); } - private function notifyMagazine(Notification $notification) + private function notifyMagazine(Notification $notification): void { if (false === $this->settingsManager->get('KBIN_MERCURE_ENABLED')) { return; @@ -139,18 +144,18 @@ private function getResponse(Notification $notification): string public function sendEdited(ContentInterface $subject): void { - /* - * @var Post $subject - */ + if (!$subject instanceof Post) { + throw new \LogicException(); + } $this->notifyMagazine(new PostEditedNotification($subject->user, $subject)); } - public function sendDeleted(ContentInterface $post): void + public function sendDeleted(ContentInterface $subject): void { - /* - * @var Post $post - */ - $this->notifyMagazine($notification = new PostDeletedNotification($post->user, $post)); + if (!$subject instanceof Post) { + throw new \LogicException(); + } + $this->notifyMagazine($notification = new PostDeletedNotification($subject->user, $subject)); } public function purgeNotifications(Post $post): void From 511971b5231f8579d407ff2ede52257d9ad89cd2 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Mon, 9 Sep 2024 22:40:16 +0200 Subject: [PATCH 252/335] Implement downvote modes (#1022) Co-authored-by: Anthony Lawn Co-authored-by: Melroy van den Berg --- config/services.yaml | 4 ++ .../Entry/Comments/EntryCommentsVoteApi.php | 9 +++- src/Controller/Api/Entry/EntriesVoteApi.php | 9 +++- .../Instance/Admin/InstanceUpdatePagesApi.php | 6 ++- .../Api/Instance/InstanceDetailsApi.php | 6 ++- .../Api/Post/Comments/PostCommentsVoteApi.php | 8 +++- src/Controller/Api/Post/PostsVoteApi.php | 8 +++- .../Comment/EntryCommentVotersController.php | 19 ++++++-- .../Entry/EntryVotersController.php | 17 +++++-- src/Controller/VoteController.php | 12 ++++- src/DTO/SettingsDto.php | 5 +- src/DTO/SiteResponseDto.php | 5 +- src/EventSubscriber/VoteHandleSubscriber.php | 5 +- src/Form/SettingsType.php | 17 +++++++ .../ActivityPub/Inbox/DislikeHandler.php | 6 +++ src/Repository/EntryCommentRepository.php | 23 +++++---- src/Repository/ReputationRepository.php | 28 +++++++---- src/Repository/StatsVotesRepository.php | 48 ++++++++++++++++--- src/Service/SettingsManager.php | 12 ++++- src/Service/StatsManager.php | 6 ++- src/Service/VoteManager.php | 5 +- src/Twig/Extension/SettingsExtension.php | 1 + src/Twig/Runtime/SettingsExtensionRuntime.php | 6 +++ src/Utils/DownvotesMode.php | 21 ++++++++ templates/admin/settings.html.twig | 4 ++ templates/components/vote.html.twig | 10 +++- templates/entry/_options_activity.html.twig | 10 ++-- .../entry/comment/_options_activity.html.twig | 10 ++-- .../Admin/InstanceSettingsRetrieveApiTest.php | 1 + .../Admin/InstanceSettingsUpdateApiTest.php | 4 ++ translations/messages.en.yaml | 5 ++ 31 files changed, 273 insertions(+), 57 deletions(-) create mode 100644 src/Utils/DownvotesMode.php diff --git a/config/services.yaml b/config/services.yaml index f03437b71..021b2591b 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -110,6 +110,9 @@ parameters: max_image_bytes: "%env(int:default:max_image_bytes_default:MAX_IMAGE_BYTES)%" max_image_bytes_default: 6000000 + mbin_downvotes_mode_default: 'enabled' + mbin_downvotes_mode: '%env(enum:\App\Utils\DownvotesMode:default:mbin_downvotes_mode_default:MBIN_DOWNVOTES_MODE)%' + services: # default configuration for services in *this* file _defaults: @@ -178,6 +181,7 @@ services: $kbinAdminOnlyOauthClients: "%env(bool:KBIN_ADMIN_ONLY_OAUTH_CLIENTS)%" $mbinSsoOnlyMode: "%sso_only_mode%" $maxImageBytes: "%max_image_bytes%" + $mbinDownvotesMode: "%mbin_downvotes_mode%" # Markdown App\Markdown\Factory\EnvironmentFactory: diff --git a/src/Controller/Api/Entry/Comments/EntryCommentsVoteApi.php b/src/Controller/Api/Entry/Comments/EntryCommentsVoteApi.php index 63cac1e16..3dc6ae6cc 100644 --- a/src/Controller/Api/Entry/Comments/EntryCommentsVoteApi.php +++ b/src/Controller/Api/Entry/Comments/EntryCommentsVoteApi.php @@ -9,7 +9,9 @@ use App\Entity\Contracts\VotableInterface; use App\Entity\EntryComment; use App\Factory\EntryCommentFactory; +use App\Service\SettingsManager; use App\Service\VoteManager; +use App\Utils\DownvotesMode; use Nelmio\ApiDocBundle\Annotation\Model; use Nelmio\ApiDocBundle\Annotation\Security; use OpenApi\Attributes as OA; @@ -79,7 +81,8 @@ public function __invoke( int $choice, VoteManager $manager, EntryCommentFactory $factory, - RateLimiterFactory $apiVoteLimiter + RateLimiterFactory $apiVoteLimiter, + SettingsManager $settingsManager, ): JsonResponse { $headers = $this->rateLimit($apiVoteLimiter); @@ -87,6 +90,10 @@ public function __invoke( throw new BadRequestHttpException('Vote must be either -1, 0, or 1'); } + if (DownvotesMode::Disabled === $settingsManager->getDownvotesMode() && VotableInterface::VOTE_DOWN === $choice) { + throw new BadRequestHttpException('Downvotes are disabled!'); + } + // Rate limiting handled above $manager->vote($choice, $comment, $this->getUserOrThrow(), rateLimit: false); diff --git a/src/Controller/Api/Entry/EntriesVoteApi.php b/src/Controller/Api/Entry/EntriesVoteApi.php index b88cba96c..db163ffcc 100644 --- a/src/Controller/Api/Entry/EntriesVoteApi.php +++ b/src/Controller/Api/Entry/EntriesVoteApi.php @@ -8,7 +8,9 @@ use App\Entity\Contracts\VotableInterface; use App\Entity\Entry; use App\Factory\EntryFactory; +use App\Service\SettingsManager; use App\Service\VoteManager; +use App\Utils\DownvotesMode; use Nelmio\ApiDocBundle\Annotation\Model; use Nelmio\ApiDocBundle\Annotation\Security; use OpenApi\Attributes as OA; @@ -78,7 +80,8 @@ public function __invoke( int $choice, VoteManager $manager, EntryFactory $factory, - RateLimiterFactory $apiVoteLimiter + RateLimiterFactory $apiVoteLimiter, + SettingsManager $settingsManager, ): JsonResponse { $headers = $this->rateLimit($apiVoteLimiter); @@ -86,6 +89,10 @@ public function __invoke( throw new BadRequestHttpException('Vote must be either -1, 0, or 1'); } + if (DownvotesMode::Disabled === $settingsManager->getDownvotesMode() && VotableInterface::VOTE_DOWN === $choice) { + throw new BadRequestHttpException('Downvotes are disabled!'); + } + // Rate limiting handled above $manager->vote($choice, $entry, $this->getUserOrThrow(), rateLimit: false); diff --git a/src/Controller/Api/Instance/Admin/InstanceUpdatePagesApi.php b/src/Controller/Api/Instance/Admin/InstanceUpdatePagesApi.php index 3762264c8..0c6526399 100644 --- a/src/Controller/Api/Instance/Admin/InstanceUpdatePagesApi.php +++ b/src/Controller/Api/Instance/Admin/InstanceUpdatePagesApi.php @@ -9,6 +9,7 @@ use App\DTO\SiteResponseDto; use App\Entity\Site; use App\Repository\SiteRepository; +use App\Service\SettingsManager; use Doctrine\ORM\EntityManagerInterface; use Nelmio\ApiDocBundle\Annotation\Model; use Nelmio\ApiDocBundle\Annotation\Security; @@ -72,7 +73,8 @@ public function __invoke( EntityManagerInterface $entityManager, SerializerInterface $serializer, ValidatorInterface $validator, - RateLimiterFactory $apiModerateLimiter + RateLimiterFactory $apiModerateLimiter, + SettingsManager $settingsManager, ): JsonResponse { $headers = $this->rateLimit($apiModerateLimiter); @@ -103,7 +105,7 @@ public function __invoke( $entityManager->flush(); return new JsonResponse( - new SiteResponseDto($entity), + new SiteResponseDto($entity, $settingsManager->getDownvotesMode()), headers: $headers ); } diff --git a/src/Controller/Api/Instance/InstanceDetailsApi.php b/src/Controller/Api/Instance/InstanceDetailsApi.php index 7e10e3f4d..a6aaa0801 100644 --- a/src/Controller/Api/Instance/InstanceDetailsApi.php +++ b/src/Controller/Api/Instance/InstanceDetailsApi.php @@ -6,6 +6,7 @@ use App\DTO\SiteResponseDto; use App\Repository\SiteRepository; +use App\Service\SettingsManager; use Nelmio\ApiDocBundle\Annotation\Model; use OpenApi\Attributes as OA; use Symfony\Component\HttpFoundation\JsonResponse; @@ -46,13 +47,14 @@ public function __invoke( SiteRepository $repository, RateLimiterFactory $apiReadLimiter, RateLimiterFactory $anonymousApiReadLimiter, + SettingsManager $settingsManager, ): JsonResponse { $headers = $this->rateLimit($apiReadLimiter, $anonymousApiReadLimiter); $results = $repository->findAll(); - $dto = new SiteResponseDto(null); + $dto = new SiteResponseDto(null, $settingsManager->getDownvotesMode()); if (0 < \count($results)) { - $dto = new SiteResponseDto($results[0]); + $dto = new SiteResponseDto($results[0], $settingsManager->getDownvotesMode()); } return new JsonResponse( diff --git a/src/Controller/Api/Post/Comments/PostCommentsVoteApi.php b/src/Controller/Api/Post/Comments/PostCommentsVoteApi.php index ee626ba7d..a52e7f22a 100644 --- a/src/Controller/Api/Post/Comments/PostCommentsVoteApi.php +++ b/src/Controller/Api/Post/Comments/PostCommentsVoteApi.php @@ -9,6 +9,7 @@ use App\Entity\Contracts\VotableInterface; use App\Entity\PostComment; use App\Factory\PostCommentFactory; +use App\Service\SettingsManager; use App\Service\VoteManager; use Nelmio\ApiDocBundle\Annotation\Model; use Nelmio\ApiDocBundle\Annotation\Security; @@ -79,7 +80,8 @@ public function __invoke( int $choice, VoteManager $manager, PostCommentFactory $factory, - RateLimiterFactory $apiVoteLimiter + RateLimiterFactory $apiVoteLimiter, + SettingsManager $settingsManager, ): JsonResponse { $headers = $this->rateLimit($apiVoteLimiter); @@ -87,6 +89,10 @@ public function __invoke( throw new BadRequestHttpException('Vote must be either -1, 0, or 1'); } + if (VotableInterface::VOTE_DOWN === $choice) { + throw new BadRequestHttpException('Downvotes for post comments are disabled!'); + } + // Rate limit handled above $manager->vote($choice, $comment, $this->getUserOrThrow(), rateLimit: false); diff --git a/src/Controller/Api/Post/PostsVoteApi.php b/src/Controller/Api/Post/PostsVoteApi.php index fd58b650c..b71c4e071 100644 --- a/src/Controller/Api/Post/PostsVoteApi.php +++ b/src/Controller/Api/Post/PostsVoteApi.php @@ -8,6 +8,7 @@ use App\Entity\Contracts\VotableInterface; use App\Entity\Post; use App\Factory\PostFactory; +use App\Service\SettingsManager; use App\Service\VoteManager; use Nelmio\ApiDocBundle\Annotation\Model; use Nelmio\ApiDocBundle\Annotation\Security; @@ -82,7 +83,8 @@ public function __invoke( int $choice, VoteManager $manager, PostFactory $factory, - RateLimiterFactory $apiVoteLimiter + RateLimiterFactory $apiVoteLimiter, + SettingsManager $settingsManager, ): JsonResponse { $headers = $this->rateLimit($apiVoteLimiter); @@ -90,6 +92,10 @@ public function __invoke( throw new BadRequestHttpException('Vote must be either -1, 0, or 1'); } + if (VotableInterface::VOTE_DOWN === $choice) { + throw new BadRequestHttpException('Downvotes for posts are disabled!'); + } + // Rate limit handled above $manager->vote($choice, $post, $this->getUserOrThrow(), rateLimit: false); diff --git a/src/Controller/Entry/Comment/EntryCommentVotersController.php b/src/Controller/Entry/Comment/EntryCommentVotersController.php index b154836c7..7de537cec 100644 --- a/src/Controller/Entry/Comment/EntryCommentVotersController.php +++ b/src/Controller/Entry/Comment/EntryCommentVotersController.php @@ -9,6 +9,8 @@ use App\Entity\Entry; use App\Entity\EntryComment; use App\Entity\Magazine; +use App\Service\SettingsManager; +use App\Utils\DownvotesMode; use Symfony\Bridge\Doctrine\Attribute\MapEntity; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; @@ -16,6 +18,11 @@ class EntryCommentVotersController extends AbstractController { + public function __construct( + private readonly SettingsManager $settingsManager, + ) { + } + public function __invoke( #[MapEntity(mapping: ['magazine_name' => 'name'])] Magazine $magazine, @@ -26,13 +33,17 @@ public function __invoke( Request $request, string $type ): Response { - $votes = $comment->votes->filter( - fn ($e) => $e->choice === ('up' === $type ? VotableInterface::VOTE_UP : VotableInterface::VOTE_DOWN) - ); + if ('down' === $type && DownvotesMode::Enabled !== $this->settingsManager->getDownvotesMode()) { + $votes = []; + } else { + $votes = $comment->votes->filter( + fn ($e) => $e->choice === ('up' === $type ? VotableInterface::VOTE_UP : VotableInterface::VOTE_DOWN) + ); + } if ($request->isXmlHttpRequest()) { return new JsonResponse([ - 'html' => $this->renderView('_layout/_voters_inline.html.twig', [ + 'html' => $this->renderView('components/voters_inline.html.twig', [ 'votes' => $votes, 'more' => null, ]), diff --git a/src/Controller/Entry/EntryVotersController.php b/src/Controller/Entry/EntryVotersController.php index 0fb03caa6..ce3d53e6a 100644 --- a/src/Controller/Entry/EntryVotersController.php +++ b/src/Controller/Entry/EntryVotersController.php @@ -8,12 +8,19 @@ use App\Entity\Contracts\VotableInterface; use App\Entity\Entry; use App\Entity\Magazine; +use App\Service\SettingsManager; +use App\Utils\DownvotesMode; use Symfony\Bridge\Doctrine\Attribute\MapEntity; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; class EntryVotersController extends AbstractController { + public function __construct( + private readonly SettingsManager $settingsManager, + ) { + } + public function __invoke( string $type, #[MapEntity(mapping: ['magazine_name' => 'name'])] @@ -22,9 +29,13 @@ public function __invoke( Entry $entry, Request $request ): Response { - $votes = $entry->votes->filter( - fn ($e) => $e->choice === ('up' === $type ? VotableInterface::VOTE_UP : VotableInterface::VOTE_DOWN) - ); + if ('down' === $type && DownvotesMode::Enabled !== $this->settingsManager->getDownvotesMode()) { + $votes = []; + } else { + $votes = $entry->votes->filter( + fn ($e) => $e->choice === ('up' === $type ? VotableInterface::VOTE_UP : VotableInterface::VOTE_DOWN) + ); + } return $this->render('entry/voters.html.twig', [ 'magazine' => $magazine, diff --git a/src/Controller/VoteController.php b/src/Controller/VoteController.php index 03eeff30f..44aa61e62 100644 --- a/src/Controller/VoteController.php +++ b/src/Controller/VoteController.php @@ -9,7 +9,10 @@ use App\Entity\EntryComment; use App\Entity\Post; use App\Entity\PostComment; +use App\Service\SettingsManager; use App\Service\VoteManager; +use App\Utils\DownvotesMode; +use Symfony\Component\HttpFoundation\Exception\BadRequestException; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -17,8 +20,10 @@ class VoteController extends AbstractController { - public function __construct(private readonly VoteManager $manager) - { + public function __construct( + private readonly VoteManager $manager, + private readonly SettingsManager $settingsManager, + ) { } #[IsGranted('ROLE_USER')] @@ -26,6 +31,9 @@ public function __construct(private readonly VoteManager $manager) public function __invoke(VotableInterface $votable, int $choice, Request $request): Response { $this->validateCsrf('vote', $request->request->get('token')); + if (VotableInterface::VOTE_DOWN === $choice && DownvotesMode::Disabled === $this->settingsManager->getDownvotesMode()) { + throw new BadRequestException('Downvotes are disabled!'); + } $vote = $this->manager->vote($choice, $votable, $this->getUserOrThrow()); diff --git a/src/DTO/SettingsDto.php b/src/DTO/SettingsDto.php index 684a22f88..d298bf40e 100644 --- a/src/DTO/SettingsDto.php +++ b/src/DTO/SettingsDto.php @@ -36,7 +36,8 @@ public function __construct( public bool $MBIN_SSO_REGISTRATIONS_ENABLED, public bool $MBIN_RESTRICT_MAGAZINE_CREATION, public bool $MBIN_SSO_SHOW_FIRST, - public int $MAX_IMAGE_BYTES + public int $MAX_IMAGE_BYTES, + public string $MBIN_DOWNVOTES_MODE, ) { } @@ -68,6 +69,7 @@ public function mergeIntoDto(SettingsDto $dto): SettingsDto $dto->MBIN_RESTRICT_MAGAZINE_CREATION = $this->MBIN_RESTRICT_MAGAZINE_CREATION ?? $dto->MBIN_RESTRICT_MAGAZINE_CREATION; $dto->MBIN_SSO_SHOW_FIRST = $this->MBIN_SSO_SHOW_FIRST ?? $dto->MBIN_SSO_SHOW_FIRST; $dto->MAX_IMAGE_BYTES = $this->MAX_IMAGE_BYTES ?? $dto->MAX_IMAGE_BYTES; + $dto->MBIN_DOWNVOTES_MODE = $this->MBIN_DOWNVOTES_MODE ?? $dto->MBIN_DOWNVOTES_MODE; return $dto; } @@ -101,6 +103,7 @@ public function jsonSerialize(): mixed 'MBIN_RESTRICT_MAGAZINE_CREATION' => $this->MBIN_RESTRICT_MAGAZINE_CREATION, 'MBIN_SSO_SHOW_FIRST' => $this->MBIN_SSO_SHOW_FIRST, 'MAX_IMAGE_BYTES' => $this->MAX_IMAGE_BYTES, + 'MBIN_DOWNVOTES_MODE' => $this->MBIN_DOWNVOTES_MODE, ]; } } diff --git a/src/DTO/SiteResponseDto.php b/src/DTO/SiteResponseDto.php index 2f0ef0e56..133b221ea 100644 --- a/src/DTO/SiteResponseDto.php +++ b/src/DTO/SiteResponseDto.php @@ -5,6 +5,7 @@ namespace App\DTO; use App\Entity\Site; +use App\Utils\DownvotesMode; use OpenApi\Attributes as OA; #[OA\Schema()] @@ -23,14 +24,16 @@ class SiteResponseDto implements \JsonSerializable public ?string $faq = null; public ?string $privacyPolicy = null; public ?string $terms = null; + public DownvotesMode $downvotesMode = DownvotesMode::Enabled; - public function __construct(?Site $site) + public function __construct(?Site $site, DownvotesMode $downvotesMode) { $this->terms = $site?->terms; $this->privacyPolicy = $site?->privacyPolicy; $this->faq = $site?->faq; $this->about = $site?->about; $this->contact = $site?->contact; + $this->downvotesMode = $downvotesMode; } public function jsonSerialize(): mixed diff --git a/src/EventSubscriber/VoteHandleSubscriber.php b/src/EventSubscriber/VoteHandleSubscriber.php index 40a3cfcad..202f522c5 100644 --- a/src/EventSubscriber/VoteHandleSubscriber.php +++ b/src/EventSubscriber/VoteHandleSubscriber.php @@ -13,6 +13,8 @@ use App\Message\Notification\VoteNotificationMessage; use App\Service\CacheService; use App\Service\FavouriteManager; +use App\Service\SettingsManager; +use App\Utils\DownvotesMode; use Doctrine\Common\Util\ClassUtils; use JetBrains\PhpStorm\ArrayShape; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -26,6 +28,7 @@ public function __construct( private readonly CacheService $cacheService, private readonly CacheInterface $cache, private readonly FavouriteManager $favouriteManager, + private readonly SettingsManager $settingsManager, ) { } @@ -40,7 +43,7 @@ public static function getSubscribedEvents(): array public function onVote(VoteEvent $event): void { if (VotableInterface::VOTE_DOWN === $event->vote->choice) { - $this->favouriteManager->toggle($event->vote->user, $event->votable, FavouriteManager::TYPE_UNLIKE); + $this->favouriteManager->toggle($event->vote->user, $event->votable, DownvotesMode::Disabled !== $this->settingsManager->getDownvotesMode() ? FavouriteManager::TYPE_UNLIKE : null); } $this->clearCache($event->votable); diff --git a/src/Form/SettingsType.php b/src/Form/SettingsType.php index a49e62356..561450dc2 100644 --- a/src/Form/SettingsType.php +++ b/src/Form/SettingsType.php @@ -6,6 +6,9 @@ use App\DTO\SettingsDto; use App\Repository\Criteria; +use App\Service\SettingsManager; +use App\Utils\DownvotesMode; +use Psr\Log\LoggerInterface; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; @@ -16,8 +19,16 @@ class SettingsType extends AbstractType { + public function __construct( + private readonly LoggerInterface $logger, + private readonly SettingsManager $settingsManager, + ) { + } + public function buildForm(FormBuilderInterface $builder, array $options): void { + $dto = $this->settingsManager->getDto(); + $this->logger->debug('downvotes mode is: {mode}', ['mode' => $dto->MBIN_DOWNVOTES_MODE]); $builder ->add('KBIN_DOMAIN') ->add('KBIN_CONTACT_EMAIL', EmailType::class) @@ -42,6 +53,12 @@ public function buildForm(FormBuilderInterface $builder, array $options): void ->add('MBIN_SIDEBAR_SECTIONS_LOCAL_ONLY', CheckboxType::class, ['required' => false]) ->add('MBIN_RESTRICT_MAGAZINE_CREATION', CheckboxType::class, ['required' => false]) ->add('MBIN_SSO_SHOW_FIRST', CheckboxType::class, ['required' => false]) + ->add('MBIN_DOWNVOTES_MODE', ChoiceType::class, [ + 'choices' => DownvotesMode::GetChoices(), + 'choice_attr' => [ + $dto->MBIN_DOWNVOTES_MODE => ['checked' => true], + ], + ]) ->add('submit', SubmitType::class); } diff --git a/src/MessageHandler/ActivityPub/Inbox/DislikeHandler.php b/src/MessageHandler/ActivityPub/Inbox/DislikeHandler.php index 9a753b4a0..03f66cd79 100644 --- a/src/MessageHandler/ActivityPub/Inbox/DislikeHandler.php +++ b/src/MessageHandler/ActivityPub/Inbox/DislikeHandler.php @@ -15,7 +15,9 @@ use App\Message\Contracts\MessageInterface; use App\MessageHandler\MbinMessageHandler; use App\Service\ActivityPubManager; +use App\Service\SettingsManager; use App\Service\VoteManager; +use App\Utils\DownvotesMode; use Doctrine\ORM\EntityManagerInterface; use Psr\Log\LoggerInterface; use Symfony\Component\Messenger\Attribute\AsMessageHandler; @@ -30,6 +32,7 @@ public function __construct( private readonly MessageBusInterface $bus, private readonly VoteManager $voteManager, private readonly LoggerInterface $logger, + private readonly SettingsManager $settingsManager, ) { parent::__construct($this->entityManager); } @@ -47,6 +50,9 @@ public function doWork(MessageInterface $message): void if (!isset($message->payload['type'])) { return; } + if (DownvotesMode::Disabled === $this->settingsManager->getDownvotesMode()) { + return; + } $chainDispatchCallback = function (array $object, ?string $adjustedUrl) use ($message) { if ($adjustedUrl) { diff --git a/src/Repository/EntryCommentRepository.php b/src/Repository/EntryCommentRepository.php index 3b136f984..ddb178c0f 100644 --- a/src/Repository/EntryCommentRepository.php +++ b/src/Repository/EntryCommentRepository.php @@ -20,6 +20,8 @@ use App\Entity\User; use App\Entity\UserBlock; use App\Entity\UserFollow; +use App\Service\SettingsManager; +use App\Utils\DownvotesMode; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\DBAL\ArrayParameterType; use Doctrine\DBAL\Types\Types; @@ -44,13 +46,12 @@ class EntryCommentRepository extends ServiceEntityRepository public const SORT_DEFAULT = 'active'; public const PER_PAGE = 15; - private Security $security; - - public function __construct(ManagerRegistry $registry, Security $security) - { + public function __construct( + ManagerRegistry $registry, + private readonly Security $security, + private readonly SettingsManager $settingsManager, + ) { parent::__construct($registry, EntryComment::class); - - $this->security = $security; } public function findByCriteria(Criteria $criteria): PagerfantaInterface @@ -180,8 +181,8 @@ private function filter(QueryBuilder $qb, Criteria $criteria): QueryBuilder if ($criteria->subscribed) { $qb->andWhere( - 'c.magazine IN (SELECT IDENTITY(ms.magazine) FROM '.MagazineSubscription::class.' ms WHERE ms.user = :follower) - OR + 'c.magazine IN (SELECT IDENTITY(ms.magazine) FROM '.MagazineSubscription::class.' ms WHERE ms.user = :follower) + OR c.user IN (SELECT IDENTITY(uf.following) FROM '.UserFollow::class.' uf WHERE uf.follower = :follower) OR c.user = :follower @@ -243,7 +244,11 @@ private function filter(QueryBuilder $qb, Criteria $criteria): QueryBuilder $qb->orderBy('c.upVotes', 'DESC'); break; case Criteria::SORT_TOP: - $qb->orderBy('c.upVotes + c.favouriteCount - c.downVotes', 'DESC'); + if (DownvotesMode::Disabled === $this->settingsManager->getDownvotesMode()) { + $qb->orderBy('c.upVotes + c.favouriteCount', 'DESC'); + } else { + $qb->orderBy('c.upVotes + c.favouriteCount - c.downVotes', 'DESC'); + } break; case Criteria::SORT_ACTIVE: $qb->orderBy('c.lastActive', 'DESC'); diff --git a/src/Repository/ReputationRepository.php b/src/Repository/ReputationRepository.php index bb837f9dd..3c1a2f593 100644 --- a/src/Repository/ReputationRepository.php +++ b/src/Repository/ReputationRepository.php @@ -6,6 +6,8 @@ use App\Entity\Site; use App\Entity\User; +use App\Service\SettingsManager; +use App\Utils\DownvotesMode; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; use Pagerfanta\Adapter\ArrayAdapter; @@ -23,8 +25,10 @@ class ReputationRepository extends ServiceEntityRepository public const PER_PAGE = 48; - public function __construct(ManagerRegistry $registry) - { + public function __construct( + ManagerRegistry $registry, + private readonly SettingsManager $settingsManager, + ) { parent::__construct($registry, Site::class); } @@ -35,7 +39,7 @@ public function getUserReputation(User $user, string $className, int $page = 1): $table = $this->getEntityManager()->getClassMetadata($className)->getTableName().'_vote'; - $sql = "SELECT date_trunc('day', v.created_at) as day, sum(v.choice) as points FROM ".$table.' v + $sql = "SELECT date_trunc('day', v.created_at) as day, sum(v.choice) as points FROM ".$table.' v WHERE v.author_id = :userId GROUP BY day ORDER BY day DESC'; $stmt = $conn->prepare($sql); @@ -63,11 +67,19 @@ public function getUserReputationTotal(User $user): int $conn = $this->getEntityManager() ->getConnection(); - $sql = 'SELECT - COALESCE((SELECT SUM((up_votes * 2) - down_votes + favourite_count) FROM entry WHERE user_id = :user), 0) + - COALESCE((SELECT SUM((up_votes * 2) - down_votes + favourite_count) FROM entry_comment WHERE user_id = :user), 0) + - COALESCE((SELECT SUM((up_votes * 2) - down_votes + favourite_count) FROM post WHERE user_id = :user), 0) + - COALESCE((SELECT SUM((up_votes * 2) - down_votes + favourite_count) FROM post_comment WHERE user_id = :user), 0) as total'; + if (DownvotesMode::Disabled === $this->settingsManager->getDownvotesMode()) { + $sql = 'SELECT + COALESCE((SELECT SUM((up_votes * 2) + favourite_count) FROM entry WHERE user_id = :user), 0) + + COALESCE((SELECT SUM((up_votes * 2) + favourite_count) FROM entry_comment WHERE user_id = :user), 0) + + COALESCE((SELECT SUM((up_votes * 2) + favourite_count) FROM post WHERE user_id = :user), 0) + + COALESCE((SELECT SUM((up_votes * 2) + favourite_count) FROM post_comment WHERE user_id = :user), 0) as total'; + } else { + $sql = 'SELECT + COALESCE((SELECT SUM((up_votes * 2) - down_votes + favourite_count) FROM entry WHERE user_id = :user), 0) + + COALESCE((SELECT SUM((up_votes * 2) - down_votes + favourite_count) FROM entry_comment WHERE user_id = :user), 0) + + COALESCE((SELECT SUM((up_votes * 2) - down_votes + favourite_count) FROM post WHERE user_id = :user), 0) + + COALESCE((SELECT SUM((up_votes * 2) - down_votes + favourite_count) FROM post_comment WHERE user_id = :user), 0) as total'; + } $stmt = $conn->prepare($sql); $stmt->bindValue('user', $user->getId()); diff --git a/src/Repository/StatsVotesRepository.php b/src/Repository/StatsVotesRepository.php index fab78166d..cdb6bf9fa 100644 --- a/src/Repository/StatsVotesRepository.php +++ b/src/Repository/StatsVotesRepository.php @@ -6,11 +6,21 @@ use App\Entity\Magazine; use App\Entity\User; +use App\Service\SettingsManager; +use App\Utils\DownvotesMode; use Doctrine\DBAL\ParameterType; +use Doctrine\Persistence\ManagerRegistry; use JetBrains\PhpStorm\ArrayShape; class StatsVotesRepository extends StatsRepository { + public function __construct( + private readonly SettingsManager $settingsManager, + ManagerRegistry $registry + ) { + parent::__construct($registry); + } + #[ArrayShape(['entries' => 'array', 'comments' => 'array', 'posts' => 'array', 'replies' => 'array'])] public function getOverallStats( ?User $user = null, @@ -98,7 +108,14 @@ private function getMonthlyVoteStats(string $table, string $relation): array $stmt->bindValue('magazineId', $this->magazine->getId()); } - return $stmt->executeQuery()->fetchAllAssociative(); + $results = $stmt->executeQuery()->fetchAllAssociative(); + if (DownvotesMode::Disabled === $this->settingsManager->getDownvotesMode()) { + for ($i = 0; $i < \count($results); ++$i) { + $results[$i]['down'] = 0; + } + } + + return $results; } #[ArrayShape([[ @@ -125,7 +142,14 @@ private function getMonthlyFavouriteStats(string $table): array $stmt->bindValue('magazineId', $this->magazine->getId()); } - return $stmt->executeQuery()->fetchAllAssociative(); + $results = $stmt->executeQuery()->fetchAllAssociative(); + if (DownvotesMode::Disabled === $this->settingsManager->getDownvotesMode()) { + for ($i = 0; $i < \count($results); ++$i) { + $results[$i]['down'] = 0; + } + } + + return $results; } protected function prepareContentOverall(array $entries, int $startYear, int $startMonth): array @@ -148,6 +172,9 @@ protected function prepareContentOverall(array $entries, int $startYear, int $st if (!empty($existed)) { $results[] = current($existed); + if (DownvotesMode::Disabled === $this->settingsManager->getDownvotesMode()) { + $results[0]['down'] = 0; + } continue; } @@ -202,6 +229,9 @@ protected function prepareContentDaily(array $entries): array if (!empty($existed)) { $existed = current($existed); $existed['day'] = new \DateTime($existed['day']); + if (DownvotesMode::Disabled === $this->settingsManager->getDownvotesMode()) { + $existed['down'] = 0; + } $results[] = $existed; continue; @@ -264,7 +294,7 @@ private function getDailyVoteStats(string $table, string $relation): array $onlyLocalWhere = $this->onlyLocal ? ' AND u.ap_id IS NULL ' : ''; $userWhere = $this->user ? ' AND e.user_id = :userId ' : ''; $magazineJoin = $this->magazine ? 'INNER JOIN '.str_replace('_vote', '', $table).' AS parent ON '.$relation.' = parent.id AND parent.magazine_id = :magazineId' : ''; - $sql = "SELECT date_trunc('day', e.created_at) as day, COUNT(case e.choice when 1 then 1 else null end) as boost, + $sql = "SELECT date_trunc('day', e.created_at) as day, COUNT(case e.choice when 1 then 1 else null end) as boost, COUNT(case e.choice when -1 then 1 else null end) as down FROM $table e INNER JOIN public.user u ON u.id = e.user_id $magazineJoin @@ -351,6 +381,9 @@ private function aggregateStats(?Magazine $magazine, string $interval, ?\DateTim for ($i = 0; $i < \count($results[$table]); ++$i) { $datemap[$results[$table][$i]['datetime']] = $i; $results[$table][$i]['up'] = 0; + if (DownvotesMode::Disabled === $this->settingsManager->getDownvotesMode()) { + $results[$table][$i]['down'] = 0; + } } $favourites = $this->aggregateFavouriteStats($table, $magazine, $interval, $end); @@ -380,7 +413,7 @@ private function aggregateVoteStats(string $table, ?Magazine $magazine, string $ $voteTable = $table.'_vote'; $magazineJoinCond = $magazine ? ' AND parent.magazine_id = ? ' : ''; $onlyLocalWhere = $this->onlyLocal ? 'u.ap_id IS NULL ' : ''; - $sql = "SELECT date_trunc(?, e.created_at) as datetime, COUNT(case e.choice when 1 then 1 else null end) as boost, COUNT(case e.choice when -1 then 1 else null end) as down FROM $voteTable e + $sql = "SELECT date_trunc(?, e.created_at) as datetime, COUNT(case e.choice when 1 then 1 else null end) as boost, COUNT(case e.choice when -1 then 1 else null end) as down FROM $voteTable e INNER JOIN $table AS parent ON $relation = parent.id INNER JOIN public.user u ON e.user_id = u.id $magazineJoinCond WHERE u.is_deleted = false AND e.created_at BETWEEN ? AND ? $onlyLocalWhere GROUP BY 1 ORDER BY 1"; @@ -403,7 +436,7 @@ private function aggregateFavouriteStats(string $table, ?Magazine $magazine, str $magazineWhere = $magazine ? ' AND e.magazine_id = ? ' : ''; $onlyLocalWhere = $this->onlyLocal ? 'u.ap_id IS NULL ' : ''; $idCol = $table.'_id'; - $sql = "SELECT date_trunc(?, e.created_at) as datetime, COUNT(e.id) as up FROM favourite e + $sql = "SELECT date_trunc(?, e.created_at) as datetime, COUNT(e.id) as up FROM favourite e INNER JOIN public.user u on e.user_id = u.id WHERE u.is_deleted = false AND e.created_at BETWEEN ? AND ? AND e.$idCol IS NOT NULL $magazineWhere $onlyLocalWhere GROUP BY 1 ORDER BY 1"; @@ -443,7 +476,7 @@ private function aggregateTotalStats(?Magazine $magazine): array $magazineWhere = $magazine ? ' AND e.magazine_id = ?' : ''; $idCol = $table.'_id'; - $sql = "SELECT COUNT(e.id) as up FROM favourite e + $sql = "SELECT COUNT(e.id) as up FROM favourite e INNER JOIN public.user u on u.id = e.user_id WHERE u.is_deleted = false $magazineWhere $onlyLocalWhere AND e.$idCol IS NOT NULL"; @@ -469,6 +502,9 @@ private function aggregateTotalStats(?Magazine $magazine): array 'up' => 0, ]; } + if (DownvotesMode::Disabled === $this->settingsManager->getDownvotesMode()) { + $results[$table][0]['down'] = 0; + } usort($results[$table], fn ($a, $b): int => $a['datetime'] <=> $b['datetime']); } diff --git a/src/Service/SettingsManager.php b/src/Service/SettingsManager.php index edd3ad812..b7cebbe0b 100644 --- a/src/Service/SettingsManager.php +++ b/src/Service/SettingsManager.php @@ -7,6 +7,7 @@ use App\DTO\SettingsDto; use App\Entity\Settings; use App\Repository\SettingsRepository; +use App\Utils\DownvotesMode; use Doctrine\ORM\EntityManagerInterface; use JetBrains\PhpStorm\Pure; use Symfony\Component\HttpFoundation\RequestStack; @@ -36,7 +37,8 @@ public function __construct( private readonly bool $kbinFederationPageEnabled, private readonly bool $kbinAdminOnlyOauthClients, private readonly bool $mbinSsoOnlyMode, - private readonly int $maxImageBytes + private readonly int $maxImageBytes, + private readonly DownvotesMode $mbinDownvotesMode, ) { if (!self::$dto) { $results = $this->repository->findAll(); @@ -80,7 +82,8 @@ public function __construct( $this->find($results, 'MBIN_SSO_REGISTRATIONS_ENABLED', FILTER_VALIDATE_BOOLEAN) ?? true, $this->find($results, 'MBIN_RESTRICT_MAGAZINE_CREATION', FILTER_VALIDATE_BOOLEAN) ?? false, $this->find($results, 'MBIN_SSO_SHOW_FIRST', FILTER_VALIDATE_BOOLEAN) ?? false, - $maxImageBytesEdited + $maxImageBytesEdited, + $this->find($results, 'MBIN_DOWNVOTES_MODE') ?? $this->mbinDownvotesMode->value, ); } } @@ -155,6 +158,11 @@ public function get(string $name) return self::$dto->{$name}; } + public function getDownvotesMode(): DownvotesMode + { + return DownvotesMode::from($this->get('MBIN_DOWNVOTES_MODE')); + } + public function set(string $name, $value): void { self::$dto->{$name} = $value; diff --git a/src/Service/StatsManager.php b/src/Service/StatsManager.php index 478213126..37be2270c 100644 --- a/src/Service/StatsManager.php +++ b/src/Service/StatsManager.php @@ -9,6 +9,7 @@ use App\Repository\StatsContentRepository; use App\Repository\StatsRepository; use App\Repository\StatsVotesRepository; +use App\Utils\DownvotesMode; use Symfony\Contracts\Translation\TranslatorInterface; use Symfony\UX\Chartjs\Builder\ChartBuilderInterface; use Symfony\UX\Chartjs\Model\Chart; @@ -19,6 +20,7 @@ public function __construct( private readonly StatsVotesRepository $votesRepository, private readonly StatsContentRepository $contentRepository, private readonly ChartBuilderInterface $chartBuilder, + private readonly SettingsManager $settingsManager, private readonly TranslatorInterface $translator, ) { } @@ -90,7 +92,7 @@ private function createVotesDataset(array $stats, array $labels): Chart $results = []; foreach ($stats['entries'] as $index => $entry) { $entry['up'] = array_sum(array_map(fn ($type) => $type[$index]['up'], $stats)); - $entry['down'] = array_sum(array_map(fn ($type) => $type[$index]['down'], $stats)); + $entry['down'] = DownvotesMode::Disabled !== $this->settingsManager->getDownvotesMode() ? 0 : array_sum(array_map(fn ($type) => $type[$index]['down'], $stats)); $entry['boost'] = array_sum(array_map(fn ($type) => $type[$index]['boost'], $stats)); $results[] = $entry; @@ -110,7 +112,7 @@ private function createVotesDataset(array $stats, array $labels): Chart [ 'label' => $this->translator->trans('down_votes'), 'borderColor' => '#8f0b00', - 'data' => array_map(fn ($val) => $val['down'], $results), + 'data' => DownvotesMode::Disabled !== $this->settingsManager->getDownvotesMode() ? [] : array_map(fn ($val) => $val['down'], $results), ], ]; diff --git a/src/Service/VoteManager.php b/src/Service/VoteManager.php index c2014ae19..c846c560a 100644 --- a/src/Service/VoteManager.php +++ b/src/Service/VoteManager.php @@ -25,7 +25,8 @@ public function __construct( private readonly VoteFactory $factory, private readonly RateLimiterFactory $voteLimiter, private readonly EventDispatcherInterface $dispatcher, - private readonly EntityManagerInterface $entityManager + private readonly EntityManagerInterface $entityManager, + private readonly SettingsManager $settingsManager, ) { } @@ -64,7 +65,7 @@ public function vote(int $choice, VotableInterface $votable, User $user, $rateLi } $vote->choice = $choice; - } else { + } elseif (VotableInterface::VOTE_DOWN !== $choice) { if (VotableInterface::VOTE_UP === $choice) { return $this->upvote($votable, $user); } diff --git a/src/Twig/Extension/SettingsExtension.php b/src/Twig/Extension/SettingsExtension.php index 1b966c0c3..e0b5c1d3f 100644 --- a/src/Twig/Extension/SettingsExtension.php +++ b/src/Twig/Extension/SettingsExtension.php @@ -27,6 +27,7 @@ public function getFunctions(): array new TwigFunction('kbin_captcha_enabled', [SettingsExtensionRuntime::class, 'kbinCaptchaEnabled']), new TwigFunction('kbin_mercure_enabled', [SettingsExtensionRuntime::class, 'kbinMercureEnabled']), new TwigFunction('kbin_federation_page_enabled', [SettingsExtensionRuntime::class, 'kbinFederationPageEnabled']), + new TwigFunction('mbin_downvotes_mode', [SettingsExtensionRuntime::class, 'mbinDownvotesMode']), new TwigFunction('mbin_current_version', [SettingsExtensionRuntime::class, 'mbinCurrentVersion']), new TwigFunction('mbin_restrict_magazine_creation', [SettingsExtensionRuntime::class, 'mbinRestrictMagazineCreation']), new TwigFunction('mbin_private_instance', [SettingsExtensionRuntime::class, 'mbinPrivateInstance']), diff --git a/src/Twig/Runtime/SettingsExtensionRuntime.php b/src/Twig/Runtime/SettingsExtensionRuntime.php index 2213d98fc..9157b0566 100644 --- a/src/Twig/Runtime/SettingsExtensionRuntime.php +++ b/src/Twig/Runtime/SettingsExtensionRuntime.php @@ -6,6 +6,7 @@ use App\Service\ProjectInfoService; use App\Service\SettingsManager; +use App\Utils\DownvotesMode; use JetBrains\PhpStorm\Pure; use Twig\Extension\RuntimeExtensionInterface; @@ -99,6 +100,11 @@ public function kbinFederatedSearchOnlyLoggedIn(): bool return $this->settings->get('KBIN_FEDERATED_SEARCH_ONLY_LOGGEDIN'); } + public function mbinDownvotesMode(): DownvotesMode + { + return $this->settings->getDownvotesMode(); + } + public function mbinCurrentVersion(): string { return $this->projectInfo->getVersion(); diff --git a/src/Utils/DownvotesMode.php b/src/Utils/DownvotesMode.php new file mode 100644 index 000000000..4df8e2871 --- /dev/null +++ b/src/Utils/DownvotesMode.php @@ -0,0 +1,21 @@ +name => self::Enabled->value, + self::Hidden->name => self::Hidden->value, + self::Disabled->name => self::Disabled->value, + ]; + } +} diff --git a/templates/admin/settings.html.twig b/templates/admin/settings.html.twig index e2ef8d96a..80dc0d6ad 100644 --- a/templates/admin/settings.html.twig +++ b/templates/admin/settings.html.twig @@ -31,6 +31,10 @@ {{ form_row(form.KBIN_META_KEYWORDS, {label: 'keywords'}) }}

        {{ 'instance'|trans }}

        {{ form_row(form.KBIN_TITLE, {label: 'title'}) }} +
        + {{ form_label(form.MBIN_DOWNVOTES_MODE, 'downvotes_mode') }} + {{ form_widget(form.MBIN_DOWNVOTES_MODE, {attr: {'aria-label': 'change_downvotes_mode'|trans}}) }} +
        {{ form_label(form.KBIN_HEADER_LOGO, 'header_logo') }} {{ form_widget(form.KBIN_HEADER_LOGO) }} diff --git a/templates/components/vote.html.twig b/templates/components/vote.html.twig index a2847ee5c..dbda8eb23 100644 --- a/templates/components/vote.html.twig +++ b/templates/components/vote.html.twig @@ -1,6 +1,8 @@ {%- set VOTE_NONE = constant('App\\Entity\\Contracts\\VotableInterface::VOTE_NONE') -%} {%- set VOTE_UP = constant('App\\Entity\\Contracts\\VotableInterface::VOTE_UP') -%} {%- set VOTE_DOWN = constant('App\\Entity\\Contracts\\VotableInterface::VOTE_DOWN') -%} +{%- set DOWNVOTES_HIDDEN = constant('App\\Utils\\DownvotesMode::Hidden') %} +{%- set DOWNVOTES_DISABLED = constant('App\\Utils\\DownvotesMode::Disabled') %} {% if app.user %} {%- set user_choice = is_granted('ROLE_USER') ? subject.userChoice(app.user) : null -%} @@ -33,7 +35,8 @@ - {% if showDownvote %} + {% set downvoteMode = mbin_downvotes_mode() %} + {% if showDownvote and downvoteMode is not same as DOWNVOTES_DISABLED %}
        - {{ subject.apDislikeCount ?? subject.countDownvotes }} + {% if downvoteMode is not same as DOWNVOTES_HIDDEN %} + {{ subject.apDislikeCount ?? subject.countDownvotes }} + {% endif %} +
        diff --git a/templates/entry/_options_activity.html.twig b/templates/entry/_options_activity.html.twig index 5b944ec05..a2d853136 100644 --- a/templates/entry/_options_activity.html.twig +++ b/templates/entry/_options_activity.html.twig @@ -1,3 +1,5 @@ +{%- set downvoteMode = mbin_downvotes_mode() %} +{%- set DOWNVOTES_ENABLED = constant('App\\Utils\\DownvotesMode::Enabled') %} diff --git a/templates/entry/comment/_options_activity.html.twig b/templates/entry/comment/_options_activity.html.twig index 53d3237db..d243be0c2 100644 --- a/templates/entry/comment/_options_activity.html.twig +++ b/templates/entry/comment/_options_activity.html.twig @@ -1,3 +1,5 @@ +{% set downvoteMode = mbin_downvotes_mode() %} +{%- set DOWNVOTES_ENABLED = constant('App\\Utils\\DownvotesMode::Enabled') %} diff --git a/tests/Functional/Controller/Api/Instance/Admin/InstanceSettingsRetrieveApiTest.php b/tests/Functional/Controller/Api/Instance/Admin/InstanceSettingsRetrieveApiTest.php index cb11c5423..cf8c44987 100644 --- a/tests/Functional/Controller/Api/Instance/Admin/InstanceSettingsRetrieveApiTest.php +++ b/tests/Functional/Controller/Api/Instance/Admin/InstanceSettingsRetrieveApiTest.php @@ -32,6 +32,7 @@ class InstanceSettingsRetrieveApiTest extends WebTestCase 'MBIN_SIDEBAR_SECTIONS_LOCAL_ONLY', 'MBIN_SSO_REGISTRATIONS_ENABLED', 'MBIN_RESTRICT_MAGAZINE_CREATION', + 'MBIN_DOWNVOTES_MODE', ]; public function testApiCannotRetrieveInstanceSettingsAnonymous(): void diff --git a/tests/Functional/Controller/Api/Instance/Admin/InstanceSettingsUpdateApiTest.php b/tests/Functional/Controller/Api/Instance/Admin/InstanceSettingsUpdateApiTest.php index f255c314d..8e8552051 100644 --- a/tests/Functional/Controller/Api/Instance/Admin/InstanceSettingsUpdateApiTest.php +++ b/tests/Functional/Controller/Api/Instance/Admin/InstanceSettingsUpdateApiTest.php @@ -5,6 +5,7 @@ namespace App\Tests\Functional\Controller\Api\Instance\Admin; use App\Tests\WebTestCase; +use App\Utils\DownvotesMode; class InstanceSettingsUpdateApiTest extends WebTestCase { @@ -32,6 +33,7 @@ class InstanceSettingsUpdateApiTest extends WebTestCase 'MBIN_SIDEBAR_SECTIONS_LOCAL_ONLY', 'MBIN_SSO_REGISTRATIONS_ENABLED', 'MBIN_RESTRICT_MAGAZINE_CREATION', + 'MBIN_DOWNVOTES_MODE', ]; public function testApiCannotUpdateInstanceSettingsAnonymous(): void @@ -110,6 +112,7 @@ public function testApiCanUpdateInstanceSettings(): void 'MBIN_SIDEBAR_SECTIONS_LOCAL_ONLY' => false, 'MBIN_SSO_REGISTRATIONS_ENABLED' => true, 'MBIN_RESTRICT_MAGAZINE_CREATION' => false, + 'MBIN_DOWNVOTES_MODE' => DownvotesMode::Enabled, ]; $client->jsonRequest('PUT', '/api/instance/settings', $settings, server: ['HTTP_AUTHORIZATION' => $token]); @@ -146,6 +149,7 @@ public function testApiCanUpdateInstanceSettings(): void 'MBIN_SIDEBAR_SECTIONS_LOCAL_ONLY' => true, 'MBIN_SSO_REGISTRATIONS_ENABLED' => false, 'MBIN_RESTRICT_MAGAZINE_CREATION' => true, + 'MBIN_DOWNVOTES_MODE' => DownvotesMode::Hidden, ]; $client->jsonRequest('PUT', '/api/instance/settings', $settings, server: ['HTTP_AUTHORIZATION' => $token]); diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml index 53aaab3a3..73defe147 100644 --- a/translations/messages.en.yaml +++ b/translations/messages.en.yaml @@ -106,6 +106,11 @@ contact: Contact faq: FAQ rss: RSS change_theme: Change theme +downvotes_mode: Downvotes mode +change_downvotes_mode: Change downvotes mode +disabled: Disabled +hidden: Hidden +enabled: Enabled useful: Useful help: Help check_email: Check your email From 84b1c46d03c4697c2746709d38a2f45ccf4a41e9 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Tue, 10 Sep 2024 16:44:34 +0200 Subject: [PATCH 253/335] Add the downvotes mode to the .env.example (#1104) --- .env.example | 6 ++++++ .env.example_docker | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/.env.example b/.env.example index 7aa3d6a92..991e08da9 100644 --- a/.env.example +++ b/.env.example @@ -41,6 +41,12 @@ TRUSTED_PROXIES= # This should be set to <= `upload_max_filesize` and `post_max_size` in the server's php.ini file MAX_IMAGE_BYTES=6000000 +# possible values: +# 'enabled' => default mode downvotes are enabled +# 'hidden' => downvotes are counted and users can downvote, but the number is hidden +# 'disabled' => downvotes are ignored and the downvote button is hidden. They also do not count in the sorting +MBIN_DOWNVOTES_MODE=enabled + # Captcha (also enable in admin panel/settings) KBIN_CAPTCHA_ENABLED=false ###> meteo-concept/hcaptcha-bundle ### diff --git a/.env.example_docker b/.env.example_docker index 94d692b03..370f106ca 100644 --- a/.env.example_docker +++ b/.env.example_docker @@ -41,6 +41,12 @@ TRUSTED_PROXIES=::1,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 # This should be set to <= `upload_max_filesize` and `post_max_size` in the server's php.ini file MAX_IMAGE_BYTES=6000000 +# possible values: +# 'enabled' => default mode downvotes are enabled +# 'hidden' => downvotes are counted and users can downvote, but the number is hidden +# 'disabled' => downvotes are ignored and the downvote button is hidden. They also do not count in the sorting +MBIN_DOWNVOTES_MODE=enabled + # Captcha (also enable in admin panel/settings) KBIN_CAPTCHA_ENABLED=false From db74860954c2c4b76594e1c45ba2f134bb8fe69a Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Tue, 10 Sep 2024 17:20:11 +0200 Subject: [PATCH 254/335] Translations update from Hosted Weblate (#1103) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jiri Grönroos Co-authored-by: BentiGorlich Co-authored-by: Λευτέρης Τ Co-authored-by: gallegonovato --- translations/messages.de.yaml | 5 +++ translations/messages.el.yaml | 19 +++++++++ translations/messages.es.yaml | 61 +++++++++++++++++++++++++-- translations/messages.fi.yaml | 77 ++++++++++++++++++++++++++++++++++- 4 files changed, 158 insertions(+), 4 deletions(-) diff --git a/translations/messages.de.yaml b/translations/messages.de.yaml index c5c9703ab..95e89a355 100644 --- a/translations/messages.de.yaml +++ b/translations/messages.de.yaml @@ -933,3 +933,8 @@ admin_users_suspended: Suspendiert admin_users_banned: Gebannt user_verify: Account aktivieren max_image_size: Maximale Dateigröße +change_downvotes_mode: Reduzieren Modus ändern +disabled: Deaktiviert +downvotes_mode: Reduzieren Modus +hidden: Versteckt +enabled: Aktiviert diff --git a/translations/messages.el.yaml b/translations/messages.el.yaml index 9267acca1..a79a3a4df 100644 --- a/translations/messages.el.yaml +++ b/translations/messages.el.yaml @@ -569,3 +569,22 @@ oauth2.grant.entry.all: Δημιούργησε, επεξεργάσου ή διά oauth2.grant.entry.delete: Διάγραψε τα υπάρχοντα σου νήματα. oauth2.grant.entry_comment.all: Δημιούργησε, επεξεργάσου ή διάγραψε τα σχόλιά σου σε νήματα και ψήφισε, ενίσχυσε ή ανέφερε οποιοδήποτε σχόλιο σε ένα νήμα. +downvotes_mode: Λειτουργία αρνητικών ψήφων +change_downvotes_mode: Αλλαγή λειτουργίας αρνητικών ψήφων +hidden: Κρυφό +enabled: Ενεργό +disabled: Ανενεργό +oauth2.grant.magazine.block: Απέκλεισε ή κατάργησε τον αποκλεισμό περιοδικών και προβολή + των περιοδικών που έχεις αποκλείσει. +oauth2.grant.post.edit: Επεξεργάσου υπάρχουσες αναρτήσεις. +oauth2.grant.post.delete: Διέγραψε τις υπάρχουσες αναρτήσεις σου. +oauth2.grant.magazine.subscribe: Εγγράψου ή κατάργησε την εγγραφή σου σε περιοδικά + και δες τα περιοδικά στα οποία έχεις εγγραφεί. +oauth2.grant.entry_comment.vote: Δώσε θετική ή αρνητική ψήφο ή ενίσχυσε οποιοδήποτε + σχόλιο σ' ένα νήμα. +oauth2.grant.entry_comment.report: Ανέφερε οποιοδήποτε σχόλιο σ' ένα νήμα. +oauth2.grant.magazine.all: Κάνε εγγραφή ή απέκλεισε περιοδικά και δες τα περιοδικά + στα οποία έχεις εγγραφεί ή απέκλεισέ τα. +oauth2.grant.post.create: Δημιούργησε νέες αναρτήσεις. +oauth2.grant.post.all: Δημιούργησε, επεξεργάσου ή διέγραψε τα μικροϊστολόγιά σου και + ψήφισε, ενίσχυσε ή ανέφερε οποιοδήποτε μικροϊστολόγιο. diff --git a/translations/messages.es.yaml b/translations/messages.es.yaml index 99a04dbcd..06455e626 100644 --- a/translations/messages.es.yaml +++ b/translations/messages.es.yaml @@ -6,7 +6,7 @@ type.smart_contract: Contrato inteligente type.magazine: Revista thread: Hilo threads: Hilos -microblog: Microblog +microblog: Nanoblogueo people: Gente events: Eventos magazine: Revista @@ -32,7 +32,7 @@ avatar: Avatar added: Añadido general: General created_at: Creado -owner: Propietario/a +owner: Propietari@ subscribers: Suscriptores down_votes: Votos negativos no_comments: No hay comentarios @@ -274,7 +274,7 @@ comment: Comentario post: Publicación ban_expired: Suspensión expirada purge: Eliminar -send_message: Enviar un mensaje +send_message: Enviar un mensaje directo message: Mensaje infinite_scroll: Desplazamiento infinito show_top_bar: Mostrar la barra superior @@ -532,3 +532,58 @@ marked_for_deletion_at: Marcado para eliminar el %date% sort_by: Ordenar por filter_by_subscription: Filtrar por suscripción filter_by_federation: Filtrar por estado de la federación +hidden: Oculto +disabled: Desactivado +edit_entry: Editar hilo +oauth2.grant.entry_comment.create: Crear nuevos comentarios en hilos. +oauth2.grant.entry_comment.delete: Elimina todos tus comentarios de los hilos. +enabled: Activado +downvotes_mode: Modo de votos negativos +unban_hashtag_description: Si eliminas la prohibición de un hashtag, se podrán volver + a crear publicaciones con este hashtag. Las publicaciones existentes con este hashtag + ya no estarán ocultas. +change_downvotes_mode: Cambiar la forma de votar negativamente +oauth2.grant.magazine.all: Suscríbete o bloquea revistas y mira las revistas a las + que estás suscrito o bloqueadas. +oauth2.grant.magazine.subscribe: Suscríbete o cancela tu suscripción a una revista + y consulta las revistas a las que estás suscrito. +oauth2.grant.post.report: Reportar cualquier publicación. +unban_hashtag_btn: Eliminar la prohibición de hashtags +ban_hashtag_description: Prohibir un hashtag impedirá que se creen publicaciones con + ese hashtag, además de ocultar las publicaciones existentes con ese hashtag. +account_deletion_immediate: Eliminar inmediatamente +account_deletion_button: Eliminar cuenta +private_instance: Obligar a los usuarios a iniciar sesión antes de poder acceder a + cualquier contenido +oauth2.grant.entry.edit: Edite tus hilos. +oauth2.grant.entry.report: Reportar cualquier hilo. +oauth2.grant.entry_comment.all: Crea, edita o elimina tus comentarios en hilos, y + vota, impulsa o denuncia cualquier comentario en un hilo. +oauth2.grant.entry_comment.vote: Vota a favor, impulsa o rechaza cualquier comentario + en un hilo. +oauth2.grant.magazine.block: Bloquea o desbloquea revistas y visualiza las revistas + que has bloqueado. +oauth2.grant.post.all: Crea, edita o elimina tus microblogs y vota, impulsa o denuncia + cualquier microblog. +oauth2.grant.post.create: Crear nuevas publicaciones. +oauth2.grant.post_comment.create: Crear nuevos comentarios en las publicaciones. +oauth2.grant.post_comment.delete: Elimina todos tus comentarios en las publicaciones. +oauth2.grant.post_comment.edit: Edita todos tus comentarios en las publicaciones. +oauth2.grant.entry.create: Crear nuevos hilos. +oauth2.grant.entry.vote: Vota a favor, impulsa o rechaza cualquier hilo. +oauth2.grant.entry.delete: Elimina tus hilos. +oauth2.grant.entry_comment.edit: Edita todos tus comentarios en los hilos. +oauth2.grant.post.vote: Voto a favor o en contra, o promoción de cualquier publicación. +oauth2.grant.entry.all: Crea, edita o elimina tus hilos y vota, impulsa o denuncia + cualquier hilo. +account_deletion_title: Eliminar la cuenta +oauth2.grant.post.edit: Edita todas tus publicaciones. +oauth2.grant.post.delete: Elimina todas tus publicaciones. +oauth2.grant.post_comment.all: Crea, edita o elimina tus comentarios en las publicaciones + y vota, impulsa o denuncia cualquier comentario en una publicación. +oauth2.grant.entry_comment.report: Reportar cualquier comentario en un hilo. +federation_page_dead_description: Casos en los que no pudimos realizar al menos 10 + actividades seguidas y donde la última entrega exitosa fue hace más de una semana +account_deletion_description: Tu cuenta se eliminará en 30 días a menos que elijas + eliminarla inmediatamente. Para recuperar tu cuenta en un plazo de 30 días, inicia + sesión con las mismas credenciales de usuario o comunícate con un administrador. diff --git a/translations/messages.fi.yaml b/translations/messages.fi.yaml index cd13a685a..140142457 100644 --- a/translations/messages.fi.yaml +++ b/translations/messages.fi.yaml @@ -169,7 +169,7 @@ top: Parhaimmat active: Aktiivinen newest: Uusimmat no_comments: Ei kommentteja -favourite: Suosikki +favourite: Suosi add_comment: Lisää kommentti remove_media: Poista media empty: Tyhjä @@ -279,3 +279,78 @@ random_posts: Satunnaiset viestit page_width_fixed: Kiinteä kbin_intro_desc: on hajautettu alusta sisällön yhteenkokoamiseen sekä mikrobloggaukseen, ja se toimii osana Fediverse-verkkoa. +show_profile_subscriptions: Näytä makasiinitilaukset +show_related_entries: Näytä satunnaisia ketjuja +show_related_posts: Näytä satunnaisia viestejä +filter_by_federation: Suodata federoinnin tilan mukaan +filter_by_time: Suodata ajan mukaan +subscribers_count: '{0}tilaajaa|{1}tilaaja|]1,Inf[ tilaajaa' +marked_for_deletion: Merkitty poistettavaksi +marked_for_deletion_at: Merkitty poistettavaksi %date% +subscriptions_in_own_sidebar: Erillisessä sivupalkissa +sidebars_same_side: Sivupalkit samalla puolella +type.magazine: Makasiini +magazine: Makasiini +magazines: Makasiinit +change_view: Vaihda näkymää +comments_count: '{0}kommenttia|{1}kommentti|]1,Inf[ kommenttia' +followers_count: '{0}seuraajaa|{1}seuraaja|]1,Inf[ seuraajaa' +filter_by_type: Suodata tyypin mukaan +filter_by_subscription: Suodata tilauksen mukaan +markdown_howto: Kuinka muokkain toimii? +related_posts: Asiaan liittyvät viestit +always_disconnected_magazine_info: Tämä makasiini ei vastaanota päivityksiä. +subscribe_for_updates: Tilaa vastaanottaaksesi päivityksiä. +all_magazines: Kaikki makasiinit +create_new_magazine: Luo uusi makasiini +useful: Hyödyllinen +down_vote: Vähennä +select_magazine: Valitse makasiini +followers: Seuraajat +go_to_content: Siirry sisältöön +go_to_filters: Siirry suodattimiin +go_to_search: Siirry hakuun +tree_view: Puunäkymä +chat_view: Keskustelunäkymä +table_view: Taulukkonäkymä +cards_view: Korttinäkymä +copy_url: Kopioi Mbin-osoite +copy_url_to_fediverse: Kopioi alkuperäinen osoite +show_magazines_icons: Näytä makasiinien kuvakkeet +subject_reported: Sisällöstä on ilmoitettu. +change_magazine: Vaihda makasiinia +related_magazines: Aiheeseen liittyvät makasiinit +random_magazines: Satunnaiset makasiinit +comment_reply_position: Kommentin vastauksen sijainti +subscription_header: TIlatut makasiinit +position_bottom: Alhaalla +position_top: Ylhäällä +flash_account_settings_changed: Tilisi asetukset on muutettu onnistuneesti. Sinun + täytyy kirjautua uudelleen sisään. +subscription_sort: Järjestä +alphabetically: Aakkosjärjestys +subscription_sidebar_pop_out_right: Siirrä erilliseen sivupalkkiin oikealle +subscription_sidebar_pop_out_left: Siirrä erilliseen sivupalkkiin vasemmalle +flash_user_edit_profile_error: Profiilin asetusten tallentaminen epäonnistui. +flash_user_settings_general_error: Käyttäjän asetusten tallentaminen epäonnistui. +magazine_deletion: Makasiinin poisto +delete_magazine: Poista makasiini +restore_magazine: Palauta makasiini +open_url_to_fediverse: Avaa alkuperäinen osoite +magazine_is_deleted: Makasiini on poistettu. Voit palauttaa + sen 30 päivän sisällä. +request_magazine_ownership: Pyydä makasiinin omistajuutta +accept: Hyväksy +abandoned: Hylätty +cancel_request: Peru pyyntö +sso_registrations_enabled: Kertakirjautumisrekisteröinnit käytössä +edited: muokattu +keywords: Avainsanat +notification_title_mention: Sinut mainittiin +notification_title_removed_comment: Kommentti poistettiin +notification_title_edited_comment: Kommenttia muokattiin +notification_title_removed_thread: Ketju poistettiin +notification_title_edited_thread: Ketjua muokattiin +show_related_magazines: Näytä satunnaisia makasiineja +new_user_description: Tämä käyttäjä on uusi (aktiivinen alle %days% päivää) +new_magazine_description: Tämä makasiini on uusi (aktiivinen alle %days% päivää) From db4f748d0d2f025c98b4257227b017fa027c7170 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 10 Sep 2024 15:22:51 +0000 Subject: [PATCH 255/335] docs(contributor): contributors readme action update (#1106) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Melroy van den Berg --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 48a6693ab..d2033c6b6 100644 --- a/README.md +++ b/README.md @@ -114,17 +114,17 @@ Unofficial magazines: - - cooperaj + + weblate
        - Adam Cooper + Weblate (bot)
        - - weblate + + cooperaj
        - Weblate (bot) + Adam Cooper
        From 24c8f55e32e8008c64ef3f2e0ca532e4f1a2459b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Sep 2024 20:56:00 +0200 Subject: [PATCH 256/335] Bump twig/twig from 3.11.0 to 3.11.1 in the composer group (#1107) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- composer.lock | 54 +++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/composer.lock b/composer.lock index ef5c4fd9f..85da6c8e0 100644 --- a/composer.lock +++ b/composer.lock @@ -11143,20 +11143,20 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c" + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fd22ab50000ef01661e2a31d850ebaa297f8e03c", - "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-mbstring": "*" @@ -11203,7 +11203,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" }, "funding": [ { @@ -11219,24 +11219,24 @@ "type": "tidelift" } ], - "time": "2024-06-19T12:30:46+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "77fa7995ac1b21ab60769b7323d600a991a90433" + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/77fa7995ac1b21ab60769b7323d600a991a90433", - "reference": "77fa7995ac1b21ab60769b7323d600a991a90433", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { @@ -11283,7 +11283,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" }, "funding": [ { @@ -11299,24 +11299,24 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php81", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "3fb075789fb91f9ad9af537c4012d523085bd5af" + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/3fb075789fb91f9ad9af537c4012d523085bd5af", - "reference": "3fb075789fb91f9ad9af537c4012d523085bd5af", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { @@ -11359,7 +11359,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0" }, "funding": [ { @@ -11375,7 +11375,7 @@ "type": "tidelift" } ], - "time": "2024-06-19T12:30:46+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php83", @@ -14787,16 +14787,16 @@ }, { "name": "twig/twig", - "version": "v3.11.0", + "version": "v3.11.1", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "e80fb8ebba85c7341a97a9ebf825d7fd4b77708d" + "reference": "ff063afc691e1cfda6714f1915ed766cb108d188" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/e80fb8ebba85c7341a97a9ebf825d7fd4b77708d", - "reference": "e80fb8ebba85c7341a97a9ebf825d7fd4b77708d", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/ff063afc691e1cfda6714f1915ed766cb108d188", + "reference": "ff063afc691e1cfda6714f1915ed766cb108d188", "shasum": "" }, "require": { @@ -14851,7 +14851,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.11.0" + "source": "https://github.com/twigphp/Twig/tree/v3.11.1" }, "funding": [ { @@ -14863,7 +14863,7 @@ "type": "tidelift" } ], - "time": "2024-08-08T16:15:16+00:00" + "time": "2024-09-10T10:40:14+00:00" }, { "name": "web-token/jwt-library", From 309aac66212c4592236c34a825d27d29ed91f9ff Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Wed, 11 Sep 2024 12:17:41 +0200 Subject: [PATCH 257/335] Fix the downvote error (#1110) --- src/Service/VoteManager.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Service/VoteManager.php b/src/Service/VoteManager.php index c846c560a..6b18aa958 100644 --- a/src/Service/VoteManager.php +++ b/src/Service/VoteManager.php @@ -13,6 +13,7 @@ use App\Entity\Vote; use App\Event\VoteEvent; use App\Factory\VoteFactory; +use App\Utils\DownvotesMode; use Doctrine\ORM\EntityManagerInterface; use Psr\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; @@ -43,6 +44,11 @@ public function vote(int $choice, VotableInterface $votable, User $user, $rateLi throw new AccessDeniedHttpException('Bots are not allowed to vote on items!'); } + $downVotesMode = $this->settingsManager->getDownvotesMode(); + if (DownvotesMode::Disabled === $downVotesMode && VotableInterface::VOTE_DOWN === $choice) { + throw new \LogicException('cannot downvote, because that is disabled'); + } + $vote = $votable->getUserVote($user); $votedAgain = false; @@ -65,7 +71,7 @@ public function vote(int $choice, VotableInterface $votable, User $user, $rateLi } $vote->choice = $choice; - } elseif (VotableInterface::VOTE_DOWN !== $choice) { + } else { if (VotableInterface::VOTE_UP === $choice) { return $this->upvote($votable, $user); } From 3498eb3395a2e3ce481f7ed5292068d81b6d83e0 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Wed, 11 Sep 2024 12:21:38 +0200 Subject: [PATCH 258/335] Clean-up push controller js (#1105) --- assets/controllers/push_controller.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/assets/controllers/push_controller.js b/assets/controllers/push_controller.js index aa09e8096..b30542e0a 100644 --- a/assets/controllers/push_controller.js +++ b/assets/controllers/push_controller.js @@ -7,17 +7,15 @@ export default class extends Controller { connect() { this.applicationServerPublicKey = this.element.dataset.applicationServerPublicKey - console.log("got application server public key", this.applicationServerPublicKey) window.navigator.serviceWorker.getRegistration() .then((registration) => { - console.log("got service worker registration", registration) return registration?.pushManager.getSubscription() }) .then(pushSubscription => { this.updateButtonVisibility(pushSubscription) }) .catch((error) => { - console.log("there was an error in the connect method", error) + console.error("There was an error in the service worker registration method", error) this.element.style.display = "none" }) From ac20a3284989345873711bba70f364634297b545 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Wed, 11 Sep 2024 13:41:05 +0200 Subject: [PATCH 259/335] Clean up push controller js even more (#1111) --- assets/controllers/push_controller.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/assets/controllers/push_controller.js b/assets/controllers/push_controller.js index b30542e0a..5808a49f1 100644 --- a/assets/controllers/push_controller.js +++ b/assets/controllers/push_controller.js @@ -74,7 +74,6 @@ export default class extends Controller { this.askPermission() .then(() => window.navigator.serviceWorker.getRegistration()) .then(registration => { - console.log("got service worker registration:", registration) const subscribeOptions = { userVisibleOnly: true, applicationServerKey: this.applicationServerPublicKey, @@ -83,10 +82,8 @@ export default class extends Controller { return registration.pushManager.subscribe(subscribeOptions) }) .then(pushSubscription => { - console.log("Received PushSubscription: ", JSON.stringify(pushSubscription)) this.updateButtonVisibility(pushSubscription) const jsonSub = pushSubscription.toJSON() - console.log("registering push to server") let payload = { endpoint: pushSubscription.endpoint, deviceKey: this.getDeviceKey(), @@ -104,9 +101,6 @@ export default class extends Controller { throw response } return response.json() - }) - .then(data => { - }) .catch(error => { console.error(error) @@ -120,7 +114,6 @@ export default class extends Controller { .then(pushSubscription => pushSubscription.unsubscribe()) .then((successful) => { if (successful) { - console.log("removed push subscription") this.updateButtonVisibility(null) let payload = { deviceKey: this.getDeviceKey(), @@ -135,6 +128,9 @@ export default class extends Controller { }) .catch(error => console.error(error)) } + }) + .catch((error) => { + console.error("There was an error in the service worker registration method, for unsubscribing", error) }) } From 882380256fb4e9383f02a18a1ac550553a441cde Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Wed, 11 Sep 2024 15:01:45 +0200 Subject: [PATCH 260/335] Add spoiler to markdown editor (#1108) Co-authored-by: BentiGorlich --- .../markdown_toolbar_controller.js | 39 +++++++++++++++++++ templates/components/editor_toolbar.html.twig | 7 +++- translations/messages.en.yaml | 1 + 3 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 assets/controllers/markdown_toolbar_controller.js diff --git a/assets/controllers/markdown_toolbar_controller.js b/assets/controllers/markdown_toolbar_controller.js new file mode 100644 index 000000000..a8a9717c6 --- /dev/null +++ b/assets/controllers/markdown_toolbar_controller.js @@ -0,0 +1,39 @@ +// SPDX-FileCopyrightText: 2023-2024 /kbin & Mbin contributors +// +// SPDX-License-Identifier: AGPL-3.0-only + +import { Controller } from '@hotwired/stimulus'; + +/* stimulusFetch: 'lazy' */ +export default class extends Controller { + addSpoiler(event) { + event.preventDefault(); + + const input = document.getElementById(this.element.getAttribute('for')); + let spoilerBody = 'spoiler body'; + let contentAfterCursor; + + const start = input.selectionStart; + const end = input.selectionEnd; + + const contentBeforeCursor = input.value.substring(0, start); + if (start === end) { + contentAfterCursor = input.value.substring(start); + } else { + contentAfterCursor = input.value.substring(end); + spoilerBody = input.value.substring(start, end); + } + + const spoiler = ` +::: spoiler spoiler-title +${spoilerBody} +:::`; + + input.value = contentBeforeCursor + spoiler + contentAfterCursor; + input.dispatchEvent(new Event('input')); + + const spoilerTitlePosition = contentBeforeCursor.length + '::: spoiler '.length + 1; + input.setSelectionRange(spoilerTitlePosition, spoilerTitlePosition); + input.focus(); + } +} diff --git a/templates/components/editor_toolbar.html.twig b/templates/components/editor_toolbar.html.twig index d6ba08cb7..31f6ddf26 100644 --- a/templates/components/editor_toolbar.html.twig +++ b/templates/components/editor_toolbar.html.twig @@ -1,10 +1,10 @@ - + - + @@ -32,4 +32,7 @@ + + + diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml index 73defe147..7ac3e3890 100644 --- a/translations/messages.en.yaml +++ b/translations/messages.en.yaml @@ -448,6 +448,7 @@ toolbar.image: Image toolbar.unordered_list: Unordered List toolbar.ordered_list: Ordered List toolbar.mention: Mention +toolbar.spoiler: Spoiler federation_page_enabled: Federation page enabled federation_page_allowed_description: Known instances we federate with federation_page_disallowed_description: Instances we do not federate with From a78998c7d8b6d2e807a058813208319cb9fadbed Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Wed, 11 Sep 2024 16:20:45 +0200 Subject: [PATCH 261/335] Fix some npm vulnerabilities (#1112) Co-authored-by: Melroy van den Berg --- package-lock.json | 123 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 97 insertions(+), 26 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7761d8f0d..8823c1b17 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4439,9 +4439,9 @@ } }, "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "dev": true, "license": "MIT", "dependencies": { @@ -4453,7 +4453,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.11.0", + "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -4490,6 +4490,22 @@ "dev": true, "license": "MIT" }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/bonjour-service": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", @@ -6171,38 +6187,38 @@ } }, "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/express/-/express-4.20.0.tgz", + "integrity": "sha512-pLdae7I6QqShF5PnNTCVn4hI91Dx0Grkn2+IAsMTgMIKuQVte2dN9PeGSSAME2FR8anOhVA62QDIUaWVfEXVLw==", "dev": true, "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.2", + "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "finalhandler": "1.2.0", "fresh": "0.5.2", "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", + "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", + "path-to-regexp": "0.1.10", "proxy-addr": "~2.0.7", "qs": "6.11.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "0.19.0", + "serve-static": "1.16.0", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", @@ -6223,6 +6239,16 @@ "ms": "2.0.0" } }, + "node_modules/express/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/express/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -7858,11 +7884,14 @@ } }, "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/merge-stream": { "version": "2.0.0", @@ -8497,9 +8526,9 @@ "license": "MIT" }, "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", "dev": true, "license": "MIT" }, @@ -9856,9 +9885,9 @@ } }, "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "dev": true, "license": "MIT", "dependencies": { @@ -9994,9 +10023,9 @@ } }, "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.0.tgz", + "integrity": "sha512-pDLK8zwl2eKaYrs8mrPZBJua4hMplRWJ1tIFksVC3FtBEBnl8dxgeHtsaMS8DhS9i4fLObaon6ABoc4/hQGdPA==", "dev": true, "license": "MIT", "dependencies": { @@ -10009,6 +10038,48 @@ "node": ">= 0.8.0" } }, + "node_modules/serve-static/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-static/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/serve-static/node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", From 9867a35f2b87e8cb60f8af090bb15f3fe2b1fac3 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Wed, 11 Sep 2024 18:15:40 +0200 Subject: [PATCH 262/335] Translations update from Hosted Weblate (#1113) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Λευτέρης Τ Co-authored-by: Melroy van den Berg --- translations/messages.el.yaml | 7 +++++++ translations/messages.nl.yaml | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/translations/messages.el.yaml b/translations/messages.el.yaml index a79a3a4df..af0aa90fc 100644 --- a/translations/messages.el.yaml +++ b/translations/messages.el.yaml @@ -588,3 +588,10 @@ oauth2.grant.magazine.all: Κάνε εγγραφή ή απέκλεισε περ oauth2.grant.post.create: Δημιούργησε νέες αναρτήσεις. oauth2.grant.post.all: Δημιούργησε, επεξεργάσου ή διέγραψε τα μικροϊστολόγιά σου και ψήφισε, ενίσχυσε ή ανέφερε οποιοδήποτε μικροϊστολόγιο. +oauth2.grant.post.vote: Ψήφισε θετικά ή αρνητικά, ενίσχυσε οποιαδήποτε ανάρτηση. +oauth2.grant.post.report: Ανέφερε οποιαδήποτε ανάρτηση. +oauth2.grant.post_comment.edit: Επεξεργάσου τα υπάρχοντα σχόλιά σου σε αναρτήσεις. +oauth2.grant.post_comment.delete: Διέγραψε τα υπάρχοντα σχόλιά σου σε αναρτήσεις. +oauth2.grant.post_comment.all: Δημιούργησε, επεξεργάσου ή διέγραψε τα σχόλιά σου σε + αναρτήσεις και ψήφισε, ενίσχυσε ή να ανέφερε οποιοδήποτε σχόλιο σε με μια ανάρτηση. +oauth2.grant.post_comment.create: Δημιούργησε νέα σχόλια σε αναρτήσεις. diff --git a/translations/messages.nl.yaml b/translations/messages.nl.yaml index b15444e84..9461dda06 100644 --- a/translations/messages.nl.yaml +++ b/translations/messages.nl.yaml @@ -926,3 +926,9 @@ admin_users_active: Actief admin_users_inactive: Inactief admin_users_suspended: Opgeschort edit_entry: Bewerk gesprek +downvotes_mode: Omlaagstem-modus +change_downvotes_mode: Wijzig omlaagstem modus +disabled: Uitgeschakeld +hidden: Verborgen +enabled: Ingeschakeld +toolbar.spoiler: Spoiler From 88e8ae35312236169de0b6cbcbb730776e51d873 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Wed, 11 Sep 2024 22:45:03 +0200 Subject: [PATCH 263/335] Also check if filePath is not null (#1114) --- templates/layout/_magazine_activity_list.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/layout/_magazine_activity_list.html.twig b/templates/layout/_magazine_activity_list.html.twig index 50b908fcd..bd2d9bda7 100644 --- a/templates/layout/_magazine_activity_list.html.twig +++ b/templates/layout/_magazine_activity_list.html.twig @@ -7,7 +7,7 @@
          {% for subject in list %}
        • - {% if attribute(subject, actor).icon and (app.user or attribute(subject, actor).isAdult is same as false) %} + {% if attribute(subject, actor).icon and attribute(subject, actor).icon.filePath and (app.user or attribute(subject, actor).isAdult is same as false) %}
          Date: Thu, 12 Sep 2024 19:14:01 +0200 Subject: [PATCH 264/335] Null error on reported post comment notifications (#1118) --- templates/notifications/_blocks.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/notifications/_blocks.html.twig b/templates/notifications/_blocks.html.twig index 47c616867..4e9a157e4 100644 --- a/templates/notifications/_blocks.html.twig +++ b/templates/notifications/_blocks.html.twig @@ -119,7 +119,7 @@ {% elseif notification.report.postComment is defined and notification.report.postComment is not same as null %} {% set postComment = notification.report.postComment %} - {{ post.getShortTitle() }} + {{ postComment.getShortTitle() }} {% endif %} {% endblock %} From a8b8af19c8b131228ee15bf12ef005a5be863888 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Thu, 12 Sep 2024 20:43:41 +0200 Subject: [PATCH 265/335] Fix 3rd miscellaneous bug (#1120) --- src/Service/ActivityPubManager.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Service/ActivityPubManager.php b/src/Service/ActivityPubManager.php index 7b3f11062..b432d8291 100644 --- a/src/Service/ActivityPubManager.php +++ b/src/Service/ActivityPubManager.php @@ -551,7 +551,7 @@ public function updateMagazine(string $actorUrl): ?Magazine $magazine->apInboxUrl = $actor['endpoints']['sharedInbox'] ?? $actor['inbox']; $magazine->apDomain = parse_url($actor['id'], PHP_URL_HOST); $magazine->apFollowersUrl = $actor['followers'] ?? null; - $magazine->apAttributedToUrl = \is_string($actor['attributedTo']) ? $actor['attributedTo'] : null; + $magazine->apAttributedToUrl = isset($actor['attributedTo']) && \is_string($actor['attributedTo']) ? $actor['attributedTo'] : null; $magazine->apFeaturedUrl = $actor['featured'] ?? null; $magazine->apPreferredUsername = $actor['preferredUsername'] ?? null; $magazine->apDiscoverable = $actor['discoverable'] ?? true; @@ -579,7 +579,7 @@ public function updateMagazine(string $actorUrl): ?Magazine $this->handleModeratorCollection($actorUrl, $magazine); } catch (InvalidArgumentException $ignored) { } - } elseif (\is_array($actor['attributedTo'])) { + } elseif (isset($actor['attributedTo']) && \is_array($actor['attributedTo'])) { $this->handleModeratorArray($magazine, $this->getActorFromAttributedTo($actor['attributedTo'])); } From 4da5315de86aa9e97ffb2a455de92d4b7e1fe4f3 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Thu, 12 Sep 2024 20:45:13 +0200 Subject: [PATCH 266/335] Fix 4th miscellaneous bug (#1121) --- src/Service/ActivityPub/SignatureValidator.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Service/ActivityPub/SignatureValidator.php b/src/Service/ActivityPub/SignatureValidator.php index 84eda3481..e30a094e4 100644 --- a/src/Service/ActivityPub/SignatureValidator.php +++ b/src/Service/ActivityPub/SignatureValidator.php @@ -113,7 +113,11 @@ public function validate(array $request, array $headers, string $body): void $user = $this->activityPubManager->findActorOrCreate($actorUrl); if (!empty($user)) { - $pkey = openssl_pkey_get_public($this->client->getActorObject($user->apProfileId)['publicKey']['publicKeyPem']); + $pem = $this->client->getActorObject($user->apProfileId)['publicKey']['publicKeyPem'] ?? null; + if (null === $pem) { + throw new InvalidUserPublicKeyException($user->apProfileId); + } + $pkey = openssl_pkey_get_public($pem); if (false === $pkey) { throw new InvalidUserPublicKeyException($user->apProfileId); From f415e54ff9d4ce783d7bf7913481927d2944c724 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Thu, 12 Sep 2024 20:47:09 +0200 Subject: [PATCH 267/335] Fix 7th miscellaneous bug (#1123) --- src/MessageHandler/ActivityPub/Inbox/ChainActivityHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MessageHandler/ActivityPub/Inbox/ChainActivityHandler.php b/src/MessageHandler/ActivityPub/Inbox/ChainActivityHandler.php index 70c55acd2..ea2683c84 100644 --- a/src/MessageHandler/ActivityPub/Inbox/ChainActivityHandler.php +++ b/src/MessageHandler/ActivityPub/Inbox/ChainActivityHandler.php @@ -68,7 +68,7 @@ public function doWork(MessageInterface $message): void $entity = $this->retrieveObject($object['id']); if (!$entity) { - $this->logger->error('could not retrieve all the dependencies of {o}', ['o' => $object]); + $this->logger->error('could not retrieve all the dependencies of {o}', ['o' => $object['id']]); return; } From 822ed4634ad2be7b8d5f28cb8eb5a15ca21bf3e5 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Thu, 12 Sep 2024 20:48:46 +0200 Subject: [PATCH 268/335] Fix 2nd miscellaneous bug (#1124) --- src/Service/ActivityPub/Page.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Service/ActivityPub/Page.php b/src/Service/ActivityPub/Page.php index ca80a0b63..b929a1829 100644 --- a/src/Service/ActivityPub/Page.php +++ b/src/Service/ActivityPub/Page.php @@ -51,6 +51,10 @@ public function __construct( */ public function create(array $object, bool $stickyIt = false): Entry { + $current = $this->repository->findByObjectId($object['id']); + if ($current) { + return $this->entityManager->getRepository($current['type'])->find((int) $current['id']); + } $actorUrl = $this->activityPubManager->getSingleActorFromAttributedTo($object['attributedTo']); if ($this->settingsManager->isBannedInstance($actorUrl)) { throw new InstanceBannedException(); From 30cbcfd404ce16dd34a92bce151bee57db913f50 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Thu, 12 Sep 2024 20:50:25 +0200 Subject: [PATCH 269/335] Fix 6th miscellaneous bug (#1125) --- .../ActivityPub/Inbox/ChainActivityHandler.php | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/MessageHandler/ActivityPub/Inbox/ChainActivityHandler.php b/src/MessageHandler/ActivityPub/Inbox/ChainActivityHandler.php index ea2683c84..d1e9d1796 100644 --- a/src/MessageHandler/ActivityPub/Inbox/ChainActivityHandler.php +++ b/src/MessageHandler/ActivityPub/Inbox/ChainActivityHandler.php @@ -23,6 +23,7 @@ use App\Service\ActivityPub\ApHttpClient; use App\Service\ActivityPub\Note; use App\Service\ActivityPub\Page; +use App\Service\SettingsManager; use Doctrine\ORM\EntityManagerInterface; use Psr\Log\LoggerInterface; use Symfony\Component\Messenger\Attribute\AsMessageHandler; @@ -38,7 +39,8 @@ public function __construct( private readonly MessageBusInterface $bus, private readonly ApActivityRepository $repository, private readonly Note $note, - private readonly Page $page + private readonly Page $page, + private readonly SettingsManager $settingsManager, ) { parent::__construct($this->entityManager); } @@ -64,8 +66,13 @@ public function doWork(MessageInterface $message): void return; } + try { + $entity = $this->retrieveObject($object['id']); + } catch (InstanceBannedException) { + $this->logger->info('the instance is banned, url: {url}', ['url' => $object['id']]); - $entity = $this->retrieveObject($object['id']); + return; + } if (!$entity) { $this->logger->error('could not retrieve all the dependencies of {o}', ['o' => $object['id']]); @@ -91,6 +98,9 @@ public function doWork(MessageInterface $message): void */ private function retrieveObject(string $apUrl): Entry|EntryComment|Post|PostComment|null { + if ($this->settingsManager->isBannedInstance($apUrl)) { + throw new InstanceBannedException(); + } try { $object = $this->client->getActivityObject($apUrl); if (!$object) { @@ -141,8 +151,8 @@ private function retrieveObject(string $apUrl): Entry|EntryComment|Post|PostComm $this->logger->info('one of the used tags is banned, url: {url}', ['url' => $apUrl]); } catch (EntityNotFoundException $e) { $this->logger->error('There was an exception while getting {url}: {ex} - {m}. {o}', ['url' => $apUrl, 'ex' => \get_class($e), 'm' => $e->getMessage(), 'o' => $e]); - } catch (InstanceBannedException $e) { - $this->logger->info('the user\'s instance is banned, url: {url}', ['url' => $apUrl]); + } catch (InstanceBannedException) { + $this->logger->info('the instance is banned, url: {url}', ['url' => $apUrl]); } return null; From b12adeb5fb0908fb8856ee2d599b66a1e9c72d65 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Thu, 12 Sep 2024 20:56:20 +0200 Subject: [PATCH 270/335] Fix 9th miscellaneous bug (#1122) --- src/Service/ActivityPubManager.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Service/ActivityPubManager.php b/src/Service/ActivityPubManager.php index b432d8291..ec10cf293 100644 --- a/src/Service/ActivityPubManager.php +++ b/src/Service/ActivityPubManager.php @@ -284,10 +284,14 @@ public function buildHandle(string $id): string $port = !\is_null(parse_url($id, PHP_URL_PORT)) ? ':'.parse_url($id, PHP_URL_PORT) : ''; + $apObj = $this->apHttpClient->getActorObject($id); + if (!isset($apObj['preferredUsername'])) { + throw new \InvalidArgumentException("webfinger from $id does not supply a valid user object"); + } return \sprintf( '%s@%s%s', - $this->apHttpClient->getActorObject($id)['preferredUsername'], + $apObj['preferredUsername'], parse_url($id, PHP_URL_HOST), $port ); From e07c08a6b08b5cf7bc20ebeb2c5800c13e709564 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Fri, 13 Sep 2024 09:08:45 +0200 Subject: [PATCH 271/335] Fix null error when an instance does not have a nodeinfo endpoint (#1117) Co-authored-by: Melroy van den Berg --- src/Service/RemoteInstanceManager.php | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Service/RemoteInstanceManager.php b/src/Service/RemoteInstanceManager.php index b7f0f353c..2eae931c9 100644 --- a/src/Service/RemoteInstanceManager.php +++ b/src/Service/RemoteInstanceManager.php @@ -35,16 +35,18 @@ public function updateInstance(Instance $instance, bool $force = false): bool if ($instance->getUpdatedAt() < new \DateTime('now - 1day') || $force) { $nodeInfoEndpointsRaw = $this->client->fetchInstanceNodeInfoEndpoints($instance->domain, false); $serializer = $this->getSerializer(); - /** @var WellKnownNodeInfo $nodeInfoEndpoints */ - $nodeInfoEndpoints = $serializer->deserialize($nodeInfoEndpointsRaw, WellKnownNodeInfo::class, 'json'); - $linkToUse = null; - foreach ($nodeInfoEndpoints->links as $link) { - if (NodeInfoController::NODE_REL_v21 === $link->rel) { - $linkToUse = $link; - break; - } elseif (null === $linkToUse && NodeInfoController::NODE_REL_v20 === $link->rel) { - $linkToUse = $link; + if (null !== $nodeInfoEndpointsRaw) { + /** @var WellKnownNodeInfo $nodeInfoEndpoints */ + $nodeInfoEndpoints = $serializer->deserialize($nodeInfoEndpointsRaw, WellKnownNodeInfo::class, 'json'); + + foreach ($nodeInfoEndpoints->links as $link) { + if (NodeInfoController::NODE_REL_v21 === $link->rel) { + $linkToUse = $link; + break; + } elseif (null === $linkToUse && NodeInfoController::NODE_REL_v20 === $link->rel) { + $linkToUse = $link; + } } } From 36927bb5329dbb2929843cb26880ea0ef197b8fc Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Fri, 13 Sep 2024 12:16:32 +0200 Subject: [PATCH 272/335] Update composer PHP depedencies (#1101) --- composer.json | 14 +- composer.lock | 1709 ++++++++--------- .../User/Profile/User2FAController.php | 8 +- symfony.lock | 9 - 4 files changed, 832 insertions(+), 908 deletions(-) diff --git a/composer.json b/composer.json index f44a0eb81..13d4ad19d 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,7 @@ "doctrine/doctrine-migrations-bundle": "^3.3.1", "doctrine/orm": "^2.19.6", "embed/embed": "^4.4.12", - "endroid/qr-code": "^4.8.5", + "endroid/qr-code": "^5.1.0", "friendsofsymfony/jsrouting-bundle": "^3.5.0", "furqansiddiqui/bip39-mnemonic-php": "^0.1.7", "gmostafa/php-graphql-client": "^1.13", @@ -33,8 +33,6 @@ "knplabs/knp-time-bundle": "^2.4.0", "knpuniversity/oauth2-client-bundle": "^2.18.1", "kornrunner/blurhash": "^1.2.2", - "laminas/laminas-diactoros": "^2.26.0", - "landrok/activitypub": "^0.5.8", "league/commonmark": "^2.5.1", "league/flysystem-aws-s3-v3": "^3.28.0", "league/html-to-markdown": "^5.1.1", @@ -51,7 +49,7 @@ "nyholm/psr7": "^1.8.1", "omines/antispam-bundle": "^0.1.8", "oneup/flysystem-bundle": "^4.12.2", - "pagerfanta/core": "^3.8.0", + "pagerfanta/core": "^4.7.0", "pagerfanta/doctrine-collections-adapter": "^4.6.0", "pagerfanta/doctrine-dbal-adapter": "^4.6.0", "pagerfanta/doctrine-orm-adapter": "^4.6.0", @@ -63,7 +61,7 @@ "scheb/2fa-backup-code": "^7.5.0", "scheb/2fa-bundle": "^7.5.0", "scheb/2fa-totp": "^7.5.0", - "scienta/doctrine-json-functions": "^5.5.0", + "scienta/doctrine-json-functions": "^6.1.0", "stevenmaguire/oauth2-keycloak": "^5.1.0", "symfony/amqp-messenger": "7.1.*", "symfony/asset": "7.1.*", @@ -119,12 +117,12 @@ "dama/doctrine-test-bundle": "^8.2.0", "doctrine/doctrine-fixtures-bundle": "^3.6.1", "fakerphp/faker": "^1.23.1", - "justinrainbow/json-schema": "^5.3.0", + "justinrainbow/json-schema": "^6.0.0", "phpstan/phpstan": "^1.11.9", - "phpunit/phpunit": "^10.5.29", + "phpunit/phpunit": "^11.3.4", "symfony/browser-kit": "7.1.*", "symfony/debug-bundle": "7.1.*", - "symfony/maker-bundle": "1.60.0", + "symfony/maker-bundle": "1.61.0", "symfony/phpunit-bridge": "7.1.*", "symfony/stopwatch": "7.1.*", "symfony/web-profiler-bundle": "7.1.*" diff --git a/composer.lock b/composer.lock index 85da6c8e0..a676396d8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f4d9c1ae81fa4d1f914079c0ac2c53d1", + "content-hash": "7ed49456d146886c9e0644e6f2fd03ba", "packages": [ { "name": "aws/aws-crt-php", @@ -62,16 +62,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.320.2", + "version": "3.321.7", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "dbae075b861316237d63418715f8bf4bfdd9d33d" + "reference": "c64ee32d80ec2ab5d8d6a0b77297c2d69602ef3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/dbae075b861316237d63418715f8bf4bfdd9d33d", - "reference": "dbae075b861316237d63418715f8bf4bfdd9d33d", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/c64ee32d80ec2ab5d8d6a0b77297c2d69602ef3b", + "reference": "c64ee32d80ec2ab5d8d6a0b77297c2d69602ef3b", "shasum": "" }, "require": { @@ -154,9 +154,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.320.2" + "source": "https://github.com/aws/aws-sdk-php/tree/3.321.7" }, - "time": "2024-08-16T18:06:17+00:00" + "time": "2024-09-09T18:09:23+00:00" }, { "name": "babdev/pagerfanta-bundle", @@ -247,28 +247,28 @@ }, { "name": "bacon/bacon-qr-code", - "version": "2.0.8", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/Bacon/BaconQrCode.git", - "reference": "8674e51bb65af933a5ffaf1c308a660387c35c22" + "reference": "510de6eca6248d77d31b339d62437cc995e2fb41" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/8674e51bb65af933a5ffaf1c308a660387c35c22", - "reference": "8674e51bb65af933a5ffaf1c308a660387c35c22", + "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/510de6eca6248d77d31b339d62437cc995e2fb41", + "reference": "510de6eca6248d77d31b339d62437cc995e2fb41", "shasum": "" }, "require": { "dasprid/enum": "^1.0.3", "ext-iconv": "*", - "php": "^7.1 || ^8.0" + "php": "^8.1" }, "require-dev": { - "phly/keep-a-changelog": "^2.1", - "phpunit/phpunit": "^7 | ^8 | ^9", - "spatie/phpunit-snapshot-assertions": "^4.2.9", - "squizlabs/php_codesniffer": "^3.4" + "phly/keep-a-changelog": "^2.12", + "phpunit/phpunit": "^10.5.11 || 11.0.4", + "spatie/phpunit-snapshot-assertions": "^5.1.5", + "squizlabs/php_codesniffer": "^3.9" }, "suggest": { "ext-imagick": "to generate QR code images" @@ -295,9 +295,9 @@ "homepage": "https://github.com/Bacon/BaconQrCode", "support": { "issues": "https://github.com/Bacon/BaconQrCode/issues", - "source": "https://github.com/Bacon/BaconQrCode/tree/2.0.8" + "source": "https://github.com/Bacon/BaconQrCode/tree/v3.0.0" }, - "time": "2022-12-07T17:46:57+00:00" + "time": "2024-04-18T11:16:25+00:00" }, { "name": "brick/math", @@ -752,16 +752,16 @@ }, { "name": "doctrine/annotations", - "version": "2.0.1", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f" + "reference": "901c2ee5d26eb64ff43c47976e114bf00843acf7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f", - "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/901c2ee5d26eb64ff43c47976e114bf00843acf7", + "reference": "901c2ee5d26eb64ff43c47976e114bf00843acf7", "shasum": "" }, "require": { @@ -773,10 +773,10 @@ "require-dev": { "doctrine/cache": "^2.0", "doctrine/coding-standard": "^10", - "phpstan/phpstan": "^1.8.0", + "phpstan/phpstan": "^1.10.28", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "symfony/cache": "^5.4 || ^6", - "vimeo/psalm": "^4.10" + "symfony/cache": "^5.4 || ^6.4 || ^7", + "vimeo/psalm": "^4.30 || ^5.14" }, "suggest": { "php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations" @@ -822,9 +822,9 @@ ], "support": { "issues": "https://github.com/doctrine/annotations/issues", - "source": "https://github.com/doctrine/annotations/tree/2.0.1" + "source": "https://github.com/doctrine/annotations/tree/2.0.2" }, - "time": "2023-02-02T22:02:53+00:00" + "time": "2024-09-05T10:17:24+00:00" }, { "name": "doctrine/cache", @@ -1098,16 +1098,16 @@ }, { "name": "doctrine/dbal", - "version": "3.9.0", + "version": "3.9.1", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "d8f68ea6cc00912e5313237130b8c8decf4d28c6" + "reference": "d7dc08f98cba352b2bab5d32c5e58f7e745c11a7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/d8f68ea6cc00912e5313237130b8c8decf4d28c6", - "reference": "d8f68ea6cc00912e5313237130b8c8decf4d28c6", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/d7dc08f98cba352b2bab5d32c5e58f7e745c11a7", + "reference": "d7dc08f98cba352b2bab5d32c5e58f7e745c11a7", "shasum": "" }, "require": { @@ -1123,7 +1123,7 @@ "doctrine/coding-standard": "12.0.0", "fig/log-test": "^1", "jetbrains/phpstorm-stubs": "2023.1", - "phpstan/phpstan": "1.11.7", + "phpstan/phpstan": "1.12.0", "phpstan/phpstan-strict-rules": "^1.6", "phpunit/phpunit": "9.6.20", "psalm/plugin-phpunit": "0.18.4", @@ -1191,7 +1191,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.9.0" + "source": "https://github.com/doctrine/dbal/tree/3.9.1" }, "funding": [ { @@ -1207,7 +1207,7 @@ "type": "tidelift" } ], - "time": "2024-08-15T07:34:42+00:00" + "time": "2024-09-01T13:49:23+00:00" }, { "name": "doctrine/deprecations", @@ -1258,16 +1258,16 @@ }, { "name": "doctrine/doctrine-bundle", - "version": "2.12.0", + "version": "2.13.0", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineBundle.git", - "reference": "5418e811a14724068e95e0ba43353b903ada530f" + "reference": "ca59d84b8e63143ce1aed90cdb333ba329d71563" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/5418e811a14724068e95e0ba43353b903ada530f", - "reference": "5418e811a14724068e95e0ba43353b903ada530f", + "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/ca59d84b8e63143ce1aed90cdb333ba329d71563", + "reference": "ca59d84b8e63143ce1aed90cdb333ba329d71563", "shasum": "" }, "require": { @@ -1358,7 +1358,7 @@ ], "support": { "issues": "https://github.com/doctrine/DoctrineBundle/issues", - "source": "https://github.com/doctrine/DoctrineBundle/tree/2.12.0" + "source": "https://github.com/doctrine/DoctrineBundle/tree/2.13.0" }, "funding": [ { @@ -1374,7 +1374,7 @@ "type": "tidelift" } ], - "time": "2024-03-19T07:20:37+00:00" + "time": "2024-09-01T09:46:40+00:00" }, { "name": "doctrine/doctrine-migrations-bundle", @@ -1799,16 +1799,16 @@ }, { "name": "doctrine/migrations", - "version": "3.8.0", + "version": "3.8.1", "source": { "type": "git", "url": "https://github.com/doctrine/migrations.git", - "reference": "535a70dcbd88b8c6ba945be050977457f4f4c06c" + "reference": "7760fbd0b7cb58bfb50415505a7bab821adf0877" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/migrations/zipball/535a70dcbd88b8c6ba945be050977457f4f4c06c", - "reference": "535a70dcbd88b8c6ba945be050977457f4f4c06c", + "url": "https://api.github.com/repos/doctrine/migrations/zipball/7760fbd0b7cb58bfb50415505a7bab821adf0877", + "reference": "7760fbd0b7cb58bfb50415505a7bab821adf0877", "shasum": "" }, "require": { @@ -1831,6 +1831,7 @@ "doctrine/persistence": "^2 || ^3", "doctrine/sql-formatter": "^1.0", "ext-pdo_sqlite": "*", + "fig/log-test": "^1", "phpstan/phpstan": "^1.10", "phpstan/phpstan-deprecation-rules": "^1.1", "phpstan/phpstan-phpunit": "^1.3", @@ -1881,7 +1882,7 @@ ], "support": { "issues": "https://github.com/doctrine/migrations/issues", - "source": "https://github.com/doctrine/migrations/tree/3.8.0" + "source": "https://github.com/doctrine/migrations/tree/3.8.1" }, "funding": [ { @@ -1897,20 +1898,20 @@ "type": "tidelift" } ], - "time": "2024-06-26T14:12:46+00:00" + "time": "2024-08-28T13:17:28+00:00" }, { "name": "doctrine/orm", - "version": "2.19.6", + "version": "2.19.7", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "c1bb2ccf4b19c845f91ff7c4c01dc7cbba7f4073" + "reference": "168ac31084226f94d42e7461a40ff5607a56bd35" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/c1bb2ccf4b19c845f91ff7c4c01dc7cbba7f4073", - "reference": "c1bb2ccf4b19c845f91ff7c4c01dc7cbba7f4073", + "url": "https://api.github.com/repos/doctrine/orm/zipball/168ac31084226f94d42e7461a40ff5607a56bd35", + "reference": "168ac31084226f94d42e7461a40ff5607a56bd35", "shasum": "" }, "require": { @@ -1996,9 +1997,9 @@ ], "support": { "issues": "https://github.com/doctrine/orm/issues", - "source": "https://github.com/doctrine/orm/tree/2.19.6" + "source": "https://github.com/doctrine/orm/tree/2.19.7" }, - "time": "2024-06-26T17:24:40+00:00" + "time": "2024-08-23T06:54:57+00:00" }, { "name": "doctrine/persistence", @@ -2310,29 +2311,26 @@ }, { "name": "endroid/qr-code", - "version": "4.8.5", + "version": "5.1.0", "source": { "type": "git", "url": "https://github.com/endroid/qr-code.git", - "reference": "0db25b506a8411a5e1644ebaa67123a6eb7b6a77" + "reference": "393fec6c4cbdc1bd65570ac9d245704428010122" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/endroid/qr-code/zipball/0db25b506a8411a5e1644ebaa67123a6eb7b6a77", - "reference": "0db25b506a8411a5e1644ebaa67123a6eb7b6a77", + "url": "https://api.github.com/repos/endroid/qr-code/zipball/393fec6c4cbdc1bd65570ac9d245704428010122", + "reference": "393fec6c4cbdc1bd65570ac9d245704428010122", "shasum": "" }, "require": { - "bacon/bacon-qr-code": "^2.0.5", + "bacon/bacon-qr-code": "^3.0", "php": "^8.1" }, - "conflict": { - "khanamiryan/qrcode-detector-decoder": "^1.0.6" - }, "require-dev": { - "endroid/quality": "dev-master", + "endroid/quality": "dev-main", "ext-gd": "*", - "khanamiryan/qrcode-detector-decoder": "^1.0.4||^2.0.2", + "khanamiryan/qrcode-detector-decoder": "^2.0.2", "setasign/fpdf": "^1.8.2" }, "suggest": { @@ -2344,7 +2342,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.x-dev" + "dev-main": "5.x-dev" } }, "autoload": { @@ -2373,7 +2371,7 @@ ], "support": { "issues": "https://github.com/endroid/qr-code/issues", - "source": "https://github.com/endroid/qr-code/tree/4.8.5" + "source": "https://github.com/endroid/qr-code/tree/5.1.0" }, "funding": [ { @@ -2381,7 +2379,7 @@ "type": "github" } ], - "time": "2023-09-29T14:03:20+00:00" + "time": "2024-09-08T08:52:55+00:00" }, { "name": "firebase/php-jwt", @@ -3247,152 +3245,6 @@ }, "time": "2022-07-13T19:38:39+00:00" }, - { - "name": "laminas/laminas-diactoros", - "version": "2.26.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-diactoros.git", - "reference": "6584d44eb8e477e89d453313b858daac6183cddc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/6584d44eb8e477e89d453313b858daac6183cddc", - "reference": "6584d44eb8e477e89d453313b858daac6183cddc", - "shasum": "" - }, - "require": { - "php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0", - "psr/http-factory": "^1.0", - "psr/http-message": "^1.1" - }, - "conflict": { - "zendframework/zend-diactoros": "*" - }, - "provide": { - "psr/http-factory-implementation": "1.0", - "psr/http-message-implementation": "1.0" - }, - "require-dev": { - "ext-curl": "*", - "ext-dom": "*", - "ext-gd": "*", - "ext-libxml": "*", - "http-interop/http-factory-tests": "^0.9.0", - "laminas/laminas-coding-standard": "^2.5", - "php-http/psr7-integration-tests": "^1.2", - "phpunit/phpunit": "^9.5.28", - "psalm/plugin-phpunit": "^0.18.4", - "vimeo/psalm": "^5.6" - }, - "type": "library", - "extra": { - "laminas": { - "config-provider": "Laminas\\Diactoros\\ConfigProvider", - "module": "Laminas\\Diactoros" - } - }, - "autoload": { - "files": [ - "src/functions/create_uploaded_file.php", - "src/functions/marshal_headers_from_sapi.php", - "src/functions/marshal_method_from_sapi.php", - "src/functions/marshal_protocol_version_from_sapi.php", - "src/functions/marshal_uri_from_sapi.php", - "src/functions/normalize_server.php", - "src/functions/normalize_uploaded_files.php", - "src/functions/parse_cookie_header.php", - "src/functions/create_uploaded_file.legacy.php", - "src/functions/marshal_headers_from_sapi.legacy.php", - "src/functions/marshal_method_from_sapi.legacy.php", - "src/functions/marshal_protocol_version_from_sapi.legacy.php", - "src/functions/marshal_uri_from_sapi.legacy.php", - "src/functions/normalize_server.legacy.php", - "src/functions/normalize_uploaded_files.legacy.php", - "src/functions/parse_cookie_header.legacy.php" - ], - "psr-4": { - "Laminas\\Diactoros\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "PSR HTTP Message implementations", - "homepage": "https://laminas.dev", - "keywords": [ - "http", - "laminas", - "psr", - "psr-17", - "psr-7" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-diactoros/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-diactoros/issues", - "rss": "https://github.com/laminas/laminas-diactoros/releases.atom", - "source": "https://github.com/laminas/laminas-diactoros" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2023-10-29T16:17:44+00:00" - }, - { - "name": "landrok/activitypub", - "version": "0.5.8", - "source": { - "type": "git", - "url": "https://github.com/landrok/activitypub.git", - "reference": "f30b8f726cf1a196337ec065536eba2d66a4b329" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/landrok/activitypub/zipball/f30b8f726cf1a196337ec065536eba2d66a4b329", - "reference": "f30b8f726cf1a196337ec065536eba2d66a4b329", - "shasum": "" - }, - "require": { - "guzzlehttp/guzzle": ">=6.3", - "monolog/monolog": "^1.12|^2.0|^3.0", - "php": "^7.2|^8.0", - "phpseclib/phpseclib": "^3.0.7", - "psr/cache": "^1.0|^2.0|^3.0", - "symfony/cache": ">=4.0", - "symfony/http-foundation": ">=3.4" - }, - "require-dev": { - "phpunit/phpunit": "*" - }, - "type": "library", - "autoload": { - "psr-4": { - "ActivityPhp\\": "src/ActivityPhp/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A PHP implementation of ActivityPub protocol based upon the ActivityStreams 2.0 data format.", - "homepage": "https://github.com/landrok/activitypub", - "keywords": [ - "Federation", - "activitypub", - "activitystreams" - ], - "support": { - "issues": "https://github.com/landrok/activitypub/issues", - "source": "https://github.com/landrok/activitypub/tree/0.5.8" - }, - "time": "2022-06-07T11:22:35+00:00" - }, { "name": "lcobucci/clock", "version": "3.2.0", @@ -4232,16 +4084,16 @@ }, { "name": "league/oauth2-github", - "version": "3.1.0", + "version": "3.1.1", "source": { "type": "git", "url": "https://github.com/thephpleague/oauth2-github.git", - "reference": "97f31cd70e76f81e8f5b4e2ab6f3708e2db7ac18" + "reference": "84211f62b757f7266fe605a0aa874a32f52c24fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/oauth2-github/zipball/97f31cd70e76f81e8f5b4e2ab6f3708e2db7ac18", - "reference": "97f31cd70e76f81e8f5b4e2ab6f3708e2db7ac18", + "url": "https://api.github.com/repos/thephpleague/oauth2-github/zipball/84211f62b757f7266fe605a0aa874a32f52c24fd", + "reference": "84211f62b757f7266fe605a0aa874a32f52c24fd", "shasum": "" }, "require": { @@ -4292,9 +4144,9 @@ ], "support": { "issues": "https://github.com/thephpleague/oauth2-github/issues", - "source": "https://github.com/thephpleague/oauth2-github/tree/3.1.0" + "source": "https://github.com/thephpleague/oauth2-github/tree/3.1.1" }, - "time": "2022-11-04T14:01:49+00:00" + "time": "2024-09-03T10:42:10+00:00" }, { "name": "league/oauth2-google", @@ -4688,16 +4540,16 @@ }, { "name": "liip/imagine-bundle", - "version": "2.13.1", + "version": "2.13.2", "source": { "type": "git", "url": "https://github.com/liip/LiipImagineBundle.git", - "reference": "f3b67426800a6a86840de7447bb552c61a79f4b6" + "reference": "98e0318ea0f7b9500343236e63cc29ded58a1d43" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/liip/LiipImagineBundle/zipball/f3b67426800a6a86840de7447bb552c61a79f4b6", - "reference": "f3b67426800a6a86840de7447bb552c61a79f4b6", + "url": "https://api.github.com/repos/liip/LiipImagineBundle/zipball/98e0318ea0f7b9500343236e63cc29ded58a1d43", + "reference": "98e0318ea0f7b9500343236e63cc29ded58a1d43", "shasum": "" }, "require": { @@ -4788,9 +4640,9 @@ ], "support": { "issues": "https://github.com/liip/LiipImagineBundle/issues", - "source": "https://github.com/liip/LiipImagineBundle/tree/2.13.1" + "source": "https://github.com/liip/LiipImagineBundle/tree/2.13.2" }, - "time": "2024-07-03T13:28:14+00:00" + "time": "2024-09-04T12:55:26+00:00" }, { "name": "meteo-concept/hcaptcha-bundle", @@ -5128,16 +4980,16 @@ }, { "name": "mtdowling/jmespath.php", - "version": "2.7.0", + "version": "2.8.0", "source": { "type": "git", "url": "https://github.com/jmespath/jmespath.php.git", - "reference": "bbb69a935c2cbb0c03d7f481a238027430f6440b" + "reference": "a2a865e05d5f420b50cc2f85bb78d565db12a6bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/bbb69a935c2cbb0c03d7f481a238027430f6440b", - "reference": "bbb69a935c2cbb0c03d7f481a238027430f6440b", + "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/a2a865e05d5f420b50cc2f85bb78d565db12a6bc", + "reference": "a2a865e05d5f420b50cc2f85bb78d565db12a6bc", "shasum": "" }, "require": { @@ -5154,7 +5006,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "2.8-dev" } }, "autoload": { @@ -5188,9 +5040,9 @@ ], "support": { "issues": "https://github.com/jmespath/jmespath.php/issues", - "source": "https://github.com/jmespath/jmespath.php/tree/2.7.0" + "source": "https://github.com/jmespath/jmespath.php/tree/2.8.0" }, - "time": "2023-08-25T10:54:48+00:00" + "time": "2024-09-04T18:46:31+00:00" }, { "name": "neitanod/forceutf8", @@ -5567,16 +5419,16 @@ }, { "name": "nyholm/psr7", - "version": "1.8.1", + "version": "1.8.2", "source": { "type": "git", "url": "https://github.com/Nyholm/psr7.git", - "reference": "aa5fc277a4f5508013d571341ade0c3886d4d00e" + "reference": "a71f2b11690f4b24d099d6b16690a90ae14fc6f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Nyholm/psr7/zipball/aa5fc277a4f5508013d571341ade0c3886d4d00e", - "reference": "aa5fc277a4f5508013d571341ade0c3886d4d00e", + "url": "https://api.github.com/repos/Nyholm/psr7/zipball/a71f2b11690f4b24d099d6b16690a90ae14fc6f3", + "reference": "a71f2b11690f4b24d099d6b16690a90ae14fc6f3", "shasum": "" }, "require": { @@ -5629,7 +5481,7 @@ ], "support": { "issues": "https://github.com/Nyholm/psr7/issues", - "source": "https://github.com/Nyholm/psr7/tree/1.8.1" + "source": "https://github.com/Nyholm/psr7/tree/1.8.2" }, "funding": [ { @@ -5641,7 +5493,7 @@ "type": "github" } ], - "time": "2023-11-13T09:31:12+00:00" + "time": "2024-09-09T07:06:30+00:00" }, { "name": "omines/antispam-bundle", @@ -5879,26 +5731,24 @@ }, { "name": "pagerfanta/core", - "version": "v3.8.0", + "version": "v4.7.0", "source": { "type": "git", "url": "https://github.com/Pagerfanta/core.git", - "reference": "a995f69ff9af64a45c3dc3d8217100624ae214f2" + "reference": "4509db0e1e22baea6678b724f3254609acbaa9cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Pagerfanta/core/zipball/a995f69ff9af64a45c3dc3d8217100624ae214f2", - "reference": "a995f69ff9af64a45c3dc3d8217100624ae214f2", + "url": "https://api.github.com/repos/Pagerfanta/core/zipball/4509db0e1e22baea6678b724f3254609acbaa9cc", + "reference": "4509db0e1e22baea6678b724f3254609acbaa9cc", "shasum": "" }, "require": { "ext-json": "*", - "php": "^7.4 || ^8.0", - "symfony/deprecation-contracts": "^2.1 || ^3.0", - "symfony/polyfill-php80": "^1.15" + "php": "^8.1" }, "require-dev": { - "phpunit/phpunit": "^9.6 || ^10.0" + "phpunit/phpunit": "^10.5" }, "type": "library", "autoload": { @@ -5918,9 +5768,9 @@ "pagerfanta" ], "support": { - "source": "https://github.com/Pagerfanta/core/tree/v3.8.0" + "source": "https://github.com/Pagerfanta/core/tree/v4.7.0" }, - "time": "2023-04-15T16:39:14+00:00" + "time": "2024-08-13T23:43:44+00:00" }, { "name": "pagerfanta/doctrine-collections-adapter", @@ -6398,128 +6248,18 @@ }, "time": "2024-02-23T11:10:43+00:00" }, - { - "name": "phpseclib/phpseclib", - "version": "3.0.41", - "source": { - "type": "git", - "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "621c73f7dcb310b61de34d1da4c4204e8ace6ceb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/621c73f7dcb310b61de34d1da4c4204e8ace6ceb", - "reference": "621c73f7dcb310b61de34d1da4c4204e8ace6ceb", - "shasum": "" - }, - "require": { - "paragonie/constant_time_encoding": "^1|^2|^3", - "paragonie/random_compat": "^1.4|^2.0|^9.99.99", - "php": ">=5.6.1" - }, - "require-dev": { - "phpunit/phpunit": "*" - }, - "suggest": { - "ext-dom": "Install the DOM extension to load XML formatted public keys.", - "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", - "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", - "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", - "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." - }, - "type": "library", - "autoload": { - "files": [ - "phpseclib/bootstrap.php" - ], - "psr-4": { - "phpseclib3\\": "phpseclib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jim Wigginton", - "email": "terrafrost@php.net", - "role": "Lead Developer" - }, - { - "name": "Patrick Monnerat", - "email": "pm@datasphere.ch", - "role": "Developer" - }, - { - "name": "Andreas Fischer", - "email": "bantu@phpbb.com", - "role": "Developer" - }, - { - "name": "Hans-Jürgen Petrich", - "email": "petrich@tronic-media.com", - "role": "Developer" - }, - { - "name": "Graham Campbell", - "email": "graham@alt-three.com", - "role": "Developer" - } - ], - "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", - "homepage": "http://phpseclib.sourceforge.net", - "keywords": [ - "BigInteger", - "aes", - "asn.1", - "asn1", - "blowfish", - "crypto", - "cryptography", - "encryption", - "rsa", - "security", - "sftp", - "signature", - "signing", - "ssh", - "twofish", - "x.509", - "x509" - ], - "support": { - "issues": "https://github.com/phpseclib/phpseclib/issues", - "source": "https://github.com/phpseclib/phpseclib/tree/3.0.41" - }, - "funding": [ - { - "url": "https://github.com/terrafrost", - "type": "github" - }, - { - "url": "https://www.patreon.com/phpseclib", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", - "type": "tidelift" - } - ], - "time": "2024-08-12T00:13:54+00:00" - }, { "name": "phpstan/phpdoc-parser", - "version": "1.29.1", + "version": "1.30.1", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4" + "reference": "51b95ec8670af41009e2b2b56873bad96682413e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fcaefacf2d5c417e928405b71b400d4ce10daaf4", - "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/51b95ec8670af41009e2b2b56873bad96682413e", + "reference": "51b95ec8670af41009e2b2b56873bad96682413e", "shasum": "" }, "require": { @@ -6551,9 +6291,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.1" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.30.1" }, - "time": "2024-05-31T08:52:43+00:00" + "time": "2024-09-07T20:13:05+00:00" }, { "name": "predis/predis", @@ -7099,16 +6839,16 @@ }, { "name": "psr/log", - "version": "3.0.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + "reference": "79dff0b268932c640297f5208d6298f71855c03e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "url": "https://api.github.com/repos/php-fig/log/zipball/79dff0b268932c640297f5208d6298f71855c03e", + "reference": "79dff0b268932c640297f5208d6298f71855c03e", "shasum": "" }, "require": { @@ -7143,9 +6883,9 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/3.0.0" + "source": "https://github.com/php-fig/log/tree/3.0.1" }, - "time": "2021-07-14T16:46:02+00:00" + "time": "2024-08-21T13:31:24+00:00" }, { "name": "ralouphie/getallheaders", @@ -7359,31 +7099,30 @@ }, { "name": "scienta/doctrine-json-functions", - "version": "5.5.0", + "version": "6.1.0", "source": { "type": "git", "url": "https://github.com/ScientaNL/DoctrineJsonFunctions.git", - "reference": "afcb6af4d1421f795fec5cbf29c02aaf486f21c7" + "reference": "0d9c01ab012e628b845191d2c3b369855308c457" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ScientaNL/DoctrineJsonFunctions/zipball/afcb6af4d1421f795fec5cbf29c02aaf486f21c7", - "reference": "afcb6af4d1421f795fec5cbf29c02aaf486f21c7", + "url": "https://api.github.com/repos/ScientaNL/DoctrineJsonFunctions/zipball/0d9c01ab012e628b845191d2c3b369855308c457", + "reference": "0d9c01ab012e628b845191d2c3b369855308c457", "shasum": "" }, "require": { - "doctrine/dbal": "^3.2", + "doctrine/dbal": "^3.2 || ^4", "doctrine/lexer": "^2.0 || ^3.0", "doctrine/orm": "^2.19 || ^3", "ext-pdo": "*", - "php": "^7.4 || ^8.0" + "php": "^8.1" }, "require-dev": { - "doctrine/annotations": "^2", - "doctrine/coding-standard": "^8.0 || ^9.0", - "phpunit/phpunit": "^8.0 || ^9.0", + "doctrine/coding-standard": "^9.0 || ^10.0 || ^11.0 || ^12.0", + "phpunit/phpunit": "^10.1", "psalm/plugin-phpunit": "^0.18", - "slevomat/coding-standard": "^8.4", + "slevomat/coding-standard": "~8", "symfony/cache": "^5.4 || ^6.4 || ^7", "vimeo/psalm": "^5.2", "webmozart/assert": "^1.11" @@ -7392,11 +7131,6 @@ "dunglas/doctrine-json-odm": "To serialize / deserialize objects as JSON documents." }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.1-dev" - } - }, "autoload": { "psr-4": { "Scienta\\DoctrineJsonFunctions\\": "src/" @@ -7412,7 +7146,7 @@ "homepage": "https://github.com/ScientaNL/DoctrineJsonFunctions/contributors" } ], - "description": "A set of extensions to Doctrine 2 that add support for json query functions.", + "description": "A set of extensions to Doctrine that add support for json query functions.", "keywords": [ "database", "doctrine", @@ -7427,9 +7161,9 @@ ], "support": { "issues": "https://github.com/ScientaNL/DoctrineJsonFunctions/issues", - "source": "https://github.com/ScientaNL/DoctrineJsonFunctions/tree/5.5.0" + "source": "https://github.com/ScientaNL/DoctrineJsonFunctions/tree/6.1.0" }, - "time": "2024-03-08T08:39:12+00:00" + "time": "2024-04-10T07:24:09+00:00" }, { "name": "spomky-labs/base64url", @@ -7890,16 +7624,16 @@ }, { "name": "symfony/cache", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "8ac37acee794372f9732fe8a61a8221f6762148e" + "reference": "b61e464d7687bb7e8f677d5031c632bf3820df18" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/8ac37acee794372f9732fe8a61a8221f6762148e", - "reference": "8ac37acee794372f9732fe8a61a8221f6762148e", + "url": "https://api.github.com/repos/symfony/cache/zipball/b61e464d7687bb7e8f677d5031c632bf3820df18", + "reference": "b61e464d7687bb7e8f677d5031c632bf3820df18", "shasum": "" }, "require": { @@ -7967,7 +7701,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v7.1.3" + "source": "https://github.com/symfony/cache/tree/v7.1.4" }, "funding": [ { @@ -7983,7 +7717,7 @@ "type": "tidelift" } ], - "time": "2024-07-17T06:10:24+00:00" + "time": "2024-08-12T09:59:40+00:00" }, { "name": "symfony/cache-contracts", @@ -8212,16 +7946,16 @@ }, { "name": "symfony/console", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9" + "reference": "1eed7af6961d763e7832e874d7f9b21c3ea9c111" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9", - "reference": "cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9", + "url": "https://api.github.com/repos/symfony/console/zipball/1eed7af6961d763e7832e874d7f9b21c3ea9c111", + "reference": "1eed7af6961d763e7832e874d7f9b21c3ea9c111", "shasum": "" }, "require": { @@ -8285,7 +8019,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.1.3" + "source": "https://github.com/symfony/console/tree/v7.1.4" }, "funding": [ { @@ -8301,7 +8035,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:41:01+00:00" + "time": "2024-08-15T22:48:53+00:00" }, { "name": "symfony/css-selector", @@ -8370,16 +8104,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "8126f0be4ff984e4db0140e60917900a53facb49" + "reference": "5320e0bc2c9e2d7450bb4091e497a305a68b28ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/8126f0be4ff984e4db0140e60917900a53facb49", - "reference": "8126f0be4ff984e4db0140e60917900a53facb49", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/5320e0bc2c9e2d7450bb4091e497a305a68b28ed", + "reference": "5320e0bc2c9e2d7450bb4091e497a305a68b28ed", "shasum": "" }, "require": { @@ -8430,7 +8164,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v7.1.3" + "source": "https://github.com/symfony/dependency-injection/tree/v7.1.4" }, "funding": [ { @@ -8446,7 +8180,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T07:35:39+00:00" + "time": "2024-08-29T08:16:25+00:00" }, { "name": "symfony/deprecation-contracts", @@ -8517,16 +8251,16 @@ }, { "name": "symfony/doctrine-bridge", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "b526822483124b62ff3cda14237418408f444e4d" + "reference": "5c31b278a52023970f4ef398e42ab9048483abfa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/b526822483124b62ff3cda14237418408f444e4d", - "reference": "b526822483124b62ff3cda14237418408f444e4d", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/5c31b278a52023970f4ef398e42ab9048483abfa", + "reference": "5c31b278a52023970f4ef398e42ab9048483abfa", "shasum": "" }, "require": { @@ -8605,7 +8339,7 @@ "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/doctrine-bridge/tree/v7.1.3" + "source": "https://github.com/symfony/doctrine-bridge/tree/v7.1.4" }, "funding": [ { @@ -8621,20 +8355,20 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:41:01+00:00" + "time": "2024-08-13T10:29:23+00:00" }, { "name": "symfony/doctrine-messenger", - "version": "v7.1.2", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-messenger.git", - "reference": "64e2195442df86a7a0c85a77162d0247601e9da9" + "reference": "7f2a9262d7af3f892e49382b918e991af2ae0738" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-messenger/zipball/64e2195442df86a7a0c85a77162d0247601e9da9", - "reference": "64e2195442df86a7a0c85a77162d0247601e9da9", + "url": "https://api.github.com/repos/symfony/doctrine-messenger/zipball/7f2a9262d7af3f892e49382b918e991af2ae0738", + "reference": "7f2a9262d7af3f892e49382b918e991af2ae0738", "shasum": "" }, "require": { @@ -8677,7 +8411,7 @@ "description": "Symfony Doctrine Messenger Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/doctrine-messenger/tree/v7.1.2" + "source": "https://github.com/symfony/doctrine-messenger/tree/v7.1.4" }, "funding": [ { @@ -8693,7 +8427,7 @@ "type": "tidelift" } ], - "time": "2024-06-20T15:47:37+00:00" + "time": "2024-08-30T07:19:54+00:00" }, { "name": "symfony/dotenv", @@ -9002,16 +8736,16 @@ }, { "name": "symfony/expression-language", - "version": "v7.1.1", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/expression-language.git", - "reference": "463cb95f80c14136175f4e03f7f6199b01c6b8b4" + "reference": "b9e4bc6685d513c10235145ed1042a6081635806" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/expression-language/zipball/463cb95f80c14136175f4e03f7f6199b01c6b8b4", - "reference": "463cb95f80c14136175f4e03f7f6199b01c6b8b4", + "url": "https://api.github.com/repos/symfony/expression-language/zipball/b9e4bc6685d513c10235145ed1042a6081635806", + "reference": "b9e4bc6685d513c10235145ed1042a6081635806", "shasum": "" }, "require": { @@ -9046,7 +8780,7 @@ "description": "Provides an engine that can compile and evaluate expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/expression-language/tree/v7.1.1" + "source": "https://github.com/symfony/expression-language/tree/v7.1.4" }, "funding": [ { @@ -9062,7 +8796,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:57:53+00:00" + "time": "2024-08-12T09:59:40+00:00" }, { "name": "symfony/filesystem", @@ -9132,16 +8866,16 @@ }, { "name": "symfony/finder", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "717c6329886f32dc65e27461f80f2a465412fdca" + "reference": "d95bbf319f7d052082fb7af147e0f835a695e823" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/717c6329886f32dc65e27461f80f2a465412fdca", - "reference": "717c6329886f32dc65e27461f80f2a465412fdca", + "url": "https://api.github.com/repos/symfony/finder/zipball/d95bbf319f7d052082fb7af147e0f835a695e823", + "reference": "d95bbf319f7d052082fb7af147e0f835a695e823", "shasum": "" }, "require": { @@ -9176,7 +8910,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.1.3" + "source": "https://github.com/symfony/finder/tree/v7.1.4" }, "funding": [ { @@ -9192,7 +8926,7 @@ "type": "tidelift" } ], - "time": "2024-07-24T07:08:44+00:00" + "time": "2024-08-13T14:28:19+00:00" }, { "name": "symfony/flex", @@ -9261,16 +8995,16 @@ }, { "name": "symfony/form", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/form.git", - "reference": "11df2e2e142161824eb341e96cbb3c56c3bb57dc" + "reference": "3018ad169ea7532eec19e001f2c9f049ff051bd6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/form/zipball/11df2e2e142161824eb341e96cbb3c56c3bb57dc", - "reference": "11df2e2e142161824eb341e96cbb3c56c3bb57dc", + "url": "https://api.github.com/repos/symfony/form/zipball/3018ad169ea7532eec19e001f2c9f049ff051bd6", + "reference": "3018ad169ea7532eec19e001f2c9f049ff051bd6", "shasum": "" }, "require": { @@ -9338,7 +9072,7 @@ "description": "Allows to easily create, process and reuse HTML forms", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/form/tree/v7.1.3" + "source": "https://github.com/symfony/form/tree/v7.1.4" }, "funding": [ { @@ -9354,20 +9088,20 @@ "type": "tidelift" } ], - "time": "2024-07-19T08:30:01+00:00" + "time": "2024-08-12T09:59:40+00:00" }, { "name": "symfony/framework-bundle", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/framework-bundle.git", - "reference": "a32ec544bd501eb4619eb977860ad3076ee55061" + "reference": "711af4eefcb4054a9c93e44b403626e1826bcddd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/a32ec544bd501eb4619eb977860ad3076ee55061", - "reference": "a32ec544bd501eb4619eb977860ad3076ee55061", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/711af4eefcb4054a9c93e44b403626e1826bcddd", + "reference": "711af4eefcb4054a9c93e44b403626e1826bcddd", "shasum": "" }, "require": { @@ -9485,7 +9219,7 @@ "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/framework-bundle/tree/v7.1.3" + "source": "https://github.com/symfony/framework-bundle/tree/v7.1.4" }, "funding": [ { @@ -9501,20 +9235,20 @@ "type": "tidelift" } ], - "time": "2024-07-26T13:24:34+00:00" + "time": "2024-08-11T16:10:02+00:00" }, { "name": "symfony/http-client", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "b79858aa7a051ea791b0d50269a234a0b50cb231" + "reference": "a8f8d60b30b331cf4b743b3632e5acdba3f8285c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/b79858aa7a051ea791b0d50269a234a0b50cb231", - "reference": "b79858aa7a051ea791b0d50269a234a0b50cb231", + "url": "https://api.github.com/repos/symfony/http-client/zipball/a8f8d60b30b331cf4b743b3632e5acdba3f8285c", + "reference": "a8f8d60b30b331cf4b743b3632e5acdba3f8285c", "shasum": "" }, "require": { @@ -9579,7 +9313,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v7.1.3" + "source": "https://github.com/symfony/http-client/tree/v7.1.4" }, "funding": [ { @@ -9595,7 +9329,7 @@ "type": "tidelift" } ], - "time": "2024-07-17T06:10:24+00:00" + "time": "2024-08-26T06:32:37+00:00" }, { "name": "symfony/http-client-contracts", @@ -9754,16 +9488,16 @@ }, { "name": "symfony/http-kernel", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "db9702f3a04cc471ec8c70e881825db26ac5f186" + "reference": "6efcbd1b3f444f631c386504fc83eeca25963747" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/db9702f3a04cc471ec8c70e881825db26ac5f186", - "reference": "db9702f3a04cc471ec8c70e881825db26ac5f186", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/6efcbd1b3f444f631c386504fc83eeca25963747", + "reference": "6efcbd1b3f444f631c386504fc83eeca25963747", "shasum": "" }, "require": { @@ -9848,7 +9582,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v7.1.3" + "source": "https://github.com/symfony/http-kernel/tree/v7.1.4" }, "funding": [ { @@ -9864,7 +9598,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T14:58:15+00:00" + "time": "2024-08-30T17:02:28+00:00" }, { "name": "symfony/intl", @@ -10348,16 +10082,16 @@ }, { "name": "symfony/messenger", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/messenger.git", - "reference": "604e182a7758ceea35921a8ad5dd492a6e13bae4" + "reference": "e1dc743492ff9f1cfb23e6eea3592bf2ec9bd079" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/messenger/zipball/604e182a7758ceea35921a8ad5dd492a6e13bae4", - "reference": "604e182a7758ceea35921a8ad5dd492a6e13bae4", + "url": "https://api.github.com/repos/symfony/messenger/zipball/e1dc743492ff9f1cfb23e6eea3592bf2ec9bd079", + "reference": "e1dc743492ff9f1cfb23e6eea3592bf2ec9bd079", "shasum": "" }, "require": { @@ -10414,7 +10148,7 @@ "description": "Helps applications send and receive messages to/from other applications or via message queues", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/messenger/tree/v7.1.3" + "source": "https://github.com/symfony/messenger/tree/v7.1.4" }, "funding": [ { @@ -10430,20 +10164,20 @@ "type": "tidelift" } ], - "time": "2024-07-09T19:36:07+00:00" + "time": "2024-08-06T14:26:51+00:00" }, { "name": "symfony/mime", - "version": "v7.1.2", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "26a00b85477e69a4bab63b66c5dce64f18b0cbfc" + "reference": "ccaa6c2503db867f472a587291e764d6a1e58758" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/26a00b85477e69a4bab63b66c5dce64f18b0cbfc", - "reference": "26a00b85477e69a4bab63b66c5dce64f18b0cbfc", + "url": "https://api.github.com/repos/symfony/mime/zipball/ccaa6c2503db867f472a587291e764d6a1e58758", + "reference": "ccaa6c2503db867f472a587291e764d6a1e58758", "shasum": "" }, "require": { @@ -10498,7 +10232,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v7.1.2" + "source": "https://github.com/symfony/mime/tree/v7.1.4" }, "funding": [ { @@ -10514,7 +10248,7 @@ "type": "tidelift" } ], - "time": "2024-06-28T10:03:55+00:00" + "time": "2024-08-13T14:28:19+00:00" }, { "name": "symfony/monolog-bridge", @@ -10816,20 +10550,20 @@ }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "64647a7c30b2283f5d49b874d84a18fc22054b7a" + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/64647a7c30b2283f5d49b874d84a18fc22054b7a", - "reference": "64647a7c30b2283f5d49b874d84a18fc22054b7a", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" @@ -10874,7 +10608,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" }, "funding": [ { @@ -10890,24 +10624,24 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-icu", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-icu.git", - "reference": "e76343c631b453088e2260ac41dfebe21954de81" + "reference": "d80a05e9904d2c2b9b95929f3e4b5d3a8f418d78" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/e76343c631b453088e2260ac41dfebe21954de81", - "reference": "e76343c631b453088e2260ac41dfebe21954de81", + "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/d80a05e9904d2c2b9b95929f3e4b5d3a8f418d78", + "reference": "d80a05e9904d2c2b9b95929f3e4b5d3a8f418d78", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance and support of other locales than \"en\"" @@ -10958,7 +10692,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.31.0" }, "funding": [ { @@ -10974,26 +10708,25 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "a6e83bdeb3c84391d1dfe16f42e40727ce524a5c" + "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/a6e83bdeb3c84391d1dfe16f42e40727ce524a5c", - "reference": "a6e83bdeb3c84391d1dfe16f42e40727ce524a5c", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/c36586dcf89a12315939e00ec9b4474adcb1d773", + "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773", "shasum": "" }, "require": { - "php": ">=7.1", - "symfony/polyfill-intl-normalizer": "^1.10", - "symfony/polyfill-php72": "^1.10" + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" }, "suggest": { "ext-intl": "For best performance" @@ -11042,7 +10775,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.31.0" }, "funding": [ { @@ -11058,24 +10791,24 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb" + "reference": "3833d7255cc303546435cb650316bff708a1c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/a95281b0be0d9ab48050ebd988b967875cdb9fdb", - "reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" @@ -11123,7 +10856,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" }, "funding": [ { @@ -11139,7 +10872,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -11379,20 +11112,20 @@ }, { "name": "symfony/polyfill-php83", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9" + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9", - "reference": "dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/2fb86d65e2d424369ad2905e83b236a8805ba491", + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { @@ -11435,7 +11168,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.31.0" }, "funding": [ { @@ -11451,24 +11184,24 @@ "type": "tidelift" } ], - "time": "2024-06-19T12:35:24+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-uuid", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-uuid.git", - "reference": "2ba1f33797470debcda07fe9dce20a0003df18e9" + "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/2ba1f33797470debcda07fe9dce20a0003df18e9", - "reference": "2ba1f33797470debcda07fe9dce20a0003df18e9", + "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/21533be36c24be3f4b1669c4725c7d1d2bab4ae2", + "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-uuid": "*" @@ -11514,7 +11247,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/polyfill-uuid/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.31.0" }, "funding": [ { @@ -11530,7 +11263,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/process", @@ -11595,16 +11328,16 @@ }, { "name": "symfony/property-access", - "version": "v7.1.1", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "74e39e6a6276b8e384f34c6ddbc10a6c9a60193a" + "reference": "6c709f97103355016e5782d0622437ae381012ad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/74e39e6a6276b8e384f34c6ddbc10a6c9a60193a", - "reference": "74e39e6a6276b8e384f34c6ddbc10a6c9a60193a", + "url": "https://api.github.com/repos/symfony/property-access/zipball/6c709f97103355016e5782d0622437ae381012ad", + "reference": "6c709f97103355016e5782d0622437ae381012ad", "shasum": "" }, "require": { @@ -11651,7 +11384,7 @@ "reflection" ], "support": { - "source": "https://github.com/symfony/property-access/tree/v7.1.1" + "source": "https://github.com/symfony/property-access/tree/v7.1.4" }, "funding": [ { @@ -11667,7 +11400,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:57:53+00:00" + "time": "2024-08-30T16:12:47+00:00" }, { "name": "symfony/property-info", @@ -11755,16 +11488,16 @@ }, { "name": "symfony/psr-http-message-bridge", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/psr-http-message-bridge.git", - "reference": "1365d10f5476f74a27cf9c2d1eee70c069019db0" + "reference": "405a7bcd872f1563966f64be19f1362d94ce71ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/1365d10f5476f74a27cf9c2d1eee70c069019db0", - "reference": "1365d10f5476f74a27cf9c2d1eee70c069019db0", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/405a7bcd872f1563966f64be19f1362d94ce71ab", + "reference": "405a7bcd872f1563966f64be19f1362d94ce71ab", "shasum": "" }, "require": { @@ -11818,7 +11551,7 @@ "psr-7" ], "support": { - "source": "https://github.com/symfony/psr-http-message-bridge/tree/v7.1.3" + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v7.1.4" }, "funding": [ { @@ -11834,7 +11567,7 @@ "type": "tidelift" } ], - "time": "2024-07-17T06:10:24+00:00" + "time": "2024-08-15T22:48:53+00:00" }, { "name": "symfony/rate-limiter", @@ -11908,16 +11641,16 @@ }, { "name": "symfony/redis-messenger", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/redis-messenger.git", - "reference": "0e13be260a411afbe14f77df45728a23ffb50e7d" + "reference": "e0bb8685e54e17394c6bef231b7097611ea06d29" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/redis-messenger/zipball/0e13be260a411afbe14f77df45728a23ffb50e7d", - "reference": "0e13be260a411afbe14f77df45728a23ffb50e7d", + "url": "https://api.github.com/repos/symfony/redis-messenger/zipball/e0bb8685e54e17394c6bef231b7097611ea06d29", + "reference": "e0bb8685e54e17394c6bef231b7097611ea06d29", "shasum": "" }, "require": { @@ -11955,7 +11688,7 @@ "description": "Symfony Redis extension Messenger Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/redis-messenger/tree/v7.1.3" + "source": "https://github.com/symfony/redis-messenger/tree/v7.1.4" }, "funding": [ { @@ -11971,20 +11704,20 @@ "type": "tidelift" } ], - "time": "2024-07-17T06:10:24+00:00" + "time": "2024-08-15T22:48:53+00:00" }, { "name": "symfony/routing", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "8a908a3f22d5a1b5d297578c2ceb41b02fa916d0" + "reference": "1500aee0094a3ce1c92626ed8cf3c2037e86f5a7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/8a908a3f22d5a1b5d297578c2ceb41b02fa916d0", - "reference": "8a908a3f22d5a1b5d297578c2ceb41b02fa916d0", + "url": "https://api.github.com/repos/symfony/routing/zipball/1500aee0094a3ce1c92626ed8cf3c2037e86f5a7", + "reference": "1500aee0094a3ce1c92626ed8cf3c2037e86f5a7", "shasum": "" }, "require": { @@ -12036,7 +11769,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v7.1.3" + "source": "https://github.com/symfony/routing/tree/v7.1.4" }, "funding": [ { @@ -12052,7 +11785,7 @@ "type": "tidelift" } ], - "time": "2024-07-17T06:10:24+00:00" + "time": "2024-08-29T08:16:25+00:00" }, { "name": "symfony/runtime", @@ -12215,16 +11948,16 @@ }, { "name": "symfony/security-bundle", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/security-bundle.git", - "reference": "4f77a89e21c2e700b5fbbf3c1eccd71b9a5d69ad" + "reference": "5e10107856ff64d477c61fed7bcbb8a16125ea01" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-bundle/zipball/4f77a89e21c2e700b5fbbf3c1eccd71b9a5d69ad", - "reference": "4f77a89e21c2e700b5fbbf3c1eccd71b9a5d69ad", + "url": "https://api.github.com/repos/symfony/security-bundle/zipball/5e10107856ff64d477c61fed7bcbb8a16125ea01", + "reference": "5e10107856ff64d477c61fed7bcbb8a16125ea01", "shasum": "" }, "require": { @@ -12233,7 +11966,7 @@ "php": ">=8.2", "symfony/clock": "^6.4|^7.0", "symfony/config": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4.11|^7.1.4", "symfony/event-dispatcher": "^6.4|^7.0", "symfony/http-foundation": "^6.4|^7.0", "symfony/http-kernel": "^6.4|^7.0", @@ -12301,7 +12034,7 @@ "description": "Provides a tight integration of the Security component into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-bundle/tree/v7.1.3" + "source": "https://github.com/symfony/security-bundle/tree/v7.1.4" }, "funding": [ { @@ -12317,20 +12050,20 @@ "type": "tidelift" } ], - "time": "2024-07-26T07:24:20+00:00" + "time": "2024-08-20T11:38:55+00:00" }, { "name": "symfony/security-core", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/security-core.git", - "reference": "aa4f432586a129017ce0ba34e2b1bfe6babfe8c7" + "reference": "f5ccd9d005993e5ff7251e57fe4a0615c8535866" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-core/zipball/aa4f432586a129017ce0ba34e2b1bfe6babfe8c7", - "reference": "aa4f432586a129017ce0ba34e2b1bfe6babfe8c7", + "url": "https://api.github.com/repos/symfony/security-core/zipball/f5ccd9d005993e5ff7251e57fe4a0615c8535866", + "reference": "f5ccd9d005993e5ff7251e57fe4a0615c8535866", "shasum": "" }, "require": { @@ -12387,7 +12120,7 @@ "description": "Symfony Security Component - Core Library", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-core/tree/v7.1.3" + "source": "https://github.com/symfony/security-core/tree/v7.1.4" }, "funding": [ { @@ -12403,7 +12136,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:41:01+00:00" + "time": "2024-08-29T08:16:25+00:00" }, { "name": "symfony/security-csrf", @@ -12475,16 +12208,16 @@ }, { "name": "symfony/security-http", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/security-http.git", - "reference": "19f07b6530dbb82017c38ee7582b154f5c42b179" + "reference": "acd1ecc807b76b9bdefe53168c3a52a11205fc20" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-http/zipball/19f07b6530dbb82017c38ee7582b154f5c42b179", - "reference": "19f07b6530dbb82017c38ee7582b154f5c42b179", + "url": "https://api.github.com/repos/symfony/security-http/zipball/acd1ecc807b76b9bdefe53168c3a52a11205fc20", + "reference": "acd1ecc807b76b9bdefe53168c3a52a11205fc20", "shasum": "" }, "require": { @@ -12543,7 +12276,7 @@ "description": "Symfony Security Component - HTTP Integration", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-http/tree/v7.1.3" + "source": "https://github.com/symfony/security-http/tree/v7.1.4" }, "funding": [ { @@ -12559,20 +12292,20 @@ "type": "tidelift" } ], - "time": "2024-07-26T07:24:20+00:00" + "time": "2024-08-15T22:52:38+00:00" }, { "name": "symfony/serializer", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "0d5ddac365fbfffc30ca9bc944ad3eb9b3763c09" + "reference": "0158b0e91b7cf7e744a6fb9acaeb613d1ca40dbb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/0d5ddac365fbfffc30ca9bc944ad3eb9b3763c09", - "reference": "0d5ddac365fbfffc30ca9bc944ad3eb9b3763c09", + "url": "https://api.github.com/repos/symfony/serializer/zipball/0158b0e91b7cf7e744a6fb9acaeb613d1ca40dbb", + "reference": "0158b0e91b7cf7e744a6fb9acaeb613d1ca40dbb", "shasum": "" }, "require": { @@ -12640,7 +12373,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/serializer/tree/v7.1.3" + "source": "https://github.com/symfony/serializer/tree/v7.1.4" }, "funding": [ { @@ -12656,7 +12389,7 @@ "type": "tidelift" } ], - "time": "2024-07-17T06:10:24+00:00" + "time": "2024-08-22T09:39:57+00:00" }, { "name": "symfony/service-contracts", @@ -12874,16 +12607,16 @@ }, { "name": "symfony/string", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "ea272a882be7f20cad58d5d78c215001617b7f07" + "reference": "6cd670a6d968eaeb1c77c2e76091c45c56bc367b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/ea272a882be7f20cad58d5d78c215001617b7f07", - "reference": "ea272a882be7f20cad58d5d78c215001617b7f07", + "url": "https://api.github.com/repos/symfony/string/zipball/6cd670a6d968eaeb1c77c2e76091c45c56bc367b", + "reference": "6cd670a6d968eaeb1c77c2e76091c45c56bc367b", "shasum": "" }, "require": { @@ -12941,7 +12674,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.1.3" + "source": "https://github.com/symfony/string/tree/v7.1.4" }, "funding": [ { @@ -12957,7 +12690,7 @@ "type": "tidelift" } ], - "time": "2024-07-22T10:25:37+00:00" + "time": "2024-08-12T09:59:40+00:00" }, { "name": "symfony/translation", @@ -13133,16 +12866,16 @@ }, { "name": "symfony/twig-bridge", - "version": "v7.1.1", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/twig-bridge.git", - "reference": "96e6e12a63db80bcedefc012042d2cb2d1a015f8" + "reference": "2db32cfe8fc57797908ef0bee232b90dbe42af66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/96e6e12a63db80bcedefc012042d2cb2d1a015f8", - "reference": "96e6e12a63db80bcedefc012042d2cb2d1a015f8", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/2db32cfe8fc57797908ef0bee232b90dbe42af66", + "reference": "2db32cfe8fc57797908ef0bee232b90dbe42af66", "shasum": "" }, "require": { @@ -13222,7 +12955,7 @@ "description": "Provides integration for Twig with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bridge/tree/v7.1.1" + "source": "https://github.com/symfony/twig-bridge/tree/v7.1.4" }, "funding": [ { @@ -13238,7 +12971,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:57:53+00:00" + "time": "2024-08-29T08:16:25+00:00" }, { "name": "symfony/twig-bundle", @@ -13408,16 +13141,16 @@ }, { "name": "symfony/uid", - "version": "v7.1.1", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/uid.git", - "reference": "bb59febeecc81528ff672fad5dab7f06db8c8277" + "reference": "82177535395109075cdb45a70533aa3d7a521cdf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/uid/zipball/bb59febeecc81528ff672fad5dab7f06db8c8277", - "reference": "bb59febeecc81528ff672fad5dab7f06db8c8277", + "url": "https://api.github.com/repos/symfony/uid/zipball/82177535395109075cdb45a70533aa3d7a521cdf", + "reference": "82177535395109075cdb45a70533aa3d7a521cdf", "shasum": "" }, "require": { @@ -13462,7 +13195,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/uid/tree/v7.1.1" + "source": "https://github.com/symfony/uid/tree/v7.1.4" }, "funding": [ { @@ -13478,7 +13211,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:57:53+00:00" + "time": "2024-08-12T09:59:40+00:00" }, { "name": "symfony/ux-autocomplete", @@ -13738,16 +13471,16 @@ }, { "name": "symfony/validator", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "ba711a6cfc008544dad059abb3c1d997f1472237" + "reference": "0d7e0dfd41702d6b9356214b76110421c1e74368" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/ba711a6cfc008544dad059abb3c1d997f1472237", - "reference": "ba711a6cfc008544dad059abb3c1d997f1472237", + "url": "https://api.github.com/repos/symfony/validator/zipball/0d7e0dfd41702d6b9356214b76110421c1e74368", + "reference": "0d7e0dfd41702d6b9356214b76110421c1e74368", "shasum": "" }, "require": { @@ -13815,7 +13548,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/validator/tree/v7.1.3" + "source": "https://github.com/symfony/validator/tree/v7.1.4" }, "funding": [ { @@ -13831,20 +13564,20 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:41:01+00:00" + "time": "2024-08-30T15:58:06+00:00" }, { "name": "symfony/var-dumper", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "86af4617cca75a6e28598f49ae0690f3b9d4591f" + "reference": "a5fa7481b199090964d6fd5dab6294d5a870c7aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/86af4617cca75a6e28598f49ae0690f3b9d4591f", - "reference": "86af4617cca75a6e28598f49ae0690f3b9d4591f", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/a5fa7481b199090964d6fd5dab6294d5a870c7aa", + "reference": "a5fa7481b199090964d6fd5dab6294d5a870c7aa", "shasum": "" }, "require": { @@ -13898,7 +13631,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.1.3" + "source": "https://github.com/symfony/var-dumper/tree/v7.1.4" }, "funding": [ { @@ -13914,7 +13647,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:41:01+00:00" + "time": "2024-08-30T16:12:47+00:00" }, { "name": "symfony/var-exporter", @@ -14235,16 +13968,16 @@ }, { "name": "symfony/yaml", - "version": "v7.1.1", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "fa34c77015aa6720469db7003567b9f772492bf2" + "reference": "92e080b851c1c655c786a2da77f188f2dccd0f4b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/fa34c77015aa6720469db7003567b9f772492bf2", - "reference": "fa34c77015aa6720469db7003567b9f772492bf2", + "url": "https://api.github.com/repos/symfony/yaml/zipball/92e080b851c1c655c786a2da77f188f2dccd0f4b", + "reference": "92e080b851c1c655c786a2da77f188f2dccd0f4b", "shasum": "" }, "require": { @@ -14286,7 +14019,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.1.1" + "source": "https://github.com/symfony/yaml/tree/v7.1.4" }, "funding": [ { @@ -14302,7 +14035,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:57:53+00:00" + "time": "2024-08-12T09:59:40+00:00" }, { "name": "symfonycasts/reset-password-bundle", @@ -14512,23 +14245,23 @@ }, { "name": "twig/cssinliner-extra", - "version": "v3.11.0", + "version": "v3.13.0", "source": { "type": "git", "url": "https://github.com/twigphp/cssinliner-extra.git", - "reference": "7312a0275812b86918febb4b7a67d0cb084c5d02" + "reference": "cef36c444b1cce4c0978d7aebd20427671a918f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/cssinliner-extra/zipball/7312a0275812b86918febb4b7a67d0cb084c5d02", - "reference": "7312a0275812b86918febb4b7a67d0cb084c5d02", + "url": "https://api.github.com/repos/twigphp/cssinliner-extra/zipball/cef36c444b1cce4c0978d7aebd20427671a918f4", + "reference": "cef36c444b1cce4c0978d7aebd20427671a918f4", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.0.2", "symfony/deprecation-contracts": "^2.5|^3", "tijsverkoyen/css-to-inline-styles": "^2.0", - "twig/twig": "^3.0" + "twig/twig": "^3.13|^4.0" }, "require-dev": { "symfony/phpunit-bridge": "^6.4|^7.0" @@ -14565,7 +14298,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/cssinliner-extra/tree/v3.11.0" + "source": "https://github.com/twigphp/cssinliner-extra/tree/v3.13.0" }, "funding": [ { @@ -14577,27 +14310,27 @@ "type": "tidelift" } ], - "time": "2024-06-21T06:22:31+00:00" + "time": "2024-09-03T13:08:40+00:00" }, { "name": "twig/extra-bundle", - "version": "v3.11.0", + "version": "v3.13.0", "source": { "type": "git", "url": "https://github.com/twigphp/twig-extra-bundle.git", - "reference": "bf8a304eac15838d7724fdf64c345bdefbb75f03" + "reference": "21a9a7aa9f79d4493bb6fed4eb2794339f9551f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/twig-extra-bundle/zipball/bf8a304eac15838d7724fdf64c345bdefbb75f03", - "reference": "bf8a304eac15838d7724fdf64c345bdefbb75f03", + "url": "https://api.github.com/repos/twigphp/twig-extra-bundle/zipball/21a9a7aa9f79d4493bb6fed4eb2794339f9551f5", + "reference": "21a9a7aa9f79d4493bb6fed4eb2794339f9551f5", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.0.2", "symfony/framework-bundle": "^5.4|^6.4|^7.0", "symfony/twig-bundle": "^5.4|^6.4|^7.0", - "twig/twig": "^3.0" + "twig/twig": "^3.0|^4.0" }, "require-dev": { "league/commonmark": "^1.0|^2.0", @@ -14639,7 +14372,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/twig-extra-bundle/tree/v3.11.0" + "source": "https://github.com/twigphp/twig-extra-bundle/tree/v3.13.0" }, "funding": [ { @@ -14651,27 +14384,27 @@ "type": "tidelift" } ], - "time": "2024-06-21T06:25:01+00:00" + "time": "2024-09-01T20:39:12+00:00" }, { "name": "twig/html-extra", - "version": "v3.11.0", + "version": "v3.13.0", "source": { "type": "git", "url": "https://github.com/twigphp/html-extra.git", - "reference": "e5de60eb0afb24a60f371de428864b5df9414aa6" + "reference": "8229e750091171c1f11801a525927811c7ac5a7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/html-extra/zipball/e5de60eb0afb24a60f371de428864b5df9414aa6", - "reference": "e5de60eb0afb24a60f371de428864b5df9414aa6", + "url": "https://api.github.com/repos/twigphp/html-extra/zipball/8229e750091171c1f11801a525927811c7ac5a7e", + "reference": "8229e750091171c1f11801a525927811c7ac5a7e", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.0.2", "symfony/deprecation-contracts": "^2.5|^3", "symfony/mime": "^5.4|^6.4|^7.0", - "twig/twig": "^3.0" + "twig/twig": "^3.13|^4.0" }, "require-dev": { "symfony/phpunit-bridge": "^6.4|^7.0" @@ -14707,7 +14440,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/html-extra/tree/v3.11.0" + "source": "https://github.com/twigphp/html-extra/tree/v3.13.0" }, "funding": [ { @@ -14719,26 +14452,26 @@ "type": "tidelift" } ], - "time": "2024-06-21T06:25:01+00:00" + "time": "2024-09-03T13:08:40+00:00" }, { "name": "twig/intl-extra", - "version": "v3.11.0", + "version": "v3.13.0", "source": { "type": "git", "url": "https://github.com/twigphp/intl-extra.git", - "reference": "e9cadd61342e71e45b2f4f0558122433fd7e4566" + "reference": "1b8d78c5db08bdc61015fd55009d2e84b3aa7e38" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/intl-extra/zipball/e9cadd61342e71e45b2f4f0558122433fd7e4566", - "reference": "e9cadd61342e71e45b2f4f0558122433fd7e4566", + "url": "https://api.github.com/repos/twigphp/intl-extra/zipball/1b8d78c5db08bdc61015fd55009d2e84b3aa7e38", + "reference": "1b8d78c5db08bdc61015fd55009d2e84b3aa7e38", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.0.2", "symfony/intl": "^5.4|^6.4|^7.0", - "twig/twig": "^3.10" + "twig/twig": "^3.13|^4.0" }, "require-dev": { "symfony/phpunit-bridge": "^6.4|^7.0" @@ -14771,7 +14504,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/intl-extra/tree/v3.11.0" + "source": "https://github.com/twigphp/intl-extra/tree/v3.13.0" }, "funding": [ { @@ -14783,28 +14516,27 @@ "type": "tidelift" } ], - "time": "2024-06-21T06:25:01+00:00" + "time": "2024-09-03T13:08:40+00:00" }, { "name": "twig/twig", - "version": "v3.11.1", + "version": "v3.14.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "ff063afc691e1cfda6714f1915ed766cb108d188" + "reference": "126b2c97818dbff0cdf3fbfc881aedb3d40aae72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/ff063afc691e1cfda6714f1915ed766cb108d188", - "reference": "ff063afc691e1cfda6714f1915ed766cb108d188", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/126b2c97818dbff0cdf3fbfc881aedb3d40aae72", + "reference": "126b2c97818dbff0cdf3fbfc881aedb3d40aae72", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.0.2", "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-mbstring": "^1.3", - "symfony/polyfill-php80": "^1.22", "symfony/polyfill-php81": "^1.29" }, "require-dev": { @@ -14851,7 +14583,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.11.1" + "source": "https://github.com/twigphp/Twig/tree/v3.14.0" }, "funding": [ { @@ -14863,7 +14595,7 @@ "type": "tidelift" } ], - "time": "2024-09-10T10:40:14+00:00" + "time": "2024-09-09T17:55:12+00:00" }, { "name": "web-token/jwt-library", @@ -15505,25 +15237,142 @@ }, "time": "2024-01-02T13:46:09+00:00" }, + { + "name": "icecave/parity", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/icecave/parity.git", + "reference": "0109fef58b3230d23b20b2ac52ecdf477218d300" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/icecave/parity/zipball/0109fef58b3230d23b20b2ac52ecdf477218d300", + "reference": "0109fef58b3230d23b20b2ac52ecdf477218d300", + "shasum": "" + }, + "require": { + "icecave/repr": "~1", + "php": ">=5.3" + }, + "require-dev": { + "eloquent/liberator": "~1", + "icecave/archer": "~1" + }, + "suggest": { + "eloquent/asplode": "Drop-in exception-based error handling." + }, + "type": "library", + "autoload": { + "psr-0": { + "Icecave\\Parity": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "James Harris", + "email": "james.harris@icecave.com.au", + "homepage": "https://github.com/jmalloc" + } + ], + "description": "A customizable deep comparison library.", + "homepage": "https://github.com/IcecaveStudios/parity", + "keywords": [ + "compare", + "comparison", + "equal", + "equality", + "greater", + "less", + "sort", + "sorting" + ], + "support": { + "issues": "https://github.com/icecave/parity/issues", + "source": "https://github.com/icecave/parity/tree/1.0.0" + }, + "time": "2014-01-17T05:56:27+00:00" + }, + { + "name": "icecave/repr", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/icecave/repr.git", + "reference": "8a3d2953adf5f464a06e3e2587aeacc97e2bed07" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/icecave/repr/zipball/8a3d2953adf5f464a06e3e2587aeacc97e2bed07", + "reference": "8a3d2953adf5f464a06e3e2587aeacc97e2bed07", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "icecave/archer": "~1" + }, + "suggest": { + "eloquent/asplode": "Drop-in exception-based error handling." + }, + "type": "library", + "autoload": { + "psr-4": { + "Icecave\\Repr\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "James Harris", + "email": "james.harris@icecave.com.au", + "homepage": "https://github.com/jmalloc" + } + ], + "description": "A library for generating string representations of any value, inspired by Python's reprlib library.", + "homepage": "https://github.com/IcecaveStudios/repr", + "keywords": [ + "human", + "readable", + "repr", + "representation", + "string" + ], + "support": { + "issues": "https://github.com/icecave/repr/issues", + "source": "https://github.com/icecave/repr/tree/1.0.1" + }, + "time": "2014-07-25T05:44:41+00:00" + }, { "name": "justinrainbow/json-schema", - "version": "5.3.0", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/jsonrainbow/json-schema.git", - "reference": "feb2ca6dd1cebdaf1ed60a4c8de2e53ce11c4fd8" + "reference": "a38c6198d53b09c0702f440585a4f4a5d9137bd9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/feb2ca6dd1cebdaf1ed60a4c8de2e53ce11c4fd8", - "reference": "feb2ca6dd1cebdaf1ed60a4c8de2e53ce11c4fd8", + "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/a38c6198d53b09c0702f440585a4f4a5d9137bd9", + "reference": "a38c6198d53b09c0702f440585a4f4a5d9137bd9", "shasum": "" }, "require": { - "php": ">=7.1" + "icecave/parity": "1.0.0", + "marc-mabe/php-enum": "^2.0 || ^3.0 || ^4.0", + "php": ">=5.3.3" }, "require-dev": { - "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", + "friendsofphp/php-cs-fixer": "~2.2.20 || ~2.19.0", "json-schema/json-schema-test-suite": "1.2.0", "phpunit/phpunit": "^4.8.35" }, @@ -15531,6 +15380,11 @@ "bin/validate-json" ], "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.x-dev" + } + }, "autoload": { "psr-4": { "JsonSchema\\": "src/JsonSchema/" @@ -15559,16 +15413,89 @@ } ], "description": "A library to validate a json schema.", - "homepage": "https://github.com/justinrainbow/json-schema", + "homepage": "https://github.com/jsonrainbow/json-schema", "keywords": [ "json", "schema" ], "support": { "issues": "https://github.com/jsonrainbow/json-schema/issues", - "source": "https://github.com/jsonrainbow/json-schema/tree/5.3.0" + "source": "https://github.com/jsonrainbow/json-schema/tree/6.0.0" + }, + "time": "2024-07-30T17:49:21+00:00" + }, + { + "name": "marc-mabe/php-enum", + "version": "v4.7.0", + "source": { + "type": "git", + "url": "https://github.com/marc-mabe/php-enum.git", + "reference": "3da42cc1daceaf98c858e56f59d1ccd52b011fdc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/marc-mabe/php-enum/zipball/3da42cc1daceaf98c858e56f59d1ccd52b011fdc", + "reference": "3da42cc1daceaf98c858e56f59d1ccd52b011fdc", + "shasum": "" + }, + "require": { + "ext-reflection": "*", + "php": "^7.1 | ^8.0" + }, + "require-dev": { + "phpbench/phpbench": "^0.16.10 || ^1.0.4", + "phpstan/phpstan": "^1.3.1", + "phpunit/phpunit": "^7.5.20 | ^8.5.22 | ^9.5.11", + "vimeo/psalm": "^4.17.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.6-dev", + "dev-3.x": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "MabeEnum\\": "src/" + }, + "classmap": [ + "stubs/Stringable.php" + ] }, - "time": "2024-07-06T21:00:26+00:00" + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Marc Bennewitz", + "email": "dev@mabe.berlin", + "homepage": "https://mabe.berlin/", + "role": "Lead" + } + ], + "description": "Simple and fast implementation of enumerations with native PHP", + "homepage": "https://github.com/marc-mabe/php-enum", + "keywords": [ + "enum", + "enum-map", + "enum-set", + "enumeration", + "enumerator", + "enummap", + "enumset", + "map", + "set", + "type", + "type-hint", + "typehint" + ], + "support": { + "issues": "https://github.com/marc-mabe/php-enum/issues", + "source": "https://github.com/marc-mabe/php-enum/tree/v4.7.0" + }, + "time": "2022-04-19T02:21:46+00:00" }, { "name": "masterminds/html5", @@ -15875,16 +15802,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.11.10", + "version": "1.12.3", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "640410b32995914bde3eed26fa89552f9c2c082f" + "reference": "0fcbf194ab63d8159bb70d9aa3e1350051632009" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/640410b32995914bde3eed26fa89552f9c2c082f", - "reference": "640410b32995914bde3eed26fa89552f9c2c082f", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/0fcbf194ab63d8159bb70d9aa3e1350051632009", + "reference": "0fcbf194ab63d8159bb70d9aa3e1350051632009", "shasum": "" }, "require": { @@ -15929,39 +15856,39 @@ "type": "github" } ], - "time": "2024-08-08T09:02:50+00:00" + "time": "2024-09-09T08:10:35+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "10.1.15", + "version": "11.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "5da8b1728acd1e6ffdf2ff32ffbdfd04307f26ae" + "reference": "ebdffc9e09585dafa71b9bffcdb0a229d4704c45" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/5da8b1728acd1e6ffdf2ff32ffbdfd04307f26ae", - "reference": "5da8b1728acd1e6ffdf2ff32ffbdfd04307f26ae", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ebdffc9e09585dafa71b9bffcdb0a229d4704c45", + "reference": "ebdffc9e09585dafa71b9bffcdb0a229d4704c45", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=8.1", - "phpunit/php-file-iterator": "^4.0", - "phpunit/php-text-template": "^3.0", - "sebastian/code-unit-reverse-lookup": "^3.0", - "sebastian/complexity": "^3.0", - "sebastian/environment": "^6.0", - "sebastian/lines-of-code": "^2.0", - "sebastian/version": "^4.0", - "theseer/tokenizer": "^1.2.0" + "nikic/php-parser": "^5.1.0", + "php": ">=8.2", + "phpunit/php-file-iterator": "^5.0.1", + "phpunit/php-text-template": "^4.0.1", + "sebastian/code-unit-reverse-lookup": "^4.0.1", + "sebastian/complexity": "^4.0.1", + "sebastian/environment": "^7.2.0", + "sebastian/lines-of-code": "^3.0.1", + "sebastian/version": "^5.0.1", + "theseer/tokenizer": "^1.2.3" }, "require-dev": { - "phpunit/phpunit": "^10.1" + "phpunit/phpunit": "^11.0" }, "suggest": { "ext-pcov": "PHP extension that provides line coverage", @@ -15970,7 +15897,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.1-dev" + "dev-main": "11.0.x-dev" } }, "autoload": { @@ -15999,7 +15926,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.15" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.6" }, "funding": [ { @@ -16007,32 +15934,32 @@ "type": "github" } ], - "time": "2024-06-29T08:25:15+00:00" + "time": "2024-08-22T04:37:56+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "4.1.0", + "version": "5.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", - "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6", + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -16060,7 +15987,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.0" }, "funding": [ { @@ -16068,28 +15995,28 @@ "type": "github" } ], - "time": "2023-08-31T06:24:48+00:00" + "time": "2024-08-27T05:02:59+00:00" }, { "name": "phpunit/php-invoker", - "version": "4.0.0", + "version": "5.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", - "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { "ext-pcntl": "*", - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "suggest": { "ext-pcntl": "*" @@ -16097,7 +16024,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -16123,7 +16050,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1" }, "funding": [ { @@ -16131,32 +16059,32 @@ "type": "github" } ], - "time": "2023-02-03T06:56:09+00:00" + "time": "2024-07-03T05:07:44+00:00" }, { "name": "phpunit/php-text-template", - "version": "3.0.1", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", - "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -16183,7 +16111,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-text-template/issues", "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" + "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1" }, "funding": [ { @@ -16191,32 +16119,32 @@ "type": "github" } ], - "time": "2023-08-31T14:07:24+00:00" + "time": "2024-07-03T05:08:43+00:00" }, { "name": "phpunit/php-timer", - "version": "6.0.0", + "version": "7.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", - "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -16242,7 +16170,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1" }, "funding": [ { @@ -16250,20 +16179,20 @@ "type": "github" } ], - "time": "2023-02-03T06:57:52+00:00" + "time": "2024-07-03T05:09:35+00:00" }, { "name": "phpunit/phpunit", - "version": "10.5.30", + "version": "11.3.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "b15524febac0153876b4ba9aab3326c2ee94c897" + "reference": "d2ef57db1410b102b250e0cdce6675a60c2a993d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b15524febac0153876b4ba9aab3326c2ee94c897", - "reference": "b15524febac0153876b4ba9aab3326c2ee94c897", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d2ef57db1410b102b250e0cdce6675a60c2a993d", + "reference": "d2ef57db1410b102b250e0cdce6675a60c2a993d", "shasum": "" }, "require": { @@ -16276,23 +16205,22 @@ "myclabs/deep-copy": "^1.12.0", "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", - "php": ">=8.1", - "phpunit/php-code-coverage": "^10.1.15", - "phpunit/php-file-iterator": "^4.1.0", - "phpunit/php-invoker": "^4.0.0", - "phpunit/php-text-template": "^3.0.1", - "phpunit/php-timer": "^6.0.0", - "sebastian/cli-parser": "^2.0.1", - "sebastian/code-unit": "^2.0.0", - "sebastian/comparator": "^5.0.2", - "sebastian/diff": "^5.1.1", - "sebastian/environment": "^6.1.0", - "sebastian/exporter": "^5.1.2", - "sebastian/global-state": "^6.0.2", - "sebastian/object-enumerator": "^5.0.0", - "sebastian/recursion-context": "^5.0.0", - "sebastian/type": "^4.0.0", - "sebastian/version": "^4.0.1" + "php": ">=8.2", + "phpunit/php-code-coverage": "^11.0.6", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-invoker": "^5.0.1", + "phpunit/php-text-template": "^4.0.1", + "phpunit/php-timer": "^7.0.1", + "sebastian/cli-parser": "^3.0.2", + "sebastian/code-unit": "^3.0.1", + "sebastian/comparator": "^6.0.2", + "sebastian/diff": "^6.0.2", + "sebastian/environment": "^7.2.0", + "sebastian/exporter": "^6.1.3", + "sebastian/global-state": "^7.0.2", + "sebastian/object-enumerator": "^6.0.1", + "sebastian/type": "^5.0.1", + "sebastian/version": "^5.0.1" }, "suggest": { "ext-soap": "To be able to generate mocks based on WSDL files" @@ -16303,7 +16231,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.5-dev" + "dev-main": "11.3-dev" } }, "autoload": { @@ -16335,7 +16263,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.30" + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.3.4" }, "funding": [ { @@ -16351,32 +16279,32 @@ "type": "tidelift" } ], - "time": "2024-08-13T06:09:37+00:00" + "time": "2024-09-09T06:08:34+00:00" }, { "name": "sebastian/cli-parser", - "version": "2.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084" + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084", - "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -16400,7 +16328,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/cli-parser/issues", "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1" + "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.2" }, "funding": [ { @@ -16408,32 +16336,32 @@ "type": "github" } ], - "time": "2024-03-02T07:12:49+00:00" + "time": "2024-07-03T04:41:36+00:00" }, { "name": "sebastian/code-unit", - "version": "2.0.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" + "reference": "6bb7d09d6623567178cf54126afa9c2310114268" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", - "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/6bb7d09d6623567178cf54126afa9c2310114268", + "reference": "6bb7d09d6623567178cf54126afa9c2310114268", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -16456,7 +16384,8 @@ "homepage": "https://github.com/sebastianbergmann/code-unit", "support": { "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" + "security": "https://github.com/sebastianbergmann/code-unit/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.1" }, "funding": [ { @@ -16464,32 +16393,32 @@ "type": "github" } ], - "time": "2023-02-03T06:58:43+00:00" + "time": "2024-07-03T04:44:28+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "3.0.0", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" + "reference": "183a9b2632194febd219bb9246eee421dad8d45e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", - "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -16511,7 +16440,8 @@ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "support": { "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" + "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.1" }, "funding": [ { @@ -16519,36 +16449,36 @@ "type": "github" } ], - "time": "2023-02-03T06:59:15+00:00" + "time": "2024-07-03T04:45:54+00:00" }, { "name": "sebastian/comparator", - "version": "5.0.2", + "version": "6.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "2d3e04c3b4c1e84a5e7382221ad8883c8fbc4f53" + "reference": "450d8f237bd611c45b5acf0733ce43e6bb280f81" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2d3e04c3b4c1e84a5e7382221ad8883c8fbc4f53", - "reference": "2d3e04c3b4c1e84a5e7382221ad8883c8fbc4f53", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/450d8f237bd611c45b5acf0733ce43e6bb280f81", + "reference": "450d8f237bd611c45b5acf0733ce43e6bb280f81", "shasum": "" }, "require": { "ext-dom": "*", "ext-mbstring": "*", - "php": ">=8.1", - "sebastian/diff": "^5.0", - "sebastian/exporter": "^5.0" + "php": ">=8.2", + "sebastian/diff": "^6.0", + "sebastian/exporter": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^10.4" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -16588,7 +16518,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.2" + "source": "https://github.com/sebastianbergmann/comparator/tree/6.0.2" }, "funding": [ { @@ -16596,33 +16526,33 @@ "type": "github" } ], - "time": "2024-08-12T06:03:08+00:00" + "time": "2024-08-12T06:07:25+00:00" }, { "name": "sebastian/complexity", - "version": "3.2.0", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "68ff824baeae169ec9f2137158ee529584553799" + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", - "reference": "68ff824baeae169ec9f2137158ee529584553799", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0", "shasum": "" }, "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=8.1" + "nikic/php-parser": "^5.0", + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.2-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -16646,7 +16576,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", "security": "https://github.com/sebastianbergmann/complexity/security/policy", - "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" + "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.1" }, "funding": [ { @@ -16654,33 +16584,33 @@ "type": "github" } ], - "time": "2023-12-21T08:37:17+00:00" + "time": "2024-07-03T04:49:50+00:00" }, { "name": "sebastian/diff", - "version": "5.1.1", + "version": "6.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e" + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e", - "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0", - "symfony/process": "^6.4" + "phpunit/phpunit": "^11.0", + "symfony/process": "^4.2 || ^5" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.1-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -16713,7 +16643,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1" + "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2" }, "funding": [ { @@ -16721,27 +16651,27 @@ "type": "github" } ], - "time": "2024-03-02T07:15:17+00:00" + "time": "2024-07-03T04:53:05+00:00" }, { "name": "sebastian/environment", - "version": "6.1.0", + "version": "7.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "8074dbcd93529b357029f5cc5058fd3e43666984" + "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984", - "reference": "8074dbcd93529b357029f5cc5058fd3e43666984", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", + "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "suggest": { "ext-posix": "*" @@ -16749,7 +16679,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "6.1-dev" + "dev-main": "7.2-dev" } }, "autoload": { @@ -16777,7 +16707,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0" + "source": "https://github.com/sebastianbergmann/environment/tree/7.2.0" }, "funding": [ { @@ -16785,34 +16715,34 @@ "type": "github" } ], - "time": "2024-03-23T08:47:14+00:00" + "time": "2024-07-03T04:54:44+00:00" }, { "name": "sebastian/exporter", - "version": "5.1.2", + "version": "6.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "955288482d97c19a372d3f31006ab3f37da47adf" + "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/955288482d97c19a372d3f31006ab3f37da47adf", - "reference": "955288482d97c19a372d3f31006ab3f37da47adf", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e", + "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e", "shasum": "" }, "require": { "ext-mbstring": "*", - "php": ">=8.1", - "sebastian/recursion-context": "^5.0" + "php": ">=8.2", + "sebastian/recursion-context": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.2" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.1-dev" + "dev-main": "6.1-dev" } }, "autoload": { @@ -16855,7 +16785,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.2" + "source": "https://github.com/sebastianbergmann/exporter/tree/6.1.3" }, "funding": [ { @@ -16863,35 +16793,35 @@ "type": "github" } ], - "time": "2024-03-02T07:17:12+00:00" + "time": "2024-07-03T04:56:19+00:00" }, { "name": "sebastian/global-state", - "version": "6.0.2", + "version": "7.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9" + "reference": "3be331570a721f9a4b5917f4209773de17f747d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", - "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7", "shasum": "" }, "require": { - "php": ">=8.1", - "sebastian/object-reflector": "^3.0", - "sebastian/recursion-context": "^5.0" + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -16917,7 +16847,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", "security": "https://github.com/sebastianbergmann/global-state/security/policy", - "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2" + "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.2" }, "funding": [ { @@ -16925,33 +16855,33 @@ "type": "github" } ], - "time": "2024-03-02T07:19:19+00:00" + "time": "2024-07-03T04:57:36+00:00" }, { "name": "sebastian/lines-of-code", - "version": "2.0.2", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", - "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a", "shasum": "" }, "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=8.1" + "nikic/php-parser": "^5.0", + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -16975,7 +16905,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.1" }, "funding": [ { @@ -16983,34 +16913,34 @@ "type": "github" } ], - "time": "2023-12-21T08:38:20+00:00" + "time": "2024-07-03T04:58:38+00:00" }, { "name": "sebastian/object-enumerator", - "version": "5.0.0", + "version": "6.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" + "reference": "f5b498e631a74204185071eb41f33f38d64608aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", - "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa", "shasum": "" }, "require": { - "php": ">=8.1", - "sebastian/object-reflector": "^3.0", - "sebastian/recursion-context": "^5.0" + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -17032,7 +16962,8 @@ "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1" }, "funding": [ { @@ -17040,32 +16971,32 @@ "type": "github" } ], - "time": "2023-02-03T07:08:32+00:00" + "time": "2024-07-03T05:00:13+00:00" }, { "name": "sebastian/object-reflector", - "version": "3.0.0", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", - "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -17087,7 +17018,8 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1" }, "funding": [ { @@ -17095,32 +17027,32 @@ "type": "github" } ], - "time": "2023-02-03T07:06:18+00:00" + "time": "2024-07-03T05:01:32+00:00" }, { "name": "sebastian/recursion-context", - "version": "5.0.0", + "version": "6.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "05909fb5bc7df4c52992396d0116aed689f93712" + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", - "reference": "05909fb5bc7df4c52992396d0116aed689f93712", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/694d156164372abbd149a4b85ccda2e4670c0e16", + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -17150,7 +17082,8 @@ "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.2" }, "funding": [ { @@ -17158,32 +17091,32 @@ "type": "github" } ], - "time": "2023-02-03T07:05:40+00:00" + "time": "2024-07-03T05:10:34+00:00" }, { "name": "sebastian/type", - "version": "4.0.0", + "version": "5.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" + "reference": "fb6a6566f9589e86661291d13eba708cce5eb4aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb6a6566f9589e86661291d13eba708cce5eb4aa", + "reference": "fb6a6566f9589e86661291d13eba708cce5eb4aa", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -17206,7 +17139,8 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/5.0.1" }, "funding": [ { @@ -17214,29 +17148,29 @@ "type": "github" } ], - "time": "2023-02-03T07:10:45+00:00" + "time": "2024-07-03T05:11:49+00:00" }, { "name": "sebastian/version", - "version": "4.0.1", + "version": "5.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" + "reference": "45c9debb7d039ce9b97de2f749c2cf5832a06ac4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/45c9debb7d039ce9b97de2f749c2cf5832a06ac4", + "reference": "45c9debb7d039ce9b97de2f749c2cf5832a06ac4", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -17259,7 +17193,8 @@ "homepage": "https://github.com/sebastianbergmann/version", "support": { "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/5.0.1" }, "funding": [ { @@ -17267,7 +17202,7 @@ "type": "github" } ], - "time": "2023-02-07T11:34:05+00:00" + "time": "2024-07-03T05:13:08+00:00" }, { "name": "symfony/browser-kit", @@ -17480,16 +17415,16 @@ }, { "name": "symfony/maker-bundle", - "version": "v1.60.0", + "version": "v1.61.0", "source": { "type": "git", "url": "https://github.com/symfony/maker-bundle.git", - "reference": "c305a02a22974670f359d4274c9431e1a191f559" + "reference": "a3b7f14d349f8f44ed752d4dde2263f77510cc18" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/c305a02a22974670f359d4274c9431e1a191f559", - "reference": "c305a02a22974670f359d4274c9431e1a191f559", + "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/a3b7f14d349f8f44ed752d4dde2263f77510cc18", + "reference": "a3b7f14d349f8f44ed752d4dde2263f77510cc18", "shasum": "" }, "require": { @@ -17552,7 +17487,7 @@ ], "support": { "issues": "https://github.com/symfony/maker-bundle/issues", - "source": "https://github.com/symfony/maker-bundle/tree/v1.60.0" + "source": "https://github.com/symfony/maker-bundle/tree/v1.61.0" }, "funding": [ { @@ -17568,20 +17503,20 @@ "type": "tidelift" } ], - "time": "2024-06-10T06:03:18+00:00" + "time": "2024-08-29T22:50:23+00:00" }, { "name": "symfony/phpunit-bridge", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "e823122d31935eb711e2767c31f3d71cb0b87fb1" + "reference": "e876eb90e32a8fc4c4911d458e09f88d65877d1c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/e823122d31935eb711e2767c31f3d71cb0b87fb1", - "reference": "e823122d31935eb711e2767c31f3d71cb0b87fb1", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/e876eb90e32a8fc4c4911d458e09f88d65877d1c", + "reference": "e876eb90e32a8fc4c4911d458e09f88d65877d1c", "shasum": "" }, "require": { @@ -17634,7 +17569,7 @@ "description": "Provides utilities for PHPUnit, especially user deprecation notices management", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/phpunit-bridge/tree/v7.1.3" + "source": "https://github.com/symfony/phpunit-bridge/tree/v7.1.4" }, "funding": [ { @@ -17650,20 +17585,20 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:41:01+00:00" + "time": "2024-08-13T14:28:19+00:00" }, { "name": "symfony/web-profiler-bundle", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/web-profiler-bundle.git", - "reference": "b9357f73d2c14dcd36783a67386f510654828668" + "reference": "3cfc775277a8f2dacdd0f72d196bc87b272a763f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/b9357f73d2c14dcd36783a67386f510654828668", - "reference": "b9357f73d2c14dcd36783a67386f510654828668", + "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/3cfc775277a8f2dacdd0f72d196bc87b272a763f", + "reference": "3cfc775277a8f2dacdd0f72d196bc87b272a763f", "shasum": "" }, "require": { @@ -17715,7 +17650,7 @@ "dev" ], "support": { - "source": "https://github.com/symfony/web-profiler-bundle/tree/v7.1.3" + "source": "https://github.com/symfony/web-profiler-bundle/tree/v7.1.4" }, "funding": [ { @@ -17731,7 +17666,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:41:01+00:00" + "time": "2024-08-12T09:59:40+00:00" }, { "name": "theseer/tokenizer", diff --git a/src/Controller/User/Profile/User2FAController.php b/src/Controller/User/Profile/User2FAController.php index ed9df92d4..03fbe4684 100644 --- a/src/Controller/User/Profile/User2FAController.php +++ b/src/Controller/User/Profile/User2FAController.php @@ -12,8 +12,8 @@ use App\Service\UserManager; use Endroid\QrCode\Builder\Builder; use Endroid\QrCode\Encoding\Encoding; -use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelHigh; -use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeMargin; +use Endroid\QrCode\ErrorCorrectionLevel; +use Endroid\QrCode\RoundBlockSizeMode; use Endroid\QrCode\Writer\PngWriter; use Psr\Log\LoggerInterface; use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\Totp\TotpAuthenticatorInterface; @@ -130,10 +130,10 @@ public function qrCode(Request $request): Response ->writerOptions([]) ->data($this->totpAuthenticator->getQRContent($user)) ->encoding(new Encoding('UTF-8')) - ->errorCorrectionLevel(new ErrorCorrectionLevelHigh()) + ->errorCorrectionLevel(ErrorCorrectionLevel::High) ->size(250) ->margin(0) - ->roundBlockSizeMode(new RoundBlockSizeModeMargin()) + ->roundBlockSizeMode(RoundBlockSizeMode::Margin) ->build(); return new Response($result->getString(), 200, ['Content-Type' => 'image/png']); diff --git a/symfony.lock b/symfony.lock index 10d6e0485..a6889adb1 100644 --- a/symfony.lock +++ b/symfony.lock @@ -172,12 +172,6 @@ "config/packages/knpu_oauth2_client.yaml" ] }, - "laminas/laminas-diactoros": { - "version": "2.6.0" - }, - "landrok/activitypub": { - "version": "0.5.6" - }, "lcobucci/clock": { "version": "2.0.0" }, @@ -328,9 +322,6 @@ "phpdocumentor/type-resolver": { "version": "1.4.0" }, - "phpseclib/phpseclib": { - "version": "3.0.9" - }, "phpstan/phpdoc-parser": { "version": "0.4.9" }, From 4d930f6c8cf276bb2ec14ed5e579f4400af4222c Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Fri, 13 Sep 2024 12:24:09 +0200 Subject: [PATCH 273/335] Disable badges for now (#1116) --- src/Form/EntryArticleType.php | 16 ++++++++-------- src/Form/EntryEditType.php | 16 ++++++++-------- src/Form/EntryImageType.php | 16 ++++++++-------- src/Form/EntryLinkType.php | 16 ++++++++-------- templates/entry/_form_article.html.twig | 2 +- templates/entry/_form_edit.html.twig | 2 +- templates/entry/_form_image.html.twig | 2 +- templates/entry/_form_link.html.twig | 2 +- templates/entry/create_article.html.twig | 4 +++- templates/entry/create_image.html.twig | 4 +++- templates/entry/create_link.html.twig | 4 +++- templates/entry/edit_entry.html.twig | 4 +++- templates/magazine/create.html.twig | 4 +++- templates/magazine/list_abandoned.html.twig | 1 + 14 files changed, 52 insertions(+), 41 deletions(-) diff --git a/src/Form/EntryArticleType.php b/src/Form/EntryArticleType.php index ea0769218..999096291 100644 --- a/src/Form/EntryArticleType.php +++ b/src/Form/EntryArticleType.php @@ -10,7 +10,7 @@ use App\Form\EventListener\DefaultLanguage; use App\Form\EventListener\DisableFieldsOnEntryEdit; use App\Form\EventListener\ImageListener; -use App\Form\Type\BadgesType; +// use App\Form\Type\BadgesType; use App\Form\Type\LanguageType; use App\Form\Type\MagazineAutocompleteType; use Symfony\Component\Form\AbstractType; @@ -47,13 +47,13 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'delimiter' => ' ', ], ]) - ->add( - 'badges', - BadgesType::class, - [ - 'required' => false, - ] - ) + // ->add( + // 'badges', + // BadgesType::class, + // [ + // 'required' => false, + // ] + // ) ->add( 'image', FileType::class, diff --git a/src/Form/EntryEditType.php b/src/Form/EntryEditType.php index 1747be892..c331eed00 100644 --- a/src/Form/EntryEditType.php +++ b/src/Form/EntryEditType.php @@ -10,7 +10,7 @@ use App\Form\EventListener\DefaultLanguage; use App\Form\EventListener\DisableFieldsOnEntryEdit; use App\Form\EventListener\ImageListener; -use App\Form\Type\BadgesType; +// use App\Form\Type\BadgesType; use App\Form\Type\LanguageType; use App\Form\Type\MagazineAutocompleteType; use Symfony\Component\Form\AbstractType; @@ -48,13 +48,13 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'delimiter' => ' ', ], ]) - ->add( - 'badges', - BadgesType::class, - [ - 'required' => false, - ] - ) + // ->add( + // 'badges', + // BadgesType::class, + // [ + // 'required' => false, + // ] + // ) ->add( 'image', FileType::class, diff --git a/src/Form/EntryImageType.php b/src/Form/EntryImageType.php index 44c53a625..49ea7f2c9 100644 --- a/src/Form/EntryImageType.php +++ b/src/Form/EntryImageType.php @@ -11,7 +11,7 @@ use App\Form\EventListener\DisableFieldsOnEntryEdit; use App\Form\EventListener\ImageListener; use App\Form\EventListener\RemoveFieldsOnEntryImageEdit; -use App\Form\Type\BadgesType; +// use App\Form\Type\BadgesType; use App\Form\Type\LanguageType; use App\Form\Type\MagazineAutocompleteType; use Symfony\Component\Form\AbstractType; @@ -48,13 +48,13 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'delimiter' => ' ', ], ]) - ->add( - 'badges', - BadgesType::class, - [ - 'required' => false, - ] - ) + // ->add( + // 'badges', + // BadgesType::class, + // [ + // 'required' => false, + // ] + // ) ->add( 'image', FileType::class, diff --git a/src/Form/EntryLinkType.php b/src/Form/EntryLinkType.php index f3e78811e..f879d5484 100644 --- a/src/Form/EntryLinkType.php +++ b/src/Form/EntryLinkType.php @@ -10,7 +10,7 @@ use App\Form\EventListener\DefaultLanguage; use App\Form\EventListener\DisableFieldsOnEntryEdit; use App\Form\EventListener\ImageListener; -use App\Form\Type\BadgesType; +// use App\Form\Type\BadgesType; use App\Form\Type\LanguageType; use App\Form\Type\MagazineAutocompleteType; use Symfony\Component\Form\AbstractType; @@ -51,13 +51,13 @@ public function buildForm(FormBuilderInterface $builder, array $options): void ->add('body', TextareaType::class, [ 'required' => false, ]) - ->add( - 'badges', - BadgesType::class, - [ - 'required' => false, - ] - ) + // ->add( + // 'badges', + // BadgesType::class, + // [ + // 'required' => false, + // ] + // ) ->add('magazine', MagazineAutocompleteType::class) ->add( 'image', diff --git a/templates/entry/_form_article.html.twig b/templates/entry/_form_article.html.twig index b493b39ec..ca937bf19 100644 --- a/templates/entry/_form_article.html.twig +++ b/templates/entry/_form_article.html.twig @@ -24,7 +24,7 @@ }}) }} {{ form_row(form.magazine, {label: false}) }} {{ form_row(form.tags, {label: 'tags'}) }} - {{ form_row(form.badges, {label: 'badges'}) }} + {# form_row(form.badges, {label: 'badges'}) #}
          {{ form_row(form.isAdult, {label: 'is_adult', row_attr: {class: 'checkbox'}}) }} {{ form_row(form.isOc, {label: 'oc', row_attr: {class: 'checkbox'}}) }} diff --git a/templates/entry/_form_edit.html.twig b/templates/entry/_form_edit.html.twig index 9034a2acc..df791e587 100644 --- a/templates/entry/_form_edit.html.twig +++ b/templates/entry/_form_edit.html.twig @@ -31,7 +31,7 @@ }}) }} {{ form_row(form.magazine, {label: false}) }} {{ form_row(form.tags, {label: 'tags'}) }} - {{ form_row(form.badges, {label: 'badges'}) }} + {# form_row(form.badges, {label: 'badges'}) #}
          {{ form_row(form.isAdult, {label: 'is_adult', row_attr: {class: 'checkbox'}}) }} {{ form_row(form.isOc, {label: 'oc', row_attr: {class: 'checkbox'}}) }} diff --git a/templates/entry/_form_image.html.twig b/templates/entry/_form_image.html.twig index 6c18f211f..88b3306bc 100644 --- a/templates/entry/_form_image.html.twig +++ b/templates/entry/_form_image.html.twig @@ -14,7 +14,7 @@ }}) }} {{ form_row(form.magazine, {label: false}) }} {{ form_row(form.tags, {label: 'tags'}) }} - {{ form_row(form.badges, {label: 'badges'}) }} + {# form_row(form.badges, {label: 'badges'}) #}
          {{ form_row(form.isAdult, {label: 'is_adult', row_attr: {class: 'checkbox'}}) }} {{ form_row(form.isOc, {label: 'oc', row_attr: {class: 'checkbox'}}) }} diff --git a/templates/entry/_form_link.html.twig b/templates/entry/_form_link.html.twig index 3b2eb0eb1..6e7eea005 100644 --- a/templates/entry/_form_link.html.twig +++ b/templates/entry/_form_link.html.twig @@ -34,7 +34,7 @@ }}) }} {{ form_row(form.magazine, {label: false}) }} {{ form_row(form.tags, {label: 'tags'}) }} - {{ form_row(form.badges, {label: 'badges'}) }} + {# form_row(form.badges, {label: 'badges'}) #}
          {{ form_row(form.isAdult, {label: 'is_adult', row_attr: {class: 'checkbox'}}) }} {{ form_row(form.isOc, {label: 'oc', row_attr: {class: 'checkbox'}}) }} diff --git a/templates/entry/create_article.html.twig b/templates/entry/create_article.html.twig index 017fec1e7..16951974c 100644 --- a/templates/entry/create_article.html.twig +++ b/templates/entry/create_article.html.twig @@ -14,7 +14,9 @@ {% block body %} {% include 'entry/_create_options.html.twig' %} -

          {{ 'add_new_article'|trans }}

          +
          +

          {{ 'add_new_article'|trans }}

          +
          {% include 'layout/_flash.html.twig' %} {% include('user/_visibility_info.html.twig') %} diff --git a/templates/entry/create_image.html.twig b/templates/entry/create_image.html.twig index 2c1896b14..ae50099d2 100644 --- a/templates/entry/create_image.html.twig +++ b/templates/entry/create_image.html.twig @@ -14,7 +14,9 @@ {% block body %} {% include 'entry/_create_options.html.twig' %} -

          {{ 'add_new_photo'|trans }}

          +
          +

          {{ 'add_new_photo'|trans }}

          +
          {% include('user/_visibility_info.html.twig') %} {% include 'layout/_flash.html.twig' %} diff --git a/templates/entry/create_link.html.twig b/templates/entry/create_link.html.twig index 1f3b17942..8c6dbab7e 100644 --- a/templates/entry/create_link.html.twig +++ b/templates/entry/create_link.html.twig @@ -14,7 +14,9 @@ {% block body %} {% include 'entry/_create_options.html.twig' %} -

          {{ 'add_new_link'|trans }}

          +
          +

          {{ 'add_new_link'|trans }}

          +
          {% include 'layout/_flash.html.twig' %} {% include('user/_visibility_info.html.twig') %} diff --git a/templates/entry/edit_entry.html.twig b/templates/entry/edit_entry.html.twig index f1626172f..c274bf8c2 100644 --- a/templates/entry/edit_entry.html.twig +++ b/templates/entry/edit_entry.html.twig @@ -18,7 +18,9 @@ class: 'section--top' }) }} -

          {{ 'edit_entry'|trans }}

          +
          +

          {{ 'edit_entry'|trans }}

          +
          {% include 'layout/_flash.html.twig' %}
          diff --git a/templates/magazine/create.html.twig b/templates/magazine/create.html.twig index 6f1af4d13..598587163 100644 --- a/templates/magazine/create.html.twig +++ b/templates/magazine/create.html.twig @@ -17,7 +17,9 @@ {% include('user/_visibility_info.html.twig') %} {% if user.visibility is same as 'visible' %} -

          {{ 'create_new_magazine'|trans }}

          +
          +

          {{ 'create_new_magazine'|trans }}

          +
          {{ form_start(form) }} diff --git a/templates/magazine/list_abandoned.html.twig b/templates/magazine/list_abandoned.html.twig index fe51ad43e..8210dea61 100644 --- a/templates/magazine/list_abandoned.html.twig +++ b/templates/magazine/list_abandoned.html.twig @@ -16,6 +16,7 @@

          {{ 'magazines'|trans }}

          + {% include 'magazine/_options.html.twig' %}
          {% if magazines|length %} From f26b674e8c4c6b5060df0155edb0b0d4a5e543c4 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Fri, 13 Sep 2024 14:37:17 +0200 Subject: [PATCH 274/335] Check on empty/null filePath image (#1128) --- src/Command/ImageCacheCommand.php | 42 ++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/src/Command/ImageCacheCommand.php b/src/Command/ImageCacheCommand.php index 431af96c6..dda21ecaa 100644 --- a/src/Command/ImageCacheCommand.php +++ b/src/Command/ImageCacheCommand.php @@ -50,6 +50,9 @@ private function buildUsersCache(): void ->getArrayResult(); foreach ($res as $image) { + if (!$image['filePath']) { + continue; + } $command = $this->getApplication()->find('liip:imagine:cache:resolve'); $arguments = [ @@ -57,8 +60,8 @@ private function buildUsersCache(): void '--filter' => ['avatar_thumb'], ]; - $greetInput = new ArrayInput($arguments); - $returnCode = $command->run($greetInput, new NullOutput()); + $input = new ArrayInput($arguments); + $returnCode = $command->run($input, new NullOutput()); } } @@ -71,6 +74,9 @@ private function buildEntriesCache(): void ->getArrayResult(); foreach ($res as $image) { + if (!$image['filePath']) { + continue; + } $command = $this->getApplication()->find('liip:imagine:cache:resolve'); $arguments = [ @@ -78,8 +84,8 @@ private function buildEntriesCache(): void '--filter' => ['entry_thumb'], ]; - $greetInput = new ArrayInput($arguments); - $returnCode = $command->run($greetInput, new NullOutput()); + $input = new ArrayInput($arguments); + $returnCode = $command->run($input, new NullOutput()); } } @@ -92,6 +98,9 @@ private function buildEntryCommentsCache(): void ->getArrayResult(); foreach ($res as $image) { + if (!$image['filePath']) { + continue; + } $command = $this->getApplication()->find('liip:imagine:cache:resolve'); $arguments = [ @@ -99,8 +108,8 @@ private function buildEntryCommentsCache(): void '--filter' => ['post_thumb'], ]; - $greetInput = new ArrayInput($arguments); - $returnCode = $command->run($greetInput, new NullOutput()); + $input = new ArrayInput($arguments); + $returnCode = $command->run($input, new NullOutput()); } } @@ -113,6 +122,9 @@ private function buildPostsCache(): void ->getArrayResult(); foreach ($res as $image) { + if (!$image['filePath']) { + continue; + } $command = $this->getApplication()->find('liip:imagine:cache:resolve'); $arguments = [ @@ -120,8 +132,8 @@ private function buildPostsCache(): void '--filter' => ['post_thumb'], ]; - $greetInput = new ArrayInput($arguments); - $returnCode = $command->run($greetInput, new NullOutput()); + $input = new ArrayInput($arguments); + $returnCode = $command->run($input, new NullOutput()); } } @@ -134,6 +146,9 @@ private function buildPostCommentsCache(): void ->getArrayResult(); foreach ($res as $image) { + if (!$image['filePath']) { + continue; + } $command = $this->getApplication()->find('liip:imagine:cache:resolve'); $arguments = [ @@ -141,8 +156,8 @@ private function buildPostCommentsCache(): void '--filter' => ['post_thumb'], ]; - $greetInput = new ArrayInput($arguments); - $returnCode = $command->run($greetInput, new NullOutput()); + $input = new ArrayInput($arguments); + $returnCode = $command->run($input, new NullOutput()); } } @@ -155,6 +170,9 @@ private function buildMagazinesCache(): void ->getArrayResult(); foreach ($res as $image) { + if (!$image['filePath']) { + continue; + } $command = $this->getApplication()->find('liip:imagine:cache:resolve'); $arguments = [ @@ -162,8 +180,8 @@ private function buildMagazinesCache(): void '--filter' => ['post_thumb'], ]; - $greetInput = new ArrayInput($arguments); - $returnCode = $command->run($greetInput, new NullOutput()); + $input = new ArrayInput($arguments); + $returnCode = $command->run($input, new NullOutput()); } } } From 89c1334564311dee690d03604782eba08720734c Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Sat, 14 Sep 2024 00:56:08 +0200 Subject: [PATCH 275/335] Check if EntryComment is defined and not null (#1129) --- templates/entry/comment/view.html.twig | 24 ++++++++++++++++++------ translations/messages.en.yaml | 1 + 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/templates/entry/comment/view.html.twig b/templates/entry/comment/view.html.twig index 5538e09e5..7ad9accad 100644 --- a/templates/entry/comment/view.html.twig +++ b/templates/entry/comment/view.html.twig @@ -46,11 +46,23 @@ }) }}" data-controller="subject-list" data-action="{{- DYNAMIC_LISTS is same as V_TRUE ? autoAction : manualAction -}}"> - {{ component('entry_comment', { - comment: comment.root ?? comment, - showEntryTitle: false, - showMagazineName: false, - showNested: true, - }) }} + {% set entryComment = comment.root ?? comment %} + {% if entryComment is defined and entryComment is not null %} + {{ component('entry_comment', { + comment: entryComment, + showEntryTitle: false, + showMagazineName: false, + showNested: true, + }) }} + {% else %} +
          +

          + + {{ 'back'|trans }} + + {{ 'comment_not_found'|trans }} +

          +
          + {% endif %}
          {% endblock %} diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml index 7ac3e3890..d58507727 100644 --- a/translations/messages.en.yaml +++ b/translations/messages.en.yaml @@ -896,3 +896,4 @@ admin_users_suspended: Suspended admin_users_banned: Banned user_verify: Activate account max_image_size: Maximum file size +comment_not_found: Comment not found From 5aec5d890c831100c7f770cb1c199a1b65ca6701 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Mon, 16 Sep 2024 11:53:52 +0200 Subject: [PATCH 276/335] Improve invalid CSRF token logging + add explicit dependency (#1130) --- composer.json | 3 ++- composer.lock | 2 +- src/Controller/AbstractController.php | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 13d4ad19d..3d2b5cc25 100644 --- a/composer.json +++ b/composer.json @@ -89,11 +89,12 @@ "symfony/runtime": "7.1.*", "symfony/scheduler": "7.1.*", "symfony/security-bundle": "7.1.*", + "symfony/security-csrf": "7.1.*", "symfony/serializer": "7.1.*", "symfony/string": "7.1.*", "symfony/translation": "7.1.*", - "symfony/type-info": "7.1.*", "symfony/twig-bundle": "7.1.*", + "symfony/type-info": "7.1.*", "symfony/uid": "7.1.*", "symfony/ux-autocomplete": "^2.18.0", "symfony/ux-chartjs": "^2.18.0", diff --git a/composer.lock b/composer.lock index a676396d8..bc2ca40b8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7ed49456d146886c9e0644e6f2fd03ba", + "content-hash": "d0882e299980e712ba5773b8b8663c31", "packages": [ { "name": "aws/aws-crt-php", diff --git a/src/Controller/AbstractController.php b/src/Controller/AbstractController.php index c8beee2b2..c3b34d49e 100644 --- a/src/Controller/AbstractController.php +++ b/src/Controller/AbstractController.php @@ -36,7 +36,7 @@ protected function getUserOrThrow(): User protected function validateCsrf(string $id, $token): void { if (!\is_string($token) || !$this->isCsrfTokenValid($id, $token)) { - throw new BadRequestHttpException('Invalid CSRF token'); + throw new BadRequestHttpException("Invalid CSRF token, with ID: $id."); } } From e6a8ebb04e2ac657b8bcf0c4460c409ff8f4e991 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Mon, 16 Sep 2024 22:05:04 +0200 Subject: [PATCH 277/335] Make CSRF tokens better named (#1131) --- .../Admin/AdminMagazineOwnershipRequestController.php | 4 ++-- src/Controller/Admin/AdminModeratorController.php | 2 +- src/Controller/BoostController.php | 2 +- src/Controller/Domain/DomainBlockController.php | 4 ++-- src/Controller/Domain/DomainSubController.php | 4 ++-- .../Entry/Comment/EntryCommentChangeAdultController.php | 2 +- .../Entry/Comment/EntryCommentDeleteController.php | 6 +++--- src/Controller/Entry/EntryChangeAdultController.php | 2 +- src/Controller/Entry/EntryChangeMagazineController.php | 2 +- src/Controller/Entry/EntryDeleteController.php | 6 +++--- src/Controller/Entry/EntryPinController.php | 2 +- src/Controller/FavouriteController.php | 2 +- src/Controller/Magazine/MagazineBlockController.php | 4 ++-- src/Controller/Magazine/MagazineDeleteController.php | 8 ++++---- .../Magazine/MagazineModeratorRequestController.php | 2 +- .../Magazine/MagazineOwnershipRequestController.php | 4 ++-- .../Magazine/MagazineRemoveSubscriptionsController.php | 2 +- src/Controller/Magazine/MagazineSubController.php | 4 ++-- src/Controller/Magazine/Panel/MagazineBadgeController.php | 2 +- src/Controller/Magazine/Panel/MagazineBanController.php | 2 +- .../Magazine/Panel/MagazineModeratorController.php | 2 +- .../Panel/MagazineModeratorRequestsController.php | 4 ++-- .../Magazine/Panel/MagazineReportController.php | 4 ++-- .../Post/Comment/PostCommentChangeAdultController.php | 2 +- .../Post/Comment/PostCommentDeleteController.php | 6 +++--- src/Controller/Post/PostChangeAdultController.php | 2 +- src/Controller/Post/PostChangeMagazineController.php | 2 +- src/Controller/Post/PostDeleteController.php | 6 +++--- src/Controller/Post/PostPinController.php | 2 +- src/Controller/Tag/TagBanController.php | 4 ++-- src/Controller/User/Profile/User2FAController.php | 4 ++-- .../User/Profile/UserNotificationController.php | 4 ++-- src/Controller/User/Profile/UserVerifyController.php | 2 +- src/Controller/User/UserBanController.php | 4 ++-- src/Controller/User/UserBlockController.php | 4 ++-- src/Controller/User/UserDeleteController.php | 6 +++--- src/Controller/User/UserFollowController.php | 4 ++-- src/Controller/User/UserRemoveFollowing.php | 2 +- src/Controller/User/UserSuspendController.php | 4 ++-- src/Controller/VoteController.php | 2 +- templates/components/favourite.html.twig | 4 ++-- templates/components/vote.html.twig | 4 ++-- 42 files changed, 72 insertions(+), 72 deletions(-) diff --git a/src/Controller/Admin/AdminMagazineOwnershipRequestController.php b/src/Controller/Admin/AdminMagazineOwnershipRequestController.php index bdb856476..eb5541f91 100644 --- a/src/Controller/Admin/AdminMagazineOwnershipRequestController.php +++ b/src/Controller/Admin/AdminMagazineOwnershipRequestController.php @@ -32,7 +32,7 @@ public function requests(Request $request): Response #[IsGranted('ROLE_ADMIN')] public function accept(Magazine $magazine, User $user, Request $request): Response { - $this->validateCsrf('admin_magazine_ownership_requests_accept', $request->request->get('token')); + $this->validateCsrf('admin_magazine_ownership_requests_accept', $request->getPayload()->get('token')); $this->manager->acceptOwnershipRequest($magazine, $user, $this->getUserOrThrow()); @@ -42,7 +42,7 @@ public function accept(Magazine $magazine, User $user, Request $request): Respon #[IsGranted('ROLE_ADMIN')] public function reject(Magazine $magazine, User $user, Request $request): Response { - $this->validateCsrf('admin_magazine_ownership_requests_reject', $request->request->get('token')); + $this->validateCsrf('admin_magazine_ownership_requests_reject', $request->getPayload()->get('token')); $this->manager->toggleOwnershipRequest($magazine, $user); diff --git a/src/Controller/Admin/AdminModeratorController.php b/src/Controller/Admin/AdminModeratorController.php index 1cb61b225..334268785 100644 --- a/src/Controller/Admin/AdminModeratorController.php +++ b/src/Controller/Admin/AdminModeratorController.php @@ -49,7 +49,7 @@ public function moderators(Request $request): Response #[IsGranted('ROLE_ADMIN')] public function removeModerator(User $user, Request $request): Response { - $this->validateCsrf('remove_moderator', $request->request->get('token')); + $this->validateCsrf('remove_moderator', $request->getPayload()->get('token')); $this->manager->removeModerator($user); diff --git a/src/Controller/BoostController.php b/src/Controller/BoostController.php index db02d21da..582829cc5 100644 --- a/src/Controller/BoostController.php +++ b/src/Controller/BoostController.php @@ -23,7 +23,7 @@ public function __construct( #[IsGranted('ROLE_USER')] public function __invoke(VotableInterface $subject, Request $request): Response { - $this->validateCsrf('boost', $request->request->get('token')); + $this->validateCsrf('boost', $request->getPayload()->get('token')); $this->manager->vote(VotableInterface::VOTE_UP, $subject, $this->getUserOrThrow()); diff --git a/src/Controller/Domain/DomainBlockController.php b/src/Controller/Domain/DomainBlockController.php index d56e9c41f..35e50b477 100644 --- a/src/Controller/Domain/DomainBlockController.php +++ b/src/Controller/Domain/DomainBlockController.php @@ -22,7 +22,7 @@ public function __construct( #[IsGranted('ROLE_USER')] public function block(Domain $domain, Request $request): Response { - $this->validateCsrf('block', $request->request->get('token')); + $this->validateCsrf('block', $request->getPayload()->get('token')); $this->manager->block($domain, $this->getUserOrThrow()); @@ -36,7 +36,7 @@ public function block(Domain $domain, Request $request): Response #[IsGranted('ROLE_USER')] public function unblock(Domain $domain, Request $request): Response { - $this->validateCsrf('block', $request->request->get('token')); + $this->validateCsrf('block', $request->getPayload()->get('token')); $this->manager->unblock($domain, $this->getUserOrThrow()); diff --git a/src/Controller/Domain/DomainSubController.php b/src/Controller/Domain/DomainSubController.php index 694d524ef..18107f5b2 100644 --- a/src/Controller/Domain/DomainSubController.php +++ b/src/Controller/Domain/DomainSubController.php @@ -22,7 +22,7 @@ public function __construct( #[IsGranted('ROLE_USER')] public function subscribe(Domain $domain, Request $request): Response { - $this->validateCsrf('subscribe', $request->request->get('token')); + $this->validateCsrf('subscribe', $request->getPayload()->get('token')); $this->manager->subscribe($domain, $this->getUserOrThrow()); @@ -36,7 +36,7 @@ public function subscribe(Domain $domain, Request $request): Response #[IsGranted('ROLE_USER')] public function unsubscribe(Domain $domain, Request $request): Response { - $this->validateCsrf('subscribe', $request->request->get('token')); + $this->validateCsrf('subscribe', $request->getPayload()->get('token')); $this->manager->unsubscribe($domain, $this->getUserOrThrow()); diff --git a/src/Controller/Entry/Comment/EntryCommentChangeAdultController.php b/src/Controller/Entry/Comment/EntryCommentChangeAdultController.php index dd0b3e231..70fd3bc5e 100644 --- a/src/Controller/Entry/Comment/EntryCommentChangeAdultController.php +++ b/src/Controller/Entry/Comment/EntryCommentChangeAdultController.php @@ -31,7 +31,7 @@ public function __invoke( EntryComment $comment, Request $request ): Response { - $this->validateCsrf('change_adult', $request->request->get('token')); + $this->validateCsrf('change_adult', $request->getPayload()->get('token')); $comment->isAdult = 'on' === $request->get('adult'); diff --git a/src/Controller/Entry/Comment/EntryCommentDeleteController.php b/src/Controller/Entry/Comment/EntryCommentDeleteController.php index 514b59198..79ffceaeb 100644 --- a/src/Controller/Entry/Comment/EntryCommentDeleteController.php +++ b/src/Controller/Entry/Comment/EntryCommentDeleteController.php @@ -32,7 +32,7 @@ public function delete( EntryComment $comment, Request $request ): Response { - $this->validateCsrf('entry_comment_delete', $request->request->get('token')); + $this->validateCsrf('entry_comment_delete', $request->getPayload()->get('token')); $this->manager->delete($this->getUserOrThrow(), $comment); @@ -50,7 +50,7 @@ public function restore( EntryComment $comment, Request $request ): Response { - $this->validateCsrf('entry_comment_restore', $request->request->get('token')); + $this->validateCsrf('entry_comment_restore', $request->getPayload()->get('token')); $this->manager->restore($this->getUserOrThrow(), $comment); @@ -68,7 +68,7 @@ public function purge( EntryComment $comment, Request $request ): Response { - $this->validateCsrf('entry_comment_purge', $request->request->get('token')); + $this->validateCsrf('entry_comment_purge', $request->getPayload()->get('token')); $this->manager->purge($this->getUserOrThrow(), $comment); diff --git a/src/Controller/Entry/EntryChangeAdultController.php b/src/Controller/Entry/EntryChangeAdultController.php index 5c4e17e9e..1bec8a962 100644 --- a/src/Controller/Entry/EntryChangeAdultController.php +++ b/src/Controller/Entry/EntryChangeAdultController.php @@ -28,7 +28,7 @@ public function __invoke( Entry $entry, Request $request ): Response { - $this->validateCsrf('change_adult', $request->request->get('token')); + $this->validateCsrf('change_adult', $request->getPayload()->get('token')); $entry->isAdult = 'on' === $request->get('adult'); diff --git a/src/Controller/Entry/EntryChangeMagazineController.php b/src/Controller/Entry/EntryChangeMagazineController.php index 6ad9fa749..6807b215d 100644 --- a/src/Controller/Entry/EntryChangeMagazineController.php +++ b/src/Controller/Entry/EntryChangeMagazineController.php @@ -30,7 +30,7 @@ public function __invoke( Entry $entry, Request $request ): Response { - $this->validateCsrf('change_magazine', $request->request->get('token')); + $this->validateCsrf('change_magazine', $request->getPayload()->get('token')); $newMagazine = $this->repository->findOneByName($request->get('change_magazine')['new_magazine']); diff --git a/src/Controller/Entry/EntryDeleteController.php b/src/Controller/Entry/EntryDeleteController.php index 9b674f781..45e852c9f 100644 --- a/src/Controller/Entry/EntryDeleteController.php +++ b/src/Controller/Entry/EntryDeleteController.php @@ -29,7 +29,7 @@ public function delete( Entry $entry, Request $request ): Response { - $this->validateCsrf('entry_delete', $request->request->get('token')); + $this->validateCsrf('entry_delete', $request->getPayload()->get('token')); $this->manager->delete($this->getUserOrThrow(), $entry); @@ -50,7 +50,7 @@ public function restore( Entry $entry, Request $request ): Response { - $this->validateCsrf('entry_restore', $request->request->get('token')); + $this->validateCsrf('entry_restore', $request->getPayload()->get('token')); $this->manager->restore($this->getUserOrThrow(), $entry); @@ -66,7 +66,7 @@ public function purge( Entry $entry, Request $request ): Response { - $this->validateCsrf('entry_purge', $request->request->get('token')); + $this->validateCsrf('entry_purge', $request->getPayload()->get('token')); $this->manager->purge($this->getUserOrThrow(), $entry); diff --git a/src/Controller/Entry/EntryPinController.php b/src/Controller/Entry/EntryPinController.php index 2710df542..05382df88 100644 --- a/src/Controller/Entry/EntryPinController.php +++ b/src/Controller/Entry/EntryPinController.php @@ -29,7 +29,7 @@ public function __invoke( Entry $entry, Request $request ): Response { - $this->validateCsrf('entry_pin', $request->request->get('token')); + $this->validateCsrf('entry_pin', $request->getPayload()->get('token')); $entry = $this->manager->pin($entry, $this->getUserOrThrow()); diff --git a/src/Controller/FavouriteController.php b/src/Controller/FavouriteController.php index 86acad0e4..28ba605a6 100644 --- a/src/Controller/FavouriteController.php +++ b/src/Controller/FavouriteController.php @@ -21,7 +21,7 @@ public function __construct(private readonly GenerateHtmlClassService $classServ #[IsGranted('ROLE_USER')] public function __invoke(FavouriteInterface $subject, Request $request, FavouriteManager $manager): Response { - $this->validateCsrf('favourite', $request->request->get('token')); + $this->validateCsrf('up_vote', $request->getPayload()->get('token')); $manager->toggle($this->getUserOrThrow(), $subject); diff --git a/src/Controller/Magazine/MagazineBlockController.php b/src/Controller/Magazine/MagazineBlockController.php index 51591ecb7..0d18e49fc 100644 --- a/src/Controller/Magazine/MagazineBlockController.php +++ b/src/Controller/Magazine/MagazineBlockController.php @@ -22,7 +22,7 @@ public function __construct(private readonly MagazineManager $manager) #[IsGranted('block', subject: 'magazine')] public function block(Magazine $magazine, Request $request): Response { - $this->validateCsrf('block', $request->request->get('token')); + $this->validateCsrf('block', $request->getPayload()->get('token')); $this->manager->block($magazine, $this->getUserOrThrow()); @@ -37,7 +37,7 @@ public function block(Magazine $magazine, Request $request): Response #[IsGranted('block', subject: 'magazine')] public function unblock(Magazine $magazine, Request $request): Response { - $this->validateCsrf('block', $request->request->get('token')); + $this->validateCsrf('block', $request->getPayload()->get('token')); $this->manager->unblock($magazine, $this->getUserOrThrow()); diff --git a/src/Controller/Magazine/MagazineDeleteController.php b/src/Controller/Magazine/MagazineDeleteController.php index 9f6b2e638..9823e5494 100644 --- a/src/Controller/Magazine/MagazineDeleteController.php +++ b/src/Controller/Magazine/MagazineDeleteController.php @@ -21,7 +21,7 @@ public function __construct(private readonly MagazineManager $manager) #[IsGranted('delete', subject: 'magazine')] public function delete(Magazine $magazine, Request $request): Response { - $this->validateCsrf('magazine_delete', $request->request->get('token')); + $this->validateCsrf('magazine_delete', $request->getPayload()->get('token')); $this->manager->delete($magazine); @@ -32,7 +32,7 @@ public function delete(Magazine $magazine, Request $request): Response #[IsGranted('delete', subject: 'magazine')] public function restore(Magazine $magazine, Request $request): Response { - $this->validateCsrf('magazine_restore', $request->request->get('token')); + $this->validateCsrf('magazine_restore', $request->getPayload()->get('token')); $this->manager->restore($magazine); @@ -43,7 +43,7 @@ public function restore(Magazine $magazine, Request $request): Response #[IsGranted('purge', subject: 'magazine')] public function purge(Magazine $magazine, Request $request): Response { - $this->validateCsrf('magazine_purge', $request->request->get('token')); + $this->validateCsrf('magazine_purge', $request->getPayload()->get('token')); $this->manager->purge($magazine); @@ -54,7 +54,7 @@ public function purge(Magazine $magazine, Request $request): Response #[IsGranted('purge', subject: 'magazine')] public function purgeContent(Magazine $magazine, Request $request): Response { - $this->validateCsrf('magazine_purge_content', $request->request->get('token')); + $this->validateCsrf('magazine_purge_content', $request->getPayload()->get('token')); $this->manager->purge($magazine, true); diff --git a/src/Controller/Magazine/MagazineModeratorRequestController.php b/src/Controller/Magazine/MagazineModeratorRequestController.php index db0aaa5aa..2ede57d73 100644 --- a/src/Controller/Magazine/MagazineModeratorRequestController.php +++ b/src/Controller/Magazine/MagazineModeratorRequestController.php @@ -27,7 +27,7 @@ public function __invoke(Magazine $magazine, Request $request): Response throw new AccessDeniedException(); } - $this->validateCsrf('moderator_request', $request->request->get('token')); + $this->validateCsrf('moderator_request', $request->getPayload()->get('token')); $this->manager->toggleModeratorRequest($magazine, $this->getUserOrThrow()); diff --git a/src/Controller/Magazine/MagazineOwnershipRequestController.php b/src/Controller/Magazine/MagazineOwnershipRequestController.php index 37a712627..253778cdc 100644 --- a/src/Controller/Magazine/MagazineOwnershipRequestController.php +++ b/src/Controller/Magazine/MagazineOwnershipRequestController.php @@ -27,7 +27,7 @@ public function toggle(Magazine $magazine, Request $request): Response throw new AccessDeniedException(); } - $this->validateCsrf('magazine_ownership_request', $request->request->get('token')); + $this->validateCsrf('magazine_ownership_request', $request->getPayload()->get('token')); $this->manager->toggleOwnershipRequest($magazine, $this->getUserOrThrow()); @@ -37,7 +37,7 @@ public function toggle(Magazine $magazine, Request $request): Response #[IsGranted('ROLE_ADMIN')] public function accept(Magazine $magazine, Request $request): Response { - $this->validateCsrf('magazine_ownership_request', $request->request->get('token')); + $this->validateCsrf('magazine_ownership_request', $request->getPayload()->get('token')); $user = $this->getUserOrThrow(); $this->manager->acceptOwnershipRequest($magazine, $user, $user); diff --git a/src/Controller/Magazine/MagazineRemoveSubscriptionsController.php b/src/Controller/Magazine/MagazineRemoveSubscriptionsController.php index 050382012..6f37efb82 100644 --- a/src/Controller/Magazine/MagazineRemoveSubscriptionsController.php +++ b/src/Controller/Magazine/MagazineRemoveSubscriptionsController.php @@ -20,7 +20,7 @@ public function __construct(private readonly MagazineManager $manager) #[IsGranted('ROLE_ADMIN')] public function __invoke(Magazine $magazine, Request $request): Response { - $this->validateCsrf('magazine_remove_subscriptions', $request->request->get('token')); + $this->validateCsrf('magazine_remove_subscriptions', $request->getPayload()->get('token')); $this->manager->removeSubscriptions($magazine); diff --git a/src/Controller/Magazine/MagazineSubController.php b/src/Controller/Magazine/MagazineSubController.php index a4f457fa5..66ac93d1c 100644 --- a/src/Controller/Magazine/MagazineSubController.php +++ b/src/Controller/Magazine/MagazineSubController.php @@ -22,7 +22,7 @@ public function __construct(private readonly MagazineManager $manager) #[IsGranted('subscribe', subject: 'magazine')] public function subscribe(Magazine $magazine, Request $request): Response { - $this->validateCsrf('subscribe', $request->request->get('token')); + $this->validateCsrf('subscribe', $request->getPayload()->get('token')); $this->manager->subscribe($magazine, $this->getUserOrThrow()); @@ -37,7 +37,7 @@ public function subscribe(Magazine $magazine, Request $request): Response #[IsGranted('subscribe', subject: 'magazine')] public function unsubscribe(Magazine $magazine, Request $request): Response { - $this->validateCsrf('subscribe', $request->request->get('token')); + $this->validateCsrf('subscribe', $request->getPayload()->get('token')); $this->manager->unsubscribe($magazine, $this->getUserOrThrow()); diff --git a/src/Controller/Magazine/Panel/MagazineBadgeController.php b/src/Controller/Magazine/Panel/MagazineBadgeController.php index fbf4d0d91..d10fd8c55 100644 --- a/src/Controller/Magazine/Panel/MagazineBadgeController.php +++ b/src/Controller/Magazine/Panel/MagazineBadgeController.php @@ -61,7 +61,7 @@ public function remove( BadgeManager $manager, Request $request ): Response { - $this->validateCsrf('badge_remove', $request->request->get('token')); + $this->validateCsrf('badge_remove', $request->getPayload()->get('token')); $manager->delete($badge); diff --git a/src/Controller/Magazine/Panel/MagazineBanController.php b/src/Controller/Magazine/Panel/MagazineBanController.php index af20dcf98..9a03945d2 100644 --- a/src/Controller/Magazine/Panel/MagazineBanController.php +++ b/src/Controller/Magazine/Panel/MagazineBanController.php @@ -69,7 +69,7 @@ public function ban(Magazine $magazine, Request $request, ?User $user = null): R #[IsGranted('moderate', subject: 'magazine')] public function unban(Magazine $magazine, User $user, Request $request): Response { - $this->validateCsrf('magazine_unban', $request->request->get('token')); + $this->validateCsrf('magazine_unban', $request->getPayload()->get('token')); $this->manager->unban($magazine, $user); diff --git a/src/Controller/Magazine/Panel/MagazineModeratorController.php b/src/Controller/Magazine/Panel/MagazineModeratorController.php index 5e65020d2..513cbd731 100644 --- a/src/Controller/Magazine/Panel/MagazineModeratorController.php +++ b/src/Controller/Magazine/Panel/MagazineModeratorController.php @@ -59,7 +59,7 @@ public function remove( Moderator $moderator, Request $request ): Response { - $this->validateCsrf('remove_moderator', $request->request->get('token')); + $this->validateCsrf('remove_moderator', $request->getPayload()->get('token')); $this->manager->removeModerator($moderator, $this->getUser()); diff --git a/src/Controller/Magazine/Panel/MagazineModeratorRequestsController.php b/src/Controller/Magazine/Panel/MagazineModeratorRequestsController.php index aaee641a8..9fa7b1ad3 100644 --- a/src/Controller/Magazine/Panel/MagazineModeratorRequestsController.php +++ b/src/Controller/Magazine/Panel/MagazineModeratorRequestsController.php @@ -34,7 +34,7 @@ public function requests(Magazine $magazine, Request $request): Response #[IsGranted('edit', subject: 'magazine')] public function accept(Magazine $magazine, User $user, Request $request): Response { - $this->validateCsrf('magazine_panel_moderator_request_accept', $request->request->get('token')); + $this->validateCsrf('magazine_panel_moderator_request_accept', $request->getPayload()->get('token')); $this->manager->acceptModeratorRequest($magazine, $user, $this->getUserOrThrow()); @@ -45,7 +45,7 @@ public function accept(Magazine $magazine, User $user, Request $request): Respon #[IsGranted('edit', subject: 'magazine')] public function reject(Magazine $magazine, User $user, Request $request): Response { - $this->validateCsrf('magazine_panel_moderator_request_reject', $request->request->get('token')); + $this->validateCsrf('magazine_panel_moderator_request_reject', $request->getPayload()->get('token')); $this->manager->toggleModeratorRequest($magazine, $user); diff --git a/src/Controller/Magazine/Panel/MagazineReportController.php b/src/Controller/Magazine/Panel/MagazineReportController.php index cfc0fbdea..33dae7b33 100644 --- a/src/Controller/Magazine/Panel/MagazineReportController.php +++ b/src/Controller/Magazine/Panel/MagazineReportController.php @@ -49,7 +49,7 @@ public function reportApprove( Report $report, Request $request ): Response { - $this->validateCsrf('report_approve', $request->request->get('token')); + $this->validateCsrf('report_approve', $request->getPayload()->get('token')); $this->reportManager->accept($report, $this->getUserOrThrow()); @@ -65,7 +65,7 @@ public function reportReject( Report $report, Request $request ): Response { - $this->validateCsrf('report_decline', $request->request->get('token')); + $this->validateCsrf('report_decline', $request->getPayload()->get('token')); $this->reportManager->reject($report, $this->getUserOrThrow()); diff --git a/src/Controller/Post/Comment/PostCommentChangeAdultController.php b/src/Controller/Post/Comment/PostCommentChangeAdultController.php index 71e7e38e6..e70ff4f64 100644 --- a/src/Controller/Post/Comment/PostCommentChangeAdultController.php +++ b/src/Controller/Post/Comment/PostCommentChangeAdultController.php @@ -31,7 +31,7 @@ public function __invoke( PostComment $comment, Request $request ): Response { - $this->validateCsrf('change_adult', $request->request->get('token')); + $this->validateCsrf('change_adult', $request->getPayload()->get('token')); $comment->isAdult = 'on' === $request->get('adult'); diff --git a/src/Controller/Post/Comment/PostCommentDeleteController.php b/src/Controller/Post/Comment/PostCommentDeleteController.php index 84c43d634..9b61f746a 100644 --- a/src/Controller/Post/Comment/PostCommentDeleteController.php +++ b/src/Controller/Post/Comment/PostCommentDeleteController.php @@ -28,7 +28,7 @@ public function delete( PostComment $comment, Request $request ): Response { - $this->validateCsrf('post_comment_delete', $request->request->get('token')); + $this->validateCsrf('post_comment_delete', $request->getPayload()->get('token')); $this->manager->delete($this->getUserOrThrow(), $comment); @@ -44,7 +44,7 @@ public function restore( PostComment $comment, Request $request ): Response { - $this->validateCsrf('post_comment_restore', $request->request->get('token')); + $this->validateCsrf('post_comment_restore', $request->getPayload()->get('token')); $this->manager->restore($this->getUserOrThrow(), $comment); @@ -60,7 +60,7 @@ public function purge( PostComment $comment, Request $request ): Response { - $this->validateCsrf('post_comment_purge', $request->request->get('token')); + $this->validateCsrf('post_comment_purge', $request->getPayload()->get('token')); $this->manager->purge($this->getUserOrThrow(), $comment); diff --git a/src/Controller/Post/PostChangeAdultController.php b/src/Controller/Post/PostChangeAdultController.php index 1875ae1be..12b491ba1 100644 --- a/src/Controller/Post/PostChangeAdultController.php +++ b/src/Controller/Post/PostChangeAdultController.php @@ -27,7 +27,7 @@ public function __invoke( Post $post, Request $request ): Response { - $this->validateCsrf('change_adult', $request->request->get('token')); + $this->validateCsrf('change_adult', $request->getPayload()->get('token')); $post->isAdult = 'on' === $request->get('adult'); diff --git a/src/Controller/Post/PostChangeMagazineController.php b/src/Controller/Post/PostChangeMagazineController.php index 3dec783fc..674e04e95 100644 --- a/src/Controller/Post/PostChangeMagazineController.php +++ b/src/Controller/Post/PostChangeMagazineController.php @@ -30,7 +30,7 @@ public function __invoke( Post $post, Request $request ): Response { - $this->validateCsrf('change_magazine', $request->request->get('token')); + $this->validateCsrf('change_magazine', $request->getPayload()->get('token')); $newMagazine = $this->repository->findOneByName($request->get('change_magazine')['new_magazine']); diff --git a/src/Controller/Post/PostDeleteController.php b/src/Controller/Post/PostDeleteController.php index d238d8042..b2f6d0055 100644 --- a/src/Controller/Post/PostDeleteController.php +++ b/src/Controller/Post/PostDeleteController.php @@ -28,7 +28,7 @@ public function delete( Post $post, Request $request ): Response { - $this->validateCsrf('post_delete', $request->request->get('token')); + $this->validateCsrf('post_delete', $request->getPayload()->get('token')); $this->manager->delete($this->getUserOrThrow(), $post); @@ -44,7 +44,7 @@ public function restore( Post $post, Request $request ): Response { - $this->validateCsrf('post_restore', $request->request->get('token')); + $this->validateCsrf('post_restore', $request->getPayload()->get('token')); $this->manager->restore($this->getUserOrThrow(), $post); @@ -60,7 +60,7 @@ public function purge( Post $post, Request $request ): Response { - $this->validateCsrf('post_purge', $request->request->get('token')); + $this->validateCsrf('post_purge', $request->getPayload()->get('token')); $this->manager->purge($this->getUserOrThrow(), $post); diff --git a/src/Controller/Post/PostPinController.php b/src/Controller/Post/PostPinController.php index 03d8b2fbe..dc0f18c15 100644 --- a/src/Controller/Post/PostPinController.php +++ b/src/Controller/Post/PostPinController.php @@ -29,7 +29,7 @@ public function __invoke( Post $post, Request $request ): Response { - $this->validateCsrf('post_pin', $request->request->get('token')); + $this->validateCsrf('post_pin', $request->getPayload()->get('token')); $entry = $this->manager->pin($post); diff --git a/src/Controller/Tag/TagBanController.php b/src/Controller/Tag/TagBanController.php index b6cad5814..688f3a73b 100644 --- a/src/Controller/Tag/TagBanController.php +++ b/src/Controller/Tag/TagBanController.php @@ -22,7 +22,7 @@ public function __construct( #[IsGranted('ROLE_ADMIN')] public function ban(string $name, Request $request): Response { - $this->validateCsrf('ban', $request->request->get('token')); + $this->validateCsrf('ban', $request->getPayload()->get('token')); $hashtag = $this->tagRepository->findOneBy(['tag' => $name]); if (null === $hashtag) { @@ -36,7 +36,7 @@ public function ban(string $name, Request $request): Response #[IsGranted('ROLE_ADMIN')] public function unban(string $name, Request $request): Response { - $this->validateCsrf('ban', $request->request->get('token')); + $this->validateCsrf('ban', $request->getPayload()->get('token')); $hashtag = $this->tagRepository->findOneBy(['tag' => $name]); if ($hashtag) { diff --git a/src/Controller/User/Profile/User2FAController.php b/src/Controller/User/Profile/User2FAController.php index 03fbe4684..df639691a 100644 --- a/src/Controller/User/Profile/User2FAController.php +++ b/src/Controller/User/Profile/User2FAController.php @@ -101,7 +101,7 @@ public function enable(Request $request): Response #[IsGranted('ROLE_USER')] public function disable(Request $request): Response { - $this->validateCsrf('user_2fa_remove', $request->request->get('token')); + $this->validateCsrf('user_2fa_remove', $request->getPayload()->get('token')); $user = $this->getUserOrThrow(); if (!$user->isTotpAuthenticationEnabled()) { @@ -142,7 +142,7 @@ public function qrCode(Request $request): Response #[IsGranted('ROLE_ADMIN')] public function remove(User $user, Request $request): Response { - $this->validateCsrf('user_2fa_remove', $request->request->get('token')); + $this->validateCsrf('user_2fa_remove', $request->getPayload()->get('token')); $this->twoFactorManager->remove2FA($user); diff --git a/src/Controller/User/Profile/UserNotificationController.php b/src/Controller/User/Profile/UserNotificationController.php index b67ead9e0..162d56aa1 100644 --- a/src/Controller/User/Profile/UserNotificationController.php +++ b/src/Controller/User/Profile/UserNotificationController.php @@ -29,7 +29,7 @@ public function notifications(NotificationRepository $repository, Request $reque #[IsGranted('ROLE_USER')] public function read(NotificationManager $manager, Request $request): Response { - $this->validateCsrf('read_notifications', $request->request->get('token')); + $this->validateCsrf('read_notifications', $request->getPayload()->get('token')); $manager->markAllAsRead($this->getUserOrThrow()); @@ -39,7 +39,7 @@ public function read(NotificationManager $manager, Request $request): Response #[IsGranted('ROLE_USER')] public function clear(NotificationManager $manager, Request $request): Response { - $this->validateCsrf('clear_notifications', $request->request->get('token')); + $this->validateCsrf('clear_notifications', $request->getPayload()->get('token')); $manager->clear($this->getUserOrThrow()); diff --git a/src/Controller/User/Profile/UserVerifyController.php b/src/Controller/User/Profile/UserVerifyController.php index ecfb784a8..feb5aea19 100644 --- a/src/Controller/User/Profile/UserVerifyController.php +++ b/src/Controller/User/Profile/UserVerifyController.php @@ -22,7 +22,7 @@ public function __construct( #[IsGranted('ROLE_ADMIN')] public function __invoke(User $user, Request $request): Response { - $this->validateCsrf('user_verify', $request->request->get('token')); + $this->validateCsrf('user_verify', $request->getPayload()->get('token')); $this->manager->adminUserVerify($user); diff --git a/src/Controller/User/UserBanController.php b/src/Controller/User/UserBanController.php index ba3fd161e..8d071be90 100644 --- a/src/Controller/User/UserBanController.php +++ b/src/Controller/User/UserBanController.php @@ -18,7 +18,7 @@ class UserBanController extends AbstractController #[IsGranted(new Expression('is_granted("ROLE_ADMIN") or is_granted("ROLE_MODERATOR")'))] public function ban(User $user, UserManager $manager, Request $request): Response { - $this->validateCsrf('user_ban', $request->request->get('token')); + $this->validateCsrf('user_ban', $request->getPayload()->get('token')); $manager->ban($user); @@ -38,7 +38,7 @@ public function ban(User $user, UserManager $manager, Request $request): Respons #[IsGranted(new Expression('is_granted("ROLE_ADMIN") or is_granted("ROLE_MODERATOR")'))] public function unban(User $user, UserManager $manager, Request $request): Response { - $this->validateCsrf('user_ban', $request->request->get('token')); + $this->validateCsrf('user_ban', $request->getPayload()->get('token')); $manager->unban($user); diff --git a/src/Controller/User/UserBlockController.php b/src/Controller/User/UserBlockController.php index 94396277a..482e5a514 100644 --- a/src/Controller/User/UserBlockController.php +++ b/src/Controller/User/UserBlockController.php @@ -17,7 +17,7 @@ class UserBlockController extends AbstractController #[IsGranted('ROLE_USER')] public function block(User $blocked, UserManager $manager, Request $request): Response { - $this->validateCsrf('block', $request->request->get('token')); + $this->validateCsrf('block', $request->getPayload()->get('token')); $manager->block($this->getUserOrThrow(), $blocked); @@ -31,7 +31,7 @@ public function block(User $blocked, UserManager $manager, Request $request): Re #[IsGranted('ROLE_USER')] public function unblock(User $blocked, UserManager $manager, Request $request): Response { - $this->validateCsrf('block', $request->request->get('token')); + $this->validateCsrf('block', $request->getPayload()->get('token')); $manager->unblock($this->getUserOrThrow(), $blocked); diff --git a/src/Controller/User/UserDeleteController.php b/src/Controller/User/UserDeleteController.php index 8cc69dcf8..9467770ff 100644 --- a/src/Controller/User/UserDeleteController.php +++ b/src/Controller/User/UserDeleteController.php @@ -16,7 +16,7 @@ class UserDeleteController extends AbstractController #[IsGranted('ROLE_ADMIN')] public function deleteAccount(User $user, UserManager $manager, Request $request): Response { - $this->validateCsrf('user_delete_account', $request->request->get('token')); + $this->validateCsrf('user_delete_account', $request->getPayload()->get('token')); $manager->delete($user); @@ -26,7 +26,7 @@ public function deleteAccount(User $user, UserManager $manager, Request $request #[IsGranted('ROLE_ADMIN')] public function scheduleDeleteAccount(User $user, UserManager $manager, Request $request): Response { - $this->validateCsrf('schedule_user_delete_account', $request->request->get('token')); + $this->validateCsrf('schedule_user_delete_account', $request->getPayload()->get('token')); $manager->deleteRequest($user, false); @@ -36,7 +36,7 @@ public function scheduleDeleteAccount(User $user, UserManager $manager, Request #[IsGranted('ROLE_ADMIN')] public function removeScheduleDeleteAccount(User $user, UserManager $manager, Request $request): Response { - $this->validateCsrf('remove_schedule_user_delete_account', $request->request->get('token')); + $this->validateCsrf('remove_schedule_user_delete_account', $request->getPayload()->get('token')); $manager->removeDeleteRequest($user); diff --git a/src/Controller/User/UserFollowController.php b/src/Controller/User/UserFollowController.php index ef9f4fd88..8a5f19bf1 100644 --- a/src/Controller/User/UserFollowController.php +++ b/src/Controller/User/UserFollowController.php @@ -18,7 +18,7 @@ class UserFollowController extends AbstractController #[IsGranted('follow', subject: 'following')] public function follow(User $following, UserManager $manager, Request $request): Response { - $this->validateCsrf('follow', $request->request->get('token')); + $this->validateCsrf('follow', $request->getPayload()->get('token')); $manager->follow($this->getUserOrThrow(), $following); @@ -33,7 +33,7 @@ public function follow(User $following, UserManager $manager, Request $request): #[IsGranted('follow', subject: 'following')] public function unfollow(User $following, UserManager $manager, Request $request): Response { - $this->validateCsrf('follow', $request->request->get('token')); + $this->validateCsrf('follow', $request->getPayload()->get('token')); $manager->unfollow($this->getUserOrThrow(), $following); diff --git a/src/Controller/User/UserRemoveFollowing.php b/src/Controller/User/UserRemoveFollowing.php index dd6cafe0b..bc0cb9748 100644 --- a/src/Controller/User/UserRemoveFollowing.php +++ b/src/Controller/User/UserRemoveFollowing.php @@ -16,7 +16,7 @@ class UserRemoveFollowing extends AbstractController #[IsGranted('ROLE_ADMIN')] public function __invoke(User $user, UserManager $manager, Request $request): Response { - $this->validateCsrf('user_remove_following', $request->request->get('token')); + $this->validateCsrf('user_remove_following', $request->getPayload()->get('token')); $manager->removeFollowing($user); diff --git a/src/Controller/User/UserSuspendController.php b/src/Controller/User/UserSuspendController.php index e9be231f6..d41b0fc5c 100644 --- a/src/Controller/User/UserSuspendController.php +++ b/src/Controller/User/UserSuspendController.php @@ -22,7 +22,7 @@ public function __construct( #[IsGranted(new Expression('is_granted("ROLE_ADMIN") or is_granted("ROLE_MODERATOR")'))] public function suspend(User $user, Request $request): Response { - $this->validateCsrf('user_suspend', $request->request->get('token')); + $this->validateCsrf('user_suspend', $request->getPayload()->get('token')); $this->userManager->suspend($user); @@ -34,7 +34,7 @@ public function suspend(User $user, Request $request): Response #[IsGranted(new Expression('is_granted("ROLE_ADMIN") or is_granted("ROLE_MODERATOR")'))] public function unsuspend(User $user, Request $request): Response { - $this->validateCsrf('user_suspend', $request->request->get('token')); + $this->validateCsrf('user_suspend', $request->getPayload()->get('token')); $this->userManager->unsuspend($user); diff --git a/src/Controller/VoteController.php b/src/Controller/VoteController.php index 44aa61e62..f9b5c3635 100644 --- a/src/Controller/VoteController.php +++ b/src/Controller/VoteController.php @@ -30,7 +30,7 @@ public function __construct( #[IsGranted('vote', subject: 'votable')] public function __invoke(VotableInterface $votable, int $choice, Request $request): Response { - $this->validateCsrf('vote', $request->request->get('token')); + $this->validateCsrf('down_vote', $request->getPayload()->get('token')); if (VotableInterface::VOTE_DOWN === $choice && DownvotesMode::Disabled === $this->settingsManager->getDownvotesMode()) { throw new BadRequestException('Downvotes are disabled!'); } diff --git a/templates/components/favourite.html.twig b/templates/components/favourite.html.twig index 4a7212935..bbe51501e 100644 --- a/templates/components/favourite.html.twig +++ b/templates/components/favourite.html.twig @@ -1,6 +1,6 @@
          - + -
          \ No newline at end of file + diff --git a/templates/components/vote.html.twig b/templates/components/vote.html.twig index dbda8eb23..c56aba7be 100644 --- a/templates/components/vote.html.twig +++ b/templates/components/vote.html.twig @@ -33,7 +33,7 @@ data-action="subject#vote"> {{ subject.apLikeCount ?? subject.favouriteCount }} - + {% set downvoteMode = mbin_downvotes_mode() %} {% if showDownvote and downvoteMode is not same as DOWNVOTES_DISABLED %} @@ -51,7 +51,7 @@ {% endif %} - + {% endif %} From be57737e55e48c2906a7db72dae22650ca703d26 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Thu, 19 Sep 2024 12:11:35 +0200 Subject: [PATCH 278/335] Add new command: "Remove failed messages command" (#1132) --- src/Command/RemoveFailedMessagesCommand.php | 49 +++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/Command/RemoveFailedMessagesCommand.php diff --git a/src/Command/RemoveFailedMessagesCommand.php b/src/Command/RemoveFailedMessagesCommand.php new file mode 100644 index 000000000..fdc4f1fa4 --- /dev/null +++ b/src/Command/RemoveFailedMessagesCommand.php @@ -0,0 +1,49 @@ +removeFailedMessages(); + + return Command::SUCCESS; + } + + /** + * Remove all failed messages from database. + */ + private function removeFailedMessages() + { + $this->entityManager->getConnection()->executeQuery( + 'DELETE FROM messenger_messages WHERE queue_name = ?', + ['failed'] + ); + } +} From 754eb919ef9c2f453068591f355bb773805e0a5d Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Thu, 19 Sep 2024 12:19:23 +0200 Subject: [PATCH 279/335] Update docs with failed messages remove command (#1133) --- docs/02-admin/04-running-mbin/messenger.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/02-admin/04-running-mbin/messenger.md b/docs/02-admin/04-running-mbin/messenger.md index 1ae941f4b..598d1e582 100644 --- a/docs/02-admin/04-running-mbin/messenger.md +++ b/docs/02-admin/04-running-mbin/messenger.md @@ -20,3 +20,11 @@ We have a few different queues: 9. `dead` [PostgreSQL]: dead jobs that will not be retried We need the `dead` queue so that messages that throw a `UnrecoverableMessageHandlingException`, which is used to indicate that a message should not be retried and go straight to the supplied failure queue + +## Remove failed messages + +We created a simple command to clean-up all the failed messages from the database at once: + +```bash +./bin/console mbin:messenger:failed:remove_all +``` From 0cdd11f48d5e47cad97b6e4934191e39fc3a62cb Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Thu, 19 Sep 2024 13:21:09 +0200 Subject: [PATCH 280/335] Don't log full html pages (stop error log pollution) (#1134) Co-authored-by: BentiGorlich --- src/Service/ActivityPub/ApHttpClient.php | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/Service/ActivityPub/ApHttpClient.php b/src/Service/ActivityPub/ApHttpClient.php index 38800a710..42ff00850 100644 --- a/src/Service/ActivityPub/ApHttpClient.php +++ b/src/Service/ActivityPub/ApHttpClient.php @@ -101,7 +101,8 @@ private function getActivityObjectImpl(string $url): ?string $statusCode = $r->getStatusCode(); // Accepted status code are 2xx or 410 (used Tombstone types) if (!str_starts_with((string) $statusCode, '2') && 410 !== $statusCode) { - throw new InvalidApPostException("Invalid status code while getting: $url : $statusCode, ".substr($r->getContent(false), 0, 1000)); + // Do NOT include the content in the error message, this will be often a full HTML page + throw new InvalidApPostException("Invalid status code while getting: $url : $statusCode"); } // Read also non-OK responses (like 410) by passing 'false' @@ -316,7 +317,8 @@ private function getCollectionObjectImpl(string $apAddress): ?string $statusCode = $response->getStatusCode(); // Accepted status code are 2xx or 410 (used Tombstone types) if (!str_starts_with((string) $statusCode, '2') && 410 !== $statusCode) { - throw new InvalidApPostException("Invalid status code while getting: $apAddress : $statusCode, ".substr($response->getContent(false), 0, 1000)); + // Do NOT include the content in the error message, this will be often a full HTML page + throw new InvalidApPostException("Invalid status code while getting: $apAddress : $statusCode"); } } catch (\Exception $e) { $this->logRequestException($response, $apAddress, 'ApHttpClient:getCollectionObject', $e); @@ -337,13 +339,21 @@ private function logRequestException(?ResponseInterface $response, string $reque } } - $this->logger->error('{type} get fail: {address}, ex: {e}: {msg} - {content}', [ + // Often 400, 404 errors just return the full HTML page, so we don't want to log the full content of them + // We truncate the content to 200 characters max. + $this->logger->error('{type} get fail: {address}, ex: {e}: {msg}. Truncated content: {content}', [ 'type' => $requestType, 'address' => $requestUrl, 'e' => \get_class($e), 'msg' => $e->getMessage(), - 'content' => $content ?? 'no content provided', + 'content' => substr($content ?? 'No content provided', 0, 200), ]); + // And only log the full content in debug log mode + if ($content) { + $this->logger->debug('Full response body content: {content}', [ + 'content' => $content, + ]); + } throw $e; } From 9268b2abcba81cb5527d1d764ca5163794092134 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Thu, 19 Sep 2024 17:40:53 +0200 Subject: [PATCH 281/335] =?UTF-8?q?Add=20explicit=20require=20dep=20phpsec?= =?UTF-8?q?lib/phpseclib.=20Update=20minor=20releases=20o=E2=80=A6=20(#113?= =?UTF-8?q?5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- composer.json | 1 + composer.lock | 218 +++++++++++++++++++++++++++++++++++++------------- 2 files changed, 165 insertions(+), 54 deletions(-) diff --git a/composer.json b/composer.json index 3d2b5cc25..c4be322d4 100644 --- a/composer.json +++ b/composer.json @@ -55,6 +55,7 @@ "pagerfanta/doctrine-orm-adapter": "^4.6.0", "pagerfanta/twig": "^4.6.0", "phpdocumentor/reflection-docblock": "^5.4.1", + "phpseclib/phpseclib": "^3.0.42", "phpstan/phpdoc-parser": "^1.29.1", "predis/predis": "^2.2.2", "privacyportal/oauth2-privacyportal": "^0.1.1", diff --git a/composer.lock b/composer.lock index bc2ca40b8..3a9da7d9d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d0882e299980e712ba5773b8b8663c31", + "content-hash": "4b66e16b3d61acf4006bbcacb3a1af7a", "packages": [ { "name": "aws/aws-crt-php", @@ -62,16 +62,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.321.7", + "version": "3.322.0", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "c64ee32d80ec2ab5d8d6a0b77297c2d69602ef3b" + "reference": "3eeb8d400acc902965f7de5bc85635853f27c109" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/c64ee32d80ec2ab5d8d6a0b77297c2d69602ef3b", - "reference": "c64ee32d80ec2ab5d8d6a0b77297c2d69602ef3b", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/3eeb8d400acc902965f7de5bc85635853f27c109", + "reference": "3eeb8d400acc902965f7de5bc85635853f27c109", "shasum": "" }, "require": { @@ -154,9 +154,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.321.7" + "source": "https://github.com/aws/aws-sdk-php/tree/3.322.0" }, - "time": "2024-09-09T18:09:23+00:00" + "time": "2024-09-18T18:09:42+00:00" }, { "name": "babdev/pagerfanta-bundle", @@ -5087,16 +5087,16 @@ }, { "name": "nelmio/api-doc-bundle", - "version": "v4.29.3", + "version": "v4.30.0", "source": { "type": "git", "url": "https://github.com/nelmio/NelmioApiDocBundle.git", - "reference": "61a3f8bb95111fade6eace55c071c43da0cc75d9" + "reference": "277fa17b912be31b5170e49f0924b1028058c938" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nelmio/NelmioApiDocBundle/zipball/61a3f8bb95111fade6eace55c071c43da0cc75d9", - "reference": "61a3f8bb95111fade6eace55c071c43da0cc75d9", + "url": "https://api.github.com/repos/nelmio/NelmioApiDocBundle/zipball/277fa17b912be31b5170e49f0924b1028058c938", + "reference": "277fa17b912be31b5170e49f0924b1028058c938", "shasum": "" }, "require": { @@ -5197,7 +5197,7 @@ ], "support": { "issues": "https://github.com/nelmio/NelmioApiDocBundle/issues", - "source": "https://github.com/nelmio/NelmioApiDocBundle/tree/v4.29.3" + "source": "https://github.com/nelmio/NelmioApiDocBundle/tree/v4.30.0" }, "funding": [ { @@ -5205,7 +5205,7 @@ "type": "github" } ], - "time": "2024-08-17T13:03:07+00:00" + "time": "2024-09-14T10:54:47+00:00" }, { "name": "nelmio/cors-bundle", @@ -6248,6 +6248,116 @@ }, "time": "2024-02-23T11:10:43+00:00" }, + { + "name": "phpseclib/phpseclib", + "version": "3.0.42", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "db92f1b1987b12b13f248fe76c3a52cadb67bb98" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/db92f1b1987b12b13f248fe76c3a52cadb67bb98", + "reference": "db92f1b1987b12b13f248fe76c3a52cadb67bb98", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^1|^2|^3", + "paragonie/random_compat": "^1.4|^2.0|^9.99.99", + "php": ">=5.6.1" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-dom": "Install the DOM extension to load XML formatted public keys.", + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + }, + "type": "library", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib3\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "support": { + "issues": "https://github.com/phpseclib/phpseclib/issues", + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.42" + }, + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], + "time": "2024-09-16T03:06:04+00:00" + }, { "name": "phpstan/phpdoc-parser", "version": "1.30.1", @@ -6839,16 +6949,16 @@ }, { "name": "psr/log", - "version": "3.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "79dff0b268932c640297f5208d6298f71855c03e" + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/79dff0b268932c640297f5208d6298f71855c03e", - "reference": "79dff0b268932c640297f5208d6298f71855c03e", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", "shasum": "" }, "require": { @@ -6883,9 +6993,9 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/3.0.1" + "source": "https://github.com/php-fig/log/tree/3.0.2" }, - "time": "2024-08-21T13:31:24+00:00" + "time": "2024-09-11T13:17:53+00:00" }, { "name": "ralouphie/getallheaders", @@ -15626,16 +15736,16 @@ }, { "name": "nikic/php-parser", - "version": "v5.1.0", + "version": "v5.2.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1" + "reference": "23c79fbbfb725fb92af9bcf41065c8e9a0d49ddb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/683130c2ff8c2739f4822ff7ac5c873ec529abd1", - "reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/23c79fbbfb725fb92af9bcf41065c8e9a0d49ddb", + "reference": "23c79fbbfb725fb92af9bcf41065c8e9a0d49ddb", "shasum": "" }, "require": { @@ -15678,9 +15788,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.1.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.2.0" }, - "time": "2024-07-01T20:03:41+00:00" + "time": "2024-09-15T16:40:33+00:00" }, { "name": "phar-io/manifest", @@ -15802,16 +15912,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.12.3", + "version": "1.12.4", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "0fcbf194ab63d8159bb70d9aa3e1350051632009" + "reference": "ffa517cb918591b93acc9b95c0bebdcd0e4538bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/0fcbf194ab63d8159bb70d9aa3e1350051632009", - "reference": "0fcbf194ab63d8159bb70d9aa3e1350051632009", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/ffa517cb918591b93acc9b95c0bebdcd0e4538bd", + "reference": "ffa517cb918591b93acc9b95c0bebdcd0e4538bd", "shasum": "" }, "require": { @@ -15856,7 +15966,7 @@ "type": "github" } ], - "time": "2024-09-09T08:10:35+00:00" + "time": "2024-09-19T07:58:01+00:00" }, { "name": "phpunit/php-code-coverage", @@ -16183,16 +16293,16 @@ }, { "name": "phpunit/phpunit", - "version": "11.3.4", + "version": "11.3.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "d2ef57db1410b102b250e0cdce6675a60c2a993d" + "reference": "d62c45a19c665bb872c2a47023a0baf41a98bb2b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d2ef57db1410b102b250e0cdce6675a60c2a993d", - "reference": "d2ef57db1410b102b250e0cdce6675a60c2a993d", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d62c45a19c665bb872c2a47023a0baf41a98bb2b", + "reference": "d62c45a19c665bb872c2a47023a0baf41a98bb2b", "shasum": "" }, "require": { @@ -16213,13 +16323,13 @@ "phpunit/php-timer": "^7.0.1", "sebastian/cli-parser": "^3.0.2", "sebastian/code-unit": "^3.0.1", - "sebastian/comparator": "^6.0.2", + "sebastian/comparator": "^6.1.0", "sebastian/diff": "^6.0.2", "sebastian/environment": "^7.2.0", "sebastian/exporter": "^6.1.3", "sebastian/global-state": "^7.0.2", "sebastian/object-enumerator": "^6.0.1", - "sebastian/type": "^5.0.1", + "sebastian/type": "^5.1.0", "sebastian/version": "^5.0.1" }, "suggest": { @@ -16263,7 +16373,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/11.3.4" + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.3.6" }, "funding": [ { @@ -16279,7 +16389,7 @@ "type": "tidelift" } ], - "time": "2024-09-09T06:08:34+00:00" + "time": "2024-09-19T10:54:28+00:00" }, { "name": "sebastian/cli-parser", @@ -16453,16 +16563,16 @@ }, { "name": "sebastian/comparator", - "version": "6.0.2", + "version": "6.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "450d8f237bd611c45b5acf0733ce43e6bb280f81" + "reference": "fa37b9e2ca618cb051d71b60120952ee8ca8b03d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/450d8f237bd611c45b5acf0733ce43e6bb280f81", - "reference": "450d8f237bd611c45b5acf0733ce43e6bb280f81", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa37b9e2ca618cb051d71b60120952ee8ca8b03d", + "reference": "fa37b9e2ca618cb051d71b60120952ee8ca8b03d", "shasum": "" }, "require": { @@ -16473,12 +16583,12 @@ "sebastian/exporter": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "6.1-dev" } }, "autoload": { @@ -16518,7 +16628,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/6.0.2" + "source": "https://github.com/sebastianbergmann/comparator/tree/6.1.0" }, "funding": [ { @@ -16526,7 +16636,7 @@ "type": "github" } ], - "time": "2024-08-12T06:07:25+00:00" + "time": "2024-09-11T15:42:56+00:00" }, { "name": "sebastian/complexity", @@ -17095,28 +17205,28 @@ }, { "name": "sebastian/type", - "version": "5.0.1", + "version": "5.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb6a6566f9589e86661291d13eba708cce5eb4aa" + "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb6a6566f9589e86661291d13eba708cce5eb4aa", - "reference": "fb6a6566f9589e86661291d13eba708cce5eb4aa", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/461b9c5da241511a2a0e8f240814fb23ce5c0aac", + "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac", "shasum": "" }, "require": { "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -17140,7 +17250,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/type/issues", "security": "https://github.com/sebastianbergmann/type/security/policy", - "source": "https://github.com/sebastianbergmann/type/tree/5.0.1" + "source": "https://github.com/sebastianbergmann/type/tree/5.1.0" }, "funding": [ { @@ -17148,7 +17258,7 @@ "type": "github" } ], - "time": "2024-07-03T05:11:49+00:00" + "time": "2024-09-17T13:12:04+00:00" }, { "name": "sebastian/version", From 6091824a59347f2214d94665c599990581c91d30 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Thu, 19 Sep 2024 18:58:10 +0200 Subject: [PATCH 282/335] Translations update from Hosted Weblate (#1137) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Λευτέρης Τ Co-authored-by: Melroy van den Berg --- translations/messages.el.yaml | 26 ++++++++++++++++++++++++++ translations/messages.nl.yaml | 1 + 2 files changed, 27 insertions(+) diff --git a/translations/messages.el.yaml b/translations/messages.el.yaml index af0aa90fc..f0f60e7d2 100644 --- a/translations/messages.el.yaml +++ b/translations/messages.el.yaml @@ -595,3 +595,29 @@ oauth2.grant.post_comment.delete: Διέγραψε τα υπάρχοντα σχ oauth2.grant.post_comment.all: Δημιούργησε, επεξεργάσου ή διέγραψε τα σχόλιά σου σε αναρτήσεις και ψήφισε, ενίσχυσε ή να ανέφερε οποιοδήποτε σχόλιο σε με μια ανάρτηση. oauth2.grant.post_comment.create: Δημιούργησε νέα σχόλια σε αναρτήσεις. +oauth2.grant.user.message.create: Στείλε μηνύματα σε άλλους χρήστες. +oauth2.grant.user.notification.all: Διάβασε και καθάρισε τις ειδοποιήσεις σου. +oauth2.grant.user.notification.read: Διάβασε τις ειδοποιήσεις σου, συμπεριλαμβανομένων + αυτών για μηνύματα. +oauth2.grant.user.notification.delete: Καθάρισε τις ειδοποιήσεις σου. +toolbar.spoiler: Σπόιλερ +oauth2.grant.user.profile.all: Διάβασε και επεξεργάσου το προφίλ σου. +oauth2.grant.user.message.all: Διάβασε τα μηνύματά σου και στείλε μηνύματα σε άλλους + χρήστες. +oauth2.grant.user.profile.read: Διάβασε το προφίλ σου. +oauth2.grant.post_comment.vote: Ψήφισε θετικά ή αρητικά, ενίσχυσε οποιοδήποτε σχόλιο + σε μια ανάρτηση. +oauth2.grant.post_comment.report: Ανέφερε οποιοδήποτε σχόλιο σε μια ανάρτηση. +oauth2.grant.user.profile.edit: Επεξεργάσου το προφίλ σου. +oauth2.grant.user.message.read: Διάβασε τα μηνύματά σου. +oauth2.grant.user.oauth_clients.all: Διάβασε και επεξεργάσου τα δικαιώματα που έχεις + χορηγήσει σε άλλες εφαρμογές OAuth2. +oauth2.grant.user.oauth_clients.read: Διάβασε τα δικαιώματα που έχεις χορηγήσει σε + άλλες εφαρμογές OAuth2. +oauth2.grant.user.all: Διάβασε και επεξεργάσου το προφίλ, τα μηνύματα ή τις ειδοποιήσεις + σου· διάβασε και επεξεργάσου δικαιώματα που έχεις δώσει σε άλλες εφαρμογές, ακολούθησε + ή μπλόκαρε άλλους χρήστες· δες λίστες των χρηστών που ακολουθείς ή έχεις αποκλείσει. +oauth2.grant.user.oauth_clients.edit: Επεξεργάσου τα δικαιώματα που έχεις χορηγήσει + σε άλλες εφαρμογές OAuth2. +oauth2.grant.user.follow: Ακολούθησε ή αφαίρεσε από ακόλουθο χρήστες και διάβασε μια + λίστα χρηστών που ακολουθείς. diff --git a/translations/messages.nl.yaml b/translations/messages.nl.yaml index 9461dda06..08211bfd5 100644 --- a/translations/messages.nl.yaml +++ b/translations/messages.nl.yaml @@ -932,3 +932,4 @@ disabled: Uitgeschakeld hidden: Verborgen enabled: Ingeschakeld toolbar.spoiler: Spoiler +comment_not_found: Commentaar niet gevonden From 701388b9eb971ed7f28eb3647aa4fb6217db365b Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Thu, 19 Sep 2024 22:28:30 +0200 Subject: [PATCH 283/335] Remove dead messages + docs update (#1139) --- docs/02-admin/04-running-mbin/messenger.md | 8 ++++ docs/02-admin/FAQ.md | 28 ++++++----- src/Command/RemoveDeadMessagesCommand.php | 52 +++++++++++++++++++++ src/Command/RemoveFailedMessagesCommand.php | 3 ++ 4 files changed, 76 insertions(+), 15 deletions(-) create mode 100644 src/Command/RemoveDeadMessagesCommand.php diff --git a/docs/02-admin/04-running-mbin/messenger.md b/docs/02-admin/04-running-mbin/messenger.md index 598d1e582..431602ac5 100644 --- a/docs/02-admin/04-running-mbin/messenger.md +++ b/docs/02-admin/04-running-mbin/messenger.md @@ -28,3 +28,11 @@ We created a simple command to clean-up all the failed messages from the databas ```bash ./bin/console mbin:messenger:failed:remove_all ``` + +And to remove the dead messages from the database at once: + +```bash +./bin/console mbin:messenger:dead:remove_all +``` + +However, most messages stored in the database are most likely failed messages. So it is advised to regularly run the `./bin/console mbin:messenger:failed:remove_all` command to clean-up the database. diff --git a/docs/02-admin/FAQ.md b/docs/02-admin/FAQ.md index fe3debde2..4f1e87f3e 100644 --- a/docs/02-admin/FAQ.md +++ b/docs/02-admin/FAQ.md @@ -103,8 +103,8 @@ RabbitMQ will now have new queues being added for the different delays (so a mes The global overview from RabbitMQ shows the ready messages for all queues combined. Messages in the retry queues count as ready messages the whole time they are in there, so for a correct ready count you have to go to the queue specific overview. -| Overview | Queue Tab | "Message" Queue Overview | -| --------------------------------------------------------- | --------------------------------------------------- | ------------------------------------------------------------------- | +| Overview | Queue Tab | "Message" Queue Overview | +| ------------------------------------------------------- | ------------------------------------------------- | ----------------------------------------------------------------- | | ![Queued messages](../images/rabbit_queue_overview.png) | ![Queue overview](../images/rabbit_queue_tab.png) | ![Message Queue Overview](../images/rabbit_messages_overview.png) | ## RabbitMQ Prometheus exporter @@ -134,23 +134,19 @@ scrape_configs: ## How to clean-up all failed messages? -If you wish to **delete all messages** (`dead` and `failed`) at once, execute the following PostgreSQL query (assuming you're connected to the correct PostgreSQL database): +If you want to delete all failed messages (`failed` queue) you can execute the following command: -```sql -DELETE FROM messenger_messages; +```bash +./bin/console mbin:messenger:failed:remove_all ``` -If you want to delete only the messages that are no longer being worked (`dead`) on you can execute this query: +And if you want to delete the dead messages (`dead` queue) you can execute the following command: -```sql -DELETE FROM messenger_messages WHERE queue_name = 'dead'; +```bash +./bin/console mbin:messenger:dead:remove_all ``` -To free up the disk space used by the now deleted messages, execute the following query: - -```sql -VACUUM messenger_messages; -``` +_Hint:_ Most messages that are stored in the database are most likely in the `failed` queue, thus running the first command (`mbin:messenger:failed:remove_all`) will most likely delete all messages in the `messenger_messages` table. Regularly running this command will keep your database clean. ## Where can I find my logging? @@ -208,12 +204,14 @@ first, so any updates to the keys requires a `DEL instance_private_key instance_ First thing you should do to debug the issue is looking at the "Queues and Streams" tab to find out what queues have the high publishing rate. If the queue/s in question are `inbox` and `resolve` it is most likely a circulating `ChainActivityMessage`. To verify that assumption: + 1. stop all messengers - - if you're on bare metal, as root: `supervisorctl stop messenger:*` - - if you're on docker, inside the `docker` folder : `docker compose down messenger*` + - if you're on bare metal, as root: `supervisorctl stop messenger:*` + - if you're on docker, inside the `docker` folder : `docker compose down messenger*` 2. look again at the publishing rate. If it has gone down, then it definitely is a circulating message To fix the problem: + 1. start the messengers if they are not already started 2. go to the `resolve` queue 3. open the "Get Message" panel diff --git a/src/Command/RemoveDeadMessagesCommand.php b/src/Command/RemoveDeadMessagesCommand.php new file mode 100644 index 000000000..5acd13a8d --- /dev/null +++ b/src/Command/RemoveDeadMessagesCommand.php @@ -0,0 +1,52 @@ +removeDeadMessages(); + + return Command::SUCCESS; + } + + /** + * Remove all dead messages from database. + */ + private function removeDeadMessages() + { + $this->entityManager->getConnection()->executeQuery( + 'DELETE FROM messenger_messages WHERE queue_name = ?', + ['dead'] + ); + + // Followed by vacuuming the messenger_messages table. + $this->entityManager->getConnection()->executeQuery('VACUUM messenger_messages'); + } +} diff --git a/src/Command/RemoveFailedMessagesCommand.php b/src/Command/RemoveFailedMessagesCommand.php index fdc4f1fa4..466e71c4d 100644 --- a/src/Command/RemoveFailedMessagesCommand.php +++ b/src/Command/RemoveFailedMessagesCommand.php @@ -45,5 +45,8 @@ private function removeFailedMessages() 'DELETE FROM messenger_messages WHERE queue_name = ?', ['failed'] ); + + // Followed by vacuuming the messenger_messages table. + $this->entityManager->getConnection()->executeQuery('VACUUM messenger_messages'); } } From b744109f68a04c39542a61cb47ab0fbf389fcf9f Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Fri, 20 Sep 2024 16:48:39 +0200 Subject: [PATCH 284/335] Disable CSRF checks on some most-used forms (#1136) --- src/Controller/BoostController.php | 3 ++- src/Controller/Domain/DomainBlockController.php | 6 ++++-- src/Controller/Domain/DomainSubController.php | 6 ++++-- src/Controller/FavouriteController.php | 3 ++- src/Controller/Magazine/MagazineBlockController.php | 6 ++++-- src/Controller/Magazine/MagazineSubController.php | 6 ++++-- src/Controller/Post/PostDeleteController.php | 9 ++++++--- .../User/Profile/UserNotificationController.php | 6 ++++-- src/Controller/User/UserBlockController.php | 6 ++++-- src/Controller/User/UserFollowController.php | 6 ++++-- src/Controller/VoteController.php | 3 ++- 11 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/Controller/BoostController.php b/src/Controller/BoostController.php index 582829cc5..75284d737 100644 --- a/src/Controller/BoostController.php +++ b/src/Controller/BoostController.php @@ -23,7 +23,8 @@ public function __construct( #[IsGranted('ROLE_USER')] public function __invoke(VotableInterface $subject, Request $request): Response { - $this->validateCsrf('boost', $request->getPayload()->get('token')); + // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 + // $this->validateCsrf('boost', $request->getPayload()->get('token')); $this->manager->vote(VotableInterface::VOTE_UP, $subject, $this->getUserOrThrow()); diff --git a/src/Controller/Domain/DomainBlockController.php b/src/Controller/Domain/DomainBlockController.php index 35e50b477..67462ec90 100644 --- a/src/Controller/Domain/DomainBlockController.php +++ b/src/Controller/Domain/DomainBlockController.php @@ -22,7 +22,8 @@ public function __construct( #[IsGranted('ROLE_USER')] public function block(Domain $domain, Request $request): Response { - $this->validateCsrf('block', $request->getPayload()->get('token')); + // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 + // $this->validateCsrf('block', $request->getPayload()->get('token')); $this->manager->block($domain, $this->getUserOrThrow()); @@ -36,7 +37,8 @@ public function block(Domain $domain, Request $request): Response #[IsGranted('ROLE_USER')] public function unblock(Domain $domain, Request $request): Response { - $this->validateCsrf('block', $request->getPayload()->get('token')); + // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 + // $this->validateCsrf('block', $request->getPayload()->get('token')); $this->manager->unblock($domain, $this->getUserOrThrow()); diff --git a/src/Controller/Domain/DomainSubController.php b/src/Controller/Domain/DomainSubController.php index 18107f5b2..5e06810d5 100644 --- a/src/Controller/Domain/DomainSubController.php +++ b/src/Controller/Domain/DomainSubController.php @@ -22,7 +22,8 @@ public function __construct( #[IsGranted('ROLE_USER')] public function subscribe(Domain $domain, Request $request): Response { - $this->validateCsrf('subscribe', $request->getPayload()->get('token')); + // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 + // $this->validateCsrf('subscribe', $request->getPayload()->get('token')); $this->manager->subscribe($domain, $this->getUserOrThrow()); @@ -36,7 +37,8 @@ public function subscribe(Domain $domain, Request $request): Response #[IsGranted('ROLE_USER')] public function unsubscribe(Domain $domain, Request $request): Response { - $this->validateCsrf('subscribe', $request->getPayload()->get('token')); + // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 + // $this->validateCsrf('subscribe', $request->getPayload()->get('token')); $this->manager->unsubscribe($domain, $this->getUserOrThrow()); diff --git a/src/Controller/FavouriteController.php b/src/Controller/FavouriteController.php index 28ba605a6..2834255cb 100644 --- a/src/Controller/FavouriteController.php +++ b/src/Controller/FavouriteController.php @@ -21,7 +21,8 @@ public function __construct(private readonly GenerateHtmlClassService $classServ #[IsGranted('ROLE_USER')] public function __invoke(FavouriteInterface $subject, Request $request, FavouriteManager $manager): Response { - $this->validateCsrf('up_vote', $request->getPayload()->get('token')); + // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 + // $this->validateCsrf('up_vote', $request->getPayload()->get('token')); $manager->toggle($this->getUserOrThrow(), $subject); diff --git a/src/Controller/Magazine/MagazineBlockController.php b/src/Controller/Magazine/MagazineBlockController.php index 0d18e49fc..ad1972da1 100644 --- a/src/Controller/Magazine/MagazineBlockController.php +++ b/src/Controller/Magazine/MagazineBlockController.php @@ -22,7 +22,8 @@ public function __construct(private readonly MagazineManager $manager) #[IsGranted('block', subject: 'magazine')] public function block(Magazine $magazine, Request $request): Response { - $this->validateCsrf('block', $request->getPayload()->get('token')); + // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 + // $this->validateCsrf('block', $request->getPayload()->get('token')); $this->manager->block($magazine, $this->getUserOrThrow()); @@ -37,7 +38,8 @@ public function block(Magazine $magazine, Request $request): Response #[IsGranted('block', subject: 'magazine')] public function unblock(Magazine $magazine, Request $request): Response { - $this->validateCsrf('block', $request->getPayload()->get('token')); + // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 + // $this->validateCsrf('block', $request->getPayload()->get('token')); $this->manager->unblock($magazine, $this->getUserOrThrow()); diff --git a/src/Controller/Magazine/MagazineSubController.php b/src/Controller/Magazine/MagazineSubController.php index 66ac93d1c..1a5d0a4c4 100644 --- a/src/Controller/Magazine/MagazineSubController.php +++ b/src/Controller/Magazine/MagazineSubController.php @@ -22,7 +22,8 @@ public function __construct(private readonly MagazineManager $manager) #[IsGranted('subscribe', subject: 'magazine')] public function subscribe(Magazine $magazine, Request $request): Response { - $this->validateCsrf('subscribe', $request->getPayload()->get('token')); + // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 + // $this->validateCsrf('subscribe', $request->getPayload()->get('token')); $this->manager->subscribe($magazine, $this->getUserOrThrow()); @@ -37,7 +38,8 @@ public function subscribe(Magazine $magazine, Request $request): Response #[IsGranted('subscribe', subject: 'magazine')] public function unsubscribe(Magazine $magazine, Request $request): Response { - $this->validateCsrf('subscribe', $request->getPayload()->get('token')); + // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 + // $this->validateCsrf('subscribe', $request->getPayload()->get('token')); $this->manager->unsubscribe($magazine, $this->getUserOrThrow()); diff --git a/src/Controller/Post/PostDeleteController.php b/src/Controller/Post/PostDeleteController.php index b2f6d0055..1bf5b42b7 100644 --- a/src/Controller/Post/PostDeleteController.php +++ b/src/Controller/Post/PostDeleteController.php @@ -28,7 +28,8 @@ public function delete( Post $post, Request $request ): Response { - $this->validateCsrf('post_delete', $request->getPayload()->get('token')); + // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 + // $this->validateCsrf('post_delete', $request->getPayload()->get('token')); $this->manager->delete($this->getUserOrThrow(), $post); @@ -44,7 +45,8 @@ public function restore( Post $post, Request $request ): Response { - $this->validateCsrf('post_restore', $request->getPayload()->get('token')); + // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 + // $this->validateCsrf('post_restore', $request->getPayload()->get('token')); $this->manager->restore($this->getUserOrThrow(), $post); @@ -60,7 +62,8 @@ public function purge( Post $post, Request $request ): Response { - $this->validateCsrf('post_purge', $request->getPayload()->get('token')); + // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 + // $this->validateCsrf('post_purge', $request->getPayload()->get('token')); $this->manager->purge($this->getUserOrThrow(), $post); diff --git a/src/Controller/User/Profile/UserNotificationController.php b/src/Controller/User/Profile/UserNotificationController.php index 162d56aa1..bd161ec9f 100644 --- a/src/Controller/User/Profile/UserNotificationController.php +++ b/src/Controller/User/Profile/UserNotificationController.php @@ -29,7 +29,8 @@ public function notifications(NotificationRepository $repository, Request $reque #[IsGranted('ROLE_USER')] public function read(NotificationManager $manager, Request $request): Response { - $this->validateCsrf('read_notifications', $request->getPayload()->get('token')); + // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 + // $this->validateCsrf('read_notifications', $request->getPayload()->get('token')); $manager->markAllAsRead($this->getUserOrThrow()); @@ -39,7 +40,8 @@ public function read(NotificationManager $manager, Request $request): Response #[IsGranted('ROLE_USER')] public function clear(NotificationManager $manager, Request $request): Response { - $this->validateCsrf('clear_notifications', $request->getPayload()->get('token')); + // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 + // $this->validateCsrf('clear_notifications', $request->getPayload()->get('token')); $manager->clear($this->getUserOrThrow()); diff --git a/src/Controller/User/UserBlockController.php b/src/Controller/User/UserBlockController.php index 482e5a514..0ba8568f5 100644 --- a/src/Controller/User/UserBlockController.php +++ b/src/Controller/User/UserBlockController.php @@ -17,7 +17,8 @@ class UserBlockController extends AbstractController #[IsGranted('ROLE_USER')] public function block(User $blocked, UserManager $manager, Request $request): Response { - $this->validateCsrf('block', $request->getPayload()->get('token')); + // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 + // $this->validateCsrf('block', $request->getPayload()->get('token')); $manager->block($this->getUserOrThrow(), $blocked); @@ -31,7 +32,8 @@ public function block(User $blocked, UserManager $manager, Request $request): Re #[IsGranted('ROLE_USER')] public function unblock(User $blocked, UserManager $manager, Request $request): Response { - $this->validateCsrf('block', $request->getPayload()->get('token')); + // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 + // $this->validateCsrf('block', $request->getPayload()->get('token')); $manager->unblock($this->getUserOrThrow(), $blocked); diff --git a/src/Controller/User/UserFollowController.php b/src/Controller/User/UserFollowController.php index 8a5f19bf1..8ab905ad3 100644 --- a/src/Controller/User/UserFollowController.php +++ b/src/Controller/User/UserFollowController.php @@ -18,7 +18,8 @@ class UserFollowController extends AbstractController #[IsGranted('follow', subject: 'following')] public function follow(User $following, UserManager $manager, Request $request): Response { - $this->validateCsrf('follow', $request->getPayload()->get('token')); + // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 + // $this->validateCsrf('follow', $request->getPayload()->get('token')); $manager->follow($this->getUserOrThrow(), $following); @@ -33,7 +34,8 @@ public function follow(User $following, UserManager $manager, Request $request): #[IsGranted('follow', subject: 'following')] public function unfollow(User $following, UserManager $manager, Request $request): Response { - $this->validateCsrf('follow', $request->getPayload()->get('token')); + // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 + // $this->validateCsrf('follow', $request->getPayload()->get('token')); $manager->unfollow($this->getUserOrThrow(), $following); diff --git a/src/Controller/VoteController.php b/src/Controller/VoteController.php index f9b5c3635..bc5eeeeda 100644 --- a/src/Controller/VoteController.php +++ b/src/Controller/VoteController.php @@ -30,7 +30,8 @@ public function __construct( #[IsGranted('vote', subject: 'votable')] public function __invoke(VotableInterface $votable, int $choice, Request $request): Response { - $this->validateCsrf('down_vote', $request->getPayload()->get('token')); + // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 + // $this->validateCsrf('down_vote', $request->getPayload()->get('token')); if (VotableInterface::VOTE_DOWN === $choice && DownvotesMode::Disabled === $this->settingsManager->getDownvotesMode()) { throw new BadRequestException('Downvotes are disabled!'); } From 4b1c2d1de8c539b25c6b5404d8de6666c80ee661 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Sat, 21 Sep 2024 17:01:13 +0200 Subject: [PATCH 285/335] Translations update from Hosted Weblate (#1143) Co-authored-by: ButterflyOfFire Co-authored-by: veroandi --- translations/messages.fr.yaml | 4 + translations/messages.pt.yaml | 64 ++++++++++- translations/messages.pt_BR.yaml | 191 +++++++++++++++++++++++++++++++ 3 files changed, 257 insertions(+), 2 deletions(-) diff --git a/translations/messages.fr.yaml b/translations/messages.fr.yaml index e5b62a993..fffc97800 100644 --- a/translations/messages.fr.yaml +++ b/translations/messages.fr.yaml @@ -742,3 +742,7 @@ two_factor_authentication: Authentification à deux facteurs admin_users_suspended: Suspendus admin_users_banned: Bannis admin_users_inactive: Inactifs +enabled: Activé +disabled: Désactivé +hidden: Masqué +magazine_deletion: Suppression de magazine diff --git a/translations/messages.pt.yaml b/translations/messages.pt.yaml index 4f89c780f..fe5a9e765 100644 --- a/translations/messages.pt.yaml +++ b/translations/messages.pt.yaml @@ -47,8 +47,8 @@ activity: Atividade cover: Capa related_posts: Postagens relacionadas random_posts: Postagens aleatórias -federated_user_info: O perfil do servidor federado pode estar incompleto. -go_to_original_instance: Navega mais na instância federada. +federated_user_info: Esse perfil é de um servidor federado e pode estar incompleto. +go_to_original_instance: Visualizar na instância remota empty: Vazio subscribe: Subscrever unsubscribe: Cancelar subscrição @@ -336,3 +336,63 @@ set_magazines_bar: Barra de magazines set_magazines_bar_desc: adicione os nomes dos magazines após a virgula set_magazines_bar_empty_desc: se o espaço estiver vazio, magazines ativos serão mostrados na barra +subscribe_for_updates: Inscreva-se para começar a receber atualizações. +remove_media: Remover mídia +unmark_as_adult: Desmarcar como NSFW +flash_mark_as_adult_success: A publicação foi marcada com sucesso como NSFW. +delete_account: Excluir conta +menu: Menu +flash_unmark_as_adult_success: A publicação foi desmarcada com sucesso como NSFW. +unban_hashtag_btn: Desbanir Hashtag +unban_hashtag_description: Ao "desbanir" uma hashtag, novas publicações com essa hashtag + poderão ser criadas. As publicações existentes com essa hashtag não serão mais ocultadas. +dynamic_lists: Listas dinâmicas +banned_instances: Instâncias banidas +report_issue: Relatar problema +disabled: Desativado +hidden: Oculto +enabled: Ativado +default_theme: Tema padrão +ban_hashtag_description: Ao banir uma hashtag, você impedirá a criação de publicações + com essa hashtag, além de ocultar as publicações existentes com essa hashtag. +Your account is not active: Sua conta não está ativa. +firstname: Nome +reload_to_apply: Recarregar a página para aplicar as alterações +marked_for_deletion_at: Marcado para ser excluído em %date% +mark_as_adult: Marcar como NSFW +ban_account: Banir conta +header_logo: Logotipo do cabeçalho +filter.fields.only_names: Somente nomes +filter.fields.names_and_descriptions: Nomes e descrições +unban_account: Desbanir conta +sidebar: Barra lateral +captcha_enabled: Captcha ativado +browsing_one_thread: Você está navegando apenas em um tópico da discussão! Todos os + comentários estão disponíveis na página do post. +return: Retornar +filter.adult.hide: Ocultar NSFW +filter.adult.show: Mostrar NSFW +filter.adult.only: Somente NSFW +your_account_has_been_banned: Sua conta foi banida +send: Enviar +sticky_navbar_help: A barra de navegação permanecerá na parte superior da página quando + você rolar para baixo. +toolbar.italic: Itálico +kbin_promo_title: Crie sua própria instância +kbin_intro_title: Explorar o Fediverso +infinite_scroll_help: Carregar automaticamente mais conteúdo quando chegar ao final + da página. +subscribers_count: '{0}Inscritos|{1}Inscrito|]1,Inf[ Inscritos' +followers_count: '{0}Seguidores|{1}Seguidor|]1,Inf[ Seguidores' +marked_for_deletion: Marcado para ser excluído +sort_by: Ordenar por +filter_by_subscription: Filtrar por assinatura +filter_by_federation: Filtrar por status da federação +kbin_bot: Agente Mbin +toolbar.bold: Negrito +Your account has been banned: Sua conta foi banida. +active_users: Pessoas ativas +password_confirm_header: Confirme sua solicitação de alteração de senha. +toolbar.strikethrough: Riscado +Password is invalid: Senha inválida. +toolbar.header: Cabeçalho diff --git a/translations/messages.pt_BR.yaml b/translations/messages.pt_BR.yaml index 61bc2d6f2..cd46200a4 100644 --- a/translations/messages.pt_BR.yaml +++ b/translations/messages.pt_BR.yaml @@ -46,3 +46,194 @@ moderators: Moderadores mod_log: Registro de moderação add_comment: Adicionar comentário add_post: Adicionar postagem +contact: Contato +faq: Perguntas Freqüentes (FAQ) +delete: Excluir +comments_count: '{0}Comentários|{1}Comentário|]1,Inf[ Comentários' +subscribers_count: '{0}Inscritos|{1}Inscrito|]1,Inf[ Inscritos' +followers_count: '{0}Seguidores|{1}Seguidor|]1,Inf[ Seguidores' +add_media: Adicionar mídia +remove_media: Remover mídia +markdown_howto: Como funciona o editor? +enter_your_comment: Insira seu comentário +activity: Atividade +cover: Capa +subscribe_for_updates: Inscreva-se para começar a receber atualizações. +federated_user_info: Este perfil é de um servidor federado e pode estar incompleto. +empty: Vazio +go_to_original_instance: Ver na instância remota +subscribe: Se inscrever +follow: Seguir +unfollow: Deixar de seguir +unsubscribe: Cancelar inscrição +remember_me: Lembrar de mim +reply: Responder +login_or_email: Login ou e-mail +password: Senha +dont_have_account: Não possui uma conta? +you_cant_login: Esqueceu a sua senha? +show_more: Mostrar mais +to: para +in: em +already_have_account: Você já possui uma conta? +reset_password: Redefinir a senha +username: Nome do usuário +email: E-mail +repeat_password: Repetir a senha +privacy_policy: Política de privacidade +useful: Útil +help: Ajuda +check_email: Verifique o seu e-mail +email_confirm_content: 'Pronto para ativar a sua conta Mbin? Clique no link abaixo:' +email_verify: Confirmar endereço de e-mail +email_confirm_expire: O link expirará em uma hora. +email_confirm_title: Confirme seu endereço de e-mail. +add_new: Adicionar novo(a) +overview: Visão Geral +new_email_repeat: Confirme novo e-mail +current_password: Senha atual +new_password: Nova senha +new_password_repeat: Confirmar nova senha +change_email: Alterar e-mail +change_password: Alterar a senha +expand: Expandir +domains: Domínios +flash_register_success: 'Bem-vindo a bordo! Sua conta já está registrada. Uma última + etapa: verifique sua caixa de entrada para receber um link de ativação que dará + vida à sua conta.' +send: Enviar +firstname: Nome +unban_account: Desbanir conta +banned_instances: Instâncias banidas +kbin_intro_title: Explore o Fediverso +kbin_promo_title: Crie sua própria instância +return: Retornar +reload_to_apply: Recarregar a página para aplicar alterações +filter.origin.label: Escolha a origem +filter.adult.hide: Ocultar NSFW +filter.adult.show: Mostrar NSFW +filter.adult.only: Somente NSFW +password_confirm_header: Confirme seu pedido de alteração de senha. +disabled: Desativado +hidden: Oculto +enabled: Ativado +reset_check_email_desc2: Se você não receber um e-mail, verifique sua pasta de spam. +url: URL +title: Título +reset_check_email_desc: Se já houver uma conta associada ao seu endereço de e-mail, + você deverá receber um e-mail em breve contendo um link que poderá ser usado para + redefinir sua senha. Esse link expirará em %expire%. +body: Conteúdo +rules: Regras +domain: Domínio +followers: Seguidores +compact_view: Vista compacta +chat_view: Vista do chat +links: Links +photos: Fotos +1m: 1m +general: Geral +about: Sobre +old_email: E-mail atual +solarized_light: Luz Solarizada +solarized_dark: Escuro Solarizado +size: Tamanho +type_search_term: Digite o termo de pesquisa +auto_preview: Visualização automática de mídia +dynamic_lists: Listas dinâmicas +captcha_enabled: Captcha habilitado +from: de +about_instance: Sobre +stats: Estatísticas +fediverse: Fediverso +add_new_link: Adicionar novo link +add_new_photo: Adicionar nova foto +add_new_video: Adicionar novo vídeo +rss: RSS +change_theme: Mudar tema +try_again: Tente novamente +down_vote: Reduzir +is_adult: 18+ / NSFW +email_confirm_header: Olá! Confirme seu endereço de e-mail. +image_alt: Texto alternativo da imagem +description: Descrição +image: Imagem +name: Nome +following: Seguindo +columns: Colunas +user: Usuário +people_federated: Federado +go_to_content: Ir para o conteúdo +logout: Sair +classic_view: Vista clássica +go_to_filters: Ir para os filtros +subscribed: Inscrito +all: Todos +3h: 3h +12h: 12h +1d: 1d +6h: 6h +1w: 1s +1y: 1a +videos: Vídeos +share: Compartilhar +copy_url: Copiar URL Mbin +copy_url_to_fediverse: Copiar URL original +share_on_fediverse: Compartilhar no Fediverso +edit: Editar +are_you_sure: Tem certeza? +moderate: Moderar +reason: Razão +menu: Menu +profile: Perfil +blocked: Bloqueado +reports: Denúncias +notifications: Notificações +messages: Mensagens +appearance: Aparência +homepage: Página inicial +hide_adult: Ocultar conteúdo NSFW +privacy: Privacidade +save: Salvar +error: Erro +new_email: Novo e-mail +theme: Tema +dark: Escuro +light: Claro +default_theme: Tema padrão +solarized_auto: Solarizado (Detecção Automática) +default_theme_auto: Claro/escuro (Detecção Automática) +font_size: Tamanho da fonte +show_users_avatars: Mostrar avatares dos usuários +yes: Sim +no: Não +show_thumbnails: Mostrar miniaturas +rounded_edges: Bordas arredondadas +read_all: Ler tudo +show_all: Mostrar tudo +FAQ: Perguntas Frequentes (FAQ) +restore: Restaurar +settings: Configurações +federation_enabled: Federação habilitada +registration_disabled: Registro desativado +registrations_enabled: Registro ativado +Password is invalid: A senha é inválida. +Your account is not active: Sua conta não está ativa. +Your account has been banned: Sua conta foi banida. +delete_account: Excluir conta +purge_account: Purgar conta +ban_account: Banir conta +sidebar: Barra lateral +sticky_navbar_help: A barra de navegação permanecerá na parte superior da página quando + você rolar para baixo. +auto_preview_help: Expanda automaticamente as pré-visualizações de mídia. +filter.adult.label: Escolha se você deseja exibir NSFW +local_and_federated: Local e federado +filter.fields.only_names: Apenas nomes +header_logo: Logotipo do cabeçalho +mercure_enabled: Mercure ativado +report_issue: Relatar problema +infinite_scroll_help: Carregar automaticamente mais conteúdo quando chegar ao final + da página. +filter.fields.names_and_descriptions: Nomes e descrições +kbin_bot: Agente Mbin From 0dfcccb8eaa11c706269f44f99b24f403b831234 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Sun, 22 Sep 2024 22:26:44 +0200 Subject: [PATCH 286/335] Translations update from Hosted Weblate (#1144) Co-authored-by: mondstern --- translations/messages.de.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/translations/messages.de.yaml b/translations/messages.de.yaml index 95e89a355..a1e4e13d6 100644 --- a/translations/messages.de.yaml +++ b/translations/messages.de.yaml @@ -938,3 +938,5 @@ disabled: Deaktiviert downvotes_mode: Reduzieren Modus hidden: Versteckt enabled: Aktiviert +toolbar.spoiler: Spoiler +comment_not_found: Kommentar nicht gefunden From f0d29f4b905fca5cd22cd99327a429b8d4639586 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Mon, 23 Sep 2024 18:26:12 +0200 Subject: [PATCH 287/335] Reduce error pollution even more on post request failures (#1140) --- src/Service/ActivityPub/ApHttpClient.php | 70 +++++++++++++++--------- 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/src/Service/ActivityPub/ApHttpClient.php b/src/Service/ActivityPub/ApHttpClient.php index 42ff00850..d5139fe1c 100644 --- a/src/Service/ActivityPub/ApHttpClient.php +++ b/src/Service/ActivityPub/ApHttpClient.php @@ -89,27 +89,27 @@ public function getActivityObject(string $url, bool $decoded = true): array|stri private function getActivityObjectImpl(string $url): ?string { $this->logger->debug("ApHttpClient:getActivityObject:url: $url"); - - $client = new CurlHttpClient(); + $content = null; try { - $r = $client->request('GET', $url, [ + $client = new CurlHttpClient(); + $response = $client->request('GET', $url, [ 'max_duration' => self::MAX_DURATION, 'timeout' => self::TIMEOUT, 'headers' => $this->getInstanceHeaders($url), ]); - $statusCode = $r->getStatusCode(); + $statusCode = $response->getStatusCode(); // Accepted status code are 2xx or 410 (used Tombstone types) if (!str_starts_with((string) $statusCode, '2') && 410 !== $statusCode) { - // Do NOT include the content in the error message, this will be often a full HTML page - throw new InvalidApPostException("Invalid status code while getting: $url : $statusCode"); + // Do NOT include the response content in the error message, this will be often a full HTML page + throw new InvalidApPostException("Invalid status code while getting: $url, status code: $statusCode"); } // Read also non-OK responses (like 410) by passing 'false' - $content = $r->getContent(false); + $content = $response->getContent(false); $this->logger->debug('ApHttpClient:getActivityObject:url: {url} - content: {content}', ['url' => $url, 'content' => $content]); } catch (\Exception $e) { - $this->logRequestException($r, $url, 'ApHttpClient:getActivityObject', $e); + $this->logRequestException($response, $url, 'ApHttpClient:getActivityObject', $e); } return $content; @@ -171,19 +171,19 @@ public function getWebfingerObject(string $url): ?array private function getWebfingerObjectImpl(string $url): ?string { $this->logger->debug("ApHttpClient:getWebfingerObject:url: $url"); - $r = null; + $response = null; try { $client = new CurlHttpClient(); - $r = $client->request('GET', $url, [ + $response = $client->request('GET', $url, [ 'max_duration' => self::MAX_DURATION, 'timeout' => self::TIMEOUT, 'headers' => $this->getInstanceHeaders($url, null, 'get', ApRequestType::WebFinger), ]); } catch (\Exception $e) { - $this->logRequestException($r, $url, 'ApHttpClient:getWebfingerObject', $e); + $this->logRequestException($response, $url, 'ApHttpClient:getWebfingerObject', $e); } - return $r->getContent(); + return $response->getContent(); } private function getActorCacheKey(string $apProfileId): string @@ -317,8 +317,8 @@ private function getCollectionObjectImpl(string $apAddress): ?string $statusCode = $response->getStatusCode(); // Accepted status code are 2xx or 410 (used Tombstone types) if (!str_starts_with((string) $statusCode, '2') && 410 !== $statusCode) { - // Do NOT include the content in the error message, this will be often a full HTML page - throw new InvalidApPostException("Invalid status code while getting: $apAddress : $statusCode"); + // Do NOT include the response content in the error message, this will be often a full HTML page + throw new InvalidApPostException("Invalid status code while getting: $apAddress, status code: $statusCode"); } } catch (\Exception $e) { $this->logRequestException($response, $apAddress, 'ApHttpClient:getCollectionObject', $e); @@ -328,6 +328,16 @@ private function getCollectionObjectImpl(string $apAddress): ?string return $response->getContent(); } + /** + * Helper function for logging get/post/.. requests to the error & debug log with additional info. + * + * @param ResponseInterface|null $response Optional response object + * @param string $requestUrl Full URL of the request + * @param string $requestType an additional string where the error happened in the code + * @param \Exception $e Error object + * + * @throws InvalidApPostException rethrows the error + */ private function logRequestException(?ResponseInterface $response, string $requestUrl, string $requestType, \Exception $e): void { if (null !== $response) { @@ -341,7 +351,7 @@ private function logRequestException(?ResponseInterface $response, string $reque // Often 400, 404 errors just return the full HTML page, so we don't want to log the full content of them // We truncate the content to 200 characters max. - $this->logger->error('{type} get fail: {address}, ex: {e}: {msg}. Truncated content: {content}', [ + $this->logger->error('{type} failed: {address}, ex: {e}: {msg}. Truncated content: {content}', [ 'type' => $requestType, 'address' => $requestUrl, 'e' => \get_class($e), @@ -354,7 +364,7 @@ private function logRequestException(?ResponseInterface $response, string $reque 'content' => $content, ]); } - throw $e; + throw $e; // re-throw the exception } /** @@ -379,20 +389,28 @@ public function post(string $url, User|Magazine $actor, ?array $body = null): vo return; } + $jsonBody = json_encode($body ?? []); + $this->logger->debug("ApHttpClient:post:url: $url"); - $this->logger->debug('ApHttpClient:post:body '.json_encode($body ?? [])); + $this->logger->debug("ApHttpClient:post:body $jsonBody"); // Set-up request - $client = new CurlHttpClient(); - $response = $client->request('POST', $url, [ - 'max_duration' => self::MAX_DURATION, - 'timeout' => self::TIMEOUT, - 'body' => json_encode($body), - 'headers' => $this->getHeaders($url, $actor, $body), - ]); + try { + $client = new CurlHttpClient(); + $response = $client->request('POST', $url, [ + 'max_duration' => self::MAX_DURATION, + 'timeout' => self::TIMEOUT, + 'body' => $jsonBody, + 'headers' => $this->getHeaders($url, $actor, $body), + ]); - if (!str_starts_with((string) $response->getStatusCode(), '2')) { - throw new InvalidApPostException("Post fail: $url, ".substr($response->getContent(false), 0, 1000).' '.json_encode($body)); + $statusCode = $response->getStatusCode(); + if (!str_starts_with((string) $statusCode, '2')) { + // Do NOT include the response content in the error message, this will be often a full HTML page + throw new InvalidApPostException("Post failed: $url, status code: $statusCode, request body: $jsonBody"); + } + } catch (\Exception $e) { + $this->logRequestException($response, $url, 'ApHttpClient:post', $e); } // build cache From 47427d94be99fcba6b8b9f1c7a0d3911f9b56b2f Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Tue, 24 Sep 2024 23:02:24 +0200 Subject: [PATCH 288/335] Translations update from Hosted Weblate (#1146) Co-authored-by: veroandi --- translations/messages.pt.yaml | 77 ++++++++++++++++++++++++++++++++ translations/messages.pt_BR.yaml | 55 +++++++++++++++++++++++ 2 files changed, 132 insertions(+) diff --git a/translations/messages.pt.yaml b/translations/messages.pt.yaml index fe5a9e765..eabfb804f 100644 --- a/translations/messages.pt.yaml +++ b/translations/messages.pt.yaml @@ -396,3 +396,80 @@ password_confirm_header: Confirme sua solicitação de alteração de senha. toolbar.strikethrough: Riscado Password is invalid: Senha inválida. toolbar.header: Cabeçalho +oauth2.grant.domain.all: Assine ou bloqueie domínios e visualize os domínios que você + assinou ou bloqueou. +downvotes_mode: Modo de votos negativos +change_downvotes_mode: Alterar o modo de votos negativos +errors.server500.description: Desculpe, algo deu errado aqui do nosso lado. Se você + continuar a ver esse erro, tente entrar em contato com o proprietário da instância. + Se essa instância não estiver funcionando, verifique %link_start%outras instâncias + do Mbin%link_end% enquanto isso, até que o problema seja resolvido. +errors.server404.title: 404 Não encontrado +errors.server403.title: 403 Proibido +email.delete.title: Pedido de exclusão da conta do usuário +block: Bloquear +always_disconnected_magazine_info: Esta revista não está recebendo atualizações. +from: de +resend_account_activation_email_success: Se houver uma conta associada a esse e-mail, + enviaremos um novo e-mail de ativação. +resend_account_activation_email_description: Digite o endereço de e-mail associado + à sua conta. Nós te enviaremos outro e-mail de ativação. +custom_css: CSS Personalizado +ignore_magazines_custom_css: Ignorar o CSS personalizado das revistas +oauth.consent.title: Formulário de Consentimento OAuth2 +oauth.consent.app_requesting_permissions: gostaria de realizar as seguintes ações + em seu nome +oauth.consent.to_allow_access: Para permitir esse acesso, clique no botão 'Permitir' + abaixo +oauth.consent.allow: Permitir +oauth.client_identifier.invalid: ID de cliente OAuth inválido! +oauth2.grant.moderate.magazine.ban.delete: Desbanir usuários em suas revistas moderadas. +unblock: Desbloquear +private_instance: Forçar os usuários a fazer login antes de poderem acessar qualquer + conteúdo +oauth2.grant.moderate.magazine.list: Leia uma lista de suas revistas moderadas. +oauth2.grant.moderate.magazine.reports.all: Gerencie denúncias nas suas revistas moderadas. +oauth2.grant.moderate.magazine_admin.all: Crie, edite ou exclua suas próprias revistas. +oauth2.grant.moderate.magazine.reports.read: Leia denúncias nas suas revistas moderadas. +oauth2.grant.moderate.magazine.trash.read: Veja o conteúdo descartado em suas revistas + moderadas. +oauth2.grant.moderate.magazine_admin.create: Crie novas revistas. +oauth2.grant.moderate.magazine_admin.edit_theme: Edite o CSS personalizado de qualquer + uma de suas revistas. +oauth2.grant.subscribe.general: Assine ou siga qualquer revista, domínio ou usuário + e veja as revistas, domínios e usuários nos quais você se inscreveu. +oauth2.grant.moderate.magazine_admin.update: Edite as regras, a descrição, o status + NSFW ou o ícone de qualquer uma das suas revistas. +oauth2.grant.domain.block: Bloqueie ou desbloqueie domínios e visualize os domínios + que você bloqueou. +email.delete.description: O usuário seguinte solicitou que sua conta fosse excluída +resend_account_activation_email: Reenviar o e-mail de ativação da conta +errors.server429.title: 429 Solicitações em excesso +email_confirm_button_text: Confirme sua solicitação de alteração de senha +email_confirm_link_help: Como alternativa, você pode copiar e colar o seguinte em + seu navegador +oauth.consent.app_has_permissions: já pode executar as seguintes ações +oauth.client_not_granted_message_read_permission: Este aplicativo não recebeu permissão + para ler suas mensagens. +restrict_oauth_clients: Restringir a criação de clientes OAuth2 aos administradores +oauth2.grant.moderate.magazine.reports.action: Aceite ou rejeite denúncias em suas + revistas moderadas. +oauth2.grant.admin.all: Execute ações administrativas em sua instância. +oauth2.grant.read.general: Leia todo o conteúdo ao qual você tem acesso. +resend_account_activation_email_error: Houve um problema ao enviar esta solicitação. + Talvez não tenha uma conta associada a esse e-mail ou talvez ele já esteja ativado. +oauth2.grant.domain.subscribe: Assine ou cancele a assinatura de domínios e visualize + os domínios a que você se inscreveu. +oauth2.grant.moderate.magazine_admin.delete: Exclua qualquer uma de suas revistas. +oauth2.grant.block.general: Bloqueie ou desbloqueie qualquer revista, domínio ou usuário + e visualize as revistas, os domínios e os usuários que você bloqueou. +comment_not_found: Comentário não encontrado +oauth.consent.deny: Recusar +oauth2.grant.moderate.magazine_admin.moderators: Adicionar ou remover moderadores + de qualquer uma de suas revistas. +oauth2.grant.moderate.magazine_admin.badges: Crie ou remova selos de suas revistas + próprias. +disconnected_magazine_info: Esta revista não está recebendo atualizações (última atividade + %dias% dia(s) atrás). +resend_account_activation_email_question: Conta inativa? +oauth.consent.grant_permissions: Conceder permissões diff --git a/translations/messages.pt_BR.yaml b/translations/messages.pt_BR.yaml index cd46200a4..e0d6fbe47 100644 --- a/translations/messages.pt_BR.yaml +++ b/translations/messages.pt_BR.yaml @@ -237,3 +237,58 @@ infinite_scroll_help: Carregar automaticamente mais conteúdo quando chegar ao f da página. filter.fields.names_and_descriptions: Nomes e descrições kbin_bot: Agente Mbin +up_votes: Boosts +enter_your_post: Insira sua publicação +related_posts: Publicações relacionadas +random_posts: Publicações aleatórias +federated_magazine_info: Esta revista é de um servidor federado e pode estar incompleta. +disconnected_magazine_info: Esta revista não está recebendo atualizações (última atividade + %days% dia(s) atrás). +always_disconnected_magazine_info: Esta revista não está recebendo atualizações. +select_magazine: Selecione uma revista +collapse: Mostrar menos +flash_magazine_edit_success: A revista foi editada com sucesso. +set_magazines_bar_empty_desc: se o campo estiver vazio, as revistas ativas serão exibidas + na barra. +edited_comment: Editou um comentário +added_new_comment: Adicionou um novo comentário +edited_post: Editou uma publicação +replied_to_your_comment: Respondeu ao seu comentário +mod_remove_your_post: Um moderador removeu a sua publicação +added_new_reply: Adicionou uma nova resposta +change_downvotes_mode: Alterar o modo de votos negativos +downvotes_mode: Modo de votos negativos +notify_on_new_post_comment_reply: Respostas aos meus comentários em qualquer publicação +notify_on_new_posts: Novas publicações de qualquer revista a que estou inscrito +flash_unmark_as_adult_success: A publicação foi desmarcada como NSFW. +too_many_requests: Limite ultrapassado, tente novamente mais tarde. +set_magazines_bar: Barra de revistas +mod_deleted_your_comment: Um moderador excluiu seu comentário +added_new_post: Adicionou uma nova publicação +wrote_message: Escreveu uma mensagem +removed: Removido por mod +deleted: Excluído pelo autor +mentioned_you: Mencionou você +all_magazines: Todas as revistas +create_new_magazine: Criar nova revista +add_new_post: Adicionar nova publicação +up_vote: Impulsionar +badges: Selos +joined: Membro desde +moderated: Moderado +reputation_points: Pontos de reputação +go_to_search: Ir para a busca +table_view: Visualização da tabela +tree_view: Visualização em árvore +report: Denunciar +edit_comment: Salvar alterações +edit_post: Editar publicação +show_profile_subscriptions: Mostrar assinaturas de revistas +featured_magazines: Revistas em destaque +votes: Votos +boosts: Boosts +show_magazines_icons: Mostrar ícones das revistas +flash_magazine_new_success: A revista foi criada com sucesso. Você pode adicionar + novo conteúdo ou explorar o painel de administração da revista. +flash_mark_as_adult_success: A publicação foi marcada como NSFW. +post: Publicação From e5a994d2684c8284d9558d6dcc5b12ea2718434a Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Fri, 27 Sep 2024 17:58:58 +0200 Subject: [PATCH 289/335] add new develop branch for gh trigger (#1147) --- .github/workflows/action.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/action.yaml b/.github/workflows/action.yaml index fe2fd6454..cfd77275f 100644 --- a/.github/workflows/action.yaml +++ b/.github/workflows/action.yaml @@ -4,9 +4,11 @@ on: branches: - main - develop + - dev/new_features push: branches: - main + - dev/new_features tags: - 'v*' From 3782397c3b87c0e929f13be1e03322ff6124391c Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Fri, 27 Sep 2024 19:11:56 +0200 Subject: [PATCH 290/335] Store sessions in DB + improve cookies/sessions (#1145) --- config/packages/framework.yaml | 14 +- config/packages/security.yaml | 2 +- config/services.yaml | 198 +++++++++--------- migrations/Version20240923164233.php | 27 +++ src/Controller/BoostController.php | 3 - .../Domain/DomainBlockController.php | 6 - src/Controller/Domain/DomainSubController.php | 6 - src/Controller/FavouriteController.php | 3 - .../Magazine/MagazineBlockController.php | 6 - .../Magazine/MagazineSubController.php | 6 - src/Controller/Post/PostDeleteController.php | 9 - .../Profile/UserNotificationController.php | 6 - src/Controller/User/UserBlockController.php | 6 - src/Controller/User/UserFollowController.php | 6 - src/Controller/VoteController.php | 2 - templates/components/boost.html.twig | 1 - templates/components/domain_sub.html.twig | 2 - templates/components/favourite.html.twig | 1 - templates/components/magazine_sub.html.twig | 2 - templates/components/post.html.twig | 1 - templates/components/user_actions.html.twig | 2 - templates/components/vote.html.twig | 2 - templates/notifications/front.html.twig | 2 - templates/post/_menu.html.twig | 1 - templates/post/_moderate_panel.html.twig | 2 - 25 files changed, 139 insertions(+), 177 deletions(-) create mode 100644 migrations/Version20240923164233.php diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml index 91ee2939b..862e9f3cd 100644 --- a/config/packages/framework.yaml +++ b/config/packages/framework.yaml @@ -13,13 +13,19 @@ framework: 'x-forwarded-prefix', ] - # Enables session support. Note that the session will ONLY be started if you read or write from it. - # Remove or comment this section to explicitly disable session support. + # Sessions are stored in database, because saving sessions in Redis can give race conditions. + # See last paragraph of https://symfony.com/doc/current/session.html#store-sessions-in-a-key-value-database-redis + # + # PHP session handling is often (in Debian/Ubuntu) not doing gargage collection for sessions + # (session.gc_probability option in PHP). + # Hence we do also not want to set gc_maxlifetime for idle periods. + # We set our cookie session lifetime to the same value as remember_me token. + # More info: https://symfony.com/doc/current/session.html#session-idle-time-keep-alive session: - handler_id: '%env(REDIS_DNS)%' + handler_id: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler cookie_secure: auto cookie_samesite: lax - gc_maxlifetime: 1814400 # Match the remember_me lifetime + cookie_lifetime: 10512000 # 4 months long lifetime storage_factory_id: session.storage.factory.native http_client: diff --git a/config/packages/security.yaml b/config/packages/security.yaml index 44e441b7d..626baa730 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -49,7 +49,7 @@ security: user_checker: App\Security\UserChecker remember_me: secret: '%kernel.secret%' - lifetime: 1814400 + lifetime: 10512000 # 4 Months path: / token_provider: doctrine: true diff --git a/config/services.yaml b/config/services.yaml index 021b2591b..b5924f19a 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -1,77 +1,76 @@ framework: serializer: mapping: - paths: ["%kernel.project_dir%/config/kbin_serialization"] + paths: ['%kernel.project_dir%/config/kbin_serialization'] parameters: - kbin_domain: "%env(KBIN_DOMAIN)%" - kbin_title: "%env(KBIN_TITLE)%" - kbin_meta_title: "%env(KBIN_META_TITLE)%" - kbin_meta_description: "%env(KBIN_META_DESCRIPTION)%" - kbin_meta_keywords: "%env(KBIN_META_KEYWORDS)%" - kbin_contact_email: "%env(KBIN_CONTACT_EMAIL)%" - kbin_sender_email: "%env(KBIN_SENDER_EMAIL)%" - kbin_default_lang: "%env(KBIN_DEFAULT_LANG)%" - kbin_api_items_per_page: "%env(KBIN_API_ITEMS_PER_PAGE)%" - kbin_js_enabled: "%env(bool:KBIN_JS_ENABLED)%" - kbin_federation_enabled: "%env(KBIN_FEDERATION_ENABLED)%" - kbin_registrations_enabled: "%env(KBIN_REGISTRATIONS_ENABLED)%" + kbin_domain: '%env(KBIN_DOMAIN)%' + kbin_title: '%env(KBIN_TITLE)%' + kbin_meta_title: '%env(KBIN_META_TITLE)%' + kbin_meta_description: '%env(KBIN_META_DESCRIPTION)%' + kbin_meta_keywords: '%env(KBIN_META_KEYWORDS)%' + kbin_contact_email: '%env(KBIN_CONTACT_EMAIL)%' + kbin_sender_email: '%env(KBIN_SENDER_EMAIL)%' + kbin_default_lang: '%env(KBIN_DEFAULT_LANG)%' + kbin_api_items_per_page: '%env(KBIN_API_ITEMS_PER_PAGE)%' + kbin_js_enabled: '%env(bool:KBIN_JS_ENABLED)%' + kbin_federation_enabled: '%env(KBIN_FEDERATION_ENABLED)%' + kbin_registrations_enabled: '%env(KBIN_REGISTRATIONS_ENABLED)%' kbin_ap_route_condition: 'request.getAcceptableContentTypes() and request.getAcceptableContentTypes()[0] in ["application/activity+json", "application/ld+json", "application/json"]' - kbin_storage_url: "%env(KBIN_STORAGE_URL)%" + kbin_storage_url: '%env(KBIN_STORAGE_URL)%' # Grab the default theme to use from the MBIN_DEFAULT_THEME env var # with a fall back of light/dark auto detection based on user setting default_theme: default - mbin_default_theme: "%env(default:default_theme:MBIN_DEFAULT_THEME)%" + mbin_default_theme: '%env(default:default_theme:MBIN_DEFAULT_THEME)%' - amazon.s3.key: "%env(S3_KEY)%" - amazon.s3.secret: "%env(S3_SECRET)%" - amazon.s3.bucket: "%env(S3_BUCKET)%" - amazon.s3.region: "%env(S3_REGION)%" - amazon.s3.version: "%env(S3_VERSION)%" - amazon.s3.endpoint: "%env(S3_ENDPOINT)%" + amazon.s3.key: '%env(S3_KEY)%' + amazon.s3.secret: '%env(S3_SECRET)%' + amazon.s3.bucket: '%env(S3_BUCKET)%' + amazon.s3.region: '%env(S3_REGION)%' + amazon.s3.version: '%env(S3_VERSION)%' + amazon.s3.endpoint: '%env(S3_ENDPOINT)%' - hcaptcha_site_key: "%env(resolve:HCAPTCHA_SITE_KEY)%" - hcaptcha_secret: "%env(resolve:HCAPTCHA_SECRET)%" + hcaptcha_site_key: '%env(resolve:HCAPTCHA_SITE_KEY)%' + hcaptcha_secret: '%env(resolve:HCAPTCHA_SECRET)%' - oauth_azure_id: "%env(default::OAUTH_AZURE_ID)%" - oauth_azure_secret: "%env(OAUTH_AZURE_SECRET)%" - oauth_azure_tenant: "%env(OAUTH_AZURE_TENANT)%" + oauth_azure_id: '%env(default::OAUTH_AZURE_ID)%' + oauth_azure_secret: '%env(OAUTH_AZURE_SECRET)%' + oauth_azure_tenant: '%env(OAUTH_AZURE_TENANT)%' - oauth_facebook_id: "%env(default::OAUTH_FACEBOOK_ID)%" - oauth_facebook_secret: "%env(OAUTH_FACEBOOK_SECRET)%" + oauth_facebook_id: '%env(default::OAUTH_FACEBOOK_ID)%' + oauth_facebook_secret: '%env(OAUTH_FACEBOOK_SECRET)%' - oauth_google_id: "%env(default::OAUTH_GOOGLE_ID)%" - oauth_google_secret: "%env(OAUTH_GOOGLE_SECRET)%" + oauth_google_id: '%env(default::OAUTH_GOOGLE_ID)%' + oauth_google_secret: '%env(OAUTH_GOOGLE_SECRET)%' - oauth_discord_id: "%env(default::OAUTH_DISCORD_ID)%" - oauth_discord_secret: "%env(OAUTH_DISCORD_SECRET)%" + oauth_discord_id: '%env(default::OAUTH_DISCORD_ID)%' + oauth_discord_secret: '%env(OAUTH_DISCORD_SECRET)%' - oauth_github_id: "%env(default::OAUTH_GITHUB_ID)%" - oauth_github_secret: "%env(OAUTH_GITHUB_SECRET)%" + oauth_github_id: '%env(default::OAUTH_GITHUB_ID)%' + oauth_github_secret: '%env(OAUTH_GITHUB_SECRET)%' - oauth_privacyportal_id: "%env(default::OAUTH_PRIVACYPORTAL_ID)%" - oauth_privacyportal_secret: "%env(OAUTH_PRIVACYPORTAL_SECRET)%" + oauth_privacyportal_id: '%env(default::OAUTH_PRIVACYPORTAL_ID)%' + oauth_privacyportal_secret: '%env(OAUTH_PRIVACYPORTAL_SECRET)%' - oauth_keycloak_id: "%env(default::OAUTH_KEYCLOAK_ID)%" - oauth_keycloak_secret: "%env(OAUTH_KEYCLOAK_SECRET)%" - oauth_keycloak_uri: "%env(OAUTH_KEYCLOAK_URI)%" - oauth_keycloak_realm: "%env(OAUTH_KEYCLOAK_REALM)%" - oauth_keycloak_version: "%env(OAUTH_KEYCLOAK_VERSION)%" + oauth_keycloak_id: '%env(default::OAUTH_KEYCLOAK_ID)%' + oauth_keycloak_secret: '%env(OAUTH_KEYCLOAK_SECRET)%' + oauth_keycloak_uri: '%env(OAUTH_KEYCLOAK_URI)%' + oauth_keycloak_realm: '%env(OAUTH_KEYCLOAK_REALM)%' + oauth_keycloak_version: '%env(OAUTH_KEYCLOAK_VERSION)%' - oauth_simplelogin_id: "%env(default::OAUTH_SIMPLELOGIN_ID)%" - oauth_simplelogin_secret: "%env(OAUTH_SIMPLELOGIN_SECRET)%" + oauth_simplelogin_id: '%env(default::OAUTH_SIMPLELOGIN_ID)%' + oauth_simplelogin_secret: '%env(OAUTH_SIMPLELOGIN_SECRET)%' - oauth_zitadel_id: "%env(default::OAUTH_ZITADEL_ID)%" - oauth_zitadel_secret: "%env(OAUTH_ZITADEL_SECRET)%" - oauth_zitadel_base_url: "%env(OAUTH_ZITADEL_BASE_URL)%" + oauth_zitadel_id: '%env(default::OAUTH_ZITADEL_ID)%' + oauth_zitadel_secret: '%env(OAUTH_ZITADEL_SECRET)%' + oauth_zitadel_base_url: '%env(OAUTH_ZITADEL_BASE_URL)%' - oauth_authentik_id: "%env(default::OAUTH_AUTHENTIK_ID)%" - oauth_authentik_secret: "%env(OAUTH_AUTHENTIK_SECRET)%" - oauth_authentik_base_url: "%env(OAUTH_AUTHENTIK_BASE_URL)%" + oauth_authentik_id: '%env(default::OAUTH_AUTHENTIK_ID)%' + oauth_authentik_secret: '%env(OAUTH_AUTHENTIK_SECRET)%' + oauth_authentik_base_url: '%env(OAUTH_AUTHENTIK_BASE_URL)%' - - router.request_context.host: "%env(KBIN_DOMAIN)%" + router.request_context.host: '%env(KBIN_DOMAIN)%' router.request_context.scheme: https html5_validation: true @@ -88,16 +87,16 @@ parameters: stats_type: general|content|votes - number_regex: "[1-9][0-9]{0,17}" + number_regex: '[1-9][0-9]{0,17}' username_regex: '\w{2,25}|!deleted\d+' - uploads_dir_name: "media" - uploads_base_url: "/" + uploads_dir_name: 'media' + uploads_base_url: '/' - mercure_public_url: "%env(MERCURE_PUBLIC_URL)%" - mercure_subscriptions_token: "%env(MERCURE_JWT_SECRET)%" + mercure_public_url: '%env(MERCURE_PUBLIC_URL)%' + mercure_subscriptions_token: '%env(MERCURE_JWT_SECRET)%' - sso_only_mode: "%env(bool:default::SSO_ONLY_MODE)%" + sso_only_mode: '%env(bool:default::SSO_ONLY_MODE)%' exif_default_uploaded: 'sanitize' exif_default_external: 'none' @@ -107,7 +106,7 @@ parameters: exif_exiftool_path: '%env(default::EXIF_EXIFTOOL_PATH)%' exif_exiftool_timeout: '%env(int:default::EXIF_EXIFTOOL_TIMEOUT)%' - max_image_bytes: "%env(int:default:max_image_bytes_default:MAX_IMAGE_BYTES)%" + max_image_bytes: '%env(int:default:max_image_bytes_default:MAX_IMAGE_BYTES)%' max_image_bytes_default: 6000000 mbin_downvotes_mode_default: 'enabled' @@ -119,41 +118,41 @@ services: autowire: true # Automatically injects dependencies in your services. autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. bind: - $kbinDomain: "%kbin_domain%" - $html5Validation: "%html5_validation%" - $uploadedAssetsBaseUrl: "%uploads_base_url%" - $mercurePublicUrl: "%mercure_public_url%" - $mercureSubscriptionsToken: "%mercure_subscriptions_token%" - $kbinApiItemsPerPage: "%kbin_api_items_per_page%" - $storageUrl: "%kbin_storage_url%" - $publicDir: "%kernel.project_dir%/public" + $kbinDomain: '%kbin_domain%' + $html5Validation: '%html5_validation%' + $uploadedAssetsBaseUrl: '%uploads_base_url%' + $mercurePublicUrl: '%mercure_public_url%' + $mercureSubscriptionsToken: '%mercure_subscriptions_token%' + $kbinApiItemsPerPage: '%kbin_api_items_per_page%' + $storageUrl: '%kbin_storage_url%' + $publicDir: '%kernel.project_dir%/public' kbin.s3_client: class: Aws\S3\S3Client arguments: - - version: "%amazon.s3.version%" - region: "%amazon.s3.region%" - endpoint: "%amazon.s3.endpoint%" + - version: '%amazon.s3.version%' + region: '%amazon.s3.region%' + endpoint: '%amazon.s3.endpoint%' #use_path_style_endpoint: true credentials: - key: "%amazon.s3.key%" - secret: "%amazon.s3.secret%" + key: '%amazon.s3.key%' + secret: '%amazon.s3.secret%' #proxies: [ 'https://media.domain.tld' ] # makes classes in src/ available to be used as services # this creates a service per class whose id is the fully-qualified class name App\: - resource: "../src/" + resource: '../src/' exclude: - - "../src/DependencyInjection/" - - "../src/Entity/" - - "../src/Kernel.php" + - '../src/DependencyInjection/' + - '../src/Entity/' + - '../src/Kernel.php' # add more service definitions when explicit configuration is needed # please note that last definitions always *replace* previous ones App\Controller\: - resource: "../src/Controller/" - tags: ["controller.service_arguments"] + resource: '../src/Controller/' + tags: ['controller.service_arguments'] # App\Http\RequestDTOResolver: # arguments: @@ -164,24 +163,24 @@ services: # Instance settings App\Service\SettingsManager: arguments: - $kbinTitle: "%kbin_title%" - $kbinMetaTitle: "%kbin_meta_title%" - $kbinMetaDescription: "%kbin_meta_description%" - $kbinMetaKeywords: "%kbin_meta_keywords%" - $kbinDefaultLang: "%kbin_default_lang%" - $kbinContactEmail: "%kbin_contact_email%" - $kbinSenderEmail: "%kbin_sender_email%" - $mbinDefaultTheme: "%mbin_default_theme%" - $kbinJsEnabled: "%env(bool:KBIN_JS_ENABLED)%" - $kbinFederationEnabled: "%env(bool:KBIN_FEDERATION_ENABLED)%" - $kbinRegistrationsEnabled: "%env(bool:KBIN_REGISTRATIONS_ENABLED)%" - $kbinHeaderLogo: "%env(bool:KBIN_HEADER_LOGO)%" - $kbinCaptchaEnabled: "%env(bool:KBIN_CAPTCHA_ENABLED)%" - $kbinFederationPageEnabled: "%env(bool:KBIN_FEDERATION_PAGE_ENABLED)%" - $kbinAdminOnlyOauthClients: "%env(bool:KBIN_ADMIN_ONLY_OAUTH_CLIENTS)%" - $mbinSsoOnlyMode: "%sso_only_mode%" - $maxImageBytes: "%max_image_bytes%" - $mbinDownvotesMode: "%mbin_downvotes_mode%" + $kbinTitle: '%kbin_title%' + $kbinMetaTitle: '%kbin_meta_title%' + $kbinMetaDescription: '%kbin_meta_description%' + $kbinMetaKeywords: '%kbin_meta_keywords%' + $kbinDefaultLang: '%kbin_default_lang%' + $kbinContactEmail: '%kbin_contact_email%' + $kbinSenderEmail: '%kbin_sender_email%' + $mbinDefaultTheme: '%mbin_default_theme%' + $kbinJsEnabled: '%env(bool:KBIN_JS_ENABLED)%' + $kbinFederationEnabled: '%env(bool:KBIN_FEDERATION_ENABLED)%' + $kbinRegistrationsEnabled: '%env(bool:KBIN_REGISTRATIONS_ENABLED)%' + $kbinHeaderLogo: '%env(bool:KBIN_HEADER_LOGO)%' + $kbinCaptchaEnabled: '%env(bool:KBIN_CAPTCHA_ENABLED)%' + $kbinFederationPageEnabled: '%env(bool:KBIN_FEDERATION_PAGE_ENABLED)%' + $kbinAdminOnlyOauthClients: '%env(bool:KBIN_ADMIN_ONLY_OAUTH_CLIENTS)%' + $mbinSsoOnlyMode: '%sso_only_mode%' + $maxImageBytes: '%max_image_bytes%' + $mbinDownvotesMode: '%mbin_downvotes_mode%' # Markdown App\Markdown\Factory\EnvironmentFactory: @@ -192,7 +191,7 @@ services: League\CommonMark\Extension\Strikethrough\StrikethroughExtension: '@League\CommonMark\Extension\Strikethrough\StrikethroughExtension' League\CommonMark\Extension\Table\TableExtension: '@League\CommonMark\Extension\Table\TableExtension' App\Markdown\MarkdownExtension: '@App\Markdown\MarkdownExtension' - $config: "%commonmark.configuration%" + $config: '%commonmark.configuration%' # Language App\EventListener\LanguageListener: @@ -202,7 +201,7 @@ services: event: kernel.request, priority: 200, } - arguments: ["%kbin_default_lang%"] + arguments: ['%kbin_default_lang%'] # Federation App\EventListener\FederationStatusListener: @@ -241,3 +240,8 @@ services: messenger.failure.add_error_details_stamp_listener: class: App\Utils\AddErrorDetailsStampListener + + # Store session in database using PdoSessionHandler, by providing the DB DSN + Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler: + arguments: + - '%env(DATABASE_URL)%' diff --git a/migrations/Version20240923164233.php b/migrations/Version20240923164233.php new file mode 100644 index 000000000..81fc40b02 --- /dev/null +++ b/migrations/Version20240923164233.php @@ -0,0 +1,27 @@ +addSql('CREATE TABLE sessions (sess_id VARCHAR(128) NOT NULL, sess_data BYTEA NOT NULL, sess_lifetime INT NOT NULL, sess_time INT NOT NULL, PRIMARY KEY(sess_id))'); + $this->addSql('CREATE INDEX sess_lifetime_idx ON sessions (sess_lifetime)'); + } + + public function down(Schema $schema): void + { + $this->addSql('DROP TABLE sessions'); + } +} diff --git a/src/Controller/BoostController.php b/src/Controller/BoostController.php index 75284d737..bb8974630 100644 --- a/src/Controller/BoostController.php +++ b/src/Controller/BoostController.php @@ -23,9 +23,6 @@ public function __construct( #[IsGranted('ROLE_USER')] public function __invoke(VotableInterface $subject, Request $request): Response { - // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 - // $this->validateCsrf('boost', $request->getPayload()->get('token')); - $this->manager->vote(VotableInterface::VOTE_UP, $subject, $this->getUserOrThrow()); if ($request->isXmlHttpRequest()) { diff --git a/src/Controller/Domain/DomainBlockController.php b/src/Controller/Domain/DomainBlockController.php index 67462ec90..c53750218 100644 --- a/src/Controller/Domain/DomainBlockController.php +++ b/src/Controller/Domain/DomainBlockController.php @@ -22,9 +22,6 @@ public function __construct( #[IsGranted('ROLE_USER')] public function block(Domain $domain, Request $request): Response { - // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 - // $this->validateCsrf('block', $request->getPayload()->get('token')); - $this->manager->block($domain, $this->getUserOrThrow()); if ($request->isXmlHttpRequest()) { @@ -37,9 +34,6 @@ public function block(Domain $domain, Request $request): Response #[IsGranted('ROLE_USER')] public function unblock(Domain $domain, Request $request): Response { - // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 - // $this->validateCsrf('block', $request->getPayload()->get('token')); - $this->manager->unblock($domain, $this->getUserOrThrow()); if ($request->isXmlHttpRequest()) { diff --git a/src/Controller/Domain/DomainSubController.php b/src/Controller/Domain/DomainSubController.php index 5e06810d5..30cafd9cc 100644 --- a/src/Controller/Domain/DomainSubController.php +++ b/src/Controller/Domain/DomainSubController.php @@ -22,9 +22,6 @@ public function __construct( #[IsGranted('ROLE_USER')] public function subscribe(Domain $domain, Request $request): Response { - // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 - // $this->validateCsrf('subscribe', $request->getPayload()->get('token')); - $this->manager->subscribe($domain, $this->getUserOrThrow()); if ($request->isXmlHttpRequest()) { @@ -37,9 +34,6 @@ public function subscribe(Domain $domain, Request $request): Response #[IsGranted('ROLE_USER')] public function unsubscribe(Domain $domain, Request $request): Response { - // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 - // $this->validateCsrf('subscribe', $request->getPayload()->get('token')); - $this->manager->unsubscribe($domain, $this->getUserOrThrow()); if ($request->isXmlHttpRequest()) { diff --git a/src/Controller/FavouriteController.php b/src/Controller/FavouriteController.php index 2834255cb..299fb3f75 100644 --- a/src/Controller/FavouriteController.php +++ b/src/Controller/FavouriteController.php @@ -21,9 +21,6 @@ public function __construct(private readonly GenerateHtmlClassService $classServ #[IsGranted('ROLE_USER')] public function __invoke(FavouriteInterface $subject, Request $request, FavouriteManager $manager): Response { - // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 - // $this->validateCsrf('up_vote', $request->getPayload()->get('token')); - $manager->toggle($this->getUserOrThrow(), $subject); if ($request->isXmlHttpRequest()) { diff --git a/src/Controller/Magazine/MagazineBlockController.php b/src/Controller/Magazine/MagazineBlockController.php index ad1972da1..3034dd0ec 100644 --- a/src/Controller/Magazine/MagazineBlockController.php +++ b/src/Controller/Magazine/MagazineBlockController.php @@ -22,9 +22,6 @@ public function __construct(private readonly MagazineManager $manager) #[IsGranted('block', subject: 'magazine')] public function block(Magazine $magazine, Request $request): Response { - // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 - // $this->validateCsrf('block', $request->getPayload()->get('token')); - $this->manager->block($magazine, $this->getUserOrThrow()); if ($request->isXmlHttpRequest()) { @@ -38,9 +35,6 @@ public function block(Magazine $magazine, Request $request): Response #[IsGranted('block', subject: 'magazine')] public function unblock(Magazine $magazine, Request $request): Response { - // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 - // $this->validateCsrf('block', $request->getPayload()->get('token')); - $this->manager->unblock($magazine, $this->getUserOrThrow()); if ($request->isXmlHttpRequest()) { diff --git a/src/Controller/Magazine/MagazineSubController.php b/src/Controller/Magazine/MagazineSubController.php index 1a5d0a4c4..2289f6a4b 100644 --- a/src/Controller/Magazine/MagazineSubController.php +++ b/src/Controller/Magazine/MagazineSubController.php @@ -22,9 +22,6 @@ public function __construct(private readonly MagazineManager $manager) #[IsGranted('subscribe', subject: 'magazine')] public function subscribe(Magazine $magazine, Request $request): Response { - // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 - // $this->validateCsrf('subscribe', $request->getPayload()->get('token')); - $this->manager->subscribe($magazine, $this->getUserOrThrow()); if ($request->isXmlHttpRequest()) { @@ -38,9 +35,6 @@ public function subscribe(Magazine $magazine, Request $request): Response #[IsGranted('subscribe', subject: 'magazine')] public function unsubscribe(Magazine $magazine, Request $request): Response { - // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 - // $this->validateCsrf('subscribe', $request->getPayload()->get('token')); - $this->manager->unsubscribe($magazine, $this->getUserOrThrow()); if ($request->isXmlHttpRequest()) { diff --git a/src/Controller/Post/PostDeleteController.php b/src/Controller/Post/PostDeleteController.php index 1bf5b42b7..271e28bc5 100644 --- a/src/Controller/Post/PostDeleteController.php +++ b/src/Controller/Post/PostDeleteController.php @@ -28,9 +28,6 @@ public function delete( Post $post, Request $request ): Response { - // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 - // $this->validateCsrf('post_delete', $request->getPayload()->get('token')); - $this->manager->delete($this->getUserOrThrow(), $post); return $this->redirectToRefererOrHome($request); @@ -45,9 +42,6 @@ public function restore( Post $post, Request $request ): Response { - // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 - // $this->validateCsrf('post_restore', $request->getPayload()->get('token')); - $this->manager->restore($this->getUserOrThrow(), $post); return $this->redirectToRefererOrHome($request); @@ -62,9 +56,6 @@ public function purge( Post $post, Request $request ): Response { - // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 - // $this->validateCsrf('post_purge', $request->getPayload()->get('token')); - $this->manager->purge($this->getUserOrThrow(), $post); return $this->redirectToMagazine($magazine); diff --git a/src/Controller/User/Profile/UserNotificationController.php b/src/Controller/User/Profile/UserNotificationController.php index bd161ec9f..46d0c197c 100644 --- a/src/Controller/User/Profile/UserNotificationController.php +++ b/src/Controller/User/Profile/UserNotificationController.php @@ -29,9 +29,6 @@ public function notifications(NotificationRepository $repository, Request $reque #[IsGranted('ROLE_USER')] public function read(NotificationManager $manager, Request $request): Response { - // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 - // $this->validateCsrf('read_notifications', $request->getPayload()->get('token')); - $manager->markAllAsRead($this->getUserOrThrow()); return $this->redirectToRefererOrHome($request); @@ -40,9 +37,6 @@ public function read(NotificationManager $manager, Request $request): Response #[IsGranted('ROLE_USER')] public function clear(NotificationManager $manager, Request $request): Response { - // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 - // $this->validateCsrf('clear_notifications', $request->getPayload()->get('token')); - $manager->clear($this->getUserOrThrow()); return $this->redirectToRefererOrHome($request); diff --git a/src/Controller/User/UserBlockController.php b/src/Controller/User/UserBlockController.php index 0ba8568f5..35bee56ba 100644 --- a/src/Controller/User/UserBlockController.php +++ b/src/Controller/User/UserBlockController.php @@ -17,9 +17,6 @@ class UserBlockController extends AbstractController #[IsGranted('ROLE_USER')] public function block(User $blocked, UserManager $manager, Request $request): Response { - // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 - // $this->validateCsrf('block', $request->getPayload()->get('token')); - $manager->block($this->getUserOrThrow(), $blocked); if ($request->isXmlHttpRequest()) { @@ -32,9 +29,6 @@ public function block(User $blocked, UserManager $manager, Request $request): Re #[IsGranted('ROLE_USER')] public function unblock(User $blocked, UserManager $manager, Request $request): Response { - // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 - // $this->validateCsrf('block', $request->getPayload()->get('token')); - $manager->unblock($this->getUserOrThrow(), $blocked); if ($request->isXmlHttpRequest()) { diff --git a/src/Controller/User/UserFollowController.php b/src/Controller/User/UserFollowController.php index 8ab905ad3..372699db5 100644 --- a/src/Controller/User/UserFollowController.php +++ b/src/Controller/User/UserFollowController.php @@ -18,9 +18,6 @@ class UserFollowController extends AbstractController #[IsGranted('follow', subject: 'following')] public function follow(User $following, UserManager $manager, Request $request): Response { - // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 - // $this->validateCsrf('follow', $request->getPayload()->get('token')); - $manager->follow($this->getUserOrThrow(), $following); if ($request->isXmlHttpRequest()) { @@ -34,9 +31,6 @@ public function follow(User $following, UserManager $manager, Request $request): #[IsGranted('follow', subject: 'following')] public function unfollow(User $following, UserManager $manager, Request $request): Response { - // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 - // $this->validateCsrf('follow', $request->getPayload()->get('token')); - $manager->unfollow($this->getUserOrThrow(), $following); if ($request->isXmlHttpRequest()) { diff --git a/src/Controller/VoteController.php b/src/Controller/VoteController.php index bc5eeeeda..9a453710e 100644 --- a/src/Controller/VoteController.php +++ b/src/Controller/VoteController.php @@ -30,8 +30,6 @@ public function __construct( #[IsGranted('vote', subject: 'votable')] public function __invoke(VotableInterface $votable, int $choice, Request $request): Response { - // CSRF is causing a lot of issues, so we disable it for now. See PR: https://github.com/MbinOrg/mbin/pull/1136 - // $this->validateCsrf('down_vote', $request->getPayload()->get('token')); if (VotableInterface::VOTE_DOWN === $choice && DownvotesMode::Disabled === $this->settingsManager->getDownvotesMode()) { throw new BadRequestException('Downvotes are disabled!'); } diff --git a/templates/components/boost.html.twig b/templates/components/boost.html.twig index 776850973..e6489c9c3 100644 --- a/templates/components/boost.html.twig +++ b/templates/components/boost.html.twig @@ -2,7 +2,6 @@ {%- set user_choice = is_granted('ROLE_USER') ? subject.userChoice(app.user) : null -%}
          - -
          {{ is_domain_blocked(domain) ? 'unblock'|trans : 'block'|trans }} -
          diff --git a/templates/components/favourite.html.twig b/templates/components/favourite.html.twig index bbe51501e..442e6529f 100644 --- a/templates/components/favourite.html.twig +++ b/templates/components/favourite.html.twig @@ -1,6 +1,5 @@
          - -
          {{ is_magazine_blocked(magazine) ? 'unblock'|trans : 'block'|trans }} -
          diff --git a/templates/components/post.html.twig b/templates/components/post.html.twig index 38da11dd9..04a79d7e6 100644 --- a/templates/components/post.html.twig +++ b/templates/components/post.html.twig @@ -128,7 +128,6 @@
          -
        • diff --git a/templates/components/user_actions.html.twig b/templates/components/user_actions.html.twig index baf73c141..512a8632f 100644 --- a/templates/components/user_actions.html.twig +++ b/templates/components/user_actions.html.twig @@ -18,7 +18,6 @@ {% endif %} -
          -
          - {% set downvoteMode = mbin_downvotes_mode() %} {% if showDownvote and downvoteMode is not same as DOWNVOTES_DISABLED %} @@ -51,7 +50,6 @@ {% endif %} - {% endif %} diff --git a/templates/notifications/front.html.twig b/templates/notifications/front.html.twig index 98e790b5a..6612eee1a 100644 --- a/templates/notifications/front.html.twig +++ b/templates/notifications/front.html.twig @@ -19,14 +19,12 @@
          -
          - diff --git a/templates/post/_menu.html.twig b/templates/post/_menu.html.twig index 89b5dff8b..e4db4f07a 100644 --- a/templates/post/_menu.html.twig +++ b/templates/post/_menu.html.twig @@ -51,7 +51,6 @@ -
          diff --git a/templates/post/_moderate_panel.html.twig b/templates/post/_moderate_panel.html.twig index 0bf6281c0..fe80e27e8 100644 --- a/templates/post/_moderate_panel.html.twig +++ b/templates/post/_moderate_panel.html.twig @@ -32,7 +32,6 @@
          - @@ -43,7 +42,6 @@ - From d9e60a9354643f41e8f9b45b384eb69ee68d0f21 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Mon, 30 Sep 2024 15:42:06 +0200 Subject: [PATCH 291/335] Translations update from Hosted Weblate (#1149) Co-authored-by: ruine Co-authored-by: veroandi --- translations/messages.ja.yaml | 39 +++++++++++++++++--------------- translations/messages.pt_BR.yaml | 2 ++ 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/translations/messages.ja.yaml b/translations/messages.ja.yaml index 2570c308a..28392671c 100644 --- a/translations/messages.ja.yaml +++ b/translations/messages.ja.yaml @@ -10,7 +10,7 @@ microblog: ミニブログ people: ユーザー events: イベント magazine: 雑誌 -magazines: 雑誌ら +magazines: 雑誌 search: 検索 add: 追加 select_channel: チャンネルを選択 @@ -24,7 +24,7 @@ commented: コメントの多い順 change_view: 表示を変更 filter_by_time: 時間でフィルター filter_by_type: 投稿でフィルター -favourites: お気に入りら +favourites: お気に入り favourite: お気に入り more: さらに avatar: アバター @@ -50,8 +50,8 @@ activity: アクティビティ cover: プロフィールのバナー related_posts: 関連投稿 random_posts: 最近のコメント -federated_user_info: このプロフィールは連合サーバから、 かも知れない未完だ。 -go_to_original_instance: 連合元インスタンスで表示する。 +federated_user_info: このプロフィールは連合サーバからのもので、不完全な可能性があります。 +go_to_original_instance: 連合元インスタンスで表示 empty: 投稿なし subscribe: 購読する unsubscribe: 購読を解除 @@ -140,7 +140,7 @@ articles: スレッド photos: 画像 videos: 動画 report: 通報 -share: シェア +share: 共有 copy_url_to_fediverse: オリジナルURLをコピー share_on_fediverse: フェディバースへシェア edit: 編集 @@ -164,7 +164,7 @@ email_confirm_expire: リンクの有効期限は1時間です。 enter_your_comment: コメントを入力してください fediverse: フェディバース create_new_magazine: 新しいマガジンを作成 -federated_magazine_info: この雑誌は連合サーバから、 かも知れない未完だ。 +federated_magazine_info: この雑誌は連合サーバからのもので、不完全な可能性があります。 add_new_photo: 新しい画像を追加 image_alt: 画像の代替テキスト moderated: モデレートしている雑誌 @@ -192,7 +192,7 @@ notify_on_new_post_comment_reply: 自分の投稿のコメントのリプライ notify_on_new_entry: 購読しているマガジンの新スレッドを通知する notify_on_new_posts: 購読しているマガジンの新規投稿を通知する save: 保存 -about: kvinについて +about: Mbinについて old_email: 現在のメールアドレス new_email: 新しいメールアドレス new_email_repeat: もう一度新しいメールを入力 @@ -264,7 +264,7 @@ post: 投稿する comment: コメントする ban_expired: バンの期限切れました purge: 消去する -send_message: メッセージを送る +send_message: ダイレクトメッセージを送る message: メッセージ infinite_scroll: 無限スクロール show_top_bar: トップバーを表示する @@ -363,7 +363,7 @@ boost: ブースト mercure_enabled: Mercureが有効 report_issue: バグを報告 tokyo_night: 東京ナイト -oauth2.grant.post.edit: 既存ポストをエディット 。 +oauth2.grant.post.edit: 既存ポストを編集 。 oauth2.grant.user.message.all: メッセージを読んで、 他ユーザーにメッセージを飛ばす。 oauth2.grant.moderate.magazine_admin.create: 新しい雑誌を作る。 filter.adult.hide: R18/NSFWを見せない @@ -379,10 +379,10 @@ filter.fields.names_and_descriptions: 名前と記述 oauth2.grant.user.profile.all: プロフィールを読んで、 エディットする。 oauth2.grant.entry_comment.create: スレッドに新しいコメントを作る。 oauth.consent.deny: 打ち消す -oauth2.grant.entry_comment.delete: スレッドに既存コメントを消す。 +oauth2.grant.entry_comment.delete: スレッドの既存コメントを消す。 subject_reported_exists: このコンテンツはもう報告しました。 -oauth2.grant.entry.edit: 既存スレッドをエディットする。 -oauth2.grant.entry_comment.edit: スレッドに既存コメントをエディットする。 +oauth2.grant.entry.edit: 既存スレッドを編集する。 +oauth2.grant.entry_comment.edit: スレッドの既存コメントを編集する。 oauth2.grant.user.profile.read: プロフィールを読む。 toolbar.link: リンク moderation.report.ban_user_title: ユーザーを禁止します @@ -398,24 +398,27 @@ toolbar.italic: 斜体 oauth2.grant.user.profile.edit: プロフィールをエディット。 moderation.report.approve_report_title: 通知を許す moderation.report.reject_report_title: 通知を断る -errors.server429.title: 429要望する過ぎる +errors.server429.title: 429 Too Many Requests local_and_federated: ローカルと連合 toolbar.ordered_list: 順序付きリスト custom_css: カスタムCSS -toolbar.quote: 引き合いに出す +toolbar.quote: 引用 toolbar.unordered_list: 順序不同リスト -errors.server404.title: 404見つからない +errors.server404.title: 404 Not found resend_account_activation_email: もう一度アカウントアクティブ化メールを飛ばす -errors.server500.title: 500サーバエラー +errors.server500.title: 500 Internal Server Error toolbar.mention: メンション oauth2.grant.write.general: スレッドとポストとコメントを作ってか、 エディットする。 single_settings: 単一 resend_account_activation_email_question: 非活動アカウント? -your_account_has_been_banned: アカウントは禁しました +your_account_has_been_banned: あなたのアカウントはバンされました oauth2.grant.delete.general: スレッドとポストとコメントを消す。 -oauth2.grant.user.notification.delete: 通知を晴れる。 +oauth2.grant.user.notification.delete: 通知を消去する。 email.delete.title: ユーザーのアカウント削除を要望する comment_reply_position: コメントのレスの位置 kbin_bot: Mbinのボット federation_page_enabled: 連合は使用可能をしました show_avatars_on_comments: コメントでアバターを見せる +tag: タグ +remove_media: メディアを削除 +edit_entry: スレッドを編集 diff --git a/translations/messages.pt_BR.yaml b/translations/messages.pt_BR.yaml index e0d6fbe47..1c9a53341 100644 --- a/translations/messages.pt_BR.yaml +++ b/translations/messages.pt_BR.yaml @@ -292,3 +292,5 @@ flash_magazine_new_success: A revista foi criada com sucesso. Você pode adicion novo conteúdo ou explorar o painel de administração da revista. flash_mark_as_adult_success: A publicação foi marcada como NSFW. post: Publicação +terms: Termos de Serviço +people_local: Local From d9fe926f971ed87232ccbcbbe874ef464d29f932 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Tue, 1 Oct 2024 15:01:52 +0200 Subject: [PATCH 292/335] Add stricter requirements to existing routes (#1150) --- config/kbin_routes/ajax.yaml | 10 ++++ config/kbin_routes/entry.yaml | 92 ++++++++++++++++++++++++++++++--- config/kbin_routes/message.yaml | 2 + config/kbin_routes/post.yaml | 74 ++++++++++++++++++++++++++ 4 files changed, 172 insertions(+), 6 deletions(-) diff --git a/config/kbin_routes/ajax.yaml b/config/kbin_routes/ajax.yaml index 1e29cc2d0..642087898 100644 --- a/config/kbin_routes/ajax.yaml +++ b/config/kbin_routes/ajax.yaml @@ -21,30 +21,40 @@ ajax_fetch_post_comments: defaults: { _format: json } path: /ajax/fetch_post_comments/{id} methods: [GET] + requirements: + id: \d+ ajax_fetch_entry: controller: App\Controller\AjaxController::fetchEntry defaults: { _format: json } path: /ajax/fetch_entry/{id} methods: [GET] + requirements: + id: \d+ ajax_fetch_entry_comment: controller: App\Controller\AjaxController::fetchEntryComment defaults: { _format: json } path: /ajax/fetch_entry_comment/{id} methods: [GET] + requirements: + id: \d+ ajax_fetch_post: controller: App\Controller\AjaxController::fetchPost defaults: { _format: json } path: /ajax/fetch_post/{id} methods: [GET] + requirements: + id: \d+ ajax_fetch_post_comment: controller: App\Controller\AjaxController::fetchPostComment defaults: { _format: json } path: /ajax/fetch_post_comment/{id} methods: [GET] + requirements: + id: \d+ ajax_fetch_online: controller: App\Controller\AjaxController::fetchOnline diff --git a/config/kbin_routes/entry.yaml b/config/kbin_routes/entry.yaml index c99f2eda3..ff7f63d03 100644 --- a/config/kbin_routes/entry.yaml +++ b/config/kbin_routes/entry.yaml @@ -3,73 +3,109 @@ entry_comment_create: defaults: { slug: -, parent_comment_id: null } path: /m/{magazine_name}/t/{entry_id}/{slug}/comment/create/{parent_comment_id} methods: [ GET, POST ] + requirements: + entry_id: \d+ + parent_comment_id: \d+ entry_comment_view: - controller: App\Controller\Entry\Comment\EntryCommentViewController - defaults: { slug: -, comment_id: null } - path: /m/{magazine_name}/t/{entry_id}/{slug}/comment/{comment_id} - methods: [ GET ] + controller: App\Controller\Entry\Comment\EntryCommentViewController + defaults: { slug: -, comment_id: null } + path: /m/{magazine_name}/t/{entry_id}/{slug}/comment/{comment_id} + methods: [ GET ] + requirements: + entry_id: \d+ + comment_id: \d+ entry_comment_edit: controller: App\Controller\Entry\Comment\EntryCommentEditController defaults: { slug: -, } path: /m/{magazine_name}/t/{entry_id}/{slug}/comment/{comment_id}/edit methods: [ GET, POST ] + requirements: + entry_id: \d+ + comment_id: \d+ entry_comment_delete: controller: App\Controller\Entry\Comment\EntryCommentDeleteController::delete defaults: { slug: -, } path: /m/{magazine_name}/t/{entry_id}/{slug}/comments/{comment_id}/delete methods: [ POST ] + requirements: + entry_id: \d+ + comment_id: \d+ entry_comment_restore: controller: App\Controller\Entry\Comment\EntryCommentDeleteController::restore defaults: { slug: -, } path: /m/{magazine_name}/t/{entry_id}/{slug}/comments/{comment_id}/restore methods: [ POST ] + requirements: + entry_id: \d+ + comment_id: \d+ entry_comment_purge: controller: App\Controller\Entry\Comment\EntryCommentDeleteController::purge defaults: { slug: -, } path: /m/{magazine_name}/t/{entry_id}/{slug}/comments/{comment_id}/purge methods: [ POST ] + requirements: + entry_id: \d+ + comment_id: \d+ entry_comment_change_lang: controller: App\Controller\Entry\Comment\EntryCommentChangeLangController defaults: { slug: - } path: /m/{magazine_name}/t/{entry_id}/{slug}/comments/{comment_id}/change_lang methods: [ POST ] + requirements: + entry_id: \d+ + comment_id: \d+ entry_comment_change_adult: controller: App\Controller\Entry\Comment\EntryCommentChangeAdultController defaults: { slug: - } path: /m/{magazine_name}/t/{entry_id}/{slug}/comments/{comment_id}/change_adult methods: [ POST ] + requirements: + entry_id: \d+ + comment_id: \d+ entry_comment_image_delete: controller: App\Controller\Entry\Comment\EntryCommentDeleteImageController defaults: { slug: -, } path: /m/{magazine_name}/t/{entry_id}/{slug}/comments/{comment_id}/delete_image methods: [ POST ] + requirements: + entry_id: \d+ + comment_id: \d+ entry_comment_voters: controller: App\Controller\Entry\Comment\EntryCommentVotersController defaults: { slug: -, } - requirements: { type: 'up' } path: /m/{magazine_name}/t/{entry_id}/{slug}/comment/{comment_id}/votes/{type} methods: [ GET ] + requirements: + type: 'up' + entry_id: \d+ + comment_id: \d+ entry_comment_favourites: controller: App\Controller\Entry\Comment\EntryCommentFavouriteController defaults: { slug: -, } path: /m/{magazine_name}/t/{entry_id}/{slug}/comment/{comment_id}/favourites methods: [ GET ] + requirements: + entry_id: \d+ + comment_id: \d+ entry_comment_moderate: controller: App\Controller\Entry\Comment\EntryCommentModerateController defaults: { slug: -, } path: /m/{magazine_name}/t/{entry_id}/{slug}/comment/{comment_id}/moderate methods: [ GET ] + requirements: + entry_id: \d+ + comment_id: \d+ entry_comments_front: controller: App\Controller\Entry\Comment\EntryCommentFrontController::front @@ -121,24 +157,32 @@ entry_comment_vote: defaults: { entityClass: App\Entity\EntryComment } path: /ecv/{id}/{choice} methods: [ POST ] + requirements: + id: \d+ entry_comment_report: controller: App\Controller\ReportController defaults: { entityClass: App\Entity\EntryComment } path: /ecr/{id} methods: [ GET, POST ] + requirements: + id: \d+ entry_comment_favourite: controller: App\Controller\FavouriteController defaults: { entityClass: App\Entity\EntryComment } path: /ecf/{id} methods: [ POST ] + requirements: + id: \d+ entry_comment_boost: controller: App\Controller\BoostController defaults: { entityClass: App\Entity\EntryComment } path: /ecb/{id} methods: [ POST ] + requirements: + id: \d+ entry_create: controller: App\Controller\Entry\EntryCreateController @@ -157,79 +201,105 @@ entry_edit: defaults: { slug: -, sortBy: hot } path: /m/{magazine_name}/t/{entry_id}/{slug}/edit methods: [ GET, POST ] + requirements: + entry_id: \d+ entry_moderate: controller: App\Controller\Entry\EntryModerateController defaults: { slug: -, sortBy: hot } path: /m/{magazine_name}/t/{entry_id}/{slug}/moderate methods: [ GET ] + requirements: + entry_id: \d+ entry_delete: controller: App\Controller\Entry\EntryDeleteController::delete defaults: { slug: -, sortBy: hot } path: /m/{magazine_name}/t/{entry_id}/{slug}/delete methods: [ POST ] + requirements: + entry_id: \d+ entry_restore: controller: App\Controller\Entry\EntryDeleteController::restore defaults: { slug: -, sortBy: hot } path: /m/{magazine_name}/t/{entry_id}/{slug}/restore methods: [ POST ] + requirements: + entry_id: \d+ entry_purge: controller: App\Controller\Entry\EntryDeleteController::purge defaults: { slug: -, sortBy: hot } path: /m/{magazine_name}/t/{entry_id}/{slug}/purge methods: [ POST ] + requirements: + entry_id: \d+ entry_image_delete: controller: App\Controller\Entry\EntryDeleteImageController defaults: { slug: -, } path: /m/{magazine_name}/e/{entry_id}/{slug}/delete_image methods: [ POST ] + requirements: + entry_id: \d+ entry_change_magazine: controller: App\Controller\Entry\EntryChangeMagazineController defaults: { slug: - } path: /m/{magazine_name}/e/{entry_id}/{slug}/change_magazine methods: [ POST ] + requirements: + entry_id: \d+ entry_change_lang: controller: App\Controller\Entry\EntryChangeLangController defaults: { slug: - } path: /m/{magazine_name}/e/{entry_id}/{slug}/change_lang methods: [ POST ] + requirements: + entry_id: \d+ entry_change_adult: controller: App\Controller\Entry\EntryChangeAdultController defaults: { slug: - } path: /m/{magazine_name}/e/{entry_id}/{slug}/change_adult methods: [ POST ] + requirements: + entry_id: \d+ entry_pin: controller: App\Controller\Entry\EntryPinController defaults: { slug: -, sortBy: hot } path: /m/{magazine_name}/t/{entry_id}/{slug}/pin methods: [ POST ] + requirements: + entry_id: \d+ entry_voters: controller: App\Controller\Entry\EntryVotersController defaults: { slug: -, sortBy: hot } - requirements: { type: 'up' } path: /m/{magazine_name}/t/{entry_id}/{slug}/votes/{type} methods: [ GET ] + requirements: + type: 'up' + entry_id: \d+ entry_fav: controller: App\Controller\Entry\EntryFavouriteController defaults: { slug: -, sortBy: hot } path: /m/{magazine_name}/t/{entry_id}/{slug}/favourites methods: [ GET ] + requirements: + entry_id: \d+ entry_tips: controller: App\Controller\Entry\EntryTipController defaults: { slug: -, sortBy: hot } path: /m/{magazine_name}/t/{entry_id}/{slug}/tips methods: [ GET ] + requirements: + entry_id: \d+ entry_single: controller: App\Controller\Entry\EntrySingleController @@ -238,6 +308,7 @@ entry_single: methods: [ GET ] requirements: sortBy: "%comment_sort_options%" + entry_id: \d+ entry_single_comments: controller: App\Controller\Entry\EntrySingleController @@ -246,27 +317,36 @@ entry_single_comments: methods: [ GET ] requirements: sortBy: "%comment_sort_options%" + entry_id: \d+ entry_vote: controller: App\Controller\VoteController defaults: { entityClass: App\Entity\Entry } path: /ev/{id}/{choice} methods: [ POST ] + requirements: + id: \d+ entry_report: controller: App\Controller\ReportController defaults: { entityClass: App\Entity\Entry } path: /er/{id} methods: [ GET, POST ] + requirements: + id: \d+ entry_favourite: controller: App\Controller\FavouriteController defaults: { entityClass: App\Entity\Entry } path: /ef/{id} methods: [ POST ] + requirements: + id: \d+ entry_boost: controller: App\Controller\BoostController defaults: { entityClass: App\Entity\Entry } path: /eb/{id} methods: [ POST ] + requirements: + id: \d+ diff --git a/config/kbin_routes/message.yaml b/config/kbin_routes/message.yaml index 447b4adf5..cc6bb1e36 100644 --- a/config/kbin_routes/message.yaml +++ b/config/kbin_routes/message.yaml @@ -7,6 +7,8 @@ messages_single: controller: App\Controller\Message\MessageThreadController path: /profile/messages/{id} methods: [ GET, POST ] + requirements: + id: \d+ messages_create: controller: App\Controller\Message\MessageCreateThreadController diff --git a/config/kbin_routes/post.yaml b/config/kbin_routes/post.yaml index e371ce2cc..64dc08392 100644 --- a/config/kbin_routes/post.yaml +++ b/config/kbin_routes/post.yaml @@ -3,108 +3,155 @@ post_comment_create: defaults: { slug: -, parent_comment_id: null } path: /m/{magazine_name}/p/{post_id}/{slug}/reply/{parent_comment_id} methods: [ GET, POST ] + requirements: + post_id: \d+ + parent_comment_id: \d+ post_comment_edit: controller: App\Controller\Post\Comment\PostCommentEditController defaults: { slug: -, } path: /m/{magazine_name}/p/{post_id}/{slug}/reply/{comment_id}/edit methods: [ GET, POST ] + requirements: + post_id: \d+ + comment_id: \d+ post_comment_moderate: controller: App\Controller\Post\Comment\PostCommentModerateController defaults: { slug: -, } path: /m/{magazine_name}/p/{post_id}/{slug}/reply/{comment_id}/moderate methods: [ GET, POST ] + requirements: + post_id: \d+ + comment_id: \d+ post_comment_delete: controller: App\Controller\Post\Comment\PostCommentDeleteController::delete defaults: { slug: -, } path: /m/{magazine_name}/p/{post_id}/{slug}/reply/{comment_id}/delete methods: [ POST ] + requirements: + post_id: \d+ + comment_id: \d+ post_comment_restore: controller: App\Controller\Post\Comment\PostCommentDeleteController::restore defaults: { slug: -, } path: /m/{magazine_name}/p/{post_id}/{slug}/reply/{comment_id}/restore methods: [ POST ] + requirements: + post_id: \d+ + comment_id: \d+ post_comment_purge: controller: App\Controller\Post\Comment\PostCommentDeleteController::purge defaults: { slug: -, } path: /m/{magazine_name}/p/{post_id}/{slug}/reply/{comment_id}/purge methods: [ POST ] + requirements: + post_id: \d+ + comment_id: \d+ post_comment_change_lang: controller: App\Controller\Post\Comment\PostCommentChangeLangController defaults: { slug: - } path: /m/{magazine_name}/p/{post_id}/{slug}/comments/{comment_id}/change_lang methods: [ POST ] + requirements: + post_id: \d+ + comment_id: \d+ post_comment_change_adult: controller: App\Controller\Post\Comment\PostCommentChangeAdultController defaults: { slug: - } path: /m/{magazine_name}/p/{post_id}/{slug}/comments/{comment_id}/change_adult methods: [ POST ] + requirements: + post_id: \d+ + comment_id: \d+ post_comment_image_delete: controller: App\Controller\Post\Comment\PostCommentDeleteImageController defaults: { slug: -, } path: /m/{magazine_name}/p/{post_id}/{slug}/reply/{comment_id}/delete_image methods: [ POST ] + requirements: + post_id: \d+ + comment_id: \d+ post_comment_voters: controller: App\Controller\Post\Comment\PostCommentVotersController defaults: { slug: -, } path: /m/{magazine_name}/p/{post_id}/{slug}/reply/{comment_id}/votes methods: [ GET ] + requirements: + post_id: \d+ + comment_id: \d+ post_comment_favourites: controller: App\Controller\Post\Comment\PostCommentFavouriteController defaults: { slug: -, } path: /m/{magazine_name}/p/{post_id}/{slug}/reply/{comment_id}/favourites methods: [ GET ] + requirements: + post_id: \d+ + comment_id: \d+ post_comment_vote: controller: App\Controller\VoteController defaults: { entityClass: App\Entity\PostComment } path: /pcv/{id}/{choice} methods: [ POST ] + requirements: + id: \d+ post_comment_report: controller: App\Controller\ReportController defaults: { entityClass: App\Entity\PostComment } path: /pcr/{id} methods: [ GET, POST ] + requirements: + id: \d+ post_comment_favourite: controller: App\Controller\FavouriteController defaults: { entityClass: App\Entity\PostComment } path: /pcf/{id} methods: [ POST ] + requirements: + id: \d+ post_comment_boost: controller: App\Controller\BoostController defaults: { entityClass: App\Entity\PostComment } path: /pcb/{id} methods: [ POST ] + requirements: + id: \d+ post_pin: controller: App\Controller\Post\PostPinController defaults: { slug: - } path: /m/{magazine_name}/p/{post_id}/{slug}/pin methods: [ POST ] + requirements: + post_id: \d+ post_voters: controller: App\Controller\Post\PostVotersController defaults: { slug: -, } path: /m/{magazine_name}/p/{post_id}/{slug}/votes methods: [ GET ] + requirements: + post_id: \d+ post_favourites: controller: App\Controller\Post\PostFavouriteController defaults: { slug: -, } path: /m/{magazine_name}/p/{post_id}/{slug}/favourites methods: [ GET ] + requirements: + post_id: \d+ post_create: controller: App\Controller\Post\PostCreateController @@ -116,54 +163,72 @@ post_edit: defaults: { slug: -, } path: /m/{magazine_name}/p/{post_id}/{slug}/edit methods: [ GET, POST ] + requirements: + post_id: \d+ post_moderate: controller: App\Controller\Post\PostModerateController defaults: { slug: -, } path: /m/{magazine_name}/p/{post_id}/{slug}/moderate methods: [ GET, POST ] + requirements: + post_id: \d+ post_delete: controller: App\Controller\Post\PostDeleteController::delete defaults: { slug: -, } path: /m/{magazine_name}/p/{post_id}/{slug}/delete methods: [ POST ] + requirements: + post_id: \d+ post_restore: controller: App\Controller\Post\PostDeleteController::restore defaults: { slug: -, } path: /m/{magazine_name}/p/{post_id}/{slug}/restore methods: [ POST ] + requirements: + post_id: \d+ post_purge: controller: App\Controller\Post\PostDeleteController::purge defaults: { slug: -, } path: /m/{magazine_name}/p/{post_id}/{slug}/purge methods: [ POST ] + requirements: + post_id: \d+ post_image_delete: controller: App\Controller\Post\PostDeleteImageController defaults: { slug: -, } path: /m/{magazine_name}/p/{post_id}/{slug}/delete_image methods: [ POST ] + requirements: + post_id: \d+ post_change_magazine: controller: App\Controller\Post\PostChangeMagazineController defaults: { slug: - } path: /m/{magazine_name}/p/{post_id}/{slug}/change_magazine methods: [ POST ] + requirements: + post_id: \d+ post_change_lang: controller: App\Controller\Post\PostChangeLangController defaults: { slug: - } path: /m/{magazine_name}/p/{post_id}/{slug}/change_lang methods: [ POST ] + requirements: + post_id: \d+ post_change_adult: controller: App\Controller\Post\PostChangeAdultController defaults: { slug: - } path: /m/{magazine_name}/p/{post_id}/{slug}/change_adult methods: [ POST ] + requirements: + post_id: \d+ post_single: controller: App\Controller\Post\PostSingleController @@ -172,27 +237,36 @@ post_single: methods: [ GET ] requirements: sortBy: "%comment_sort_options%" + post_id: \d+ post_vote: controller: App\Controller\VoteController defaults: { entityClass: App\Entity\Post } path: /pv/{id}/{choice} methods: [ POST ] + requirements: + id: \d+ post_report: controller: App\Controller\ReportController defaults: { entityClass: App\Entity\Post } path: /pr/{id} methods: [ GET, POST ] + requirements: + id: \d+ post_favourite: controller: App\Controller\FavouriteController defaults: { entityClass: App\Entity\Post } path: /pf/{id} methods: [ POST ] + requirements: + id: \d+ post_boost: controller: App\Controller\BoostController defaults: { entityClass: App\Entity\Post } path: /pb/{id} methods: [ POST ] + requirements: + id: \d+ From fc869140d4eb0939552ee1ef176f39b2d6b0ae3e Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Tue, 1 Oct 2024 17:42:48 +0200 Subject: [PATCH 293/335] Translations update from Hosted Weblate (#1151) Co-authored-by: veroandi --- translations/messages.pt_BR.yaml | 395 +++++++++++++++++++++++++++++++ 1 file changed, 395 insertions(+) diff --git a/translations/messages.pt_BR.yaml b/translations/messages.pt_BR.yaml index 1c9a53341..b072dd868 100644 --- a/translations/messages.pt_BR.yaml +++ b/translations/messages.pt_BR.yaml @@ -294,3 +294,398 @@ flash_mark_as_adult_success: A publicação foi marcada como NSFW. post: Publicação terms: Termos de Serviço people_local: Local +page_width_fixed: Fixo +magazine_posting_restricted_to_mods_warning: Somente os moderadores podem criar tópicos + nesta revista +flash_posting_restricted_error: Criar fios é restrito aos moderadores desta revista + e você não é um deles +magazine_log_mod_removed: removeu um moderador +magazine_log_mod_added: adicionou um moderador +down_votes: Reduz +register: Criar conta +agree_terms: Concordo com os %terms_link_start%Termos e Condições%terms_link_end% + e a %policy_link_start%Política de Privacidade%policy_link_end% +flash_thread_new_success: O tópico foi criado com sucesso e agora está visível para + outros usuários. +flash_thread_delete_success: O fio foi excluído com sucesso. +flash_thread_edit_success: O fio foi editado com sucesso. +flash_thread_pin_success: O fio foi fixado com sucesso. +flash_thread_unpin_success: O tópico foi desafixado com sucesso. +mod_log_alert: AVISO - O Modlog pode conter conteúdo desagradável ou perturbador que + foi removido pelos moderadores. Por favor, tenha cuidado. +banned: baniu você +show_top_bar: Mostrar barra superior +sticky_navbar: Barra de navegação fixa +federation: Federação +status: Status +sidebar_position: Posição da barra lateral +left: Esquerda +right: Direita +ban_hashtag_description: Ao banir uma hashtag, você impedirá a criação de publicações + com essa hashtag, além de ocultar as publicações existentes que a utilizam. +unban_hashtag_btn: Desbanir Hashtag +unban_hashtag_description: Ao desbanir uma hashtag, você poderá criar novamente publicações + com essa hashtag. As publicações existentes com essa hashtag não serão mais ocultadas. +filters: Filtros +add_moderator: Adicionar moderador +add_badge: Adicionar selo +change_magazine: Mudar a revista +change_language: Alterar idioma +mark_as_adult: Marcar como NSFW +users: Usuários +writing: Escrever +meta: Meta +contact_email: E-mail de contato +active_users: Pessoas ativas +related_magazines: Revistas relacionadas +random_magazines: Revistas aleatórias +kbin_intro_desc: é uma plataforma descentralizada para agregação de conteúdo e microblogging + que opera dentro da rede Fediverso. +kbin_promo_desc: '%link_start%Clone o repositório%link_end% e desenvolva o fediverso' +your_account_is_not_active: Sua conta não foi ativada. Verifique seu e-mail para obter + instruções de ativação da conta ousolicite um novo e-mail + de ativação da conta. +toolbar.code: Código +toolbar.bold: Negrito +toolbar.italic: Itálico +toolbar.header: Cabeçalho +toolbar.quote: Citação +toolbar.strikethrough: Tachado +federated_search_only_loggedin: Pesquisa federada limitada se você não estiver logado +federation_page_allowed_description: Instâncias conhecidas com as quais federamos +federation_page_disallowed_description: Instâncias com as quais não nos federamos +errors.server500.description: Desculpe, algo deu errado do nosso lado. Se você continuar + a ver esse erro, tente entrar em contato com o proprietário da instância. Se essa + instância não estiver funcionando, verifique enquanto isso %link_start%outras instâncias + do Mbin%link_end%, até que o problema seja resolvido. +errors.server500.title: 500 Erro interno do servidor +resend_account_activation_email_description: Digite o endereço de e-mail associado + à sua conta. Nós enviaremos outro e-mail de ativação para você. +custom_css: CSS personalizado +oauth.consent.to_allow_access: Para permitir esse acesso, clique no botão “Permitir” + abaixo +oauth.consent.allow: Permitir +oauth.consent.deny: Negar +oauth.consent.app_requesting_permissions: gostaria de realizar as seguintes ações + em seu nome +oauth.client_identifier.invalid: ID de cliente OAuth inválido! +block: Bloquear +oauth.consent.app_has_permissions: já pode executar as seguintes ações +oauth2.grant.admin.all: Execute ações administrativas na sua instância. +oauth2.grant.delete.general: Exclua qualquer um dos seus fios, publicações ou comentários. +oauth2.grant.write.general: Você pode criar ou editar qualquer um dos seus fios, publicações + ou comentários. +oauth2.grant.read.general: Leia todo o conteúdo ao qual você tem acesso. +oauth2.grant.entry.create: Criar novos fios. +oauth2.grant.entry.edit: Edite os fios existentes. +oauth2.grant.entry.all: Crie, edite ou exclua seus fios e vote, impulsione ou denuncie + qualquer um deles. +oauth2.grant.post.report: Denuncie qualquer publicação. +oauth2.grant.moderate.entry.set_adult: Marcar os fios como NSFW nas suas revistas + moderadas. +oauth2.grant.moderate.entry.trash: Jogar no lixo ou restaurar fios nas suas revistas + moderadas. +tags: Tags +articles: Fios +notify_on_new_post_reply: Qualquer nível de resposta a publicações de minha autoria +mod_remove_your_thread: Um moderador removeu o seu fio +purge: Purgar +instances: Instâncias +preview: Visualizar +random_entries: Fios aleatórios +federation_page_dead_title: Instâncias mortas +errors.server429.title: 429 Requisições em excesso +oauth2.grant.moderate.magazine.reports.all: Gerencie as denúncias de suas revistas + moderadas. +ignore_magazines_custom_css: Ignorar o CSS personalizado das revistas +oauth2.grant.moderate.magazine.reports.read: Leia as denúncias nas suas revistas moderadas. +oauth2.grant.moderate.magazine_admin.moderators: Adicione ou remova moderadores das + suas revistas. +oauth2.grant.report.general: Denunciar fios, publicações ou comentários. +oauth2.grant.moderate.magazine_admin.edit_theme: Edite o CSS personalizado das suas + revistas. +oauth2.grant.vote.general: Você pode votar a favor, contra ou impulsionar fios, publicações + ou comentários. +oauth2.grant.post.all: Crie, edite ou exclua seus microblogs e vote, impulsione ou + denuncie qualquer microblog. +oauth2.grant.magazine.block: Bloqueie ou desbloqueie revistas e veja as revistas que + você bloqueou. +oauth2.grant.user.message.read: Leia suas mensagens. +oauth2.grant.moderate.post.all: Moderar as publicações nas suas revistas moderadas. +approve: Aprovar +approved: Aprovado +rejected: Rejeitado +created: Criado +expires: Expira em +bans: Banimentos +months: Meses +content: Conteúdo +week: Semana +month: Mês +year: Ano +add_new_article: Adicionar novo fio +subscriptions: Assinaturas +notify_on_new_entry_comment_reply: Respostas aos meus comentários em qualquer fio +removed_comment_by: removeu um comentário de +restored_comment_by: restaurou o comentário de +removed_post_by: removeu um post de +restored_post_by: restaurou uma publicação de +he_banned: banir +he_unbanned: desbanir +set_magazines_bar_desc: adicionar os nomes da revista após a vírgula +added_new_thread: Novo fio adicionado +comment: Comentário +send_message: Enviar mensagem direta +message: Mensagem +infinite_scroll: Rolagem infinita +from_url: Do URL +upload_file: Fazer upload do arquivo +magazine_panel: Painel de revista +reject: Rejeitar +ban: Banir +add_ban: Adicionar banimento +unban: Desbanir +ban_hashtag_btn: Banir Hashtag +perm: Permanente +expired_at: Expirou em +change: Alterar +trash: Lixeira +icon: Ícone +done: Feito +pin: Fixar +unpin: Desafixar +unmark_as_adult: Desmarcar como NSFW +pinned: Fixado +article: Fio +reputation: Reputação +note: Nota +weeks: Semanas +federated: Federado +local: Local +admin_panel: Painel de administração +dashboard: Painel de controle +instance: Instância +pages: Páginas +toolbar.mention: Menção +email.delete.description: O usuário a seguir solicitou a exclusão de sua conta +resend_account_activation_email: Reenviar email de ativação da conta +unblock: Desbloquear +oauth2.grant.moderate.magazine.trash.read: Veja o conteúdo descartado em suas revistas + moderadas. +oauth2.grant.moderate.magazine_admin.all: Crie, edite ou exclua as revistas que você + possui. +oauth2.grant.user.profile.edit: Edite o seu perfil. +oauth2.grant.user.profile.read: Leia o seu perfil. +oauth2.grant.moderate.post.trash: Eliminar ou restaurar publicações nas suas revistas + moderadas. +oauth2.grant.moderate.post_comment.set_adult: Marcar comentários em publicações como + NSFW nas suas revistas moderadas. +continue_with: Continue com +account_deletion_button: Excluir conta +account_deletion_immediate: Excluir imediatamente +more_from_domain: Mais do domínio +federation_page_enabled: Página da federação ativada +errors.server404.title: 404 Não encontrado +toolbar.spoiler: Spoiler +sidebar_sections_local_only: Restringir as seções “X Aleatório” e “Pessoas Ativas” + somente em local +oauth2.grant.moderate.magazine.ban.delete: Desbanir usuários de suas revistas moderadas. +oauth2.grant.moderate.magazine_admin.delete: Exclua as revistas que você possui. +oauth2.grant.moderate.magazine_admin.update: Edite as regras, a descrição, o status + NSFW ou o ícone de qualquer uma das revistas que você possui. +oauth2.grant.admin.entry.purge: Exclua completamente qualquer fio de sua instância. +oauth2.grant.block.general: Bloqueie ou desbloqueie qualquer revista, domínio ou usuário + e veja quais foram bloqueados. +oauth2.grant.domain.all: Assine ou bloqueie domínios e visualize os domínios que você + assinou ou bloqueou. +oauth2.grant.domain.block: Bloqueie ou desbloqueie domínios e visualize os domínios + que você bloqueou. +oauth2.grant.entry.delete: Exclua os fios existentes. +oauth2.grant.entry.vote: Vote a favor, contra ou dê um impulso em qualquer fio. +oauth2.grant.entry.report: Denunciar qualquer fio. +oauth2.grant.entry_comment.create: Criar novos comentários nos fios. +oauth2.grant.entry_comment.edit: Edite seus comentários existentes nos fios. +oauth2.grant.entry_comment.delete: Exclua seus comentários existentes nos fios. +oauth2.grant.entry_comment.report: Denunciar comentário em um fio. +oauth2.grant.magazine.all: Assine ou bloqueie revistas e veja as revistas assinadas + ou bloqueadas. +oauth2.grant.post.create: Criar novas publicações. +oauth2.grant.post.edit: Edite suas publicações existentes. +oauth2.grant.post.delete: Exclua suas publicações existentes. +oauth2.grant.post.vote: Dê um voto positivo, negativo ou um impulso em uma publicação. +oauth2.grant.post_comment.all: Crie, edite ou exclua seus comentários nas publicações + e vote, impulsione ou denuncie qualquer comentário em uma publicação. +oauth2.grant.post_comment.create: Crie novos comentários nas publicações. +oauth2.grant.post_comment.edit: Edite seus comentários existentes em publicações. +oauth2.grant.post_comment.delete: Exclua seus comentários existentes em publicações. +oauth2.grant.user.message.all: Leia suas mensagens e envie mensagens para outros usuários. +oauth2.grant.user.message.create: Envie mensagens para outros usuários. +oauth2.grant.user.notification.all: Leia e limpe suas notificações. +oauth2.grant.user.notification.read: Leia suas notificações, inclusive as de mensagens. +oauth2.grant.user.notification.delete: Limpe suas notificações. +oauth2.grant.user.follow: Siga ou deixe de seguir usuários e veja uma lista dos usuários + que você segue. +oauth2.grant.user.block: Bloquear ou desbloquear usuários e ver a lista de usuários + bloqueados. +oauth2.grant.moderate.all: Execute ações de moderação para as quais você tem permissão + em suas revistas moderadas. +oauth2.grant.moderate.entry.pin: Fixar os tópicos na parte superior das revistas moderadas. +oauth2.grant.moderate.entry_comment.all: Moderar comentários em fios nas suas revistas + moderadas. +oauth2.grant.moderate.entry_comment.change_language: Altere o idioma dos comentários + nos fios das suas revistas moderadas. +oauth2.grant.moderate.post_comment.all: Moderar comentários nas publicações das suas + revistas moderadas. +show_related_posts: Mostrar publicações aleatórias +someone: Alguém +report_accepted: Uma denúncia foi aceita +related_entry: Relacionado +ban_expired: Banimento expirado +on: Em +off: Desligado +subject_reported: O conteúdo foi denunciado. +browsing_one_thread: Você está navegando apenas em um fio da discussão! Todos os comentários + estão disponíveis na página da publicação. +tag: Tag +eng: ENG +notify_on_new_entry: Novos fios (links ou artigos) em qualquer revista da qual eu + seja assinante +notify_on_new_entry_reply: Qualquer nível de comentários nos fios de minha autoria +removed_thread_by: removeu um fio de +restored_thread_by: restaurou um fio de +toolbar.ordered_list: Lista ordenada +errors.server403.title: 403 Proibido +resend_account_activation_email_question: Conta inativa? +resend_account_activation_email_error: Houve um problema ao enviar esta solicitação. + Talvez você não tenha uma conta associada a esse e-mail ou talvez ele já esteja + ativado. +resend_account_activation_email_success: Se você tiver uma conta associada a esse + e-mail, enviaremos um novo e-mail de ativação. +oauth2.grant.domain.subscribe: Assine ou cancele a assinatura de domínios e visualize + os domínios que você assinou. +related_tags: Tags relacionadas +oc: OC +oauth.consent.title: Formulário de Consentimento OAuth2 +private_instance: Forçar os usuários a fazer login antes de poderem acessar qualquer + conteúdo +oauth2.grant.moderate.magazine.reports.action: Aceite ou rejeite denúncias em suas + revistas moderadas. +oauth2.grant.moderate.magazine_admin.create: Criar novas revistas. +oauth2.grant.moderate.magazine_admin.badges: Crie ou remova selos das revistas que + você possui. +oauth2.grant.moderate.magazine_admin.stats: Veja o conteúdo, vote e veja as estatísticas + das revistas que você possui. +oauth2.grant.moderate.magazine_admin.tags: Crie ou remova tags das revistas que você + possui. +oauth2.grant.subscribe.general: Assine ou siga qualquer revista, domínio ou usuário + e veja em quais você se inscreveu. +oauth2.grant.entry_comment.all: Crie, edite ou exclua seus comentários nos fios e + vote, impulsione ou denuncie quaisquer comentários em um fio. +oauth2.grant.entry_comment.vote: Dê um voto positivo, negativo ou impulsione qualquer + comentário em um fio. +oauth2.grant.magazine.subscribe: Assine ou cancele a assinatura de revistas e veja + as revistas que você assinou. +oauth2.grant.post_comment.vote: Dê um voto positivo, negativo ou impulsione um comentário + em uma publicação. +oauth2.grant.user.oauth_clients.all: Leia e edite as permissões que você concedeu + a outros aplicativos OAuth2. +oauth2.grant.user.oauth_clients.read: Leia as permissões que você concedeu a outros + aplicativos OAuth2. +oauth2.grant.user.oauth_clients.edit: Edite as permissões que você concedeu a outros + aplicativos OAuth2. +oauth2.grant.moderate.entry.all: Moderar fios em suas revistas moderadas. +oauth2.grant.moderate.entry.change_language: Altere o idioma dos fios em suas revistas + moderadas. +page_width: Largura da página +page_width_max: Max +page_width_auto: Automático +oauth2.grant.moderate.entry_comment.trash: Eliminar ou restaurar comentários em fios + das suas revistas moderadas. +oauth2.grant.moderate.post.change_language: Altere o idioma das publicações das suas + revistas moderadas. +oauth2.grant.moderate.post.set_adult: Marcar as publicações como NSFW nas suas revistas + moderadas. +show_active_users: Mostrar usuários ativos +cake_day: Dia do bolo +oauth2.grant.moderate.post_comment.change_language: Alterar o idioma dos comentários + das publicações nas suas revistas moderadas. +own_content_reported_accepted: Uma denúncia do seu conteúdo foi aceita. +restrict_magazine_creation: Restringir a criação de revistas locais a administradores + e moderadores globais +report_subject: Assunto +own_report_accepted: Sua denúncia foi aceita +own_report_rejected: Uma denúncia foi rejeitada +direct_message: Mensagem direta +last_updated: Última atualização +magazine_log_entry_unpinned: removida a entrada fixada +email_confirm_button_text: Confirme seu pedido de alteração de senha +email_confirm_link_help: Como alternativa, você pode copiar e colar o que se segue + em seu navegador +email.delete.title: Pedido de exclusão da conta do usuário +oauth.consent.grant_permissions: Conceder Permissões +oauth.client_not_granted_message_read_permission: Este aplicativo não recebeu permissão + para ler suas mensagens. +restrict_oauth_clients: Restringir a criação de clientes OAuth2 a administradores +oauth2.grant.moderate.entry_comment.set_adult: Marcar comentários em fios como NSFW + nas suas revistas moderadas. +notification_title_new_report: Uma nova denúncia foi criada +server_software: Software do servidor +edit_entry: Editar fio +edited_thread: Editou um fio +and: e +show_related_magazines: Mostrar revistas aleatórias +related_entries: Fios relacionados +magazine_panel_tags_info: Preencha apenas se você quiser que o conteúdo do fediverso + seja incluído nesta revista com base em tags +add_mentions_entries: Adicionar tags de menção nos fios +add_mentions_posts: Adicionar tags de menção em publicações +your_account_has_been_banned: Sua conta foi banida +toolbar.link: Link +toolbar.image: Imagem +toolbar.unordered_list: Lista desordenada +boost: Dar Boost +tokyo_night: Noite em Tóquio +preferred_languages: Filtrar idiomas dos fios e publicações +filter.fields.label: Escolha os campos que você deseja pesquisar +bot_body_content: "Bem-vindo ao Agente Mbin! Esse Agente desempenha um papel crucial + na implementação do ActivityPub na Mbin. Ele garante que a Mbin possa se comunicar + e se federar com outras instâncias no fediverso.\n\nO ActivityPub é um protocolo + de padrão aberto que permite que plataformas descentralizadas de redes sociais se + comuniquem e interajam entre si. Ele permite que usuários em diferentes instâncias + (servidores) sigam, interajam e compartilhem conteúdo na rede social federada conhecida + como fediverso. Ele fornece uma maneira padronizada para que os usuários publiquem + conteúdo, sigam outros usuários e participem de interações sociais, como curtir, + compartilhar e comentar em fios ou publicações." +oauth2.grant.moderate.magazine.list: Leia uma lista de suas revistas moderadas. +account_deletion_title: Exclusão da conta +account_deletion_description: Sua conta será excluída em 30 dias, a menos que você + opte por excluir a conta imediatamente. Para restaurar sua conta dentro de 30 dias, + faça login com as mesmas credenciais de usuário ou entre em contato com um administrador. +federation_page_dead_description: Instâncias em que não conseguimos entregar pelo + menos 10 atividades seguidas e em que a última entrega bem-sucedida foi há mais + de uma semana +oauth2.grant.post_comment.report: Denuncie qualquer comentário em uma publicação. +oauth2.grant.user.all: Leia e edite seu perfil, mensagens ou notificações; Leia e + edite as permissões que você concedeu a outros aplicativos; siga ou bloqueie outros + usuários; visualize listas de usuários que você segue ou bloqueia. +oauth2.grant.user.profile.all: Leia e edite seu perfil. +unregister_push_notifications_button: Remover registro de push +register_push_notifications_button: Cadastre-se para notificações push +manually_approves_followers: Aprovar manualmente os seguidores +reported_user: Usuário denunciado +show_related_entries: Mostrar fios aleatórios +notification_title_edited_post: Uma publicação foi editada +notification_title_removed_post: Uma publicação foi removida +notification_title_new_post: Nova publicação +notification_title_message: Nova mensagem direta +notification_title_ban: Você foi banido +notification_title_edited_thread: Um fio foi editado +notification_title_removed_thread: Um fio foi removido +notification_title_new_thread: Novo fio +notification_title_new_reply: Nova resposta +notification_title_mention: Você foi mencionado +notification_title_edited_comment: Um comentário foi editado +notification_title_removed_comment: Um comentário foi removido +notification_title_new_comment: Novo comentário +test_push_message: Olá, mundo! +test_push_notifications_button: Teste as notificações por push From 27212bf7dbdac8a58e714895a05c39f37371f92c Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Wed, 2 Oct 2024 18:26:20 +0200 Subject: [PATCH 294/335] Increase the interval for fetch_user_notifications (#1152) --- assets/controllers/notifications_controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/controllers/notifications_controller.js b/assets/controllers/notifications_controller.js index 055519b8c..7cab7735d 100644 --- a/assets/controllers/notifications_controller.js +++ b/assets/controllers/notifications_controller.js @@ -116,7 +116,7 @@ export default class extends Controller { if (typeof data.messages === "number") { this.setMessageCount(data.messages) } - window.setTimeout(() => this.fetchAndSetNewNotificationAndMessageCount(), 10 * 1000) + window.setTimeout(() => this.fetchAndSetNewNotificationAndMessageCount(), 30 * 1000) }) } From 6f0d99a6165895a10edf0a84102b0ec7446ffe95 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Wed, 2 Oct 2024 21:26:41 +0200 Subject: [PATCH 295/335] Translations update from Hosted Weblate (#1154) Co-authored-by: veroandi --- translations/messages.pt_BR.yaml | 231 +++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) diff --git a/translations/messages.pt_BR.yaml b/translations/messages.pt_BR.yaml index b072dd868..9eb8a9759 100644 --- a/translations/messages.pt_BR.yaml +++ b/translations/messages.pt_BR.yaml @@ -689,3 +689,234 @@ notification_title_removed_comment: Um comentário foi removido notification_title_new_comment: Novo comentário test_push_message: Olá, mundo! test_push_notifications_button: Teste as notificações por push +flash_magazine_theme_changed_success: Atualizou com sucesso a aparência da revista. +open_url_to_fediverse: Abrir URL original +change_my_avatar: Modificar meu avatar +filter_labels: Filtrar Etiquetas +unsuspend_account: Cancelar a suspensão da conta +account_suspended: A conta foi suspensa. +account_unsuspended: A suspensão da conta foi cancelada. +deletion: Exclusão +cancel_request: Cancelar pedido +abandoned: Abandonado +ownership_requests: Solicitações de propriedade +sensitive_warning: Conteúdo sensível +sensitive_toggle: Alternar a visibilidade de conteúdo sensível +last_successful_deliver: Última entrega bem-sucedida +version: Versão +last_successful_receive: Última recepção bem-sucedida +last_failed_contact: Último contato que não deu certo +admin_users_inactive: Inativo +admin_users_active: Ativo +user_verify: Ativar conta +oauth2.grant.moderate.magazine.ban.create: Banir usuários nas suas revistas moderadas. +oauth2.grant.admin.entry_comment.purge: Exclua completamente um comentário em fios + da sua instância. +oauth2.grant.admin.post.purge: Excluir completamente qualquer publicação de sua instância. +oauth2.grant.moderate.magazine.ban.read: Visualizar usuários banidos em suas revistas + moderadas. +oauth2.grant.admin.user.ban: Banir ou desbanir usuários da sua instância. +oauth2.grant.admin.magazine.move_entry: Mover fios entre revistas da sua instância. +oauth2.grant.admin.magazine.purge: Excluir completamente revistas da sua instância. +oauth2.grant.admin.user.all: Banir, verificar ou excluir completamente os usuários + da sua instância. +oauth2.grant.admin.user.verify: Verificar usuários da sua instância. +oauth2.grant.admin.user.delete: Excluir usuários da sua instância. +comment_reply_position: Posição de resposta ao comentário +magazine_theme_appearance_custom_css: CSS personalizado que será aplicado quando você + visualizar o conteúdo da sua revista. +update_comment: Atualizar comentário +show_avatars_on_comments_help: Exibir/ocultar avatares de usuários ao visualizar comentários + em um único fio ou publicação. +moderation.report.ban_user_title: Banir Usuário +moderation.report.reject_report_confirmation: Você tem certeza de que deseja rejeitar + essa denúncia? +schedule_delete_account: Programar exclusão +schedule_delete_account_desc: Programar a exclusão dessa conta em 30 dias. Isso ocultará + o usuário e seu conteúdo, além de impedir que ele faça login. +2fa.code_invalid: O código de autenticação não é válido +cancel: Cancelar +2fa.enable: Configurar a autenticação de dois fatores +2fa.setup_error: Erro ao ativar a 2FA para a conta +magazine_is_deleted: A revista foi excluída. Você pode restaurá-la + dentro de 30 dias. +user_suspend_desc: Suspender sua conta oculta seu conteúdo na instância, mas não o + remove permanentemente, e você pode restaurá-la a qualquer momento. +remove_subscriptions: Remover assinaturas +remove_following: Remover seguidor +apply_for_moderator: Candidatar-se a moderador +deleted_by_moderator: O fio, a publicação ou o comentário foi excluído pelo moderador +announcement: Anúncio +keywords: Palavras-chave +delete_content: Excluir conteúdo +remove_schedule_delete_account: Remover a exclusão programada +two_factor_backup: Códigos de backup da autenticação de dois fatores +cards_view: Visualização dos cartões +oauth2.grant.admin.user.purge: Excluir completamente usuários da sua instância. +oauth2.grant.moderate.magazine.ban.all: Gerenciar usuários banidos em suas revistas + moderadas. +2fa.verify: Verificar +flash_email_failed_to_sent: O e-mail não pode ser enviado. +flash_user_edit_password_error: Não foi possível alterar a senha. +edit_my_profile: Editar meu perfil +hide: Ocultar +all_time: Todo o período +spoiler: Spoiler +oauth2.grant.moderate.magazine.all: Gerenciar banimentos, denúncias e visualizar itens + descartados em suas revistas moderadas. +oauth2.grant.admin.post_comment.purge: Excluir completamente uma publicação da sua + instância. +oauth2.grant.admin.instance.all: Visualizar e atualizar as configurações ou informações + da instância. +oauth2.grant.admin.instance.settings.all: Exibir ou atualizar as configurações da + sua instância. +oauth2.grant.admin.federation.read: Exibir a lista das instâncias desfederadas. +oauth2.grant.admin.oauth_clients.all: Visualizar ou revogar clientes OAuth2 que existem + em sua instância. +flash_post_pin_success: A publicação foi fixada com sucesso. +show_avatars_on_comments: Mostrar avatares de comentários +single_settings: Único +moderation.report.approve_report_confirmation: Você tem certeza de que deseja aprovar + esta denúncia? +subject_reported_exists: Esse conteúdo já foi denunciado. +oauth2.grant.moderate.post.pin: Fixe as publicações na parte superior de suas revistas + moderadas. +purge_content: Purgar conteúdo +delete_content_desc: Excluir o conteúdo do usuário, deixando as respostas de outros + usuários nos fios, publicações e comentários criados. +remove_schedule_delete_account_desc: Remover a exclusão programada. Todo o conteúdo + estará disponível novamente e o usuário poderá fazer login. +2fa.authentication_code.label: Código de Autenticação +2fa.disable: Desativar a autenticação de dois fatores +2fa.backup: Seus códigos de backup de dois fatores +2fa.backup-create.help: Você pode criar novos códigos de autenticação de backup; ao + fazer isso, os códigos existentes serão invalidados. +2fa.backup-create.label: Criar novos códigos de autenticação de backup +2fa.remove: Remover 2FA +2fa.verify_authentication_code.label: Inserir um código de dois fatores para verificar + a configuração +2fa.qr_code_link.title: Ao acessar este link, você permite que sua plataforma registre + essa autenticação de dois fatores +2fa.backup_codes.recommendation: Recomenda-se que você mantenha uma cópia deles em + um local seguro. +password_and_2fa: Senha e 2FA +show_subscriptions: Mostrar assinaturas +alphabetically: Por ordem alfabética +subscriptions_in_own_sidebar: Em uma barra lateral separada +sidebars_same_side: Barras laterais no mesmo lado +subscription_sidebar_pop_out_right: Mover para a barra lateral separada à direita +subscription_sidebar_pop_out_left: Mover para a barra lateral separada à esquerda +subscription_panel_large: Painel grande +subscription_header: Revistas Assinadas +close: Fechar +position_bottom: Inferior +flash_image_download_too_large_error: Não foi possível criar a imagem, pois ela é + muito grande (tamanho máximo %bytes%) +flash_post_new_error: Não foi possível criar a publicação. Algo deu errado. +flash_magazine_theme_changed_error: Não foi possível atualizar a aparência da revista. +flash_comment_new_success: O comentário foi criado com sucesso. +flash_comment_edit_success: O comentário foi atualizado com sucesso. +flash_comment_edit_error: Não foi possível editar o comentário. Algo deu errado. +flash_user_settings_general_error: Não foi possível salvar as configurações do usuário. +flash_user_edit_profile_error: Não foi possível salvar as configurações de perfil. +flash_user_edit_email_error: Não foi possível alterar o e-mail. +flash_thread_edit_error: Não foi possível editar o fio. Algo deu errado. +flash_post_edit_error: Não foi possível editar a publicação. +change_my_cover: Modificar minha capa +account_settings_changed: As configurações da sua conta foram alteradas com sucesso. + Você precisará fazer login novamente. +magazine_deletion: Exclusão da revista +restore_magazine: Restaurar revista +purge_magazine: Purgar revista +suspend_account: Suspender conta +account_banned: A conta foi banida. +account_unbanned: A conta foi desbanida. +account_is_suspended: A conta do usuário está suspensa. +request_magazine_ownership: Solicitar a propriedade da revista +action: Ação +user_badge_op: OP +user_badge_admin: Administrador +deleted_by_author: O fio, a publicação ou o comentário foi excluído pelo autor +sensitive_show: Clique para mostrar +sensitive_hide: Clique para ocultar +details: Detalhes +show: Exibir +edited: editado +sso_registrations_enabled.error: Novos registros de conta com gerenciadores de identidade + de terceiros estão desativados no momento. +sso_only_mode: Restringir o login e o registro apenas aos métodos de SSO +magazine_posting_restricted_to_mods: Restringir a criação de fios aos moderadores +new_user_description: Este usuário é novo (ativo há menos de %days% dias) +admin_users_suspended: Suspenso +admin_users_banned: Banido +max_image_size: Tamanho máximo do arquivo +cards: Cartões +oauth2.grant.moderate.post_comment.trash: Remover ou restaurar comentários de publicações + em suas revistas moderadas. +oauth2.grant.admin.magazine.all: Mover fios entre revistas ou excluí-las completamente + da sua instância. +oauth2.grant.admin.instance.stats: Veja as estatísticas da sua instância. +oauth2.grant.admin.federation.all: Exibir e atualizar instâncias atualmente desfederadas. +oauth2.grant.admin.federation.update: Adicionar ou remover instâncias de ou para a + lista de instâncias desfederadas. +oauth2.grant.admin.oauth_clients.read: Veja os clientes OAuth2 que existem em sua + instância e suas estatísticas de uso. +last_active: Última atividade +magazine_theme_appearance_icon: Ícone personalizado para a revista. Se você não selecionar + nenhum, será usado o ícone padrão. +purge_content_desc: Purgar completamente o conteúdo do usuário, incluindo excluir + as respostas de outros usuários em fios, publicações e comentários criados. +delete_account_desc: Excluir a conta, incluindo as respostas de outros usuários em + fios, publicações e comentários criados. +two_factor_authentication: Autenticação de dois fatores +2fa.add: Adicionar à minha conta +2fa.qr_code_img.alt: Um código QR que permite a configuração da autenticação de dois + fatores para sua conta +2fa.user_active_tfa.title: O usuário tem a 2FA ativada +2fa.available_apps: Use um aplicativo de autenticação de dois fatores, como %google_authenticator%, + %aegis% (Android) ou %raivo% (iOS) para fazer a leitura do código QR. +2fa.backup_codes.help: Você pode usar esses códigos quando não tiver seu dispositivo + ou aplicativo de autenticação de dois fatores. Você não os verá novamente + e poderá usar cada um deles apenas uma vez. +subscription_sort: Ordenar +flash_thread_tag_banned_error: Não foi possível criar o fio. O conteúdo não é permitido. +flash_email_was_sent: O email foi enviado com sucesso. +flash_post_new_success: A publicação foi criada com sucesso. +flash_comment_new_error: Não foi possível criar o comentário. Algo deu errado. +flash_user_edit_profile_success: As configurações do perfil do usuário foram salvas + com sucesso. +flash_post_edit_success: A publicação foi editada com sucesso. +auto: Automático +delete_magazine: Excluir revista +sso_show_first: Mostrar o SSO primeiro nas páginas de login e registro +new_magazine_description: Esta revista é nova (ativa há menos de %days% dias) +comment_not_found: Comentário não encontrado +oauth2.grant.admin.oauth_clients.revoke: Revogar o acesso a clientes OAuth2 na sua + instância. +flash_post_unpin_success: A publicação foi desafixada com sucesso. +oauth2.grant.admin.instance.settings.read: Exibir as configurações da sua instância. +oauth2.grant.admin.instance.settings.edit: Atualizar as configurações da sua instância. +oauth2.grant.admin.instance.information.edit: Atualizar as páginas Sobre, Perguntas + frequentes, Contato, Termos de serviço e Política de privacidade da sua instância. +magazine_theme_appearance_background_image: Imagem de fundo personalizada que será + aplicada quando você visualizar o conteúdo da sua revista. +moderation.report.approve_report_title: Aprovar a Denúncia +flash_user_settings_general_success: As configurações do usuário foram salvas com + sucesso. +accept: Aceitar +sso_registrations_enabled: Registros SSO ativados +back: Anterior +comment_reply_position_help: Exibir o formulário de resposta a comentários na parte + superior ou inferior da página. Quando a “rolagem infinita” estiver ativada, a posição + sempre aparecerá na parte superior. +moderation.report.reject_report_title: Rejeitar a Denúncia +moderation.report.ban_user_description: Você deseja banir o usuário (%username%) que + criou esse conteúdo desta revista? +subscription_sidebar_pop_in: Mover as assinaturas para o painel em linha +position_top: Topo +pending: Pendente +flash_account_settings_changed: As configurações da sua conta foram alteradas com + sucesso. Você precisará fazer login novamente. +flash_thread_new_error: Não foi possível criar o fio. Algo deu errado. +reported: denunciado +open_report: abrir denúncia From 185703d91f3d4493969310c8bca7742869eafd7f Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Wed, 2 Oct 2024 21:34:40 +0200 Subject: [PATCH 296/335] Adding Valkey to docs (#1153) --- docs/02-admin/01-installation/bare_metal.md | 12 ++++++------ docs/02-admin/02-configuration/redis.md | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/02-admin/01-installation/bare_metal.md b/docs/02-admin/01-installation/bare_metal.md index 5d2a2b2a2..92b4da153 100644 --- a/docs/02-admin/01-installation/bare_metal.md +++ b/docs/02-admin/01-installation/bare_metal.md @@ -157,9 +157,10 @@ The `.env` file holds a lot of environment variables and is the main point for c We suggest you place your variables in the `.env.local` file and have a 'clean' default one as the `.env` file. Each time this documentation talks about the `.env` file be sure to edit the `.env.local` file if you decided to use that. -> In all environments, the following files are loaded if they exist, the latter taking precedence over the former: -> - .env contains default values for the environment variables needed by the app -> - .env.local uncommitted file with local overrides +> In all environments, the following files are loaded if they exist, the latter taking precedence over the former: +> +> - .env contains default values for the environment variables needed by the app +> - .env.local uncommitted file with local overrides Make a copy of the `.env.example` to `.env` and `.env.local` and edit the `.env.local` file: @@ -325,10 +326,10 @@ composer clear-cache ### Caching -You can choose between either Redis or KeyDB. +You can choose between either Redis, Valkey or KeyDB. > [!TIP] -> More Redis/KeyDB fine-tuning settings can be found in the [Redis configuration guide](../02-configuration/redis.md). +> More Redis/Valkey/KeyDB fine-tuning settings can be found in the [Redis configuration guide](../02-configuration/redis.md). #### Redis @@ -544,7 +545,6 @@ Save and close the file. Note: you can increase the number of running messenger jobs if your queue is building up (i.e. more messages are coming in than your messengers can handle) - Save and close the file. Restart supervisor jobs: ```bash diff --git a/docs/02-admin/02-configuration/redis.md b/docs/02-admin/02-configuration/redis.md index 2950a51c6..9f01c284c 100644 --- a/docs/02-admin/02-configuration/redis.md +++ b/docs/02-admin/02-configuration/redis.md @@ -1,6 +1,6 @@ # Redis / KeyDB -This documentation is valid for both Redis as well as KeyDB. KeyDB is a fork of Redis, but should work mostly in the same manner. +This documentation is valid for both Redis as well as KeyDB and Valkey. Both Valkey and KeyDB are forks of Redis, but should work mostly in the same manner. ## Configure Redis @@ -29,7 +29,7 @@ Feel free to adjust the memory settings to your liking. ## Multithreading -Configure multiple threads in Redis by setting the following two lines: +Configure multiple threads in Redis/Valkey by setting the following two lines: ```ruby # THREADED I/O @@ -46,9 +46,9 @@ server-threads 4 ## Redis as a cache -_Optionally:_ If you are using this Redis instance only for Mbin as a cache, you can disable snapshots in Redis. Which will no longer dump the database to disk and reduce the amount of disk space used as well the disk I/O. +_Optionally:_ If you are using this Redis instance only for Mbin as a cache, you can disable snapshots in Redis/Valkey/KeyDB. Which will no longer dump the database to disk and reduce the amount of disk space used as well the disk I/O. -First comment out existing "save lines" in the Redis configuration file: +First comment out existing "save lines" in the Redis/Valkey/KeyDB configuration file: ```ruby #save 900 1 From a9d12dae0b974e283a9be9a9c3e74679401f9908 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Fri, 4 Oct 2024 11:25:03 +0200 Subject: [PATCH 297/335] Introducing dependabot for npm & composer (#1141) --- .github/dependabot.yml | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..4bd3a9a31 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,35 @@ +# Inspired by: https://github.com/dependabot/dependabot-core/blob/main/.github/dependabot.yml +# Please see the documentation for all configuration options: +# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file + +version: 2 +updates: + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "weekly" + day: "saturday" + time: "14:00" + groups: + dev-symfony-and-webpack-dependencies: + dependency-type: "development" + patterns: + - "@symfony/*" + - "webpack*" + dev-dependencies: + dependency-type: "development" + update-types: + - "minor" + - "patch" + - package-ecosystem: "composer" + directory: "/" + schedule: + interval: "weekly" + day: "saturday" + time: "14:00" + groups: + php: + applies-to: security-updates + update-types: + - "minor" + - "patch" From 5f5dd36dda09527661a8653ddf8da8d8ad7407d8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Oct 2024 11:28:48 +0200 Subject: [PATCH 298/335] Bump symfony/http-client from 7.1.4 to 7.1.5 (#1155) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 3a9da7d9d..b8c19d084 100644 --- a/composer.lock +++ b/composer.lock @@ -9349,16 +9349,16 @@ }, { "name": "symfony/http-client", - "version": "v7.1.4", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "a8f8d60b30b331cf4b743b3632e5acdba3f8285c" + "reference": "abca35865118edf35a23f2f24978a1784c831cb4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/a8f8d60b30b331cf4b743b3632e5acdba3f8285c", - "reference": "a8f8d60b30b331cf4b743b3632e5acdba3f8285c", + "url": "https://api.github.com/repos/symfony/http-client/zipball/abca35865118edf35a23f2f24978a1784c831cb4", + "reference": "abca35865118edf35a23f2f24978a1784c831cb4", "shasum": "" }, "require": { @@ -9423,7 +9423,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v7.1.4" + "source": "https://github.com/symfony/http-client/tree/v7.1.5" }, "funding": [ { @@ -9439,7 +9439,7 @@ "type": "tidelift" } ], - "time": "2024-08-26T06:32:37+00:00" + "time": "2024-09-20T13:35:23+00:00" }, { "name": "symfony/http-client-contracts", From 97aad2a0f6c90e99170a6f646ddf1ede4800efb9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Oct 2024 11:30:58 +0200 Subject: [PATCH 299/335] Bump symfony/uid from 7.1.4 to 7.1.5 (#1158) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Melroy van den Berg --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index b8c19d084..1a5fa72b4 100644 --- a/composer.lock +++ b/composer.lock @@ -13251,16 +13251,16 @@ }, { "name": "symfony/uid", - "version": "v7.1.4", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/uid.git", - "reference": "82177535395109075cdb45a70533aa3d7a521cdf" + "reference": "8c7bb8acb933964055215d89f9a9871df0239317" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/uid/zipball/82177535395109075cdb45a70533aa3d7a521cdf", - "reference": "82177535395109075cdb45a70533aa3d7a521cdf", + "url": "https://api.github.com/repos/symfony/uid/zipball/8c7bb8acb933964055215d89f9a9871df0239317", + "reference": "8c7bb8acb933964055215d89f9a9871df0239317", "shasum": "" }, "require": { @@ -13305,7 +13305,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/uid/tree/v7.1.4" + "source": "https://github.com/symfony/uid/tree/v7.1.5" }, "funding": [ { @@ -13321,7 +13321,7 @@ "type": "tidelift" } ], - "time": "2024-08-12T09:59:40+00:00" + "time": "2024-09-17T09:16:35+00:00" }, { "name": "symfony/ux-autocomplete", From fd00861f6ec33906bf1ccc9b2ea55068b4a20984 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Oct 2024 11:36:45 +0200 Subject: [PATCH 300/335] Bump symfony/translation from 7.1.3 to 7.1.5 (#1156) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 1a5fa72b4..333aa0faf 100644 --- a/composer.lock +++ b/composer.lock @@ -12804,16 +12804,16 @@ }, { "name": "symfony/translation", - "version": "v7.1.3", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "8d5e50c813ba2859a6dfc99a0765c550507934a1" + "reference": "235535e3f84f3dfbdbde0208ede6ca75c3a489ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/8d5e50c813ba2859a6dfc99a0765c550507934a1", - "reference": "8d5e50c813ba2859a6dfc99a0765c550507934a1", + "url": "https://api.github.com/repos/symfony/translation/zipball/235535e3f84f3dfbdbde0208ede6ca75c3a489ea", + "reference": "235535e3f84f3dfbdbde0208ede6ca75c3a489ea", "shasum": "" }, "require": { @@ -12878,7 +12878,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v7.1.3" + "source": "https://github.com/symfony/translation/tree/v7.1.5" }, "funding": [ { @@ -12894,7 +12894,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:41:01+00:00" + "time": "2024-09-16T06:30:38+00:00" }, { "name": "symfony/translation-contracts", From 6e38aefd0814e1569974fd61e6bbc713fe6fd22f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Oct 2024 09:38:44 +0000 Subject: [PATCH 301/335] Bump symfony/webpack-encore-bundle from 2.1.1 to 2.2.0 (#1159) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Melroy van den Berg --- composer.lock | 99 ++++++++++++++++++++++++++------------------------- 1 file changed, 50 insertions(+), 49 deletions(-) diff --git a/composer.lock b/composer.lock index 333aa0faf..86f0f093f 100644 --- a/composer.lock +++ b/composer.lock @@ -8214,16 +8214,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v7.1.4", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "5320e0bc2c9e2d7450bb4091e497a305a68b28ed" + "reference": "38465f925ec4e0707b090e9147c65869837d639d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/5320e0bc2c9e2d7450bb4091e497a305a68b28ed", - "reference": "5320e0bc2c9e2d7450bb4091e497a305a68b28ed", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/38465f925ec4e0707b090e9147c65869837d639d", + "reference": "38465f925ec4e0707b090e9147c65869837d639d", "shasum": "" }, "require": { @@ -8274,7 +8274,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v7.1.4" + "source": "https://github.com/symfony/dependency-injection/tree/v7.1.5" }, "funding": [ { @@ -8290,7 +8290,7 @@ "type": "tidelift" } ], - "time": "2024-08-29T08:16:25+00:00" + "time": "2024-09-20T08:28:38+00:00" }, { "name": "symfony/deprecation-contracts", @@ -8910,16 +8910,16 @@ }, { "name": "symfony/filesystem", - "version": "v7.1.2", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "92a91985250c251de9b947a14bb2c9390b1a562c" + "reference": "61fe0566189bf32e8cfee78335d8776f64a66f5a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/92a91985250c251de9b947a14bb2c9390b1a562c", - "reference": "92a91985250c251de9b947a14bb2c9390b1a562c", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/61fe0566189bf32e8cfee78335d8776f64a66f5a", + "reference": "61fe0566189bf32e8cfee78335d8776f64a66f5a", "shasum": "" }, "require": { @@ -8956,7 +8956,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.1.2" + "source": "https://github.com/symfony/filesystem/tree/v7.1.5" }, "funding": [ { @@ -8972,7 +8972,7 @@ "type": "tidelift" } ], - "time": "2024-06-28T10:03:55+00:00" + "time": "2024-09-17T09:16:35+00:00" }, { "name": "symfony/finder", @@ -9521,16 +9521,16 @@ }, { "name": "symfony/http-foundation", - "version": "v7.1.3", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "f602d5c17d1fa02f8019ace2687d9d136b7f4a1a" + "reference": "e30ef73b1e44eea7eb37ba69600a354e553f694b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/f602d5c17d1fa02f8019ace2687d9d136b7f4a1a", - "reference": "f602d5c17d1fa02f8019ace2687d9d136b7f4a1a", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e30ef73b1e44eea7eb37ba69600a354e553f694b", + "reference": "e30ef73b1e44eea7eb37ba69600a354e553f694b", "shasum": "" }, "require": { @@ -9578,7 +9578,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.1.3" + "source": "https://github.com/symfony/http-foundation/tree/v7.1.5" }, "funding": [ { @@ -9594,20 +9594,20 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:41:01+00:00" + "time": "2024-09-20T08:28:38+00:00" }, { "name": "symfony/http-kernel", - "version": "v7.1.4", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "6efcbd1b3f444f631c386504fc83eeca25963747" + "reference": "44204d96150a9df1fc57601ec933d23fefc2d65b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/6efcbd1b3f444f631c386504fc83eeca25963747", - "reference": "6efcbd1b3f444f631c386504fc83eeca25963747", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/44204d96150a9df1fc57601ec933d23fefc2d65b", + "reference": "44204d96150a9df1fc57601ec933d23fefc2d65b", "shasum": "" }, "require": { @@ -9692,7 +9692,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v7.1.4" + "source": "https://github.com/symfony/http-kernel/tree/v7.1.5" }, "funding": [ { @@ -9708,7 +9708,7 @@ "type": "tidelift" } ], - "time": "2024-08-30T17:02:28+00:00" + "time": "2024-09-21T06:09:21+00:00" }, { "name": "symfony/intl", @@ -10278,16 +10278,16 @@ }, { "name": "symfony/mime", - "version": "v7.1.4", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "ccaa6c2503db867f472a587291e764d6a1e58758" + "reference": "711d2e167e8ce65b05aea6b258c449671cdd38ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/ccaa6c2503db867f472a587291e764d6a1e58758", - "reference": "ccaa6c2503db867f472a587291e764d6a1e58758", + "url": "https://api.github.com/repos/symfony/mime/zipball/711d2e167e8ce65b05aea6b258c449671cdd38ff", + "reference": "711d2e167e8ce65b05aea6b258c449671cdd38ff", "shasum": "" }, "require": { @@ -10342,7 +10342,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v7.1.4" + "source": "https://github.com/symfony/mime/tree/v7.1.5" }, "funding": [ { @@ -10358,7 +10358,7 @@ "type": "tidelift" } ], - "time": "2024-08-13T14:28:19+00:00" + "time": "2024-09-20T08:28:38+00:00" }, { "name": "symfony/monolog-bridge", @@ -11377,16 +11377,16 @@ }, { "name": "symfony/process", - "version": "v7.1.3", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "7f2f542c668ad6c313dc4a5e9c3321f733197eca" + "reference": "5c03ee6369281177f07f7c68252a280beccba847" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/7f2f542c668ad6c313dc4a5e9c3321f733197eca", - "reference": "7f2f542c668ad6c313dc4a5e9c3321f733197eca", + "url": "https://api.github.com/repos/symfony/process/zipball/5c03ee6369281177f07f7c68252a280beccba847", + "reference": "5c03ee6369281177f07f7c68252a280beccba847", "shasum": "" }, "require": { @@ -11418,7 +11418,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.1.3" + "source": "https://github.com/symfony/process/tree/v7.1.5" }, "funding": [ { @@ -11434,7 +11434,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:44:47+00:00" + "time": "2024-09-19T21:48:23+00:00" }, { "name": "symfony/property-access", @@ -13678,16 +13678,16 @@ }, { "name": "symfony/var-dumper", - "version": "v7.1.4", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "a5fa7481b199090964d6fd5dab6294d5a870c7aa" + "reference": "e20e03889539fd4e4211e14d2179226c513c010d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/a5fa7481b199090964d6fd5dab6294d5a870c7aa", - "reference": "a5fa7481b199090964d6fd5dab6294d5a870c7aa", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/e20e03889539fd4e4211e14d2179226c513c010d", + "reference": "e20e03889539fd4e4211e14d2179226c513c010d", "shasum": "" }, "require": { @@ -13741,7 +13741,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.1.4" + "source": "https://github.com/symfony/var-dumper/tree/v7.1.5" }, "funding": [ { @@ -13757,7 +13757,7 @@ "type": "tidelift" } ], - "time": "2024-08-30T16:12:47+00:00" + "time": "2024-09-16T10:07:02+00:00" }, { "name": "symfony/var-exporter", @@ -13920,16 +13920,16 @@ }, { "name": "symfony/webpack-encore-bundle", - "version": "v2.1.1", + "version": "v2.2.0", "source": { "type": "git", "url": "https://github.com/symfony/webpack-encore-bundle.git", - "reference": "75cb918df3f65e28cf0d4bc03042bc45ccb19dd0" + "reference": "e335394b68a775a9b2bd173a8ba4fd2001f3870c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/webpack-encore-bundle/zipball/75cb918df3f65e28cf0d4bc03042bc45ccb19dd0", - "reference": "75cb918df3f65e28cf0d4bc03042bc45ccb19dd0", + "url": "https://api.github.com/repos/symfony/webpack-encore-bundle/zipball/e335394b68a775a9b2bd173a8ba4fd2001f3870c", + "reference": "e335394b68a775a9b2bd173a8ba4fd2001f3870c", "shasum": "" }, "require": { @@ -13942,6 +13942,7 @@ }, "require-dev": { "symfony/framework-bundle": "^5.4 || ^6.2 || ^7.0", + "symfony/http-client": "^5.4 || ^6.2 || ^7.0", "symfony/phpunit-bridge": "^5.4 || ^6.2 || ^7.0", "symfony/twig-bundle": "^5.4 || ^6.2 || ^7.0", "symfony/web-link": "^5.4 || ^6.2 || ^7.0" @@ -13968,10 +13969,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Integration with your Symfony app & Webpack Encore!", + "description": "Integration of your Symfony app with Webpack Encore", "support": { "issues": "https://github.com/symfony/webpack-encore-bundle/issues", - "source": "https://github.com/symfony/webpack-encore-bundle/tree/v2.1.1" + "source": "https://github.com/symfony/webpack-encore-bundle/tree/v2.2.0" }, "funding": [ { @@ -13987,7 +13988,7 @@ "type": "tidelift" } ], - "time": "2023-10-22T18:53:08+00:00" + "time": "2024-10-02T07:27:19+00:00" }, { "name": "symfony/workflow", From 96584b97d7dda6f9362f478d45054c594f869b00 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Sun, 6 Oct 2024 16:11:27 +0200 Subject: [PATCH 302/335] Translations update from Hosted Weblate (#1160) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Λευτέρης Τ Co-authored-by: ssantos --- translations/messages.el.yaml | 16 + translations/messages.pt.yaml | 529 +++++++++++++++++++++++++++++++--- 2 files changed, 499 insertions(+), 46 deletions(-) diff --git a/translations/messages.el.yaml b/translations/messages.el.yaml index f0f60e7d2..6cf975bbf 100644 --- a/translations/messages.el.yaml +++ b/translations/messages.el.yaml @@ -621,3 +621,19 @@ oauth2.grant.user.oauth_clients.edit: Επεξεργάσου τα δικαιώμ σε άλλες εφαρμογές OAuth2. oauth2.grant.user.follow: Ακολούθησε ή αφαίρεσε από ακόλουθο χρήστες και διάβασε μια λίστα χρηστών που ακολουθείς. +oauth2.grant.moderate.entry.all: Συντόνισε τα νήματα στα περιοδικά που συντονίζεις. +oauth2.grant.moderate.entry.change_language: Άλλαξε τη γλώσσα των νημάτων στα περιοδικά + που συντονίζεις. +oauth2.grant.moderate.all: Εκτέλεσε οποιαδήποτε ενέργεια συντονισμού που έχετε την + άδεια να εκτελέσετε στα περιοδικά που συντονίζεις. +oauth2.grant.user.block: Αποκλεισμός ή άρση αποκλεισμού χρήστη και δες την λίστα χρηστών + που έχεις αποκλείσει. +oauth2.grant.moderate.entry.pin: Καρφίτσωσε νήματα στην κορυφή των περιοδικών που + συντονίζεις. +oauth2.grant.moderate.entry.set_adult: Επισήμανση νημάτων ως NSFW στα περιοδικά που + συντονίζεις. +oauth2.grant.moderate.entry.trash: Απόρριψε ή ανάκτησε νήματα στα περιοδικά που συντονίζεις. +oauth2.grant.moderate.entry_comment.all: Συντόνισε τα σχόλια σε νήματα στα περιοδικά + που συντονίζεις. +oauth2.grant.moderate.entry_comment.change_language: Άλλαξε τη γλώσσα των σχολίων + σε νήματα στα περιοδικά που συντονίζεις. diff --git a/translations/messages.pt.yaml b/translations/messages.pt.yaml index eabfb804f..2a15977b1 100644 --- a/translations/messages.pt.yaml +++ b/translations/messages.pt.yaml @@ -109,12 +109,12 @@ cards_view: Vista de cartão 1m: 1m links: Links articles: Artigos -1w: 1s +1w: 1sem photos: Fotos videos: Videos report: Reportar share: Partilhar -copy_url_to_fediverse: Copiar url para o Fediverso +copy_url_to_fediverse: Copiar URL original share_on_fediverse: Partilhar no Fediverso edit: Editar are_you_sure: Tem a certeza? @@ -122,7 +122,7 @@ moderate: Moderar reason: Motivo delete: Apagar edit_post: Editar postagem -edit_comment: Editar comentário +edit_comment: Gravar alterações settings: Definições general: Geral profile: Perfil @@ -135,11 +135,11 @@ hide_adult: Esconder conteúdo NSFW featured_magazines: Magazines em destaque privacy: Privacidade show_profile_followings: Mostrar utilizadores seguidos -notify_on_new_entry_reply: Notificar-me de comentários nos meus tópicos -notify_on_new_post_reply: Notificar-me de respostas às minhas postagens -notify_on_new_post_comment_reply: Notificar-me de respostas aos meus comentários em - postagens -notify_on_new_entry: Notificar-me de novos tópicos em magazines subscritos +notify_on_new_entry_reply: Qualquer nível de comentários nos fios da minha autoria +notify_on_new_post_reply: Qualquer nível de resposta a publicações da minha autoria +notify_on_new_post_comment_reply: Respostas aos meus comentários em qualquer publicação +notify_on_new_entry: Novos fios (ligações ou artigos) em qualquer revista da qual + seja assinante save: Guardar about: Sobre old_email: Email atual @@ -167,11 +167,11 @@ no: Não show_magazines_icons: Mostrar os ícones das magazines show_thumbnails: Mostrar miniaturas rounded_edges: Cantos redondos -removed_thread_by: removeu tópico por -removed_comment_by: removeu tópico por +removed_thread_by: removeu um fio de +removed_comment_by: removeu um comentário de restored_comment_by: restaurou comentário por -removed_post_by: removeu a postagem por -restored_post_by: restaurou postagem por +removed_post_by: removeu um post de +restored_post_by: restaurou uma publicação de he_banned: banir he_unbanned: desbanir read_all: Ler tudo @@ -194,9 +194,9 @@ comment: Comentário post: Postagem ban_expired: O ban expirou purge: Limpar -send_message: Enviar mensagem +send_message: Enviar mensagem direta message: Mensagem -infinite_scroll: Scroll infinito +infinite_scroll: Rolagem infinita show_top_bar: Mostrar barra do topo subject_reported: O conteúdo foi reportado. sidebar_position: Posição da barra lateral @@ -219,7 +219,7 @@ add_badge: Adicionar distintivo bans: Expulsões created: Criado expires: Expira -perm: Perm +perm: Permanente expired_at: Expirou em add_ban: Adicionar expulsão trash: Lixo @@ -231,7 +231,7 @@ change_language: Alterar idioma change: Alterar pinned: Fixado preview: Previsualizar -article: Artigo +article: Fio reputation: Reputação note: Nota users: Utilizadores @@ -251,7 +251,7 @@ pages: Páginas FAQ: FAQ type_search_term: Introduza termo de pesquisa federation_enabled: Federação ativada -registrations_enabled: Registos ativados +registrations_enabled: Registo ativado registration_disabled: Registos desativados restore: Restaurar type.smart_contract: Contrato inteligente @@ -260,21 +260,22 @@ agree_terms: Consentimento dos %terms_link_start%Termos e Condições%terms_link e %policy_link_start%Política de Privacidade%policy_link_end% check_email: Verifique o seu email comments_count: '{0}Comentários|{1}Comentário|]1,Inf[ Comentários' -reset_check_email_desc: Se uma conta com o seu email existir, então um email será - enviado com um link para redefinir a sua password. Este link irá expirar em %expire%. +reset_check_email_desc: Se já houver uma conta associada ao seu endereço de e-mail, + deverá receber um e-mail em breve contendo uma ligação que poderá ser usada para + redefinir a sua palavra-passe. Esta ligação expirará em %expire%. replies: Respostas markdown_howto: Como funciona o editor? email_confirm_expire: O link expira em uma hora. -federated_magazine_info: A magazine do servidor federado pode estar incompleta. +federated_magazine_info: Esta revista é de um servidor federado e pode estar incompleta. remember_me: Lembrar-me username: Username table_view: Vista de tabela -edited_post: Editada uma postagem +edited_post: Editou uma publicação 12h: 12h deleted: Apagado pelo autor 1y: 1a -mod_log_alert: No Modlog pode encontrar conteúdo removido drasticamente por moderadores. - Por favor saiba o que está a fazer. +mod_log_alert: AVISO - O Modlog pode conter conteúdo desagradável ou perturbador que + foi removido pelos moderadores. Por favor, tenha cuidado. sticky_navbar: Barra de navegação fixa copy_url: Copiar url de Mbin off: Desligado @@ -283,13 +284,12 @@ appearance: Aparência done: Feito show_profile_subscriptions: Mostrar subscrições de magazines writing: Escrita -notify_on_new_entry_comment_reply: Notificar-me de respostas ao meus comentários em - tópicos +notify_on_new_entry_comment_reply: Respostas aos meus comentários em qualquer fio admin_panel: Painel de administração -notify_on_new_posts: Notificar-me de novas postagens numa magazine subscrita +notify_on_new_posts: Novas publicações de qualquer revista a que estou inscrito theme: Tema show_users_avatars: Mostrar os avatars dos utilizadores -restored_thread_by: restaurou tópico por +restored_thread_by: restaurou um fio de add_new: Adicionar novo url: URL title: Título @@ -320,17 +320,18 @@ reputation_points: Pontos de reputação related_tags: Etiquetas relacionadas go_to_content: Ir para o conteúdo go_to_filters: Ir para os filtros -flash_thread_new_success: O tópico foi criado corretamente e agora está visível a - outros usuários. -flash_thread_edit_success: O tópico foi editado corretamente. -flash_thread_delete_success: O tópico foi removido corretamente. -flash_thread_unpin_success: O tópico foi desafixado corretamente. -flash_register_success: Bem-vindo, sua conta foi criada. Último passo! - Busque no - seu e-mail pelo link de ativação que ativará a sua conta. -flash_thread_pin_success: O tópico foi fixado corretamente. -flash_magazine_new_success: A magazine foi criada corretamente. Agora você pode adicionar - novos conteúdos ou explorar o painel de administração da magazine. -flash_magazine_edit_success: A magazine foi editada corretamente. +flash_thread_new_success: O tópico foi criado com sucesso e agora está visível para + outros utilizadores. +flash_thread_edit_success: O fio foi editado com sucesso. +flash_thread_delete_success: O fio foi apagado com sucesso. +flash_thread_unpin_success: O tópico foi desafixado com sucesso. +flash_register_success: 'Bem-vindo a bordo! A sua conta já está registada. Uma última + etapa: verifique a sua caixa de entrada para receber uma ligação de ativação que + dará vida à sua conta.' +flash_thread_pin_success: O fio foi fixado com sucesso. +flash_magazine_new_success: A revista foi criada com sucesso. Pode adicionar novo + conteúdo ou explorar o painel de administração da revista. +flash_magazine_edit_success: A revista foi editada com sucesso. too_many_requests: Limite excedido, por favor tente novamente mais tarde. set_magazines_bar: Barra de magazines set_magazines_bar_desc: adicione os nomes dos magazines após a virgula @@ -430,12 +431,12 @@ private_instance: Forçar os usuários a fazer login antes de poderem acessar qu oauth2.grant.moderate.magazine.list: Leia uma lista de suas revistas moderadas. oauth2.grant.moderate.magazine.reports.all: Gerencie denúncias nas suas revistas moderadas. oauth2.grant.moderate.magazine_admin.all: Crie, edite ou exclua suas próprias revistas. -oauth2.grant.moderate.magazine.reports.read: Leia denúncias nas suas revistas moderadas. +oauth2.grant.moderate.magazine.reports.read: Leia as denúncias nas suas revistas moderadas. oauth2.grant.moderate.magazine.trash.read: Veja o conteúdo descartado em suas revistas moderadas. oauth2.grant.moderate.magazine_admin.create: Crie novas revistas. -oauth2.grant.moderate.magazine_admin.edit_theme: Edite o CSS personalizado de qualquer - uma de suas revistas. +oauth2.grant.moderate.magazine_admin.edit_theme: Edite o CSS personalizado das suas + revistas. oauth2.grant.subscribe.general: Assine ou siga qualquer revista, domínio ou usuário e veja as revistas, domínios e usuários nos quais você se inscreveu. oauth2.grant.moderate.magazine_admin.update: Edite as regras, a descrição, o status @@ -452,7 +453,7 @@ oauth.consent.app_has_permissions: já pode executar as seguintes ações oauth.client_not_granted_message_read_permission: Este aplicativo não recebeu permissão para ler suas mensagens. restrict_oauth_clients: Restringir a criação de clientes OAuth2 aos administradores -oauth2.grant.moderate.magazine.reports.action: Aceite ou rejeite denúncias em suas +oauth2.grant.moderate.magazine.reports.action: Aceite ou rejeite denúncias nas suas revistas moderadas. oauth2.grant.admin.all: Execute ações administrativas em sua instância. oauth2.grant.read.general: Leia todo o conteúdo ao qual você tem acesso. @@ -465,11 +466,447 @@ oauth2.grant.block.general: Bloqueie ou desbloqueie qualquer revista, domínio o e visualize as revistas, os domínios e os usuários que você bloqueou. comment_not_found: Comentário não encontrado oauth.consent.deny: Recusar -oauth2.grant.moderate.magazine_admin.moderators: Adicionar ou remover moderadores - de qualquer uma de suas revistas. -oauth2.grant.moderate.magazine_admin.badges: Crie ou remova selos de suas revistas - próprias. +oauth2.grant.moderate.magazine_admin.moderators: Adicione ou remova moderadores das + suas revistas. +oauth2.grant.moderate.magazine_admin.badges: Crie ou remova selos das revistas que + possui. disconnected_magazine_info: Esta revista não está recebendo atualizações (última atividade %dias% dia(s) atrás). resend_account_activation_email_question: Conta inativa? oauth.consent.grant_permissions: Conceder permissões +account_banned: A conta foi banida. +flash_image_download_too_large_error: Não foi possível criar a imagem, pois ela é + muito grande (tamanho máximo %bytes%) +flash_comment_edit_error: Não foi possível editar o comentário. Algo deu errado. +flash_user_settings_general_success: As configurações do utilizador foram gravadas + com sucesso. +flash_user_settings_general_error: Não foi possível gravar as configurações do utilizador. +flash_user_edit_profile_error: Não foi possível gravar as configurações de perfil. +announcement: Anúncio +magazine_log_entry_unpinned: a entrada fixada foi removida +manually_approves_followers: Aprovar manualmente os seguidores +user_verify: Ativar conta +random_entries: Fios aleatórios +random_magazines: Revistas aleatórias +oauth2.grant.user.block: Bloquear ou desbloquear utilizadores e ver a lista de utilizadores + bloqueados. +oauth2.grant.moderate.entry_comment.set_adult: Marcar comentários em fios como NSFW + nas suas revistas moderadas. +oauth2.grant.moderate.magazine.ban.read: Visualizar utilizadores banidos nas suas + revistas moderadas. +oauth2.grant.admin.instance.information.edit: Atualizar as páginas Sobre, Perguntas + frequentes, Contato, Termos de serviço e Política de privacidade da sua instância. +magazine_theme_appearance_custom_css: CSS personalizado que será aplicado quando visualizar + o conteúdo da sua revista. +2fa.backup_codes.recommendation: Recomenda-se que mantenha uma cópia deles num local + seguro. +subscription_sidebar_pop_out_left: Mover para a barra lateral separada à esquerda +subscription_sidebar_pop_in: Mover as assinaturas para o painel em linha +flash_comment_new_success: O comentário foi criado com sucesso. +page_width_fixed: Fixo +deletion: Apagar +direct_message: Mensagem direta +tag: Tag +unban: Desbanir +ban_hashtag_btn: Banir Hashtag +auto_preview: Visualização automática de mídia +oauth2.grant.user.notification.all: Leia e limpe as suas notificações. +oauth2.grant.moderate.magazine.ban.all: Gerir utilizadores banidos nas suas revistas + moderadas. +oauth2.grant.moderate.magazine.ban.create: Banir utilizadores nas suas revistas moderadas. +oauth2.grant.admin.entry_comment.purge: Apagar completamente um comentário em fios + da sua instância. +2fa.qr_code_img.alt: Um código QR que permite a configuração da autenticação de dois + fatores para a sua conta +2fa.qr_code_link.title: Ao aceder esta ligação, permite que a sua plataforma registe + esta autenticação de dois fatores +2fa.user_active_tfa.title: O utilizador tem a 2FA ativada +2fa.backup_codes.help: Pode usar estes códigos quando não tiver o seu dispositivo + ou aplicação de autenticação de dois fatores. Não os verá novamente + e poderá usar cada um deles apenas uma vez. +magazine_log_mod_removed: removeu um moderador +edit_entry: Editar fio +default_theme_auto: Claro/escuro (Detecção Automática) +preferred_languages: Filtrar idiomas dos fios e publicações +oauth2.grant.user.oauth_clients.read: Leia as permissões que concedeu a outras aplicações + do OAuth2. +oauth2.grant.moderate.post.trash: Eliminar ou restaurar publicações nas suas revistas + moderadas. +2fa.authentication_code.label: Código de Autenticação +2fa.backup-create.help: Pode criar códigos de autenticação de backup; ao fazer isso, + os códigos existentes serão invalidados. +flash_account_settings_changed: As configurações da sua conta foram alteradas com + sucesso. Precisará fazer login novamente. +subscription_sort: Ordenar +pending: Pendente +deleted_by_moderator: O fio, a publicação ou o comentário foi apagado pelo moderador +register_push_notifications_button: Cadastre-se para notificações push +tokyo_night: Noite em Tóquio +federation_page_enabled: Página da federação ativada +oauth2.grant.magazine.subscribe: Assine ou cancele a assinatura de revistas e veja + as revistas que assinou. +oauth2.grant.post.vote: Dê um voto positivo, negativo ou um impulso numa publicação. +oauth2.grant.user.message.all: Leia as suas mensagens e envie mensagens para outros + utilizadores. +oauth2.grant.user.message.read: Leia as suas mensagens. +delete_content_desc: Apagar o conteúdo do utilizador, deixando as respostas de outros + utilizadores nos fios, publicações e comentários criados. +action: Ação +solarized_auto: Solarizado (Detecção Automática) +kbin_promo_desc: '%link_start%Clone o repositório%link_end% e desenvolva o fediverso' +filter.origin.label: Escolha a origem +filter.fields.label: Escolha os campos que deseja pesquisar +filter.adult.label: Escolha se deseja exibir NSFW +your_account_is_not_active: A sua conta não foi ativada. Verifique o seu e-mail para + obter instruções de ativação da conta ousolicite um novo + e-mail de ativação da conta. +toolbar.quote: Citação +toolbar.code: Código +toolbar.link: Ligação +toolbar.image: Imagem +oauth2.grant.entry.create: Criar fios. +oauth2.grant.post.all: Crie, edite ou apague os seus microblogs e vote, impulsione + ou denuncie qualquer microblog. +moderation.report.approve_report_title: Aprovar a Denúncia +moderation.report.reject_report_title: Rejeitar a Denúncia +moderation.report.reject_report_confirmation: Tem certeza de que deseja rejeitar essa + denúncia? +show_subscriptions: Mostrar assinaturas +flash_post_new_success: A publicação foi criada com sucesso. +purge_magazine: Purgar revista +suspend_account: Suspender conta +unsuspend_account: Cancelar a suspensão da conta +accept: Aceitar +sso_registrations_enabled.error: Novos registos de conta com gestores de identidade + de terceiros estão desativados no momento. +sso_only_mode: Restringir o login e o registo apenas aos métodos de SSO +related_entry: Relacionado +continue_with: Continue com +two_factor_authentication: Autenticação de dois fatores +oauth2.grant.moderate.magazine_admin.tags: Crie ou remova tags das revistas que possui. +oauth2.grant.entry.all: Crie, edite ou apague os seus fios e vote, impulsione ou denuncie + qualquer um deles. +oauth2.grant.entry_comment.edit: Edite os seus comentários existentes nos fios. +oauth2.grant.post.delete: Apague as suas publicações existentes. +oauth2.grant.user.profile.all: Leia e edite o seu perfil. +2fa.verify_authentication_code.label: Inserir um código de dois fatores para verificar + a configuração +password_and_2fa: Palavra-passe e 2FA +subscriptions_in_own_sidebar: Numa barra lateral separada +sidebars_same_side: Barras laterais no mesmo lado +subscription_sidebar_pop_out_right: Mover para a barra lateral separada à direita +subscription_panel_large: Painel grande +restore_magazine: Restaurar revista +account_unsuspended: A suspensão da conta foi cancelada. +account_unbanned: A conta foi desbanida. +account_is_suspended: A conta do utilizador está suspensa. +remove_following: Remover seguidor +apply_for_moderator: Candidatar-se a moderador +abandoned: Abandonado +ownership_requests: Solicitações de propriedade +related_magazines: Revistas relacionadas +boost: Dar Boost +mercure_enabled: Mercure ativado +errors.server500.title: 500 Erro interno do servidor +oauth2.grant.vote.general: Pode votar a favor, contra ou impulsionar fios, publicações + ou comentários. +oauth2.grant.entry.report: Denunciar qualquer fio. +oauth2.grant.entry_comment.delete: Apague os seus comentários existentes nos fios. +oauth2.grant.entry_comment.vote: Dê um voto positivo, negativo ou impulsione qualquer + comentário num fio. +oauth2.grant.post.create: Criar publicações. +oauth2.grant.post_comment.delete: Apague os seus comentários existentes em publicações. +oauth2.grant.moderate.post_comment.all: Moderar comentários nas publicações das suas + revistas moderadas. +oauth2.grant.admin.instance.stats: Veja as estatísticas da sua instância. +flash_post_unpin_success: A publicação foi desafixada com sucesso. +oauth2.grant.moderate.post.pin: Fixe as publicações na parte superior das suas revistas + moderadas. +delete_content: Apagar conteúdo +purge_content_desc: Purgar completamente o conteúdo do utilizador, incluindo apagar + as respostas de outros utilizadores em fios, publicações e comentários criados. +2fa.verify: Verificar +2fa.code_invalid: O código de autenticação não é válido +flash_email_was_sent: O email foi enviado com sucesso. +flash_user_edit_password_error: Não foi possível alterar a palavra-passe. +change_my_avatar: Modificar o meu avatar +change_my_cover: Modificar a minha capa +oauth2.grant.admin.entry.purge: Apagar completamente qualquer fio da sua instância. +oauth2.grant.entry_comment.report: Denunciar comentário num fio. +oauth2.grant.magazine.all: Assine ou bloqueie revistas e veja as revistas assinadas + ou bloqueadas. +oauth2.grant.post.edit: Edite as suas publicações existentes. +oauth2.grant.post.report: Denuncie qualquer publicação. +oauth2.grant.admin.user.ban: Banir ou desbanir utilizadores da sua instância. +oauth2.grant.admin.instance.all: Visualizar e atualizar as configurações ou informações + da instância. +oauth2.grant.admin.instance.settings.all: Exibir ou atualizar as configurações da + sua instância. +oauth2.grant.admin.oauth_clients.all: Visualizar ou revogar clientes OAuth2 que existem + na sua instância. +request_magazine_ownership: Solicitar a propriedade da revista +hide: Ocultar +sensitive_warning: Conteúdo sensível +show: Exibir +oauth2.grant.write.general: Pode criar ou editar qualquer um dos seus fios, publicações + ou comentários. +oauth2.grant.delete.general: Apague qualquer um dos seus fios, publicações ou comentários. +oauth2.grant.report.general: Denunciar fios, publicações ou comentários. +oauth2.grant.moderate.entry.trash: Deitar no lixo ou restaurar fios nas suas revistas + moderadas. +report_accepted: Uma denúncia foi aceita +kbin_intro_desc: é uma plataforma descentralizada para agregação de conteúdo e microblogging + que opera dentro da rede Fediverso. +auto_preview_help: Expanda automaticamente as pré-visualizações de mídia. +oauth2.grant.entry_comment.create: Criar comentários nos fios. +bot_body_content: "Bem-vindo ao Agente Mbin! Este Agente desempenha um papel crucial + na implementação do ActivityPub na Mbin. Ele garante que a Mbin possa comunicar + e se federar com outras instâncias no fediverso.\n\nO ActivityPub é um protocolo + de padrão aberto que permite que plataformas descentralizadas de redes sociais comuniquem + e interajam entre si. Ele permite que utilizadores em diferentes instâncias (servidores) + sigam, interajam e partilhem conteúdo na rede social federada conhecida como fediverso. + Ele fornece uma maneira padronizada para que os utilizadores publiquem conteúdo, + sigam outros utilizadores e participem de interações sociais, como curtir, partilhar + e comentar em fios ou publicações." +toolbar.spoiler: Spoiler +federated_search_only_loggedin: Pesquisa federada limitada se não estiver logado +sidebar_sections_local_only: Restringir as secções “X Aleatório” e “Pessoas Ativas” + somente em local +account_deletion_title: Apagar contas +account_deletion_immediate: Apagar imediatamente +more_from_domain: Mais do domínio +oauth2.grant.entry.vote: Vote a favor, contra ou dê um impulso em qualquer fio. +oauth2.grant.entry_comment.all: Crie, edite ou apague os seus comentários nos fios + e vote, impulsione ou denuncie quaisquer comentários num fio. +oauth2.grant.post_comment.all: Crie, edite ou apague os seus comentários nas publicações + e vote, impulsione ou denuncie qualquer comentário numa publicação. +oauth2.grant.post_comment.create: Crie novos comentários nas publicações. +oauth2.grant.post_comment.report: Denuncie qualquer comentário numa publicação. +oauth2.grant.user.profile.read: Leia o seu perfil. +oauth2.grant.user.profile.edit: Edite o seu perfil. +oauth2.grant.user.notification.read: Leia as suas notificações, inclusive as de mensagens. +oauth2.grant.user.notification.delete: Limpe as suas notificações. +oauth2.grant.moderate.entry.all: Moderar fios nas suas revistas moderadas. +oauth2.grant.moderate.entry.change_language: Altere o idioma dos fios nas suas revistas + moderadas. +oauth2.grant.moderate.entry.pin: Fixar os tópicos na parte superior das revistas moderadas. +oauth2.grant.moderate.entry_comment.change_language: Altere o idioma dos comentários + nos fios das suas revistas moderadas. +oauth2.grant.user.oauth_clients.all: Leia e edite as permissões que concedeu a outras + aplicatções do OAuth2. +oauth2.grant.user.oauth_clients.edit: Edite as permissões que concedeu a outras aplicações + do OAuth2. +oauth2.grant.moderate.all: Execute ações de moderação para as quais tem permissão + nas suas revistas moderadas. +oauth2.grant.moderate.entry_comment.trash: Eliminar ou restaurar comentários em fios + das suas revistas moderadas. +oauth2.grant.moderate.post.all: Moderar as publicações nas suas revistas moderadas. +oauth2.grant.moderate.post.change_language: Altere o idioma das publicações das suas + revistas moderadas. +oauth2.grant.moderate.post.set_adult: Marcar as publicações como NSFW nas suas revistas + moderadas. +oauth2.grant.moderate.post_comment.change_language: Alterar o idioma dos comentários + das publicações nas suas revistas moderadas. +oauth2.grant.moderate.post_comment.set_adult: Marcar comentários em publicações como + NSFW nas suas revistas moderadas. +oauth2.grant.moderate.post_comment.trash: Remover ou restaurar comentários de publicações + nas suas revistas moderadas. +oauth2.grant.admin.post.purge: Apagar completamente qualquer publicação da sua instância. +oauth2.grant.admin.post_comment.purge: Apagar completamente uma publicação da sua + instância. +oauth2.grant.admin.magazine.all: Mover fios entre revistas ou apagá-las completamente + da sua instância. +oauth2.grant.admin.user.verify: Verificar utilizadores da sua instância. +oauth2.grant.admin.user.delete: Apagar utilizadores da sua instância. +oauth2.grant.admin.oauth_clients.read: Veja os clientes OAuth2 que existem na sua + instância e as suas estatísticas de uso. +oauth2.grant.admin.oauth_clients.revoke: Revogar o acesso a clientes OAuth2 na sua + instância. +last_active: Última atividade +flash_post_pin_success: A publicação foi fixada com sucesso. +comment_reply_position_help: Exibir o formulário de resposta a comentários na parte + superior ou inferior da página. Quando a “rolagem infinita” estiver ativada, a posição + sempre aparecerá na parte superior. +show_avatars_on_comments: Mostrar avatares de comentários +show_avatars_on_comments_help: Exibir/ocultar avatares de utilizadores ao visualizar + comentários num único fio ou publicação. +magazine_theme_appearance_background_image: Imagem de fundo personalizada que será + aplicada quando visualizar o conteúdo da sua revista. +subject_reported_exists: Este conteúdo já foi denunciado. +delete_account_desc: Apagar a conta, incluindo as respostas de outros utilizadores + em fios, publicações e comentários criados. +schedule_delete_account: Programar o apagar +schedule_delete_account_desc: Programar o apagar desta conta em 30 dias. Isto ocultará + o utilizador e o seu conteúdo, além de impedir que ele faça login. +remove_schedule_delete_account: Remover o apagar programado +remove_schedule_delete_account_desc: Remover o apagar programado. Todo o conteúdo + estará disponível novamente e o utilizador poderá fazer login. +two_factor_backup: Códigos de backup da autenticação de dois fatores +2fa.setup_error: Erro ao ativar a 2FA para a conta +2fa.enable: Configurar a autenticação de dois fatores +2fa.disable: Desativar a autenticação de dois fatores +2fa.backup-create.label: Criar códigos de autenticação de backup +2fa.add: Adicionar à minha conta +2fa.available_apps: Use uma aplicação de autenticação de dois fatores, como %google_authenticator%, + %aegis% (Android) ou %raivo% (iOS) para fazer a leitura do código QR. +flash_thread_new_error: Não foi possível criar o fio. Algo deu errado. +flash_thread_tag_banned_error: Não foi possível criar o fio. O conteúdo não é permitido. +flash_post_new_error: Não foi possível criar a publicação. Algo deu errado. +flash_magazine_theme_changed_success: Atualizou com sucesso a aparência da revista. +flash_magazine_theme_changed_error: Não foi possível atualizar a aparência da revista. +flash_comment_edit_success: O comentário foi atualizado com sucesso. +flash_comment_new_error: Não foi possível criar o comentário. Algo deu errado. +flash_user_edit_profile_success: As configurações do perfil do utilizador foram gravadas + com sucesso. +flash_post_edit_success: A publicação foi editada com sucesso. +page_width: Largura da página +edit_my_profile: Editar o meu perfil +keywords: Palavras-chave +deleted_by_author: O fio, a publicação ou o comentário foi apagado pelo autor +sensitive_show: Clique para mostrar +details: Pormenores +spoiler: Spoiler +all_time: Todo o período +edited: editado +restrict_magazine_creation: Restringir a criação de revistas locais a administradores + e moderadores globais +magazine_log_mod_added: adicionou um moderador +last_updated: Última atualização +unregister_push_notifications_button: Remover registo de push +test_push_notifications_button: Teste as notificações por push +notification_title_removed_post: Uma publicação foi removida +notification_title_edited_post: Uma publicação foi editada +notification_title_new_report: Uma nova denúncia foi criada +version: Versão +last_successful_deliver: Última entrega bem-sucedida +last_successful_receive: Última receção bem-sucedida +last_failed_contact: Último contato que não deu certo +magazine_posting_restricted_to_mods: Restringir a criação de fios aos moderadores +max_image_size: Tamanho máximo do ficheiro +federation_page_dead_title: Instâncias mortas +federation_page_dead_description: Instâncias em que não conseguimos entregar pelo + menos 10 atividades seguidas e em que a última entrega bem-sucedida foi há mais + que uma semana +open_url_to_fediverse: Abrir URL original +delete_magazine: Apagar revista +magazine_is_deleted: A revista foi apagada. Pode restaurá-la + dentro de 30 dias. +account_suspended: A conta foi suspensa. +oauth2.grant.moderate.magazine.all: Gerir banimentos, denúncias e visualizar elementos + descartados nas suas revistas moderadas. +oauth2.grant.admin.magazine.move_entry: Mover fios entre revistas da sua instância. +oauth2.grant.admin.user.all: Banir, verificar ou apagar completamente os utilizadores + da sua instância. +oauth2.grant.admin.magazine.purge: Apagar completamente revistas da sua instância. +oauth2.grant.admin.user.purge: Apagar completamente utilizadores da sua instância. +oauth2.grant.admin.instance.settings.read: Exibir as configurações da sua instância. +update_comment: Atualizar comentário +magazine_theme_appearance_icon: Ícone personalizado para a revista. Se não selecionar + nenhum, o ícone padrão será usado. +moderation.report.ban_user_description: Deseja banir o utilizador (%username%) que + criou este conteúdo desta revista? +moderation.report.approve_report_confirmation: Tem certeza de que deseja aprovar esta + denúncia? +alphabetically: Por ordem alfabética +flash_email_failed_to_sent: O e-mail não pode ser enviado. +page_width_auto: Automático +filter_labels: Filtrar Etiquetas +auto: Automático +page_width_max: Max +account_settings_changed: As configurações da sua conta foram alteradas com sucesso. + Precisará fazer login novamente. +magazine_deletion: Apagar a revista +sensitive_hide: Clique para ocultar +oauth2.grant.user.message.create: Envie mensagens para outros utilizadores. +oauth2.grant.admin.instance.settings.edit: Atualizar as configurações da sua instância. +oauth2.grant.admin.federation.all: Exibir e atualizar instâncias atualmente desfederadas. +oauth2.grant.admin.federation.read: Exibir a lista das instâncias desfederadas. +oauth2.grant.admin.federation.update: Adicionar ou remover instâncias de ou para a + lista de instâncias desfederadas. +moderation.report.ban_user_title: Banir Utilizador +purge_content: Purgar conteúdo +2fa.remove: Remover 2FA +cancel: Cancelar +sensitive_toggle: Alternar a visibilidade de conteúdo sensível +flash_posting_restricted_error: Criar fios é restrito aos moderadores desta revista + e não é um deles +magazine_posting_restricted_to_mods_warning: Somente os moderadores podem criar tópicos + nesta revista +server_software: Software do servidor +purge_account: Purgar conta +close: Fechar +flash_thread_edit_error: Não foi possível editar o fio. Algo deu errado. +oauth2.grant.moderate.magazine_admin.stats: Veja o conteúdo, vote e veja as estatísticas + das revistas que possui. +oauth2.grant.entry.edit: Edite os fios existentes. +oauth2.grant.entry.delete: Apague os fios existentes. +oauth2.grant.post_comment.edit: Edite os seus comentários existentes em publicações. +oauth2.grant.post_comment.vote: Dê um voto positivo, negativo ou impulsione um comentário + numa publicação. +oauth2.grant.user.all: Leia e edite o seu perfil, mensagens ou notificações; Leia + e edite as permissões que concedeu a outras apps; siga ou bloqueie outros utilizadores; + visualize listas de utilizadores que segue ou bloqueia. +oauth2.grant.user.follow: Siga ou deixe de seguir utilizadores e veja uma lista dos + utilizadores que segue. +cancel_request: Cancelar pedido +user_suspend_desc: Suspender a sua conta oculta o seu conteúdo na instância, mas não + o remove permanentemente e pode restaurá-la a qualquer momento. +remove_subscriptions: Remover assinaturas +subscription_header: Revistas Assinadas +position_bottom: Inferior +position_top: Topo +and: e +show_related_magazines: Mostrar revistas aleatórias +show_related_entries: Mostrar fios aleatórios +show_related_posts: Mostrar publicações aleatórias +show_active_users: Mostrar utilizadores ativos +add_mentions_posts: Adicionar tags de menção em publicações +related_entries: Fios relacionados +local_and_federated: Local e federado +add_mentions_entries: Adicionar tags de menção nos fios +toolbar.unordered_list: Lista desordenada +toolbar.ordered_list: Lista ordenada +toolbar.mention: Menção +federation_page_allowed_description: Instâncias conhecidas com as quais federamos +federation_page_disallowed_description: Instâncias com as quais não nos federamos +account_deletion_description: A sua conta será apagada em 30 dias, a menos que opte + por apagar a conta imediatamente. Para restaurar a sua conta dentro de 30 dias, + faça login com as mesmas credenciais de utilizador ou entre em contato com um administrador. +oauth2.grant.magazine.block: Bloqueie ou desbloqueie revistas e veja as revistas que + bloqueou. +oauth2.grant.moderate.entry.set_adult: Marcar os fios como NSFW nas suas revistas + moderadas. +oauth2.grant.moderate.entry_comment.all: Moderar comentários em fios nas suas revistas + moderadas. +flash_user_edit_email_error: Não foi possível alterar o e-mail. +flash_post_edit_error: Não foi possível editar a publicação. +user_badge_admin: Administrador +sso_registrations_enabled: Registos SSO ativados +sso_show_first: Mostrar o SSO primeiro nas páginas de login e registo +reported_user: Utilizador denunciado +reported: denunciado +report_subject: Assunto +own_report_rejected: Uma denúncia foi rejeitada +own_report_accepted: A sua denúncia foi aceita +own_content_reported_accepted: Uma denúncia do seu conteúdo foi aceita. +cake_day: Dia do bolo +someone: Alguém +back: Anterior +test_push_message: Olá, mundo! +notification_title_new_comment: Novo comentário +notification_title_removed_comment: Um comentário foi removido +notification_title_edited_comment: Um comentário foi editado +notification_title_mention: Foi mencionado +notification_title_new_reply: Nova resposta +notification_title_new_thread: Novo fio +notification_title_removed_thread: Um fio foi removido +notification_title_edited_thread: Um fio foi editado +notification_title_ban: Foi banido +notification_title_message: Nova mensagem direta +notification_title_new_post: Nova publicação +new_user_description: Este utilizador é novo (ativo há menos que %days% dias) +new_magazine_description: Esta revista é nova (ativa há menos que %days% dias) +admin_users_active: Ativo +admin_users_inactive: Inativo +admin_users_suspended: Suspenso +admin_users_banned: Banido From 4231f425adb271869a3f4e8d4e639dc091cea5ac Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Sun, 6 Oct 2024 17:29:08 +0200 Subject: [PATCH 303/335] Fix the docker build error due to an old symfon/cache version (#1165) --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 86f0f093f..6c13f56ad 100644 --- a/composer.lock +++ b/composer.lock @@ -7734,16 +7734,16 @@ }, { "name": "symfony/cache", - "version": "v7.1.4", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "b61e464d7687bb7e8f677d5031c632bf3820df18" + "reference": "86e5296b10e4dec8c8441056ca606aedb8a3be0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/b61e464d7687bb7e8f677d5031c632bf3820df18", - "reference": "b61e464d7687bb7e8f677d5031c632bf3820df18", + "url": "https://api.github.com/repos/symfony/cache/zipball/86e5296b10e4dec8c8441056ca606aedb8a3be0a", + "reference": "86e5296b10e4dec8c8441056ca606aedb8a3be0a", "shasum": "" }, "require": { @@ -7811,7 +7811,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v7.1.4" + "source": "https://github.com/symfony/cache/tree/v7.1.5" }, "funding": [ { @@ -7827,7 +7827,7 @@ "type": "tidelift" } ], - "time": "2024-08-12T09:59:40+00:00" + "time": "2024-09-17T09:16:35+00:00" }, { "name": "symfony/cache-contracts", From 4c5e5a92ddafe1fd1e0ac0c94b9153b006e953fd Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Mon, 7 Oct 2024 12:03:04 +0200 Subject: [PATCH 304/335] Make the body not required while editing (#1168) --- src/Form/EntryEditType.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Form/EntryEditType.php b/src/Form/EntryEditType.php index c331eed00..e641f922a 100644 --- a/src/Form/EntryEditType.php +++ b/src/Form/EntryEditType.php @@ -37,7 +37,9 @@ public function buildForm(FormBuilderInterface $builder, array $options): void $builder ->add('url', UrlType::class, ['required' => false]) ->add('title', TextareaType::class) - ->add('body', TextareaType::class) + ->add('body', TextareaType::class, [ + 'required' => false, + ]) ->add('magazine', MagazineAutocompleteType::class) ->add('tags', TextType::class, [ 'required' => false, From aabdd74a2e674516e3a6ae2adbc18cc0a5834a00 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Mon, 7 Oct 2024 14:22:46 +0200 Subject: [PATCH 305/335] Fix wrong title showing while editing a thread (#1169) --- templates/entry/edit_entry.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/entry/edit_entry.html.twig b/templates/entry/edit_entry.html.twig index c274bf8c2..8ef11af74 100644 --- a/templates/entry/edit_entry.html.twig +++ b/templates/entry/edit_entry.html.twig @@ -1,7 +1,7 @@ {% extends 'base.html.twig' %} {%- block title -%} - {{- 'edit_article'|trans }} - {{ parent() -}} + {{- 'edit_entry'|trans }} - {{ parent() -}} {%- endblock -%} {% block mainClass %}page-entry-create page-entry-edit-article{% endblock %} From fedb739e7b0797b497068ba555347eb97b784db0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 16:13:18 +0000 Subject: [PATCH 306/335] Bump phpunit/phpunit from 11.3.6 to 11.4.0 (#1162) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Melroy van den Berg --- composer.lock | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/composer.lock b/composer.lock index 6c13f56ad..f421cd337 100644 --- a/composer.lock +++ b/composer.lock @@ -15737,16 +15737,16 @@ }, { "name": "nikic/php-parser", - "version": "v5.2.0", + "version": "v5.3.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "23c79fbbfb725fb92af9bcf41065c8e9a0d49ddb" + "reference": "3abf7425cd284141dc5d8d14a9ee444de3345d1a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/23c79fbbfb725fb92af9bcf41065c8e9a0d49ddb", - "reference": "23c79fbbfb725fb92af9bcf41065c8e9a0d49ddb", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/3abf7425cd284141dc5d8d14a9ee444de3345d1a", + "reference": "3abf7425cd284141dc5d8d14a9ee444de3345d1a", "shasum": "" }, "require": { @@ -15789,9 +15789,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.2.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.3.0" }, - "time": "2024-09-15T16:40:33+00:00" + "time": "2024-09-29T13:56:26+00:00" }, { "name": "phar-io/manifest", @@ -16294,16 +16294,16 @@ }, { "name": "phpunit/phpunit", - "version": "11.3.6", + "version": "11.4.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "d62c45a19c665bb872c2a47023a0baf41a98bb2b" + "reference": "89fe0c530133c08f7fff89d3d727154e4e504925" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d62c45a19c665bb872c2a47023a0baf41a98bb2b", - "reference": "d62c45a19c665bb872c2a47023a0baf41a98bb2b", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/89fe0c530133c08f7fff89d3d727154e4e504925", + "reference": "89fe0c530133c08f7fff89d3d727154e4e504925", "shasum": "" }, "require": { @@ -16342,7 +16342,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "11.3-dev" + "dev-main": "11.4-dev" } }, "autoload": { @@ -16374,7 +16374,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/11.3.6" + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.4.0" }, "funding": [ { @@ -16390,7 +16390,7 @@ "type": "tidelift" } ], - "time": "2024-09-19T10:54:28+00:00" + "time": "2024-10-05T08:39:03+00:00" }, { "name": "sebastian/cli-parser", From 6e2422c67afa3366d8a23b64b098a94628f168c9 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Mon, 7 Oct 2024 18:15:16 +0200 Subject: [PATCH 307/335] Translations update from Hosted Weblate (#1170) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Λευτέρης Τ --- translations/messages.el.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/translations/messages.el.yaml b/translations/messages.el.yaml index 6cf975bbf..0b6277c5a 100644 --- a/translations/messages.el.yaml +++ b/translations/messages.el.yaml @@ -637,3 +637,5 @@ oauth2.grant.moderate.entry_comment.all: Συντόνισε τα σχόλια σ που συντονίζεις. oauth2.grant.moderate.entry_comment.change_language: Άλλαξε τη γλώσσα των σχολίων σε νήματα στα περιοδικά που συντονίζεις. +oauth2.grant.moderate.entry_comment.set_adult: Επισημάνετε τα σχόλια στα νήματα ως + NSFW στα περιοδικά που συντονίζετε. From f6553a3128ffed76aa2ed802d36139cf39459274 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 18:38:26 +0200 Subject: [PATCH 308/335] Bump symfony/ux-chartjs from 2.19.3 to 2.20.0 (#1164) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- composer.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/composer.lock b/composer.lock index f421cd337..a6a0ec544 100644 --- a/composer.lock +++ b/composer.lock @@ -12586,16 +12586,16 @@ }, { "name": "symfony/stimulus-bundle", - "version": "v2.19.0", + "version": "v2.20.0", "source": { "type": "git", "url": "https://github.com/symfony/stimulus-bundle.git", - "reference": "5e2e1aff3e7cff2875e2f901437543fda9ca9910" + "reference": "ae69e3a764694b9f45d8a009dd2b8c22444c5e0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stimulus-bundle/zipball/5e2e1aff3e7cff2875e2f901437543fda9ca9910", - "reference": "5e2e1aff3e7cff2875e2f901437543fda9ca9910", + "url": "https://api.github.com/repos/symfony/stimulus-bundle/zipball/ae69e3a764694b9f45d8a009dd2b8c22444c5e0c", + "reference": "ae69e3a764694b9f45d8a009dd2b8c22444c5e0c", "shasum": "" }, "require": { @@ -12635,7 +12635,7 @@ "symfony-ux" ], "support": { - "source": "https://github.com/symfony/stimulus-bundle/tree/v2.19.0" + "source": "https://github.com/symfony/stimulus-bundle/tree/v2.20.0" }, "funding": [ { @@ -12651,7 +12651,7 @@ "type": "tidelift" } ], - "time": "2024-07-30T19:26:23+00:00" + "time": "2024-09-24T09:27:42+00:00" }, { "name": "symfony/stopwatch", @@ -13417,16 +13417,16 @@ }, { "name": "symfony/ux-chartjs", - "version": "v2.19.3", + "version": "v2.20.0", "source": { "type": "git", "url": "https://github.com/symfony/ux-chartjs.git", - "reference": "a16c8272e8e9d362c0f3b4d70742747e26d66147" + "reference": "3a669e28d6665515da4d3117d245650d325212da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/ux-chartjs/zipball/a16c8272e8e9d362c0f3b4d70742747e26d66147", - "reference": "a16c8272e8e9d362c0f3b4d70742747e26d66147", + "url": "https://api.github.com/repos/symfony/ux-chartjs/zipball/3a669e28d6665515da4d3117d245650d325212da", + "reference": "3a669e28d6665515da4d3117d245650d325212da", "shasum": "" }, "require": { @@ -13477,7 +13477,7 @@ "symfony-ux" ], "support": { - "source": "https://github.com/symfony/ux-chartjs/tree/v2.19.3" + "source": "https://github.com/symfony/ux-chartjs/tree/v2.20.0" }, "funding": [ { @@ -13493,7 +13493,7 @@ "type": "tidelift" } ], - "time": "2024-08-14T04:55:38+00:00" + "time": "2024-09-24T09:27:42+00:00" }, { "name": "symfony/ux-twig-component", From d1c70ad77daa458cdc70b88e2dab88e0889a94f3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 16:49:58 +0000 Subject: [PATCH 309/335] Bump symfony/console from 7.1.4 to 7.1.5 (#1161) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Melroy van den Berg --- composer.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/composer.lock b/composer.lock index a6a0ec544..7f43d9de9 100644 --- a/composer.lock +++ b/composer.lock @@ -8056,16 +8056,16 @@ }, { "name": "symfony/console", - "version": "v7.1.4", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "1eed7af6961d763e7832e874d7f9b21c3ea9c111" + "reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/1eed7af6961d763e7832e874d7f9b21c3ea9c111", - "reference": "1eed7af6961d763e7832e874d7f9b21c3ea9c111", + "url": "https://api.github.com/repos/symfony/console/zipball/0fa539d12b3ccf068a722bbbffa07ca7079af9ee", + "reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee", "shasum": "" }, "require": { @@ -8129,7 +8129,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.1.4" + "source": "https://github.com/symfony/console/tree/v7.1.5" }, "funding": [ { @@ -8145,7 +8145,7 @@ "type": "tidelift" } ], - "time": "2024-08-15T22:48:53+00:00" + "time": "2024-09-20T08:28:38+00:00" }, { "name": "symfony/css-selector", @@ -12717,16 +12717,16 @@ }, { "name": "symfony/string", - "version": "v7.1.4", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "6cd670a6d968eaeb1c77c2e76091c45c56bc367b" + "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/6cd670a6d968eaeb1c77c2e76091c45c56bc367b", - "reference": "6cd670a6d968eaeb1c77c2e76091c45c56bc367b", + "url": "https://api.github.com/repos/symfony/string/zipball/d66f9c343fa894ec2037cc928381df90a7ad4306", + "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306", "shasum": "" }, "require": { @@ -12784,7 +12784,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.1.4" + "source": "https://github.com/symfony/string/tree/v7.1.5" }, "funding": [ { @@ -12800,7 +12800,7 @@ "type": "tidelift" } ], - "time": "2024-08-12T09:59:40+00:00" + "time": "2024-09-20T08:28:38+00:00" }, { "name": "symfony/translation", From 06f8a0f486a29c18c6a1f34fb4961945fe64c7e4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 16:54:00 +0000 Subject: [PATCH 310/335] docs(contributor): contributors readme action update (#1172) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Melroy van den Berg --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d2033c6b6..40611220c 100644 --- a/README.md +++ b/README.md @@ -105,19 +105,19 @@ Unofficial magazines: - - SzymonKaminski + + weblate
          - SzymonKaminski + Weblate (bot)
          - - weblate + + SzymonKaminski
          - Weblate (bot) + SzymonKaminski
          From 853e11121f1606e10bc5d22144cc1670638d0911 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Wed, 9 Oct 2024 16:25:58 +0200 Subject: [PATCH 311/335] Check if the openssl_sign went OK (#1102) --- src/Service/ActivityPub/ApHttpClient.php | 50 ++++++++++++++++++------ 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/src/Service/ActivityPub/ApHttpClient.php b/src/Service/ActivityPub/ApHttpClient.php index d5139fe1c..33c6a2bcf 100644 --- a/src/Service/ActivityPub/ApHttpClient.php +++ b/src/Service/ActivityPub/ApHttpClient.php @@ -529,16 +529,27 @@ private function getHeaders(string $url, User|Magazine $actor, ?array $body = nu $stringToSign = self::headersToSigningString($headers); $signedHeaders = implode(' ', array_map('strtolower', array_keys($headers))); $key = openssl_pkey_get_private($actor->privateKey); - openssl_sign($stringToSign, $signature, $key, OPENSSL_ALGO_SHA256); - $signature = base64_encode($signature); - - $keyId = $actor instanceof User - ? $this->personFactory->getActivityPubId($actor).'#main-key' - : $this->groupFactory->getActivityPubId($actor).'#main-key'; - - $signatureHeader = 'keyId="'.$keyId.'",headers="'.$signedHeaders.'",algorithm="rsa-sha256",signature="'.$signature.'"'; + $success_sign = openssl_sign($stringToSign, $signature, $key, OPENSSL_ALGO_SHA256); + // Free the key from memory + openssl_free_key($key); + $signatureHeader = null; + if ($success_sign) { + $signature = base64_encode($signature); + $keyId = $actor instanceof User + ? $this->personFactory->getActivityPubId($actor).'#main-key' + : $this->groupFactory->getActivityPubId($actor).'#main-key'; + $signatureHeader = 'keyId="'.$keyId.'",headers="'.$signedHeaders.'",algorithm="rsa-sha256",signature="'.$signature.'"'; + } else { + $this->logger->error('Failed to sign headers for {url}: {headers}', [ + 'url' => $url, + 'headers' => $headers, + ]); + throw new \Exception('Failed to sign headers'); + } unset($headers['(request-target)']); - $headers['Signature'] = $signatureHeader; + if ($signatureHeader) { + $headers['Signature'] = $signatureHeader; + } $headers['User-Agent'] = $this->projectInfo->getUserAgent(); $headers['Accept'] = 'application/activity+json'; $headers['Content-Type'] = 'application/activity+json'; @@ -554,11 +565,24 @@ private function getInstanceHeaders(string $url, ?array $body = null, string $me $stringToSign = self::headersToSigningString($headers); $signedHeaders = implode(' ', array_map('strtolower', array_keys($headers))); $key = openssl_pkey_get_private($privateKey); - openssl_sign($stringToSign, $signature, $key, OPENSSL_ALGO_SHA256); - $signature = base64_encode($signature); - $signatureHeader = 'keyId="'.$keyId.'",headers="'.$signedHeaders.'",algorithm="rsa-sha256",signature="'.$signature.'"'; + $success_sign = openssl_sign($stringToSign, $signature, $key, OPENSSL_ALGO_SHA256); + // Free the key from memory + openssl_free_key($key); + $signatureHeader = null; + if ($success_sign) { + $signature = base64_encode($signature); + $signatureHeader = 'keyId="'.$keyId.'",headers="'.$signedHeaders.'",algorithm="rsa-sha256",signature="'.$signature.'"'; + } else { + $this->logger->error('Failed to sign headers for {url}: {headers}', [ + 'url' => $url, + 'headers' => $headers, + ]); + throw new \Exception('Failed to sign headers'); + } unset($headers['(request-target)']); - $headers['Signature'] = $signatureHeader; + if ($signatureHeader) { + $headers['Signature'] = $signatureHeader; + } $headers['User-Agent'] = $this->projectInfo->getUserAgent(); $headers = array_merge($headers, $this->getFetchAcceptHeaders($requestType)); From f1db652d91bbc25a2ecaa40c690075c8b9ce1cd6 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Wed, 9 Oct 2024 16:49:25 +0200 Subject: [PATCH 312/335] Fix scheduler not running (#1166) Co-authored-by: Melroy van den Berg --- src/Message/ClearDeadMessagesMessage.php | 14 +++++++ src/Message/ClearDeletedUserMessage.php | 14 +++++++ src/Message/Contracts/SchedulerInterface.php | 9 +++++ .../ClearDeadMessagesHandler.php | 30 +++++++++++++++ .../ClearDeletedUserHandler.php | 4 +- src/Scheduler/DeleteUserTaskProvider.php | 25 ------------ src/Scheduler/MbinTaskProvider.php | 38 +++++++++++++++++++ .../Messages/ClearDeletedUserMessage.php | 9 ----- src/Service/UserManager.php | 3 +- 9 files changed, 109 insertions(+), 37 deletions(-) create mode 100644 src/Message/ClearDeadMessagesMessage.php create mode 100644 src/Message/ClearDeletedUserMessage.php create mode 100644 src/Message/Contracts/SchedulerInterface.php create mode 100644 src/MessageHandler/ClearDeadMessagesHandler.php rename src/{Scheduler/Handlers => MessageHandler}/ClearDeletedUserHandler.php (92%) delete mode 100644 src/Scheduler/DeleteUserTaskProvider.php create mode 100644 src/Scheduler/MbinTaskProvider.php delete mode 100644 src/Scheduler/Messages/ClearDeletedUserMessage.php diff --git a/src/Message/ClearDeadMessagesMessage.php b/src/Message/ClearDeadMessagesMessage.php new file mode 100644 index 000000000..25b556b09 --- /dev/null +++ b/src/Message/ClearDeadMessagesMessage.php @@ -0,0 +1,14 @@ +logger->info('Clearing dead messages'); + $sql = 'DELETE FROM messenger_messages WHERE queue_name = :queue_name'; + $this->entityManager->createNativeQuery($sql, new ResultSetMapping()) + ->setParameter('queue_name', 'dead') + ->getResult(); + } +} diff --git a/src/Scheduler/Handlers/ClearDeletedUserHandler.php b/src/MessageHandler/ClearDeletedUserHandler.php similarity index 92% rename from src/Scheduler/Handlers/ClearDeletedUserHandler.php rename to src/MessageHandler/ClearDeletedUserHandler.php index b8188ee12..1c2fdcaf1 100644 --- a/src/Scheduler/Handlers/ClearDeletedUserHandler.php +++ b/src/MessageHandler/ClearDeletedUserHandler.php @@ -2,10 +2,10 @@ declare(strict_types=1); -namespace App\Scheduler\Handlers; +namespace App\MessageHandler; +use App\Message\ClearDeletedUserMessage; use App\Message\DeleteUserMessage; -use App\Scheduler\Messages\ClearDeletedUserMessage; use App\Service\UserManager; use Psr\Log\LoggerInterface; use Symfony\Component\Messenger\Attribute\AsMessageHandler; diff --git a/src/Scheduler/DeleteUserTaskProvider.php b/src/Scheduler/DeleteUserTaskProvider.php deleted file mode 100644 index 4d7b62c19..000000000 --- a/src/Scheduler/DeleteUserTaskProvider.php +++ /dev/null @@ -1,25 +0,0 @@ -schedule ??= (new Schedule()) - ->with( - RecurringMessage::every('1 day', new ClearDeletedUserMessage()) - ); - } -} diff --git a/src/Scheduler/MbinTaskProvider.php b/src/Scheduler/MbinTaskProvider.php new file mode 100644 index 000000000..4b821d444 --- /dev/null +++ b/src/Scheduler/MbinTaskProvider.php @@ -0,0 +1,38 @@ +schedule) { + $this->schedule = (new Schedule()) + ->add( + RecurringMessage::every('1 day', new ClearDeletedUserMessage()), + RecurringMessage::every('1 day', new ClearDeadMessagesMessage()), + ) + ->stateful($this->cache); + } + + return $this->schedule; + } +} diff --git a/src/Scheduler/Messages/ClearDeletedUserMessage.php b/src/Scheduler/Messages/ClearDeletedUserMessage.php deleted file mode 100644 index cc3552c47..000000000 --- a/src/Scheduler/Messages/ClearDeletedUserMessage.php +++ /dev/null @@ -1,9 +0,0 @@ - Date: Wed, 9 Oct 2024 16:51:10 +0200 Subject: [PATCH 313/335] Bump to 1.7.2 release now (#1176) --- config/packages/framework.yaml | 2 +- src/Service/ProjectInfoService.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml index 862e9f3cd..054d9d483 100644 --- a/config/packages/framework.yaml +++ b/config/packages/framework.yaml @@ -31,7 +31,7 @@ framework: http_client: default_options: headers: - 'User-Agent': 'Mbin/1.7.1 (+https://%kbin_domain%/agent)' + 'User-Agent': 'Mbin/1.7.2 (+https://%kbin_domain%/agent)' #esi: true #fragments: true diff --git a/src/Service/ProjectInfoService.php b/src/Service/ProjectInfoService.php index e27ce0192..a44a7b062 100644 --- a/src/Service/ProjectInfoService.php +++ b/src/Service/ProjectInfoService.php @@ -10,7 +10,7 @@ class ProjectInfoService { // If updating version, please also update http client UA in [/config/packages/framework.yaml] - private const VERSION = '1.7.1'; // TODO: Retrieve the version from git tags or getenv()? + private const VERSION = '1.7.2'; // TODO: Retrieve the version from git tags or getenv()? private const NAME = 'mbin'; private const CANONICAL_NAME = 'Mbin'; private const REPOSITORY_URL = 'https://github.com/MbinOrg/mbin'; From 66107765cbf92d91cd9c61a4e022c8cacc6a7870 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Wed, 9 Oct 2024 18:25:23 +0200 Subject: [PATCH 314/335] Fix logic error in the posting restriction logic (#1177) --- src/Entity/Magazine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Entity/Magazine.php b/src/Entity/Magazine.php index 87fdb0c05..405585510 100644 --- a/src/Entity/Magazine.php +++ b/src/Entity/Magazine.php @@ -505,7 +505,7 @@ public function isActorPostingRestricted(Magazine|User $actor): bool return false; } - if (null === $this->apId && ($actor->isAdmin() || $actor->isModerator() || $this->userIsModerator($actor))) { + if ((null === $this->apId && ($actor->isAdmin() || $actor->isModerator())) || $this->userIsModerator($actor)) { return false; } } From b16fa3f25e9420fafa9be98607fb10739dbde930 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Wed, 9 Oct 2024 18:28:04 +0200 Subject: [PATCH 315/335] Execute `npm audit fix` (#1178) --- package-lock.json | 260 ++++++++++++++++++++-------------------------- 1 file changed, 111 insertions(+), 149 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8823c1b17..9cd3382cc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2731,9 +2731,9 @@ "license": "Apache-2.0" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.2.tgz", - "integrity": "sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", + "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==", "cpu": [ "arm" ], @@ -2746,9 +2746,9 @@ "peer": true }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.2.tgz", - "integrity": "sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz", + "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==", "cpu": [ "arm64" ], @@ -2761,9 +2761,9 @@ "peer": true }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.2.tgz", - "integrity": "sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz", + "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==", "cpu": [ "arm64" ], @@ -2776,9 +2776,9 @@ "peer": true }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.2.tgz", - "integrity": "sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz", + "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==", "cpu": [ "x64" ], @@ -2791,9 +2791,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.2.tgz", - "integrity": "sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz", + "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==", "cpu": [ "arm" ], @@ -2806,9 +2806,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.2.tgz", - "integrity": "sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz", + "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==", "cpu": [ "arm" ], @@ -2821,9 +2821,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.2.tgz", - "integrity": "sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz", + "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==", "cpu": [ "arm64" ], @@ -2836,9 +2836,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.2.tgz", - "integrity": "sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz", + "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==", "cpu": [ "arm64" ], @@ -2851,9 +2851,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.2.tgz", - "integrity": "sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz", + "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==", "cpu": [ "ppc64" ], @@ -2866,9 +2866,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.2.tgz", - "integrity": "sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz", + "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==", "cpu": [ "riscv64" ], @@ -2881,9 +2881,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.2.tgz", - "integrity": "sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz", + "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==", "cpu": [ "s390x" ], @@ -2896,9 +2896,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.2.tgz", - "integrity": "sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz", + "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==", "cpu": [ "x64" ], @@ -2911,9 +2911,9 @@ "peer": true }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.2.tgz", - "integrity": "sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz", + "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==", "cpu": [ "x64" ], @@ -2926,9 +2926,9 @@ "peer": true }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.2.tgz", - "integrity": "sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz", + "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==", "cpu": [ "arm64" ], @@ -2941,9 +2941,9 @@ "peer": true }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.2.tgz", - "integrity": "sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz", + "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==", "cpu": [ "ia32" ], @@ -2956,9 +2956,9 @@ "peer": true }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.2.tgz", - "integrity": "sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz", + "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==", "cpu": [ "x64" ], @@ -3349,9 +3349,9 @@ } }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true, "license": "MIT" }, @@ -4490,22 +4490,6 @@ "dev": true, "license": "MIT" }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/bonjour-service": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", @@ -5003,9 +4987,9 @@ "license": "MIT" }, "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "dev": true, "license": "MIT", "engines": { @@ -6187,9 +6171,9 @@ } }, "node_modules/express": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.20.0.tgz", - "integrity": "sha512-pLdae7I6QqShF5PnNTCVn4hI91Dx0Grkn2+IAsMTgMIKuQVte2dN9PeGSSAME2FR8anOhVA62QDIUaWVfEXVLw==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6198,14 +6182,14 @@ "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.2.0", + "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", "merge-descriptors": "1.0.3", @@ -6214,11 +6198,11 @@ "parseurl": "~1.3.3", "path-to-regexp": "0.1.10", "proxy-addr": "~2.0.7", - "qs": "6.11.0", + "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "0.19.0", - "serve-static": "1.16.0", + "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", @@ -6395,14 +6379,14 @@ } }, "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "dev": true, "license": "MIT", "dependencies": { "debug": "2.6.9", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", @@ -6423,6 +6407,16 @@ "ms": "2.0.0" } }, + "node_modules/finalhandler/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -9318,13 +9312,13 @@ } }, "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.0.4" + "side-channel": "^1.0.6" }, "engines": { "node": ">=0.6" @@ -9687,14 +9681,14 @@ } }, "node_modules/rollup": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.2.tgz", - "integrity": "sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz", + "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@types/estree": "1.0.5" + "@types/estree": "1.0.6" }, "bin": { "rollup": "dist/bin/rollup" @@ -9704,22 +9698,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.21.2", - "@rollup/rollup-android-arm64": "4.21.2", - "@rollup/rollup-darwin-arm64": "4.21.2", - "@rollup/rollup-darwin-x64": "4.21.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.21.2", - "@rollup/rollup-linux-arm-musleabihf": "4.21.2", - "@rollup/rollup-linux-arm64-gnu": "4.21.2", - "@rollup/rollup-linux-arm64-musl": "4.21.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.21.2", - "@rollup/rollup-linux-riscv64-gnu": "4.21.2", - "@rollup/rollup-linux-s390x-gnu": "4.21.2", - "@rollup/rollup-linux-x64-gnu": "4.21.2", - "@rollup/rollup-linux-x64-musl": "4.21.2", - "@rollup/rollup-win32-arm64-msvc": "4.21.2", - "@rollup/rollup-win32-ia32-msvc": "4.21.2", - "@rollup/rollup-win32-x64-msvc": "4.21.2", + "@rollup/rollup-android-arm-eabi": "4.24.0", + "@rollup/rollup-android-arm64": "4.24.0", + "@rollup/rollup-darwin-arm64": "4.24.0", + "@rollup/rollup-darwin-x64": "4.24.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.24.0", + "@rollup/rollup-linux-arm-musleabihf": "4.24.0", + "@rollup/rollup-linux-arm64-gnu": "4.24.0", + "@rollup/rollup-linux-arm64-musl": "4.24.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0", + "@rollup/rollup-linux-riscv64-gnu": "4.24.0", + "@rollup/rollup-linux-s390x-gnu": "4.24.0", + "@rollup/rollup-linux-x64-gnu": "4.24.0", + "@rollup/rollup-linux-x64-musl": "4.24.0", + "@rollup/rollup-win32-arm64-msvc": "4.24.0", + "@rollup/rollup-win32-ia32-msvc": "4.24.0", + "@rollup/rollup-win32-x64-msvc": "4.24.0", "fsevents": "~2.3.2" } }, @@ -10023,61 +10017,29 @@ } }, "node_modules/serve-static": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.0.tgz", - "integrity": "sha512-pDLK8zwl2eKaYrs8mrPZBJua4hMplRWJ1tIFksVC3FtBEBnl8dxgeHtsaMS8DhS9i4fLObaon6ABoc4/hQGdPA==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "dev": true, "license": "MIT", "dependencies": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "0.19.0" }, "engines": { "node": ">= 0.8.0" } }, - "node_modules/serve-static/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/serve-static/node_modules/debug/node_modules/ms": { + "node_modules/serve-static/node_modules/encodeurl": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "license": "MIT" - }, - "node_modules/serve-static/node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "dev": true, "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, "engines": { - "node": ">= 0.8.0" + "node": ">= 0.8" } }, "node_modules/set-function-length": { @@ -11022,9 +10984,9 @@ } }, "node_modules/vite": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.3.tgz", - "integrity": "sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==", + "version": "5.4.8", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz", + "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==", "dev": true, "license": "MIT", "peer": true, From 077d3698bc5d10642a2f68390783a1d8922c0d48 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Thu, 10 Oct 2024 16:51:01 +0200 Subject: [PATCH 316/335] Exclude InvalidApPostException from rolling back the transaction (#1180) --- .../ActivityPub/Outbox/DeliverHandler.php | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/MessageHandler/ActivityPub/Outbox/DeliverHandler.php b/src/MessageHandler/ActivityPub/Outbox/DeliverHandler.php index f2c02476b..4895692d4 100644 --- a/src/MessageHandler/ActivityPub/Outbox/DeliverHandler.php +++ b/src/MessageHandler/ActivityPub/Outbox/DeliverHandler.php @@ -42,6 +42,28 @@ public function __invoke(DeliverMessage $message): void $this->workWrapper($message); } + public function workWrapper(MessageInterface $message): void + { + $conn = $this->entityManager->getConnection(); + if (!$conn->isConnected()) { + $conn->connect(); + } + $conn->beginTransaction(); + try { + $this->doWork($message); + $conn->commit(); + } catch (InvalidApPostException $e) { + $conn->commit(); + // we don't roll back on an InvalidApPostException, so the failed delivery attempt gets written to the DB + throw $e; + } catch (\Exception $e) { + $conn->rollBack(); + throw $e; + } + + $conn->close(); + } + public function doWork(MessageInterface $message): void { if (!($message instanceof DeliverMessage)) { From c57b89025a5677abb7b48d19590ed9afdfe39120 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Thu, 10 Oct 2024 16:55:56 +0200 Subject: [PATCH 317/335] Use composer audit (#1179) --- .github/workflows/action.yaml | 33 ++++++++++++++++++++++++++++++--- README.md | 3 +-- ci/Dockerfile | 6 ------ 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/.github/workflows/action.yaml b/.github/workflows/action.yaml index cfd77275f..ec14b5a65 100644 --- a/.github/workflows/action.yaml +++ b/.github/workflows/action.yaml @@ -59,6 +59,7 @@ jobs: run: npm ci --include=dev env: NODE_ENV: production + - name: Build frontend (production) run: npm run build @@ -95,15 +96,41 @@ jobs: SYMFONY_DEPRECATIONS_HELPER: disabled run: php bin/phpunit tests/Unit - security-check: + audit-check: runs-on: ubuntu-latest container: image: danger89/mbin-pipeline:1.2.0 + continue-on-error: true steps: - uses: actions/checkout@v4 - - name: Run security checker - run: local-php-security-checker + - name: Get Composer Cache Directory + id: composer-cache + run: | + echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - name: Calculate composer.lock hash + id: composer-lock-hash + run: | + echo "hash=$(md5sum composer.lock)" >> $GITHUB_OUTPUT + + - uses: actions/cache@v4 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ steps.composer-lock-hash.outputs.hash }} + restore-keys: ${{ runner.os }}-composer- + + - run: cp .env.example .env + - name: Composer install + run: composer install --no-scripts --no-progress + + - name: Run Npm audit + run: npm audit --omit=dev + + - name: Run Composer audit + env: + COMPOSER_AUDIT_ABANDONED: ignore + run: composer audit fixer-dry-run: runs-on: ubuntu-latest diff --git a/README.md b/README.md index 40611220c..b1ecd9f90 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ For developers: - Improved [bare metal/VM guide](https://docs.joinmbin.org/admin/installation/bare_metal) and [Docker guide](https://docs.joinmbin.org/admin/installation/docker/) - [Improved Docker setup](https://github.com/MbinOrg/mbin/pulls?q=is%3Apr+is%3Amerged+label%3Adocker) - _Developer_ server explained (see [Development Server documentation here](https://docs.joinmbin.org/contributing/development_server) ) -- GitHub Security advisories, vulnerability reporting, [Dependabot](https://github.com/features/security) and [Advanced code scanning](https://docs.github.com/en/code-security/code-scanning/introduction-to-code-scanning/about-code-scanning) enabled. And we run [`local-php-security-checker`](https://github.com/fabpot/local-php-security-checker). +- GitHub Security advisories, vulnerability reporting, [Dependabot](https://github.com/features/security) and [Advanced code scanning](https://docs.github.com/en/code-security/code-scanning/introduction-to-code-scanning/about-code-scanning) enabled. And we run `composer audit`. - Improved **code documentation** - **Tight integration** with [Mbin Weblate project](https://hosted.weblate.org/engage/mbin/) for translations (Two way sync) - Last but not least, a **community-focus project embracing the [Collective Code Construction Contract](./C4.md)** (C4). No single maintainer. @@ -292,7 +292,6 @@ Unofficial magazines: - ## Getting Started ### Documentation diff --git a/ci/Dockerfile b/ci/Dockerfile index fcab4a06a..9eb8fc6e2 100644 --- a/ci/Dockerfile +++ b/ci/Dockerfile @@ -17,11 +17,5 @@ RUN chmod +x /usr/local/bin/install-php-extensions RUN install-php-extensions amqp intl redis gd zip bcmath xsl -# Install local-php-security-checker (same as used by "symfony security:check") -RUN curl -sSLf \ - -o /usr/local/bin/local-php-security-checker \ - https://github.com/fabpot/local-php-security-checker/releases/download/v2.1.3/local-php-security-checker_linux_amd64 -RUN chmod +x /usr/local/bin/local-php-security-checker - # Unlimited memory RUN echo "memory_limit = -1" >>/usr/local/etc/php/conf.d/docker-php-memlimit.ini From edb913011cf9e1e9b761f2290d87b6e29c50a02d Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Thu, 10 Oct 2024 17:00:37 +0200 Subject: [PATCH 318/335] Redesign federation page (#1181) --- templates/page/federation.html.twig | 85 +++++++++++++++++++---------- translations/messages.en.yaml | 1 + 2 files changed, 58 insertions(+), 28 deletions(-) diff --git a/templates/page/federation.html.twig b/templates/page/federation.html.twig index 0218b8307..9f38bd3dd 100644 --- a/templates/page/federation.html.twig +++ b/templates/page/federation.html.twig @@ -13,11 +13,25 @@ {% endblock %} {% block body %} -

          {{ 'federation'|trans }}

          -
          +

          {{ 'federation'|trans }}

          + +
          +

          {{'federation_page_allowed_description'|trans}}

          {% if allowedInstances is not empty %} -

          {{'federation_page_allowed_description'|trans}}

          @@ -52,10 +66,15 @@ {% endfor %}
          + {% else %} + {% endif %} - +
          +
          +

          {{'federation_page_disallowed_description'|trans}}

          {% if defederatedInstances is not empty %} -

          {{'federation_page_disallowed_description'|trans}}

          @@ -65,20 +84,26 @@ - {% for instance in defederatedInstances %} - - - - - - {% endfor %} + {% for instance in defederatedInstances %} + + + + + + {% endfor %}
          {{instance.domain}}{{ instance.software ?? '' }}{{ instance.version ?? '' }}
          {{instance.domain}}{{ instance.software ?? '' }}{{ instance.version ?? '' }}
          + {% else %} + {% endif %} +
          +
          +

          {{'federation_page_dead_title'|trans}}

          +

          {{ 'federation_page_dead_description'|trans }}

          {% if deadInstances is not empty %} -

          {{'federation_page_dead_title'|trans}}

          -

          {{ 'federation_page_dead_description'|trans }}

          @@ -91,22 +116,26 @@ - {% for instance in deadInstances %} - - - - - {% if app.user is defined and app.user is not same as null and app.user.admin %} - - {% endif %} - - {% endfor %} + {% for instance in deadInstances %} + + + + + {% if app.user is defined and app.user is not same as null and app.user.admin %} + + {% endif %} + + {% endfor %}
          {{instance.domain}}{{ instance.software ?? ''}}{{ instance.version ?? '' }} - {% if instance.lastFailedDeliver is not same as null %} - {{ component('date', { date: instance.lastFailedDeliver }) }} - {% endif %} -
          {{instance.domain}}{{ instance.software ?? ''}}{{ instance.version ?? '' }} + {% if instance.lastFailedDeliver is not same as null %} + {{ component('date', { date: instance.lastFailedDeliver }) }} + {% endif %} +
          + {% else %} + {% endif %}
          {% endblock %} diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml index d58507727..bff5a1bb6 100644 --- a/translations/messages.en.yaml +++ b/translations/messages.en.yaml @@ -897,3 +897,4 @@ admin_users_banned: Banned user_verify: Activate account max_image_size: Maximum file size comment_not_found: Comment not found +table_of_contents: Table of contents From 93aed855041bcce607f429aa0f7f906f165dab5f Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Fri, 11 Oct 2024 18:34:41 +0200 Subject: [PATCH 319/335] Fix toolbar broken in thread edit (#1182) --- templates/entry/_form_edit.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/entry/_form_edit.html.twig b/templates/entry/_form_edit.html.twig index df791e587..a8e3ea501 100644 --- a/templates/entry/_form_edit.html.twig +++ b/templates/entry/_form_edit.html.twig @@ -20,7 +20,7 @@ 'data-action' : 'input-length#updateDisplay', 'data-input-length-max-value' : constant('App\\Entity\\Entry::MAX_TITLE_LENGTH') }}) }} - {{ component('editor_toolbar', {id: 'entry_article_body'}) }} + {{ component('editor_toolbar', {id: 'entry_edit_body'}) }} {{ form_row(form.body, { label: false, attr: { placeholder: 'body', From 1f9c1ae4f749f762bd2f4cc358c78bc6e681d6e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 13 Oct 2024 13:32:14 +0200 Subject: [PATCH 320/335] Bump phpstan/phpstan from 1.12.4 to 1.12.6 (#1185) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- composer.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/composer.lock b/composer.lock index 7f43d9de9..98b1ad3ca 100644 --- a/composer.lock +++ b/composer.lock @@ -15913,16 +15913,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.12.4", + "version": "1.12.6", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "ffa517cb918591b93acc9b95c0bebdcd0e4538bd" + "reference": "dc4d2f145a88ea7141ae698effd64d9df46527ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/ffa517cb918591b93acc9b95c0bebdcd0e4538bd", - "reference": "ffa517cb918591b93acc9b95c0bebdcd0e4538bd", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/dc4d2f145a88ea7141ae698effd64d9df46527ae", + "reference": "dc4d2f145a88ea7141ae698effd64d9df46527ae", "shasum": "" }, "require": { @@ -15967,7 +15967,7 @@ "type": "github" } ], - "time": "2024-09-19T07:58:01+00:00" + "time": "2024-10-06T15:03:59+00:00" }, { "name": "phpunit/php-code-coverage", From 19804ed921d1b5d23e6cfc2597dd28c0d40d3fc0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 13 Oct 2024 11:34:04 +0000 Subject: [PATCH 321/335] Bump aws/aws-sdk-php from 3.322.0 to 3.324.1 (#1187) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Melroy van den Berg --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 98b1ad3ca..2318d9cba 100644 --- a/composer.lock +++ b/composer.lock @@ -62,16 +62,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.322.0", + "version": "3.324.1", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "3eeb8d400acc902965f7de5bc85635853f27c109" + "reference": "5b824a9b8015a38f18c53b023975c0f63c7bd3dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/3eeb8d400acc902965f7de5bc85635853f27c109", - "reference": "3eeb8d400acc902965f7de5bc85635853f27c109", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/5b824a9b8015a38f18c53b023975c0f63c7bd3dc", + "reference": "5b824a9b8015a38f18c53b023975c0f63c7bd3dc", "shasum": "" }, "require": { @@ -154,9 +154,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.322.0" + "source": "https://github.com/aws/aws-sdk-php/tree/3.324.1" }, - "time": "2024-09-18T18:09:42+00:00" + "time": "2024-10-11T18:22:01+00:00" }, { "name": "babdev/pagerfanta-bundle", From 871ade82cace9fee8b9866d2bcf54cc95460f6bc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 13 Oct 2024 11:36:38 +0000 Subject: [PATCH 322/335] Bump phpstan/phpdoc-parser from 1.30.1 to 1.33.0 (#1188) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 2318d9cba..c68eedb30 100644 --- a/composer.lock +++ b/composer.lock @@ -6360,16 +6360,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.30.1", + "version": "1.33.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "51b95ec8670af41009e2b2b56873bad96682413e" + "reference": "82a311fd3690fb2bf7b64d5c98f912b3dd746140" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/51b95ec8670af41009e2b2b56873bad96682413e", - "reference": "51b95ec8670af41009e2b2b56873bad96682413e", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/82a311fd3690fb2bf7b64d5c98f912b3dd746140", + "reference": "82a311fd3690fb2bf7b64d5c98f912b3dd746140", "shasum": "" }, "require": { @@ -6401,9 +6401,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.30.1" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.33.0" }, - "time": "2024-09-07T20:13:05+00:00" + "time": "2024-10-13T11:25:22+00:00" }, { "name": "predis/predis", From 4304d3867467a6a430516e1d10af1ce74e7dc79c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 13 Oct 2024 13:39:30 +0200 Subject: [PATCH 323/335] Bump symfony/messenger from 7.1.4 to 7.1.5 (#1186) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index c68eedb30..194b4d68d 100644 --- a/composer.lock +++ b/composer.lock @@ -10192,16 +10192,16 @@ }, { "name": "symfony/messenger", - "version": "v7.1.4", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/messenger.git", - "reference": "e1dc743492ff9f1cfb23e6eea3592bf2ec9bd079" + "reference": "e1c0ced845e3dac12ab428c5ed42dbe7a58ca576" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/messenger/zipball/e1dc743492ff9f1cfb23e6eea3592bf2ec9bd079", - "reference": "e1dc743492ff9f1cfb23e6eea3592bf2ec9bd079", + "url": "https://api.github.com/repos/symfony/messenger/zipball/e1c0ced845e3dac12ab428c5ed42dbe7a58ca576", + "reference": "e1c0ced845e3dac12ab428c5ed42dbe7a58ca576", "shasum": "" }, "require": { @@ -10258,7 +10258,7 @@ "description": "Helps applications send and receive messages to/from other applications or via message queues", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/messenger/tree/v7.1.4" + "source": "https://github.com/symfony/messenger/tree/v7.1.5" }, "funding": [ { @@ -10274,7 +10274,7 @@ "type": "tidelift" } ], - "time": "2024-08-06T14:26:51+00:00" + "time": "2024-09-08T12:32:26+00:00" }, { "name": "symfony/mime", From f1b26d70bc27a88d7ffa62e3ab1ca6117445fcb0 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Fri, 18 Oct 2024 22:08:57 +0200 Subject: [PATCH 324/335] Translations update from Hosted Weblate (#1190) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Λευτέρης Τ Co-authored-by: hankskyjames777 --- translations/messages.el.yaml | 31 +++++++++++++++++++++++++++++++ translations/messages.fil.yaml | 17 +++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/translations/messages.el.yaml b/translations/messages.el.yaml index 0b6277c5a..9f11becd5 100644 --- a/translations/messages.el.yaml +++ b/translations/messages.el.yaml @@ -639,3 +639,34 @@ oauth2.grant.moderate.entry_comment.change_language: Άλλαξε τη γλώσ σε νήματα στα περιοδικά που συντονίζεις. oauth2.grant.moderate.entry_comment.set_adult: Επισημάνετε τα σχόλια στα νήματα ως NSFW στα περιοδικά που συντονίζετε. +oauth2.grant.admin.post_comment.purge: Διέγραψε εντελώς οποιοδήποτε σχόλιο σε μια + ανάρτηση από την οντότητα σου. +oauth2.grant.admin.entry_comment.purge: Διέγραψε εντελώς οποιοδήποτε σχόλιο σε ένα + νήμα από την οντότητα σου. +oauth2.grant.admin.post.purge: Διέγραψε εντελώς οποιαδήποτε ανάρτηση από την οντότητα + σου. +oauth2.grant.moderate.entry_comment.trash: Πέταξε ή επανέφερε σχολίων σε νήματα στα + περιοδικά που διαχειρίζεσαι. +oauth2.grant.moderate.post.set_adult: Επισήμανε τις αναρτήσεις ως NSFW στα περιοδικά + που συντονίζεις. +oauth2.grant.moderate.post_comment.set_adult: Επισήμανε τα σχόλια σε αναρτήσεις ως + NSFW στα περιοδικά που συντονίζεις. +oauth2.grant.moderate.post_comment.all: Συντόνισε σχόλια σε αναρτήσεις στα περιοδικά + που συντονίζεις. +oauth2.grant.moderate.post_comment.change_language: Άλλαξε τη γλώσσα των σχολίων σε + αναρτήσεις στα περιοδικά που συντονίζεις. +oauth2.grant.moderate.magazine.ban.all: Διαχειρίσου τους αποκλεισμένους χρήστες στα + περιοδικά που συντονίζεις. +oauth2.grant.moderate.post.all: Συντόνισε αναρτήσεις στα περιοδικά που συντονίζεις. +oauth2.grant.moderate.post.change_language: Άλλαξε τη γλώσσα των αναρτήσεων στα περιοδικά + που συντονίζεις. +oauth2.grant.moderate.post.trash: Πέταξε ή επανέφερε τις αναρτήσεις στα περιοδικά + που συντονίζεις. +oauth2.grant.moderate.post_comment.trash: Πέταξε ή επανέφερε τα σχόλια σε αναρτήσεις + στα περιοδικά που συντονίζεις. +oauth2.grant.moderate.magazine.all: Διαχειρίσου τους αποκλεισμούς, τις αναφορές και + την προβολή αντικειμένων στον κάδο απορριμμάτων στα περιοδικά που συντονίζεις. +oauth2.grant.moderate.magazine.ban.read: Δες τους αποκλεισμένους χρήστες στα περιοδικά + που συντονίζεις. +oauth2.grant.moderate.magazine.ban.create: Απέκλεισε τους χρήστες στα περιοδικά που + συντονίζεις. diff --git a/translations/messages.fil.yaml b/translations/messages.fil.yaml index ca25953ab..dcf7b21cc 100644 --- a/translations/messages.fil.yaml +++ b/translations/messages.fil.yaml @@ -227,3 +227,20 @@ purge_magazine: Purgahin ang magasin sensitive_hide: Pindutin upang itago sensitive_show: Pindutin upang ipakita sensitive_warning: Sensitibong nilalaman +notification_title_mention: Binabanggit ka +notification_title_edited_comment: Nabago ang puna +notification_title_new_reply: Bagong tugon +notification_title_removed_comment: Natanggal ang puna +notification_title_ban: Binabawalan ka +max_image_size: Pinakamataas na laki ng file +hidden: Nakatago +enabled: Pinagana +notification_title_new_report: Nagawa ang isang bagong ulat +notification_title_edited_post: Nabago ang isang post +notification_title_removed_post: Natanggal ang isang post +magazine_posting_restricted_to_mods_warning: Mga tagatimpi lamang ang gumagawa ng + mga thread sa magasin na ito +open_report: nakabukas na ulat +already_have_account: Mayroon ka na bang account? +eng: ENG +comment_not_found: Hindi nakita ang puna From 31eaebd50d62377dd340a2722a3bd1da777ccdc9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 13:24:22 +0000 Subject: [PATCH 325/335] Bump symfony/mailer from 7.1.2 to 7.1.6 (#1203) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- composer.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/composer.lock b/composer.lock index 194b4d68d..21c501a5b 100644 --- a/composer.lock +++ b/composer.lock @@ -8690,16 +8690,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v7.1.1", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7" + "reference": "87254c78dd50721cfd015b62277a8281c5589702" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7", - "reference": "9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/87254c78dd50721cfd015b62277a8281c5589702", + "reference": "87254c78dd50721cfd015b62277a8281c5589702", "shasum": "" }, "require": { @@ -8750,7 +8750,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.1.1" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.1.6" }, "funding": [ { @@ -8766,7 +8766,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:57:53+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -9876,16 +9876,16 @@ }, { "name": "symfony/mailer", - "version": "v7.1.2", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "8fcff0af9043c8f8a8e229437cea363e282f9aee" + "reference": "69c9948451fb3a6a4d47dc8261d1794734e76cdd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/8fcff0af9043c8f8a8e229437cea363e282f9aee", - "reference": "8fcff0af9043c8f8a8e229437cea363e282f9aee", + "url": "https://api.github.com/repos/symfony/mailer/zipball/69c9948451fb3a6a4d47dc8261d1794734e76cdd", + "reference": "69c9948451fb3a6a4d47dc8261d1794734e76cdd", "shasum": "" }, "require": { @@ -9936,7 +9936,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v7.1.2" + "source": "https://github.com/symfony/mailer/tree/v7.1.6" }, "funding": [ { @@ -9952,7 +9952,7 @@ "type": "tidelift" } ], - "time": "2024-06-28T08:00:31+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/mailgun-mailer", @@ -10278,16 +10278,16 @@ }, { "name": "symfony/mime", - "version": "v7.1.5", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "711d2e167e8ce65b05aea6b258c449671cdd38ff" + "reference": "caa1e521edb2650b8470918dfe51708c237f0598" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/711d2e167e8ce65b05aea6b258c449671cdd38ff", - "reference": "711d2e167e8ce65b05aea6b258c449671cdd38ff", + "url": "https://api.github.com/repos/symfony/mime/zipball/caa1e521edb2650b8470918dfe51708c237f0598", + "reference": "caa1e521edb2650b8470918dfe51708c237f0598", "shasum": "" }, "require": { @@ -10342,7 +10342,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v7.1.5" + "source": "https://github.com/symfony/mime/tree/v7.1.6" }, "funding": [ { @@ -10358,7 +10358,7 @@ "type": "tidelift" } ], - "time": "2024-09-20T08:28:38+00:00" + "time": "2024-10-25T15:11:02+00:00" }, { "name": "symfony/monolog-bridge", From 4c3ac7be85eea74c9bc6d7234e32afbc53c479ff Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Mon, 4 Nov 2024 14:26:38 +0100 Subject: [PATCH 326/335] Translations update from Hosted Weblate (#1198) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jiri Grönroos --- translations/messages.fi.yaml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/translations/messages.fi.yaml b/translations/messages.fi.yaml index 140142457..41eb2031d 100644 --- a/translations/messages.fi.yaml +++ b/translations/messages.fi.yaml @@ -354,3 +354,28 @@ notification_title_edited_thread: Ketjua muokattiin show_related_magazines: Näytä satunnaisia makasiineja new_user_description: Tämä käyttäjä on uusi (aktiivinen alle %days% päivää) new_magazine_description: Tämä makasiini on uusi (aktiivinen alle %days% päivää) +hidden: Piilotettu +enabled: Käytössä +title: Otsikko +is_adult: 18+ / NSFW +overview: Yleisnäkymä +columns: Sarakkeet +joined: Liittynyt +rejected: Hylätty +help: Tuki +url: URL-osoite +body: Sisältö +tags: Tunnisteet +tag: Tunniste +cards: Kortit +featured_magazines: Esittelyssä olevat makasiinit +votes: Äänet +reject: Hylkää +approve: Hyväksy +approved: Hyväksytty +dashboard: Kojelauta +registration_disabled: Rekisteröinti poistettu käytöstä +password_confirm_header: Vahvista salasanan vaihtopyyntö. +notification_title_new_report: Uusi raportti luotiin +comment_not_found: Kommenttia ei löydy +table_of_contents: Sisällysluettelo From b288c9d306426a37fea924efe89934a4716c065d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 13:33:19 +0000 Subject: [PATCH 327/335] Bump symfony/dotenv from 7.1.3 to 7.1.6 (#1202) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 21c501a5b..0910baac7 100644 --- a/composer.lock +++ b/composer.lock @@ -8541,16 +8541,16 @@ }, { "name": "symfony/dotenv", - "version": "v7.1.3", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/dotenv.git", - "reference": "a26be30fd61678dab694a18a85084cea7673bbf3" + "reference": "56a10f3032a6c2f085b13bc429e9d78a2c895dc4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dotenv/zipball/a26be30fd61678dab694a18a85084cea7673bbf3", - "reference": "a26be30fd61678dab694a18a85084cea7673bbf3", + "url": "https://api.github.com/repos/symfony/dotenv/zipball/56a10f3032a6c2f085b13bc429e9d78a2c895dc4", + "reference": "56a10f3032a6c2f085b13bc429e9d78a2c895dc4", "shasum": "" }, "require": { @@ -8595,7 +8595,7 @@ "environment" ], "support": { - "source": "https://github.com/symfony/dotenv/tree/v7.1.3" + "source": "https://github.com/symfony/dotenv/tree/v7.1.6" }, "funding": [ { @@ -8611,7 +8611,7 @@ "type": "tidelift" } ], - "time": "2024-07-09T19:36:07+00:00" + "time": "2024-09-28T11:14:12+00:00" }, { "name": "symfony/error-handler", From 39f17b25a2f9b5ca91385a41191558d0f98ee6d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 13:36:00 +0000 Subject: [PATCH 328/335] Bump symfony/ux-autocomplete from 2.19.2 to 2.21.0 (#1199) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- composer.lock | 136 +++++++++++++++++++++++++------------------------- 1 file changed, 67 insertions(+), 69 deletions(-) diff --git a/composer.lock b/composer.lock index 0910baac7..47014dd07 100644 --- a/composer.lock +++ b/composer.lock @@ -8214,16 +8214,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v7.1.5", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "38465f925ec4e0707b090e9147c65869837d639d" + "reference": "1f12f9d580ef8dd09e3b756aa111cc2d5f311bfd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/38465f925ec4e0707b090e9147c65869837d639d", - "reference": "38465f925ec4e0707b090e9147c65869837d639d", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/1f12f9d580ef8dd09e3b756aa111cc2d5f311bfd", + "reference": "1f12f9d580ef8dd09e3b756aa111cc2d5f311bfd", "shasum": "" }, "require": { @@ -8274,7 +8274,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v7.1.5" + "source": "https://github.com/symfony/dependency-injection/tree/v7.1.6" }, "funding": [ { @@ -8290,7 +8290,7 @@ "type": "tidelift" } ], - "time": "2024-09-20T08:28:38+00:00" + "time": "2024-10-25T15:11:02+00:00" }, { "name": "symfony/deprecation-contracts", @@ -8615,16 +8615,16 @@ }, { "name": "symfony/error-handler", - "version": "v7.1.3", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "432bb369952795c61ca1def65e078c4a80dad13c" + "reference": "d60117093c2a9fe667baa8fedf84e8a09b9c592f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/432bb369952795c61ca1def65e078c4a80dad13c", - "reference": "432bb369952795c61ca1def65e078c4a80dad13c", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/d60117093c2a9fe667baa8fedf84e8a09b9c592f", + "reference": "d60117093c2a9fe667baa8fedf84e8a09b9c592f", "shasum": "" }, "require": { @@ -8670,7 +8670,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v7.1.3" + "source": "https://github.com/symfony/error-handler/tree/v7.1.6" }, "funding": [ { @@ -8686,7 +8686,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T13:02:51+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/event-dispatcher", @@ -9521,16 +9521,16 @@ }, { "name": "symfony/http-foundation", - "version": "v7.1.5", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "e30ef73b1e44eea7eb37ba69600a354e553f694b" + "reference": "3d7bbf071b25f802f7d55524d408bed414ea71e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e30ef73b1e44eea7eb37ba69600a354e553f694b", - "reference": "e30ef73b1e44eea7eb37ba69600a354e553f694b", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/3d7bbf071b25f802f7d55524d408bed414ea71e2", + "reference": "3d7bbf071b25f802f7d55524d408bed414ea71e2", "shasum": "" }, "require": { @@ -9578,7 +9578,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.1.5" + "source": "https://github.com/symfony/http-foundation/tree/v7.1.6" }, "funding": [ { @@ -9594,20 +9594,20 @@ "type": "tidelift" } ], - "time": "2024-09-20T08:28:38+00:00" + "time": "2024-10-11T19:23:14+00:00" }, { "name": "symfony/http-kernel", - "version": "v7.1.5", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "44204d96150a9df1fc57601ec933d23fefc2d65b" + "reference": "5d8315899cd76b2e7e29179bf5fea103e41bdf03" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/44204d96150a9df1fc57601ec933d23fefc2d65b", - "reference": "44204d96150a9df1fc57601ec933d23fefc2d65b", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/5d8315899cd76b2e7e29179bf5fea103e41bdf03", + "reference": "5d8315899cd76b2e7e29179bf5fea103e41bdf03", "shasum": "" }, "require": { @@ -9692,7 +9692,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v7.1.5" + "source": "https://github.com/symfony/http-kernel/tree/v7.1.6" }, "funding": [ { @@ -9708,7 +9708,7 @@ "type": "tidelift" } ], - "time": "2024-09-21T06:09:21+00:00" + "time": "2024-10-27T13:54:21+00:00" }, { "name": "symfony/intl", @@ -11438,16 +11438,16 @@ }, { "name": "symfony/property-access", - "version": "v7.1.4", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "6c709f97103355016e5782d0622437ae381012ad" + "reference": "975d7f7fd8fcb952364c6badc46d01a580532bf9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/6c709f97103355016e5782d0622437ae381012ad", - "reference": "6c709f97103355016e5782d0622437ae381012ad", + "url": "https://api.github.com/repos/symfony/property-access/zipball/975d7f7fd8fcb952364c6badc46d01a580532bf9", + "reference": "975d7f7fd8fcb952364c6badc46d01a580532bf9", "shasum": "" }, "require": { @@ -11494,7 +11494,7 @@ "reflection" ], "support": { - "source": "https://github.com/symfony/property-access/tree/v7.1.4" + "source": "https://github.com/symfony/property-access/tree/v7.1.6" }, "funding": [ { @@ -11510,20 +11510,20 @@ "type": "tidelift" } ], - "time": "2024-08-30T16:12:47+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/property-info", - "version": "v7.1.3", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "88a279df2db5b7919cac6f35d6a5d1d7147e6a9b" + "reference": "6b630ff585d9fdc72f50369885ad4364a849cf02" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/88a279df2db5b7919cac6f35d6a5d1d7147e6a9b", - "reference": "88a279df2db5b7919cac6f35d6a5d1d7147e6a9b", + "url": "https://api.github.com/repos/symfony/property-info/zipball/6b630ff585d9fdc72f50369885ad4364a849cf02", + "reference": "6b630ff585d9fdc72f50369885ad4364a849cf02", "shasum": "" }, "require": { @@ -11578,7 +11578,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v7.1.3" + "source": "https://github.com/symfony/property-info/tree/v7.1.6" }, "funding": [ { @@ -11594,7 +11594,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T07:36:36+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/psr-http-message-bridge", @@ -12717,16 +12717,16 @@ }, { "name": "symfony/string", - "version": "v7.1.5", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306" + "reference": "61b72d66bf96c360a727ae6232df5ac83c71f626" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/d66f9c343fa894ec2037cc928381df90a7ad4306", - "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306", + "url": "https://api.github.com/repos/symfony/string/zipball/61b72d66bf96c360a727ae6232df5ac83c71f626", + "reference": "61b72d66bf96c360a727ae6232df5ac83c71f626", "shasum": "" }, "require": { @@ -12784,7 +12784,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.1.5" + "source": "https://github.com/symfony/string/tree/v7.1.6" }, "funding": [ { @@ -12800,7 +12800,7 @@ "type": "tidelift" } ], - "time": "2024-09-20T08:28:38+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/translation", @@ -13169,16 +13169,16 @@ }, { "name": "symfony/type-info", - "version": "v7.1.1", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/type-info.git", - "reference": "60b28eb733f1453287f1263ed305b96091e0d1dc" + "reference": "a13032128c307470955c45c99201349b15cd7f4a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/type-info/zipball/60b28eb733f1453287f1263ed305b96091e0d1dc", - "reference": "60b28eb733f1453287f1263ed305b96091e0d1dc", + "url": "https://api.github.com/repos/symfony/type-info/zipball/a13032128c307470955c45c99201349b15cd7f4a", + "reference": "a13032128c307470955c45c99201349b15cd7f4a", "shasum": "" }, "require": { @@ -13231,7 +13231,7 @@ "type" ], "support": { - "source": "https://github.com/symfony/type-info/tree/v7.1.1" + "source": "https://github.com/symfony/type-info/tree/v7.1.6" }, "funding": [ { @@ -13247,7 +13247,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:59:31+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/uid", @@ -13325,16 +13325,16 @@ }, { "name": "symfony/ux-autocomplete", - "version": "v2.19.2", + "version": "v2.21.0", "source": { "type": "git", "url": "https://github.com/symfony/ux-autocomplete.git", - "reference": "ef15862c55e15a2225587e8b226df21561d36c7c" + "reference": "357a4b8eef612b279568292a878e60b8b0992413" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/ux-autocomplete/zipball/ef15862c55e15a2225587e8b226df21561d36c7c", - "reference": "ef15862c55e15a2225587e8b226df21561d36c7c", + "url": "https://api.github.com/repos/symfony/ux-autocomplete/zipball/357a4b8eef612b279568292a878e60b8b0992413", + "reference": "357a4b8eef612b279568292a878e60b8b0992413", "shasum": "" }, "require": { @@ -13343,8 +13343,7 @@ "symfony/deprecation-contracts": "^2.5|^3", "symfony/http-foundation": "^6.3|^7.0", "symfony/http-kernel": "^6.3|^7.0", - "symfony/property-access": "^6.3|^7.0", - "symfony/string": "^6.3|^7.0" + "symfony/property-access": "^6.3|^7.0" }, "conflict": { "doctrine/orm": "2.9.0 || 2.9.1" @@ -13362,7 +13361,6 @@ "symfony/phpunit-bridge": "^6.3|^7.0", "symfony/process": "^6.3|^7.0", "symfony/security-bundle": "^6.3|^7.0", - "symfony/security-csrf": "^6.3|^7.0", "symfony/twig-bundle": "^6.3|^7.0", "symfony/uid": "^6.3|^7.0", "twig/twig": "^2.14.7|^3.0.4", @@ -13397,7 +13395,7 @@ "symfony-ux" ], "support": { - "source": "https://github.com/symfony/ux-autocomplete/tree/v2.19.2" + "source": "https://github.com/symfony/ux-autocomplete/tree/v2.21.0" }, "funding": [ { @@ -13413,7 +13411,7 @@ "type": "tidelift" } ], - "time": "2024-08-13T14:54:57+00:00" + "time": "2024-10-21T19:02:15+00:00" }, { "name": "symfony/ux-chartjs", @@ -13678,16 +13676,16 @@ }, { "name": "symfony/var-dumper", - "version": "v7.1.5", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "e20e03889539fd4e4211e14d2179226c513c010d" + "reference": "cb5bd55a6b8c2c1c7fb68b0aeae0e257948a720c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/e20e03889539fd4e4211e14d2179226c513c010d", - "reference": "e20e03889539fd4e4211e14d2179226c513c010d", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/cb5bd55a6b8c2c1c7fb68b0aeae0e257948a720c", + "reference": "cb5bd55a6b8c2c1c7fb68b0aeae0e257948a720c", "shasum": "" }, "require": { @@ -13741,7 +13739,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.1.5" + "source": "https://github.com/symfony/var-dumper/tree/v7.1.6" }, "funding": [ { @@ -13757,20 +13755,20 @@ "type": "tidelift" } ], - "time": "2024-09-16T10:07:02+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/var-exporter", - "version": "v7.1.2", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "b80a669a2264609f07f1667f891dbfca25eba44c" + "reference": "90173ef89c40e7c8c616653241048705f84130ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/b80a669a2264609f07f1667f891dbfca25eba44c", - "reference": "b80a669a2264609f07f1667f891dbfca25eba44c", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/90173ef89c40e7c8c616653241048705f84130ef", + "reference": "90173ef89c40e7c8c616653241048705f84130ef", "shasum": "" }, "require": { @@ -13817,7 +13815,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v7.1.2" + "source": "https://github.com/symfony/var-exporter/tree/v7.1.6" }, "funding": [ { @@ -13833,7 +13831,7 @@ "type": "tidelift" } ], - "time": "2024-06-28T08:00:31+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/web-link", From 8180d0e5df15d79bb67152af1be07d462d973635 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 13:38:51 +0000 Subject: [PATCH 329/335] Bump symfonycasts/verify-email-bundle from 1.17.0 to 1.17.1 (#1194) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- composer.lock | 60 +++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/composer.lock b/composer.lock index 47014dd07..9075980b6 100644 --- a/composer.lock +++ b/composer.lock @@ -7981,16 +7981,16 @@ }, { "name": "symfony/config", - "version": "v7.1.1", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "2210fc99fa42a259eb6c89d1f724ce0c4d62d5d2" + "reference": "5c6152766251ff45a44b76affadd5287e253fb27" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/2210fc99fa42a259eb6c89d1f724ce0c4d62d5d2", - "reference": "2210fc99fa42a259eb6c89d1f724ce0c4d62d5d2", + "url": "https://api.github.com/repos/symfony/config/zipball/5c6152766251ff45a44b76affadd5287e253fb27", + "reference": "5c6152766251ff45a44b76affadd5287e253fb27", "shasum": "" }, "require": { @@ -8036,7 +8036,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v7.1.1" + "source": "https://github.com/symfony/config/tree/v7.1.6" }, "funding": [ { @@ -8052,7 +8052,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:57:53+00:00" + "time": "2024-10-25T15:11:02+00:00" }, { "name": "symfony/console", @@ -8910,16 +8910,16 @@ }, { "name": "symfony/filesystem", - "version": "v7.1.5", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "61fe0566189bf32e8cfee78335d8776f64a66f5a" + "reference": "c835867b3c62bb05c7fe3d637c871c7ae52024d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/61fe0566189bf32e8cfee78335d8776f64a66f5a", - "reference": "61fe0566189bf32e8cfee78335d8776f64a66f5a", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/c835867b3c62bb05c7fe3d637c871c7ae52024d4", + "reference": "c835867b3c62bb05c7fe3d637c871c7ae52024d4", "shasum": "" }, "require": { @@ -8956,7 +8956,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.1.5" + "source": "https://github.com/symfony/filesystem/tree/v7.1.6" }, "funding": [ { @@ -8972,7 +8972,7 @@ "type": "tidelift" } ], - "time": "2024-09-17T09:16:35+00:00" + "time": "2024-10-25T15:11:02+00:00" }, { "name": "symfony/finder", @@ -11377,16 +11377,16 @@ }, { "name": "symfony/process", - "version": "v7.1.5", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "5c03ee6369281177f07f7c68252a280beccba847" + "reference": "6aaa189ddb4ff6b5de8fa3210f2fb42c87b4d12e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/5c03ee6369281177f07f7c68252a280beccba847", - "reference": "5c03ee6369281177f07f7c68252a280beccba847", + "url": "https://api.github.com/repos/symfony/process/zipball/6aaa189ddb4ff6b5de8fa3210f2fb42c87b4d12e", + "reference": "6aaa189ddb4ff6b5de8fa3210f2fb42c87b4d12e", "shasum": "" }, "require": { @@ -11418,7 +11418,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.1.5" + "source": "https://github.com/symfony/process/tree/v7.1.6" }, "funding": [ { @@ -11434,7 +11434,7 @@ "type": "tidelift" } ], - "time": "2024-09-19T21:48:23+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/property-access", @@ -11818,16 +11818,16 @@ }, { "name": "symfony/routing", - "version": "v7.1.4", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "1500aee0094a3ce1c92626ed8cf3c2037e86f5a7" + "reference": "66a2c469f6c22d08603235c46a20007c0701ea0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/1500aee0094a3ce1c92626ed8cf3c2037e86f5a7", - "reference": "1500aee0094a3ce1c92626ed8cf3c2037e86f5a7", + "url": "https://api.github.com/repos/symfony/routing/zipball/66a2c469f6c22d08603235c46a20007c0701ea0a", + "reference": "66a2c469f6c22d08603235c46a20007c0701ea0a", "shasum": "" }, "require": { @@ -11879,7 +11879,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v7.1.4" + "source": "https://github.com/symfony/routing/tree/v7.1.6" }, "funding": [ { @@ -11895,7 +11895,7 @@ "type": "tidelift" } ], - "time": "2024-08-29T08:16:25+00:00" + "time": "2024-10-01T08:31:23+00:00" }, { "name": "symfony/runtime", @@ -14195,16 +14195,16 @@ }, { "name": "symfonycasts/verify-email-bundle", - "version": "v1.17.0", + "version": "v1.17.1", "source": { "type": "git", "url": "https://github.com/SymfonyCasts/verify-email-bundle.git", - "reference": "f72af149070b39ef82a7095074378d0a98b4d2ef" + "reference": "c6b1431fc4a8f6483a1bbb7c781da229a82cca81" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/SymfonyCasts/verify-email-bundle/zipball/f72af149070b39ef82a7095074378d0a98b4d2ef", - "reference": "f72af149070b39ef82a7095074378d0a98b4d2ef", + "url": "https://api.github.com/repos/SymfonyCasts/verify-email-bundle/zipball/c6b1431fc4a8f6483a1bbb7c781da229a82cca81", + "reference": "c6b1431fc4a8f6483a1bbb7c781da229a82cca81", "shasum": "" }, "require": { @@ -14235,9 +14235,9 @@ "description": "Simple, stylish Email Verification for Symfony", "support": { "issues": "https://github.com/SymfonyCasts/verify-email-bundle/issues", - "source": "https://github.com/SymfonyCasts/verify-email-bundle/tree/v1.17.0" + "source": "https://github.com/SymfonyCasts/verify-email-bundle/tree/v1.17.1" }, - "time": "2024-03-17T02:29:53+00:00" + "time": "2024-10-18T20:06:04+00:00" }, { "name": "thenetworg/oauth2-azure", From 56b7d939eafe759da6bdda7aeffa892e9e2deece Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Mon, 4 Nov 2024 21:04:22 +0100 Subject: [PATCH 330/335] Fix dead instance query by allowing lastSuccessfulDeliver is null (#1204) --- src/Entity/Instance.php | 3 ++- src/Repository/InstanceRepository.php | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Entity/Instance.php b/src/Entity/Instance.php index 270d9fddd..748ba1707 100644 --- a/src/Entity/Instance.php +++ b/src/Entity/Instance.php @@ -100,6 +100,7 @@ public function getFailedDelivers(): int public function isDead(): bool { - return $this->getLastSuccessfulDeliver() < self::getDateBeforeDead() && $this->getFailedDelivers() >= self::NUMBER_OF_FAILED_DELIVERS_UNTIL_DEAD; + return ($this->getLastSuccessfulDeliver() < self::getDateBeforeDead() || null === $this->getLastSuccessfulDeliver()) + && $this->getFailedDelivers() >= self::NUMBER_OF_FAILED_DELIVERS_UNTIL_DEAD; } } diff --git a/src/Repository/InstanceRepository.php b/src/Repository/InstanceRepository.php index 7b9a8fd03..1ca67be85 100644 --- a/src/Repository/InstanceRepository.php +++ b/src/Repository/InstanceRepository.php @@ -84,7 +84,7 @@ public function getDeadInstances(): array { return $this->createQueryBuilder('i') ->where('i.failedDelivers >= :numToDead') - ->andWhere('i.lastSuccessfulDeliver < :dateBeforeDead') + ->andWhere('i.lastSuccessfulDeliver < :dateBeforeDead OR i.lastSuccessfulDeliver IS NULL') ->setParameter('numToDead', Instance::NUMBER_OF_FAILED_DELIVERS_UNTIL_DEAD) ->setParameter('dateBeforeDead', Instance::getDateBeforeDead()) ->orderBy('i.id') From a96ec890dd16a4efe9e238713abb4e928ccf266b Mon Sep 17 00:00:00 2001 From: TheVillageGuy <47496248+TheVillageGuy@users.noreply.github.com> Date: Wed, 6 Nov 2024 10:35:49 +0100 Subject: [PATCH 331/335] increase pm.max_children (#1206) --- docs/02-admin/01-installation/bare_metal.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/02-admin/01-installation/bare_metal.md b/docs/02-admin/01-installation/bare_metal.md index 92b4da153..2ec8d2096 100644 --- a/docs/02-admin/01-installation/bare_metal.md +++ b/docs/02-admin/01-installation/bare_metal.md @@ -283,7 +283,7 @@ With the content (these are personal preferences, adjust to your needs): ```ini pm = dynamic -pm.max_children = 60 +pm.max_children = 70 pm.start_servers = 10 pm.min_spare_servers = 5 pm.max_spare_servers = 10 From facdb1b77cf0f74e66e8c04fa0c7eb8cb9946e2c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Nov 2024 11:03:13 +0000 Subject: [PATCH 332/335] Bump symfony/runtime from 7.1.1 to 7.1.7 in the php group (#1207) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 9075980b6..3f547bbd1 100644 --- a/composer.lock +++ b/composer.lock @@ -11899,16 +11899,16 @@ }, { "name": "symfony/runtime", - "version": "v7.1.1", + "version": "v7.1.7", "source": { "type": "git", "url": "https://github.com/symfony/runtime.git", - "reference": "ea34522c447dd91a2b31cb330ee4540a56ba53f6" + "reference": "9889783c17e8a68fa5e88c8e8a1a85e802558dba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/runtime/zipball/ea34522c447dd91a2b31cb330ee4540a56ba53f6", - "reference": "ea34522c447dd91a2b31cb330ee4540a56ba53f6", + "url": "https://api.github.com/repos/symfony/runtime/zipball/9889783c17e8a68fa5e88c8e8a1a85e802558dba", + "reference": "9889783c17e8a68fa5e88c8e8a1a85e802558dba", "shasum": "" }, "require": { @@ -11958,7 +11958,7 @@ "runtime" ], "support": { - "source": "https://github.com/symfony/runtime/tree/v7.1.1" + "source": "https://github.com/symfony/runtime/tree/v7.1.7" }, "funding": [ { @@ -11974,7 +11974,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:55:39+00:00" + "time": "2024-11-05T16:45:54+00:00" }, { "name": "symfony/scheduler", From 5a8733e857229e8b1a9c11f6212b10369e14b01a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Nov 2024 11:08:15 +0000 Subject: [PATCH 333/335] Bump the php group with 4 updates (#1209) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- composer.lock | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/composer.lock b/composer.lock index 3f547bbd1..2dd266e12 100644 --- a/composer.lock +++ b/composer.lock @@ -9349,16 +9349,16 @@ }, { "name": "symfony/http-client", - "version": "v7.1.5", + "version": "v7.1.7", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "abca35865118edf35a23f2f24978a1784c831cb4" + "reference": "90ab2a4992dcf5d1f19a9b8737eba36a7c305fd0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/abca35865118edf35a23f2f24978a1784c831cb4", - "reference": "abca35865118edf35a23f2f24978a1784c831cb4", + "url": "https://api.github.com/repos/symfony/http-client/zipball/90ab2a4992dcf5d1f19a9b8737eba36a7c305fd0", + "reference": "90ab2a4992dcf5d1f19a9b8737eba36a7c305fd0", "shasum": "" }, "require": { @@ -9423,7 +9423,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v7.1.5" + "source": "https://github.com/symfony/http-client/tree/v7.1.7" }, "funding": [ { @@ -9439,7 +9439,7 @@ "type": "tidelift" } ], - "time": "2024-09-20T13:35:23+00:00" + "time": "2024-11-05T16:45:54+00:00" }, { "name": "symfony/http-client-contracts", @@ -9521,16 +9521,16 @@ }, { "name": "symfony/http-foundation", - "version": "v7.1.6", + "version": "v7.1.7", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "3d7bbf071b25f802f7d55524d408bed414ea71e2" + "reference": "5183b61657807099d98f3367bcccb850238b17a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/3d7bbf071b25f802f7d55524d408bed414ea71e2", - "reference": "3d7bbf071b25f802f7d55524d408bed414ea71e2", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/5183b61657807099d98f3367bcccb850238b17a9", + "reference": "5183b61657807099d98f3367bcccb850238b17a9", "shasum": "" }, "require": { @@ -9578,7 +9578,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.1.6" + "source": "https://github.com/symfony/http-foundation/tree/v7.1.7" }, "funding": [ { @@ -9594,7 +9594,7 @@ "type": "tidelift" } ], - "time": "2024-10-11T19:23:14+00:00" + "time": "2024-11-06T09:02:46+00:00" }, { "name": "symfony/http-kernel", @@ -11377,16 +11377,16 @@ }, { "name": "symfony/process", - "version": "v7.1.6", + "version": "v7.1.7", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "6aaa189ddb4ff6b5de8fa3210f2fb42c87b4d12e" + "reference": "9b8a40b7289767aa7117e957573c2a535efe6585" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/6aaa189ddb4ff6b5de8fa3210f2fb42c87b4d12e", - "reference": "6aaa189ddb4ff6b5de8fa3210f2fb42c87b4d12e", + "url": "https://api.github.com/repos/symfony/process/zipball/9b8a40b7289767aa7117e957573c2a535efe6585", + "reference": "9b8a40b7289767aa7117e957573c2a535efe6585", "shasum": "" }, "require": { @@ -11418,7 +11418,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.1.6" + "source": "https://github.com/symfony/process/tree/v7.1.7" }, "funding": [ { @@ -11434,7 +11434,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-11-06T09:25:12+00:00" }, { "name": "symfony/property-access", @@ -14629,16 +14629,16 @@ }, { "name": "twig/twig", - "version": "v3.14.0", + "version": "v3.14.1", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "126b2c97818dbff0cdf3fbfc881aedb3d40aae72" + "reference": "f405356d20fb43603bcadc8b09bfb676cb04a379" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/126b2c97818dbff0cdf3fbfc881aedb3d40aae72", - "reference": "126b2c97818dbff0cdf3fbfc881aedb3d40aae72", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/f405356d20fb43603bcadc8b09bfb676cb04a379", + "reference": "f405356d20fb43603bcadc8b09bfb676cb04a379", "shasum": "" }, "require": { @@ -14692,7 +14692,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.14.0" + "source": "https://github.com/twigphp/Twig/tree/v3.14.1" }, "funding": [ { @@ -14704,7 +14704,7 @@ "type": "tidelift" } ], - "time": "2024-09-09T17:55:12+00:00" + "time": "2024-11-06T18:17:38+00:00" }, { "name": "web-token/jwt-library", From 2c52c2123c74db9ec31da2a6381cd71622771cc4 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Fri, 8 Nov 2024 14:00:52 +0100 Subject: [PATCH 334/335] Fix private comments being retrieved via API (#1208) --- .../Api/Entry/Comments/EntryCommentsRetrieveApi.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Controller/Api/Entry/Comments/EntryCommentsRetrieveApi.php b/src/Controller/Api/Entry/Comments/EntryCommentsRetrieveApi.php index 9631da487..30f7e5291 100644 --- a/src/Controller/Api/Entry/Comments/EntryCommentsRetrieveApi.php +++ b/src/Controller/Api/Entry/Comments/EntryCommentsRetrieveApi.php @@ -155,8 +155,13 @@ public function __invoke( $dtos = []; foreach ($comments->getCurrentPageResults() as $value) { - \assert($value instanceof EntryComment); - array_push($dtos, $this->serializeCommentTree($value)); + try { + \assert($value instanceof EntryComment); + $this->handlePrivateContent($value); + array_push($dtos, $this->serializeCommentTree($value)); + } catch (\Exception $e) { + continue; + } } return new JsonResponse( From 944fa5f606447a971499ad24dd3688ffcad0a78d Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Fri, 8 Nov 2024 18:15:05 +0100 Subject: [PATCH 335/335] Fix delivering to oneself (#1211) --- src/Service/DeliverManager.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Service/DeliverManager.php b/src/Service/DeliverManager.php index c79f5c485..7621d0c67 100644 --- a/src/Service/DeliverManager.php +++ b/src/Service/DeliverManager.php @@ -6,6 +6,7 @@ use App\Entity\Traits\ActivityPubActorTrait; use App\Message\ActivityPub\Outbox\DeliverMessage; +use Psr\Log\LoggerInterface; use Symfony\Component\Messenger\MessageBusInterface; readonly class DeliverManager @@ -13,6 +14,7 @@ public function __construct( private SettingsManager $settingsManager, private MessageBusInterface $bus, + private LoggerInterface $logger, ) { } @@ -32,6 +34,11 @@ public function deliver(array $inboxes, array $activity): void continue; } + if ($this->settingsManager->isLocalUrl($inboxUrl)) { + $this->logger->warning('tried delivering to a local url, {payload}', ['payload' => $activity]); + continue; + } + $this->bus->dispatch(new DeliverMessage($inboxUrl, $activity)); } }