forkoff 1.0.8 → 1.0.10
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/E2EE-COMPLETE.md +290 -0
- package/README.md +11 -0
- package/dist/__tests__/crypto/e2e-integration.test.d.ts +17 -0
- package/dist/__tests__/crypto/e2e-integration.test.d.ts.map +1 -0
- package/dist/__tests__/crypto/e2e-integration.test.js +338 -0
- package/dist/__tests__/crypto/e2e-integration.test.js.map +1 -0
- package/dist/__tests__/crypto/e2eeManager.test.d.ts +2 -0
- package/dist/__tests__/crypto/e2eeManager.test.d.ts.map +1 -0
- package/dist/__tests__/crypto/e2eeManager.test.js +242 -0
- package/dist/__tests__/crypto/e2eeManager.test.js.map +1 -0
- package/dist/__tests__/crypto/encryption.test.d.ts +2 -0
- package/dist/__tests__/crypto/encryption.test.d.ts.map +1 -0
- package/dist/__tests__/crypto/encryption.test.js +116 -0
- package/dist/__tests__/crypto/encryption.test.js.map +1 -0
- package/dist/__tests__/crypto/keyExchange.test.d.ts +2 -0
- package/dist/__tests__/crypto/keyExchange.test.d.ts.map +1 -0
- package/dist/__tests__/crypto/keyExchange.test.js +84 -0
- package/dist/__tests__/crypto/keyExchange.test.js.map +1 -0
- package/dist/__tests__/crypto/keyGeneration.test.d.ts +2 -0
- package/dist/__tests__/crypto/keyGeneration.test.d.ts.map +1 -0
- package/dist/__tests__/crypto/keyGeneration.test.js +61 -0
- package/dist/__tests__/crypto/keyGeneration.test.js.map +1 -0
- package/dist/__tests__/crypto/keyStorage.test.d.ts +2 -0
- package/dist/__tests__/crypto/keyStorage.test.d.ts.map +1 -0
- package/dist/__tests__/crypto/keyStorage.test.js +133 -0
- package/dist/__tests__/crypto/keyStorage.test.js.map +1 -0
- package/dist/__tests__/crypto/websocketIntegration.test.d.ts +2 -0
- package/dist/__tests__/crypto/websocketIntegration.test.d.ts.map +1 -0
- package/dist/__tests__/crypto/websocketIntegration.test.js +259 -0
- package/dist/__tests__/crypto/websocketIntegration.test.js.map +1 -0
- package/dist/__tests__/tools/claude-process.test.d.ts +8 -0
- package/dist/__tests__/tools/claude-process.test.d.ts.map +1 -0
- package/dist/__tests__/tools/claude-process.test.js +224 -0
- package/dist/__tests__/tools/claude-process.test.js.map +1 -0
- package/dist/crypto/e2eeManager.d.ts +82 -0
- package/dist/crypto/e2eeManager.d.ts.map +1 -0
- package/dist/crypto/e2eeManager.js +270 -0
- package/dist/crypto/e2eeManager.js.map +1 -0
- package/dist/crypto/encryption.d.ts +19 -0
- package/dist/crypto/encryption.d.ts.map +1 -0
- package/dist/crypto/encryption.js +111 -0
- package/dist/crypto/encryption.js.map +1 -0
- package/dist/crypto/keyExchange.d.ts +24 -0
- package/dist/crypto/keyExchange.d.ts.map +1 -0
- package/dist/crypto/keyExchange.js +119 -0
- package/dist/crypto/keyExchange.js.map +1 -0
- package/dist/crypto/keyGeneration.d.ts +18 -0
- package/dist/crypto/keyGeneration.d.ts.map +1 -0
- package/dist/crypto/keyGeneration.js +99 -0
- package/dist/crypto/keyGeneration.js.map +1 -0
- package/dist/crypto/keyStorage.d.ts +39 -0
- package/dist/crypto/keyStorage.d.ts.map +1 -0
- package/dist/crypto/keyStorage.js +117 -0
- package/dist/crypto/keyStorage.js.map +1 -0
- package/dist/crypto/sessionPersistence.d.ts +33 -0
- package/dist/crypto/sessionPersistence.d.ts.map +1 -0
- package/dist/crypto/sessionPersistence.js +173 -0
- package/dist/crypto/sessionPersistence.js.map +1 -0
- package/dist/crypto/types.d.ts +35 -0
- package/dist/crypto/types.d.ts.map +1 -0
- package/dist/crypto/types.js +8 -0
- package/dist/crypto/types.js.map +1 -0
- package/dist/crypto/websocketE2EE.d.ts +47 -0
- package/dist/crypto/websocketE2EE.d.ts.map +1 -0
- package/dist/crypto/websocketE2EE.js +144 -0
- package/dist/crypto/websocketE2EE.js.map +1 -0
- package/dist/index.js +103 -2
- package/dist/index.js.map +1 -1
- package/dist/tools/claude-process.d.ts +19 -3
- package/dist/tools/claude-process.d.ts.map +1 -1
- package/dist/tools/claude-process.js +107 -164
- package/dist/tools/claude-process.js.map +1 -1
- package/dist/websocket.d.ts +33 -1
- package/dist/websocket.d.ts.map +1 -1
- package/dist/websocket.js +30 -1
- package/dist/websocket.js.map +1 -1
- package/jest.config.js +15 -0
- package/package.json +9 -2
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const keyStorage_1 = require("../../crypto/keyStorage");
|
|
37
|
+
// Mock keytar to avoid actual OS keychain operations during tests
|
|
38
|
+
jest.mock('keytar', () => ({
|
|
39
|
+
setPassword: jest.fn(),
|
|
40
|
+
getPassword: jest.fn(),
|
|
41
|
+
deletePassword: jest.fn(),
|
|
42
|
+
}));
|
|
43
|
+
const keytar = __importStar(require("keytar"));
|
|
44
|
+
describe('CLI Key Storage', () => {
|
|
45
|
+
const mockKeytar = keytar;
|
|
46
|
+
beforeEach(() => {
|
|
47
|
+
jest.clearAllMocks();
|
|
48
|
+
// Clear session keys between tests
|
|
49
|
+
(0, keyStorage_1.clearSessionKeys)();
|
|
50
|
+
});
|
|
51
|
+
describe('OS Keychain Operations', () => {
|
|
52
|
+
it('stores private key in OS keychain', async () => {
|
|
53
|
+
const deviceId = 'device-123';
|
|
54
|
+
const privateKey = 'AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE=';
|
|
55
|
+
mockKeytar.setPassword.mockResolvedValue();
|
|
56
|
+
await (0, keyStorage_1.storePrivateKey)(deviceId, privateKey);
|
|
57
|
+
expect(mockKeytar.setPassword).toHaveBeenCalledWith('forkoff-cli', `e2ee-private-key-${deviceId}`, privateKey);
|
|
58
|
+
});
|
|
59
|
+
it('retrieves private key from OS keychain', async () => {
|
|
60
|
+
const deviceId = 'device-123';
|
|
61
|
+
const privateKey = 'AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE=';
|
|
62
|
+
mockKeytar.getPassword.mockResolvedValue(privateKey);
|
|
63
|
+
const result = await (0, keyStorage_1.getPrivateKey)(deviceId);
|
|
64
|
+
expect(result).toBe(privateKey);
|
|
65
|
+
expect(mockKeytar.getPassword).toHaveBeenCalledWith('forkoff-cli', `e2ee-private-key-${deviceId}`);
|
|
66
|
+
});
|
|
67
|
+
it('returns null when no key exists', async () => {
|
|
68
|
+
const deviceId = 'device-123';
|
|
69
|
+
mockKeytar.getPassword.mockResolvedValue(null);
|
|
70
|
+
const result = await (0, keyStorage_1.getPrivateKey)(deviceId);
|
|
71
|
+
expect(result).toBeNull();
|
|
72
|
+
});
|
|
73
|
+
it('deletes keys from keychain', async () => {
|
|
74
|
+
const deviceId = 'device-123';
|
|
75
|
+
mockKeytar.deletePassword.mockResolvedValue(true);
|
|
76
|
+
await (0, keyStorage_1.deletePrivateKey)(deviceId);
|
|
77
|
+
expect(mockKeytar.deletePassword).toHaveBeenCalledWith('forkoff-cli', `e2ee-private-key-${deviceId}`);
|
|
78
|
+
});
|
|
79
|
+
it('handles keychain errors gracefully', async () => {
|
|
80
|
+
const deviceId = 'device-123';
|
|
81
|
+
mockKeytar.getPassword.mockRejectedValue(new Error('Keychain access denied'));
|
|
82
|
+
// Should not throw, should return null
|
|
83
|
+
const result = await (0, keyStorage_1.getPrivateKey)(deviceId);
|
|
84
|
+
expect(result).toBeNull();
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
describe('Session Key Storage (In-Memory)', () => {
|
|
88
|
+
it('stores session keys in memory', () => {
|
|
89
|
+
const deviceId = 'device-456';
|
|
90
|
+
const sessionKey = new Uint8Array(32).fill(1);
|
|
91
|
+
const sessionId = 'session-abc';
|
|
92
|
+
(0, keyStorage_1.storeSessionKey)(deviceId, sessionKey, sessionId);
|
|
93
|
+
const retrieved = (0, keyStorage_1.getSessionKey)(deviceId);
|
|
94
|
+
expect(retrieved).toEqual({
|
|
95
|
+
encryptionKey: sessionKey,
|
|
96
|
+
sessionId,
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
it('retrieves session keys by device ID', () => {
|
|
100
|
+
const deviceId = 'device-456';
|
|
101
|
+
const sessionKey = new Uint8Array(32).fill(2);
|
|
102
|
+
const sessionId = 'session-xyz';
|
|
103
|
+
(0, keyStorage_1.storeSessionKey)(deviceId, sessionKey, sessionId);
|
|
104
|
+
const retrieved = (0, keyStorage_1.getSessionKey)(deviceId);
|
|
105
|
+
expect(retrieved?.encryptionKey).toEqual(sessionKey);
|
|
106
|
+
expect(retrieved?.sessionId).toBe(sessionId);
|
|
107
|
+
});
|
|
108
|
+
it('returns null for non-existent session keys', () => {
|
|
109
|
+
const result = (0, keyStorage_1.getSessionKey)('nonexistent-device');
|
|
110
|
+
expect(result).toBeNull();
|
|
111
|
+
});
|
|
112
|
+
it('clears all session keys', () => {
|
|
113
|
+
const device1 = 'device-1';
|
|
114
|
+
const device2 = 'device-2';
|
|
115
|
+
(0, keyStorage_1.storeSessionKey)(device1, new Uint8Array(32).fill(1), 'session-1');
|
|
116
|
+
(0, keyStorage_1.storeSessionKey)(device2, new Uint8Array(32).fill(2), 'session-2');
|
|
117
|
+
(0, keyStorage_1.clearSessionKeys)();
|
|
118
|
+
expect((0, keyStorage_1.getSessionKey)(device1)).toBeNull();
|
|
119
|
+
expect((0, keyStorage_1.getSessionKey)(device2)).toBeNull();
|
|
120
|
+
});
|
|
121
|
+
it('overwrites existing session key for same device', () => {
|
|
122
|
+
const deviceId = 'device-123';
|
|
123
|
+
const firstKey = new Uint8Array(32).fill(1);
|
|
124
|
+
const secondKey = new Uint8Array(32).fill(2);
|
|
125
|
+
(0, keyStorage_1.storeSessionKey)(deviceId, firstKey, 'session-1');
|
|
126
|
+
(0, keyStorage_1.storeSessionKey)(deviceId, secondKey, 'session-2');
|
|
127
|
+
const retrieved = (0, keyStorage_1.getSessionKey)(deviceId);
|
|
128
|
+
expect(retrieved?.encryptionKey).toEqual(secondKey);
|
|
129
|
+
expect(retrieved?.sessionId).toBe('session-2');
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
//# sourceMappingURL=keyStorage.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyStorage.test.js","sourceRoot":"","sources":["../../../src/__tests__/crypto/keyStorage.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocketIntegration.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/crypto/websocketIntegration.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
const e2eeManager_1 = require("../../crypto/e2eeManager");
|
|
40
|
+
const keyStorage = __importStar(require("../../crypto/keyStorage"));
|
|
41
|
+
// Mock socket.io-client
|
|
42
|
+
jest.mock('socket.io-client', () => ({
|
|
43
|
+
io: jest.fn(),
|
|
44
|
+
}));
|
|
45
|
+
// Mock keytar
|
|
46
|
+
jest.mock('keytar');
|
|
47
|
+
// Mock axios
|
|
48
|
+
jest.mock('axios');
|
|
49
|
+
const axios_1 = __importDefault(require("axios"));
|
|
50
|
+
const mockAxios = axios_1.default;
|
|
51
|
+
describe('CLI WebSocket E2EE Integration', () => {
|
|
52
|
+
let wsClient;
|
|
53
|
+
let e2eeManager;
|
|
54
|
+
let mockSocket;
|
|
55
|
+
const deviceId = 'cli-device-123';
|
|
56
|
+
const mobileDeviceId = 'mobile-device-456';
|
|
57
|
+
const apiUrl = 'https://api.forkoff.app/api';
|
|
58
|
+
const authToken = 'mock-token';
|
|
59
|
+
// Mock axios instance
|
|
60
|
+
const mockAxiosInstance = {
|
|
61
|
+
put: jest.fn(),
|
|
62
|
+
get: jest.fn(),
|
|
63
|
+
};
|
|
64
|
+
beforeEach(async () => {
|
|
65
|
+
jest.clearAllMocks();
|
|
66
|
+
keyStorage.clearSessionKeys();
|
|
67
|
+
// Mock axios.create
|
|
68
|
+
mockAxios.create = jest.fn().mockReturnValue(mockAxiosInstance);
|
|
69
|
+
// Mock successful API responses
|
|
70
|
+
mockAxiosInstance.put.mockResolvedValue({ data: { success: true, keyVersion: 1 } });
|
|
71
|
+
mockAxiosInstance.get.mockResolvedValue({
|
|
72
|
+
data: {
|
|
73
|
+
publicKey: 'AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE=',
|
|
74
|
+
keyVersion: 1,
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
// Create mock socket
|
|
78
|
+
mockSocket = {
|
|
79
|
+
on: jest.fn(),
|
|
80
|
+
emit: jest.fn(),
|
|
81
|
+
connected: true,
|
|
82
|
+
disconnect: jest.fn(),
|
|
83
|
+
};
|
|
84
|
+
// Mock io to return our mock socket
|
|
85
|
+
const { io } = require('socket.io-client');
|
|
86
|
+
io.mockReturnValue(mockSocket);
|
|
87
|
+
// Mock key storage
|
|
88
|
+
jest.spyOn(keyStorage, 'getPrivateKey').mockResolvedValue(null);
|
|
89
|
+
jest.spyOn(keyStorage, 'storePrivateKey').mockResolvedValue();
|
|
90
|
+
// Initialize E2EE manager
|
|
91
|
+
e2eeManager = new e2eeManager_1.E2EEManager(deviceId, apiUrl, authToken);
|
|
92
|
+
await e2eeManager.initialize();
|
|
93
|
+
});
|
|
94
|
+
describe('Key Exchange Events', () => {
|
|
95
|
+
it('emits encrypted_key_exchange_init when starting encrypted session', async () => {
|
|
96
|
+
const initPayload = await e2eeManager.initiateKeyExchange(mobileDeviceId);
|
|
97
|
+
// Simulate emitting via WebSocket
|
|
98
|
+
mockSocket.emit('encrypted_key_exchange_init', {
|
|
99
|
+
recipientDeviceId: mobileDeviceId,
|
|
100
|
+
...initPayload,
|
|
101
|
+
});
|
|
102
|
+
expect(mockSocket.emit).toHaveBeenCalledWith('encrypted_key_exchange_init', expect.objectContaining({
|
|
103
|
+
senderDeviceId: deviceId,
|
|
104
|
+
recipientDeviceId: mobileDeviceId,
|
|
105
|
+
ephemeralPublicKey: expect.any(String),
|
|
106
|
+
}));
|
|
107
|
+
});
|
|
108
|
+
it('handles incoming encrypted_key_exchange_init', async () => {
|
|
109
|
+
const incomingInit = {
|
|
110
|
+
senderDeviceId: mobileDeviceId,
|
|
111
|
+
ephemeralPublicKey: 'AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI=',
|
|
112
|
+
};
|
|
113
|
+
// Handle key exchange init
|
|
114
|
+
const ackPayload = await e2eeManager.handleKeyExchangeInit(incomingInit.senderDeviceId, incomingInit.ephemeralPublicKey);
|
|
115
|
+
expect(ackPayload).toHaveProperty('recipientDeviceId', deviceId);
|
|
116
|
+
expect(ackPayload).toHaveProperty('ephemeralPublicKey');
|
|
117
|
+
expect(e2eeManager.hasSessionKey(mobileDeviceId)).toBe(true);
|
|
118
|
+
});
|
|
119
|
+
it('emits encrypted_key_exchange_ack after key derivation', async () => {
|
|
120
|
+
const incomingInit = {
|
|
121
|
+
senderDeviceId: mobileDeviceId,
|
|
122
|
+
ephemeralPublicKey: 'AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI=',
|
|
123
|
+
};
|
|
124
|
+
const ackPayload = await e2eeManager.handleKeyExchangeInit(incomingInit.senderDeviceId, incomingInit.ephemeralPublicKey);
|
|
125
|
+
// Simulate emitting ack via WebSocket
|
|
126
|
+
mockSocket.emit('encrypted_key_exchange_ack', {
|
|
127
|
+
senderDeviceId: deviceId,
|
|
128
|
+
...ackPayload,
|
|
129
|
+
});
|
|
130
|
+
expect(mockSocket.emit).toHaveBeenCalledWith('encrypted_key_exchange_ack', expect.objectContaining({
|
|
131
|
+
senderDeviceId: deviceId,
|
|
132
|
+
recipientDeviceId: deviceId,
|
|
133
|
+
ephemeralPublicKey: expect.any(String),
|
|
134
|
+
}));
|
|
135
|
+
});
|
|
136
|
+
it('handles incoming encrypted_key_exchange_ack', async () => {
|
|
137
|
+
// First initiate
|
|
138
|
+
await e2eeManager.initiateKeyExchange(mobileDeviceId);
|
|
139
|
+
// Then handle ack
|
|
140
|
+
const incomingAck = {
|
|
141
|
+
recipientDeviceId: deviceId,
|
|
142
|
+
ephemeralPublicKey: 'AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM=',
|
|
143
|
+
};
|
|
144
|
+
await e2eeManager.handleKeyExchangeAck(mobileDeviceId, incomingAck.ephemeralPublicKey);
|
|
145
|
+
expect(e2eeManager.hasSessionKey(mobileDeviceId)).toBe(true);
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
describe('Message Encryption', () => {
|
|
149
|
+
beforeEach(async () => {
|
|
150
|
+
// Set up E2EE session
|
|
151
|
+
await e2eeManager.initiateKeyExchange(mobileDeviceId);
|
|
152
|
+
await e2eeManager.handleKeyExchangeAck(mobileDeviceId, 'AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM=');
|
|
153
|
+
});
|
|
154
|
+
it('encrypts user_message before sending when E2EE established', () => {
|
|
155
|
+
const plaintext = 'Hello from CLI';
|
|
156
|
+
const sessionId = 'session-abc';
|
|
157
|
+
const encryptedMessage = e2eeManager.encryptMessage(plaintext, mobileDeviceId, sessionId);
|
|
158
|
+
// Simulate emitting encrypted message via WebSocket
|
|
159
|
+
mockSocket.emit('encrypted_message', encryptedMessage);
|
|
160
|
+
expect(mockSocket.emit).toHaveBeenCalledWith('encrypted_message', expect.objectContaining({
|
|
161
|
+
senderDeviceId: deviceId,
|
|
162
|
+
recipientDeviceId: mobileDeviceId,
|
|
163
|
+
sessionId,
|
|
164
|
+
payload: expect.objectContaining({
|
|
165
|
+
ciphertext: expect.any(String),
|
|
166
|
+
nonce: expect.any(String),
|
|
167
|
+
authTag: expect.any(String),
|
|
168
|
+
}),
|
|
169
|
+
messageCounter: expect.any(Number),
|
|
170
|
+
timestamp: expect.any(String),
|
|
171
|
+
}));
|
|
172
|
+
});
|
|
173
|
+
it('falls back to plaintext if E2EE not established', () => {
|
|
174
|
+
const unknownDeviceId = 'unknown-device';
|
|
175
|
+
const plaintext = 'Hello';
|
|
176
|
+
// Should throw because no session key exists
|
|
177
|
+
expect(() => e2eeManager.encryptMessage(plaintext, unknownDeviceId, 'session-123')).toThrow(/No session key found/);
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
describe('Message Decryption', () => {
|
|
181
|
+
beforeEach(async () => {
|
|
182
|
+
// Set up E2EE session as recipient
|
|
183
|
+
const ephemeralPublicKey = 'AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI=';
|
|
184
|
+
await e2eeManager.handleKeyExchangeInit(mobileDeviceId, ephemeralPublicKey);
|
|
185
|
+
});
|
|
186
|
+
it('decrypts incoming encrypted_message', () => {
|
|
187
|
+
const plaintext = 'Secret message from mobile';
|
|
188
|
+
const sessionId = 'session-xyz';
|
|
189
|
+
// Get session key
|
|
190
|
+
const sessionKeys = keyStorage.getSessionKey(mobileDeviceId);
|
|
191
|
+
if (!sessionKeys) {
|
|
192
|
+
throw new Error('Session key not found');
|
|
193
|
+
}
|
|
194
|
+
// Create encrypted message (simulating what mobile would send)
|
|
195
|
+
const { encrypt } = require('../../crypto/encryption');
|
|
196
|
+
const encryptedPayload = encrypt(plaintext, sessionKeys.encryptionKey);
|
|
197
|
+
const encryptedMessage = {
|
|
198
|
+
senderDeviceId: mobileDeviceId,
|
|
199
|
+
recipientDeviceId: deviceId,
|
|
200
|
+
sessionId,
|
|
201
|
+
payload: encryptedPayload,
|
|
202
|
+
messageCounter: 1,
|
|
203
|
+
timestamp: new Date().toISOString(),
|
|
204
|
+
};
|
|
205
|
+
// Decrypt
|
|
206
|
+
const decrypted = e2eeManager.decryptMessage(encryptedMessage, mobileDeviceId);
|
|
207
|
+
expect(decrypted).toBe(plaintext);
|
|
208
|
+
});
|
|
209
|
+
it('rejects tampered encrypted messages', () => {
|
|
210
|
+
const sessionKeys = keyStorage.getSessionKey(mobileDeviceId);
|
|
211
|
+
if (!sessionKeys) {
|
|
212
|
+
throw new Error('Session key not found');
|
|
213
|
+
}
|
|
214
|
+
const { encrypt } = require('../../crypto/encryption');
|
|
215
|
+
const encryptedPayload = encrypt('Original message', sessionKeys.encryptionKey);
|
|
216
|
+
// Tamper with ciphertext
|
|
217
|
+
const tamperedCiphertext = Buffer.from(encryptedPayload.ciphertext, 'base64');
|
|
218
|
+
tamperedCiphertext[0] ^= 0xff;
|
|
219
|
+
encryptedPayload.ciphertext = tamperedCiphertext.toString('base64');
|
|
220
|
+
const encryptedMessage = {
|
|
221
|
+
senderDeviceId: mobileDeviceId,
|
|
222
|
+
recipientDeviceId: deviceId,
|
|
223
|
+
sessionId: 'session-xyz',
|
|
224
|
+
payload: encryptedPayload,
|
|
225
|
+
messageCounter: 1,
|
|
226
|
+
timestamp: new Date().toISOString(),
|
|
227
|
+
};
|
|
228
|
+
// Should throw on decryption
|
|
229
|
+
expect(() => e2eeManager.decryptMessage(encryptedMessage, mobileDeviceId)).toThrow();
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
describe('E2EE Session Status', () => {
|
|
233
|
+
it('tracks E2EE session status per device', async () => {
|
|
234
|
+
expect(e2eeManager.hasSessionKey(mobileDeviceId)).toBe(false);
|
|
235
|
+
// Set up session
|
|
236
|
+
const ephemeralPublicKey = 'AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI=';
|
|
237
|
+
await e2eeManager.handleKeyExchangeInit(mobileDeviceId, ephemeralPublicKey);
|
|
238
|
+
expect(e2eeManager.hasSessionKey(mobileDeviceId)).toBe(true);
|
|
239
|
+
});
|
|
240
|
+
it('indicates when message should be encrypted', async () => {
|
|
241
|
+
// No session - should not be able to encrypt
|
|
242
|
+
expect(e2eeManager.hasSessionKey(mobileDeviceId)).toBe(false);
|
|
243
|
+
// Set up session
|
|
244
|
+
await e2eeManager.initiateKeyExchange(mobileDeviceId);
|
|
245
|
+
await e2eeManager.handleKeyExchangeAck(mobileDeviceId, 'AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM=');
|
|
246
|
+
// Now should be able to encrypt
|
|
247
|
+
expect(e2eeManager.hasSessionKey(mobileDeviceId)).toBe(true);
|
|
248
|
+
});
|
|
249
|
+
it('cleans up E2EE sessions on disconnect', () => {
|
|
250
|
+
// Set up session
|
|
251
|
+
keyStorage.storeSessionKey(mobileDeviceId, new Uint8Array(32), 'session-abc');
|
|
252
|
+
expect(e2eeManager.hasSessionKey(mobileDeviceId)).toBe(true);
|
|
253
|
+
// Cleanup
|
|
254
|
+
e2eeManager.cleanup();
|
|
255
|
+
expect(e2eeManager.hasSessionKey(mobileDeviceId)).toBe(false);
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
//# sourceMappingURL=websocketIntegration.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocketIntegration.test.js","sourceRoot":"","sources":["../../../src/__tests__/crypto/websocketIntegration.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for Claude Process Manager
|
|
3
|
+
* Covers:
|
|
4
|
+
* - Bug 1: dangerouslySkipPermissions threading through startSession, resumeSession, sendInput, registerSession
|
|
5
|
+
* - Bug 2: tool_activity event instead of claude_approval_request for SDK tool_use, disabled regex approval, guarded stdin writes
|
|
6
|
+
*/
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=claude-process.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-process.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/tools/claude-process.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|