Compare commits
22 Commits
v0.10.3-et
...
v0.10.3-et
Author | SHA1 | Date | |
---|---|---|---|
![]() |
cb1314ab1d | ||
![]() |
dae6872fe8 | ||
![]() |
61b91adf25 | ||
![]() |
5f7f587477 | ||
![]() |
75b9aeea01 | ||
![]() |
fb71b5ed08 | ||
![]() |
2e8e5e73bc | ||
![]() |
befcd15298 | ||
![]() |
86d0fd04e6 | ||
![]() |
c28ed94ca0 | ||
![]() |
d139ab4a7d | ||
![]() |
6575a05a8a | ||
![]() |
3f2c3f2c0c | ||
![]() |
2c5ee7da10 | ||
![]() |
03bf4a5c5d | ||
![]() |
3fce37b735 | ||
![]() |
6c6ec227fa | ||
![]() |
128fea726e | ||
![]() |
97c44f85ef | ||
![]() |
ca2decda3a | ||
![]() |
e394a7e186 | ||
![]() |
c182f600f8 |
223
README.md
223
README.md
@@ -5,29 +5,29 @@
|
||||
<a href="https://matrix.to/#/#synapse-admin:etke.cc">
|
||||
<img alt="Community room" src="https://img.shields.io/badge/room-community_room-green?logo=matrix&label=%23synapse-admin%3Aetke.cc">
|
||||
</a><br>
|
||||
<img alt="License" src="https://img.shields.io/github/license/etkecc/synapse-admin">
|
||||
<a href="./LICENSE">
|
||||
<img alt="License" src="https://img.shields.io/github/license/etkecc/synapse-admin">
|
||||
</a>
|
||||
</h3>
|
||||
<p align="center">Manager your Synapse homeserver with ease</p>
|
||||
<p align="center">Feature-packed and visually customizable: A better way to manage your Synapse homeserver.</p>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||

