@mcesystems/apple-kit 1.0.96 → 1.0.97
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +90 -64
- package/dist/index.js.map +2 -2
- package/dist/index.mjs +90 -64
- package/dist/index.mjs.map +2 -2
- package/dist/types/index.d.ts +13 -35
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -38620,31 +38620,34 @@ function escapeXml(str) {
|
|
|
38620
38620
|
var { logInfo: logInfo5 } = createLoggers("apple-kit:wifi-profile");
|
|
38621
38621
|
async function generateWifiProfile(config, options) {
|
|
38622
38622
|
const {
|
|
38623
|
-
ssid,
|
|
38624
38623
|
encryptionType,
|
|
38625
38624
|
password,
|
|
38626
38625
|
autoJoin = true,
|
|
38627
38626
|
organizationName = "MCE Systems",
|
|
38628
|
-
displayName = `WiFi - ${ssid}`,
|
|
38629
38627
|
enterprise = false,
|
|
38630
38628
|
username,
|
|
38631
38629
|
acceptAnyCertificate = true
|
|
38632
38630
|
} = config;
|
|
38631
|
+
const resolvedSsid = config.ssid ?? process.env.WIFI_SSID ?? "";
|
|
38632
|
+
if (!resolvedSsid) {
|
|
38633
|
+
throw new Error("WiFi SSID is required. Set config.ssid or WIFI_SSID environment variable.");
|
|
38634
|
+
}
|
|
38633
38635
|
const profileUuid = (0, import_node_crypto2.randomUUID)().toUpperCase();
|
|
38634
38636
|
const payloadUuid = (0, import_node_crypto2.randomUUID)().toUpperCase();
|
|
38635
|
-
const profileId = `com.mce.wifi.${
|
|
38637
|
+
const profileId = `com.mce.wifi.${resolvedSsid.replace(/[^a-zA-Z0-9]/g, "")}.${Date.now()}`;
|
|
38636
38638
|
const payloadId = `${profileId}.payload`;
|
|
38637
|
-
|
|
38639
|
+
const displayNameToUse = config.displayName ?? `WiFi - ${resolvedSsid}`;
|
|
38640
|
+
logInfo5(`Generating WiFi profile for SSID: ${resolvedSsid}, encryption: ${encryptionType}`);
|
|
38638
38641
|
const templateName = enterprise ? "wifi-enterprise.xml" : "wifi-standard.xml";
|
|
38639
38642
|
const template = await loadTemplate(templateName, options?.plistDir);
|
|
38640
38643
|
const variables = {
|
|
38641
|
-
ssid:
|
|
38644
|
+
ssid: resolvedSsid,
|
|
38642
38645
|
password: config.password ?? process.env.WIFI_PASSWORD,
|
|
38643
38646
|
encryptionType: parseWifiEncryptionType(config.encryptionType ?? process.env.WIFI_ENCRYPTION),
|
|
38644
38647
|
autoJoin: autoJoin ? "true" : "false",
|
|
38645
38648
|
hiddenNetwork: config.hiddenNetwork ?? process.env.WIFI_HIDDEN === "true",
|
|
38646
38649
|
organizationName,
|
|
38647
|
-
displayName,
|
|
38650
|
+
displayName: displayNameToUse,
|
|
38648
38651
|
profileId,
|
|
38649
38652
|
profileUuid,
|
|
38650
38653
|
payloadId,
|
|
@@ -38739,10 +38742,9 @@ function isAbortError(error) {
|
|
|
38739
38742
|
return error instanceof DOMException && error.name === "AbortError";
|
|
38740
38743
|
}
|
|
38741
38744
|
var ActivationFlow = class {
|
|
38742
|
-
constructor(udid, iosClient
|
|
38745
|
+
constructor(udid, iosClient) {
|
|
38743
38746
|
this.udid = udid;
|
|
38744
38747
|
this.iosClient = iosClient;
|
|
38745
|
-
this.deviceActions = deviceActions;
|
|
38746
38748
|
setNamespace4(`${udid}`);
|
|
38747
38749
|
}
|
|
38748
38750
|
mdmClient;
|
|
@@ -38778,14 +38780,6 @@ var ActivationFlow = class {
|
|
|
38778
38780
|
signal
|
|
38779
38781
|
);
|
|
38780
38782
|
throwIfAborted2(signal);
|
|
38781
|
-
const expectedSsid = config.wifiProfileConfig?.ssid;
|
|
38782
|
-
if (expectedSsid) {
|
|
38783
|
-
if (await this.deviceActions.isWifiConnected(15e3) !== expectedSsid) {
|
|
38784
|
-
throw new Error(
|
|
38785
|
-
`WiFi profile not installed correctly, expected ${expectedSsid} but got ${await this.deviceActions.isWifiConnected(15e3)}`
|
|
38786
|
-
);
|
|
38787
|
-
}
|
|
38788
|
-
}
|
|
38789
38783
|
await this.installMdmProfile(events, signal);
|
|
38790
38784
|
throwIfAborted2(signal);
|
|
38791
38785
|
}
|
|
@@ -39189,45 +39183,59 @@ var IosClient = class {
|
|
|
39189
39183
|
return this.runIosCommand(["devmode", "enable", "--udid", this.udid]);
|
|
39190
39184
|
}
|
|
39191
39185
|
async tunnelStart(userspace = false, pairRecordPath) {
|
|
39192
|
-
|
|
39193
|
-
|
|
39194
|
-
|
|
39195
|
-
|
|
39196
|
-
|
|
39197
|
-
|
|
39198
|
-
|
|
39199
|
-
|
|
39200
|
-
|
|
39186
|
+
return new Promise((resolve2, reject) => {
|
|
39187
|
+
const args = [
|
|
39188
|
+
"tunnel",
|
|
39189
|
+
"start",
|
|
39190
|
+
`--pair-record-path=${pairRecordPath ?? "default"}`,
|
|
39191
|
+
"--udid",
|
|
39192
|
+
this.udid,
|
|
39193
|
+
...userspace ? ["--userspace"] : []
|
|
39194
|
+
];
|
|
39195
|
+
logDetail(`Spawning tunnel: ${this.iosPath} ${args.join(" ")}`);
|
|
39196
|
+
const child = (0, import_node_child_process.spawn)(this.iosPath, args, {
|
|
39197
|
+
windowsHide: true,
|
|
39198
|
+
env: {
|
|
39199
|
+
...process.env,
|
|
39200
|
+
USBMUXD_SOCKET_ADDRESS: this.usbmuxdAddress
|
|
39201
|
+
},
|
|
39202
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
39203
|
+
});
|
|
39204
|
+
let settled = false;
|
|
39205
|
+
const cleanup = () => {
|
|
39206
|
+
child.off("error", onError);
|
|
39207
|
+
child.off("exit", onExit);
|
|
39208
|
+
child.stdout?.off("data", onReadyCheck);
|
|
39209
|
+
child.stderr?.off("data", onReadyCheck);
|
|
39210
|
+
clearTimeout(readyTimeout);
|
|
39211
|
+
};
|
|
39212
|
+
const finish = (result) => {
|
|
39213
|
+
if (settled) {
|
|
39214
|
+
return;
|
|
39215
|
+
}
|
|
39216
|
+
settled = true;
|
|
39217
|
+
cleanup();
|
|
39218
|
+
if (result.reject) {
|
|
39219
|
+
reject(result.reject);
|
|
39220
|
+
return;
|
|
39221
|
+
}
|
|
39222
|
+
if (result.resolve !== void 0) {
|
|
39223
|
+
resolve2(result.resolve);
|
|
39224
|
+
}
|
|
39225
|
+
};
|
|
39226
|
+
const onError = (err) => finish({ reject: err });
|
|
39227
|
+
const onExit = (code) => finish({ reject: new Error(`Tunnel exited early (code=${code})`) });
|
|
39228
|
+
const onReadyCheck = (data) => {
|
|
39229
|
+
const line = data.toString();
|
|
39230
|
+
const isReady = line.includes("Tunnel server started") || line.includes("tunnel") && (line.includes("listening") || line.includes("connected"));
|
|
39231
|
+
if (isReady) finish({ resolve: child });
|
|
39232
|
+
};
|
|
39233
|
+
const readyTimeout = setTimeout(() => finish({ resolve: child }), 1e4);
|
|
39234
|
+
child.once("error", onError);
|
|
39235
|
+
child.once("exit", onExit);
|
|
39236
|
+
child.stdout?.on("data", onReadyCheck);
|
|
39237
|
+
child.stderr?.on("data", onReadyCheck);
|
|
39201
39238
|
});
|
|
39202
|
-
let settled = false;
|
|
39203
|
-
const cleanup = () => {
|
|
39204
|
-
child.off("error", onError);
|
|
39205
|
-
child.off("exit", onExit);
|
|
39206
|
-
child.stdout?.off("data", onReadyCheck);
|
|
39207
|
-
child.stderr?.off("data", onReadyCheck);
|
|
39208
|
-
clearTimeout(readyTimeout);
|
|
39209
|
-
};
|
|
39210
|
-
const finish = (result) => {
|
|
39211
|
-
if (settled) return;
|
|
39212
|
-
settled = true;
|
|
39213
|
-
cleanup();
|
|
39214
|
-
if (result.reject) throw result.reject;
|
|
39215
|
-
if (result.resolve !== void 0) return result.resolve;
|
|
39216
|
-
throw new Error("Tunnel process not found");
|
|
39217
|
-
};
|
|
39218
|
-
const onError = (err) => finish({ reject: err });
|
|
39219
|
-
const onExit = (code) => finish({ reject: new Error(`Tunnel exited early (code=${code})`) });
|
|
39220
|
-
const onReadyCheck = (data) => {
|
|
39221
|
-
const line = data.toString();
|
|
39222
|
-
const isReady = line.includes("Tunnel server started") || line.includes("tunnel") && (line.includes("listening") || line.includes("connected"));
|
|
39223
|
-
if (isReady) finish({ resolve: child });
|
|
39224
|
-
};
|
|
39225
|
-
const readyTimeout = setTimeout(() => finish({ resolve: child }), 1e4);
|
|
39226
|
-
child.once("error", onError);
|
|
39227
|
-
child.once("exit", onExit);
|
|
39228
|
-
child.stdout?.on("data", onReadyCheck);
|
|
39229
|
-
child.stderr?.on("data", onReadyCheck);
|
|
39230
|
-
return child;
|
|
39231
39239
|
}
|
|
39232
39240
|
async fsyncPull({
|
|
39233
39241
|
app,
|
|
@@ -39349,9 +39357,9 @@ var AppleDeviceKit = class _AppleDeviceKit {
|
|
|
39349
39357
|
this.iosClient = new IosClient(iosBinaryPath, udid, usbmuxdAddress);
|
|
39350
39358
|
this.deviceActions = new DeviceActions(this.deviceId, this.iosClient);
|
|
39351
39359
|
this.installActions = new InstallActions(this.deviceId, this.iosClient);
|
|
39352
|
-
this.activationFlow = new ActivationFlow(this.deviceId, this.iosClient
|
|
39360
|
+
this.activationFlow = new ActivationFlow(this.deviceId, this.iosClient);
|
|
39353
39361
|
this.proxyActions = new ProxyActions(this.deviceId, this.iosClient);
|
|
39354
|
-
this.
|
|
39362
|
+
this.getTunnelReady();
|
|
39355
39363
|
}
|
|
39356
39364
|
deviceId;
|
|
39357
39365
|
proxyProcess = null;
|
|
@@ -39363,7 +39371,18 @@ var AppleDeviceKit = class _AppleDeviceKit {
|
|
|
39363
39371
|
activationFlow;
|
|
39364
39372
|
proxyActions;
|
|
39365
39373
|
tunnelProcess = null;
|
|
39374
|
+
tunnelReadyPromise = null;
|
|
39366
39375
|
static IOS_17_VERSION = 17;
|
|
39376
|
+
/**
|
|
39377
|
+
* Returns a promise that resolves when the tunnel is ready (or immediately if not needed).
|
|
39378
|
+
* Reuses the same in-flight promise so constructor and methods don't race.
|
|
39379
|
+
*/
|
|
39380
|
+
getTunnelReady() {
|
|
39381
|
+
if (!this.tunnelReadyPromise) {
|
|
39382
|
+
this.tunnelReadyPromise = this.runEnsureTunnel();
|
|
39383
|
+
}
|
|
39384
|
+
return this.tunnelReadyPromise;
|
|
39385
|
+
}
|
|
39367
39386
|
/**
|
|
39368
39387
|
* Check if iOS version requires tunneling (iOS 17+)
|
|
39369
39388
|
*/
|
|
@@ -39381,9 +39400,15 @@ var AppleDeviceKit = class _AppleDeviceKit {
|
|
|
39381
39400
|
}
|
|
39382
39401
|
}
|
|
39383
39402
|
/**
|
|
39384
|
-
* Ensure tunnel is started for iOS 17+ devices
|
|
39403
|
+
* Ensure tunnel is started for iOS 17+ devices. Safe to call multiple times; reuses in-flight setup.
|
|
39385
39404
|
*/
|
|
39386
39405
|
async ensureTunnel() {
|
|
39406
|
+
await this.getTunnelReady();
|
|
39407
|
+
}
|
|
39408
|
+
/**
|
|
39409
|
+
* Internal tunnel startup. Called once per tunnel lifecycle; getTunnelReady() caches this promise.
|
|
39410
|
+
*/
|
|
39411
|
+
async runEnsureTunnel() {
|
|
39387
39412
|
const requiresTunnel = await this.requiresTunneling();
|
|
39388
39413
|
if (!requiresTunnel) {
|
|
39389
39414
|
logDetail2(`Device ${this.deviceId} does not require tunneling (iOS < 17)`);
|
|
@@ -39396,21 +39421,28 @@ var AppleDeviceKit = class _AppleDeviceKit {
|
|
|
39396
39421
|
}
|
|
39397
39422
|
logInfo7(`Starting tunnel for device ${this.deviceId} (iOS 17+)`);
|
|
39398
39423
|
try {
|
|
39399
|
-
const pairRecordPath = (0, import_node_path5.join)(
|
|
39424
|
+
const pairRecordPath = (0, import_node_path5.join)(
|
|
39425
|
+
this.deviceActions.getLockdownPath() ?? "",
|
|
39426
|
+
"RemotePairing",
|
|
39427
|
+
`${this.deviceId}`
|
|
39428
|
+
);
|
|
39400
39429
|
await (0, import_promises3.mkdir)(pairRecordPath, { recursive: true });
|
|
39401
39430
|
const tunnelProcess = await this.iosClient.tunnelStart(true, pairRecordPath);
|
|
39402
39431
|
this.tunnelProcess = tunnelProcess;
|
|
39403
39432
|
tunnelProcess.on("exit", (code) => {
|
|
39404
39433
|
logError3(`Tunnel process for device ${this.deviceId} exited with code ${code}`);
|
|
39405
39434
|
this.tunnelProcess = null;
|
|
39435
|
+
this.tunnelReadyPromise = null;
|
|
39406
39436
|
});
|
|
39407
39437
|
tunnelProcess.on("error", (error) => {
|
|
39408
39438
|
logError3(`Tunnel process error for device ${this.deviceId}: ${error.message}`);
|
|
39409
39439
|
this.tunnelProcess = null;
|
|
39440
|
+
this.tunnelReadyPromise = null;
|
|
39410
39441
|
});
|
|
39411
39442
|
await new Promise((resolve2) => setTimeout(resolve2, 1e3));
|
|
39412
39443
|
logInfo7(`Tunnel started successfully for device ${this.deviceId}`);
|
|
39413
39444
|
} catch (error) {
|
|
39445
|
+
this.tunnelReadyPromise = null;
|
|
39414
39446
|
logError3(
|
|
39415
39447
|
`Failed to start tunnel for device ${this.deviceId}: ${error instanceof Error ? error.message : String(error)}`
|
|
39416
39448
|
);
|
|
@@ -39648,9 +39680,6 @@ var AppleDeviceKit = class _AppleDeviceKit {
|
|
|
39648
39680
|
}
|
|
39649
39681
|
logInfo7(`File ${fileName} pushed to device ${this.deviceId}`);
|
|
39650
39682
|
} finally {
|
|
39651
|
-
if (requiresTunnel) {
|
|
39652
|
-
this.stopTunnel();
|
|
39653
|
-
}
|
|
39654
39683
|
try {
|
|
39655
39684
|
(0, import_node_fs5.unlinkSync)(tmpFilePath);
|
|
39656
39685
|
} catch (_error) {
|
|
@@ -39687,9 +39716,6 @@ var AppleDeviceKit = class _AppleDeviceKit {
|
|
|
39687
39716
|
logInfo7(`File ${fileName} pulled from device ${this.deviceId}`);
|
|
39688
39717
|
return fileData;
|
|
39689
39718
|
} finally {
|
|
39690
|
-
if (requiresTunnel) {
|
|
39691
|
-
this.stopTunnel();
|
|
39692
|
-
}
|
|
39693
39719
|
try {
|
|
39694
39720
|
(0, import_node_fs5.unlinkSync)(tmpFilePath);
|
|
39695
39721
|
} catch (_error) {
|