appium-adb 9.10.21 → 9.10.23

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.
@@ -1 +1 @@
1
- {"version":3,"file":"apk-signing.js","names":["DEFAULT_PRIVATE_KEY","path","resolve","getModuleRoot","DEFAULT_CERTIFICATE","BUNDLETOOL_TUTORIAL","APKSIGNER_VERIFY_FAIL","SHA1","SHA256","SHA512","MD5","DEFAULT_CERT_HASH","JAVA_PROPS_INIT_ERROR","SIGNED_APPS_CACHE","LRU","max","apkSigningMethods","executeApksigner","args","apkSignerJar","getApksignerForOs","fullCmd","getJavaForOs","log","debug","util","quote","stdout","stderr","exec","slice","cwd","dirname","windowsVerbatimArguments","system","isWindows","name","stream","_","trim","split","filter","line","includes","join","signWithDefaultCert","apk","fs","exists","Error","e","message","signWithCustomCert","keystorePath","keyAlias","keystorePassword","keyPassword","err","warn","unsignApk","jarsigner","getJavaHome","sign","appPath","endsWith","APKS_EXTENSION","useKeystore","zipAlignApk","initZipAlign","binaries","zipalign","access","_fs","W_OK","alignedApk","tempDir","prefix","suffix","mkdirp","mv","unlink","checkApkCert","pkg","opts","extname","extractBaseApk","hashMatches","apksignerOutput","expectedHashes","value","toPairs","RegExp","test","basename","requireDefaultCert","appHash","hash","has","output","expected","get","getKeystoreHash","hasMatch","info","isSigned","set","errMsg","keytool","result","hashName","hashRe","match","replace","toLowerCase","isEmpty","JSON","stringify"],"sources":["../../../lib/tools/apk-signing.js"],"sourcesContent":["import _ from 'lodash';\nimport _fs from 'fs';\nimport { exec } from 'teen_process';\nimport path from 'path';\nimport log from '../logger.js';\nimport { tempDir, system, mkdirp, fs, util } from '@appium/support';\nimport LRU from 'lru-cache';\nimport {\n getJavaForOs, getApksignerForOs, getJavaHome, getModuleRoot, APKS_EXTENSION, unsignApk,\n} from '../helpers.js';\n\nconst DEFAULT_PRIVATE_KEY = path.resolve(getModuleRoot(), 'keys', 'testkey.pk8');\nconst DEFAULT_CERTIFICATE = path.resolve(getModuleRoot(), 'keys', 'testkey.x509.pem');\nconst BUNDLETOOL_TUTORIAL = 'https://developer.android.com/studio/command-line/bundletool';\nconst APKSIGNER_VERIFY_FAIL = 'DOES NOT VERIFY';\nconst SHA1 = 'sha1';\nconst SHA256 = 'sha256';\nconst SHA512 = 'sha512';\nconst MD5 = 'md5';\nconst DEFAULT_CERT_HASH = {\n [SHA256]: 'a40da80a59d170caa950cf15c18c454d47a39b26989d8b640ecd745ba71bf5dc'\n};\nconst JAVA_PROPS_INIT_ERROR = 'java.lang.Error: Properties init';\nconst SIGNED_APPS_CACHE = new LRU({\n max: 30,\n});\n\n\nconst apkSigningMethods = {};\n\n/**\n * Execute apksigner utility with given arguments.\n *\n * @param {?Array<String>} args - The list of tool arguments.\n * @return {string} - Command stdout\n * @throws {Error} If apksigner binary is not present on the local file system\n * or the return code is not equal to zero.\n */\napkSigningMethods.executeApksigner = async function executeApksigner (args = []) {\n const apkSignerJar = await getApksignerForOs(this);\n const fullCmd = [\n await getJavaForOs(), '-Xmx1024M', '-Xss1m',\n '-jar', apkSignerJar,\n ...args\n ];\n log.debug(`Starting apksigner: ${util.quote(fullCmd)}`);\n // It is necessary to specify CWD explicitly; see https://github.com/appium/appium/issues/14724#issuecomment-737446715\n const {stdout, stderr} = await exec(fullCmd[0], fullCmd.slice(1), {\n cwd: path.dirname(apkSignerJar), windowsVerbatimArguments: system.isWindows()\n });\n for (let [name, stream] of [['stdout', stdout], ['stderr', stderr]]) {\n if (!_.trim(stream)) {\n continue;\n }\n\n if (name === 'stdout') {\n // Make the output less talkative\n stream = stream.split('\\n')\n .filter((line) => !line.includes('WARNING:'))\n .join('\\n');\n }\n log.debug(`apksigner ${name}: ${stream}`);\n }\n return stdout;\n};\n\n/**\n * (Re)sign the given apk file on the local file system with the default certificate.\n *\n * @param {string} apk - The full path to the local apk file.\n * @throws {Error} If signing fails.\n */\napkSigningMethods.signWithDefaultCert = async function signWithDefaultCert (apk) {\n log.debug(`Signing '${apk}' with default cert`);\n if (!(await fs.exists(apk))) {\n throw new Error(`${apk} file doesn't exist.`);\n }\n\n const args = [\n 'sign',\n '--key', DEFAULT_PRIVATE_KEY,\n '--cert', DEFAULT_CERTIFICATE,\n apk,\n ];\n try {\n await this.executeApksigner(args);\n } catch (e) {\n throw new Error(`Could not sign '${apk}' with the default certificate. ` +\n `Original error: ${e.stderr || e.stdout || e.message}`);\n }\n};\n\n/**\n * (Re)sign the given apk file on the local file system with a custom certificate.\n *\n * @param {string} apk - The full path to the local apk file.\n * @throws {Error} If signing fails.\n */\napkSigningMethods.signWithCustomCert = async function signWithCustomCert (apk) {\n log.debug(`Signing '${apk}' with custom cert`);\n if (!(await fs.exists(this.keystorePath))) {\n throw new Error(`Keystore: ${this.keystorePath} doesn't exist.`);\n }\n if (!(await fs.exists(apk))) {\n throw new Error(`'${apk}' doesn't exist.`);\n }\n\n try {\n await this.executeApksigner(['sign',\n '--ks', this.keystorePath,\n '--ks-key-alias', this.keyAlias,\n '--ks-pass', `pass:${this.keystorePassword}`,\n '--key-pass', `pass:${this.keyPassword}`,\n apk]);\n } catch (err) {\n log.warn(`Cannot use apksigner tool for signing. Defaulting to jarsigner. ` +\n `Original error: ${err.stderr || err.stdout || err.message}`);\n try {\n if (await unsignApk(apk)) {\n log.debug(`'${apk}' has been successfully unsigned`);\n } else {\n log.debug(`'${apk}' does not need to be unsigned`);\n }\n const jarsigner = path.resolve(await getJavaHome(), 'bin',\n `jarsigner${system.isWindows() ? '.exe' : ''}`);\n const fullCmd = [jarsigner,\n '-sigalg', 'MD5withRSA',\n '-digestalg', 'SHA1',\n '-keystore', this.keystorePath,\n '-storepass', this.keystorePassword,\n '-keypass', this.keyPassword,\n apk, this.keyAlias];\n log.debug(`Starting jarsigner: ${util.quote(fullCmd)}`);\n await exec(fullCmd[0], fullCmd.slice(1), { windowsVerbatimArguments: system.isWindows() });\n } catch (e) {\n throw new Error(`Could not sign with custom certificate. ` +\n `Original error: ${e.stderr || e.message}`);\n }\n }\n};\n\n/**\n * (Re)sign the given apk file on the local file system with either\n * custom or default certificate based on _this.useKeystore_ property value\n * and Zip-aligns it after signing.\n *\n * @param {string} appPath - The full path to the local .apk(s) file.\n * @throws {Error} If signing fails.\n */\napkSigningMethods.sign = async function sign (appPath) {\n if (appPath.endsWith(APKS_EXTENSION)) {\n let message = 'Signing of .apks-files is not supported. ';\n if (this.useKeystore) {\n message += 'Consider manual application bundle signing with the custom keystore ' +\n `like it is described at ${BUNDLETOOL_TUTORIAL}`;\n } else {\n message += `Consider manual application bundle signing with the key at '${DEFAULT_PRIVATE_KEY}' ` +\n `and the certificate at '${DEFAULT_CERTIFICATE}'. Read ${BUNDLETOOL_TUTORIAL} for more details.`;\n }\n log.warn(message);\n return;\n }\n\n // it is necessary to apply zipalign only before signing\n // if apksigner is used\n await this.zipAlignApk(appPath);\n\n if (this.useKeystore) {\n await this.signWithCustomCert(appPath);\n } else {\n await this.signWithDefaultCert(appPath);\n }\n};\n\n/**\n * Perform zip-aligning to the given local apk file.\n *\n * @param {string} apk - The full path to the local apk file.\n * @returns {boolean} True if the apk has been successfully aligned\n * or false if the apk has been already aligned.\n * @throws {Error} If zip-align fails.\n */\napkSigningMethods.zipAlignApk = async function zipAlignApk (apk) {\n await this.initZipAlign();\n try {\n await exec(this.binaries.zipalign, ['-c', '4', apk]);\n log.debug(`${apk}' is already zip-aligned. Doing nothing`);\n return false;\n } catch (e) {\n log.debug(`'${apk}' is not zip-aligned. Aligning`);\n }\n try {\n await fs.access(apk, _fs.W_OK);\n } catch (e) {\n throw new Error(`The file at '${apk}' is not writeable. ` +\n `Please grant write permissions to this file or to its parent folder '${path.dirname(apk)}' ` +\n `for the Appium process, so it can zip-align the file`);\n }\n const alignedApk = await tempDir.path({prefix: 'appium', suffix: '.tmp'});\n await mkdirp(path.dirname(alignedApk));\n try {\n await exec(this.binaries.zipalign, ['-f', '4', apk, alignedApk]);\n await fs.mv(alignedApk, apk, { mkdirp: true });\n return true;\n } catch (e) {\n if (await fs.exists(alignedApk)) {\n await fs.unlink(alignedApk);\n }\n throw new Error(`zipAlignApk failed. Original error: ${e.stderr || e.message}`);\n }\n};\n\n/**\n * @typedef {Object} CertCheckOptions\n * @property {boolean} requireDefaultCert [true] Whether to require that the destination APK\n * is signed with the default Appium certificate or any valid certificate. This option\n * only has effect if `useKeystore` property is unset.\n */\n\n/**\n * Check if the app is already signed with the default Appium certificate.\n *\n * @param {string} appPath - The full path to the local .apk(s) file.\n * @param {string} pgk - The name of application package.\n * @param {CertCheckOptions} opts - Certificate checking options\n * @return {boolean} True if given application is already signed.\n */\napkSigningMethods.checkApkCert = async function checkApkCert (appPath, pkg, opts = {}) {\n log.debug(`Checking app cert for ${appPath}`);\n if (!await fs.exists(appPath)) {\n log.debug(`'${appPath}' does not exist`);\n return false;\n }\n\n if (path.extname(appPath) === APKS_EXTENSION) {\n appPath = await this.extractBaseApk(appPath);\n }\n\n const hashMatches = (apksignerOutput, expectedHashes) => {\n for (const [name, value] of _.toPairs(expectedHashes)) {\n if (new RegExp(`digest:\\\\s+${value}\\\\b`, 'i').test(apksignerOutput)) {\n log.debug(`${name} hash did match for '${path.basename(appPath)}'`);\n return true;\n }\n }\n return false;\n };\n\n const {\n requireDefaultCert = true,\n } = opts;\n\n const appHash = await fs.hash(appPath);\n if (SIGNED_APPS_CACHE.has(appHash)) {\n log.debug(`Using the previously cached signature entry for '${path.basename(appPath)}'`);\n const {keystorePath, output, expected} = SIGNED_APPS_CACHE.get(appHash);\n if (this.useKeystore && this.keystorePath === keystorePath || !this.useKeystore) {\n return (!this.useKeystore && !requireDefaultCert) || hashMatches(output, expected);\n }\n }\n\n const expected = this.useKeystore\n ? await this.getKeystoreHash(appPath, pkg)\n : DEFAULT_CERT_HASH;\n try {\n await getApksignerForOs(this);\n const output = await this.executeApksigner(['verify', '--print-certs', appPath]);\n const hasMatch = hashMatches(output, expected);\n if (hasMatch) {\n log.info(`'${appPath}' is signed with the ` +\n `${this.useKeystore ? 'keystore' : 'default'} certificate`);\n } else {\n log.info(`'${appPath}' is signed with a ` +\n `non-${this.useKeystore ? 'keystore' : 'default'} certificate`);\n }\n const isSigned = (!this.useKeystore && !requireDefaultCert) || hasMatch;\n if (isSigned) {\n SIGNED_APPS_CACHE.set(appHash, {\n output,\n expected,\n keystorePath: this.keystorePath,\n });\n }\n return isSigned;\n } catch (err) {\n // check if there is no signature\n if (_.includes(err.stderr, APKSIGNER_VERIFY_FAIL)) {\n log.info(`'${appPath}' is not signed`);\n return false;\n }\n const errMsg = err.stderr || err.stdout || err.message;\n if (_.includes(errMsg, JAVA_PROPS_INIT_ERROR)) {\n // This error pops up randomly and we are not quite sure why.\n // My guess - a race condition in java vm initialization.\n // Nevertheless, lets make Appium to believe the file is already signed,\n // because it would be true for 99% of UIAutomator2-based\n // tests, where we presign server binaries while publishing their NPM module.\n // If these are not signed, e.g. in case of Espresso, then the next step(s)\n // would anyway fail.\n // See https://github.com/appium/appium/issues/14724 for more details.\n log.warn(errMsg);\n log.warn(`Assuming '${appPath}' is already signed and continuing anyway`);\n return true;\n }\n throw new Error(`Cannot verify the signature of '${appPath}'. ` +\n `Original error: ${errMsg}`);\n }\n};\n\n/**\n * @typedef {Object} KeystoreHash\n * @property {?string} md5 the md5 hash value of the keystore\n * @property {?string} sha1 the sha1 hash value of the keystore\n * @property {?string} sha256 the sha256 hash value of the keystore\n * @property {?string} sha512 the sha512 hash value of the keystore\n */\n\n/**\n * Retrieve the the hash of the given keystore.\n *\n * @return {KeystoreHash}\n * @throws {Error} If getting keystore hash fails.\n */\napkSigningMethods.getKeystoreHash = async function getKeystoreHash () {\n log.debug(`Getting hash of the '${this.keystorePath}' keystore`);\n const keytool = path.resolve(await getJavaHome(), 'bin',\n `keytool${system.isWindows() ? '.exe' : ''}`);\n if (!await fs.exists(keytool)) {\n throw new Error(`The keytool utility cannot be found at '${keytool}'`);\n }\n const args = [\n '-v', '-list',\n '-alias', this.keyAlias,\n '-keystore', this.keystorePath,\n '-storepass', this.keystorePassword\n ];\n log.info(`Running '${keytool}' with arguments: ${util.quote(args)}`);\n try {\n const {stdout} = await exec(keytool, args, { windowsVerbatimArguments: system.isWindows() });\n const result = {};\n for (const hashName of [SHA512, SHA256, SHA1, MD5]) {\n const hashRe = new RegExp(`^\\\\s*${hashName}:\\\\s*([a-f0-9:]+)`, 'mi');\n const match = hashRe.exec(stdout);\n if (!match) {\n continue;\n }\n result[hashName] = match[1].replace(/:/g, '').toLowerCase();\n }\n if (_.isEmpty(result)) {\n log.debug(stdout);\n throw new Error('Cannot parse the hash value from the keytool output');\n }\n log.debug(`Keystore hash: ${JSON.stringify(result)}`);\n return result;\n } catch (e) {\n throw new Error(`Cannot get the hash of '${this.keystorePath}' keystore. ` +\n `Original error: ${e.stderr || e.message}`);\n }\n};\n\nexport default apkSigningMethods;\n"],"mappings":"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"}
1
+ {"version":3,"file":"apk-signing.js","names":["DEFAULT_PRIVATE_KEY","path","join","DEFAULT_CERTIFICATE","BUNDLETOOL_TUTORIAL","APKSIGNER_VERIFY_FAIL","SHA1","SHA256","SHA512","MD5","DEFAULT_CERT_HASH","JAVA_PROPS_INIT_ERROR","SIGNED_APPS_CACHE","LRU","max","apkSigningMethods","executeApksigner","args","apkSignerJar","getApksignerForOs","fullCmd","getJavaForOs","log","debug","util","quote","stdout","stderr","exec","slice","cwd","dirname","windowsVerbatimArguments","system","isWindows","name","stream","_","trim","split","filter","line","includes","signWithDefaultCert","apk","fs","exists","Error","getResourcePath","e","message","signWithCustomCert","keystorePath","keyAlias","keystorePassword","keyPassword","err","warn","unsignApk","jarsigner","resolve","getJavaHome","sign","appPath","endsWith","APKS_EXTENSION","useKeystore","zipAlignApk","initZipAlign","binaries","zipalign","access","_fs","W_OK","alignedApk","tempDir","prefix","suffix","mkdirp","mv","unlink","checkApkCert","pkg","opts","extname","extractBaseApk","hashMatches","apksignerOutput","expectedHashes","value","toPairs","RegExp","test","basename","requireDefaultCert","appHash","hash","has","output","expected","get","getKeystoreHash","hasMatch","info","isSigned","set","errMsg","keytool","result","hashName","hashRe","match","replace","toLowerCase","isEmpty","JSON","stringify"],"sources":["../../../lib/tools/apk-signing.js"],"sourcesContent":["import _ from 'lodash';\nimport _fs from 'fs';\nimport { exec } from 'teen_process';\nimport path from 'path';\nimport log from '../logger.js';\nimport { tempDir, system, mkdirp, fs, util } from '@appium/support';\nimport LRU from 'lru-cache';\nimport {\n getJavaForOs, getApksignerForOs, getJavaHome, getResourcePath, APKS_EXTENSION, unsignApk,\n} from '../helpers.js';\n\nconst DEFAULT_PRIVATE_KEY = path.join('keys', 'testkey.pk8');\nconst DEFAULT_CERTIFICATE = path.join('keys', 'testkey.x509.pem');\nconst BUNDLETOOL_TUTORIAL = 'https://developer.android.com/studio/command-line/bundletool';\nconst APKSIGNER_VERIFY_FAIL = 'DOES NOT VERIFY';\nconst SHA1 = 'sha1';\nconst SHA256 = 'sha256';\nconst SHA512 = 'sha512';\nconst MD5 = 'md5';\nconst DEFAULT_CERT_HASH = {\n [SHA256]: 'a40da80a59d170caa950cf15c18c454d47a39b26989d8b640ecd745ba71bf5dc'\n};\nconst JAVA_PROPS_INIT_ERROR = 'java.lang.Error: Properties init';\nconst SIGNED_APPS_CACHE = new LRU({\n max: 30,\n});\n\n\nconst apkSigningMethods = {};\n\n/**\n * Execute apksigner utility with given arguments.\n *\n * @param {?Array<String>} args - The list of tool arguments.\n * @return {string} - Command stdout\n * @throws {Error} If apksigner binary is not present on the local file system\n * or the return code is not equal to zero.\n */\napkSigningMethods.executeApksigner = async function executeApksigner (args = []) {\n const apkSignerJar = await getApksignerForOs(this);\n const fullCmd = [\n await getJavaForOs(), '-Xmx1024M', '-Xss1m',\n '-jar', apkSignerJar,\n ...args\n ];\n log.debug(`Starting apksigner: ${util.quote(fullCmd)}`);\n // It is necessary to specify CWD explicitly; see https://github.com/appium/appium/issues/14724#issuecomment-737446715\n const {stdout, stderr} = await exec(fullCmd[0], fullCmd.slice(1), {\n cwd: path.dirname(apkSignerJar), windowsVerbatimArguments: system.isWindows()\n });\n for (let [name, stream] of [['stdout', stdout], ['stderr', stderr]]) {\n if (!_.trim(stream)) {\n continue;\n }\n\n if (name === 'stdout') {\n // Make the output less talkative\n stream = stream.split('\\n')\n .filter((line) => !line.includes('WARNING:'))\n .join('\\n');\n }\n log.debug(`apksigner ${name}: ${stream}`);\n }\n return stdout;\n};\n\n/**\n * (Re)sign the given apk file on the local file system with the default certificate.\n *\n * @param {string} apk - The full path to the local apk file.\n * @throws {Error} If signing fails.\n */\napkSigningMethods.signWithDefaultCert = async function signWithDefaultCert (apk) {\n log.debug(`Signing '${apk}' with default cert`);\n if (!(await fs.exists(apk))) {\n throw new Error(`${apk} file doesn't exist.`);\n }\n\n const args = [\n 'sign',\n '--key', await getResourcePath(DEFAULT_PRIVATE_KEY),\n '--cert', await getResourcePath(DEFAULT_CERTIFICATE),\n apk,\n ];\n try {\n await this.executeApksigner(args);\n } catch (e) {\n throw new Error(`Could not sign '${apk}' with the default certificate. ` +\n `Original error: ${e.stderr || e.stdout || e.message}`);\n }\n};\n\n/**\n * (Re)sign the given apk file on the local file system with a custom certificate.\n *\n * @param {string} apk - The full path to the local apk file.\n * @throws {Error} If signing fails.\n */\napkSigningMethods.signWithCustomCert = async function signWithCustomCert (apk) {\n log.debug(`Signing '${apk}' with custom cert`);\n if (!(await fs.exists(this.keystorePath))) {\n throw new Error(`Keystore: ${this.keystorePath} doesn't exist.`);\n }\n if (!(await fs.exists(apk))) {\n throw new Error(`'${apk}' doesn't exist.`);\n }\n\n try {\n await this.executeApksigner(['sign',\n '--ks', this.keystorePath,\n '--ks-key-alias', this.keyAlias,\n '--ks-pass', `pass:${this.keystorePassword}`,\n '--key-pass', `pass:${this.keyPassword}`,\n apk]);\n } catch (err) {\n log.warn(`Cannot use apksigner tool for signing. Defaulting to jarsigner. ` +\n `Original error: ${err.stderr || err.stdout || err.message}`);\n try {\n if (await unsignApk(apk)) {\n log.debug(`'${apk}' has been successfully unsigned`);\n } else {\n log.debug(`'${apk}' does not need to be unsigned`);\n }\n const jarsigner = path.resolve(await getJavaHome(), 'bin',\n `jarsigner${system.isWindows() ? '.exe' : ''}`);\n const fullCmd = [jarsigner,\n '-sigalg', 'MD5withRSA',\n '-digestalg', 'SHA1',\n '-keystore', this.keystorePath,\n '-storepass', this.keystorePassword,\n '-keypass', this.keyPassword,\n apk, this.keyAlias];\n log.debug(`Starting jarsigner: ${util.quote(fullCmd)}`);\n await exec(fullCmd[0], fullCmd.slice(1), { windowsVerbatimArguments: system.isWindows() });\n } catch (e) {\n throw new Error(`Could not sign with custom certificate. ` +\n `Original error: ${e.stderr || e.message}`);\n }\n }\n};\n\n/**\n * (Re)sign the given apk file on the local file system with either\n * custom or default certificate based on _this.useKeystore_ property value\n * and Zip-aligns it after signing.\n *\n * @param {string} appPath - The full path to the local .apk(s) file.\n * @throws {Error} If signing fails.\n */\napkSigningMethods.sign = async function sign (appPath) {\n if (appPath.endsWith(APKS_EXTENSION)) {\n let message = 'Signing of .apks-files is not supported. ';\n if (this.useKeystore) {\n message += 'Consider manual application bundle signing with the custom keystore ' +\n `like it is described at ${BUNDLETOOL_TUTORIAL}`;\n } else {\n message += `Consider manual application bundle signing with the key at '${DEFAULT_PRIVATE_KEY}' ` +\n `and the certificate at '${DEFAULT_CERTIFICATE}'. Read ${BUNDLETOOL_TUTORIAL} for more details.`;\n }\n log.warn(message);\n return;\n }\n\n // it is necessary to apply zipalign only before signing\n // if apksigner is used\n await this.zipAlignApk(appPath);\n\n if (this.useKeystore) {\n await this.signWithCustomCert(appPath);\n } else {\n await this.signWithDefaultCert(appPath);\n }\n};\n\n/**\n * Perform zip-aligning to the given local apk file.\n *\n * @param {string} apk - The full path to the local apk file.\n * @returns {boolean} True if the apk has been successfully aligned\n * or false if the apk has been already aligned.\n * @throws {Error} If zip-align fails.\n */\napkSigningMethods.zipAlignApk = async function zipAlignApk (apk) {\n await this.initZipAlign();\n try {\n await exec(this.binaries.zipalign, ['-c', '4', apk]);\n log.debug(`${apk}' is already zip-aligned. Doing nothing`);\n return false;\n } catch (e) {\n log.debug(`'${apk}' is not zip-aligned. Aligning`);\n }\n try {\n await fs.access(apk, _fs.W_OK);\n } catch (e) {\n throw new Error(`The file at '${apk}' is not writeable. ` +\n `Please grant write permissions to this file or to its parent folder '${path.dirname(apk)}' ` +\n `for the Appium process, so it can zip-align the file`);\n }\n const alignedApk = await tempDir.path({prefix: 'appium', suffix: '.tmp'});\n await mkdirp(path.dirname(alignedApk));\n try {\n await exec(this.binaries.zipalign, ['-f', '4', apk, alignedApk]);\n await fs.mv(alignedApk, apk, { mkdirp: true });\n return true;\n } catch (e) {\n if (await fs.exists(alignedApk)) {\n await fs.unlink(alignedApk);\n }\n throw new Error(`zipAlignApk failed. Original error: ${e.stderr || e.message}`);\n }\n};\n\n/**\n * @typedef {Object} CertCheckOptions\n * @property {boolean} requireDefaultCert [true] Whether to require that the destination APK\n * is signed with the default Appium certificate or any valid certificate. This option\n * only has effect if `useKeystore` property is unset.\n */\n\n/**\n * Check if the app is already signed with the default Appium certificate.\n *\n * @param {string} appPath - The full path to the local .apk(s) file.\n * @param {string} pgk - The name of application package.\n * @param {CertCheckOptions} opts - Certificate checking options\n * @return {boolean} True if given application is already signed.\n */\napkSigningMethods.checkApkCert = async function checkApkCert (appPath, pkg, opts = {}) {\n log.debug(`Checking app cert for ${appPath}`);\n if (!await fs.exists(appPath)) {\n log.debug(`'${appPath}' does not exist`);\n return false;\n }\n\n if (path.extname(appPath) === APKS_EXTENSION) {\n appPath = await this.extractBaseApk(appPath);\n }\n\n const hashMatches = (apksignerOutput, expectedHashes) => {\n for (const [name, value] of _.toPairs(expectedHashes)) {\n if (new RegExp(`digest:\\\\s+${value}\\\\b`, 'i').test(apksignerOutput)) {\n log.debug(`${name} hash did match for '${path.basename(appPath)}'`);\n return true;\n }\n }\n return false;\n };\n\n const {\n requireDefaultCert = true,\n } = opts;\n\n const appHash = await fs.hash(appPath);\n if (SIGNED_APPS_CACHE.has(appHash)) {\n log.debug(`Using the previously cached signature entry for '${path.basename(appPath)}'`);\n const {keystorePath, output, expected} = SIGNED_APPS_CACHE.get(appHash);\n if (this.useKeystore && this.keystorePath === keystorePath || !this.useKeystore) {\n return (!this.useKeystore && !requireDefaultCert) || hashMatches(output, expected);\n }\n }\n\n const expected = this.useKeystore\n ? await this.getKeystoreHash(appPath, pkg)\n : DEFAULT_CERT_HASH;\n try {\n await getApksignerForOs(this);\n const output = await this.executeApksigner(['verify', '--print-certs', appPath]);\n const hasMatch = hashMatches(output, expected);\n if (hasMatch) {\n log.info(`'${appPath}' is signed with the ` +\n `${this.useKeystore ? 'keystore' : 'default'} certificate`);\n } else {\n log.info(`'${appPath}' is signed with a ` +\n `non-${this.useKeystore ? 'keystore' : 'default'} certificate`);\n }\n const isSigned = (!this.useKeystore && !requireDefaultCert) || hasMatch;\n if (isSigned) {\n SIGNED_APPS_CACHE.set(appHash, {\n output,\n expected,\n keystorePath: this.keystorePath,\n });\n }\n return isSigned;\n } catch (err) {\n // check if there is no signature\n if (_.includes(err.stderr, APKSIGNER_VERIFY_FAIL)) {\n log.info(`'${appPath}' is not signed`);\n return false;\n }\n const errMsg = err.stderr || err.stdout || err.message;\n if (_.includes(errMsg, JAVA_PROPS_INIT_ERROR)) {\n // This error pops up randomly and we are not quite sure why.\n // My guess - a race condition in java vm initialization.\n // Nevertheless, lets make Appium to believe the file is already signed,\n // because it would be true for 99% of UIAutomator2-based\n // tests, where we presign server binaries while publishing their NPM module.\n // If these are not signed, e.g. in case of Espresso, then the next step(s)\n // would anyway fail.\n // See https://github.com/appium/appium/issues/14724 for more details.\n log.warn(errMsg);\n log.warn(`Assuming '${appPath}' is already signed and continuing anyway`);\n return true;\n }\n throw new Error(`Cannot verify the signature of '${appPath}'. ` +\n `Original error: ${errMsg}`);\n }\n};\n\n/**\n * @typedef {Object} KeystoreHash\n * @property {?string} md5 the md5 hash value of the keystore\n * @property {?string} sha1 the sha1 hash value of the keystore\n * @property {?string} sha256 the sha256 hash value of the keystore\n * @property {?string} sha512 the sha512 hash value of the keystore\n */\n\n/**\n * Retrieve the the hash of the given keystore.\n *\n * @return {KeystoreHash}\n * @throws {Error} If getting keystore hash fails.\n */\napkSigningMethods.getKeystoreHash = async function getKeystoreHash () {\n log.debug(`Getting hash of the '${this.keystorePath}' keystore`);\n const keytool = path.resolve(await getJavaHome(), 'bin',\n `keytool${system.isWindows() ? '.exe' : ''}`);\n if (!await fs.exists(keytool)) {\n throw new Error(`The keytool utility cannot be found at '${keytool}'`);\n }\n const args = [\n '-v', '-list',\n '-alias', this.keyAlias,\n '-keystore', this.keystorePath,\n '-storepass', this.keystorePassword\n ];\n log.info(`Running '${keytool}' with arguments: ${util.quote(args)}`);\n try {\n const {stdout} = await exec(keytool, args, { windowsVerbatimArguments: system.isWindows() });\n const result = {};\n for (const hashName of [SHA512, SHA256, SHA1, MD5]) {\n const hashRe = new RegExp(`^\\\\s*${hashName}:\\\\s*([a-f0-9:]+)`, 'mi');\n const match = hashRe.exec(stdout);\n if (!match) {\n continue;\n }\n result[hashName] = match[1].replace(/:/g, '').toLowerCase();\n }\n if (_.isEmpty(result)) {\n log.debug(stdout);\n throw new Error('Cannot parse the hash value from the keytool output');\n }\n log.debug(`Keystore hash: ${JSON.stringify(result)}`);\n return result;\n } catch (e) {\n throw new Error(`Cannot get the hash of '${this.keystorePath}' keystore. ` +\n `Original error: ${e.stderr || e.message}`);\n }\n};\n\nexport default apkSigningMethods;\n"],"mappings":"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"}
package/lib/helpers.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import path from 'path';
2
- import { system, fs, zip, util, tempDir, node } from '@appium/support';
2
+ import { system, fs, zip, util, tempDir } from '@appium/support';
3
3
  import log from './logger.js';
