appium-ios-remotexpc 0.21.2 → 0.23.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.
Files changed (114) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/build/src/index.d.ts +1 -1
  3. package/build/src/index.d.ts.map +1 -1
  4. package/build/src/lib/apple-tv/constants.d.ts +4 -3
  5. package/build/src/lib/apple-tv/constants.d.ts.map +1 -1
  6. package/build/src/lib/apple-tv/constants.js +10 -3
  7. package/build/src/lib/apple-tv/discovery/device-discovery.d.ts.map +1 -1
  8. package/build/src/lib/apple-tv/discovery/device-discovery.js +2 -2
  9. package/build/src/lib/apple-tv/encryption/index.d.ts +1 -0
  10. package/build/src/lib/apple-tv/encryption/index.d.ts.map +1 -1
  11. package/build/src/lib/apple-tv/encryption/index.js +1 -0
  12. package/build/src/lib/apple-tv/encryption/x25519.d.ts +8 -0
  13. package/build/src/lib/apple-tv/encryption/x25519.d.ts.map +1 -0
  14. package/build/src/lib/apple-tv/encryption/x25519.js +52 -0
  15. package/build/src/lib/apple-tv/index.d.ts +1 -0
  16. package/build/src/lib/apple-tv/index.d.ts.map +1 -1
  17. package/build/src/lib/apple-tv/index.js +1 -0
  18. package/build/src/lib/apple-tv/network/network-client.js +2 -2
  19. package/build/src/lib/apple-tv/pairing/user-input-service.d.ts.map +1 -1
  20. package/build/src/lib/apple-tv/pairing/user-input-service.js +2 -2
  21. package/build/src/lib/apple-tv/pairing-protocol/constants.d.ts +17 -0
  22. package/build/src/lib/apple-tv/pairing-protocol/constants.d.ts.map +1 -1
  23. package/build/src/lib/apple-tv/pairing-protocol/constants.js +25 -0
  24. package/build/src/lib/apple-tv/pairing-protocol/index.d.ts +2 -1
  25. package/build/src/lib/apple-tv/pairing-protocol/index.d.ts.map +1 -1
  26. package/build/src/lib/apple-tv/pairing-protocol/index.js +2 -1
  27. package/build/src/lib/apple-tv/pairing-protocol/pair-verification-protocol.d.ts +66 -0
  28. package/build/src/lib/apple-tv/pairing-protocol/pair-verification-protocol.d.ts.map +1 -0
  29. package/build/src/lib/apple-tv/pairing-protocol/pair-verification-protocol.js +178 -0
  30. package/build/src/lib/apple-tv/pairing-protocol/pairing-protocol.d.ts +35 -2
  31. package/build/src/lib/apple-tv/pairing-protocol/pairing-protocol.d.ts.map +1 -1
  32. package/build/src/lib/apple-tv/pairing-protocol/pairing-protocol.js +48 -14
  33. package/build/src/lib/apple-tv/storage/index.d.ts +1 -1
  34. package/build/src/lib/apple-tv/storage/index.d.ts.map +1 -1
  35. package/build/src/lib/apple-tv/storage/pairing-storage.d.ts +4 -1
  36. package/build/src/lib/apple-tv/storage/pairing-storage.d.ts.map +1 -1
  37. package/build/src/lib/apple-tv/storage/pairing-storage.js +59 -4
  38. package/build/src/lib/apple-tv/storage/types.d.ts +7 -1
  39. package/build/src/lib/apple-tv/storage/types.d.ts.map +1 -1
  40. package/build/src/lib/apple-tv/tunnel/index.d.ts +3 -0
  41. package/build/src/lib/apple-tv/tunnel/index.d.ts.map +1 -0
  42. package/build/src/lib/apple-tv/tunnel/index.js +1 -0
  43. package/build/src/lib/apple-tv/tunnel/tunnel-service.d.ts +57 -0
  44. package/build/src/lib/apple-tv/tunnel/tunnel-service.d.ts.map +1 -0
  45. package/build/src/lib/apple-tv/tunnel/tunnel-service.js +357 -0
  46. package/build/src/lib/apple-tv/tunnel/types.d.ts +22 -0
  47. package/build/src/lib/apple-tv/tunnel/types.d.ts.map +1 -0
  48. package/build/src/lib/apple-tv/tunnel/types.js +1 -0
  49. package/build/src/lib/bonjour/bonjour-discovery.d.ts.map +1 -1
  50. package/build/src/lib/bonjour/bonjour-discovery.js +3 -3
  51. package/build/src/lib/lockdown/index.d.ts.map +1 -1
  52. package/build/src/lib/plist/length-based-splitter.d.ts.map +1 -1
  53. package/build/src/lib/plist/length-based-splitter.js +0 -7
  54. package/build/src/lib/tunnel/index.d.ts +1 -0
  55. package/build/src/lib/tunnel/index.d.ts.map +1 -1
  56. package/build/src/lib/tunnel/packet-stream-server.d.ts.map +1 -1
  57. package/build/src/lib/tunnel/tunnel-registry-server.d.ts +1 -0
  58. package/build/src/lib/tunnel/tunnel-registry-server.d.ts.map +1 -1
  59. package/build/src/lib/tunnel/tunnel-registry-server.js +1 -1
  60. package/build/src/lib/types.d.ts +59 -0
  61. package/build/src/lib/types.d.ts.map +1 -1
  62. package/build/src/services/index.d.ts +2 -1
  63. package/build/src/services/index.d.ts.map +1 -1
  64. package/build/src/services/index.js +2 -1
  65. package/build/src/services/ios/afc/codec.d.ts +12 -0
  66. package/build/src/services/ios/afc/codec.d.ts.map +1 -1
  67. package/build/src/services/ios/afc/codec.js +26 -0
  68. package/build/src/services/ios/afc/index.d.ts.map +1 -1
  69. package/build/src/services/ios/afc/index.js +3 -14
  70. package/build/src/services/ios/afc/stream-utils.d.ts.map +1 -1
  71. package/build/src/services/ios/afc/stream-utils.js +0 -2
  72. package/build/src/services/ios/crash-reports/index.d.ts +54 -0
  73. package/build/src/services/ios/crash-reports/index.d.ts.map +1 -0
  74. package/build/src/services/ios/crash-reports/index.js +136 -0
  75. package/build/src/services/ios/mobile-config/index.js +2 -2
  76. package/build/src/services.d.ts +6 -1
  77. package/build/src/services.d.ts.map +1 -1
  78. package/build/src/services.js +14 -0
  79. package/package.json +3 -1
  80. package/scripts/pair-appletv.ts +2 -2
  81. package/scripts/start-appletv-tunnel.ts +178 -0
  82. package/scripts/test-tunnel-creation.ts +32 -23
  83. package/src/index.ts +3 -0
  84. package/src/lib/apple-tv/constants.ts +11 -3
  85. package/src/lib/apple-tv/discovery/device-discovery.ts +2 -3
  86. package/src/lib/apple-tv/encryption/index.ts +6 -0
  87. package/src/lib/apple-tv/encryption/x25519.ts +79 -0
  88. package/src/lib/apple-tv/index.ts +1 -0
  89. package/src/lib/apple-tv/network/network-client.ts +2 -2
  90. package/src/lib/apple-tv/pairing/user-input-service.ts +2 -2
  91. package/src/lib/apple-tv/pairing-protocol/constants.ts +29 -0
  92. package/src/lib/apple-tv/pairing-protocol/index.ts +12 -1
  93. package/src/lib/apple-tv/pairing-protocol/pair-verification-protocol.ts +329 -0
  94. package/src/lib/apple-tv/pairing-protocol/pairing-protocol.ts +49 -19
  95. package/src/lib/apple-tv/storage/index.ts +1 -1
  96. package/src/lib/apple-tv/storage/pairing-storage.ts +73 -5
  97. package/src/lib/apple-tv/storage/types.ts +8 -1
  98. package/src/lib/apple-tv/tunnel/index.ts +2 -0
  99. package/src/lib/apple-tv/tunnel/tunnel-service.ts +543 -0
  100. package/src/lib/apple-tv/tunnel/types.ts +23 -0
  101. package/src/lib/bonjour/bonjour-discovery.ts +3 -5
  102. package/src/lib/lockdown/index.ts +0 -7
  103. package/src/lib/plist/length-based-splitter.ts +0 -22
  104. package/src/lib/tunnel/index.ts +2 -8
  105. package/src/lib/tunnel/packet-stream-server.ts +0 -8
  106. package/src/lib/tunnel/tunnel-registry-server.ts +1 -1
  107. package/src/lib/types.ts +70 -0
  108. package/src/services/index.ts +2 -0
  109. package/src/services/ios/afc/codec.ts +34 -0
  110. package/src/services/ios/afc/index.ts +4 -17
  111. package/src/services/ios/afc/stream-utils.ts +0 -2
  112. package/src/services/ios/crash-reports/index.ts +180 -0
  113. package/src/services/ios/mobile-config/index.ts +2 -2
  114. package/src/services.ts +27 -0
