Merge branch 'master' into remove_translate

This commit is contained in:
Dirk Klimpel 2022-02-17 22:10:56 +01:00 committed by GitHub
commit ec4b205600
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 356 additions and 124 deletions

View File

@ -5,7 +5,7 @@
This project is built using [react-admin](https://marmelab.com/react-admin/). This project is built using [react-admin](https://marmelab.com/react-admin/).
It needs at least Synapse v1.41.0 for all functions to work as expected! It needs at least Synapse v1.42.0 for all functions to work as expected!
You get your server version with the request `/_synapse/admin/v1/server_version`. You get your server version with the request `/_synapse/admin/v1/server_version`.
See also [Synapse version API](https://matrix-org.github.io/synapse/develop/admin_api/version_api.html). See also [Synapse version API](https://matrix-org.github.io/synapse/develop/admin_api/version_api.html).

View File

@ -8,12 +8,18 @@ import { RoomList, RoomShow } from "./components/rooms";
import { ReportList, ReportShow } from "./components/EventReports"; import { ReportList, ReportShow } from "./components/EventReports";
import LoginPage from "./components/LoginPage"; import LoginPage from "./components/LoginPage";
import UserIcon from "@material-ui/icons/Group"; import UserIcon from "@material-ui/icons/Group";
import ConfirmationNumberIcon from "@material-ui/icons/ConfirmationNumber";
import EqualizerIcon from "@material-ui/icons/Equalizer"; import EqualizerIcon from "@material-ui/icons/Equalizer";
import { UserMediaStatsList } from "./components/statistics"; import { UserMediaStatsList } from "./components/statistics";
import RoomIcon from "@material-ui/icons/ViewList"; import RoomIcon from "@material-ui/icons/ViewList";
import ReportIcon from "@material-ui/icons/Warning"; import ReportIcon from "@material-ui/icons/Warning";
import FolderSharedIcon from "@material-ui/icons/FolderShared"; import FolderSharedIcon from "@material-ui/icons/FolderShared";
import { ImportFeature } from "./components/ImportFeature"; import { ImportFeature } from "./components/ImportFeature";
import {
RegistrationTokenCreate,
RegistrationTokenEdit,
RegistrationTokenList,
} from "./components/RegistrationTokens";
import { RoomDirectoryList } from "./components/RoomDirectory"; import { RoomDirectoryList } from "./components/RoomDirectory";
import { Route } from "react-router-dom"; import { Route } from "react-router-dom";
import germanMessages from "./i18n/de"; import germanMessages from "./i18n/de";
@ -66,6 +72,13 @@ const App = () => (
list={RoomDirectoryList} list={RoomDirectoryList}
icon={FolderSharedIcon} icon={FolderSharedIcon}
/> />
<Resource
name="registration_tokens"
list={RegistrationTokenList}
create={RegistrationTokenCreate}
edit={RegistrationTokenEdit}
icon={ConfirmationNumberIcon}
/>
<Resource name="connections" /> <Resource name="connections" />
<Resource name="devices" /> <Resource name="devices" />
<Resource name="room_members" /> <Resource name="room_members" />

View File

@ -15,6 +15,15 @@ import {
import PageviewIcon from "@material-ui/icons/Pageview"; import PageviewIcon from "@material-ui/icons/Pageview";
import ViewListIcon from "@material-ui/icons/ViewList"; import ViewListIcon from "@material-ui/icons/ViewList";
const date_format = {
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
};
const ReportPagination = props => ( const ReportPagination = props => (
<Pagination {...props} rowsPerPageOptions={[10, 25, 50, 100, 500, 1000]} /> <Pagination {...props} rowsPerPageOptions={[10, 25, 50, 100, 500, 1000]} />
); );
@ -33,14 +42,7 @@ export const ReportShow = props => {
<DateField <DateField
source="received_ts" source="received_ts"
showTime showTime
options={{ options={date_format}
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
}}
sortable={true} sortable={true}
/> />
<ReferenceField source="user_id" reference="users"> <ReferenceField source="user_id" reference="users">
@ -72,14 +74,7 @@ export const ReportShow = props => {
<DateField <DateField
source="event_json.origin_server_ts" source="event_json.origin_server_ts"
showTime showTime
options={{ options={date_format}
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
}}
sortable={true} sortable={true}
/> />
<ReferenceField source="sender" reference="users"> <ReferenceField source="sender" reference="users">
@ -116,14 +111,7 @@ export const ReportList = ({ ...props }) => {
<DateField <DateField
source="received_ts" source="received_ts"
showTime showTime
options={{ options={date_format}
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
}}
sortable={true} sortable={true}
/> />
<TextField sortable={false} source="user_id" /> <TextField sortable={false} source="user_id" />

View File

@ -78,11 +78,48 @@ const LoginPage = ({ theme }) => {
const login = useLogin(); const login = useLogin();
const notify = useNotify(); const notify = useNotify();
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [supportPassAuth, setSupportPassAuth] = useState(true);
var locale = useLocale(); var locale = useLocale();
const setLocale = useSetLocale(); const setLocale = useSetLocale();
const translate = useTranslate(); const translate = useTranslate();
const base_url = localStorage.getItem("base_url"); const base_url = localStorage.getItem("base_url");
const cfg_base_url = process.env.REACT_APP_SERVER; const cfg_base_url = process.env.REACT_APP_SERVER;
const [ssoBaseUrl, setSSOBaseUrl] = useState("");
const loginToken = /\?loginToken=([a-zA-Z0-9_-]+)/.exec(window.location.href);
if (loginToken) {
const ssoToken = loginToken[1];
console.log("SSO token is", ssoToken);
// Prevent further requests
window.history.replaceState(
{},
"",
window.location.href.replace(loginToken[0], "#").split("#")[0]
);
const baseUrl = localStorage.getItem("sso_base_url");
localStorage.removeItem("sso_base_url");
if (baseUrl) {
const auth = {
base_url: baseUrl,
username: null,
password: null,
loginToken: ssoToken,
};
console.log("Base URL is:", baseUrl);
console.log("SSO Token is:", ssoToken);
console.log("Let's try token login...");
login(auth).catch(error => {
alert(
typeof error === "string"
? error
: typeof error === "undefined" || !error.message
? "ra.auth.sign_in_error"
: error.message
);
console.error(error);
});
}
}
const renderInput = ({ const renderInput = ({
meta: { touched, error } = {}, meta: { touched, error } = {},
@ -137,6 +174,14 @@ const LoginPage = ({ theme }) => {
}); });
}; };
const handleSSO = () => {
localStorage.setItem("sso_base_url", ssoBaseUrl);
const ssoFullUrl = `${ssoBaseUrl}/_matrix/client/r0/login/sso/redirect?redirectUrl=${encodeURIComponent(
window.location.href
)}`;
window.location.href = ssoFullUrl;
};
const extractHomeServer = username => { const extractHomeServer = username => {
const usernameRegex = /@[a-zA-Z0-9._=\-/]+:([a-zA-Z0-9\-.]+\.[a-zA-Z]+)/; const usernameRegex = /@[a-zA-Z0-9._=\-/]+:([a-zA-Z0-9\-.]+\.[a-zA-Z]+)/;
if (!username) return null; if (!username) return null;
@ -188,6 +233,31 @@ const LoginPage = ({ theme }) => {
.catch(_ => { .catch(_ => {
setServerVersion(""); setServerVersion("");
}); });
// Set SSO Url
const authMethodUrl = `${formData.base_url}/_matrix/client/r0/login`;
let supportPass = false,
supportSSO = false;
fetchUtils
.fetchJson(authMethodUrl, { method: "GET" })
.then(({ json }) => {
json.flows.forEach(f => {
if (f.type === "m.login.password") {
supportPass = true;
} else if (f.type === "m.login.sso") {
supportSSO = true;
}
});
setSupportPassAuth(supportPass);
if (supportSSO) {
setSSOBaseUrl(formData.base_url);
} else {
setSSOBaseUrl("");
}
})
.catch(_ => {
setSSOBaseUrl("");
});
}, },
[formData.base_url] [formData.base_url]
); );
@ -200,7 +270,7 @@ const LoginPage = ({ theme }) => {
name="username" name="username"
component={renderInput} component={renderInput}
label="ra.auth.username" label="ra.auth.username"
disabled={loading} disabled={loading || !supportPassAuth}
onBlur={handleUsernameChange} onBlur={handleUsernameChange}
resettable resettable
fullWidth fullWidth
@ -212,7 +282,7 @@ const LoginPage = ({ theme }) => {
component={renderInput} component={renderInput}
label="ra.auth.password" label="ra.auth.password"
type="password" type="password"
disabled={loading} disabled={loading || !supportPassAuth}
resettable resettable
fullWidth fullWidth
/> />
@ -273,13 +343,24 @@ const LoginPage = ({ theme }) => {
variant="contained" variant="contained"
type="submit" type="submit"
color="primary" color="primary"
disabled={loading} disabled={loading || !supportPassAuth}
className={classes.button} className={classes.button}
fullWidth fullWidth
> >
{loading && <CircularProgress size={25} thickness={2} />} {loading && <CircularProgress size={25} thickness={2} />}
{translate("ra.auth.sign_in")} {translate("ra.auth.sign_in")}
</Button> </Button>
<Button
variant="contained"
color="secondary"
onClick={handleSSO}
disabled={loading || ssoBaseUrl === ""}
className={classes.button}
fullWidth
>
{loading && <CircularProgress size={25} thickness={2} />}
{translate("synapseadmin.auth.sso_sign_in")}
</Button>
</CardActions> </CardActions>
</Card> </Card>
<Notification /> <Notification />

View File

@ -0,0 +1,132 @@
import React from "react";
import {
BooleanInput,
Create,
Datagrid,
DateField,
DateTimeInput,
Edit,
Filter,
List,
maxValue,
number,
NumberField,
NumberInput,
regex,
SimpleForm,
TextInput,
TextField,
Toolbar,
} from "react-admin";
const date_format = {
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
};
const validateToken = [regex(/^[A-Za-z0-9._~-]{0,64}$/)];
const validateUsesAllowed = [number()];
const validateLength = [number(), maxValue(64)];
const dateParser = v => {
const d = new Date(v);
if (isNaN(d)) return 0;
return d.getTime();
};
const dateFormatter = v => {
if (v === undefined || v === null) return;
const d = new Date(v);
const pad = "00";
const year = d.getFullYear().toString();
const month = (pad + (d.getMonth() + 1).toString()).slice(-2);
const day = (pad + d.getDate().toString()).slice(-2);
const hour = (pad + d.getHours().toString()).slice(-2);
const minute = (pad + d.getMinutes().toString()).slice(-2);
// target format yyyy-MM-ddThh:mm
return `${year}-${month}-${day}T${hour}:${minute}`;
};
const RegistrationTokenFilter = props => (
<Filter {...props}>
<BooleanInput source="valid" alwaysOn />
</Filter>
);
export const RegistrationTokenList = props => {
return (
<List
{...props}
filters={<RegistrationTokenFilter />}
filterDefaultValues={{ valid: true }}
pagination={false}
perPage={500}
>
<Datagrid rowClick="edit">
<TextField source="token" sortable={false} />
<NumberField source="uses_allowed" sortable={false} />
<NumberField source="pending" sortable={false} />
<NumberField source="completed" sortable={false} />
<DateField
source="expiry_time"
showTime
options={date_format}
sortable={false}
/>
</Datagrid>
</List>
);
};
export const RegistrationTokenCreate = props => (
<Create {...props}>
<SimpleForm redirect="list" toolbar={<Toolbar alwaysEnableSaveButton />}>
<TextInput
source="token"
autoComplete="off"
validate={validateToken}
resettable
/>
<NumberInput
source="length"
validate={validateLength}
helperText="resources.registration_tokens.helper.length"
step={1}
/>
<NumberInput
source="uses_allowed"
validate={validateUsesAllowed}
step={1}
/>
<DateTimeInput source="expiry_time" parse={dateParser} />
</SimpleForm>
</Create>
);
export const RegistrationTokenEdit = props => {
return (
<Edit {...props}>
<SimpleForm>
<TextInput source="token" disabled />
<NumberInput source="pending" disabled />
<NumberInput source="completed" disabled />
<NumberInput
source="uses_allowed"
validate={validateUsesAllowed}
step={1}
/>
<DateTimeInput
source="expiry_time"
parse={dateParser}
format={dateFormatter}
/>
</SimpleForm>
</Edit>
);
};

View File

@ -8,7 +8,7 @@ import {
} from "react-admin"; } from "react-admin";
import ActionDelete from "@material-ui/icons/Delete"; import ActionDelete from "@material-ui/icons/Delete";
import { makeStyles } from "@material-ui/core/styles"; import { makeStyles } from "@material-ui/core/styles";
import { fade } from "@material-ui/core/styles/colorManipulator"; import { alpha } from "@material-ui/core/styles/colorManipulator";
import classnames from "classnames"; import classnames from "classnames";
const useStyles = makeStyles( const useStyles = makeStyles(
@ -16,7 +16,7 @@ const useStyles = makeStyles(
deleteButton: { deleteButton: {
color: theme.palette.error.main, color: theme.palette.error.main,
"&:hover": { "&:hover": {
backgroundColor: fade(theme.palette.error.main, 0.12), backgroundColor: alpha(theme.palette.error.main, 0.12),
// Reset on mouse devices // Reset on mouse devices
"@media (hover: none)": { "@media (hover: none)": {
backgroundColor: "transparent", backgroundColor: "transparent",

View File

@ -1,6 +1,6 @@
import React, { Fragment, useState } from "react"; import React, { Fragment, useState } from "react";
import classnames from "classnames"; import classnames from "classnames";
import { fade } from "@material-ui/core/styles/colorManipulator"; import { alpha } from "@material-ui/core/styles/colorManipulator";
import { makeStyles } from "@material-ui/core/styles"; import { makeStyles } from "@material-ui/core/styles";
import { Tooltip } from "@material-ui/core"; import { Tooltip } from "@material-ui/core";
import { import {
@ -33,7 +33,7 @@ const useStyles = makeStyles(
deleteButton: { deleteButton: {
color: theme.palette.error.main, color: theme.palette.error.main,
"&:hover": { "&:hover": {
backgroundColor: fade(theme.palette.error.main, 0.12), backgroundColor: alpha(theme.palette.error.main, 0.12),
// Reset on mouse devices // Reset on mouse devices
"@media (hover: none)": { "@media (hover: none)": {
backgroundColor: "transparent", backgroundColor: "transparent",

View File

@ -41,6 +41,15 @@ import {
RoomDirectorySaveButton, RoomDirectorySaveButton,
} from "./RoomDirectory"; } from "./RoomDirectory";
const date_format = {
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
};
const useStyles = makeStyles(theme => ({ const useStyles = makeStyles(theme => ({
helper_forward_extremities: { helper_forward_extremities: {
fontFamily: "Roboto, Helvetica, Arial, sans-serif", fontFamily: "Roboto, Helvetica, Arial, sans-serif",
@ -247,14 +256,7 @@ export const RoomShow = props => {
<DateField <DateField
source="origin_server_ts" source="origin_server_ts"
showTime showTime
options={{ options={date_format}
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
}}
sortable={false} sortable={false}
/> />
<TextField source="content" sortable={false} /> <TextField source="content" sortable={false} />
@ -287,14 +289,7 @@ export const RoomShow = props => {
<DateField <DateField
source="received_ts" source="received_ts"
showTime showTime
options={{ options={date_format}
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
}}
sortable={false} sortable={false}
/> />
<NumberField source="depth" sortable={false} /> <NumberField source="depth" sortable={false} />

View File

@ -71,6 +71,15 @@ const useStyles = makeStyles({
}, },
}); });
const date_format = {
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
};
const UserListActions = ({ const UserListActions = ({
currentSort, currentSort,
className, className,
@ -180,14 +189,7 @@ export const UserList = props => {
source="creation_ts" source="creation_ts"
label="resources.users.fields.creation_ts_ms" label="resources.users.fields.creation_ts_ms"
showTime showTime
options={{ options={date_format}
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
}}
/> />
</Datagrid> </Datagrid>
</List> </List>
@ -336,18 +338,7 @@ export const UserEdit = props => {
source="deactivated" source="deactivated"
helperText="resources.users.helper.deactivate" helperText="resources.users.helper.deactivate"
/> />
<DateField <DateField source="creation_ts_ms" showTime options={date_format} />
source="creation_ts_ms"
showTime
options={{
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
}}
/>
<TextField source="consent_version" /> <TextField source="consent_version" />
</FormTab> </FormTab>
@ -404,14 +395,7 @@ export const UserEdit = props => {
<DateField <DateField
source="last_seen_ts" source="last_seen_ts"
showTime showTime
options={{ options={date_format}
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
}}
sortable={false} sortable={false}
/> />
<DeviceRemoveButton /> <DeviceRemoveButton />
@ -439,14 +423,7 @@ export const UserEdit = props => {
<DateField <DateField
source="last_seen" source="last_seen"
showTime showTime
options={{ options={date_format}
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
}}
sortable={false} sortable={false}
/> />
<TextField <TextField
@ -473,29 +450,11 @@ export const UserEdit = props => {
sort={{ field: "created_ts", order: "DESC" }} sort={{ field: "created_ts", order: "DESC" }}
> >
<Datagrid style={{ width: "100%" }}> <Datagrid style={{ width: "100%" }}>
<DateField <DateField source="created_ts" showTime options={date_format} />
source="created_ts"
showTime
options={{
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
}}
/>
<DateField <DateField
source="last_access_ts" source="last_access_ts"
showTime showTime
options={{ options={date_format}
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
}}
/> />
<TextField source="media_id" /> <TextField source="media_id" />
<NumberField source="media_length" /> <NumberField source="media_length" />

View File

@ -10,6 +10,7 @@ const de = {
username_error: "Bitte vollständigen Nutzernamen angeben: '@user:domain'", username_error: "Bitte vollständigen Nutzernamen angeben: '@user:domain'",
protocol_error: "Die URL muss mit 'http://' oder 'https://' beginnen", protocol_error: "Die URL muss mit 'http://' oder 'https://' beginnen",
url_error: "Keine gültige Matrix Server URL", url_error: "Keine gültige Matrix Server URL",
sso_sign_in: "Anmeldung mit SSO",
}, },
users: { users: {
invalid_user_id: "Lokaler Anteil der Matrix Benutzer-ID ohne Homeserver.", invalid_user_id: "Lokaler Anteil der Matrix Benutzer-ID ohne Homeserver.",
@ -351,6 +352,19 @@ const de = {
send_failure: "Beim Entfernen ist ein Fehler aufgetreten.", send_failure: "Beim Entfernen ist ein Fehler aufgetreten.",
}, },
}, },
registration_tokens: {
name: "Registrierungstoken",
fields: {
token: "Token",
valid: "Gültige Token",
uses_allowed: "Anzahl",
pending: "Ausstehend",
completed: "Abgeschlossen",
expiry_time: "Ablaufzeit",
length: "Länge",
},
helper: { length: "Länge des Tokens, wenn kein Token vorgegeben wird." },
},
}, },
ra: { ra: {
...germanMessages.ra, ...germanMessages.ra,
@ -371,7 +385,7 @@ const de = {
}, },
}, },
notification: { notification: {
...germanMessages.ra.notifiaction, ...germanMessages.ra.notification,
logged_out: "Abgemeldet", logged_out: "Abgemeldet",
}, },
page: { page: {

View File

@ -10,6 +10,7 @@ const en = {
username_error: "Please enter fully qualified user ID: '@user:domain'", username_error: "Please enter fully qualified user ID: '@user:domain'",
protocol_error: "URL has to start with 'http://' or 'https://'", protocol_error: "URL has to start with 'http://' or 'https://'",
url_error: "Not a valid Matrix server URL", url_error: "Not a valid Matrix server URL",
sso_sign_in: "Sign in with SSO",
}, },
users: { users: {
invalid_user_id: "Localpart of a Matrix user-id without homeserver.", invalid_user_id: "Localpart of a Matrix user-id without homeserver.",
@ -173,12 +174,14 @@ const en = {
}, },
unencrypted: "Unencrypted", unencrypted: "Unencrypted",
}, },
action: {
erase: { erase: {
title: "Delete room", title: "Delete room",
content: content:
"Are you sure you want to delete the room? This cannot be undone. All messages and shared media in the room will be deleted from the server!", "Are you sure you want to delete the room? This cannot be undone. All messages and shared media in the room will be deleted from the server!",
}, },
}, },
},
reports: { reports: {
name: "Reported event |||| Reported events", name: "Reported event |||| Reported events",
fields: { fields: {
@ -348,5 +351,18 @@ const en = {
}, },
}, },
}, },
registration_tokens: {
name: "Registration tokens",
fields: {
token: "Token",
valid: "Valid token",
uses_allowed: "Uses allowed",
pending: "Pending",
completed: "Completed",
expiry_time: "Expiry time",
length: "Length",
},
helper: { length: "Length of the token if no token is given." },
},
}; };
export default en; export default en;

View File

@ -10,10 +10,12 @@ const zh = {
username_error: "请输入完整有效的用户 ID: '@user:domain'", username_error: "请输入完整有效的用户 ID: '@user:domain'",
protocol_error: "URL 需要以'http://'或'https://'作为起始", protocol_error: "URL 需要以'http://'或'https://'作为起始",
url_error: "不是一个有效的 Matrix 服务器地址", url_error: "不是一个有效的 Matrix 服务器地址",
sso_sign_in: "使用 SSO 登录",
}, },
users: { users: {
invalid_user_id: invalid_user_id:
"必须要是一个有效的 Matrix 用户 ID ,例如 @user_id:homeserver", "必须要是一个有效的 Matrix 用户 ID ,例如 @user_id:homeserver",
tabs: { sso: "SSO" },
}, },
rooms: { rooms: {
tabs: { tabs: {

View File

@ -2,20 +2,31 @@ import { fetchUtils } from "react-admin";
const authProvider = { const authProvider = {
// called when the user attempts to log in // called when the user attempts to log in
login: ({ base_url, username, password }) => { login: ({ base_url, username, password, loginToken }) => {
// force homeserver for protection in case the form is manipulated // force homeserver for protection in case the form is manipulated
base_url = process.env.REACT_APP_SERVER || base_url; base_url = process.env.REACT_APP_SERVER || base_url;
console.log("login "); console.log("login ");
const options = { const options = {
method: "POST", method: "POST",
body: JSON.stringify({ body: JSON.stringify(
Object.assign(
{
device_id: localStorage.getItem("device_id"),
initial_device_display_name: "Synapse Admin",
},
loginToken
? {
type: "m.login.token",
token: loginToken,
}
: {
type: "m.login.password", type: "m.login.password",
user: username, user: username,
password: password, password: password,
device_id: localStorage.getItem("device_id"), }
initial_device_display_name: "Synapse Admin", )
}), ),
}; };
// use the base_url from login instead of the well_known entry from the // use the base_url from login instead of the well_known entry from the

View File

@ -275,6 +275,25 @@ const resourceMap = {
method: "PUT", method: "PUT",
}), }),
}, },
registration_tokens: {
path: "/_synapse/admin/v1/registration_tokens",
map: rt => ({
...rt,
id: rt.token,
}),
data: "registration_tokens",
total: json => {
return json.registration_tokens.length;
},
create: params => ({
endpoint: "/_synapse/admin/v1/registration_tokens/new",
body: params,
method: "POST",
}),
delete: params => ({
endpoint: `/_synapse/admin/v1/registration_tokens/${params.id}`,
}),
},
}; };
function filterNullValues(key, value) { function filterNullValues(key, value) {
@ -296,7 +315,8 @@ function getSearchOrder(order) {
const dataProvider = { const dataProvider = {
getList: (resource, params) => { getList: (resource, params) => {
console.log("getList " + resource); console.log("getList " + resource);
const { user_id, name, guests, deactivated, search_term } = params.filter; const { user_id, name, guests, deactivated, search_term, valid } =
params.filter;
const { page, perPage } = params.pagination; const { page, perPage } = params.pagination;
const { field, order } = params.sort; const { field, order } = params.sort;
const from = (page - 1) * perPage; const from = (page - 1) * perPage;
@ -308,6 +328,7 @@ const dataProvider = {
name: name, name: name,
guests: guests, guests: guests,
deactivated: deactivated, deactivated: deactivated,
valid: valid,
order_by: field, order_by: field,
dir: getSearchOrder(order), dir: getSearchOrder(order),
}; };

View File

@ -5290,9 +5290,9 @@ flush-write-stream@^1.0.0:
readable-stream "^2.3.6" readable-stream "^2.3.6"
follow-redirects@^1.0.0: follow-redirects@^1.0.0:
version "1.14.7" version "1.14.8"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc"
integrity sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ== integrity sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==
for-in@^1.0.2: for-in@^1.0.2:
version "1.0.2" version "1.0.2"
@ -11457,9 +11457,9 @@ url-loader@4.1.1:
schema-utils "^3.0.0" schema-utils "^3.0.0"
url-parse@^1.4.3, url-parse@^1.5.3: url-parse@^1.4.3, url-parse@^1.5.3:
version "1.5.3" version "1.5.7"
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.3.tgz#71c1303d38fb6639ade183c2992c8cc0686df862" resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.7.tgz#00780f60dbdae90181f51ed85fb24109422c932a"
integrity sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ== integrity sha512-HxWkieX+STA38EDk7CE9MEryFeHCKzgagxlGvsdS7WBImq9Mk+PGwiT56w82WI3aicwJA8REp42Cxo98c8FZMA==
dependencies: dependencies:
querystringify "^2.1.1" querystringify "^2.1.1"
requires-port "^1.0.0" requires-port "^1.0.0"