diff --git a/app/Http/Controllers/GroupController.php b/app/Http/Controllers/GroupController.php
index fe69022718..ca28014d04 100644
--- a/app/Http/Controllers/GroupController.php
+++ b/app/Http/Controllers/GroupController.php
@@ -455,7 +455,7 @@ public function delete($id): RedirectResponse
$group->delete();
return redirect('/group')->with('success', __('groups.delete_succeeded', [
- 'name' => $name,
+ 'name' => e($name),
]));
} else {
return redirect('/user/forbidden');
@@ -576,7 +576,7 @@ public function getJoinGroup($group_id): RedirectResponse
return redirect()
->back()
->with('success', __('groups.now_following', [
- 'name' => $group->name,
+ 'name' => e($group->name),
'link' => url('/group/view/'.$group->idgroups),
]));
} catch (\Exception $e) {
@@ -661,7 +661,7 @@ public function inviteNearbyRestarter($groupId, $userId): RedirectResponse
}
}
- return redirect('/group/nearby/'.intval($groupId))->with('success', $user->name.' has been invited');
+ return redirect('/group/nearby/'.intval($groupId))->with('success', e($user->name).' has been invited');
}
/**
diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php
index fe174a0c8f..419ba1f523 100644
--- a/app/Http/Controllers/UserController.php
+++ b/app/Http/Controllers/UserController.php
@@ -294,7 +294,7 @@ public function postSoftDeleteUser(Request $request): RedirectResponse
if (Auth::id() !== $user_id) {
return redirect('user/all')->with('danger', __('profile.soft_deleted', [
- 'name' => $old_user_name
+ 'name' => e($old_user_name)
]));
} else {
return redirect('login');
diff --git a/app/Http/Middleware/AcceptUserInvites.php b/app/Http/Middleware/AcceptUserInvites.php
index 465d1c2af1..3631e4d762 100644
--- a/app/Http/Middleware/AcceptUserInvites.php
+++ b/app/Http/Middleware/AcceptUserInvites.php
@@ -45,13 +45,13 @@ public function handle(Request $request, Closure $next): Response
$acceptance->delete();
$request->session()->push('invites-feedback', __('groups.you_have_joined', [
'url' => url("/group/view/{$group->idgroups}"),
- 'name' => $group->name
+ 'name' => e($group->name)
]));
// Else that must mean the User is already part of the Group.
// We can then delete the Invite and create a new session
} else {
- $request->session()->push('invites-feedback', 'You are already a member of idgroups}").'">'.e($group->name).'');
}
}
$request->session()->forget('groups');
@@ -78,13 +78,13 @@ public function handle(Request $request, Closure $next): Response
$acceptance->delete();
$request->session()->push('invites-feedback', __('events.you_have_joined', [
'url' => url("/party/view/{$event->idevents}"),
- 'name' => $event->venue
+ 'name' => e($event->venue)
]));
// Else that must mean the User is already part of the Event.
// We can then delete the Invite and create a new session
} else {
- $request->session()->push('invites-feedback', 'You are already a member of idevents}").'">'.e($event->venue).'');
}
}
$request->session()->forget('events');
diff --git a/app/Models/Brands.php b/app/Models/Brands.php
index bb0dad6dd1..1535a94715 100644
--- a/app/Models/Brands.php
+++ b/app/Models/Brands.php
@@ -21,4 +21,9 @@ class Brands extends Model
* @var array
*/
protected $hidden = [];
+
+ public function setBrandNameAttribute($value)
+ {
+ $this->attributes['brand_name'] = $value === null ? null : strip_tags((string) $value);
+ }
}
diff --git a/app/Models/Category.php b/app/Models/Category.php
index 0b8f0ddf20..e678160513 100644
--- a/app/Models/Category.php
+++ b/app/Models/Category.php
@@ -33,6 +33,11 @@ class Category extends Model
// Setters
+ public function setNameAttribute($value)
+ {
+ $this->attributes['name'] = $value === null ? null : strip_tags((string) $value);
+ }
+
//Getters
public function findAll()
{
diff --git a/app/Models/Group.php b/app/Models/Group.php
index b949d3d555..a49a083c1a 100644
--- a/app/Models/Group.php
+++ b/app/Models/Group.php
@@ -12,6 +12,7 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Lang;
use Illuminate\Support\Facades\Log;
+use Stevebauman\Purify\Facades\Purify;
use OwenIt\Auditing\Contracts\Auditable;
use Illuminate\Database\Eloquent\SoftDeletes;
@@ -446,6 +447,16 @@ public function setDistanceAttribute($val)
$this->distance = $val;
}
+ public function setNameAttribute($value)
+ {
+ $this->attributes['name'] = $value === null ? null : strip_tags((string) $value);
+ }
+
+ public function setFreeTextAttribute($value)
+ {
+ $this->attributes['free_text'] = $value === null ? null : Purify::clean((string) $value);
+ }
+
public function createDiscourseGroup() {
// Get the host who created the group.
$success = false;
diff --git a/app/Models/GroupTags.php b/app/Models/GroupTags.php
index ae1ad1bffc..9ffbeba2a0 100644
--- a/app/Models/GroupTags.php
+++ b/app/Models/GroupTags.php
@@ -42,5 +42,10 @@ public function groupTagGroups(): HasMany
// Setters
+ public function setTagNameAttribute($value)
+ {
+ $this->attributes['tag_name'] = $value === null ? null : strip_tags((string) $value);
+ }
+
//Getters
}
diff --git a/app/Models/Network.php b/app/Models/Network.php
index 2a0bda8ba6..fa18de9afb 100644
--- a/app/Models/Network.php
+++ b/app/Models/Network.php
@@ -6,11 +6,22 @@
use Illuminate\Database\Eloquent\Factories\HasFactory;
use App\Models\Group;
use Illuminate\Database\Eloquent\Model;
+use Stevebauman\Purify\Facades\Purify;
class Network extends Model
{
use HasFactory;
+ public function setNameAttribute($value)
+ {
+ $this->attributes['name'] = $value === null ? null : strip_tags((string) $value);
+ }
+
+ public function setDescriptionAttribute($value)
+ {
+ $this->attributes['description'] = $value === null ? null : Purify::clean((string) $value);
+ }
+
public function groups(): BelongsToMany
{
return $this->belongsToMany(Group::class, 'group_network', 'network_id', 'group_id');
diff --git a/app/Models/Party.php b/app/Models/Party.php
index 25aadd1a2e..e72a36a3b4 100644
--- a/app/Models/Party.php
+++ b/app/Models/Party.php
@@ -13,6 +13,7 @@
use DB;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
+use Stevebauman\Purify\Facades\Purify;
use Illuminate\Support\Str;
use Notification;
use OwenIt\Auditing\Contracts\Auditable;
@@ -767,6 +768,16 @@ public function getEventEndUtcAttribute() {
return array_key_exists('event_end_utc', $this->attributes) ? Carbon::parse($this->attributes['event_end_utc'], 'UTC')->toIso8601String() : null;
}
+ public function setVenueAttribute($value)
+ {
+ $this->attributes['venue'] = $value === null ? null : strip_tags((string) $value);
+ }
+
+ public function setFreeTextAttribute($value)
+ {
+ $this->attributes['free_text'] = $value === null ? null : Purify::clean((string) $value);
+ }
+
// Mutators for previous event_date/start/end fields. These are now superceded by the UTC fields and therefore
// should never be set directly. Throw exceptions to ensure that they are not.
public function setEventDateAttribute($val) {
diff --git a/app/Models/Skills.php b/app/Models/Skills.php
index fb5a5a98b8..efa9d547a0 100644
--- a/app/Models/Skills.php
+++ b/app/Models/Skills.php
@@ -26,5 +26,10 @@ class Skills extends Model
// Setters
+ public function setSkillNameAttribute($value)
+ {
+ $this->attributes['skill_name'] = $value === null ? null : strip_tags((string) $value);
+ }
+
//Getters
}
diff --git a/app/Models/User.php b/app/Models/User.php
index 9cd00516e5..40c1d0bd55 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -9,6 +9,7 @@
use Illuminate\Database\Eloquent\Factories\HasFactory;
use App\Events\UserDeleted;
use App\Events\UserUpdated;
+use Stevebauman\Purify\Facades\Purify;
use App\Helpers\Fixometer;
use App\Models\Network;
use App\Models\UserGroups;
@@ -64,6 +65,21 @@ class User extends Authenticatable implements Auditable, HasLocalePreference
'remember_token',
];
+ public function setNameAttribute($value)
+ {
+ $this->attributes['name'] = $value === null ? null : strip_tags((string) $value);
+ }
+
+ public function setLocationAttribute($value)
+ {
+ $this->attributes['location'] = $value === null ? null : strip_tags((string) $value);
+ }
+
+ public function setBiographyAttribute($value)
+ {
+ $this->attributes['biography'] = $value === null ? null : Purify::clean((string) $value);
+ }
+
/**
* The event map for the model.
*
diff --git a/composer.json b/composer.json
index 88c2ac6508..164523713f 100644
--- a/composer.json
+++ b/composer.json
@@ -44,9 +44,10 @@
"sentry/sentry-laravel": "^4.13",
"soundasleep/html2text": "^1.1",
"spatie/calendar-links": "^1.6",
- "spatie/laravel-validation-rules": "^3.4",
"spatie/laravel-html": "^3.12.0",
+ "spatie/laravel-validation-rules": "^3.4",
"spinen/laravel-discourse-sso": "dev-l12-compatibility",
+ "stevebauman/purify": "^6.3",
"symfony/http-client": "^7.2",
"symfony/http-foundation": "^7.2",
"symfony/mailgun-mailer": "^7.2",
diff --git a/composer.lock b/composer.lock
index 0be2dcd596..dffeae7e4c 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": "a79d8dc54c6b1514c5b254e265806d8f",
+ "content-hash": "3c3716ad51a3bef71683f8aa7d634fe5",
"packages": [
{
"name": "addwiki/mediawiki-api",
@@ -1706,6 +1706,67 @@
],
"time": "2023-06-01T07:04:22+00:00"
},
+ {
+ "name": "ezyang/htmlpurifier",
+ "version": "v4.19.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/ezyang/htmlpurifier.git",
+ "reference": "b287d2a16aceffbf6e0295559b39662612b77fcf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/b287d2a16aceffbf6e0295559b39662612b77fcf",
+ "reference": "b287d2a16aceffbf6e0295559b39662612b77fcf",
+ "shasum": ""
+ },
+ "require": {
+ "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0"
+ },
+ "require-dev": {
+ "cerdic/css-tidy": "^1.7 || ^2.0",
+ "simpletest/simpletest": "dev-master"
+ },
+ "suggest": {
+ "cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.",
+ "ext-bcmath": "Used for unit conversion and imagecrash protection",
+ "ext-iconv": "Converts text to and from non-UTF-8 encodings",
+ "ext-tidy": "Used for pretty-printing HTML"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "library/HTMLPurifier.composer.php"
+ ],
+ "psr-0": {
+ "HTMLPurifier": "library/"
+ },
+ "exclude-from-classmap": [
+ "/library/HTMLPurifier/Language/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "LGPL-2.1-or-later"
+ ],
+ "authors": [
+ {
+ "name": "Edward Z. Yang",
+ "email": "admin@htmlpurifier.org",
+ "homepage": "http://ezyang.com"
+ }
+ ],
+ "description": "Standards compliant HTML filter written in PHP",
+ "homepage": "http://htmlpurifier.org/",
+ "keywords": [
+ "html"
+ ],
+ "support": {
+ "issues": "https://github.com/ezyang/htmlpurifier/issues",
+ "source": "https://github.com/ezyang/htmlpurifier/tree/v4.19.0"
+ },
+ "time": "2025-10-17T16:34:55+00:00"
+ },
{
"name": "filp/whoops",
"version": "2.18.0",
@@ -7177,6 +7238,72 @@
},
"time": "2025-02-17T00:51:48+00:00"
},
+ {
+ "name": "stevebauman/purify",
+ "version": "v6.3.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/stevebauman/purify.git",
+ "reference": "deba4aa55a45a7593c369b52d481c87b545a5bf8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/stevebauman/purify/zipball/deba4aa55a45a7593c369b52d481c87b545a5bf8",
+ "reference": "deba4aa55a45a7593c369b52d481c87b545a5bf8",
+ "shasum": ""
+ },
+ "require": {
+ "ezyang/htmlpurifier": "^4.17",
+ "illuminate/contracts": "^7.0|^8.0|^9.0|^10.0|^11.0|^12.0|^13.0",
+ "illuminate/support": "^7.0|^8.0|^9.0|^10.0|^11.0|^12.0|^13.0",
+ "php": ">=7.4"
+ },
+ "require-dev": {
+ "orchestra/testbench": "^5.0|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
+ "phpunit/phpunit": "^8.0|^9.0|^10.0|^11.5.3|^12.5.12"
+ },
+ "type": "library",
+ "extra": {
+ "laravel": {
+ "aliases": {
+ "Purify": "Stevebauman\\Purify\\Facades\\Purify"
+ },
+ "providers": [
+ "Stevebauman\\Purify\\PurifyServiceProvider"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Stevebauman\\Purify\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Steve Bauman",
+ "email": "steven_bauman@outlook.com"
+ }
+ ],
+ "description": "An HTML Purifier / Sanitizer for Laravel",
+ "keywords": [
+ "Purifier",
+ "clean",
+ "cleaner",
+ "html",
+ "laravel",
+ "purification",
+ "purify"
+ ],
+ "support": {
+ "issues": "https://github.com/stevebauman/purify/issues",
+ "source": "https://github.com/stevebauman/purify/tree/v6.3.2"
+ },
+ "time": "2026-03-18T16:42:42+00:00"
+ },
{
"name": "swagger-api/swagger-ui",
"version": "v5.21.0",
@@ -13980,5 +14107,5 @@
"php": "^8.2"
},
"platform-dev": {},
- "plugin-api-version": "2.6.0"
+ "plugin-api-version": "2.9.0"
}
diff --git a/config/purify.php b/config/purify.php
new file mode 100644
index 0000000000..e9b68556f9
--- /dev/null
+++ b/config/purify.php
@@ -0,0 +1,120 @@
+ 'default',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Config sets
+ |--------------------------------------------------------------------------
+ |
+ | Here you may configure various sets of configuration for differentiated use of HTMLPurifier.
+ | A specific set of configuration can be applied by calling the "config($name)" method on
+ | a Purify instance. Feel free to add/remove/customize these attributes as you wish.
+ |
+ | Documentation: http://htmlpurifier.org/live/configdoc/plain.html
+ |
+ | Core.Encoding The encoding to convert input to.
+ | HTML.Doctype Doctype to use during filtering.
+ | HTML.Allowed The allowed HTML Elements with their allowed attributes.
+ | HTML.ForbiddenElements The forbidden HTML elements. Elements that are listed in this
+ | string will be removed, however their content will remain.
+ | CSS.AllowedProperties The Allowed CSS properties.
+ | AutoFormat.AutoParagraph Newlines are converted in to paragraphs whenever possible.
+ | AutoFormat.RemoveEmpty Remove empty elements that contribute no semantic information to the document.
+ |
+ */
+
+ 'configs' => [
+
+ 'default' => [
+ 'Core.Encoding' => 'utf-8',
+ 'HTML.Doctype' => 'HTML 4.01 Transitional',
+ 'HTML.Allowed' => 'h1,h2,h3,h4,h5,h6,b,u,strong,i,em,s,del,a[href|title],ul,ol,li,p[style],br,span,img[width|height|alt|src],blockquote',
+ 'HTML.ForbiddenElements' => '',
+ 'CSS.AllowedProperties' => 'font,font-size,font-weight,font-style,font-family,text-decoration,padding-left,color,background-color,text-align',
+ 'URI.AllowedSchemes' => [
+ 'http' => true,
+ 'https' => true,
+ 'mailto' => true,
+ ],
+ 'AutoFormat.AutoParagraph' => false,
+ 'AutoFormat.RemoveEmpty' => false,
+ ],
+
+ ],
+
+ /*
+ |--------------------------------------------------------------------------
+ | HTMLPurifier definitions
+ |--------------------------------------------------------------------------
+ |
+ | Here you may specify a class that augments the HTML definitions used by
+ | HTMLPurifier. Additional HTML5 definitions are provided out of the box.
+ | When specifying a custom class, make sure it implements the interface:
+ |
+ | \Stevebauman\Purify\Definitions\Definition
+ |
+ | Note that these definitions are applied to every Purifier instance.
+ |
+ | Documentation: http://htmlpurifier.org/docs/enduser-customize.html
+ |
+ */
+
+ 'definitions' => Html5Definition::class,
+
+ /*
+ |--------------------------------------------------------------------------
+ | HTMLPurifier CSS definitions
+ |--------------------------------------------------------------------------
+ |
+ | Here you may specify a class that augments the CSS definitions used by
+ | HTMLPurifier. When specifying a custom class, make sure it implements
+ | the interface:
+ |
+ | \Stevebauman\Purify\Definitions\CssDefinition
+ |
+ | Note that these definitions are applied to every Purifier instance.
+ |
+ | CSS should be extending $definition->info['css-attribute'] = values
+ | See HTMLPurifier_CSSDefinition for further explanation
+ |
+ */
+
+ 'css-definitions' => null,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Serializer
+ |--------------------------------------------------------------------------
+ |
+ | The storage implementation where HTMLPurifier can store its serializer files.
+ | If the filesystem cache is in use, the path must be writable through the
+ | storage disk by the web server, otherwise an exception will be thrown.
+ |
+ */
+
+ 'serializer' => [
+ 'driver' => env('CACHE_STORE', env('CACHE_DRIVER', 'file')),
+ 'cache' => \Stevebauman\Purify\Cache\CacheDefinitionCache::class,
+ ],
+
+ // 'serializer' => [
+ // 'disk' => env('FILESYSTEM_DISK', 'local'),
+ // 'path' => 'purify',
+ // 'cache' => \Stevebauman\Purify\Cache\FilesystemDefinitionCache::class,
+ // ],
+
+];
diff --git a/package-lock.json b/package-lock.json
index b07eb4401f..d8a72208d4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -17,6 +17,7 @@
"bootstrap4-datetimepicker": "^5.2.3",
"chart.js": "^2.7.2",
"codemirror": "^5.39.2",
+ "dompurify": "^3.4.0",
"dropzone": "^5.7.2",
"ekko-lightbox": "^5.3.0",
"floatthead": "^2.1.2",
@@ -104,23 +105,74 @@
}
},
"node_modules/@asamuzakjp/css-color": {
- "version": "3.1.4",
- "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.1.4.tgz",
- "integrity": "sha512-SeuBV4rnjpFNjI8HSgKUwteuFdkHwkboq31HWzznuqgySQir+jSTczoWVVL4jvOjKjuH80fMDG0Fvg1Sb+OJsA==",
+ "version": "5.1.11",
+ "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.1.11.tgz",
+ "integrity": "sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@asamuzakjp/generational-cache": "^1.0.1",
+ "@csstools/css-calc": "^3.2.0",
+ "@csstools/css-color-parser": "^4.1.0",
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0"
+ },
+ "engines": {
+ "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@asamuzakjp/dom-selector": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-7.1.1.tgz",
+ "integrity": "sha512-67RZDnYRc8H/8MLDgQCDE//zoqVFwajkepHZgmXrbwybzXOEwOWGPYGmALYl9J2DOLfFPPs6kKCqmbzV895hTQ==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@asamuzakjp/generational-cache": "^1.0.1",
+ "@asamuzakjp/nwsapi": "^2.3.9",
+ "bidi-js": "^1.0.3",
+ "css-tree": "^3.2.1",
+ "is-potential-custom-element-name": "^1.0.1"
+ },
+ "engines": {
+ "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@asamuzakjp/dom-selector/node_modules/css-tree": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz",
+ "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==",
"dev": true,
"peer": true,
"dependencies": {
- "@csstools/css-calc": "^2.1.3",
- "@csstools/css-color-parser": "^3.0.9",
- "@csstools/css-parser-algorithms": "^3.0.4",
- "@csstools/css-tokenizer": "^3.0.3",
- "lru-cache": "^10.4.3"
+ "mdn-data": "2.27.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
}
},
- "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": {
- "version": "10.4.3",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
- "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "node_modules/@asamuzakjp/dom-selector/node_modules/mdn-data": {
+ "version": "2.27.1",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz",
+ "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==",
+ "dev": true,
+ "peer": true
+ },
+ "node_modules/@asamuzakjp/generational-cache": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@asamuzakjp/generational-cache/-/generational-cache-1.0.1.tgz",
+ "integrity": "sha512-wajfB8KqzMCN2KGNFdLkReeHncd0AslUSrvHVvvYWuU8ghncRJoA50kT3zP9MVL0+9g4/67H+cdvBskj9THPzg==",
+ "dev": true,
+ "peer": true,
+ "engines": {
+ "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@asamuzakjp/nwsapi": {
+ "version": "2.3.9",
+ "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz",
+ "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==",
"dev": true,
"peer": true
},
@@ -1914,6 +1966,40 @@
"integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
"dev": true
},
+ "node_modules/@bramus/specificity": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/@bramus/specificity/-/specificity-2.4.2.tgz",
+ "integrity": "sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "css-tree": "^3.0.0"
+ },
+ "bin": {
+ "specificity": "bin/cli.js"
+ }
+ },
+ "node_modules/@bramus/specificity/node_modules/css-tree": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz",
+ "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "mdn-data": "2.27.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
+ }
+ },
+ "node_modules/@bramus/specificity/node_modules/mdn-data": {
+ "version": "2.27.1",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz",
+ "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==",
+ "dev": true,
+ "peer": true
+ },
"node_modules/@colors/colors": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
@@ -1925,9 +2011,9 @@
}
},
"node_modules/@csstools/color-helpers": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.2.tgz",
- "integrity": "sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==",
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.0.2.tgz",
+ "integrity": "sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==",
"dev": true,
"funding": [
{
@@ -1941,13 +2027,13 @@
],
"peer": true,
"engines": {
- "node": ">=18"
+ "node": ">=20.19.0"
}
},
"node_modules/@csstools/css-calc": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.3.tgz",
- "integrity": "sha512-XBG3talrhid44BY1x3MHzUx/aTG8+x/Zi57M4aTKK9RFB4aLlF3TTSzfzn8nWVHWL3FgAXAxmupmDd6VWww+pw==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.2.0.tgz",
+ "integrity": "sha512-bR9e6o2BDB12jzN/gIbjHa5wLJ4UjD1CB9pM7ehlc0ddk6EBz+yYS1EV2MF55/HUxrHcB/hehAyt5vhsA3hx7w==",
"dev": true,
"funding": [
{
@@ -1961,17 +2047,17 @@
],
"peer": true,
"engines": {
- "node": ">=18"
+ "node": ">=20.19.0"
},
"peerDependencies": {
- "@csstools/css-parser-algorithms": "^3.0.4",
- "@csstools/css-tokenizer": "^3.0.3"
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0"
}
},
"node_modules/@csstools/css-color-parser": {
- "version": "3.0.9",
- "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.9.tgz",
- "integrity": "sha512-wILs5Zk7BU86UArYBJTPy/FMPPKVKHMj1ycCEyf3VUptol0JNRLFU/BZsJ4aiIHJEbSLiizzRrw8Pc1uAEDrXw==",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.1.0.tgz",
+ "integrity": "sha512-U0KhLYmy2GVj6q4T3WaAe6NPuFYCPQoE3b0dRGxejWDgcPp8TP7S5rVdM5ZrFaqu4N67X8YaPBw14dQSYx3IyQ==",
"dev": true,
"funding": [
{
@@ -1985,21 +2071,21 @@
],
"peer": true,
"dependencies": {
- "@csstools/color-helpers": "^5.0.2",
- "@csstools/css-calc": "^2.1.3"
+ "@csstools/color-helpers": "^6.0.2",
+ "@csstools/css-calc": "^3.2.0"
},
"engines": {
- "node": ">=18"
+ "node": ">=20.19.0"
},
"peerDependencies": {
- "@csstools/css-parser-algorithms": "^3.0.4",
- "@csstools/css-tokenizer": "^3.0.3"
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0"
}
},
"node_modules/@csstools/css-parser-algorithms": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.4.tgz",
- "integrity": "sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz",
+ "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==",
"dev": true,
"funding": [
{
@@ -2013,16 +2099,16 @@
],
"peer": true,
"engines": {
- "node": ">=18"
+ "node": ">=20.19.0"
},
"peerDependencies": {
- "@csstools/css-tokenizer": "^3.0.3"
+ "@csstools/css-tokenizer": "^4.0.0"
}
},
"node_modules/@csstools/css-tokenizer": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.3.tgz",
- "integrity": "sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz",
+ "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==",
"dev": true,
"funding": [
{
@@ -2036,7 +2122,7 @@
],
"peer": true,
"engines": {
- "node": ">=18"
+ "node": ">=20.19.0"
}
},
"node_modules/@discoveryjs/json-ext": {
@@ -2048,6 +2134,24 @@
"node": ">=10.0.0"
}
},
+ "node_modules/@exodus/bytes": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.0.tgz",
+ "integrity": "sha512-UY0nlA+feH81UGSHv92sLEPLCeZFjXOuHhrIo0HQydScuQc8s0A7kL/UdgwgDq8g8ilksmuoF35YVTNphV2aBQ==",
+ "dev": true,
+ "peer": true,
+ "engines": {
+ "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
+ },
+ "peerDependencies": {
+ "@noble/hashes": "^1.8.0 || ^2.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@noble/hashes": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@istanbuljs/load-nyc-config": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
@@ -3643,9 +3747,9 @@
"dev": true
},
"node_modules/@types/leaflet": {
- "version": "1.9.17",
- "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.17.tgz",
- "integrity": "sha512-IJ4K6t7I3Fh5qXbQ1uwL3CFVbCi6haW9+53oLWgdKlLP7EaS21byWFJxxqOx9y8I0AP0actXSJLVMbyvxhkUTA==",
+ "version": "1.9.21",
+ "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.21.tgz",
+ "integrity": "sha512-TbAd9DaPGSnzp6QvtYngntMZgcRk+igFELwR2N99XZn7RXUdKgsXMR+28bUO0rPsWp8MIu/f47luLIQuSLYv/w==",
"peer": true,
"dependencies": {
"@types/geojson": "*"
@@ -3783,6 +3887,12 @@
"integrity": "sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==",
"dev": true
},
+ "node_modules/@types/trusted-types": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
+ "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
+ "optional": true
+ },
"node_modules/@types/ws": {
"version": "8.18.1",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
@@ -5021,6 +5131,16 @@
"node": ">= 6.0.0"
}
},
+ "node_modules/bidi-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz",
+ "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "require-from-string": "^2.0.2"
+ }
+ },
"node_modules/big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
@@ -6492,20 +6612,20 @@
}
},
"node_modules/css-loader": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz",
- "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==",
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.4.tgz",
+ "integrity": "sha512-vv3J9tlOl04WjiMvHQI/9tmIrCxVrj6PFbHemBB1iihpeRbi/I4h033eoFIhwxBBqLhI0KYFS7yvynBFhIZfTw==",
"dev": true,
"peer": true,
"dependencies": {
"icss-utils": "^5.1.0",
- "postcss": "^8.4.33",
+ "postcss": "^8.4.40",
"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"
+ "semver": "^7.6.3"
},
"engines": {
"node": ">= 18.12.0"
@@ -6515,7 +6635,7 @@
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
- "@rspack/core": "0.x || 1.x",
+ "@rspack/core": "0.x || ^1.0.0 || ^2.0.0-0",
"webpack": "^5.27.0"
},
"peerDependenciesMeta": {
@@ -6841,9 +6961,9 @@
}
},
"node_modules/decimal.js": {
- "version": "10.5.0",
- "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz",
- "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==",
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz",
+ "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==",
"dev": true
},
"node_modules/dedent": {
@@ -7138,9 +7258,12 @@
}
},
"node_modules/dompurify": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.8.tgz",
- "integrity": "sha512-eVhaWoVibIzqdGYjwsBWodIQIaXFSB+cKDf4cfxLMsK0xiud6SE+/WCVx/Xw/UwQsa4cS3T2eITcdtmTg2UKcw=="
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.1.tgz",
+ "integrity": "sha512-JahakDAIg1gyOm7dlgWSDjV4n7Ip2PKR55NIT6jrMfIgLFgWo81vdr1/QGqWtFNRqXP9UV71oVePtjqS2ebnPw==",
+ "optionalDependencies": {
+ "@types/trusted-types": "^2.0.7"
+ }
},
"node_modules/domutils": {
"version": "1.7.0",
@@ -12659,35 +12782,36 @@
"license": "MIT"
},
"node_modules/jsdom": {
- "version": "26.1.0",
- "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz",
- "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==",
+ "version": "29.0.2",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-29.0.2.tgz",
+ "integrity": "sha512-9VnGEBosc/ZpwyOsJBCQ/3I5p7Q5ngOY14a9bf5btenAORmZfDse1ZEheMiWcJ3h81+Fv7HmJFdS0szo/waF2w==",
"dev": true,
"peer": true,
"dependencies": {
- "cssstyle": "^4.2.1",
- "data-urls": "^5.0.0",
- "decimal.js": "^10.5.0",
- "html-encoding-sniffer": "^4.0.0",
- "http-proxy-agent": "^7.0.2",
- "https-proxy-agent": "^7.0.6",
+ "@asamuzakjp/css-color": "^5.1.5",
+ "@asamuzakjp/dom-selector": "^7.0.6",
+ "@bramus/specificity": "^2.4.2",
+ "@csstools/css-syntax-patches-for-csstree": "^1.1.1",
+ "@exodus/bytes": "^1.15.0",
+ "css-tree": "^3.2.1",
+ "data-urls": "^7.0.0",
+ "decimal.js": "^10.6.0",
+ "html-encoding-sniffer": "^6.0.0",
"is-potential-custom-element-name": "^1.0.1",
- "nwsapi": "^2.2.16",
- "parse5": "^7.2.1",
- "rrweb-cssom": "^0.8.0",
+ "lru-cache": "^11.2.7",
+ "parse5": "^8.0.0",
"saxes": "^6.0.0",
"symbol-tree": "^3.2.4",
- "tough-cookie": "^5.1.1",
+ "tough-cookie": "^6.0.1",
+ "undici": "^7.24.5",
"w3c-xmlserializer": "^5.0.0",
- "webidl-conversions": "^7.0.0",
- "whatwg-encoding": "^3.1.1",
- "whatwg-mimetype": "^4.0.0",
- "whatwg-url": "^14.1.1",
- "ws": "^8.18.0",
+ "webidl-conversions": "^8.0.1",
+ "whatwg-mimetype": "^5.0.0",
+ "whatwg-url": "^16.0.1",
"xml-name-validator": "^5.0.0"
},
"engines": {
- "node": ">=18"
+ "node": "^20.19.0 || ^22.13.0 || >=24.0.0"
},
"peerDependencies": {
"canvas": "^3.0.0"
@@ -12707,156 +12831,148 @@
"jsdom": ">=10.0.0"
}
},
- "node_modules/jsdom/node_modules/agent-base": {
- "version": "7.1.3",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
- "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
+ "node_modules/jsdom/node_modules/@csstools/css-syntax-patches-for-csstree": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.3.tgz",
+ "integrity": "sha512-SH60bMfrRCJF3morcdk57WklujF4Jr/EsQUzqkarfHXEFcAR1gg7fS/chAE922Sehgzc1/+Tz5H3Ypa1HiEKrg==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
"peer": true,
- "engines": {
- "node": ">= 14"
+ "peerDependencies": {
+ "css-tree": "^3.2.1"
+ },
+ "peerDependenciesMeta": {
+ "css-tree": {
+ "optional": true
+ }
}
},
- "node_modules/jsdom/node_modules/cssstyle": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.3.1.tgz",
- "integrity": "sha512-ZgW+Jgdd7i52AaLYCriF8Mxqft0gD/R9i9wi6RWBhs1pqdPEzPjym7rvRKi397WmQFf3SlyUsszhw+VVCbx79Q==",
+ "node_modules/jsdom/node_modules/css-tree": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz",
+ "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==",
"dev": true,
"peer": true,
"dependencies": {
- "@asamuzakjp/css-color": "^3.1.2",
- "rrweb-cssom": "^0.8.0"
+ "mdn-data": "2.27.1",
+ "source-map-js": "^1.2.1"
},
"engines": {
- "node": ">=18"
+ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
}
},
"node_modules/jsdom/node_modules/data-urls": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz",
- "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-7.0.0.tgz",
+ "integrity": "sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==",
"dev": true,
"peer": true,
"dependencies": {
- "whatwg-mimetype": "^4.0.0",
- "whatwg-url": "^14.0.0"
+ "whatwg-mimetype": "^5.0.0",
+ "whatwg-url": "^16.0.0"
},
"engines": {
- "node": ">=18"
+ "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
}
},
"node_modules/jsdom/node_modules/html-encoding-sniffer": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz",
- "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz",
+ "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==",
"dev": true,
"peer": true,
"dependencies": {
- "whatwg-encoding": "^3.1.1"
+ "@exodus/bytes": "^1.6.0"
},
"engines": {
- "node": ">=18"
+ "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
}
},
- "node_modules/jsdom/node_modules/http-proxy-agent": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
- "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
+ "node_modules/jsdom/node_modules/lru-cache": {
+ "version": "11.3.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz",
+ "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==",
"dev": true,
"peer": true,
- "dependencies": {
- "agent-base": "^7.1.0",
- "debug": "^4.3.4"
- },
"engines": {
- "node": ">= 14"
+ "node": "20 || >=22"
}
},
- "node_modules/jsdom/node_modules/https-proxy-agent": {
- "version": "7.0.6",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
- "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
+ "node_modules/jsdom/node_modules/mdn-data": {
+ "version": "2.27.1",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz",
+ "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==",
"dev": true,
- "peer": true,
- "dependencies": {
- "agent-base": "^7.1.2",
- "debug": "4"
- },
- "engines": {
- "node": ">= 14"
- }
+ "peer": true
},
"node_modules/jsdom/node_modules/tough-cookie": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz",
- "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.1.tgz",
+ "integrity": "sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==",
"dev": true,
"peer": true,
"dependencies": {
- "tldts": "^6.1.32"
+ "tldts": "^7.0.5"
},
"engines": {
"node": ">=16"
}
},
"node_modules/jsdom/node_modules/tr46": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
- "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz",
+ "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==",
"dev": true,
"peer": true,
"dependencies": {
"punycode": "^2.3.1"
},
"engines": {
- "node": ">=18"
+ "node": ">=20"
}
},
"node_modules/jsdom/node_modules/webidl-conversions": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
- "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
- "dev": true,
- "peer": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/jsdom/node_modules/whatwg-encoding": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
- "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz",
+ "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==",
"dev": true,
"peer": true,
- "dependencies": {
- "iconv-lite": "0.6.3"
- },
"engines": {
- "node": ">=18"
+ "node": ">=20"
}
},
"node_modules/jsdom/node_modules/whatwg-mimetype": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
- "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz",
+ "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==",
"dev": true,
"peer": true,
"engines": {
- "node": ">=18"
+ "node": ">=20"
}
},
"node_modules/jsdom/node_modules/whatwg-url": {
- "version": "14.2.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
- "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
+ "version": "16.0.1",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-16.0.1.tgz",
+ "integrity": "sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==",
"dev": true,
"peer": true,
"dependencies": {
- "tr46": "^5.1.0",
- "webidl-conversions": "^7.0.0"
+ "@exodus/bytes": "^1.11.0",
+ "tr46": "^6.0.0",
+ "webidl-conversions": "^8.0.1"
},
"engines": {
- "node": ">=18"
+ "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
}
},
"node_modules/jsdom/node_modules/xml-name-validator": {
@@ -17185,26 +17301,26 @@
}
},
"node_modules/parse5": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
- "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz",
+ "integrity": "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==",
"dev": true,
"peer": true,
"dependencies": {
- "entities": "^6.0.0"
+ "entities": "^8.0.0"
},
"funding": {
"url": "https://github.com/inikulin/parse5?sponsor=1"
}
},
"node_modules/parse5/node_modules/entities": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.0.tgz",
- "integrity": "sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==",
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz",
+ "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==",
"dev": true,
"peer": true,
"engines": {
- "node": ">=0.12"
+ "node": ">=20.19.0"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
@@ -18259,6 +18375,11 @@
"quill": "^1.3.5"
}
},
+ "node_modules/quill-paste-smart/node_modules/dompurify": {
+ "version": "2.5.9",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.5.9.tgz",
+ "integrity": "sha512-i6mvVmWN4xo9LrhCOZrDgSs9noW6nOahbrmzjRbPF36YPyj5Ue5lgok0MHDWkG7xzpWFO2OYttXdzM7rJxHvNA=="
+ },
"node_modules/randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@@ -18657,13 +18778,6 @@
"inherits": "^2.0.1"
}
},
- "node_modules/rrweb-cssom": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz",
- "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==",
- "dev": true,
- "peer": true
- },
"node_modules/run-parallel": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@@ -18890,13 +19004,10 @@
}
},
"node_modules/semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
"dev": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
"bin": {
"semver": "bin/semver.js"
},
@@ -18904,24 +19015,6 @@
"node": ">=10"
}
},
- "node_modules/semver/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/semver/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/send": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
@@ -19999,22 +20092,22 @@
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="
},
"node_modules/tldts": {
- "version": "6.1.86",
- "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz",
- "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==",
+ "version": "7.0.28",
+ "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.28.tgz",
+ "integrity": "sha512-+Zg3vWhRUv8B1maGSTFdev9mjoo8Etn2Ayfs4cnjlD3CsGkxXX4QyW3j2WJ0wdjYcYmy7Lx2RDsZMhgCWafKIw==",
"dev": true,
"peer": true,
"dependencies": {
- "tldts-core": "^6.1.86"
+ "tldts-core": "^7.0.28"
},
"bin": {
"tldts": "bin/cli.js"
}
},
"node_modules/tldts-core": {
- "version": "6.1.86",
- "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz",
- "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==",
+ "version": "7.0.28",
+ "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.28.tgz",
+ "integrity": "sha512-7W5Efjhsc3chVdFhqtaU0KtK32J37Zcr9RKtID54nG+tIpcY79CQK/veYPODxtD/LJ4Lue66jvrQzIX2Z2/pUQ==",
"dev": true,
"peer": true
},
@@ -20197,6 +20290,16 @@
"node": "*"
}
},
+ "node_modules/undici": {
+ "version": "7.25.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-7.25.0.tgz",
+ "integrity": "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==",
+ "dev": true,
+ "peer": true,
+ "engines": {
+ "node": ">=20.18.1"
+ }
+ },
"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",
diff --git a/package.json b/package.json
index ecb0d41f12..54643f4b06 100644
--- a/package.json
+++ b/package.json
@@ -59,6 +59,7 @@
"bootstrap4-datetimepicker": "^5.2.3",
"chart.js": "^2.7.2",
"codemirror": "^5.39.2",
+ "dompurify": "^3.4.0",
"dropzone": "^5.7.2",
"ekko-lightbox": "^5.3.0",
"floatthead": "^2.1.2",
diff --git a/resources/js/components/GroupActions.vue b/resources/js/components/GroupActions.vue
index eabb0bdc6d..73046e2656 100644
--- a/resources/js/components/GroupActions.vue
+++ b/resources/js/components/GroupActions.vue
@@ -56,10 +56,10 @@