4
4
  import _ from 'lodash';
5
5
  import B from 'bluebird';
@@ -16,17 +16,46 @@ const LAUNCHER_CATEGORY = 'android.intent.category.LAUNCHER';
16
16
  const MODULE_NAME = 'appium-adb';
17
17
 
18
18
  /**
19
- * Calculates the path to the current module's root folder
19
+ * Calculates the absolute path to the current module's root folder
20
20
  *
21
- * @returns {string} The full path to module root
21
+ * @returns {Promise<string>} The full path to module root
22
22
  * @throws {Error} If the current module root folder cannot be determined
23
23
  */
24
- const getModuleRoot = _.memoize(function getModuleRoot () {
25
- const root = node.getModuleRootSync(MODULE_NAME, __filename);
26
- if (!root) {
24
+ const getModuleRoot = _.memoize(async function getModuleRoot () {
25
+ let moduleRoot = path.dirname(path.resolve(__filename));
26
+ let isAtFsRoot = false;
27
+ while (!isAtFsRoot) {
28
+ const manifestPath = path.join(moduleRoot, 'package.json');
29
+ try {
30
+ if (await fs.exists(manifestPath) &&
31
+ JSON.parse(await fs.readFile(manifestPath, 'utf8')).name === MODULE_NAME) {
32
+ return moduleRoot;
33
+ }
34
+ } catch (ign) {}
35
+ moduleRoot = path.dirname(moduleRoot);
36
+ isAtFsRoot = moduleRoot.length <= path.dirname(moduleRoot).length;
37
+ }
38
+ if (isAtFsRoot) {
27
39
  throw new Error(`Cannot find the root folder of the ${MODULE_NAME} Node.js module`);
28
40
  }
29
- return root;
41
+ return moduleRoot;
42
+ });
43
+
44
+ /**
45
+ * Calculates the absolsute path to the given resource
46
+ *
47
+ * @param {string} relPath Relative path to the resource starting from the current module root
48
+ * @returns {Promise<string>} The full path to the resource
49
+ * @throws {Error} If the absolute resource path cannot be determined
50
+ */
51
+ const getResourcePath = _.memoize(async function getResourcePath (relPath) {
52
+ const moduleRoot = await getModuleRoot();
53
+ const resultPath = path.resolve(moduleRoot, relPath);
54
+ if (!await fs.exists(resultPath)) {
55
+ throw new Error(`Cannot find the resource '${relPath}' under the '${moduleRoot}' ` +
56
+ `folder of ${MODULE_NAME} Node.js module`);
57
+ }
58
+ return resultPath;
30
59
  });
31
60
 
32
61
  /**
@@ -1049,5 +1078,5 @@ export {
1049
1078
  DEFAULT_ADB_EXEC_TIMEOUT, parseManifest, parseAaptStrings, parseAapt2Strings,
1050
1079
  formatConfigMarker, parseJsonData, unsignApk, toAvdLocaleArgs, requireSdkRoot,
1051
1080
  getSdkRootFromEnv, getAndroidPrefsRoot, dirExists, escapeShellArg,
1052
- parseLaunchableActivityNames, matchComponentName, getModuleRoot
1081
+ parseLaunchableActivityNames, matchComponentName, getResourcePath
1053
1082
  };
@@ -6,11 +6,11 @@ import log from '../logger.js';
6
6
  import { tempDir, system, mkdirp, fs, util } from '@appium/support';
7
7
  import LRU from 'lru-cache';
8
8
  import {
9
- getJavaForOs, getApksignerForOs, getJavaHome, getModuleRoot, APKS_EXTENSION, unsignApk,
9
+ getJavaForOs, getApksignerForOs, getJavaHome, getResourcePath, APKS_EXTENSION, unsignApk,
10
10
  } from '../helpers.js';
11
11
 
12
- const DEFAULT_PRIVATE_KEY = path.resolve(getModuleRoot(), 'keys', 'testkey.pk8');
13
- const DEFAULT_CERTIFICATE = path.resolve(getModuleRoot(), 'keys', 'testkey.x509.pem');
12
+ const DEFAULT_PRIVATE_KEY = path.join('keys', 'testkey.pk8');
13
+ const DEFAULT_CERTIFICATE = path.join('keys', 'testkey.x509.pem');
14
14
  const BUNDLETOOL_TUTORIAL = 'https://developer.android.com/studio/command-line/bundletool';
15
15
  const APKSIGNER_VERIFY_FAIL = 'DOES NOT VERIFY';
16
16
  const SHA1 = 'sha1';
@@ -78,8 +78,8 @@ apkSigningMethods.signWithDefaultCert = async function signWithDefaultCert (apk)
78
78
 
79
79
  const args = [
80
80
  'sign',
81
- '--key', DEFAULT_PRIVATE_KEY,
82
- '--cert', DEFAULT_CERTIFICATE,
81
+ '--key', await getResourcePath(DEFAULT_PRIVATE_KEY),
82
+ '--cert', await getResourcePath(DEFAULT_CERTIFICATE),
83
83
  apk,
84
84
  ];
85
85
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appium-adb",
3
- "version": "9.10.21",
3
+ "version": "9.10.23",
4
4
  "description": "Android Debug Bridge interface",
5
5
  "main": "./build/index.js",
6
6
  "scripts": {
@@ -93,7 +93,7 @@
93
93
  "mocha": "^10.0.0",
94
94
  "pre-commit": "^1.1.3",
95
95
  "prettier": "^2.7.1",
96
- "rimraf": "^3.0.2",
96
+ "rimraf": "^4.0.4",
97
97
  "semantic-release": "^19.0.2",
98
98
  "sinon": "^15.0.0",
99
99
  "temp": "^0.x"