Files
synapse-admin/src/components/users.js
T

275 lines
6.9 KiB
JavaScript
Raw Normal View History

2020-04-09 10:32:06 +02:00
import React, { Fragment } from "react";
import PersonPinIcon from "@material-ui/icons/PersonPin";
import SettingsInputComponentIcon from "@material-ui/icons/SettingsInputComponent";
2020-02-07 17:44:48 +01:00
import {
2020-03-30 10:22:27 +02:00
ArrayInput,
ArrayField,
2020-02-07 17:44:48 +01:00
Datagrid,
DateField,
2020-02-07 17:44:48 +01:00
Create,
Edit,
List,
Filter,
2020-04-09 10:32:06 +02:00
Toolbar,
2020-02-07 17:44:48 +01:00
SimpleForm,
2020-03-30 10:22:27 +02:00
SimpleFormIterator,
TabbedForm,
FormTab,
2020-02-07 17:44:48 +01:00
BooleanField,
BooleanInput,
ImageField,
PasswordInput,
TextField,
TextInput,
2020-04-15 15:31:10 +02:00
SearchInput,
2020-02-07 17:44:48 +01:00
ReferenceField,
2020-03-30 10:22:27 +02:00
SelectInput,
2020-04-09 10:32:06 +02:00
BulkDeleteButton,
DeleteButton,
2020-02-07 16:25:32 +01:00
SaveButton,
2020-02-07 17:44:48 +01:00
regex,
2020-04-09 10:32:06 +02:00
useTranslate,
2020-03-27 21:02:37 +01:00
Pagination,
2020-02-07 17:44:48 +01:00
} from "react-admin";
2020-04-14 13:06:55 +02:00
import SaveQrButton from "./SaveQrButton";
2020-02-07 17:44:48 +01:00
2020-03-27 21:02:37 +01:00
const UserPagination = props => (
<Pagination {...props} rowsPerPageOptions={[10, 25, 50, 100, 500, 1000]} />
);
2020-02-07 17:44:48 +01:00
const UserFilter = props => (
<Filter {...props}>
2020-04-20 10:38:58 +02:00
<SearchInput source="user_id" alwaysOn />
2020-02-07 17:44:48 +01:00
<BooleanInput source="guests" alwaysOn />
<BooleanInput
label="resources.users.fields.show_deactivated"
source="deactivated"
alwaysOn
/>
</Filter>
);
2020-04-09 10:32:06 +02:00
const UserBulkActionButtons = props => {
const translate = useTranslate();
return (
<Fragment>
<BulkDeleteButton
{...props}
label="resources.users.action.erase"
title={translate("resources.users.helper.erase")}
/>
</Fragment>
);
};
2020-02-07 17:44:48 +01:00
export const UserList = props => (
<List
{...props}
filters={<UserFilter />}
filterDefaultValues={{ guests: true, deactivated: false }}
2020-04-09 10:32:06 +02:00
bulkActionButtons={<UserBulkActionButtons />}
2020-03-27 21:02:37 +01:00
pagination={<UserPagination />}
2020-02-07 17:44:48 +01:00
>
<Datagrid rowClick="edit">
2020-04-20 10:38:58 +02:00
<ImageField source="avatar_url" title="displayname" />
<TextField source="id" sortable={false} />
<TextField source="displayname" />
2020-02-07 17:44:48 +01:00
<BooleanField source="is_guest" sortable={false} />
<BooleanField source="admin" sortable={false} />
<BooleanField source="deactivated" sortable={false} />
</Datagrid>
</List>
);
function generateRandomUser() {
2020-04-21 14:00:57 +02:00
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,
};
}
2020-02-07 16:25:32 +01:00
// 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}>
2020-04-14 13:06:55 +02:00
<SaveQrButton
2020-02-07 16:25:32 +01:00
label="synapseadmin.action.save_and_show"
redirect={redirect}
submitOnEnter={true}
/>
<SaveButton
label="synapseadmin.action.save_only"
2020-02-10 18:16:16 +01:00
redirect="list"
2020-02-07 16:25:32 +01:00
submitOnEnter={false}
variant="text"
/>
</Toolbar>
);
2020-02-07 17:44:48 +01:00
// https://matrix.org/docs/spec/appendices#user-identifiers
const validateUser = regex(
/^@[a-z0-9._=\-/]+:.*/,
"synapseadmin.users.invalid_user_id"
);
2020-04-09 10:32:06 +02:00
const UserEditToolbar = props => {
const translate = useTranslate();
return (
<Toolbar {...props}>
2020-04-20 16:57:23 +02:00
<SaveQrButton
label="synapseadmin.action.save_and_show"
redirect={redirect}
submitOnEnter={true}
/>
<SaveButton
label="synapseadmin.action.save_only"
redirect="list"
submitOnEnter={false}
variant="text"
/>
2020-04-09 10:32:06 +02:00
<DeleteButton
label="resources.users.action.erase"
title={translate("resources.users.helper.erase")}
/>
</Toolbar>
);
};
2020-02-07 17:44:48 +01:00
export const UserCreate = props => (
<Create record={generateRandomUser()} {...props}>
2020-02-07 16:25:32 +01:00
<SimpleForm toolbar={<UserCreateToolbar />}>
2020-02-07 17:44:48 +01:00
<TextInput source="id" autoComplete="off" validate={validateUser} />
<TextInput source="displayname" />
<PasswordInput source="password" autoComplete="new-password" />
<BooleanInput source="admin" />
2020-03-30 10:22:27 +02:00
<ArrayInput source="threepids">
<SimpleFormIterator>
<SelectInput
source="medium"
choices={[
{ id: "email", name: "resources.users.email" },
{ id: "msisdn", name: "resources.users.msisdn" },
]}
/>
<TextInput source="address" />
</SimpleFormIterator>
</ArrayInput>
2020-02-07 17:44:48 +01:00
</SimpleForm>
</Create>
);
2020-04-21 18:39:51 +02:00
const UserTitle = ({ record }) => {
const translate = useTranslate();
return (
<span>
{translate("resources.users.name")}{" "}
{record ? `"${record.displayname}"` : ""}
</span>
);
};
2020-02-07 17:44:48 +01:00
export const UserEdit = props => (
2020-04-21 18:39:51 +02:00
<Edit {...props} title={<UserTitle />}>
2020-04-09 10:32:06 +02:00
<TabbedForm toolbar={<UserEditToolbar />}>
<FormTab label="resources.users.name" icon={<PersonPinIcon />}>
<TextInput source="id" disabled />
<TextInput source="displayname" />
<PasswordInput source="password" autoComplete="new-password" />
<BooleanInput source="admin" />
<BooleanInput
source="deactivated"
helperText="resources.users.helper.deactivate"
/>
<ArrayInput source="threepids">
<SimpleFormIterator>
<SelectInput
source="medium"
choices={[
{ id: "email", name: "resources.users.email" },
{ id: "msisdn", name: "resources.users.msisdn" },
]}
/>
<TextInput source="address" />
</SimpleFormIterator>
</ArrayInput>
</FormTab>
<FormTab
label="resources.connections.name"
icon={<SettingsInputComponentIcon />}
>
<ReferenceField reference="connections" source="id" addLabel={false}>
<ArrayField
source="devices[].sessions[0].connections"
label="resources.connections.name"
>
<Datagrid style={{ width: "100%" }}>
<TextField source="ip" sortable={false} />
<DateField
source="last_seen"
showTime
options={{
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
}}
sortable={false}
/>
<TextField
source="user_agent"
sortable={false}
style={{ width: "100%" }}
/>
</Datagrid>
</ArrayField>
</ReferenceField>
</FormTab>
</TabbedForm>
2020-02-07 17:44:48 +01:00
</Edit>
);