|
||||
|
||||
This project is built using [react-admin](https://marmelab.com/react-admin/).
|
||||

|
||||

|
||||
|
||||
<!-- vim-markdown-toc GFM -->
|
||||
|
||||
* [Fork differences](#fork-differences)
|
||||
* [Availability](#availability)
|
||||
* [Changes](#changes)
|
||||
* [Development](#development)
|
||||
* [Support](#support)
|
||||
* [Configuration](#configuration)
|
||||
* [Prefilling login form](#prefilling-login-form)
|
||||
* [Restricting available homeserver](#restricting-available-homeserver)
|
||||
* [Protecting appservice managed users](#protecting-appservice-managed-users)
|
||||
* [Adding custom menu items](#adding-custom-menu-items)
|
||||
* [Providing support URL](#providing-support-url)
|
||||
* [Usage](#usage)
|
||||
* [Supported Synapse](#supported-synapse)
|
||||
* [Prerequisites](#prerequisites)
|
||||
@@ -43,57 +43,61 @@ This project is built using [react-admin](https://marmelab.com/react-admin/).
|
||||
|
||||
## Fork differences
|
||||
|
||||
With [Awesome-Technologies/synapse-admin](https://github.com/Awesome-Technologies/synapse-admin) as the upstream, this
|
||||
fork is intended to be a more feature-rich version of the original project. The main goal is to provide a more
|
||||
user-friendly interface for managing Synapse homeservers.
|
||||
With [Awesome-Technologies/synapse-admin](https://github.com/Awesome-Technologies/synapse-admin) as the upstream,
|
||||
this fork introduces numerous enhancements to improve usability and extend functionality,
|
||||
including support for authenticated media, advanced user management options, and visual customization.
|
||||
The full list is described below in the [Changes](#changes) section.
|
||||
|
||||
### Availability
|
||||
**Availability**
|
||||
|
||||
* As a core/default component on [etke.cc](https://etke.cc/?utm_source=github&utm_medium=readme&utm_campaign=synapse-admin)
|
||||
* Via CDN on [admin.etke.cc](https://admin.etke.cc)
|
||||
* As a standalone app on [admin.etke.cc](https://admin.etke.cc)
|
||||
* As a prebuilt distribution on [GitHub Releases](https://github.com/etkecc/synapse-admin/releases)
|
||||
* As a Docker container on [GitHub Container Registry](https://github.com/etkecc/synapse-admin/pkgs/container/synapse-admin)
|
||||
* As a component in [Matrix-Docker-Ansible-Deploy Playbook](https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/docs/configuring-playbook-synapse-admin.md)
|
||||
|
||||
### Changes
|
||||
|
||||
The following changes are already implemented:
|
||||
|
||||
* [Prevent admins from deleting themselves](https://github.com/etkecc/synapse-admin/pull/1)
|
||||
* [Fix user's default tab not being shown](https://github.com/etkecc/synapse-admin/pull/8)
|
||||
* [Add identifier when authorizing with password](https://github.com/Awesome-Technologies/synapse-admin/pull/601)
|
||||
* [Add ability to toggle whether to show locked users](https://github.com/Awesome-Technologies/synapse-admin/pull/573)
|
||||
* [Fix user's display name in header on user's page](https://github.com/etkecc/synapse-admin/pull/9)
|
||||
* [Fix footer overlapping content](https://github.com/Awesome-Technologies/synapse-admin/issues/574)
|
||||
* Switch from nginx to [SWS](https://static-web-server.net/) for serving the app, reducing the size of the Docker image
|
||||
* [Fix redirect URL after user creation](https://github.com/etkecc/synapse-admin/pull/16)
|
||||
* [Display actual Synapse errors](https://github.com/etkecc/synapse-admin/pull/17)
|
||||
* [Fix base_url being undefined on unsuccessful login](https://github.com/etkecc/synapse-admin/pull/18)
|
||||
* [Put the version into manifest.json](https://github.com/Awesome-Technologies/synapse-admin/issues/507) (later replaced
|
||||
with a proper manifest.json generation on build)
|
||||
* [Federation page improvements](https://github.com/Awesome-Technologies/synapse-admin/pull/583) (using icons)
|
||||
* [Add UI option to block deleted rooms from being rejoined](https://github.com/etkecc/synapse-admin/pull/26)
|
||||
* [Fix required fields check on Bulk registration CSV upload](https://github.com/etkecc/synapse-admin/pull/32)
|
||||
* [Fix requests with invalid MXIDs on Bulk registration](https://github.com/etkecc/synapse-admin/pull/33)
|
||||
* [Expose user avatar URL field in the UI](https://github.com/etkecc/synapse-admin/pull/27)
|
||||
* [Upgrade react-admin to v5](https://github.com/etkecc/synapse-admin/pull/40)
|
||||
* [Restrict actions on specific users](https://github.com/etkecc/synapse-admin/pull/42)
|
||||
* [Add `Contact support` menu item](https://github.com/etkecc/synapse-admin/pull/45)
|
||||
* [Provide options to delete media and redact events on user erase](https://github.com/etkecc/synapse-admin/pull/49)
|
||||
* [Authenticated Media support](https://github.com/etkecc/synapse-admin/pull/51)
|
||||
* [Better media preview/download](https://github.com/etkecc/synapse-admin/pull/53)
|
||||
* [Login with access token](https://github.com/etkecc/synapse-admin/pull/58)
|
||||
* [Fix footer causing vertical scrollbar](https://github.com/etkecc/synapse-admin/pull/60)
|
||||
* [Custom Menu Items](https://github.com/etkecc/synapse-admin/pull/79)
|
||||
* [Add user profile to the top menu](https://github.com/etkecc/synapse-admin/pull/80)
|
||||
* [Enable visual customization](https://github.com/etkecc/synapse-admin/pull/81)
|
||||
* [Fix room state events display](https://github.com/etkecc/synapse-admin/pull/100)
|
||||
* [Sanitize CSV on import](https://github.com/etkecc/synapse-admin/pull/101)
|
||||
* Allow setting version using `SYNAPSE_ADMIN_VERSION` environment variable on build (if git is not available)
|
||||
* [Add option to control user's experimental features](https://github.com/etkecc/synapse-admin/pull/111)
|
||||
* [Add random password generation on user create/edit form](https://github.com/etkecc/synapse-admin/pull/123)
|
||||
* [Add option to set user's rate limits](https://github.com/etkecc/synapse-admin/pull/125)
|
||||
* [Support configuration via /.well-known/matrix/client](https://github.com/etkecc/synapse-admin/pull/126)
|
||||
* [Prevent accidental user overwrites](https://github.com/etkecc/synapse-admin/pull/139)
|
||||
* [Allow providing login form details via GET params](https://github.com/etkecc/synapse-admin/pull/140)
|
||||
* 🛑 [Prevent admins from deleting themselves](https://github.com/etkecc/synapse-admin/pull/1)
|
||||
* 🐛 [Fix user's default tab not being shown](https://github.com/etkecc/synapse-admin/pull/8)
|
||||
* 🔑 [Add identifier when authorizing with password](https://github.com/Awesome-Technologies/synapse-admin/pull/601)
|
||||
* 🔒 [Add ability to toggle whether to show locked users](https://github.com/Awesome-Technologies/synapse-admin/pull/573)
|
||||
* 🖊️ [Fix user's display name in header on user's page](https://github.com/etkecc/synapse-admin/pull/9)
|
||||
* 🧹 [Fix footer overlapping content](https://github.com/Awesome-Technologies/synapse-admin/issues/574)
|
||||
* 🐋 Switch from nginx to [SWS](https://static-web-server.net/) for serving the app, reducing the size of the Docker image
|
||||
* 🔄 [Fix redirect URL after user creation](https://github.com/etkecc/synapse-admin/pull/16)
|
||||
* 🔍 [Display actual Synapse errors](https://github.com/etkecc/synapse-admin/pull/17)
|
||||
* ⚠️ [Fix base_url being undefined on unsuccessful login](https://github.com/etkecc/synapse-admin/pull/18)
|
||||
* 📜 [Put the version into manifest.json](https://github.com/Awesome-Technologies/synapse-admin/issues/507) (later replaced with a proper manifest.json generation on build)
|
||||
* 📊 [Federation page improvements](https://github.com/Awesome-Technologies/synapse-admin/pull/583) (using icons)
|
||||
* 🚪 [Add UI option to block deleted rooms from being rejoined](https://github.com/etkecc/synapse-admin/pull/26)
|
||||
* 🛠️ [Fix required fields check on Bulk registration CSV upload](https://github.com/etkecc/synapse-admin/pull/32)
|
||||
* 🛡️ [Fix requests with invalid MXIDs on Bulk registration](https://github.com/etkecc/synapse-admin/pull/33)
|
||||
* 🖼️ [Expose user avatar URL field in the UI](https://github.com/etkecc/synapse-admin/pull/27)
|
||||
* 🚀 [Upgrade react-admin to v5](https://github.com/etkecc/synapse-admin/pull/40)
|
||||
* 🔒 [Restrict actions on specific users](https://github.com/etkecc/synapse-admin/pull/42)
|
||||
* 📞 [Add `Contact support` menu item](https://github.com/etkecc/synapse-admin/pull/45)
|
||||
* 🧹 [Provide options to delete media and redact events on user erase](https://github.com/etkecc/synapse-admin/pull/49)
|
||||
* 🎞️ [Authenticated Media support](https://github.com/etkecc/synapse-admin/pull/51)
|
||||
* 👁️ [Better media preview/download](https://github.com/etkecc/synapse-admin/pull/53)
|
||||
* 🔐 [Login with access token](https://github.com/etkecc/synapse-admin/pull/58)
|
||||
* 📏 [Fix footer causing vertical scrollbar](https://github.com/etkecc/synapse-admin/pull/60)
|
||||
* 🍴 [Custom Menu Items](https://github.com/etkecc/synapse-admin/pull/79)
|
||||
* 🧑💻 [Add user profile to the top menu](https://github.com/etkecc/synapse-admin/pull/80)
|
||||
* 🎨 [Enable visual customization](https://github.com/etkecc/synapse-admin/pull/81)
|
||||
* 🛋️ [Fix room state events display](https://github.com/etkecc/synapse-admin/pull/100)
|
||||
* 🧹 [Sanitize CSV on import](https://github.com/etkecc/synapse-admin/pull/101)
|
||||
* ⚙️ Allow setting version using `SYNAPSE_ADMIN_VERSION` environment variable on build (if git is not available)
|
||||
* 🧪 [Add option to control user's experimental features](https://github.com/etkecc/synapse-admin/pull/111)
|
||||
* 🔑 [Add random password generation on user create/edit form](https://github.com/etkecc/synapse-admin/pull/123)
|
||||
* 🚦 [Add option to set user's rate limits](https://github.com/etkecc/synapse-admin/pull/125)
|
||||
* 🌐 [Support configuration via /.well-known/matrix/client](https://github.com/etkecc/synapse-admin/pull/126)
|
||||
* 🛑 [Prevent accidental user overwrites](https://github.com/etkecc/synapse-admin/pull/139)
|
||||
* 🔍 [Allow providing login form details via GET params](https://github.com/etkecc/synapse-admin/pull/140)
|
||||
* 🎨 [Add preferred theme colors to login page and footer](https://github.com/etkecc/synapse-admin/pull/155)
|
||||
* 🔰 [Add "Assign Admin" button to the rooms](https://github.com/etkecc/synapse-admin/pull/156)
|
||||
|
||||
_the list will be updated as new changes are added_
|
||||
|
||||
@@ -102,12 +106,19 @@ _the list will be updated as new changes are added_
|
||||
`just run-dev` to start the development stack (depending on your system speed, you may want to re-run this command if
|
||||
user creation fails)
|
||||
|
||||
This command initializes the development environment (local Synapse server and Postgres DB),
|
||||
and launches the app in a dev mode at `http://localhost:5173`
|
||||
|
||||
After that open `http://localhost:5173` in your browser, login using the following credentials:
|
||||
|
||||
* Login: admin
|
||||
* Password: admin
|
||||
* Homeserver URL: http://localhost:8008
|
||||
|
||||
### Support
|
||||
|
||||
If you have any questions or need help, feel free to join the [community room](https://matrix.to/#/#synapse-admin:etke.cc) or create an issue on GitHub.
|
||||
|
||||
## Configuration
|
||||
|
||||
You can use `config.json` file to configure Synapse Admin instance,
|
||||
@@ -120,6 +131,8 @@ In case you use [spantaleev/matrix-docker-ansible-deploy](https://github.com/spa
|
||||
[etkecc/ansible](https://github.com/etkecc/ansible),
|
||||
configuration will be automatically added to the `/.well-known/matrix/client` file.
|
||||
|
||||
[Configuration options](./docs/config.md)
|
||||
|
||||
The `config.json` can be injected into a Docker container using a bind mount.
|
||||
|
||||
```yml
|
||||
@@ -146,120 +159,20 @@ That way `username` and `homeserver` fields will be pre-filled with `admin` and
|
||||
|
||||
You can restrict the homeserver(s), so that the user can no longer define it himself.
|
||||
|
||||
Edit `config.json` to restrict either to a single homeserver:
|
||||
|
||||
```json
|
||||
{
|
||||
"restrictBaseUrl": "https://matrix.example.com"
|
||||
}
|
||||
```
|
||||
|
||||
similar for `/.well-known/matrix/client`:
|
||||
|
||||
```json
|
||||
{
|
||||
"cc.etke.synapse-admin": {
|
||||
"restrictBaseUrl": "https://matrix.example.com"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
or to a list of homeservers:
|
||||
|
||||
```json
|
||||
{
|
||||
"restrictBaseUrl": ["https://your-first-matrix-server.example.com", "https://your-second-matrix-server.example.com"]
|
||||
}
|
||||
```
|
||||
|
||||
similar for `/.well-known/matrix/client`:
|
||||
|
||||
```json
|
||||
{
|
||||
"cc.etke.synapse-admin": {
|
||||
"restrictBaseUrl": ["https://your-first-matrix-server.example.com", "https://your-second-matrix-server.example.com"]
|
||||
}
|
||||
}
|
||||
```
|
||||
[Documentation](./docs/restrict-hs.md)
|
||||
|
||||
### Protecting appservice managed users
|
||||
|
||||
To avoid accidental adjustments of appservice-managed users (e.g., puppets created by a bridge) and breaking the bridge,
|
||||
you can specify the list of MXIDs (regexp) that should be prohibited from any changes, except display name and avatar.
|
||||
|
||||
Example for [mautrix-telegram](https://github.com/mautrix/telegram)
|
||||
|
||||
```json
|
||||
{
|
||||
"asManagedUsers": ["^@telegram_[a-zA-Z0-9]+:example\\.com$"]
|
||||
}
|
||||
```
|
||||
|
||||
similar for `/.well-known/matrix/client`:
|
||||
|
||||
```json
|
||||
{
|
||||
"cc.etke.synapse-admin": {
|
||||
"asManagedUsers": ["^@telegram_[a-zA-Z0-9]+:example\\.com$"]
|
||||
}
|
||||
}
|
||||
```
|
||||
[Documentation](./docs/system-users.md)
|
||||
|
||||
### Adding custom menu items
|
||||
|
||||
You can add custom menu items to the main menu by providing a `menu` array in the `config.json`.
|
||||
You can add custom menu items to the main menu by providing a `menu` array in the config.
|
||||
|
||||
```json
|
||||
{
|
||||
"menu": [
|
||||
{
|
||||
"label": "Contact support",
|
||||
"icon": "SupportAgent",
|
||||
"url": "https://github.com/etkecc/synapse-admin/issues"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
similar for `/.well-known/matrix/client`:
|
||||
|
||||
```json
|
||||
{
|
||||
"cc.etke.synapse-admin": {
|
||||
"menu": [
|
||||
{
|
||||
"label": "Contact support",
|
||||
"icon": "SupportAgent",
|
||||
"url": "https://github.com/etkecc/synapse-admin/issues"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Where `icon` is one of the [preloaded icons](./src/components/icons.ts)
|
||||
|
||||
### Providing support URL
|
||||
|
||||
**Deprecated**: use `menu` config option described above. Automatically migrated to the `menu` if the `supportURL` is present.
|
||||
|
||||
~~Synapse Admin provides a support link in the main menu - `Contact support`. By default, the link points to the GitHub issues page of the project. You can change this link by providing a `supportURL` in the `config.json`.~~
|
||||
|
||||
```json
|
||||
{
|
||||
"supportURL": "https://example.com/support"
|
||||
}
|
||||
```
|
||||
|
||||
similar for `/.well-known/matrix/client`:
|
||||
|
||||
```json
|
||||
{
|
||||
"cc.etke.synapse-admin": {
|
||||
"supportURL": "https://example.com/support"
|
||||
}
|
||||
}
|
||||
```
|
||||
[Documentation](./docs/custom-menu.md)
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -308,6 +221,8 @@ You have three options:
|
||||
- move or symlink the `synapse-admin` into your vhosts root dir
|
||||
- open the url of the vhost in your browser
|
||||
|
||||
[Reverse Proxy Documentation with Examples](./docs/reverse-proxy.md)
|
||||
|
||||
#### Steps for 2)
|
||||
|
||||
- make sure you have installed the following: git, yarn, nodejs
|
||||
@@ -366,7 +281,7 @@ services:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
|
||||
synapse-admin:
|
||||
image: etkecc/synapse-admin:latest
|
||||
image: ghcr.io/etkecc/synapse-admin:latest
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
|
94
docs/config.md
Normal file
94
docs/config.md
Normal file
@@ -0,0 +1,94 @@
|
||||
# Configuration
|
||||
|
||||
Synapse Admin could be configured using the following ways (both are optional, and both could be used together):
|
||||
|
||||
* By providing the `config.json` file alongside with the Synapse Admin deployment, example: [admin.etke.cc/config.json](https://admin.etke.cc/config.json)
|
||||
* By providing configuration under the `cc.etke.synapse-admin` key in the `/.well-known/matrix/client` file, example:
|
||||
[demo.etke.host/.well-known/matrix/client](https://demo.etke.host/.well-known/matrix/client)
|
||||
|
||||
In case you are an [etke.cc](https://etke.cc) customer,
|
||||
or use [spantaleev/matrix-docker-ansible-deploy](https://github.com/spantaleev/matrix-docker-ansible-deploy),
|
||||
or [etkecc/ansible](https://github.com/etkecc/ansible),
|
||||
configuration will be automatically added to the `/.well-known/matrix/client` file.
|
||||
|
||||
**Why `/.well-known/matrix/client`?**
|
||||
|
||||
Because any instance of Synapse Admin will automatically pick up the configuration from the homeserver.
|
||||
Common use case when you have a Synapse server running, but don't want (or can't) deploy Synapse Admin alongside with it.
|
||||
In this case, you could provide the configuration in the `/.well-known/matrix/client` file,
|
||||
and any Synapse Admin instance (e.g., [admin.etke.cc](https://admin.etke.cc) will pick it up.
|
||||
|
||||
Another common case is when you have multiple Synapse servers running and want to use a single Synapse Admin instance to manage them all.
|
||||
In this case, you could provide the configuration in the `/.well-known/matrix/client` file for each of the servers.
|
||||
|
||||
## Configuration options
|
||||
|
||||
* `restrictBaseUrl` - restrictBaseUrl restricts the Synapse Admin instance to work only with specific homeserver(-s).
|
||||
It accepts both a string and an array of strings.
|
||||
The homeserver URL should be the _actual_ homeserver URL, and not the delegated one.
|
||||
Example: `https://matrix.example.com` or `https://synapse.example.net`
|
||||
[More details](restrict-hs.md)
|
||||
* `asManagedUsers` - protect system user accounts managed by appservices (such as bridges) / system (such as bots) from accidental changes.
|
||||
By defining a list of MXID regex patterns, you can protect these accounts from accidental changes.
|
||||
Example: `^@baibot:example\\.com$`, `^@slackbot:example\\.com$`, `^@slack_[a-zA-Z0-9\\-]+:example\\.com$`, `^@telegrambot:example\\.com$`, `^@telegram_[a-zA-Z0-9]+:example\\.com$`
|
||||
[More details](system-users.md)
|
||||
* `menu` - add custom menu items to the main menu (sidebar) by providing a `menu` array in the config.
|
||||
Each `menu` item can contain the following fields:
|
||||
* `label` (required): The text to display in the menu.
|
||||
* `icon` (optional): The icon to display next to the label, one of the [../src/components/icons.ts] icons, otherwise a default icon will be used.
|
||||
* `url` (required): The URL to navigate to when the menu item is clicked.
|
||||
[More details](custom-menu.md)
|
||||
|
||||
## Examples
|
||||
|
||||
### config.json
|
||||
|
||||
```json
|
||||
{
|
||||
"restrictBaseUrl": [
|
||||
"https://matrix.example.com",
|
||||
"https://synapse.example.net"
|
||||
],
|
||||
"asManagedUsers": [
|
||||
"^@baibot:example\\.com$",
|
||||
"^@slackbot:example\\.com$",
|
||||
"^@slack_[a-zA-Z0-9\\-]+:example\\.com$",
|
||||
"^@telegrambot:example\\.com$",
|
||||
"^@telegram_[a-zA-Z0-9]+:example\\.com$"
|
||||
],
|
||||
"menu": [
|
||||
{
|
||||
"label": "Contact support",
|
||||
"icon": "SupportAgent",
|
||||
"url": "https://github.com/etkecc/synapse-admin/issues"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### `/.well-known/matrix/client`
|
||||
|
||||
```json
|
||||
{
|
||||
"cc.etke.synapse-admin": {
|
||||
"restrictBaseUrl": [
|
||||
"https://matrix.example.com",
|
||||
"https://synapse.example.net"
|
||||
],
|
||||
"asManagedUsers": [
|
||||
"^@baibot:example\\.com$",
|
||||
"^@slackbot:example\\.com$",
|
||||
"^@slack_[a-zA-Z0-9\\-]+:example\\.com$",
|
||||
"^@telegrambot:example\\.com$",
|
||||
"^@telegram_[a-zA-Z0-9]+:example\\.com$"
|
||||
],
|
||||
"menu": [
|
||||
{
|
||||
"label": "Contact support",
|
||||
"icon": "SupportAgent",
|
||||
"url": "https://github.com/etkecc/synapse-admin/issues"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
47
docs/custom-menu.md
Normal file
47
docs/custom-menu.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# Custom Menu Items
|
||||
|
||||
You can add custom menu items to the main menu (sidebar) by providing a `menu` array in the config.
|
||||
This is useful for adding links to external sites or other pages in your documentation, like a support page or internal wiki.
|
||||
|
||||
## Configuration
|
||||
|
||||
The examples below contain the configuration settings to add a link to the [Synapse Admin issues](https://github.com/etke.cc/synapse-admin/issues).
|
||||
|
||||
Each `menu` item can contain the following fields:
|
||||
|
||||
* `label` (required): The text to display in the menu.
|
||||
* `icon` (optional): The icon to display next to the label, one of the [../src/components/icons.ts] icons, otherwise a
|
||||
default icon will be used.
|
||||
* `url` (required): The URL to navigate to when the menu item is clicked.
|
||||
|
||||
[Configuration options](config.md)
|
||||
|
||||
### config.json
|
||||
|
||||
```json
|
||||
{
|
||||
"menu": [
|
||||
{
|
||||
"label": "Contact support",
|
||||
"icon": "SupportAgent",
|
||||
"url": "https://github.com/etkecc/synapse-admin/issues"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### `/.well-known/matrix/client`
|
||||
|
||||
```json
|
||||
{
|
||||
"cc.etke.synapse-admin": {
|
||||
"menu": [
|
||||
{
|
||||
"label": "Contact support",
|
||||
"icon": "SupportAgent",
|
||||
"url": "https://github.com/etkecc/synapse-admin/issues"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
44
docs/restrict-hs.md
Normal file
44
docs/restrict-hs.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Restricting available homeserver
|
||||
|
||||
If you want to have your Synapse Admin instance work only with specific homeserver(-s),
|
||||
you can do that by setting `restrictBaseUrl` in the configuration.
|
||||
|
||||
## Configuration
|
||||
|
||||
You can do that for a single homeserver or multiple homeservers at once, as `restrictBaseUrl` accepts both a string and
|
||||
an array of strings.
|
||||
|
||||
The examples below contain the configuration settings to restrict the Synapse Admin instance to work only with
|
||||
`example.com` (with Synapse runing at `matrix.example.com`) and
|
||||
`example.net` (with Synapse running at `synapse.example.net`) homeservers.
|
||||
Note that the homeserver URL should be the _actual_ homeserver URL, and not the delegated one.
|
||||
|
||||
So, if you have a homeserver `example.com` where users have MXIDs like `@user:example.com`,
|
||||
but actual Synapse is installed on `matrix.example.com` subdomain, you should use `https://matrix.example.com` in the
|
||||
configuration.
|
||||
|
||||
[Configuration options](config.md)
|
||||
|
||||
### config.json
|
||||
|
||||
```json
|
||||
{
|
||||
"restrictBaseUrl": [
|
||||
"https://matrix.example.com",
|
||||
"https://synapse.example.net"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### `/.well-known/matrix/client`
|
||||
|
||||
```json
|
||||
{
|
||||
"cc.etke.synapse-admin": {
|
||||
"restrictBaseUrl": [
|
||||
"https://matrix.example.com",
|
||||
"https://synapse.example.net"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
53
docs/reverse-proxy.md
Normal file
53
docs/reverse-proxy.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# Serving Synapse Admin behind a reverse proxy
|
||||
|
||||
Your are supposed to do so for any service you want to expose to the internet,
|
||||
and here you can find specific instructions and example configurations for Synapse Admin.
|
||||
|
||||
## Nginx
|
||||
|
||||
Place the config below into `/etc/nginx/conf.d/synapse-admin.conf` (don't forget to replace `server_name` and `root`):
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name example.com; # REPLACE with your domain
|
||||
root /var/www/synapse-admin; # REPLACE with path where you extracted synapse admin
|
||||
index index.html;
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
location ~* \.(?:css|js|jpg|jpeg|gif|png|svg|ico|woff|woff2|ttf|eot|webp)$ {
|
||||
expires 30d; # Set caching for static assets
|
||||
add_header Cache-Control "public";
|
||||
}
|
||||
|
||||
gzip on;
|
||||
gzip_types text/plain application/javascript application/json text/css text/xml application/xml+rss;
|
||||
gzip_min_length 1000;
|
||||
}
|
||||
```
|
||||
|
||||
After you've done that, ensure that the configuration is correct by running `nginx -t` and then reload Nginx
|
||||
(e.g. `systemctl reload nginx`).
|
||||
|
||||
> **Note:** This configuration doesn't cover HTTPS, which is highly recommended to use. You can find more information
|
||||
about setting up HTTPS in the [Nginx documentation](https://nginx.org/en/docs/http/configuring_https_servers.html).
|
||||
|
||||
## Traefik (docker labels)
|
||||
|
||||
If you are using Traefik as a reverse proxy, you can use the following labels, `docker-compose.yml` example:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
synapse-admin:
|
||||
image: ghcr.io/etkecc/synapse-admin:latest
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.synapse-admin.rule=Host(`example.com`)"
|
||||
```
|
||||
|
||||
## Other reverse proxies
|
||||
|
||||
There is no examples for other reverse proxies yet, and so PRs are greatly appreciated.
|
44
docs/system-users.md
Normal file
44
docs/system-users.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# System / Appservice-managed Users
|
||||
|
||||
Inadvertently altering system user accounts managed by appservices (such as bridges) / system (such as bots) is a common issue.
|
||||
Editing, deleting, locking, or changing the passwords of these appservice-managed accounts can cause serious problems.
|
||||
To prevent this, we've added a new feature that blocks these types of modifications to such accounts,
|
||||
while still allowing other risk-free changes (changing display names and avatars).
|
||||
By defining a list of MXID regex patterns in the new `asManagedUsers` configuration setting,
|
||||
you can protect these accounts from accidental changes.
|
||||
|
||||
## Configuration
|
||||
|
||||
The examples below contain the configuration settings to mark
|
||||
[Telegram bridge (mautrix-telegram)](https://github.com/mautrix/telegram),
|
||||
[Slack bridge (mautrix-slack)](https://github.com/mautrix/slack),
|
||||
and [Baibot](https://github.com/etkecc/baibot) users of `example.com` homeserver as appservice-managed users,
|
||||
just to illustrate the options to protect both specific MXIDs (as in the Baibot example) and all puppets of a bridge (as in the Telegram and Slack examples).
|
||||
|
||||
[Configuration options](config.md)
|
||||
|
||||
### config.json
|
||||
|
||||
```json
|
||||
"asManagedUsers": [
|
||||
"^@baibot:example\\.com$",
|
||||
"^@slackbot:example\\.com$",
|
||||
"^@slack_[a-zA-Z0-9\\-]+:example\\.com$",
|
||||
"^@telegrambot:example\\.com$",
|
||||
"^@telegram_[a-zA-Z0-9]+:example\\.com$"
|
||||
]
|
||||
```
|
||||
|
||||
### `/.well-known/matrix/client`
|
||||
|
||||
```json
|
||||
"cc.etke.synapse-admin": {
|
||||
"asManagedUsers": [
|
||||
"^@baibot:example\\.com$",
|
||||
"^@slackbot:example\\.com$",
|
||||
"^@slack_[a-zA-Z0-9\\-]+:example\\.com$",
|
||||
"^@telegrambot:example\\.com$",
|
||||
"^@telegram_[a-zA-Z0-9]+:example\\.com$"
|
||||
]
|
||||
}
|
||||
```
|
20
package.json
20
package.json
@@ -21,10 +21,10 @@
|
||||
"@types/node": "^22.8.7",
|
||||
"@types/papaparse": "^5.3.15",
|
||||
"@types/react": "^18.3.12",
|
||||
"@typescript-eslint/eslint-plugin": "^8.11.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.14.0",
|
||||
"@typescript-eslint/parser": "^8.13.0",
|
||||
"@vitejs/plugin-react": "^4.3.3",
|
||||
"eslint": "^9.14.0",
|
||||
"eslint": "^9.15.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-import": "^2.31.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.10.2",
|
||||
@@ -40,7 +40,7 @@
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.6.3",
|
||||
"typescript-eslint": "^8.13.0",
|
||||
"vite": "^5.4.10",
|
||||
"vite": "^5.4.11",
|
||||
"vite-plugin-version-mark": "^0.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -48,18 +48,18 @@
|
||||
"@emotion/styled": "^11.13.0",
|
||||
"@haleos/ra-language-german": "^1.0.0",
|
||||
"@haxqer/ra-language-chinese": "^4.16.2",
|
||||
"@mui/icons-material": "^6.1.5",
|
||||
"@mui/material": "^6.1.6",
|
||||
"@mui/icons-material": "^6.1.7",
|
||||
"@mui/material": "^6.1.7",
|
||||
"@mui/utils": "^5.16.6",
|
||||
"@tanstack/react-query": "^5.59.20",
|
||||
"@tanstack/react-query": "^5.60.5",
|
||||
"history": "^5.3.0",
|
||||
"lodash": "^4.17.21",
|
||||
"papaparse": "^5.4.1",
|
||||
"ra-core": "^5.3.2",
|
||||
"ra-i18n-polyglot": "^5.3.2",
|
||||
"ra-language-english": "^5.3.2",
|
||||
"ra-core": "^5.3.4",
|
||||
"ra-i18n-polyglot": "^5.3.4",
|
||||
"ra-language-english": "^5.3.4",
|
||||
"ra-language-farsi": "^5.0.0",
|
||||
"ra-language-french": "^5.3.3",
|
||||
"ra-language-french": "^5.3.4",
|
||||
"ra-language-italian": "^3.13.1",
|
||||
"ra-language-russian": "^4.14.2",
|
||||
"react": "^18.3.1",
|
||||
|
BIN
screenshots/auth.webp
Normal file
BIN
screenshots/auth.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 83 KiB |
Before Width: | Height: | Size: 222 KiB After Width: | Height: | Size: 222 KiB |
@@ -7,6 +7,6 @@ import App from "./App";
|
||||
describe("App", () => {
|
||||
it("renders", async () => {
|
||||
render(<App />);
|
||||
await screen.findAllByText("Welcome to Synapse-admin");
|
||||
await screen.findAllByText("Welcome to Synapse Admin");
|
||||
});
|
||||
});
|
||||
|
@@ -23,7 +23,6 @@ import users from "./resources/users";
|
||||
import authProvider from "./synapse/authProvider";
|
||||
import dataProvider from "./synapse/dataProvider";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import Footer from "./components/Footer";
|
||||
|
||||
// TODO: Can we use lazy loading together with browser locale?
|
||||
const messages = {
|
||||
@@ -82,7 +81,6 @@ const App = () => (
|
||||
<Resource name="room_state" />
|
||||
<Resource name="destination_rooms" />
|
||||
</Admin>
|
||||
<Footer />
|
||||
</QueryClientProvider>
|
||||
);
|
||||
|
||||
|
@@ -3,6 +3,7 @@ import { LoginMethod } from "../pages/LoginPage";
|
||||
import { useEffect, useState, Suspense } from "react";
|
||||
import { Icons, DefaultIcon } from "./icons";
|
||||
import { ClearConfig } from "./config";
|
||||
import Footer from "./Footer";
|
||||
|
||||
const AdminUserMenu = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
@@ -88,8 +89,9 @@ const AdminMenu = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export const AdminLayout = ({ children }) => (
|
||||
<Layout appBar={AdminAppBar} menu={AdminMenu} sx={{
|
||||
export const AdminLayout = ({ children }) => {
|
||||
return <>
|
||||
<Layout appBar={AdminAppBar} menu={AdminMenu} sx={{
|
||||
['& .RaLayout-appFrame']: {
|
||||
minHeight: '90vh',
|
||||
height: '90vh',
|
||||
@@ -98,7 +100,9 @@ export const AdminLayout = ({ children }) => (
|
||||
marginBottom: '3rem',
|
||||
},
|
||||
}}>
|
||||
{children}
|
||||
<CheckForApplicationUpdate />
|
||||
</Layout>
|
||||
);
|
||||
{children}
|
||||
<CheckForApplicationUpdate />
|
||||
</Layout>
|
||||
<Footer />
|
||||
</>
|
||||
};
|
@@ -1,8 +1,11 @@
|
||||
import { Avatar, Box, Link, Typography } from "@mui/material";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useTheme } from "@mui/material/styles";
|
||||
|
||||
const Footer = () => {
|
||||
const [version, setVersion] = useState<string | null>(null);
|
||||
const theme = useTheme();
|
||||
|
||||
useEffect(() => {
|
||||
const version = document.getElementById("js-version")?.textContent;
|
||||
if (version) {
|
||||
@@ -17,23 +20,28 @@ const Footer = () => {
|
||||
zIndex: 100,
|
||||
bottom: 0,
|
||||
width: '100%',
|
||||
bgcolor: "#eee",
|
||||
bgcolor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
borderTop: '1px solid',
|
||||
borderColor: '#ddd',
|
||||
borderColor: theme.palette.divider,
|
||||
fontSize: '0.89rem',
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'start',
|
||||
p: 1,
|
||||
gap: '10px'
|
||||
}}>
|
||||
<Typography variant="body2" component="div">
|
||||
<Avatar src="./images/logo.webp" sx={{ width: "1rem", height: "1rem", display: "inline-block", verticalAlign: "sub" }} />
|
||||
<Link sx={{ color: "#888", textDecoration: 'none' }} href="https://github.com/etkecc/synapse-admin" target="_blank">
|
||||
Synapse Admin
|
||||
</Link> <Link href={`https://github.com/etkecc/synapse-admin/releases/tag/`+version} target="_blank">
|
||||
<span style={{ fontWeight: 'bold', color: "#000" }}>{version}</span>
|
||||
</Link> <Link sx={{ color: "#888", textDecoration: 'none' }} href="https://etke.cc/?utm_source=synapse-admin&utm_medium=footer&utm_campaign=synapse-admin" target="_blank">
|
||||
by etke.cc
|
||||
</Link> <Link sx={{ color: "#888", textDecoration: 'none' }} href="https://github.com/awesome-technologies/synapse-admin" target="_blank">
|
||||
(originally developed by Awesome Technologies Innovationslabor GmbH).
|
||||
</Link> <Link sx={{ fontWeight: 'bold', color: "#000", textDecoration: 'none' }} href="https://matrix.to/#/#synapse-admin:etke.cc" target="_blank">#synapse-admin:etke.cc</Link>
|
||||
</Typography>
|
||||
<Link href="https://github.com/etkecc/synapse-admin" target="_blank">
|
||||
Synapse Admin {version}
|
||||
</Link>
|
||||
by
|
||||
<Link href="https://etke.cc/?utm_source=synapse-admin&utm_medium=footer&utm_campaign=synapse-admin" target="_blank">
|
||||
etke.cc
|
||||
</Link>
|
||||
(originally developed by Awesome Technologies Innovationslabor GmbH).
|
||||
<Link sx={{ fontWeight: 'bold' }} href="https://matrix.to/#/#synapse-admin:etke.cc" target="_blank">#synapse-admin:etke.cc</Link>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
@@ -2,57 +2,58 @@ import { styled } from "@mui/material/styles";
|
||||
import { Box } from "@mui/material";
|
||||
|
||||
const LoginFormBox = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
minHeight: "calc(100vh - 1rem)",
|
||||
alignItems: "center",
|
||||
justifyContent: "flex-start",
|
||||
background: "url(./images/floating-cogs.svg)",
|
||||
backgroundColor: "#f9f9f9",
|
||||
backgroundRepeat: "no-repeat",
|
||||
backgroundSize: "cover",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
minHeight: "calc(100vh - 1rem)",
|
||||
alignItems: "center",
|
||||
justifyContent: "flex-start",
|
||||
background: "url(./images/floating-cogs.svg)",
|
||||
backgroundColor: theme.palette.mode === 'dark' ? theme.palette.background.default : theme.palette.background.paper,
|
||||
backgroundRepeat: "no-repeat",
|
||||
backgroundSize: "cover",
|
||||
|
||||
[`& .card`]: {
|
||||
width: "30rem",
|
||||
marginTop: "6rem",
|
||||
marginBottom: "6rem",
|
||||
},
|
||||
[`& .avatar`]: {
|
||||
margin: "1rem",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
},
|
||||
[`& .icon`]: {
|
||||
backgroundColor: theme.palette.grey[500],
|
||||
},
|
||||
[`& .hint`]: {
|
||||
marginTop: "1em",
|
||||
marginBottom: "1em",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
color: theme.palette.grey[600],
|
||||
},
|
||||
[`& .form`]: {
|
||||
padding: "0 1rem 1rem 1rem",
|
||||
},
|
||||
[`& .select`]: {
|
||||
marginBottom: "2rem",
|
||||
},
|
||||
[`& .actions`]: {
|
||||
padding: "0 1rem 1rem 1rem",
|
||||
},
|
||||
[`& .serverVersion`]: {
|
||||
color: theme.palette.grey[500],
|
||||
fontFamily: "Roboto, Helvetica, Arial, sans-serif",
|
||||
marginLeft: "0.5rem",
|
||||
},
|
||||
[`& .matrixVersions`]: {
|
||||
color: theme.palette.grey[500],
|
||||
fontFamily: "Roboto, Helvetica, Arial, sans-serif",
|
||||
fontSize: "0.8rem",
|
||||
marginBottom: "1rem",
|
||||
marginLeft: "0.5rem",
|
||||
},
|
||||
}));
|
||||
[`& .card`]: {
|
||||
width: "30rem",
|
||||
marginTop: "6rem",
|
||||
marginBottom: "6rem",
|
||||
},
|
||||
[`& .avatar`]: {
|
||||
margin: "1rem",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
},
|
||||
[`& .icon`]: {
|
||||
backgroundColor: theme.palette.grey[500],
|
||||
},
|
||||
[`& .hint`]: {
|
||||
marginTop: "1em",
|
||||
marginBottom: "1em",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
color: theme.palette.grey[600],
|
||||
},
|
||||
[`& .form`]: {
|
||||
padding: "0 1rem 1rem 1rem",
|
||||
},
|
||||
[`& .select`]: {
|
||||
marginBottom: "2rem",
|
||||
},
|
||||
[`& .actions`]: {
|
||||
padding: "0 1rem 1rem 1rem",
|
||||
},
|
||||
[`& .serverVersion`]: {
|
||||
color: theme.palette.grey[500],
|
||||
fontFamily: "Roboto, Helvetica, Arial, sans-serif",
|
||||
marginLeft: "0.5rem",
|
||||
},
|
||||
[`& .matrixVersions`]: {
|
||||
color: theme.palette.grey[500],
|
||||
fontFamily: "Roboto, Helvetica, Arial, sans-serif",
|
||||
fontSize: "0.8rem",
|
||||
marginBottom: "1rem",
|
||||
marginLeft: "0.5rem",
|
||||
},
|
||||
}
|
||||
));
|
||||
|
||||
export default LoginFormBox;
|
||||
|
@@ -37,7 +37,7 @@ const de: SynapseTranslationMessages = {
|
||||
synapseadmin: {
|
||||
auth: {
|
||||
base_url: "Heimserver URL",
|
||||
welcome: "Willkommen bei Synapse-admin",
|
||||
welcome: "Willkommen bei Synapse Admin",
|
||||
server_version: "Synapse Version",
|
||||
supports_specs: "unterstützt Matrix-Specs",
|
||||
username_error: "Bitte vollständigen Nutzernamen angeben: '@user:domain'",
|
||||
@@ -260,6 +260,14 @@ const de: SynapseTranslationMessages = {
|
||||
success: "Raum/Räume erfolgreich gelöscht.",
|
||||
failure: "Der/die Raum/Räume konnten nicht gelöscht werden.",
|
||||
},
|
||||
make_admin: {
|
||||
assign_admin: "Raumadministrator zuweisen",
|
||||
title: "Raumadministrator zu %{roomName} zuweisen",
|
||||
confirm: "Raumadministrator zuweisen",
|
||||
content: "Geben Sie die vollständige MXID des Benutzers an, der als Administrator gesetzt werden soll.\nWarnung: Damit dies funktioniert, muss der Raum mindestens einen lokalen Mitglied als Administrator haben.",
|
||||
success: "Der/die Benutzer wurde/n als Raumadministrator gesetzt.",
|
||||
failure: "Der/die Benutzer konnte/n nicht als Raumadministrator gesetzt werden. %{errMsg}",
|
||||
}
|
||||
},
|
||||
},
|
||||
reports: {
|
||||
|
@@ -7,7 +7,7 @@ const en: SynapseTranslationMessages = {
|
||||
synapseadmin: {
|
||||
auth: {
|
||||
base_url: "Homeserver URL",
|
||||
welcome: "Welcome to Synapse-admin",
|
||||
welcome: "Welcome to Synapse Admin",
|
||||
server_version: "Synapse version",
|
||||
supports_specs: "supports Matrix specs",
|
||||
username_error: "Please enter fully qualified user ID: '@user:domain'",
|
||||
@@ -38,7 +38,7 @@ const en: SynapseTranslationMessages = {
|
||||
members: "Members",
|
||||
detail: "Details",
|
||||
permission: "Permissions",
|
||||
},
|
||||
}
|
||||
},
|
||||
reports: { tabs: { basic: "Basic", detail: "Details" } },
|
||||
},
|
||||
@@ -233,6 +233,14 @@ const en: SynapseTranslationMessages = {
|
||||
success: "Room/s successfully deleted.",
|
||||
failure: "The room/s could not be deleted.",
|
||||
},
|
||||
make_admin: {
|
||||
assign_admin: "Assign admin",
|
||||
title: "Assign a room admin to %{roomName}",
|
||||
confirm: "Make admin",
|
||||
content: "Put the full MXID of the user which will be set as admin.\nWarning: for this to work, the room needs to have at least one local member as admin.",
|
||||
success: "The user has been set as room admin.",
|
||||
failure: "The user could not be set as room admin. %{errMsg}",
|
||||
}
|
||||
},
|
||||
},
|
||||
reports: {
|
||||
|
@@ -225,6 +225,14 @@ const fa: SynapseTranslationMessages = {
|
||||
success: "اتاق با موفقیت حذف شد.",
|
||||
failure: "خطایی رخ داده است.",
|
||||
},
|
||||
make_admin: {
|
||||
assign_admin: "مدیر انتخاب کنید",
|
||||
title: "مدیر اتاق %{roomName} را انتخاب کنید",
|
||||
confirm: "مدیر انتخاب کنید",
|
||||
content: "کامل MXID کاربری را وارد کنید که به عنوان مدیر تنظیم شود.\nهشدار: برای این کار، اتاق باید حداقل یک اعضای محلی به عنوان مدیر داشته باشد.",
|
||||
success: "کاربر به عنوان مدیر اتاق تنظیم شد.",
|
||||
failure: "کاربر به عنوان مدیر اتاق تنظیم نشد. %{errMsg}",
|
||||
}
|
||||
},
|
||||
},
|
||||
reports: {
|
||||
|
@@ -7,7 +7,7 @@ const fr: SynapseTranslationMessages = {
|
||||
synapseadmin: {
|
||||
auth: {
|
||||
base_url: "URL du serveur d’accueil",
|
||||
welcome: "Bienvenue sur Synapse-admin",
|
||||
welcome: "Bienvenue sur Synapse Admin",
|
||||
server_version: "Version du serveur Synapse",
|
||||
username_error: "Veuillez entrer un nom d'utilisateur complet : « @utilisateur:domaine »",
|
||||
protocol_error: "L'URL doit commencer par « http:// » ou « https:// »",
|
||||
@@ -227,6 +227,14 @@ const fr: SynapseTranslationMessages = {
|
||||
success: "Salle/s supprimées avec succès.",
|
||||
failure: "La/les salle/s n'ont pas pu être supprimées.",
|
||||
},
|
||||
make_admin: {
|
||||
assign_admin: "Assigner un administrateur",
|
||||
title: "Assigner un administrateur au salon %{roomName}",
|
||||
confirm: "Assigner un administrateur",
|
||||
content: "Entrez la MXID complète de l'utilisateur qui sera désigné comme administrateur.\nAttention : pour que cela fonctionne, la salle doit avoir au moins un membre local en tant qu'administrateur.",
|
||||
success: "L'utilisateur a été désigné comme administrateur de la salle.",
|
||||
failure: "L'utilisateur n'a pas pu être désigné comme administrateur de la salle. %{errMsg}",
|
||||
}
|
||||
},
|
||||
},
|
||||
reports: {
|
||||
|
8
src/i18n/index.d.ts
vendored
8
src/i18n/index.d.ts
vendored
@@ -223,6 +223,14 @@ interface SynapseTranslationMessages extends TranslationMessages {
|
||||
success: string;
|
||||
failure: string;
|
||||
};
|
||||
make_admin: {
|
||||
assign_admin: string;
|
||||
title: string;
|
||||
confirm: string;
|
||||
content: string;
|
||||
success: string;
|
||||
failure: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
reports: {
|
||||
|
@@ -7,7 +7,7 @@ const it: SynapseTranslationMessages = {
|
||||
synapseadmin: {
|
||||
auth: {
|
||||
base_url: "URL dell'homeserver",
|
||||
welcome: "Benvenuto in Synapse-admin",
|
||||
welcome: "Benvenuto in Synapse Admin",
|
||||
server_version: "Versione di Synapse",
|
||||
username_error: "Per favore inserisci un ID utente completo: '@utente:dominio'",
|
||||
protocol_error: "L'URL deve iniziare per 'http://' o 'https://'",
|
||||
@@ -221,6 +221,14 @@ const it: SynapseTranslationMessages = {
|
||||
content:
|
||||
"Sei sicuro di voler eliminare questa stanza? Questa azione è definitiva. Tutti i messaggi e i media condivisi in questa stanza verranno eliminati dal server!",
|
||||
},
|
||||
make_admin: {
|
||||
assign_admin: "Assegna un amministratore",
|
||||
title: "Assegna un amministratore alla stanza %{roomName}",
|
||||
confirm: "Assegna un amministratore",
|
||||
content: "Inserisci la MXID completa dell'utente che sarà designato come amministratore.\nAttenzione: per questo funzionare, la stanza deve avere almeno un membro locale come amministratore.",
|
||||
success: "L'utente è stato designato come amministratore della stanza.",
|
||||
failure: "L'utente non può essere designato come amministratore della stanza. %{errMsg}",
|
||||
}
|
||||
},
|
||||
},
|
||||
reports: {
|
||||
|
@@ -32,7 +32,7 @@ const ru: SynapseTranslationMessages = {
|
||||
synapseadmin: {
|
||||
auth: {
|
||||
base_url: "Адрес домашнего сервера",
|
||||
welcome: "Добро пожаловать в Synapse-admin",
|
||||
welcome: "Добро пожаловать в Synapse Admin",
|
||||
server_version: "Версия Synapse",
|
||||
supports_specs: "поддерживает спецификации Matrix",
|
||||
username_error: "Пожалуйста, укажите полный ID пользователя: '@user:domain'",
|
||||
@@ -266,6 +266,14 @@ const ru: SynapseTranslationMessages = {
|
||||
success: "Комната/ы успешно удалены",
|
||||
failure: "Комната/ы не могут быть удалены.",
|
||||
},
|
||||
make_admin: {
|
||||
assign_admin: "Назначить администратора",
|
||||
title: "Назначить администратора комнате %{roomName}",
|
||||
confirm: "Назначить администратора",
|
||||
content: "Введите полную MXID пользователя, которого нужно назначить администратором.\nПредупреждение: для этого должен быть назначен хотя бы один локальный участник в качестве администратора.",
|
||||
success: "Пользователь назначен администратором комнаты.",
|
||||
failure: "Пользователь не может быть назначен администратором комнаты. %{errMsg}",
|
||||
}
|
||||
},
|
||||
},
|
||||
reports: {
|
||||
|
@@ -35,7 +35,7 @@ const zh: SynapseTranslationMessages = {
|
||||
synapseadmin: {
|
||||
auth: {
|
||||
base_url: "服务器 URL",
|
||||
welcome: "欢迎来到 Synapse-admin",
|
||||
welcome: "欢迎来到 Synapse Admin",
|
||||
server_version: "Synapse 版本",
|
||||
username_error: "请输入完整有效的用户 ID: '@user:domain'",
|
||||
protocol_error: "URL 需要以'http://'或'https://'作为起始",
|
||||
|
@@ -26,6 +26,7 @@ import {
|
||||
splitMxid,
|
||||
} from "../synapse/synapse";
|
||||
import storage from "../storage";
|
||||
import Footer from "../components/Footer";
|
||||
|
||||
export type LoginMethod = "credentials" | "accessToken";
|
||||
|
||||
@@ -321,6 +322,7 @@ const LoginPage = () => {
|
||||
</Card>
|
||||
</LoginFormBox>
|
||||
<Notification />
|
||||
<Footer />
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
@@ -27,8 +27,7 @@ import {
|
||||
} from "react-admin";
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
import AvatarField from "../components/AvatarField";
|
||||
|
||||
|
||||
import { MakeAdminBtn } from "./rooms";
|
||||
const RoomDirectoryPagination = () => <Pagination rowsPerPageOptions={[100, 500, 1000, 2000]} />;
|
||||
|
||||
export const RoomDirectoryUnpublishButton = (props: DeleteButtonProps) => {
|
||||
@@ -154,6 +153,7 @@ export const RoomDirectoryList = () => (
|
||||
<NumberField source="num_joined_members" sortable={false} label="resources.rooms.fields.joined_members" />
|
||||
<BooleanField source="world_readable" sortable={false} label="resources.room_directory.fields.world_readable" />
|
||||
<BooleanField source="guest_can_join" sortable={false} label="resources.room_directory.fields.guest_can_join" />
|
||||
<MakeAdminBtn />
|
||||
</DatagridConfigurable>
|
||||
</List>
|
||||
);
|
||||
|
@@ -11,11 +11,11 @@ import Box from "@mui/material/Box";
|
||||
import { useTheme } from "@mui/material/styles";
|
||||
import {
|
||||
BooleanField,
|
||||
BulkDeleteButton,
|
||||
DateField,
|
||||
EditButton,
|
||||
WrapperField,
|
||||
Datagrid,
|
||||
DatagridConfigurable,
|
||||
DeleteButton,
|
||||
ExportButton,
|
||||
FunctionField,
|
||||
List,
|
||||
@@ -32,13 +32,15 @@ import {
|
||||
ShowProps,
|
||||
Tab,
|
||||
TabbedShowLayout,
|
||||
TextField,
|
||||
TextField as RaTextField,
|
||||
TopToolbar,
|
||||
useRecordContext,
|
||||
useTranslate,
|
||||
useListContext,
|
||||
useNotify,
|
||||
} from "react-admin";
|
||||
|
||||
import TextField from "@mui/material/TextField";
|
||||
import {
|
||||
RoomDirectoryBulkUnpublishButton,
|
||||
RoomDirectoryBulkPublishButton,
|
||||
@@ -48,7 +50,14 @@ import {
|
||||
import { DATE_FORMAT } from "../components/date";
|
||||
import DeleteRoomButton from "../components/DeleteRoomButton";
|
||||
import AvatarField from "../components/AvatarField";
|
||||
|
||||
import { Room } from "../synapse/dataProvider";
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
import { useDataProvider } from "react-admin";
|
||||
import { Confirm } from "react-admin";
|
||||
import { useState } from "react";
|
||||
import Button from "@mui/material/Button";
|
||||
import PersonIcon from '@mui/icons-material/Person';
|
||||
import Typography from "@mui/material/Typography";
|
||||
const RoomPagination = () => <Pagination rowsPerPageOptions={[10, 25, 50, 100, 500, 1000]} />;
|
||||
|
||||
const RoomTitle = () => {
|
||||
@@ -76,6 +85,7 @@ const RoomShowActions = () => {
|
||||
return (
|
||||
<TopToolbar>
|
||||
{publishButton}
|
||||
<MakeAdminBtn />
|
||||
<DeleteRoomButton
|
||||
selectedIds={[record.id]}
|
||||
confirmTitle="resources.rooms.action.erase.title"
|
||||
@@ -85,8 +95,97 @@ const RoomShowActions = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export const MakeAdminBtn = () => {
|
||||
const record = useRecordContext() as Room;
|
||||
|
||||
if (!record) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (record.joined_local_members < 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
const ownMXID = localStorage.getItem("user_id") || "";
|
||||
const [open, setOpen] = useState(false);
|
||||
const [userIdValue, setUserIdValue] = useState(ownMXID);
|
||||
const dataProvider = useDataProvider();
|
||||
const notify = useNotify();
|
||||
const translate = useTranslate();
|
||||
|
||||
const { mutate, isPending } = useMutation({
|
||||
mutationFn: async () => {
|
||||
try {
|
||||
const result = await dataProvider.makeRoomAdmin(record.room_id, userIdValue);
|
||||
if (!result.success) {
|
||||
throw new Error(result.error);
|
||||
}
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
onSuccess: () => {
|
||||
notify("resources.rooms.action.make_admin.success", { type: "success" });
|
||||
setOpen(false);
|
||||
setUserIdValue("");
|
||||
},
|
||||
onError: (err) => {
|
||||
const errorMessage = err instanceof Error ? err.message : "Unknown error";
|
||||
notify("resources.rooms.action.make_admin.failure", { type: "error", messageArgs: { errMsg: errorMessage } });
|
||||
setOpen(false);
|
||||
setUserIdValue("");
|
||||
}
|
||||
});
|
||||
|
||||
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setUserIdValue(event.target.value);
|
||||
};
|
||||
|
||||
const handleConfirm = async () => {
|
||||
mutate();
|
||||
setOpen(false);
|
||||
};
|
||||
|
||||
const handleDialogClose = () => {
|
||||
setOpen(false);
|
||||
};
|
||||
|
||||
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
if (event.key === "Enter") {
|
||||
handleConfirm();
|
||||
}
|
||||
};
|
||||
|
||||
return (<>
|
||||
<Button size="small" onClick={(e) => { e.stopPropagation(); setOpen(true); }} disabled={isPending}>
|
||||
<PersonIcon /> {translate("resources.rooms.action.make_admin.assign_admin")}
|
||||
</Button>
|
||||
<Confirm
|
||||
isOpen={open}
|
||||
onConfirm={handleConfirm}
|
||||
onClose={handleDialogClose}
|
||||
confirm="resources.rooms.action.make_admin.confirm"
|
||||
cancel="ra.action.cancel"
|
||||
title={translate("resources.rooms.action.make_admin.title", { roomName: record.name ? record.name : record.room_id })}
|
||||
content={<>
|
||||
<Typography sx={{ marginBottom: 2, whiteSpace: "pre-line"}}>{translate("resources.rooms.action.make_admin.content")}</Typography>
|
||||
<TextField
|
||||
type="text"
|
||||
variant="filled"
|
||||
value={userIdValue}
|
||||
onChange={handleChange}
|
||||
onKeyDown={handleKeyDown}
|
||||
label={"Matrix ID"}
|
||||
/>
|
||||
</>}
|
||||
/>
|
||||
</>);
|
||||
};
|
||||
|
||||
export const RoomShow = (props: ShowProps) => {
|
||||
const translate = useTranslate();
|
||||
const record = useRecordContext();
|
||||
return (
|
||||
<Show {...props} actions={<RoomShowActions />} title={<RoomTitle />}>
|
||||
<TabbedShowLayout>
|
||||
@@ -96,28 +195,29 @@ export const RoomShow = (props: ShowProps) => {
|
||||
sx={{ height: "120px", width: "120px" }}
|
||||
label="resources.rooms.fields.avatar"
|
||||
/>
|
||||
<TextField source="room_id" />
|
||||
<TextField source="name" />
|
||||
<TextField source="topic" />
|
||||
<TextField source="canonical_alias" />
|
||||
<RaTextField source="room_id" />
|
||||
<RaTextField source="name" />
|
||||
<RaTextField source="topic" />
|
||||
<RaTextField source="canonical_alias" />
|
||||
<ReferenceField source="creator" reference="users">
|
||||
<TextField source="id" />
|
||||
<RaTextField source="id" />
|
||||
</ReferenceField>
|
||||
</Tab>
|
||||
|
||||
<Tab label="synapseadmin.rooms.tabs.detail" icon={<PageviewIcon />} path="detail">
|
||||
<TextField source="joined_members" />
|
||||
<TextField source="joined_local_members" />
|
||||
<TextField source="joined_local_devices" />
|
||||
<TextField source="state_events" />
|
||||
<TextField source="version" />
|
||||
<TextField source="encryption" emptyText={translate("resources.rooms.enums.unencrypted")} />
|
||||
<RaTextField source="joined_members" />
|
||||
<RaTextField source="joined_local_members" />
|
||||
<RaTextField source="joined_local_devices" />
|
||||
<RaTextField source="state_events" />
|
||||
<RaTextField source="version" />
|
||||
<RaTextField source="encryption" emptyText={translate("resources.rooms.enums.unencrypted")} />
|
||||
</Tab>
|
||||
|
||||
<Tab label="synapseadmin.rooms.tabs.members" icon={<UserIcon />} path="members">
|
||||
<MakeAdminBtn />
|
||||
<ReferenceManyField reference="room_members" target="room_id" label={false}>
|
||||
<Datagrid style={{ width: "100%" }} rowClick={id => "/users/" + id} bulkActionButtons={false}>
|
||||
<TextField source="id" sortable={false} label="resources.users.fields.id" />
|
||||
<RaTextField source="id" sortable={false} label="resources.users.fields.id" />
|
||||
<ReferenceField
|
||||
label="resources.users.fields.displayname"
|
||||
source="id"
|
||||
@@ -125,7 +225,7 @@ export const RoomShow = (props: ShowProps) => {
|
||||
sortable={false}
|
||||
link=""
|
||||
>
|
||||
<TextField source="displayname" sortable={false} />
|
||||
<RaTextField source="displayname" sortable={false} />
|
||||
</ReferenceField>
|
||||
</Datagrid>
|
||||
</ReferenceManyField>
|
||||
@@ -185,11 +285,11 @@ export const RoomShow = (props: ShowProps) => {
|
||||
<Tab label={translate("resources.room_state.name", { smart_count: 2 })} icon={<EventIcon />} path="state">
|
||||
<ReferenceManyField reference="room_state" target="room_id" label={false}>
|
||||
<Datagrid style={{ width: "100%" }} bulkActionButtons={false}>
|
||||
<TextField source="type" sortable={false} />
|
||||
<RaTextField source="type" sortable={false} />
|
||||
<DateField source="origin_server_ts" showTime options={DATE_FORMAT} sortable={false} />
|
||||
<FunctionField source="content" sortable={false} render={record => `${JSON.stringify(record.content, null, 2)}`} />
|
||||
<ReferenceField source="sender" reference="users" sortable={false}>
|
||||
<TextField source="id" />
|
||||
<RaTextField source="id" />
|
||||
</ReferenceField>
|
||||
</Datagrid>
|
||||
</ReferenceManyField>
|
||||
@@ -206,10 +306,10 @@ export const RoomShow = (props: ShowProps) => {
|
||||
</Box>
|
||||
<ReferenceManyField reference="forward_extremities" target="room_id" label={false}>
|
||||
<Datagrid style={{ width: "100%" }} bulkActionButtons={false}>
|
||||
<TextField source="id" sortable={false} />
|
||||
<RaTextField source="id" sortable={false} />
|
||||
<DateField source="received_ts" showTime options={DATE_FORMAT} sortable={false} />
|
||||
<NumberField source="depth" sortable={false} />
|
||||
<TextField source="state_group" sortable={false} />
|
||||
<RaTextField source="state_group" sortable={false} />
|
||||
</Datagrid>
|
||||
</ReferenceManyField>
|
||||
</Tab>
|
||||
@@ -270,12 +370,13 @@ export const RoomList = (props: ListProps) => {
|
||||
}}
|
||||
/>
|
||||
<FunctionField source="name" render={record => record["name"] || record["canonical_alias"] || record["id"]} />
|
||||
<TextField source="joined_members" />
|
||||
<TextField source="joined_local_members" />
|
||||
<TextField source="state_events" />
|
||||
<TextField source="version" />
|
||||
<RaTextField source="joined_members" />
|
||||
<RaTextField source="joined_local_members" />
|
||||
<RaTextField source="state_events" />
|
||||
<RaTextField source="version" />
|
||||
<BooleanField source="federatable" />
|
||||
<BooleanField source="public" />
|
||||
<MakeAdminBtn />
|
||||
</DatagridConfigurable>
|
||||
</List>
|
||||
);
|
||||
|
@@ -79,6 +79,7 @@ import { useFormContext } from "react-hook-form";
|
||||
import { ExperimentalFeaturesList } from "../components/ExperimentalFeatures";
|
||||
import { UserRateLimits } from "../components/UserRateLimits";
|
||||
import { User, UsernameAvailabilityResult } from "../synapse/dataProvider";
|
||||
import { MakeAdminBtn } from "./rooms";
|
||||
|
||||
const choices_medium = [
|
||||
{ id: "email", name: "resources.users.email" },
|
||||
@@ -526,6 +527,7 @@ export const UserEdit = (props: EditProps) => {
|
||||
>
|
||||
<TextField source="name" sortable={false} />
|
||||
</ReferenceField>
|
||||
<MakeAdminBtn />
|
||||
</Datagrid>
|
||||
</ReferenceManyField>
|
||||
</FormTab>
|
||||
|
@@ -52,7 +52,7 @@ interface Action {
|
||||
body?: Record<string, any>;
|
||||
}
|
||||
|
||||
interface Room {
|
||||
export interface Room {
|
||||
room_id: string;
|
||||
name?: string;
|
||||
canonical_alias?: string;
|
||||
@@ -273,6 +273,7 @@ export interface SynapseDataProvider extends DataProvider {
|
||||
getRateLimits: (id: Identifier) => Promise<RateLimitsModel>;
|
||||
setRateLimits: (id: Identifier, rateLimits: RateLimitsModel) => Promise<void>;
|
||||
checkUsernameAvailability: (username: string) => Promise<UsernameAvailabilityResult>;
|
||||
makeRoomAdmin: (room_id: string, user_id: string) => Promise<{ success: boolean; error?: string; errcode?: string }>;
|
||||
}
|
||||
|
||||
const resourceMap = {
|
||||
@@ -866,6 +867,20 @@ const baseDataProvider: SynapseDataProvider = {
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
makeRoomAdmin: async (room_id: string, user_id: string) => {
|
||||
const base_url = storage.getItem("base_url");
|
||||
|
||||
const endpoint_url = `${base_url}/_synapse/admin/v1/rooms/${encodeURIComponent(room_id)}/make_room_admin`;
|
||||
try {
|
||||
const { json } = await jsonClient(endpoint_url, { method: "POST", body: JSON.stringify({ user_id }) });
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
if (error instanceof HttpError) {
|
||||
return { success: false, error: error.body.error, errcode: error.body.errcode };
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
288
yarn.lock
288
yarn.lock
@@ -332,7 +332,7 @@
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.25.7"
|
||||
|
||||
"@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.21.0", "@babel/runtime@^7.23.8", "@babel/runtime@^7.23.9", "@babel/runtime@^7.25.7", "@babel/runtime@^7.26.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.7":
|
||||
"@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.21.0", "@babel/runtime@^7.23.8", "@babel/runtime@^7.23.9", "@babel/runtime@^7.26.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.7":
|
||||
version "7.26.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.0.tgz#8600c2f595f277c60815256418b85356a65173c1"
|
||||
integrity sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==
|
||||
@@ -663,24 +663,24 @@
|
||||
resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0"
|
||||
integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==
|
||||
|
||||
"@eslint/config-array@^0.18.0":
|
||||
version "0.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.18.0.tgz#37d8fe656e0d5e3dbaea7758ea56540867fd074d"
|
||||
integrity sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==
|
||||
"@eslint/config-array@^0.19.0":
|
||||
version "0.19.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.19.0.tgz#3251a528998de914d59bb21ba4c11767cf1b3519"
|
||||
integrity sha512-zdHg2FPIFNKPdcHWtiNT+jEFCHYVplAXRDlQDyqy0zGx/q2parwh7brGJSiTxRk/TSMkbM//zt/f5CHgyTyaSQ==
|
||||
dependencies:
|
||||
"@eslint/object-schema" "^2.1.4"
|
||||
debug "^4.3.1"
|
||||
minimatch "^3.1.2"
|
||||
|
||||
"@eslint/core@^0.7.0":
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.7.0.tgz#a1bb4b6a4e742a5ff1894b7ee76fbf884ec72bd3"
|
||||
integrity sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==
|
||||
"@eslint/core@^0.9.0":
|
||||
version "0.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.9.0.tgz#168ee076f94b152c01ca416c3e5cf82290ab4fcd"
|
||||
integrity sha512-7ATR9F0e4W85D/0w7cU0SNj7qkAexMG+bAHEZOjo9akvGuhHE2m7umzWzfnpa0XAg5Kxc1BWmtPMV67jJ+9VUg==
|
||||
|
||||
"@eslint/eslintrc@^3.1.0":
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.1.0.tgz#dbd3482bfd91efa663cbe7aa1f506839868207b6"
|
||||
integrity sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==
|
||||
"@eslint/eslintrc@^3.2.0":
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.2.0.tgz#57470ac4e2e283a6bf76044d63281196e370542c"
|
||||
integrity sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==
|
||||
dependencies:
|
||||
ajv "^6.12.4"
|
||||
debug "^4.3.2"
|
||||
@@ -692,20 +692,20 @@
|
||||
minimatch "^3.1.2"
|
||||
strip-json-comments "^3.1.1"
|
||||
|
||||
"@eslint/js@9.14.0", "@eslint/js@^9.13.0":
|
||||
version "9.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.14.0.tgz#2347a871042ebd11a00fd8c2d3d56a265ee6857e"
|
||||
integrity sha512-pFoEtFWCPyDOl+C6Ift+wC7Ro89otjigCf5vcuWqWgqNSQbRrpjSvdeE6ofLz4dHmyxD5f7gIdGT4+p36L6Twg==
|
||||
"@eslint/js@9.15.0", "@eslint/js@^9.13.0":
|
||||
version "9.15.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.15.0.tgz#df0e24fe869143b59731942128c19938fdbadfb5"
|
||||
integrity sha512-tMTqrY+EzbXmKJR5ToI8lxu7jaN5EdmrBFJpQk5JmSlyLsx6o4t27r883K5xsLuCYCpfKBCGswMSWXsM+jB7lg==
|
||||
|
||||
"@eslint/object-schema@^2.1.4":
|
||||
version "2.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.4.tgz#9e69f8bb4031e11df79e03db09f9dbbae1740843"
|
||||
integrity sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==
|
||||
|
||||
"@eslint/plugin-kit@^0.2.0":
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.1.tgz#cd14fe2db79fa639839dfef4105e83bad1814482"
|
||||
integrity sha512-HFZ4Mp26nbWk9d/BpvP0YNL6W4UoZF0VFcTw/aPPA8RpOxeFQgK+ClABGgAUXs9Y/RGX/l1vOmrqz1MQt9MNuw==
|
||||
"@eslint/plugin-kit@^0.2.3":
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.3.tgz#812980a6a41ecf3a8341719f92a6d1e784a2e0e8"
|
||||
integrity sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==
|
||||
dependencies:
|
||||
levn "^0.4.1"
|
||||
|
||||
@@ -748,7 +748,7 @@
|
||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.1.tgz#c72a5c76a9fbaf3488e231b13dc52c0da7bab42a"
|
||||
integrity sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==
|
||||
|
||||
"@humanwhocodes/retry@^0.4.0":
|
||||
"@humanwhocodes/retry@^0.4.1":
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.1.tgz#9a96ce501bc62df46c4031fbd970e3cc6b10f07b"
|
||||
integrity sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==
|
||||
@@ -1006,10 +1006,10 @@
|
||||
resolved "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.7.tgz"
|
||||
integrity sha512-RtsCt4Geed2/v74sbihWzzRs+HsIQCfclHeORh5Ynu2fS4icIKozcSubwuG7vtzq2uW3fOR1zITSP84TNt2GoQ==
|
||||
|
||||
"@mui/core-downloads-tracker@^6.1.6":
|
||||
version "6.1.6"
|
||||
resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-6.1.6.tgz#73d96e75689b2af922a989123149a3497c8a96fa"
|
||||
integrity sha512-nz1SlR9TdBYYPz4qKoNasMPRiGb4PaIHFkzLzhju0YVYS5QSuFF2+n7CsiHMIDcHv3piPu/xDWI53ruhOqvZwQ==
|
||||
"@mui/core-downloads-tracker@^6.1.7":
|
||||
version "6.1.7"
|
||||
resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-6.1.7.tgz#80f4327804ee97b6af7b11980f87e29dc2231226"
|
||||
integrity sha512-POuIBi80BZBogQkG4PQKIGwy4QFwB+kOr+OI4k7Znh7LqMAIhwB9OC00l6M+w1GrZJYj3T8R5WX8G6QAIvoVEw==
|
||||
|
||||
"@mui/icons-material@^5.15.20":
|
||||
version "5.16.7"
|
||||
@@ -1018,12 +1018,12 @@
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.23.9"
|
||||
|
||||
"@mui/icons-material@^6.1.5":
|
||||
version "6.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-6.1.5.tgz#5b5a4237796956e208d480ebd68350a78d81d202"
|
||||
integrity sha512-SbxFtO5I4cXfvhjAMgGib/t2lQUzcEzcDFYiRHRufZUeMMeXuoKaGsptfwAHTepYkv0VqcCwvxtvtWbpZLAbjQ==
|
||||
"@mui/icons-material@^6.1.7":
|
||||
version "6.1.7"
|
||||
resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-6.1.7.tgz#79c0fa7087acbcba2fe81f89d9dda15cb65c6742"
|
||||
integrity sha512-RGzkeHNArIVy5ZQ12bq/8VYNeICEyngngsFskTJ/2hYKhIeIII3iRGtaZaSvLpXh7h3Fg3VKTulT+QU0w5K4XQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.25.7"
|
||||
"@babel/runtime" "^7.26.0"
|
||||
|
||||
"@mui/material@^5.15.20":
|
||||
version "5.16.7"
|
||||
@@ -1043,16 +1043,16 @@
|
||||
react-is "^18.3.1"
|
||||
react-transition-group "^4.4.5"
|
||||
|
||||
"@mui/material@^6.1.6":
|
||||
version "6.1.6"
|
||||
resolved "https://registry.yarnpkg.com/@mui/material/-/material-6.1.6.tgz#505d7300401f6af38426006d7fb3b8707dc10fbc"
|
||||
integrity sha512-1yvejiQ/601l5AK3uIdUlAVElyCxoqKnl7QA+2oFB/2qYPWfRwDgavW/MoywS5Y2gZEslcJKhe0s2F3IthgFgw==
|
||||
"@mui/material@^6.1.7":
|
||||
version "6.1.7"
|
||||
resolved "https://registry.yarnpkg.com/@mui/material/-/material-6.1.7.tgz#a30dcfdae6e3cbb184669813d6b3a8addd4540ee"
|
||||
integrity sha512-KsjujQL/A2hLd1PV3QboF+W6SSL5QqH6ZlSuQoeYz9r69+TnyBFIevbYLxdjJcJmGBjigL5pfpn7hTGop+vhSg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.26.0"
|
||||
"@mui/core-downloads-tracker" "^6.1.6"
|
||||
"@mui/system" "^6.1.6"
|
||||
"@mui/core-downloads-tracker" "^6.1.7"
|
||||
"@mui/system" "^6.1.7"
|
||||
"@mui/types" "^7.2.19"
|
||||
"@mui/utils" "^6.1.6"
|
||||
"@mui/utils" "^6.1.7"
|
||||
"@popperjs/core" "^2.11.8"
|
||||
"@types/react-transition-group" "^4.4.11"
|
||||
clsx "^2.1.1"
|
||||
@@ -1070,13 +1070,13 @@
|
||||
"@mui/utils" "^5.16.6"
|
||||
prop-types "^15.8.1"
|
||||
|
||||
"@mui/private-theming@^6.1.6":
|
||||
version "6.1.6"
|
||||
resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-6.1.6.tgz#9966bf2eca3d626cddd6e173752f46d344c7d7d1"
|
||||
integrity sha512-ioAiFckaD/fJSnTrUMWgjl9HYBWt7ixCh7zZw7gDZ+Tae7NuprNV6QJK95EidDT7K0GetR2rU3kAeIR61Myttw==
|
||||
"@mui/private-theming@^6.1.7":
|
||||
version "6.1.7"
|
||||
resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-6.1.7.tgz#9415c32eb567194b713941243cf18fde09981ba1"
|
||||
integrity sha512-uLbfUSsug5K0LVkv0PI6Flste3le8+6WSL2omdTiYde93P89Qr7pKr8TA6d2yXfr+Bm+SvD8/fGnkaRwFkryuQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.26.0"
|
||||
"@mui/utils" "^6.1.6"
|
||||
"@mui/utils" "^6.1.7"
|
||||
prop-types "^15.8.1"
|
||||
|
||||
"@mui/styled-engine@^5.16.6":
|
||||
@@ -1089,10 +1089,10 @@
|
||||
csstype "^3.1.3"
|
||||
prop-types "^15.8.1"
|
||||
|
||||
"@mui/styled-engine@^6.1.6":
|
||||
version "6.1.6"
|
||||
resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-6.1.6.tgz#61996621a0297aac16061e1739a738a899613fd6"
|
||||
integrity sha512-I+yS1cSuSvHnZDBO7e7VHxTWpj+R7XlSZvTC4lS/OIbUNJOMMSd3UDP6V2sfwzAdmdDNBi7NGCRv2SZ6O9hGDA==
|
||||
"@mui/styled-engine@^6.1.7":
|
||||
version "6.1.7"
|
||||
resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-6.1.7.tgz#2e38642325afe473dd14349c95a56e947640b154"
|
||||
integrity sha512-Ou4CxN7MQmwrfG1Pu6EYjPgPChQXxPDJrwgizLXlRPOad5qAq4gYXRuzrGQ2DfGjjwmJhjI8T6A0SeapAZPGig==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.26.0"
|
||||
"@emotion/cache" "^11.13.1"
|
||||
@@ -1115,16 +1115,16 @@
|
||||
csstype "^3.1.3"
|
||||
prop-types "^15.8.1"
|
||||
|
||||
"@mui/system@^6.1.6":
|
||||
version "6.1.6"
|
||||
resolved "https://registry.yarnpkg.com/@mui/system/-/system-6.1.6.tgz#d335d6952092f3c758c8b78c2d993aa13ef58175"
|
||||
integrity sha512-qOf1VUE9wK8syiB0BBCp82oNBAVPYdj4Trh+G1s+L+ImYiKlubWhhqlnvWt3xqMevR+D2h1CXzA1vhX2FvA+VQ==
|
||||
"@mui/system@^6.1.7":
|
||||
version "6.1.7"
|
||||
resolved "https://registry.yarnpkg.com/@mui/system/-/system-6.1.7.tgz#041d450b842d5c2fb1608d4027360ad2ba25bd9a"
|
||||
integrity sha512-qbMGgcC/FodpuRSfjXlEDdbNQaW++eATh0vNBcPUv2/YXSpReoOpoT9FhogxEBNks+aQViDXBRZKh6HX2fVmwg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.26.0"
|
||||
"@mui/private-theming" "^6.1.6"
|
||||
"@mui/styled-engine" "^6.1.6"
|
||||
"@mui/private-theming" "^6.1.7"
|
||||
"@mui/styled-engine" "^6.1.7"
|
||||
"@mui/types" "^7.2.19"
|
||||
"@mui/utils" "^6.1.6"
|
||||
"@mui/utils" "^6.1.7"
|
||||
clsx "^2.1.1"
|
||||
csstype "^3.1.3"
|
||||
prop-types "^15.8.1"
|
||||
@@ -1146,10 +1146,10 @@
|
||||
prop-types "^15.8.1"
|
||||
react-is "^18.3.1"
|
||||
|
||||
"@mui/utils@^6.1.6":
|
||||
version "6.1.6"
|
||||
resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-6.1.6.tgz#4b9fd34da3a1dd4700fe506a20ca7da3933ba48e"
|
||||
integrity sha512-sBS6D9mJECtELASLM+18WUcXF6RH3zNxBRFeyCRg8wad6NbyNrdxLuwK+Ikvc38sTZwBzAz691HmSofLqHd9sQ==
|
||||
"@mui/utils@^6.1.7":
|
||||
version "6.1.7"
|
||||
resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-6.1.7.tgz#0959d9772ae13c6ceac984a493e06aebb9087e71"
|
||||
integrity sha512-Gr7cRZxBoZ0BIa3Xqf/2YaUrBLyNPJvXPQH3OsD9WMZukI/TutibbQBVqLYpgqJn8pKSjbD50Yq2auG0wI1xOw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.26.0"
|
||||
"@mui/types" "^7.2.19"
|
||||
@@ -1298,17 +1298,17 @@
|
||||
dependencies:
|
||||
"@sinonjs/commons" "^3.0.0"
|
||||
|
||||
"@tanstack/query-core@5.59.20":
|
||||
version "5.59.20"
|
||||
resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.59.20.tgz#356718976536727b9af0ad1163a21fd6a44ee0a9"
|
||||
integrity sha512-e8vw0lf7KwfGe1if4uPFhvZRWULqHjFcz3K8AebtieXvnMOz5FSzlZe3mTLlPuUBcydCnBRqYs2YJ5ys68wwLg==
|
||||
"@tanstack/query-core@5.60.5":
|
||||
version "5.60.5"
|
||||
resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.60.5.tgz#37b7c5ab7e6894cea9ef341299a7a3febc2ea361"
|
||||
integrity sha512-jiS1aC3XI3BJp83ZiTuDLerTmn9P3U95r6p+6/SNauLJaYxfIC4dMuWygwnBHIZxjn2zJqEpj3nysmPieoxfPQ==
|
||||
|
||||
"@tanstack/react-query@^5.59.20", "@tanstack/react-query@^5.8.4":
|
||||
version "5.59.20"
|
||||
resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.59.20.tgz#bacf1983f44c5690bb99b518f2ef71dc2fa875a4"
|
||||
integrity sha512-Zly0egsK0tFdfSbh5/mapSa+Zfc3Et0Zkar7Wo5sQkFzWyB3p3uZWOHR2wrlAEEV2L953eLuDBtbgFvMYiLvUw==
|
||||
"@tanstack/react-query@^5.60.5", "@tanstack/react-query@^5.8.4":
|
||||
version "5.60.5"
|
||||
resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.60.5.tgz#3194c390f7eff20542b321c3042880dc3f1a81e2"
|
||||
integrity sha512-M77bOsPwj1wYE56gk7iJvxGAr4IC12NWdIDhT+Eo8ldkWRHMvIR8I/rufIvT1OXoV/bl7EECwuRuMlxxWtvW2Q==
|
||||
dependencies:
|
||||
"@tanstack/query-core" "5.59.20"
|
||||
"@tanstack/query-core" "5.60.5"
|
||||
|
||||
"@testing-library/dom@^10.0.0":
|
||||
version "10.4.0"
|
||||
@@ -1541,7 +1541,7 @@
|
||||
dependencies:
|
||||
"@types/yargs-parser" "*"
|
||||
|
||||
"@typescript-eslint/eslint-plugin@8.13.0", "@typescript-eslint/eslint-plugin@^8.11.0":
|
||||
"@typescript-eslint/eslint-plugin@8.13.0":
|
||||
version "8.13.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.13.0.tgz#650c50b8c795b5d092189f139f6d00535b5b0f3d"
|
||||
integrity sha512-nQtBLiZYMUPkclSeC3id+x4uVd1SGtHuElTxL++SfP47jR0zfkZBJHc+gL4qPsgTuypz0k8Y2GheaDYn6Gy3rg==
|
||||
@@ -1556,6 +1556,21 @@
|
||||
natural-compare "^1.4.0"
|
||||
ts-api-utils "^1.3.0"
|
||||
|
||||
"@typescript-eslint/eslint-plugin@^8.14.0":
|
||||
version "8.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.14.0.tgz#7dc0e419c87beadc8f554bf5a42e5009ed3748dc"
|
||||
integrity sha512-tqp8H7UWFaZj0yNO6bycd5YjMwxa6wIHOLZvWPkidwbgLCsBMetQoGj7DPuAlWa2yGO3H48xmPwjhsSPPCGU5w==
|
||||
dependencies:
|
||||
"@eslint-community/regexpp" "^4.10.0"
|
||||
"@typescript-eslint/scope-manager" "8.14.0"
|
||||
"@typescript-eslint/type-utils" "8.14.0"
|
||||
"@typescript-eslint/utils" "8.14.0"
|
||||
"@typescript-eslint/visitor-keys" "8.14.0"
|
||||
graphemer "^1.4.0"
|
||||
ignore "^5.3.1"
|
||||
natural-compare "^1.4.0"
|
||||
ts-api-utils "^1.3.0"
|
||||
|
||||
"@typescript-eslint/parser@8.13.0", "@typescript-eslint/parser@^8.13.0":
|
||||
version "8.13.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.13.0.tgz#ef76203b7cac515aa3ccc4f7ce5320dd61c46b29"
|
||||
@@ -1575,6 +1590,14 @@
|
||||
"@typescript-eslint/types" "8.13.0"
|
||||
"@typescript-eslint/visitor-keys" "8.13.0"
|
||||
|
||||
"@typescript-eslint/scope-manager@8.14.0":
|
||||
version "8.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.14.0.tgz#01f37c147a735cd78f0ff355e033b9457da1f373"
|
||||
integrity sha512-aBbBrnW9ARIDn92Zbo7rguLnqQ/pOrUguVpbUwzOhkFg2npFDwTgPGqFqE0H5feXcOoJOfX3SxlJaKEVtq54dw==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "8.14.0"
|
||||
"@typescript-eslint/visitor-keys" "8.14.0"
|
||||
|
||||
"@typescript-eslint/type-utils@8.13.0":
|
||||
version "8.13.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.13.0.tgz#8c8fa68490dcb9ae1687ffc7de8fbe23c26417bd"
|
||||
@@ -1585,11 +1608,26 @@
|
||||
debug "^4.3.4"
|
||||
ts-api-utils "^1.3.0"
|
||||
|
||||
"@typescript-eslint/type-utils@8.14.0":
|
||||
version "8.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.14.0.tgz#455c6af30c336b24a1af28bc4f81b8dd5d74d94d"
|
||||
integrity sha512-Xcz9qOtZuGusVOH5Uk07NGs39wrKkf3AxlkK79RBK6aJC1l03CobXjJbwBPSidetAOV+5rEVuiT1VSBUOAsanQ==
|
||||
dependencies:
|
||||
"@typescript-eslint/typescript-estree" "8.14.0"
|
||||
"@typescript-eslint/utils" "8.14.0"
|
||||
debug "^4.3.4"
|
||||
ts-api-utils "^1.3.0"
|
||||
|
||||
"@typescript-eslint/types@8.13.0":
|
||||
version "8.13.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.13.0.tgz#3f35dead2b2491a04339370dcbcd17bbdfc204d8"
|
||||
integrity sha512-4cyFErJetFLckcThRUFdReWJjVsPCqyBlJTi6IDEpc1GWCIIZRFxVppjWLIMcQhNGhdWJJRYFHpHoDWvMlDzng==
|
||||
|
||||
"@typescript-eslint/types@8.14.0":
|
||||
version "8.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.14.0.tgz#0d33d8d0b08479c424e7d654855fddf2c71e4021"
|
||||
integrity sha512-yjeB9fnO/opvLJFAsPNYlKPnEM8+z4og09Pk504dkqonT02AyL5Z9SSqlE0XqezS93v6CXn49VHvB2G7XSsl0g==
|
||||
|
||||
"@typescript-eslint/typescript-estree@8.13.0":
|
||||
version "8.13.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.13.0.tgz#db8c93dd5437ca3ce417a255fb35ddc3c12c3e95"
|
||||
@@ -1604,6 +1642,20 @@
|
||||
semver "^7.6.0"
|
||||
ts-api-utils "^1.3.0"
|
||||
|
||||
"@typescript-eslint/typescript-estree@8.14.0":
|
||||
version "8.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.14.0.tgz#a7a3a5a53a6c09313e12fb4531d4ff582ee3c312"
|
||||
integrity sha512-OPXPLYKGZi9XS/49rdaCbR5j/S14HazviBlUQFvSKz3npr3NikF+mrgK7CFVur6XEt95DZp/cmke9d5i3vtVnQ==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "8.14.0"
|
||||
"@typescript-eslint/visitor-keys" "8.14.0"
|
||||
debug "^4.3.4"
|
||||
fast-glob "^3.3.2"
|
||||
is-glob "^4.0.3"
|
||||
minimatch "^9.0.4"
|
||||
semver "^7.6.0"
|
||||
ts-api-utils "^1.3.0"
|
||||
|
||||
"@typescript-eslint/utils@8.13.0":
|
||||
version "8.13.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.13.0.tgz#f6d40e8b5053dcaeabbd2e26463857abf27d62c0"
|
||||
@@ -1614,6 +1666,16 @@
|
||||
"@typescript-eslint/types" "8.13.0"
|
||||
"@typescript-eslint/typescript-estree" "8.13.0"
|
||||
|
||||
"@typescript-eslint/utils@8.14.0":
|
||||
version "8.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.14.0.tgz#ac2506875e03aba24e602364e43b2dfa45529dbd"
|
||||
integrity sha512-OGqj6uB8THhrHj0Fk27DcHPojW7zKwKkPmHXHvQ58pLYp4hy8CSUdTKykKeh+5vFqTTVmjz0zCOOPKRovdsgHA==
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils" "^4.4.0"
|
||||
"@typescript-eslint/scope-manager" "8.14.0"
|
||||
"@typescript-eslint/types" "8.14.0"
|
||||
"@typescript-eslint/typescript-estree" "8.14.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@8.13.0":
|
||||
version "8.13.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.13.0.tgz#e97b0d92b266ef38a1faf40a74da289b66683a5b"
|
||||
@@ -1622,6 +1684,14 @@
|
||||
"@typescript-eslint/types" "8.13.0"
|
||||
eslint-visitor-keys "^3.4.3"
|
||||
|
||||
"@typescript-eslint/visitor-keys@8.14.0":
|
||||
version "8.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.14.0.tgz#2418d5a54669af9658986ade4e6cfb7767d815ad"
|
||||
integrity sha512-vG0XZo8AdTH9OE6VFRwAZldNc7qtJ/6NLGWak+BtENuEUXGZgFpihILPiBvKXvJ2nFu27XNGC6rKiwuaoMbYzQ==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "8.14.0"
|
||||
eslint-visitor-keys "^3.4.3"
|
||||
|
||||
"@vitejs/plugin-react@^4.3.3":
|
||||
version "4.3.3"
|
||||
resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-4.3.3.tgz#28301ac6d7aaf20b73a418ee5c65b05519b4836c"
|
||||
@@ -2212,10 +2282,10 @@ cross-fetch@^3.0.4:
|
||||
dependencies:
|
||||
node-fetch "^2.6.12"
|
||||
|
||||
cross-spawn@^7.0.2, cross-spawn@^7.0.3:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz"
|
||||
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
|
||||
cross-spawn@^7.0.3, cross-spawn@^7.0.5:
|
||||
version "7.0.5"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.5.tgz#910aac880ff5243da96b728bc6521a5f6c2f2f82"
|
||||
integrity sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==
|
||||
dependencies:
|
||||
path-key "^3.1.0"
|
||||
shebang-command "^2.0.0"
|
||||
@@ -2779,26 +2849,26 @@ eslint-visitor-keys@^4.2.0:
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz#687bacb2af884fcdda8a6e7d65c606f46a14cd45"
|
||||
integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==
|
||||
|
||||
eslint@^9.14.0:
|
||||
version "9.14.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.14.0.tgz#534180a97c00af08bcf2b60b0ebf0c4d6c1b2c95"
|
||||
integrity sha512-c2FHsVBr87lnUtjP4Yhvk4yEhKrQavGafRA/Se1ouse8PfbfC/Qh9Mxa00yWsZRlqeUB9raXip0aiiUZkgnr9g==
|
||||
eslint@^9.15.0:
|
||||
version "9.15.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.15.0.tgz#77c684a4e980e82135ebff8ee8f0a9106ce6b8a6"
|
||||
integrity sha512-7CrWySmIibCgT1Os28lUU6upBshZ+GxybLOrmRzi08kS8MBuO8QA7pXEgYgY5W8vK3e74xv0lpjo9DbaGU9Rkw==
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils" "^4.2.0"
|
||||
"@eslint-community/regexpp" "^4.12.1"
|
||||
"@eslint/config-array" "^0.18.0"
|
||||
"@eslint/core" "^0.7.0"
|
||||
"@eslint/eslintrc" "^3.1.0"
|
||||
"@eslint/js" "9.14.0"
|
||||
"@eslint/plugin-kit" "^0.2.0"
|
||||
"@eslint/config-array" "^0.19.0"
|
||||
"@eslint/core" "^0.9.0"
|
||||
"@eslint/eslintrc" "^3.2.0"
|
||||
"@eslint/js" "9.15.0"
|
||||
"@eslint/plugin-kit" "^0.2.3"
|
||||
"@humanfs/node" "^0.16.6"
|
||||
"@humanwhocodes/module-importer" "^1.0.1"
|
||||
"@humanwhocodes/retry" "^0.4.0"
|
||||
"@humanwhocodes/retry" "^0.4.1"
|
||||
"@types/estree" "^1.0.6"
|
||||
"@types/json-schema" "^7.0.15"
|
||||
ajv "^6.12.4"
|
||||
chalk "^4.0.0"
|
||||
cross-spawn "^7.0.2"
|
||||
cross-spawn "^7.0.5"
|
||||
debug "^4.3.2"
|
||||
escape-string-regexp "^4.0.0"
|
||||
eslint-scope "^8.2.0"
|
||||
@@ -2818,7 +2888,6 @@ eslint@^9.14.0:
|
||||
minimatch "^3.1.2"
|
||||
natural-compare "^1.4.0"
|
||||
optionator "^0.9.3"
|
||||
text-table "^0.2.0"
|
||||
|
||||
espree@^10.0.1, espree@^10.3.0:
|
||||
version "10.3.0"
|
||||
@@ -4648,10 +4717,10 @@ ra-core@^4.11.2, ra-core@^4.16.2:
|
||||
react-is "^17.0.2"
|
||||
react-query "^3.32.1"
|
||||
|
||||
ra-core@^5.3.2, ra-core@^5.3.3:
|
||||
version "5.3.3"
|
||||
resolved "https://registry.yarnpkg.com/ra-core/-/ra-core-5.3.3.tgz#b9ca8bb9517718b444f291f5ccf5ff45bf28feef"
|
||||
integrity sha512-M1EyuSyc6QCblRWUtNklgcK3mnh34SnKF01JOuIcncaKW0DQhLE7R9sagBVTJ44ZxxZGBSweW6+Ah8YZ162cCg==
|
||||
ra-core@^5.3.3, ra-core@^5.3.4:
|
||||
version "5.3.4"
|
||||
resolved "https://registry.yarnpkg.com/ra-core/-/ra-core-5.3.4.tgz#849f6da3460b896f295f5a88ea2b8a1487c7111d"
|
||||
integrity sha512-BC6pO8jaUjJESfO0FS6J2CMgeRreJ2kpdPkkySBODM0M5S4ZRC0rOFh1jBXFnjSUcNoPWaVc/WaZPwfAg00Wmw==
|
||||
dependencies:
|
||||
"@tanstack/react-query" "^5.8.4"
|
||||
clsx "^2.1.1"
|
||||
@@ -4664,32 +4733,32 @@ ra-core@^5.3.2, ra-core@^5.3.3:
|
||||
react-error-boundary "^4.0.13"
|
||||
react-is "^18.2.0"
|
||||
|
||||
ra-i18n-polyglot@^5.3.2, ra-i18n-polyglot@^5.3.3:
|
||||
version "5.3.3"
|
||||
resolved "https://registry.yarnpkg.com/ra-i18n-polyglot/-/ra-i18n-polyglot-5.3.3.tgz#d85c5b9496660454e815d64682f40dbd6ccb4347"
|
||||
integrity sha512-IqTg364wwPjz+DssVTKe6tKwyCp9336yHhjwil8/xnANLJvEVU6jz4JfQniT9RDg2HtA895hAR/o21dazzXsOg==
|
||||
ra-i18n-polyglot@^5.3.3, ra-i18n-polyglot@^5.3.4:
|
||||
version "5.3.4"
|
||||
resolved "https://registry.yarnpkg.com/ra-i18n-polyglot/-/ra-i18n-polyglot-5.3.4.tgz#f4653d6d6a9bcf1f52d65993e2a6e5acf2b7e000"
|
||||
integrity sha512-9BtWoCHE5LxIN4+VJGOrxL29lDhCTgBjIDkTb/i228vr/CD3+ozjyMiBG8NGeLN5wCqtHpsKDwUNJOcoPtwkiQ==
|
||||
dependencies:
|
||||
node-polyglot "^2.2.2"
|
||||
ra-core "^5.3.3"
|
||||
ra-core "^5.3.4"
|
||||
|
||||
ra-language-english@^5.3.2, ra-language-english@^5.3.3:
|
||||
version "5.3.3"
|
||||
resolved "https://registry.yarnpkg.com/ra-language-english/-/ra-language-english-5.3.3.tgz#9f532dd2471d3b9ae818245044d186d5b27c707e"
|
||||
integrity sha512-MM8y1R+Ts8Q9Vn+lph27kFwscs+lzMb+xmtDSQIK0/1Fq8f96JA8ogw0u+lKGhTA7t1iudjulBlD/mnuYZJoGg==
|
||||
ra-language-english@^5.3.3, ra-language-english@^5.3.4:
|
||||
version "5.3.4"
|
||||
resolved "https://registry.yarnpkg.com/ra-language-english/-/ra-language-english-5.3.4.tgz#a1ffcd848ec1b080f4dc3728332e0ceedb1f6783"
|
||||
integrity sha512-QR0ej0JKQaGmtGSh1W+O4HnoaTv/9SQBtpztAkTitPVjlCGJeNBr/IjriAxsp0ezhhCr+uZrwrCfoWjKPkjpDg==
|
||||
dependencies:
|
||||
ra-core "^5.3.3"
|
||||
ra-core "^5.3.4"
|
||||
|
||||
ra-language-farsi@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.npmjs.org/ra-language-farsi/-/ra-language-farsi-5.0.0.tgz"
|
||||
integrity sha512-wdveom01mdPY3KiFBWj4cc1f1YhWWi4pqNIuY79jgbJ43Kk72qOQIr3byWipy/Nt7dYzrAP3IvXmylWLLMmgnw==
|
||||
|
||||
ra-language-french@^5.3.3:
|
||||
version "5.3.3"
|
||||
resolved "https://registry.yarnpkg.com/ra-language-french/-/ra-language-french-5.3.3.tgz#38bfe37ef991a31596cd2b5230d0393a1c51a4ab"
|
||||
integrity sha512-N5r6qUpEIkyxU4dFf+57kBaugPPWJ1ZCJ0Y9bnqrvENdsxcYDZwXx1hWUP4TU69iynEnsCCwkl8Sxcbo37vJ2Q==
|
||||
ra-language-french@^5.3.4:
|
||||
version "5.3.4"
|
||||
resolved "https://registry.yarnpkg.com/ra-language-french/-/ra-language-french-5.3.4.tgz#11c16d9fcefcf1e9f82ac291fe7f6beb083a1a22"
|
||||
integrity sha512-7w+Z7Dpvo+hSa3MWcM3O6HnbGgrhi9RnDxDygDCOlV01oDgYBz+sgZE+aZUzOHkmVdvCT1hpaytGJYqiT06Sqg==
|
||||
dependencies:
|
||||
ra-core "^5.3.3"
|
||||
ra-core "^5.3.4"
|
||||
|
||||
ra-language-italian@^3.13.1:
|
||||
version "3.13.1"
|
||||
@@ -5276,11 +5345,6 @@ test-exclude@^6.0.0:
|
||||
glob "^7.1.4"
|
||||
minimatch "^3.0.4"
|
||||
|
||||
text-table@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz"
|
||||
integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==
|
||||
|
||||
tmpl@1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz"
|
||||
@@ -5524,10 +5588,10 @@ vite-plugin-version-mark@^0.1.2:
|
||||
resolved "https://registry.yarnpkg.com/vite-plugin-version-mark/-/vite-plugin-version-mark-0.1.2.tgz#85b2315cffce7ac2d83b6afceb313d0d1c47c4d4"
|
||||
integrity sha512-+mPRTwx6SOEfEq3/y1u+O0ju5Lz0Ac27Fx6hE5Xn1fMpIQfo3aERPB2/xxYI8lIa8GPHCX5c8ApqBKWwFNHxwA==
|
||||
|
||||
vite@^5.4.10:
|
||||
version "5.4.10"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.10.tgz#d358a7bd8beda6cf0f3b7a450a8c7693a4f80c18"
|
||||
integrity sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==
|
||||
vite@^5.4.11:
|
||||
version "5.4.11"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.11.tgz#3b415cd4aed781a356c1de5a9ebafb837715f6e5"
|
||||
integrity sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==
|
||||
dependencies:
|
||||
esbuild "^0.21.3"
|
||||
postcss "^8.4.43"
|
||||
|
Reference in New Issue
Block a user