19 Commits

Author SHA1 Message Date
Manuel Stahl
76fdc80e3e Merge branch 'master' into amp.chat
Change-Id: I08a7a34e041993c29bb12fff52d07534374cda4e
2020-04-28 16:35:40 +02:00
Manuel Stahl
375649756f Add page to show room details
Change-Id: Iec4f402c4322d775cc14c567069a3295ad383b44
2020-04-28 16:30:47 +02:00
Manuel Stahl
662735a91f Adapt for changes in v2/users API
Change-Id: I927b81882fa20e5b3de3d9fc216e2136f7036bba
2020-04-28 16:30:47 +02:00
Manuel Stahl
1e6e526e3c Show displayname as title for user
Change-Id: I0ba8e2265e5b8e1fe392f56052e96e0243cd3eb6
2020-04-23 16:50:58 +02:00
Manuel Stahl
0823976edd Cleanup room creation
Change-Id: Ieb5189513d21606f8d0bea5692112350a68f2e14
2020-04-23 16:31:26 +02:00
Manuel Stahl
d812cff5fc Rename homeserver_url to endpoint_url in dataProvider
Change-Id: I86441cd90e9b9b6b04ba2d28fee12a1cfa0684a7
2020-04-23 14:29:13 +02:00
Manuel Stahl
a39033e25b yarn: Upgrade packages
Change-Id: Id01070e1e4ca2c2dd42c8ffcd278a57cb31b7b51
2020-04-23 14:29:00 +02:00
Michael Albert
d3cd2e9e33 Fix localStorage entry of homeserver url
Change-Id: I206e3b4428df1f51d4281ad4db26bd64bdffb85d
2020-04-21 17:42:43 +02:00
Timo Paulssen
24abcd4e4a Normalize alias a little, display initial sigil
turns all whitespace into underscores, shows leading
sigil if the alias is non-empty, so the user doesn't get
confused about whether they have to input a # or not.

