appium-adb 14.1.0 → 14.1.2
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/lib/adb.d.ts.map +1 -1
- package/build/lib/adb.js.map +1 -1
- package/build/lib/helpers.d.ts.map +1 -1
- package/build/lib/helpers.js +3 -3
- package/build/lib/helpers.js.map +1 -1
- package/build/lib/logcat.d.ts.map +1 -1
- package/build/lib/logcat.js +16 -6
- package/build/lib/logcat.js.map +1 -1
- package/build/lib/logger.js.map +1 -1
- package/build/lib/tools/aab-utils.d.ts.map +1 -1
- package/build/lib/tools/aab-utils.js +25 -18
- package/build/lib/tools/aab-utils.js.map +1 -1
- package/build/lib/tools/android-manifest.d.ts.map +1 -1
- package/build/lib/tools/android-manifest.js +36 -24
- package/build/lib/tools/android-manifest.js.map +1 -1
- package/build/lib/tools/apk-signing.d.ts.map +1 -1
- package/build/lib/tools/apk-signing.js +58 -37
- package/build/lib/tools/apk-signing.js.map +1 -1
- package/build/lib/tools/apk-utils.d.ts.map +1 -1
- package/build/lib/tools/apk-utils.js +46 -38
- package/build/lib/tools/apk-utils.js.map +1 -1
- package/build/lib/tools/apks-utils.d.ts.map +1 -1
- package/build/lib/tools/apks-utils.js +21 -14
- package/build/lib/tools/apks-utils.js.map +1 -1
- package/build/lib/tools/app-commands.d.ts.map +1 -1
- package/build/lib/tools/app-commands.js +44 -45
- package/build/lib/tools/app-commands.js.map +1 -1
- package/build/lib/tools/device-settings.d.ts.map +1 -1
- package/build/lib/tools/device-settings.js +38 -32
- package/build/lib/tools/device-settings.js.map +1 -1
- package/build/lib/tools/emu-constants.d.ts.map +1 -1
- package/build/lib/tools/emu-constants.js +4 -4
- package/build/lib/tools/emu-constants.js.map +1 -1
- package/build/lib/tools/emulator-commands.d.ts.map +1 -1
- package/build/lib/tools/emulator-commands.js +20 -17
- package/build/lib/tools/emulator-commands.js.map +1 -1
- package/build/lib/tools/fs-commands.d.ts.map +1 -1
- package/build/lib/tools/fs-commands.js +2 -1
- package/build/lib/tools/fs-commands.js.map +1 -1
- package/build/lib/tools/general-commands.d.ts.map +1 -1
- package/build/lib/tools/general-commands.js +11 -15
- package/build/lib/tools/general-commands.js.map +1 -1
- package/build/lib/tools/keyboard-commands.d.ts.map +1 -1
- package/build/lib/tools/keyboard-commands.js.map +1 -1
- package/build/lib/tools/lockmgmt.d.ts.map +1 -1
- package/build/lib/tools/lockmgmt.js +24 -23
- package/build/lib/tools/lockmgmt.js.map +1 -1
- package/build/lib/tools/logcat-commands.d.ts.map +1 -1
- package/build/lib/tools/logcat-commands.js.map +1 -1
- package/build/lib/tools/network-commands.d.ts.map +1 -1
- package/build/lib/tools/network-commands.js +0 -1
- package/build/lib/tools/network-commands.js.map +1 -1
- package/build/lib/tools/process-commands.d.ts.map +1 -1
- package/build/lib/tools/process-commands.js +1 -1
- package/build/lib/tools/process-commands.js.map +1 -1
- package/build/lib/tools/system-calls.d.ts.map +1 -1
- package/build/lib/tools/system-calls.js +30 -36
- package/build/lib/tools/system-calls.js.map +1 -1
- package/build/lib/tools/types.d.ts +6 -6
- package/build/lib/tools/types.d.ts.map +1 -1
- package/lib/adb.ts +20 -25
- package/lib/helpers.ts +48 -36
- package/lib/logcat.ts +32 -22
- package/lib/logger.ts +1 -2
- package/lib/tools/aab-utils.js +42 -33
- package/lib/tools/android-manifest.js +78 -54
- package/lib/tools/apk-signing.ts +123 -89
- package/lib/tools/apk-utils.ts +206 -109
- package/lib/tools/apks-utils.js +50 -40
- package/lib/tools/app-commands.ts +220 -135
- package/lib/tools/device-settings.ts +154 -124
- package/lib/tools/emu-constants.ts +4 -5
- package/lib/tools/emulator-commands.ts +113 -65
- package/lib/tools/fs-commands.js +9 -8
- package/lib/tools/general-commands.js +48 -51
- package/lib/tools/keyboard-commands.js +22 -20
- package/lib/tools/lockmgmt.js +80 -51
- package/lib/tools/logcat-commands.js +6 -6
- package/lib/tools/network-commands.js +11 -12
- package/lib/tools/process-commands.ts +28 -15
- package/lib/tools/system-calls.ts +319 -221
- package/lib/tools/types.ts +19 -10
- package/package.json +4 -3
package/lib/tools/apk-signing.ts
CHANGED
|
@@ -1,23 +1,13 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
2
|
import _fs from 'fs';
|
|
3
|
-
import {
|
|
3
|
+
import {exec, type ExecError} from 'teen_process';
|
|
4
4
|
import path from 'path';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
APKS_EXTENSION,
|
|
12
|
-
getResourcePath,
|
|
13
|
-
} from '../helpers.js';
|
|
14
|
-
import type { ADB } from '../adb.js';
|
|
15
|
-
import type {
|
|
16
|
-
StringRecord,
|
|
17
|
-
SignedAppCacheValue,
|
|
18
|
-
CertCheckOptions,
|
|
19
|
-
KeystoreHash
|
|
20
|
-
} from './types.js';
|
|
5
|
+
import {log} from '../logger.js';
|
|
6
|
+
import {tempDir, system, mkdirp, fs, util, zip} from '@appium/support';
|
|
7
|
+
import {LRUCache} from 'lru-cache';
|
|
8
|
+
import {getJavaForOs, getJavaHome, APKS_EXTENSION, getResourcePath} from '../helpers.js';
|
|
9
|
+
import type {ADB} from '../adb.js';
|
|
10
|
+
import type {StringRecord, SignedAppCacheValue, CertCheckOptions, KeystoreHash} from './types.js';
|
|
21
11
|
|
|
22
12
|
const DEFAULT_PRIVATE_KEY = path.join('keys', 'testkey.pk8');
|
|
23
13
|
const DEFAULT_CERTIFICATE = path.join('keys', 'testkey.x509.pem');
|
|
@@ -28,7 +18,7 @@ const SHA256 = 'sha256';
|
|
|
28
18
|
const SHA512 = 'sha512';
|
|
29
19
|
const MD5 = 'md5';
|
|
30
20
|
const DEFAULT_CERT_HASH: KeystoreHash = {
|
|
31
|
-
[SHA256]: 'a40da80a59d170caa950cf15c18c454d47a39b26989d8b640ecd745ba71bf5dc'
|
|
21
|
+
[SHA256]: 'a40da80a59d170caa950cf15c18c454d47a39b26989d8b640ecd745ba71bf5dc',
|
|
32
22
|
};
|
|
33
23
|
const JAVA_PROPS_INIT_ERROR = 'java.lang.Error: Properties init';
|
|
34
24
|
const SIGNED_APPS_CACHE = new LRUCache<string, SignedAppCacheValue>({
|
|
@@ -43,13 +33,9 @@ const SIGNED_APPS_CACHE = new LRUCache<string, SignedAppCacheValue>({
|
|
|
43
33
|
* @throws If apksigner binary is not present on the local file system
|
|
44
34
|
* or the return code is not equal to zero.
|
|
45
35
|
*/
|
|
46
|
-
export async function executeApksigner
|
|
36
|
+
export async function executeApksigner(this: ADB, args: string[]): Promise<string> {
|
|
47
37
|
const apkSignerJar = await getApksignerForOs.bind(this)();
|
|
48
|
-
const fullCmd = [
|
|
49
|
-
await getJavaForOs(), '-Xmx1024M', '-Xss1m',
|
|
50
|
-
'-jar', apkSignerJar,
|
|
51
|
-
...args
|
|
52
|
-
];
|
|
38
|
+
const fullCmd = [await getJavaForOs(), '-Xmx1024M', '-Xss1m', '-jar', apkSignerJar, ...args];
|
|
53
39
|
log.debug(`Starting apksigner: ${util.quote(fullCmd)}`);
|
|
54
40
|
// It is necessary to specify CWD explicitly; see https://github.com/appium/appium/issues/14724#issuecomment-737446715
|
|
55
41
|
const {stdout, stderr} = await exec(fullCmd[0], fullCmd.slice(1), {
|
|
@@ -57,14 +43,18 @@ export async function executeApksigner (this: ADB, args: string[]): Promise<stri
|
|
|
57
43
|
// @ts-ignore This works
|
|
58
44
|
windowsVerbatimArguments: system.isWindows(),
|
|
59
45
|
});
|
|
60
|
-
for (const [name, stream] of [
|
|
46
|
+
for (const [name, stream] of [
|
|
47
|
+
['stdout', stdout],
|
|
48
|
+
['stderr', stderr],
|
|
49
|
+
] as const) {
|
|
61
50
|
if (!_.trim(stream)) {
|
|
62
51
|
continue;
|
|
63
52
|
}
|
|
64
53
|
|
|
65
54
|
if (name === 'stdout') {
|
|
66
55
|
// Make the output less talkative
|
|
67
|
-
const filteredStream = stream
|
|
56
|
+
const filteredStream = stream
|
|
57
|
+
.split('\n')
|
|
68
58
|
.filter((line) => !line.includes('WARNING:'))
|
|
69
59
|
.join('\n');
|
|
70
60
|
log.debug(`apksigner ${name}: ${filteredStream}`);
|
|
@@ -81,7 +71,7 @@ export async function executeApksigner (this: ADB, args: string[]): Promise<stri
|
|
|
81
71
|
* @param apk - The full path to the local apk file.
|
|
82
72
|
* @throws If signing fails.
|
|
83
73
|
*/
|
|
84
|
-
export async function signWithDefaultCert
|
|
74
|
+
export async function signWithDefaultCert(this: ADB, apk: string): Promise<void> {
|
|
85
75
|
log.debug(`Signing '${apk}' with default cert`);
|
|
86
76
|
if (!(await fs.exists(apk))) {
|
|
87
77
|
throw new Error(`${apk} file doesn't exist.`);
|
|
@@ -89,16 +79,20 @@ export async function signWithDefaultCert (this: ADB, apk: string): Promise<void
|
|
|
89
79
|
|
|
90
80
|
const args = [
|
|
91
81
|
'sign',
|
|
92
|
-
'--key',
|
|
93
|
-
|
|
82
|
+
'--key',
|
|
83
|
+
await getResourcePath(DEFAULT_PRIVATE_KEY),
|
|
84
|
+
'--cert',
|
|
85
|
+
await getResourcePath(DEFAULT_CERTIFICATE),
|
|
94
86
|
apk,
|
|
95
87
|
];
|
|
96
88
|
try {
|
|
97
89
|
await this.executeApksigner(args);
|
|
98
90
|
} catch (e) {
|
|
99
91
|
const err = e as ExecError;
|
|
100
|
-
throw new Error(
|
|
101
|
-
`
|
|
92
|
+
throw new Error(
|
|
93
|
+
`Could not sign '${apk}' with the default certificate. ` +
|
|
94
|
+
`Original error: ${err.stderr || err.stdout || err.message}`,
|
|
95
|
+
);
|
|
102
96
|
}
|
|
103
97
|
}
|
|
104
98
|
|
|
@@ -108,7 +102,7 @@ export async function signWithDefaultCert (this: ADB, apk: string): Promise<void
|
|
|
108
102
|
* @param apk - The full path to the local apk file.
|
|
109
103
|
* @throws If signing fails.
|
|
110
104
|
*/
|
|
111
|
-
export async function signWithCustomCert
|
|
105
|
+
export async function signWithCustomCert(this: ADB, apk: string): Promise<void> {
|
|
112
106
|
log.debug(`Signing '${apk}' with custom cert`);
|
|
113
107
|
if (!(await fs.exists(this.keystorePath as string))) {
|
|
114
108
|
throw new Error(`Keystore: ${this.keystorePath} doesn't exist.`);
|
|
@@ -118,31 +112,50 @@ export async function signWithCustomCert (this: ADB, apk: string): Promise<void>
|
|
|
118
112
|
}
|
|
119
113
|
|
|
120
114
|
try {
|
|
121
|
-
await this.executeApksigner([
|
|
122
|
-
'
|
|
123
|
-
'--ks
|
|
124
|
-
|
|
125
|
-
'--key-
|
|
126
|
-
|
|
115
|
+
await this.executeApksigner([
|
|
116
|
+
'sign',
|
|
117
|
+
'--ks',
|
|
118
|
+
this.keystorePath as string,
|
|
119
|
+
'--ks-key-alias',
|
|
120
|
+
this.keyAlias as string,
|
|
121
|
+
'--ks-pass',
|
|
122
|
+
`pass:${this.keystorePassword}`,
|
|
123
|
+
'--key-pass',
|
|
124
|
+
`pass:${this.keyPassword}`,
|
|
125
|
+
apk,
|
|
126
|
+
]);
|
|
127
127
|
} catch (err) {
|
|
128
128
|
const error = err as ExecError;
|
|
129
|
-
log.warn(
|
|
130
|
-
`
|
|
129
|
+
log.warn(
|
|
130
|
+
`Cannot use apksigner tool for signing. Defaulting to jarsigner. ` +
|
|
131
|
+
`Original error: ${error.stderr || error.stdout || error.message}`,
|
|
132
|
+
);
|
|
131
133
|
try {
|
|
132
134
|
if (await unsignApk(apk)) {
|
|
133
135
|
log.debug(`'${apk}' has been successfully unsigned`);
|
|
134
136
|
} else {
|
|
135
137
|
log.debug(`'${apk}' does not need to be unsigned`);
|
|
136
138
|
}
|
|
137
|
-
const jarsigner = path.resolve(
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
'
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
'-
|
|
145
|
-
|
|
139
|
+
const jarsigner = path.resolve(
|
|
140
|
+
await getJavaHome(),
|
|
141
|
+
'bin',
|
|
142
|
+
`jarsigner${system.isWindows() ? '.exe' : ''}`,
|
|
143
|
+
);
|
|
144
|
+
const fullCmd: string[] = [
|
|
145
|
+
jarsigner,
|
|
146
|
+
'-sigalg',
|
|
147
|
+
'MD5withRSA',
|
|
148
|
+
'-digestalg',
|
|
149
|
+
'SHA1',
|
|
150
|
+
'-keystore',
|
|
151
|
+
this.keystorePath as string,
|
|
152
|
+
'-storepass',
|
|
153
|
+
this.keystorePassword as string,
|
|
154
|
+
'-keypass',
|
|
155
|
+
this.keyPassword as string,
|
|
156
|
+
apk,
|
|
157
|
+
this.keyAlias as string,
|
|
158
|
+
];
|
|
146
159
|
log.debug(`Starting jarsigner: ${util.quote(fullCmd)}`);
|
|
147
160
|
await exec(fullCmd[0], fullCmd.slice(1), {
|
|
148
161
|
// @ts-ignore This works
|
|
@@ -150,8 +163,10 @@ export async function signWithCustomCert (this: ADB, apk: string): Promise<void>
|
|
|
150
163
|
});
|
|
151
164
|
} catch (e) {
|
|
152
165
|
const execErr = e as ExecError;
|
|
153
|
-
throw new Error(
|
|
154
|
-
`
|
|
166
|
+
throw new Error(
|
|
167
|
+
`Could not sign with custom certificate. ` +
|
|
168
|
+
`Original error: ${execErr.stderr || execErr.message}`,
|
|
169
|
+
);
|
|
155
170
|
}
|
|
156
171
|
}
|
|
157
172
|
}
|
|
@@ -164,14 +179,16 @@ export async function signWithCustomCert (this: ADB, apk: string): Promise<void>
|
|
|
164
179
|
* @param appPath - The full path to the local .apk(s) file.
|
|
165
180
|
* @throws If signing fails.
|
|
166
181
|
*/
|
|
167
|
-
export async function sign
|
|
182
|
+
export async function sign(this: ADB, appPath: string): Promise<void> {
|
|
168
183
|
if (appPath.endsWith(APKS_EXTENSION)) {
|
|
169
184
|
let message = 'Signing of .apks-files is not supported. ';
|
|
170
185
|
if (this.useKeystore) {
|
|
171
|
-
message +=
|
|
186
|
+
message +=
|
|
187
|
+
'Consider manual application bundle signing with the custom keystore ' +
|
|
172
188
|
`like it is described at ${BUNDLETOOL_TUTORIAL}`;
|
|
173
189
|
} else {
|
|
174
|
-
message +=
|
|
190
|
+
message +=
|
|
191
|
+
`Consider manual application bundle signing with the key at '${DEFAULT_PRIVATE_KEY}' ` +
|
|
175
192
|
`and the certificate at '${DEFAULT_CERTIFICATE}'. Read ${BUNDLETOOL_TUTORIAL} for more details.`;
|
|
176
193
|
}
|
|
177
194
|
log.warn(message);
|
|
@@ -197,7 +214,7 @@ export async function sign (this: ADB, appPath: string): Promise<void> {
|
|
|
197
214
|
* or false if the apk has been already aligned.
|
|
198
215
|
* @throws If zip-align fails.
|
|
199
216
|
*/
|
|
200
|
-
export async function zipAlignApk
|
|
217
|
+
export async function zipAlignApk(this: ADB, apk: string): Promise<boolean> {
|
|
201
218
|
await this.initZipAlign();
|
|
202
219
|
try {
|
|
203
220
|
await exec((this.binaries as StringRecord).zipalign as string, ['-c', '4', apk]);
|
|
@@ -209,25 +226,26 @@ export async function zipAlignApk (this: ADB, apk: string): Promise<boolean> {
|
|
|
209
226
|
try {
|
|
210
227
|
await fs.access(apk, _fs.constants.W_OK);
|
|
211
228
|
} catch {
|
|
212
|
-
throw new Error(
|
|
213
|
-
`
|
|
214
|
-
|
|
229
|
+
throw new Error(
|
|
230
|
+
`The file at '${apk}' is not writeable. ` +
|
|
231
|
+
`Please grant write permissions to this file or to its parent folder '${path.dirname(apk)}' ` +
|
|
232
|
+
`for the Appium process, so it can zip-align the file`,
|
|
233
|
+
);
|
|
215
234
|
}
|
|
216
235
|
const alignedApk = await tempDir.path({prefix: 'appium', suffix: '.tmp'});
|
|
217
236
|
await mkdirp(path.dirname(alignedApk));
|
|
218
237
|
try {
|
|
219
|
-
await exec(
|
|
220
|
-
|
|
221
|
-
['-f', '4', apk, alignedApk]
|
|
222
|
-
);
|
|
223
|
-
await fs.mv(alignedApk, apk, { mkdirp: true });
|
|
238
|
+
await exec((this.binaries as StringRecord).zipalign as string, ['-f', '4', apk, alignedApk]);
|
|
239
|
+
await fs.mv(alignedApk, apk, {mkdirp: true});
|
|
224
240
|
return true;
|
|
225
241
|
} catch (e) {
|
|
226
242
|
const err = e as Error;
|
|
227
243
|
if (await fs.exists(alignedApk)) {
|
|
228
244
|
await fs.unlink(alignedApk);
|
|
229
245
|
}
|
|
230
|
-
throw new Error(
|
|
246
|
+
throw new Error(
|
|
247
|
+
`zipAlignApk failed. Original error: ${err.message || (err as ExecError).stderr}`,
|
|
248
|
+
);
|
|
231
249
|
}
|
|
232
250
|
}
|
|
233
251
|
|
|
@@ -239,9 +257,14 @@ export async function zipAlignApk (this: ADB, apk: string): Promise<boolean> {
|
|
|
239
257
|
* @param opts - Certificate checking options
|
|
240
258
|
* @returns True if given application is already signed.
|
|
241
259
|
*/
|
|
242
|
-
export async function checkApkCert
|
|
260
|
+
export async function checkApkCert(
|
|
261
|
+
this: ADB,
|
|
262
|
+
appPath: string,
|
|
263
|
+
pkg: string,
|
|
264
|
+
opts: CertCheckOptions = {},
|
|
265
|
+
): Promise<boolean> {
|
|
243
266
|
log.debug(`Checking app cert for ${appPath}`);
|
|
244
|
-
if (!await fs.exists(appPath)) {
|
|
267
|
+
if (!(await fs.exists(appPath))) {
|
|
245
268
|
log.debug(`'${appPath}' does not exist`);
|
|
246
269
|
return false;
|
|
247
270
|
}
|
|
@@ -261,9 +284,7 @@ export async function checkApkCert (this: ADB, appPath: string, pkg: string, opt
|
|
|
261
284
|
return false;
|
|
262
285
|
};
|
|
263
286
|
|
|
264
|
-
const {
|
|
265
|
-
requireDefaultCert = true,
|
|
266
|
-
} = opts;
|
|
287
|
+
const {requireDefaultCert = true} = opts;
|
|
267
288
|
|
|
268
289
|
const appHash = await fs.hash(actualAppPath);
|
|
269
290
|
if (SIGNED_APPS_CACHE.has(appHash)) {
|
|
@@ -271,7 +292,7 @@ export async function checkApkCert (this: ADB, appPath: string, pkg: string, opt
|
|
|
271
292
|
const cached = SIGNED_APPS_CACHE.get(appHash);
|
|
272
293
|
if (cached) {
|
|
273
294
|
const {keystorePath, output, expected} = cached;
|
|
274
|
-
if (this.useKeystore && this.keystorePath === keystorePath || !this.useKeystore) {
|
|
295
|
+
if ((this.useKeystore && this.keystorePath === keystorePath) || !this.useKeystore) {
|
|
275
296
|
return (!this.useKeystore && !requireDefaultCert) || hashMatches(output, expected);
|
|
276
297
|
}
|
|
277
298
|
}
|
|
@@ -283,11 +304,15 @@ export async function checkApkCert (this: ADB, appPath: string, pkg: string, opt
|
|
|
283
304
|
const output = await this.executeApksigner(['verify', '--print-certs', actualAppPath]);
|
|
284
305
|
const hasMatch = hashMatches(output, expected);
|
|
285
306
|
if (hasMatch) {
|
|
286
|
-
log.info(
|
|
287
|
-
|
|
307
|
+
log.info(
|
|
308
|
+
`'${actualAppPath}' is signed with the ` +
|
|
309
|
+
`${this.useKeystore ? 'keystore' : 'default'} certificate`,
|
|
310
|
+
);
|
|
288
311
|
} else {
|
|
289
|
-
log.info(
|
|
290
|
-
`
|
|
312
|
+
log.info(
|
|
313
|
+
`'${actualAppPath}' is signed with a ` +
|
|
314
|
+
`non-${this.useKeystore ? 'keystore' : 'default'} certificate`,
|
|
315
|
+
);
|
|
291
316
|
}
|
|
292
317
|
const isSigned = (!this.useKeystore && !requireDefaultCert) || hasMatch;
|
|
293
318
|
if (isSigned) {
|
|
@@ -319,8 +344,9 @@ export async function checkApkCert (this: ADB, appPath: string, pkg: string, opt
|
|
|
319
344
|
log.warn(`Assuming '${actualAppPath}' is already signed and continuing anyway`);
|
|
320
345
|
return true;
|
|
321
346
|
}
|
|
322
|
-
throw new Error(
|
|
323
|
-
`Original error: ${errMsg}
|
|
347
|
+
throw new Error(
|
|
348
|
+
`Cannot verify the signature of '${actualAppPath}'. ` + `Original error: ${errMsg}`,
|
|
349
|
+
);
|
|
324
350
|
}
|
|
325
351
|
}
|
|
326
352
|
|
|
@@ -330,18 +356,25 @@ export async function checkApkCert (this: ADB, appPath: string, pkg: string, opt
|
|
|
330
356
|
* @returns
|
|
331
357
|
* @throws If getting keystore hash fails.
|
|
332
358
|
*/
|
|
333
|
-
export async function getKeystoreHash
|
|
359
|
+
export async function getKeystoreHash(this: ADB): Promise<KeystoreHash> {
|
|
334
360
|
log.debug(`Getting hash of the '${this.keystorePath}' keystore`);
|
|
335
|
-
const keytool = path.resolve(
|
|
336
|
-
|
|
337
|
-
|
|
361
|
+
const keytool = path.resolve(
|
|
362
|
+
await getJavaHome(),
|
|
363
|
+
'bin',
|
|
364
|
+
`keytool${system.isWindows() ? '.exe' : ''}`,
|
|
365
|
+
);
|
|
366
|
+
if (!(await fs.exists(keytool))) {
|
|
338
367
|
throw new Error(`The keytool utility cannot be found at '${keytool}'`);
|
|
339
368
|
}
|
|
340
369
|
const args: string[] = [
|
|
341
|
-
'-v',
|
|
342
|
-
'-
|
|
343
|
-
'-
|
|
344
|
-
|
|
370
|
+
'-v',
|
|
371
|
+
'-list',
|
|
372
|
+
'-alias',
|
|
373
|
+
this.keyAlias as string,
|
|
374
|
+
'-keystore',
|
|
375
|
+
this.keystorePath as string,
|
|
376
|
+
'-storepass',
|
|
377
|
+
this.keystorePassword as string,
|
|
345
378
|
];
|
|
346
379
|
log.info(`Running '${keytool}' with arguments: ${util.quote(args)}`);
|
|
347
380
|
try {
|
|
@@ -366,8 +399,10 @@ export async function getKeystoreHash (this: ADB): Promise<KeystoreHash> {
|
|
|
366
399
|
return result;
|
|
367
400
|
} catch (e) {
|
|
368
401
|
const err = e as ExecError;
|
|
369
|
-
throw new Error(
|
|
370
|
-
`
|
|
402
|
+
throw new Error(
|
|
403
|
+
`Cannot get the hash of '${this.keystorePath}' keystore. ` +
|
|
404
|
+
`Original error: ${err.stderr || err.message}`,
|
|
405
|
+
);
|
|
371
406
|
}
|
|
372
407
|
}
|
|
373
408
|
|
|
@@ -379,7 +414,7 @@ export async function getKeystoreHash (this: ADB): Promise<KeystoreHash> {
|
|
|
379
414
|
* @returns An absolute path to apksigner tool.
|
|
380
415
|
* @throws If the tool is not present on the local file system.
|
|
381
416
|
*/
|
|
382
|
-
export async function getApksignerForOs
|
|
417
|
+
export async function getApksignerForOs(this: ADB): Promise<string> {
|
|
383
418
|
return await this.getBinaryFromSdkRoot('apksigner.jar');
|
|
384
419
|
}
|
|
385
420
|
|
|
@@ -393,7 +428,7 @@ export async function getApksignerForOs (this: ADB): Promise<string> {
|
|
|
393
428
|
* unsigned and overwritten
|
|
394
429
|
* @throws if there was an error during the unsign operation
|
|
395
430
|
*/
|
|
396
|
-
export async function unsignApk
|
|
431
|
+
export async function unsignApk(apkPath: string): Promise<boolean> {
|
|
397
432
|
const tmpRoot = await tempDir.openDir();
|
|
398
433
|
const metaInfFolderName = 'META-INF';
|
|
399
434
|
try {
|
|
@@ -422,4 +457,3 @@ export async function unsignApk (apkPath: string): Promise<boolean> {
|
|
|
422
457
|
}
|
|
423
458
|
|
|
424
459
|
// #endregion
|
|
425
|
-
|