@aalis/plugin-reach 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/credential.d.ts +3 -8
- package/dist/credential.d.ts.map +1 -1
- package/dist/credential.js +11 -30
- package/dist/credential.js.map +1 -1
- package/dist/index.d.ts +4 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -77
- package/dist/index.js.map +1 -1
- package/dist/locales/en.d.ts +5 -0
- package/dist/locales/en.d.ts.map +1 -0
- package/dist/locales/en.js +5 -0
- package/dist/locales/en.js.map +1 -0
- package/dist/process-env.d.ts +3 -2
- package/dist/process-env.d.ts.map +1 -1
- package/dist/process-env.js +25 -32
- package/dist/process-env.js.map +1 -1
- package/dist/texts.d.ts +9 -0
- package/dist/texts.d.ts.map +1 -0
- package/dist/texts.js +8 -0
- package/dist/texts.js.map +1 -0
- package/package.json +11 -13
- package/dist/provenance.d.ts +0 -12
- package/dist/provenance.d.ts.map +0 -1
- package/dist/provenance.js +0 -74
- package/dist/provenance.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @aalis/plugin-reach
|
|
2
2
|
|
|
3
|
-
触及:按一次工具调用签发触及凭据(契约见 `@aalis/api-reach
|
|
3
|
+
触及:按一次工具调用签发触及凭据(契约见 `@aalis/api-reach`)。主体取权限服务的 `principalOf`,场所与绑定取会话管理里的记录,档位与越界策略固定,三张受保护清单在激活时按家目录布局与真实路径算好,交给 `resolveReach` 定上限:主体是 owner 的调用有本地效果,不看会话的受众(主体的判法见权限服务的 `principalOf`:续做与子任务的类别随起它的那一轮,参与者按这次调用的)。另管本会话临时区(建、随会话删、定期清扫)与子进程环境(owner 的 login shell 环境,沙箱内同样完整,只去掉本实例的变量与 ssh-agent 的 socket)。
|
|
4
4
|
|
|
5
5
|
## 角色
|
|
6
6
|
|
package/dist/credential.d.ts
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type Reach, type ReachCredential } from '@aalis/api-reach';
|
|
2
2
|
interface CredentialDeps {
|
|
3
|
-
|
|
4
|
-
/** 舞台上放各场所白纸的目录:写进这里的才进来源账本 */
|
|
5
|
-
papers: string;
|
|
6
|
-
/** 操作系统用户的家目录:沙箱里 npm 的用户配置从这里的 .npmrc 去掉凭据行 */
|
|
3
|
+
/** 操作系统用户的家目录:沙箱里 npm 的用户配置从这里的 .npmrc 去掉 npm 的认证键 */
|
|
7
4
|
userHome: string;
|
|
8
5
|
/** 在场所的主目录下取的 login shell 环境 */
|
|
9
6
|
loginEnv(home: string): Promise<Record<string, string>>;
|
|
10
|
-
/** 记进来源账本 */
|
|
11
|
-
record(realPath: string, entry: ProvenanceRecord): void;
|
|
12
7
|
}
|
|
13
|
-
/** current
|
|
8
|
+
/** current 每次调用都算出这次调用当时的触及 */
|
|
14
9
|
export declare function issueCredential(current: () => Reach, deps: CredentialDeps): ReachCredential;
|
|
15
10
|
export {};
|
|
16
11
|
//# sourceMappingURL=credential.d.ts.map
|
package/dist/credential.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credential.d.ts","sourceRoot":"","sources":["../src/credential.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"credential.d.ts","sourceRoot":"","sources":["../src/credential.ts"],"names":[],"mappings":"AAMA,OAAO,EAGL,KAAK,KAAK,EAEV,KAAK,eAAe,EAIrB,MAAM,kBAAkB,CAAC;AAG1B,UAAU,cAAc;IACtB,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACzD;AAED,+BAA+B;AAC/B,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,KAAK,EAAE,IAAI,EAAE,cAAc,GAAG,eAAe,CAoB3F"}
|
package/dist/credential.js
CHANGED
|
@@ -1,29 +1,20 @@
|
|
|
1
1
|
// ============================================================
|
|
2
2
|
// 触及凭据:按一次工具调用签发,带品牌符号,冻结
|
|
3
3
|
//
|
|
4
|
-
//
|
|
5
|
-
// 签发之后降档或受污染立即生效。
|
|
4
|
+
// 签发时的触及定下命令在哪执行、场所的主目录、子进程环境;判定、存储兜底与沙箱策略每次按当时的触及。
|
|
6
5
|
// ============================================================
|
|
7
|
-
import { judgeReach,
|
|
6
|
+
import { judgeReach, REACH_CREDENTIAL, sandboxPolicyOf, } from '@aalis/api-reach';
|
|
8
7
|
import { sandboxEnv } from './process-env.js';
|
|
9
|
-
/** current
|
|
8
|
+
/** current 每次调用都算出这次调用当时的触及 */
|
|
10
9
|
export function issueCredential(current, deps) {
|
|
11
10
|
const issued = current();
|
|
12
11
|
const local = issued.exec === 'none' ? undefined : issued;
|
|
13
12
|
const credential = {
|
|
14
13
|
exec: issued.exec,
|
|
15
|
-
...(local && {
|
|
16
|
-
home: local.home,
|
|
17
|
-
paper: local.paper,
|
|
18
|
-
// 全权档不带:全权不提示,确认卡上也不写来源
|
|
19
|
-
...(local.tainted && local.tier !== 'full' && { tainted: local.tainted }),
|
|
20
|
-
}),
|
|
14
|
+
...(local && { home: local.home }),
|
|
21
15
|
async require(request) {
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
return decision.verdict === 'allow'
|
|
25
|
-
? { allowed: true }
|
|
26
|
-
: { allowed: false, message: explain(decision, request, reach.exec === 'none' ? undefined : reach.tainted) };
|
|
16
|
+
const decision = judgeReach(current(), request);
|
|
17
|
+
return decision.verdict === 'allow' ? { allowed: true } : { allowed: false, message: explain(decision, request) };
|
|
27
18
|
},
|
|
28
19
|
allows: (effect, realPath) => judgeReach(current(), { effect, path: realPath }).verdict === 'allow',
|
|
29
20
|
sandboxPolicy: () => sandboxPolicyOf(current()),
|
|
@@ -33,32 +24,24 @@ export function issueCredential(current, deps) {
|
|
|
33
24
|
const env = await deps.loginEnv(local.home);
|
|
34
25
|
return mode === 'host' ? { ...env } : sandboxEnv(env, local.sessionTmp, deps.userHome);
|
|
35
26
|
},
|
|
36
|
-
noteWrite(realPath) {
|
|
37
|
-
const reach = current();
|
|
38
|
-
if (reach.exec === 'none' || !reach.tainted)
|
|
39
|
-
return;
|
|
40
|
-
if (!matchesRule({ path: deps.papers }, realPath, reach.lists.platform))
|
|
41
|
-
return;
|
|
42
|
-
deps.record(realPath, { sessionId: deps.sessionId, sources: reach.tainted, at: Date.now() });
|
|
43
|
-
},
|
|
44
27
|
};
|
|
45
28
|
// 品牌不可枚举:展开或 Object.assign 复制出来、改了方法再转交的对象不带它
|
|
46
29
|
return Object.freeze(Object.defineProperty(credential, REACH_CREDENTIAL, { value: true }));
|
|
47
30
|
}
|
|
48
31
|
/** 回给模型的话:要做什么、为什么不行、能不能申请 */
|
|
49
|
-
function explain(decision, request
|
|
32
|
+
function explain(decision, request) {
|
|
50
33
|
const subject = subjectOf(request);
|
|
51
34
|
if (decision.verdict === 'ask')
|
|
52
|
-
return `${subject}:${why(decision.reason
|
|
35
|
+
return `${subject}:${why(decision.reason)},要 owner 批准,这里没有可用的审批`;
|
|
53
36
|
switch (decision.rule) {
|
|
54
37
|
case 'no-local-effect':
|
|
55
|
-
return `${subject}
|
|
38
|
+
return `${subject}:这一轮不只有 owner 的话,没有本地效果`;
|
|
56
39
|
case 'control-plane':
|
|
57
40
|
return `${subject}:在宿主控制面里,任何档位都不能写;不可申请,不要尝试绕过`;
|
|
58
41
|
case 'deny-read':
|
|
59
42
|
return `${subject}:在拒读清单里;不可申请,不要尝试绕过`;
|
|
60
43
|
case 'boundary-policy':
|
|
61
|
-
return `${subject}:${why(decision.reason
|
|
44
|
+
return `${subject}:${why(decision.reason)},越界策略是直接拒绝`;
|
|
62
45
|
}
|
|
63
46
|
}
|
|
64
47
|
function subjectOf(request) {
|
|
@@ -73,7 +56,7 @@ function subjectOf(request) {
|
|
|
73
56
|
return { url: '访问模型给的网址', command: '执行要联网的命令', provider: '联网' }[request.via];
|
|
74
57
|
}
|
|
75
58
|
}
|
|
76
|
-
function why(reason
|
|
59
|
+
function why(reason) {
|
|
77
60
|
switch (reason.kind) {
|
|
78
61
|
case 'tier':
|
|
79
62
|
return '修改确认档里每一次写与执行都要问';
|
|
@@ -81,8 +64,6 @@ function why(reason, tainted) {
|
|
|
81
64
|
return { 'write-path': '超出了可写范围', 'host-exec': '要在沙箱外执行', network: '只读档里联网要问' }[reason.target];
|
|
82
65
|
case 'landing':
|
|
83
66
|
return '这里会被自动执行或用于持久化';
|
|
84
|
-
case 'outbound':
|
|
85
|
-
return `这个会话读进过别人写的内容(${tainted?.join('、')}),这一步会把内容送出会话`;
|
|
86
67
|
}
|
|
87
68
|
}
|
|
88
69
|
//# sourceMappingURL=credential.js.map
|
package/dist/credential.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credential.js","sourceRoot":"","sources":["../src/credential.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,0BAA0B;AAC1B,EAAE;AACF,
|
|
1
|
+
{"version":3,"file":"credential.js","sourceRoot":"","sources":["../src/credential.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,13 +4,11 @@ declare const _default: import("@aalis/core").PluginDefinition<{
|
|
|
4
4
|
events: import("@aalis/core").ServiceDescriptor<(identity: symbol) => import("@aalis/core").Events, import("@aalis/core").Events>;
|
|
5
5
|
lifecycle: import("@aalis/core").ServiceDescriptor<(identity: symbol) => import("@aalis/core").LifecycleCap, import("@aalis/core").LifecycleCap>;
|
|
6
6
|
logger: import("@aalis/core").ServiceDescriptor<(identity: symbol) => import("@aalis/core").Logger, import("@aalis/core").Logger>;
|
|
7
|
-
/**
|
|
7
|
+
/** 家目录布局:三张清单、默认工作区与本会话临时区都按它 */
|
|
8
8
|
paths: import("@aalis/core").ServiceDescriptor<HostPaths, HostPaths>;
|
|
9
|
-
/**
|
|
10
|
-
sessionManager: import("@aalis/core").ServiceDescriptor<import("@aalis/api-session-manager").SessionManagerService, import("@aalis/api-session-manager").
|
|
11
|
-
/**
|
|
12
|
-
storage: import("@aalis/core").ServiceDescriptor<import("@aalis/api-storage").StorageService, import("@aalis/api-storage").BoundStorage>;
|
|
13
|
-
/** 发起类别与 owner 判定;缺席时谁都不是 owner,一律没有本地效果 */
|
|
9
|
+
/** 会话记录与绑定 */
|
|
10
|
+
sessionManager: import("@aalis/core").ServiceDescriptor<import("@aalis/api-session-manager").SessionManagerService, import("@aalis/api-session-manager").SessionManagerService>;
|
|
11
|
+
/** 这一轮的主体;缺席时谁都不是 owner,一律没有本地效果 */
|
|
14
12
|
authority: import("@aalis/core").OptionalUse<import("@aalis/api-authority").AuthorityService, import("@aalis/api-authority").AuthorityService>;
|
|
15
13
|
/** 取 owner 的 login shell 环境;缺席时子进程用守护进程的环境 */
|
|
16
14
|
process: import("@aalis/core").OptionalUse<import("@aalis/api-process").ProcessService, import("@aalis/api-process").ProcessService>;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,SAAS,EAAa,MAAM,uBAAuB,CAAC;;;;;;IAuChE,iCAAiC;;IAEjC,cAAc;;IAEd,oCAAoC;;IAEpC,8CAA8C;;;AAKhD,wBAOG"}
|
package/dist/index.js
CHANGED
|
@@ -2,28 +2,26 @@
|
|
|
2
2
|
import { mkdir, realpath, rm } from 'node:fs/promises';
|
|
3
3
|
// biome-ignore lint/style/noRestrictedImports: 拒读清单与落点按操作系统用户的家目录生成
|
|
4
4
|
import { homedir } from 'node:os';
|
|
5
|
-
import { join } from 'node:path';
|
|
6
5
|
import { authority } from '@aalis/api-authority';
|
|
7
6
|
import { hostPaths } from '@aalis/api-host-paths';
|
|
8
7
|
import { processService } from '@aalis/api-process';
|
|
9
8
|
import { protectedLists, reach, resolveReach, withRealRoots, } from '@aalis/api-reach';
|
|
10
|
-
import {
|
|
11
|
-
import { storage } from '@aalis/api-storage';
|
|
9
|
+
import { rootSessionOf, sessionManager } from '@aalis/api-session-manager';
|
|
12
10
|
import { definePlugin, events, lifecycle, logger, optional, provide } from '@aalis/core';
|
|
13
11
|
import { issueCredential } from './credential.js';
|
|
14
12
|
import { codeDirsOf, entryOf, formOf, gitDirOf, realRootsOf } from './host-dirs.js';
|
|
15
13
|
import { loginEnvs } from './process-env.js';
|
|
16
|
-
import { openProvenance } from './provenance.js';
|
|
17
14
|
import { SWEEP_EVERY_MS, sessionTmpOf, sweepSessionTmp } from './session-tmp.js';
|
|
15
|
+
import { t } from './texts.js';
|
|
18
16
|
// ════════════════════════════════════════════════════════════
|
|
19
17
|
// plugin-reach —— 触及服务(契约见 @aalis/api-reach)
|
|
20
18
|
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
//
|
|
19
|
+
// 按一次工具调用签发凭据:主体取权限服务的 principalOf(类别为人亲手、这次调用的参与者都是 owner 的为 owner;续做与子任务的
|
|
20
|
+
// 类别随起它的那一轮,批过的调用参与者是批的人),不看会话的受众;绑定取会话管理里的记录,主目录是绑定目录、没有绑定的是默认
|
|
21
|
+
// 工作区目录,档位与越界策略固定(工作区档、越界要问),仓库的 git 目录按磁盘找,三张清单在激活时按家目录布局与真实路径算好;
|
|
22
|
+
// 交给 api-reach 的 resolveReach 定上限。绑定与 git 目录在签发时取好。另管本会话临时区与子进程环境。
|
|
25
23
|
// ════════════════════════════════════════════════════════════
|
|
26
|
-
/**
|
|
24
|
+
/** 档位与越界策略:还不能按会话设,固定为工作区档、越界要问 */
|
|
27
25
|
const DEFAULT_TIER = 'workspace';
|
|
28
26
|
const DEFAULT_BOUNDARY = 'ask';
|
|
29
27
|
const uses = {
|
|
@@ -31,20 +29,18 @@ const uses = {
|
|
|
31
29
|
events,
|
|
32
30
|
lifecycle,
|
|
33
31
|
logger,
|
|
34
|
-
/**
|
|
32
|
+
/** 家目录布局:三张清单、默认工作区与本会话临时区都按它 */
|
|
35
33
|
paths: hostPaths,
|
|
36
|
-
/**
|
|
34
|
+
/** 会话记录与绑定 */
|
|
37
35
|
sessionManager,
|
|
38
|
-
/**
|
|
39
|
-
storage,
|
|
40
|
-
/** 发起类别与 owner 判定;缺席时谁都不是 owner,一律没有本地效果 */
|
|
36
|
+
/** 这一轮的主体;缺席时谁都不是 owner,一律没有本地效果 */
|
|
41
37
|
authority: optional(authority),
|
|
42
38
|
/** 取 owner 的 login shell 环境;缺席时子进程用守护进程的环境 */
|
|
43
39
|
process: optional(processService),
|
|
44
40
|
};
|
|
45
41
|
export default definePlugin({
|
|
46
42
|
name: '@aalis/plugin-reach',
|
|
47
|
-
displayName: '
|
|
43
|
+
displayName: t('displayName'),
|
|
48
44
|
subsystem: 'authority',
|
|
49
45
|
provides: [reach],
|
|
50
46
|
uses,
|
|
@@ -54,7 +50,6 @@ async function run(caps) {
|
|
|
54
50
|
const { events, lifecycle, logger } = caps;
|
|
55
51
|
const sm = caps.sessionManager.use;
|
|
56
52
|
const lookup = (id) => sm.getSession(id);
|
|
57
|
-
const isOwner = (platform, userId) => caps.authority.present ? caps.authority.use.isOwner(platform, userId) : false;
|
|
58
53
|
// 清单与路径比较一律用真实路径:安装集可能经符号链接给出,用户家目录同理;清单里链接出去的根按真实路径补一份
|
|
59
54
|
const given = caps.paths.use;
|
|
60
55
|
const app = await realpath(given.app);
|
|
@@ -71,65 +66,34 @@ async function run(caps) {
|
|
|
71
66
|
});
|
|
72
67
|
const realRoots = await realRootsOf(declared, logger.use);
|
|
73
68
|
const lists = withRealRoots(declared, root => realRoots.get(root));
|
|
74
|
-
const provenance = await openProvenance(caps.storage.use.own, logger.use);
|
|
75
69
|
const loginEnv = loginEnvs({ process: caps.process, userHome, logger: logger.use });
|
|
76
|
-
/** 会话所在场所的白纸目录:白纸 id 由场所键算出,目录名把 `:` 换成 `-`(与白纸插件同一写法) */
|
|
77
|
-
const paperOf = (sessionId) => join(paths.stage.paper, placePaperId(sm.placeOf(sessionId).key).replace(':', '-'));
|
|
78
|
-
/** 每个会话最近一次签发凭据的那一轮的主体:子任务的任务消息发出时,据它定那条消息之后的子任务回合随谁 */
|
|
79
|
-
const lastPrincipal = new Map();
|
|
80
|
-
/** 子会话:发来最近一条任务消息的那一轮父会话的主体 */
|
|
81
|
-
const spawnedBy = new Map();
|
|
82
70
|
/** 删会话时在后台删着的临时区 */
|
|
83
71
|
const deleting = new Map();
|
|
84
|
-
/**
|
|
85
|
-
|
|
86
|
-
* 自己的,按根会话的生效设置)、房间类别、污点与子任务的父会话在每次调用时取当时的
|
|
87
|
-
*/
|
|
88
|
-
async function reachOf(sessionId, platform, principal) {
|
|
72
|
+
/** 一个会话的触及,返回每次调用都重算的函数:绑定与仓库的 git 目录(按磁盘找,异步)在这里取好 */
|
|
73
|
+
async function reachOf(sessionId, principal) {
|
|
89
74
|
const work = rootSessionOf(sm.getSession(sessionId), lookup)?.work;
|
|
90
75
|
const gitDir = work && (await gitDirOf(work.root));
|
|
91
|
-
return () => {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
gitDirs: gitDir ? [gitDir] : [],
|
|
105
|
-
sessionTmp: sessionTmpOf(paths.tmp, sessionId),
|
|
106
|
-
othersContent: [],
|
|
107
|
-
localPorts: [],
|
|
108
|
-
lists,
|
|
109
|
-
paths,
|
|
110
|
-
});
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
async function principalOf(call) {
|
|
114
|
-
const origin = caps.authority.present ? caps.authority.use.originOf(call) : undefined;
|
|
115
|
-
if (origin === 'subtask') {
|
|
116
|
-
const parentId = sm.getSession(call.sessionId)?.parentId;
|
|
117
|
-
return parentId && spawnedBy.get(call.sessionId) === 'owner'
|
|
118
|
-
? reachOf(parentId, call.platform, 'owner')
|
|
119
|
-
: 'other';
|
|
120
|
-
}
|
|
121
|
-
const principal = origin === 'owner' || origin === 'owner-chain' ? 'owner' : 'other';
|
|
122
|
-
lastPrincipal.set(call.sessionId, principal);
|
|
123
|
-
return principal;
|
|
76
|
+
return () => resolveReach({
|
|
77
|
+
principal,
|
|
78
|
+
tier: DEFAULT_TIER,
|
|
79
|
+
onBoundary: DEFAULT_BOUNDARY,
|
|
80
|
+
// 主目录:项目工作区是绑定目录,其余是默认工作区目录
|
|
81
|
+
place: { home: work?.root ?? paths.workspace },
|
|
82
|
+
binding: work,
|
|
83
|
+
gitDirs: gitDir ? [gitDir] : [],
|
|
84
|
+
sessionTmp: sessionTmpOf(paths.tmp, sessionId),
|
|
85
|
+
localPorts: [],
|
|
86
|
+
lists,
|
|
87
|
+
paths,
|
|
88
|
+
});
|
|
124
89
|
}
|
|
125
90
|
const service = {
|
|
126
91
|
async forCall(call) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
92
|
+
// 这一轮的主体:权限服务不在时是 other
|
|
93
|
+
const principal = caps.authority.present ? caps.authority.use.principalOf(call) : 'other';
|
|
94
|
+
const credential = issueCredential(await reachOf(call.sessionId, principal), {
|
|
130
95
|
userHome,
|
|
131
96
|
loginEnv,
|
|
132
|
-
record: provenance.record,
|
|
133
97
|
});
|
|
134
98
|
if (credential.exec !== 'none') {
|
|
135
99
|
// 同一个 id 的会话删了又建:前一份还在删,先等它删完,免得删掉新建的
|
|
@@ -138,20 +102,9 @@ async function run(caps) {
|
|
|
138
102
|
}
|
|
139
103
|
return credential;
|
|
140
104
|
},
|
|
141
|
-
markTainted: provenance.markTainted,
|
|
142
|
-
provenanceOf: provenance.provenanceOf,
|
|
143
105
|
};
|
|
144
|
-
// 子任务插件在父会话的一轮里发出任务消息(source 为 subtask):那一轮的主体就是这条消息之后的子任务回合的主体
|
|
145
|
-
events.use.on('inbound:message', (msg) => {
|
|
146
|
-
if (msg.source !== 'subtask' || !msg.sessionId)
|
|
147
|
-
return;
|
|
148
|
-
const parentId = sm.getSession(msg.sessionId)?.parentId;
|
|
149
|
-
spawnedBy.set(msg.sessionId, (parentId && lastPrincipal.get(parentId)) || 'other');
|
|
150
|
-
});
|
|
151
106
|
// 删会话时在后台删它的临时区,不拖住删会话;删不掉记 warn
|
|
152
107
|
events.use.on('session:deleted', sessionId => {
|
|
153
|
-
lastPrincipal.delete(sessionId);
|
|
154
|
-
spawnedBy.delete(sessionId);
|
|
155
108
|
const dir = sessionTmpOf(paths.tmp, sessionId);
|
|
156
109
|
const done = rm(dir, { recursive: true, force: true })
|
|
157
110
|
.catch(err => logger.use.warn(`删不掉会话 ${sessionId} 的临时区 ${dir}:`, err))
|
|
@@ -177,7 +130,7 @@ async function run(caps) {
|
|
|
177
130
|
sweepTimer.unref();
|
|
178
131
|
lifecycle.use.onDispose(async () => {
|
|
179
132
|
clearInterval(sweepTimer);
|
|
180
|
-
await Promise.all([sweeping, ...deleting.values()
|
|
133
|
+
await Promise.all([sweeping, ...deleting.values()]);
|
|
181
134
|
});
|
|
182
135
|
caps.provide.use(reach, service);
|
|
183
136
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACvD,oEAAoE;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../src/locales/en.ts"],"names":[],"mappings":";;;AAGA,wBAEG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"en.js","sourceRoot":"","sources":["../../src/locales/en.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,eAAe,YAAY,EAAU,CAAC;IACpC,WAAW,EAAE,OAAO;CACrB,CAAC,CAAC"}
|
package/dist/process-env.d.ts
CHANGED
|
@@ -8,8 +8,9 @@ export declare function loginEnvs(deps: {
|
|
|
8
8
|
logger: Logger;
|
|
9
9
|
}): (home: string) => Promise<Env>;
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* 沙箱里的命令拿到的环境:完整的登录环境去掉本实例的变量与 ssh-agent 的 socket,注入 npm 的用户配置(去掉认证键的副本,写在
|
|
12
|
+
* 本会话临时区)、本机 Node 的头文件、浏览器的缓存目录,关掉 pnpm 的构建产物缓存(沙箱里构建出的产物不能被沙箱外的安装直接
|
|
13
|
+
* 复用),SSH 地址的拉取走 HTTPS
|
|
13
14
|
*/
|
|
14
15
|
export declare function sandboxEnv(login: Env, sessionTmp: string, userHome: string): Promise<Env>;
|
|
15
16
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-env.d.ts","sourceRoot":"","sources":["../src/process-env.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"process-env.d.ts","sourceRoot":"","sources":["../src/process-env.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG5D,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAmBlC,8DAA8D;AAC9D,wBAAgB,SAAS,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,IAuCrG,MAAM,MAAM,KAAG,OAAO,CAAC,GAAG,CAAC,CAcpC;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CA8C/F"}
|
package/dist/process-env.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
// ============================================================
|
|
2
|
-
// 子进程环境:owner 的 login shell
|
|
2
|
+
// 子进程环境:owner 的 login shell 环境,沙箱内另去掉两样并注入沙箱要的几项
|
|
3
3
|
//
|
|
4
4
|
// 环境在场所的主目录下用 owner 的 login shell 取一次(项目的 .nvmrc、venv 这类按目录选的工具链与 owner 自己的终端一致),
|
|
5
5
|
// 缓存在内存,不落盘;取不到时用守护进程的环境,1 分钟后再取(一次超时不能让这个主目录一直用守护进程的环境)。
|
|
6
|
-
//
|
|
7
|
-
//
|
|
6
|
+
// 宿主执行与沙箱里的命令都拿到完整的登录环境,不按名字或值猜凭据:能进沙箱的只有主体是 owner 的一轮,密钥不靠出口过滤,
|
|
7
|
+
// 靠权限隔离。沙箱里只去掉本实例自己的变量与 ssh-agent 的 socket,git 的命令行配置接上沙箱要的几项,npm 的用户配置换成
|
|
8
|
+
// 去掉认证键的副本。
|
|
8
9
|
// ============================================================
|
|
9
|
-
// biome-ignore lint/style/noRestrictedImports: 读用户家目录的 .npmrc
|
|
10
|
+
// biome-ignore lint/style/noRestrictedImports: 读用户家目录的 .npmrc、在本会话临时区写去掉认证键的副本(不跟随链接)、按 PATH 找本机 Node 的头文件,这些路径不在存储根里
|
|
10
11
|
import { access, lstat, readFile, realpath, rename, stat, writeFile } from 'node:fs/promises';
|
|
11
12
|
// biome-ignore lint/style/noRestrictedImports: 没有 SHELL 时取操作系统账户登记的 login shell
|
|
12
13
|
import { userInfo } from 'node:os';
|
|
@@ -16,29 +17,17 @@ import { isMissing } from './host-dirs.js';
|
|
|
16
17
|
const CAPTURE_TIMEOUT_MS = 10_000;
|
|
17
18
|
/** 取不到时这么久之后再取 */
|
|
18
19
|
const RETRY_AFTER_MS = 60_000;
|
|
19
|
-
/**
|
|
20
|
-
const
|
|
21
|
-
/**
|
|
22
|
-
const
|
|
23
|
-
/**
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
/** git 的命令行配置:值里可能是凭据(如 extraheader 的认证头),整组不进沙箱,沙箱要的另从 0 编号注入 */
|
|
28
|
-
const GIT_CONFIG_ENV = /^GIT_CONFIG_(COUNT$|PARAMETERS$|KEY_|VALUE_)/;
|
|
29
|
-
/** npm 配置里的凭据行:令牌、用户名与密码、客户端证书与私钥(文件或内联) */
|
|
20
|
+
/** AALIS_ 开头的是实例自己的命名空间(家目录这类本实例的配置),不交给沙箱里的命令 */
|
|
21
|
+
const INSTANCE_VARS = /^AALIS_/;
|
|
22
|
+
/** ssh-agent 的 socket:ssh-agent 不对沙箱开放,经 SSH 的推送要宿主执行 */
|
|
23
|
+
const SSH_AGENT_SOCK = 'SSH_AUTH_SOCK';
|
|
24
|
+
/**
|
|
25
|
+
* npm 定义的认证键:令牌、用户名与密码、客户端证书与私钥(文件或内联)。~/.npmrc 在拒读清单里,沙箱里的 npm 读的是去掉这些键
|
|
26
|
+
* 的副本
|
|
27
|
+
*/
|
|
30
28
|
const NPMRC_SECRET = /(^|:)(_authToken|_auth|_password|username|password|(cert|key)(file)?)\s*=/i;
|
|
31
|
-
/**
|
|
29
|
+
/** SSH 地址的拉取改走 HTTPS(沙箱里没有 SSH 凭据),推送仍是 SSH(沙箱里推不了,要宿主执行) */
|
|
32
30
|
const HTTPS_HOSTS = ['github.com', 'gitlab.com'];
|
|
33
|
-
function isSecret(name, value) {
|
|
34
|
-
return (SECRET_NAMES.test(name) ||
|
|
35
|
-
SECRET_WORDS.test(name) ||
|
|
36
|
-
name
|
|
37
|
-
.toUpperCase()
|
|
38
|
-
.split('_')
|
|
39
|
-
.some(segment => SECRET_SEGMENTS.has(segment)) ||
|
|
40
|
-
URL_WITH_PASSWORD.test(value));
|
|
41
|
-
}
|
|
42
31
|
/** 按 owner 的 login shell 取环境的入口:同一个主目录取到一次就一直用,同时来的调用共用一次取 */
|
|
43
32
|
export function loginEnvs(deps) {
|
|
44
33
|
const cache = new Map();
|
|
@@ -51,7 +40,7 @@ export function loginEnvs(deps) {
|
|
|
51
40
|
const shell = process.env.SHELL || userInfo().shell;
|
|
52
41
|
if (!shell)
|
|
53
42
|
throw new Error('不知道 owner 的 login shell(没有 SHELL,账户也没登记)');
|
|
54
|
-
//
|
|
43
|
+
// 默认工作区目录由 runtime 初始化时建;主目录不在(如被删掉)时在用户家目录下取,与新开一个终端相同
|
|
55
44
|
const cwd = await stat(home).then(s => (s.isDirectory() ? home : deps.userHome), () => deps.userHome);
|
|
56
45
|
const mark = `__AALIS_ENV_${crypto.randomUUID()}__`;
|
|
57
46
|
const { stdout } = await proc.execFile(shell, ['-i', '-l', '-c', `printf '%s' '${mark}'; /usr/bin/env -0`], {
|
|
@@ -91,11 +80,12 @@ export function loginEnvs(deps) {
|
|
|
91
80
|
};
|
|
92
81
|
}
|
|
93
82
|
/**
|
|
94
|
-
*
|
|
95
|
-
*
|
|
83
|
+
* 沙箱里的命令拿到的环境:完整的登录环境去掉本实例的变量与 ssh-agent 的 socket,注入 npm 的用户配置(去掉认证键的副本,写在
|
|
84
|
+
* 本会话临时区)、本机 Node 的头文件、浏览器的缓存目录,关掉 pnpm 的构建产物缓存(沙箱里构建出的产物不能被沙箱外的安装直接
|
|
85
|
+
* 复用),SSH 地址的拉取走 HTTPS
|
|
96
86
|
*/
|
|
97
87
|
export async function sandboxEnv(login, sessionTmp, userHome) {
|
|
98
|
-
const env = Object.fromEntries(Object.entries(login).filter(([name
|
|
88
|
+
const env = Object.fromEntries(Object.entries(login).filter(([name]) => !INSTANCE_VARS.test(name) && name !== SSH_AGENT_SOCK));
|
|
99
89
|
const npmrc = join(sessionTmp, 'npmrc');
|
|
100
90
|
const owned = await readFile(join(userHome, '.npmrc'), 'utf8').catch(err => {
|
|
101
91
|
if (isMissing(err))
|
|
@@ -129,11 +119,14 @@ export async function sandboxEnv(login, sessionTmp, userHome) {
|
|
|
129
119
|
[`url.git@${host}:.pushInsteadOf`, `git@${host}:`],
|
|
130
120
|
[`url.ssh://git@${host}/.pushInsteadOf`, `ssh://git@${host}/`],
|
|
131
121
|
]);
|
|
122
|
+
// git 的命令行配置只有一组连续编号:沙箱要的几项接在登录环境原有的那组后面重新编号,原有的照留(计数不是数字时 git 本就
|
|
123
|
+
// 读不了那组,从 0 编号)
|
|
124
|
+
const base = /^\d+$/.test(env.GIT_CONFIG_COUNT ?? '') ? Number(env.GIT_CONFIG_COUNT) : 0;
|
|
132
125
|
git.forEach(([key, value], i) => {
|
|
133
|
-
env[`GIT_CONFIG_KEY_${i}`] = key;
|
|
134
|
-
env[`GIT_CONFIG_VALUE_${i}`] = value;
|
|
126
|
+
env[`GIT_CONFIG_KEY_${base + i}`] = key;
|
|
127
|
+
env[`GIT_CONFIG_VALUE_${base + i}`] = value;
|
|
135
128
|
});
|
|
136
|
-
env.GIT_CONFIG_COUNT = String(git.length);
|
|
129
|
+
env.GIT_CONFIG_COUNT = String(base + git.length);
|
|
137
130
|
return { ...env, ...injected };
|
|
138
131
|
}
|
|
139
132
|
/** 这份 PATH 上的 node 所在的安装(带头文件的才算):源码编译原生模块时 node-gyp 用它,不必去下载头文件 */
|
package/dist/process-env.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-env.js","sourceRoot":"","sources":["../src/process-env.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,
|
|
1
|
+
{"version":3,"file":"process-env.js","sourceRoot":"","sources":["../src/process-env.ts"],"names":[],"mappings":"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"}
|
package/dist/texts.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"texts.d.ts","sourceRoot":"","sources":["../src/texts.ts"],"names":[],"mappings":"AAIA,QAAA,MAAM,MAAM;;CAEF,CAAC;AACX,MAAM,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC;AAEnC,eAAO,MAAM,CAAC;;EAAiG,CAAC"}
|
package/dist/texts.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// 本插件自己的原文字典:显示名
|
|
2
|
+
import { defineTexts } from '@aalis/schema-i18n';
|
|
3
|
+
import en from './locales/en.js';
|
|
4
|
+
const SOURCE = {
|
|
5
|
+
displayName: '触及',
|
|
6
|
+
};
|
|
7
|
+
export const t = defineTexts({ ns: '@aalis/plugin-reach', language: 'zh-CN', source: SOURCE, locales: { en } });
|
|
8
|
+
//# sourceMappingURL=texts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"texts.js","sourceRoot":"","sources":["../src/texts.ts"],"names":[],"mappings":"AAAA,iBAAiB;AACjB,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAEjC,MAAM,MAAM,GAAG;IACb,WAAW,EAAE,IAAI;CACT,CAAC;AAGX,MAAM,CAAC,MAAM,CAAC,GAAG,WAAW,CAAC,EAAE,EAAE,EAAE,qBAAqB,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aalis/plugin-reach",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"url": "https://github.com/AalisLabs/Aalis/issues"
|
|
13
13
|
},
|
|
14
14
|
"homepage": "https://github.com/AalisLabs/Aalis#readme",
|
|
15
|
-
"description": "
|
|
15
|
+
"description": "触及:按一次工具调用签发触及凭据(这一轮的主体、档位与场所定下本机能读写执行什么),管本会话临时区与子进程环境",
|
|
16
16
|
"type": "module",
|
|
17
17
|
"keywords": [
|
|
18
18
|
"aalis",
|
|
@@ -24,21 +24,20 @@
|
|
|
24
24
|
"dist"
|
|
25
25
|
],
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@aalis/api-authority": ">=0.
|
|
28
|
-
"@aalis/api-host-paths": ">=0.
|
|
29
|
-
"@aalis/api-process": ">=0.
|
|
30
|
-
"@aalis/api-reach": ">=0.
|
|
31
|
-
"@aalis/api-session-manager": ">=0.
|
|
32
|
-
"@aalis/
|
|
33
|
-
"@aalis/schema-message": ">=0.10.0 <1.0.0"
|
|
27
|
+
"@aalis/api-authority": ">=0.12.0 <1.0.0",
|
|
28
|
+
"@aalis/api-host-paths": ">=0.2.0 <1.0.0",
|
|
29
|
+
"@aalis/api-process": ">=0.10.0 <1.0.0",
|
|
30
|
+
"@aalis/api-reach": ">=0.3.0 <1.0.0",
|
|
31
|
+
"@aalis/api-session-manager": ">=0.12.0 <1.0.0",
|
|
32
|
+
"@aalis/schema-i18n": ">=0.1.0 <1.0.0"
|
|
34
33
|
},
|
|
35
34
|
"devDependencies": {
|
|
36
35
|
"@types/node": "^22.0.0",
|
|
37
36
|
"typescript": "^5.7.0",
|
|
38
|
-
"@aalis/core": "0.
|
|
37
|
+
"@aalis/core": "0.21.0"
|
|
39
38
|
},
|
|
40
39
|
"peerDependencies": {
|
|
41
|
-
"@aalis/core": ">=0.
|
|
40
|
+
"@aalis/core": ">=0.21.0 <1.0.0"
|
|
42
41
|
},
|
|
43
42
|
"aalis": {
|
|
44
43
|
"service": {
|
|
@@ -55,8 +54,7 @@
|
|
|
55
54
|
"lifecycle",
|
|
56
55
|
"logger",
|
|
57
56
|
"provide",
|
|
58
|
-
"session-manager"
|
|
59
|
-
"storage"
|
|
57
|
+
"session-manager"
|
|
60
58
|
]
|
|
61
59
|
}
|
|
62
60
|
},
|
package/dist/provenance.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { ProvenanceRecord } from '@aalis/api-reach';
|
|
2
|
-
import { type OwnStorage } from '@aalis/api-storage';
|
|
3
|
-
import type { Logger } from '@aalis/core';
|
|
4
|
-
export declare function openProvenance(storage: Pick<OwnStorage, 'readFile' | 'writeFile' | 'uri'>, logger: Logger): Promise<{
|
|
5
|
-
taintOf: (sessionId: string) => readonly string[] | undefined;
|
|
6
|
-
markTainted(sessionId: string, sources: readonly string[]): void;
|
|
7
|
-
record(realPath: string, entry: ProvenanceRecord): void;
|
|
8
|
-
provenanceOf: (realPath: string) => ProvenanceRecord | undefined;
|
|
9
|
-
/** 等排队的写盘落定 */
|
|
10
|
-
flushed: () => Promise<void>;
|
|
11
|
-
}>;
|
|
12
|
-
//# sourceMappingURL=provenance.d.ts.map
|
package/dist/provenance.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"provenance.d.ts","sourceRoot":"","sources":["../src/provenance.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAqB,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AA6B1C,wBAAsB,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,WAAW,GAAG,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM;yBA4BvF,MAAM,KAAG,SAAS,MAAM,EAAE,GAAG,SAAS;2BACpC,MAAM,WAAW,SAAS,MAAM,EAAE,GAAG,IAAI;qBAO/C,MAAM,SAAS,gBAAgB,GAAG,IAAI;6BAI9B,MAAM,KAAG,gBAAgB,GAAG,SAAS;IAC9D,eAAe;;GAGlB"}
|
package/dist/provenance.js
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// 污点与来源账本:落在本插件的私有目录里(pluginData:/reach/provenance.json)
|
|
3
|
-
//
|
|
4
|
-
// 污点:每个会话读进过谁的内容(来源称呼),粘在会话上,之后签发的凭据都带着。
|
|
5
|
-
// 来源账本:受污染的会话经凭据写进白纸的文件(真实路径)→ 写入会话、来源称呼与时间。
|
|
6
|
-
// 整份原子写;改动之后排队写盘。文件不存在时从空起步;存在但读不出或形状不对时抛错,插件不激活:
|
|
7
|
-
// 从空起步等于当作谁都没读进过别人的内容,凭据会把受污染的会话当成干净的签发。
|
|
8
|
-
// ============================================================
|
|
9
|
-
import { isStorageNotFound } from '@aalis/api-storage';
|
|
10
|
-
/** 私有目录下的账本文件 */
|
|
11
|
-
const FILE = 'provenance.json';
|
|
12
|
-
const isSources = (value) => Array.isArray(value) && value.length > 0 && value.every(s => typeof s === 'string' && s.trim() !== '');
|
|
13
|
-
const isRecord = (value) => {
|
|
14
|
-
const r = value;
|
|
15
|
-
return typeof r?.sessionId === 'string' && isSources(r.sources) && typeof r.at === 'number';
|
|
16
|
-
};
|
|
17
|
-
function parse(text) {
|
|
18
|
-
const doc = JSON.parse(text);
|
|
19
|
-
const entries = (value) => typeof value === 'object' && value !== null && !Array.isArray(value) ? Object.entries(value) : undefined;
|
|
20
|
-
const taint = entries(doc?.taint);
|
|
21
|
-
const ledger = entries(doc?.ledger);
|
|
22
|
-
if (!taint?.every(([, sources]) => isSources(sources)))
|
|
23
|
-
throw new Error('taint 要是「会话 id → 来源称呼的数组」');
|
|
24
|
-
if (!ledger?.every(([, record]) => isRecord(record))) {
|
|
25
|
-
throw new Error('ledger 要是「真实路径 → { sessionId, sources, at }」');
|
|
26
|
-
}
|
|
27
|
-
return {
|
|
28
|
-
taint: new Map(taint),
|
|
29
|
-
ledger: new Map(ledger),
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
export async function openProvenance(storage, logger) {
|
|
33
|
-
const text = await storage.readFile(FILE, 'utf-8').then(data => String(data), err => {
|
|
34
|
-
if (isStorageNotFound(err))
|
|
35
|
-
return undefined;
|
|
36
|
-
throw err;
|
|
37
|
-
});
|
|
38
|
-
let state;
|
|
39
|
-
try {
|
|
40
|
-
state = text === undefined ? { taint: new Map(), ledger: new Map() } : parse(text);
|
|
41
|
-
}
|
|
42
|
-
catch (err) {
|
|
43
|
-
throw new Error(`污点与来源记录 ${storage.uri(FILE)}(家目录的 state/plugins/reach/provenance.json)读不出:${err instanceof Error ? err.message : String(err)}。修好或移走后重启`);
|
|
44
|
-
}
|
|
45
|
-
const { taint, ledger } = state;
|
|
46
|
-
// 写盘排队:每次写当时的整份,失败上报,下一次改动照常再写整份
|
|
47
|
-
let saving = Promise.resolve();
|
|
48
|
-
const save = () => {
|
|
49
|
-
const snapshot = JSON.stringify({ taint: Object.fromEntries(taint), ledger: Object.fromEntries(ledger) });
|
|
50
|
-
saving = saving
|
|
51
|
-
.then(() => storage.writeFile(FILE, snapshot))
|
|
52
|
-
.catch(err => logger.error('污点与来源记录写盘失败(本次运行里照常生效):', err));
|
|
53
|
-
};
|
|
54
|
-
return {
|
|
55
|
-
taintOf: (sessionId) => taint.get(sessionId),
|
|
56
|
-
markTainted(sessionId, sources) {
|
|
57
|
-
if (!isSources(sources))
|
|
58
|
-
throw new Error('污点要带来源称呼:至少一个,且不能是空白');
|
|
59
|
-
const merged = [...new Set([...(taint.get(sessionId) ?? []), ...sources])];
|
|
60
|
-
if (merged.length === taint.get(sessionId)?.length)
|
|
61
|
-
return;
|
|
62
|
-
taint.set(sessionId, merged);
|
|
63
|
-
save();
|
|
64
|
-
},
|
|
65
|
-
record(realPath, entry) {
|
|
66
|
-
ledger.set(realPath, entry);
|
|
67
|
-
save();
|
|
68
|
-
},
|
|
69
|
-
provenanceOf: (realPath) => ledger.get(realPath),
|
|
70
|
-
/** 等排队的写盘落定 */
|
|
71
|
-
flushed: () => saving,
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
//# sourceMappingURL=provenance.js.map
|
package/dist/provenance.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"provenance.js","sourceRoot":"","sources":["../src/provenance.ts"],"names":[],"mappings":"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"}
|