Change-Id: Ic81e69cc3f0074d63a67b976c9bda32f8de025de
2020-04-20 19:31:33 +02:00
Timo Paulssen
c1c32e3268 Offer "alias" field in room create form
Tries its best to not allow aliases that are too
long (full alias including leading #, : in the
middle, and homeserver domain name must not exceed
255 bytes.

Change-Id: I1e784a94cb599eca7e30736d666b20e37aad5444
2020-04-20 19:31:33 +02:00
Timo Paulssen
ca15435625 Offer room creation form
A choice of public or private is offered, which maps to matrix'
visibility parameter. A name can also be provided.

Change-Id: I34d99acbc4624a9ed54ca6f6609573d5fc1049da
2020-04-20 19:31:33 +02:00
Michael Albert
e9c3901b68 Merge branch 'master' into amp.chat
Change-Id: Iac4e56401aab3f7f39b623b617990ec1952f8cd0
2020-04-20 16:57:23 +02:00
Michael Albert
7aec6f9369 Allow searching for users
Change-Id: Icf4a3b05b24c66971f55b22e7540a1dc904a3a92
2020-04-20 11:22:06 +00:00
Michael Albert
d2a3f07a59 Fix QR code creation
Change-Id: Ib6bbd1be6d4dca1f617043c3c2338924b2321ea3
2020-04-20 12:15:52 +02:00
Manuel Stahl
bf7867f106 Merge branch 'master' into amp.chat
Change-Id: I45b7a6db27456aaa2eca66b406cdaa49e492e61e
2020-02-11 18:56:53 +01:00
Michael Albert
f0e32abc4f Fix QR code creation
Change-Id: If05856a6fdafa43a93c6b57963820710db188d42
2020-02-11 17:35:19 +00:00
Michael Albert
61b1580735 Fix redirect after create/edit user
Change-Id: Icdb797bf6b1a47cbeff901b1952672584b2e8e8f
2020-02-11 17:34:32 +00:00
Manuel Stahl
0f7e4c1909 Create PDF with QR code on user create/edit
Change-Id: Ib89b68e956d96002ddbf6ac5ddcaea73b5b3e3fb
2020-02-10 13:10:08 +01:00
Michael Albert
c9bce409d2 Prefill user_id and password on user creation
Change-Id: I3f604f38c1842f155f3b39da20ba45992ba522be
2020-02-10 13:10:08 +01:00
11 changed files with 650 additions and 164 deletions

View File

@@ -20,7 +20,10 @@
"prettier": "^2.0.0"
},
"dependencies": {
"@progress/kendo-drawing": "^1.6.0",
"@progress/kendo-react-pdf": "^3.10.1",
"prop-types": "^15.7.2",
"qrcode.react": "^1.0.0",
"ra-language-german": "^2.1.2",
"react": "^16.13.1",
"react-admin": "^3.4.0",

BIN
public/images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 KiB

View File

@@ -4,12 +4,14 @@ import polyglotI18nProvider from "ra-i18n-polyglot";
import authProvider from "./synapse/authProvider";
import dataProvider from "./synapse/dataProvider";
import { UserList, UserCreate, UserEdit } from "./components/users";
import { RoomList } from "./components/rooms";
import { RoomList, RoomCreate, RoomShow } from "./components/rooms";
import LoginPage from "./components/LoginPage";
import UserIcon from "@material-ui/icons/Group";
import { ViewListIcon as RoomIcon } from "@material-ui/icons/ViewList";
import germanMessages from "./i18n/de";
import englishMessages from "./i18n/en";
import ShowUserPdf from "./components/ShowUserPdf";
import { Route } from "react-router-dom";
// TODO: Can we use lazy loading together with browser locale?
const messages = {
@@ -27,6 +29,9 @@ const App = () => (
authProvider={authProvider}
dataProvider={dataProvider}
i18nProvider={i18nProvider}
customRoutes={[
<Route key="showpdf" path="/showpdf" component={ShowUserPdf} />,
]}
>
<Resource
name="users"
@@ -35,7 +40,13 @@ const App = () => (
edit={UserEdit}
icon={UserIcon}
/>
<Resource name="rooms" list={RoomList} icon={RoomIcon} />
<Resource
name="rooms"
list={RoomList}
create={RoomCreate}
show={RoomShow}
icon={RoomIcon}
/>
<Resource name="connections" />
</Admin>
);

View File

@@ -0,0 +1,35 @@
import React, { useCallback } from "react";
import { SaveButton, useCreate, useRedirect, useNotify } from "react-admin";
const SaveQrButton = props => {
const [create] = useCreate("users");
const redirectTo = useRedirect();
const notify = useNotify();
const { basePath } = props;
const handleSave = useCallback(
(values, redirect) => {
create(
{
payload: { data: { ...values } },
},
{
onSuccess: ({ data: newRecord }) => {
notify("ra.notification.created", "info", {
smart_count: 1,
});
redirectTo(redirect, basePath, newRecord.id, {
password: values.password,
...newRecord,
});
},
}
);
},
[create, notify, redirectTo, basePath]
);
return <SaveButton {...props} onSave={handleSave} />;
};
export default SaveQrButton;

View File

@@ -0,0 +1,132 @@
import React from "react";
import { Title, Button } from "react-admin";
import { makeStyles } from "@material-ui/core/styles";
import { PDFExport } from "@progress/kendo-react-pdf";
import QRCode from "qrcode.react";
function xor(a, b) {
var res = "";
for (var i = 0; i < a.length; i++) {
res += String.fromCharCode(a.charCodeAt(i) ^ b.charCodeAt(i % b.length));
}
return res;
}
function calculateQrString(serverUrl, username, password) {
const magicString = "wo9k5tep252qxsa5yde7366kugy6c01w7oeeya9hrmpf0t7ii7";
var urlString = "user=" + username + "&password=" + password;
urlString = xor(urlString, magicString); // xor with magic string
urlString = btoa(urlString); // to base64
return serverUrl + "/#" + urlString;
}
const ShowUserPdf = props => {
const useStyles = makeStyles(theme => ({
page: {
height: 800,
width: 566,
padding: "none",
backgroundColor: "white",
boxShadow: "5px 5px 5px black",
margin: "auto",
overflowX: "hidden",
overflowY: "hidden",
},
header: {
height: 144,
width: 534,
marginLeft: 32,
marginTop: 15,
},
name: {
width: 233,
fontSize: 40,
float: "left",
marginTop: 15,
},
logo: {
width: 90,
marginTop: 20,
marginRight: 32,
float: "left",
},
code: {
marginLeft: 330,
marginTop: 86,
},
qr: {
marginRight: 40,
float: "right",
},
note: {
fontSize: 18,
marginTop: 100,
marginLeft: 32,
marginRight: 32,
},
}));
const classes = useStyles();
var resume;
const exportPDF = () => {
resume.save();
};
var qrCode = "";
var displayname = "";
if (
props.location.state &&
props.location.state.id &&
props.location.state.password
) {
const { id, password } = props.location.state;
const username = id.substring(1, id.indexOf(":"));
const serverUrl = "https://" + id.substring(id.indexOf(":") + 1);
const qrString = calculateQrString(serverUrl, username, password);
qrCode = <QRCode value={qrString} size={128} />;
displayname = props.location.state.displayname;
}
return (
<div>
<Title title="PDF" />
<Button label="synapseadmin.action.download_pdf" onClick={exportPDF} />
<PDFExport
paperSize={"A4"}
fileName="User.pdf"
title=""
subject=""
keywords=""
ref={r => (resume = r)}
>
<div className={classes.page}>
<div className={classes.code}>Ihr persönlicher Anmeldecode:</div>
<div className={classes.header}>
<div className={classes.name}>{displayname}</div>
<img className={classes.logo} alt="Logo" src="images/logo.png" />
<div className={classes.qr}>{qrCode}</div>
</div>
<div className={classes.note}>
Hier können Sie Ihre selbst gewählte Schlüsselsicherungs-Passphrase
notieren:
<br />
<br />
<br />
<hr />
</div>
</div>
</PDFExport>
</div>
);
};
export default ShowUserPdf;

View File

@@ -1,5 +1,22 @@
import React from "react";
import { Datagrid, List, TextField, Pagination } from "react-admin";
import {
BooleanField,
BooleanInput,
Create,
Datagrid,
List,
Pagination,
ReferenceArrayField,
Show,
SimpleForm,
Tab,
TabbedShowLayout,
TextField,
TextInput,
useTranslate,
} from "react-admin";
import ViewListIcon from "@material-ui/icons/ViewList";
import UserIcon from "@material-ui/icons/Group";
const RoomPagination = props => (
<Pagination {...props} rowsPerPageOptions={[10, 25, 50, 100, 500, 1000]} />
@@ -7,7 +24,7 @@ const RoomPagination = props => (
export const RoomList = props => (
<List {...props} pagination={<RoomPagination />}>
<Datagrid>
<Datagrid rowClick="show">
<TextField source="room_id" />
<TextField source="name" />
<TextField source="canonical_alias" />
@@ -15,3 +32,117 @@ export const RoomList = props => (
</Datagrid>
</List>
);
const validateDisplayName = fieldval =>
fieldval === undefined
? "synapseadmin.rooms.room_name_required"
: fieldval.length === 0
? "synapseadmin.rooms.room_name_required"
: undefined;
function approximateAliasLength(alias, homeserver) {
/* TODO maybe handle punycode in homeserver URL */
var te;
// Support for TextEncoder is quite widespread, but the polyfill is
// pretty large; We will only underestimate the size with the regular
// length attribute of String, so we never prevent the user from using
// an alias that is short enough for the server, but too long for our
// heuristic.
try {
te = new TextEncoder();
} catch (err) {
if (err instanceof ReferenceError) {
te = undefined;
}
}
const aliasLength = te === undefined ? alias.length : te.encode(alias).length;
return "#".length + aliasLength + ":".length + homeserver.length;
}
const validateAlias = fieldval => {
if (fieldval === undefined) {
return undefined;
}
const homeserver = localStorage.getItem("home_server_url");
if (approximateAliasLength(fieldval, homeserver) > 255) {
return "synapseadmin.rooms.alias_too_long";
}
};
const removeLeadingWhitespace = fieldVal =>
fieldVal === undefined ? undefined : fieldVal.trimStart();
const replaceAllWhitespace = fieldVal =>
fieldVal === undefined ? undefined : fieldVal.replace(/\s/, "_");
const removeLeadingSigil = fieldVal =>
fieldVal === undefined
? undefined
: fieldVal.startsWith("#")
? fieldVal.substr(1)
: fieldVal;
const validateHasAliasIfPublic = formdata => {
let errors = {};
if (formdata.public) {
if (
formdata.canonical_alias === undefined ||
formdata.canonical_alias.trim().length === 0
) {
errors.canonical_alias = "synapseadmin.rooms.alias_required_if_public";
}
}
return errors;
};
export const RoomCreate = props => (
<Create {...props}>
<SimpleForm validate={validateHasAliasIfPublic}>
<TextInput
source="name"
parse={removeLeadingWhitespace}
validate={validateDisplayName}
/>
<TextInput
source="canonical_alias"
parse={fv => replaceAllWhitespace(removeLeadingSigil(fv))}
validate={validateAlias}
placeholder="#"
/>
<BooleanInput source="public" label="synapseadmin.rooms.make_public" />
</SimpleForm>
</Create>
);
const RoomTitle = ({ record }) => {
const translate = useTranslate();
return (
<span>
{translate("resources.rooms.name", 1)} {record ? `"${record.name}"` : ""}
</span>
);
};
export const RoomShow = props => (
<Show {...props} title={<RoomTitle />}>
<TabbedShowLayout>
<Tab label="synapseadmin.rooms.details" icon={<ViewListIcon />}>
<TextField source="id" disabled />
<TextField source="name" />
<TextField source="canonical_alias" />
<TextField source="join_rules" />
<TextField source="guest_access" />
</Tab>
<Tab label="resources.rooms.fields.joined_members" icon={<UserIcon />}>
<ReferenceArrayField reference="users" source="members">
<Datagrid>
<TextField source="id" />
<TextField source="displayname" />
</Datagrid>
</ReferenceArrayField>
</Tab>
</TabbedShowLayout>
</Show>
);

View File

@@ -21,6 +21,7 @@ import {
PasswordInput,
TextField,
TextInput,
SearchInput,
ReferenceField,
SelectInput,
BulkDeleteButton,
@@ -30,6 +31,7 @@ import {
useTranslate,
Pagination,
} from "react-admin";
import SaveQrButton from "./SaveQrButton";
const UserPagination = props => (
<Pagination {...props} rowsPerPageOptions={[10, 25, 50, 100, 500, 1000]} />
@@ -37,6 +39,7 @@ const UserPagination = props => (
const UserFilter = props => (
<Filter {...props}>
<SearchInput source="user_id" alwaysOn />
<BooleanInput source="guests" alwaysOn />
<BooleanInput
label="resources.users.fields.show_deactivated"
@@ -68,24 +71,9 @@ export const UserList = props => (
pagination={<UserPagination />}
>
<Datagrid rowClick="edit">
<ReferenceField
source="Avatar"
reference="users"
link={false}
sortable={false}
>
<ImageField source="avatar_url" title="displayname" />
</ReferenceField>
<TextField source="id" />
{/* Hack since the users endpoint does not give displaynames in the list*/}
<ReferenceField
source="name"
reference="users"
link={false}
sortable={false}
>
<TextField source="displayname" />
</ReferenceField>
<ImageField source="avatar_url" title="displayname" />
<TextField source="id" sortable={false} />
<TextField source="displayname" />
<BooleanField source="is_guest" sortable={false} />
<BooleanField source="admin" sortable={false} />
<BooleanField source="deactivated" sortable={false} />
@@ -93,6 +81,75 @@ export const UserList = props => (
</List>
);
function generateRandomUser() {
const homeserver = localStorage.getItem("home_server_url");
const user_id =
"@" +
Array(8)
.fill("0123456789abcdefghijklmnopqrstuvwxyz")
.map(
x =>
x[
Math.floor(
(crypto.getRandomValues(new Uint32Array(1))[0] /
(0xffffffff + 1)) *
x.length
)
]
)
.join("") +
":" +
homeserver;
const password = Array(20)
.fill(
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@-#$"
)
.map(
x =>
x[
Math.floor(
(crypto.getRandomValues(new Uint32Array(1))[0] / (0xffffffff + 1)) *
x.length
)
]
)
.join("");
return {
id: user_id,
password: password,
};
}
// redirect to the related Author show page
const redirect = (basePath, id, data) => {
return {
pathname: "/showpdf",
state: {
id: data.id,
displayname: data.displayname,
password: data.password,
},
};
};
const UserCreateToolbar = props => (
<Toolbar {...props}>
<SaveQrButton
label="synapseadmin.action.save_and_show"
redirect={redirect}
submitOnEnter={true}
/>
<SaveButton
label="synapseadmin.action.save_only"
redirect="list"
submitOnEnter={false}
variant="text"
/>
</Toolbar>
);
// https://matrix.org/docs/spec/appendices#user-identifiers
const validateUser = regex(
/^@[a-z0-9._=\-/]+:.*/,
@@ -103,7 +160,17 @@ const UserEditToolbar = props => {
const translate = useTranslate();
return (
<Toolbar {...props}>
<SaveButton submitOnEnter={true} />
<SaveQrButton
label="synapseadmin.action.save_and_show"
redirect={redirect}
submitOnEnter={true}
/>
<SaveButton
label="synapseadmin.action.save_only"
redirect="list"
submitOnEnter={false}
variant="text"
/>
<DeleteButton
label="resources.users.action.erase"
title={translate("resources.users.helper.erase")}
@@ -113,8 +180,8 @@ const UserEditToolbar = props => {
};
export const UserCreate = props => (
<Create {...props}>
<SimpleForm>
<Create record={generateRandomUser()} {...props}>
<SimpleForm toolbar={<UserCreateToolbar />}>
<TextInput source="id" autoComplete="off" validate={validateUser} />
<TextInput source="displayname" />
<PasswordInput source="password" autoComplete="new-password" />
@@ -135,8 +202,17 @@ export const UserCreate = props => (
</Create>
);
const UserTitle = ({ record }) => {
const translate = useTranslate();
return (
<span>
{translate("resources.users.name")}{" "}
{record ? `"${record.displayname}"` : ""}
</span>
);
};
export const UserEdit = props => (
<Edit {...props}>
<Edit {...props} title={<UserTitle />}>
<TabbedForm toolbar={<UserEditToolbar />}>
<FormTab label="resources.users.name" icon={<PersonPinIcon />}>
<TextInput source="id" disabled />

View File

@@ -7,10 +7,25 @@ export default {
homeserver: "Heimserver",
welcome: "Willkommen bei Synapse-admin",
},
action: {
save_and_show: "Speichern und QR Code erzeugen",
save_only: "Nur speichern",
download_pdf: "PDF speichern",
},
users: {
invalid_user_id:
"Muss eine vollständige Matrix Benutzer-ID sein, z.B. @benutzer_id:homeserver",
},
rooms: {
details: "Raumdetails",
room_name: "Raumname",
make_public: "Öffentlicher Raum",
room_name_required: "Muss angegeben werden",
alias_required_if_public: "Muss für öffentliche Räume angegeben werden.",
alias: "Alias",
alias_too_long:
"Darf zusammen mit der Domain des Homeservers 255 bytes nicht überschreiten",
},
},
resources: {
users: {
@@ -61,4 +76,15 @@ export default {
},
},
},
ra: {
...germanMessages.ra,
input: {
...germanMessages.ra.input,
password: {
...germanMessages.ra.input.password,
toggle_hidden: "Anzeigen",
toggle_visible: "Verstecken",
},
},
},
};

View File

@@ -7,10 +7,25 @@ export default {
homeserver: "Homeserver",
welcome: "Welcome to Synapse-admin",
},
action: {
save_and_show: "Create QR code",
save_only: "Save",
download_pdf: "Download PDF",
},
users: {
invalid_user_id:
"Must be a fully qualified Matrix user-id, e.g. @user_id:homeserver",
},
rooms: {
details: "Room Details",
room_name: "Room Name",
make_public: "Make room public",
room_name_required: "Must be provided",
alias_required_if_public: "Must be provided for a public room",
alias: "Alias",
alias_too_long:
"Must not exceed 255 bytes including the domain of the homeserver.",
},
},
resources: {
users: {

View File

@@ -25,11 +25,7 @@ const resourceMap = {
deactivated: !!u.deactivated,
}),
data: "users",
total: (json, from, perPage) => {
return json.next_token
? parseInt(json.next_token, 10) + perPage
: from + json.users.length;
},
total: json => json.total,
delete: id => ({
endpoint: `/_synapse/admin/v1/deactivate/${id}`,
body: { erase: true },
@@ -41,13 +37,19 @@ const resourceMap = {
map: r => ({
...r,
id: r.room_id,
alias: r.canonical_alias,
members: r.joined_members,
}),
data: "rooms",
total: json => {
return json.total_rooms;
},
total: json => json.total_rooms,
create: params => ({
method: "POST",
endpoint: "/_matrix/client/r0/createRoom",
body: {
name: params.data.name,
room_alias_name: params.data.canonical_alias,
visibility: params.data.public ? "public" : "private",
},
map: r => ({ id: r.room_id }),
}),
},
connections: {
path: "/_synapse/admin/v1/whois",
@@ -85,8 +87,8 @@ const dataProvider = {
const res = resourceMap[resource];
const homeserver_url = homeserver + res.path;
const url = `${homeserver_url}?${stringify(query)}`;
const endpoint_url = homeserver + res.path;
const url = `${endpoint_url}?${stringify(query)}`;
return jsonClient(url).then(({ json }) => ({
data: json[res.data].map(res.map),
@@ -101,8 +103,8 @@ const dataProvider = {
const res = resourceMap[resource];
const homeserver_url = homeserver + res.path;
return jsonClient(`${homeserver_url}/${params.id}`).then(({ json }) => ({
const endpoint_url = homeserver + res.path;
return jsonClient(`${endpoint_url}/${params.id}`).then(({ json }) => ({
data: res.map(json),
}));
},
@@ -114,9 +116,9 @@ const dataProvider = {
const res = resourceMap[resource];
const homeserver_url = homeserver + res.path;
const endpoint_url = homeserver + res.path;
return Promise.all(
params.ids.map(id => jsonClient(`${homeserver_url}/${id}`))
params.ids.map(id => jsonClient(`${endpoint_url}/${id}`))
).then(responses => ({
data: responses.map(({ json }) => res.map(json)),
}));
@@ -141,8 +143,8 @@ const dataProvider = {
const res = resourceMap[resource];
const homeserver_url = homeserver + res.path;
const url = `${homeserver_url}?${stringify(query)}`;
const endpoint_url = homeserver + res.path;
const url = `${endpoint_url}?${stringify(query)}`;
return jsonClient(url).then(({ headers, json }) => ({
data: json,
@@ -157,8 +159,8 @@ const dataProvider = {
const res = resourceMap[resource];
const homeserver_url = homeserver + res.path;
return jsonClient(`${homeserver_url}/${params.data.id}`, {
const endpoint_url = homeserver + res.path;
return jsonClient(`${endpoint_url}/${params.data.id}`, {
method: "PUT",
body: JSON.stringify(params.data, filterNullValues),
}).then(({ json }) => ({
@@ -173,9 +175,9 @@ const dataProvider = {
const res = resourceMap[resource];
const homeserver_url = homeserver + res.path;
const endpoint_url = homeserver + res.path;
return Promise.all(
params.ids.map(id => jsonClient(`${homeserver_url}/${id}`), {
params.ids.map(id => jsonClient(`${endpoint_url}/${id}`), {
method: "PUT",
body: JSON.stringify(params.data, filterNullValues),
})
@@ -191,13 +193,24 @@ const dataProvider = {
const res = resourceMap[resource];
const homeserver_url = homeserver + res.path;
return jsonClient(`${homeserver_url}/${params.data.id}`, {
method: "PUT",
body: JSON.stringify(params.data, filterNullValues),
}).then(({ json }) => ({
data: res.map(json),
}));
if ("create" in res) {
const create = res["create"](params);
const endpoint_url = homeserver + create.endpoint;
return jsonClient(endpoint_url, {
method: create.method,
body: JSON.stringify(create.body, filterNullValues),
}).then(({ json }) => ({
data: create.map(json),
}));
} else {
const endpoint_url = homeserver + res.path;
return jsonClient(`${endpoint_url}/${params.data.id}`, {
method: "PUT",
body: JSON.stringify(params.data, filterNullValues),
}).then(({ json }) => ({
data: res.map(json),
}));
}
},
delete: (resource, params) => {
@@ -209,16 +222,16 @@ const dataProvider = {
if ("delete" in res) {
const del = res["delete"](params.id);
const homeserver_url = homeserver + del.endpoint;
return jsonClient(homeserver_url, {
const endpoint_url = homeserver + del.endpoint;
return jsonClient(endpoint_url, {
method: del.method,
body: JSON.stringify(del.body),
}).then(({ json }) => ({
data: json,
}));
} else {
const homeserver_url = homeserver + res.path;
return jsonClient(`${homeserver_url}/${params.id}`, {
const endpoint_url = homeserver + res.path;
return jsonClient(`${endpoint_url}/${params.id}`, {
method: "DELETE",
body: JSON.stringify(params.data, filterNullValues),
}).then(({ json }) => ({
@@ -238,8 +251,8 @@ const dataProvider = {
return Promise.all(
params.ids.map(id => {
const del = res["delete"](id);
const homeserver_url = homeserver + del.endpoint;
return jsonClient(homeserver_url, {
const endpoint_url = homeserver + del.endpoint;
return jsonClient(endpoint_url, {
method: del.method,
body: JSON.stringify(del.body),
});
@@ -248,10 +261,10 @@ const dataProvider = {
data: responses.map(({ json }) => json),
}));
} else {
const homeserver_url = homeserver + res.path;
const endpoint_url = homeserver + res.path;
return Promise.all(
params.ids.map(id =>
jsonClient(`${homeserver_url}/${id}`, {
jsonClient(`${endpoint_url}/${id}`, {
method: "DELETE",
body: JSON.stringify(params.data, filterNullValues),
})

246
yarn.lock
View File

@@ -1142,10 +1142,10 @@
"@types/istanbul-reports" "^1.1.1"
"@types/yargs" "^13.0.0"
"@jest/types@^25.2.6":
version "25.2.6"
resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.2.6.tgz#c12f44af9bed444438091e4b59e7ed05f8659cb6"
integrity sha512-myJTTV37bxK7+3NgKc4Y/DlQ5q92/NOwZsZ+Uch7OXdElxOg61QYc72fPYNAjlvbnJ2YvbXLamIsa9tj48BmyQ==
"@jest/types@^25.4.0":
version "25.4.0"
resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.4.0.tgz#5afeb8f7e1cba153a28e5ac3c9fe3eede7206d59"
integrity sha512-XBeaWNzw2PPnGW5aXvZt3+VO60M+34RY3XDsCK5tW7kyj3RK0XClRutCfjqcBuaR2aBQTbluEDME9b5MB9UAPw==
dependencies:
"@types/istanbul-lib-coverage" "^2.0.0"
"@types/istanbul-reports" "^1.1.1"
@@ -1153,19 +1153,20 @@
chalk "^3.0.0"
"@material-ui/core@^4.3.3":
version "4.9.9"
resolved "https://registry.yarnpkg.com/@material-ui/core/-/core-4.9.9.tgz#902dc37eeb415dd3288feb2c92e0dc27d9caed48"
integrity sha512-Gp0UdJLxPEnkn7O0QpJ2/LOeIuT8nX9e6CjQFuLnOy10rUGjRsOZ2T170Y057xdUmw1VNE+0bvkkO6dOghxt4g==
version "4.9.11"
resolved "https://registry.yarnpkg.com/@material-ui/core/-/core-4.9.11.tgz#02f45f4dbea6db191fdc0d993323d64cfae613fd"
integrity sha512-S2Ha9GpTxzl29XMeMc8dQX2pj97yApNzuhe/23If53fMdg5Fmd3SgbE1bMbyXeKhxwtXZjOFxd0vU+W/sez8Ew==
dependencies:
"@babel/runtime" "^7.4.4"
"@material-ui/styles" "^4.9.6"
"@material-ui/system" "^4.9.6"
"@material-ui/types" "^5.0.0"
"@material-ui/react-transition-group" "^4.2.0"
"@material-ui/styles" "^4.9.10"
"@material-ui/system" "^4.9.10"
"@material-ui/types" "^5.0.1"
"@material-ui/utils" "^4.9.6"
"@types/react-transition-group" "^4.2.0"
clsx "^1.0.2"
clsx "^1.0.4"
hoist-non-react-statics "^3.3.2"
popper.js "^1.14.1"
popper.js "^1.16.1-lts"
prop-types "^15.7.2"
react-is "^16.8.0"
react-transition-group "^4.3.0"
@@ -1177,14 +1178,24 @@
dependencies:
"@babel/runtime" "^7.4.4"
"@material-ui/styles@^4.3.3", "@material-ui/styles@^4.9.6":
version "4.9.6"
resolved "https://registry.yarnpkg.com/@material-ui/styles/-/styles-4.9.6.tgz#924a30bf7c9b91af9c8f19c12c8573b8a4ecd085"
integrity sha512-ijgwStEkw1OZ6gCz18hkjycpr/3lKs1hYPi88O/AUn4vMuuGEGAIrqKVFq/lADmZUNF3DOFIk8LDkp7zmjPxtA==
"@material-ui/react-transition-group@^4.2.0":
version "4.3.0"
resolved "https://registry.yarnpkg.com/@material-ui/react-transition-group/-/react-transition-group-4.3.0.tgz#92529142addb5cc179dbf42d246c7e3fe4d6104b"
integrity sha512-CwQ0aXrlUynUTY6sh3UvKuvye1o92en20VGAs6TORnSxUYeRmkX8YeTUN3lAkGiBX1z222FxLFO36WWh6q73rQ==
dependencies:
"@babel/runtime" "^7.5.5"
dom-helpers "^5.0.1"
loose-envify "^1.4.0"
prop-types "^15.6.2"
"@material-ui/styles@^4.3.3", "@material-ui/styles@^4.9.10":
version "4.9.10"
resolved "https://registry.yarnpkg.com/@material-ui/styles/-/styles-4.9.10.tgz#182ccdd0bc8525a459486499bbaebcd92b0db3ab"
integrity sha512-EXIXlqVyFDnjXF6tj72y6ZxiSy+mHtrsCo3Srkm3XUeu3Z01aftDBy7ZSr3TQ02gXHTvDSBvegp3Le6p/tl7eA==
dependencies:
"@babel/runtime" "^7.4.4"
"@emotion/hash" "^0.8.0"
"@material-ui/types" "^5.0.0"
"@material-ui/types" "^5.0.1"
"@material-ui/utils" "^4.9.6"
clsx "^1.0.2"
csstype "^2.5.2"
@@ -1199,19 +1210,19 @@
jss-plugin-vendor-prefixer "^10.0.3"
prop-types "^15.7.2"
"@material-ui/system@^4.9.6":
version "4.9.6"
resolved "https://registry.yarnpkg.com/@material-ui/system/-/system-4.9.6.tgz#fd060540224da4d1740da8ca6e7af288e217717e"
integrity sha512-QtfoAePyqXoZ2HUVSwGb1Ro0kucMCvVjbI0CdYIR21t0Opgfm1Oer6ni9P5lfeXA39xSt0wCierw37j+YES48Q==
"@material-ui/system@^4.9.10":
version "4.9.10"
resolved "https://registry.yarnpkg.com/@material-ui/system/-/system-4.9.10.tgz#5de6ec7bea0f222b10b45e5bd5bb8b9a7b938926"
integrity sha512-E+t0baX2TBZk6ALm8twG6objpsxLdMM4MDm1++LMt2m7CetCAEc3aIAfDaprk4+tm5hFT1Cah5dRWk8EeIFQYw==
dependencies:
"@babel/runtime" "^7.4.4"
"@material-ui/utils" "^4.9.6"
prop-types "^15.7.2"
"@material-ui/types@^5.0.0":
version "5.0.0"
resolved "https://registry.yarnpkg.com/@material-ui/types/-/types-5.0.0.tgz#26d6259dc6b39f4c2e1e9aceff7a11e031941741"
integrity sha512-UeH2BuKkwDndtMSS0qgx1kCzSMw+ydtj0xx/XbFtxNSTlXydKwzs5gVW5ZKsFlAkwoOOQ9TIsyoCC8hq18tOwg==
"@material-ui/types@^5.0.1":
version "5.0.1"
resolved "https://registry.yarnpkg.com/@material-ui/types/-/types-5.0.1.tgz#c4954063cdc196eb327ee62c041368b1aebb6d61"
integrity sha512-wURPSY7/3+MAtng3i26g+WKwwNE3HEeqa/trDBR5+zWKmcjO+u9t7Npu/J1r+3dmIa/OeziN9D/18IrBKvKffw==
"@material-ui/utils@^4.9.6":
version "4.9.6"
@@ -1235,6 +1246,25 @@
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==
"@progress/kendo-drawing@^1.6.0":
version "1.6.0"
resolved "https://registry.yarnpkg.com/@progress/kendo-drawing/-/kendo-drawing-1.6.0.tgz#66e9df431f52c7dd9fd5567be80dcbfa3a162281"
integrity sha512-9dGlFvW9fMgqAgcbLi+SfTeMUpNYdoVthwNxwAtsRQ+QwcgXJcdzFpLrLBXp17pXpDDFpiOyMqiwjffNGwtc3w==
dependencies:
pako "^1.0.5"
"@progress/kendo-file-saver@^1.0.1":
version "1.0.7"
resolved "https://registry.yarnpkg.com/@progress/kendo-file-saver/-/kendo-file-saver-1.0.7.tgz#5b602115d1b0b5e26f3e52451a3ed7c29ed76c51"
integrity sha512-8tsho/+DATzfTW4BBaHrkF3C3jqH2/bQ+XbjqA0KfmTiBRVK6ygK+tkvkYeDhFlQBbJ02MmJlEC6OmXvXRFkUg==
"@progress/kendo-react-pdf@^3.10.1":
version "3.10.1"
resolved "https://registry.yarnpkg.com/@progress/kendo-react-pdf/-/kendo-react-pdf-3.10.1.tgz#348517daaddb366bbe840a92ec2fffbfd07ac2d2"
integrity sha512-2EKfQCwLFEa+mgCLKQ70iWVu7q2Dh/wJl6pPJ6Ix42BA7SiA2k5UmDk819FLY9pnMgv7WDxwqBP+8CvdkLoP5w==
dependencies:
"@progress/kendo-file-saver" "^1.0.1"
"@redux-saga/core@^1.1.3":
version "1.1.3"
resolved "https://registry.yarnpkg.com/@redux-saga/core/-/core-1.1.3.tgz#3085097b57a4ea8db5528d58673f20ce0950f6a4"
@@ -1399,9 +1429,9 @@
wait-for-expect "^1.2.0"
"@testing-library/dom@^7.1.0":
version "7.2.0"
resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-7.2.0.tgz#948894c2ef52017d299c35da02e085498363cd1e"
integrity sha512-K1Sao38VxsTrjTkFkzeW8m/oCtgCI5lANCE7u9ZaF+TTL3uKuiZ+vazeurxjvRHAsE6PvXjOIl6JFuZfgcWJSQ==
version "7.2.1"
resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-7.2.1.tgz#bb3b31d669bbe0c4939dadd95d69caa3c1d0b372"
integrity sha512-xIGoHlQ2ZiEL1dJIFKNmLDypzYF+4OJTTASRctl/aoIDaS5y/pRVHRigoqvPUV11mdJoR71IIgi/6UviMgyz4g==
dependencies:
"@babel/runtime" "^7.9.2"
"@types/testing-library__dom" "^7.0.0"
@@ -1410,9 +1440,9 @@
pretty-format "^25.1.0"
"@testing-library/jest-dom@^5.1.1":
version "5.3.0"
resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.3.0.tgz#2ae813b8b0eb69e8808f75d3af8efa3f0dc4d7ec"
integrity sha512-Cdhpc3BHL888X55qBNyra9eM0UG63LCm/FqCWTa1Ou/0MpsUbQTM9vW1NU6/jBQFoSLgkFfDG5XVpm2V0dOm/A==
version "5.5.0"
resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.5.0.tgz#4707023e8f572021e8a84f65721303ff60828d88"
integrity sha512-7sWHrpxG4Yd8TmryI7Rtbx8Ff4mbs3ASye3oshQIuHvsCR+QHgr7rTR/PfeXvOmwUwR36wSTTAvrLKsPmr6VEQ==
dependencies:
"@babel/runtime" "^7.9.2"
"@types/testing-library__jest-dom" "^5.0.2"
@@ -1425,9 +1455,9 @@
redent "^3.0.0"
"@testing-library/react@^10.0.2":
version "10.0.2"
resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-10.0.2.tgz#8eca7aa52d810cf7150048a2829fdc487162006d"
integrity sha512-YT6Mw0oJz7R6vlEkmo1FlUD+K15FeXApOB5Ffm9zooFVnrwkt00w18dUJFMOh1yRp9wTdVRonbor7o4PIpFCmA==
version "10.0.3"
resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-10.0.3.tgz#7781adc75cce172f8cda28faa77be29c6270ab43"
integrity sha512-EVmd3ghDFBEjOSLnISUdi7OcLdP6tsqjmTprpMaBz5TreoM8jnxGKIPkLD579CE0LYGqK01iffQiy6wwW/RUig==
dependencies:
"@babel/runtime" "^7.9.2"
"@testing-library/dom" "^7.1.0"
@@ -1442,9 +1472,9 @@
"@testing-library/dom" "^5.6.1"
"@testing-library/user-event@^10.0.1":
version "10.0.1"
resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-10.0.1.tgz#9a02dbbc813135f25778b17f92a63933a58e8af5"
integrity sha512-M63ftowo1QpAGMnWyz7df0ygqnu4XyF68Sty7mivMAz2HLcY1uLoN3qcen6WMobdY0MoZUi4+BLsziSDAP62Vg==
version "10.0.2"
resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-10.0.2.tgz#c44197998a9b7a8d60ff66bb9d41635d9648f064"
integrity sha512-fVeP4U37BIYdp9nBRKEITFSLPqgCSS7Og6LHvxoQ2JSOTJ1NJI4Dfesv4uNXxvNNcJgBS88V+Tc6h8vbDsa2iA==
"@types/babel__core@^7.1.0":
version "7.1.7"
@@ -1576,9 +1606,9 @@
"@types/react" "*"
"@types/react@*":
version "16.9.32"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.32.tgz#f6368625b224604148d1ddf5920e4fefbd98d383"
integrity sha512-fmejdp0CTH00mOJmxUPPbWCEBWPvRIL4m8r0qD+BSDUqmutPyGQCHifzMpMzdvZwROdEdL78IuZItntFWgPXHQ==
version "16.9.34"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.34.tgz#f7d5e331c468f53affed17a8a4d488cd44ea9349"
integrity sha512-8AJlYMOfPe1KGLKyHpflCg5z46n0b5DbRfqDksxBLBTUpB75ypDBAO9eCUcjNwE6LCUslwTz00yyG/X9gaVtow==
dependencies:
"@types/prop-types" "*"
csstype "^2.2.0"
@@ -3004,7 +3034,7 @@ clone-deep@^4.0.1:
kind-of "^6.0.2"
shallow-clone "^3.0.0"
clsx@^1.0.2:
clsx@^1.0.2, clsx@^1.0.4:
version "1.1.0"
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.0.tgz#62937c6adfea771247c34b54d320fb99624f5702"
integrity sha512-3avwM37fSK5oP6M5rQ9CNe99lwxhXDOeSWVPAOYF6OazUTgZCMb0yWlJpmdD74REy1gkEaFiub2ULv4fq9GUhA==
@@ -3247,9 +3277,9 @@ core-js-compat@^3.6.2:
semver "7.0.0"
core-js-pure@^3.0.0:
version "3.6.4"
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.4.tgz#4bf1ba866e25814f149d4e9aaa08c36173506e3a"
integrity sha512-epIhRLkXdgv32xIUFaaAry2wdxZYBi6bgM7cB136dzzXXa+dFyRLTZeLUJxnd8ShrmyVXBub63n2NHo2JAt8Cw==
version "3.6.5"
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.5.tgz#c79e75f5e38dbc85a662d91eea52b8256d53b813"
integrity sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==
core-js@^1.0.0:
version "1.2.7"
@@ -4233,9 +4263,9 @@ escodegen@^1.11.0, escodegen@^1.9.1:
source-map "~0.6.1"
eslint-config-prettier@^6.10.1:
version "6.10.1"
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.10.1.tgz#129ef9ec575d5ddc0e269667bf09defcd898642a"
integrity sha512-svTy6zh1ecQojvpbJSgH3aei/Rt7C6i090l5f2WQ4aB05lYHeZIR1qL4wZyyILTbtmnbHP5Yn8MrsOJMGa8RkQ==
version "6.11.0"
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz#f6d2238c1290d01c859a8b5c1f7d352a0b0da8b1"
integrity sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==
dependencies:
get-stdin "^6.0.0"
@@ -4314,9 +4344,9 @@ eslint-plugin-jsx-a11y@6.2.3:
jsx-ast-utils "^2.2.1"
eslint-plugin-prettier@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.2.tgz#432e5a667666ab84ce72f945c72f77d996a5c9ba"
integrity sha512-GlolCC9y3XZfv3RQfwGew7NnuFDKsfI4lbvRK+PIIo23SFH+LemGs4cKwzAaRa+Mdb+lQO/STaIayno8T5sJJA==
version "3.1.3"
resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.3.tgz#ae116a0fc0e598fdae48743a4430903de5b4e6ca"
integrity sha512-+HG5jmu/dN3ZV3T6eCD7a4BlAySdN7mLIbJYo0z1cFQuI+r2DiTJEFeF68ots93PsnrMxbzIZ2S/ieX+mkrBeQ==
dependencies:
prettier-linter-helpers "^1.0.0"
@@ -6204,15 +6234,15 @@ jest-diff@^24.9.0:
jest-get-type "^24.9.0"
pretty-format "^24.9.0"
jest-diff@^25.1.0, jest-diff@^25.2.1, jest-diff@^25.2.6:
version "25.2.6"
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.2.6.tgz#a6d70a9ab74507715ea1092ac513d1ab81c1b5e7"
integrity sha512-KuadXImtRghTFga+/adnNrv9s61HudRMR7gVSbP35UKZdn4IK2/0N0PpGZIqtmllK9aUyye54I3nu28OYSnqOg==
jest-diff@^25.1.0, jest-diff@^25.2.1, jest-diff@^25.4.0:
version "25.4.0"
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.4.0.tgz#260b70f19a46c283adcad7f081cae71eb784a634"
integrity sha512-kklLbJVXW0y8UKOWOdYhI6TH5MG6QAxrWiBMgQaPIuhj3dNFGirKCd+/xfplBXICQ7fI+3QcqHm9p9lWu1N6ug==
dependencies:
chalk "^3.0.0"
diff-sequences "^25.2.6"
jest-get-type "^25.2.6"
pretty-format "^25.2.6"
pretty-format "^25.4.0"
jest-docblock@^24.3.0:
version "24.9.0"
@@ -6337,14 +6367,14 @@ jest-matcher-utils@^24.9.0:
pretty-format "^24.9.0"
jest-matcher-utils@^25.1.0:
version "25.2.7"
resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-25.2.7.tgz#53fad3c11fc42e92e374306df543026712c957a3"
integrity sha512-jNYmKQPRyPO3ny0KY1I4f0XW4XnpJ3Nx5ovT4ik0TYDOYzuXJW40axqOyS61l/voWbVT9y9nZ1THL1DlpaBVpA==
version "25.4.0"
resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-25.4.0.tgz#dc3e7aec402a1e567ed80b572b9ad285878895e6"
integrity sha512-yPMdtj7YDgXhnGbc66bowk8AkQ0YwClbbwk3Kzhn5GVDrciiCr27U4NJRbrqXbTdtxjImONITg2LiRIw650k5A==
dependencies:
chalk "^3.0.0"
jest-diff "^25.2.6"
jest-diff "^25.4.0"
jest-get-type "^25.2.6"
pretty-format "^25.2.6"
pretty-format "^25.4.0"
jest-message-util@^24.9.0:
version "24.9.0"
@@ -7908,7 +7938,7 @@ p-try@^2.0.0:
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
pako@~1.0.5:
pako@^1.0.5, pako@~1.0.5:
version "1.0.11"
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==
@@ -8201,7 +8231,7 @@ pnp-webpack-plugin@1.6.4:
dependencies:
ts-pnp "^1.1.6"
popper.js@^1.14.1:
popper.js@^1.16.1-lts:
version "1.16.1"
resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b"
integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==
@@ -8899,9 +8929,9 @@ prettier-linter-helpers@^1.0.0:
fast-diff "^1.1.2"
prettier@^2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.3.tgz#9a06f0e94a51420e78b6925568b5bec72afe41ea"
integrity sha512-5qpBDBHO9fpE0zruKiTZm8Gxmz7kknO+WlQR/ivV+RMwgDw/WjOgmxLDn66MPrxq/WZPx/EgEZzh87xJO5E6Fw==
version "2.0.5"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.5.tgz#d6d56282455243f2f92cc1716692c08aa31522d4"
integrity sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==
pretty-bytes@^5.1.0:
version "5.3.0"
@@ -8926,12 +8956,12 @@ pretty-format@^24.8.0, pretty-format@^24.9.0:
ansi-styles "^3.2.0"
react-is "^16.8.4"
pretty-format@^25.1.0, pretty-format@^25.2.1, pretty-format@^25.2.6:
version "25.2.6"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.2.6.tgz#542a1c418d019bbf1cca2e3620443bc1323cb8d7"
integrity sha512-DEiWxLBaCHneffrIT4B+TpMvkV9RNvvJrd3lY9ew1CEQobDzEXmYT1mg0hJhljZty7kCc10z13ohOFAE8jrUDg==
pretty-format@^25.1.0, pretty-format@^25.2.1, pretty-format@^25.4.0:
version "25.4.0"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.4.0.tgz#c58801bb5c4926ff4a677fe43f9b8b99812c7830"
integrity sha512-PI/2dpGjXK5HyXexLPZU/jw5T9Q6S1YVXxxVxco+LIqzUFHXIbKZKdUVt7GcX7QUCr31+3fzhi4gN4/wUYPVxQ==
dependencies:
"@jest/types" "^25.2.6"
"@jest/types" "^25.4.0"
ansi-regex "^5.0.0"
ansi-styles "^4.0.0"
react-is "^16.12.0"
@@ -9076,6 +9106,20 @@ q@^1.1.2:
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=
qr.js@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/qr.js/-/qr.js-0.0.0.tgz#cace86386f59a0db8050fa90d9b6b0e88a1e364f"
integrity sha1-ys6GOG9ZoNuAUPqQ2baw6IoeNk8=
qrcode.react@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/qrcode.react/-/qrcode.react-1.0.0.tgz#7e8889db3b769e555e8eb463d4c6de221c36d5de"
integrity sha512-jBXleohRTwvGBe1ngV+62QvEZ/9IZqQivdwzo9pJM4LQMoCM2VnvNBnKdjvGnKyDZ/l0nCDgsPod19RzlPvm/Q==
dependencies:
loose-envify "^1.4.0"
prop-types "^15.6.0"
qr.js "0.0.0"
qs@6.7.0:
version "6.7.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
@@ -9118,10 +9162,10 @@ querystringify@^2.1.1:
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e"
integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==
ra-core@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/ra-core/-/ra-core-3.4.0.tgz#1d4b49b78cf60eb2b0d2c1584ccfce73611ab9a6"
integrity sha512-hpC0r6s6Uodj3e8T06uvBbk/dcv2H/C2Gih+ouAyuKOR4gglAWIPqcpy6SfN5cZrBxbGkvDCFSKDNNMw5067+g==
ra-core@^3.4.1:
version "3.4.1"
resolved "https://registry.yarnpkg.com/ra-core/-/ra-core-3.4.1.tgz#4390f7f317a1bbdabf03b6cd2d4484d7048450ef"
integrity sha512-XHcYAU36aMhIAmspdQ299SLCclu7qMmPS/IXN1VPVlRJHAIurK5tgRUMStAgDRO05qIkU5Xnb9C9PA63VmlPwA==
dependencies:
"@testing-library/react" "^8.0.7"
classnames "~2.2.5"
@@ -9134,30 +9178,30 @@ ra-core@^3.4.0:
recompose "~0.26.0"
reselect "~3.0.0"
ra-i18n-polyglot@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/ra-i18n-polyglot/-/ra-i18n-polyglot-3.4.0.tgz#fcc2067e55e953c58f496d579837241615eca85b"
integrity sha512-53VWZ3C9cza9cqfibzGVBdFAA/zc3c8pLY2yt5RKNiD1taHylZyX0doebC///jOe7OwUaOHv1KnD5WdLaNM93Q==
ra-i18n-polyglot@^3.4.1:
version "3.4.1"
resolved "https://registry.yarnpkg.com/ra-i18n-polyglot/-/ra-i18n-polyglot-3.4.1.tgz#269618aaae5fd525e36cb52cf1709e5fcd79bb9b"
integrity sha512-i13N/wGi7aOxKeABdJ54wwYJZPUeLLUQ23C1TAbNynFro1pIHl2j4lxRBhRIlYPwNKdsUjuLzt30fdcVIGH+FQ==
dependencies:
node-polyglot "^2.2.2"
ra-core "^3.4.0"
ra-core "^3.4.1"
ra-language-english@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/ra-language-english/-/ra-language-english-3.4.0.tgz#1296dd9bd632f175e71f885c9bdbc06379b49d5a"
integrity sha512-H2ZapYrn4jPyj7/+aA2X4XUaXQ6t2y5gR8DlSsRZlkmlHVWcpUFlyG2gZCYTDAeVKXO5Dedgf09KlYLJ6p7p0w==
ra-language-english@^3.4.1:
version "3.4.1"
resolved "https://registry.yarnpkg.com/ra-language-english/-/ra-language-english-3.4.1.tgz#04a117d9991a2da32f313819041cac7aa2a6337c"
integrity sha512-bAoJyIGL3LJ/8hIvQ+gsHYlFKwgpOalQb3ZUdJReU+vAt52nQqN/3BxknxSMRFOxH0iMQk9k3B+EakDtiesH3Q==
dependencies:
ra-core "^3.4.0"
ra-core "^3.4.1"
ra-language-german@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/ra-language-german/-/ra-language-german-2.1.2.tgz#d183093d470ab499ece91838cb67222db88f2e4f"
integrity sha512-N+BaBP0z98ujaKVlAMIKTfWHgmTiWD8sPQrU5vA3+b5zY9U0mMB4VjvU8sQQPR7rZE0gsRgS/X4V6ycDtNL6iQ==
ra-ui-materialui@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/ra-ui-materialui/-/ra-ui-materialui-3.4.0.tgz#9f3f573384ee8c8e91637627fb888bd51a4fd0b9"
integrity sha512-nV10aD4Z8ZgmZUcnfNTzAelQCxqdc5cG/KxyYvcqqV9j0oGBrqC9dr00bKLIBHc1oFTVvLwcdPd4p78tO6B+5g==
ra-ui-materialui@^3.4.2:
version "3.4.2"
resolved "https://registry.yarnpkg.com/ra-ui-materialui/-/ra-ui-materialui-3.4.2.tgz#6ab59b44cbe351eee2afccfeb118ee3ea67db28d"
integrity sha512-P1WigQJzIGeMy2jpAoMF0PlkDKZuufUEp/J0y9YFPumHvd5Dvzzz4XCytlL+362XkzgtxVWWH+WlX8CoYD3Y2w==
dependencies:
autosuggest-highlight "^3.1.1"
classnames "~2.2.5"
@@ -9224,9 +9268,9 @@ raw-body@2.4.0:
unpipe "1.0.0"
react-admin@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/react-admin/-/react-admin-3.4.0.tgz#d2806d9bab6f1c73e4f065d6f339389dd8126195"
integrity sha512-tgxCAYPkoZa7LC8ImFU8pQVFf5ja4dbxtx4/bgCOYJ7/QbTYdwFhzwuhfspnzRWDO3Tvkx3VTiuObQuR+JIDug==
version "3.4.2"
resolved "https://registry.yarnpkg.com/react-admin/-/react-admin-3.4.2.tgz#081a9f930e5822cf31c4cc747d058a9522f945e4"
integrity sha512-C0YeuWgd1fskhOk9oG6uyZidw7IEd5MkQWBKahDOY4PW59dZk8hFSuRzkVkaF8B/c/2oM1kCGuVR5likYPrJEA==
dependencies:
"@material-ui/core" "^4.3.3"
"@material-ui/icons" "^4.2.1"
@@ -9234,10 +9278,10 @@ react-admin@^3.4.0:
connected-react-router "^6.5.2"
final-form "^4.18.5"
final-form-arrays "^3.0.1"
ra-core "^3.4.0"
ra-i18n-polyglot "^3.4.0"
ra-language-english "^3.4.0"
ra-ui-materialui "^3.4.0"
ra-core "^3.4.1"
ra-i18n-polyglot "^3.4.1"
ra-language-english "^3.4.1"
ra-ui-materialui "^3.4.2"
react-final-form "^6.3.3"
react-final-form-arrays "^3.1.1"
react-redux "^7.1.0"
@@ -10554,9 +10598,9 @@ string.prototype.trim@^1.1.2, string.prototype.trim@^1.2.1:
function-bind "^1.1.1"
string.prototype.trimend@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.0.tgz#ee497fd29768646d84be2c9b819e292439614373"
integrity sha512-EEJnGqa/xNfIg05SxiPSqRS7S9qwDhYts1TSLR1BQfYUfPe1stofgGKvwERK9+9yf+PpfBMlpBaCHucXGPQfUA==
version "1.0.1"
resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913"
integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==
dependencies:
define-properties "^1.1.3"
es-abstract "^1.17.5"
@@ -10580,9 +10624,9 @@ string.prototype.trimright@^2.1.1:
string.prototype.trimend "^1.0.0"
string.prototype.trimstart@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.0.tgz#afe596a7ce9de905496919406c9734845f01a2f2"
integrity sha512-iCP8g01NFYiiBOnwG1Xc3WZLyoo+RuBymwIlWncShXDDJYWN6DbnM3odslBJdgCdRlq94B5s63NWAZlcn2CS4w==
version "1.0.1"
resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54"
integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==
dependencies:
define-properties "^1.1.3"
es-abstract "^1.17.5"