Compare commits

3 Commits

Author SHA1 Message Date
Aine
52a2f1c936 reword managed user error 2024-09-24 21:58:24 +03:00
Aine
e328380c77 Restrict actions on specific users (#42)
* Restrict actions on specific users

* update readme
2024-09-24 13:25:29 +03:00
dependabot[bot]
a277ded227 Bump rollup from 4.22.0 to 4.22.4 (#41)
Bumps [rollup](https://github.com/rollup/rollup) from 4.22.0 to 4.22.4.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v4.22.0...v4.22.4)

---
updated-dependencies:
- dependency-name: rollup
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-24 10:18:09 +03:00
14 changed files with 211 additions and 131 deletions

View File

@@ -33,6 +33,7 @@ The following changes are already implemented:
* [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)
_the list will be updated as new changes are added_
@@ -126,37 +127,6 @@ You have three options:
- browse to http://localhost:8080
### Restricting available homeserver
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://your-matrixs-erver.example.com"
}
```
or to a list of homeservers:
```json
{
"restrictBaseUrl": ["https://your-first-matrix-server.example.com", "https://your-second-matrix-server.example.com"]
}
```
The `config.json` can be injected into a Docker container using a bind mount.
```yml
services:
synapse-admin:
...
volumes:
./config.json:/app/config.json:ro
...
```
### Serving Synapse-Admin on a different path
The path prefix where synapse-admin is served can only be changed during the build step.
@@ -194,6 +164,54 @@ services:
- "traefik.http.middlewares.admin_path.stripprefix.prefixes=/admin"
```
## Configuration
You can use `config.json` file to configure synapse-admin
The `config.json` can be injected into a Docker container using a bind mount.
```yml
services:
synapse-admin:
...
volumes:
./config.json:/app/config.json:ro
...
```
### Restricting available homeserver
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://your-matrixs-erver.example.com"
}
```
or to a list of homeservers:
```json
{
"restrictBaseUrl": ["https://your-first-matrix-server.example.com", "https://your-second-matrix-server.example.com"]
}
```
### 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$"]
}
```
## Screenshots
![Screenshots](./screenshots.jpg)

View File

@@ -2,6 +2,7 @@ import { createContext, useContext } from "react";
interface AppContextType {
restrictBaseUrl: string | string[];
asManagedUsers: string[];
}
export const AppContext = createContext({});

View File

@@ -1,9 +1,15 @@
import { DeleteWithConfirmButton, DeleteWithConfirmButtonProps, useRecordContext } from "react-admin";
import { isASManaged } from "./mxid";
export const DeviceRemoveButton = (props: DeleteWithConfirmButtonProps) => {
const record = useRecordContext();
if (!record) return null;
let isASManagedUser = false;
if (record.user_id) {
isASManagedUser = isASManaged(record.user_id);
}
return (
<DeleteWithConfirmButton
{...props}
@@ -12,6 +18,7 @@ export const DeviceRemoveButton = (props: DeleteWithConfirmButtonProps) => {
confirmContent="resources.devices.action.erase.content"
mutationMode="pessimistic"
redirect={false}
disabled={isASManagedUser}
translateOptions={{
id: record.id,
name: record.display_name ? record.display_name : record.id,

15
src/components/mxid.tsx Normal file
View File

@@ -0,0 +1,15 @@
/**
* Check if a user is managed by an application service
* @param id The user ID to check
* @returns Whether the user is managed by an application service
*/
export const isASManaged = (id: string) => {
const managedUsersString = localStorage.getItem("as_managed_users");
try {
const asManagedUsers = JSON.parse(managedUsersString).map(regex => new RegExp(regex));
return asManagedUsers.some(regex => regex.test(id));
} catch (e) {
return false;
}
};

View File

@@ -150,8 +150,9 @@ const de: SynapseTranslationMessages = {
helper: {
password: "Durch die Änderung des Passworts wird der Benutzer von allen Sitzungen abgemeldet.",
deactivate: "Sie müssen ein Passwort angeben, um ein Konto wieder zu aktivieren.",
erase: "DSGVO konformes Löschen der Benutzerdaten",
erase_admin_error: "Das Löschen des eigenen Benutzers ist nicht erlaubt",
erase: "DSGVO konformes Löschen der Benutzerdaten.",
erase_admin_error: "Das Löschen des eigenen Benutzers ist nicht erlaubt.",
modify_managed_user_error: "Das Ändern eines vom System verwalteten Benutzers ist nicht zulässig.",
},
action: {
erase: "Lösche Benutzerdaten",

View File

@@ -143,6 +143,7 @@ const en: SynapseTranslationMessages = {
deactivate: "You must provide a password to re-activate an account.",
erase: "Mark the user as GDPR-erased",
erase_admin_error: "Deleting own user is not allowed.",
modify_managed_user_error: "Modifying a system-managed user is not allowed.",
},
action: {
erase: "Erase user data",

View File

@@ -138,6 +138,8 @@ const fa: SynapseTranslationMessages = {
password: "با تغییر رمز عبور کاربر از تمام دستگاه ها خارج می شود.",
deactivate: "برای فعالسازی مجدد حساب باید رمز عبور وارد کنید.",
erase: "کاربر را به عنوان GDPR پاک شده علامت گذاری کنید",
erase_admin_error: "حذف المستخدم الخاص غير مسموح به.",
modify_managed_user_error: "لا يُسمح بتغيير المستخدم الذي يديره النظام.",
},
action: {
erase: "پاک کردن اطلاعات کاربر",

View File

@@ -141,6 +141,7 @@ const fr: SynapseTranslationMessages = {
deactivate: "Vous devrez fournir un mot de passe pour réactiver le compte.",
erase: "Marquer l'utilisateur comme effacé conformément au RGPD",
erase_admin_error: "La suppression de son propre utilisateur n'est pas autorisée.",
modify_managed_user_error: "La modification d'un utilisateur géré par le système n'est pas autorisée.",
},
action: {
erase: "Effacer les données de l'utilisateur",

View File

@@ -143,6 +143,7 @@ const it: SynapseTranslationMessages = {
action: {
erase: "Cancella i dati dell'utente",
erase_admin_error: "Non è consentito eliminare il proprio utente.",
modify_managed_user_error: "La modifica di un utente gestito dal sistema non è consentita.",
},
},
rooms: {

View File

@@ -160,6 +160,7 @@ const ru: SynapseTranslationMessages = {
deactivate: "Вы должны предоставить пароль для реактивации учётной записи.",
erase: "Пометить пользователя как удалённого в соответствии с GDPR",
erase_admin_error: "Удаление собственного пользователя запрещено.",
modify_managed_user_error: "Изменение пользователя, управляемого системой, не допускается.",
},
action: {
erase: "Удалить данные пользователя",

View File

@@ -144,6 +144,7 @@ const zh: SynapseTranslationMessages = {
deactivate: "您必须提供一串密码来激活账户。",
erase: "将用户标记为根据 GDPR 的要求抹除了",
erase_admin_error: "不允许删除自己的用户",
modify_managed_user_error: "不允许修改系统管理的用户。",
},
action: {
erase: "抹除用户信息",

View File

@@ -4,15 +4,17 @@ import { createRoot } from "react-dom/client";
import App from "./App";
import { AppContext } from "./AppContext";
import storage from "./storage";
fetch("config.json")
.then(res => res.json())
.then(props =>
createRoot(document.getElementById("root")).render(
.then(props => {
storage.setItem("as_managed_users", JSON.stringify(props.asManagedUsers));
return createRoot(document.getElementById("root")).render(
<React.StrictMode>
<AppContext.Provider value={props}>
<App />
</AppContext.Provider>
</React.StrictMode>
)
);
});

View File

@@ -61,6 +61,7 @@ import {
import { Link } from "react-router-dom";
import AvatarField from "../components/AvatarField";
import { isASManaged } from "../components/mxid";
import { ServerNoticeButton, ServerNoticeBulkButton } from "../components/ServerNotices";
import { DATE_FORMAT } from "../components/date";
import { DeviceRemoveButton } from "../components/devices";
@@ -103,8 +104,9 @@ const userFilters = [
<BooleanInput label="resources.users.fields.show_locked" source="locked" alwaysOn />,
];
const UserPreventSelfDelete: React.FC<{ children: React.ReactNode; ownUserIsSelected: boolean }> = props => {
const UserPreventSelfDelete: React.FC<{ children: React.ReactNode; ownUserIsSelected: boolean; asManagedUserIsSelected: boolean }> = props => {
const ownUserIsSelected = props.ownUserIsSelected;
const asManagedUserIsSelected = props.asManagedUserIsSelected;
const notify = useNotify();
const translate = useTranslate();
@@ -112,6 +114,9 @@ const UserPreventSelfDelete: React.FC<{ children: React.ReactNode; ownUserIsSele
if (ownUserIsSelected) {
notify(<Alert severity="error">{translate("resources.users.helper.erase_admin_error")}</Alert>);
ev.stopPropagation();
} else if (asManagedUserIsSelected) {
notify(<Alert severity="error">{translate("resources.users.helper.modify_managed_user_error")}</Alert>);
ev.stopPropagation();
}
};
@@ -121,6 +126,7 @@ const UserPreventSelfDelete: React.FC<{ children: React.ReactNode; ownUserIsSele
const UserBulkActionButtons = () => {
const record = useListContext();
const [ownUserIsSelected, setOwnUserIsSelected] = useState(false);
const [asManagedUserIsSelected, setAsManagedUserIsSelected] = useState(false);
const selectedIds = record.selectedIds;
const ownUserId = localStorage.getItem("user_id");
const notify = useNotify();
@@ -128,12 +134,13 @@ const UserBulkActionButtons = () => {
useEffect(() => {
setOwnUserIsSelected(selectedIds.includes(ownUserId));
setAsManagedUserIsSelected(selectedIds.some(id => isASManaged(id)));
}, [selectedIds]);
return (
<>
<ServerNoticeBulkButton />
<UserPreventSelfDelete ownUserIsSelected={ownUserIsSelected}>
<UserPreventSelfDelete ownUserIsSelected={ownUserIsSelected} asManagedUserIsSelected={asManagedUserIsSelected}>
<BulkDeleteButton
label="resources.users.action.erase"
confirmTitle="resources.users.helper.erase"
@@ -184,14 +191,16 @@ const UserEditActions = () => {
const translate = useTranslate();
const ownUserId = localStorage.getItem("user_id");
let ownUserIsSelected = false;
let asManagedUserIsSelected = false;
if (record && record.id) {
ownUserIsSelected = record.id === ownUserId;
asManagedUserIsSelected = isASManaged(record.id);
}
return (
<TopToolbar>
{!record?.deactivated && <ServerNoticeButton />}
<UserPreventSelfDelete ownUserIsSelected={ownUserIsSelected}>
<UserPreventSelfDelete ownUserIsSelected={ownUserIsSelected} asManagedUserIsSelected={asManagedUserIsSelected}>
<DeleteButton
label="resources.users.action.erase"
confirmTitle={translate("resources.users.helper.erase", {
@@ -236,12 +245,16 @@ export const UserCreate = (props: CreateProps) => (
const UserTitle = () => {
const record = useRecordContext();
const translate = useTranslate();
let username = record ? (record.displayname ? `"${record.displayname}"` : `"${record.name}"`) : ""
if (isASManaged(record?.id)) {
username += " 🤖";
}
return (
<span>
{translate("resources.users.name", {
smart_count: 1,
})}{" "}
{record ? (record.displayname ? `"${record.displayname}"` : `"${record.name}"`) : ""}
{username}
</span>
);
};
@@ -250,8 +263,10 @@ const UserEditToolbar = () => {
const record = useRecordContext();
const ownUserId = localStorage.getItem("user_id");
let ownUserIsSelected = false;
let asManagedUserIsSelected = false;
if (record && record.id) {
ownUserIsSelected = record.id === ownUserId;
asManagedUserIsSelected = isASManaged(record.id);
}
return (
@@ -259,7 +274,7 @@ const UserEditToolbar = () => {
<div className={ToolbarClasses.defaultToolbar}>
<Toolbar sx={{ justifyContent: "space-between" }}>
<SaveButton />
<UserPreventSelfDelete ownUserIsSelected={ownUserIsSelected}>
<UserPreventSelfDelete ownUserIsSelected={ownUserIsSelected} asManagedUserIsSelected={asManagedUserIsSelected}>
<DeleteButton />
</UserPreventSelfDelete>
</Toolbar>
@@ -272,17 +287,31 @@ const UserBooleanInput = props => {
const record = useRecordContext();
const ownUserId = localStorage.getItem("user_id");
let ownUserIsSelected = false;
if (record && record.id === ownUserId) {
ownUserIsSelected = true;
let asManagedUserIsSelected = false;
if (record) {
ownUserIsSelected = record.id === ownUserId;
asManagedUserIsSelected = isASManaged(record.id);
}
return (
<UserPreventSelfDelete ownUserIsSelected={ownUserIsSelected}>
<BooleanInput {...props} disabled={ownUserIsSelected} />
<UserPreventSelfDelete ownUserIsSelected={ownUserIsSelected} asManagedUserIsSelected={asManagedUserIsSelected}>
<BooleanInput {...props} disabled={ownUserIsSelected || asManagedUserIsSelected} />
</UserPreventSelfDelete>
);
};
const UserPasswordInput = props => {
const record = useRecordContext();
let asManagedUserIsSelected = false;
if (record) {
asManagedUserIsSelected = isASManaged(record.id);
}
return (
<PasswordInput {...props} helperText="resources.users.helper.modify_managed_user_error" disabled={asManagedUserIsSelected} />
);
};
export const UserEdit = (props: EditProps) => {
const translate = useTranslate();
@@ -301,10 +330,10 @@ export const UserEdit = (props: EditProps) => {
</ImageInput>
<TextInput source="id" readOnly />
<TextInput source="displayname" />
<PasswordInput source="password" autoComplete="new-password" helperText="resources.users.helper.password" />
<UserPasswordInput source="password" autoComplete="new-password" helperText="resources.users.helper.password" />
<SelectInput source="user_type" choices={choices_type} translateChoice={false} resettable />
<BooleanInput source="admin" />
<BooleanInput source="locked" />
<UserBooleanInput source="locked" />
<UserBooleanInput source="deactivated" helperText="resources.users.helper.deactivate" />
<BooleanInput source="erased" disabled />
<DateField source="creation_ts_ms" showTime options={DATE_FORMAT} />
@@ -331,7 +360,7 @@ export const UserEdit = (props: EditProps) => {
<FormTab label={translate("resources.devices.name", { smart_count: 2 })} icon={<DevicesIcon />} path="devices">
<ReferenceManyField reference="devices" target="user_id" label={false}>
<Datagrid style={{ width: "100%" }}>
<Datagrid style={{ width: "100%" }} bulkActionButtons="">
<TextField source="device_id" sortable={false} />
<TextField source="display_name" sortable={false} />
<TextField source="last_seen_ip" sortable={false} />

166
yarn.lock
View File

@@ -1058,85 +1058,85 @@
resolved "https://registry.npmjs.org/@remix-run/router/-/router-1.19.2.tgz"
integrity sha512-baiMx18+IMuD1yyvOGaHM9QrVUPGGG0jC+z+IPHnRJWUAUvaKuWKyE8gjDj2rzv3sz9zOGoRSPgeBVHRhZnBlA==
"@rollup/rollup-android-arm-eabi@4.22.0":
version "4.22.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.0.tgz#e8c16c336f060b4cb592f62eb4f0e543d79d51fe"
integrity sha512-/IZQvg6ZR0tAkEi4tdXOraQoWeJy9gbQ/cx4I7k9dJaCk9qrXEcdouxRVz5kZXt5C2bQ9pILoAA+KB4C/d3pfw==
"@rollup/rollup-android-arm-eabi@4.22.4":
version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz#8b613b9725e8f9479d142970b106b6ae878610d5"
integrity sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==
"@rollup/rollup-android-arm64@4.22.0":
version "4.22.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.0.tgz#7a44160a14017fa744912d7037c7d81d6f8a46e7"
integrity sha512-ETHi4bxrYnvOtXeM7d4V4kZWixib2jddFacJjsOjwbgYSRsyXYtZHC4ht134OsslPIcnkqT+TKV4eU8rNBKyyQ==
"@rollup/rollup-android-arm64@4.22.4":
version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz#654ca1049189132ff602bfcf8df14c18da1f15fb"
integrity sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==
"@rollup/rollup-darwin-arm64@4.22.0":
version "4.22.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.0.tgz#6122dc37d4a09521d8abe18925956d3b46cfbac9"
integrity sha512-ZWgARzhSKE+gVUX7QWaECoRQsPwaD8ZR0Oxb3aUpzdErTvlEadfQpORPXkKSdKbFci9v8MJfkTtoEHnnW9Ulng==
"@rollup/rollup-darwin-arm64@4.22.4":
version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz#6d241d099d1518ef0c2205d96b3fa52e0fe1954b"
integrity sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==
"@rollup/rollup-darwin-x64@4.22.0":
version "4.22.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.0.tgz#453f345899cbf544aa0d6f5808d24d2e42f605b7"
integrity sha512-h0ZAtOfHyio8Az6cwIGS+nHUfRMWBDO5jXB8PQCARVF6Na/G6XS2SFxDl8Oem+S5ZsHQgtsI7RT4JQnI1qrlaw==
"@rollup/rollup-darwin-x64@4.22.4":
version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz#42bd19d292a57ee11734c980c4650de26b457791"
integrity sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==
"@rollup/rollup-linux-arm-gnueabihf@4.22.0":
version "4.22.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.0.tgz#3a32fa4e80a62a6d733014838b1123fe76b060fe"
integrity sha512-9pxQJSPwFsVi0ttOmqLY4JJ9pg9t1gKhK0JDbV1yUEETSx55fdyCjt39eBQ54OQCzAF0nVGO6LfEH1KnCPvelA==
"@rollup/rollup-linux-arm-gnueabihf@4.22.4":
version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz#f23555ee3d8fe941c5c5fd458cd22b65eb1c2232"
integrity sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==
"@rollup/rollup-linux-arm-musleabihf@4.22.0":
version "4.22.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.0.tgz#55d3953c54419e93efe124882a3103c8a2f65641"
integrity sha512-YJ5Ku5BmNJZb58A4qSEo3JlIG4d3G2lWyBi13ABlXzO41SsdnUKi3HQHe83VpwBVG4jHFTW65jOQb8qyoR+qzg==
"@rollup/rollup-linux-arm-musleabihf@4.22.4":
version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz#f3bbd1ae2420f5539d40ac1fde2b38da67779baa"
integrity sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==
"@rollup/rollup-linux-arm64-gnu@4.22.0":
version "4.22.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.0.tgz#cd626963b9962baf8e09d792e67b87269a5bcfff"
integrity sha512-U4G4u7f+QCqHlVg1Nlx+qapZy+QoG+NV6ux+upo/T7arNGwKvKP2kmGM4W5QTbdewWFgudQxi3kDNST9GT1/mg==
"@rollup/rollup-linux-arm64-gnu@4.22.4":
version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz#7abe900120113e08a1f90afb84c7c28774054d15"
integrity sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==
"@rollup/rollup-linux-arm64-musl@4.22.0":
version "4.22.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.0.tgz#ad209270c9937a27346fce5b0670cbdfb1e6a0a6"
integrity sha512-aQpNlKmx3amwkA3a5J6nlXSahE1ijl0L9KuIjVOUhfOh7uw2S4piR3mtpxpRtbnK809SBtyPsM9q15CPTsY7HQ==
"@rollup/rollup-linux-arm64-musl@4.22.4":
version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz#9e655285c8175cd44f57d6a1e8e5dedfbba1d820"
integrity sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==
"@rollup/rollup-linux-powerpc64le-gnu@4.22.0":
version "4.22.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.0.tgz#fdd173929a5bba8b7e8b37314380213d9604088f"
integrity sha512-9fx6Zj/7vve/Fp4iexUFRKb5+RjLCff6YTRQl4CoDhdMfDoobWmhAxQWV3NfShMzQk1Q/iCnageFyGfqnsmeqQ==
"@rollup/rollup-linux-powerpc64le-gnu@4.22.4":
version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz#9a79ae6c9e9d8fe83d49e2712ecf4302db5bef5e"
integrity sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==
"@rollup/rollup-linux-riscv64-gnu@4.22.0":
version "4.22.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.0.tgz#90b11314fbf45d04083f658e08dc3b32fd713061"
integrity sha512-VWQiCcN7zBgZYLjndIEh5tamtnKg5TGxyZPWcN9zBtXBwfcGSZ5cHSdQZfQH/GB4uRxk0D3VYbOEe/chJhPGLQ==
"@rollup/rollup-linux-riscv64-gnu@4.22.4":
version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz#67ac70eca4ace8e2942fabca95164e8874ab8128"
integrity sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==
"@rollup/rollup-linux-s390x-gnu@4.22.0":
version "4.22.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.0.tgz#46bb2f1135aeec646b720d6032d7c86915f8b2ec"
integrity sha512-EHmPnPWvyYqncObwqrosb/CpH3GOjE76vWVs0g4hWsDRUVhg61hBmlVg5TPXqF+g+PvIbqkC7i3h8wbn4Gp2Fg==
"@rollup/rollup-linux-s390x-gnu@4.22.4":
version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz#9f883a7440f51a22ed7f99e1d070bd84ea5005fc"
integrity sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==
"@rollup/rollup-linux-x64-gnu@4.22.0":
version "4.22.0"
resolved "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.0.tgz"
integrity sha512-tsSWy3YQzmpjDKnQ1Vcpy3p9Z+kMFbSIesCdMNgLizDWFhrLZIoN21JSq01g+MZMDFF+Y1+4zxgrlqPjid5ohg==
"@rollup/rollup-linux-x64-gnu@4.22.4":
version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz#70116ae6c577fe367f58559e2cffb5641a1dd9d0"
integrity sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==
"@rollup/rollup-linux-x64-musl@4.22.0":
version "4.22.0"
resolved "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.0.tgz"
integrity sha512-anr1Y11uPOQrpuU8XOikY5lH4Qu94oS6j0xrulHk3NkLDq19MlX8Ng/pVipjxBJ9a2l3+F39REZYyWQFkZ4/fw==
"@rollup/rollup-linux-x64-musl@4.22.4":
version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz#f473f88219feb07b0b98b53a7923be716d1d182f"
integrity sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==
"@rollup/rollup-win32-arm64-msvc@4.22.0":
version "4.22.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.0.tgz#6bd66c198f80c8e7050cfd901701cfb9555d768a"
integrity sha512-7LB+Bh+Ut7cfmO0m244/asvtIGQr5pG5Rvjz/l1Rnz1kDzM02pSX9jPaS0p+90H5I1x4d1FkCew+B7MOnoatNw==
"@rollup/rollup-win32-arm64-msvc@4.22.4":
version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz#4349482d17f5d1c58604d1c8900540d676f420e0"
integrity sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==
"@rollup/rollup-win32-ia32-msvc@4.22.0":
version "4.22.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.0.tgz#58daea1f1e65143c44c8f3311f30ff8eefa62bae"
integrity sha512-+3qZ4rer7t/QsC5JwMpcvCVPRcJt1cJrYS/TMJZzXIJbxWFQEVhrIc26IhB+5Z9fT9umfVc+Es2mOZgl+7jdJQ==
"@rollup/rollup-win32-ia32-msvc@4.22.4":
version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz#a6fc39a15db618040ec3c2a24c1e26cb5f4d7422"
integrity sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==
"@rollup/rollup-win32-x64-msvc@4.22.0":
version "4.22.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.0.tgz#956948629f6b87de0bdf526b28d940221540bbb6"
integrity sha512-YdicNOSJONVx/vuPkgPTyRoAPx3GbknBZRCOUkK84FJ/YTfs/F0vl/YsMscrB6Y177d+yDRcj+JWMPMCgshwrA==
"@rollup/rollup-win32-x64-msvc@4.22.4":
version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz#3dd5d53e900df2a40841882c02e56f866c04d202"
integrity sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==
"@rtsao/scc@^1.1.0":
version "1.1.0"
@@ -4992,28 +4992,28 @@ rimraf@3.0.2, rimraf@^3.0.2:
glob "^7.1.3"
rollup@^4.20.0:
version "4.22.0"
resolved "https://registry.npmjs.org/rollup/-/rollup-4.22.0.tgz"
integrity sha512-W21MUIFPZ4+O2Je/EU+GP3iz7PH4pVPUXSbEZdatQnxo29+3rsUjgrJmzuAZU24z7yRAnFN6ukxeAhZh/c7hzg==
version "4.22.4"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.22.4.tgz#4135a6446671cd2a2453e1ad42a45d5973ec3a0f"
integrity sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==
dependencies:
"@types/estree" "1.0.5"
optionalDependencies:
"@rollup/rollup-android-arm-eabi" "4.22.0"
"@rollup/rollup-android-arm64" "4.22.0"
"@rollup/rollup-darwin-arm64" "4.22.0"
"@rollup/rollup-darwin-x64" "4.22.0"
"@rollup/rollup-linux-arm-gnueabihf" "4.22.0"
"@rollup/rollup-linux-arm-musleabihf" "4.22.0"
"@rollup/rollup-linux-arm64-gnu" "4.22.0"
"@rollup/rollup-linux-arm64-musl" "4.22.0"
"@rollup/rollup-linux-powerpc64le-gnu" "4.22.0"
"@rollup/rollup-linux-riscv64-gnu" "4.22.0"
"@rollup/rollup-linux-s390x-gnu" "4.22.0"
"@rollup/rollup-linux-x64-gnu" "4.22.0"
"@rollup/rollup-linux-x64-musl" "4.22.0"
"@rollup/rollup-win32-arm64-msvc" "4.22.0"
"@rollup/rollup-win32-ia32-msvc" "4.22.0"
"@rollup/rollup-win32-x64-msvc" "4.22.0"
"@rollup/rollup-android-arm-eabi" "4.22.4"
"@rollup/rollup-android-arm64" "4.22.4"
"@rollup/rollup-darwin-arm64" "4.22.4"
"@rollup/rollup-darwin-x64" "4.22.4"
"@rollup/rollup-linux-arm-gnueabihf" "4.22.4"
"@rollup/rollup-linux-arm-musleabihf" "4.22.4"
"@rollup/rollup-linux-arm64-gnu" "4.22.4"
"@rollup/rollup-linux-arm64-musl" "4.22.4"
"@rollup/rollup-linux-powerpc64le-gnu" "4.22.4"
"@rollup/rollup-linux-riscv64-gnu" "4.22.4"
"@rollup/rollup-linux-s390x-gnu" "4.22.4"
"@rollup/rollup-linux-x64-gnu" "4.22.4"
"@rollup/rollup-linux-x64-musl" "4.22.4"
"@rollup/rollup-win32-arm64-msvc" "4.22.4"
"@rollup/rollup-win32-ia32-msvc" "4.22.4"
"@rollup/rollup-win32-x64-msvc" "4.22.4"
fsevents "~2.3.2"
run-parallel@^1.1.9: