Compare commits

66 Commits

Author SHA1 Message Date
Aine
fe4ba22a03 update README 2024-10-30 18:49:32 +02:00
Aine
eb35d9e122 remove CI hack to include version into manifest.json (now generated on each build automatically) 2024-10-30 18:00:05 +02:00
Aine
fa79fecc9d Generate extended manifest.json on build 2024-10-30 17:58:33 +02:00
dependabot[bot]
61366b3792 Bump ra-language-english from 5.3.0 to 5.3.1 (#102)
Bumps [ra-language-english](https://github.com/marmelab/react-admin) from 5.3.0 to 5.3.1.
- [Release notes](https://github.com/marmelab/react-admin/releases)
- [Changelog](https://github.com/marmelab/react-admin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/marmelab/react-admin/compare/v5.3.0...v5.3.1)

---
updated-dependencies:
- dependency-name: ra-language-english
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-28 10:55:00 +02:00
dependabot[bot]
b55033d983 Bump react-admin from 5.3.0 to 5.3.1 (#103)
Bumps [react-admin](https://github.com/marmelab/react-admin) from 5.3.0 to 5.3.1.
- [Release notes](https://github.com/marmelab/react-admin/releases)
- [Changelog](https://github.com/marmelab/react-admin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/marmelab/react-admin/compare/v5.3.0...v5.3.1)

---
updated-dependencies:
- dependency-name: react-admin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-28 10:54:46 +02:00
dependabot[bot]
b1f42988c8 Bump ra-language-french from 5.3.0 to 5.3.1 (#104)
Bumps [ra-language-french](https://github.com/marmelab/react-admin) from 5.3.0 to 5.3.1.
- [Release notes](https://github.com/marmelab/react-admin/releases)
- [Changelog](https://github.com/marmelab/react-admin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/marmelab/react-admin/compare/v5.3.0...v5.3.1)

---
updated-dependencies:
- dependency-name: ra-language-french
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-28 10:54:27 +02:00
dependabot[bot]
ef05b366c3 Bump eslint-plugin-jsx-a11y from 6.10.1 to 6.10.2 (#105)
Bumps [eslint-plugin-jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y) from 6.10.1 to 6.10.2.
- [Release notes](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/releases)
- [Changelog](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/compare/v6.10.1...v6.10.2)

---
updated-dependencies:
- dependency-name: eslint-plugin-jsx-a11y
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-28 10:53:30 +02:00
dependabot[bot]
b3d52e7d23 Bump @types/node from 22.7.9 to 22.8.1 (#106)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.7.9 to 22.8.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-28 10:53:18 +02:00
dependabot[bot]
d1c4250b46 Bump @tanstack/react-query from 5.59.15 to 5.59.16 (#107)
Bumps [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) from 5.59.15 to 5.59.16.
- [Release notes](https://github.com/TanStack/query/releases)
- [Commits](https://github.com/TanStack/query/commits/v5.59.16/packages/react-query)

---
updated-dependencies:
- dependency-name: "@tanstack/react-query"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-28 10:53:04 +02:00
dependabot[bot]
8d44077b24 Bump ra-core from 5.3.0 to 5.3.1 (#109)
Bumps [ra-core](https://github.com/marmelab/react-admin) from 5.3.0 to 5.3.1.
- [Release notes](https://github.com/marmelab/react-admin/releases)
- [Changelog](https://github.com/marmelab/react-admin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/marmelab/react-admin/compare/v5.3.0...v5.3.1)

---
updated-dependencies:
- dependency-name: ra-core
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-28 10:52:37 +02:00
Aine
44e8b82412 Sanitize CSV on import (#101)
* Sanitize CSV on import

* update readme
2024-10-25 11:52:26 +03:00
Aine
791ae2c869 update naming 2024-10-24 21:49:00 +03:00
Aine
ee3753466a update manifest 2024-10-24 17:27:10 +03:00
Aine
b7dc703157 add community room to the footer 2024-10-24 14:17:02 +03:00
Aine
2eca0dcc33 better visual 2024-10-24 14:11:59 +03:00
Aine
d2219c1667 try adding community room to the readme 2024-10-24 14:11:23 +03:00
Aine
132ea6f97f add images 2024-10-24 13:44:12 +03:00
Aine
28ef08de03 Fix room state events display (#100)
* Fix room state events table display

* update readme
2024-10-23 13:48:21 +03:00
Aine
865e53388e fix yarn lint 2024-10-23 12:31:52 +03:00
dependabot[bot]
3a105bb8c7 Bump eslint from 8.57.1 to 9.13.0 (#99)
Bumps [eslint](https://github.com/eslint/eslint) from 8.57.1 to 9.13.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.57.1...v9.13.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-23 12:14:33 +03:00
dependabot[bot]
edcda7a202 Bump @mui/icons-material from 6.1.1 to 6.1.5 (#98)
Bumps [@mui/icons-material](https://github.com/mui/material-ui/tree/HEAD/packages/mui-icons-material) from 6.1.1 to 6.1.5.
- [Release notes](https://github.com/mui/material-ui/releases)
- [Changelog](https://github.com/mui/material-ui/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mui/material-ui/commits/v6.1.5/packages/mui-icons-material)

---
updated-dependencies:
- dependency-name: "@mui/icons-material"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-23 12:13:59 +03:00
dependabot[bot]
edd69273e2 Bump typescript-eslint from 8.10.0 to 8.11.0 (#88)
Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.10.0 to 8.11.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.11.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: typescript-eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-23 12:10:43 +03:00
dependabot[bot]
444bfacbd9 Bump eslint-plugin-unused-imports from 3.2.0 to 4.1.4 (#93)
Bumps [eslint-plugin-unused-imports](https://github.com/sweepline/eslint-plugin-unused-imports) from 3.2.0 to 4.1.4.
- [Commits](https://github.com/sweepline/eslint-plugin-unused-imports/commits/v4.1.4)

---
updated-dependencies:
- dependency-name: eslint-plugin-unused-imports
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-23 12:07:18 +03:00
dependabot[bot]
970e0a550f Bump @types/node from 22.7.7 to 22.7.9 (#91)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.7.7 to 22.7.9.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-23 12:06:41 +03:00
dependabot[bot]
b3ef68d66e Bump @types/jest from 29.5.13 to 29.5.14 (#95)
Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 29.5.13 to 29.5.14.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest)

---
updated-dependencies:
- dependency-name: "@types/jest"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-23 12:06:26 +03:00
dependabot[bot]
31382a42ee Bump @typescript-eslint/eslint-plugin from 8.10.0 to 8.11.0 (#92)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.10.0 to 8.11.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.11.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-23 12:06:11 +03:00
dependabot[bot]
1a7748d1ef Bump @vitejs/plugin-react from 4.3.2 to 4.3.3 (#87)
Bumps [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react) from 4.3.2 to 4.3.3.
- [Release notes](https://github.com/vitejs/vite-plugin-react/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-react/commits/v4.3.3/packages/plugin-react)

---
updated-dependencies:
- dependency-name: "@vitejs/plugin-react"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-23 12:05:51 +03:00
dependabot[bot]
039b28cc5c Bump vite from 5.4.6 to 5.4.10 (#89)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.4.6 to 5.4.10.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v5.4.10/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.4.10/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-23 12:03:42 +03:00
dependabot[bot]
57eae3edb3 Bump @mui/material from 6.1.1 to 6.1.5 (#94)
Bumps [@mui/material](https://github.com/mui/material-ui/tree/HEAD/packages/mui-material) from 6.1.1 to 6.1.5.
- [Release notes](https://github.com/mui/material-ui/releases)
- [Changelog](https://github.com/mui/material-ui/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mui/material-ui/commits/v6.1.5/packages/mui-material)

---
updated-dependencies:
- dependency-name: "@mui/material"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-23 12:03:20 +03:00
dependabot[bot]
dadc9416c0 Bump eslint-plugin-jsx-a11y from 6.10.0 to 6.10.1 (#97)
Bumps [eslint-plugin-jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y) from 6.10.0 to 6.10.1.
- [Release notes](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/releases)
- [Changelog](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/compare/v6.10.0...v6.10.1)

---
updated-dependencies:
- dependency-name: eslint-plugin-jsx-a11y
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-23 12:03:03 +03:00
dependabot[bot]
eab2342114 Bump @types/lodash from 4.17.7 to 4.17.12 (#96)
Bumps [@types/lodash](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/lodash) from 4.17.7 to 4.17.12.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/lodash)

---
updated-dependencies:
- dependency-name: "@types/lodash"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-23 12:02:40 +03:00
dependabot[bot]
9cf2f83936 Bump ra-language-french from 5.2.0 to 5.3.0 (#90)
Bumps [ra-language-french](https://github.com/marmelab/react-admin) from 5.2.0 to 5.3.0.
- [Release notes](https://github.com/marmelab/react-admin/releases)
- [Changelog](https://github.com/marmelab/react-admin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/marmelab/react-admin/compare/v5.2.0...v5.3.0)

---
updated-dependencies:
- dependency-name: ra-language-french
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-23 12:02:09 +03:00
dependabot[bot]
d823856873 Bump @typescript-eslint/parser from 8.10.0 to 8.11.0 (#86)
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.10.0 to 8.11.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.11.0/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-23 12:01:17 +03:00
dependabot[bot]
9b96c7cec8 Bump @eslint/js from 9.10.0 to 9.13.0 (#85)
Bumps [@eslint/js](https://github.com/eslint/eslint/tree/HEAD/packages/js) from 9.10.0 to 9.13.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/commits/v9.13.0/packages/js)

---
updated-dependencies:
- dependency-name: "@eslint/js"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-23 12:01:01 +03:00
dependabot[bot]
f211aba873 Bump @types/react from 18.3.8 to 18.3.12 (#84)
Bumps [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) from 18.3.8 to 18.3.12.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

---
updated-dependencies:
- dependency-name: "@types/react"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-23 12:00:50 +03:00
dependabot[bot]
c0fc2d8937 Bump @tanstack/react-query from 5.56.2 to 5.59.15 (#83)
Bumps [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) from 5.56.2 to 5.59.15.
- [Release notes](https://github.com/TanStack/query/releases)
- [Commits](https://github.com/TanStack/query/commits/v5.59.15/packages/react-query)

---
updated-dependencies:
- dependency-name: "@tanstack/react-query"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-23 12:00:37 +03:00
Aine
a88b397748 increase dependabot PR limits 2024-10-23 11:58:50 +03:00
Aine
abc922c956 Enable visual customization (#81)
* Enable visual customization

* update readme
2024-10-23 00:03:06 +03:00
Aine
4f2cd38344 Add user profile to the top menu (#80)
* Add user profile to the top menu

* update readme
2024-10-22 12:18:55 +03:00
Aine
ca71038874 Custom Menu Items (#79)
* Custom Menu Items

* update readme

* fix indentation
2024-10-21 23:33:51 +03:00
Borislav Pantaleev
be867b6b0d Fix types and missing translations (#78) 2024-10-21 19:37:29 +03:00
Aine
f2f540b429 fix footer content overlapping and scrollbar 2024-10-21 13:27:32 +03:00
Aine
7feec4ba07 update eslint typescript 2024-10-21 12:01:12 +03:00
Aine
1d5fef1e53 add missing package 2024-10-21 11:43:26 +03:00
dependabot[bot]
9c40efde17 Bump typescript-eslint from 7.18.0 to 8.10.0 (#76)
Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 7.18.0 to 8.10.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.10.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: typescript-eslint
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-21 11:34:26 +03:00
dependabot[bot]
53dff66978 Bump react-admin from 5.2.0 to 5.3.0 (#77)
Bumps [react-admin](https://github.com/marmelab/react-admin) from 5.2.0 to 5.3.0.
- [Release notes](https://github.com/marmelab/react-admin/releases)
- [Changelog](https://github.com/marmelab/react-admin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/marmelab/react-admin/compare/v5.2.0...v5.3.0)

---
updated-dependencies:
- dependency-name: react-admin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-21 11:31:09 +03:00
dependabot[bot]
3a595247e8 Bump vite-plugin-version-mark from 0.1.1 to 0.1.2 (#75)
Bumps [vite-plugin-version-mark](https://github.com/ZhongxuYang/vite-plugin-version-mark) from 0.1.1 to 0.1.2.
- [Release notes](https://github.com/ZhongxuYang/vite-plugin-version-mark/releases)
- [Changelog](https://github.com/ZhongxuYang/vite-plugin-version-mark/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ZhongxuYang/vite-plugin-version-mark/compare/v0.1.1...v0.1.2)

---
updated-dependencies:
- dependency-name: vite-plugin-version-mark
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-21 11:29:57 +03:00
dependabot[bot]
33f5f60e31 Bump eslint-plugin-import from 2.30.0 to 2.31.0 (#74)
Bumps [eslint-plugin-import](https://github.com/import-js/eslint-plugin-import) from 2.30.0 to 2.31.0.
- [Release notes](https://github.com/import-js/eslint-plugin-import/releases)
- [Changelog](https://github.com/import-js/eslint-plugin-import/blob/main/CHANGELOG.md)
- [Commits](https://github.com/import-js/eslint-plugin-import/compare/v2.30.0...v2.31.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-import
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-21 11:29:35 +03:00
dependabot[bot]
9dd2ea57c9 Bump @types/papaparse from 5.3.14 to 5.3.15 (#73)
Bumps [@types/papaparse](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/papaparse) from 5.3.14 to 5.3.15.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/papaparse)

---
updated-dependencies:
- dependency-name: "@types/papaparse"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-21 11:29:16 +03:00
dependabot[bot]
fae7a696de Bump ra-i18n-polyglot from 5.2.0 to 5.3.0 (#68)
Bumps [ra-i18n-polyglot](https://github.com/marmelab/react-admin) from 5.2.0 to 5.3.0.
- [Release notes](https://github.com/marmelab/react-admin/releases)
- [Changelog](https://github.com/marmelab/react-admin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/marmelab/react-admin/compare/v5.2.0...v5.3.0)

---
updated-dependencies:
- dependency-name: ra-i18n-polyglot
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-19 16:23:56 +03:00
dependabot[bot]
49e8b2d0f5 Bump vite-plugin-version-mark from 0.1.0 to 0.1.1 (#72)
Bumps [vite-plugin-version-mark](https://github.com/ZhongxuYang/vite-plugin-version-mark) from 0.1.0 to 0.1.1.
- [Release notes](https://github.com/ZhongxuYang/vite-plugin-version-mark/releases)
- [Changelog](https://github.com/ZhongxuYang/vite-plugin-version-mark/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ZhongxuYang/vite-plugin-version-mark/compare/v0.1.0...v0.1.1)

---
updated-dependencies:
- dependency-name: vite-plugin-version-mark
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-19 16:22:15 +03:00
dependabot[bot]
281d908d3f Bump ra-language-english from 5.2.0 to 5.3.0 (#71)
Bumps [ra-language-english](https://github.com/marmelab/react-admin) from 5.2.0 to 5.3.0.
- [Release notes](https://github.com/marmelab/react-admin/releases)
- [Changelog](https://github.com/marmelab/react-admin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/marmelab/react-admin/compare/v5.2.0...v5.3.0)

---
updated-dependencies:
- dependency-name: ra-language-english
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-19 16:21:57 +03:00
dependabot[bot]
bacc42fe9c Bump react-router-dom from 6.26.2 to 6.27.0 (#70)
Bumps [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) from 6.26.2 to 6.27.0.
- [Release notes](https://github.com/remix-run/react-router/releases)
- [Changelog](https://github.com/remix-run/react-router/blob/react-router-dom@6.27.0/packages/react-router-dom/CHANGELOG.md)
- [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@6.27.0/packages/react-router-dom)

---
updated-dependencies:
- dependency-name: react-router-dom
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-19 16:21:44 +03:00
dependabot[bot]
1c26a28ca9 Bump react-hook-form from 7.53.0 to 7.53.1 (#69)
Bumps [react-hook-form](https://github.com/react-hook-form/react-hook-form) from 7.53.0 to 7.53.1.
- [Release notes](https://github.com/react-hook-form/react-hook-form/releases)
- [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md)
- [Commits](https://github.com/react-hook-form/react-hook-form/compare/v7.53.0...v7.53.1)

---
updated-dependencies:
- dependency-name: react-hook-form
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-19 16:21:33 +03:00
dependabot[bot]
d3a04cd132 Bump @vitejs/plugin-react from 4.3.1 to 4.3.2 (#67)
Bumps [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react) from 4.3.1 to 4.3.2.
- [Release notes](https://github.com/vitejs/vite-plugin-react/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-react/commits/v4.3.2/packages/plugin-react)

---
updated-dependencies:
- dependency-name: "@vitejs/plugin-react"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-19 16:20:58 +03:00
dependabot[bot]
e6060a23ac Bump @types/node from 20.16.5 to 22.7.7 (#66)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.16.5 to 22.7.7.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-19 16:20:43 +03:00
dependabot[bot]
4b7fbf483a Bump typescript from 5.6.2 to 5.6.3 (#65)
Bumps [typescript](https://github.com/microsoft/TypeScript) from 5.6.2 to 5.6.3.
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml)
- [Commits](https://github.com/microsoft/TypeScript/compare/v5.6.2...v5.6.3)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-19 16:20:31 +03:00
dependabot[bot]
bc3c30da92 Bump @testing-library/jest-dom from 6.5.0 to 6.6.2 (#64)
Bumps [@testing-library/jest-dom](https://github.com/testing-library/jest-dom) from 6.5.0 to 6.6.2.
- [Release notes](https://github.com/testing-library/jest-dom/releases)
- [Changelog](https://github.com/testing-library/jest-dom/blob/main/CHANGELOG.md)
- [Commits](https://github.com/testing-library/jest-dom/compare/v6.5.0...v6.6.2)

---
updated-dependencies:
- dependency-name: "@testing-library/jest-dom"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-19 16:20:02 +03:00
dependabot[bot]
1896f770d1 Bump ra-core from 5.2.0 to 5.3.0 (#63)
Bumps [ra-core](https://github.com/marmelab/react-admin) from 5.2.0 to 5.3.0.
- [Release notes](https://github.com/marmelab/react-admin/releases)
- [Changelog](https://github.com/marmelab/react-admin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/marmelab/react-admin/compare/v5.2.0...v5.3.0)

---
updated-dependencies:
- dependency-name: ra-core
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-19 16:19:34 +03:00
dependabot[bot]
99d0b9ad72 Bump docker/setup-buildx-action from 1 to 3 (#62)
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 1 to 3.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v1...v3)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-19 16:19:06 +03:00
Aine
944afb9056 bring back dependabot config 2024-10-19 16:15:23 +03:00
Aine
23f5a24803 update README.md 2024-10-19 15:57:12 +03:00
Borislav Pantaleev
60ae00ac14 Add seprate login button for access token (#61) 2024-10-19 12:03:46 +00:00
Borislav Pantaleev
26862fa708 Add etke.cc to footer and package.json (#60)
* Add etke.cc to footer and package.json

* more links
2024-10-19 11:24:45 +03:00
Aine
853d14c1ce fix 'Sign in' button disabled on SSO-only servers when attempting access token login 2024-10-18 10:21:48 +03:00
jamazi
11a5cac709 Refactor required fields check on Bulk CSV upload (#59)
Related to https://github.com/etkecc/synapse-admin/pull/32
2024-10-17 22:56:19 +03:00
31 changed files with 1009 additions and 797 deletions

19
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,19 @@
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10

View File

@@ -25,10 +25,6 @@ jobs:
cache: yarn cache: yarn
- name: Install dependencies - name: Install dependencies
run: yarn install --immutable --network-timeout=300000 run: yarn install --immutable --network-timeout=300000
- name: Set version into manifest.json
run: |
TAG=$(git describe --tags --abbrev=0 || echo "latest")
sed -i "s|\"icons\"|\"version\": \"$TAG\",\\n \"icons\"|g" public/manifest.json
- name: Build - name: Build
run: yarn build --base=${{ env.base_path }} run: yarn build --base=${{ env.base_path }}
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
@@ -52,7 +48,7 @@ jobs:
name: dist name: dist
path: dist/ path: dist/
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v3
- name: Login to ghcr.io - name: Login to ghcr.io
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:

View File

@@ -1,4 +1,16 @@
# Synapse Admin UI [![GitHub license](https://img.shields.io/github/license/Awesome-Technologies/synapse-admin)](https://github.com/Awesome-Technologies/synapse-admin/blob/master/LICENSE) <p align="center">
<img alt="Synapse Admin Logo" src="./public/images/logo.webp" height="140" />
<h3 align="center">
Synapse Admin<br>
<a href="https://matrix.to/#/#synapse-admin:etke.cc">
<img alt="Community room" src="https://img.shields.io/badge/room-community_room-green?logo=matrix&label=%23synapse-admin%3Aetke.cc">
</a><br>
<img alt="License" src="https://img.shields.io/github/license/etkecc/synapse-admin">
</h3>
<p align="center">Manager your Synapse homeserver with ease</p>
</p>
---
![Screenshots](./screenshots.jpg) ![Screenshots](./screenshots.jpg)
@@ -13,6 +25,7 @@ This project is built using [react-admin](https://marmelab.com/react-admin/).
* [Configuration](#configuration) * [Configuration](#configuration)
* [Restricting available homeserver](#restricting-available-homeserver) * [Restricting available homeserver](#restricting-available-homeserver)
* [Protecting appservice managed users](#protecting-appservice-managed-users) * [Protecting appservice managed users](#protecting-appservice-managed-users)
* [Adding custom menu items](#adding-custom-menu-items)
* [Providing support URL](#providing-support-url) * [Providing support URL](#providing-support-url)
* [Usage](#usage) * [Usage](#usage)
* [Supported Synapse](#supported-synapse) * [Supported Synapse](#supported-synapse)
@@ -22,7 +35,7 @@ This project is built using [react-admin](https://marmelab.com/react-admin/).
* [Steps for 1)](#steps-for-1) * [Steps for 1)](#steps-for-1)
* [Steps for 2)](#steps-for-2) * [Steps for 2)](#steps-for-2)
* [Steps for 3)](#steps-for-3) * [Steps for 3)](#steps-for-3)
* [Serving Synapse-Admin on a different path](#serving-synapse-admin-on-a-different-path) * [Serving Synapse Admin on a different path](#serving-synapse-admin-on-a-different-path)
* [Development](#development-1) * [Development](#development-1)
<!-- vim-markdown-toc --> <!-- vim-markdown-toc -->
@@ -53,8 +66,9 @@ The following changes are already implemented:
* [Fix redirect URL after user creation](https://github.com/etkecc/synapse-admin/pull/16) * [Fix redirect URL after user creation](https://github.com/etkecc/synapse-admin/pull/16)
* [Display actual Synapse errors](https://github.com/etkecc/synapse-admin/pull/17) * [Display actual Synapse errors](https://github.com/etkecc/synapse-admin/pull/17)
* [Fix base_url being undefined on unsuccessful login](https://github.com/etkecc/synapse-admin/pull/18) * [Fix base_url being undefined on unsuccessful login](https://github.com/etkecc/synapse-admin/pull/18)
* [Put the version into manifest.json](https://github.com/Awesome-Technologies/synapse-admin/issues/507) (CI only) * [Put the version into manifest.json](https://github.com/Awesome-Technologies/synapse-admin/issues/507) (later replaced
* [Federation page improvements](https://github.com/Awesome-Technologies/synapse-admin/pull/583) (using theme colors) with a proper manifest.json generation on build)
* [Federation page improvements](https://github.com/Awesome-Technologies/synapse-admin/pull/583) (using icons)
* [Add UI option to block deleted rooms from being rejoined](https://github.com/etkecc/synapse-admin/pull/26) * [Add UI option to block deleted rooms from being rejoined](https://github.com/etkecc/synapse-admin/pull/26)
* [Fix required fields check on Bulk registration CSV upload](https://github.com/etkecc/synapse-admin/pull/32) * [Fix required fields check on Bulk registration CSV upload](https://github.com/etkecc/synapse-admin/pull/32)
* [Fix requests with invalid MXIDs on Bulk registration](https://github.com/etkecc/synapse-admin/pull/33) * [Fix requests with invalid MXIDs on Bulk registration](https://github.com/etkecc/synapse-admin/pull/33)
@@ -66,6 +80,12 @@ The following changes are already implemented:
* [Authenticated Media support](https://github.com/etkecc/synapse-admin/pull/51) * [Authenticated Media support](https://github.com/etkecc/synapse-admin/pull/51)
* [Better media preview/download](https://github.com/etkecc/synapse-admin/pull/53) * [Better media preview/download](https://github.com/etkecc/synapse-admin/pull/53)
* [Login with access token](https://github.com/etkecc/synapse-admin/pull/58) * [Login with access token](https://github.com/etkecc/synapse-admin/pull/58)
* [Fix footer causing vertical scrollbar](https://github.com/etkecc/synapse-admin/pull/60)
* [Custom Menu Items](https://github.com/etkecc/synapse-admin/pull/79)
* [Add user profile to the top menu](https://github.com/etkecc/synapse-admin/pull/80)
* [Enable visual customization](https://github.com/etkecc/synapse-admin/pull/81)
* [Fix room state events display](https://github.com/etkecc/synapse-admin/pull/100)
* [Sanitize CSV on import](https://github.com/etkecc/synapse-admin/pull/101)
_the list will be updated as new changes are added_ _the list will be updated as new changes are added_
@@ -128,9 +148,29 @@ Example for [mautrix-telegram](https://github.com/mautrix/telegram)
} }
``` ```
### Adding custom menu items
You can add custom menu items to the main menu by providing a `menu` array in the `config.json`.
```json
{
"menu": [
{
"label": "Contact support",
"icon": "SupportAgent",
"url": "https://github.com/etkecc/synapse-admin/issues"
}
]
}
```
Where `icon` is one of the [preloaded icons](./src/components/icons.ts)
### Providing support URL ### Providing support URL
Synapse-Admin provides a support link in the main menu - `Contact support`. By default, the link points to the GitHub issues page of the project. You can change this link by providing a `supportURL` in the `config.json`. **Deprecated**: use `menu` config option described above. Automatically migrated to the `menu` if the `supportURL` is present.
~~Synapse Admin provides a support link in the main menu - `Contact support`. By default, the link points to the GitHub issues page of the project. You can change this link by providing a `supportURL` in the `config.json`.~~
```json ```json
{ {
@@ -217,7 +257,7 @@ You have three options:
- browse to http://localhost:8080 - browse to http://localhost:8080
### Serving Synapse-Admin on a different path ### Serving Synapse Admin on a different path
The path prefix where synapse-admin is served can only be changed during the build step. The path prefix where synapse-admin is served can only be changed during the build step.
@@ -225,7 +265,7 @@ If you downloaded the source code, use `yarn build --base=/my-prefix` to set a p
If you want to build your own Docker container, use the `BASE_PATH` argument. If you want to build your own Docker container, use the `BASE_PATH` argument.
We do not support directly changing the path where Synapse-Admin is served in the pre-built Docker container. Instead please use a reverse proxy if you need to move Synapse-Admin to a different base path. If you want to serve multiple applications with different paths on the same domain, you need a reverse proxy anyway. We do not support directly changing the path where Synapse Admin is served in the pre-built Docker container. Instead please use a reverse proxy if you need to move Synapse Admin to a different base path. If you want to serve multiple applications with different paths on the same domain, you need a reverse proxy anyway.
Example for Traefik: Example for Traefik:

View File

@@ -4,17 +4,14 @@
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" /> <meta name="theme-color" content="#000000" />
<meta <meta name="description" content="Synapse Admin" />
name="description"
content="Synapse-Admin"
/>
<!-- <!--
manifest.json provides metadata used when your web app is installed on a manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
--> -->
<link rel="manifest" href="./manifest.json" /> <link rel="manifest" href="./manifest.json" />
<link rel="shortcut icon" href="./favicon.ico" /> <link rel="shortcut icon" href="./favicon.ico" />
<title>Synapse-Admin</title> <title>Synapse Admin</title>
<style> <style>
body { body {
margin: 0; margin: 0;
@@ -22,6 +19,11 @@
font-family: sans-serif; font-family: sans-serif;
} }
.layout {
min-height: 90vh !important;
height: 90vh;
}
.loader-container { .loader-container {
display: flex; display: flex;
align-items: center; align-items: center;
@@ -120,13 +122,7 @@
</div> </div>
</div> </div>
<script type="module" src="/src/index.tsx"></script> <script type="module" src="/src/index.tsx"></script>
<footer <span id="js-version" style="display: none;"></span>
style="position: relative; z-index: 2; height: 2em; margin-top: 0; line-height: 2em; background-color: #eee; border: 0.5px solid #ddd">
<a id="copyright" href="https://github.com/etkecc/synapse-admin"
style="margin-left: 1em; color: #888; font-family: Roboto, Helvetica, Arial, sans-serif; font-weight: 100; font-size: 0.8em; text-decoration: none;">
Synapse-Admin <b><span id="version"></span></b> by Awesome Technologies Innovationslabor GmbH
</a>
</footer>
</body> </body>
<script>document.getElementById("version").textContent = __SYNAPSE_ADMIN_VERSION__</script> <script>document.getElementById("js-version").textContent = __SYNAPSE_ADMIN_VERSION__</script>
</html> </html>

View File

@@ -3,7 +3,7 @@
"version": "0.10.3", "version": "0.10.3",
"description": "Admin GUI for the Matrix.org server Synapse", "description": "Admin GUI for the Matrix.org server Synapse",
"type": "module", "type": "module",
"author": "Awesome Technologies Innovationslabor GmbH", "author": "etke.cc (originally by Awesome Technologies Innovationslabor GmbH)",
"license": "Apache-2.0", "license": "Apache-2.0",
"homepage": ".", "homepage": ".",
"repository": { "repository": {
@@ -11,25 +11,25 @@
"url": "https://github.com/etkecc/synapse-admin" "url": "https://github.com/etkecc/synapse-admin"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.7.0", "@eslint/js": "^9.13.0",
"@testing-library/dom": "^10.0.0", "@testing-library/dom": "^10.0.0",
"@testing-library/jest-dom": "^6.0.0", "@testing-library/jest-dom": "^6.6.2",
"@testing-library/react": "^16.0.0", "@testing-library/react": "^16.0.0",
"@testing-library/user-event": "^14.5.2", "@testing-library/user-event": "^14.5.2",
"@types/jest": "^29.5.13", "@types/jest": "^29.5.14",
"@types/lodash": "^4.17.7", "@types/lodash": "^4.17.12",
"@types/node": "^20.14.12", "@types/node": "^22.8.1",
"@types/papaparse": "^5.3.14", "@types/papaparse": "^5.3.15",
"@types/react": "^18.3.3", "@types/react": "^18.3.12",
"@typescript-eslint/eslint-plugin": "^7.16.1", "@typescript-eslint/eslint-plugin": "^8.11.0",
"@typescript-eslint/parser": "^7.16.1", "@typescript-eslint/parser": "^8.11.0",
"@vitejs/plugin-react": "^4.3.1", "@vitejs/plugin-react": "^4.3.3",
"eslint": "^8.57.0", "eslint": "^9.13.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.29.1", "eslint-plugin-import": "^2.31.0",
"eslint-plugin-jsx-a11y": "^6.9.0", "eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-prettier": "^5.2.1", "eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-unused-imports": "^3.2.0", "eslint-plugin-unused-imports": "^4.1.4",
"eslint-plugin-yaml": "^1.0.3", "eslint-plugin-yaml": "^1.0.3",
"jest": "^29.7.0", "jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0", "jest-environment-jsdom": "^29.7.0",
@@ -38,41 +38,42 @@
"react-test-renderer": "^18.3.1", "react-test-renderer": "^18.3.1",
"ts-jest": "^29.2.5", "ts-jest": "^29.2.5",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typescript": "^5.4.5", "typescript": "^5.6.3",
"typescript-eslint": "^7.16.1", "typescript-eslint": "^8.11.0",
"vite": "^5.4.6", "vite": "^5.4.10",
"vite-plugin-version-mark": "^0.1.0" "vite-plugin-version-mark": "^0.1.2"
}, },
"dependencies": { "dependencies": {
"@emotion/react": "^11.13.0", "@emotion/react": "^11.13.0",
"@emotion/styled": "^11.13.0", "@emotion/styled": "^11.13.0",
"@haleos/ra-language-german": "^1.0.0", "@haleos/ra-language-german": "^1.0.0",
"@haxqer/ra-language-chinese": "^4.16.2", "@haxqer/ra-language-chinese": "^4.16.2",
"@mui/icons-material": "^6.1.1", "@mui/icons-material": "^6.1.5",
"@mui/material": "^6.1.1", "@mui/material": "^6.1.5",
"@tanstack/react-query": "^5.56.2", "@mui/utils": "^5.16.6",
"@tanstack/react-query": "^5.59.16",
"history": "^5.3.0", "history": "^5.3.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"papaparse": "^5.4.1", "papaparse": "^5.4.1",
"ra-core": "^5.2.0", "ra-core": "^5.3.1",
"ra-i18n-polyglot": "^5.2.0", "ra-i18n-polyglot": "^5.3.0",
"ra-language-english": "^5.2.0", "ra-language-english": "^5.3.1",
"ra-language-farsi": "^5.0.0", "ra-language-farsi": "^5.0.0",
"ra-language-french": "^5.2.0", "ra-language-french": "^5.3.1",
"ra-language-italian": "^3.13.1", "ra-language-italian": "^3.13.1",
"ra-language-russian": "^4.14.2", "ra-language-russian": "^4.14.2",
"react": "^18.3.1", "react": "^18.3.1",
"react-admin": "^5.2.0", "react-admin": "^5.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"react-hook-form": "^7.53.0", "react-hook-form": "^7.53.1",
"react-is": "^18.3.1", "react-is": "^18.3.1",
"react-router": "^6.26.2", "react-router": "^6.26.2",
"react-router-dom": "^6.26.2" "react-router-dom": "^6.27.0"
}, },
"scripts": { "scripts": {
"start": "vite serve", "start": "vite serve",
"build": "vite build", "build": "vite build",
"lint": "eslint --ignore-path .gitignore --ext .ts,.tsx,.yml,.yaml .", "lint": "ESLINT_USE_FLAT_CONFIG=false eslint --ignore-path .gitignore --ignore-pattern testdata/ --ext .ts,.tsx,.yml,.yaml .",
"fix": "yarn lint --fix", "fix": "yarn lint --fix",
"test": "yarn jest", "test": "yarn jest",
"test:watch": "yarn jest --watch" "test:watch": "yarn jest --watch"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
public/images/logo.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -1,15 +0,0 @@
{
"short_name": "Synapse-Admin",
"name": "Synapse-Admin",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

View File

@@ -1,4 +1,4 @@
import { render, screen, waitFor } from "@testing-library/react"; import { render, screen } from "@testing-library/react";
import fetchMock from "jest-fetch-mock"; import fetchMock from "jest-fetch-mock";
fetchMock.enableMocks(); fetchMock.enableMocks();
@@ -9,4 +9,4 @@ describe("App", () => {
render(<App />); render(<App />);
await screen.findAllByText("Welcome to Synapse-admin"); await screen.findAllByText("Welcome to Synapse-admin");
}); });
}); });

View File

@@ -23,6 +23,7 @@ import users from "./resources/users";
import authProvider from "./synapse/authProvider"; import authProvider from "./synapse/authProvider";
import dataProvider from "./synapse/dataProvider"; import dataProvider from "./synapse/dataProvider";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import Footer from "./components/Footer";
// TODO: Can we use lazy loading together with browser locale? // TODO: Can we use lazy loading together with browser locale?
const messages = { const messages = {
@@ -81,6 +82,7 @@ const App = () => (
<Resource name="room_state" /> <Resource name="room_state" />
<Resource name="destination_rooms" /> <Resource name="destination_rooms" />
</Admin> </Admin>
<Footer />
</QueryClientProvider> </QueryClientProvider>
); );

View File

@@ -4,6 +4,13 @@ interface AppContextType {
restrictBaseUrl: string | string[]; restrictBaseUrl: string | string[];
asManagedUsers: string[]; asManagedUsers: string[];
supportURL: string; supportURL: string;
menu: MenuItem[];
}
interface MenuItem {
label: string;
icon: string;
url: string;
} }
export const AppContext = createContext({}); export const AppContext = createContext({});

View File

@@ -1,17 +1,7 @@
import { AppBar, Confirm, Layout, Logout, Menu, useLogout, UserMenu } from "react-admin"; import { AppBar, TitlePortal, InspectorButton, Confirm, Layout, Logout, Menu, useLogout, UserMenu } from "react-admin";
import LiveHelpIcon from "@mui/icons-material/LiveHelp";
import { LoginMethod } from "../pages/LoginPage"; import { LoginMethod } from "../pages/LoginPage";
import { useState } from "react"; import { useEffect, useState, Suspense } from "react";
import { Icons, DefaultIcon } from "./icons";
const DEFAULT_SUPPORT_LINK = "https://github.com/etkecc/synapse-admin/issues";
const supportLink = (): string => {
try {
new URL(localStorage.getItem("support_url") || ""); // Check if the URL is valid
return localStorage.getItem("support_url") || DEFAULT_SUPPORT_LINK;
} catch (e) {
return DEFAULT_SUPPORT_LINK;
}
};
const AdminUserMenu = () => { const AdminUserMenu = () => {
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
@@ -54,17 +44,60 @@ const AdminUserMenu = () => {
); );
}; };
const AdminAppBar = () => <AppBar userMenu={<AdminUserMenu />} />; const AdminAppBar = () => {
return (<AppBar userMenu={<AdminUserMenu />}>
<TitlePortal />
<InspectorButton />
</AppBar>);
};
const AdminMenu = () => ( const AdminMenu = (props) => {
<Menu> const [menu, setMenu] = useState([]);
<Menu.ResourceItems />
<Menu.Item to={supportLink()} target="_blank" primaryText="Contact support" leftIcon={<LiveHelpIcon />} /> useEffect(() => {
</Menu> const menuConfig = localStorage.getItem('menu');
); if (menuConfig) {
try {
setMenu(JSON.parse(menuConfig));
} catch (e) {
console.error('Error parsing menu configuration', e);
}
}
}, []);
return (
<Menu {...props}>
<Menu.ResourceItems />
{menu.map((item, index) => {
const { url, icon, label } = item;
const IconComponent = Icons[icon] as React.ComponentType<any> | undefined;
return (
<Suspense key={index}>
<Menu.Item
to={url}
target="_blank"
primaryText={label}
leftIcon={IconComponent ? <IconComponent /> : <DefaultIcon />}
onClick={props.onMenuClick}
/>
</Suspense>
);
})}
</Menu>
);
};
export const AdminLayout = ({ children }) => ( export const AdminLayout = ({ children }) => (
<Layout appBar={AdminAppBar} menu={AdminMenu}> <Layout appBar={AdminAppBar} menu={AdminMenu} sx={{
['& .RaLayout-appFrame']: {
minHeight: '90vh',
height: '90vh',
},
['& .RaLayout-content']: {
marginBottom: '3rem',
},
}}>
{children} {children}
</Layout> </Layout>
); );

41
src/components/Footer.tsx Normal file
View File

@@ -0,0 +1,41 @@
import { Avatar, Box, Link, Typography } from "@mui/material";
import { useEffect, useState } from "react";
const Footer = () => {
const [version, setVersion] = useState<string | null>(null);
useEffect(() => {
const version = document.getElementById("js-version")?.textContent;
if (version) {
setVersion(version);
}
}, []);
return (<Box
component="footer"
sx={{
position: 'fixed',
zIndex: 100,
bottom: 0,
width: '100%',
bgcolor: "#eee",
borderTop: '1px solid',
borderColor: '#ddd',
p: 1,
}}>
<Typography variant="body2">
<Avatar src="./images/logo.webp" sx={{ width: "1rem", height: "1rem", display: "inline-block", verticalAlign: "sub" }} />
<Link sx={{ color: "#888", textDecoration: 'none' }} href="https://github.com/etkecc/synapse-admin" target="_blank">
Synapse Admin
</Link> <Link href={`https://github.com/etkecc/synapse-admin/releases/tag/`+version} target="_blank">
<span style={{ fontWeight: 'bold', color: "#000" }}>{version}</span>
</Link> <Link sx={{ color: "#888", textDecoration: 'none' }} href="https://etke.cc/?utm_source=synapse-admin&utm_medium=footer&utm_campaign=synapse-admin" target="_blank">
by etke.cc
</Link> <Link sx={{ color: "#888", textDecoration: 'none' }} href="https://github.com/awesome-technologies/synapse-admin" target="_blank">
(originally developed by Awesome Technologies Innovationslabor GmbH).
</Link> <Link sx={{ fontWeight: 'bold', color: "#000", textDecoration: 'none' }} href="https://matrix.to/#/#synapse-admin:etke.cc" target="_blank">#synapse-admin:etke.cc</Link>
</Typography>
</Box>
);
};
export default Footer;

View File

@@ -121,11 +121,8 @@ const FilePicker = () => {
const verifyCsv = ({ data, meta, errors }: ParseResult<ImportLine>, { setValues, setStats, setError }) => { const verifyCsv = ({ data, meta, errors }: ParseResult<ImportLine>, { setValues, setStats, setError }) => {
/* First, verify the presence of required fields */ /* First, verify the presence of required fields */
const missingFields = expectedFields.filter(eF => { meta.fields = meta.fields?.map(f => f.trim().toLowerCase());
const result = meta.fields?.find(mF => eF === mF); const missingFields = expectedFields.filter(eF => !meta.fields?.find(mF => eF === mF));
if (result === undefined) { return eF; } // missing field
return undefined; // field found
});
if (missingFields.length > 0) { if (missingFields.length > 0) {
setError(translate("import_users.error.required_field", { field: missingFields[0] })); setError(translate("import_users.error.required_field", { field: missingFields[0] }));
@@ -151,6 +148,15 @@ const FilePicker = () => {
}; };
const errorMessages = errors.map(e => e.message); const errorMessages = errors.map(e => e.message);
// sanitize the data first
data = data.map(line => {
const newLine = {} as ImportLine;
for (const [key, value] of Object.entries(line)) {
newLine[key.trim().toLowerCase()] = value;
}
return newLine;
});
// process the data
data.forEach((line, idx) => { data.forEach((line, idx) => {
if (line.user_type === undefined || line.user_type === "") { if (line.user_type === undefined || line.user_type === "") {
stats.user_types.default++; stats.user_types.default++;
@@ -177,6 +183,7 @@ const FilePicker = () => {
line[f] = true; // we need true booleans instead of strings line[f] = true; // we need true booleans instead of strings
} else { } else {
if (line[f] !== "false" && line[f] !== "") { if (line[f] !== "false" && line[f] !== "") {
console.log("invalid value", line[f], "for field " + f + " in row " + idx);
errorMessages.push( errorMessages.push(
translate("import_users.error.invalid_value", { translate("import_users.error.invalid_value", {
field: f, field: f,

12
src/components/icons.ts Normal file
View File

@@ -0,0 +1,12 @@
import { lazy } from "react";
export const Icons = {
Announcement: lazy(() => import('@mui/icons-material/Announcement')),
Engineering: lazy(() => import('@mui/icons-material/Engineering')),
HelpCenter: lazy(() => import('@mui/icons-material/HelpCenter')),
SupportAgent: lazy(() => import('@mui/icons-material/SupportAgent')),
Default: lazy(() => import('@mui/icons-material/OpenInNew')),
// Add more icons as needed
};
export const DefaultIcon = Icons.Default;

View File

@@ -2,7 +2,7 @@ import { formalGermanMessages } from "@haleos/ra-language-german";
import { SynapseTranslationMessages } from "."; import { SynapseTranslationMessages } from ".";
const de: SynapseTranslationMessages = { const fixedGermanMessages = {
...formalGermanMessages, ...formalGermanMessages,
ra: { ra: {
...formalGermanMessages.ra, ...formalGermanMessages.ra,
@@ -10,8 +10,30 @@ const de: SynapseTranslationMessages = {
...formalGermanMessages.ra.navigation, ...formalGermanMessages.ra.navigation,
no_filtered_results: "Keine Ergebnisse", no_filtered_results: "Keine Ergebnisse",
clear_filters: "Alle Filter entfernen", clear_filters: "Alle Filter entfernen",
add_filter: "Filter hinzufügen",
},
action: {
...formalGermanMessages.ra.action,
update_application: "Anwendung aktualisieren",
},
page: {
...formalGermanMessages.ra.page,
empty: "Leer",
access_denied: "Zugriff verweigert",
authentication_error: "Authentifizierungsfehler",
},
message: {
...formalGermanMessages.ra.message,
access_denied:
"Sie haben nicht die richtigen Berechtigungen um auf diese Seite zuzugreifen.",
authentication_error:
"Der Authentifizierungsserver hat einen Fehler zurückgegeben und Ihre Anmeldedaten konnten nicht überprüft werden.",
}, },
}, },
}
const de: SynapseTranslationMessages = {
...fixedGermanMessages,
synapseadmin: { synapseadmin: {
auth: { auth: {
base_url: "Heimserver URL", base_url: "Heimserver URL",

View File

@@ -2,7 +2,7 @@ import russianMessages from "ra-language-russian";
import { SynapseTranslationMessages } from "."; import { SynapseTranslationMessages } from ".";
const ru: SynapseTranslationMessages = { const fixedRussianMessages = {
...russianMessages, ...russianMessages,
ra: { ra: {
...russianMessages.ra, ...russianMessages.ra,
@@ -11,7 +11,24 @@ const ru: SynapseTranslationMessages = {
no_filtered_results: "Нет результатов", no_filtered_results: "Нет результатов",
clear_filters: "Все фильтры сбросить", clear_filters: "Все фильтры сбросить",
}, },
page: {
...russianMessages.ra.page,
empty: "Пусто",
access_denied: "Доступ запрещен",
authentication_error: "Ошибка аутентификации",
},
message: {
...russianMessages.ra.message,
access_denied:
"У вас нет прав доступа к этой странице.",
authentication_error:
"Сервер аутентификации вернул ошибку и не смог проверить ваши учетные данные.",
},
}, },
}
const ru: SynapseTranslationMessages = {
...fixedRussianMessages,
synapseadmin: { synapseadmin: {
auth: { auth: {
base_url: "Адрес домашнего сервера", base_url: "Адрес домашнего сервера",

View File

@@ -2,7 +2,7 @@ import chineseMessages from "@haxqer/ra-language-chinese";
import { SynapseTranslationMessages } from "."; import { SynapseTranslationMessages } from ".";
const zh: SynapseTranslationMessages = { const fixedChineseMessages = {
...chineseMessages, ...chineseMessages,
ra: { ra: {
...chineseMessages.ra, ...chineseMessages.ra,
@@ -11,7 +11,27 @@ const zh: SynapseTranslationMessages = {
no_filtered_results: "没有结果", no_filtered_results: "没有结果",
clear_filters: "清除所有过滤器", clear_filters: "清除所有过滤器",
}, },
action: {
...chineseMessages.ra.action,
update_application: "Anwendung aktualisieren",
},
page: {
...chineseMessages.ra.page,
access_denied: "拒绝访问",
authentication_error: "认证错误",
},
message: {
...chineseMessages.ra.message,
access_denied:
"您没有访问此页面的权限。",
authentication_error:
"身份验证服务器返回错误,无法验证您的凭据。",
},
}, },
}
const zh: SynapseTranslationMessages = {
...fixedChineseMessages,
synapseadmin: { synapseadmin: {
auth: { auth: {
base_url: "服务器 URL", base_url: "服务器 URL",

View File

@@ -3,7 +3,7 @@ import React from "react";
import { createRoot } from "react-dom/client"; import { createRoot } from "react-dom/client";
import App from "./App"; import App from "./App";
import { AppContext } from "./AppContext"; import { AppContext, MenuItem } from "./AppContext";
import storage from "./storage"; import storage from "./storage";
fetch("config.json") fetch("config.json")
@@ -12,9 +12,24 @@ fetch("config.json")
if (props.asManagedUsers) { if (props.asManagedUsers) {
storage.setItem("as_managed_users", JSON.stringify(props.asManagedUsers)); storage.setItem("as_managed_users", JSON.stringify(props.asManagedUsers));
} }
if (props.supportURL) {
storage.setItem("support_url", props.supportURL); let menu: MenuItem[] = [];
if (props.menu) {
menu = props.menu;
} }
if (props.supportURL) {
const migratedSupportURL = {
label: "Contact support",
icon: "SupportAgent",
url: props.supportURL,
};
console.warn("supportURL config option is deprecated. Please, use the menu option instead. Automatically migrated to the new menu option:", migratedSupportURL);
menu.push(migratedSupportURL as MenuItem);
}
if (menu.length > 0) {
storage.setItem("menu", JSON.stringify(menu));
}
return createRoot(document.getElementById("root")).render( return createRoot(document.getElementById("root")).render(
<React.StrictMode> <React.StrictMode>
<AppContext.Provider value={props}> <AppContext.Provider value={props}>

View File

@@ -1,6 +1,5 @@
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import LockIcon from "@mui/icons-material/Lock";
import { Avatar, Box, Button, Card, CardActions, CircularProgress, MenuItem, Select, Tab, Tabs, Typography } from "@mui/material"; import { Avatar, Box, Button, Card, CardActions, CircularProgress, MenuItem, Select, Tab, Tabs, Typography } from "@mui/material";
import { import {
Form, Form,
@@ -249,9 +248,7 @@ const LoginPage = () => {
{loading ? ( {loading ? (
<CircularProgress size={25} thickness={2} /> <CircularProgress size={25} thickness={2} />
) : ( ) : (
<Avatar className="icon"> <Avatar sx={{ width: "120px", height: "120px" }} src="./images/logo.webp"/>
<LockIcon />
</Avatar>
)} )}
</Box> </Box>
<Box className="hint">{translate("synapseadmin.auth.welcome")}</Box> <Box className="hint">{translate("synapseadmin.auth.welcome")}</Box>
@@ -270,7 +267,7 @@ const LoginPage = () => {
))} ))}
</Select> </Select>
<FormDataConsumer>{formDataProps => <UserData {...formDataProps} />}</FormDataConsumer> <FormDataConsumer>{formDataProps => <UserData {...formDataProps} />}</FormDataConsumer>
<CardActions className="actions"> {loginMethod === "credentials" && <CardActions className="actions">
<Button <Button
variant="contained" variant="contained"
type="submit" type="submit"
@@ -289,7 +286,18 @@ const LoginPage = () => {
> >
{translate("synapseadmin.auth.sso_sign_in")} {translate("synapseadmin.auth.sso_sign_in")}
</Button> </Button>
</CardActions> </CardActions>}
{loginMethod === "accessToken" && <CardActions className="actions">
<Button
variant="contained"
type="submit"
color="primary"
disabled={loading}
fullWidth
>
{translate("ra.auth.sign_in")}
</Button>
</CardActions>}
</Box> </Box>
</Card> </Card>
</LoginFormBox> </LoginFormBox>

View File

@@ -8,6 +8,7 @@ import ErrorIcon from '@mui/icons-material/Error';
import { import {
Button, Button,
Datagrid, Datagrid,
DatagridConfigurable,
DateField, DateField,
List, List,
ListProps, ListProps,
@@ -123,14 +124,14 @@ export const DestinationList = (props: ListProps) => {
pagination={<DestinationPagination />} pagination={<DestinationPagination />}
sort={{ field: "destination", order: "ASC" }} sort={{ field: "destination", order: "ASC" }}
> >
<Datagrid rowClick={id => `${id}/show/rooms`} bulkActionButtons={false}> <DatagridConfigurable rowClick={id => `${id}/show/rooms`} bulkActionButtons={false}>
<FunctionField source="destination" render={destinationFieldRender} /> <FunctionField source="destination" render={destinationFieldRender} />
<DateField source="failure_ts" showTime options={DATE_FORMAT} /> <DateField source="failure_ts" showTime options={DATE_FORMAT} />
<RetryDateField source="retry_last_ts" showTime options={DATE_FORMAT} /> <RetryDateField source="retry_last_ts" showTime options={DATE_FORMAT} />
<TextField source="retry_interval" /> <TextField source="retry_interval" />
<TextField source="last_successful_stream_ordering" /> <TextField source="last_successful_stream_ordering" />
<DestinationReconnectButton /> <DestinationReconnectButton />
</Datagrid> </DatagridConfigurable>
</List> </List>
); );
}; };

View File

@@ -4,6 +4,7 @@ import {
Create, Create,
CreateProps, CreateProps,
Datagrid, Datagrid,
DatagridConfigurable,
DateField, DateField,
DateTimeInput, DateTimeInput,
Edit, Edit,
@@ -39,13 +40,13 @@ export const RegistrationTokenList = (props: ListProps) => (
pagination={false} pagination={false}
perPage={500} perPage={500}
> >
<Datagrid rowClick="edit"> <DatagridConfigurable rowClick="edit">
<TextField source="token" sortable={false} /> <TextField source="token" sortable={false} />
<NumberField source="uses_allowed" sortable={false} /> <NumberField source="uses_allowed" sortable={false} />
<NumberField source="pending" sortable={false} /> <NumberField source="pending" sortable={false} />
<NumberField source="completed" sortable={false} /> <NumberField source="completed" sortable={false} />
<DateField source="expiry_time" showTime options={DATE_FORMAT} sortable={false} /> <DateField source="expiry_time" showTime options={DATE_FORMAT} sortable={false} />
</Datagrid> </DatagridConfigurable>
</List> </List>
); );

View File

@@ -3,6 +3,7 @@ import ViewListIcon from "@mui/icons-material/ViewList";
import ReportIcon from "@mui/icons-material/Warning"; import ReportIcon from "@mui/icons-material/Warning";
import { import {
Datagrid, Datagrid,
DatagridConfigurable,
DateField, DateField,
DeleteButton, DeleteButton,
List, List,
@@ -90,13 +91,13 @@ const ReportShowActions = () => {
export const ReportList = (props: ListProps) => ( export const ReportList = (props: ListProps) => (
<List {...props} pagination={<ReportPagination />} sort={{ field: "received_ts", order: "DESC" }}> <List {...props} pagination={<ReportPagination />} sort={{ field: "received_ts", order: "DESC" }}>
<Datagrid rowClick="show" bulkActionButtons={false}> <DatagridConfigurable rowClick="show" bulkActionButtons={false}>
<TextField source="id" sortable={false} /> <TextField source="id" sortable={false} />
<DateField source="received_ts" showTime options={DATE_FORMAT} sortable={true} /> <DateField source="received_ts" showTime options={DATE_FORMAT} sortable={true} />
<TextField sortable={false} source="user_id" /> <TextField sortable={false} source="user_id" />
<TextField sortable={false} source="name" /> <TextField sortable={false} source="name" />
<TextField sortable={false} source="score" /> <TextField sortable={false} source="score" />
</Datagrid> </DatagridConfigurable>
</List> </List>
); );

View File

@@ -187,7 +187,7 @@ export const RoomShow = (props: ShowProps) => {
<Datagrid style={{ width: "100%" }} bulkActionButtons={false}> <Datagrid style={{ width: "100%" }} bulkActionButtons={false}>
<TextField source="type" sortable={false} /> <TextField source="type" sortable={false} />
<DateField source="origin_server_ts" showTime options={DATE_FORMAT} sortable={false} /> <DateField source="origin_server_ts" showTime options={DATE_FORMAT} sortable={false} />
<TextField source="content" sortable={false} /> <FunctionField source="content" sortable={false} render={record => `${JSON.stringify(record.content, null, 2)}`} />
<ReferenceField source="sender" reference="users" sortable={false}> <ReferenceField source="sender" reference="users" sortable={false}>
<TextField source="id" /> <TextField source="id" />
</ReferenceField> </ReferenceField>

View File

@@ -1,6 +1,7 @@
import PermMediaIcon from "@mui/icons-material/PermMedia"; import PermMediaIcon from "@mui/icons-material/PermMedia";
import { import {
Datagrid, Datagrid,
DatagridConfigurable,
ExportButton, ExportButton,
List, List,
ListProps, ListProps,
@@ -37,12 +38,12 @@ export const UserMediaStatsList = (props: ListProps) => (
pagination={<UserMediaStatsPagination />} pagination={<UserMediaStatsPagination />}
sort={{ field: "media_length", order: "DESC" }} sort={{ field: "media_length", order: "DESC" }}
> >
<Datagrid rowClick={id => "/users/" + id + "/media"} bulkActionButtons={false}> <DatagridConfigurable rowClick={id => "/users/" + id + "/media"} bulkActionButtons={false}>
<TextField source="user_id" label="resources.users.fields.id" /> <TextField source="user_id" label="resources.users.fields.id" />
<TextField source="displayname" label="resources.users.fields.displayname" /> <TextField source="displayname" label="resources.users.fields.displayname" />
<NumberField source="media_count" /> <NumberField source="media_count" />
<NumberField source="media_length" /> <NumberField source="media_length" />
</Datagrid> </DatagridConfigurable>
</List> </List>
); );

View File

@@ -15,6 +15,7 @@ import {
ArrayField, ArrayField,
Button, Button,
Datagrid, Datagrid,
DatagridConfigurable,
DateField, DateField,
Create, Create,
CreateProps, CreateProps,
@@ -156,7 +157,7 @@ export const UserList = (props: ListProps) => (
actions={<UserListActions />} actions={<UserListActions />}
pagination={<UserPagination />} pagination={<UserPagination />}
> >
<Datagrid <DatagridConfigurable
rowClick={(id: Identifier, resource: string) => `/${resource}/${id}`} rowClick={(id: Identifier, resource: string) => `/${resource}/${id}`}
bulkActionButtons={<UserBulkActionButtons />} bulkActionButtons={<UserBulkActionButtons />}
> >
@@ -169,7 +170,7 @@ export const UserList = (props: ListProps) => (
<BooleanField source="locked" /> <BooleanField source="locked" />
<BooleanField source="erased" sortable={false} /> <BooleanField source="erased" sortable={false} />
<DateField source="creation_ts" label="resources.users.fields.creation_ts_ms" showTime options={DATE_FORMAT} /> <DateField source="creation_ts" label="resources.users.fields.creation_ts_ms" showTime options={DATE_FORMAT} />
</Datagrid> </DatagridConfigurable>
</List> </List>
); );

View File

@@ -30,7 +30,7 @@ describe("authProvider", () => {
}); });
expect(ret).toEqual({redirectTo: "/"}); expect(ret).toEqual({redirectTo: "/"});
expect(fetch).toBeCalledWith("http://example.com/_matrix/client/r0/login", { expect(fetch).toHaveBeenCalledWith("http://example.com/_matrix/client/v3/login", {
body: '{"device_id":null,"initial_device_display_name":"Synapse Admin","type":"m.login.password","identifier":{"type":"m.id.user","user":"@user:example.com"},"password":"secret"}', body: '{"device_id":null,"initial_device_display_name":"Synapse Admin","type":"m.login.password","identifier":{"type":"m.id.user","user":"@user:example.com"},"password":"secret"}',
headers: new Headers({ headers: new Headers({
Accept: "application/json", Accept: "application/json",
@@ -61,7 +61,7 @@ describe("authProvider", () => {
}); });
expect(ret).toEqual({redirectTo: "/"}); expect(ret).toEqual({redirectTo: "/"});
expect(fetch).toHaveBeenCalledWith("https://example.com/_matrix/client/r0/login", { expect(fetch).toHaveBeenCalledWith("https://example.com/_matrix/client/v3/login", {
body: '{"device_id":null,"initial_device_display_name":"Synapse Admin","type":"m.login.token","token":"login_token"}', body: '{"device_id":null,"initial_device_display_name":"Synapse Admin","type":"m.login.token","token":"login_token"}',
headers: new Headers({ headers: new Headers({
Accept: "application/json", Accept: "application/json",
@@ -83,7 +83,7 @@ describe("authProvider", () => {
await authProvider.logout(null); await authProvider.logout(null);
expect(fetch).toBeCalledWith("example.com/_matrix/client/r0/logout", { expect(fetch).toHaveBeenCalledWith("example.com/_matrix/client/v3/logout", {
headers: new Headers({ headers: new Headers({
Accept: "application/json", Accept: "application/json",
Authorization: "Bearer foo", Authorization: "Bearer foo",
@@ -123,7 +123,9 @@ describe("authProvider", () => {
describe("getPermissions", () => { describe("getPermissions", () => {
it("should do nothing", async () => { it("should do nothing", async () => {
await expect(authProvider.getPermissions(null)).resolves.toBeUndefined(); if (authProvider.getPermissions) {
await expect(authProvider.getPermissions(null)).resolves.toBeUndefined();
}
}); });
}); });
}); });

View File

@@ -1,7 +1,8 @@
import { AuthProvider, HttpError, Options, fetchUtils, useTranslate } from "react-admin"; import { AuthProvider, HttpError, Options, fetchUtils } from "react-admin";
import storage from "../storage"; import storage from "../storage";
import { MatrixError, displayError } from "../components/error"; import { MatrixError, displayError } from "../components/error";
import { fetchAuthenticatedMedia } from "../utils/fetchMedia";
const authProvider: AuthProvider = { const authProvider: AuthProvider = {
// called when the user attempts to log in // called when the user attempts to log in
@@ -57,7 +58,7 @@ const authProvider: AuthProvider = {
storage.setItem("base_url", base_url); storage.setItem("base_url", base_url);
const decoded_base_url = window.decodeURIComponent(base_url); const decoded_base_url = window.decodeURIComponent(base_url);
let login_api_url = decoded_base_url + (accessToken ? "/_matrix/client/v3/account/whoami" : "/_matrix/client/r0/login"); let login_api_url = decoded_base_url + (accessToken ? "/_matrix/client/v3/account/whoami" : "/_matrix/client/v3/login");
let response; let response;
@@ -74,7 +75,7 @@ const authProvider: AuthProvider = {
response = await fetchUtils.fetchJson(login_api_url, options); response = await fetchUtils.fetchJson(login_api_url, options);
const json = response.json; const json = response.json;
storage.setItem("home_server", accessToken ? base_url : json.home_server); storage.setItem("home_server", accessToken ? json.user_id.split(":")[1] : json.home_server);
storage.setItem("user_id", json.user_id); storage.setItem("user_id", json.user_id);
storage.setItem("access_token", accessToken ? accessToken : json.access_token); storage.setItem("access_token", accessToken ? accessToken : json.access_token);
storage.setItem("device_id", json.device_id); storage.setItem("device_id", json.device_id);
@@ -95,11 +96,48 @@ const authProvider: AuthProvider = {
); );
} }
}, },
getIdentity: async () => {
const access_token = storage.getItem("access_token");
const user_id = storage.getItem("user_id");
const base_url = storage.getItem("base_url");
if (typeof access_token !== "string" || typeof user_id !== "string" || typeof base_url !== "string") {
return Promise.reject();
}
const options: Options = {
headers: new Headers({
Accept: "application/json",
Authorization: `Bearer ${access_token}`,
}),
};
const whoami_api_url = base_url + `/_matrix/client/v3/profile/${user_id}`;
try {
let avatar_url = "";
const response = await fetchUtils.fetchJson(whoami_api_url, options);
if (response.json.avatar_url) {
const mediaresp = await fetchAuthenticatedMedia(response.json.avatar_url, "thumbnail");
const blob = await mediaresp.blob();
avatar_url = URL.createObjectURL(blob);
}
return Promise.resolve({
id: user_id,
fullName: response.json.displayname,
avatar: avatar_url,
});
} catch (err) {
console.log("Error getting identity", err);
return Promise.reject();
}
},
// called when the user clicks on the logout button // called when the user clicks on the logout button
logout: async () => { logout: async () => {
console.log("logout"); console.log("logout");
const logout_api_url = storage.getItem("base_url") + "/_matrix/client/r0/logout"; const logout_api_url = storage.getItem("base_url") + "/_matrix/client/v3/logout";
const access_token = storage.getItem("access_token"); const access_token = storage.getItem("access_token");
const options: Options = { const options: Options = {

View File

@@ -575,13 +575,28 @@ const baseDataProvider: SynapseDataProvider = {
getMany: async (resource, params) => { getMany: async (resource, params) => {
console.log("getMany " + resource); console.log("getMany " + resource);
const homeserver = storage.getItem("base_url"); const base_url = storage.getItem("base_url");
if (!homeserver || !(resource in resourceMap)) throw Error("Homerserver not set"); const homeserver = storage.getItem("home_server");
if (!base_url || !(resource in resourceMap)) throw Error("base_url not set");
const res = resourceMap[resource]; const res = resourceMap[resource];
const endpoint_url = homeserver + res.path; const endpoint_url = base_url + res.path;
const responses = await Promise.all(params.ids.map(id => jsonClient(`${endpoint_url}/${encodeURIComponent(id)}`))); const responses = await Promise.all(params.ids.map(id => {
// edge case: when user is external / federated, homeserver will return error, as querying external users via
// /_synapse/admin/v2/users is not allowed.
// That leads to an issue when a user is referenced (e.g., in room state datagrid) - the user cell is just empty.
// To avoid that, we fake the response with one specific field (name) which is used in the datagrid.
if (homeserver && resource === "users") {
if (!(<string>id).endsWith(homeserver)) {
const json = {
name: id,
};
return Promise.resolve({ json });
}
}
return jsonClient(`${endpoint_url}/${encodeURIComponent(id)}`);
}));
return { return {
data: responses.map(({ json }) => res.map(json)), data: responses.map(({ json }) => res.map(json)),
total: responses.length, total: responses.length,

View File

@@ -8,10 +8,35 @@ export default defineConfig({
plugins: [ plugins: [
react(), react(),
vitePluginVersionMark({ vitePluginVersionMark({
name: "Synapse Admin",
command: "git describe --tags || git rev-parse --short HEAD", command: "git describe --tags || git rev-parse --short HEAD",
ifMeta: true, ifMeta: false,
ifLog: true, ifLog: false,
ifGlobal: true, ifGlobal: true,
outputFile: (version) => ({
path: "manifest.json",
content: JSON.stringify({
name: "Synapse Admin",
version: version,
description: "Synapse Admin is an admin console for synapse Matrix homeserver with additional features.",
categories: ["productivity", "utilities"],
orientation: "landscape",
icons: [{
src: "favicon.ico",
sizes: "32x32",
type: "image/x-icon"
},{
src: "images/logo.webp",
sizes: "512x512",
type: "image/webp",
purpose: "any maskable"
}],
start_url: ".",
display: "standalone",
theme_color: "#000000",
background_color: "#ffffff"
}),
}),
}), }),
], ],
}); });

1230
yarn.lock

File diff suppressed because it is too large Load Diff