refactor: move group access into setup wizard

This commit is contained in:
Peter Steinberger
2026-03-15 19:52:17 -07:00
parent d8e138c743
commit 84c0326f4d
15 changed files with 305 additions and 217 deletions

View File

@@ -1,5 +1,4 @@
import type { ChannelOnboardingDmPolicy } from "../../../src/channels/plugins/onboarding-types.js";
import { promptChannelAccessConfig } from "../../../src/channels/plugins/onboarding/channel-access.js";
import {
addWildcardAllowFrom,
buildSingleChannelSecretPromptState,
@@ -171,6 +170,78 @@ function setMatrixGroupRooms(cfg: CoreConfig, roomKeys: string[]) {
};
}
async function resolveMatrixGroupRooms(params: {
cfg: CoreConfig;
entries: string[];
prompter: Pick<WizardPrompter, "note">;
}): Promise<string[]> {
if (params.entries.length === 0) {
return [];
}
try {
const resolvedIds: string[] = [];
const unresolved: string[] = [];
for (const entry of params.entries) {
const trimmed = entry.trim();
if (!trimmed) {
continue;
}
const cleaned = trimmed.replace(/^(room|channel):/i, "").trim();
if (cleaned.startsWith("!") && cleaned.includes(":")) {
resolvedIds.push(cleaned);
continue;
}
const matches = await listMatrixDirectoryGroupsLive({
cfg: params.cfg,
query: trimmed,
limit: 10,
});
const exact = matches.find(
(match) => (match.name ?? "").toLowerCase() === trimmed.toLowerCase(),
);
const best = exact ?? matches[0];
if (best?.id) {
resolvedIds.push(best.id);
} else {
unresolved.push(entry);
}
}
const roomKeys = [...resolvedIds, ...unresolved.map((entry) => entry.trim()).filter(Boolean)];
const resolution = formatResolvedUnresolvedNote({
resolved: resolvedIds,
unresolved,
});
if (resolution) {
await params.prompter.note(resolution, "Matrix rooms");
}
return roomKeys;
} catch (err) {
await params.prompter.note(
`Room lookup failed; keeping entries as typed. ${String(err)}`,
"Matrix rooms",
);
return params.entries.map((entry) => entry.trim()).filter(Boolean);
}
}
const matrixGroupAccess: NonNullable<ChannelSetupWizard["groupAccess"]> = {
label: "Matrix rooms",
placeholder: "!roomId:server, #alias:server, Project Room",
currentPolicy: ({ cfg }) => cfg.channels?.matrix?.groupPolicy ?? "allowlist",
currentEntries: ({ cfg }) =>
Object.keys(cfg.channels?.matrix?.groups ?? cfg.channels?.matrix?.rooms ?? {}),
updatePrompt: ({ cfg }) => Boolean(cfg.channels?.matrix?.groups ?? cfg.channels?.matrix?.rooms),
setPolicy: ({ cfg, policy }) => setMatrixGroupPolicy(cfg as CoreConfig, policy),
resolveAllowlist: async ({ cfg, entries, prompter }) =>
await resolveMatrixGroupRooms({
cfg: cfg as CoreConfig,
entries,
prompter,
}),
applyAllowlist: ({ cfg, resolved }) =>
setMatrixGroupRooms(cfg as CoreConfig, resolved as string[]),
};
const matrixDmPolicy: ChannelOnboardingDmPolicy = {
label: "Matrix",
channel,
@@ -386,72 +457,10 @@ export const matrixSetupWizard: ChannelSetupWizard = {
next = await promptMatrixAllowFrom({ cfg: next, prompter });
}
const existingGroups = next.channels?.matrix?.groups ?? next.channels?.matrix?.rooms;
const accessConfig = await promptChannelAccessConfig({
prompter,
label: "Matrix rooms",
currentPolicy: next.channels?.matrix?.groupPolicy ?? "allowlist",
currentEntries: Object.keys(existingGroups ?? {}),
placeholder: "!roomId:server, #alias:server, Project Room",
updatePrompt: Boolean(existingGroups),
});
if (accessConfig) {
if (accessConfig.policy !== "allowlist") {
next = setMatrixGroupPolicy(next, accessConfig.policy);
} else {
let roomKeys = accessConfig.entries;
if (accessConfig.entries.length > 0) {
try {
const resolvedIds: string[] = [];
const unresolved: string[] = [];
for (const entry of accessConfig.entries) {
const trimmed = entry.trim();
if (!trimmed) {
continue;
}
const cleaned = trimmed.replace(/^(room|channel):/i, "").trim();
if (cleaned.startsWith("!") && cleaned.includes(":")) {
resolvedIds.push(cleaned);
continue;
}
const matches = await listMatrixDirectoryGroupsLive({
cfg: next,
query: trimmed,
limit: 10,
});
const exact = matches.find(
(match) => (match.name ?? "").toLowerCase() === trimmed.toLowerCase(),
);
const best = exact ?? matches[0];
if (best?.id) {
resolvedIds.push(best.id);
} else {
unresolved.push(entry);
}
}
roomKeys = [...resolvedIds, ...unresolved.map((entry) => entry.trim()).filter(Boolean)];
const resolution = formatResolvedUnresolvedNote({
resolved: resolvedIds,
unresolved,
});
if (resolution) {
await prompter.note(resolution, "Matrix rooms");
}
} catch (err) {
await prompter.note(
`Room lookup failed; keeping entries as typed. ${String(err)}`,
"Matrix rooms",
);
}
}
next = setMatrixGroupPolicy(next, "allowlist");
next = setMatrixGroupRooms(next, roomKeys);
}
}
return { cfg: next };
},
dmPolicy: matrixDmPolicy,
groupAccess: matrixGroupAccess,
disable: (cfg) => ({
...(cfg as CoreConfig),
channels: {