appium-adb 16.0.9 → 16.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.
Files changed (41) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +1 -1
  3. package/build/lib/tools/aab-utils.js +35 -35
  4. package/build/lib/tools/aab-utils.js.map +1 -1
  5. package/build/lib/tools/android-manifest.js +1 -1
  6. package/build/lib/tools/android-manifest.js.map +1 -1
  7. package/build/lib/tools/apk-signing.d.ts.map +1 -1
  8. package/build/lib/tools/apk-signing.js +21 -9
  9. package/build/lib/tools/apk-signing.js.map +1 -1
  10. package/build/lib/tools/apks-utils.d.ts.map +1 -1
  11. package/build/lib/tools/apks-utils.js +7 -6
  12. package/build/lib/tools/apks-utils.js.map +1 -1
  13. package/build/lib/tools/lockmgmt.d.ts +8 -0
  14. package/build/lib/tools/lockmgmt.d.ts.map +1 -1
  15. package/build/lib/tools/lockmgmt.js +15 -14
  16. package/build/lib/tools/lockmgmt.js.map +1 -1
  17. package/build/lib/tools/system-calls.d.ts.map +1 -1
  18. package/build/lib/tools/system-calls.js +7 -6
  19. package/build/lib/tools/system-calls.js.map +1 -1
  20. package/build/lib/utils/helpers/index.d.ts +1 -0
  21. package/build/lib/utils/helpers/index.d.ts.map +1 -1
  22. package/build/lib/utils/helpers/index.js +1 -0
  23. package/build/lib/utils/helpers/index.js.map +1 -1
  24. package/build/lib/utils/helpers/redact.d.ts +19 -0
  25. package/build/lib/utils/helpers/redact.d.ts.map +1 -0
  26. package/build/lib/utils/helpers/redact.js +57 -0
  27. package/build/lib/utils/helpers/redact.js.map +1 -0
  28. package/build/lib/utils/index.d.ts +2 -0
  29. package/build/lib/utils/index.d.ts.map +1 -1
  30. package/build/lib/utils/index.js +2 -0
  31. package/build/lib/utils/index.js.map +1 -1
  32. package/lib/tools/aab-utils.ts +36 -36
  33. package/lib/tools/android-manifest.ts +1 -1
  34. package/lib/tools/apk-signing.ts +26 -9
  35. package/lib/tools/apks-utils.ts +14 -6
  36. package/lib/tools/lockmgmt.ts +16 -17
  37. package/lib/tools/system-calls.ts +15 -6
  38. package/lib/utils/helpers/index.ts +1 -0
  39. package/lib/utils/helpers/redact.ts +59 -0
  40. package/lib/utils/index.ts +2 -0
  41. package/package.json +12 -17
@@ -8,7 +8,15 @@ import type {ExecError, TeenProcessExecResult} from 'teen_process';
8
8
 
9
9
  import type {ADB} from '../adb.js';
10
10
  import {log} from '../logger.js';
