├── .azurepipelines ├── build-rn-code-push-1es.yml └── test-rn-code-push.yml ├── .config └── CredScanSuppressions.json ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE.md └── policies │ └── resourceManagement.yml ├── .gitignore ├── .node-version ├── .npmignore ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── .watchmanconfig ├── AlertAdapter.js ├── CONTRIBUTING.md ├── CodePush.js ├── CodePush.podspec ├── Examples ├── CodePushDemoApp │ ├── .buckconfig │ ├── .editorconfig │ ├── .eslintrc.js │ ├── .flowconfig │ ├── .gitattributes │ ├── .gitignore │ ├── .prettierrc.js │ ├── .watchmanconfig │ ├── App.js │ ├── __tests__ │ │ └── App-test.js │ ├── android │ │ ├── app │ │ │ ├── BUCK │ │ │ ├── build.gradle │ │ │ ├── build_defs.bzl │ │ │ ├── debug.keystore │ │ │ ├── proguard-rules.pro │ │ │ └── src │ │ │ │ └── main │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── codepushdemoapp │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ └── MainApplication.java │ │ │ │ └── res │ │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ └── values │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ ├── build.gradle │ │ ├── gradle.properties │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ └── settings.gradle │ ├── app.json │ ├── babel.config.js │ ├── images │ │ └── laptop_phone_howitworks.png │ ├── index.js │ ├── ios │ │ ├── CodePushDemoApp.xcodeproj │ │ │ ├── project.pbxproj │ │ │ └── xcshareddata │ │ │ │ └── xcschemes │ │ │ │ └── CodePushDemoApp.xcscheme │ │ ├── CodePushDemoApp.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── CodePushDemoApp │ │ │ ├── AppDelegate.h │ │ │ ├── AppDelegate.m │ │ │ ├── Images.xcassets │ │ │ │ ├── AppIcon.appiconset │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ ├── Info.plist │ │ │ ├── LaunchScreen.storyboard │ │ │ └── main.m │ │ ├── CodePushDemoAppTests │ │ │ ├── CodePushDemoAppTests.m │ │ │ └── Info.plist │ │ ├── Podfile │ │ └── Podfile.lock │ ├── metro.config.js │ ├── package-lock.json │ └── package.json ├── CodePushDemoAppCpp │ ├── .buckconfig │ ├── .eslintrc.js │ ├── .flowconfig │ ├── .gitattributes │ ├── .gitignore │ ├── .prettierrc.js │ ├── .watchmanconfig │ ├── App.js │ ├── app.json │ ├── babel.config.js │ ├── images │ │ └── laptop_phone_howitworks.png │ ├── index.js │ ├── metro.config.js │ ├── package-lock.json │ ├── package.json │ └── windows │ │ ├── .gitignore │ │ ├── CodePushDemoAppCpp.sln │ │ └── CodePushDemoAppCpp │ │ ├── .gitignore │ │ ├── App.cpp │ │ ├── App.h │ │ ├── App.idl │ │ ├── App.xaml │ │ ├── Assets │ │ ├── LockScreenLogo.scale-200.png │ │ ├── SplashScreen.scale-200.png │ │ ├── Square150x150Logo.scale-200.png │ │ ├── Square44x44Logo.scale-200.png │ │ ├── Square44x44Logo.targetsize-24_altform-unplated.png │ │ ├── StoreLogo.png │ │ └── Wide310x150Logo.scale-200.png │ │ ├── AutolinkedNativeModules.g.cpp │ │ ├── AutolinkedNativeModules.g.h │ │ ├── AutolinkedNativeModules.g.targets │ │ ├── CodePushDemoAppCpp.vcxproj │ │ ├── CodePushDemoAppCpp.vcxproj.filters │ │ ├── CodePushDemoAppCpp_TemporaryKey.pfx │ │ ├── MainPage.cpp │ │ ├── MainPage.h │ │ ├── MainPage.idl │ │ ├── MainPage.xaml │ │ ├── Package.appxmanifest │ │ ├── PropertySheet.props │ │ ├── ReactPackageProvider.cpp │ │ ├── ReactPackageProvider.h │ │ ├── packages.config │ │ ├── pch.cpp │ │ └── pch.h ├── create-app.js └── nexpect.js ├── LICENSE.md ├── README.md ├── Recipes ├── UpdateButton.ios.js └── UpdateOnStart.ios.js ├── SECURITY.md ├── android ├── app │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── microsoft │ │ └── codepush │ │ └── react │ │ ├── CodePush.java │ │ ├── CodePushConstants.java │ │ ├── CodePushDialog.java │ │ ├── CodePushInstallMode.java │ │ ├── CodePushInvalidPublicKeyException.java │ │ ├── CodePushInvalidUpdateException.java │ │ ├── CodePushMalformedDataException.java │ │ ├── CodePushNativeModule.java │ │ ├── CodePushNotInitializedException.java │ │ ├── CodePushTelemetryManager.java │ │ ├── CodePushUnknownException.java │ │ ├── CodePushUpdateManager.java │ │ ├── CodePushUpdateState.java │ │ ├── CodePushUpdateUtils.java │ │ ├── CodePushUtils.java │ │ ├── DownloadProgress.java │ │ ├── DownloadProgressCallback.java │ │ ├── FileUtils.java │ │ ├── ReactHostHolder.java │ │ ├── ReactInstanceHolder.java │ │ ├── SettingsManager.java │ │ └── TLSSocketFactory.java ├── build.gradle ├── codepush.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle ├── code-push-plugin-testing-framework ├── package.json ├── script │ ├── index.js │ ├── platform.js │ ├── projectManager.js │ ├── serverUtil.js │ ├── test.js │ ├── testBuilder.js │ ├── testConfig.js │ └── testUtil.js └── typings │ └── code-push-plugin-testing-framework.d.ts ├── docs ├── api-android.md ├── api-ios.md ├── api-js.md ├── multi-deployment-testing-android.md ├── multi-deployment-testing-ios.md ├── setup-android.md └── setup-ios.md ├── ios ├── CodePush.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── CodePush │ ├── Base64 │ │ ├── Base64 │ │ │ ├── MF_Base64Additions.h │ │ │ └── MF_Base64Additions.m │ │ └── README.md │ ├── CodePush.h │ ├── CodePush.m │ ├── CodePushConfig.m │ ├── CodePushDownloadHandler.m │ ├── CodePushErrorUtils.m │ ├── CodePushPackage.m │ ├── CodePushTelemetryManager.m │ ├── CodePushUpdateUtils.m │ ├── CodePushUtils.m │ ├── JWT │ │ ├── Core │ │ │ ├── Algorithms │ │ │ │ ├── Base │ │ │ │ │ ├── JWTAlgorithm.h │ │ │ │ │ ├── JWTAlgorithmFactory.h │ │ │ │ │ ├── JWTAlgorithmFactory.m │ │ │ │ │ ├── JWTAlgorithmNone.h │ │ │ │ │ └── JWTAlgorithmNone.m │ │ │ │ ├── ESFamily │ │ │ │ │ ├── JWTAlgorithmESBase.h │ │ │ │ │ └── JWTAlgorithmESBase.m │ │ │ │ ├── HSFamily │ │ │ │ │ ├── JWTAlgorithmHSBase.h │ │ │ │ │ └── JWTAlgorithmHSBase.m │ │ │ │ ├── Holders │ │ │ │ │ ├── JWTAlgorithmDataHolder.h │ │ │ │ │ ├── JWTAlgorithmDataHolder.m │ │ │ │ │ ├── JWTAlgorithmDataHolderChain.h │ │ │ │ │ └── JWTAlgorithmDataHolderChain.m │ │ │ │ └── RSFamily │ │ │ │ │ ├── JWTAlgorithmRSBase.h │ │ │ │ │ ├── JWTAlgorithmRSBase.m │ │ │ │ │ ├── JWTRSAlgorithm.h │ │ │ │ │ └── RSKeys │ │ │ │ │ ├── JWTCryptoKey.h │ │ │ │ │ ├── JWTCryptoKey.m │ │ │ │ │ ├── JWTCryptoKeyExtractor.h │ │ │ │ │ ├── JWTCryptoKeyExtractor.m │ │ │ │ │ ├── JWTCryptoSecurity.h │ │ │ │ │ └── JWTCryptoSecurity.m │ │ │ ├── ClaimSet │ │ │ │ ├── JWTClaim.h │ │ │ │ ├── JWTClaim.m │ │ │ │ ├── JWTClaimsSet.h │ │ │ │ ├── JWTClaimsSet.m │ │ │ │ ├── JWTClaimsSetSerializer.h │ │ │ │ ├── JWTClaimsSetSerializer.m │ │ │ │ ├── JWTClaimsSetVerifier.h │ │ │ │ └── JWTClaimsSetVerifier.m │ │ │ ├── Coding │ │ │ │ ├── JWTCoding+ResultTypes.h │ │ │ │ ├── JWTCoding+ResultTypes.m │ │ │ │ ├── JWTCoding+VersionOne.h │ │ │ │ ├── JWTCoding+VersionOne.m │ │ │ │ ├── JWTCoding+VersionThree.h │ │ │ │ ├── JWTCoding+VersionThree.m │ │ │ │ ├── JWTCoding+VersionTwo.h │ │ │ │ ├── JWTCoding+VersionTwo.m │ │ │ │ ├── JWTCoding.h │ │ │ │ └── JWTCoding.m │ │ │ ├── FrameworkSupplement │ │ │ │ ├── JWT.h │ │ │ │ └── Map.modulemap │ │ │ └── Supplement │ │ │ │ ├── JWTBase64Coder.h │ │ │ │ ├── JWTBase64Coder.m │ │ │ │ ├── JWTDeprecations.h │ │ │ │ ├── JWTErrorDescription.h │ │ │ │ └── JWTErrorDescription.m │ │ ├── LICENSE │ │ └── README.md │ ├── RCTConvert+CodePushInstallMode.m │ ├── RCTConvert+CodePushUpdateState.m │ └── SSZipArchive │ │ ├── Info.plist │ │ ├── README.md │ │ ├── SSZipArchive.h │ │ ├── SSZipArchive.m │ │ ├── SSZipCommon.h │ │ ├── Supporting Files │ │ └── PrivacyInfo.xcprivacy │ │ ├── include │ │ └── ZipArchive.h │ │ └── minizip │ │ ├── LICENSE │ │ ├── mz.h │ │ ├── mz_compat.c │ │ ├── mz_compat.h │ │ ├── mz_crypt.c │ │ ├── mz_crypt.h │ │ ├── mz_crypt_apple.c │ │ ├── mz_os.c │ │ ├── mz_os.h │ │ ├── mz_os_posix.c │ │ ├── mz_strm.c │ │ ├── mz_strm.h │ │ ├── mz_strm_buf.c │ │ ├── mz_strm_buf.h │ │ ├── mz_strm_mem.c │ │ ├── mz_strm_mem.h │ │ ├── mz_strm_os.h │ │ ├── mz_strm_os_posix.c │ │ ├── mz_strm_pkcrypt.c │ │ ├── mz_strm_pkcrypt.h │ │ ├── mz_strm_split.c │ │ ├── mz_strm_split.h │ │ ├── mz_strm_wzaes.c │ │ ├── mz_strm_wzaes.h │ │ ├── mz_strm_zlib.c │ │ ├── mz_strm_zlib.h │ │ ├── mz_zip.c │ │ ├── mz_zip.h │ │ ├── mz_zip_rw.c │ │ └── mz_zip_rw.h └── PrivacyInfo.xcprivacy ├── logging.js ├── package-lock.json ├── package-mixins.js ├── package.json ├── react-native.config.js ├── request-fetch-adapter.js ├── scripts ├── generateBundledResourcesHash.js ├── getFilesInFolder.js ├── postlink │ ├── android │ │ └── postlink.js │ ├── ios │ │ └── postlink.js │ └── run.js ├── postunlink │ ├── android │ │ └── postunlink.js │ ├── ios │ │ └── postunlink.js │ └── run.js ├── recordFilesBeforeBundleCommand.js └── tools │ ├── linkToolsAndroid.js │ └── linkToolsIos.js ├── test ├── template │ ├── android │ │ └── app │ │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── com │ │ │ │ └── testcodepush │ │ │ │ └── MainApplication.kt │ │ │ └── res │ │ │ └── values │ │ │ └── strings.xml │ ├── codePushWrapper.js │ ├── index.js │ ├── ios │ │ ├── Podfile │ │ └── TestCodePush │ │ │ ├── AppDelegate.mm │ │ │ └── AppDelegate.swift │ └── scenarios │ │ ├── scenarioCheckForUpdate.js │ │ ├── scenarioCheckForUpdateCustomKey.js │ │ ├── scenarioDisallowRestartImmediate.js │ │ ├── scenarioDisallowRestartOnResume.js │ │ ├── scenarioDisallowRestartOnSuspend.js │ │ ├── scenarioDownloadUpdate.js │ │ ├── scenarioInstall.js │ │ ├── scenarioInstallOnRestartWithRevert.js │ │ ├── scenarioInstallOnResumeWithRevert.js │ │ ├── scenarioInstallOnSuspendWithRevert.js │ │ ├── scenarioInstallRestart2x.js │ │ ├── scenarioInstallWithRevert.js │ │ ├── scenarioRestart.js │ │ ├── scenarioRestart2x.js │ │ ├── scenarioSync.js │ │ ├── scenarioSync2x.js │ │ ├── scenarioSyncMandatoryDefault.js │ │ ├── scenarioSyncMandatoryRestart.js │ │ ├── scenarioSyncMandatoryResume.js │ │ ├── scenarioSyncMandatorySuspend.js │ │ ├── scenarioSyncRestartDelay.js │ │ ├── scenarioSyncResume.js │ │ ├── scenarioSyncResumeDelay.js │ │ ├── scenarioSyncSuspend.js │ │ ├── scenarioSyncSuspendDelay.js │ │ ├── updateDeviceReady.js │ │ ├── updateNARConditional.js │ │ ├── updateNotifyApplicationReady.js │ │ ├── updateSync.js │ │ └── updateSync2x.js └── test.ts ├── tsconfig.json ├── tslint.json └── typings └── react-native-code-push.d.ts /.azurepipelines/test-rn-code-push.yml: -------------------------------------------------------------------------------- 1 | trigger: 2 | - master 3 | 4 | pr: 5 | - master 6 | 7 | variables: 8 | - name: api-level 9 | value: '27' 10 | 11 | pool: 12 | vmImage: 'macOS-12' 13 | 14 | stages: 15 | - stage: RunTests 16 | displayName: 'Run Android & IOS tests' 17 | jobs: 18 | - job: TestAndroid 19 | timeoutInMinutes: 120 20 | displayName: 'Test android' 21 | steps: 22 | 23 | - script: | 24 | adb devices 25 | displayName: 'Start adb server' 26 | 27 | - script: | 28 | $ANDROID_HOME/tools/bin/sdkmanager "system-images;android-$(api-level);google_apis;x86" 29 | displayName: 'Download system image' 30 | 31 | - script: | 32 | $ANDROID_HOME/tools/bin/avdmanager create avd --force --name TestEmulator --abi google_apis/x86 --package 'system-images;android-$(api-level);google_apis;x86' --device "Nexus 6P" 33 | displayName: 'Creating Android emulator' 34 | 35 | - script: | 36 | $ANDROID_HOME/emulator/emulator -avd TestEmulator -noaudio -no-window -no-snapshot-save -no-boot-anim -memory 6144 & 37 | displayName: 'Start Android emulator' 38 | 39 | - script: | 40 | $ANDROID_HOME/platform-tools/adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed | tr -d '\r') ]]; do sleep 1; done' 41 | displayName: 'Wait for emulator to boot' 42 | 43 | - script: | 44 | adb shell settings put global window_animation_scale 0.0 45 | displayName: 'Disable animations and transitions' 46 | 47 | - script: | 48 | adb shell settings put global transition_animation_scale 0.0 49 | displayName: 'Disable animations and transitions' 50 | 51 | - script: | 52 | adb shell settings put global animator_duration_scale 0.0 53 | displayName: 'Disable animations and transitions' 54 | 55 | 56 | - task: JavaToolInstaller@0 57 | inputs: 58 | versionSpec: '11' 59 | jdkArchitectureOption: 'x64' 60 | jdkSourceOption: 'PreInstalled' 61 | displayName: 'Change Java version' 62 | 63 | - script: | 64 | npm install 65 | displayName: 'Package Installation' 66 | 67 | - script: | 68 | npm run build:tests && npm run test:setup:android 69 | displayName: 'Setup Android tests' 70 | 71 | - script: | 72 | npm run test:fast:android 73 | displayName: 'Run Android test' 74 | 75 | - job: TestIOS 76 | timeoutInMinutes: 120 77 | displayName: 'Test IOS' 78 | steps: 79 | 80 | - script: | 81 | npm install 82 | displayName: 'Install dependencies' 83 | 84 | - script: | 85 | npm run build:tests && npm run test:setup:ios 86 | displayName: 'Setup iOS tests' 87 | 88 | - script: | 89 | npm run test:fast:ios 90 | displayName: 'Run tests' 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /.config/CredScanSuppressions.json: -------------------------------------------------------------------------------- 1 | { 2 | "tool": "Credential Scanner", 3 | "suppressions": [ 4 | { 5 | "file": "/Examples/CodePushDemoApp/android/app/debug.keystore", 6 | "_justification": "Used only in DemoApp" 7 | }, 8 | { 9 | "file": "/Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/CodePushDemoAppCpp_TemporaryKey.pfx", 10 | "_justification": "Used only in DemoApp" 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @microsoft/appcenter-fte 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thanks so much for filing an issue or feature request! Please fill out the following (wherever relevant): 2 | 3 | ### Steps to Reproduce 4 | 1. 5 | 2. 6 | 3. 7 | 8 | ### Expected Behavior 9 | What you expected to happen? 10 | 11 | ### Actual Behavior 12 | What actually happens? 13 | ``` 14 | STACK TRACE AND/OR SCREENSHOTS 15 | ``` 16 | 17 | ### Reproducible Demo 18 | 19 | * Download https://github.com/microsoft/react-native-code-push/archive/master.zip and unzip. From `Examples` folder run `node create-app.js appName react-native@0.71.19 react-native-code-push@9.0.1` command to generate plain CodePushified React Native app. Please see description on top of `create-app.js` file content if needed 20 | * If you can't reproduce the bug on it, provide us as much info as possible about your project 21 | 22 | ### Environment 23 | 24 | * react-native-code-push version: 25 | * react-native version: 26 | * iOS/Android/Windows version: 27 | * Does this reproduce on a debug build or release build? 28 | * Does this reproduce on a simulator, or only on a physical device? 29 | 30 | (The more info the faster we will be able to address it!) 31 | -------------------------------------------------------------------------------- /.github/policies/resourceManagement.yml: -------------------------------------------------------------------------------- 1 | id: 2 | name: GitOps.PullRequestIssueManagement 3 | description: GitOps.PullRequestIssueManagement primitive 4 | owner: 5 | resource: repository 6 | disabled: false 7 | where: 8 | configuration: 9 | resourceManagementConfiguration: 10 | scheduledSearches: 11 | - description: 12 | frequencies: 13 | - hourly: 14 | hour: 4 15 | filters: 16 | - isOpen 17 | - isNotLabeledWith: 18 | label: bug 19 | - isNotLabeledWith: 20 | label: security 21 | - isNotLabeledWith: 22 | label: stale 23 | - isNotLabeledWith: 24 | label: do not close 25 | - noActivitySince: 26 | days: 60 27 | - isIssue 28 | - isNotAssigned 29 | actions: 30 | - addLabel: 31 | label: stale 32 | - addReply: 33 | reply: This issue has been automatically marked as stale because it has not had any activity for 60 days. It will be closed if no further activity occurs within 15 days of this comment. 34 | - description: 35 | frequencies: 36 | - hourly: 37 | hour: 6 38 | filters: 39 | - isOpen 40 | - isIssue 41 | - hasLabel: 42 | label: stale 43 | - isNotLabeledWith: 44 | label: bug 45 | - isNotLabeledWith: 46 | label: do not close 47 | - isNotAssigned 48 | - noActivitySince: 49 | days: 15 50 | actions: 51 | - addReply: 52 | reply: This issue will now be closed because it hasn't had any activity for 15 days after stale. Please feel free to open a new issue if you still have a question/issue or suggestion. 53 | - closeIssue 54 | eventResponderTasks: 55 | - if: 56 | - payloadType: Issue_Comment 57 | - hasLabel: 58 | label: stale 59 | then: 60 | - removeLabel: 61 | label: stale 62 | description: 63 | onFailure: 64 | onSuccess: 65 | -------------------------------------------------------------------------------- /.node-version: -------------------------------------------------------------------------------- 1 | v20.18.2 2 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | 24 | # node.js 25 | # 26 | node_modules/ 27 | npm-debug.log 28 | 29 | # Don't publish example apps 30 | Examples/ 31 | Recipes/ 32 | 33 | # Don't publish testing code 34 | bin/ 35 | test/ 36 | 37 | # Remove after this framework is published on NPM 38 | code-push-plugin-testing-framework/ 39 | 40 | # Android build artifacts and Android Studio bits 41 | android/app/build 42 | android/local.properties 43 | android/.gradle 44 | android/**/*.iml 45 | android/.idea 46 | 47 | 48 | # Windows 49 | windows/.vs/ 50 | windows/obj/ 51 | 52 | #Tests 53 | windows/CodePush.Net46.Test 54 | 55 | #Visual Studio files 56 | *.[Oo]bj 57 | *.user 58 | *.aps 59 | *.pch 60 | *.vspscc 61 | *.vssscc 62 | *_i.c 63 | *_p.c 64 | *.ncb 65 | *.suo 66 | *.tlb 67 | *.tlh 68 | *.bak 69 | *.[Cc]ache 70 | *.ilk 71 | *.log 72 | *.lib 73 | *.sbr 74 | *.sdf 75 | *.opensdf 76 | *.opendb 77 | *.unsuccessfulbuild 78 | ipch/ 79 | [Oo]bj/ 80 | [Bb]in 81 | [Dd]ebug*/ 82 | [Rr]elease*/ 83 | Ankh.NoLoad 84 | 85 | #NuGet 86 | packages/ 87 | *.nupkg 88 | 89 | # VSCode 90 | .vscode/ 91 | 92 | # IntelliJIDEA 93 | .idea/ 94 | 95 | 96 | # Github 97 | .github/ 98 | 99 | # Git 100 | .git/ 101 | 102 | .watchmanconfig 103 | 104 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Tests-android", 6 | "type": "node", 7 | "request": "launch", 8 | "preLaunchTask": "Setup-android", 9 | "runtimeExecutable": "npm", 10 | "runtimeArgs": [ 11 | "run", 12 | "test:debugger:android" 13 | ], 14 | "port": 9229, 15 | "stopOnEntry": false, 16 | "sourceMaps": true, 17 | "console": "internalConsole", 18 | "internalConsoleOptions": "openOnSessionStart", 19 | "autoAttachChildProcesses": true, 20 | "timeout": 100000 21 | }, 22 | { 23 | "name": "Tests-ios", 24 | "type": "node", 25 | "request": "launch", 26 | "preLaunchTask": "Setup-ios", 27 | "runtimeExecutable": "npm", 28 | "runtimeArgs": [ 29 | "run", 30 | "test:debugger:ios" 31 | ], 32 | "port": 9229, 33 | "stopOnEntry": false, 34 | "sourceMaps": true, 35 | "console": "internalConsole", 36 | "internalConsoleOptions": "openOnSessionStart", 37 | "autoAttachChildProcesses": true, 38 | "timeout": 100000 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib" 3 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "type": "shell", 6 | "label": "Build", 7 | "command": "npm", 8 | "args": [ 9 | "run", 10 | "build:tests" 11 | ], 12 | "presentation": { 13 | "echo": false, 14 | "focus": false 15 | }, 16 | "problemMatcher": [ 17 | "$tsc" 18 | ] 19 | }, 20 | { 21 | "type": "shell", 22 | "label": "Setup-android", 23 | "dependsOn": "Build", 24 | "command": "npm", 25 | "args": [ 26 | "run", 27 | "test:setup:android" 28 | ], 29 | "presentation": { 30 | "echo": false, 31 | "focus": false 32 | }, 33 | "problemMatcher": [ 34 | "$tsc" 35 | ] 36 | }, 37 | { 38 | "type": "shell", 39 | "label": "Setup-ios", 40 | "dependsOn": "Build", 41 | "command": "npm", 42 | "args": [ 43 | "run", 44 | "test:setup:ios" 45 | ], 46 | "presentation": { 47 | "echo": false, 48 | "focus": false 49 | }, 50 | "problemMatcher": [ 51 | "$tsc" 52 | ] 53 | } 54 | ] 55 | } 56 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /AlertAdapter.js: -------------------------------------------------------------------------------- 1 | import React, { Platform } from "react-native"; 2 | let { Alert } = React; 3 | 4 | if (Platform.OS === "android") { 5 | const { NativeModules: { CodePushDialog } } = React; 6 | 7 | Alert = { 8 | alert(title, message, buttons) { 9 | if (buttons.length > 2) { 10 | throw "Can only show 2 buttons for Android dialog."; 11 | } 12 | 13 | const button1Text = buttons[0] ? buttons[0].text : null, 14 | button2Text = buttons[1] ? buttons[1].text : null; 15 | 16 | CodePushDialog.showDialog( 17 | title, message, button1Text, button2Text, 18 | (buttonId) => { buttons[buttonId].onPress && buttons[buttonId].onPress(); }, 19 | (error) => { throw error; }); 20 | } 21 | }; 22 | } 23 | 24 | module.exports = { Alert }; -------------------------------------------------------------------------------- /CodePush.podspec: -------------------------------------------------------------------------------- 1 | require 'json' 2 | 3 | package = JSON.parse(File.read(File.join(__dir__, 'package.json'))) 4 | 5 | Pod::Spec.new do |s| 6 | s.name = 'CodePush' 7 | s.version = package['version'].gsub(/v|-beta/, '') 8 | s.summary = package['description'] 9 | s.author = package['author'] 10 | s.license = package['license'] 11 | s.homepage = package['homepage'] 12 | s.source = { :git => 'https://github.com/revopush/react-native-code-push.git', :tag => "v#{s.version}"} 13 | s.ios.deployment_target = '15.5' 14 | s.tvos.deployment_target = '15.5' 15 | s.preserve_paths = '*.js' 16 | s.library = 'z' 17 | s.source_files = 'ios/CodePush/*.{h,m}' 18 | s.public_header_files = ['ios/CodePush/CodePush.h'] 19 | s.pod_target_xcconfig = { "DEFINES_MODULE" => "YES" } 20 | 21 | # Note: Even though there are copy/pasted versions of some of these dependencies in the repo, 22 | # we explicitly let CocoaPods pull in the versions below so all dependencies are resolved and 23 | # linked properly at a parent workspace level. 24 | s.dependency 'React-Core' 25 | s.dependency 'SSZipArchive', '~> 2.5.5' 26 | s.dependency 'JWT', '~> 3.0.0-beta.12' 27 | s.dependency 'Base64', '~> 1.1' 28 | end 29 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/.editorconfig: -------------------------------------------------------------------------------- 1 | # Windows files 2 | [*.bat] 3 | end_of_line = crlf 4 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native-community', 4 | }; 5 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | ; We fork some components by platform 3 | .*/*[.]android.js 4 | 5 | ; Ignore "BUCK" generated dirs 6 | /\.buckd/ 7 | 8 | ; Ignore polyfills 9 | node_modules/react-native/Libraries/polyfills/.* 10 | 11 | ; Flow doesn't support platforms 12 | .*/Libraries/Utilities/LoadingView.js 13 | 14 | [untyped] 15 | .*/node_modules/@react-native-community/cli/.*/.* 16 | 17 | [include] 18 | 19 | [libs] 20 | node_modules/react-native/interface.js 21 | node_modules/react-native/flow/ 22 | 23 | [options] 24 | emoji=true 25 | 26 | exact_by_default=true 27 | 28 | format.bracket_spacing=false 29 | 30 | module.file_ext=.js 31 | module.file_ext=.json 32 | module.file_ext=.ios.js 33 | 34 | munge_underscores=true 35 | 36 | module.name_mapper='^react-native/\(.*\)$' -> '/node_modules/react-native/\1' 37 | module.name_mapper='^@?[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '/node_modules/react-native/Libraries/Image/RelativeImageStub' 38 | 39 | suppress_type=$FlowIssue 40 | suppress_type=$FlowFixMe 41 | suppress_type=$FlowFixMeProps 42 | suppress_type=$FlowFixMeState 43 | 44 | [lints] 45 | sketchy-null-number=warn 46 | sketchy-null-mixed=warn 47 | sketchy-number=warn 48 | untyped-type-import=warn 49 | nonstrict-import=warn 50 | deprecated-type=warn 51 | unsafe-getters-setters=warn 52 | unnecessary-invariant=warn 53 | signature-verification-failure=warn 54 | 55 | [strict] 56 | deprecated-type 57 | nonstrict-import 58 | sketchy-null 59 | unclear-type 60 | unsafe-getters-setters 61 | untyped-import 62 | untyped-type-import 63 | 64 | [version] 65 | ^0.158.0 66 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/.gitattributes: -------------------------------------------------------------------------------- 1 | # Windows files should use crlf line endings 2 | # https://help.github.com/articles/dealing-with-line-endings/ 3 | *.bat text eol=crlf 4 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | 24 | # Android/IntelliJ 25 | # 26 | build/ 27 | .idea 28 | .gradle 29 | local.properties 30 | *.iml 31 | *.hprof 32 | 33 | # node.js 34 | # 35 | node_modules/ 36 | npm-debug.log 37 | yarn-error.log 38 | 39 | # BUCK 40 | buck-out/ 41 | \.buckd/ 42 | *.keystore 43 | !debug.keystore 44 | 45 | # fastlane 46 | # 47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 48 | # screenshots whenever they are needed. 49 | # For more information about the recommended setup visit: 50 | # https://docs.fastlane.tools/best-practices/source-control/ 51 | 52 | */fastlane/report.xml 53 | */fastlane/Preview.html 54 | */fastlane/screenshots 55 | 56 | # Bundle artifact 57 | *.jsbundle 58 | 59 | # CocoaPods 60 | /ios/Pods/ 61 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | bracketSpacing: false, 3 | jsxBracketSameLine: true, 4 | singleQuote: true, 5 | trailingComma: 'all', 6 | arrowParens: 'avoid', 7 | }; 8 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/__tests__/App-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import 'react-native'; 6 | import React from 'react'; 7 | import App from '../App'; 8 | 9 | // Note: test renderer must be required after react-native. 10 | import renderer from 'react-test-renderer'; 11 | 12 | it('renders correctly', () => { 13 | renderer.create(); 14 | }); 15 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/android/app/BUCK: -------------------------------------------------------------------------------- 1 | # To learn about Buck see [Docs](https://buckbuild.com/). 2 | # To run your application with Buck: 3 | # - install Buck 4 | # - `npm start` - to start the packager 5 | # - `cd android` 6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` 7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck 8 | # - `buck install -r android/app` - compile, install and run application 9 | # 10 | 11 | load(":build_defs.bzl", "create_aar_targets", "create_jar_targets") 12 | 13 | lib_deps = [] 14 | 15 | create_aar_targets(glob(["libs/*.aar"])) 16 | 17 | create_jar_targets(glob(["libs/*.jar"])) 18 | 19 | android_library( 20 | name = "all-libs", 21 | exported_deps = lib_deps, 22 | ) 23 | 24 | android_library( 25 | name = "app-code", 26 | srcs = glob([ 27 | "src/main/java/**/*.java", 28 | ]), 29 | deps = [ 30 | ":all-libs", 31 | ":build_config", 32 | ":res", 33 | ], 34 | ) 35 | 36 | android_build_config( 37 | name = "build_config", 38 | package = "com.codepushdemoapp", 39 | ) 40 | 41 | android_resource( 42 | name = "res", 43 | package = "com.codepushdemoapp", 44 | res = "src/main/res", 45 | ) 46 | 47 | android_binary( 48 | name = "app", 49 | keystore = "//android/keystores:debug", 50 | manifest = "src/main/AndroidManifest.xml", 51 | package_type = "debug", 52 | deps = [ 53 | ":app-code", 54 | ], 55 | ) 56 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/android/app/build_defs.bzl: -------------------------------------------------------------------------------- 1 | """Helper definitions to glob .aar and .jar targets""" 2 | 3 | def create_aar_targets(aarfiles): 4 | for aarfile in aarfiles: 5 | name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")] 6 | lib_deps.append(":" + name) 7 | android_prebuilt_aar( 8 | name = name, 9 | aar = aarfile, 10 | ) 11 | 12 | def create_jar_targets(jarfiles): 13 | for jarfile in jarfiles: 14 | name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")] 15 | lib_deps.append(":" + name) 16 | prebuilt_jar( 17 | name = name, 18 | binary_jar = jarfile, 19 | ) 20 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revopush/react-native-code-push/d2f3e96fd01b3d08a0768bb7e72f698f320bb194/Examples/CodePushDemoApp/android/app/debug.keystore -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 13 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/android/app/src/main/java/com/codepushdemoapp/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.codepushdemoapp; 2 | 3 | import com.facebook.react.ReactActivity; 4 | 5 | public class MainActivity extends ReactActivity { 6 | 7 | /** 8 | * Returns the name of the main component registered from JavaScript. This is used to schedule 9 | * rendering of the component. 10 | */ 11 | @Override 12 | protected String getMainComponentName() { 13 | return "CodePushDemoApp"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revopush/react-native-code-push/d2f3e96fd01b3d08a0768bb7e72f698f320bb194/Examples/CodePushDemoApp/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revopush/react-native-code-push/d2f3e96fd01b3d08a0768bb7e72f698f320bb194/Examples/CodePushDemoApp/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revopush/react-native-code-push/d2f3e96fd01b3d08a0768bb7e72f698f320bb194/Examples/CodePushDemoApp/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revopush/react-native-code-push/d2f3e96fd01b3d08a0768bb7e72f698f320bb194/Examples/CodePushDemoApp/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revopush/react-native-code-push/d2f3e96fd01b3d08a0768bb7e72f698f320bb194/Examples/CodePushDemoApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revopush/react-native-code-push/d2f3e96fd01b3d08a0768bb7e72f698f320bb194/Examples/CodePushDemoApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revopush/react-native-code-push/d2f3e96fd01b3d08a0768bb7e72f698f320bb194/Examples/CodePushDemoApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revopush/react-native-code-push/d2f3e96fd01b3d08a0768bb7e72f698f320bb194/Examples/CodePushDemoApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revopush/react-native-code-push/d2f3e96fd01b3d08a0768bb7e72f698f320bb194/Examples/CodePushDemoApp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revopush/react-native-code-push/d2f3e96fd01b3d08a0768bb7e72f698f320bb194/Examples/CodePushDemoApp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | deployment-key-here 3 | CodePushDemoApp 4 | 5 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext { 5 | buildToolsVersion = "30.0.2" 6 | minSdkVersion = 21 7 | compileSdkVersion = 30 8 | targetSdkVersion = 30 9 | ndkVersion = "21.4.7075529" 10 | } 11 | repositories { 12 | google() 13 | mavenCentral() 14 | } 15 | dependencies { 16 | classpath("com.android.tools.build:gradle:4.2.2") 17 | // NOTE: Do not place your application dependencies here; they belong 18 | // in the individual module build.gradle files 19 | } 20 | } 21 | 22 | allprojects { 23 | repositories { 24 | mavenCentral() 25 | mavenLocal() 26 | maven { 27 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 28 | url("$rootDir/../node_modules/react-native/android") 29 | } 30 | maven { 31 | // Android JSC is installed from npm 32 | url("$rootDir/../node_modules/jsc-android/dist") 33 | } 34 | 35 | google() 36 | maven { url 'https://www.jitpack.io' } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | # AndroidX package structure to make it clearer which packages are bundled with the 21 | # Android operating system, and which are packaged with your app's APK 22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 23 | android.useAndroidX=true 24 | # Automatically convert third-party libraries to use AndroidX 25 | android.enableJetifier=true 26 | 27 | # Version of flipper SDK to use with React Native 28 | FLIPPER_VERSION=0.99.0 29 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revopush/react-native-code-push/d2f3e96fd01b3d08a0768bb7e72f698f320bb194/Examples/CodePushDemoApp/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'CodePushDemoApp' 2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 3 | include ':app', ':react-native-code-push' 4 | project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app') 5 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CodePushDemoApp", 3 | "displayName": "CodePushDemoApp" 4 | } -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/images/laptop_phone_howitworks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revopush/react-native-code-push/d2f3e96fd01b3d08a0768bb7e72f698f320bb194/Examples/CodePushDemoApp/images/laptop_phone_howitworks.png -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/index.js: -------------------------------------------------------------------------------- 1 | import { AppRegistry } from 'react-native'; 2 | import App from './App'; 3 | 4 | AppRegistry.registerComponent('CodePushDemoApp', () => App); 5 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/ios/CodePushDemoApp.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/ios/CodePushDemoApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/ios/CodePushDemoApp/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : UIResponder 5 | 6 | @property (nonatomic, strong) UIWindow *window; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/ios/CodePushDemoApp/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | #import 3 | 4 | #import 5 | #import 6 | #import 7 | 8 | #ifdef FB_SONARKIT_ENABLED 9 | #import 10 | #import 11 | #import 12 | #import 13 | #import 14 | #import 15 | 16 | static void InitializeFlipper(UIApplication *application) { 17 | FlipperClient *client = [FlipperClient sharedClient]; 18 | SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults]; 19 | [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]]; 20 | [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]]; 21 | [client addPlugin:[FlipperKitReactPlugin new]]; 22 | [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]]; 23 | [client start]; 24 | } 25 | #endif 26 | 27 | @implementation AppDelegate 28 | 29 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 30 | { 31 | #ifdef FB_SONARKIT_ENABLED 32 | InitializeFlipper(application); 33 | #endif 34 | 35 | RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; 36 | RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge 37 | moduleName:@"CodePushDemoApp" 38 | initialProperties:nil]; 39 | 40 | if (@available(iOS 13.0, *)) { 41 | rootView.backgroundColor = [UIColor systemBackgroundColor]; 42 | } else { 43 | rootView.backgroundColor = [UIColor whiteColor]; 44 | } 45 | 46 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 47 | UIViewController *rootViewController = [UIViewController new]; 48 | rootViewController.view = rootView; 49 | self.window.rootViewController = rootViewController; 50 | [self.window makeKeyAndVisible]; 51 | return YES; 52 | } 53 | 54 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 55 | { 56 | #if DEBUG 57 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; 58 | #else 59 | return [CodePush bundleURL]; 60 | #endif 61 | } 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/ios/CodePushDemoApp/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/ios/CodePushDemoApp/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/ios/CodePushDemoApp/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | CodePushDemoApp 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSExceptionDomains 30 | 31 | localhost 32 | 33 | NSExceptionAllowsInsecureHTTPLoads 34 | 35 | 36 | 37 | 38 | NSLocationWhenInUseUsageDescription 39 | 40 | UILaunchStoryboardName 41 | LaunchScreen 42 | UIRequiredDeviceCapabilities 43 | 44 | armv7 45 | 46 | UISupportedInterfaceOrientations 47 | 48 | UIInterfaceOrientationPortrait 49 | UIInterfaceOrientationLandscapeLeft 50 | UIInterfaceOrientationLandscapeRight 51 | 52 | UIViewControllerBasedStatusBarAppearance 53 | 54 | CodePushDeploymentKey 55 | deployment-key-here 56 | 57 | 58 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/ios/CodePushDemoApp/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char * argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/ios/CodePushDemoAppTests/CodePushDemoAppTests.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | #import 5 | #import 6 | 7 | #define TIMEOUT_SECONDS 600 8 | #define TEXT_TO_LOOK_FOR @"Welcome to React" 9 | 10 | @interface CodePushDemoAppTests : XCTestCase 11 | 12 | @end 13 | 14 | @implementation CodePushDemoAppTests 15 | 16 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test 17 | { 18 | if (test(view)) { 19 | return YES; 20 | } 21 | for (UIView *subview in [view subviews]) { 22 | if ([self findSubviewInView:subview matching:test]) { 23 | return YES; 24 | } 25 | } 26 | return NO; 27 | } 28 | 29 | - (void)testRendersWelcomeScreen 30 | { 31 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; 32 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 33 | BOOL foundElement = NO; 34 | 35 | __block NSString *redboxError = nil; 36 | #ifdef DEBUG 37 | RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { 38 | if (level >= RCTLogLevelError) { 39 | redboxError = message; 40 | } 41 | }); 42 | #endif 43 | 44 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 45 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 46 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 47 | 48 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) { 49 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 50 | return YES; 51 | } 52 | return NO; 53 | }]; 54 | } 55 | 56 | #ifdef DEBUG 57 | RCTSetLogFunction(RCTDefaultLogFunction); 58 | #endif 59 | 60 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 61 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 62 | } 63 | 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/ios/CodePushDemoAppTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/ios/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../node_modules/react-native/scripts/react_native_pods' 2 | require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' 3 | 4 | platform :ios, '11.0' 5 | 6 | target 'CodePushDemoApp' do 7 | config = use_native_modules! 8 | 9 | use_react_native!( 10 | :path => config[:reactNativePath], 11 | # to enable hermes on iOS, change `false` to `true` and then install pods 12 | :hermes_enabled => false 13 | ) 14 | 15 | target 'CodePushDemoAppTests' do 16 | inherit! :complete 17 | # Pods for testing 18 | end 19 | 20 | # Enables Flipper. 21 | # 22 | # Note that if you have use_frameworks! enabled, Flipper will not work and 23 | # you should disable the next line. 24 | use_flipper!() 25 | 26 | post_install do |installer| 27 | react_native_post_install(installer) 28 | __apply_Xcode_12_5_M1_post_install_workaround(installer) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/metro.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Metro configuration for React Native 3 | * https://github.com/facebook/react-native 4 | * 5 | * @format 6 | */ 7 | 8 | module.exports = { 9 | transformer: { 10 | getTransformOptions: async () => ({ 11 | transform: { 12 | experimentalImportSupport: false, 13 | inlineRequires: true, 14 | }, 15 | }), 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /Examples/CodePushDemoApp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CodePushDemoApp", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "android": "react-native run-android", 7 | "ios": "react-native run-ios", 8 | "start": "react-native start", 9 | "test": "jest", 10 | "lint": "eslint ." 11 | }, 12 | "dependencies": { 13 | "react": "17.0.2", 14 | "react-native": "0.68.5", 15 | "react-native-code-push": "8.1.0" 16 | }, 17 | "resolutions": { 18 | "strip-ansi": "^6.0.1", 19 | "ansi-regex": "^5.0.1" 20 | }, 21 | "devDependencies": { 22 | "@babel/core": "^7.15.8", 23 | "@babel/runtime": "^7.15.4", 24 | "@react-native-community/eslint-config": "^3.0.1", 25 | "babel-jest": "^27.2.5", 26 | "eslint": "^8.0.0", 27 | "jest": "^27.2.5", 28 | "metro-react-native-babel-preset": "^0.66.2", 29 | "react-test-renderer": "17.0.2" 30 | }, 31 | "jest": { 32 | "preset": "react-native" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native-community', 4 | }; 5 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | ; We fork some components by platform 3 | .*/*[.]android.js 4 | 5 | ; Ignore "BUCK" generated dirs 6 | /\.buckd/ 7 | 8 | ; Ignore polyfills 9 | node_modules/react-native/Libraries/polyfills/.* 10 | 11 | ; These should not be required directly 12 | ; require from fbjs/lib instead: require('fbjs/lib/warning') 13 | node_modules/warning/.* 14 | 15 | ; Flow doesn't support platforms 16 | .*/Libraries/Utilities/LoadingView.js 17 | 18 | [untyped] 19 | .*/node_modules/@react-native-community/cli/.*/.* 20 | 21 | [include] 22 | 23 | [libs] 24 | node_modules/react-native/interface.js 25 | node_modules/react-native/flow/ 26 | 27 | [options] 28 | emoji=true 29 | 30 | esproposal.optional_chaining=enable 31 | esproposal.nullish_coalescing=enable 32 | 33 | module.file_ext=.js 34 | module.file_ext=.json 35 | module.file_ext=.ios.js 36 | 37 | munge_underscores=true 38 | 39 | module.name_mapper='^react-native/\(.*\)$' -> '/node_modules/react-native/\1' 40 | module.name_mapper='^@?[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '/node_modules/react-native/Libraries/Image/RelativeImageStub' 41 | 42 | suppress_type=$FlowIssue 43 | suppress_type=$FlowFixMe 44 | suppress_type=$FlowFixMeProps 45 | suppress_type=$FlowFixMeState 46 | 47 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\) 48 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+ 49 | suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError 50 | 51 | [lints] 52 | sketchy-null-number=warn 53 | sketchy-null-mixed=warn 54 | sketchy-number=warn 55 | untyped-type-import=warn 56 | nonstrict-import=warn 57 | deprecated-type=warn 58 | unsafe-getters-setters=warn 59 | unnecessary-invariant=warn 60 | signature-verification-failure=warn 61 | deprecated-utility=error 62 | 63 | [strict] 64 | deprecated-type 65 | nonstrict-import 66 | sketchy-null 67 | unclear-type 68 | unsafe-getters-setters 69 | untyped-import 70 | untyped-type-import 71 | 72 | [version] 73 | ^0.122.0 74 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | 24 | # Android/IntelliJ 25 | # 26 | build/ 27 | .idea 28 | .gradle 29 | local.properties 30 | *.iml 31 | 32 | # Visual Studio Code 33 | # 34 | .vscode/ 35 | 36 | # node.js 37 | # 38 | node_modules/ 39 | npm-debug.log 40 | yarn-error.log 41 | 42 | # BUCK 43 | buck-out/ 44 | \.buckd/ 45 | *.keystore 46 | !debug.keystore 47 | 48 | # fastlane 49 | # 50 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 51 | # screenshots whenever they are needed. 52 | # For more information about the recommended setup visit: 53 | # https://docs.fastlane.tools/best-practices/source-control/ 54 | 55 | */fastlane/report.xml 56 | */fastlane/Preview.html 57 | */fastlane/screenshots 58 | 59 | # Bundle artifact 60 | *.jsbundle 61 | 62 | # CocoaPods 63 | /ios/Pods/ 64 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | bracketSpacing: false, 3 | jsxBracketSameLine: true, 4 | singleQuote: true, 5 | trailingComma: 'all', 6 | }; 7 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CodePushDemoAppCpp", 3 | "displayName": "CodePushDemoAppCpp" 4 | } 5 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/images/laptop_phone_howitworks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revopush/react-native-code-push/d2f3e96fd01b3d08a0768bb7e72f698f320bb194/Examples/CodePushDemoAppCpp/images/laptop_phone_howitworks.png -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import {AppRegistry} from 'react-native'; 6 | import App from './App'; 7 | import {name as appName} from './app.json'; 8 | 9 | AppRegistry.registerComponent(appName, () => App); 10 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/metro.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Metro configuration for React Native 3 | * https://github.com/facebook/react-native 4 | * 5 | * @format 6 | */ 7 | const path = require('path'); 8 | const blacklist = require('metro-config/src/defaults/blacklist'); 9 | 10 | module.exports = { 11 | resolver: { 12 | blacklistRE: blacklist([ 13 | // This stops "react-native run-windows" from causing the metro server to crash if its already running 14 | new RegExp( 15 | `${path.resolve(__dirname, 'windows').replace(/[/\\]/g, '/')}.*`, 16 | ), 17 | // This prevents "react-native run-windows" from hitting: EBUSY: resource busy or locked, open msbuild.ProjectImports.zip 18 | /.*\.ProjectImports\.zip/, 19 | ]), 20 | }, 21 | transformer: { 22 | getTransformOptions: async () => ({ 23 | transform: { 24 | experimentalImportSupport: false, 25 | inlineRequires: false, 26 | }, 27 | }), 28 | }, 29 | }; 30 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CodePushDemoAppCpp", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "start": "react-native start", 7 | "test": "jest", 8 | "lint": "eslint .", 9 | "windows": "react-native run-windows" 10 | }, 11 | "dependencies": { 12 | "react": "^17.0.2", 13 | "react-native": "^0.68.5", 14 | "react-native-code-push": "^8.1.0", 15 | "react-native-windows": "^1.0.0" 16 | }, 17 | "resolutions": { 18 | "strip-ansi": "^6.0.1", 19 | "ansi-regex": "^5.0.1", 20 | "node-fetch": "^2.6.7" 21 | }, 22 | "devDependencies": { 23 | "@babel/core": "^7.8.4", 24 | "@babel/runtime": "^7.8.4", 25 | "@react-native-community/eslint-config": "^3.0.1", 26 | "appcenter-cli": "^2.14.0", 27 | "babel-jest": "^27.2.5", 28 | "eslint": "^8.0.0", 29 | "jest": "^27.2.5", 30 | "metro-react-native-babel-preset": "^0.66.2", 31 | "react-test-renderer": "17.0.2" 32 | }, 33 | "jest": { 34 | "preset": "react-native" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/.gitignore: -------------------------------------------------------------------------------- 1 | *AppPackages* 2 | *BundleArtifacts* 3 | 4 | #OS junk files 5 | [Tt]humbs.db 6 | *.DS_Store 7 | 8 | #Visual Studio files 9 | *.[Oo]bj 10 | *.user 11 | *.aps 12 | *.pch 13 | *.vspscc 14 | *.vssscc 15 | *_i.c 16 | *_p.c 17 | *.ncb 18 | *.suo 19 | *.tlb 20 | *.tlh 21 | *.bak 22 | *.[Cc]ache 23 | *.ilk 24 | *.log 25 | *.lib 26 | *.sbr 27 | *.sdf 28 | *.opensdf 29 | *.opendb 30 | *.unsuccessfulbuild 31 | ipch/ 32 | [Oo]bj/ 33 | [Bb]in 34 | [Dd]ebug*/ 35 | [Rr]elease*/ 36 | Ankh.NoLoad 37 | 38 | # Visual C++ cache files 39 | ipch/ 40 | *.aps 41 | *.ncb 42 | *.opendb 43 | *.opensdf 44 | *.sdf 45 | *.cachefile 46 | *.VC.db 47 | *.VC.VC.opendb 48 | 49 | #MonoDevelop 50 | *.pidb 51 | *.userprefs 52 | 53 | #Tooling 54 | _ReSharper*/ 55 | *.resharper 56 | [Tt]est[Rr]esult* 57 | *.sass-cache 58 | 59 | #Project files 60 | [Bb]uild/ 61 | 62 | #Subversion files 63 | .svn 64 | 65 | # Office Temp Files 66 | ~$* 67 | 68 | # vim Temp Files 69 | *~ 70 | 71 | #NuGet 72 | packages/ 73 | *.nupkg 74 | 75 | #ncrunch 76 | *ncrunch* 77 | *crunch*.local.xml 78 | 79 | # visual studio database projects 80 | *.dbmdl 81 | 82 | #Test files 83 | *.testsettings 84 | 85 | #Other files 86 | *.DotSettings 87 | .vs/ 88 | *project.lock.json 89 | 90 | #Files generated by the VS build 91 | **/Generated Files/** 92 | 93 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/.gitignore: -------------------------------------------------------------------------------- 1 | /Bundle 2 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/App.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "App.xaml.g.h" 4 | #include "winrt/Microsoft.ReactNative.h" 5 | 6 | namespace activation = winrt::Windows::ApplicationModel::Activation; 7 | 8 | namespace winrt::CodePushDemoAppCpp::implementation 9 | { 10 | struct App : AppT 11 | { 12 | App() noexcept; 13 | 14 | void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs const&); 15 | void OnSuspending(IInspectable const&, Windows::ApplicationModel::SuspendingEventArgs const&); 16 | void OnNavigationFailed(IInspectable const&, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs const&); 17 | 18 | winrt::Microsoft::ReactNative::ReactNativeHost& Host() noexcept { return m_host; } 19 | private: 20 | winrt::Microsoft::ReactNative::ReactNativeHost m_host; 21 | }; 22 | } // namespace winrt::CodePushDemoAppCpp::implementation 23 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/App.idl: -------------------------------------------------------------------------------- 1 | namespace CodePushDemoAppCpp 2 | { 3 | } 4 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/App.xaml: -------------------------------------------------------------------------------- 1 |  6 | 7 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/Assets/LockScreenLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revopush/react-native-code-push/d2f3e96fd01b3d08a0768bb7e72f698f320bb194/Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/Assets/LockScreenLogo.scale-200.png -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/Assets/SplashScreen.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revopush/react-native-code-push/d2f3e96fd01b3d08a0768bb7e72f698f320bb194/Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/Assets/SplashScreen.scale-200.png -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/Assets/Square150x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revopush/react-native-code-push/d2f3e96fd01b3d08a0768bb7e72f698f320bb194/Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/Assets/Square150x150Logo.scale-200.png -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/Assets/Square44x44Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revopush/react-native-code-push/d2f3e96fd01b3d08a0768bb7e72f698f320bb194/Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/Assets/Square44x44Logo.scale-200.png -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/Assets/Square44x44Logo.targetsize-24_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revopush/react-native-code-push/d2f3e96fd01b3d08a0768bb7e72f698f320bb194/Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/Assets/Square44x44Logo.targetsize-24_altform-unplated.png -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/Assets/StoreLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revopush/react-native-code-push/d2f3e96fd01b3d08a0768bb7e72f698f320bb194/Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/Assets/StoreLogo.png -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/Assets/Wide310x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revopush/react-native-code-push/d2f3e96fd01b3d08a0768bb7e72f698f320bb194/Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/Assets/Wide310x150Logo.scale-200.png -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/AutolinkedNativeModules.g.cpp: -------------------------------------------------------------------------------- 1 | // AutolinkedNativeModules.g.cpp contents generated by "react-native autolink-windows" 2 | // clang-format off 3 | #include "pch.h" 4 | #include "AutolinkedNativeModules.g.h" 5 | 6 | // Includes from react-native-code-push-windows 7 | #include "winrt/Microsoft.CodePush.ReactNative.h" 8 | 9 | namespace winrt::Microsoft::ReactNative 10 | { 11 | 12 | void RegisterAutolinkedNativeModulePackages(winrt::Windows::Foundation::Collections::IVector const& packageProviders) 13 | { 14 | // IReactPackageProviders from react-native-code-push-windows 15 | packageProviders.Append(winrt::Microsoft::CodePush::ReactNative::ReactPackageProvider()); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/AutolinkedNativeModules.g.h: -------------------------------------------------------------------------------- 1 | // AutolinkedNativeModules.g.h contents generated by "react-native autolink-windows" 2 | 3 | #pragma once 4 | 5 | namespace winrt::Microsoft::ReactNative 6 | { 7 | 8 | void RegisterAutolinkedNativeModulePackages(winrt::Windows::Foundation::Collections::IVector const& packageProviders); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/AutolinkedNativeModules.g.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/CodePushDemoAppCpp.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | Assets 25 | 26 | 27 | Assets 28 | 29 | 30 | Assets 31 | 32 | 33 | Assets 34 | 35 | 36 | Assets 37 | 38 | 39 | Assets 40 | 41 | 42 | Assets 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | {e48dc53e-40b1-40cb-970a-f89935452892} 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/CodePushDemoAppCpp_TemporaryKey.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revopush/react-native-code-push/d2f3e96fd01b3d08a0768bb7e72f698f320bb194/Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/CodePushDemoAppCpp_TemporaryKey.pfx -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/MainPage.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "MainPage.h" 3 | #if __has_include("MainPage.g.cpp") 4 | #include "MainPage.g.cpp" 5 | #endif 6 | 7 | #include "App.h" 8 | 9 | 10 | 11 | using namespace winrt; 12 | using namespace Windows::UI::Xaml; 13 | 14 | namespace winrt::CodePushDemoAppCpp::implementation 15 | { 16 | MainPage::MainPage() 17 | { 18 | InitializeComponent(); 19 | auto app = Application::Current().as(); 20 | ReactRootView().ReactNativeHost(app->Host()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/MainPage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "MainPage.g.h" 3 | #include 4 | 5 | 6 | namespace winrt::CodePushDemoAppCpp::implementation 7 | { 8 | struct MainPage : MainPageT 9 | { 10 | MainPage(); 11 | }; 12 | } 13 | 14 | namespace winrt::CodePushDemoAppCpp::factory_implementation 15 | { 16 | struct MainPage : MainPageT 17 | { 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/MainPage.idl: -------------------------------------------------------------------------------- 1 | namespace CodePushDemoAppCpp 2 | { 3 | [default_interface] 4 | runtimeclass MainPage : Windows.UI.Xaml.Controls.Page 5 | { 6 | MainPage(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/MainPage.xaml: -------------------------------------------------------------------------------- 1 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/Package.appxmanifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 8 | 9 | 13 | 14 | 15 | 16 | 17 | CodePushDemoAppCpp 18 | Aleksey 19 | Assets\StoreLogo.png 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 35 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/PropertySheet.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/ReactPackageProvider.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "ReactPackageProvider.h" 3 | #include "NativeModules.h" 4 | 5 | 6 | using namespace winrt::Microsoft::ReactNative; 7 | 8 | namespace winrt::CodePushDemoAppCpp::implementation 9 | { 10 | 11 | void ReactPackageProvider::CreatePackage(IReactPackageBuilder const &packageBuilder) noexcept 12 | { 13 | AddAttributedModules(packageBuilder); 14 | } 15 | 16 | } // namespace winrt::CodePushDemoAppCpp::implementation 17 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/ReactPackageProvider.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "winrt/Microsoft.ReactNative.h" 4 | 5 | namespace winrt::CodePushDemoAppCpp::implementation 6 | { 7 | struct ReactPackageProvider : winrt::implements 8 | { 9 | public: // IReactPackageProvider 10 | void CreatePackage(winrt::Microsoft::ReactNative::IReactPackageBuilder const &packageBuilder) noexcept; 11 | }; 12 | } // namespace winrt::CodePushDemoAppCpp::implementation 13 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/pch.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | -------------------------------------------------------------------------------- /Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define NOMINMAX 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Microsoft CodePush Plugin for React Native 2 | 3 | Copyright (c) Microsoft Corporation 4 | 5 | All rights reserved. 6 | 7 | MIT License 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Recipes/UpdateButton.ios.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var pkg = require('./package'); 4 | var React = require('react-native'); 5 | var { 6 | AppRegistry, 7 | StyleSheet, 8 | Text, 9 | View, 10 | } = React; 11 | var Button = require('react-native-button'); 12 | 13 | var CodePush = require('react-native-code-push'); 14 | 15 | var UpdateButton = React.createClass({ 16 | getInitialState: function() { 17 | return {}; 18 | }, 19 | componentDidMount: function() { 20 | CodePush.checkForUpdate().done((update) => { 21 | if (update && !update.downloadURL) { 22 | this.setState({ 23 | update: update 24 | }); 25 | } 26 | }); 27 | }, 28 | update: function() { 29 | this.state.update.download().done((newPackage) => { 30 | newPackage.install(); 31 | }); 32 | }, 33 | render: function() { 34 | var updateButton = null; 35 | if (this.state.update) { 36 | updateButton = ; 37 | } 38 | 39 | return ( 40 | 41 | 42 | Welcome to {pkg.name} {pkg.version}! 43 | 44 | {updateButton} 45 | 46 | ); 47 | } 48 | }); 49 | 50 | var styles = StyleSheet.create({ 51 | container: { 52 | flex: 1, 53 | justifyContent: 'center', 54 | alignItems: 'center', 55 | backgroundColor: '#F5FCFF', 56 | } 57 | }); 58 | 59 | AppRegistry.registerComponent('UpdateButton', () => UpdateButton); 60 | -------------------------------------------------------------------------------- /Recipes/UpdateOnStart.ios.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var pkg = require('./package'); 4 | var React = require('react-native'); 5 | var { 6 | AppRegistry, 7 | StyleSheet, 8 | Text, 9 | View, 10 | } = React; 11 | 12 | var CodePush = require('react-native-code-push'); 13 | 14 | var UpdateOnStart = React.createClass({ 15 | componentDidMount: function() { 16 | CodePush.checkForUpdate().done((update) => { 17 | if (update && update.downloadUrl) { 18 | update.download().done((newPackage) => { 19 | newPackage.install(); 20 | }); 21 | } 22 | }); 23 | }, 24 | render: function() { 25 | return ( 26 | 27 | 28 | Welcome to {pkg.name} {pkg.version}! 29 | 30 | 31 | ); 32 | } 33 | }); 34 | 35 | var styles = StyleSheet.create({ 36 | container: { 37 | flex: 1, 38 | justifyContent: 'center', 39 | alignItems: 'center', 40 | backgroundColor: '#F5FCFF', 41 | } 42 | }); 43 | 44 | AppRegistry.registerComponent('UpdateOnStart', () => UpdateOnStart); 45 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). 40 | 41 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.library" 2 | 3 | def isNewArchitectureEnabled() { 4 | // To opt-in for the New Architecture, you can either: 5 | // - Set `newArchEnabled` to true inside the `gradle.properties` file 6 | // - Invoke gradle with `-newArchEnabled=true` 7 | // - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true` 8 | return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true" 9 | } 10 | 11 | def IS_NEW_ARCHITECTURE_ENABLED = isNewArchitectureEnabled() 12 | 13 | if (IS_NEW_ARCHITECTURE_ENABLED) { 14 | apply plugin: "com.facebook.react" 15 | } 16 | 17 | def DEFAULT_COMPILE_SDK_VERSION = 26 18 | def DEFAULT_BUILD_TOOLS_VERSION = "26.0.3" 19 | def DEFAULT_TARGET_SDK_VERSION = 26 20 | def DEFAULT_MIN_SDK_VERSION = 16 21 | 22 | android { 23 | namespace "com.microsoft.codepush.react" 24 | 25 | compileSdkVersion rootProject.hasProperty('compileSdkVersion') ? rootProject.compileSdkVersion : DEFAULT_COMPILE_SDK_VERSION 26 | buildToolsVersion rootProject.hasProperty('buildToolsVersion') ? rootProject.buildToolsVersion : DEFAULT_BUILD_TOOLS_VERSION 27 | 28 | defaultConfig { 29 | minSdkVersion rootProject.hasProperty('minSdkVersion') ? rootProject.minSdkVersion : DEFAULT_MIN_SDK_VERSION 30 | targetSdkVersion rootProject.hasProperty('targetSdkVersion') ? rootProject.targetSdkVersion : DEFAULT_TARGET_SDK_VERSION 31 | versionCode 1 32 | versionName "1.0" 33 | buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", IS_NEW_ARCHITECTURE_ENABLED.toString() 34 | } 35 | 36 | lintOptions { 37 | abortOnError false 38 | } 39 | 40 | defaultConfig { 41 | consumerProguardFiles 'proguard-rules.pro' 42 | } 43 | } 44 | 45 | dependencies { 46 | implementation "com.facebook.react:react-native:+" 47 | implementation 'com.nimbusds:nimbus-jose-jwt:9.37.3' 48 | } 49 | -------------------------------------------------------------------------------- /android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Invoked via reflection, when setting js bundle. 20 | -keepclassmembers class com.facebook.react.ReactInstanceManager { 21 | private final ** mBundleLoader; 22 | } 23 | 24 | -keepclassmembers class com.facebook.react.runtime.ReactHostImpl { 25 | private final ** mReactHostDelegate; 26 | } 27 | 28 | -keep interface com.facebook.react.runtime.ReactHostDelegate { *; } 29 | 30 | -keep class * implements com.facebook.react.runtime.ReactHostDelegate { *; } 31 | 32 | # Can't find referenced class org.bouncycastle.** 33 | -dontwarn com.nimbusds.jose.** 34 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/microsoft/codepush/react/CodePushConstants.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.codepush.react; 2 | 3 | public class CodePushConstants { 4 | public static final String ASSETS_BUNDLE_PREFIX = "assets://"; 5 | public static final String BINARY_MODIFIED_TIME_KEY = "binaryModifiedTime"; 6 | public static final String CODE_PUSH_FOLDER_PREFIX = "CodePush"; 7 | public static final String CODE_PUSH_HASH_FILE_NAME = "CodePushHash"; 8 | public static final String CODE_PUSH_OLD_HASH_FILE_NAME = "CodePushHash.json"; 9 | public static final String CODE_PUSH_PREFERENCES = "CodePush"; 10 | public static final String CURRENT_PACKAGE_KEY = "currentPackage"; 11 | public static final String DEFAULT_JS_BUNDLE_NAME = "index.android.bundle"; 12 | public static final String DIFF_MANIFEST_FILE_NAME = "hotcodepush.json"; 13 | public static final int DOWNLOAD_BUFFER_SIZE = 1024 * 256; 14 | public static final String DOWNLOAD_FILE_NAME = "download.zip"; 15 | public static final String DOWNLOAD_PROGRESS_EVENT_NAME = "CodePushDownloadProgress"; 16 | public static final String DOWNLOAD_URL_KEY = "downloadUrl"; 17 | public static final String FAILED_UPDATES_KEY = "CODE_PUSH_FAILED_UPDATES"; 18 | public static final String PACKAGE_FILE_NAME = "app.json"; 19 | public static final String PACKAGE_HASH_KEY = "packageHash"; 20 | public static final String PENDING_UPDATE_HASH_KEY = "hash"; 21 | public static final String PENDING_UPDATE_IS_LOADING_KEY = "isLoading"; 22 | public static final String PENDING_UPDATE_KEY = "CODE_PUSH_PENDING_UPDATE"; 23 | public static final String PREVIOUS_PACKAGE_KEY = "previousPackage"; 24 | public static final String REACT_NATIVE_LOG_TAG = "ReactNative"; 25 | public static final String RELATIVE_BUNDLE_PATH_KEY = "bundlePath"; 26 | public static final String STATUS_FILE = "codepush.json"; 27 | public static final String UNZIPPED_FOLDER_NAME = "unzipped"; 28 | public static final String CODE_PUSH_APK_BUILD_TIME_KEY = "CODE_PUSH_APK_BUILD_TIME"; 29 | public static final String BUNDLE_JWT_FILE = ".codepushrelease"; 30 | public static final String LATEST_ROLLBACK_INFO_KEY = "LATEST_ROLLBACK_INFO"; 31 | public static final String LATEST_ROLLBACK_PACKAGE_HASH_KEY = "packageHash"; 32 | public static final String LATEST_ROLLBACK_TIME_KEY = "time"; 33 | public static final String LATEST_ROLLBACK_COUNT_KEY = "count"; 34 | public static final String CLIENT_UNIQUE_ID_KEY = "clientUniqueId"; 35 | } 36 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/microsoft/codepush/react/CodePushInstallMode.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.codepush.react; 2 | 3 | public enum CodePushInstallMode { 4 | IMMEDIATE(0), 5 | ON_NEXT_RESTART(1), 6 | ON_NEXT_RESUME(2), 7 | ON_NEXT_SUSPEND(3); 8 | 9 | private final int value; 10 | CodePushInstallMode(int value) { 11 | this.value = value; 12 | } 13 | public int getValue() { 14 | return this.value; 15 | } 16 | } -------------------------------------------------------------------------------- /android/app/src/main/java/com/microsoft/codepush/react/CodePushInvalidPublicKeyException.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.codepush.react; 2 | 3 | class CodePushInvalidPublicKeyException extends RuntimeException { 4 | 5 | public CodePushInvalidPublicKeyException(String message, Throwable cause) { 6 | super(message, cause); 7 | } 8 | 9 | public CodePushInvalidPublicKeyException(String message) { 10 | super(message); 11 | } 12 | } -------------------------------------------------------------------------------- /android/app/src/main/java/com/microsoft/codepush/react/CodePushInvalidUpdateException.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.codepush.react; 2 | 3 | public class CodePushInvalidUpdateException extends RuntimeException { 4 | public CodePushInvalidUpdateException(String message) { 5 | super(message); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/microsoft/codepush/react/CodePushMalformedDataException.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.codepush.react; 2 | 3 | import java.net.MalformedURLException; 4 | 5 | public class CodePushMalformedDataException extends RuntimeException { 6 | public CodePushMalformedDataException(String path, Throwable cause) { 7 | super("Unable to parse contents of " + path + ", the file may be corrupted.", cause); 8 | } 9 | public CodePushMalformedDataException(String url, MalformedURLException cause) { 10 | super("The package has an invalid downloadUrl: " + url, cause); 11 | } 12 | } -------------------------------------------------------------------------------- /android/app/src/main/java/com/microsoft/codepush/react/CodePushNotInitializedException.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.codepush.react; 2 | 3 | public final class CodePushNotInitializedException extends RuntimeException { 4 | 5 | public CodePushNotInitializedException(String message, Throwable cause) { 6 | super(message, cause); 7 | } 8 | 9 | public CodePushNotInitializedException(String message) { 10 | super(message); 11 | } 12 | } -------------------------------------------------------------------------------- /android/app/src/main/java/com/microsoft/codepush/react/CodePushUnknownException.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.codepush.react; 2 | 3 | class CodePushUnknownException extends RuntimeException { 4 | 5 | public CodePushUnknownException(String message, Throwable cause) { 6 | super(message, cause); 7 | } 8 | 9 | public CodePushUnknownException(String message) { 10 | super(message); 11 | } 12 | } -------------------------------------------------------------------------------- /android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateState.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.codepush.react; 2 | 3 | public enum CodePushUpdateState { 4 | RUNNING(0), 5 | PENDING(1), 6 | LATEST(2); 7 | 8 | private final int value; 9 | CodePushUpdateState(int value) { 10 | this.value = value; 11 | } 12 | public int getValue() { 13 | return this.value; 14 | } 15 | } -------------------------------------------------------------------------------- /android/app/src/main/java/com/microsoft/codepush/react/DownloadProgress.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.codepush.react; 2 | 3 | import com.facebook.react.bridge.WritableMap; 4 | import com.facebook.react.bridge.WritableNativeMap; 5 | 6 | class DownloadProgress { 7 | private long mTotalBytes; 8 | private long mReceivedBytes; 9 | 10 | public DownloadProgress (long totalBytes, long receivedBytes){ 11 | mTotalBytes = totalBytes; 12 | mReceivedBytes = receivedBytes; 13 | } 14 | 15 | public WritableMap createWritableMap() { 16 | WritableMap map = new WritableNativeMap(); 17 | if (mTotalBytes < Integer.MAX_VALUE) { 18 | map.putInt("totalBytes", (int) mTotalBytes); 19 | map.putInt("receivedBytes", (int) mReceivedBytes); 20 | } else { 21 | map.putDouble("totalBytes", mTotalBytes); 22 | map.putDouble("receivedBytes", mReceivedBytes); 23 | } 24 | return map; 25 | } 26 | 27 | public boolean isCompleted() { 28 | return mTotalBytes == mReceivedBytes; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/microsoft/codepush/react/DownloadProgressCallback.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.codepush.react; 2 | 3 | interface DownloadProgressCallback { 4 | void call(DownloadProgress downloadProgress); 5 | } 6 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/microsoft/codepush/react/ReactHostHolder.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.codepush.react; 2 | 3 | import com.facebook.react.ReactHost; 4 | import com.facebook.react.runtime.ReactHostDelegate; 5 | 6 | /** 7 | * Provides access to a {@link ReactHostDelegate} 8 | */ 9 | public interface ReactHostHolder { 10 | ReactHost getReactHost(); 11 | } -------------------------------------------------------------------------------- /android/app/src/main/java/com/microsoft/codepush/react/ReactInstanceHolder.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.codepush.react; 2 | 3 | import com.facebook.react.ReactInstanceManager; 4 | 5 | /** 6 | * Provides access to a {@link ReactInstanceManager}. 7 | * 8 | * ReactNativeHost already implements this interface, if you make use of that react-native 9 | * component (just add `implements ReactInstanceHolder`). 10 | */ 11 | public interface ReactInstanceHolder { 12 | 13 | /** 14 | * Get the current {@link ReactInstanceManager} instance. May return null. 15 | */ 16 | ReactInstanceManager getReactInstanceManager(); 17 | } 18 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/microsoft/codepush/react/TLSSocketFactory.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.codepush.react; 2 | 3 | import java.io.IOException; 4 | import java.net.InetAddress; 5 | import java.net.Socket; 6 | import java.net.UnknownHostException; 7 | import java.security.KeyManagementException; 8 | import java.security.NoSuchAlgorithmException; 9 | 10 | import javax.net.ssl.SSLContext; 11 | import javax.net.ssl.SSLSocket; 12 | import javax.net.ssl.SSLSocketFactory; 13 | 14 | public class TLSSocketFactory extends SSLSocketFactory { 15 | 16 | private SSLSocketFactory delegate; 17 | 18 | public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException { 19 | SSLContext context = SSLContext.getInstance("TLS"); 20 | context.init(null, null, null); 21 | delegate = context.getSocketFactory(); 22 | } 23 | 24 | @Override 25 | public String[] getDefaultCipherSuites() { 26 | return delegate.getDefaultCipherSuites(); 27 | } 28 | 29 | @Override 30 | public String[] getSupportedCipherSuites() { 31 | return delegate.getSupportedCipherSuites(); 32 | } 33 | 34 | @Override 35 | public Socket createSocket() throws IOException { 36 | return enableTLSOnSocket(delegate.createSocket()); 37 | } 38 | 39 | @Override 40 | public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { 41 | return enableTLSOnSocket(delegate.createSocket(s, host, port, autoClose)); 42 | } 43 | 44 | @Override 45 | public Socket createSocket(String host, int port) throws IOException, UnknownHostException { 46 | return enableTLSOnSocket(delegate.createSocket(host, port)); 47 | } 48 | 49 | @Override 50 | public Socket createSocket(String host, int port, InetAddress localHost, int localPort) 51 | throws IOException, UnknownHostException { 52 | return enableTLSOnSocket(delegate.createSocket(host, port, localHost, localPort)); 53 | } 54 | 55 | @Override 56 | public Socket createSocket(InetAddress host, int port) throws IOException { 57 | return enableTLSOnSocket(delegate.createSocket(host, port)); 58 | } 59 | 60 | @Override 61 | public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) 62 | throws IOException { 63 | return enableTLSOnSocket(delegate.createSocket(address, port, localAddress, localPort)); 64 | } 65 | 66 | private Socket enableTLSOnSocket(Socket socket) { 67 | if (socket != null && (socket instanceof SSLSocket)) { 68 | ((SSLSocket) socket).setEnabledProtocols(new String[] { "TLSv1.1", "TLSv1.2" }); 69 | } 70 | return socket; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | google() 6 | mavenCentral() 7 | } 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:1.3.0' 10 | 11 | // NOTE: Do not place your application dependencies here; they belong 12 | // in the individual module build.gradle files 13 | } 14 | } 15 | 16 | allprojects { 17 | android { 18 | namespace "com.microsoft.codepush.react" 19 | } 20 | repositories { 21 | mavenLocal() 22 | mavenCentral() 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | android.useDeprecatedNdk=true 21 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/revopush/react-native-code-push/d2f3e96fd01b3d08a0768bb7e72f698f320bb194/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip 6 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' -------------------------------------------------------------------------------- /code-push-plugin-testing-framework/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "code-push-plugin-testing-framework", 3 | "version": "0.0.1", 4 | "description": "Plugin Testing Framework for CodePush Plugins", 5 | "main": "script/index.js", 6 | "scripts": { 7 | "test": "gulp" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/microsoft/code-push.git" 12 | }, 13 | "author": { 14 | "name": "Microsoft Corporation" 15 | }, 16 | "license": "MIT", 17 | "homepage": "https://microsoft.github.io/code-push", 18 | "dependencies": { 19 | "@types/uuid": "^8.3.1", 20 | "base-64": "^1.0.0", 21 | "mocha": "latest", 22 | "mocha-junit-reporter": "latest", 23 | "q": "^1.5.1", 24 | "replace": "latest", 25 | "superagent": "^6.1.0", 26 | "superagent-proxy": "^3.0.0", 27 | "uuid": "^8.3.2" 28 | }, 29 | "bugs": { 30 | "url": "https://github.com/microsoft/code-push/issues" 31 | }, 32 | "readme": "ERROR: No README data found!", 33 | "_id": "code-push-plugin-testing-framework@0.0.1", 34 | "_shasum": "6ea33a661710628af266d714949fe95f88d71f0d", 35 | "_from": "../code-push/plugin-testing-framework/bin", 36 | "_resolved": "file:../code-push/plugin-testing-framework/bin" 37 | } 38 | -------------------------------------------------------------------------------- /code-push-plugin-testing-framework/script/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var Platform = require("./platform"); 3 | exports.Platform = Platform; 4 | var PluginTestingFramework = require("./test"); 5 | exports.PluginTestingFramework = PluginTestingFramework; 6 | var projectManager_1 = require("./projectManager"); 7 | exports.ProjectManager = projectManager_1.ProjectManager; 8 | exports.setupTestRunScenario = projectManager_1.setupTestRunScenario; 9 | exports.setupUpdateScenario = projectManager_1.setupUpdateScenario; 10 | var ServerUtil = require("./serverUtil"); 11 | exports.ServerUtil = ServerUtil; 12 | var testBuilder_1 = require("./testBuilder"); 13 | exports.TestBuilder = testBuilder_1.TestBuilder; 14 | var TestConfig = require("./testConfig"); 15 | exports.TestConfig = TestConfig; 16 | var testUtil_1 = require("./testUtil"); 17 | exports.TestUtil = testUtil_1.TestUtil; 18 | -------------------------------------------------------------------------------- /code-push-plugin-testing-framework/script/testConfig.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | // IMPORTS // 3 | var os = require("os"); 4 | var path = require("path"); 5 | var TestUtil_1 = require("./testUtil"); 6 | ////////////////////////////////////////////////////////////////////////////////////////// 7 | // Configuration variables. 8 | // What plugin to use, what project directories to use, etc. 9 | // COMMAND LINE OPTION NAMES, FLAGS, AND DEFAULTS 10 | var DEFAULT_TEST_RUN_DIRECTORY = path.join(os.tmpdir(), TestUtil_1.TestUtil.getPluginName(), "test-run"); 11 | var DEFAULT_UPDATES_DIRECTORY = path.join(os.tmpdir(), TestUtil_1.TestUtil.getPluginName(), "updates"); 12 | var DEFAULT_PLUGIN_PATH = path.join(__dirname, "../.."); 13 | var NPM_PLUGIN_PATH = TestUtil_1.TestUtil.getPluginName(); 14 | var SETUP_FLAG_NAME = "--setup"; 15 | var DEFAULT_PLUGIN_TGZ_NAME = TestUtil_1.TestUtil.getPluginName().replace("@", "").replace("/", "-") + "-" + TestUtil_1.TestUtil.getPluginVersion() + ".tgz"; 16 | // CONST VARIABLES 17 | exports.TestAppName = "TestCodePush"; 18 | exports.TestNamespace = "com.testcodepush"; 19 | exports.AcquisitionSDKPluginName = "code-push"; 20 | exports.templatePath = path.join(__dirname, "../../test/template"); 21 | exports.thisPluginInstallString = TestUtil_1.TestUtil.resolveBooleanVariables(process.env.NPM) ? `npm install ${NPM_PLUGIN_PATH}` : `npm pack ${DEFAULT_PLUGIN_PATH} && npm install ${DEFAULT_PLUGIN_TGZ_NAME} && npm link`; 22 | exports.testRunDirectory = process.env.RUN_DIR ? process.env.RUN_DIR: DEFAULT_TEST_RUN_DIRECTORY; 23 | exports.updatesDirectory = process.env.UPDATE_DIR ? process.env.UPDATE_DIR : DEFAULT_UPDATES_DIRECTORY; 24 | exports.onlyRunCoreTests = TestUtil_1.TestUtil.resolveBooleanVariables(process.env.CORE); 25 | exports.shouldSetup = TestUtil_1.TestUtil.readMochaCommandLineFlag(SETUP_FLAG_NAME); 26 | exports.restartEmulators = TestUtil_1.TestUtil.resolveBooleanVariables(process.env.CLEAN); 27 | exports.isOldArchitecture = TestUtil_1.TestUtil.resolveBooleanVariables(process.env.IS_OLD_ARCHITECTURE); 28 | -------------------------------------------------------------------------------- /docs/multi-deployment-testing-android.md: -------------------------------------------------------------------------------- 1 | ### Android 2 | 3 | > NOTE 4 | > 5 | > Complete demo configured with "multi-deployment testing" feature is [here](https://github.com/microsoft/react-native-code-push/files/1314118/rncp1004.zip). 6 | 7 | The [Android Gradle plugin](https://google.github.io/android-gradle-dsl/current/index.html) allows you to define custom config settings for each "build type" (like debug, release). This mechanism allows you to easily configure your debug builds to use your CodePush staging deployment key and your release builds to use your CodePush production deployment key. 8 | 9 | *NOTE: As a reminder, you can retrieve these keys by running ` revopush deployment ls -k` from your terminal.* 10 | 11 | To set this up, perform the following steps: 12 | 13 | **For React Native >= v0.76** 14 | 15 | 1. Open the project's app level `build.gradle` file (for example `android/app/build.gradle` in standard React Native projects) 16 | 17 | 2. Find the `android { buildTypes {} }` section and define `resValue` entries for both your `debug` and `release` build types, which reference your `Staging` and `Production` deployment keys respectively. 18 | 19 | ```groovy 20 | android { 21 | ... 22 | buildTypes { 23 | debug { 24 | ... 25 | // Note: CodePush updates should not be tested in Debug mode as they are overriden by the RN packager. However, because CodePush checks for updates in all modes, we must supply a key. 26 | resValue "string", "CodePushDeploymentKey", '""' 27 | ... 28 | } 29 | 30 | releaseStaging { 31 | ... 32 | resValue "string", "CodePushDeploymentKey", '""' 33 | 34 | // Note: It is a good idea to provide matchingFallbacks for the new buildType you create to prevent build issues 35 | // Add the following line if not already there 36 | matchingFallbacks = ['release'] 37 | ... 38 | } 39 | 40 | release { 41 | ... 42 | resValue "string", "CodePushDeploymentKey", '""' 43 | ... 44 | } 45 | } 46 | ... 47 | } 48 | ``` 49 | 50 | *NOTE: Remember to remove the key from `strings.xml` if you are configuring the deployment key in the build process* 51 | 52 | *NOTE: The naming convention for `releaseStaging` is significant due to [this line](https://github.com/facebook/react-native/blob/e083f9a139b3f8c5552528f8f8018529ef3193b9/react.gradle#L79).* 53 | 54 | 55 | And that's it! View [here](http://tools.android.com/tech-docs/new-build-system/resource-merging) for more details on how resource merging works in Android. 56 | -------------------------------------------------------------------------------- /ios/CodePush.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/CodePush.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/CodePush/Base64/Base64/MF_Base64Additions.h: -------------------------------------------------------------------------------- 1 | // 2 | // MF_Base64Additions.h 3 | // Base64 -- RFC 4648 compatible implementation 4 | // see http://www.ietf.org/rfc/rfc4648.txt for more details 5 | // 6 | // Designed to be compiled with Automatic Reference Counting 7 | // 8 | // Created by Dave Poirier on 2012-06-14. 9 | // Public Domain 10 | // Hosted at https://github.com/ekscrypto/Base64 11 | // 12 | 13 | #import 14 | 15 | @interface NSString (Base64Addition) 16 | +(NSString *)stringFromBase64String:(NSString *)base64String; 17 | +(NSString *)stringFromBase64UrlEncodedString:(NSString *)base64UrlEncodedString; 18 | -(NSString *)base64String; 19 | -(NSString *)base64UrlEncodedString; 20 | @end 21 | 22 | @interface NSData (Base64Addition) 23 | +(NSData *)dataWithBase64String:(NSString *)base64String; 24 | +(NSData *)dataWithBase64UrlEncodedString:(NSString *)base64UrlEncodedString; 25 | -(NSString *)base64String; 26 | -(NSString *)base64UrlEncodedString; 27 | @end 28 | 29 | @interface MF_Base64Codec : NSObject 30 | +(NSData *)dataFromBase64String:(NSString *)base64String; 31 | +(NSString *)base64StringFromData:(NSData *)data; 32 | +(NSString *)base64UrlEncodedStringFromBase64String:(NSString *)base64String; 33 | +(NSString *)base64StringFromBase64UrlEncodedString:(NSString *)base64UrlEncodedString; 34 | @end 35 | -------------------------------------------------------------------------------- /ios/CodePush/Base64/README.md: -------------------------------------------------------------------------------- 1 | [![CI Status](https://travis-ci.org/ekscrypto/Base64.svg?branch=master)](https://github.com/ekscrypto/Base64) 2 | 3 | Base64 Additions for Objective-C on Mac OS X and iOS 4 | ======= 5 | 6 | 7 | Usage 8 | ---- 9 | Open the Xcode project file, and drag MF_Base64Additions.m/.h into your project. 10 | 11 | In files where you want to use Base64 encoding/decoding, simply include the header file and use one of the provided NSData or NSString additions. 12 | 13 | Example use: 14 | #import "MF_Base64Additions.h" 15 | 16 | NSString *helloWorld = @"Hello World"; 17 | NSString *helloInBase64 = [helloWorld base64String]; 18 | NSString *helloDecoded = [NSString stringFromBase64String:helloInBase64]; 19 | 20 | 21 | 22 | 23 | Performance 24 | ---- 25 | * Encoding: Approximately 4 to 5 times faster than using the equivalent SecTransform. 26 | * Encoding: 30% faster than https://github.com/l4u/NSData-Base64 27 | * Decoding: 5% faster than using the equivalent SecTransform. 28 | * Decoding: 5% faster than https://github.com/l4u/NSData-Base64 29 | 30 | 31 | 32 | Requirements 33 | ----- 34 | * Compile with Automatic Reference Counting 35 | * Compatible with Mac OSX 10.6+ and iOS 4.0+ 36 | 37 | 38 | 39 | Implementation 40 | ---- 41 | * Implemented as per RFC 4648, see http://www.ietf.org/rfc/rfc4648.txt for more details. 42 | 43 | 44 | 45 | Licensing 46 | ---- 47 | * Public Domain 48 | -------------------------------------------------------------------------------- /ios/CodePush/CodePushErrorUtils.m: -------------------------------------------------------------------------------- 1 | #import "CodePush.h" 2 | 3 | @implementation CodePushErrorUtils 4 | 5 | static NSString *const CodePushErrorDomain = @"CodePushError"; 6 | static const int CodePushErrorCode = -1; 7 | 8 | + (NSError *)errorWithMessage:(NSString *)errorMessage 9 | { 10 | return [NSError errorWithDomain:CodePushErrorDomain 11 | code:CodePushErrorCode 12 | userInfo:@{ NSLocalizedDescriptionKey: NSLocalizedString(errorMessage, nil) }]; 13 | } 14 | 15 | + (BOOL)isCodePushError:(NSError *)err 16 | { 17 | return err != nil && [CodePushErrorDomain isEqualToString:err.domain]; 18 | } 19 | 20 | @end -------------------------------------------------------------------------------- /ios/CodePush/CodePushUtils.m: -------------------------------------------------------------------------------- 1 | #import "CodePush.h" 2 | 3 | void CPLog(NSString *formatString, ...) { 4 | va_list args; 5 | va_start(args, formatString); 6 | NSString *prependedFormatString = [NSString stringWithFormat:@"\n[CodePush] %@", formatString]; 7 | NSLogv(prependedFormatString, args); 8 | va_end(args); 9 | } -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithm.h: -------------------------------------------------------------------------------- 1 | // 2 | // JWTAlgorithm.h 3 | // JWT 4 | // 5 | // Created by Klaas Pieter Annema on 31-05-13. 6 | // Copyright (c) 2013 Karma. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "JWTDeprecations.h" 11 | 12 | @protocol JWTAlgorithm 13 | 14 | @required 15 | /** 16 | Signs data using provided secret data. 17 | @param hash The data to sign. 18 | @param key The secret to use for signing. 19 | @param error The inout error. 20 | */ 21 | - (NSData *)signHash:(NSData *)hash key:(NSData *)key error:(NSError *__autoreleasing*)error; 22 | /** 23 | Verifies data using. 24 | @param hash The data to sign. 25 | @param signature The secret to use for signing. 26 | @param error The inout error. 27 | */ 28 | - (BOOL)verifyHash:(NSData *)hash signature:(NSData *)signature key:(NSData *)key error:(NSError *__autoreleasing*)error; 29 | 30 | //@required 31 | 32 | @property (nonatomic, readonly, copy) NSString *name; 33 | 34 | /** 35 | Encodes and encrypts the provided payload using the provided secret key 36 | @param theString The string to encode 37 | @param theSecret The secret to use for encryption 38 | @return An NSData object containing the encrypted payload, or nil if something went wrong. 39 | */ 40 | - (NSData *)encodePayload:(NSString *)theString withSecret:(NSString *)theSecret __deprecated_and_will_be_removed_in_release_version(JWTVersion_3_0_0); 41 | 42 | /** 43 | Verifies the provided signature using the signed input and verification key 44 | @param input The header and payload encoded string 45 | @param signature The JWT provided signature 46 | @param verificationKey The key to use for verifying the signature 47 | @return YES if the provided signature is valid, NO otherwise 48 | */ 49 | - (BOOL)verifySignedInput:(NSString *)input withSignature:(NSString *)signature verificationKey:(NSString *)verificationKey __deprecated_and_will_be_removed_in_release_version(JWTVersion_3_0_0); 50 | 51 | @optional 52 | 53 | /** 54 | Encodes and encrypts the provided payload using the provided secret key 55 | @param theStringData The data to encode 56 | @param theSecretData The secret data to use for encryption 57 | @return An NSData object containing the encrypted payload, or nil if something went wrong. 58 | */ 59 | - (NSData *)encodePayloadData:(NSData *)theStringData withSecret:(NSData *)theSecretData; 60 | 61 | /** 62 | Verifies the provided signature using the signed input and verification key (as data) 63 | @param input The header and payload encoded string 64 | @param signature The JWT provided signature 65 | @param verificationKeyData The key data to use for verifying the signature 66 | @return YES if the provided signature is valid, NO otherwise 67 | */ 68 | - (BOOL)verifySignedInput:(NSString *)input withSignature:(NSString *)signature verificationKeyData:(NSData *)verificationKeyData; 69 | @end 70 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithmFactory.h: -------------------------------------------------------------------------------- 1 | // 2 | // JWTAlgorithmFactory.h 3 | // JWT 4 | // 5 | // Created by Lobanov Dmitry on 07.10.15. 6 | // Copyright © 2015 Karma. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "JWTAlgorithm.h" 11 | @interface JWTAlgorithmFactory : NSObject 12 | 13 | + (NSArray *)algorithms; 14 | + (id)algorithmByName:(NSString *)name; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithmFactory.m: -------------------------------------------------------------------------------- 1 | // 2 | // JWTAlgorithmFactory.m 3 | // JWT 4 | // 5 | // Created by Lobanov Dmitry on 07.10.15. 6 | // Copyright © 2015 Karma. All rights reserved. 7 | // 8 | 9 | #import "JWTAlgorithmFactory.h" 10 | #import "JWTAlgorithmHSBase.h" 11 | #import "JWTAlgorithmRSBase.h" 12 | #import "JWTAlgorithmNone.h" 13 | 14 | // not implemented. 15 | NSString *const JWTAlgorithmNameES256 = @"ES256"; 16 | NSString *const JWTAlgorithmNameES384 = @"ES384"; 17 | NSString *const JWTAlgorithmNameES512 = @"ES512"; 18 | 19 | @implementation JWTAlgorithmFactory 20 | 21 | + (NSArray *)algorithms { 22 | return @[ 23 | [JWTAlgorithmNone new], 24 | [JWTAlgorithmHSBase algorithm256], 25 | [JWTAlgorithmHSBase algorithm384], 26 | [JWTAlgorithmHSBase algorithm512], 27 | [JWTAlgorithmRSBase algorithm256], 28 | [JWTAlgorithmRSBase algorithm384], 29 | [JWTAlgorithmRSBase algorithm512] 30 | ]; 31 | 32 | } 33 | 34 | + (id)algorithmByName:(NSString *)name { 35 | id algorithm = nil; 36 | 37 | NSString *algName = [name copy]; 38 | 39 | NSUInteger index = [[self algorithms] indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) { 40 | // lowercase comparison 41 | return [obj.name.lowercaseString isEqualToString:algName.lowercaseString]; 42 | }]; 43 | 44 | if (index != NSNotFound) { 45 | algorithm = [self algorithms][index]; 46 | } 47 | 48 | return algorithm; 49 | } 50 | 51 | @end -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithmNone.h: -------------------------------------------------------------------------------- 1 | // 2 | // JWTAlgorithmNone.h 3 | // JWT 4 | // 5 | // Created by Lobanov Dmitry on 16.10.15. 6 | // Copyright © 2015 Karma. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "JWTAlgorithm.h" 11 | extern NSString *const JWTAlgorithmNameNone; 12 | 13 | @interface JWTAlgorithmNone : NSObject 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithmNone.m: -------------------------------------------------------------------------------- 1 | // 2 | // JWTAlgorithmNone.m 3 | // JWT 4 | // 5 | // Created by Lobanov Dmitry on 16.10.15. 6 | // Copyright © 2015 Karma. All rights reserved. 7 | // 8 | 9 | #import "JWTAlgorithmNone.h" 10 | NSString *const JWTAlgorithmNameNone = @"none"; 11 | 12 | @implementation JWTAlgorithmNone 13 | 14 | - (NSString *)name { 15 | return JWTAlgorithmNameNone; 16 | } 17 | 18 | - (NSData *)signHash:(NSData *)hash key:(NSData *)key error:(NSError *__autoreleasing *)error { 19 | return [NSData data]; 20 | } 21 | 22 | - (BOOL)verifyHash:(NSData *)hash signature:(NSData *)signature key:(NSData *)key error:(NSError *__autoreleasing *)error { 23 | //if a secret is provided, this isn't the None algorithm 24 | if (key && key.length > 0) { 25 | return NO; 26 | } 27 | 28 | //If the signature isn't blank, this isn't the None algorithm 29 | if (signature && signature.length > 0) { 30 | return NO; 31 | } 32 | 33 | return YES; 34 | } 35 | 36 | - (NSData *)encodePayload:(NSString *)theString withSecret:(NSString *)theSecret { 37 | return [self encodePayloadData:[theSecret dataUsingEncoding:NSUTF8StringEncoding] withSecret:[theSecret dataUsingEncoding:NSUTF8StringEncoding]]; 38 | } 39 | 40 | - (NSData *)encodePayloadData:(NSData *)theStringData withSecret:(NSData *)theSecretData 41 | { 42 | return [self signHash:theStringData key:theSecretData error:nil]; 43 | } 44 | 45 | - (BOOL)verifySignedInput:(NSString *)input withSignature:(NSString *)signature verificationKey:(NSString *)verificationKey 46 | { 47 | return [self verifySignedInput:input withSignature:signature verificationKeyData:verificationKey]; 48 | } 49 | 50 | - (BOOL)verifySignedInput:(NSString *)input withSignature:(NSString *)signature verificationKeyData:(NSData *)verificationKeyData 51 | { 52 | return [self verifyHash:[input dataUsingEncoding:NSUTF8StringEncoding] signature:[signature dataUsingEncoding:NSUTF8StringEncoding] key:verificationKeyData error:nil]; 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/Algorithms/ESFamily/JWTAlgorithmESBase.h: -------------------------------------------------------------------------------- 1 | // 2 | // JWTAlgorithmESBase.h 3 | // Pods 4 | // 5 | // Created by Lobanov Dmitry on 12.02.17. 6 | // 7 | // 8 | 9 | #import 10 | #import "JWTRSAlgorithm.h" 11 | extern NSString *const JWTAlgorithmNameES256; 12 | extern NSString *const JWTAlgorithmNameES384; 13 | extern NSString *const JWTAlgorithmNameES512; 14 | @interface JWTAlgorithmESBase : NSObject @end 15 | 16 | @interface JWTAlgorithmESBase (JWTAsymmetricKeysAlgorithm) @end 17 | 18 | @interface JWTAlgorithmESBase (Create) 19 | 20 | + (instancetype)algorithm256; 21 | + (instancetype)algorithm384; 22 | + (instancetype)algorithm512; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/Algorithms/ESFamily/JWTAlgorithmESBase.m: -------------------------------------------------------------------------------- 1 | // 2 | // JWTAlgorithmESBase.m 3 | // Pods 4 | // 5 | // Created by Lobanov Dmitry on 12.02.17. 6 | // 7 | // 8 | 9 | #import "JWTAlgorithmESBase.h" 10 | #import 11 | @interface JWTAlgorithmESBase () 12 | 13 | @end 14 | @implementation JWTAlgorithmESBase 15 | @synthesize keyExtractorType; 16 | @synthesize signKey; 17 | @synthesize verifyKey; 18 | @end 19 | 20 | // thanks! https://github.com/soyersoyer/SwCrypt 21 | @interface JWTAlgorithmESBase (ImportKeys) 22 | - (void)importKey; 23 | //importKey(publicKey, format: .importKeyBinary, keyType: .keyPublic) 24 | @end 25 | @implementation JWTAlgorithmESBase (ImportKeys) 26 | - (void)importKey { 27 | return; 28 | } 29 | @end 30 | 31 | @implementation JWTAlgorithmESBase (JWTAsymmetricKeysAlgorithm) 32 | - (NSString *)name { 33 | return @"ESBase"; 34 | } 35 | - (NSData *)signHash:(NSData *)hash key:(NSData *)key error:(NSError *__autoreleasing *)error { 36 | return nil; 37 | } 38 | - (BOOL)verifyHash:(NSData *)hash signature:(NSData *)signature key:(NSData *)key error:(NSError *__autoreleasing *)error { 39 | return NO; 40 | } 41 | @end 42 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/Algorithms/HSFamily/JWTAlgorithmHSBase.h: -------------------------------------------------------------------------------- 1 | // 2 | // JWTAlgorithmHSBase.h 3 | // JWT 4 | // 5 | // Created by Lobanov Dmitry on 13.03.16. 6 | // Copyright © 2016 Karma. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "JWTAlgorithm.h" 11 | extern NSString *const JWTAlgorithmNameHS256; 12 | extern NSString *const JWTAlgorithmNameHS384; 13 | extern NSString *const JWTAlgorithmNameHS512; 14 | 15 | @interface JWTAlgorithmHSBase : NSObject 16 | 17 | @property (assign, nonatomic, readonly) size_t ccSHANumberDigestLength; 18 | @property (assign, nonatomic, readonly) uint32_t ccHmacAlgSHANumber; 19 | 20 | @end 21 | 22 | @interface JWTAlgorithmHSBase (Create) 23 | 24 | + (instancetype)algorithm256; 25 | + (instancetype)algorithm384; 26 | + (instancetype)algorithm512; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/Algorithms/Holders/JWTAlgorithmDataHolderChain.h: -------------------------------------------------------------------------------- 1 | // 2 | // JWTAlgorithmDataHolderChain.h 3 | // JWT 4 | // 5 | // Created by Lobanov Dmitry on 02.10.16. 6 | // Copyright © 2016 Karma. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "JWTAlgorithmDataHolder.h" 11 | 12 | @interface JWTAlgorithmDataHolderChain : NSObject 13 | 14 | @property (strong, nonatomic, readonly) NSArray *holders; 15 | 16 | #pragma mark - Initialization 17 | - (instancetype)initWithHolders:(NSArray *)holders; 18 | - (instancetype)initWithHolder:(id)holder; 19 | 20 | #pragma mark - Appending 21 | - (instancetype)chainByAppendingChain:(JWTAlgorithmDataHolderChain *)chain; 22 | - (instancetype)chainByAppendingHolders:(NSArray *)holders; 23 | - (instancetype)chainByAppendingHolder:(id)holder; 24 | 25 | #pragma mark - Create 26 | + (instancetype)chainWithHolders:(NSArray *)holders; 27 | + (instancetype)chainWithHolder:(id)holder; 28 | @end 29 | 30 | @interface JWTAlgorithmDataHolderChain (HoldersPopulation) 31 | - (NSArray *)singleAlgorithm:(id)algorithm withManySecretData:(NSArray *)secretsData; 32 | - (NSArray *)singleSecretData:(NSData *)secretData withManyAlgorithms:(NSArray *)algorithms; 33 | 34 | - (instancetype)chainByPopulatingAlgorithm:(id)algorithm withManySecretData:(NSArray *)secretsData; 35 | - (instancetype)chainByPopulatingSecretData:(NSData *)secretData withManyAlgorithms:(NSArray *)algorithms; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/Algorithms/RSFamily/JWTAlgorithmRSBase.h: -------------------------------------------------------------------------------- 1 | // 2 | // JWTAlgorithmRSBase.h 3 | // JWT 4 | // 5 | // Created by Lobanov Dmitry on 13.03.16. 6 | // Copyright © 2016 Karma. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "JWTRSAlgorithm.h" 11 | extern NSString *const JWTAlgorithmNameRS256; 12 | extern NSString *const JWTAlgorithmNameRS384; 13 | extern NSString *const JWTAlgorithmNameRS512; 14 | 15 | @interface JWTAlgorithmRSBase : NSObject 16 | 17 | @property (assign, nonatomic, readonly) size_t ccSHANumberDigestLength; 18 | @property (assign, nonatomic, readonly) uint32_t secPaddingPKCS1SHANumber; 19 | - (unsigned char *)CC_SHANumberWithData:(const void *)data withLength:(uint32_t)len withHashBytes:(unsigned char *)hashBytes; 20 | 21 | @end 22 | 23 | @interface JWTAlgorithmRSBase (Create) 24 | 25 | + (instancetype)algorithm256; 26 | + (instancetype)algorithm384; 27 | + (instancetype)algorithm512; 28 | + (instancetype)mutableAlgorithm __deprecated; 29 | 30 | @end 31 | 32 | /* 33 | // when you can't live without mutability, uncomment. 34 | @class JWTAlgorithmRSFamilyMemberMutable; 35 | */ -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/Algorithms/RSFamily/JWTRSAlgorithm.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Marcelo Schroeder on 12/03/2016. 3 | // Copyright (c) 2016 Karma. All rights reserved. 4 | // 5 | 6 | #import 7 | #import "JWTAlgorithm.h" 8 | @protocol JWTCryptoKeyProtocol; 9 | 10 | @protocol JWTAsymmetricKeysAlgorithm 11 | 12 | @optional 13 | @property(nonatomic, readwrite, copy) NSString *keyExtractorType; 14 | @property(nonatomic, readwrite, strong) id signKey; 15 | @property(nonatomic, readwrite, strong) id verifyKey; 16 | 17 | @end 18 | 19 | @protocol JWTRSAlgorithm 20 | 21 | @required 22 | @property(nonatomic, readwrite, copy) NSString *privateKeyCertificatePassphrase; 23 | @end 24 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoKey.h: -------------------------------------------------------------------------------- 1 | // 2 | // JWTCryptoKey.h 3 | // JWT 4 | // 5 | // Created by Lobanov Dmitry on 04.02.17. 6 | // Copyright © 2017 JWTIO. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @protocol JWTCryptoKeyProtocol 13 | @property (copy, nonatomic, readonly) NSString *tag; 14 | @property (assign, nonatomic, readonly) SecKeyRef key; 15 | @property (copy, nonatomic, readonly) NSData *rawKey; 16 | @end 17 | 18 | @interface JWTCryptoKeyBuilder : NSObject 19 | @property (assign, nonatomic, readonly) NSString *keyType; 20 | - (instancetype)keyTypeRSA; 21 | - (instancetype)keyTypeEC; 22 | @end 23 | 24 | @interface JWTCryptoKey : NSObject 25 | - (instancetype)initWithData:(NSData *)data parameters:(NSDictionary *)parameters error:(NSError *__autoreleasing*)error; //NS_DESIGNATED_INITIALIZER 26 | - (instancetype)initWithBase64String:(NSString *)base64String parameters:(NSDictionary *)parameters error:(NSError *__autoreleasing*)error; 27 | - (instancetype)initWithPemEncoded:(NSString *)encoded parameters:(NSDictionary *)parameters error:(NSError *__autoreleasing*)error; 28 | - (instancetype)initWithPemAtURL:(NSURL *)url parameters:(NSDictionary *)parameters error:(NSError *__autoreleasing*)error; 29 | @end 30 | 31 | @interface JWTCryptoKey (Parameters) 32 | + (NSString *)parametersKeyBuilder; 33 | @end 34 | 35 | @interface JWTCryptoKeyPublic : JWTCryptoKey 36 | - (instancetype)initWithCertificateData:(NSData *)certificateData parameters:(NSDictionary *)parameters error:(NSError *__autoreleasing*)error; //NS_DESIGNATED_INITIALIZER; 37 | - (instancetype)initWithCertificateBase64String:(NSString *)certificateString parameters:(NSDictionary *)parameters error:(NSError *__autoreleasing*)error; 38 | @end 39 | 40 | @interface JWTCryptoKeyPrivate : JWTCryptoKey 41 | - (instancetype)initWithP12Data:(NSData *)p12Data withPassphrase:(NSString *)passphrase parameters:(NSDictionary *)parameters error:(NSError *__autoreleasing*)error; //NS_DESIGNATED_INITIALIZER; 42 | - (instancetype)initWithP12AtURL:(NSURL *)url withPassphrase:(NSString *)passphrase parameters:(NSDictionary *)parameters error:(NSError *__autoreleasing*)error; 43 | @end 44 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoKeyExtractor.h: -------------------------------------------------------------------------------- 1 | // 2 | // JWTCryptoKeyExtractor.h 3 | // JWT 4 | // 5 | // Created by Lobanov Dmitry on 04.02.17. 6 | // Copyright © 2017 JWTIO. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @protocol JWTCryptoKeyProtocol; 13 | @protocol JWTCryptoKeyExtractorProtocol 14 | @optional 15 | - (id)keyFromString:(NSString *)string parameters:(NSDictionary *)parameters error:(NSError *__autoreleasing*)error; 16 | - (id)keyFromData:(NSData *)data parameters:(NSDictionary *)parameters error:(NSError *__autoreleasing*)error; 17 | @end 18 | 19 | @interface JWTCryptoKeyExtractor : NSObject 20 | @property (copy, nonatomic, readonly) NSString *type; 21 | + (NSString *)type; 22 | + (NSString *)parametersKeyCertificatePassphrase; 23 | @end 24 | 25 | @interface JWTCryptoKeyExtractor (ClassCluster) 26 | + (instancetype)publicKeyWithCertificate; 27 | + (instancetype)privateKeyInP12; 28 | + (instancetype)publicKeyWithPEMBase64; 29 | + (instancetype)privateKeyWithPEMBase64; 30 | + (instancetype)createWithType:(NSString *)type; 31 | @end 32 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoSecurity.h: -------------------------------------------------------------------------------- 1 | // 2 | // JWTCryptoSecurity.h 3 | // JWT 4 | // 5 | // Created by Lobanov Dmitry on 04.02.17. 6 | // Copyright © 2017 JWTIO. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | // Thanks for https://github.com/TakeScoop/SwiftyRSA! 12 | @interface JWTCryptoSecurity : NSObject 13 | + (NSString *)keyTypeRSA; 14 | + (NSString *)keyTypeEC; 15 | + (SecKeyRef)addKeyWithData:(NSData *)data asPublic:(BOOL)public tag:(NSString *)tag type:(NSString *)type error:(NSError *__autoreleasing*)error; 16 | + (SecKeyRef)addKeyWithData:(NSData *)data asPublic:(BOOL)public tag:(NSString *)tag error:(NSError *__autoreleasing*)error; 17 | + (SecKeyRef)keyByTag:(NSString *)tag error:(NSError *__autoreleasing*)error; 18 | + (void)removeKeyByTag:(NSString *)tag error:(NSError *__autoreleasing*)error; 19 | @end 20 | 21 | @interface JWTCryptoSecurity (Certificates) 22 | + (OSStatus)extractIdentityAndTrustFromPKCS12:(CFDataRef)inPKCS12Data password:(CFStringRef)password identity:(SecIdentityRef *)outIdentity trust:(SecTrustRef *)outTrust; 23 | + (SecKeyRef)publicKeyFromCertificate:(NSData *)certificateData; 24 | @end 25 | 26 | @interface JWTCryptoSecurity (Pem) 27 | + (NSString *)certificateFromPemFileContent:(NSString *)content; 28 | + (NSString *)keyFromPemFileContent:(NSString *)content; 29 | + (NSArray *)itemsFromPemFileContent:(NSString *)content byRegex:(NSRegularExpression *)expression; 30 | + (NSString *)certificateFromPemFileWithName:(NSString *)name; 31 | + (NSString *)keyFromPemFileWithName:(NSString *)name; 32 | + (NSArray *)itemsFromPemFileWithName:(NSString *)name byRegex:(NSRegularExpression *)expression; 33 | + (NSString *)stringByRemovingPemHeadersFromString:(NSString *)string; 34 | @end 35 | 36 | @interface JWTCryptoSecurity (PublicKey) 37 | + (NSData *)dataByRemovingPublicKeyHeader:(NSData *)data error:(NSError *__autoreleasing*)error; 38 | @end 39 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/ClaimSet/JWTClaim.h: -------------------------------------------------------------------------------- 1 | // 2 | // JWTClaim.h 3 | // JWT 4 | // 5 | // Created by Lobanov Dmitry on 13.02.16. 6 | // Copyright © 2016 Karma. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface JWTClaim : NSObject 12 | 13 | + (NSString *)name; 14 | + (instancetype)claimByName:(NSString *)name; 15 | + (BOOL)verifyValue:(NSObject *)value withTrustedValue:(NSObject *)trustedValue; 16 | - (BOOL)verifyValue:(NSObject *)value withTrustedValue:(NSObject *)trustedValue; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSet.h: -------------------------------------------------------------------------------- 1 | // 2 | // JWTClaimsSet.h 3 | // JWT 4 | // 5 | // Created by Klaas Pieter Annema on 31-05-13. 6 | // Copyright (c) 2013 Karma. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface JWTClaimsSet : NSObject 12 | 13 | @property (nonatomic, readwrite, copy) NSString *issuer; 14 | @property (nonatomic, readwrite, copy) NSString *subject; 15 | @property (nonatomic, readwrite, copy) NSString *audience; 16 | @property (nonatomic, readwrite, copy) NSDate *expirationDate; 17 | @property (nonatomic, readwrite, copy) NSDate *notBeforeDate; 18 | @property (nonatomic, readwrite, copy) NSDate *issuedAt; 19 | @property (nonatomic, readwrite, copy) NSString *identifier; 20 | @property (nonatomic, readwrite, copy) NSString *type; 21 | @property (nonatomic, readwrite, copy) NSString *scope; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSet.m: -------------------------------------------------------------------------------- 1 | // 2 | // JWTClaimsSet.m 3 | // JWT 4 | // 5 | // Created by Klaas Pieter Annema on 31-05-13. 6 | // Copyright (c) 2013 Karma. All rights reserved. 7 | // 8 | 9 | #import "JWTClaimsSet.h" 10 | 11 | @implementation JWTClaimsSet 12 | 13 | - (id)copyWithZone:(NSZone *)zone { 14 | JWTClaimsSet *newClaimsSet = [[self.class alloc] init]; 15 | 16 | newClaimsSet.issuer = self.issuer; 17 | newClaimsSet.subject = self.subject; 18 | newClaimsSet.audience = self.audience; 19 | newClaimsSet.expirationDate = self.expirationDate; 20 | newClaimsSet.notBeforeDate = self.notBeforeDate; 21 | newClaimsSet.issuedAt = self.issuedAt; 22 | newClaimsSet.identifier = self.identifier; 23 | newClaimsSet.type = self.type; 24 | newClaimsSet.scope = self.scope; 25 | 26 | return newClaimsSet; 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSetSerializer.h: -------------------------------------------------------------------------------- 1 | // 2 | // JWTClaimsSetSerializer.h 3 | // JWT 4 | // 5 | // Created by Klaas Pieter Annema on 31-05-13. 6 | // Copyright (c) 2013 Karma. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "JWTClaimsSet.h" 12 | 13 | @interface JWTClaimsSetSerializer : NSObject 14 | 15 | + (NSArray *)claimsSetKeys; 16 | + (NSDictionary *)dictionaryWithClaimsSet:(JWTClaimsSet *)theClaimsSet; 17 | + (JWTClaimsSet *)claimsSetWithDictionary:(NSDictionary *)theDictionary; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSetSerializer.m: -------------------------------------------------------------------------------- 1 | // 2 | // JWTClaimsSetSerializer.m 3 | // JWT 4 | // 5 | // Created by Klaas Pieter Annema on 31-05-13. 6 | // Copyright (c) 2013 Karma. All rights reserved. 7 | // 8 | 9 | #import "JWTClaimsSetSerializer.h" 10 | 11 | @implementation JWTClaimsSetSerializer 12 | 13 | + (NSArray *)claimsSetKeys 14 | { 15 | return @[@"iss", @"sub", @"aud", @"exp", @"nbf", @"iat", @"jti", @"typ", @"scope"]; 16 | } 17 | 18 | + (NSDictionary *)dictionaryWithClaimsSet:(JWTClaimsSet *)theClaimsSet; 19 | { 20 | NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; 21 | [self dictionary:dictionary setObjectIfNotNil:theClaimsSet.issuer forKey:@"iss"]; 22 | [self dictionary:dictionary setObjectIfNotNil:theClaimsSet.subject forKey:@"sub"]; 23 | [self dictionary:dictionary setObjectIfNotNil:theClaimsSet.audience forKey:@"aud"]; 24 | [self dictionary:dictionary setDateIfNotNil:theClaimsSet.expirationDate forKey:@"exp"]; 25 | [self dictionary:dictionary setDateIfNotNil:theClaimsSet.notBeforeDate forKey:@"nbf"]; 26 | [self dictionary:dictionary setDateIfNotNil:theClaimsSet.issuedAt forKey:@"iat"]; 27 | [self dictionary:dictionary setObjectIfNotNil:theClaimsSet.identifier forKey:@"jti"]; 28 | [self dictionary:dictionary setObjectIfNotNil:theClaimsSet.type forKey:@"typ"]; 29 | [self dictionary:dictionary setObjectIfNotNil:theClaimsSet.scope forKey:@"scope"]; 30 | 31 | return [dictionary copy]; 32 | } 33 | 34 | + (JWTClaimsSet *)claimsSetWithDictionary:(NSDictionary *)theDictionary; 35 | { 36 | JWTClaimsSet *claimsSet = [[JWTClaimsSet alloc] init]; 37 | claimsSet.issuer = [theDictionary objectForKey:@"iss"]; 38 | claimsSet.subject = [theDictionary objectForKey:@"sub"]; 39 | claimsSet.audience = [theDictionary objectForKey:@"aud"]; 40 | claimsSet.expirationDate = [NSDate dateWithTimeIntervalSince1970:[[theDictionary objectForKey:@"exp"] doubleValue]]; 41 | claimsSet.notBeforeDate = [NSDate dateWithTimeIntervalSince1970:[[theDictionary objectForKey:@"nbf"] doubleValue]]; 42 | claimsSet.issuedAt = [NSDate dateWithTimeIntervalSince1970:[[theDictionary objectForKey:@"iat"] doubleValue]]; 43 | claimsSet.identifier = [theDictionary objectForKey:@"jti"]; 44 | claimsSet.type = [theDictionary objectForKey:@"typ"]; 45 | claimsSet.scope = [theDictionary objectForKey:@"scope"]; 46 | 47 | return claimsSet; 48 | } 49 | 50 | + (void)dictionary:(NSMutableDictionary *)theDictionary setObjectIfNotNil:(id)theObject forKey:(id)theKey; 51 | { 52 | if (!theObject) 53 | return; 54 | 55 | [theDictionary setObject:theObject forKey:theKey]; 56 | } 57 | 58 | + (void)dictionary:(NSMutableDictionary *)theDictionary setDateIfNotNil:(NSDate*)date forKey:(id)theKey; 59 | { 60 | if (!date) 61 | return; 62 | NSNumber* value = @((unsigned long)[date timeIntervalSince1970]); 63 | 64 | [theDictionary setObject:value forKey:theKey]; 65 | } 66 | 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSetVerifier.h: -------------------------------------------------------------------------------- 1 | // 2 | // JWTClaimsSetVerifier.h 3 | // JWT 4 | // 5 | // Created by Lobanov Dmitry on 13.02.16. 6 | // Copyright © 2016 Karma. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "JWTClaimsSet.h" 11 | 12 | @interface JWTClaimsSetVerifier : NSObject 13 | 14 | + (BOOL)verifyClaimsSet:(JWTClaimsSet *)theClaimsSet withTrustedClaimsSet:(JWTClaimsSet *)trustedClaimsSet; 15 | 16 | + (BOOL)verifyClaimsSetDictionary:(NSDictionary *)theClaimsSetDictionary withTrustedClaimsSet:(JWTClaimsSet *)trustedClaimsSet; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSetVerifier.m: -------------------------------------------------------------------------------- 1 | // 2 | // JWTClaimsSetVerifier.m 3 | // JWT 4 | // 5 | // Created by Lobanov Dmitry on 13.02.16. 6 | // Copyright © 2016 Karma. All rights reserved. 7 | // 8 | 9 | #import "JWTClaimsSetVerifier.h" 10 | #import "JWTClaimsSetSerializer.h" 11 | #import "JWTClaim.h" 12 | 13 | @implementation JWTClaimsSetVerifier 14 | 15 | + (BOOL)verifyDictionary:(NSDictionary *)dictionary withTrustedDictionary:(NSDictionary *)trustedDictionary byKey:(NSString *)key { 16 | NSObject *value = dictionary[key]; 17 | NSObject *trustedValue = trustedDictionary[key]; 18 | 19 | BOOL result = YES; 20 | 21 | if (trustedValue) { 22 | result = [[JWTClaim claimByName:key] verifyValue:value withTrustedValue:trustedValue]; 23 | } 24 | 25 | return result; 26 | } 27 | 28 | + (BOOL)verifyClaimsSetDictionary:(NSDictionary *)theClaimsSetDictionary withTrustedClaimsSetDictionary:(NSDictionary *)trustedClaimsSetDictionary { 29 | 30 | NSArray *claimsSets = [JWTClaimsSetSerializer claimsSetKeys]; 31 | 32 | if (!trustedClaimsSetDictionary) { 33 | return YES; 34 | } 35 | 36 | if (!theClaimsSetDictionary) { 37 | return NO; 38 | } 39 | 40 | BOOL result = YES; 41 | 42 | for (NSString *key in claimsSets) { 43 | result = result && [self verifyDictionary:theClaimsSetDictionary withTrustedDictionary:trustedClaimsSetDictionary byKey:key]; 44 | } 45 | 46 | return result; 47 | } 48 | 49 | 50 | + (BOOL)verifyClaimsSet:(JWTClaimsSet *)theClaimsSet withTrustedClaimsSet:(JWTClaimsSet *)trustedClaimsSet { 51 | 52 | NSDictionary *dictionary = [JWTClaimsSetSerializer dictionaryWithClaimsSet:theClaimsSet]; 53 | 54 | NSDictionary *trustedDictionary = [JWTClaimsSetSerializer dictionaryWithClaimsSet:trustedClaimsSet]; 55 | 56 | NSArray *claimsSets = [JWTClaimsSetSerializer claimsSetKeys]; 57 | 58 | BOOL result = YES; 59 | for (NSString *key in claimsSets) { 60 | result = result && [self verifyDictionary:dictionary withTrustedDictionary:trustedDictionary byKey:key]; 61 | } 62 | 63 | return result; 64 | } 65 | 66 | + (BOOL)verifyClaimsSetDictionary:(NSDictionary *)theClaimsSetDictionary withTrustedClaimsSet:(JWTClaimsSet *)trustedClaimsSet { 67 | NSDictionary *trustedDictionary = [JWTClaimsSetSerializer dictionaryWithClaimsSet:trustedClaimsSet]; 68 | 69 | return [self verifyClaimsSetDictionary:theClaimsSetDictionary withTrustedClaimsSetDictionary:trustedDictionary]; 70 | } 71 | 72 | @end -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/Coding/JWTCoding+ResultTypes.h: -------------------------------------------------------------------------------- 1 | // 2 | // JWTCoding+ResultTypes.h 3 | // JWT 4 | // 5 | // Created by Lobanov Dmitry on 30.11.16. 6 | // Copyright © 2016 JWTIO. All rights reserved. 7 | // 8 | 9 | #import 10 | @class JWTClaimsSet; 11 | 12 | extern NSString *JWTCodingResultHeaders; 13 | extern NSString *JWTCodingResultPayload; 14 | 15 | @interface JWT (ResultTypes) @end 16 | 17 | /* 18 | ResultType 19 | /\ 20 | / \ 21 | / \ 22 | Success Error 23 | 24 | Protocols: Mutable and Immutable (?!?) 25 | */ 26 | 27 | // Public 28 | @protocol JWTCodingResultTypeSuccessEncodedProtocol 29 | @property (copy, nonatomic, readonly) NSString *encoded; 30 | - (instancetype)initWithEncoded:(NSString *)encoded; 31 | @property (copy, nonatomic, readonly) NSString *token; 32 | - (instancetype)initWithToken:(NSString *)token; 33 | @end 34 | 35 | // Public 36 | @protocol JWTCodingResultTypeSuccessDecodedProtocol 37 | @property (copy, nonatomic, readonly) NSDictionary *headers; 38 | @property (copy, nonatomic, readonly) NSDictionary *payload; 39 | 40 | // dictionary @{ 41 | // JWTCodingResultHeaders : self.headers, 42 | // JWTCodingResultPayload : self.payload 43 | //} 44 | @property (copy, nonatomic, readonly) NSDictionary *headerAndPayloadDictionary; 45 | 46 | @property (nonatomic, readonly) JWTClaimsSet *claimsSet; 47 | - (instancetype)initWithHeaders:(NSDictionary *)headers withPayload:(NSDictionary *)payload; 48 | - (instancetype)initWithClaimsSet:(JWTClaimsSet *)claimsSet; 49 | @end 50 | 51 | // Public 52 | @interface JWTCodingResultTypeSuccess : NSObject @end 53 | 54 | // Public 55 | @protocol JWTCodingResultTypeErrorProtocol 56 | @property (copy, nonatomic, readonly) NSError *error; 57 | - (instancetype)initWithError:(NSError *)error; 58 | @end 59 | 60 | @interface JWTCodingResultTypeError : NSObject @end 61 | 62 | @interface JWTCodingResultType : NSObject 63 | - (instancetype)initWithSuccessResult:(JWTCodingResultTypeSuccess *)success; 64 | - (instancetype)initWithErrorResult:(JWTCodingResultTypeError *)error; 65 | @property (strong, nonatomic, readonly) JWTCodingResultTypeSuccess *successResult; 66 | @property (strong, nonatomic, readonly) JWTCodingResultTypeError *errorResult; 67 | @end 68 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/Coding/JWTCoding.h: -------------------------------------------------------------------------------- 1 | // 2 | // JWT.h 3 | // JWT 4 | // 5 | // Created by Klaas Pieter Annema on 31-05-13. 6 | // Copyright (c) 2013 Karma. All rights reserved. 7 | // 8 | 9 | #import 10 | /** 11 | @discussion JWT is a general interface for decoding and encoding. 12 | Now it is to complex and fat to support. 13 | Possible solution: split interface into several pieces. 14 | 15 | JWT_1_0 -> JWT with plain old functions. 16 | JWT_2_0 -> JWT with builder usage. 17 | JWT_3_0 -> JWT with splitted apart algorithm data and payload data. 18 | */ 19 | @interface JWT : NSObject @end 20 | 21 | typedef NS_OPTIONS(NSInteger, JWTCodingDecodingOptions) { 22 | JWTCodingDecodingOptionsNone = 0, 23 | JWTCodingDecodingOptionsSkipVerification = 1 24 | }; 25 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/Coding/JWTCoding.m: -------------------------------------------------------------------------------- 1 | // 2 | // JWT.m 3 | // JWT 4 | // 5 | // Created by Klaas Pieter Annema on 31-05-13. 6 | // Copyright (c) 2013 Karma. All rights reserved. 7 | // 8 | 9 | #import "JWTCoding.h" 10 | 11 | @implementation JWT @end 12 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/FrameworkSupplement/JWT.h: -------------------------------------------------------------------------------- 1 | // 2 | // JWT.h 3 | // JWT 4 | // 5 | // Created by Lobanov Dmitry on 23.10.16. 6 | // Copyright © 2016 Karma. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for JWT. 12 | FOUNDATION_EXPORT double JWTVersionNumber; 13 | 14 | //! Project version string for JWT. 15 | FOUNDATION_EXPORT const unsigned char JWTVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | // Coding 20 | #import 21 | #import 22 | #import 23 | #import 24 | #import 25 | 26 | // Algorithms 27 | #import 28 | #import 29 | #import 30 | #import 31 | #import 32 | #import 33 | 34 | // Holders 35 | #import 36 | #import 37 | 38 | // Claims 39 | #import 40 | #import 41 | #import 42 | #import 43 | 44 | // Supplement 45 | #import 46 | #import 47 | #import 48 | 49 | // Crypto 50 | #import 51 | #import 52 | #import 53 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/FrameworkSupplement/Map.modulemap: -------------------------------------------------------------------------------- 1 | framework module JWT { 2 | umbrella header "JWT.h" 3 | export * 4 | module * { export * } 5 | } -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/Supplement/JWTBase64Coder.h: -------------------------------------------------------------------------------- 1 | // 2 | // JWTBase64Coder.h 3 | // Pods 4 | // 5 | // Created by Lobanov Dmitry on 05.10.16. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @protocol JWTStringCoder__Protocol 12 | - (NSString *)stringWithData:(NSData *)data; 13 | - (NSData *)dataWithString:(NSString *)string; 14 | @end 15 | 16 | @interface JWTBase64Coder : NSObject 17 | + (NSString *)base64UrlEncodedStringWithData:(NSData *)data; 18 | + (NSData *)dataWithBase64UrlEncodedString:(NSString *)urlEncodedString; 19 | @end 20 | 21 | @interface JWTBase64Coder (JWTStringCoder__Protocol) @end 22 | 23 | 24 | @interface JWTStringCoder__For__Encoding : NSObject 25 | @property (assign, nonatomic, readwrite) NSStringEncoding stringEncoding; 26 | + (instancetype)utf8Encoding; 27 | @end 28 | @interface JWTStringCoder__For__Encoding (JWTStringCoder__Protocol) @end 29 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/Supplement/JWTBase64Coder.m: -------------------------------------------------------------------------------- 1 | // 2 | // JWTBase64Coder.m 3 | // Pods 4 | // 5 | // Created by Lobanov Dmitry on 05.10.16. 6 | // 7 | // 8 | 9 | #import "JWTBase64Coder.h" 10 | 11 | @interface JWTBase64Coder (ConditionLinking) 12 | + (BOOL)isBase64AddtionsAvailable; 13 | @end 14 | 15 | @implementation JWTBase64Coder (ConditionLinking) 16 | + (BOOL)isBase64AddtionsAvailable { 17 | return [[NSData class] respondsToSelector:@selector(dataWithBase64UrlEncodedString:)]; 18 | } 19 | @end 20 | 21 | #if __has_include("MF_Base64Additions.h") 22 | #import 23 | #endif 24 | 25 | @implementation JWTBase64Coder 26 | 27 | + (NSString *)base64UrlEncodedStringWithData:(NSData *)data { 28 | if ([self isBase64AddtionsAvailable] && [data respondsToSelector:@selector(base64UrlEncodedString)]) { 29 | return [data performSelector:@selector(base64UrlEncodedString)]; 30 | } 31 | else { 32 | return [data base64EncodedStringWithOptions:0]; 33 | } 34 | } 35 | 36 | + (NSData *)dataWithBase64UrlEncodedString:(NSString *)urlEncodedString { 37 | if ([self isBase64AddtionsAvailable] && [[NSData class] respondsToSelector:@selector(dataWithBase64UrlEncodedString:)]) { 38 | return [[NSData class] performSelector:@selector(dataWithBase64UrlEncodedString:) withObject:urlEncodedString]; 39 | } 40 | else { 41 | return [[NSData alloc] initWithBase64EncodedString:urlEncodedString options:0]; 42 | } 43 | } 44 | 45 | @end 46 | 47 | @implementation JWTBase64Coder (JWTStringCoder__Protocol) 48 | - (NSString *)stringWithData:(NSData *)data { 49 | return [self.class base64UrlEncodedStringWithData:data]; 50 | } 51 | - (NSData *)dataWithString:(NSString *)string { 52 | return [self.class dataWithBase64UrlEncodedString:string]; 53 | } 54 | @end 55 | 56 | @implementation JWTStringCoder__For__Encoding 57 | + (instancetype)utf8Encoding { 58 | JWTStringCoder__For__Encoding *coding = [self new]; 59 | coding.stringEncoding = NSUTF8StringEncoding; 60 | return coding; 61 | } 62 | @end 63 | @implementation JWTStringCoder__For__Encoding (JWTStringCoder__Protocol) 64 | - (NSString *)stringWithData:(NSData *)data { 65 | return [[NSString alloc] initWithData:data encoding:self.stringEncoding]; 66 | } 67 | - (NSData *)dataWithString:(NSString *)string { 68 | return [string dataUsingEncoding:self.stringEncoding]; 69 | } 70 | @end 71 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/Supplement/JWTDeprecations.h: -------------------------------------------------------------------------------- 1 | // 2 | // JWTDeprecations.h 3 | // JWT 4 | // 5 | // Created by Lobanov Dmitry on 31.08.16. 6 | // Copyright © 2016 Karma. All rights reserved. 7 | // 8 | 9 | #ifndef JWTDeprecations_h 10 | #define JWTDeprecations_h 11 | 12 | #define STR(str) #str 13 | #define JWTVersion_2_1_0 2.1 14 | #define JWTVersion_2_2_0 2.2 15 | #define JWTVersion_3_0_0 3.0 16 | #define __first_deprecated_in_release_version(version) __deprecated_msg("first deprecated in release version: " STR(version)) 17 | #define __deprecated_and_will_be_removed_in_release_version(version) __deprecated_msg("deprecated. will be removed in release version: "STR(version)) 18 | #define __available_in_release_version(version) __deprecated_msg("will be introduced in release version: " STR(version)) 19 | 20 | #define __jwt_technical_debt(debt) __deprecated_msg("Don't forget to inspect it later." STR(debt)) 21 | 22 | #endif /* JWTDeprecations_h */ 23 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/Core/Supplement/JWTErrorDescription.h: -------------------------------------------------------------------------------- 1 | // 2 | // JWTErrorDescription.h 3 | // JWT 4 | // 5 | // Created by Lobanov Dmitry on 27.11.16. 6 | // Copyright © 2016 JWTIO. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | extern NSString *JWTErrorDomain; 12 | 13 | typedef NS_ENUM(NSInteger, JWTError) { 14 | JWTInvalidFormatError = -100, 15 | JWTUnsupportedAlgorithmError, 16 | JWTAlgorithmNameMismatchError, 17 | JWTInvalidSignatureError, 18 | JWTNoPayloadError, 19 | JWTNoHeaderError, 20 | JWTEncodingHeaderError, 21 | JWTEncodingPayloadError, 22 | JWTEncodingSigningError, 23 | JWTClaimsSetVerificationFailed, 24 | JWTInvalidSegmentSerializationError, 25 | JWTUnspecifiedAlgorithmError, 26 | JWTBlacklistedAlgorithmError, 27 | JWTDecodingHeaderError, 28 | JWTDecodingPayloadError, 29 | JWTDecodingHoldersChainEmptyError 30 | }; 31 | 32 | @interface JWTErrorDescription : NSObject 33 | + (NSError *)errorWithCode:(JWTError)code; 34 | @end 35 | -------------------------------------------------------------------------------- /ios/CodePush/JWT/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Karma Mobility, Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /ios/CodePush/RCTConvert+CodePushInstallMode.m: -------------------------------------------------------------------------------- 1 | #import "CodePush.h" 2 | 3 | #if __has_include() 4 | #import 5 | #else 6 | #import "RCTConvert.h" 7 | #endif 8 | 9 | // Extending the RCTConvert class allows the React Native 10 | // bridge to handle args of type "CodePushInstallMode" 11 | @implementation RCTConvert (CodePushInstallMode) 12 | 13 | RCT_ENUM_CONVERTER(CodePushInstallMode, (@{ @"codePushInstallModeImmediate": @(CodePushInstallModeImmediate), 14 | @"codePushInstallModeOnNextRestart": @(CodePushInstallModeOnNextRestart), 15 | @"codePushInstallModeOnNextResume": @(CodePushInstallModeOnNextResume), 16 | @"codePushInstallModeOnNextSuspend": @(CodePushInstallModeOnNextSuspend) }), 17 | CodePushInstallModeImmediate, // Default enum value 18 | integerValue) 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /ios/CodePush/RCTConvert+CodePushUpdateState.m: -------------------------------------------------------------------------------- 1 | #import "CodePush.h" 2 | 3 | #if __has_include() 4 | #import 5 | #else 6 | #import "RCTConvert.h" 7 | #endif 8 | 9 | // Extending the RCTConvert class allows the React Native 10 | // bridge to handle args of type "CodePushUpdateState" 11 | @implementation RCTConvert (CodePushUpdateState) 12 | 13 | RCT_ENUM_CONVERTER(CodePushUpdateState, (@{ @"codePushUpdateStateRunning": @(CodePushUpdateStateRunning), 14 | @"codePushUpdateStatePending": @(CodePushUpdateStatePending), 15 | @"codePushUpdateStateLatest": @(CodePushUpdateStateLatest) 16 | }), 17 | CodePushUpdateStateRunning, // Default enum value 18 | integerValue) 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /ios/CodePush/SSZipArchive/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/CodePush/SSZipArchive/README.md: -------------------------------------------------------------------------------- 1 | The source code in this folder is taken from [https://github.com/ZipArchive/ZipArchive/tree/2.5.5/SSZipArchive](https://github.com/ZipArchive/ZipArchive/tree/2.5.5/SSZipArchive) which is [MIT licensed](https://github.com/ZipArchive/ZipArchive/blob/2.5.5/LICENSE.txt). -------------------------------------------------------------------------------- /ios/CodePush/SSZipArchive/Supporting Files/PrivacyInfo.xcprivacy: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSPrivacyTracking 6 | 7 | NSPrivacyCollectedDataTypes 8 | 9 | NSPrivacyTrackingDomains 10 | 11 | NSPrivacyAccessedAPITypes 12 | 13 | 14 | NSPrivacyAccessedAPIType 15 | NSPrivacyAccessedAPICategoryFileTimestamp 16 | NSPrivacyAccessedAPITypeReasons 17 | 18 | C617.1 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /ios/CodePush/SSZipArchive/include/ZipArchive.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZipArchive.h 3 | // ZipArchive 4 | // 5 | // Created by Serhii Mumriak on 12/1/15. 6 | // 7 | 8 | #import 9 | 10 | //! Project version number for ZipArchive. 11 | FOUNDATION_EXPORT double ZipArchiveVersionNumber; 12 | 13 | //! Project version string for ZipArchive. 14 | FOUNDATION_EXPORT const unsigned char ZipArchiveVersionString[]; 15 | 16 | // In this header, you should import all the public headers of your framework using statements like #import 17 | 18 | // This is to account for the many different ways this library gets imported. 19 | #if __has_include() 20 | #import 21 | #elif __has_include("../SSZipArchive.h") 22 | #import "../SSZipArchive.h" 23 | #else 24 | #import "SSZipArchive.h" 25 | #endif 26 | -------------------------------------------------------------------------------- /ios/CodePush/SSZipArchive/minizip/LICENSE: -------------------------------------------------------------------------------- 1 | Condition of use and distribution are the same as zlib: 2 | 3 | This software is provided 'as-is', without any express or implied 4 | warranty. In no event will the authors be held liable for any damages 5 | arising from the use of this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, 8 | including commercial applications, and to alter it and redistribute it 9 | freely, subject to the following restrictions: 10 | 11 | 1. The origin of this software must not be misrepresented; you must not 12 | claim that you wrote the original software. If you use this software 13 | in a product, an acknowledgement in the product documentation would be 14 | appreciated but is not required. 15 | 2. Altered source versions must be plainly marked as such, and must not be 16 | misrepresented as being the original software. 17 | 3. This notice may not be removed or altered from any source distribution. 18 | -------------------------------------------------------------------------------- /ios/CodePush/SSZipArchive/minizip/mz_crypt.h: -------------------------------------------------------------------------------- 1 | /* mz_crypt.h -- Crypto/hash functions 2 | part of the minizip-ng project 3 | 4 | Copyright (C) Nathan Moinvaziri 5 | https://github.com/zlib-ng/minizip-ng 6 | 7 | This program is distributed under the terms of the same license as zlib. 8 | See the accompanying LICENSE file for the full text of the license. 9 | */ 10 | 11 | #ifndef MZ_CRYPT_H 12 | #define MZ_CRYPT_H 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | /***************************************************************************/ 19 | 20 | uint32_t mz_crypt_crc32_update(uint32_t value, const uint8_t *buf, int32_t size); 21 | 22 | int32_t mz_crypt_pbkdf2(uint8_t *password, int32_t password_length, uint8_t *salt, 23 | int32_t salt_length, uint16_t iteration_count, uint8_t *key, uint16_t key_length); 24 | 25 | /***************************************************************************/ 26 | 27 | int32_t mz_crypt_rand(uint8_t *buf, int32_t size); 28 | 29 | void mz_crypt_sha_reset(void *handle); 30 | int32_t mz_crypt_sha_begin(void *handle); 31 | int32_t mz_crypt_sha_update(void *handle, const void *buf, int32_t size); 32 | int32_t mz_crypt_sha_end(void *handle, uint8_t *digest, int32_t digest_size); 33 | void mz_crypt_sha_set_algorithm(void *handle, uint16_t algorithm); 34 | void* mz_crypt_sha_create(void **handle); 35 | void mz_crypt_sha_delete(void **handle); 36 | 37 | void mz_crypt_aes_reset(void *handle); 38 | int32_t mz_crypt_aes_encrypt(void *handle, uint8_t *buf, int32_t size); 39 | int32_t mz_crypt_aes_decrypt(void *handle, uint8_t *buf, int32_t size); 40 | int32_t mz_crypt_aes_set_encrypt_key(void *handle, const void *key, int32_t key_length); 41 | int32_t mz_crypt_aes_set_decrypt_key(void *handle, const void *key, int32_t key_length); 42 | void mz_crypt_aes_set_mode(void *handle, int32_t mode); 43 | void* mz_crypt_aes_create(void **handle); 44 | void mz_crypt_aes_delete(void **handle); 45 | 46 | void mz_crypt_hmac_reset(void *handle); 47 | int32_t mz_crypt_hmac_init(void *handle, const void *key, int32_t key_length); 48 | int32_t mz_crypt_hmac_update(void *handle, const void *buf, int32_t size); 49 | int32_t mz_crypt_hmac_end(void *handle, uint8_t *digest, int32_t digest_size); 50 | int32_t mz_crypt_hmac_copy(void *src_handle, void *target_handle); 51 | void mz_crypt_hmac_set_algorithm(void *handle, uint16_t algorithm); 52 | void* mz_crypt_hmac_create(void **handle); 53 | void mz_crypt_hmac_delete(void **handle); 54 | 55 | int32_t mz_crypt_sign(uint8_t *message, int32_t message_size, uint8_t *cert_data, int32_t cert_data_size, 56 | const char *cert_pwd, uint8_t **signature, int32_t *signature_size); 57 | int32_t mz_crypt_sign_verify(uint8_t *message, int32_t message_size, uint8_t *signature, int32_t signature_size); 58 | 59 | /***************************************************************************/ 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /ios/CodePush/SSZipArchive/minizip/mz_strm_buf.h: -------------------------------------------------------------------------------- 1 | /* mz_strm_buf.h -- Stream for buffering reads/writes 2 | part of the minizip-ng project 3 | 4 | This version of ioapi is designed to buffer IO. 5 | 6 | Copyright (C) Nathan Moinvaziri 7 | https://github.com/zlib-ng/minizip-ng 8 | 9 | This program is distributed under the terms of the same license as zlib. 10 | See the accompanying LICENSE file for the full text of the license. 11 | */ 12 | 13 | #ifndef MZ_STREAM_BUFFERED_H 14 | #define MZ_STREAM_BUFFERED_H 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | /***************************************************************************/ 21 | 22 | int32_t mz_stream_buffered_open(void *stream, const char *path, int32_t mode); 23 | int32_t mz_stream_buffered_is_open(void *stream); 24 | int32_t mz_stream_buffered_read(void *stream, void *buf, int32_t size); 25 | int32_t mz_stream_buffered_write(void *stream, const void *buf, int32_t size); 26 | int64_t mz_stream_buffered_tell(void *stream); 27 | int32_t mz_stream_buffered_seek(void *stream, int64_t offset, int32_t origin); 28 | int32_t mz_stream_buffered_close(void *stream); 29 | int32_t mz_stream_buffered_error(void *stream); 30 | 31 | void* mz_stream_buffered_create(void **stream); 32 | void mz_stream_buffered_delete(void **stream); 33 | 34 | void* mz_stream_buffered_get_interface(void); 35 | 36 | /***************************************************************************/ 37 | 38 | #ifdef __cplusplus 39 | } 40 | #endif 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /ios/CodePush/SSZipArchive/minizip/mz_strm_mem.h: -------------------------------------------------------------------------------- 1 | /* mz_strm_mem.h -- Stream for memory access 2 | part of the minizip-ng project 3 | 4 | Copyright (C) Nathan Moinvaziri 5 | https://github.com/zlib-ng/minizip-ng 6 | 7 | This program is distributed under the terms of the same license as zlib. 8 | See the accompanying LICENSE file for the full text of the license. 9 | */ 10 | 11 | #ifndef MZ_STREAM_MEM_H 12 | #define MZ_STREAM_MEM_H 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | /***************************************************************************/ 19 | 20 | int32_t mz_stream_mem_open(void *stream, const char *filename, int32_t mode); 21 | int32_t mz_stream_mem_is_open(void *stream); 22 | int32_t mz_stream_mem_read(void *stream, void *buf, int32_t size); 23 | int32_t mz_stream_mem_write(void *stream, const void *buf, int32_t size); 24 | int64_t mz_stream_mem_tell(void *stream); 25 | int32_t mz_stream_mem_seek(void *stream, int64_t offset, int32_t origin); 26 | int32_t mz_stream_mem_close(void *stream); 27 | int32_t mz_stream_mem_error(void *stream); 28 | 29 | void mz_stream_mem_set_buffer(void *stream, void *buf, int32_t size); 30 | int32_t mz_stream_mem_get_buffer(void *stream, const void **buf); 31 | int32_t mz_stream_mem_get_buffer_at(void *stream, int64_t position, const void **buf); 32 | int32_t mz_stream_mem_get_buffer_at_current(void *stream, const void **buf); 33 | void mz_stream_mem_get_buffer_length(void *stream, int32_t *length); 34 | void mz_stream_mem_set_buffer_limit(void *stream, int32_t limit); 35 | void mz_stream_mem_set_grow_size(void *stream, int32_t grow_size); 36 | 37 | void* mz_stream_mem_create(void **stream); 38 | void mz_stream_mem_delete(void **stream); 39 | 40 | void* mz_stream_mem_get_interface(void); 41 | 42 | /***************************************************************************/ 43 | 44 | #ifdef __cplusplus 45 | } 46 | #endif 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /ios/CodePush/SSZipArchive/minizip/mz_strm_os.h: -------------------------------------------------------------------------------- 1 | /* mz_sstrm_os.h -- Stream for filesystem access 2 | part of the minizip-ng project 3 | 4 | Copyright (C) Nathan Moinvaziri 5 | https://github.com/zlib-ng/minizip-ng 6 | 7 | This program is distributed under the terms of the same license as zlib. 8 | See the accompanying LICENSE file for the full text of the license. 9 | */ 10 | 11 | #ifndef MZ_STREAM_OS_H 12 | #define MZ_STREAM_OS_H 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | /***************************************************************************/ 19 | 20 | int32_t mz_stream_os_open(void *stream, const char *path, int32_t mode); 21 | int32_t mz_stream_os_is_open(void *stream); 22 | int32_t mz_stream_os_read(void *stream, void *buf, int32_t size); 23 | int32_t mz_stream_os_write(void *stream, const void *buf, int32_t size); 24 | int64_t mz_stream_os_tell(void *stream); 25 | int32_t mz_stream_os_seek(void *stream, int64_t offset, int32_t origin); 26 | int32_t mz_stream_os_close(void *stream); 27 | int32_t mz_stream_os_error(void *stream); 28 | 29 | void* mz_stream_os_create(void **stream); 30 | void mz_stream_os_delete(void **stream); 31 | 32 | void* mz_stream_os_get_interface(void); 33 | 34 | /***************************************************************************/ 35 | 36 | #ifdef __cplusplus 37 | } 38 | #endif 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /ios/CodePush/SSZipArchive/minizip/mz_strm_pkcrypt.h: -------------------------------------------------------------------------------- 1 | /* mz_strm_pkcrypt.h -- Code for traditional PKWARE encryption 2 | part of the minizip-ng project 3 | 4 | Copyright (C) Nathan Moinvaziri 5 | https://github.com/zlib-ng/minizip-ng 6 | 7 | This program is distributed under the terms of the same license as zlib. 8 | See the accompanying LICENSE file for the full text of the license. 9 | */ 10 | 11 | #ifndef MZ_STREAM_PKCRYPT_H 12 | #define MZ_STREAM_PKCRYPT_H 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | /***************************************************************************/ 19 | 20 | int32_t mz_stream_pkcrypt_open(void *stream, const char *filename, int32_t mode); 21 | int32_t mz_stream_pkcrypt_is_open(void *stream); 22 | int32_t mz_stream_pkcrypt_read(void *stream, void *buf, int32_t size); 23 | int32_t mz_stream_pkcrypt_write(void *stream, const void *buf, int32_t size); 24 | int64_t mz_stream_pkcrypt_tell(void *stream); 25 | int32_t mz_stream_pkcrypt_seek(void *stream, int64_t offset, int32_t origin); 26 | int32_t mz_stream_pkcrypt_close(void *stream); 27 | int32_t mz_stream_pkcrypt_error(void *stream); 28 | 29 | void mz_stream_pkcrypt_set_password(void *stream, const char *password); 30 | void mz_stream_pkcrypt_set_verify(void *stream, uint8_t verify1, uint8_t verify2); 31 | void mz_stream_pkcrypt_get_verify(void *stream, uint8_t *verify1, uint8_t *verify2); 32 | int32_t mz_stream_pkcrypt_get_prop_int64(void *stream, int32_t prop, int64_t *value); 33 | int32_t mz_stream_pkcrypt_set_prop_int64(void *stream, int32_t prop, int64_t value); 34 | 35 | void* mz_stream_pkcrypt_create(void **stream); 36 | void mz_stream_pkcrypt_delete(void **stream); 37 | 38 | void* mz_stream_pkcrypt_get_interface(void); 39 | 40 | /***************************************************************************/ 41 | 42 | #ifdef __cplusplus 43 | } 44 | #endif 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /ios/CodePush/SSZipArchive/minizip/mz_strm_split.h: -------------------------------------------------------------------------------- 1 | /* mz_strm_split.h -- Stream for split files 2 | part of the minizip-ng project 3 | 4 | Copyright (C) Nathan Moinvaziri 5 | https://github.com/zlib-ng/minizip-ng 6 | 7 | This program is distributed under the terms of the same license as zlib. 8 | See the accompanying LICENSE file for the full text of the license. 9 | */ 10 | 11 | #ifndef MZ_STREAM_SPLIT_H 12 | #define MZ_STREAM_SPLIT_H 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | /***************************************************************************/ 19 | 20 | int32_t mz_stream_split_open(void *stream, const char *filename, int32_t mode); 21 | int32_t mz_stream_split_is_open(void *stream); 22 | int32_t mz_stream_split_read(void *stream, void *buf, int32_t size); 23 | int32_t mz_stream_split_write(void *stream, const void *buf, int32_t size); 24 | int64_t mz_stream_split_tell(void *stream); 25 | int32_t mz_stream_split_seek(void *stream, int64_t offset, int32_t origin); 26 | int32_t mz_stream_split_close(void *stream); 27 | int32_t mz_stream_split_error(void *stream); 28 | 29 | int32_t mz_stream_split_get_prop_int64(void *stream, int32_t prop, int64_t *value); 30 | int32_t mz_stream_split_set_prop_int64(void *stream, int32_t prop, int64_t value); 31 | 32 | void* mz_stream_split_create(void **stream); 33 | void mz_stream_split_delete(void **stream); 34 | 35 | void* mz_stream_split_get_interface(void); 36 | 37 | /***************************************************************************/ 38 | 39 | #ifdef __cplusplus 40 | } 41 | #endif 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /ios/CodePush/SSZipArchive/minizip/mz_strm_wzaes.h: -------------------------------------------------------------------------------- 1 | /* mz_strm_wzaes.h -- Stream for WinZIP AES encryption 2 | part of the minizip-ng project 3 | 4 | Copyright (C) Nathan Moinvaziri 5 | https://github.com/zlib-ng/minizip-ng 6 | 7 | This program is distributed under the terms of the same license as zlib. 8 | See the accompanying LICENSE file for the full text of the license. 9 | */ 10 | 11 | #ifndef MZ_STREAM_WZAES_SHA1_H 12 | #define MZ_STREAM_WZAES_SHA1_H 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | /***************************************************************************/ 19 | 20 | int32_t mz_stream_wzaes_open(void *stream, const char *filename, int32_t mode); 21 | int32_t mz_stream_wzaes_is_open(void *stream); 22 | int32_t mz_stream_wzaes_read(void *stream, void *buf, int32_t size); 23 | int32_t mz_stream_wzaes_write(void *stream, const void *buf, int32_t size); 24 | int64_t mz_stream_wzaes_tell(void *stream); 25 | int32_t mz_stream_wzaes_seek(void *stream, int64_t offset, int32_t origin); 26 | int32_t mz_stream_wzaes_close(void *stream); 27 | int32_t mz_stream_wzaes_error(void *stream); 28 | 29 | void mz_stream_wzaes_set_password(void *stream, const char *password); 30 | void mz_stream_wzaes_set_encryption_mode(void *stream, int16_t encryption_mode); 31 | 32 | int32_t mz_stream_wzaes_get_prop_int64(void *stream, int32_t prop, int64_t *value); 33 | int32_t mz_stream_wzaes_set_prop_int64(void *stream, int32_t prop, int64_t value); 34 | 35 | void* mz_stream_wzaes_create(void **stream); 36 | void mz_stream_wzaes_delete(void **stream); 37 | 38 | void* mz_stream_wzaes_get_interface(void); 39 | 40 | /***************************************************************************/ 41 | 42 | #ifdef __cplusplus 43 | } 44 | #endif 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /ios/CodePush/SSZipArchive/minizip/mz_strm_zlib.h: -------------------------------------------------------------------------------- 1 | /* mz_strm_zlib.h -- Stream for zlib inflate/deflate 2 | part of the minizip-ng project 3 | 4 | Copyright (C) Nathan Moinvaziri 5 | https://github.com/zlib-ng/minizip-ng 6 | 7 | This program is distributed under the terms of the same license as zlib. 8 | See the accompanying LICENSE file for the full text of the license. 9 | */ 10 | 11 | #ifndef MZ_STREAM_ZLIB_H 12 | #define MZ_STREAM_ZLIB_H 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | /***************************************************************************/ 19 | 20 | int32_t mz_stream_zlib_open(void *stream, const char *filename, int32_t mode); 21 | int32_t mz_stream_zlib_is_open(void *stream); 22 | int32_t mz_stream_zlib_read(void *stream, void *buf, int32_t size); 23 | int32_t mz_stream_zlib_write(void *stream, const void *buf, int32_t size); 24 | int64_t mz_stream_zlib_tell(void *stream); 25 | int32_t mz_stream_zlib_seek(void *stream, int64_t offset, int32_t origin); 26 | int32_t mz_stream_zlib_close(void *stream); 27 | int32_t mz_stream_zlib_error(void *stream); 28 | 29 | int32_t mz_stream_zlib_get_prop_int64(void *stream, int32_t prop, int64_t *value); 30 | int32_t mz_stream_zlib_set_prop_int64(void *stream, int32_t prop, int64_t value); 31 | 32 | void* mz_stream_zlib_create(void **stream); 33 | void mz_stream_zlib_delete(void **stream); 34 | 35 | void* mz_stream_zlib_get_interface(void); 36 | 37 | /***************************************************************************/ 38 | 39 | #ifdef __cplusplus 40 | } 41 | #endif 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /ios/PrivacyInfo.xcprivacy: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSPrivacyTracking 6 | 7 | NSPrivacyCollectedDataTypes 8 | 9 | NSPrivacyTrackingDomains 10 | 11 | NSPrivacyAccessedAPITypes 12 | 13 | 14 | NSPrivacyAccessedAPIType 15 | NSPrivacyAccessedAPICategoryFileTimestamp 16 | NSPrivacyAccessedAPITypeReasons 17 | 18 | 0A2A.1 19 | 20 | 21 | 22 | NSPrivacyAccessedAPIType 23 | NSPrivacyAccessedAPICategoryUserDefaults 24 | NSPrivacyAccessedAPITypeReasons 25 | 26 | CA92.1 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /logging.js: -------------------------------------------------------------------------------- 1 | /* Logs messages to console with the [CodePush] prefix */ 2 | function log(message) { 3 | console.log(`[CodePush] ${message}`); 4 | } 5 | 6 | module.exports = log; 7 | -------------------------------------------------------------------------------- /package-mixins.js: -------------------------------------------------------------------------------- 1 | import { NativeEventEmitter } from "react-native"; 2 | import log from "./logging"; 3 | 4 | // This function is used to augment remote and local 5 | // package objects with additional functionality/properties 6 | // beyond what is included in the metadata sent by the server. 7 | module.exports = (NativeCodePush) => { 8 | const remote = (reportStatusDownload) => { 9 | return { 10 | async download(downloadProgressCallback) { 11 | if (!this.downloadUrl) { 12 | throw new Error("Cannot download an update without a download url"); 13 | } 14 | 15 | let downloadProgressSubscription; 16 | if (downloadProgressCallback) { 17 | const codePushEventEmitter = new NativeEventEmitter(NativeCodePush); 18 | // Use event subscription to obtain download progress. 19 | downloadProgressSubscription = codePushEventEmitter.addListener( 20 | "CodePushDownloadProgress", 21 | downloadProgressCallback 22 | ); 23 | } 24 | 25 | // Use the downloaded package info. Native code will save the package info 26 | // so that the client knows what the current package version is. 27 | try { 28 | const updatePackageCopy = Object.assign({}, this); 29 | Object.keys(updatePackageCopy).forEach((key) => (typeof updatePackageCopy[key] === 'function') && delete updatePackageCopy[key]); 30 | 31 | const downloadedPackage = await NativeCodePush.downloadUpdate(updatePackageCopy, !!downloadProgressCallback); 32 | 33 | if (reportStatusDownload) { 34 | reportStatusDownload(this) 35 | .catch((err) => { 36 | log(`Report download status failed: ${err}`); 37 | }); 38 | } 39 | 40 | return { ...downloadedPackage, ...local }; 41 | } finally { 42 | downloadProgressSubscription && downloadProgressSubscription.remove(); 43 | } 44 | }, 45 | 46 | isPending: false // A remote package could never be in a pending state 47 | }; 48 | }; 49 | 50 | const local = { 51 | async install(installMode = NativeCodePush.codePushInstallModeOnNextRestart, minimumBackgroundDuration = 0, updateInstalledCallback) { 52 | const localPackage = this; 53 | const localPackageCopy = Object.assign({}, localPackage); // In dev mode, React Native deep freezes any object queued over the bridge 54 | await NativeCodePush.installUpdate(localPackageCopy, installMode, minimumBackgroundDuration); 55 | updateInstalledCallback && updateInstalledCallback(); 56 | if (installMode == NativeCodePush.codePushInstallModeImmediate) { 57 | NativeCodePush.restartApp(false); 58 | } else { 59 | NativeCodePush.clearPendingRestart(); 60 | localPackage.isPending = true; // Mark the package as pending since it hasn't been applied yet 61 | } 62 | }, 63 | 64 | isPending: false // A local package wouldn't be pending until it was installed 65 | }; 66 | 67 | return { local, remote }; 68 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@revopush/react-native-code-push", 3 | "version": "1.1.0", 4 | "description": "React Native plugin for the CodePush service", 5 | "main": "CodePush.js", 6 | "typings": "typings/react-native-code-push.d.ts", 7 | "homepage": "https://revopush.org/", 8 | "keywords": [ 9 | "react-native", 10 | "code", 11 | "revopush", 12 | "ota", 13 | "push" 14 | ], 15 | "author": "Revopush", 16 | "license": "MIT", 17 | "scripts": { 18 | "clean": "shx rm -rf bin", 19 | "setup": "npm install --quiet --no-progress", 20 | "prebuild:tests": "npm run clean && npm run tslint", 21 | "build:tests": "tsc", 22 | "test": "npm run build:tests && npm run test:setup && npm run test:fast", 23 | "test:android": "npm run build:tests && npm run test:setup:android && npm run test:fast:android", 24 | "test:ios": "npm run build:tests && npm run test:setup:ios && npm run test:fast:ios", 25 | "test:setup": "mocha --recursive bin/test --android --ios --setup", 26 | "test:setup:android": "mocha --recursive bin/test --android --setup", 27 | "test:setup:ios": "mocha --recursive bin/test --ios --setup", 28 | "test:fast": "mocha --recursive bin/test --android --ios", 29 | "test:fast:android": "mocha --recursive bin/test --android", 30 | "test:fast:ios": "mocha --recursive bin/test --ios", 31 | "test:debugger:android": "mocha --recursive --inspect-brk=0.0.0.0 bin/test --android", 32 | "test:debugger:ios": "mocha --recursive --inspect-brk=0.0.0.0 bin/test --ios", 33 | "tslint": "tslint -c tslint.json test/**/*.ts" 34 | }, 35 | "repository": { 36 | "type": "git", 37 | "url": "https://github.com/revopush/react-native-code-push" 38 | }, 39 | "dependencies": { 40 | "code-push": "4.2.3", 41 | "glob": "^7.1.7", 42 | "hoist-non-react-statics": "^3.3.2", 43 | "inquirer": "^8.1.5", 44 | "plist": "^3.0.4", 45 | "semver": "^7.3.5", 46 | "xcode": "3.0.1" 47 | }, 48 | "devDependencies": { 49 | "@types/assert": "^1.5.2", 50 | "@types/mkdirp": "^1.0.1", 51 | "@types/mocha": "^9.0.0", 52 | "@types/node": "^14.0.27", 53 | "@types/q": "^1.5.4", 54 | "archiver": "latest", 55 | "body-parser": "latest", 56 | "code-push-plugin-testing-framework": "file:./code-push-plugin-testing-framework", 57 | "del": "v6.0.0", 58 | "express": "latest", 59 | "mkdirp": "latest", 60 | "mocha": "^9.2.0", 61 | "q": "^1.5.1", 62 | "run-sequence": "latest", 63 | "shx": "^0.3.4", 64 | "slash": "^3.0.0", 65 | "tslint": "^6.1.3", 66 | "typescript": "^4.4.3" 67 | }, 68 | "rnpm": { 69 | "android": { 70 | "packageInstance": "new CodePush(getResources().getString(R.string.CodePushDeploymentKey), getApplicationContext(), BuildConfig.DEBUG)" 71 | }, 72 | "ios": { 73 | "sharedLibraries": [ 74 | "libz" 75 | ] 76 | }, 77 | "commands": { 78 | "postlink": "node node_modules/@revopush/react-native-code-push/scripts/postlink/run", 79 | "postunlink": "node node_modules/@revopush/react-native-code-push/scripts/postunlink/run" 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /react-native.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | dependency: { 3 | platforms: { 4 | android: { 5 | packageInstance: 6 | "CodePush.getInstance(getResources().getString(R.string.CodePushDeploymentKey), getApplicationContext(), BuildConfig.DEBUG)", 7 | sourceDir: './android/app', 8 | } 9 | } 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /request-fetch-adapter.js: -------------------------------------------------------------------------------- 1 | const packageJson = require("./package.json"); 2 | 3 | module.exports = { 4 | async request(verb, url, requestBody, callback) { 5 | if (typeof requestBody === "function") { 6 | callback = requestBody; 7 | requestBody = null; 8 | } 9 | 10 | const headers = { 11 | "Accept": "application/json", 12 | "Content-Type": "application/json", 13 | "X-CodePush-Plugin-Name": packageJson.name, 14 | "X-CodePush-Plugin-Version": packageJson.version, 15 | "X-CodePush-SDK-Version": packageJson.dependencies["code-push"] 16 | }; 17 | 18 | if (requestBody && typeof requestBody === "object") { 19 | requestBody = JSON.stringify(requestBody); 20 | } 21 | 22 | try { 23 | const response = await fetch(url, { 24 | method: getHttpMethodName(verb), 25 | headers: headers, 26 | body: requestBody 27 | }); 28 | 29 | const statusCode = response.status; 30 | const body = await response.text(); 31 | callback(null, { statusCode, body }); 32 | } catch (err) { 33 | callback(err); 34 | } 35 | } 36 | }; 37 | 38 | function getHttpMethodName(verb) { 39 | // Note: This should stay in sync with the enum definition in 40 | // https://github.com/microsoft/code-push/blob/master/sdk/script/acquisition-sdk.ts#L6 41 | return [ 42 | "GET", 43 | "HEAD", 44 | "POST", 45 | "PUT", 46 | "DELETE", 47 | "TRACE", 48 | "OPTIONS", 49 | "CONNECT", 50 | "PATCH" 51 | ][verb]; 52 | } -------------------------------------------------------------------------------- /scripts/getFilesInFolder.js: -------------------------------------------------------------------------------- 1 | var fs = require("fs"); 2 | var path = require("path"); 3 | 4 | // Utility function that collects the stats of every file in a directory 5 | // as well as in its subdirectories. 6 | function getFilesInFolder(folderName, fileList) { 7 | var folderFiles = fs.readdirSync(folderName); 8 | folderFiles.forEach(function(file) { 9 | var fileStats = fs.statSync(path.join(folderName, file)); 10 | if (fileStats.isDirectory()) { 11 | getFilesInFolder(path.join(folderName, file), fileList); 12 | } else { 13 | fileStats.path = path.join(folderName, file); 14 | fileList.push(fileStats); 15 | } 16 | }); 17 | } 18 | 19 | module.exports = getFilesInFolder; -------------------------------------------------------------------------------- /scripts/postlink/run.js: -------------------------------------------------------------------------------- 1 | var postlinks = [ 2 | require("./android/postlink"), 3 | require("./ios/postlink") 4 | ]; 5 | 6 | //run them sequentially 7 | postlinks 8 | .reduce((p, fn) => p.then(fn), Promise.resolve()) 9 | .catch((err) => { 10 | console.error(err.message); 11 | }); -------------------------------------------------------------------------------- /scripts/postunlink/run.js: -------------------------------------------------------------------------------- 1 | var postunlinks = [ 2 | require("./ios/postunlink"), 3 | require("./android/postunlink") 4 | ]; 5 | 6 | //run them sequentially 7 | postunlinks 8 | .reduce((p, fn) => p.then(fn), Promise.resolve()) 9 | .catch((err) => { 10 | console.error(err.message); 11 | }); 12 | -------------------------------------------------------------------------------- /scripts/recordFilesBeforeBundleCommand.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This script creates a snapshot of the contents in the resource directory 3 | * by creating a map with the modified time of all the files in the directory 4 | * and saving it to a temp file. This snapshot is later referenced in 5 | * "generatePackageHash.js" to figure out which files have changed or were 6 | * newly generated by the "react-native bundle" command. 7 | */ 8 | 9 | var fs = require("fs"); 10 | var path = require("path"); 11 | 12 | var getFilesInFolder = require("./getFilesInFolder"); 13 | 14 | 15 | var resourcesDir = process.argv[2]; 16 | var tempFileName = process.argv[3]; 17 | 18 | var tempFileLocalPath = path.join(require("os").tmpdir(), tempFileName); 19 | var resourceFiles = []; 20 | 21 | try { 22 | getFilesInFolder(resourcesDir, resourceFiles); 23 | } catch(error) { 24 | var targetPathNotFoundExceptionMessage = "\nResources directory path does not exist.\n"; 25 | targetPathNotFoundExceptionMessage += "Unable to find '" + resourcesDir; 26 | targetPathNotFoundExceptionMessage += "' directory. Please check version of Android Plugin for Gradle."; 27 | error.message += targetPathNotFoundExceptionMessage; 28 | throw error; 29 | } 30 | 31 | var fileToModifiedTimeMap = {}; 32 | 33 | resourceFiles.forEach(function(resourceFile) { 34 | fileToModifiedTimeMap[resourceFile.path.substring(resourcesDir.length)] = resourceFile.mtime.getTime(); 35 | }); 36 | 37 | fs.writeFile(tempFileLocalPath, JSON.stringify(fileToModifiedTimeMap), function(err) { 38 | if (err) { 39 | throw err; 40 | } 41 | }); -------------------------------------------------------------------------------- /scripts/tools/linkToolsAndroid.js: -------------------------------------------------------------------------------- 1 | var fs = require("fs"); 2 | var glob = require("glob"); 3 | var path = require("path"); 4 | 5 | var ignoreFolders = { ignore: ["node_modules/**", "**/build/**"] }; 6 | var manifestPath = glob.sync("**/AndroidManifest.xml", ignoreFolders)[0]; 7 | 8 | exports.getJSBundleFileOverride = ` 9 | @Override 10 | protected String getJSBundleFile(){ 11 | return CodePush.getJSBundleFile(); 12 | } 13 | `; 14 | exports.reactNativeHostInstantiation = "new ReactNativeHost(this) {"; 15 | exports.mainActivityClassDeclaration = "public class MainActivity extends ReactActivity {"; 16 | exports.codePushGradleLink = `\napply from: "../../node_modules/@revopush/react-native-code-push/android/codepush.gradle"`; 17 | exports.deploymentKeyName = "CodePushDeploymentKey"; 18 | 19 | exports.getMainApplicationLocation = function () { 20 | return findMainApplication() || glob.sync("**/MainApplication.java", ignoreFolders)[0]; 21 | } 22 | 23 | exports.getMainActivityPath = function () { 24 | return glob.sync("**/MainActivity.java", ignoreFolders)[0] 25 | } 26 | 27 | exports.getStringsResourcesPath = function () { 28 | return glob.sync("**/strings.xml", ignoreFolders)[0]; 29 | } 30 | 31 | exports.getBuildGradlePath = function () { 32 | return path.join("android", "app", "build.gradle"); 33 | } 34 | 35 | exports.isJsBundleOverridden = function (codeContents) { 36 | return /@Override\s*\n\s*protected String getJSBundleFile\(\)\s*\{[\s\S]*?\}/.test(codeContents); 37 | } 38 | 39 | function findMainApplication() { 40 | if (!manifestPath) { 41 | return null; 42 | } 43 | 44 | var manifest = fs.readFileSync(manifestPath, "utf8"); 45 | 46 | // Android manifest must include single 'application' element 47 | var matchResult = manifest.match(/application\s+android:name\s*=\s*"(.*?)"/); 48 | if (matchResult) { 49 | var appName = matchResult[1]; 50 | } else { 51 | return null; 52 | } 53 | 54 | var nameParts = appName.split('.'); 55 | var searchPath = glob.sync("**/" + nameParts[nameParts.length - 1] + ".java", ignoreFolders)[0]; 56 | return searchPath; 57 | } 58 | -------------------------------------------------------------------------------- /test/template/android/app/src/main/java/com/testcodepush/MainApplication.kt: -------------------------------------------------------------------------------- 1 | package com.testcodepush 2 | 3 | import android.app.Application 4 | import com.facebook.react.PackageList 5 | import com.facebook.react.ReactApplication 6 | import com.facebook.react.ReactHost 7 | import com.facebook.react.ReactNativeHost 8 | import com.facebook.react.ReactPackage 9 | import com.facebook.react.common.annotations.UnstableReactNativeAPI 10 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load 11 | import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost 12 | import com.facebook.react.defaults.DefaultReactNativeHost 13 | import com.facebook.react.soloader.OpenSourceMergedSoMapping 14 | import com.facebook.soloader.SoLoader 15 | import com.microsoft.codepush.react.CodePush 16 | 17 | @OptIn(UnstableReactNativeAPI::class) 18 | class MainApplication : Application(), ReactApplication { 19 | 20 | override val reactNativeHost: ReactNativeHost = 21 | object : DefaultReactNativeHost(this) { 22 | override fun getPackages(): List { 23 | val packages = PackageList(this).packages 24 | // Packages that cannot be autolinked yet can be added manually here, for example: 25 | // packages.add(new MyReactNativePackage()); 26 | return packages 27 | } 28 | 29 | override fun getJSMainModuleName(): String = "index" 30 | override fun getJSBundleFile(): String = CodePush.getJSBundleFile() 31 | 32 | override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG 33 | 34 | override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED 35 | override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED 36 | } 37 | 38 | override val reactHost: ReactHost get() = getDefaultReactHost(this, reactNativeHost) 39 | 40 | override fun onCreate() { 41 | super.onCreate() 42 | SoLoader.init(this, OpenSourceMergedSoMapping) 43 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { 44 | // If you opted-in for the New Architecture, we load the native entry point for this app. 45 | load() 46 | } 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /test/template/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | TestCodePush 3 | CODE_PUSH_ANDROID_DEPLOYMENT_KEY 4 | CODE_PUSH_SERVER_URL 5 | 6 | -------------------------------------------------------------------------------- /test/template/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Resolve react_native_pods.rb with node to allow for hoisting 2 | require Pod::Executable.execute_command('node', ['-p', 3 | 'require.resolve( 4 | "react-native/scripts/react_native_pods.rb", 5 | {paths: [process.argv[1]]}, 6 | )', __dir__]).strip 7 | 8 | platform :ios, '15.5' 9 | prepare_react_native_project! 10 | 11 | linkage = ENV['USE_FRAMEWORKS'] 12 | if linkage != nil 13 | Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green 14 | use_frameworks! :linkage => linkage.to_sym 15 | end 16 | 17 | target 'TestCodePush' do 18 | config = use_native_modules! 19 | 20 | use_react_native!( 21 | :path => config[:reactNativePath], 22 | # An absolute path to your application root. 23 | :app_path => "#{Pod::Config.instance.installation_root}/.." 24 | ) 25 | 26 | post_install do |installer| 27 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 28 | react_native_post_install( 29 | installer, 30 | config[:reactNativePath], 31 | :mac_catalyst_enabled => false, 32 | # :ccache_enabled => true 33 | ) 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /test/template/ios/TestCodePush/AppDelegate.mm: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | #import 3 | 4 | #import 5 | 6 | @implementation AppDelegate 7 | 8 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 9 | { 10 | self.moduleName = @"TestCodePush"; 11 | // You can add your custom initial props in the dictionary below. 12 | // They will be passed down to the ViewController used by React Native. 13 | self.initialProps = @{}; 14 | 15 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 16 | } 17 | 18 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 19 | { 20 | return [self bundleURL]; 21 | } 22 | 23 | - (NSURL *)bundleURL 24 | { 25 | #if DEBUG 26 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; 27 | #else 28 | return [CodePush bundleURL]; 29 | #endif 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /test/template/ios/TestCodePush/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import React 3 | import React_RCTAppDelegate 4 | import ReactAppDependencyProvider 5 | import CodePush 6 | 7 | @main 8 | class AppDelegate: RCTAppDelegate { 9 | override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { 10 | self.moduleName = "TestCodePush" 11 | self.dependencyProvider = RCTAppDependencyProvider() 12 | 13 | // You can add your custom initial props in the dictionary below. 14 | // They will be passed down to the ViewController used by React Native. 15 | self.initialProps = [:] 16 | 17 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 18 | } 19 | 20 | override func sourceURL(for bridge: RCTBridge) -> URL? { 21 | self.bundleURL() 22 | } 23 | 24 | override func bundleURL() -> URL? { 25 | #if DEBUG 26 | RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index") 27 | #else 28 | CodePush.bundleURL(); 29 | #endif 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test/template/scenarios/scenarioCheckForUpdate.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | 3 | module.exports = { 4 | startTest: function (testApp) { 5 | CodePushWrapper.checkForUpdate(testApp); 6 | }, 7 | 8 | getScenarioName: function () { 9 | return "Check for Update"; 10 | } 11 | }; -------------------------------------------------------------------------------- /test/template/scenarios/scenarioCheckForUpdateCustomKey.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | 3 | module.exports = { 4 | startTest: function (testApp) { 5 | CodePushWrapper.checkForUpdate(testApp, undefined, undefined, "CUSTOM-DEPLOYMENT-KEY"); 6 | }, 7 | 8 | getScenarioName: function () { 9 | return "Check for Update Custom Key"; 10 | } 11 | }; -------------------------------------------------------------------------------- /test/template/scenarios/scenarioDisallowRestartImmediate.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | import CodePush from "@revopush/react-native-code-push"; 3 | 4 | module.exports = { 5 | startTest: function (testApp) { 6 | CodePush.disallowRestart(); 7 | CodePushWrapper.checkAndInstall(testApp, 8 | () => { 9 | CodePush.allowRestart(); 10 | }, 11 | undefined, 12 | CodePush.InstallMode.IMMEDIATE, 13 | undefined, 14 | true 15 | ); 16 | }, 17 | 18 | getScenarioName: function () { 19 | return "disallowRestart"; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /test/template/scenarios/scenarioDisallowRestartOnResume.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | import CodePush from "@revopush/react-native-code-push"; 3 | 4 | module.exports = { 5 | startTest: function (testApp) { 6 | CodePush.disallowRestart(); 7 | CodePushWrapper.checkAndInstall(testApp, 8 | undefined, 9 | undefined, 10 | CodePush.InstallMode.ON_NEXT_RESUME, 11 | undefined, 12 | true 13 | ); 14 | }, 15 | 16 | getScenarioName: function () { 17 | return "disallowRestart"; 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /test/template/scenarios/scenarioDisallowRestartOnSuspend.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | import CodePush from "@revopush/react-native-code-push"; 3 | 4 | module.exports = { 5 | startTest: function (testApp) { 6 | CodePush.disallowRestart(); 7 | CodePushWrapper.checkAndInstall(testApp, 8 | undefined, 9 | undefined, 10 | CodePush.InstallMode.ON_NEXT_SUSPEND, 11 | undefined, 12 | true 13 | ); 14 | }, 15 | 16 | getScenarioName: function () { 17 | return "disallowRestart"; 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /test/template/scenarios/scenarioDownloadUpdate.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | 3 | module.exports = { 4 | startTest: function (testApp) { 5 | CodePushWrapper.checkForUpdate(testApp, 6 | CodePushWrapper.download.bind(undefined, testApp, undefined, undefined)); 7 | }, 8 | 9 | getScenarioName: function () { 10 | return "Download Update"; 11 | } 12 | }; -------------------------------------------------------------------------------- /test/template/scenarios/scenarioInstall.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | import CodePush from "@revopush/react-native-code-push"; 3 | 4 | module.exports = { 5 | startTest: function (testApp) { 6 | CodePushWrapper.checkAndInstall(testApp, undefined, undefined, CodePush.InstallMode.IMMEDIATE); 7 | }, 8 | 9 | getScenarioName: function () { 10 | return "Install"; 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /test/template/scenarios/scenarioInstallOnRestartWithRevert.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | import CodePush from "@revopush/react-native-code-push"; 3 | 4 | module.exports = { 5 | startTest: function (testApp) { 6 | CodePushWrapper.checkAndInstall(testApp, undefined, undefined, CodePush.InstallMode.ON_NEXT_RESTART); 7 | }, 8 | 9 | getScenarioName: function () { 10 | return "Install on Restart with Revert"; 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /test/template/scenarios/scenarioInstallOnResumeWithRevert.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | import CodePush from "@revopush/react-native-code-push"; 3 | 4 | module.exports = { 5 | startTest: function (testApp) { 6 | CodePushWrapper.checkAndInstall(testApp, undefined, undefined, CodePush.InstallMode.ON_NEXT_RESUME); 7 | }, 8 | 9 | getScenarioName: function () { 10 | return "Install on Resume with Revert"; 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /test/template/scenarios/scenarioInstallOnSuspendWithRevert.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | import CodePush from "@revopush/react-native-code-push"; 3 | 4 | module.exports = { 5 | startTest: function (testApp) { 6 | CodePushWrapper.checkAndInstall(testApp, undefined, undefined, CodePush.InstallMode.ON_NEXT_SUSPEND); 7 | }, 8 | 9 | getScenarioName: function () { 10 | return "Install on Suspend with Revert"; 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /test/template/scenarios/scenarioInstallRestart2x.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | import CodePush from "@revopush/react-native-code-push"; 3 | 4 | module.exports = { 5 | startTest: function (testApp) { 6 | CodePushWrapper.checkAndInstall(testApp, 7 | () => { 8 | CodePush.restartApp(); 9 | CodePush.restartApp(); 10 | } 11 | ); 12 | }, 13 | 14 | getScenarioName: function () { 15 | return "Install and Restart 2x"; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /test/template/scenarios/scenarioInstallWithRevert.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | import CodePush from "@revopush/react-native-code-push"; 3 | 4 | module.exports = { 5 | startTest: function (testApp) { 6 | CodePushWrapper.checkAndInstall(testApp, undefined, undefined, CodePush.InstallMode.IMMEDIATE); 7 | }, 8 | 9 | getScenarioName: function () { 10 | return "Install with Revert"; 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /test/template/scenarios/scenarioRestart.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | import CodePush from "@revopush/react-native-code-push"; 3 | 4 | module.exports = { 5 | startTest: function (testApp) { 6 | testApp.sendCurrentAndPendingPackage() 7 | .then(() => { 8 | CodePushWrapper.sync(testApp, (status) => { 9 | if (status === CodePush.SyncStatus.UPDATE_INSTALLED) { 10 | testApp.sendCurrentAndPendingPackage().then(CodePush.restartApp); 11 | } 12 | }, undefined, { installMode: CodePush.InstallMode.ON_NEXT_RESTART }); 13 | }); 14 | }, 15 | 16 | getScenarioName: function () { 17 | return "Restart"; 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /test/template/scenarios/scenarioRestart2x.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | import CodePush from "@revopush/react-native-code-push"; 3 | 4 | module.exports = { 5 | startTest: function (testApp) { 6 | CodePush.restartApp(true); 7 | CodePushWrapper.checkAndInstall(testApp, 8 | () => { 9 | CodePush.restartApp(true); 10 | } 11 | ); 12 | }, 13 | 14 | getScenarioName: function () { 15 | return "Restart2x"; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /test/template/scenarios/scenarioSync.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | import CodePush from "@revopush/react-native-code-push"; 3 | 4 | module.exports = { 5 | startTest: function (testApp) { 6 | CodePushWrapper.sync(testApp, undefined, undefined, { installMode: CodePush.InstallMode.IMMEDIATE }); 7 | }, 8 | 9 | getScenarioName: function () { 10 | return "Sync"; 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /test/template/scenarios/scenarioSync2x.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | import CodePush from "@revopush/react-native-code-push"; 3 | 4 | module.exports = { 5 | startTest: function (testApp) { 6 | CodePushWrapper.sync(testApp, undefined, undefined, { installMode: CodePush.InstallMode.IMMEDIATE }); 7 | CodePushWrapper.sync(testApp, undefined, undefined, { installMode: CodePush.InstallMode.IMMEDIATE }); 8 | }, 9 | 10 | getScenarioName: function () { 11 | return "Sync 2x"; 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /test/template/scenarios/scenarioSyncMandatoryDefault.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | import CodePush from "@revopush/react-native-code-push"; 3 | 4 | module.exports = { 5 | startTest: function (testApp) { 6 | CodePushWrapper.sync(testApp, undefined, undefined, { installMode: CodePush.InstallMode.ON_NEXT_RESTART }); 7 | }, 8 | 9 | getScenarioName: function () { 10 | return "Sync Mandatory Default"; 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /test/template/scenarios/scenarioSyncMandatoryRestart.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | import CodePush from "@revopush/react-native-code-push"; 3 | 4 | module.exports = { 5 | startTest: function (testApp) { 6 | CodePushWrapper.sync(testApp, undefined, undefined, 7 | { 8 | installMode: CodePush.InstallMode.IMMEDIATE, 9 | mandatoryInstallMode: CodePush.InstallMode.ON_NEXT_RESTART 10 | }); 11 | }, 12 | 13 | getScenarioName: function () { 14 | return "Sync Mandatory Restart"; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /test/template/scenarios/scenarioSyncMandatoryResume.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | import CodePush from "@revopush/react-native-code-push"; 3 | 4 | module.exports = { 5 | startTest: function (testApp) { 6 | CodePushWrapper.sync(testApp, undefined, undefined, 7 | { 8 | installMode: CodePush.InstallMode.ON_NEXT_RESTART, 9 | mandatoryInstallMode: CodePush.InstallMode.ON_NEXT_RESUME 10 | }); 11 | }, 12 | 13 | getScenarioName: function () { 14 | return "Sync Mandatory Resume"; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /test/template/scenarios/scenarioSyncMandatorySuspend.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | import CodePush from "@revopush/react-native-code-push"; 3 | 4 | module.exports = { 5 | startTest: function (testApp) { 6 | CodePushWrapper.sync(testApp, undefined, undefined, 7 | { 8 | installMode: CodePush.InstallMode.IMMEDIATE, 9 | mandatoryInstallMode: CodePush.InstallMode.ON_NEXT_SUSPEND 10 | }); 11 | }, 12 | 13 | getScenarioName: function () { 14 | return "Sync Mandatory Suspend"; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /test/template/scenarios/scenarioSyncRestartDelay.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | import CodePush from "@revopush/react-native-code-push"; 3 | 4 | module.exports = { 5 | startTest: function (testApp) { 6 | CodePushWrapper.sync(testApp, undefined, undefined, 7 | { 8 | installMode: CodePush.InstallMode.ON_NEXT_RESTART, 9 | minimumBackgroundDuration: 15 10 | }); 11 | }, 12 | 13 | getScenarioName: function () { 14 | return "Sync Restart Delay"; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /test/template/scenarios/scenarioSyncResume.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | import CodePush from "@revopush/react-native-code-push"; 3 | 4 | module.exports = { 5 | startTest: function (testApp) { 6 | CodePushWrapper.sync(testApp, undefined, undefined, 7 | { installMode: CodePush.InstallMode.ON_NEXT_RESUME }); 8 | }, 9 | 10 | getScenarioName: function () { 11 | return "Sync Resume"; 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /test/template/scenarios/scenarioSyncResumeDelay.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | import CodePush from "@revopush/react-native-code-push"; 3 | 4 | module.exports = { 5 | startTest: function (testApp) { 6 | CodePushWrapper.sync(testApp, undefined, undefined, 7 | { 8 | installMode: CodePush.InstallMode.ON_NEXT_RESUME, 9 | minimumBackgroundDuration: 5 10 | }); 11 | }, 12 | 13 | getScenarioName: function () { 14 | return "Sync Resume Delay"; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /test/template/scenarios/scenarioSyncSuspend.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | import CodePush from "@revopush/react-native-code-push"; 3 | 4 | module.exports = { 5 | startTest: function (testApp) { 6 | CodePushWrapper.sync(testApp, undefined, undefined, 7 | { installMode: CodePush.InstallMode.ON_NEXT_SUSPEND }); 8 | }, 9 | 10 | getScenarioName: function () { 11 | return "Sync Suspend"; 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /test/template/scenarios/scenarioSyncSuspendDelay.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | import CodePush from "@revopush/react-native-code-push"; 3 | 4 | module.exports = { 5 | startTest: function (testApp) { 6 | CodePushWrapper.sync(testApp, undefined, undefined, 7 | { 8 | installMode: CodePush.InstallMode.ON_NEXT_SUSPEND, 9 | minimumBackgroundDuration: 5 10 | }); 11 | }, 12 | 13 | getScenarioName: function () { 14 | return "Sync Suspend Delay"; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /test/template/scenarios/updateDeviceReady.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | 3 | module.exports = { 4 | startTest: function (testApp) { 5 | testApp.readyAfterUpdate(); 6 | }, 7 | 8 | getScenarioName: function () { 9 | return "Bad Update"; 10 | } 11 | }; -------------------------------------------------------------------------------- /test/template/scenarios/updateNARConditional.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | import CodePush from "@revopush/react-native-code-push"; 3 | 4 | module.exports = { 5 | startTest: function (testApp) { 6 | testApp.readyAfterUpdate((responseBody) => { 7 | if (responseBody !== "SKIP_NOTIFY_APPLICATION_READY") { 8 | CodePush.notifyAppReady(); 9 | CodePushWrapper.checkAndInstall(testApp, undefined, undefined, CodePush.InstallMode.ON_NEXT_RESTART); 10 | } else { 11 | testApp.setStateAndSendMessage("Skipping notifyApplicationReady!", "SKIPPED_NOTIFY_APPLICATION_READY"); 12 | } 13 | }); 14 | }, 15 | 16 | getScenarioName: function () { 17 | return "Conditional Update"; 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /test/template/scenarios/updateNotifyApplicationReady.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | import CodePush from "@revopush/react-native-code-push"; 3 | 4 | module.exports = { 5 | startTest: function (testApp) { 6 | testApp.readyAfterUpdate(); 7 | CodePush.notifyAppReady(); 8 | }, 9 | 10 | getScenarioName: function () { 11 | return "Good Update"; 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /test/template/scenarios/updateSync.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | 3 | module.exports = { 4 | startTest: function (testApp) { 5 | testApp.readyAfterUpdate(); 6 | CodePushWrapper.sync(testApp); 7 | }, 8 | 9 | getScenarioName: function () { 10 | return "Good Update (w/ Sync)"; 11 | } 12 | }; -------------------------------------------------------------------------------- /test/template/scenarios/updateSync2x.js: -------------------------------------------------------------------------------- 1 | var CodePushWrapper = require("../codePushWrapper.js"); 2 | 3 | module.exports = { 4 | startTest: function (testApp) { 5 | testApp.readyAfterUpdate(); 6 | CodePushWrapper.sync(testApp); 7 | CodePushWrapper.sync(testApp); 8 | }, 9 | 10 | getScenarioName: function () { 11 | return "Good Update (w/ Sync 2x)"; 12 | } 13 | }; -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES5", 4 | "module": "commonjs", 5 | "lib": ["es6"], 6 | "noImplicitAny": true, 7 | "noEmitOnError": true, 8 | "moduleResolution": "node", 9 | "sourceMap": true, 10 | "rootDir": "test", 11 | "outDir": "bin", 12 | "removeComments": true 13 | }, 14 | "exclude": [ 15 | "Examples" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "rules": { 4 | "class-name": true, 5 | "comment-format": [true, 6 | "check-space" 7 | ], 8 | "indent": [true, 9 | "spaces" 10 | ], 11 | "one-line": [true, 12 | "check-open-brace" 13 | ], 14 | "quotemark": [true, 15 | "double" 16 | ], 17 | "semicolon": true, 18 | "whitespace": [true, 19 | "check-branch", 20 | "check-operator", 21 | "check-separator", 22 | "check-type" 23 | ], 24 | "typedef-whitespace": [true, { 25 | "call-signature": "nospace", 26 | "index-signature": "nospace", 27 | "parameter": "nospace", 28 | "property-declaration": "nospace", 29 | "variable-declaration": "nospace" 30 | }] 31 | } 32 | } 33 | --------------------------------------------------------------------------------