KI-AGENT: Matrix-Daten beim Tenant-Import neu provisionieren
This commit is contained in:
@@ -18,6 +18,7 @@ import { ensureTenantBaseData } from "../modules/bootstrap.service";
|
|||||||
import { buildTenantFullExport, importTenantFullExport } from "../utils/tenantFullExport";
|
import { buildTenantFullExport, importTenantFullExport } from "../utils/tenantFullExport";
|
||||||
import type { TenantFullExport } from "../utils/tenantFullExport";
|
import type { TenantFullExport } from "../utils/tenantFullExport";
|
||||||
import { buildSystemStatus } from "../modules/system-status.service";
|
import { buildSystemStatus } from "../modules/system-status.service";
|
||||||
|
import { matrixService } from "../modules/matrix.service";
|
||||||
|
|
||||||
export default async function adminRoutes(server: FastifyInstance) {
|
export default async function adminRoutes(server: FastifyInstance) {
|
||||||
const deriveNameFromEmail = (email: string) => {
|
const deriveNameFromEmail = (email: string) => {
|
||||||
@@ -1034,8 +1035,27 @@ export default async function adminRoutes(server: FastifyInstance) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let matrixProvisioned = false;
|
||||||
|
let matrixProvisioningError: string | null = null;
|
||||||
|
if (process.env.MATRIX_REGISTRATION_SHARED_SECRET) {
|
||||||
|
try {
|
||||||
|
const matrix = matrixService(server);
|
||||||
|
await matrix.provisionTenantRoom(currentUser.id, result.tenantId, {
|
||||||
|
key: "allgemein",
|
||||||
|
name: "Allgemeiner Chat",
|
||||||
|
type: "general",
|
||||||
|
});
|
||||||
|
matrixProvisioned = true;
|
||||||
|
} catch (err: any) {
|
||||||
|
matrixProvisioningError = err?.message || String(err);
|
||||||
|
req.log.warn({ err }, "Matrix-Räume konnten nach Tenant-Import nicht neu provisioniert werden");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
|
matrixProvisioned,
|
||||||
|
matrixProvisioningError,
|
||||||
...result,
|
...result,
|
||||||
};
|
};
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
|
|||||||
@@ -48,6 +48,46 @@ const ENTITY_BANKACCOUNT_PLAIN_FIELDS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const quoteIdent = (value: string) => `"${value.replace(/"/g, '""')}"`
|
const quoteIdent = (value: string) => `"${value.replace(/"/g, '""')}"`
|
||||||
|
const matrixServerName = () =>
|
||||||
|
process.env.MATRIX_SERVER_NAME ||
|
||||||
|
secrets.MATRIX_SERVER_NAME ||
|
||||||
|
process.env.DOMAIN ||
|
||||||
|
"localhost"
|
||||||
|
|
||||||
|
const normalizeMatrixLocalpartSeed = (value: string) => {
|
||||||
|
const normalized = value
|
||||||
|
.toLowerCase()
|
||||||
|
.normalize("NFKD")
|
||||||
|
.replace(/[\u0300-\u036f]/g, "")
|
||||||
|
.replace(/ä/g, "a")
|
||||||
|
.replace(/ö/g, "o")
|
||||||
|
.replace(/ü/g, "u")
|
||||||
|
.replace(/ß/g, "ss")
|
||||||
|
.replace(/[^a-z0-9._=-]+/g, "_")
|
||||||
|
.replace(/_+/g, "_")
|
||||||
|
.replace(/^[._=-]+|[._=-]+$/g, "")
|
||||||
|
|
||||||
|
return normalized || "user"
|
||||||
|
}
|
||||||
|
|
||||||
|
const normalizeMatrixAliasSeed = (value: string) =>
|
||||||
|
normalizeMatrixLocalpartSeed(value)
|
||||||
|
.replace(/[.=]/g, "_")
|
||||||
|
.replace(/_+/g, "_")
|
||||||
|
|
||||||
|
const tenantRoomAliasLocalpart = (
|
||||||
|
tenant: { id: number, short?: string | null, name?: string | null },
|
||||||
|
roomKey: string
|
||||||
|
) => {
|
||||||
|
const tenantSeed = normalizeMatrixAliasSeed(tenant.short || tenant.name || `tenant_${tenant.id}`)
|
||||||
|
const roomSeed = normalizeMatrixAliasSeed(roomKey)
|
||||||
|
return `fedeo_${tenantSeed}_${tenant.id}_${roomSeed}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const tenantRoomAlias = (
|
||||||
|
tenant: { id: number, short?: string | null, name?: string | null },
|
||||||
|
roomKey: string
|
||||||
|
) => `#${tenantRoomAliasLocalpart(tenant, roomKey)}:${matrixServerName()}`
|
||||||
|
|
||||||
const tableColumns = async (client: any) => {
|
const tableColumns = async (client: any) => {
|
||||||
const result = await client.query(`
|
const result = await client.query(`
|
||||||
@@ -346,6 +386,34 @@ const encryptEntityBankAccountRowsForImport = (exportData: TenantFullExport) =>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const prepareCommunicationRoomsForImport = (exportData: TenantFullExport) => {
|
||||||
|
const rows = exportData.tables.communication_rooms || []
|
||||||
|
if (!rows.length) return
|
||||||
|
|
||||||
|
const tenantById = new Map((exportData.tables.tenants || []).map((tenant) => [
|
||||||
|
Number(tenant.id),
|
||||||
|
{
|
||||||
|
id: Number(tenant.id),
|
||||||
|
name: tenant.name,
|
||||||
|
short: tenant.short,
|
||||||
|
},
|
||||||
|
]))
|
||||||
|
|
||||||
|
for (const row of rows) {
|
||||||
|
const tenantId = Number(row.tenant_id)
|
||||||
|
const tenant = tenantById.get(tenantId)
|
||||||
|
|
||||||
|
row.matrix_room_id = null
|
||||||
|
row.parent_space_room_id = null
|
||||||
|
|
||||||
|
if (tenant && row.key) {
|
||||||
|
row.matrix_alias = tenantRoomAlias(tenant, String(row.key))
|
||||||
|
} else {
|
||||||
|
row.matrix_alias = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const prepareColumnValue = (value: any, isJsonColumn: boolean) => {
|
const prepareColumnValue = (value: any, isJsonColumn: boolean) => {
|
||||||
if (!isJsonColumn || value === null || typeof value === "undefined") return value
|
if (!isJsonColumn || value === null || typeof value === "undefined") return value
|
||||||
if (typeof value === "string") return value
|
if (typeof value === "string") return value
|
||||||
@@ -465,6 +533,7 @@ export const importTenantFullExport = async (
|
|||||||
|
|
||||||
const exportData = remapTenantScopedExport(rawExportData, options.targetTenantId)
|
const exportData = remapTenantScopedExport(rawExportData, options.targetTenantId)
|
||||||
encryptEntityBankAccountRowsForImport(exportData)
|
encryptEntityBankAccountRowsForImport(exportData)
|
||||||
|
prepareCommunicationRoomsForImport(exportData)
|
||||||
const client = await pool.connect()
|
const client = await pool.connect()
|
||||||
const importOrder = [
|
const importOrder = [
|
||||||
"tenants",
|
"tenants",
|
||||||
|
|||||||
Reference in New Issue
Block a user