11
- import {DEFAULT_ADB_EXEC_TIMEOUT, cloneDeep, getSdkRootFromEnv, memoize, zip} from '../utils/index.js';
11
+ import {
12
+ DEFAULT_ADB_EXEC_TIMEOUT,
13
+ cloneDeep,
14
+ getSdkRootFromEnv,
15
+ memoize,
16
+ redactExecError,
17
+ redactSecrets,
18
+ zip,
19
+ } from '../utils/index.js';
12
20
  import type {
13
21
  ConnectedDevicesOptions,
14
22
  Device,
@@ -493,11 +501,12 @@ export async function adbExec(this: ADB, cmd: string | string[], opts?: AdbExecO
493
501
  cmd = Array.isArray(cmd) ? cmd : [cmd];
494
502
  let adbRetried = false;
495
503
  const execFunc = async (): Promise<string | ExecResult> => {
504
+ const args = [...this.executable.defaultArgs, ...cmd];
496
505
  try {
497
- const args = [...this.executable.defaultArgs, ...cmd];
506
+ const logArgs = redactSecrets(args);
498
507
  log.debug(
499
508
  `Running '${this.executable.path} ` +
500
- (args.find((arg) => /\s+/.test(arg)) ? util.quote(args) : args.join(' ')) +
509
+ (logArgs.find((arg) => /\s+/.test(arg)) ? util.quote(logArgs) : logArgs.join(' ')) +
501
510
  `'`,
502
511
  );
503
512
  const {stdout: rawStdout, stderr} = (await exec(
@@ -510,10 +519,10 @@ export async function adbExec(this: ADB, cmd: string | string[], opts?: AdbExecO
510
519
  const stdout = rawStdout.replace(LINKER_WARNING_REGEXP, '').trim();
511
520
  return outputFormat === this.EXEC_OUTPUT_FORMAT.FULL ? {stdout, stderr} : stdout;
512
521
  } catch (e: unknown) {
513
- const error = e as ExecError;
522
+ const error = redactExecError(e, this.executable.path, args) as ExecError;
514
523
  const errText = `${error.message}, ${error.stdout}, ${error.stderr}`;
515
524
  if (ADB_RETRY_ERROR_PATTERNS.some((p) => p.test(errText))) {
516
- log.info(`Error sending command, reconnecting device and retrying: ${cmd}`);
525
+ log.info(`Error sending command, reconnecting device and retrying: ${redactSecrets(cmd)}`);
517
526
  await this.getDevicesWithRetry();
518
527
 
519
528
  // try again one time
@@ -589,7 +598,7 @@ export async function shell(this: ADB, cmd: string | string[], opts?: ShellExecO
589
598
  const cmdArr = Array.isArray(cmd) ? cmd : [cmd];
590
599
  const fullCmd: string[] = ['shell'];
591
600
  if (privileged) {
592
- log.info(`'adb shell ${util.quote(cmdArr)}' requires root access`);
601
+ log.info(`'adb shell ${util.quote(redactSecrets(cmdArr))}' requires root access`);
593
602
  if (await this.isRoot()) {
594
603
  log.info('The device already had root access');
595
604
  fullCmd.push(...cmdArr);
@@ -1,5 +1,6 @@
1
1
  export {APKS_EXTENSION, APK_EXTENSION, APK_INSTALL_TIMEOUT, DEFAULT_ADB_EXEC_TIMEOUT} from './constants.js';
2
2
  export {buildInstallArgs, type BuildInstallArgsOptions} from './install.js';
3
+ export {redactExecError, redactSecrets} from './redact.js';
3
4
  export {readPackageManifest} from './manifest.js';
4
5
  export {getResourcePath, unzipFile} from './resource.js';
5
6
  export {getSdkRootFromEnv, requireSdkRoot, getJavaHome, getJavaForOs} from './sdk.js';
@@ -0,0 +1,59 @@
1
+ import {util} from '@appium/support';
2
+
3
+ const SENSITIVE_ARGS = new Set(['--ks-pass', '--key-pass', '-storepass', '-keypass']);
4
+ const LOCK_CREDENTIAL_VERBS = new Set(['verify', 'clear', 'set-pin', 'set-password', 'set-pattern']);
5
+ // Matches a `locksettings` credential command embedded in a single (e.g. `su root "..."`) argument
6
+ const LOCK_COMMAND_RE = /\blocksettings\s+(verify|clear|set-pin|set-password|set-pattern)\b[\s\S]*$/;
7
+ const REDACTED = 'REDACTED';
8
+
9
+ /**
10
+ * Masks secrets in command line arguments (keystore passwords and lock screen credentials)
11
+ * so the result is safe to log.
12
+ *
13
+ * @param args - The command line arguments
14
+ * @returns A copy of the arguments with the secret values replaced
15
+ */
16
+ export function redactSecrets(args: readonly string[]): string[] {
17
+ let isLockCredentialPart = false;
18
+ return args.map((arg, i) => {
19
+ if (isLockCredentialPart) {
20
+ return arg === '--old' ? arg : REDACTED;
21
+ }
22
+ if (args[i - 1] === 'locksettings' && LOCK_CREDENTIAL_VERBS.has(arg)) {
23
+ isLockCredentialPart = true;
24
+ return arg;
25
+ }
26
+ if (i > 0 && SENSITIVE_ARGS.has(args[i - 1])) {
27
+ return REDACTED;
28
+ }
29
+ const [name] = arg.split('=', 1);
30
+ if (SENSITIVE_ARGS.has(name) && arg.includes('=')) {
31
+ return `${name}=${REDACTED}`;
32
+ }
33
+ return arg.replace(LOCK_COMMAND_RE, `locksettings $1 ${REDACTED}`);
34
+ });
35
+ }
36
+
37
+ /**
38
+ * Masks secrets in the message and stack of an error thrown by `teen_process.exec`,
39
+ * which embed the full command line. The error is modified in place.
40
+ *
41
+ * @param err - The caught error
42
+ * @param cmd - The executable passed to `exec`
43
+ * @param args - The arguments passed to `exec`
44
+ * @returns The same error, so it can be rethrown as `throw redactExecError(...)`
45
+ */
46
+ export function redactExecError<T>(err: T, cmd: string, args: readonly string[]): T {
47
+ if (!(err instanceof Error)) {
48
+ return err;
49
+ }
50
+ const rawCmd = util.quote([cmd, ...args]);
51
+ const safeCmd = util.quote(redactSecrets([cmd, ...args]));
52
+ if (rawCmd !== safeCmd) {
53
+ err.message = err.message.split(rawCmd).join(safeCmd);
54
+ if (err.stack) {
55
+ err.stack = err.stack.split(rawCmd).join(safeCmd);
56
+ }
57
+ }
58
+ return err;
59
+ }
@@ -14,6 +14,8 @@ export const getSdkRootFromEnv = helpers.getSdkRootFromEnv;
14
14
  export const requireSdkRoot = helpers.requireSdkRoot;
15
15
  export const getJavaHome = helpers.getJavaHome;
16
16
  export const getJavaForOs = helpers.getJavaForOs;
17
+ export const redactExecError = helpers.redactExecError;
18
+ export const redactSecrets = helpers.redactSecrets;
17
19
 
18
20
  export const memoize = util.memoize;
19
21
  export const cloneDeep = lodash.cloneDeep;
package/package.json CHANGED
@@ -1,16 +1,17 @@
1
1
  {
2
2
  "name": "appium-adb",
3
- "version": "16.0.9",
3
+ "version": "16.1.2",
4
4
  "description": "Android Debug Bridge interface",
5
- "homepage": "https://github.com/appium/appium-adb",
5
+ "homepage": "https://appium.io",
6
6
  "bugs": {
7
- "url": "https://github.com/appium/appium-adb/issues"
7
+ "url": "https://github.com/appium/appium-android/issues"
8
8
  },
9
9
  "license": "Apache-2.0",
10
10
  "author": "Appium Contributors",
11
11
  "repository": {
12
12
  "type": "git",
13
- "url": "https://github.com/appium/appium-adb.git"
13
+ "url": "https://github.com/appium/appium-android.git",
14
+ "directory": "packages/adb"
14
15
  },
15
16
  "bin": {},
16
17
  "directories": {
@@ -20,6 +21,7 @@
20
21
  "keys",
21
22
  "lib",
22
23
  "build/lib",
24
+ "!.DS_Store",
23
25
  "CHANGELOG.md"
24
26
  ],
25
27
  "type": "module",
@@ -36,32 +38,24 @@
36
38
  "build": "tsc -b",
37
39
  "clean": "npm run build -- --clean",
38
40
  "dev": "npm run build -- --watch",
39
- "lint": "oxlint -c oxlint.config.mjs .",
40
- "lint:fix": "oxlint -c oxlint.config.mjs --fix .",
41
- "prepare": "npm run rebuild",
41
+ "prepare": "npm run build",
42
42
  "rebuild": "npm run clean && npm run build",
43
- "format": "oxfmt -c oxfmt.config.mjs .",
44
- "format:check": "oxfmt -c oxfmt.config.mjs --check .",
45
43
  "test": "node --enable-source-maps --experimental-test-module-mocks --test --test-force-exit --test-timeout=60000 \"./build/test/unit/**/*.spec.js\"",
46
- "e2e-test": "node --enable-source-maps --test --test-force-exit --test-concurrency=1 --test-timeout=300000 \"./build/test/functional/**/*.spec.js\""
44
+ "test:e2e": "node --enable-source-maps --test --test-force-exit --test-concurrency=1 --test-timeout=300000 \"./build/test/functional/**/*.spec.js\""
47
45
  },
48
46
  "dependencies": {
49
47
  "@appium/support": "^7.2.6",
50
- "async-lock": "^1.0.0",
51
- "asyncbox": "^6.4.3",
48
+ "asyncbox": "^6.5.0",
52
49
  "ini": "^6.0.0",
53
50
  "lru-cache": "^11.1.0",
54
51
  "semver": "^7.0.0",
55
52
  "teen_process": "^4.2.0"
56
53
  },
57
54
  "devDependencies": {
58
- "@appium/oxc-config": "^1.1.0",
59
- "@appium/semantic-release-config": "^1.1.0",
60
55
  "@appium/tsconfig": "^1.2.0",
61
56
  "@appium/types": "^1.0.0-rc.1",
62
- "@types/async-lock": "^1.4.0",
63
57
  "@types/ini": "^4.1.0",
64
- "@types/node": "^26.0.0",
58
+ "@types/node": "^26.6.5",
65
59
  "@types/semver": "^7.5.0",
66
60
  "@types/sinon": "^22.0.0",
67
61
  "sinon": "^22.0.0"
@@ -69,5 +63,6 @@
69
63
  "engines": {
70
64
  "node": "^20.19.0 || ^22.12.0 || >=24.0.0",
71
65
  "npm": ">=10"
72
- }
66
+ },
67
+ "gitHead": "dd7fac6576be570d54de8ff2874b88426b4446dd"
73
68
  }