@@ -0,0 +1,357 @@
1
+ import { util } from '@appium/support';
2
+ import { lookup } from 'node:dns/promises';
3
+ import * as tls from 'node:tls';
4
+ import { BonjourDiscovery } from '../../bonjour/bonjour-discovery.js';
5
+ import { getLogger } from '../../logger.js';
6
+ import { DEFAULT_PAIRING_CONFIG } from '../constants.js';
7
+ import { decryptChaCha20Poly1305, encryptChaCha20Poly1305, } from '../encryption/index.js';
8
+ import { PairingError } from '../errors.js';
9
+ import { NetworkClient } from '../network/index.js';
10
+ import { PairVerificationProtocol } from '../pairing-protocol/index.js';
11
+ import { PairingStorage } from '../storage/pairing-storage.js';
12
+ const appleTVLog = getLogger('AppleTVTunnelService');
13
+ export class TunnelService {
14
+ networkClient;
15
+ keys;
16
+ sequenceNumber;
17
+ static log = getLogger('TunnelService');
18
+ encryptedSequenceNumber = 0;
19
+ constructor(networkClient, keys, sequenceNumber) {
20
+ this.networkClient = networkClient;
21
+ this.keys = keys;
22
+ this.sequenceNumber = sequenceNumber;
23
+ }
24
+ async createTcpListener() {
25
+ TunnelService.log.debug('Creating TCP listener (Encrypted Request)');
26
+ const request = {
27
+ request: {
28
+ _0: {
29
+ createListener: {
30
+ key: this.keys.encryptionKey.toString('base64'),
31
+ peerConnectionsInfo: [
32
+ {
33
+ owningPID: process.pid,
34
+ owningProcessName: 'CoreDeviceService',
35
+ },
36
+ ],
37
+ transportProtocolType: 'tcp',
38
+ },
39
+ },
40
+ },
41
+ };
42
+ const nonce = Buffer.alloc(12);
43
+ nonce.writeBigUInt64LE(BigInt(this.encryptedSequenceNumber), 0);
44
+ const requestJson = JSON.stringify(request);
45
+ const encrypted = encryptChaCha20Poly1305({
46
+ plaintext: Buffer.from(requestJson, 'utf8'),
47
+ key: this.keys.clientEncryptionKey,
48
+ nonce,
49
+ });
50
+ const encryptedPayload = {
51
+ message: {
52
+ streamEncrypted: {
53
+ _0: encrypted.toString('base64'),
54
+ },
55
+ },
56
+ originatedBy: 'host',
57
+ sequenceNumber: this.sequenceNumber++,
58
+ };
59
+ await this.networkClient.sendPacket(encryptedPayload);
60
+ this.encryptedSequenceNumber++;
61
+ const response = await this.networkClient.receiveResponse();
62
+ const encryptedData = response.message?.streamEncrypted?._0;
63
+ if (!encryptedData) {
64
+ throw new PairingError('Failed to receive encrypted response from device', 'ENCRYPTED_RESPONSE_MISSING', { response });
65
+ }
66
+ const responseNonce = Buffer.alloc(12);
67
+ responseNonce.writeBigUInt64LE(BigInt(this.encryptedSequenceNumber - 1), 0);
68
+ const decrypted = decryptChaCha20Poly1305({
69
+ ciphertext: Buffer.from(encryptedData, 'base64'),
70
+ key: this.keys.serverEncryptionKey,
71
+ nonce: responseNonce,
72
+ });
73
+ const responseJson = JSON.parse(decrypted.toString('utf8'));
74
+ const createListenerResponse = responseJson?.response?._1?.createListener;
75
+ if (!createListenerResponse?.port) {
76
+ TunnelService.log.error('Invalid createListener response:', responseJson);
77
+ throw new PairingError('TCP listener creation failed: missing port in response', 'LISTENER_PORT_MISSING', { response: responseJson });
78
+ }
79
+ TunnelService.log.debug(`TCP Listener created on port: ${createListenerResponse.port}`);
80
+ return createListenerResponse;
81
+ }
82
+ async createTlsPskConnection(hostname, port) {
83
+ TunnelService.log.debug(`Creating TLS-PSK connection to ${hostname}:${port}`);
84
+ return new Promise((resolve, reject) => {
85
+ const options = {
86
+ host: hostname,
87
+ port,
88
+ pskCallback: (hint) => {
89
+ TunnelService.log.debug(`PSK callback invoked with hint: ${hint}`);
90
+ return {
91
+ psk: this.keys.encryptionKey,
92
+ identity: '',
93
+ };
94
+ },
95
+ ciphers: 'PSK-AES256-CBC-SHA:PSK-AES128-CBC-SHA:PSK-3DES-EDE-CBC-SHA:PSK-RC4-SHA:PSK',
96
+ secureProtocol: 'TLSv1_2_method',
97
+ // SECURITY NOTE: Disabling certificate validation is intentional and safe in this context.
98
+ // This connection uses TLS-PSK (Pre-Shared Key) authentication, where the pre-shared key
99
+ // itself provides mutual authentication between client and server. Traditional X.509
100
+ // certificate validation is not used in PSK-based TLS connections. The encryption key
101
+ // was securely established during the pairing process (which involves PIN verification),
102
+ // and this key authenticates both parties. This is the standard approach for Apple TV's
103
+ // RemoteXPC protocol and should NOT be changed to use certificate validation.
104
+ rejectUnauthorized: false,
105
+ checkServerIdentity: () => undefined,
106
+ };
107
+ const socket = tls.connect(options, () => {
108
+ TunnelService.log.debug('TLS-PSK connection established');
109
+ resolve(socket);
110
+ });
111
+ socket.on('error', (error) => {
112
+ TunnelService.log.error('TLS-PSK connection error:', error);
113
+ if (error.message?.includes('no shared cipher') ||
114
+ error.code === 'ECONNRESET') {
115
+ TunnelService.log.error('PSK ciphers may not be available in your Node.js build');
116
+ TunnelService.log.error('You may need to:');
117
+ TunnelService.log.error('1. Use Node.js compiled with PSK-enabled OpenSSL');
118
+ TunnelService.log.error('2. Use a Python subprocess for the TLS-PSK connection');
119
+ TunnelService.log.error('3. Use a native module like node-openssl');
120
+ }
121
+ reject(error);
122
+ });
123
+ socket.on('secureConnect', () => {
124
+ TunnelService.log.debug('Secure connection event fired');
125
+ });
126
+ socket.on('tlsClientError', (error) => {
127
+ TunnelService.log.error('TLS client error:', error);
128
+ });
129
+ });
130
+ }
131
+ getSequenceNumber() {
132
+ return this.sequenceNumber;
133
+ }
134
+ }
135
+ /**
136
+ * High-level service for establishing Apple TV tunnels.
137
+ * Orchestrates device discovery, pairing verification, and tunnel creation.
138
+ */
139
+ export class AppleTVTunnelService {
140
+ networkClient;
141
+ storage;
142
+ sequenceNumber = 0;
143
+ constructor() {
144
+ this.networkClient = new NetworkClient(DEFAULT_PAIRING_CONFIG);
145
+ this.storage = new PairingStorage(DEFAULT_PAIRING_CONFIG);
146
+ }
147
+ disconnect() {
148
+ this.networkClient.disconnect();
149
+ }
150
+ async startTunnel(deviceId, specificDeviceIdentifier) {
151
+ const devices = await this.discoverDevices();
152
+ this.logDiscoveredDevices(devices);
153
+ const devicesToProcess = this.selectDevicesToProcess(devices, specificDeviceIdentifier);
154
+ const identifiersToTry = await this.validateAndGetPairRecords(deviceId);
155
+ const failedAttempts = [];
156
+ for (const device of devicesToProcess) {
157
+ for (const identifier of identifiersToTry) {
158
+ appleTVLog.debug(`\n--- Attempting connection with pair record: ${identifier} ---`);
159
+ appleTVLog.debug(`Device: ${device.ip}:${device.port}`);
160
+ const pairRecord = await this.storage.load(identifier);
161
+ if (!pairRecord) {
162
+ appleTVLog.debug(`Failed to load pair record for ${identifier}`);
163
+ failedAttempts.push({
164
+ identifier,
165
+ error: 'Failed to load pair record',
166
+ });
167
+ continue;
168
+ }
169
+ const result = await this.attemptDeviceConnection(device, identifier, pairRecord, failedAttempts);
170
+ if (result) {
171
+ return result;
172
+ }
173
+ }
174
+ }
175
+ this.logFailureSummary(failedAttempts);
176
+ throw new Error('Failed to establish tunnel with any pair record. All authentication attempts failed.');
177
+ }
178
+ /**
179
+ * Logs information about discovered devices
180
+ */
181
+ logDiscoveredDevices(devices) {
182
+ appleTVLog.debug('Step 1: Device Discovery success');
183
+ appleTVLog.debug(`Found ${util.pluralize('device', devices.length, true)} via Bonjour`);
184
+ if (devices.length > 0) {
185
+ appleTVLog.info('\nDiscovered Apple TV devices:');
186
+ devices.forEach((device, index) => {
187
+ appleTVLog.info(` ${index + 1}. Identifier: ${device.identifier}`);
188
+ appleTVLog.info(` Name: ${device.name}`);
189
+ appleTVLog.info(` IP: ${device.ip}:${device.port}`);
190
+ appleTVLog.info(` Model: ${device.model}`);
191
+ appleTVLog.info(` Version: ${device.version}`);
192
+ });
193
+ }
194
+ }
195
+ /**
196
+ * Selects devices to process based on the specific device identifier
197
+ */
198
+ selectDevicesToProcess(devices, specificDeviceIdentifier) {
199
+ if (!specificDeviceIdentifier) {
200
+ return devices;
201
+ }
202
+ const filteredDevices = devices.filter((device) => device.identifier === specificDeviceIdentifier);
203
+ if (filteredDevices.length === 0) {
204
+ appleTVLog.error(`\nDevice with identifier ${specificDeviceIdentifier} not found in discovered devices.`);
205
+ appleTVLog.error('Available devices:');
206
+ devices.forEach((device) => {
207
+ appleTVLog.error(` - ${device.identifier} (${device.name})`);
208
+ });
209
+ throw new Error(`Device with identifier ${specificDeviceIdentifier} not found. Please check available devices above.`);
210
+ }
211
+ appleTVLog.info(`\nFiltered to specific device: ${specificDeviceIdentifier}`);
212
+ return filteredDevices;
213
+ }
214
+ /**
215
+ * Validates pair records and returns the list of identifiers to try
216
+ */
217
+ async validateAndGetPairRecords(deviceId) {
218
+ const availableDeviceIds = await this.storage.getAvailableDeviceIds();
219
+ if (availableDeviceIds.length === 0) {
220
+ throw new Error('No pair records found');
221
+ }
222
+ if (deviceId && !availableDeviceIds.includes(deviceId)) {
223
+ throw new Error(`No pair record found for specified device ${deviceId}`);
224
+ }
225
+ return deviceId ? [deviceId] : availableDeviceIds;
226
+ }
227
+ /**
228
+ * Attempts to establish a connection with a device using a specific pair record
229
+ */
230
+ async attemptDeviceConnection(device, identifier, pairRecord, failedAttempts) {
231
+ try {
232
+ this.sequenceNumber = 0;
233
+ await this.networkClient.connect(device.ip, device.port);
234
+ try {
235
+ await this.performHandshake();
236
+ const keys = await this.performPairVerification(pairRecord, identifier);
237
+ appleTVLog.info(`✅ Successfully verified with pair record: ${identifier}`);
238
+ const listenerInfo = await this.createTcpListener(keys);
239
+ this.networkClient.disconnect();
240
+ const tlsSocket = await this.createTlsPskConnection(device.ip, listenerInfo.port, keys);
241
+ appleTVLog.debug('Step 6: Tunnel Establishment success');
242
+ appleTVLog.info(`🔑 Using pair record: ${identifier}`);
243
+ appleTVLog.info(`📱 Connected to device: ${device.identifier} (${device.name})`);
244
+ appleTVLog.info(` IP: ${device.ip}:${device.port}`);
245
+ return { socket: tlsSocket, device };
246
+ }
247
+ catch (error) {
248
+ const errorMessage = error.message || String(error);
249
+ appleTVLog.debug(`❌ Failed with pair record ${identifier}: ${errorMessage}`);
250
+ failedAttempts.push({ identifier, error: errorMessage });
251
+ this.networkClient.disconnect();
252
+ await new Promise((resolve) => setTimeout(resolve, 500));
253
+ }
254
+ }
255
+ catch (connectionError) {
256
+ const errorMessage = connectionError.message || String(connectionError);
257
+ appleTVLog.debug(`Failed to connect to ${device.ip}:${device.port}: ${errorMessage}`);
258
+ failedAttempts.push({
259
+ identifier,
260
+ error: `Connection failed: ${errorMessage}`,
261
+ });
262
+ this.networkClient.disconnect();
263
+ }
264
+ return null;
265
+ }
266
+ /**
267
+ * Logs a summary of all failed connection attempts
268
+ */
269
+ logFailureSummary(failedAttempts) {
270
+ appleTVLog.error('\n=== Pair Record Verification Summary ===');
271
+ appleTVLog.error(`Total pair records tried: ${failedAttempts.length}`);
272
+ failedAttempts.forEach(({ identifier, error }) => {
273
+ appleTVLog.error(` - ${identifier}: ${error}`);
274
+ });
275
+ appleTVLog.error('=======================================\n');
276
+ }
277
+ async discoverDevices() {
278
+ const discovery = new BonjourDiscovery();
279
+ await discovery.startBrowsing('_remotepairing._tcp', 'local');
280
+ await new Promise((resolve) => setTimeout(resolve, DEFAULT_PAIRING_CONFIG.discoveryTimeout));
281
+ const services = discovery.getDiscoveredServices();
282
+ const devices = [];
283
+ for (const service of services) {
284
+ try {
285
+ const resolved = await discovery.resolveService(service.name, '_remotepairing._tcp', 'local');
286
+ if (resolved.hostname && resolved.port) {
287
+ const ipResult = await lookup(resolved.hostname.endsWith('.')
288
+ ? resolved.hostname.slice(0, -1)
289
+ : resolved.hostname, { family: 4 });
290
+ devices.push({
291
+ name: resolved.name,
292
+ identifier: resolved.txtRecord?.identifier || resolved.name,
293
+ hostname: resolved.hostname,
294
+ ip: ipResult.address,
295
+ port: resolved.port,
296
+ model: resolved.txtRecord?.model || '',
297
+ version: resolved.txtRecord?.ver || '',
298
+ minVersion: resolved.txtRecord?.minVer || '17',
299
+ });
300
+ }
301
+ }
302
+ catch (err) {
303
+ appleTVLog.debug(`Failed to resolve service ${service.name}: ${err}`);
304
+ }
305
+ }
306
+ discovery.stopBrowsing();
307
+ if (devices.length === 0) {
308
+ throw new Error('No devices found via Bonjour discovery');
309
+ }
310
+ return devices;
311
+ }
312
+ async performHandshake() {
313
+ const handshakePayload = {
314
+ message: {
315
+ plain: {
316
+ _0: {
317
+ request: {
318
+ _0: {
319
+ handshake: {
320
+ _0: {
321
+ hostOptions: { attemptPairVerify: true },
322
+ wireProtocolVersion: 19,
323
+ },
324
+ },
325
+ },
326
+ },
327
+ },
328
+ },
329
+ },
330
+ originatedBy: 'host',
331
+ sequenceNumber: this.sequenceNumber++,
332
+ };
333
+ await this.networkClient.sendPacket(handshakePayload);
334
+ await this.networkClient.receiveResponse();
335
+ appleTVLog.debug('Step 2: Initial Connection & Handshake success');
336
+ }
337
+ async performPairVerification(pairRecord, deviceId) {
338
+ appleTVLog.debug('Step 3: Pair Verification (4-step process)');
339
+ const verificationProtocol = new PairVerificationProtocol(this.networkClient);
340
+ verificationProtocol.setSequenceNumber(this.sequenceNumber);
341
+ const keys = await verificationProtocol.verify(pairRecord, deviceId);
342
+ this.sequenceNumber = verificationProtocol.getSequenceNumber();
343
+ appleTVLog.debug('Step 4: Main Encryption Key Derivation success');
344
+ return keys;
345
+ }
346
+ async createTcpListener(keys) {
347
+ appleTVLog.debug('Step 5: TCP Listener Creation (Encrypted Request)');
348
+ const tunnelService = new TunnelService(this.networkClient, keys, this.sequenceNumber);
349
+ const listenerInfo = await tunnelService.createTcpListener();
350
+ this.sequenceNumber = tunnelService.getSequenceNumber();
351
+ return listenerInfo;
352
+ }
353
+ async createTlsPskConnection(hostname, port, keys) {
354
+ const tunnelService = new TunnelService(this.networkClient, keys, this.sequenceNumber);
355
+ return tunnelService.createTlsPskConnection(hostname, port);
356
+ }
357
+ }
@@ -0,0 +1,22 @@
1
+ import type * as tls from 'node:tls';
2
+ export interface TcpListenerInfo {
3
+ port: number;
4
+ serviceName: string;
5
+ devicePublicKey: string;
6
+ }
7
+ /**
8
+ * Extended TLS connection options that include PSK (Pre-Shared Key) callback support.
9
+ * This interface extends the standard Node.js TLS ConnectionOptions to add PSK authentication.
10
+ */
11
+ export interface TlsPskConnectionOptions extends tls.ConnectionOptions {
12
+ /**
13
+ * Callback function invoked during TLS handshake to provide PSK credentials.
14
+ * @param hint - Optional hint from the server about which PSK identity to use
15
+ * @returns Object containing the pre-shared key and identity string
16
+ */
17
+ pskCallback?: (hint: string | null) => {
18
+ psk: Buffer;
19
+ identity: string;
20
+ };
21
+ }
22
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/lib/apple-tv/tunnel/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,GAAG,MAAM,UAAU,CAAC;AAErC,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAwB,SAAQ,GAAG,CAAC,iBAAiB;IACpE;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK;QACrC,GAAG,EAAE,MAAM,CAAC;QACZ,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH"}
@@ -0,0 +1 @@
1
+ export {};
@@ -1 +1 @@
1
- {"version":3,"file":"bonjour-discovery.d.ts","sourceRoot":"","sources":["../../../../src/lib/bonjour/bonjour-discovery.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAkB3C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,KAAK,CAAC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,cAAc,CAAC;CACzB,CAAC,CAAC;AAwXH,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,OAAO,CAAC,cAAc,CAAC,CAAe;IACtC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA0C;IAE9E;;OAEG;IACG,aAAa,CACjB,WAAW,GAAE,MAA+C,EAC5D,MAAM,GAAE,MAA+B,GACtC,OAAO,CAAC,IAAI,CAAC;IAgBhB;;OAEG;IACH,YAAY,IAAI,IAAI;IAQpB;;OAEG;IACH,qBAAqB,IAAI,cAAc,EAAE;IAIzC;;OAEG;IACG,cAAc,CAClB,WAAW,EAAE,MAAM,EACnB,WAAW,GAAE,MAA+C,EAC5D,MAAM,GAAE,MAA+B,GACtC,OAAO,CAAC,cAAc,CAAC;IAoB1B;;OAEG;IACG,4BAA4B,CAChC,SAAS,GAAE,MAA2C,GACrD,OAAO,CAAC,aAAa,EAAE,CAAC;IAqB3B;;OAEG;IACH,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAsBzC;;OAEG;YACW,kBAAkB;IA4BhC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAuBhC;;OAEG;YACW,kBAAkB;IAuBhC;;OAEG;IACH,OAAO,CAAC,OAAO;CAMhB"}
1
+ {"version":3,"file":"bonjour-discovery.d.ts","sourceRoot":"","sources":["../../../../src/lib/bonjour/bonjour-discovery.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAkB3C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,KAAK,CAAC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,cAAc,CAAC;CACzB,CAAC,CAAC;AAwXH,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,OAAO,CAAC,cAAc,CAAC,CAAe;IACtC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA0C;IAE9E;;OAEG;IACG,aAAa,CACjB,WAAW,GAAE,MAA+C,EAC5D,MAAM,GAAE,MAA+B,GACtC,OAAO,CAAC,IAAI,CAAC;IAgBhB;;OAEG;IACH,YAAY,IAAI,IAAI;IAQpB;;OAEG;IACH,qBAAqB,IAAI,cAAc,EAAE;IAIzC;;OAEG;IACG,cAAc,CAClB,WAAW,EAAE,MAAM,EACnB,WAAW,GAAE,MAA+C,EAC5D,MAAM,GAAE,MAA+B,GACtC,OAAO,CAAC,cAAc,CAAC;IAkB1B;;OAEG;IACG,4BAA4B,CAChC,SAAS,GAAE,MAA2C,GACrD,OAAO,CAAC,aAAa,EAAE,CAAC;IAqB3B;;OAEG;IACH,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAsBzC;;OAEG;YACW,kBAAkB;IA4BhC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAuBhC;;OAEG;YACW,kBAAkB;IAuBhC;;OAEG;IACH,OAAO,CAAC,OAAO;CAMhB"}
@@ -310,7 +310,7 @@ export class BonjourDiscovery extends EventEmitter {
310
310
  log.warn('Already discovering services');
311
311
  return;
312
312
  }
313
- log.info(`Starting Bonjour discovery for ${serviceType}.${domain}`);
313
+ log.info('Starting Bonjour discovery');
314
314
  try {
315
315
  await this.initializeBrowsing(serviceType, domain);
316
316
  }
@@ -339,7 +339,7 @@ export class BonjourDiscovery extends EventEmitter {
339
339
  * Resolve a specific service to get detailed information
340
340
  */
341
341
  async resolveService(serviceName, serviceType = BONJOUR_SERVICE_TYPES.APPLE_TV_PAIRING, domain = BONJOUR_DEFAULT_DOMAIN) {
342
- log.info(`[ServiceResolver] Resolving service: ${serviceName}.${serviceType}.${domain}`);
342
+ log.info(`[ServiceResolver] Resolving service: ${serviceName}`);
343
343
  const service = await executeDnsSdCommand([DNS_SD_COMMANDS.RESOLVE, serviceName, serviceType, domain], BONJOUR_TIMEOUTS.SERVICE_RESOLUTION, (output) => parseResolveOutput(output, serviceName, serviceType, domain), `Service resolution timeout for ${serviceName}`);
344
344
  if (!service) {
345
345
  throw new Error(`Failed to resolve service ${serviceName}`);
@@ -374,7 +374,7 @@ export class BonjourDiscovery extends EventEmitter {
374
374
  case DNS_SD_ACTIONS.ADD:
375
375
  this._discoveredServices.set(service.name, service);
376
376
  this.emit('serviceAdded', service);
377
- log.info(`Discovered service: ${service.name}`);
377
+ log.debug(`Discovered service: ${service.name}`);
378
378
  break;
379
379
  case DNS_SD_ACTIONS.REMOVE:
380
380
  this._discoveredServices.delete(service.name);
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/lockdown/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/lockdown/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"length-based-splitter.d.ts","sourceRoot":"","sources":["../../../../src/lib/plist/length-based-splitter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AA2B3D;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,cAAc,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IACvC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,SAAS;IAChD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;IACvC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,SAAS,CAAkB;IAEnC;;;OAGG;gBACS,OAAO,GAAE,0BAA+B;IAkBpD;;OAEG;IACH,QAAQ,IAAI,IAAI;IAUhB,UAAU,CACR,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,cAAc,EACxB,QAAQ,EAAE,iBAAiB,GAC1B,IAAI;IA6CP;;OAEG;IACH,OAAO,CAAC,cAAc;IA+CtB;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAsG1B"}
1
+ {"version":3,"file":"length-based-splitter.d.ts","sourceRoot":"","sources":["../../../../src/lib/plist/length-based-splitter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AA2B3D;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,cAAc,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IACvC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,SAAS;IAChD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;IACvC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,SAAS,CAAkB;IAEnC;;;OAGG;gBACS,OAAO,GAAE,0BAA+B;IAkBpD;;OAEG;IACH,QAAQ,IAAI,IAAI;IAUhB,UAAU,CACR,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,cAAc,EACxB,QAAQ,EAAE,iBAAiB,GAC1B,IAAI;IAsCP;;OAEG;IACH,OAAO,CAAC,cAAc;IA+CtB;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAuF1B"}
@@ -55,8 +55,6 @@ export class LengthBasedSplitter extends Transform {
55
55
  try {
56
56
  // Add the new chunk to our buffer
57
57
  this.buffer = Buffer.concat([this.buffer, chunk]);
58
- // Check if this is XML data or binary plist before doing any other processing
59
- const bufferString = this.buffer.toString(UTF8_ENCODING, 0, Math.min(MAX_PREVIEW_LENGTH, this.buffer.length));
60
58
  // Check for binary plist format (bplist00 or Ibplist00)
61
59
  if (this.buffer.length >= BINARY_PLIST_HEADER_LENGTH) {
62
60
  const possibleBplistHeader = this.buffer.toString(UTF8_ENCODING, 0, BINARY_PLIST_HEADER_LENGTH);
@@ -157,17 +155,12 @@ export class LengthBasedSplitter extends Transform {
157
155
  messageLength = alternateLength;
158
156
  }
159
157
  else {
160
- // If length is still invalid, check if this might actually be XML
161
- const suspiciousData = this.buffer.toString(UTF8_ENCODING, 0, Math.min(MAX_PREVIEW_LENGTH, this.buffer.length));
162
158
  // Invalid length - skip one byte and try again
163
159
  this.buffer = this.buffer.slice(1);
164
160
  continue;
165
161
  }
166
162
  }
167
163
  else {
168
- // For non-4-byte length fields, just use the original approach
169
- // If length is invalid, check if this might actually be XML
170
- const suspiciousData = this.buffer.toString(UTF8_ENCODING, 0, Math.min(MAX_PREVIEW_LENGTH, this.buffer.length));
171
164
  // Invalid length - skip one byte and try again
172
165
  this.buffer = this.buffer.slice(1);
173
166
  continue;
@@ -67,4 +67,5 @@ declare class TunnelManagerService {
67
67
  export declare const TunnelManager: TunnelManagerService;
68
68
  export { PacketStreamClient } from './packet-stream-client.js';
69
69
  export { PacketStreamServer } from './packet-stream-server.js';
70
+ export type { TunnelConnection };
70
71
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/tunnel/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,gBAAgB,EAEtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAGrC,OAAO,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAC;AAsB7E;;;GAGG;AACH,cAAM,oBAAoB;IAExB,OAAO,CAAC,cAAc,CAA+C;IAErE;;;;;OAKG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAKtC;;;;OAIG;IACH,gBAAgB,IAAI,MAAM,EAAE;IAM5B;;;;;;OAMG;IACG,yBAAyB,CAC7B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,mBAAmB,CAAC;IA2C/B;;;;;;OAMG;IACG,SAAS,CAAC,mBAAmB,EAAE,SAAS,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAmD1E;;;;;OAKG;IACH,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI;IAU5D;;;;;OAKG;IACG,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgC1D;;;;OAIG;IACG,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAatC;;;;;OAKG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;CAGnC;AAGD,eAAO,MAAM,aAAa,sBAA6B,CAAC;AAExD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/tunnel/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,gBAAgB,EAEtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAGrC,OAAO,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAC;AAc7E;;;GAGG;AACH,cAAM,oBAAoB;IAExB,OAAO,CAAC,cAAc,CAA+C;IAErE;;;;;OAKG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAKtC;;;;OAIG;IACH,gBAAgB,IAAI,MAAM,EAAE;IAM5B;;;;;;OAMG;IACG,yBAAyB,CAC7B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,mBAAmB,CAAC;IA2C/B;;;;;;OAMG;IACG,SAAS,CAAC,mBAAmB,EAAE,SAAS,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAmD1E;;;;;OAKG;IACH,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI;IAU5D;;;;;OAKG;IACG,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgC1D;;;;OAIG;IACG,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAatC;;;;;OAKG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;CAGnC;AAGD,eAAO,MAAM,aAAa,sBAA6B,CAAC;AAExD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,YAAY,EAAE,gBAAgB,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"packet-stream-server.d.ts","sourceRoot":"","sources":["../../../../src/lib/tunnel/packet-stream-server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAetC;;;GAGG;AACH,qBAAa,kBAAmB,SAAQ,YAAY;IAKtC,OAAO,CAAC,QAAQ,CAAC,IAAI;IAJjC,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAClD,OAAO,CAAC,cAAc,CAA+B;gBAExB,IAAI,EAAE,MAAM;IAIzC;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAqBtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB3B,iBAAiB,IAAI,cAAc,GAAG,IAAI;IAI1C;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAe9B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAQ5B;;OAEG;IACH,OAAO,CAAC,eAAe;IAoBvB;;OAEG;IACH,OAAO,CAAC,aAAa;CAItB"}
1
+ {"version":3,"file":"packet-stream-server.d.ts","sourceRoot":"","sources":["../../../../src/lib/tunnel/packet-stream-server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAOtC;;;GAGG;AACH,qBAAa,kBAAmB,SAAQ,YAAY;IAKtC,OAAO,CAAC,QAAQ,CAAC,IAAI;IAJjC,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAClD,OAAO,CAAC,cAAc,CAA+B;gBAExB,IAAI,EAAE,MAAM;IAIzC;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAqBtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB3B,iBAAiB,IAAI,cAAc,GAAG,IAAI;IAI1C;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAe9B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAQ5B;;OAEG;IACH,OAAO,CAAC,eAAe;IAoBvB;;OAEG;IACH,OAAO,CAAC,aAAa;CAItB"}
@@ -1,4 +1,5 @@
1
1
  import type { TunnelRegistry } from '../types.js';
2
+ export declare const DEFAULT_TUNNEL_REGISTRY_PORT = 42314;
2
3
  /**
3
4
  * Tunnel Registry Server - provides API endpoints for tunnel registry operations
4
5
  */
@@ -1 +1 @@
1
- {"version":3,"file":"tunnel-registry-server.d.ts","sourceRoot":"","sources":["../../../../src/lib/tunnel/tunnel-registry-server.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAuB,MAAM,aAAa,CAAC;AAuDvE;;GAEG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAC,CAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,cAAc,CAAC;IACpC,OAAO,CAAC,QAAQ,CAOd;IAEF;;;;OAIG;gBACS,WAAW,EAAE,cAAc,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM;IAKjE;;OAEG;IACH,OAAO,KAAK,OAAO,GAElB;IAED;;OAEG;IACH,OAAO,KAAK,QAAQ,GAOnB;IAED;;OAEG;IACH,OAAO,KAAK,YAAY,GAKvB;IAED;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAgC5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB3B;;OAEG;YACW,aAAa;IA6D3B;;OAEG;YACW,aAAa;IAY3B;;OAEG;YACW,eAAe;IAwB7B;;OAEG;YACW,mBAAmB;IAgCjC;;OAEG;YACW,YAAY;IAqD1B;;OAEG;YACW,YAAY;CAmB3B;AAED;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC7C,WAAW,EAAE,cAAc,GAAG,SAAS,EACvC,IAAI,GAAE,MAAqC,GAC1C,OAAO,CAAC,oBAAoB,CAAC,CAI/B"}
1
+ {"version":3,"file":"tunnel-registry-server.d.ts","sourceRoot":"","sources":["../../../../src/lib/tunnel/tunnel-registry-server.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAuB,MAAM,aAAa,CAAC;AAGvE,eAAO,MAAM,4BAA4B,QAAQ,CAAC;AAoDlD;;GAEG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAC,CAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,cAAc,CAAC;IACpC,OAAO,CAAC,QAAQ,CAOd;IAEF;;;;OAIG;gBACS,WAAW,EAAE,cAAc,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM;IAKjE;;OAEG;IACH,OAAO,KAAK,OAAO,GAElB;IAED;;OAEG;IACH,OAAO,KAAK,QAAQ,GAOnB;IAED;;OAEG;IACH,OAAO,KAAK,YAAY,GAKvB;IAED;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAgC5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB3B;;OAEG;YACW,aAAa;IA6D3B;;OAEG;YACW,aAAa;IAY3B;;OAEG;YACW,eAAe;IAwB7B;;OAEG;YACW,mBAAmB;IAgCjC;;OAEG;YACW,YAAY;IAqD1B;;OAEG;YACW,YAAY;CAmB3B;AAED;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC7C,WAAW,EAAE,cAAc,GAAG,SAAS,EACvC,IAAI,GAAE,MAAqC,GAC1C,OAAO,CAAC,oBAAoB,CAAC,CAI/B"}
@@ -2,7 +2,7 @@ import * as http from 'node:http';
2
2
  import { URL } from 'node:url';
3
3
  import { getLogger } from '../logger.js';
4
4
  // Constants
5
- const DEFAULT_TUNNEL_REGISTRY_PORT = 42314;
5
+ export const DEFAULT_TUNNEL_REGISTRY_PORT = 42314;
6
6
  const API_BASE_PATH = '/remotexpc/tunnels';
7
7
  // Logger instance
8
8
  const log = getLogger('TunnelRegistryServer');
@@ -1322,4 +1322,63 @@ export interface MisagentServiceWithConnection {
1322
1322
  misagentService: MisagentService;
1323
1323
  remoteXPC: RemoteXpcConnection;
1324
1324
  }
1325
+ /**
1326
+ * Options for pulling crash reports from device to local
1327
+ */
1328
+ export interface CrashReportsPullOptions {
1329
+ /**
1330
+ * If true, deletes crash reports from the remote device after pulling to local.
1331
+ * @default false
1332
+ */
1333
+ erase?: boolean;
1334
+ /**
1335
+ * Glob pattern to filter crash reports (e.g., '*.ips', 'Siri*', '**\/*.crash')
1336
+ */
1337
+ match?: string;
1338
+ }
1339
+ /**
1340
+ * CrashReportsService provides an API to manage crash reports on iOS devices
1341
+ */
1342
+ export interface CrashReportsService extends BaseService {
1343
+ /**
1344
+ * List files and folders in the crash report's directory
1345
+ *
1346
+ * Crash reports are primarily stored as .ips files, which contain detailed information about
1347
+ * app crashes, including stack traces, thread states, and device information.
1348
+ * In addition to .ips files, the crash reports directory may contain:
1349
+ * - Sysdiagnose tarballs (comprehensive system diagnostic archives)
1350
+ * - Special directories like /Retired, /Cloud, /Assistant, etc.
1351
+ *
1352
+ * For details on the .ips file format, see:
1353
+ * https://developer.apple.com/documentation/xcode/analyzing-a-crash-report
1354
+ *
1355
+ * @param dirPath Path to list, defaults to "/"
1356
+ * @param depth Listing depth: 1 for immediate children, -1 for infinite
1357
+ * @returns List of file paths (e.g., .ips files, sysdiagnose tarballs, directories like /Retired, /Cloud, etc.)
1358
+ */
1359
+ ls(dirPath?: string, depth?: number): Promise<string[]>;
1360
+ /**
1361
+ * Pull crash reports from device to local machine
1362
+ * @param out Local directory path
1363
+ * @param entry Remote path on device, defaults to "/"
1364
+ * @param options Pull options (erase, match pattern)
1365
+ */
1366
+ pull(out: string, entry?: string, options?: CrashReportsPullOptions): Promise<void>;
1367
+ /**
1368
+ * Clear all crash reports from the device
1369
+ */
1370
+ clear(): Promise<void>;
1371
+ /**
1372
+ * Flush pending crash reports into CrashReports directory
1373
+ */
1374
+ flush(): Promise<void>;
1375
+ /**
1376
+ * Close the service and release resources
1377
+ */
1378
+ close(): void;
1379
+ }
1380
+ export interface CrashReportsServiceWithConnection {
1381
+ crashReportsService: CrashReportsService;
1382
+ remoteXPC: RemoteXpcConnection;
1383
+ }
1325
1384
  //# sourceMappingURL=types.d.ts.map