appium-ios-remotexpc 0.0.2 → 0.0.4
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/CHANGELOG.md +12 -0
- package/build/src/base-plist-service.d.ts +51 -0
- package/build/src/base-plist-service.d.ts.map +1 -0
- package/build/src/base-plist-service.js +61 -0
- package/build/src/base-socket-service.d.ts +15 -0
- package/build/src/base-socket-service.d.ts.map +1 -0
- package/build/src/base-socket-service.js +46 -0
- package/build/src/index.d.ts +9 -0
- package/build/src/index.d.ts.map +1 -0
- package/build/src/index.js +7 -0
- package/build/src/lib/apple-tv/constants.d.ts +49 -0
- package/build/src/lib/apple-tv/constants.d.ts.map +1 -0
- package/build/src/lib/apple-tv/constants.js +71 -0
- package/build/src/lib/apple-tv/errors.d.ts +17 -0
- package/build/src/lib/apple-tv/errors.d.ts.map +1 -0
- package/build/src/lib/apple-tv/errors.js +30 -0
- package/build/src/lib/apple-tv/tlv/decoder.d.ts +19 -0
- package/build/src/lib/apple-tv/tlv/decoder.d.ts.map +1 -0
- package/build/src/lib/apple-tv/tlv/decoder.js +49 -0
- package/build/src/lib/apple-tv/tlv/encoder.d.ts +10 -0
- package/build/src/lib/apple-tv/tlv/encoder.d.ts.map +1 -0
- package/build/src/lib/apple-tv/tlv/encoder.js +20 -0
- package/build/src/lib/apple-tv/tlv/index.d.ts +4 -0
- package/build/src/lib/apple-tv/tlv/index.d.ts.map +1 -0
- package/build/src/lib/apple-tv/tlv/index.js +3 -0
- package/build/src/lib/apple-tv/tlv/pairing-tlv.d.ts +14 -0
- package/build/src/lib/apple-tv/tlv/pairing-tlv.d.ts.map +1 -0
- package/build/src/lib/apple-tv/tlv/pairing-tlv.js +27 -0
- package/build/src/lib/apple-tv/types.d.ts +36 -0
- package/build/src/lib/apple-tv/types.d.ts.map +1 -0
- package/build/src/lib/apple-tv/types.js +1 -0
- package/build/src/lib/apple-tv/utils/buffer-utils.d.ts +40 -0
- package/build/src/lib/apple-tv/utils/buffer-utils.d.ts.map +1 -0
- package/build/src/lib/apple-tv/utils/buffer-utils.js +76 -0
- package/build/src/lib/apple-tv/utils/index.d.ts +3 -0
- package/build/src/lib/apple-tv/utils/index.d.ts.map +1 -0
- package/build/src/lib/apple-tv/utils/index.js +2 -0
- package/build/src/lib/apple-tv/utils/uuid-generator.d.ts +9 -0
- package/build/src/lib/apple-tv/utils/uuid-generator.d.ts.map +1 -0
- package/build/src/lib/apple-tv/utils/uuid-generator.js +36 -0
- package/build/src/lib/lockdown/index.d.ts +87 -0
- package/build/src/lib/lockdown/index.d.ts.map +1 -0
- package/build/src/lib/lockdown/index.js +324 -0
- package/build/src/lib/pair-record/index.d.ts +3 -0
- package/build/src/lib/pair-record/index.d.ts.map +1 -0
- package/build/src/lib/pair-record/index.js +2 -0
- package/build/src/lib/pair-record/pair-record.d.ts +48 -0
- package/build/src/lib/pair-record/pair-record.d.ts.map +1 -0
- package/build/src/lib/pair-record/pair-record.js +85 -0
- package/build/src/lib/plist/binary-plist-creator.d.ts +14 -0
- package/build/src/lib/plist/binary-plist-creator.d.ts.map +1 -0
- package/build/src/lib/plist/binary-plist-creator.js +475 -0
- package/build/src/lib/plist/binary-plist-parser.d.ts +14 -0
- package/build/src/lib/plist/binary-plist-parser.d.ts.map +1 -0
- package/build/src/lib/plist/binary-plist-parser.js +449 -0
- package/build/src/lib/plist/constants.d.ts +36 -0
- package/build/src/lib/plist/constants.d.ts.map +1 -0
- package/build/src/lib/plist/constants.js +43 -0
- package/build/src/lib/plist/index.d.ts +14 -0
- package/build/src/lib/plist/index.d.ts.map +1 -0
- package/build/src/lib/plist/index.js +16 -0
- package/build/src/lib/plist/length-based-splitter.d.ts +43 -0
- package/build/src/lib/plist/length-based-splitter.d.ts.map +1 -0
- package/build/src/lib/plist/length-based-splitter.js +228 -0
- package/build/src/lib/plist/plist-creator.d.ts +8 -0
- package/build/src/lib/plist/plist-creator.d.ts.map +1 -0
- package/build/src/lib/plist/plist-creator.js +33 -0
- package/build/src/lib/plist/plist-decoder.d.ts +25 -0
- package/build/src/lib/plist/plist-decoder.d.ts.map +1 -0
- package/build/src/lib/plist/plist-decoder.js +103 -0
- package/build/src/lib/plist/plist-encoder.d.ts +10 -0
- package/build/src/lib/plist/plist-encoder.d.ts.map +1 -0
- package/build/src/lib/plist/plist-encoder.js +27 -0
- package/build/src/lib/plist/plist-parser.d.ts +9 -0
- package/build/src/lib/plist/plist-parser.d.ts.map +1 -0
- package/build/src/lib/plist/plist-parser.js +109 -0
- package/build/src/lib/plist/plist-service.d.ts +86 -0
- package/build/src/lib/plist/plist-service.d.ts.map +1 -0
- package/build/src/lib/plist/plist-service.js +180 -0
- package/build/src/lib/plist/unified-plist-creator.d.ts +9 -0
- package/build/src/lib/plist/unified-plist-creator.d.ts.map +1 -0
- package/build/src/lib/plist/unified-plist-creator.js +14 -0
- package/build/src/lib/plist/unified-plist-parser.d.ts +8 -0
- package/build/src/lib/plist/unified-plist-parser.d.ts.map +1 -0
- package/build/src/lib/plist/unified-plist-parser.js +23 -0
- package/build/src/lib/plist/utils.d.ts +97 -0
- package/build/src/lib/plist/utils.d.ts.map +1 -0
- package/build/src/lib/plist/utils.js +287 -0
- package/build/src/lib/remote-xpc/constants.d.ts +20 -0
- package/build/src/lib/remote-xpc/constants.d.ts.map +1 -0
- package/build/src/lib/remote-xpc/constants.js +21 -0
- package/build/src/lib/remote-xpc/handshake-frames.d.ts +74 -0
- package/build/src/lib/remote-xpc/handshake-frames.d.ts.map +1 -0
- package/build/src/lib/remote-xpc/handshake-frames.js +285 -0
- package/build/src/lib/remote-xpc/handshake.d.ts +14 -0
- package/build/src/lib/remote-xpc/handshake.d.ts.map +1 -0
- package/build/src/lib/remote-xpc/handshake.js +95 -0
- package/build/src/lib/remote-xpc/remote-xpc-connection.d.ts +55 -0
- package/build/src/lib/remote-xpc/remote-xpc-connection.d.ts.map +1 -0
- package/build/src/lib/remote-xpc/remote-xpc-connection.js +365 -0
- package/build/src/lib/remote-xpc/xpc-protocol.d.ts +22 -0
- package/build/src/lib/remote-xpc/xpc-protocol.d.ts.map +1 -0
- package/build/src/lib/remote-xpc/xpc-protocol.js +368 -0
- package/build/src/lib/tunnel/index.d.ts +69 -0
- package/build/src/lib/tunnel/index.d.ts.map +1 -0
- package/build/src/lib/tunnel/index.js +205 -0
- package/build/src/lib/tunnel/packet-stream-client.d.ts +46 -0
- package/build/src/lib/tunnel/packet-stream-client.d.ts.map +1 -0
- package/build/src/lib/tunnel/packet-stream-client.js +152 -0
- package/build/src/lib/tunnel/packet-stream-server.d.ts +37 -0
- package/build/src/lib/tunnel/packet-stream-server.d.ts.map +1 -0
- package/build/src/lib/tunnel/packet-stream-server.js +109 -0
- package/build/src/lib/tunnel/tunnel-api-client.d.ts +85 -0
- package/build/src/lib/tunnel/tunnel-api-client.d.ts.map +1 -0
- package/build/src/lib/tunnel/tunnel-api-client.js +207 -0
- package/build/src/lib/tunnel/tunnel-registry-server.d.ts +68 -0
- package/build/src/lib/tunnel/tunnel-registry-server.d.ts.map +1 -0
- package/build/src/lib/tunnel/tunnel-registry-server.js +351 -0
- package/build/src/lib/types.d.ts +238 -0
- package/build/src/lib/types.d.ts.map +1 -0
- package/build/src/lib/types.js +4 -0
- package/build/src/lib/usbmux/index.d.ts +177 -0
- package/build/src/lib/usbmux/index.d.ts.map +1 -0
- package/build/src/lib/usbmux/index.js +490 -0
- package/build/src/lib/usbmux/usbmux-decoder.d.ts +19 -0
- package/build/src/lib/usbmux/usbmux-decoder.d.ts.map +1 -0
- package/build/src/lib/usbmux/usbmux-decoder.js +38 -0
- package/build/src/lib/usbmux/usbmux-encoder.d.ts +12 -0
- package/build/src/lib/usbmux/usbmux-encoder.d.ts.map +1 -0
- package/build/src/lib/usbmux/usbmux-encoder.js +32 -0
- package/build/src/service-connection.d.ts +34 -0
- package/build/src/service-connection.d.ts.map +1 -0
- package/build/src/service-connection.js +51 -0
- package/build/src/services/index.d.ts +6 -0
- package/build/src/services/index.d.ts.map +1 -0
- package/build/src/services/index.js +5 -0
- package/build/src/services/ios/base-service.d.ts +35 -0
- package/build/src/services/ios/base-service.d.ts.map +1 -0
- package/build/src/services/ios/base-service.js +55 -0
- package/build/src/services/ios/diagnostic-service/index.d.ts +46 -0
- package/build/src/services/ios/diagnostic-service/index.d.ts.map +1 -0
- package/build/src/services/ios/diagnostic-service/index.js +169 -0
- package/build/src/services/ios/diagnostic-service/keys.d.ts +5 -0
- package/build/src/services/ios/diagnostic-service/keys.d.ts.map +1 -0
- package/build/src/services/ios/diagnostic-service/keys.js +770 -0
- package/build/src/services/ios/syslog-service/index.d.ts +91 -0
- package/build/src/services/ios/syslog-service/index.d.ts.map +1 -0
- package/build/src/services/ios/syslog-service/index.js +323 -0
- package/build/src/services/ios/tunnel-service/index.d.ts +17 -0
- package/build/src/services/ios/tunnel-service/index.d.ts.map +1 -0
- package/build/src/services/ios/tunnel-service/index.js +57 -0
- package/build/src/services.d.ts +14 -0
- package/build/src/services.d.ts.map +1 -0
- package/build/src/services.js +48 -0
- package/package.json +12 -3
- package/.github/dependabot.yml +0 -38
- package/.github/workflows/format-check.yml +0 -43
- package/.github/workflows/lint-and-build.yml +0 -40
- package/.github/workflows/pr-title.yml +0 -16
- package/.github/workflows/publish.js.yml +0 -41
- package/.github/workflows/test-validation.yml +0 -40
- package/.mocharc.json +0 -8
- package/.prettierignore +0 -3
- package/.prettierrc +0 -17
- package/.releaserc +0 -48
- package/assets/images/ios-arch.png +0 -0
- package/eslint.config.js +0 -45
- package/npm-shrinkwrap.json +0 -2711
- package/test/integration/diagnostics-test.ts +0 -44
- package/test/integration/read-pair-record-test.ts +0 -39
- package/test/integration/tunnel-test.ts +0 -104
- package/test/unit/apple-tv/tlv/decoder.spec.ts +0 -144
- package/test/unit/apple-tv/tlv/encoder.spec.ts +0 -91
- package/test/unit/apple-tv/tlv/pairing-tlv.spec.ts +0 -101
- package/test/unit/apple-tv/tlv/tlv-integration.spec.ts +0 -146
- package/test/unit/apple-tv/utils/buffer-utils.spec.ts +0 -74
- package/test/unit/apple-tv/utils/uuid-generator.spec.ts +0 -39
- package/test/unit/fixtures/index.ts +0 -88
- package/test/unit/fixtures/usbmuxconnectmessage.bin +0 -0
- package/test/unit/fixtures/usbmuxlistdevicemessage.bin +0 -0
- package/test/unit/plist/error-handling.spec.ts +0 -101
- package/test/unit/plist/fixtures/sample.binary.plist +0 -0
- package/test/unit/plist/fixtures/sample.xml.plist +0 -38
- package/test/unit/plist/plist-parser.spec.ts +0 -283
- package/test/unit/plist/plist.spec.ts +0 -205
- package/test/unit/plist/tag-position-handling.spec.ts +0 -90
- package/test/unit/plist/unified-plist-parser.spec.ts +0 -227
- package/test/unit/plist/utils.spec.ts +0 -249
- package/test/unit/plist/xml-cleaning.spec.ts +0 -60
- package/test/unit/tunnel/tunnel-registry-server.spec.ts +0 -194
- package/test/unit/usbmux/usbmux-specs.ts +0 -71
- package/tsconfig.json +0 -36
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a non-negative bigint to a fixed-length Buffer in big-endian format.
|
|
3
|
+
*
|
|
4
|
+
* @param value - The bigint value to convert (must be non-negative).
|
|
5
|
+
* @param length - The target buffer length in bytes.
|
|
6
|
+
* @returns A Buffer representing the bigint, padded to the specified length.
|
|
7
|
+
*
|
|
8
|
+
* @throws {RangeError} If the value is negative or doesn't fit in the specified length.
|
|
9
|
+
*/
|
|
10
|
+
export declare function bigIntToBuffer(value: bigint, length: number): Buffer;
|
|
11
|
+
/**
|
|
12
|
+
* Converts a Buffer into a bigint by interpreting it as a big-endian hexadecimal number.
|
|
13
|
+
*
|
|
14
|
+
* @param buffer - The input Buffer.
|
|
15
|
+
* @returns A bigint representing the numeric value of the buffer.
|
|
16
|
+
*/
|
|
17
|
+
export declare function bufferToBigInt(buffer: Buffer): bigint;
|
|
18
|
+
/**
|
|
19
|
+
* Converts a non-negative bigint into a minimal-length Buffer in big-endian format.
|
|
20
|
+
* No unnecessary leading zero bytes will be included.
|
|
21
|
+
*
|
|
22
|
+
* @param value - The bigint value to convert (must be non-negative).
|
|
23
|
+
* @returns A Buffer representing the bigint with minimal byte length.
|
|
24
|
+
*
|
|
25
|
+
* @throws {RangeError} If the value is negative.
|
|
26
|
+
*/
|
|
27
|
+
export declare function bigIntToMinimalBuffer(value: bigint): Buffer;
|
|
28
|
+
/**
|
|
29
|
+
* Computes modular exponentiation: (base ^ exponent) % modulus.
|
|
30
|
+
* Efficiently handles large numbers using the binary exponentiation method.
|
|
31
|
+
*
|
|
32
|
+
* @param base - The base number.
|
|
33
|
+
* @param exponent - The exponent (must be non-negative).
|
|
34
|
+
* @param modulus - The modulus (must be non-zero).
|
|
35
|
+
* @returns The result of (base ** exponent) modulo modulus.
|
|
36
|
+
*
|
|
37
|
+
* @throws {RangeError} If the exponent is negative or the modulus is zero.
|
|
38
|
+
*/
|
|
39
|
+
export declare function modPow(base: bigint, exponent: bigint, modulus: bigint): bigint;
|
|
40
|
+
//# sourceMappingURL=buffer-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buffer-utils.d.ts","sourceRoot":"","sources":["../../../../../src/lib/apple-tv/utils/buffer-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAepE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAO3D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,MAAM,CACpB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,MAAM,CAoBR"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a non-negative bigint to a fixed-length Buffer in big-endian format.
|
|
3
|
+
*
|
|
4
|
+
* @param value - The bigint value to convert (must be non-negative).
|
|
5
|
+
* @param length - The target buffer length in bytes.
|
|
6
|
+
* @returns A Buffer representing the bigint, padded to the specified length.
|
|
7
|
+
*
|
|
8
|
+
* @throws {RangeError} If the value is negative or doesn't fit in the specified length.
|
|
9
|
+
*/
|
|
10
|
+
export function bigIntToBuffer(value, length) {
|
|
11
|
+
if (value < 0n) {
|
|
12
|
+
throw new RangeError('Negative values not supported');
|
|
13
|
+
}
|
|
14
|
+
const hex = value.toString(16);
|
|
15
|
+
const byteLength = Math.ceil(hex.length / 2);
|
|
16
|
+
if (byteLength > length) {
|
|
17
|
+
throw new RangeError(`Value 0x${hex} is too large to fit in ${length} bytes`);
|
|
18
|
+
}
|
|
19
|
+
const paddedHex = hex.padStart(length * 2, '0');
|
|
20
|
+
return Buffer.from(paddedHex, 'hex');
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Converts a Buffer into a bigint by interpreting it as a big-endian hexadecimal number.
|
|
24
|
+
*
|
|
25
|
+
* @param buffer - The input Buffer.
|
|
26
|
+
* @returns A bigint representing the numeric value of the buffer.
|
|
27
|
+
*/
|
|
28
|
+
export function bufferToBigInt(buffer) {
|
|
29
|
+
return BigInt('0x' + buffer.toString('hex'));
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Converts a non-negative bigint into a minimal-length Buffer in big-endian format.
|
|
33
|
+
* No unnecessary leading zero bytes will be included.
|
|
34
|
+
*
|
|
35
|
+
* @param value - The bigint value to convert (must be non-negative).
|
|
36
|
+
* @returns A Buffer representing the bigint with minimal byte length.
|
|
37
|
+
*
|
|
38
|
+
* @throws {RangeError} If the value is negative.
|
|
39
|
+
*/
|
|
40
|
+
export function bigIntToMinimalBuffer(value) {
|
|
41
|
+
if (value < 0n) {
|
|
42
|
+
throw new RangeError('Negative values not supported');
|
|
43
|
+
}
|
|
44
|
+
const hex = value.toString(16);
|
|
45
|
+
const paddedHex = hex.length % 2 === 0 ? hex : '0' + hex;
|
|
46
|
+
return Buffer.from(paddedHex, 'hex');
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Computes modular exponentiation: (base ^ exponent) % modulus.
|
|
50
|
+
* Efficiently handles large numbers using the binary exponentiation method.
|
|
51
|
+
*
|
|
52
|
+
* @param base - The base number.
|
|
53
|
+
* @param exponent - The exponent (must be non-negative).
|
|
54
|
+
* @param modulus - The modulus (must be non-zero).
|
|
55
|
+
* @returns The result of (base ** exponent) modulo modulus.
|
|
56
|
+
*
|
|
57
|
+
* @throws {RangeError} If the exponent is negative or the modulus is zero.
|
|
58
|
+
*/
|
|
59
|
+
export function modPow(base, exponent, modulus) {
|
|
60
|
+
if (modulus === 0n) {
|
|
61
|
+
throw new RangeError('Modulus must be non-zero');
|
|
62
|
+
}
|
|
63
|
+
if (exponent < 0n) {
|
|
64
|
+
throw new RangeError('Negative exponents not supported');
|
|
65
|
+
}
|
|
66
|
+
let result = 1n;
|
|
67
|
+
base = base % modulus;
|
|
68
|
+
while (exponent > 0n) {
|
|
69
|
+
if (exponent % 2n === 1n) {
|
|
70
|
+
result = (result * base) % modulus;
|
|
71
|
+
}
|
|
72
|
+
exponent = exponent / 2n;
|
|
73
|
+
base = (base * base) % modulus;
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/lib/apple-tv/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates a deterministic UUIDv3 (MD5-based) from a hostname string.
|
|
3
|
+
* This mimics DNS-based UUID generation using the standard DNS namespace UUID.
|
|
4
|
+
*
|
|
5
|
+
* @param hostname - The host string to be converted to a UUID
|
|
6
|
+
* @returns A UUIDv3 string in uppercase
|
|
7
|
+
*/
|
|
8
|
+
export declare function generateHostId(hostname: string): string;
|
|
9
|
+
//# sourceMappingURL=uuid-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uuid-generator.d.ts","sourceRoot":"","sources":["../../../../../src/lib/apple-tv/utils/uuid-generator.ts"],"names":[],"mappings":"AAKA;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CA8BvD"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
// UUID namespace for DNS, per RFC 4122
|
|
3
|
+
const NAMESPACE_DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
|
|
4
|
+
/**
|
|
5
|
+
* Generates a deterministic UUIDv3 (MD5-based) from a hostname string.
|
|
6
|
+
* This mimics DNS-based UUID generation using the standard DNS namespace UUID.
|
|
7
|
+
*
|
|
8
|
+
* @param hostname - The host string to be converted to a UUID
|
|
9
|
+
* @returns A UUIDv3 string in uppercase
|
|
10
|
+
*/
|
|
11
|
+
export function generateHostId(hostname) {
|
|
12
|
+
if (typeof hostname !== 'string' || hostname.length === 0) {
|
|
13
|
+
throw new TypeError('Hostname must be a non-empty string');
|
|
14
|
+
}
|
|
15
|
+
const namespaceBytes = Buffer.from(NAMESPACE_DNS.replace(/-/g, ''), 'hex');
|
|
16
|
+
// Hash the namespace and the hostname using MD5
|
|
17
|
+
const hash = createHash('md5');
|
|
18
|
+
hash.update(namespaceBytes);
|
|
19
|
+
hash.update(hostname, 'utf8');
|
|
20
|
+
const hashBytes = hash.digest();
|
|
21
|
+
// Set UUID version to 3 (MD5)
|
|
22
|
+
hashBytes[6] = (hashBytes[6] & 0x0f) | 0x30;
|
|
23
|
+
// Set UUID variant to RFC 4122
|
|
24
|
+
hashBytes[8] = (hashBytes[8] & 0x3f) | 0x80;
|
|
25
|
+
// Convert to UUID string format
|
|
26
|
+
const uuid = [
|
|
27
|
+
hashBytes.subarray(0, 4).toString('hex'),
|
|
28
|
+
hashBytes.subarray(4, 6).toString('hex'),
|
|
29
|
+
hashBytes.subarray(6, 8).toString('hex'),
|
|
30
|
+
hashBytes.subarray(8, 10).toString('hex'),
|
|
31
|
+
hashBytes.subarray(10, 16).toString('hex'),
|
|
32
|
+
]
|
|
33
|
+
.join('-')
|
|
34
|
+
.toUpperCase();
|
|
35
|
+
return uuid;
|
|
36
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { Socket } from 'node:net';
|
|
2
|
+
import { type ConnectionOptions, TLSSocket } from 'tls';
|
|
3
|
+
import { BasePlistService } from '../../base-plist-service.js';
|
|
4
|
+
import type { PlistMessage, PlistValue } from '../types.js';
|
|
5
|
+
import { RelayService } from '../usbmux/index.js';
|
|
6
|
+
interface DeviceProperties {
|
|
7
|
+
ConnectionSpeed: number;
|
|
8
|
+
ConnectionType: string;
|
|
9
|
+
DeviceID: number;
|
|
10
|
+
LocationID: number;
|
|
11
|
+
ProductID: number;
|
|
12
|
+
SerialNumber: string;
|
|
13
|
+
USBSerialNumber: string;
|
|
14
|
+
}
|
|
15
|
+
interface Device {
|
|
16
|
+
DeviceID: number;
|
|
17
|
+
MessageType: string;
|
|
18
|
+
Properties: DeviceProperties;
|
|
19
|
+
}
|
|
20
|
+
interface LockdownServiceInfo {
|
|
21
|
+
lockdownService: LockdownService;
|
|
22
|
+
device: Device;
|
|
23
|
+
}
|
|
24
|
+
interface SessionInfo {
|
|
25
|
+
sessionID: string;
|
|
26
|
+
enableSessionSSL: boolean;
|
|
27
|
+
}
|
|
28
|
+
export declare class LockdownService extends BasePlistService {
|
|
29
|
+
private readonly udid;
|
|
30
|
+
private tlsService?;
|
|
31
|
+
private isTLS;
|
|
32
|
+
private tlsUpgradePromise?;
|
|
33
|
+
private _relayService?;
|
|
34
|
+
private readonly tlsManager;
|
|
35
|
+
private readonly deviceManager;
|
|
36
|
+
constructor(socket: Socket, udid: string, autoSecure?: boolean);
|
|
37
|
+
/**
|
|
38
|
+
* Starts a lockdown session
|
|
39
|
+
*/
|
|
40
|
+
startSession(hostID: string, systemBUID: string, timeout?: number): Promise<SessionInfo>;
|
|
41
|
+
/**
|
|
42
|
+
* Attempts to upgrade the connection to TLS
|
|
43
|
+
*/
|
|
44
|
+
tryUpgradeToTLS(): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Gets the current socket (TLS or regular)
|
|
47
|
+
*/
|
|
48
|
+
getSocket(): Socket | TLSSocket;
|
|
49
|
+
/**
|
|
50
|
+
* Sends a message and receives a response
|
|
51
|
+
*/
|
|
52
|
+
sendAndReceive(msg: Record<string, PlistValue>, timeout?: number): Promise<PlistMessage>;
|
|
53
|
+
/**
|
|
54
|
+
* Closes the service and associated resources
|
|
55
|
+
*/
|
|
56
|
+
close(): void;
|
|
57
|
+
/**
|
|
58
|
+
* Sets the relay service for this lockdown instance
|
|
59
|
+
*/
|
|
60
|
+
set relayService(relay: RelayService);
|
|
61
|
+
/**
|
|
62
|
+
* Gets the relay service for this lockdown instance
|
|
63
|
+
*/
|
|
64
|
+
get relayService(): RelayService | undefined;
|
|
65
|
+
/**
|
|
66
|
+
* Waits for TLS upgrade to complete if in progress
|
|
67
|
+
*/
|
|
68
|
+
waitForTLSUpgrade(): Promise<void>;
|
|
69
|
+
/**
|
|
70
|
+
* Stops the relay service with an optional custom message
|
|
71
|
+
*/
|
|
72
|
+
stopRelayService(message?: string): void;
|
|
73
|
+
private validatePairRecord;
|
|
74
|
+
private performTLSUpgrade;
|
|
75
|
+
private closeSocket;
|
|
76
|
+
}
|
|
77
|
+
export declare class LockdownServiceFactory {
|
|
78
|
+
private readonly deviceManager;
|
|
79
|
+
/**
|
|
80
|
+
* Creates a LockdownService for a specific device UDID
|
|
81
|
+
*/
|
|
82
|
+
createByUDID(udid: string, port?: number, autoSecure?: boolean): Promise<LockdownServiceInfo>;
|
|
83
|
+
}
|
|
84
|
+
export declare function createLockdownServiceByUDID(udid: string, port?: number, autoSecure?: boolean): Promise<LockdownServiceInfo>;
|
|
85
|
+
export declare function upgradeSocketToTLS(socket: Socket, tlsOptions?: Partial<ConnectionOptions>): Promise<TLSSocket>;
|
|
86
|
+
export {};
|
|
87
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/lockdown/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
import { logger } from '@appium/support';
|
|
2
|
+
import { Socket } from 'node:net';
|
|
3
|
+
import tls, { TLSSocket } from 'tls';
|
|
4
|
+
import { BasePlistService } from '../../base-plist-service.js';
|
|
5
|
+
import {} from '../pair-record/index.js';
|
|
6
|
+
import { PlistService } from '../plist/plist-service.js';
|
|
7
|
+
import { RelayService, createUsbmux } from '../usbmux/index.js';
|
|
8
|
+
const log = logger.getLogger('Lockdown');
|
|
9
|
+
// Constants
|
|
10
|
+
const LABEL = 'appium-internal';
|
|
11
|
+
const DEFAULT_TIMEOUT = 5000;
|
|
12
|
+
const DEFAULT_LOCKDOWN_PORT = 62078;
|
|
13
|
+
const DEFAULT_RELAY_PORT = 2222;
|
|
14
|
+
// Error classes for better error handling
|
|
15
|
+
class LockdownError extends Error {
|
|
16
|
+
constructor(message) {
|
|
17
|
+
super(message);
|
|
18
|
+
this.name = 'LockdownError';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
class TLSUpgradeError extends Error {
|
|
22
|
+
constructor(message) {
|
|
23
|
+
super(message);
|
|
24
|
+
this.name = 'TLSUpgradeError';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
class DeviceNotFoundError extends Error {
|
|
28
|
+
constructor(udid) {
|
|
29
|
+
super(`Device with UDID ${udid} not found`);
|
|
30
|
+
this.name = 'DeviceNotFoundError';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// TLS Manager for handling TLS operations
|
|
34
|
+
class TLSManager {
|
|
35
|
+
log = logger.getLogger('TLSManager');
|
|
36
|
+
/**
|
|
37
|
+
* Upgrades a socket to TLS
|
|
38
|
+
*/
|
|
39
|
+
async upgradeSocketToTLS(socket, tlsOptions = {}) {
|
|
40
|
+
return new Promise((resolve, reject) => {
|
|
41
|
+
socket.pause();
|
|
42
|
+
this.log.debug('Upgrading socket to TLS...');
|
|
43
|
+
const secure = tls.connect({
|
|
44
|
+
socket,
|
|
45
|
+
rejectUnauthorized: false,
|
|
46
|
+
minVersion: 'TLSv1.2',
|
|
47
|
+
...tlsOptions,
|
|
48
|
+
}, () => {
|
|
49
|
+
this.log.info('TLS handshake completed');
|
|
50
|
+
resolve(secure);
|
|
51
|
+
});
|
|
52
|
+
secure.on('error', (err) => {
|
|
53
|
+
this.log.error(`TLS socket error: ${err}`);
|
|
54
|
+
reject(new TLSUpgradeError(`TLS socket error: ${err.message}`));
|
|
55
|
+
});
|
|
56
|
+
socket.on('error', (err) => {
|
|
57
|
+
this.log.error(`Underlying socket error during TLS: ${err}`);
|
|
58
|
+
reject(new TLSUpgradeError(`Socket error during TLS: ${err.message}`));
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Device Manager for handling device operations
|
|
64
|
+
class DeviceManager {
|
|
65
|
+
log = logger.getLogger('DeviceManager');
|
|
66
|
+
/**
|
|
67
|
+
* Lists all connected devices
|
|
68
|
+
*/
|
|
69
|
+
async listDevices() {
|
|
70
|
+
const usbmux = await createUsbmux();
|
|
71
|
+
try {
|
|
72
|
+
this.log.debug('Listing connected devices...');
|
|
73
|
+
const devices = await usbmux.listDevices();
|
|
74
|
+
this.log.debug(`Found ${devices.length} devices: ${devices.map((d) => d.Properties.SerialNumber).join(', ')}`);
|
|
75
|
+
return devices;
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
await this.closeUsbmux(usbmux);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Finds a device by UDID
|
|
83
|
+
*/
|
|
84
|
+
async findDeviceByUDID(udid) {
|
|
85
|
+
const devices = await this.listDevices();
|
|
86
|
+
if (!devices || devices.length === 0) {
|
|
87
|
+
throw new LockdownError('No devices connected');
|
|
88
|
+
}
|
|
89
|
+
const device = devices.find((d) => d.Properties.SerialNumber === udid);
|
|
90
|
+
if (!device) {
|
|
91
|
+
throw new DeviceNotFoundError(udid);
|
|
92
|
+
}
|
|
93
|
+
this.log.info(`Found device: DeviceID=${device.DeviceID}, SerialNumber=${device.Properties.SerialNumber}, ConnectionType=${device.Properties.ConnectionType}`);
|
|
94
|
+
return device;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Reads pair record for a device
|
|
98
|
+
*/
|
|
99
|
+
async readPairRecord(udid) {
|
|
100
|
+
this.log.debug(`Retrieving pair record for UDID: ${udid}`);
|
|
101
|
+
const usbmux = await createUsbmux();
|
|
102
|
+
try {
|
|
103
|
+
const record = await usbmux.readPairRecord(udid);
|
|
104
|
+
if (!record?.HostCertificate || !record.HostPrivateKey) {
|
|
105
|
+
throw new LockdownError('Pair record missing certificate or key');
|
|
106
|
+
}
|
|
107
|
+
this.log.info('Pair record retrieved successfully');
|
|
108
|
+
return record;
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
this.log.error(`Error getting pair record: ${err}`);
|
|
112
|
+
throw err;
|
|
113
|
+
}
|
|
114
|
+
finally {
|
|
115
|
+
await this.closeUsbmux(usbmux);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async closeUsbmux(usbmux) {
|
|
119
|
+
try {
|
|
120
|
+
await usbmux.close();
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
this.log.error(`Error closing usbmux: ${err}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Main LockdownService class
|
|
128
|
+
export class LockdownService extends BasePlistService {
|
|
129
|
+
udid;
|
|
130
|
+
tlsService;
|
|
131
|
+
isTLS = false;
|
|
132
|
+
tlsUpgradePromise;
|
|
133
|
+
_relayService;
|
|
134
|
+
tlsManager = new TLSManager();
|
|
135
|
+
deviceManager = new DeviceManager();
|
|
136
|
+
constructor(socket, udid, autoSecure = true) {
|
|
137
|
+
super(socket);
|
|
138
|
+
this.udid = udid;
|
|
139
|
+
log.info(`LockdownService initialized for UDID: ${udid}`);
|
|
140
|
+
if (autoSecure) {
|
|
141
|
+
this.tlsUpgradePromise = this.tryUpgradeToTLS().catch((err) => log.warn(`Auto TLS upgrade failed: ${err.message}`));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Starts a lockdown session
|
|
146
|
+
*/
|
|
147
|
+
async startSession(hostID, systemBUID, timeout = DEFAULT_TIMEOUT) {
|
|
148
|
+
log.debug(`Starting lockdown session with HostID: ${hostID}`);
|
|
149
|
+
const request = {
|
|
150
|
+
Label: LABEL,
|
|
151
|
+
Request: 'StartSession',
|
|
152
|
+
HostID: hostID,
|
|
153
|
+
SystemBUID: systemBUID,
|
|
154
|
+
};
|
|
155
|
+
const response = (await this.sendAndReceive(request, timeout));
|
|
156
|
+
if (response.Request === 'StartSession' && response.SessionID) {
|
|
157
|
+
const sessionInfo = {
|
|
158
|
+
sessionID: String(response.SessionID),
|
|
159
|
+
enableSessionSSL: Boolean(response.EnableSessionSSL),
|
|
160
|
+
};
|
|
161
|
+
log.info(`Lockdown session started, SessionID: ${sessionInfo.sessionID}`);
|
|
162
|
+
return sessionInfo;
|
|
163
|
+
}
|
|
164
|
+
throw new LockdownError(`Unexpected session data: ${JSON.stringify(response)}`);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Attempts to upgrade the connection to TLS
|
|
168
|
+
*/
|
|
169
|
+
async tryUpgradeToTLS() {
|
|
170
|
+
try {
|
|
171
|
+
const pairRecord = await this.deviceManager.readPairRecord(this.udid);
|
|
172
|
+
if (!this.validatePairRecord(pairRecord)) {
|
|
173
|
+
log.warn('Invalid pair record for TLS upgrade');
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
const sessionInfo = await this.startSession(pairRecord.HostID, pairRecord.SystemBUID);
|
|
177
|
+
if (!sessionInfo.enableSessionSSL) {
|
|
178
|
+
log.info('Device did not request TLS upgrade. Continuing unencrypted.');
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
await this.performTLSUpgrade(pairRecord);
|
|
182
|
+
}
|
|
183
|
+
catch (err) {
|
|
184
|
+
log.error(`TLS upgrade failed: ${err}`);
|
|
185
|
+
throw err;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Gets the current socket (TLS or regular)
|
|
190
|
+
*/
|
|
191
|
+
getSocket() {
|
|
192
|
+
return this.isTLS && this.tlsService
|
|
193
|
+
? this.tlsService.getSocket()
|
|
194
|
+
: this.getPlistService().getSocket();
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Sends a message and receives a response
|
|
198
|
+
*/
|
|
199
|
+
async sendAndReceive(msg, timeout = DEFAULT_TIMEOUT) {
|
|
200
|
+
const service = this.isTLS && this.tlsService ? this.tlsService : this._plistService;
|
|
201
|
+
return service.sendPlistAndReceive(msg, timeout);
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Closes the service and associated resources
|
|
205
|
+
*/
|
|
206
|
+
close() {
|
|
207
|
+
log.info('Closing LockdownService connections');
|
|
208
|
+
try {
|
|
209
|
+
this.closeSocket();
|
|
210
|
+
this.stopRelayService();
|
|
211
|
+
}
|
|
212
|
+
catch (err) {
|
|
213
|
+
log.error(`Error during close: ${err}`);
|
|
214
|
+
throw err;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Sets the relay service for this lockdown instance
|
|
219
|
+
*/
|
|
220
|
+
set relayService(relay) {
|
|
221
|
+
this._relayService = relay;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Gets the relay service for this lockdown instance
|
|
225
|
+
*/
|
|
226
|
+
get relayService() {
|
|
227
|
+
return this._relayService;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Waits for TLS upgrade to complete if in progress
|
|
231
|
+
*/
|
|
232
|
+
async waitForTLSUpgrade() {
|
|
233
|
+
if (this.tlsUpgradePromise) {
|
|
234
|
+
await this.tlsUpgradePromise;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Stops the relay service with an optional custom message
|
|
239
|
+
*/
|
|
240
|
+
stopRelayService(message = 'Stopping relay server associated with LockdownService') {
|
|
241
|
+
const relay = this.relayService;
|
|
242
|
+
if (relay) {
|
|
243
|
+
log.info(message);
|
|
244
|
+
(async () => {
|
|
245
|
+
try {
|
|
246
|
+
await relay.stop();
|
|
247
|
+
log.info('Relay server stopped successfully');
|
|
248
|
+
}
|
|
249
|
+
catch (err) {
|
|
250
|
+
log.error(`Error stopping relay server: ${err}`);
|
|
251
|
+
}
|
|
252
|
+
})();
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
validatePairRecord(record) {
|
|
256
|
+
return Boolean(record?.HostCertificate &&
|
|
257
|
+
record.HostPrivateKey &&
|
|
258
|
+
record.HostID &&
|
|
259
|
+
record.SystemBUID);
|
|
260
|
+
}
|
|
261
|
+
async performTLSUpgrade(pairRecord) {
|
|
262
|
+
const tlsConfig = {
|
|
263
|
+
cert: pairRecord.HostCertificate,
|
|
264
|
+
key: pairRecord.HostPrivateKey,
|
|
265
|
+
};
|
|
266
|
+
const tlsSocket = await this.tlsManager.upgradeSocketToTLS(this.getSocket(), tlsConfig);
|
|
267
|
+
this.tlsService = new PlistService(tlsSocket);
|
|
268
|
+
this.isTLS = true;
|
|
269
|
+
log.info('Successfully upgraded connection to TLS');
|
|
270
|
+
}
|
|
271
|
+
closeSocket() {
|
|
272
|
+
if (this.isTLS && this.tlsService) {
|
|
273
|
+
this.tlsService.close();
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
super.close();
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
// Factory class for creating LockdownService instances
|
|
281
|
+
export class LockdownServiceFactory {
|
|
282
|
+
deviceManager = new DeviceManager();
|
|
283
|
+
/**
|
|
284
|
+
* Creates a LockdownService for a specific device UDID
|
|
285
|
+
*/
|
|
286
|
+
async createByUDID(udid, port = DEFAULT_LOCKDOWN_PORT, autoSecure = true) {
|
|
287
|
+
log.info(`Creating LockdownService for UDID: ${udid}`);
|
|
288
|
+
// Find the device
|
|
289
|
+
const device = await this.deviceManager.findDeviceByUDID(udid);
|
|
290
|
+
// Create relay service
|
|
291
|
+
const relay = new RelayService(device.DeviceID, port, DEFAULT_RELAY_PORT);
|
|
292
|
+
await relay.start();
|
|
293
|
+
let service;
|
|
294
|
+
try {
|
|
295
|
+
// Connect through the relay
|
|
296
|
+
const socket = await relay.connect();
|
|
297
|
+
log.debug('Socket connected, creating LockdownService');
|
|
298
|
+
// Create the lockdown service
|
|
299
|
+
service = new LockdownService(socket, udid, autoSecure);
|
|
300
|
+
service.relayService = relay;
|
|
301
|
+
// Wait for TLS upgrade if enabled
|
|
302
|
+
if (autoSecure) {
|
|
303
|
+
log.debug('Waiting for TLS upgrade to complete...');
|
|
304
|
+
await service.waitForTLSUpgrade();
|
|
305
|
+
}
|
|
306
|
+
return { lockdownService: service, device };
|
|
307
|
+
}
|
|
308
|
+
catch (err) {
|
|
309
|
+
// Clean up relay on error
|
|
310
|
+
service?.stopRelayService('Stopping relay after failure');
|
|
311
|
+
throw err;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
// Export factory function for backward compatibility
|
|
316
|
+
export async function createLockdownServiceByUDID(udid, port = DEFAULT_LOCKDOWN_PORT, autoSecure = true) {
|
|
317
|
+
const factory = new LockdownServiceFactory();
|
|
318
|
+
return factory.createByUDID(udid, port, autoSecure);
|
|
319
|
+
}
|
|
320
|
+
// Export the TLS upgrade function for external use
|
|
321
|
+
export function upgradeSocketToTLS(socket, tlsOptions = {}) {
|
|
322
|
+
const tlsManager = new TLSManager();
|
|
323
|
+
return tlsManager.upgradeSocketToTLS(socket, tlsOptions);
|
|
324
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/pair-record/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,UAAU,EACf,aAAa,EACb,oBAAoB,EACpB,cAAc,EACf,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,cAAc,EAAE,KAAK,UAAU,EAAE,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface defining the structure of a pair record.
|
|
3
|
+
*/
|
|
4
|
+
export interface PairRecord {
|
|
5
|
+
HostID: string | null;
|
|
6
|
+
SystemBUID: string | null;
|
|
7
|
+
HostCertificate: string | null;
|
|
8
|
+
HostPrivateKey: string | null;
|
|
9
|
+
DeviceCertificate: string | null;
|
|
10
|
+
RootCertificate: string | null;
|
|
11
|
+
RootPrivateKey: string | null;
|
|
12
|
+
WiFiMACAddress: string | null;
|
|
13
|
+
EscrowBag: string | null;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Interface for the raw response from plist.parsePlist
|
|
17
|
+
*/
|
|
18
|
+
export interface RawPairRecordResponse {
|
|
19
|
+
HostID: string;
|
|
20
|
+
SystemBUID: string;
|
|
21
|
+
HostCertificate: Buffer;
|
|
22
|
+
HostPrivateKey: Buffer;
|
|
23
|
+
DeviceCertificate: Buffer;
|
|
24
|
+
RootCertificate: Buffer;
|
|
25
|
+
RootPrivateKey: Buffer;
|
|
26
|
+
WiFiMACAddress: string;
|
|
27
|
+
EscrowBag: Buffer;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Processes raw response from plist.parsePlist and formats it into a proper pair-record
|
|
31
|
+
* @param response - Response from plist.parsePlist(data.payload.PairRecordData)
|
|
32
|
+
* @returns Formatted pair-record object with properly structured data
|
|
33
|
+
*/
|
|
34
|
+
export declare function processPlistResponse(response: RawPairRecordResponse): PairRecord;
|
|
35
|
+
/**
|
|
36
|
+
* Saves a pair record to the filesystem.
|
|
37
|
+
* @param udid - Device UDID.
|
|
38
|
+
* @param pairRecord - Pair record to save.
|
|
39
|
+
* @returns Promise that resolves when record is saved.
|
|
40
|
+
*/
|
|
41
|
+
export declare function savePairRecord(udid: string, pairRecord: PairRecord): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Gets a saved pair record from the filesystem.
|
|
44
|
+
* @param udid - Device UDID.
|
|
45
|
+
* @returns Promise that resolves with the pair record or null if not found.
|
|
46
|
+
*/
|
|
47
|
+
export declare function getPairRecord(udid: string): Promise<PairRecord | null>;
|
|
48
|
+
//# sourceMappingURL=pair-record.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pair-record.d.ts","sourceRoot":"","sources":["../../../../src/lib/pair-record/pair-record.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAWD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,qBAAqB,GAC9B,UAAU,CAyBZ;AAUD;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,IAAI,CAAC,CAef;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAc5E"}
|