diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b9c926..82a6da2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ Upgrading from 1.x: every failure now rejects with a `DocuSignError`. Check any - Bump `adm-zip`, the Config Plugin's only runtime dependency, to 0.6.1. This clears GHSA-xcpc-8h2w-3j85 (high) and GHSA-vwc7-r8mq-g2x9 (moderate) from consumers' `npm audit`. Neither was reachable: the plugin never extracts to disk, and it only parses the AAR it downloaded after checking its SHA-256, or its own cached copy under `node_modules`. - **Android**: the Config Plugin matches the maven repository URL exactly when deciding whether `android/build.gradle` already declares it, and ignores declarations inside `//` and `/* */` comments. The substring check it replaces skipped adding the repository when the URL appeared only in a comment or as the prefix of a longer URL. It was also the CodeQL `js/incomplete-url-substring-sanitization` alert. +- **Android**: the Config Plugin no longer adds a `flatDir` block to `android/build.gradle`, and no longer warns Kotlin Script projects to add one by hand. The module has referenced the stripped `sdk-pdf` AAR by file path since 1.0.4, so the block did nothing. On current Expo templates it was never added anyway, because its pattern could not match the nested `maven { ... }` entry inside `allprojects.repositories`. - **iOS**: the module compiles without warnings under the Swift 6 compiler. Its exception classes restate the `@unchecked Sendable` conformance they inherit from Expo's `Exception`, and a `??` fallback on `DSMManager.defaultConfigurations()`, which never returns nil, is gone. - **iOS**: the view controller to present from is looked up on the main thread. The lookup read `UIApplication.shared` on the background queue the JS call arrived on. - **iOS**: a missing view controller settles the promise once. It previously completed the pending signing slot with a failure and also threw, rejecting the same call twice. diff --git a/README.md b/README.md index e2d1109..33786f0 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,7 @@ The DocuSign native SDKs are **NOT bundled** inside this npm package. They are d ### Android Glide collision workaround -DocuSign's `com.docusign:sdk-pdf:2.1.7` AAR ships a pre-generated `com.bumptech.glide.GeneratedAppGlideModuleImpl.class` that collides at dex time with any other Glide-based library in the host app (notably `expo-image`, `react-native-fast-image`, and similar). To avoid this without redistributing DocuSign's binary, the Expo Config Plugin downloads `sdk-pdf-2.1.7.aar` directly from DocuSign's public Maven during `expo prebuild`, verifies its SHA-256 against a pinned hash, removes the offending class from the AAR's `classes.jar` in-memory, and writes the stripped artifact to `node_modules/react-native-docusign/android/libs/`. The existing flatDir injection picks it up at consumer build time. The download is cached after the first run; corrupted or partial caches are detected and regenerated. SHA mismatch or fetch failure aborts `expo prebuild` with an actionable error rather than silently letting the Android build fail later at the dex step. +DocuSign's `com.docusign:sdk-pdf:2.1.7` AAR ships a pre-generated `com.bumptech.glide.GeneratedAppGlideModuleImpl.class` that collides at dex time with any other Glide-based library in the host app (notably `expo-image`, `react-native-fast-image`, and similar). To avoid this without redistributing DocuSign's binary, the Expo Config Plugin downloads `sdk-pdf-2.1.7.aar` directly from DocuSign's public Maven during `expo prebuild`, verifies its SHA-256 against a pinned hash, removes the offending class from the AAR's `classes.jar` in-memory, and writes the stripped artifact to `node_modules/react-native-docusign/android/libs/`. The module's `android/build.gradle` references it by file path at consumer build time. The download is cached after the first run; corrupted or partial caches are detected and regenerated. SHA mismatch or fetch failure aborts `expo prebuild` with an actionable error rather than silently letting the Android build fail later at the dex step. ### What ships inside this package diff --git a/plugin/src/index.test.ts b/plugin/src/index.test.ts index 183f920..c616776 100644 --- a/plugin/src/index.test.ts +++ b/plugin/src/index.test.ts @@ -65,6 +65,19 @@ describe('withDocuSign android maven repository', () => { ); }); + it('changes build.gradle only by adding the DocuSign repository', async () => { + const original = buildProjectGradle([]); + + const contents = await applyProjectBuildGradleMods(original); + + expect(contents).toBe( + original.replace( + 'allprojects {\n repositories {', + `allprojects {\n repositories {\n maven { url "${DOCUSIGN_REPO}" }`, + ), + ); + }); + it('adds androidMavenRepo instead of the DocuSign repository when provided', async () => { const contents = await applyProjectBuildGradleMods(buildProjectGradle([]), { androidMavenRepo: CUSTOM_REPO, diff --git a/plugin/src/index.ts b/plugin/src/index.ts index e750e2b..d6d6d33 100644 --- a/plugin/src/index.ts +++ b/plugin/src/index.ts @@ -132,53 +132,13 @@ const withDocuSignAndroidMavenRepo: ConfigPlugin = ( }); }; -const FLAT_DIR_MARKER = 'react-native-docusign-stripped-aar-flatdir'; - -const withDocuSignAndroidStrippedAarFlatDir: ConfigPlugin = (config) => - withProjectBuildGradle(config, (cfg) => { - if (cfg.modResults.language !== 'groovy') { - WarningAggregator.addWarningAndroid( - 'react-native-docusign', - 'android/build.gradle is Kotlin Script (.kts); cannot auto-inject the stripped sdk-pdf flatDir. Add this inside allprojects:\n afterEvaluate {\n rootProject.findProject(":react-native-docusign")?.let { docusignProject ->\n repositories { flatDir { dirs("${docusignProject.projectDir}/libs") } }\n }\n }', - ); - return cfg; - } - - if (cfg.modResults.contents.includes(FLAT_DIR_MARKER)) { - return cfg; - } - - const flatDirBlock = ` // ${FLAT_DIR_MARKER}: exposes the stripped sdk-pdf AAR bundled with react-native-docusign. - // The AAR has com.bumptech.glide.GeneratedAppGlideModuleImpl removed to prevent - // duplicate-class collisions with expo-image and other Glide-based libraries. - afterEvaluate { - def docusignProject = rootProject.findProject(':react-native-docusign') - if (docusignProject != null) { - repositories { - flatDir { dirs "\${docusignProject.projectDir}/libs" } - } - } - }`; - - const allprojectsRegex = /(allprojects\s*\{(?:[^{}]|\{[^{}]*\})*)(\n\})/; - if (allprojectsRegex.test(cfg.modResults.contents)) { - cfg.modResults.contents = cfg.modResults.contents.replace( - allprojectsRegex, - `$1\n${flatDirBlock}$2`, - ); - } - - return cfg; - }); - /** * Downloads the upstream `com.docusign:sdk-pdf:2.1.7` AAR from DocuSign's * public Maven repository and strips the pre-generated * `com.bumptech.glide.GeneratedAppGlideModuleImpl` class from its * `classes.jar`. The stripped artifact is written to - * `node_modules/react-native-docusign/android/libs/` so the existing flatDir - * Gradle injection (added by `withDocuSignAndroidStrippedAarFlatDir`) can - * resolve it at consumer build time. + * `node_modules/react-native-docusign/android/libs/`, where the module's + * `android/build.gradle` references it by file path at consumer build time. * * The strip prevents a duplicate-class collision at the consumer's * `mergeDexDebug` / `mergeDexRelease` step when the host app also includes @@ -233,9 +193,8 @@ const withDocuSignAndroidStripDocusignSdkPdf: ConfigPlugin = (config) => withDangerousMod(config, [ 'android', async (cfg) => { - // Resolve the installed package's android/libs/ directory so the - // `flatDir` injection (which references docusignProject.projectDir/libs) - // finds the stripped AAR. + // Resolve the installed package's android/libs/ directory, which the + // module's android/build.gradle references by file path. let packageRoot: string; try { const packageJsonPath = require.resolve( @@ -289,7 +248,6 @@ const withDocuSign: ConfigPlugin = ( updated = withDocuSignAndroidPermissions(updated); updated = withDocuSignAndroidMavenRepo(updated, resolvedProps); updated = withDocuSignAndroidStripDocusignSdkPdf(updated); - updated = withDocuSignAndroidStrippedAarFlatDir(updated); return updated; };