mirror of
				https://github.com/UA-Fediland/synapse-admin.git
				synced 2025-10-31 15:18:27 +00:00 
			
		
		
		
	Use central defintion of storage system
Change-Id: Ibf31c650b08920bf82827607c3421556ac90ae61
This commit is contained in:
		
							parent
							
								
									035baa786a
								
							
						
					
					
						commit
						dbcb4f92dc
					
				
					 9 changed files with 66 additions and 53 deletions
				
			
		|  | @ -34,6 +34,7 @@ import { Link } from "react-router-dom"; | |||
| import { dateParser } from "./date"; | ||||
| import { DeleteMediaParams, SynapseDataProvider } from "../synapse/dataProvider"; | ||||
| import { getMediaUrl } from "../synapse/synapse"; | ||||
| import storage from "../storage"; | ||||
| 
 | ||||
| const DeleteMediaDialog = ({ open, onClose, onSubmit }) => { | ||||
|   const translate = useTranslate(); | ||||
|  | @ -339,7 +340,7 @@ export const ViewMediaButton = ({ media_id, label }) => { | |||
| }; | ||||
| 
 | ||||
| export const MediaIDField = ({ source }) => { | ||||
|   const homeserver = localStorage.getItem("home_server"); | ||||
|   const homeserver = storage.getItem("home_server"); | ||||
|   const record = useRecordContext(); | ||||
|   if (!record) return null; | ||||
| 
 | ||||
|  |  | |||
|  | @ -27,6 +27,7 @@ import { | |||
|   isValidBaseUrl, | ||||
|   splitMxid, | ||||
| } from "../synapse/synapse"; | ||||
| import storage from "../storage"; | ||||
| 
 | ||||
| const FormBox = styled(Box)(({ theme }) => ({ | ||||
|   display: "flex", | ||||
|  | @ -94,7 +95,7 @@ const LoginPage = () => { | |||
|   const [locale, setLocale] = useLocaleState(); | ||||
|   const locales = useLocales(); | ||||
|   const translate = useTranslate(); | ||||
|   const base_url = allowSingleBaseUrl ? restrictBaseUrl : localStorage.getItem("base_url"); | ||||
|   const base_url = allowSingleBaseUrl ? restrictBaseUrl : storage.getItem("base_url"); | ||||
|   const [ssoBaseUrl, setSSOBaseUrl] = useState(""); | ||||
|   const loginToken = /\?loginToken=([a-zA-Z0-9_-]+)/.exec(window.location.href); | ||||
| 
 | ||||
|  | @ -103,8 +104,8 @@ const LoginPage = () => { | |||
|     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"); | ||||
|     const baseUrl = storage.getItem("sso_base_url"); | ||||
|     storage.removeItem("sso_base_url"); | ||||
|     if (baseUrl) { | ||||
|       const auth = { | ||||
|         base_url: baseUrl, | ||||
|  | @ -154,7 +155,7 @@ const LoginPage = () => { | |||
|   }; | ||||
| 
 | ||||
|   const handleSSO = () => { | ||||
|     localStorage.setItem("sso_base_url", ssoBaseUrl); | ||||
|     storage.setItem("sso_base_url", ssoBaseUrl); | ||||
|     const ssoFullUrl = `${ssoBaseUrl}/_matrix/client/r0/login/sso/redirect?redirectUrl=${encodeURIComponent( | ||||
|       window.location.href | ||||
|     )}`;
 | ||||
|  |  | |||
|  | @ -128,8 +128,8 @@ export const UserList = (props: ListProps) => ( | |||
| 
 | ||||
| // https://matrix.org/docs/spec/appendices#user-identifiers
 | ||||
| // here only local part of user_id
 | ||||
| // maxLength = 255 - "@" - ":" - localStorage.getItem("home_server").length
 | ||||
| // localStorage.getItem("home_server").length is not valid here
 | ||||
| // maxLength = 255 - "@" - ":" - storage.getItem("home_server").length
 | ||||
| // storage.getItem("home_server").length is not valid here
 | ||||
| const validateUser = [required(), maxLength(253), regex(/^[a-z0-9._=\-/]+$/, "synapseadmin.users.invalid_user_id")]; | ||||
| 
 | ||||
| const validateAddress = [required(), maxLength(255)]; | ||||
|  |  | |||
							
								
								
									
										3
									
								
								src/storage.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/storage.ts
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | |||
| const storage = localStorage; | ||||
| 
 | ||||
| export default storage; | ||||
|  | @ -1,13 +1,14 @@ | |||
| import fetchMock from "jest-fetch-mock"; | ||||
| 
 | ||||
| import authProvider from "./authProvider"; | ||||
| import storage from "../storage"; | ||||
| 
 | ||||
| fetchMock.enableMocks(); | ||||
| 
 | ||||
| describe("authProvider", () => { | ||||
|   beforeEach(() => { | ||||
|     fetchMock.resetMocks(); | ||||
|     localStorage.clear(); | ||||
|     storage.clear(); | ||||
|   }); | ||||
| 
 | ||||
|   describe("login", () => { | ||||
|  | @ -36,10 +37,10 @@ describe("authProvider", () => { | |||
|         }), | ||||
|         method: "POST", | ||||
|       }); | ||||
|       expect(localStorage.getItem("base_url")).toEqual("http://example.com"); | ||||
|       expect(localStorage.getItem("user_id")).toEqual("@user:example.com"); | ||||
|       expect(localStorage.getItem("access_token")).toEqual("foobar"); | ||||
|       expect(localStorage.getItem("device_id")).toEqual("some_device"); | ||||
|       expect(storage.getItem("base_url")).toEqual("http://example.com"); | ||||
|       expect(storage.getItem("user_id")).toEqual("@user:example.com"); | ||||
|       expect(storage.getItem("access_token")).toEqual("foobar"); | ||||
|       expect(storage.getItem("device_id")).toEqual("some_device"); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
|  | @ -67,16 +68,16 @@ describe("authProvider", () => { | |||
|       }), | ||||
|       method: "POST", | ||||
|     }); | ||||
|     expect(localStorage.getItem("base_url")).toEqual("https://example.com"); | ||||
|     expect(localStorage.getItem("user_id")).toEqual("@user:example.com"); | ||||
|     expect(localStorage.getItem("access_token")).toEqual("foobar"); | ||||
|     expect(localStorage.getItem("device_id")).toEqual("some_device"); | ||||
|     expect(storage.getItem("base_url")).toEqual("https://example.com"); | ||||
|     expect(storage.getItem("user_id")).toEqual("@user:example.com"); | ||||
|     expect(storage.getItem("access_token")).toEqual("foobar"); | ||||
|     expect(storage.getItem("device_id")).toEqual("some_device"); | ||||
|   }); | ||||
| 
 | ||||
|   describe("logout", () => { | ||||
|     it("should remove the access_token from localStorage", async () => { | ||||
|       localStorage.setItem("base_url", "example.com"); | ||||
|       localStorage.setItem("access_token", "foo"); | ||||
|     it("should remove the access_token from storage", async () => { | ||||
|       storage.setItem("base_url", "example.com"); | ||||
|       storage.setItem("access_token", "foo"); | ||||
|       fetchMock.mockResponse(JSON.stringify({})); | ||||
| 
 | ||||
|       await authProvider.logout(null); | ||||
|  | @ -89,7 +90,7 @@ describe("authProvider", () => { | |||
|         method: "POST", | ||||
|         user: { authenticated: true, token: "Bearer foo" }, | ||||
|       }); | ||||
|       expect(localStorage.getItem("access_token")).toBeNull(); | ||||
|       expect(storage.getItem("access_token")).toBeNull(); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
|  | @ -113,7 +114,7 @@ describe("authProvider", () => { | |||
|     }); | ||||
| 
 | ||||
|     it("should resolve when logged in", async () => { | ||||
|       localStorage.setItem("access_token", "foobar"); | ||||
|       storage.setItem("access_token", "foobar"); | ||||
| 
 | ||||
|       await expect(authProvider.checkAuth({})).resolves.toBeUndefined(); | ||||
|     }); | ||||
|  |  | |||
|  | @ -1,5 +1,7 @@ | |||
| import { AuthProvider, Options, fetchUtils } from "react-admin"; | ||||
| 
 | ||||
| import storage from "../storage"; | ||||
| 
 | ||||
| const authProvider: AuthProvider = { | ||||
|   // called when the user attempts to log in
 | ||||
|   login: async ({ | ||||
|  | @ -19,7 +21,7 @@ const authProvider: AuthProvider = { | |||
|       body: JSON.stringify( | ||||
|         Object.assign( | ||||
|           { | ||||
|             device_id: localStorage.getItem("device_id"), | ||||
|             device_id: storage.getItem("device_id"), | ||||
|             initial_device_display_name: "Synapse Admin", | ||||
|           }, | ||||
|           loginToken | ||||
|  | @ -40,23 +42,23 @@ const authProvider: AuthProvider = { | |||
|     // server, since the admin might want to access the admin API via some
 | ||||
|     // private address
 | ||||
|     base_url = base_url.replace(/\/+$/g, ""); | ||||
|     localStorage.setItem("base_url", base_url); | ||||
|     storage.setItem("base_url", base_url); | ||||
| 
 | ||||
|     const decoded_base_url = window.decodeURIComponent(base_url); | ||||
|     const login_api_url = decoded_base_url + "/_matrix/client/r0/login"; | ||||
| 
 | ||||
|     const { json } = await fetchUtils.fetchJson(login_api_url, options); | ||||
|     localStorage.setItem("home_server", json.home_server); | ||||
|     localStorage.setItem("user_id", json.user_id); | ||||
|     localStorage.setItem("access_token", json.access_token); | ||||
|     localStorage.setItem("device_id", json.device_id); | ||||
|     storage.setItem("home_server", json.home_server); | ||||
|     storage.setItem("user_id", json.user_id); | ||||
|     storage.setItem("access_token", json.access_token); | ||||
|     storage.setItem("device_id", json.device_id); | ||||
|   }, | ||||
|   // called when the user clicks on the logout button
 | ||||
|   logout: async () => { | ||||
|     console.log("logout"); | ||||
| 
 | ||||
|     const logout_api_url = localStorage.getItem("base_url") + "/_matrix/client/r0/logout"; | ||||
|     const access_token = localStorage.getItem("access_token"); | ||||
|     const logout_api_url = storage.getItem("base_url") + "/_matrix/client/r0/logout"; | ||||
|     const access_token = storage.getItem("access_token"); | ||||
| 
 | ||||
|     const options: Options = { | ||||
|       method: "POST", | ||||
|  | @ -68,7 +70,7 @@ const authProvider: AuthProvider = { | |||
| 
 | ||||
|     if (typeof access_token === "string") { | ||||
|       await fetchUtils.fetchJson(logout_api_url, options); | ||||
|       localStorage.removeItem("access_token"); | ||||
|       storage.removeItem("access_token"); | ||||
|     } | ||||
|   }, | ||||
|   // called when the API returns an error
 | ||||
|  | @ -81,7 +83,7 @@ const authProvider: AuthProvider = { | |||
|   }, | ||||
|   // called when the user navigates to a new location, to check for authentication
 | ||||
|   checkAuth: () => { | ||||
|     const access_token = localStorage.getItem("access_token"); | ||||
|     const access_token = storage.getItem("access_token"); | ||||
|     console.log("checkAuth " + access_token); | ||||
|     return typeof access_token === "string" ? Promise.resolve() : Promise.reject(); | ||||
|   }, | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| import fetchMock from "jest-fetch-mock"; | ||||
| 
 | ||||
| import dataProvider from "./dataProvider"; | ||||
| import storage from "../storage"; | ||||
| 
 | ||||
| fetchMock.enableMocks(); | ||||
| 
 | ||||
|  | @ -9,8 +10,8 @@ beforeEach(() => { | |||
| }); | ||||
| 
 | ||||
| describe("dataProvider", () => { | ||||
|   localStorage.setItem("base_url", "http://localhost"); | ||||
|   localStorage.setItem("access_token", "access_token"); | ||||
|   storage.setItem("base_url", "http://localhost"); | ||||
|   storage.setItem("access_token", "access_token"); | ||||
| 
 | ||||
|   it("fetches all users", async () => { | ||||
|     fetchMock.mockResponseOnce( | ||||
|  |  | |||
|  | @ -2,9 +2,11 @@ import { stringify } from "query-string"; | |||
| 
 | ||||
| import { DataProvider, DeleteParams, Identifier, Options, RaRecord, fetchUtils } from "react-admin"; | ||||
| 
 | ||||
| import storage from "../storage"; | ||||
| 
 | ||||
| // Adds the access token to all requests
 | ||||
| const jsonClient = (url: string, options: Options = {}) => { | ||||
|   const token = localStorage.getItem("access_token"); | ||||
|   const token = storage.getItem("access_token"); | ||||
|   console.log("httpClient " + url); | ||||
|   if (token != null) { | ||||
|     options.user = { | ||||
|  | @ -16,7 +18,7 @@ const jsonClient = (url: string, options: Options = {}) => { | |||
| }; | ||||
| 
 | ||||
| const mxcUrlToHttp = (mxcUrl: string) => { | ||||
|   const homeserver = localStorage.getItem("base_url"); | ||||
|   const homeserver = storage.getItem("base_url"); | ||||
|   const re = /^mxc:\/\/([^/]+)\/(\w+)/; | ||||
|   const ret = re.exec(mxcUrl); | ||||
|   console.log("mxcClient " + ret); | ||||
|  | @ -232,7 +234,7 @@ const resourceMap = { | |||
|     data: "users", | ||||
|     total: json => json.total, | ||||
|     create: (data: RaRecord) => ({ | ||||
|       endpoint: `/_synapse/admin/v2/users/@${encodeURIComponent(data.id)}:${localStorage.getItem("home_server")}`, | ||||
|       endpoint: `/_synapse/admin/v2/users/@${encodeURIComponent(data.id)}:${storage.getItem("home_server")}`, | ||||
|       body: data, | ||||
|       method: "PUT", | ||||
|     }), | ||||
|  | @ -341,7 +343,7 @@ const resourceMap = { | |||
|     data: "media", | ||||
|     total: json => json.total, | ||||
|     delete: (params: DeleteParams) => ({ | ||||
|       endpoint: `/_synapse/admin/v1/media/${localStorage.getItem("home_server")}/${params.id}`, | ||||
|       endpoint: `/_synapse/admin/v1/media/${storage.getItem("home_server")}/${params.id}`, | ||||
|     }), | ||||
|   }, | ||||
|   protect_media: { | ||||
|  | @ -358,11 +360,11 @@ const resourceMap = { | |||
|   quarantine_media: { | ||||
|     map: (qm: UserMedia) => ({ id: qm.media_id }), | ||||
|     create: (params: UserMedia) => ({ | ||||
|       endpoint: `/_synapse/admin/v1/media/quarantine/${localStorage.getItem("home_server")}/${params.media_id}`, | ||||
|       endpoint: `/_synapse/admin/v1/media/quarantine/${storage.getItem("home_server")}/${params.media_id}`, | ||||
|       method: "POST", | ||||
|     }), | ||||
|     delete: (params: DeleteParams) => ({ | ||||
|       endpoint: `/_synapse/admin/v1/media/unquarantine/${localStorage.getItem("home_server")}/${params.id}`, | ||||
|       endpoint: `/_synapse/admin/v1/media/unquarantine/${storage.getItem("home_server")}/${params.id}`, | ||||
|       method: "POST", | ||||
|     }), | ||||
|   }, | ||||
|  | @ -506,7 +508,7 @@ const dataProvider: SynapseDataProvider = { | |||
|       order_by: field, | ||||
|       dir: getSearchOrder(order), | ||||
|     }; | ||||
|     const homeserver = localStorage.getItem("base_url"); | ||||
|     const homeserver = storage.getItem("base_url"); | ||||
|     if (!homeserver || !(resource in resourceMap)) throw Error("Homeserver not set"); | ||||
| 
 | ||||
|     const res = resourceMap[resource]; | ||||
|  | @ -523,7 +525,7 @@ const dataProvider: SynapseDataProvider = { | |||
| 
 | ||||
|   getOne: async (resource, params) => { | ||||
|     console.log("getOne " + resource); | ||||
|     const homeserver = localStorage.getItem("base_url"); | ||||
|     const homeserver = storage.getItem("base_url"); | ||||
|     if (!homeserver || !(resource in resourceMap)) throw Error("Homeserver not set"); | ||||
| 
 | ||||
|     const res = resourceMap[resource]; | ||||
|  | @ -535,7 +537,7 @@ const dataProvider: SynapseDataProvider = { | |||
| 
 | ||||
|   getMany: async (resource, params) => { | ||||
|     console.log("getMany " + resource); | ||||
|     const homeserver = localStorage.getItem("base_url"); | ||||
|     const homeserver = storage.getItem("base_url"); | ||||
|     if (!homeserver || !(resource in resourceMap)) throw Error("Homerserver not set"); | ||||
| 
 | ||||
|     const res = resourceMap[resource]; | ||||
|  | @ -560,7 +562,7 @@ const dataProvider: SynapseDataProvider = { | |||
|       dir: getSearchOrder(order), | ||||
|     }; | ||||
| 
 | ||||
|     const homeserver = localStorage.getItem("base_url"); | ||||
|     const homeserver = storage.getItem("base_url"); | ||||
|     if (!homeserver || !(resource in resourceMap)) throw Error("Homeserver not set"); | ||||
| 
 | ||||
|     const res = resourceMap[resource]; | ||||
|  | @ -577,7 +579,7 @@ const dataProvider: SynapseDataProvider = { | |||
| 
 | ||||
|   update: async (resource, params) => { | ||||
|     console.log("update " + resource); | ||||
|     const homeserver = localStorage.getItem("base_url"); | ||||
|     const homeserver = storage.getItem("base_url"); | ||||
|     if (!homeserver || !(resource in resourceMap)) throw Error("Homeserver not set"); | ||||
| 
 | ||||
|     const res = resourceMap[resource]; | ||||
|  | @ -592,7 +594,7 @@ const dataProvider: SynapseDataProvider = { | |||
| 
 | ||||
|   updateMany: async (resource, params) => { | ||||
|     console.log("updateMany " + resource); | ||||
|     const homeserver = localStorage.getItem("base_url"); | ||||
|     const homeserver = storage.getItem("base_url"); | ||||
|     if (!homeserver || !(resource in resourceMap)) throw Error("Homeserver not set"); | ||||
| 
 | ||||
|     const res = resourceMap[resource]; | ||||
|  | @ -609,7 +611,7 @@ const dataProvider: SynapseDataProvider = { | |||
| 
 | ||||
|   create: async (resource, params) => { | ||||
|     console.log("create " + resource); | ||||
|     const homeserver = localStorage.getItem("base_url"); | ||||
|     const homeserver = storage.getItem("base_url"); | ||||
|     if (!homeserver || !(resource in resourceMap)) throw Error("Homeserver not set"); | ||||
| 
 | ||||
|     const res = resourceMap[resource]; | ||||
|  | @ -626,7 +628,7 @@ const dataProvider: SynapseDataProvider = { | |||
| 
 | ||||
|   createMany: async (resource: string, params: { ids: Identifier[]; data: RaRecord }) => { | ||||
|     console.log("createMany " + resource); | ||||
|     const homeserver = localStorage.getItem("base_url"); | ||||
|     const homeserver = storage.getItem("base_url"); | ||||
|     if (!homeserver || !(resource in resourceMap)) throw Error("Homeserver not set"); | ||||
| 
 | ||||
|     const res = resourceMap[resource]; | ||||
|  | @ -648,7 +650,7 @@ const dataProvider: SynapseDataProvider = { | |||
| 
 | ||||
|   delete: async (resource, params) => { | ||||
|     console.log("delete " + resource); | ||||
|     const homeserver = localStorage.getItem("base_url"); | ||||
|     const homeserver = storage.getItem("base_url"); | ||||
|     if (!homeserver || !(resource in resourceMap)) throw Error("Homeserver not set"); | ||||
| 
 | ||||
|     const res = resourceMap[resource]; | ||||
|  | @ -673,7 +675,7 @@ const dataProvider: SynapseDataProvider = { | |||
| 
 | ||||
|   deleteMany: async (resource, params) => { | ||||
|     console.log("deleteMany " + resource); | ||||
|     const homeserver = localStorage.getItem("base_url"); | ||||
|     const homeserver = storage.getItem("base_url"); | ||||
|     if (!homeserver || !(resource in resourceMap)) throw Error("Homeserver not set"); | ||||
| 
 | ||||
|     const res = resourceMap[resource]; | ||||
|  | @ -719,10 +721,10 @@ const dataProvider: SynapseDataProvider = { | |||
|    * @returns | ||||
|    */ | ||||
|   deleteMedia: async ({ before_ts, size_gt = 0, keep_profiles = true }) => { | ||||
|     const homeserver = localStorage.getItem("home_server"); // TODO only required for synapse < 1.78.0
 | ||||
|     const homeserver = storage.getItem("home_server"); // TODO only required for synapse < 1.78.0
 | ||||
|     const endpoint = `/_synapse/admin/v1/media/${homeserver}/delete?before_ts=${before_ts}&size_gt=${size_gt}&keep_profiles=${keep_profiles}`; | ||||
| 
 | ||||
|     const base_url = localStorage.getItem("base_url"); | ||||
|     const base_url = storage.getItem("base_url"); | ||||
|     const endpoint_url = base_url + endpoint; | ||||
|     const { json } = await jsonClient(endpoint_url, { method: "POST" }); | ||||
|     return json as DeleteMediaResult; | ||||
|  |  | |||
|  | @ -1,5 +1,7 @@ | |||
| import { fetchUtils } from "react-admin"; | ||||
| 
 | ||||
| import storage from "../storage"; | ||||
| 
 | ||||
| export const splitMxid = mxid => { | ||||
|   const re = /^@(?<name>[a-zA-Z0-9._=\-/]+):(?<domain>[a-zA-Z0-9\-.]+\.[a-zA-Z]+)$/; | ||||
|   return re.exec(mxid)?.groups; | ||||
|  | @ -53,7 +55,7 @@ export const getSupportedLoginFlows = async baseUrl => { | |||
| }; | ||||
| 
 | ||||
| export const getMediaUrl = media_id => { | ||||
|   const baseUrl = localStorage.getItem("base_url"); | ||||
|   const baseUrl = storage.getItem("base_url"); | ||||
|   return `${baseUrl}/_matrix/media/v1/download/${media_id}?allow_redirect=true`; | ||||
| }; | ||||
| 
 | ||||
|  | @ -62,7 +64,7 @@ export const getMediaUrl = media_id => { | |||
|  * @returns full MXID as string | ||||
|  */ | ||||
| export function generateRandomMxId(): string { | ||||
|   const homeserver = localStorage.getItem("home_server"); | ||||
|   const homeserver = storage.getItem("home_server"); | ||||
|   const characters = "0123456789abcdefghijklmnopqrstuvwxyz"; | ||||
|   const localpart = Array.from(crypto.getRandomValues(new Uint32Array(8))) | ||||
|     .map(x => characters[x % characters.length]) | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue