buckyos 0.7.115 → 0.7.118
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 +8 -0
- package/cli/README.md +14 -10
- package/cli/core/app.ts +1 -0
- package/cli/core/argv.ts +14 -7
- package/cli/core/auth.ts +104 -20
- package/cli/core/config.ts +0 -38
- package/cli/core/development_mode.ts +103 -0
- package/cli/core/identity.ts +39 -31
- package/cli/core/registry.ts +7 -2
- package/cli/dist/cli.mjs +341 -233
- package/cli/dist/cli.mjs.map +1 -1
- package/cli/runtime/host.ts +10 -10
- package/cli/version.ts +1 -1
- package/dist/browser.cjs +1 -1
- package/dist/browser.mjs +58 -57
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +58 -57
- package/dist/ndm_proxy-20e0a471.js +13 -0
- package/dist/ndm_proxy-20e0a471.js.map +1 -0
- package/dist/{ndm_proxy-a719bc58.mjs → ndm_proxy-6cb0701b.mjs} +62 -56
- package/dist/ndm_proxy-6cb0701b.mjs.map +1 -0
- package/dist/node.cjs +1 -1
- package/dist/node.mjs +58 -57
- package/dist/task_mgr_client.d.ts +10 -0
- package/dist/task_mgr_client.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/ndm_proxy-36879436.js +0 -13
- package/dist/ndm_proxy-36879436.js.map +0 -1
- package/dist/ndm_proxy-a719bc58.mjs.map +0 -1
package/cli/dist/cli.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import process from "node:process";
|
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
3
|
import * as nodePath from "node:path";
|
|
4
4
|
import { resolve as resolve$5, dirname as dirname$3 } from "node:path";
|
|
5
|
-
import {
|
|
5
|
+
import { BuckyOSSDK, RuntimeType, buckyos, namelib, VerifyHubClient, createAppInstanceId, parseSessionTokenClaims, ndn, ndm_proxy } from "buckyos/node";
|
|
6
6
|
import { createHash } from "node:crypto";
|
|
7
7
|
import { readFile, writeFile, readdir, stat, lstat, realpath, mkdtemp, rename, rm, mkdir, chmod, symlink, copyFile, open } from "node:fs/promises";
|
|
8
8
|
import { createReadStream, createWriteStream } from "node:fs";
|
|
@@ -94,8 +94,6 @@ const STRING_GLOBALS = /* @__PURE__ */ new Map([
|
|
|
94
94
|
["zone", "zone"],
|
|
95
95
|
["endpoint", "endpoint"],
|
|
96
96
|
["identity", "identity"],
|
|
97
|
-
["identity-root", "identityRoot"],
|
|
98
|
-
["security-root", "securityRoot"],
|
|
99
97
|
["session-token", "sessionToken"],
|
|
100
98
|
["session-token-file", "sessionTokenFile"],
|
|
101
99
|
["output", "output"],
|
|
@@ -104,6 +102,9 @@ const STRING_GLOBALS = /* @__PURE__ */ new Map([
|
|
|
104
102
|
["trace-id", "traceId"],
|
|
105
103
|
["idempotency-key", "idempotencyKey"]
|
|
106
104
|
]);
|
|
105
|
+
const REPEATABLE_STRING_GLOBALS = /* @__PURE__ */ new Map([
|
|
106
|
+
["allow-read", "allowRead"]
|
|
107
|
+
]);
|
|
107
108
|
const BOOLEAN_GLOBALS = /* @__PURE__ */ new Map([
|
|
108
109
|
["cli", "cli"],
|
|
109
110
|
["wait", "wait"],
|
|
@@ -149,11 +150,16 @@ function parseInvocation(argv) {
|
|
|
149
150
|
continue;
|
|
150
151
|
}
|
|
151
152
|
const stringProperty = STRING_GLOBALS.get(parsed.name);
|
|
152
|
-
|
|
153
|
+
const repeatableStringProperty = REPEATABLE_STRING_GLOBALS.get(parsed.name);
|
|
154
|
+
if (!stringProperty && !repeatableStringProperty) {
|
|
153
155
|
throw new UsageError("UNKNOWN_OPTION", `unknown global option: --${parsed.name}`);
|
|
154
156
|
}
|
|
155
157
|
const { value, consumed } = readOptionValue(argv, index, parsed);
|
|
156
|
-
|
|
158
|
+
if (repeatableStringProperty === "allowRead") {
|
|
159
|
+
global.allowRead = [...global.allowRead ?? [], value];
|
|
160
|
+
} else {
|
|
161
|
+
setGlobal(global, stringProperty, normalizeGlobalValue(parsed.name, value));
|
|
162
|
+
}
|
|
157
163
|
index += consumed;
|
|
158
164
|
}
|
|
159
165
|
const module = argv[index];
|
|
@@ -214,7 +220,7 @@ function parseCommandArgs(command, argv, inputObject, allowReplScopedGlobals = f
|
|
|
214
220
|
index += consumed2;
|
|
215
221
|
continue;
|
|
216
222
|
}
|
|
217
|
-
if (allowReplScopedGlobals && (STRING_GLOBALS.has(parsed.name) || BOOLEAN_GLOBALS.has(parsed.name))) {
|
|
223
|
+
if (allowReplScopedGlobals && (STRING_GLOBALS.has(parsed.name) || REPEATABLE_STRING_GLOBALS.has(parsed.name) || BOOLEAN_GLOBALS.has(parsed.name))) {
|
|
218
224
|
throw new UsageError(
|
|
219
225
|
"SESSION_OPTION_FROZEN",
|
|
220
226
|
`--${parsed.name} is frozen for the interactive session`
|
|
@@ -477,8 +483,6 @@ const TOOL_ENVIRONMENT_NAMES = [
|
|
|
477
483
|
"BUCKYOS_TOOL_ENDPOINT",
|
|
478
484
|
"BUCKYOS_TOOL_IDENTITY",
|
|
479
485
|
"BUCKYOS_TOOL_OUTPUT",
|
|
480
|
-
"BUCKYOS_IDENTITY_ROOT",
|
|
481
|
-
"BUCKYOS_SECURITY_ROOT",
|
|
482
486
|
"BUCKYOS_APPCLIENT_SESSION_TOKEN",
|
|
483
487
|
"BUCKYOS_ROOT",
|
|
484
488
|
"SOURCE_DATE_EPOCH"
|
|
@@ -491,14 +495,16 @@ function buildDistributionPolicy(options) {
|
|
|
491
495
|
const configRoot = path.resolve(
|
|
492
496
|
environment2.BUCKYOS_TOOL_CONFIG_DIR ?? path.join(homeDir, ".buckyos_tool")
|
|
493
497
|
);
|
|
494
|
-
const readPaths = /* @__PURE__ */ new Set([
|
|
498
|
+
const readPaths = /* @__PURE__ */ new Set([
|
|
499
|
+
path.resolve(packageRoot2),
|
|
500
|
+
path.resolve(cwd),
|
|
501
|
+
configRoot,
|
|
502
|
+
path.resolve(path.join(homeDir, ".buckyos")),
|
|
503
|
+
path.resolve(path.join(homeDir, ".buckycli"))
|
|
504
|
+
]);
|
|
495
505
|
const writePaths = /* @__PURE__ */ new Set([path.resolve(cwd), configRoot]);
|
|
496
506
|
if (options.distribution === "system")
|
|
497
507
|
readPaths.add(buckyosRoot);
|
|
498
|
-
if (environment2.BUCKYOS_IDENTITY_ROOT && environment2.BUCKYOS_SECURITY_ROOT) {
|
|
499
|
-
readPaths.add(path.resolve(environment2.BUCKYOS_IDENTITY_ROOT));
|
|
500
|
-
readPaths.add(path.resolve(environment2.BUCKYOS_SECURITY_ROOT));
|
|
501
|
-
}
|
|
502
508
|
const parsed = collectArgumentPaths(argv);
|
|
503
509
|
for (const candidate of parsed.read)
|
|
504
510
|
readPaths.add(resolveInputPath(candidate, cwd, path));
|
|
@@ -593,7 +599,9 @@ function collectArgumentPaths(argv) {
|
|
|
593
599
|
if (name === "config-dir") {
|
|
594
600
|
read.push(value);
|
|
595
601
|
write.push(value);
|
|
596
|
-
} else if (
|
|
602
|
+
} else if (name === "allow-read") {
|
|
603
|
+
read.push(value);
|
|
604
|
+
} else if (["input", "session-token-file", "pikg"].includes(name)) {
|
|
597
605
|
if (value !== "-")
|
|
598
606
|
read.push(value);
|
|
599
607
|
} else if (name === "source" && module === "pikg") {
|
|
@@ -676,8 +684,6 @@ const ENVIRONMENT_NAMES = [
|
|
|
676
684
|
"BUCKYOS_TOOL_ENDPOINT",
|
|
677
685
|
"BUCKYOS_TOOL_IDENTITY",
|
|
678
686
|
"BUCKYOS_TOOL_OUTPUT",
|
|
679
|
-
"BUCKYOS_IDENTITY_ROOT",
|
|
680
|
-
"BUCKYOS_SECURITY_ROOT",
|
|
681
687
|
"BUCKYOS_APPCLIENT_SESSION_TOKEN",
|
|
682
688
|
"BUCKYOS_ROOT"
|
|
683
689
|
];
|
|
@@ -820,34 +826,6 @@ async function resolveConfig(explicit, environment2 = readEnvironment(), options
|
|
|
820
826
|
void 0,
|
|
821
827
|
sources
|
|
822
828
|
);
|
|
823
|
-
const identityRoot = select(
|
|
824
|
-
"identity_root",
|
|
825
|
-
explicit.identityRoot,
|
|
826
|
-
environment2.BUCKYOS_IDENTITY_ROOT,
|
|
827
|
-
void 0,
|
|
828
|
-
void 0,
|
|
829
|
-
sources
|
|
830
|
-
);
|
|
831
|
-
const securityRoot = select(
|
|
832
|
-
"security_root",
|
|
833
|
-
explicit.securityRoot,
|
|
834
|
-
environment2.BUCKYOS_SECURITY_ROOT,
|
|
835
|
-
void 0,
|
|
836
|
-
void 0,
|
|
837
|
-
sources
|
|
838
|
-
);
|
|
839
|
-
if (!!explicit.identityRoot !== !!explicit.securityRoot) {
|
|
840
|
-
throw new UsageError(
|
|
841
|
-
"IDENTITY_ROOT_PAIR_REQUIRED",
|
|
842
|
-
"--identity-root and --security-root must be provided together"
|
|
843
|
-
);
|
|
844
|
-
}
|
|
845
|
-
if (!!environment2.BUCKYOS_IDENTITY_ROOT !== !!environment2.BUCKYOS_SECURITY_ROOT && !explicit.identityRoot) {
|
|
846
|
-
throw new UsageError(
|
|
847
|
-
"IDENTITY_ROOT_PAIR_REQUIRED",
|
|
848
|
-
"BUCKYOS_IDENTITY_ROOT and BUCKYOS_SECURITY_ROOT must be provided together"
|
|
849
|
-
);
|
|
850
|
-
}
|
|
851
829
|
let output;
|
|
852
830
|
if (options.interactive && explicit.output === void 0) {
|
|
853
831
|
output = "table";
|
|
@@ -880,8 +858,6 @@ async function resolveConfig(explicit, environment2 = readEnvironment(), options
|
|
|
880
858
|
zone,
|
|
881
859
|
endpoint,
|
|
882
860
|
identity,
|
|
883
|
-
identityRoot,
|
|
884
|
-
securityRoot,
|
|
885
861
|
sessionToken,
|
|
886
862
|
sessionTokenFile: explicit.sessionTokenFile,
|
|
887
863
|
output,
|
|
@@ -915,8 +891,6 @@ function localResolvedConfig(explicit, environment2 = readEnvironment(), options
|
|
|
915
891
|
zone: explicit.zone ?? environment2.BUCKYOS_TOOL_ZONE,
|
|
916
892
|
endpoint: explicit.endpoint ?? environment2.BUCKYOS_TOOL_ENDPOINT,
|
|
917
893
|
identity: explicit.identity ?? environment2.BUCKYOS_TOOL_IDENTITY,
|
|
918
|
-
identityRoot: explicit.identityRoot ?? environment2.BUCKYOS_IDENTITY_ROOT,
|
|
919
|
-
securityRoot: explicit.securityRoot ?? environment2.BUCKYOS_SECURITY_ROOT,
|
|
920
894
|
sessionToken: explicit.sessionToken ?? environment2.BUCKYOS_APPCLIENT_SESSION_TOKEN,
|
|
921
895
|
sessionTokenFile: explicit.sessionTokenFile,
|
|
922
896
|
output,
|
|
@@ -1081,6 +1055,196 @@ function redactUrl(value) {
|
|
|
1081
1055
|
function configValueError(message) {
|
|
1082
1056
|
return new ToolError("INVALID_CONFIG_VALUE", message, 2);
|
|
1083
1057
|
}
|
|
1058
|
+
class BuckyOSRuntimeAdapter {
|
|
1059
|
+
#sdk = new BuckyOSSDK("node");
|
|
1060
|
+
async initialize(config, session) {
|
|
1061
|
+
const authenticated = session.current();
|
|
1062
|
+
const zoneHost = resolveZoneHost(config);
|
|
1063
|
+
const initialize = this.#sdk.initBuckyOS;
|
|
1064
|
+
await initialize.call(this.#sdk, authenticated.principal.appId, {
|
|
1065
|
+
appId: authenticated.principal.appId,
|
|
1066
|
+
ownerUserId: authenticated.principal.id,
|
|
1067
|
+
runtimeType: RuntimeType.AppClient,
|
|
1068
|
+
zoneHost,
|
|
1069
|
+
defaultProtocol: config.defaultProtocol,
|
|
1070
|
+
sessionToken: authenticated.token,
|
|
1071
|
+
privateKeySearchPaths: [],
|
|
1072
|
+
autoRenew: false,
|
|
1073
|
+
verifyHubServiceUrl: resolveServiceUrl(config, "verify-hub")
|
|
1074
|
+
});
|
|
1075
|
+
return {
|
|
1076
|
+
zone: config.zone ?? zoneHost,
|
|
1077
|
+
endpoint: config.endpoint ?? `${config.defaultProtocol}${zoneHost}`,
|
|
1078
|
+
defaultProtocol: config.defaultProtocol
|
|
1079
|
+
};
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
class BuckyOSServiceClientRegistry {
|
|
1083
|
+
#config;
|
|
1084
|
+
#session;
|
|
1085
|
+
#clients = /* @__PURE__ */ new Map();
|
|
1086
|
+
constructor(config, session) {
|
|
1087
|
+
this.#config = config;
|
|
1088
|
+
this.#session = session;
|
|
1089
|
+
}
|
|
1090
|
+
async call(service, method, params, options) {
|
|
1091
|
+
let client = this.#clients.get(service);
|
|
1092
|
+
if (!client) {
|
|
1093
|
+
const RpcClient = buckyos.kRPCClient;
|
|
1094
|
+
client = new RpcClient(resolveServiceUrl(this.#config, service), null, null, {
|
|
1095
|
+
sessionTokenProvider: async () => (await this.#session.ensureValid()).token
|
|
1096
|
+
});
|
|
1097
|
+
this.#clients.set(service, client);
|
|
1098
|
+
}
|
|
1099
|
+
const request = client.call(method, params, { traceId: options.traceId });
|
|
1100
|
+
return await withDeadline(request, options.timeoutMs, options.signal);
|
|
1101
|
+
}
|
|
1102
|
+
async createEventReader(pattern, signal) {
|
|
1103
|
+
return await buckyos.createEventReader(pattern, { keepaliveMs: 5e3, signal });
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
class InteractiveSession {
|
|
1107
|
+
constructor(authentication, clients, connection) {
|
|
1108
|
+
this.authentication = authentication;
|
|
1109
|
+
this.clients = clients;
|
|
1110
|
+
this.connection = connection;
|
|
1111
|
+
this.startedAt = Date.now();
|
|
1112
|
+
}
|
|
1113
|
+
static async create(config, authentication, runtime = new BuckyOSRuntimeAdapter(), clients) {
|
|
1114
|
+
await authentication.connect();
|
|
1115
|
+
const connection = await runtime.initialize(config, authentication);
|
|
1116
|
+
return new InteractiveSession(
|
|
1117
|
+
authentication,
|
|
1118
|
+
clients ?? new BuckyOSServiceClientRegistry(config, authentication),
|
|
1119
|
+
connection
|
|
1120
|
+
);
|
|
1121
|
+
}
|
|
1122
|
+
async reconnect() {
|
|
1123
|
+
await this.authentication.reconnect();
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
function resolveServiceUrl(config, service) {
|
|
1127
|
+
if (config.endpoint) {
|
|
1128
|
+
const endpoint = new URL(config.endpoint);
|
|
1129
|
+
const marker = endpoint.pathname.indexOf("/kapi/");
|
|
1130
|
+
if (marker >= 0)
|
|
1131
|
+
endpoint.pathname = `${endpoint.pathname.slice(0, marker)}/kapi/${service}`;
|
|
1132
|
+
else if (endpoint.pathname.endsWith("/kapi")) {
|
|
1133
|
+
endpoint.pathname = `${endpoint.pathname}/${service}`;
|
|
1134
|
+
} else
|
|
1135
|
+
endpoint.pathname = `${endpoint.pathname.replace(/\/$/, "")}/kapi/${service}`;
|
|
1136
|
+
endpoint.search = "";
|
|
1137
|
+
endpoint.hash = "";
|
|
1138
|
+
return endpoint.toString().replace(/\/$/, "");
|
|
1139
|
+
}
|
|
1140
|
+
const host2 = resolveZoneHost(config);
|
|
1141
|
+
return `${config.defaultProtocol}${host2}/kapi/${service}`;
|
|
1142
|
+
}
|
|
1143
|
+
function resolveZoneHost(config) {
|
|
1144
|
+
if (config.zone) {
|
|
1145
|
+
try {
|
|
1146
|
+
return namelib.DID.fromStr(config.zone).toRawHostName();
|
|
1147
|
+
} catch {
|
|
1148
|
+
throw new UsageError("INVALID_ZONE", `invalid zone host or DID: ${config.zone}`);
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
if (config.endpoint)
|
|
1152
|
+
return new URL(config.endpoint).host;
|
|
1153
|
+
throw new UsageError("CONNECTION_REQUIRED", "an endpoint or zone is required for online commands");
|
|
1154
|
+
}
|
|
1155
|
+
async function withDeadline(promise, timeoutMs, signal) {
|
|
1156
|
+
if (signal?.aborted)
|
|
1157
|
+
throw new ToolError("CANCELED", "operation canceled", 8);
|
|
1158
|
+
let timer;
|
|
1159
|
+
let abortHandler;
|
|
1160
|
+
const guards = [
|
|
1161
|
+
new Promise((_, reject) => {
|
|
1162
|
+
timer = setTimeout(
|
|
1163
|
+
() => reject(new ToolError("TIMEOUT", "operation timed out", 8, true)),
|
|
1164
|
+
timeoutMs
|
|
1165
|
+
);
|
|
1166
|
+
})
|
|
1167
|
+
];
|
|
1168
|
+
if (signal) {
|
|
1169
|
+
guards.push(
|
|
1170
|
+
new Promise((_, reject) => {
|
|
1171
|
+
abortHandler = () => reject(new ToolError("CANCELED", "operation canceled", 8));
|
|
1172
|
+
signal.addEventListener("abort", abortHandler, { once: true });
|
|
1173
|
+
})
|
|
1174
|
+
);
|
|
1175
|
+
}
|
|
1176
|
+
try {
|
|
1177
|
+
return await Promise.race([promise, ...guards]);
|
|
1178
|
+
} finally {
|
|
1179
|
+
if (timer !== void 0)
|
|
1180
|
+
clearTimeout(timer);
|
|
1181
|
+
if (signal && abortHandler)
|
|
1182
|
+
signal.removeEventListener("abort", abortHandler);
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
const BUCKYOS_DEV_CONFIG_SCHEMA_VERSION = 1;
|
|
1186
|
+
async function readTargetDevelopmentMode(config) {
|
|
1187
|
+
try {
|
|
1188
|
+
const url = resolveServiceUrl(config, "control-panel");
|
|
1189
|
+
const client = new buckyos.kRPCClient(url);
|
|
1190
|
+
const value = await withTimeout(
|
|
1191
|
+
client.call("system.dev_mode.get", {}),
|
|
1192
|
+
config.timeoutMs
|
|
1193
|
+
);
|
|
1194
|
+
const parsed = parseBuckyOSDevConfig(value);
|
|
1195
|
+
return parsed.enabled ? { state: "enabled", config: parsed } : { state: "disabled", config: parsed };
|
|
1196
|
+
} catch (error) {
|
|
1197
|
+
return {
|
|
1198
|
+
state: "unavailable",
|
|
1199
|
+
reason: error instanceof Error ? error.message : String(error)
|
|
1200
|
+
};
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
function parseBuckyOSDevConfig(value) {
|
|
1204
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1205
|
+
throw new Error("BuckyOSDevConfig must be an object");
|
|
1206
|
+
}
|
|
1207
|
+
const config = value;
|
|
1208
|
+
const keys = Object.keys(config).sort();
|
|
1209
|
+
const expectedKeys = ["enabled", "enabled_at", "enabled_by", "schema_version"];
|
|
1210
|
+
if (JSON.stringify(keys) !== JSON.stringify(expectedKeys)) {
|
|
1211
|
+
throw new Error("BuckyOSDevConfig contains missing or unsupported fields");
|
|
1212
|
+
}
|
|
1213
|
+
if (config.schema_version !== BUCKYOS_DEV_CONFIG_SCHEMA_VERSION) {
|
|
1214
|
+
throw new Error(`unsupported BuckyOSDevConfig schema_version ${String(config.schema_version)}`);
|
|
1215
|
+
}
|
|
1216
|
+
if (typeof config.enabled !== "boolean") {
|
|
1217
|
+
throw new Error("BuckyOSDevConfig enabled must be a boolean");
|
|
1218
|
+
}
|
|
1219
|
+
const enabledAt = config.enabled_at;
|
|
1220
|
+
const enabledBy = config.enabled_by;
|
|
1221
|
+
const hasAuditFields = Number.isSafeInteger(enabledAt) && enabledAt > 0 && typeof enabledBy === "string" && enabledBy.trim().length > 0;
|
|
1222
|
+
const hasNoAuditFields = enabledAt === null && enabledBy === null;
|
|
1223
|
+
if (!hasAuditFields && !hasNoAuditFields) {
|
|
1224
|
+
throw new Error("BuckyOSDevConfig enabled_at and enabled_by must be valid and present together");
|
|
1225
|
+
}
|
|
1226
|
+
if (config.enabled && !hasAuditFields) {
|
|
1227
|
+
throw new Error("enabled BuckyOSDevConfig requires enable audit fields");
|
|
1228
|
+
}
|
|
1229
|
+
return {
|
|
1230
|
+
schema_version: 1,
|
|
1231
|
+
enabled: config.enabled,
|
|
1232
|
+
enabled_at: enabledAt,
|
|
1233
|
+
enabled_by: enabledBy
|
|
1234
|
+
};
|
|
1235
|
+
}
|
|
1236
|
+
async function withTimeout(promise, timeoutMs) {
|
|
1237
|
+
let timer;
|
|
1238
|
+
const timeout = new Promise((_, reject) => {
|
|
1239
|
+
timer = setTimeout(() => reject(new Error("developer-mode lookup timed out")), timeoutMs);
|
|
1240
|
+
});
|
|
1241
|
+
try {
|
|
1242
|
+
return await Promise.race([promise, timeout]);
|
|
1243
|
+
} finally {
|
|
1244
|
+
if (timer !== void 0)
|
|
1245
|
+
clearTimeout(timer);
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1084
1248
|
const join$2 = (...parts) => getHost().path.join(...parts);
|
|
1085
1249
|
const LOCAL_NODE_GATEWAY_ENDPOINT = "http://127.0.0.1:3180";
|
|
1086
1250
|
const IDENTITY_CANDIDATE_LIMIT = 8;
|
|
@@ -1164,45 +1328,38 @@ async function readCurrentDeviceIdentity(environment2 = readEnvironment()) {
|
|
|
1164
1328
|
securityRoot: join$2(buckyosRoot, "security")
|
|
1165
1329
|
};
|
|
1166
1330
|
}
|
|
1167
|
-
function identityRootPairs(config, environment2 = readEnvironment()) {
|
|
1331
|
+
function identityRootPairs(config, environment2 = readEnvironment(), options = {}) {
|
|
1332
|
+
const device = config.implicitDeviceIdentity;
|
|
1333
|
+
if (device) {
|
|
1334
|
+
return [{
|
|
1335
|
+
publicRoot: device.publicRoot,
|
|
1336
|
+
securityRoot: device.securityRoot,
|
|
1337
|
+
source: "current-device"
|
|
1338
|
+
}];
|
|
1339
|
+
}
|
|
1340
|
+
const home = environment2.HOME ?? environment2.USERPROFILE ?? getHost().homeDir();
|
|
1168
1341
|
const pairs = [];
|
|
1169
|
-
if (
|
|
1342
|
+
if (options.includeOperations ?? true) {
|
|
1170
1343
|
pairs.push({
|
|
1171
|
-
publicRoot:
|
|
1172
|
-
securityRoot:
|
|
1173
|
-
source: "
|
|
1344
|
+
publicRoot: join$2(home, ".buckyos", "local", "identity"),
|
|
1345
|
+
securityRoot: join$2(home, ".buckyos", "security"),
|
|
1346
|
+
source: "buckyos-home"
|
|
1174
1347
|
});
|
|
1175
1348
|
}
|
|
1176
|
-
|
|
1177
|
-
publicRoot: join$2(config.configDir, "local", "identity"),
|
|
1178
|
-
securityRoot: join$2(config.configDir, "security"),
|
|
1179
|
-
source: "tool"
|
|
1180
|
-
});
|
|
1181
|
-
if (environment2.BUCKYOS_IDENTITY_ROOT && environment2.BUCKYOS_SECURITY_ROOT) {
|
|
1182
|
-
const duplicate = config.identityRoot === environment2.BUCKYOS_IDENTITY_ROOT && config.securityRoot === environment2.BUCKYOS_SECURITY_ROOT;
|
|
1183
|
-
if (!duplicate) {
|
|
1184
|
-
pairs.push({
|
|
1185
|
-
publicRoot: environment2.BUCKYOS_IDENTITY_ROOT,
|
|
1186
|
-
securityRoot: environment2.BUCKYOS_SECURITY_ROOT,
|
|
1187
|
-
source: "environment"
|
|
1188
|
-
});
|
|
1189
|
-
}
|
|
1190
|
-
}
|
|
1191
|
-
if (getHost().policy.distribution === "system") {
|
|
1192
|
-
const buckyosRoot = environment2.BUCKYOS_ROOT ?? defaultBuckyOSRoot(environment2);
|
|
1349
|
+
if (options.includeDeveloper ?? false) {
|
|
1193
1350
|
pairs.push({
|
|
1194
|
-
publicRoot: join$2(
|
|
1195
|
-
securityRoot: join$2(
|
|
1196
|
-
source: "
|
|
1351
|
+
publicRoot: join$2(home, ".buckycli", "local", "identity"),
|
|
1352
|
+
securityRoot: join$2(home, ".buckycli", "security"),
|
|
1353
|
+
source: "buckycli-home"
|
|
1197
1354
|
});
|
|
1198
1355
|
}
|
|
1199
1356
|
return deduplicatePairs(pairs);
|
|
1200
1357
|
}
|
|
1201
|
-
async function resolveIdentityMaterial(selectedIdentity, config, environment2 = readEnvironment()) {
|
|
1358
|
+
async function resolveIdentityMaterial(selectedIdentity, config, environment2 = readEnvironment(), options = {}) {
|
|
1202
1359
|
const selected = selectedIdentity.trim();
|
|
1203
1360
|
if (!selected)
|
|
1204
1361
|
throw new UsageError("IDENTITY_REQUIRED", "identity is empty");
|
|
1205
|
-
for (const roots of identityRootPairs(config, environment2)) {
|
|
1362
|
+
for (const roots of identityRootPairs(config, environment2, options)) {
|
|
1206
1363
|
for (const directory of await candidateDirectories(roots.publicRoot, selected)) {
|
|
1207
1364
|
const material = await loadIdentityMaterial(roots, directory, selected);
|
|
1208
1365
|
if (material)
|
|
@@ -1215,11 +1372,11 @@ async function resolveIdentityMaterial(selectedIdentity, config, environment2 =
|
|
|
1215
1372
|
EXIT_AUTH
|
|
1216
1373
|
);
|
|
1217
1374
|
}
|
|
1218
|
-
async function scanIdentityCandidates(config, environment2 = readEnvironment()) {
|
|
1375
|
+
async function scanIdentityCandidates(config, environment2 = readEnvironment(), options = {}) {
|
|
1219
1376
|
const candidates = [];
|
|
1220
1377
|
const skipped = [];
|
|
1221
1378
|
const seen = /* @__PURE__ */ new Set();
|
|
1222
|
-
const roots = identityRootPairs(config, environment2);
|
|
1379
|
+
const roots = identityRootPairs(config, environment2, options);
|
|
1223
1380
|
for (const pair of roots) {
|
|
1224
1381
|
let directories;
|
|
1225
1382
|
try {
|
|
@@ -1273,16 +1430,18 @@ async function scanIdentityCandidates(config, environment2 = readEnvironment())
|
|
|
1273
1430
|
break;
|
|
1274
1431
|
}
|
|
1275
1432
|
return {
|
|
1276
|
-
order: Object.freeze(
|
|
1433
|
+
order: Object.freeze(roots.map((pair) => pair.source)),
|
|
1277
1434
|
limit: IDENTITY_CANDIDATE_LIMIT,
|
|
1278
1435
|
candidates,
|
|
1279
1436
|
skipped
|
|
1280
1437
|
};
|
|
1281
1438
|
}
|
|
1282
|
-
async function identityCandidateView(config, environment2 = readEnvironment()) {
|
|
1439
|
+
async function identityCandidateView(config, environment2 = readEnvironment(), developerModeEnabled = false) {
|
|
1283
1440
|
if (config.identity) {
|
|
1284
1441
|
try {
|
|
1285
|
-
const material = await resolveIdentityMaterial(config.identity, config, environment2
|
|
1442
|
+
const material = await resolveIdentityMaterial(config.identity, config, environment2, {
|
|
1443
|
+
includeDeveloper: developerModeEnabled
|
|
1444
|
+
});
|
|
1286
1445
|
return {
|
|
1287
1446
|
mode: "explicit",
|
|
1288
1447
|
order: [material.did],
|
|
@@ -1307,7 +1466,9 @@ async function identityCandidateView(config, environment2 = readEnvironment()) {
|
|
|
1307
1466
|
};
|
|
1308
1467
|
}
|
|
1309
1468
|
}
|
|
1310
|
-
const scan = await scanIdentityCandidates(config, environment2
|
|
1469
|
+
const scan = await scanIdentityCandidates(config, environment2, {
|
|
1470
|
+
includeDeveloper: developerModeEnabled
|
|
1471
|
+
});
|
|
1311
1472
|
return {
|
|
1312
1473
|
mode: "search",
|
|
1313
1474
|
order: scan.order,
|
|
@@ -1343,7 +1504,8 @@ async function loadIdentityMaterial(roots, directory, selected) {
|
|
|
1343
1504
|
securityRoot: roots.securityRoot,
|
|
1344
1505
|
documentPath,
|
|
1345
1506
|
privateKeyPath,
|
|
1346
|
-
privateKeyPem
|
|
1507
|
+
privateKeyPem,
|
|
1508
|
+
source: roots.source
|
|
1347
1509
|
};
|
|
1348
1510
|
} catch (error) {
|
|
1349
1511
|
if (!isHostError(error, "NotFound"))
|
|
@@ -1428,133 +1590,6 @@ function deduplicatePairs(pairs) {
|
|
|
1428
1590
|
return true;
|
|
1429
1591
|
});
|
|
1430
1592
|
}
|
|
1431
|
-
class BuckyOSRuntimeAdapter {
|
|
1432
|
-
#sdk = new BuckyOSSDK("node");
|
|
1433
|
-
async initialize(config, session) {
|
|
1434
|
-
const authenticated = session.current();
|
|
1435
|
-
const zoneHost = resolveZoneHost(config);
|
|
1436
|
-
const initialize = this.#sdk.initBuckyOS;
|
|
1437
|
-
await initialize.call(this.#sdk, authenticated.principal.appId, {
|
|
1438
|
-
appId: authenticated.principal.appId,
|
|
1439
|
-
ownerUserId: authenticated.principal.id,
|
|
1440
|
-
runtimeType: RuntimeType.AppClient,
|
|
1441
|
-
zoneHost,
|
|
1442
|
-
defaultProtocol: config.defaultProtocol,
|
|
1443
|
-
sessionToken: authenticated.token,
|
|
1444
|
-
privateKeySearchPaths: [],
|
|
1445
|
-
autoRenew: false,
|
|
1446
|
-
verifyHubServiceUrl: resolveServiceUrl(config, "verify-hub")
|
|
1447
|
-
});
|
|
1448
|
-
return {
|
|
1449
|
-
zone: config.zone ?? zoneHost,
|
|
1450
|
-
endpoint: config.endpoint ?? `${config.defaultProtocol}${zoneHost}`,
|
|
1451
|
-
defaultProtocol: config.defaultProtocol
|
|
1452
|
-
};
|
|
1453
|
-
}
|
|
1454
|
-
}
|
|
1455
|
-
class BuckyOSServiceClientRegistry {
|
|
1456
|
-
#config;
|
|
1457
|
-
#session;
|
|
1458
|
-
#clients = /* @__PURE__ */ new Map();
|
|
1459
|
-
constructor(config, session) {
|
|
1460
|
-
this.#config = config;
|
|
1461
|
-
this.#session = session;
|
|
1462
|
-
}
|
|
1463
|
-
async call(service, method, params, options) {
|
|
1464
|
-
let client = this.#clients.get(service);
|
|
1465
|
-
if (!client) {
|
|
1466
|
-
const RpcClient = buckyos.kRPCClient;
|
|
1467
|
-
client = new RpcClient(resolveServiceUrl(this.#config, service), null, null, {
|
|
1468
|
-
sessionTokenProvider: async () => (await this.#session.ensureValid()).token
|
|
1469
|
-
});
|
|
1470
|
-
this.#clients.set(service, client);
|
|
1471
|
-
}
|
|
1472
|
-
const request = client.call(method, params, { traceId: options.traceId });
|
|
1473
|
-
return await withDeadline(request, options.timeoutMs, options.signal);
|
|
1474
|
-
}
|
|
1475
|
-
async createEventReader(pattern, signal) {
|
|
1476
|
-
return await buckyos.createEventReader(pattern, { keepaliveMs: 5e3, signal });
|
|
1477
|
-
}
|
|
1478
|
-
}
|
|
1479
|
-
class InteractiveSession {
|
|
1480
|
-
constructor(authentication, clients, connection) {
|
|
1481
|
-
this.authentication = authentication;
|
|
1482
|
-
this.clients = clients;
|
|
1483
|
-
this.connection = connection;
|
|
1484
|
-
this.startedAt = Date.now();
|
|
1485
|
-
}
|
|
1486
|
-
static async create(config, authentication, runtime = new BuckyOSRuntimeAdapter(), clients) {
|
|
1487
|
-
await authentication.connect();
|
|
1488
|
-
const connection = await runtime.initialize(config, authentication);
|
|
1489
|
-
return new InteractiveSession(
|
|
1490
|
-
authentication,
|
|
1491
|
-
clients ?? new BuckyOSServiceClientRegistry(config, authentication),
|
|
1492
|
-
connection
|
|
1493
|
-
);
|
|
1494
|
-
}
|
|
1495
|
-
async reconnect() {
|
|
1496
|
-
await this.authentication.reconnect();
|
|
1497
|
-
}
|
|
1498
|
-
}
|
|
1499
|
-
function resolveServiceUrl(config, service) {
|
|
1500
|
-
if (config.endpoint) {
|
|
1501
|
-
const endpoint = new URL(config.endpoint);
|
|
1502
|
-
const marker = endpoint.pathname.indexOf("/kapi/");
|
|
1503
|
-
if (marker >= 0)
|
|
1504
|
-
endpoint.pathname = `${endpoint.pathname.slice(0, marker)}/kapi/${service}`;
|
|
1505
|
-
else if (endpoint.pathname.endsWith("/kapi")) {
|
|
1506
|
-
endpoint.pathname = `${endpoint.pathname}/${service}`;
|
|
1507
|
-
} else
|
|
1508
|
-
endpoint.pathname = `${endpoint.pathname.replace(/\/$/, "")}/kapi/${service}`;
|
|
1509
|
-
endpoint.search = "";
|
|
1510
|
-
endpoint.hash = "";
|
|
1511
|
-
return endpoint.toString().replace(/\/$/, "");
|
|
1512
|
-
}
|
|
1513
|
-
const host2 = resolveZoneHost(config);
|
|
1514
|
-
return `${config.defaultProtocol}${host2}/kapi/${service}`;
|
|
1515
|
-
}
|
|
1516
|
-
function resolveZoneHost(config) {
|
|
1517
|
-
if (config.zone) {
|
|
1518
|
-
try {
|
|
1519
|
-
return namelib.DID.fromStr(config.zone).toRawHostName();
|
|
1520
|
-
} catch {
|
|
1521
|
-
throw new UsageError("INVALID_ZONE", `invalid zone host or DID: ${config.zone}`);
|
|
1522
|
-
}
|
|
1523
|
-
}
|
|
1524
|
-
if (config.endpoint)
|
|
1525
|
-
return new URL(config.endpoint).host;
|
|
1526
|
-
throw new UsageError("CONNECTION_REQUIRED", "an endpoint or zone is required for online commands");
|
|
1527
|
-
}
|
|
1528
|
-
async function withDeadline(promise, timeoutMs, signal) {
|
|
1529
|
-
if (signal?.aborted)
|
|
1530
|
-
throw new ToolError("CANCELED", "operation canceled", 8);
|
|
1531
|
-
let timer;
|
|
1532
|
-
let abortHandler;
|
|
1533
|
-
const guards = [
|
|
1534
|
-
new Promise((_, reject) => {
|
|
1535
|
-
timer = setTimeout(
|
|
1536
|
-
() => reject(new ToolError("TIMEOUT", "operation timed out", 8, true)),
|
|
1537
|
-
timeoutMs
|
|
1538
|
-
);
|
|
1539
|
-
})
|
|
1540
|
-
];
|
|
1541
|
-
if (signal) {
|
|
1542
|
-
guards.push(
|
|
1543
|
-
new Promise((_, reject) => {
|
|
1544
|
-
abortHandler = () => reject(new ToolError("CANCELED", "operation canceled", 8));
|
|
1545
|
-
signal.addEventListener("abort", abortHandler, { once: true });
|
|
1546
|
-
})
|
|
1547
|
-
);
|
|
1548
|
-
}
|
|
1549
|
-
try {
|
|
1550
|
-
return await Promise.race([promise, ...guards]);
|
|
1551
|
-
} finally {
|
|
1552
|
-
if (timer !== void 0)
|
|
1553
|
-
clearTimeout(timer);
|
|
1554
|
-
if (signal && abortHandler)
|
|
1555
|
-
signal.removeEventListener("abort", abortHandler);
|
|
1556
|
-
}
|
|
1557
|
-
}
|
|
1558
1593
|
const LOGIN_APP_ID = "buckycli";
|
|
1559
1594
|
const LOGIN_TOKEN_TTL_SECONDS = 10 * 60;
|
|
1560
1595
|
class AuthenticationSession {
|
|
@@ -1565,15 +1600,18 @@ class AuthenticationSession {
|
|
|
1565
1600
|
this.#transport = dependencies.transport ?? new SdkAuthenticationTransport();
|
|
1566
1601
|
this.#readPassword = dependencies.readPassword ?? readSecret;
|
|
1567
1602
|
this.#readUsername = dependencies.readUsername ?? readVisible;
|
|
1603
|
+
this.#readDevelopmentMode = dependencies.readDevelopmentMode ?? readTargetDevelopmentMode;
|
|
1568
1604
|
this.#now = dependencies.now ?? Date.now;
|
|
1569
1605
|
}
|
|
1570
1606
|
#environment;
|
|
1571
1607
|
#transport;
|
|
1572
1608
|
#readPassword;
|
|
1573
1609
|
#readUsername;
|
|
1610
|
+
#readDevelopmentMode;
|
|
1574
1611
|
#now;
|
|
1575
1612
|
#session;
|
|
1576
1613
|
#acceptedIdentity;
|
|
1614
|
+
#developmentMode;
|
|
1577
1615
|
#identityAttempts;
|
|
1578
1616
|
async connect() {
|
|
1579
1617
|
if (this.#session)
|
|
@@ -1621,6 +1659,7 @@ class AuthenticationSession {
|
|
|
1621
1659
|
renewable: session.renewable,
|
|
1622
1660
|
expires_at: expiresAt ?? null,
|
|
1623
1661
|
remaining_seconds: remainingSeconds,
|
|
1662
|
+
developer_mode: this.#developmentMode?.state ?? null,
|
|
1624
1663
|
identity_attempts: this.#identityAttempts
|
|
1625
1664
|
};
|
|
1626
1665
|
}
|
|
@@ -1648,34 +1687,39 @@ class AuthenticationSession {
|
|
|
1648
1687
|
const injected = this.#environment.BUCKYOS_APPCLIENT_SESSION_TOKEN?.trim();
|
|
1649
1688
|
if (injected)
|
|
1650
1689
|
return externalSession(injected, "environment", this.#now());
|
|
1651
|
-
if (this.#acceptedIdentity)
|
|
1690
|
+
if (this.#acceptedIdentity) {
|
|
1691
|
+
if (this.#acceptedIdentity.source === "buckycli-home") {
|
|
1692
|
+
await this.#requireDeveloperIdentityAccess();
|
|
1693
|
+
}
|
|
1652
1694
|
return await this.#loginWithIdentity(this.#acceptedIdentity);
|
|
1695
|
+
}
|
|
1653
1696
|
if (this.config.identity) {
|
|
1654
|
-
const material = await
|
|
1655
|
-
this.config.identity,
|
|
1656
|
-
this.config,
|
|
1657
|
-
this.#environment
|
|
1658
|
-
);
|
|
1697
|
+
const material = await this.#resolveExplicitIdentity(this.config.identity);
|
|
1659
1698
|
const session = await this.#loginWithIdentity(material);
|
|
1660
1699
|
this.#acceptedIdentity = material;
|
|
1661
1700
|
return session;
|
|
1662
1701
|
}
|
|
1663
|
-
const candidates = await scanIdentityCandidates(this.config, this.#environment);
|
|
1664
1702
|
this.#identityAttempts = [];
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1703
|
+
const operations = await scanIdentityCandidates(this.config, this.#environment);
|
|
1704
|
+
const operationsSession = await this.#tryIdentityCandidates(operations.candidates);
|
|
1705
|
+
if (operationsSession)
|
|
1706
|
+
return operationsSession;
|
|
1707
|
+
const developmentMode = await this.#checkDevelopmentMode();
|
|
1708
|
+
if (developmentMode.state === "enabled" && operations.candidates.length < IDENTITY_CANDIDATE_LIMIT) {
|
|
1709
|
+
const operationsDids = new Set(
|
|
1710
|
+
operations.candidates.map((candidate) => candidate.material.did)
|
|
1711
|
+
);
|
|
1712
|
+
const developer = await scanIdentityCandidates(this.config, this.#environment, {
|
|
1713
|
+
includeOperations: false,
|
|
1714
|
+
includeDeveloper: true
|
|
1715
|
+
});
|
|
1716
|
+
const remaining = IDENTITY_CANDIDATE_LIMIT - operations.candidates.length;
|
|
1717
|
+
const candidates = developer.candidates.filter(
|
|
1718
|
+
(candidate) => !operationsDids.has(candidate.material.did)
|
|
1719
|
+
).slice(0, remaining);
|
|
1720
|
+
const developerSession = await this.#tryIdentityCandidates(candidates);
|
|
1721
|
+
if (developerSession)
|
|
1722
|
+
return developerSession;
|
|
1679
1723
|
}
|
|
1680
1724
|
if (this.#identityAttempts.length > 0) {
|
|
1681
1725
|
throw new ToolError(
|
|
@@ -1706,6 +1750,40 @@ class AuthenticationSession {
|
|
|
1706
1750
|
);
|
|
1707
1751
|
return authenticatedSession(token, "password", true, this.#now());
|
|
1708
1752
|
}
|
|
1753
|
+
async #resolveExplicitIdentity(selectedIdentity) {
|
|
1754
|
+
if (this.config.implicitDeviceIdentity) {
|
|
1755
|
+
return await resolveIdentityMaterial(selectedIdentity, this.config, this.#environment);
|
|
1756
|
+
}
|
|
1757
|
+
try {
|
|
1758
|
+
return await resolveIdentityMaterial(selectedIdentity, this.config, this.#environment);
|
|
1759
|
+
} catch (error) {
|
|
1760
|
+
if (!(error instanceof ToolError) || error.code !== "IDENTITY_NOT_FOUND")
|
|
1761
|
+
throw error;
|
|
1762
|
+
}
|
|
1763
|
+
await this.#requireDeveloperIdentityAccess();
|
|
1764
|
+
return await resolveIdentityMaterial(selectedIdentity, this.config, this.#environment, {
|
|
1765
|
+
includeOperations: false,
|
|
1766
|
+
includeDeveloper: true
|
|
1767
|
+
});
|
|
1768
|
+
}
|
|
1769
|
+
async #tryIdentityCandidates(candidates) {
|
|
1770
|
+
for (const candidate of candidates) {
|
|
1771
|
+
try {
|
|
1772
|
+
const session = await this.#loginWithIdentity(candidate.material);
|
|
1773
|
+
this.#acceptedIdentity = candidate.material;
|
|
1774
|
+
return session;
|
|
1775
|
+
} catch (error) {
|
|
1776
|
+
if (!isIdentityRejection(error))
|
|
1777
|
+
throw error;
|
|
1778
|
+
this.#identityAttempts.push({
|
|
1779
|
+
identity: candidate.material.did,
|
|
1780
|
+
code: error.code,
|
|
1781
|
+
message: sanitizeMessage(error.message)
|
|
1782
|
+
});
|
|
1783
|
+
}
|
|
1784
|
+
}
|
|
1785
|
+
return void 0;
|
|
1786
|
+
}
|
|
1709
1787
|
async #loginWithIdentity(material) {
|
|
1710
1788
|
const loginJwt = await createLoginJwt(
|
|
1711
1789
|
material.subject,
|
|
@@ -1721,6 +1799,30 @@ class AuthenticationSession {
|
|
|
1721
1799
|
);
|
|
1722
1800
|
return authenticatedSession(token, "identity", true, this.#now());
|
|
1723
1801
|
}
|
|
1802
|
+
async #checkDevelopmentMode() {
|
|
1803
|
+
this.#developmentMode = await this.#readDevelopmentMode(this.config);
|
|
1804
|
+
return this.#developmentMode;
|
|
1805
|
+
}
|
|
1806
|
+
async #requireDeveloperIdentityAccess() {
|
|
1807
|
+
const decision = await this.#checkDevelopmentMode();
|
|
1808
|
+
if (decision.state === "enabled")
|
|
1809
|
+
return;
|
|
1810
|
+
this.#acceptedIdentity = void 0;
|
|
1811
|
+
if (decision.state === "disabled") {
|
|
1812
|
+
throw new ToolError(
|
|
1813
|
+
"DEVELOPER_IDENTITY_DISABLED",
|
|
1814
|
+
"the target Zone has developer mode disabled; local developer identities are unavailable",
|
|
1815
|
+
EXIT_AUTH
|
|
1816
|
+
);
|
|
1817
|
+
}
|
|
1818
|
+
throw new ToolError(
|
|
1819
|
+
"DEVELOPER_MODE_UNAVAILABLE",
|
|
1820
|
+
"the target Zone developer-mode configuration could not be verified",
|
|
1821
|
+
EXIT_AUTH,
|
|
1822
|
+
true,
|
|
1823
|
+
{ reason: sanitizeMessage(decision.reason) }
|
|
1824
|
+
);
|
|
1825
|
+
}
|
|
1724
1826
|
}
|
|
1725
1827
|
function isIdentityRejection(error) {
|
|
1726
1828
|
return error instanceof ToolError && IDENTITY_REJECTION_CODES.includes(error.code);
|
|
@@ -1984,12 +2086,17 @@ function displayValue(value) {
|
|
|
1984
2086
|
const KEBAB_CASE = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
|
|
1985
2087
|
const GLOBAL_OPTIONS = [
|
|
1986
2088
|
{ name: "config-dir", property: "configDir", type: "string", scope: "process" },
|
|
2089
|
+
{
|
|
2090
|
+
name: "allow-read",
|
|
2091
|
+
property: "allowRead",
|
|
2092
|
+
type: "string",
|
|
2093
|
+
scope: "process",
|
|
2094
|
+
repeatable: true
|
|
2095
|
+
},
|
|
1987
2096
|
{ name: "profile", property: "profile", type: "string", scope: "session" },
|
|
1988
2097
|
{ name: "zone", property: "zone", type: "string", scope: "session" },
|
|
1989
2098
|
{ name: "endpoint", property: "endpoint", type: "string", scope: "session" },
|
|
1990
2099
|
{ name: "identity", property: "identity", type: "string", scope: "session" },
|
|
1991
|
-
{ name: "identity-root", property: "identityRoot", type: "string", scope: "session" },
|
|
1992
|
-
{ name: "security-root", property: "securityRoot", type: "string", scope: "session" },
|
|
1993
2100
|
{
|
|
1994
2101
|
name: "session-token",
|
|
1995
2102
|
property: "sessionToken",
|
|
@@ -4741,7 +4848,7 @@ function invalid(stage, message, entry) {
|
|
|
4741
4848
|
function stableJsonDigest(value) {
|
|
4742
4849
|
return sha256Bytes(new TextEncoder().encode(ndn.toCanonicalJsonString(value)));
|
|
4743
4850
|
}
|
|
4744
|
-
const PACKAGE_VERSION = "0.7.
|
|
4851
|
+
const PACKAGE_VERSION = "0.7.118";
|
|
4745
4852
|
const TOOL_VERSION = PACKAGE_VERSION;
|
|
4746
4853
|
const SDK_VERSION = PACKAGE_VERSION;
|
|
4747
4854
|
const PROTOCOL_VERSION = "1";
|
|
@@ -8795,6 +8902,7 @@ function topLevelHelp(registry) {
|
|
|
8795
8902
|
"",
|
|
8796
8903
|
"Global options:",
|
|
8797
8904
|
" --config-dir <path> --profile <name> --zone <host-or-did>",
|
|
8905
|
+
" --allow-read <path> Add a readable filesystem root (repeatable)",
|
|
8798
8906
|
" --endpoint <url> --identity <did-or-name>",
|
|
8799
8907
|
" --session-token <token> | --session-token-file <path>",
|
|
8800
8908
|
" Prefer --session-token-file for automation; argv tokens may appear in process listings.",
|