diff --git a/backend/src/modules/matrix.service.ts b/backend/src/modules/matrix.service.ts index 0d870ec..eb2f332 100644 --- a/backend/src/modules/matrix.service.ts +++ b/backend/src/modules/matrix.service.ts @@ -29,6 +29,15 @@ type MatrixJoinedMembersResponse = { }> } +type MatrixUserSession = { + accessToken: string + matrixUserId: string + validUntilMs: number +} + +const matrixUserSessionCache = new Map() +const matrixJoinedRoomCache = new Map() + const trimTrailingSlash = (value: string) => value.replace(/\/+$/, "") const readLocalDevRegistrationSharedSecret = () => { if (process.env.NODE_ENV === "production") return "" @@ -296,11 +305,18 @@ export function matrixService(server: FastifyInstance) { } const createAccessTokenForUser = async (userId: string, tenantId: number | null) => { + const matrixUserId = await matrixUserIdForUser(userId, tenantId) + const cacheKey = `${tenantId || "global"}:${userId}` + const cachedSession = matrixUserSessionCache.get(cacheKey) + + if (cachedSession && cachedSession.validUntilMs > Date.now() + 60_000) { + return cachedSession + } + await provisionCurrentUser(userId, tenantId) - const matrixUserId = await matrixUserIdForUser(userId, tenantId) const serviceLogin = await ensureServiceAccessToken() - const validUntilMs = Date.now() + 10 * 60 * 1000 + const validUntilMs = Date.now() + 30 * 60 * 1000 const login = await requestMatrixJson<{ access_token: string }>( `/_synapse/admin/v1/users/${encodeURIComponent(matrixUserId)}/login`, @@ -312,11 +328,14 @@ export function matrixService(server: FastifyInstance) { } ) - return { + const session = { accessToken: login.access_token, matrixUserId, validUntilMs, } + + matrixUserSessionCache.set(cacheKey, session) + return session } const getStatus = async () => { @@ -655,6 +674,12 @@ export function matrixService(server: FastifyInstance) { room: { roomId: string, alias: string } ) => { const session = await createAccessTokenForUser(userId, tenantId) + const joinCacheKey = `${session.matrixUserId}:${room.roomId || room.alias}` + const joinedUntil = matrixJoinedRoomCache.get(joinCacheKey) + + if (joinedUntil && joinedUntil > Date.now()) { + return session + } try { await requestMatrixJson( @@ -672,6 +697,7 @@ export function matrixService(server: FastifyInstance) { } } + matrixJoinedRoomCache.set(joinCacheKey, Date.now() + 30 * 60 * 1000) return session } diff --git a/frontend/pages/communication/index.vue b/frontend/pages/communication/index.vue index 2fcfc05..1ac2306 100644 --- a/frontend/pages/communication/index.vue +++ b/frontend/pages/communication/index.vue @@ -24,6 +24,8 @@ const matrixMessageSending = ref(false) const matrixAutoRefreshActive = ref(false) const lastUpdated = ref(null) let matrixRefreshInterval = null +let matrixMessagesRequestActive = false +let matrixMembersRequestActive = false const statusItems = computed(() => [ { @@ -125,7 +127,7 @@ const loadMatrixInfo = async () => { lastUpdated.value = new Date() if (generalRoomRes?.exists && canUseMatrixChat.value) { - await loadGeneralChat({ silent: true }) + await loadGeneralChat({ silent: true, includeMembers: true }) } } catch (error) { toast.add({ @@ -225,7 +227,7 @@ const provisionGeneralRoom = async () => { color: "success" }) - await loadGeneralChat() + await loadGeneralChat({ includeMembers: true }) } catch (error) { toast.add({ title: "Allgemeiner Chat konnte nicht erstellt werden", @@ -238,6 +240,9 @@ const provisionGeneralRoom = async () => { const loadGeneralMessages = async ({ silent = false } = {}) => { if (!canUseMatrixChat.value) return + if (matrixMessagesRequestActive) return + + matrixMessagesRequestActive = true if (!silent) matrixMessagesLoading.value = true try { @@ -258,12 +263,16 @@ const loadGeneralMessages = async ({ silent = false } = {}) => { }) } } finally { + matrixMessagesRequestActive = false if (!silent) matrixMessagesLoading.value = false } } const loadGeneralMembers = async ({ silent = false } = {}) => { if (!canUseMatrixChat.value) return + if (matrixMembersRequestActive) return + + matrixMembersRequestActive = true if (!silent) matrixMembersLoading.value = true try { @@ -277,15 +286,17 @@ const loadGeneralMembers = async ({ silent = false } = {}) => { }) } } finally { + matrixMembersRequestActive = false if (!silent) matrixMembersLoading.value = false } } -const loadGeneralChat = async ({ silent = false } = {}) => { - await Promise.all([ - loadGeneralMessages({ silent }), - loadGeneralMembers({ silent }) - ]) +const loadGeneralChat = async ({ silent = false, includeMembers = false } = {}) => { + await loadGeneralMessages({ silent }) + + if (includeMembers) { + await loadGeneralMembers({ silent }) + } } const sendMatrixMessage = async () => { @@ -321,7 +332,6 @@ const sendMatrixMessage = async () => { matrixMessages.value = matrixMessages.value.map((item) => item.id === optimisticId ? message : item ) - await loadGeneralMembers({ silent: true }) } catch (error) { matrixMessages.value = matrixMessages.value.map((item) => item.id === optimisticId ? { ...item, pending: false, failed: true } : item @@ -343,7 +353,7 @@ const startMatrixAutoRefresh = () => { if (!document.hidden && canUseMatrixChat.value) { loadGeneralChat({ silent: true }) } - }, 5000) + }, 15000) } const stopMatrixAutoRefresh = () => {