mirror of
https://github.com/moltbot/moltbot.git
synced 2026-05-10 20:45:15 +00:00
refactor: centralize channel ingress access
This commit is contained in:
111
scripts/check-no-deprecated-channel-access.ts
Normal file
111
scripts/check-no-deprecated-channel-access.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { collectFilesSync, isCodeFile, relativeToCwd } from "./check-file-utils.js";
|
||||
import { classifyBundledExtensionSourcePath } from "./lib/extension-source-classifier.mjs";
|
||||
|
||||
type Rule = {
|
||||
label: string;
|
||||
pattern: RegExp;
|
||||
};
|
||||
|
||||
const RULES: Rule[] = [
|
||||
{
|
||||
label: "deprecated channel ingress resolver aliases",
|
||||
pattern:
|
||||
/\b(?:resolved|result|directResolved|groupResolved)\.(?:legacyAccess|senderReasonCode|commandAuthorized|shouldBlockControlCommand)\b/u,
|
||||
},
|
||||
{
|
||||
label: "inline deprecated channel ingress legacyAccess projection",
|
||||
pattern: /\)\.legacyAccess\b/u,
|
||||
},
|
||||
{
|
||||
label: "low-level compatibility ingress resolver",
|
||||
pattern: /\bresolveChannelIngressAccess\b/u,
|
||||
},
|
||||
{
|
||||
label: "deprecated channel ingress compatibility projection",
|
||||
pattern:
|
||||
/\b(?:findChannelIngressSenderReasonCode|formatChannelIngressPolicyReason|mapChannelIngressReasonCodeToDmGroupAccessReason|projectChannelIngressDmGroupAccess|projectChannelIngressSenderGroupAccess)\b/u,
|
||||
},
|
||||
{
|
||||
label: "deprecated pairing-store access helper",
|
||||
pattern: /\breadStoreAllowFromForDmPolicy\b/u,
|
||||
},
|
||||
{
|
||||
label: "deprecated DM/group access helper",
|
||||
pattern: /\bresolveDmGroupAccessWith(?:Lists|CommandGate)\b/u,
|
||||
},
|
||||
{
|
||||
label: "deprecated DM/group access reason constants",
|
||||
pattern: /\bDM_GROUP_ACCESS_REASON\b/u,
|
||||
},
|
||||
{
|
||||
label: "deprecated group policy access helper",
|
||||
pattern:
|
||||
/\b(?:resolveSenderScopedGroupPolicy|evaluateSenderGroupAccess(?:ForPolicy)?|evaluateGroupRouteAccessForPolicy|evaluateMatchedGroupAccessForPolicy)\b/u,
|
||||
},
|
||||
{
|
||||
label: "deprecated group access compatibility module",
|
||||
pattern: /from\s+["']openclaw\/plugin-sdk\/group-access["']/u,
|
||||
},
|
||||
{
|
||||
label: "deprecated command authorization helper",
|
||||
pattern: /\bresolveSenderCommandAuthorization(?:WithRuntime)?\b/u,
|
||||
},
|
||||
{
|
||||
label: "deprecated command auth SDK facade",
|
||||
pattern: /from\s+["']openclaw\/plugin-sdk\/command-auth["']/u,
|
||||
},
|
||||
{
|
||||
label: "deprecated AccessFacts command authorizers",
|
||||
pattern: /\bcommands\.authorizers\b/u,
|
||||
},
|
||||
];
|
||||
|
||||
function collectBundledPluginProductionFiles(): string[] {
|
||||
const extensionsDir = path.join(process.cwd(), "extensions");
|
||||
return collectFilesSync(extensionsDir, {
|
||||
includeFile(filePath) {
|
||||
if (!isCodeFile(filePath)) {
|
||||
return false;
|
||||
}
|
||||
const repoPath = relativeToCwd(filePath);
|
||||
const classified = classifyBundledExtensionSourcePath(repoPath);
|
||||
return classified.isProductionSource;
|
||||
},
|
||||
}).toSorted((left, right) => relativeToCwd(left).localeCompare(relativeToCwd(right)));
|
||||
}
|
||||
|
||||
function main() {
|
||||
const offenders: Array<{ file: string; line: number; label: string; text: string }> = [];
|
||||
for (const file of collectBundledPluginProductionFiles()) {
|
||||
const content = fs.readFileSync(file, "utf8");
|
||||
const lines = content.split(/\r?\n/u);
|
||||
for (const [index, line] of lines.entries()) {
|
||||
for (const rule of RULES) {
|
||||
if (rule.pattern.test(line)) {
|
||||
offenders.push({
|
||||
file: relativeToCwd(file),
|
||||
line: index + 1,
|
||||
label: rule.label,
|
||||
text: line.trim(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (offenders.length > 0) {
|
||||
console.error(
|
||||
"Bundled plugin production code must use modern channel access results, not deprecated compatibility seams.",
|
||||
);
|
||||
for (const offender of offenders) {
|
||||
console.error(`- ${offender.file}:${offender.line}: ${offender.label}: ${offender.text}`);
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log("OK: bundled plugin production code avoids deprecated channel access seams.");
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
const { repoRoot, sourceRoots, resolveFromRepo } = createPairingGuardContext(import.meta.url);
|
||||
|
||||
const allowedFiles = new Set([
|
||||
resolveFromRepo("src/security/dm-policy-shared.ts"),
|
||||
resolveFromRepo("src/channels/message-access/legacy-policy.ts"),
|
||||
resolveFromRepo("src/channels/allow-from.ts"),
|
||||
// Config migration/audit logic may intentionally reference store + group fields.
|
||||
resolveFromRepo("src/security/fix.ts"),
|
||||
|
||||
@@ -39,6 +39,10 @@ export async function main(argv = process.argv.slice(2)) {
|
||||
name: "plugin-sdk wildcard re-exports",
|
||||
args: ["lint:extensions:no-plugin-sdk-wildcard-reexports"],
|
||||
},
|
||||
{
|
||||
name: "deprecated channel access seams",
|
||||
args: ["lint:extensions:no-deprecated-channel-access"],
|
||||
},
|
||||
{ name: "runtime sidecar loader guard", args: ["check:runtime-sidecar-loaders"] },
|
||||
{ name: "tool display", args: ["tool-display:check"] },
|
||||
{ name: "host env policy", args: ["check:host-env-policy:swift"] },
|
||||
|
||||
@@ -16,7 +16,10 @@ function docsFiles() {
|
||||
cwd: ROOT,
|
||||
encoding: "utf8",
|
||||
});
|
||||
return output.split("\n").filter(Boolean);
|
||||
return output
|
||||
.split("\n")
|
||||
.filter(Boolean)
|
||||
.filter((relativePath) => fs.existsSync(path.join(ROOT, relativePath)));
|
||||
}
|
||||
|
||||
function runOxfmt(files) {
|
||||
|
||||
@@ -50,6 +50,9 @@ export const pluginSdkDocMetadata = {
|
||||
"plugin-test-runtime": {
|
||||
category: "utilities",
|
||||
},
|
||||
"access-groups": {
|
||||
category: "channel",
|
||||
},
|
||||
"channel-actions": {
|
||||
category: "channel",
|
||||
},
|
||||
@@ -68,6 +71,12 @@ export const pluginSdkDocMetadata = {
|
||||
"channel-pairing": {
|
||||
category: "channel",
|
||||
},
|
||||
"channel-ingress": {
|
||||
category: "channel",
|
||||
},
|
||||
"channel-ingress-runtime": {
|
||||
category: "channel",
|
||||
},
|
||||
"channel-reply-pipeline": {
|
||||
category: "channel",
|
||||
},
|
||||
|
||||
@@ -131,6 +131,7 @@
|
||||
"account-resolution",
|
||||
"account-resolution-runtime",
|
||||
"agent-config-primitives",
|
||||
"access-groups",
|
||||
"allow-from",
|
||||
"allowlist-config-edit",
|
||||
"browser-config",
|
||||
@@ -177,6 +178,8 @@
|
||||
"channel-location",
|
||||
"channel-mention-gating",
|
||||
"channel-lifecycle",
|
||||
"channel-ingress",
|
||||
"channel-ingress-runtime",
|
||||
"channel-message",
|
||||
"channel-message-runtime",
|
||||
"channel-pairing",
|
||||
|
||||
Reference in New Issue
Block a user