@nowcrew/daemon 0.6.97-beta.14 → 0.6.97-beta.16
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.
|
@@ -4,6 +4,7 @@ import { buildServiceSpec, serviceStatus, windowsCommandArg, } from "./computer-
|
|
|
4
4
|
import { daemonGlobalInstallation } from "./daemon-installation.js";
|
|
5
5
|
import { inspectLegacyServiceInstallationDetails } from "./legacy-service-installation.js";
|
|
6
6
|
import { powershellCommandArgs } from "./powershell-command.js";
|
|
7
|
+
import { windowsTaskPrincipalFields, windowsTaskPrincipalMatches, windowsTaskPrincipalScript, } from "./windows-task-principal.js";
|
|
7
8
|
function encoded(value) {
|
|
8
9
|
return Buffer.from(value, "utf16le").toString("base64");
|
|
9
10
|
}
|
|
@@ -143,8 +144,9 @@ async function discoverWindows(input, identity) {
|
|
|
143
144
|
"$n=[Text.Encoding]::Unicode.GetString([Convert]::FromBase64String($args[0]));",
|
|
144
145
|
"$tasks=@(Get-ScheduledTask -ErrorAction Stop|Where-Object{$_.TaskPath -eq '\\' -and $_.TaskName -ceq $n});",
|
|
145
146
|
"if($tasks.Count -ne 1){[pscustomobject]@{count=$tasks.Count}|ConvertTo-Json -Compress;exit 0};",
|
|
146
|
-
"$task=$tasks[0];$actions=@($task.Actions)
|
|
147
|
-
|
|
147
|
+
"$task=$tasks[0];$actions=@($task.Actions);",
|
|
148
|
+
windowsTaskPrincipalScript,
|
|
149
|
+
`[pscustomobject]@{count=1;state=[int]$task.State;actionCount=$actions.Count;execute=if($actions.Count -eq 1){$actions[0].Execute}else{$null};arguments=if($actions.Count -eq 1){$actions[0].Arguments}else{$null};${windowsTaskPrincipalFields}}|ConvertTo-Json -Compress;`,
|
|
148
150
|
].join("");
|
|
149
151
|
const result = await input.runner("powershell.exe", powershellCommandArgs(script, [encoded(identity.id)]));
|
|
150
152
|
if (result.exitCode !== 0) {
|
|
@@ -164,7 +166,7 @@ async function discoverWindows(input, identity) {
|
|
|
164
166
|
: null;
|
|
165
167
|
if (definition.count !== 1
|
|
166
168
|
|| definition.actionCount !== 1
|
|
167
|
-
|| definition
|
|
169
|
+
|| !windowsTaskPrincipalMatches(definition)
|
|
168
170
|
|| !win32.isAbsolute(definition.execute ?? "")
|
|
169
171
|
|| match === null
|
|
170
172
|
|| match[2] !== input.desired.profile
|
package/dist/computer-main.js
CHANGED
|
File without changes
|
package/dist/computer-service.js
CHANGED
|
@@ -6,6 +6,7 @@ import { promisify } from "node:util";
|
|
|
6
6
|
import { dirname, resolve } from "node:path";
|
|
7
7
|
import { normalizeDaemonNpmRegistry } from "./npm-registry.js";
|
|
8
8
|
import { daemonRegistryCandidates } from "./daemon-registry.js";
|
|
9
|
+
import { windowsTaskPrincipalFields, windowsTaskPrincipalMatches, windowsTaskPrincipalScript, } from "./windows-task-principal.js";
|
|
9
10
|
import { npmInvocation } from "./npm-command.js";
|
|
10
11
|
import { powershellCommandArgs } from "./powershell-command.js";
|
|
11
12
|
const execFileAsync = promisify(execFile);
|
|
@@ -196,8 +197,9 @@ async function windowsTaskDefinitionMatches(spec, runner) {
|
|
|
196
197
|
"$n=[Text.Encoding]::Unicode.GetString([Convert]::FromBase64String($args[0]));",
|
|
197
198
|
"$tasks=@(Get-ScheduledTask -ErrorAction Stop|Where-Object{$_.TaskPath -eq '\\' -and $_.TaskName -ceq $n});",
|
|
198
199
|
"if($tasks.Count -ne 1){[pscustomobject]@{count=$tasks.Count}|ConvertTo-Json -Compress;exit 0};",
|
|
199
|
-
"$task=$tasks[0];$actions=@($task.Actions)
|
|
200
|
-
|
|
200
|
+
"$task=$tasks[0];$actions=@($task.Actions);",
|
|
201
|
+
windowsTaskPrincipalScript,
|
|
202
|
+
`[pscustomobject]@{count=1;actionCount=$actions.Count;execute=if($actions.Count -eq 1){$actions[0].Execute}else{$null};arguments=if($actions.Count -eq 1){$actions[0].Arguments}else{$null};${windowsTaskPrincipalFields}}|ConvertTo-Json -Compress;`,
|
|
201
203
|
].join("");
|
|
202
204
|
const result = await runner("powershell.exe", powershellCommandArgs(script, [encodedName]));
|
|
203
205
|
if (result.exitCode !== 0) {
|
|
@@ -213,7 +215,7 @@ async function windowsTaskDefinitionMatches(spec, runner) {
|
|
|
213
215
|
const expectedArguments = spec.daemonCommand.slice(1).map(windowsCommandArg).join(" ");
|
|
214
216
|
return definition.count === 1
|
|
215
217
|
&& definition.actionCount === 1
|
|
216
|
-
&& definition
|
|
218
|
+
&& windowsTaskPrincipalMatches(definition)
|
|
217
219
|
&& sameWindowsPath(definition.execute, spec.daemonCommand[0])
|
|
218
220
|
&& definition.arguments === expectedArguments;
|
|
219
221
|
}
|
package/dist/main.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** Read only: resolve the task's account with Windows, without guessing or stripping its domain. */
|
|
2
|
+
export const windowsTaskPrincipalScript = [
|
|
3
|
+
"$currentUserSid=[Security.Principal.WindowsIdentity]::GetCurrent().User.Value;",
|
|
4
|
+
"$principalSid=$null;",
|
|
5
|
+
"try{",
|
|
6
|
+
"$account=[string]$task.Principal.UserId;",
|
|
7
|
+
"if($account -match '^S-\\d-'){",
|
|
8
|
+
"$principalSid=([Security.Principal.SecurityIdentifier]::new($account)).Value;",
|
|
9
|
+
"}else{",
|
|
10
|
+
"$principalSid=([Security.Principal.NTAccount]::new($account)).Translate([Security.Principal.SecurityIdentifier]).Value;",
|
|
11
|
+
"}",
|
|
12
|
+
"}catch{$principalSid=$null};",
|
|
13
|
+
].join("");
|
|
14
|
+
export const windowsTaskPrincipalFields = [
|
|
15
|
+
"currentUserSid=$currentUserSid;",
|
|
16
|
+
"principalSid=$principalSid;",
|
|
17
|
+
"logonType=[int]$task.Principal.LogonType;",
|
|
18
|
+
"runLevel=[int]$task.Principal.RunLevel;",
|
|
19
|
+
].join("");
|
|
20
|
+
export function windowsTaskPrincipalMatches(principal) {
|
|
21
|
+
return typeof principal.currentUserSid === "string"
|
|
22
|
+
&& /^S-1-(?:\d+-)*\d+$/.test(principal.currentUserSid)
|
|
23
|
+
&& principal.principalSid === principal.currentUserSid
|
|
24
|
+
&& principal.logonType === 3 // Interactive
|
|
25
|
+
&& principal.runLevel === 0; // Limited
|
|
26
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nowcrew/daemon",
|
|
3
|
-
"version": "0.6.97-beta.
|
|
3
|
+
"version": "0.6.97-beta.16",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "crew daemon — 运行在用户机器:拉起/管理 agent 进程,注入 crew CLI,归一化 runtime 事件",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -18,6 +18,13 @@
|
|
|
18
18
|
"publishConfig": {
|
|
19
19
|
"access": "public"
|
|
20
20
|
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"daemon": "pnpm --filter @nowcrew/cli build && tsx src/main.ts",
|
|
23
|
+
"build": "tsc -p tsconfig.json",
|
|
24
|
+
"prepublishOnly": "pnpm build && node ../scripts/daemon-release-artifact.mjs --strict-registry",
|
|
25
|
+
"test": "vitest run",
|
|
26
|
+
"typecheck": "tsc --noEmit"
|
|
27
|
+
},
|
|
21
28
|
"dependencies": {
|
|
22
29
|
"@agentclientprotocol/sdk": "1.2.1",
|
|
23
30
|
"@nowcrew/cli": "0.4.17",
|
|
@@ -39,11 +46,5 @@
|
|
|
39
46
|
"tsx": "^4.19.0",
|
|
40
47
|
"typescript": "^5.6.0",
|
|
41
48
|
"vitest": "^2.1.0"
|
|
42
|
-
},
|
|
43
|
-
"scripts": {
|
|
44
|
-
"daemon": "pnpm --filter @nowcrew/cli build && tsx src/main.ts",
|
|
45
|
-
"build": "tsc -p tsconfig.json",
|
|
46
|
-
"test": "vitest run",
|
|
47
|
-
"typecheck": "tsc --noEmit"
|
|
48
49
|
}
|
|
49
|
-
}
|
|
50
|
+
}
|