happy-coder 0.10.0-3 → 0.10.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 +10 -1
- package/dist/{index-DPVbp4Yx.mjs → index-BI37NnoW.mjs} +93 -87
- package/dist/{index-tqOLc1Il.cjs → index-ettJex_e.cjs} +115 -87
- package/dist/index.cjs +3 -2
- package/dist/index.mjs +3 -2
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +44 -110
- package/dist/lib.d.mts +44 -110
- package/dist/lib.mjs +1 -1
- package/dist/{runCodex-C07HQlsW.mjs → runCodex-HlLNepHI.mjs} +47 -6
- package/dist/{runCodex-BxLD6H6G.cjs → runCodex-QdQBx9HK.cjs} +47 -6
- package/dist/{types-xds_c-JJ.mjs → types-8Ad05p3x.mjs} +213 -166
- package/dist/{types-CsJGQvQ3.cjs → types-CQOz_mPp.cjs} +214 -166
- package/package.json +5 -2
|
@@ -42,7 +42,7 @@ function _interopNamespaceDefault(e) {
|
|
|
42
42
|
var z__namespace = /*#__PURE__*/_interopNamespaceDefault(z);
|
|
43
43
|
|
|
44
44
|
var name = "happy-coder";
|
|
45
|
-
var version = "0.10.0
|
|
45
|
+
var version = "0.10.0";
|
|
46
46
|
var description = "Mobile and Web client for Claude Code and Codex";
|
|
47
47
|
var author = "Kirill Dubovitskiy";
|
|
48
48
|
var license = "MIT";
|
|
@@ -102,7 +102,7 @@ var scripts = {
|
|
|
102
102
|
build: "shx rm -rf dist && npx tsc --noEmit && pkgroll",
|
|
103
103
|
test: "yarn build && tsx --env-file .env.integration-test node_modules/.bin/vitest run",
|
|
104
104
|
start: "yarn build && ./bin/happy.mjs",
|
|
105
|
-
dev: "
|
|
105
|
+
dev: "tsx --env-file .env.dev src/index.ts",
|
|
106
106
|
"dev:local-server": "yarn build && tsx --env-file .env.dev-local-server src/index.ts",
|
|
107
107
|
"dev:integration-test-env": "yarn build && tsx --env-file .env.integration-test src/index.ts",
|
|
108
108
|
prepublishOnly: "yarn build && yarn test",
|
|
@@ -114,11 +114,13 @@ var dependencies = {
|
|
|
114
114
|
"@anthropic-ai/sdk": "^0.56.0",
|
|
115
115
|
"@modelcontextprotocol/sdk": "^1.15.1",
|
|
116
116
|
"@stablelib/base64": "^2.0.1",
|
|
117
|
+
"@stablelib/hex": "^2.0.1",
|
|
117
118
|
"@types/cross-spawn": "^6.0.6",
|
|
118
119
|
"@types/http-proxy": "^1.17.16",
|
|
119
120
|
"@types/ps-list": "^6.2.1",
|
|
120
121
|
"@types/qrcode-terminal": "^0.12.2",
|
|
121
122
|
"@types/react": "^19.1.9",
|
|
123
|
+
"@types/tmp": "^0.2.6",
|
|
122
124
|
axios: "^1.10.0",
|
|
123
125
|
chalk: "^5.4.1",
|
|
124
126
|
"cross-spawn": "^7.0.6",
|
|
@@ -134,6 +136,7 @@ var dependencies = {
|
|
|
134
136
|
react: "^19.1.1",
|
|
135
137
|
"socket.io-client": "^4.8.1",
|
|
136
138
|
tar: "^7.4.3",
|
|
139
|
+
tmp: "^0.2.5",
|
|
137
140
|
tweetnacl: "^1.0.3",
|
|
138
141
|
zod: "^3.23.8"
|
|
139
142
|
};
|
|
@@ -187,6 +190,7 @@ var packageJson = {
|
|
|
187
190
|
|
|
188
191
|
class Configuration {
|
|
189
192
|
serverUrl;
|
|
193
|
+
webappUrl;
|
|
190
194
|
isDaemonProcess;
|
|
191
195
|
// Directories and paths (from persistence)
|
|
192
196
|
happyHomeDir;
|
|
@@ -199,6 +203,7 @@ class Configuration {
|
|
|
199
203
|
isExperimentalEnabled;
|
|
200
204
|
constructor() {
|
|
201
205
|
this.serverUrl = process.env.HAPPY_SERVER_URL || "https://api.cluster-fluster.com";
|
|
206
|
+
this.webappUrl = process.env.HAPPY_WEBAPP_URL || "https://app.happy.engineering";
|
|
202
207
|
const args = process.argv.slice(2);
|
|
203
208
|
this.isDaemonProcess = args.length >= 2 && args[0] === "daemon" && args[1] === "start-sync";
|
|
204
209
|
if (process.env.HAPPY_HOME_DIR) {
|
|
@@ -243,7 +248,17 @@ function decodeBase64(base64, variant = "base64") {
|
|
|
243
248
|
function getRandomBytes(size) {
|
|
244
249
|
return new Uint8Array(node_crypto.randomBytes(size));
|
|
245
250
|
}
|
|
246
|
-
function
|
|
251
|
+
function libsodiumEncryptForPublicKey(data, recipientPublicKey) {
|
|
252
|
+
const ephemeralKeyPair = tweetnacl.box.keyPair();
|
|
253
|
+
const nonce = getRandomBytes(tweetnacl.box.nonceLength);
|
|
254
|
+
const encrypted = tweetnacl.box(data, nonce, recipientPublicKey, ephemeralKeyPair.secretKey);
|
|
255
|
+
const result = new Uint8Array(ephemeralKeyPair.publicKey.length + nonce.length + encrypted.length);
|
|
256
|
+
result.set(ephemeralKeyPair.publicKey, 0);
|
|
257
|
+
result.set(nonce, ephemeralKeyPair.publicKey.length);
|
|
258
|
+
result.set(encrypted, ephemeralKeyPair.publicKey.length + nonce.length);
|
|
259
|
+
return result;
|
|
260
|
+
}
|
|
261
|
+
function encryptLegacy(data, secret) {
|
|
247
262
|
const nonce = getRandomBytes(tweetnacl.secretbox.nonceLength);
|
|
248
263
|
const encrypted = tweetnacl.secretbox(new TextEncoder().encode(JSON.stringify(data)), nonce, secret);
|
|
249
264
|
const result = new Uint8Array(nonce.length + encrypted.length);
|
|
@@ -251,7 +266,7 @@ function encrypt(data, secret) {
|
|
|
251
266
|
result.set(encrypted, nonce.length);
|
|
252
267
|
return result;
|
|
253
268
|
}
|
|
254
|
-
function
|
|
269
|
+
function decryptLegacy(data, secret) {
|
|
255
270
|
const nonce = data.slice(0, tweetnacl.secretbox.nonceLength);
|
|
256
271
|
const encrypted = data.slice(tweetnacl.secretbox.nonceLength);
|
|
257
272
|
const decrypted = tweetnacl.secretbox.open(encrypted, nonce, secret);
|
|
@@ -260,6 +275,61 @@ function decrypt(data, secret) {
|
|
|
260
275
|
}
|
|
261
276
|
return JSON.parse(new TextDecoder().decode(decrypted));
|
|
262
277
|
}
|
|
278
|
+
function encryptWithDataKey(data, dataKey) {
|
|
279
|
+
const nonce = getRandomBytes(12);
|
|
280
|
+
const cipher = node_crypto.createCipheriv("aes-256-gcm", dataKey, nonce);
|
|
281
|
+
const plaintext = new TextEncoder().encode(JSON.stringify(data));
|
|
282
|
+
const encrypted = Buffer.concat([
|
|
283
|
+
cipher.update(plaintext),
|
|
284
|
+
cipher.final()
|
|
285
|
+
]);
|
|
286
|
+
const authTag = cipher.getAuthTag();
|
|
287
|
+
const bundle = new Uint8Array(12 + encrypted.length + 16 + 1);
|
|
288
|
+
bundle.set([0], 0);
|
|
289
|
+
bundle.set(nonce, 1);
|
|
290
|
+
bundle.set(new Uint8Array(encrypted), 13);
|
|
291
|
+
bundle.set(new Uint8Array(authTag), 13 + encrypted.length);
|
|
292
|
+
return bundle;
|
|
293
|
+
}
|
|
294
|
+
function decryptWithDataKey(bundle, dataKey) {
|
|
295
|
+
if (bundle.length < 1) {
|
|
296
|
+
return null;
|
|
297
|
+
}
|
|
298
|
+
if (bundle[0] !== 0) {
|
|
299
|
+
return null;
|
|
300
|
+
}
|
|
301
|
+
if (bundle.length < 12 + 16 + 1) {
|
|
302
|
+
return null;
|
|
303
|
+
}
|
|
304
|
+
const nonce = bundle.slice(1, 13);
|
|
305
|
+
const authTag = bundle.slice(bundle.length - 16);
|
|
306
|
+
const ciphertext = bundle.slice(13, bundle.length - 16);
|
|
307
|
+
try {
|
|
308
|
+
const decipher = node_crypto.createDecipheriv("aes-256-gcm", dataKey, nonce);
|
|
309
|
+
decipher.setAuthTag(authTag);
|
|
310
|
+
const decrypted = Buffer.concat([
|
|
311
|
+
decipher.update(ciphertext),
|
|
312
|
+
decipher.final()
|
|
313
|
+
]);
|
|
314
|
+
return JSON.parse(new TextDecoder().decode(decrypted));
|
|
315
|
+
} catch (error) {
|
|
316
|
+
return null;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
function encrypt(key, variant, data) {
|
|
320
|
+
if (variant === "legacy") {
|
|
321
|
+
return encryptLegacy(data, key);
|
|
322
|
+
} else {
|
|
323
|
+
return encryptWithDataKey(data, key);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
function decrypt(key, variant, data) {
|
|
327
|
+
if (variant === "legacy") {
|
|
328
|
+
return decryptLegacy(data, key);
|
|
329
|
+
} else {
|
|
330
|
+
return decryptWithDataKey(data, key);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
263
333
|
|
|
264
334
|
const defaultSettings = {
|
|
265
335
|
onboardingCompleted: false
|
|
@@ -323,8 +393,13 @@ async function updateSettings(updater) {
|
|
|
323
393
|
}
|
|
324
394
|
}
|
|
325
395
|
const credentialsSchema = z__namespace.object({
|
|
326
|
-
|
|
327
|
-
|
|
396
|
+
token: z__namespace.string(),
|
|
397
|
+
secret: z__namespace.string().base64().nullish(),
|
|
398
|
+
// Legacy
|
|
399
|
+
encryption: z__namespace.object({
|
|
400
|
+
publicKey: z__namespace.string().base64(),
|
|
401
|
+
machineKey: z__namespace.string().base64()
|
|
402
|
+
}).nullish()
|
|
328
403
|
});
|
|
329
404
|
async function readCredentials() {
|
|
330
405
|
if (!fs.existsSync(configuration.privateKeyFile)) {
|
|
@@ -333,15 +408,30 @@ async function readCredentials() {
|
|
|
333
408
|
try {
|
|
334
409
|
const keyBase64 = await promises.readFile(configuration.privateKeyFile, "utf8");
|
|
335
410
|
const credentials = credentialsSchema.parse(JSON.parse(keyBase64));
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
411
|
+
if (credentials.secret) {
|
|
412
|
+
return {
|
|
413
|
+
token: credentials.token,
|
|
414
|
+
encryption: {
|
|
415
|
+
type: "legacy",
|
|
416
|
+
secret: new Uint8Array(Buffer.from(credentials.secret, "base64"))
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
} else if (credentials.encryption) {
|
|
420
|
+
return {
|
|
421
|
+
token: credentials.token,
|
|
422
|
+
encryption: {
|
|
423
|
+
type: "dataKey",
|
|
424
|
+
publicKey: new Uint8Array(Buffer.from(credentials.encryption.publicKey, "base64")),
|
|
425
|
+
machineKey: new Uint8Array(Buffer.from(credentials.encryption.machineKey, "base64"))
|
|
426
|
+
}
|
|
427
|
+
};
|
|
428
|
+
}
|
|
340
429
|
} catch {
|
|
341
430
|
return null;
|
|
342
431
|
}
|
|
432
|
+
return null;
|
|
343
433
|
}
|
|
344
|
-
async function
|
|
434
|
+
async function writeCredentialsLegacy(credentials) {
|
|
345
435
|
if (!fs.existsSync(configuration.happyHomeDir)) {
|
|
346
436
|
await promises.mkdir(configuration.happyHomeDir, { recursive: true });
|
|
347
437
|
}
|
|
@@ -350,6 +440,15 @@ async function writeCredentials(credentials) {
|
|
|
350
440
|
token: credentials.token
|
|
351
441
|
}, null, 2));
|
|
352
442
|
}
|
|
443
|
+
async function writeCredentialsDataKey(credentials) {
|
|
444
|
+
if (!fs.existsSync(configuration.happyHomeDir)) {
|
|
445
|
+
await promises.mkdir(configuration.happyHomeDir, { recursive: true });
|
|
446
|
+
}
|
|
447
|
+
await promises.writeFile(configuration.privateKeyFile, JSON.stringify({
|
|
448
|
+
encryption: { publicKey: encodeBase64(credentials.publicKey), machineKey: encodeBase64(credentials.machineKey) },
|
|
449
|
+
token: credentials.token
|
|
450
|
+
}, null, 2));
|
|
451
|
+
}
|
|
353
452
|
async function clearCredentials() {
|
|
354
453
|
if (fs.existsSync(configuration.privateKeyFile)) {
|
|
355
454
|
await promises.unlink(configuration.privateKeyFile);
|
|
@@ -684,32 +783,6 @@ z.z.object({
|
|
|
684
783
|
]),
|
|
685
784
|
createdAt: z.z.number()
|
|
686
785
|
});
|
|
687
|
-
z.z.object({
|
|
688
|
-
createdAt: z.z.number(),
|
|
689
|
-
id: z.z.string(),
|
|
690
|
-
seq: z.z.number(),
|
|
691
|
-
updatedAt: z.z.number(),
|
|
692
|
-
metadata: z.z.any(),
|
|
693
|
-
metadataVersion: z.z.number(),
|
|
694
|
-
agentState: z.z.any().nullable(),
|
|
695
|
-
agentStateVersion: z.z.number(),
|
|
696
|
-
// Connectivity tracking (from server)
|
|
697
|
-
connectivityStatus: z.z.union([
|
|
698
|
-
z.z.enum(["neverConnected", "online", "offline"]),
|
|
699
|
-
z.z.string()
|
|
700
|
-
// Forward compatibility
|
|
701
|
-
]).optional(),
|
|
702
|
-
connectivityStatusSince: z.z.number().optional(),
|
|
703
|
-
connectivityStatusReason: z.z.string().optional(),
|
|
704
|
-
// State tracking (from server)
|
|
705
|
-
state: z.z.union([
|
|
706
|
-
z.z.enum(["running", "archiveRequested", "archived"]),
|
|
707
|
-
z.z.string()
|
|
708
|
-
// Forward compatibility
|
|
709
|
-
]).optional(),
|
|
710
|
-
stateSince: z.z.number().optional(),
|
|
711
|
-
stateReason: z.z.string().optional()
|
|
712
|
-
});
|
|
713
786
|
z.z.object({
|
|
714
787
|
host: z.z.string(),
|
|
715
788
|
platform: z.z.string(),
|
|
@@ -734,37 +807,6 @@ z.z.object({
|
|
|
734
807
|
// Forward compatibility
|
|
735
808
|
]).optional()
|
|
736
809
|
});
|
|
737
|
-
z.z.object({
|
|
738
|
-
id: z.z.string(),
|
|
739
|
-
metadata: z.z.any(),
|
|
740
|
-
// Decrypted MachineMetadata
|
|
741
|
-
metadataVersion: z.z.number(),
|
|
742
|
-
daemonState: z.z.any().nullable(),
|
|
743
|
-
// Decrypted DaemonState
|
|
744
|
-
daemonStateVersion: z.z.number(),
|
|
745
|
-
// We don't really care about these on the CLI for now
|
|
746
|
-
// ApiMachineClient will not sync these
|
|
747
|
-
active: z.z.boolean(),
|
|
748
|
-
activeAt: z.z.number(),
|
|
749
|
-
createdAt: z.z.number(),
|
|
750
|
-
updatedAt: z.z.number(),
|
|
751
|
-
// Connectivity tracking (from server)
|
|
752
|
-
connectivityStatus: z.z.union([
|
|
753
|
-
z.z.enum(["neverConnected", "online", "offline"]),
|
|
754
|
-
z.z.string()
|
|
755
|
-
// Forward compatibility
|
|
756
|
-
]).optional(),
|
|
757
|
-
connectivityStatusSince: z.z.number().optional(),
|
|
758
|
-
connectivityStatusReason: z.z.string().optional(),
|
|
759
|
-
// State tracking (from server)
|
|
760
|
-
state: z.z.union([
|
|
761
|
-
z.z.enum(["running", "archiveRequested", "archived"]),
|
|
762
|
-
z.z.string()
|
|
763
|
-
// Forward compatibility
|
|
764
|
-
]).optional(),
|
|
765
|
-
stateSince: z.z.number().optional(),
|
|
766
|
-
stateReason: z.z.string().optional()
|
|
767
|
-
});
|
|
768
810
|
z.z.object({
|
|
769
811
|
content: SessionMessageContentSchema,
|
|
770
812
|
createdAt: z.z.number(),
|
|
@@ -888,12 +930,14 @@ class AsyncLock {
|
|
|
888
930
|
class RpcHandlerManager {
|
|
889
931
|
handlers = /* @__PURE__ */ new Map();
|
|
890
932
|
scopePrefix;
|
|
891
|
-
|
|
933
|
+
encryptionKey;
|
|
934
|
+
encryptionVariant;
|
|
892
935
|
logger;
|
|
893
936
|
socket = null;
|
|
894
937
|
constructor(config) {
|
|
895
938
|
this.scopePrefix = config.scopePrefix;
|
|
896
|
-
this.
|
|
939
|
+
this.encryptionKey = config.encryptionKey;
|
|
940
|
+
this.encryptionVariant = config.encryptionVariant;
|
|
897
941
|
this.logger = config.logger || ((msg, data) => logger.debug(msg, data));
|
|
898
942
|
}
|
|
899
943
|
/**
|
|
@@ -919,20 +963,19 @@ class RpcHandlerManager {
|
|
|
919
963
|
if (!handler) {
|
|
920
964
|
this.logger("[RPC] [ERROR] Method not found", { method: request.method });
|
|
921
965
|
const errorResponse = { error: "Method not found" };
|
|
922
|
-
const encryptedError = encodeBase64(encrypt(
|
|
966
|
+
const encryptedError = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, errorResponse));
|
|
923
967
|
return encryptedError;
|
|
924
968
|
}
|
|
925
|
-
const decryptedParams = decrypt(decodeBase64(request.params)
|
|
969
|
+
const decryptedParams = decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(request.params));
|
|
926
970
|
const result = await handler(decryptedParams);
|
|
927
|
-
const encryptedResponse = encodeBase64(encrypt(
|
|
971
|
+
const encryptedResponse = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, result));
|
|
928
972
|
return encryptedResponse;
|
|
929
973
|
} catch (error) {
|
|
930
974
|
this.logger("[RPC] [ERROR] Error handling request", { error });
|
|
931
975
|
const errorResponse = {
|
|
932
976
|
error: error instanceof Error ? error.message : "Unknown error"
|
|
933
977
|
};
|
|
934
|
-
|
|
935
|
-
return encryptedError;
|
|
978
|
+
return encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, errorResponse));
|
|
936
979
|
}
|
|
937
980
|
}
|
|
938
981
|
onSocketConnect(socket) {
|
|
@@ -974,7 +1017,7 @@ class RpcHandlerManager {
|
|
|
974
1017
|
}
|
|
975
1018
|
}
|
|
976
1019
|
|
|
977
|
-
const __dirname$1 = path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-
|
|
1020
|
+
const __dirname$1 = path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-CQOz_mPp.cjs', document.baseURI).href))));
|
|
978
1021
|
function projectPath() {
|
|
979
1022
|
const path$1 = path.resolve(__dirname$1, "..");
|
|
980
1023
|
return path$1;
|
|
@@ -1277,7 +1320,6 @@ function registerCommonHandlers(rpcHandlerManager) {
|
|
|
1277
1320
|
|
|
1278
1321
|
class ApiSessionClient extends node_events.EventEmitter {
|
|
1279
1322
|
token;
|
|
1280
|
-
secret;
|
|
1281
1323
|
sessionId;
|
|
1282
1324
|
metadata;
|
|
1283
1325
|
metadataVersion;
|
|
@@ -1289,18 +1331,22 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
1289
1331
|
rpcHandlerManager;
|
|
1290
1332
|
agentStateLock = new AsyncLock();
|
|
1291
1333
|
metadataLock = new AsyncLock();
|
|
1292
|
-
|
|
1334
|
+
encryptionKey;
|
|
1335
|
+
encryptionVariant;
|
|
1336
|
+
constructor(token, session) {
|
|
1293
1337
|
super();
|
|
1294
1338
|
this.token = token;
|
|
1295
|
-
this.secret = secret;
|
|
1296
1339
|
this.sessionId = session.id;
|
|
1297
1340
|
this.metadata = session.metadata;
|
|
1298
1341
|
this.metadataVersion = session.metadataVersion;
|
|
1299
1342
|
this.agentState = session.agentState;
|
|
1300
1343
|
this.agentStateVersion = session.agentStateVersion;
|
|
1344
|
+
this.encryptionKey = session.encryptionKey;
|
|
1345
|
+
this.encryptionVariant = session.encryptionVariant;
|
|
1301
1346
|
this.rpcHandlerManager = new RpcHandlerManager({
|
|
1302
1347
|
scopePrefix: this.sessionId,
|
|
1303
|
-
|
|
1348
|
+
encryptionKey: this.encryptionKey,
|
|
1349
|
+
encryptionVariant: this.encryptionVariant,
|
|
1304
1350
|
logger: (msg, data) => logger.debug(msg, data)
|
|
1305
1351
|
});
|
|
1306
1352
|
registerCommonHandlers(this.rpcHandlerManager);
|
|
@@ -1342,7 +1388,7 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
1342
1388
|
return;
|
|
1343
1389
|
}
|
|
1344
1390
|
if (data.body.t === "new-message" && data.body.message.content.t === "encrypted") {
|
|
1345
|
-
const body = decrypt(decodeBase64(data.body.message.content.c)
|
|
1391
|
+
const body = decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(data.body.message.content.c));
|
|
1346
1392
|
logger.debugLargeJson("[SOCKET] [UPDATE] Received update:", body);
|
|
1347
1393
|
const userResult = UserMessageSchema.safeParse(body);
|
|
1348
1394
|
if (userResult.success) {
|
|
@@ -1356,11 +1402,11 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
1356
1402
|
}
|
|
1357
1403
|
} else if (data.body.t === "update-session") {
|
|
1358
1404
|
if (data.body.metadata && data.body.metadata.version > this.metadataVersion) {
|
|
1359
|
-
this.metadata = decrypt(decodeBase64(data.body.metadata.value)
|
|
1405
|
+
this.metadata = decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(data.body.metadata.value));
|
|
1360
1406
|
this.metadataVersion = data.body.metadata.version;
|
|
1361
1407
|
}
|
|
1362
1408
|
if (data.body.agentState && data.body.agentState.version > this.agentStateVersion) {
|
|
1363
|
-
this.agentState = data.body.agentState.value ? decrypt(decodeBase64(data.body.agentState.value)
|
|
1409
|
+
this.agentState = data.body.agentState.value ? decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(data.body.agentState.value)) : null;
|
|
1364
1410
|
this.agentStateVersion = data.body.agentState.version;
|
|
1365
1411
|
}
|
|
1366
1412
|
} else if (data.body.t === "update-machine") {
|
|
@@ -1414,7 +1460,7 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
1414
1460
|
};
|
|
1415
1461
|
}
|
|
1416
1462
|
logger.debugLargeJson("[SOCKET] Sending message through socket:", content);
|
|
1417
|
-
const encrypted = encodeBase64(encrypt(
|
|
1463
|
+
const encrypted = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, content));
|
|
1418
1464
|
this.socket.emit("message", {
|
|
1419
1465
|
sid: this.sessionId,
|
|
1420
1466
|
message: encrypted
|
|
@@ -1448,7 +1494,7 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
1448
1494
|
sentFrom: "cli"
|
|
1449
1495
|
}
|
|
1450
1496
|
};
|
|
1451
|
-
const encrypted = encodeBase64(encrypt(
|
|
1497
|
+
const encrypted = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, content));
|
|
1452
1498
|
this.socket.emit("message", {
|
|
1453
1499
|
sid: this.sessionId,
|
|
1454
1500
|
message: encrypted
|
|
@@ -1463,7 +1509,7 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
1463
1509
|
data: event
|
|
1464
1510
|
}
|
|
1465
1511
|
};
|
|
1466
|
-
const encrypted = encodeBase64(encrypt(
|
|
1512
|
+
const encrypted = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, content));
|
|
1467
1513
|
this.socket.emit("message", {
|
|
1468
1514
|
sid: this.sessionId,
|
|
1469
1515
|
message: encrypted
|
|
@@ -1523,14 +1569,14 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
1523
1569
|
this.metadataLock.inLock(async () => {
|
|
1524
1570
|
await backoff(async () => {
|
|
1525
1571
|
let updated = handler(this.metadata);
|
|
1526
|
-
const answer = await this.socket.emitWithAck("update-metadata", { sid: this.sessionId, expectedVersion: this.metadataVersion, metadata: encodeBase64(encrypt(
|
|
1572
|
+
const answer = await this.socket.emitWithAck("update-metadata", { sid: this.sessionId, expectedVersion: this.metadataVersion, metadata: encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, updated)) });
|
|
1527
1573
|
if (answer.result === "success") {
|
|
1528
|
-
this.metadata = decrypt(decodeBase64(answer.metadata)
|
|
1574
|
+
this.metadata = decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(answer.metadata));
|
|
1529
1575
|
this.metadataVersion = answer.version;
|
|
1530
1576
|
} else if (answer.result === "version-mismatch") {
|
|
1531
1577
|
if (answer.version > this.metadataVersion) {
|
|
1532
1578
|
this.metadataVersion = answer.version;
|
|
1533
|
-
this.metadata = decrypt(decodeBase64(answer.metadata)
|
|
1579
|
+
this.metadata = decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(answer.metadata));
|
|
1534
1580
|
}
|
|
1535
1581
|
throw new Error("Metadata version mismatch");
|
|
1536
1582
|
} else if (answer.result === "error") ;
|
|
@@ -1546,15 +1592,15 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
1546
1592
|
this.agentStateLock.inLock(async () => {
|
|
1547
1593
|
await backoff(async () => {
|
|
1548
1594
|
let updated = handler(this.agentState || {});
|
|
1549
|
-
const answer = await this.socket.emitWithAck("update-state", { sid: this.sessionId, expectedVersion: this.agentStateVersion, agentState: updated ? encodeBase64(encrypt(
|
|
1595
|
+
const answer = await this.socket.emitWithAck("update-state", { sid: this.sessionId, expectedVersion: this.agentStateVersion, agentState: updated ? encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, updated)) : null });
|
|
1550
1596
|
if (answer.result === "success") {
|
|
1551
|
-
this.agentState = answer.agentState ? decrypt(decodeBase64(answer.agentState)
|
|
1597
|
+
this.agentState = answer.agentState ? decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(answer.agentState)) : null;
|
|
1552
1598
|
this.agentStateVersion = answer.version;
|
|
1553
1599
|
logger.debug("Agent state updated", this.agentState);
|
|
1554
1600
|
} else if (answer.result === "version-mismatch") {
|
|
1555
1601
|
if (answer.version > this.agentStateVersion) {
|
|
1556
1602
|
this.agentStateVersion = answer.version;
|
|
1557
|
-
this.agentState = answer.agentState ? decrypt(decodeBase64(answer.agentState)
|
|
1603
|
+
this.agentState = answer.agentState ? decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(answer.agentState)) : null;
|
|
1558
1604
|
}
|
|
1559
1605
|
throw new Error("Agent state version mismatch");
|
|
1560
1606
|
} else if (answer.result === "error") ;
|
|
@@ -1584,13 +1630,13 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
1584
1630
|
}
|
|
1585
1631
|
|
|
1586
1632
|
class ApiMachineClient {
|
|
1587
|
-
constructor(token,
|
|
1633
|
+
constructor(token, machine) {
|
|
1588
1634
|
this.token = token;
|
|
1589
|
-
this.secret = secret;
|
|
1590
1635
|
this.machine = machine;
|
|
1591
1636
|
this.rpcHandlerManager = new RpcHandlerManager({
|
|
1592
1637
|
scopePrefix: this.machine.id,
|
|
1593
|
-
|
|
1638
|
+
encryptionKey: this.machine.encryptionKey,
|
|
1639
|
+
encryptionVariant: this.machine.encryptionVariant,
|
|
1594
1640
|
logger: (msg, data) => logger.debug(msg, data)
|
|
1595
1641
|
});
|
|
1596
1642
|
registerCommonHandlers(this.rpcHandlerManager);
|
|
@@ -1604,11 +1650,12 @@ class ApiMachineClient {
|
|
|
1604
1650
|
requestShutdown
|
|
1605
1651
|
}) {
|
|
1606
1652
|
this.rpcHandlerManager.registerHandler("spawn-happy-session", async (params) => {
|
|
1607
|
-
const { directory, sessionId, machineId, approvedNewDirectoryCreation } = params || {};
|
|
1653
|
+
const { directory, sessionId, machineId, approvedNewDirectoryCreation, agent, token } = params || {};
|
|
1654
|
+
logger.debug(`[API MACHINE] Spawning session with params: ${JSON.stringify(params)}`);
|
|
1608
1655
|
if (!directory) {
|
|
1609
1656
|
throw new Error("Directory is required");
|
|
1610
1657
|
}
|
|
1611
|
-
const result = await spawnSession({ directory, sessionId, machineId, approvedNewDirectoryCreation });
|
|
1658
|
+
const result = await spawnSession({ directory, sessionId, machineId, approvedNewDirectoryCreation, agent, token });
|
|
1612
1659
|
switch (result.type) {
|
|
1613
1660
|
case "success":
|
|
1614
1661
|
logger.debug(`[API MACHINE] Spawned session ${result.sessionId}`);
|
|
@@ -1651,17 +1698,17 @@ class ApiMachineClient {
|
|
|
1651
1698
|
const updated = handler(this.machine.metadata);
|
|
1652
1699
|
const answer = await this.socket.emitWithAck("machine-update-metadata", {
|
|
1653
1700
|
machineId: this.machine.id,
|
|
1654
|
-
metadata: encodeBase64(encrypt(
|
|
1701
|
+
metadata: encodeBase64(encrypt(this.machine.encryptionKey, this.machine.encryptionVariant, updated)),
|
|
1655
1702
|
expectedVersion: this.machine.metadataVersion
|
|
1656
1703
|
});
|
|
1657
1704
|
if (answer.result === "success") {
|
|
1658
|
-
this.machine.metadata = decrypt(decodeBase64(answer.metadata)
|
|
1705
|
+
this.machine.metadata = decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, decodeBase64(answer.metadata));
|
|
1659
1706
|
this.machine.metadataVersion = answer.version;
|
|
1660
1707
|
logger.debug("[API MACHINE] Metadata updated successfully");
|
|
1661
1708
|
} else if (answer.result === "version-mismatch") {
|
|
1662
1709
|
if (answer.version > this.machine.metadataVersion) {
|
|
1663
1710
|
this.machine.metadataVersion = answer.version;
|
|
1664
|
-
this.machine.metadata = decrypt(decodeBase64(answer.metadata)
|
|
1711
|
+
this.machine.metadata = decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, decodeBase64(answer.metadata));
|
|
1665
1712
|
}
|
|
1666
1713
|
throw new Error("Metadata version mismatch");
|
|
1667
1714
|
}
|
|
@@ -1676,17 +1723,17 @@ class ApiMachineClient {
|
|
|
1676
1723
|
const updated = handler(this.machine.daemonState);
|
|
1677
1724
|
const answer = await this.socket.emitWithAck("machine-update-state", {
|
|
1678
1725
|
machineId: this.machine.id,
|
|
1679
|
-
daemonState: encodeBase64(encrypt(
|
|
1726
|
+
daemonState: encodeBase64(encrypt(this.machine.encryptionKey, this.machine.encryptionVariant, updated)),
|
|
1680
1727
|
expectedVersion: this.machine.daemonStateVersion
|
|
1681
1728
|
});
|
|
1682
1729
|
if (answer.result === "success") {
|
|
1683
|
-
this.machine.daemonState = decrypt(decodeBase64(answer.daemonState)
|
|
1730
|
+
this.machine.daemonState = decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, decodeBase64(answer.daemonState));
|
|
1684
1731
|
this.machine.daemonStateVersion = answer.version;
|
|
1685
1732
|
logger.debug("[API MACHINE] Daemon state updated successfully");
|
|
1686
1733
|
} else if (answer.result === "version-mismatch") {
|
|
1687
1734
|
if (answer.version > this.machine.daemonStateVersion) {
|
|
1688
1735
|
this.machine.daemonStateVersion = answer.version;
|
|
1689
|
-
this.machine.daemonState = decrypt(decodeBase64(answer.daemonState)
|
|
1736
|
+
this.machine.daemonState = decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, decodeBase64(answer.daemonState));
|
|
1690
1737
|
}
|
|
1691
1738
|
throw new Error("Daemon state version mismatch");
|
|
1692
1739
|
}
|
|
@@ -1733,12 +1780,12 @@ class ApiMachineClient {
|
|
|
1733
1780
|
const update = data.body;
|
|
1734
1781
|
if (update.metadata) {
|
|
1735
1782
|
logger.debug("[API MACHINE] Received external metadata update");
|
|
1736
|
-
this.machine.metadata = decrypt(decodeBase64(update.metadata.value)
|
|
1783
|
+
this.machine.metadata = decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, decodeBase64(update.metadata.value));
|
|
1737
1784
|
this.machine.metadataVersion = update.metadata.version;
|
|
1738
1785
|
}
|
|
1739
1786
|
if (update.daemonState) {
|
|
1740
1787
|
logger.debug("[API MACHINE] Received external daemon state update");
|
|
1741
|
-
this.machine.daemonState = decrypt(decodeBase64(update.daemonState.value)
|
|
1788
|
+
this.machine.daemonState = decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, decodeBase64(update.daemonState.value));
|
|
1742
1789
|
this.machine.daemonStateVersion = update.daemonState.version;
|
|
1743
1790
|
}
|
|
1744
1791
|
} else {
|
|
@@ -1910,46 +1957,62 @@ class PushNotificationClient {
|
|
|
1910
1957
|
}
|
|
1911
1958
|
|
|
1912
1959
|
class ApiClient {
|
|
1913
|
-
|
|
1914
|
-
|
|
1960
|
+
static async create(credential) {
|
|
1961
|
+
return new ApiClient(credential);
|
|
1962
|
+
}
|
|
1963
|
+
credential;
|
|
1915
1964
|
pushClient;
|
|
1916
|
-
constructor(
|
|
1917
|
-
this.
|
|
1918
|
-
this.
|
|
1919
|
-
this.pushClient = new PushNotificationClient(token);
|
|
1965
|
+
constructor(credential) {
|
|
1966
|
+
this.credential = credential;
|
|
1967
|
+
this.pushClient = new PushNotificationClient(credential.token, configuration.serverUrl);
|
|
1920
1968
|
}
|
|
1921
1969
|
/**
|
|
1922
1970
|
* Create a new session or load existing one with the given tag
|
|
1923
1971
|
*/
|
|
1924
1972
|
async getOrCreateSession(opts) {
|
|
1973
|
+
let dataEncryptionKey = null;
|
|
1974
|
+
let encryptionKey;
|
|
1975
|
+
let encryptionVariant;
|
|
1976
|
+
if (this.credential.encryption.type === "dataKey") {
|
|
1977
|
+
encryptionKey = getRandomBytes(32);
|
|
1978
|
+
encryptionVariant = "dataKey";
|
|
1979
|
+
let encryptedDataKey = libsodiumEncryptForPublicKey(encryptionKey, this.credential.encryption.publicKey);
|
|
1980
|
+
dataEncryptionKey = new Uint8Array(encryptedDataKey.length + 1);
|
|
1981
|
+
dataEncryptionKey.set([0], 0);
|
|
1982
|
+
dataEncryptionKey.set(encryptedDataKey, 1);
|
|
1983
|
+
} else {
|
|
1984
|
+
encryptionKey = this.credential.encryption.secret;
|
|
1985
|
+
encryptionVariant = "legacy";
|
|
1986
|
+
}
|
|
1925
1987
|
try {
|
|
1926
1988
|
const response = await axios.post(
|
|
1927
1989
|
`${configuration.serverUrl}/v1/sessions`,
|
|
1928
1990
|
{
|
|
1929
1991
|
tag: opts.tag,
|
|
1930
|
-
metadata: encodeBase64(encrypt(opts.metadata
|
|
1931
|
-
agentState: opts.state ? encodeBase64(encrypt(opts.state
|
|
1992
|
+
metadata: encodeBase64(encrypt(encryptionKey, encryptionVariant, opts.metadata)),
|
|
1993
|
+
agentState: opts.state ? encodeBase64(encrypt(encryptionKey, encryptionVariant, opts.state)) : null,
|
|
1994
|
+
dataEncryptionKey: dataEncryptionKey ? encodeBase64(dataEncryptionKey) : null
|
|
1932
1995
|
},
|
|
1933
1996
|
{
|
|
1934
1997
|
headers: {
|
|
1935
|
-
"Authorization": `Bearer ${this.token}`,
|
|
1998
|
+
"Authorization": `Bearer ${this.credential.token}`,
|
|
1936
1999
|
"Content-Type": "application/json"
|
|
1937
2000
|
},
|
|
1938
|
-
timeout:
|
|
1939
|
-
//
|
|
2001
|
+
timeout: 6e4
|
|
2002
|
+
// 1 minute timeout for very bad network connections
|
|
1940
2003
|
}
|
|
1941
2004
|
);
|
|
1942
2005
|
logger.debug(`Session created/loaded: ${response.data.session.id} (tag: ${opts.tag})`);
|
|
1943
2006
|
let raw = response.data.session;
|
|
1944
2007
|
let session = {
|
|
1945
2008
|
id: raw.id,
|
|
1946
|
-
createdAt: raw.createdAt,
|
|
1947
|
-
updatedAt: raw.updatedAt,
|
|
1948
2009
|
seq: raw.seq,
|
|
1949
|
-
metadata: decrypt(decodeBase64(raw.metadata)
|
|
2010
|
+
metadata: decrypt(encryptionKey, encryptionVariant, decodeBase64(raw.metadata)),
|
|
1950
2011
|
metadataVersion: raw.metadataVersion,
|
|
1951
|
-
agentState: raw.agentState ? decrypt(decodeBase64(raw.agentState)
|
|
1952
|
-
agentStateVersion: raw.agentStateVersion
|
|
2012
|
+
agentState: raw.agentState ? decrypt(encryptionKey, encryptionVariant, decodeBase64(raw.agentState)) : null,
|
|
2013
|
+
agentStateVersion: raw.agentStateVersion,
|
|
2014
|
+
encryptionKey,
|
|
2015
|
+
encryptionVariant
|
|
1953
2016
|
};
|
|
1954
2017
|
return session;
|
|
1955
2018
|
} catch (error) {
|
|
@@ -1957,54 +2020,40 @@ class ApiClient {
|
|
|
1957
2020
|
throw new Error(`Failed to get or create session: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1958
2021
|
}
|
|
1959
2022
|
}
|
|
1960
|
-
/**
|
|
1961
|
-
* Get machine by ID from the server
|
|
1962
|
-
* Returns the current machine state from the server with decrypted metadata and daemonState
|
|
1963
|
-
*/
|
|
1964
|
-
async getMachine(machineId) {
|
|
1965
|
-
const response = await axios.get(`${configuration.serverUrl}/v1/machines/${machineId}`, {
|
|
1966
|
-
headers: {
|
|
1967
|
-
"Authorization": `Bearer ${this.token}`,
|
|
1968
|
-
"Content-Type": "application/json"
|
|
1969
|
-
},
|
|
1970
|
-
timeout: 2e3
|
|
1971
|
-
});
|
|
1972
|
-
const raw = response.data.machine;
|
|
1973
|
-
if (!raw) {
|
|
1974
|
-
return null;
|
|
1975
|
-
}
|
|
1976
|
-
logger.debug(`[API] Machine ${machineId} fetched from server`);
|
|
1977
|
-
const machine = {
|
|
1978
|
-
id: raw.id,
|
|
1979
|
-
metadata: raw.metadata ? decrypt(decodeBase64(raw.metadata), this.secret) : null,
|
|
1980
|
-
metadataVersion: raw.metadataVersion || 0,
|
|
1981
|
-
daemonState: raw.daemonState ? decrypt(decodeBase64(raw.daemonState), this.secret) : null,
|
|
1982
|
-
daemonStateVersion: raw.daemonStateVersion || 0,
|
|
1983
|
-
active: raw.active,
|
|
1984
|
-
activeAt: raw.activeAt,
|
|
1985
|
-
createdAt: raw.createdAt,
|
|
1986
|
-
updatedAt: raw.updatedAt
|
|
1987
|
-
};
|
|
1988
|
-
return machine;
|
|
1989
|
-
}
|
|
1990
2023
|
/**
|
|
1991
2024
|
* Register or update machine with the server
|
|
1992
2025
|
* Returns the current machine state from the server with decrypted metadata and daemonState
|
|
1993
2026
|
*/
|
|
1994
2027
|
async getOrCreateMachine(opts) {
|
|
2028
|
+
let dataEncryptionKey = null;
|
|
2029
|
+
let encryptionKey;
|
|
2030
|
+
let encryptionVariant;
|
|
2031
|
+
if (this.credential.encryption.type === "dataKey") {
|
|
2032
|
+
encryptionVariant = "dataKey";
|
|
2033
|
+
encryptionKey = this.credential.encryption.machineKey;
|
|
2034
|
+
let encryptedDataKey = libsodiumEncryptForPublicKey(this.credential.encryption.machineKey, this.credential.encryption.publicKey);
|
|
2035
|
+
dataEncryptionKey = new Uint8Array(encryptedDataKey.length + 1);
|
|
2036
|
+
dataEncryptionKey.set([0], 0);
|
|
2037
|
+
dataEncryptionKey.set(encryptedDataKey, 1);
|
|
2038
|
+
} else {
|
|
2039
|
+
encryptionKey = this.credential.encryption.secret;
|
|
2040
|
+
encryptionVariant = "legacy";
|
|
2041
|
+
}
|
|
1995
2042
|
const response = await axios.post(
|
|
1996
2043
|
`${configuration.serverUrl}/v1/machines`,
|
|
1997
2044
|
{
|
|
1998
2045
|
id: opts.machineId,
|
|
1999
|
-
metadata: encodeBase64(encrypt(opts.metadata
|
|
2000
|
-
daemonState: opts.daemonState ? encodeBase64(encrypt(opts.daemonState
|
|
2046
|
+
metadata: encodeBase64(encrypt(encryptionKey, encryptionVariant, opts.metadata)),
|
|
2047
|
+
daemonState: opts.daemonState ? encodeBase64(encrypt(encryptionKey, encryptionVariant, opts.daemonState)) : void 0,
|
|
2048
|
+
dataEncryptionKey: dataEncryptionKey ? encodeBase64(dataEncryptionKey) : void 0
|
|
2001
2049
|
},
|
|
2002
2050
|
{
|
|
2003
2051
|
headers: {
|
|
2004
|
-
"Authorization": `Bearer ${this.token}`,
|
|
2052
|
+
"Authorization": `Bearer ${this.credential.token}`,
|
|
2005
2053
|
"Content-Type": "application/json"
|
|
2006
2054
|
},
|
|
2007
|
-
timeout:
|
|
2055
|
+
timeout: 6e4
|
|
2056
|
+
// 1 minute timeout for very bad network connections
|
|
2008
2057
|
}
|
|
2009
2058
|
);
|
|
2010
2059
|
if (response.status !== 200) {
|
|
@@ -2016,22 +2065,20 @@ class ApiClient {
|
|
|
2016
2065
|
logger.debug(`[API] Machine ${opts.machineId} registered/updated with server`);
|
|
2017
2066
|
const machine = {
|
|
2018
2067
|
id: raw.id,
|
|
2019
|
-
|
|
2068
|
+
encryptionKey,
|
|
2069
|
+
encryptionVariant,
|
|
2070
|
+
metadata: raw.metadata ? decrypt(encryptionKey, encryptionVariant, decodeBase64(raw.metadata)) : null,
|
|
2020
2071
|
metadataVersion: raw.metadataVersion || 0,
|
|
2021
|
-
daemonState: raw.daemonState ? decrypt(decodeBase64(raw.daemonState)
|
|
2022
|
-
daemonStateVersion: raw.daemonStateVersion || 0
|
|
2023
|
-
active: raw.active,
|
|
2024
|
-
activeAt: raw.activeAt,
|
|
2025
|
-
createdAt: raw.createdAt,
|
|
2026
|
-
updatedAt: raw.updatedAt
|
|
2072
|
+
daemonState: raw.daemonState ? decrypt(encryptionKey, encryptionVariant, decodeBase64(raw.daemonState)) : null,
|
|
2073
|
+
daemonStateVersion: raw.daemonStateVersion || 0
|
|
2027
2074
|
};
|
|
2028
2075
|
return machine;
|
|
2029
2076
|
}
|
|
2030
2077
|
sessionSyncClient(session) {
|
|
2031
|
-
return new ApiSessionClient(this.token,
|
|
2078
|
+
return new ApiSessionClient(this.credential.token, session);
|
|
2032
2079
|
}
|
|
2033
2080
|
machineSyncClient(machine) {
|
|
2034
|
-
return new ApiMachineClient(this.token,
|
|
2081
|
+
return new ApiMachineClient(this.credential.token, machine);
|
|
2035
2082
|
}
|
|
2036
2083
|
push() {
|
|
2037
2084
|
return this.pushClient;
|
|
@@ -2049,7 +2096,7 @@ class ApiClient {
|
|
|
2049
2096
|
},
|
|
2050
2097
|
{
|
|
2051
2098
|
headers: {
|
|
2052
|
-
"Authorization": `Bearer ${this.token}`,
|
|
2099
|
+
"Authorization": `Bearer ${this.credential.token}`,
|
|
2053
2100
|
"Content-Type": "application/json"
|
|
2054
2101
|
},
|
|
2055
2102
|
timeout: 5e3
|
|
@@ -2137,5 +2184,6 @@ exports.readDaemonState = readDaemonState;
|
|
|
2137
2184
|
exports.readSettings = readSettings;
|
|
2138
2185
|
exports.releaseDaemonLock = releaseDaemonLock;
|
|
2139
2186
|
exports.updateSettings = updateSettings;
|
|
2140
|
-
exports.
|
|
2187
|
+
exports.writeCredentialsDataKey = writeCredentialsDataKey;
|
|
2188
|
+
exports.writeCredentialsLegacy = writeCredentialsLegacy;
|
|
2141
2189
|
exports.writeDaemonState = writeDaemonState;
|