Skip to content

Commit

Permalink
Add supervision capability
Browse files Browse the repository at this point in the history
  • Loading branch information
zner0L committed Jun 1, 2023
1 parent 2477fb1 commit c50562a
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 21 deletions.
26 changes: 13 additions & 13 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ A supported attribute for the `getDeviceAttribute()` function, depending on the

#### Defined in

[index.ts:394](https://github.com/tweaselORG/appstraction/blob/main/src/index.ts#L394)
[index.ts:406](https://github.com/tweaselORG/appstraction/blob/main/src/index.ts#L406)

___

Expand All @@ -100,7 +100,7 @@ The options for each attribute available through the `getDeviceAttribute()` func

#### Defined in

[index.ts:400](https://github.com/tweaselORG/appstraction/blob/main/src/index.ts#L400)
[index.ts:412](https://github.com/tweaselORG/appstraction/blob/main/src/index.ts#L412)

___

Expand All @@ -112,7 +112,7 @@ An ID of a known permission on iOS.

#### Defined in

[ios.ts:508](https://github.com/tweaselORG/appstraction/blob/main/src/ios.ts#L508)
[ios.ts:523](https://github.com/tweaselORG/appstraction/blob/main/src/ios.ts#L523)

___

Expand Down Expand Up @@ -199,7 +199,7 @@ The options for the `platformApi()` function.

#### Defined in

[index.ts:332](https://github.com/tweaselORG/appstraction/blob/main/src/index.ts#L332)
[index.ts:335](https://github.com/tweaselORG/appstraction/blob/main/src/index.ts#L335)

___

Expand All @@ -218,7 +218,7 @@ Connection details for a proxy.

#### Defined in

[index.ts:408](https://github.com/tweaselORG/appstraction/blob/main/src/index.ts#L408)
[index.ts:420](https://github.com/tweaselORG/appstraction/blob/main/src/index.ts#L420)

___

Expand All @@ -242,19 +242,19 @@ The options for a specific platform/run target combination.
| `android` | { `device`: `unknown` ; `emulator`: `unknown` } | The options for the Android platform. |
| `android.device` | `unknown` | The options for the Android physical device run target. |
| `android.emulator` | `unknown` | The options for the Android emulator run target. |
| `ios` | { `device`: ``"ssh"`` extends `Capability` ? { `ip`: `string` ; `rootPw?`: `string` } : `unknown` ; `emulator`: `never` } | The options for the iOS platform. |
| `ios.device` | ``"ssh"`` extends `Capability` ? { `ip`: `string` ; `rootPw?`: `string` } : `unknown` | The options for the iOS physical device run target. |
| `ios` | { `device`: ``"ssh"`` extends `Capability` ? { `ip`: `string` ; `rootPw?`: `string` } : `unknown` & ``"supervision"`` extends `Capability` ? { `supervisionKeyPassword?`: `string` } : `unknown` ; `emulator`: `never` } | The options for the iOS platform. |
| `ios.device` | ``"ssh"`` extends `Capability` ? { `ip`: `string` ; `rootPw?`: `string` } : `unknown` & ``"supervision"`` extends `Capability` ? { `supervisionKeyPassword?`: `string` } : `unknown` | The options for the iOS physical device run target. |
| `ios.emulator` | `never` | The options for the iOS emulator run target. |

#### Defined in

[index.ts:359](https://github.com/tweaselORG/appstraction/blob/main/src/index.ts#L359)
[index.ts:362](https://github.com/tweaselORG/appstraction/blob/main/src/index.ts#L362)

___

### SupportedCapability

Ƭ **SupportedCapability**<`Platform`\>: `Platform` extends ``"android"`` ? ``"wireguard"`` \| ``"root"`` \| ``"frida"`` \| ``"certificate-pinning-bypass"`` : `Platform` extends ``"ios"`` ? ``"ssh"`` \| ``"frida"`` : `never`
Ƭ **SupportedCapability**<`Platform`\>: `Platform` extends ``"android"`` ? ``"wireguard"`` \| ``"root"`` \| ``"frida"`` \| ``"certificate-pinning-bypass"`` : `Platform` extends ``"ios"`` ? ``"ssh"`` \| ``"frida"`` \| ``"supervision"`` : `never`

A capability for the `platformApi()` function.

Expand All @@ -266,7 +266,7 @@ A capability for the `platformApi()` function.

#### Defined in

[index.ts:387](https://github.com/tweaselORG/appstraction/blob/main/src/index.ts#L387)
[index.ts:399](https://github.com/tweaselORG/appstraction/blob/main/src/index.ts#L399)

___

Expand Down Expand Up @@ -308,7 +308,7 @@ Configuration string for WireGuard.

#### Defined in

[index.ts:415](https://github.com/tweaselORG/appstraction/blob/main/src/index.ts#L415)
[index.ts:427](https://github.com/tweaselORG/appstraction/blob/main/src/index.ts#L427)

## Variables

Expand All @@ -332,7 +332,7 @@ The IDs of known permissions on iOS.

#### Defined in

[ios.ts:491](https://github.com/tweaselORG/appstraction/blob/main/src/ios.ts#L491)
[ios.ts:506](https://github.com/tweaselORG/appstraction/blob/main/src/ios.ts#L506)

## Functions

Expand Down Expand Up @@ -425,4 +425,4 @@ The API object for the given platform and run target.

#### Defined in

[index.ts:424](https://github.com/tweaselORG/appstraction/blob/main/src/index.ts#L424)
[index.ts:436](https://github.com/tweaselORG/appstraction/blob/main/src/index.ts#L436)
20 changes: 16 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,11 @@ export type PlatformApi<
* expired, it will be generated.
*
* Might restart the device, if a new cofniguration is pushed. You are adviced to wait for the device.
*
* @param forceNewKey If set to `true`, a new host key will be generated and set up, even if there is
* already a valid old one.
*/
ensureSupervision: () => Promise<void>;
ensureSupervision: (forceNewKey?: boolean) => Promise<void>;
/**
* Removes all configured supervision hosts from the device.
*
Expand Down Expand Up @@ -372,22 +375,31 @@ export type RunTargetOptions<
/** The options for the iOS emulator run target. */
emulator: never;
/** The options for the iOS physical device run target. */
device: 'ssh' extends Capability
device: ('ssh' extends Capability
? {
/** The password of the root user on the device, defaults to `alpine` if not set. */
rootPw?: string;
/** The device's IP address. */
ip: string;
}
: unknown;
: unknown) &
('supervision' extends Capability
? {
/**
* The password of the private key of the supervision certificate, defaults to `appstraction` if
* not set.
*/
supervisionKeyPassword?: string;
}
: unknown);
};
};

/** A capability for the `platformApi()` function. */
export type SupportedCapability<Platform extends SupportedPlatform> = Platform extends 'android'
? 'wireguard' | 'root' | 'frida' | 'certificate-pinning-bypass'
: Platform extends 'ios'
? 'ssh' | 'frida'
? 'ssh' | 'frida' | 'supervision'
: never;

/** A supported attribute for the `getDeviceAttribute()` function, depending on the platform. */
Expand Down
23 changes: 19 additions & 4 deletions src/ios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ export const iosApi = <RunTarget extends SupportedRunTarget<'ios'>>(
ssh.dispose();
return res;
},
async ensureSupervision() {
async ensureSupervision(forceNewKey = false) {
if (!options.capabilities.includes('ssh'))
throw new Error('SSH is currently required to ensure supervison mode.');

Expand All @@ -175,6 +175,7 @@ export const iosApi = <RunTarget extends SupportedRunTarget<'ios'>>(
let hostCert;

if (
!forceNewKey &&
(await exists(join(cacheDir, 'ios', 'supervisorCert.pem'))) &&
(await exists(join(cacheDir, 'ios', 'supervisorKeyStore.p12')))
) {
Expand Down Expand Up @@ -205,13 +206,17 @@ export const iosApi = <RunTarget extends SupportedRunTarget<'ios'>>(
}
}

if (!hostCert) {
// We have no exsiting keys, so let’s generate one.
if (!hostCert || forceNewKey) {
// We have no existing keys, so let’s generate one.
const generated = await generateCertificate(OrganizationName);
hostCert = generated.certificate;
const hostKey = generated.privateKey;

const keyStore = createPkcs12Container(hostCert, hostKey, 'appstraction');
const keyStore = createPkcs12Container(
hostCert,
hostKey,
options.targetOptions?.supervisionKeyPassword || 'appstraction'
);

await mkdirp(join(cacheDir, 'ios'));
await writeFile(join(cacheDir, 'ios', 'supervisorCert.pem'), hostCert);
Expand Down Expand Up @@ -286,6 +291,16 @@ export const iosApi = <RunTarget extends SupportedRunTarget<'ios'>>(
throw new Error('Cannot connect using SSH.', { cause: err });
}
}

if (options.capabilities.includes('supervision')) {
if (!options.capabilities.includes('ssh'))
throw new Error(
'Unimplemented on this platform: Activating supervision mode without the ssh capability.'
);

await this._internal.ensureSupervision();
await this.waitForDevice();
}
},
clearStuckModals: asyncUnimplemented('clearStuckModals') as never,

Expand Down

0 comments on commit c50562a

Please sign in to comment.