@skrr-ai/cli 0.1.123 → 0.1.125
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/dist/commands/agents/chat.d.ts +26 -0
- package/dist/commands/agents/chat.js +48 -10
- package/dist/commands/agents/delete.d.ts +8 -0
- package/dist/commands/agents/delete.js +16 -0
- package/dist/commands/context.js +7 -0
- package/dist/commands/search/workspace.js +1 -1
- package/dist/commands/store/gallery-admissions/approve.js +1 -1
- package/dist/commands/store/gallery-admissions/preview.js +1 -1
- package/dist/commands/store/gallery-admissions/refuse.js +1 -1
- package/dist/commands/store/gallery-admissions/show.js +1 -1
- package/dist/generated/agent-guides.json +19 -19
- package/dist/lib/agentic-stream.js +15 -1
- package/dist/lib/auth-core-init.d.ts +15 -2
- package/dist/lib/auth-core-init.js +47 -6
- package/dist/lib/command-hygiene.js +30 -1
- package/dist/lib/daemonBrokerRefusal.js +5 -1
- package/dist/lib/keychain.js +41 -4
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/cliHandoffWire.d.ts +5 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/cliHandoffWire.js +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/credentialEnvelopeBridge.js +13 -28
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/deviceIdentityBridge.d.ts +133 -4
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/deviceIdentityBridge.js +387 -90
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/deviceKey.d.ts +106 -7
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/deviceKey.js +77 -19
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/deviceKeyHandle.d.ts +33 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/deviceKeyHandle.js +77 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/deviceKeyHardware.d.ts +68 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/deviceKeyHardware.js +264 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/deviceKeyServerSupport.d.ts +31 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/deviceKeyServerSupport.js +90 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/dpop.js +2 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/independentMachineReservation.js +2 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +7 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +102 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/kek/index.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/kek/index.js +6 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/kek/linux.d.ts +18 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/kek/linux.js +8 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/kek/macos.d.ts +22 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/kek/macos.js +11 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/kek/masterKekService.d.ts +43 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/kek/masterKekService.js +33 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/liveState.d.ts +154 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/liveState.js +281 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/machineId.js +6 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/machineUuid.js +8 -5
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/profileStateDir.js +7 -27
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/refresh.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/refresh.js +12 -10
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/stateFiles.d.ts +31 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/stateFiles.js +89 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/cliHandoffWire.d.ts +5 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/cliHandoffWire.js +4 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/credentialEnvelopeBridge.js +15 -37
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/deviceIdentityBridge.d.ts +133 -4
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/deviceIdentityBridge.js +536 -101
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/deviceKey.d.ts +106 -7
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/deviceKey.js +131 -27
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/deviceKeyHandle.d.ts +33 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/deviceKeyHandle.js +81 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/deviceKeyHardware.d.ts +68 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/deviceKeyHardware.js +317 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/deviceKeyServerSupport.d.ts +31 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/deviceKeyServerSupport.js +86 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/dpop.js +4 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/independentMachineReservation.js +4 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +7 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +13 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/kek/index.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/kek/index.js +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/kek/linux.d.ts +18 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/kek/linux.js +15 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/kek/macos.d.ts +22 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/kek/macos.js +20 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/kek/masterKekService.d.ts +43 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/kek/masterKekService.js +104 -8
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/liveState.d.ts +154 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/liveState.js +386 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/machineId.js +6 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/machineUuid.js +11 -5
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/profileStateDir.js +6 -35
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/refresh.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/refresh.js +14 -10
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/stateFiles.d.ts +31 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/stateFiles.js +73 -0
- package/dist/node_modules/@skrr-ai/auth-core/package.json +11 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +1094 -1067
- package/oclif.manifest.json +16 -3
- package/package.json +4 -1
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var deviceKeyHardware_exports = {};
|
|
30
|
+
__export(deviceKeyHardware_exports, {
|
|
31
|
+
HARDWARE_KEY_HELPER_NAME: () => HARDWARE_KEY_HELPER_NAME,
|
|
32
|
+
HARDWARE_KEY_PROTOCOL: () => HARDWARE_KEY_PROTOCOL,
|
|
33
|
+
HardwareDeviceKeyError: () => HardwareDeviceKeyError,
|
|
34
|
+
__resetHardwareProbeForTest: () => __resetHardwareProbeForTest,
|
|
35
|
+
__setHardwareHelperTimeoutForTest: () => __setHardwareHelperTimeoutForTest,
|
|
36
|
+
configureHardwareDeviceKeyHelper: () => configureHardwareDeviceKeyHelper,
|
|
37
|
+
createHardwareDeviceKey: () => createHardwareDeviceKey,
|
|
38
|
+
hardwareDeviceKeyHandle: () => hardwareDeviceKeyHandle,
|
|
39
|
+
parseHardwareKeyRecord: () => parseHardwareKeyRecord,
|
|
40
|
+
probeHardwareDeviceKey: () => probeHardwareDeviceKey,
|
|
41
|
+
resolveHardwareDeviceKeyHelper: () => resolveHardwareDeviceKeyHelper,
|
|
42
|
+
serializeHardwareKeyRecord: () => serializeHardwareKeyRecord
|
|
43
|
+
});
|
|
44
|
+
module.exports = __toCommonJS(deviceKeyHardware_exports);
|
|
45
|
+
var import_node_crypto = __toESM(require("node:crypto"), 1);
|
|
46
|
+
var import_node_child_process = require("node:child_process");
|
|
47
|
+
var import_node_fs = __toESM(require("node:fs"), 1);
|
|
48
|
+
var import_node_path = __toESM(require("node:path"), 1);
|
|
49
|
+
var import_deviceKey = require("./deviceKey.js");
|
|
50
|
+
var import_runtime = require("./runtime.js");
|
|
51
|
+
const HARDWARE_KEY_HELPER_NAME = "skrr-native-device-key";
|
|
52
|
+
const HARDWARE_KEY_PROTOCOL = 1;
|
|
53
|
+
const PROBE_TIMEOUT_MS = 5e3;
|
|
54
|
+
const CREATE_TIMEOUT_MS = 15e3;
|
|
55
|
+
const SIGN_TIMEOUT_MS = 1e4;
|
|
56
|
+
const PROBE_RETRY_MS = 6e4;
|
|
57
|
+
class HardwareDeviceKeyError extends Error {
|
|
58
|
+
code;
|
|
59
|
+
constructor(code, message) {
|
|
60
|
+
super(message);
|
|
61
|
+
this.code = code;
|
|
62
|
+
this.name = "HardwareDeviceKeyError";
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
let _resolver = null;
|
|
66
|
+
function configureHardwareDeviceKeyHelper(resolver) {
|
|
67
|
+
_resolver = resolver;
|
|
68
|
+
_probe = null;
|
|
69
|
+
}
|
|
70
|
+
function isExecutableFile(file) {
|
|
71
|
+
try {
|
|
72
|
+
if (!import_node_fs.default.statSync(file).isFile())
|
|
73
|
+
return false;
|
|
74
|
+
import_node_fs.default.accessSync(file, import_node_fs.default.constants.X_OK);
|
|
75
|
+
return true;
|
|
76
|
+
} catch {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function resolveHardwareDeviceKeyHelper() {
|
|
81
|
+
const candidates = [];
|
|
82
|
+
try {
|
|
83
|
+
candidates.push(_resolver ? _resolver() : null);
|
|
84
|
+
} catch {
|
|
85
|
+
}
|
|
86
|
+
candidates.push(import_node_path.default.join(import_node_path.default.dirname(process.execPath), HARDWARE_KEY_HELPER_NAME));
|
|
87
|
+
try {
|
|
88
|
+
candidates.push(import_node_path.default.join((0, import_runtime.getAuthMachineConfigDir)(), "bin", HARDWARE_KEY_HELPER_NAME));
|
|
89
|
+
} catch {
|
|
90
|
+
}
|
|
91
|
+
for (const candidate of candidates) {
|
|
92
|
+
if (candidate && import_node_path.default.isAbsolute(candidate) && isExecutableFile(candidate))
|
|
93
|
+
return candidate;
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
let _timeoutOverrideMs = null;
|
|
98
|
+
function __setHardwareHelperTimeoutForTest(ms) {
|
|
99
|
+
_timeoutOverrideMs = ms;
|
|
100
|
+
}
|
|
101
|
+
function runHelper(op, request, timeoutMs) {
|
|
102
|
+
const helper = resolveHardwareDeviceKeyHelper();
|
|
103
|
+
if (!helper) {
|
|
104
|
+
return Promise.reject(new HardwareDeviceKeyError("helper_missing", `${HARDWARE_KEY_HELPER_NAME} is not installed on this machine`));
|
|
105
|
+
}
|
|
106
|
+
return new Promise((resolve, reject) => {
|
|
107
|
+
const child = (0, import_node_child_process.execFile)(
|
|
108
|
+
helper,
|
|
109
|
+
[op],
|
|
110
|
+
// No shell, no inherited environment: the helper needs nothing from ours,
|
|
111
|
+
// and a signing process should not see session tokens it has no use for.
|
|
112
|
+
{
|
|
113
|
+
timeout: _timeoutOverrideMs ?? timeoutMs,
|
|
114
|
+
maxBuffer: 64 * 1024,
|
|
115
|
+
windowsHide: true,
|
|
116
|
+
env: {},
|
|
117
|
+
encoding: "utf8"
|
|
118
|
+
},
|
|
119
|
+
(error, stdout) => {
|
|
120
|
+
let parsed = null;
|
|
121
|
+
try {
|
|
122
|
+
parsed = JSON.parse(stdout);
|
|
123
|
+
} catch {
|
|
124
|
+
parsed = null;
|
|
125
|
+
}
|
|
126
|
+
if (error) {
|
|
127
|
+
if (error.killed) {
|
|
128
|
+
reject(new HardwareDeviceKeyError("timeout", `${op} did not finish within ${_timeoutOverrideMs ?? timeoutMs} ms`));
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const code = parsed?.error?.code;
|
|
132
|
+
const message = parsed?.error?.message;
|
|
133
|
+
reject(new HardwareDeviceKeyError(code === "unsupported" ? "unsupported" : "helper_failed", typeof message === "string" ? message : `${op} failed: ${error.message}`));
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (!parsed || parsed.v !== HARDWARE_KEY_PROTOCOL) {
|
|
137
|
+
reject(new HardwareDeviceKeyError("bad_response", `${op} returned an unexpected response`));
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
resolve(parsed);
|
|
141
|
+
}
|
|
142
|
+
);
|
|
143
|
+
child.stdin?.on("error", () => {
|
|
144
|
+
});
|
|
145
|
+
child.stdin?.end(JSON.stringify({ v: HARDWARE_KEY_PROTOCOL, ...request }));
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
function decodeFixed(value, bytes, what) {
|
|
149
|
+
if (typeof value !== "string")
|
|
150
|
+
throw new HardwareDeviceKeyError("bad_response", `${what} is missing`);
|
|
151
|
+
const buf = Buffer.from(value, "base64");
|
|
152
|
+
if (buf.length !== bytes) {
|
|
153
|
+
throw new HardwareDeviceKeyError("bad_response", `${what} is ${buf.length} bytes, expected ${bytes}`);
|
|
154
|
+
}
|
|
155
|
+
return buf;
|
|
156
|
+
}
|
|
157
|
+
let _probe = null;
|
|
158
|
+
async function probeHardwareDeviceKey() {
|
|
159
|
+
if (_probe && (_probe.result.available || Date.now() - _probe.at < PROBE_RETRY_MS))
|
|
160
|
+
return _probe.result;
|
|
161
|
+
let result;
|
|
162
|
+
try {
|
|
163
|
+
const res = await runHelper("probe", {}, PROBE_TIMEOUT_MS);
|
|
164
|
+
result = res.secureEnclave === true ? { available: true } : { available: false, reason: "no_secure_hardware" };
|
|
165
|
+
} catch (err) {
|
|
166
|
+
const e = err;
|
|
167
|
+
result = {
|
|
168
|
+
available: false,
|
|
169
|
+
reason: e.code === "helper_missing" ? "helper_missing" : e.code === "unsupported" ? "no_secure_hardware" : "probe_failed",
|
|
170
|
+
message: e.message
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
_probe = { result, at: Date.now() };
|
|
174
|
+
return result;
|
|
175
|
+
}
|
|
176
|
+
function __resetHardwareProbeForTest() {
|
|
177
|
+
_probe = null;
|
|
178
|
+
}
|
|
179
|
+
function serializeHardwareKeyRecord(record, createdAt = /* @__PURE__ */ new Date()) {
|
|
180
|
+
return JSON.stringify({
|
|
181
|
+
v: 1,
|
|
182
|
+
alg: "ES256",
|
|
183
|
+
custody: "hardware",
|
|
184
|
+
blob: record.blob,
|
|
185
|
+
publicJwk: record.publicJwk,
|
|
186
|
+
thumbprint: (0, import_deviceKey.jwkThumbprint)(record.publicJwk),
|
|
187
|
+
createdAt: createdAt.toISOString()
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
function parseHardwareKeyRecord(text) {
|
|
191
|
+
try {
|
|
192
|
+
const parsed = JSON.parse(text);
|
|
193
|
+
if (parsed.v !== 1 || parsed.alg !== "ES256" || typeof parsed.blob !== "string" || parsed.blob.length === 0) {
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
if (!(0, import_deviceKey.isDevicePublicJwk)(parsed.publicJwk) || parsed.publicJwk.kty !== "EC")
|
|
197
|
+
return null;
|
|
198
|
+
if (parsed.thumbprint !== (0, import_deviceKey.jwkThumbprint)(parsed.publicJwk))
|
|
199
|
+
return null;
|
|
200
|
+
return { blob: parsed.blob, publicJwk: parsed.publicJwk };
|
|
201
|
+
} catch {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
function hardwareDeviceKeyHandle(record) {
|
|
206
|
+
const publicRaw = Buffer.concat([
|
|
207
|
+
Buffer.from(record.publicJwk.x, "base64url"),
|
|
208
|
+
Buffer.from(record.publicJwk.y, "base64url")
|
|
209
|
+
]);
|
|
210
|
+
return {
|
|
211
|
+
alg: "ES256",
|
|
212
|
+
custody: "hardware",
|
|
213
|
+
publicJwk: record.publicJwk,
|
|
214
|
+
thumbprint: (0, import_deviceKey.jwkThumbprint)(record.publicJwk),
|
|
215
|
+
sign: async (signingInput) => {
|
|
216
|
+
const res = await runHelper("sign", { blob: record.blob, input: Buffer.from(signingInput).toString("base64") }, SIGN_TIMEOUT_MS);
|
|
217
|
+
const signature = decodeFixed(res.signature, 64, "signature");
|
|
218
|
+
const reported = decodeFixed(res.publicKey, 64, "publicKey");
|
|
219
|
+
if (!reported.equals(publicRaw)) {
|
|
220
|
+
throw new HardwareDeviceKeyError("key_mismatch", "the stored hardware key is not the key this record names");
|
|
221
|
+
}
|
|
222
|
+
return new Uint8Array(signature);
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
async function createHardwareDeviceKey() {
|
|
227
|
+
const res = await runHelper("create", {}, CREATE_TIMEOUT_MS);
|
|
228
|
+
if (typeof res.blob !== "string" || res.blob.length === 0) {
|
|
229
|
+
throw new HardwareDeviceKeyError("bad_response", "create returned no key");
|
|
230
|
+
}
|
|
231
|
+
const publicJwk = (0, import_deviceKey.p256PublicJwkFromRaw)(decodeFixed(res.publicKey, 64, "publicKey"));
|
|
232
|
+
if (!(0, import_deviceKey.isDevicePublicJwk)(publicJwk))
|
|
233
|
+
throw new HardwareDeviceKeyError("bad_response", "create returned an invalid key");
|
|
234
|
+
const record = { blob: res.blob, publicJwk };
|
|
235
|
+
const handle = hardwareDeviceKeyHandle(record);
|
|
236
|
+
const challenge = import_node_crypto.default.randomBytes(32);
|
|
237
|
+
const signature = await handle.sign(challenge);
|
|
238
|
+
const verified = import_node_crypto.default.verify("sha256", challenge, {
|
|
239
|
+
key: import_node_crypto.default.createPublicKey({
|
|
240
|
+
format: "jwk",
|
|
241
|
+
key: publicJwk
|
|
242
|
+
}),
|
|
243
|
+
dsaEncoding: "ieee-p1363"
|
|
244
|
+
}, Buffer.from(signature));
|
|
245
|
+
if (!verified) {
|
|
246
|
+
throw new HardwareDeviceKeyError("key_mismatch", "a signature from the new hardware key did not verify");
|
|
247
|
+
}
|
|
248
|
+
return { record, handle };
|
|
249
|
+
}
|
|
250
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
251
|
+
0 && (module.exports = {
|
|
252
|
+
HARDWARE_KEY_HELPER_NAME,
|
|
253
|
+
HARDWARE_KEY_PROTOCOL,
|
|
254
|
+
HardwareDeviceKeyError,
|
|
255
|
+
__resetHardwareProbeForTest,
|
|
256
|
+
__setHardwareHelperTimeoutForTest,
|
|
257
|
+
configureHardwareDeviceKeyHelper,
|
|
258
|
+
createHardwareDeviceKey,
|
|
259
|
+
hardwareDeviceKeyHandle,
|
|
260
|
+
parseHardwareKeyRecord,
|
|
261
|
+
probeHardwareDeviceKey,
|
|
262
|
+
resolveHardwareDeviceKeyHelper,
|
|
263
|
+
serializeHardwareKeyRecord
|
|
264
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* deviceKeyServerSupport.ts — which device-key algorithms does THIS server pin?
|
|
3
|
+
*
|
|
4
|
+
* A hardware-bound key is ES256, and a server that predates ES256 cannot pin one:
|
|
5
|
+
* enrolling it would fail, and a profile that had swapped its working key for it
|
|
6
|
+
* would be unable to sign in at all. So a client creates a hardware key only when
|
|
7
|
+
* the server has said it will accept one, and everything else (an older server,
|
|
8
|
+
* an unreachable one, a malformed answer, a redirect) is "unknown", which means
|
|
9
|
+
* "keep the key you have". The cost of being wrong in that direction is a
|
|
10
|
+
* software key a little longer; in the other it is a machine that cannot log in.
|
|
11
|
+
*
|
|
12
|
+
* The server says it in the RFC 8414 authorization-server metadata it already
|
|
13
|
+
* publishes, in the same `_values_supported` style that document uses for its own
|
|
14
|
+
* algorithm lists.
|
|
15
|
+
*/
|
|
16
|
+
import { type DeviceKeyAlg } from './deviceKey.js';
|
|
17
|
+
/** Path of the metadata document (RFC 8414 §3), relative to the server's origin. */
|
|
18
|
+
export declare const AUTH_SERVER_METADATA_PATH = "/.well-known/oauth-authorization-server";
|
|
19
|
+
/** The metadata field listing the device-key algorithms the server will pin. */
|
|
20
|
+
export declare const SERVER_DEVICE_KEY_ALGS_FIELD = "device_key_signing_alg_values_supported";
|
|
21
|
+
/** @internal Test seam. */
|
|
22
|
+
export declare function __resetServerDeviceKeyAlgsForTest(): void;
|
|
23
|
+
/**
|
|
24
|
+
* The device-key algorithms the server at `serverUrl` accepts, or null when that
|
|
25
|
+
* is not known. Never throws and never sends a credential: it is a plain GET of a
|
|
26
|
+
* public document.
|
|
27
|
+
*/
|
|
28
|
+
export declare function readServerDeviceKeyAlgs(serverUrl: string, opts?: {
|
|
29
|
+
fetchImpl?: typeof fetch;
|
|
30
|
+
timeoutMs?: number;
|
|
31
|
+
}): Promise<readonly DeviceKeyAlg[] | null>;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var deviceKeyServerSupport_exports = {};
|
|
20
|
+
__export(deviceKeyServerSupport_exports, {
|
|
21
|
+
AUTH_SERVER_METADATA_PATH: () => AUTH_SERVER_METADATA_PATH,
|
|
22
|
+
SERVER_DEVICE_KEY_ALGS_FIELD: () => SERVER_DEVICE_KEY_ALGS_FIELD,
|
|
23
|
+
__resetServerDeviceKeyAlgsForTest: () => __resetServerDeviceKeyAlgsForTest,
|
|
24
|
+
readServerDeviceKeyAlgs: () => readServerDeviceKeyAlgs
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(deviceKeyServerSupport_exports);
|
|
27
|
+
var import_deviceKey = require("./deviceKey.js");
|
|
28
|
+
const AUTH_SERVER_METADATA_PATH = "/.well-known/oauth-authorization-server";
|
|
29
|
+
const SERVER_DEVICE_KEY_ALGS_FIELD = "device_key_signing_alg_values_supported";
|
|
30
|
+
const TIMEOUT_MS = 5e3;
|
|
31
|
+
const MAX_BYTES = 64 * 1024;
|
|
32
|
+
const UNKNOWN_RETRY_MS = 6e4;
|
|
33
|
+
const cache = /* @__PURE__ */ new Map();
|
|
34
|
+
function __resetServerDeviceKeyAlgsForTest() {
|
|
35
|
+
cache.clear();
|
|
36
|
+
}
|
|
37
|
+
async function readServerDeviceKeyAlgs(serverUrl, opts = {}) {
|
|
38
|
+
let origin;
|
|
39
|
+
try {
|
|
40
|
+
origin = new URL(serverUrl).origin;
|
|
41
|
+
} catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
if (origin === "null")
|
|
45
|
+
return null;
|
|
46
|
+
const hit = cache.get(origin);
|
|
47
|
+
if (hit && (hit.algs !== null || Date.now() - hit.at < UNKNOWN_RETRY_MS))
|
|
48
|
+
return hit.algs;
|
|
49
|
+
const algs = await fetchAlgs(origin, opts);
|
|
50
|
+
cache.set(origin, { algs, at: Date.now() });
|
|
51
|
+
return algs;
|
|
52
|
+
}
|
|
53
|
+
async function fetchAlgs(origin, opts) {
|
|
54
|
+
const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
|
|
55
|
+
if (typeof fetchImpl !== "function")
|
|
56
|
+
return null;
|
|
57
|
+
const controller = new AbortController();
|
|
58
|
+
const timer = setTimeout(() => controller.abort(), opts.timeoutMs ?? TIMEOUT_MS);
|
|
59
|
+
try {
|
|
60
|
+
const res = await fetchImpl(`${origin}${AUTH_SERVER_METADATA_PATH}`, {
|
|
61
|
+
method: "GET",
|
|
62
|
+
headers: { Accept: "application/json" },
|
|
63
|
+
// The metadata lives at the issuer. A redirect is a server we did not ask.
|
|
64
|
+
redirect: "manual",
|
|
65
|
+
signal: controller.signal
|
|
66
|
+
});
|
|
67
|
+
if (res.status !== 200)
|
|
68
|
+
return null;
|
|
69
|
+
const text = await res.text();
|
|
70
|
+
if (text.length > MAX_BYTES)
|
|
71
|
+
return null;
|
|
72
|
+
const body = JSON.parse(text);
|
|
73
|
+
const listed = body[SERVER_DEVICE_KEY_ALGS_FIELD];
|
|
74
|
+
if (!Array.isArray(listed))
|
|
75
|
+
return null;
|
|
76
|
+
const known = import_deviceKey.DEVICE_KEY_ALGS.filter((alg) => listed.includes(alg));
|
|
77
|
+
return known.length > 0 ? known : null;
|
|
78
|
+
} catch {
|
|
79
|
+
return null;
|
|
80
|
+
} finally {
|
|
81
|
+
clearTimeout(timer);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
85
|
+
0 && (module.exports = {
|
|
86
|
+
AUTH_SERVER_METADATA_PATH,
|
|
87
|
+
SERVER_DEVICE_KEY_ALGS_FIELD,
|
|
88
|
+
__resetServerDeviceKeyAlgsForTest,
|
|
89
|
+
readServerDeviceKeyAlgs
|
|
90
|
+
});
|
|
@@ -113,6 +113,8 @@ function verifyDpopProof(jws, opts) {
|
|
|
113
113
|
if (!result.valid) {
|
|
114
114
|
return { valid: false, reason: result.reason };
|
|
115
115
|
}
|
|
116
|
+
if (result.publicJwk.kty !== "OKP")
|
|
117
|
+
return { valid: false, reason: "bad_jwk" };
|
|
116
118
|
if (result.claims.jti.length === 0)
|
|
117
119
|
return { valid: false, reason: "malformed" };
|
|
118
120
|
if (opts.expectedAth !== void 0) {
|
|
@@ -38,6 +38,7 @@ module.exports = __toCommonJS(independentMachineReservation_exports);
|
|
|
38
38
|
var import_node_crypto = __toESM(require("node:crypto"), 1);
|
|
39
39
|
var import_node_fs = __toESM(require("node:fs"), 1);
|
|
40
40
|
var import_node_path = __toESM(require("node:path"), 1);
|
|
41
|
+
var import_liveState = require("./liveState.js");
|
|
41
42
|
const INDEPENDENT_MACHINE_PROFILE_RE = /^desktop-bg-[a-f0-9]{32}$/;
|
|
42
43
|
const INDEPENDENT_MACHINE_RESERVATION_FILE = "independent-machine-attempt.json";
|
|
43
44
|
function canonicalOrigin(input) {
|
|
@@ -70,6 +71,7 @@ function reserveIndependentMachineProfile(options) {
|
|
|
70
71
|
throw new Error("Background authorization secure storage is unavailable");
|
|
71
72
|
}
|
|
72
73
|
const profiles = import_node_path.default.join(options.root, "profiles");
|
|
74
|
+
(0, import_liveState.assertMayMutateLiveState)(profiles, "reserve a background machine profile");
|
|
73
75
|
const rootExisted = import_node_fs.default.existsSync(options.root);
|
|
74
76
|
const profilesExisted = import_node_fs.default.existsSync(profiles);
|
|
75
77
|
import_node_fs.default.mkdirSync(profiles, { recursive: true, mode: 448 });
|
|
@@ -25,11 +25,15 @@ export { loginWithLocalhost, LoginInitError, LoginExchangeError, type BrowserOpe
|
|
|
25
25
|
export { parseTtlDays, MIN_TTL_DAYS, MAX_TTL_DAYS, type ParseTtlResult, type ParseTtlSuccess, type ParseTtlError, } from './ttlParser.js';
|
|
26
26
|
export { formatRecoveryCode, parseRecoveryCode, normalizeRecoveryCode, isValidRecoveryCode, } from './recoveryCode.js';
|
|
27
27
|
export { buildCredentialAad, decrypt as credEnvelopeDecrypt, deserialize as credEnvelopeDeserialize, encrypt as credEnvelopeEncrypt, ENVELOPE_MAGIC as CRED_ENVELOPE_MAGIC, generateDek, isEnvelopeString as isCredEnvelopeString, KEY_LEN as CRED_KEY_LEN, openBuffer as credOpenBuffer, sealBuffer as credSealBuffer, serialize as credEnvelopeSerialize, unwrap as credEnvelopeUnwrap, wrap as credEnvelopeWrap, type SealedBlob as CredSealedBlob, } from './credentialEnvelope.js';
|
|
28
|
-
export { __setKekStrategyForTest, getKekStrategy, InMemoryKek, UnavailableKek, KekUnavailableError, isMasterKekKeychainService, LinuxKek, MacosKek, MASTER_KEK_KEYCHAIN_ACCOUNT, MASTER_KEK_KEYCHAIN_SERVICE, registerZeroizeHook, WindowsKek, zeroizeKekCaches, type KekStrategy, } from './kek/index.js';
|
|
29
|
-
export {
|
|
28
|
+
export { __setKekStrategyForTest, getKekStrategy, InMemoryKek, UnavailableKek, KekUnavailableError, classifyDaemonKeychainService, isMasterKekKeychainService, isSessionKeychainService, isUserOwnedSecretKeychainService, LinuxKek, MacosKek, MASTER_KEK_KEYCHAIN_ACCOUNT, MASTER_KEK_KEYCHAIN_SERVICE, registerZeroizeHook, WindowsKek, zeroizeKekCaches, type DaemonKeychainServiceClass, type KekStrategy, } from './kek/index.js';
|
|
29
|
+
export { ALLOW_LIVE_STATE_ENV, __setAccountHomeForTest, DAEMON_BYOK_KEYCHAIN_SERVICE_BASE, DAEMON_KEYCHAIN_SERVICE_BASE, HERMETIC_HOME_ENV, LEGACY_DAEMON_KEYCHAIN_SERVICE, LIVE_DEFAULT_PROFILE, LIVE_STATE_REFUSED_CODE, LiveStateRefusedError, accountHomeDir, assertMayMutateLiveKeychain, assertMayMutateLiveState, isLiveKeychainService, isLiveStateRefusal, isTestProcess, keychainSuffixForDir, liveKeychainServices, liveStateRoot, refusesLiveKeychainMutation, refusesLiveStateInTest, rethrowIfLiveStateRefusal, testProcessSignal, type LiveKeychainProbe, type LiveStateProbe, } from './liveState.js';
|
|
30
|
+
export { algForJwk, buildProof as buildDeviceProof, DEVICE_KEY_ALGS, generateDeviceKeyPair, isDevicePublicJwk, jwkThumbprint, normalizeHtu, p256PublicJwkFromRaw, proofSigningInput, publicJwkFromX, signProofWith, tokenHash, verifyProof as verifyDeviceProof, type DeviceKeyAlg, type DeviceKeyPair, type DeviceKeySigner, type DevicePublicJwk, type DeviceProofClaims, type DeviceProofHeader, type Ed25519PrivateJwk, type Ed25519PublicJwk, type P256PublicJwk, type VerifyFailureReason as DeviceProofVerifyFailureReason, type VerifyFailure as DeviceProofVerifyFailure, type VerifyOptions as DeviceProofVerifyOptions, type VerifySuccess as DeviceProofVerifySuccess, } from './deviceKey.js';
|
|
31
|
+
export { softwareEd25519Handle, type DeviceKeyCustody, type DeviceKeyHandle } from './deviceKeyHandle.js';
|
|
32
|
+
export { AUTH_SERVER_METADATA_PATH, readServerDeviceKeyAlgs, SERVER_DEVICE_KEY_ALGS_FIELD, } from './deviceKeyServerSupport.js';
|
|
33
|
+
export { configureHardwareDeviceKeyHelper, HARDWARE_KEY_HELPER_NAME, HardwareDeviceKeyError, probeHardwareDeviceKey, resolveHardwareDeviceKeyHelper, type HardwareDeviceKeyErrorCode, type HardwareKeyCapability, } from './deviceKeyHardware.js';
|
|
30
34
|
export { DPOP_HEADER, DPOP_MAX_AGE_SECONDS, DPOP_PROOF_INVALID, DPOP_PROOF_REQUIRED, DPOP_PROOF_TYP, DPOP_PROOF_VERIFY_UNAVAILABLE, accessTokenHash, createDpopKey, isAth, isJwkThumbprint, normalizeDpopHtu, verifyDpopProof, type DpopKey, type DpopProofClaims, type DpopProofRequest, type DpopVerifyFailureReason, type DpopVerifyOptions, type DpopVerifyResult, } from './dpop.js';
|
|
31
35
|
export { initCredEnvelope, initExistingCredEnvelope, initNewIndependentCredEnvelope, resetCredEnvelope, shutdownCredEnvelope, isCredEnvelopeActive, hasCredEnvelopePathConflict, describeCredEnvelopeState, splitKeyConvergencePolicy, maybeEncryptForWrite, maybeDecryptOnRead, DEFAULT_UNREADABLE_CREDENTIAL_HINT, type DecryptOnReadOptions, __wrappedDekFilePathForTest, __setStateForTest as __setCredEnvelopeStateForTest, __getStateForTest as __getCredEnvelopeStateForTest, __resetShutdownGuardForTest, type ReadTransformResult, } from './credentialEnvelopeBridge.js';
|
|
32
|
-
export { initDeviceIdentity, resetDeviceIdentity, signServerRequest, enrollWithServer, clearEnrollmentMarker, isDeviceIdentityActive, getDevicePublicKey, describeDeviceIdentityState, describeDeviceKeySplit, __publicKeyPathForTest, __privateKeyPathForTest, __enrollmentMarkerPathForTest, __enrollmentBackoffPathForTest, __setUnreadableReloadIntervalForTest, __setStateForTest as __setDeviceIdentityStateForTest, __getStateForTest as __getDeviceIdentityStateForTest, type EnrollmentResult, } from './deviceIdentityBridge.js';
|
|
36
|
+
export { initDeviceIdentity, resetDeviceIdentity, signServerRequest, prepareHardwareKeyCandidate, commitDeviceKeyCandidate, signWithCandidate, persistPendingHardwareKey, commitPendingHardwareKey, discardPendingHardwareKey, PENDING_HARDWARE_KEY_MAX_AGE_MS, type DeviceKeyCandidate, type DeviceKeyCandidateResult, type PendingHardwareKeyOutcome, enrollWithServer, clearEnrollmentMarker, isDeviceIdentityActive, getDevicePublicKey, describeDeviceIdentityState, describeDeviceKeySplit, describeStoredDeviceKey, DEVICE_KEY_UNREADABLE_CREDENTIAL_HINT, type StoredDeviceKeyDescription, __publicKeyPathForTest, __privateKeyPathForTest, __enrollmentMarkerPathForTest, __enrollmentBackoffPathForTest, __setUnreadableReloadIntervalForTest, __setStateForTest as __setDeviceIdentityStateForTest, __getStateForTest as __getDeviceIdentityStateForTest, type EnrollmentResult, } from './deviceIdentityBridge.js';
|
|
33
37
|
export { getMachineUuid, getMachineUuidForProfile, describeMachineIdentity, type MachineIdentityDescription, type MachineIdentityReason, getHardwareMachineUuid, setMachineUuidProfile, getMachineUuidProfile, qualifyMachineUuid, MACHINE_IDENTITY_FILENAME, hostedRuntimeIdOverride, HOSTED_RUNTIME_MACHINE_SOURCES, __resetMachineUuidCacheForTest, } from './machineUuid.js';
|
|
34
38
|
export { ensureMachineDaemonId, legacyDaemonUuids, __resetCachedDaemonIdForTest, } from './machineId.js';
|
|
35
39
|
export { PAIR_AAD_PREFIX, PAIR_AAD_MAX_LEN, PAIR_BUNDLE_MAX_BASE64_LEN, PAIR_NONCE_LEN, PAIR_PUBKEY_LEN, PAIR_SECRET_LEN, PairBundleError, assemblePairBundleBase64, base64ToUint8Array as pairBase64ToUint8Array, base64UrlToUint8Array as pairBase64UrlToUint8Array, buildPairAad, buildPairUrl, generatePairKeyPair, openPairBundleBase64, parsePairBundle, parsePairPlaintext, parsePairUrl, uint8ArrayToBase64 as pairUint8ArrayToBase64, uint8ArrayToBase64Url as pairUint8ArrayToBase64Url, type AssembleBundleOptions as PairAssembleBundleOptions, type OpenBundleOptions as PairOpenBundleOptions, type PairBundle, type PairBundleErrorCode, type PairKeyPair, type PairPlaintextV1, type PairUrlFields, } from './daemonPair.js';
|