@appzung/react-native-code-push 6.4.2 → 8.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/.azurepipelines/build-rn-code-push-1es.yml +104 -0
  2. package/.azurepipelines/test-rn-code-push.yml +94 -0
  3. package/.config/CredScanSuppressions.json +14 -0
  4. package/CONTRIBUTING.md +3 -3
  5. package/CodePush.js +26 -28
  6. package/CodePush.podspec +1 -1
  7. package/README.md +8 -7
  8. package/SECURITY.md +41 -0
  9. package/android/app/build.gradle +1 -1
  10. package/android/app/src/main/AndroidManifest.xml +1 -5
  11. package/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java +14 -5
  12. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushConstants.java +1 -0
  13. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushNativeModule.java +19 -1
  14. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateUtils.java +5 -4
  15. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUtils.java +3 -1
  16. package/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java +8 -9
  17. package/android/build.gradle +3 -2
  18. package/android/codepush.gradle +79 -30
  19. package/docs/api-js.md +1 -1
  20. package/docs/setup-android.md +27 -3
  21. package/docs/setup-ios.md +1 -1
  22. package/docs/setup-windows.md +59 -3
  23. package/ios/CodePush/CodePushPackage.m +4 -0
  24. package/ios/CodePush/CodePushUpdateUtils.m +1 -1
  25. package/ios/CodePush.xcodeproj/project.pbxproj +2 -2
  26. package/package.json +11 -11
  27. package/typings/react-native-code-push.d.ts +1 -1
  28. package/windows/CodePush/CodePush.def +3 -0
  29. package/windows/CodePush/CodePush.vcxproj +198 -0
  30. package/windows/CodePush/CodePush.vcxproj.filters +91 -0
  31. package/windows/CodePush/CodePushConfig.cpp +104 -0
  32. package/windows/CodePush/CodePushConfig.h +66 -0
  33. package/windows/CodePush/CodePushConfig.idl +12 -0
  34. package/windows/CodePush/CodePushDownloadHandler.cpp +73 -0
  35. package/windows/CodePush/CodePushDownloadHandler.h +32 -0
  36. package/windows/CodePush/CodePushNativeModule.cpp +934 -0
  37. package/windows/CodePush/CodePushNativeModule.h +247 -0
  38. package/windows/CodePush/CodePushPackage.cpp +456 -0
  39. package/windows/CodePush/CodePushPackage.h +49 -0
  40. package/windows/CodePush/CodePushTelemetryManager.cpp +213 -0
  41. package/windows/CodePush/CodePushTelemetryManager.h +29 -0
  42. package/windows/CodePush/CodePushUpdateUtils.cpp +86 -0
  43. package/windows/CodePush/CodePushUpdateUtils.h +38 -0
  44. package/windows/CodePush/CodePushUtils.cpp +29 -0
  45. package/windows/CodePush/CodePushUtils.h +18 -0
  46. package/windows/CodePush/FileUtils.cpp +131 -0
  47. package/windows/CodePush/FileUtils.h +28 -0
  48. package/windows/CodePush/PropertySheet.props +16 -0
  49. package/windows/CodePush/ReactPackageProvider.cpp +15 -0
  50. package/windows/CodePush/ReactPackageProvider.h +22 -0
  51. package/windows/CodePush/ReactPackageProvider.idl +9 -0
  52. package/windows/CodePush/miniz/LICENSE +22 -0
  53. package/windows/CodePush/miniz/miniz.c +7657 -0
  54. package/windows/CodePush/miniz/miniz.h +1338 -0
  55. package/windows/CodePush/miniz/readme.md +37 -0
  56. package/windows/CodePush/packages.config +4 -0
  57. package/windows/CodePush/pch.cpp +1 -0
  58. package/windows/CodePush/pch.h +4 -0
  59. package/{windows → windows-legacy}/CodePush/CodePush.csproj +1 -1
  60. package/{windows → windows-legacy}/CodePush.Net46/CodePush.Net46.csproj +2 -2
  61. package/{windows → windows-legacy}/CodePush.Net46/packages.config +1 -1
  62. package/windows-legacy/CodePush.Net46.Test/ApplicationDataContainerTest.cs +105 -0
  63. package/windows-legacy/CodePush.Net46.Test/CodePush.Net46.Test.csproj +137 -0
  64. package/windows-legacy/CodePush.Net46.Test/Properties/AssemblyInfo.cs +36 -0
  65. package/windows-legacy/CodePush.Net46.Test/TelemetryManagerTest.cs +117 -0
  66. package/windows-legacy/CodePush.Net46.Test/app.config +11 -0
  67. package/windows-legacy/CodePush.Net46.Test/packages.config +4 -0
  68. /package/{windows → windows-legacy}/CodePush/CodePushUtils.cs +0 -0
  69. /package/{windows → windows-legacy}/CodePush/FileUtils.cs +0 -0
  70. /package/{windows → windows-legacy}/CodePush/Properties/AssemblyInfo.cs +0 -0
  71. /package/{windows → windows-legacy}/CodePush/Properties/CodePush.rd.xml +0 -0
  72. /package/{windows → windows-legacy}/CodePush/UpdateManager.cs +0 -0
  73. /package/{windows → windows-legacy}/CodePush/UpdateUtils.cs +0 -0
  74. /package/{windows → windows-legacy}/CodePush.Net46/Adapters/Http/HttpProgress.cs +0 -0
  75. /package/{windows → windows-legacy}/CodePush.Net46/Adapters/Storage/ApplicationDataContainer.cs +0 -0
  76. /package/{windows → windows-legacy}/CodePush.Net46/CodePushUtils.cs +0 -0
  77. /package/{windows → windows-legacy}/CodePush.Net46/FileUtils.cs +0 -0
  78. /package/{windows → windows-legacy}/CodePush.Net46/Properties/AssemblyInfo.cs +0 -0
  79. /package/{windows → windows-legacy}/CodePush.Net46/UpdateManager.cs +0 -0
  80. /package/{windows → windows-legacy}/CodePush.Net46/UpdateUtils.cs +0 -0
  81. /package/{windows → windows-legacy}/CodePush.Shared/CodePush.Shared.projitems +0 -0
  82. /package/{windows → windows-legacy}/CodePush.Shared/CodePush.Shared.shproj +0 -0
  83. /package/{windows → windows-legacy}/CodePush.Shared/CodePushConstants.cs +0 -0
  84. /package/{windows → windows-legacy}/CodePush.Shared/CodePushNativeModule.cs +0 -0
  85. /package/{windows → windows-legacy}/CodePush.Shared/CodePushReactPackage.cs +0 -0
  86. /package/{windows → windows-legacy}/CodePush.Shared/CodePushUtils.cs +0 -0
  87. /package/{windows → windows-legacy}/CodePush.Shared/InstallMode.cs +0 -0
  88. /package/{windows → windows-legacy}/CodePush.Shared/MinimumBackgroundListener.cs +0 -0
  89. /package/{windows → windows-legacy}/CodePush.Shared/SettingsManager.cs +0 -0
  90. /package/{windows → windows-legacy}/CodePush.Shared/TelemetryManager.cs +0 -0
  91. /package/{windows → windows-legacy}/CodePush.Shared/UpdateState.cs +0 -0
@@ -0,0 +1,104 @@
1
+ trigger:
2
+ - master
3
+
4
+ pr:
5
+ - master
6
+
7
+ resources:
8
+ repositories:
9
+ - repository: 1ESPipelineTemplates
10
+ type: git
11
+ name: 1ESPipelineTemplates/1ESPipelineTemplates
12
+ ref: refs/tags/release
13
+ name: $(Build.SourceBranchName)_$(date:yyyyMMdd)$(rev:.r)
14
+
15
+ extends:
16
+ ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/master') }}:
17
+ template: v1/1ES.Official.PipelineTemplate.yml@1ESPipelineTemplates
18
+ ${{ else }}:
19
+ template: v1/1ES.Unofficial.PipelineTemplate.yml@1ESPipelineTemplates
20
+ parameters:
21
+ pool:
22
+ name: 1ES-PT-CBL-Mariner-2.0-Gen2
23
+ os: linux
24
+ customBuildTags:
25
+ - ES365AIMigrationTooling-BulkMigrated
26
+ sdl:
27
+ sourceAnalysisPool: 1ES-PT-Windows-2022
28
+ credscan:
29
+ suppressionsFile: $(Build.SourcesDirectory)/.config/CredScanSuppressions.json
30
+ stages:
31
+ - stage: Stage
32
+ jobs:
33
+ - job: HostJob
34
+ templateContext:
35
+ outputs:
36
+ - output: pipelineArtifact
37
+ displayName: "Publish Artifact: artifacts"
38
+ path: '$(Build.ArtifactStagingDirectory)/npm'
39
+ artifactName: npm
40
+
41
+ steps:
42
+ - task: NodeTool@0
43
+ inputs:
44
+ versionSpec: '14.x'
45
+ displayName: 'Install Node.js'
46
+
47
+ - script: |
48
+ npm pack
49
+ npm install -g react-native-code-push*.tgz
50
+ displayName: 'Package react-native-code-push'
51
+ workingDirectory: $(Build.SourcesDirectory)
52
+
53
+ - task: DeleteFiles@1
54
+ inputs:
55
+ contents: node_modules
56
+ displayName: 'Delete node_modules'
57
+
58
+ - task: ArchiveFiles@2
59
+ inputs:
60
+ rootFolderOrFile: '$(Build.SourcesDirectory)'
61
+ includeRootFolder: false
62
+ archiveType: 'tar'
63
+ archiveFile: '$(Build.ArtifactStagingDirectory)/npm/$(Build.BuildId).tgz'
64
+ replaceExistingArchive: true
65
+ verbose: true
66
+ displayName: 'Prepare npm artifact'
67
+
68
+ - stage: APIScan
69
+ dependsOn: Stage
70
+ pool:
71
+ name: 1ES-PT-Windows-2022
72
+ os: windows
73
+ variables:
74
+ "agent.source.skip": true
75
+ jobs:
76
+ - job: APIScan
77
+ steps:
78
+ - task: DownloadPipelineArtifact@2
79
+ displayName: Download Build Artifacts for APIScan
80
+ inputs:
81
+ artifactName: npm
82
+ targetPath: '$(Agent.BuildDirectory)/npm'
83
+ - task: ExtractFiles@1
84
+ inputs:
85
+ archiveFilePatterns: '$(Agent.BuildDirectory)/npm/*.tgz'
86
+ destinationFolder: '$(Agent.BuildDirectory)/npm_extracted'
87
+ - task: AzureKeyVault@2
88
+ inputs:
89
+ azureSubscription: 'AC - Dev Infra & Build Pool'
90
+ KeyVaultName: 'mobile-center-sdk'
91
+ SecretsFilter: 'appcenter-sdk-managed-identity-clientid'
92
+ RunAsPreJob: false
93
+ - task: APIScan@2
94
+ displayName: 'Run APIScan'
95
+ inputs:
96
+ softwareFolder: '$(Agent.BuildDirectory)\npm_extracted'
97
+ softwareName: 'react-native-code-push'
98
+ softwareVersionNum: '$(Build.BuildId)'
99
+ isLargeApp: false
100
+ toolVersion: 'Latest'
101
+ verbosityLevel: verbose
102
+ condition: and(succeeded(), ne(variables['DisableAPIScan'], 'true'))
103
+ env:
104
+ AzureServicesAuthConnectionString: 'runAs=App;AppId=$(appcenter-sdk-managed-identity-clientid)'
@@ -0,0 +1,94 @@
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
+
@@ -0,0 +1,14 @@
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
+
package/CONTRIBUTING.md CHANGED
@@ -37,10 +37,10 @@ Follow these steps to test your modifications to the plugin manually:
37
37
 
38
38
  First, make sure you have installed the dependencies for the plugin by following the steps above.
39
39
 
40
- Then, make sure you have installed `react-native-cli`.
40
+ Then, make sure you have installed `react-native`.
41
41
 
42
42
  ```
43
- npm install -g react-native-cli
43
+ npm install -g react-native
44
44
  ```
45
45
 
46
46
  To run Android tests, make sure you have `sdk\tools`, `sdk\emulator` and `sdk\platform-tools` in your PATH.
@@ -131,4 +131,4 @@ To run the core unit tests on Android and pull the plugin from NPM:
131
131
  NPM=true CORE=true npm run test:android
132
132
  ```
133
133
 
134
- ...and so on!
134
+ ...and so on!
package/CodePush.js CHANGED
@@ -180,7 +180,7 @@ async function notifyApplicationReadyInternal() {
180
180
  return statusReport;
181
181
  }
182
182
 
183
- async function tryReportStatus(statusReport, resumeListener) {
183
+ async function tryReportStatus(statusReport, retryOnAppResume) {
184
184
  const config = await getConfiguration();
185
185
  const previousLabelOrAppVersion = statusReport.previousLabelOrAppVersion;
186
186
  const previousDeploymentKey = statusReport.previousDeploymentKey || config.deploymentKey;
@@ -209,22 +209,21 @@ async function tryReportStatus(statusReport, resumeListener) {
209
209
  }
210
210
 
211
211
  NativeCodePush.recordStatusReported(statusReport);
212
- resumeListener && AppState.removeEventListener("change", resumeListener);
212
+ retryOnAppResume && retryOnAppResume.remove();
213
213
  } catch (e) {
214
214
  log(`Report status failed: ${JSON.stringify(statusReport)}`);
215
215
  NativeCodePush.saveStatusReportForRetry(statusReport);
216
216
  // Try again when the app resumes
217
- if (!resumeListener) {
218
- resumeListener = async (newState) => {
217
+ if (!retryOnAppResume) {
218
+ const resumeListener = AppState.addEventListener("change", async (newState) => {
219
219
  if (newState !== "active") return;
220
220
  const refreshedStatusReport = await NativeCodePush.getNewStatusReport();
221
221
  if (refreshedStatusReport) {
222
222
  tryReportStatus(refreshedStatusReport, resumeListener);
223
223
  } else {
224
- AppState.removeEventListener("change", resumeListener);
224
+ resumeListener && resumeListener.remove();
225
225
  }
226
- };
227
- AppState.addEventListener("change", resumeListener);
226
+ });
228
227
  }
229
228
  }
230
229
  }
@@ -532,42 +531,41 @@ function codePushify(options = {}) {
532
531
  );
533
532
  }
534
533
 
535
- var decorator = (RootComponent) => {
536
- const extended = class CodePushComponent extends React.Component {
534
+ const decorator = (RootComponent) => {
535
+ class CodePushComponent extends React.Component {
536
+ constructor(props) {
537
+ super(props);
538
+ this.rootComponentRef = React.createRef();
539
+ }
540
+
537
541
  componentDidMount() {
538
542
  if (options.checkFrequency === CodePush.CheckFrequency.MANUAL) {
539
543
  CodePush.notifyAppReady();
540
544
  } else {
541
- let rootComponentInstance = this.refs.rootComponent;
545
+ const rootComponentInstance = this.rootComponentRef.current;
542
546
 
543
547
  let syncStatusCallback;
544
548
  if (rootComponentInstance && rootComponentInstance.codePushStatusDidChange) {
545
- syncStatusCallback = rootComponentInstance.codePushStatusDidChange;
546
- if (rootComponentInstance instanceof React.Component) {
547
- syncStatusCallback = syncStatusCallback.bind(rootComponentInstance);
548
- }
549
+ syncStatusCallback = rootComponentInstance.codePushStatusDidChange.bind(rootComponentInstance);
549
550
  }
550
551
 
551
552
  let downloadProgressCallback;
552
553
  if (rootComponentInstance && rootComponentInstance.codePushDownloadDidProgress) {
553
- downloadProgressCallback = rootComponentInstance.codePushDownloadDidProgress;
554
- if (rootComponentInstance instanceof React.Component) {
555
- downloadProgressCallback = downloadProgressCallback.bind(rootComponentInstance);
556
- }
554
+ downloadProgressCallback = rootComponentInstance.codePushDownloadDidProgress.bind(rootComponentInstance);
557
555
  }
558
556
 
559
557
  let handleBinaryVersionMismatchCallback;
560
558
  if (rootComponentInstance && rootComponentInstance.codePushOnBinaryVersionMismatch) {
561
- handleBinaryVersionMismatchCallback = rootComponentInstance.codePushOnBinaryVersionMismatch;
562
- if (rootComponentInstance instanceof React.Component) {
563
- handleBinaryVersionMismatchCallback = handleBinaryVersionMismatchCallback.bind(rootComponentInstance);
564
- }
559
+ handleBinaryVersionMismatchCallback = rootComponentInstance.codePushOnBinaryVersionMismatch.bind(rootComponentInstance);
565
560
  }
566
561
 
567
562
  CodePush.sync(options, syncStatusCallback, downloadProgressCallback, handleBinaryVersionMismatchCallback);
563
+
568
564
  if (options.checkFrequency === CodePush.CheckFrequency.ON_APP_RESUME) {
569
565
  ReactNative.AppState.addEventListener("change", (newState) => {
570
- newState === "active" && CodePush.sync(options, syncStatusCallback, downloadProgressCallback);
566
+ if (newState === "active") {
567
+ CodePush.sync(options, syncStatusCallback, downloadProgressCallback);
568
+ }
571
569
  });
572
570
  }
573
571
  }
@@ -576,17 +574,17 @@ function codePushify(options = {}) {
576
574
  render() {
577
575
  const props = {...this.props};
578
576
 
579
- // we can set ref property on class components only (not stateless)
580
- // check it by render method
581
- if (RootComponent.prototype.render) {
582
- props.ref = "rootComponent";
577
+ // We can set ref property on class components only (not stateless)
578
+ // Check it by render method
579
+ if (RootComponent.prototype && RootComponent.prototype.render) {
580
+ props.ref = this.rootComponentRef;
583
581
  }
584
582
 
585
583
  return <RootComponent {...props} />
586
584
  }
587
585
  }
588
586
 
589
- return hoistStatics(extended, RootComponent);
587
+ return hoistStatics(CodePushComponent, RootComponent);
590
588
  }
591
589
 
592
590
  if (typeof options === "function") {
package/CodePush.podspec CHANGED
@@ -10,7 +10,7 @@ Pod::Spec.new do |s|
10
10
  s.license = package['license']
11
11
  s.homepage = package['homepage']
12
12
  s.source = { :git => 'https://github.com/appzung/react-native-code-push.git', :tag => "v#{s.version}"}
13
- s.ios.deployment_target = '7.0'
13
+ s.ios.deployment_target = '9.0'
14
14
  s.tvos.deployment_target = '9.0'
15
15
  s.preserve_paths = '*.js'
16
16
  s.library = 'z'
package/README.md CHANGED
@@ -39,7 +39,7 @@ This plugin provides client-side integration for the [CodePush service](https://
39
39
 
40
40
  ## How does it work?
41
41
 
42
- A React Native app is composed of JavaScript files and any accompanying [images](https://facebook.github.io/react-native/docs/images.html#content), which are bundled together by the [packager](https://github.com/facebook/react-native/tree/master/packager) and distributed as part of a platform-specific binary (i.e. an `.ipa` or `.apk` file). Once the app is released, updating either the JavaScript code (e.g. making bug fixes, adding new features) or image assets, requires you to recompile and redistribute the entire binary, which of course, includes any review time associated with the store(s) you are publishing to.
42
+ A React Native app is composed of JavaScript files and any accompanying [images](https://reactnative.dev/docs/image), which are bundled together by the [metro bundler](https://github.com/facebook/metro) and distributed as part of a platform-specific binary (i.e. an `.ipa` or `.apk` file). Once the app is released, updating either the JavaScript code (e.g. making bug fixes, adding new features) or image assets, requires you to recompile and redistribute the entire binary, which of course, includes any review time associated with the store(s) you are publishing to.
43
43
 
44
44
  The CodePush plugin helps get product improvements in front of your end users instantly, by keeping your JavaScript and images synchronized with updates you release to the CodePush server. This way, your app gets the benefits of an offline mobile experience, as well as the "web-like" agility of side-loading updates as soon as they are available. It's a win-win!
45
45
 
@@ -74,7 +74,9 @@ We try our best to maintain backwards compatibility of our plugin with previous
74
74
  | v0.56-v0.58 | v5.4+ *(RN upgraded versions for Android tools)* |
75
75
  | v0.59 | v5.6+ *(RN refactored js bundle loader code)* |
76
76
  | v0.60-v0.61 | v6.0+ *(RN migrated to Autolinking)* |
77
- | v0.62-v0.63 | v6.2+ *(RN removed LiveReload)* |
77
+ | v0.62-v0.64 | v6.2+ *(RN removed LiveReload)* |
78
+ | v0.65-v0.70 | v7.0+ *(RN updated iPhone-target-version)* |
79
+ | v0.71 | v8.0+ *(RN moved to react-native-gradle-plugin)* |
78
80
 
79
81
  *NOTE: `react-native-code-push` versions lower than **[v5.7.0](https://github.com/microsoft/react-native-code-push/releases/tag/v5.7.0)** will stop working in the near future. You can find more information in our [documentation](https://github.com/microsoft/code-push/blob/master/migration-notice.md).*
80
82
 
@@ -250,7 +252,7 @@ Android Google Play and iOS App Store have corresponding guidelines that have ru
250
252
 
251
253
  #### Google play
252
254
 
253
- Third paragraph of [Device and Network Abuse](https://support.google.com/googleplay/android-developer/answer/9888379?hl=en) topic describe that updating source code by any method other than Google Play's update mechanism is restricted. But this restriction is not apply to updating javascript bundles.
255
+ Third paragraph of [Device and Network Abuse](https://support.google.com/googleplay/android-developer/answer/9888379?hl=en) topic describe that updating source code by any method other than Google Play's update mechanism is restricted. But this restriction does not apply to updating javascript bundles.
254
256
  > This restriction does not apply to code that runs in a virtual machine and has limited access to Android APIs (such as JavaScript in a webview or browser).
255
257
 
256
258
  That fully allow CodePush as it updates just JS bundles and can't update native code part.
@@ -275,7 +277,7 @@ Once your app is configured and distributed to your users, and you have made som
275
277
 
276
278
  *NOTE: Before you can start releasing updates, please log into App Center by running the `appcenter login` command.*
277
279
 
278
- In it's the most basic form, this command only requires one parameter: your owner name + "/" + app name.
280
+ In its most basic form, this command only requires one parameter: your owner name + "/" + app name.
279
281
 
280
282
  ```shell
281
283
  appcenter codepush release-react -a <ownerName>/<appName>
@@ -386,7 +388,6 @@ The React Native community has graciously created some awesome open source apps
386
388
 
387
389
  Additionally, if you're looking to get started with React Native + CodePush, and are looking for an awesome starter kit, you should check out the following:
388
390
 
389
- * [Native Starter Pro](http://strapmobile.com/native-starter-pro/)
390
391
  * [Pepperoni](http://getpepperoni.com/)
391
392
 
392
393
  *Note: If you've developed a React Native app using CodePush, that is also open-source, please let us know. We would love to add it to this list!*
@@ -426,12 +427,12 @@ Now you'll be able to see CodePush logs in either debug or release mode, on both
426
427
 
427
428
  ### Continuous Integration / Delivery
428
429
 
429
- In addition to being able to use the CodePush CLI to "manually" release updates, we believe that it's important to create a repeatable and sustainable solution for contiously delivering updates to your app. That way, it's simple enough for you and/or your team to create and maintain the rhythm of performing agile deployments. In order to assist with seting up a CodePush-based CD pipeline, refer to the following integrations with various CI servers:
430
+ In addition to being able to use the CodePush CLI to "manually" release updates, we believe that it's important to create a repeatable and sustainable solution for contiously delivering updates to your app. That way, it's simple enough for you and/or your team to create and maintain the rhythm of performing agile deployments. In order to assist with setting up a CodePush-based CD pipeline, refer to the following integrations with various CI servers:
430
431
 
431
432
  * [Visual Studio Team Services](https://marketplace.visualstudio.com/items?itemName=ms-vsclient.code-push) - *NOTE: VSTS also has extensions for publishing to [HockeyApp](https://marketplace.visualstudio.com/items?itemName=ms.hockeyapp) and the [Google Play](https://github.com/microsoft/google-play-vsts-extension) store, so it provides a pretty great mobile CD solution in general.*
432
433
  * [Travis CI](https://github.com/mondora/code-push-travis-cli)
433
434
 
434
- Additionally, if you'd like more details of what a complete mobile CI/CD workflow can look like, which includes CodePush, check out this [excellent article](https://zeemee.engineering/zeemee-engineering-and-the-quest-for-the-holy-mobile-dev-grail-1310be4953d1#.zfwaxtbco) by the [ZeeMee engineering team](https://zeemee.engineering).
435
+ Additionally, if you'd like more details of what a complete mobile CI/CD workflow can look like, which includes CodePush, check out this [excellent article](https://medium.com/zeemee-engineering/zeemee-engineering-and-the-quest-for-the-holy-mobile-dev-grail-1310be4953d1) by the [ZeeMee engineering team](https://www.zeemee.com/).
435
436
 
436
437
  ### TypeScript Consumption
437
438
 
package/SECURITY.md ADDED
@@ -0,0 +1,41 @@
1
+ <!-- BEGIN MICROSOFT SECURITY.MD V0.0.5 BLOCK -->
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
+ <!-- END MICROSOFT SECURITY.MD BLOCK -->
@@ -27,5 +27,5 @@ android {
27
27
 
28
28
  dependencies {
29
29
  implementation "com.facebook.react:react-native:+"
30
- implementation 'com.nimbusds:nimbus-jose-jwt:5.1'
30
+ implementation 'com.nimbusds:nimbus-jose-jwt:9.37.3'
31
31
  }
@@ -3,8 +3,4 @@
3
3
 
4
4
  <uses-permission android:name="android.permission.INTERNET" />
5
5
 
6
- <application>
7
- <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
8
- </application>
9
-
10
- </manifest>
6
+ </manifest>
@@ -10,8 +10,8 @@ import com.facebook.react.ReactPackage;
10
10
  import com.facebook.react.bridge.JavaScriptModule;
11
11
  import com.facebook.react.bridge.NativeModule;
12
12
  import com.facebook.react.bridge.ReactApplicationContext;
13
- import com.facebook.react.devsupport.DevInternalSettings;
14
13
  import com.facebook.react.devsupport.interfaces.DevSupportManager;
14
+ import com.facebook.react.modules.debug.interfaces.DeveloperSettings;
15
15
  import com.facebook.react.uimanager.ViewManager;
16
16
 
17
17
  import org.json.JSONException;
@@ -152,12 +152,12 @@ public class CodePush implements ReactPackage {
152
152
  if (instanceManager != null) {
153
153
  DevSupportManager devSupportManager = instanceManager.getDevSupportManager();
154
154
  if (devSupportManager != null) {
155
- DevInternalSettings devInternalSettings = (DevInternalSettings)devSupportManager.getDevSettings();
156
- Method[] methods = devInternalSettings.getClass().getMethods();
155
+ DeveloperSettings devSettings = devSupportManager.getDevSettings();
156
+ Method[] methods = devSettings.getClass().getMethods();
157
157
  for (Method m : methods) {
158
158
  if (m.getName().equals("isReloadOnJSChangeEnabled")) {
159
159
  try {
160
- return (boolean) m.invoke(devInternalSettings);
160
+ return (boolean) m.invoke(devSettings);
161
161
  } catch (Exception x) {
162
162
  return false;
163
163
  }
@@ -295,7 +295,16 @@ public class CodePush implements ReactPackage {
295
295
 
296
296
  JSONObject pendingUpdate = mSettingsManager.getPendingUpdate();
297
297
  if (pendingUpdate != null) {
298
- JSONObject packageMetadata = this.mUpdateManager.getCurrentPackage();
298
+ JSONObject packageMetadata = null;
299
+
300
+ try {
301
+ packageMetadata = this.mUpdateManager.getCurrentPackage();
302
+ } catch (CodePushMalformedDataException e) {
303
+ // We need to recover the app in case 'codepush.json' is corrupted
304
+ CodePushUtils.log(e);
305
+ clearUpdates();
306
+ return;
307
+ }
299
308
  if (packageMetadata == null || !isPackageBundleLatest(packageMetadata) && hasBinaryVersionChanged(packageMetadata)) {
300
309
  CodePushUtils.log("Skipping initializeUpdateAfterRestart(), binary version is newer");
301
310
  return;
@@ -31,4 +31,5 @@ public class CodePushConstants {
31
31
  public static final String LATEST_ROLLBACK_PACKAGE_HASH_KEY = "packageHash";
32
32
  public static final String LATEST_ROLLBACK_TIME_KEY = "time";
33
33
  public static final String LATEST_ROLLBACK_COUNT_KEY = "count";
34
+ public static final String CLIENT_UNIQUE_ID_KEY = "clientUniqueId";
34
35
  }
@@ -1,6 +1,7 @@
1
1
  package com.microsoft.codepush.react;
2
2
 
3
3
  import android.app.Activity;
4
+ import android.content.SharedPreferences;
4
5
  import android.os.AsyncTask;
5
6
  import android.os.Handler;
6
7
  import android.os.Looper;
@@ -34,6 +35,7 @@ import java.util.Date;
34
35
  import java.util.HashMap;
35
36
  import java.util.List;
36
37
  import java.util.Map;
38
+ import java.util.UUID;
37
39
 
38
40
  public class CodePushNativeModule extends ReactContextBaseJavaModule {
39
41
  private String mBinaryContentsHash = null;
@@ -60,7 +62,13 @@ public class CodePushNativeModule extends ReactContextBaseJavaModule {
60
62
 
61
63
  // Initialize module state while we have a reference to the current context.
62
64
  mBinaryContentsHash = CodePushUpdateUtils.getHashForBinaryContents(reactContext, mCodePush.isDebugMode());
63
- mClientUniqueId = Settings.Secure.getString(reactContext.getContentResolver(), Settings.Secure.ANDROID_ID);
65
+
66
+ SharedPreferences preferences = codePush.getContext().getSharedPreferences(CodePushConstants.CODE_PUSH_PREFERENCES, 0);
67
+ mClientUniqueId = preferences.getString(CodePushConstants.CLIENT_UNIQUE_ID_KEY, null);
68
+ if (mClientUniqueId == null) {
69
+ mClientUniqueId = UUID.randomUUID().toString();
70
+ preferences.edit().putString(CodePushConstants.CLIENT_UNIQUE_ID_KEY, mClientUniqueId).apply();
71
+ }
64
72
  }
65
73
 
66
74
  @Override
@@ -693,4 +701,14 @@ public class CodePushNativeModule extends ReactContextBaseJavaModule {
693
701
  CodePushUtils.log("Clearing updates.");
694
702
  mCodePush.clearUpdates();
695
703
  }
704
+
705
+ @ReactMethod
706
+ public void addListener(String eventName) {
707
+ // Set up any upstream listeners or background tasks as necessary
708
+ }
709
+
710
+ @ReactMethod
711
+ public void removeListeners(Integer count) {
712
+ // Remove upstream listeners, stop unnecessary background tasks
713
+ }
696
714
  }
@@ -3,11 +3,12 @@ package com.microsoft.codepush.react;
3
3
  import android.content.Context;
4
4
  import android.util.Base64;
5
5
 
6
+ import com.nimbusds.jose.JWSVerifier;
7
+ import com.nimbusds.jose.crypto.RSASSAVerifier;
8
+ import com.nimbusds.jwt.SignedJWT;
9
+
6
10
  import java.security.interfaces.*;
7
11
 
8
- import com.nimbusds.jose.*;
9
- import com.nimbusds.jose.crypto.*;
10
- import com.nimbusds.jwt.*;
11
12
 
12
13
  import org.json.JSONArray;
13
14
  import org.json.JSONException;
@@ -97,7 +98,7 @@ public class CodePushUpdateUtils {
97
98
  }
98
99
 
99
100
  public static void copyNecessaryFilesFromCurrentPackage(String diffManifestFilePath, String currentPackageFolderPath, String newPackageFolderPath) throws IOException {
100
- FileUtils.copyDirectoryContents(currentPackageFolderPath, newPackageFolderPath);
101
+ FileUtils.copyDirectoryContents(currentPackageFolderPath, newPackageFolderPath);
101
102
  JSONObject diffManifest = CodePushUtils.getJsonObjectFromFile(diffManifestFilePath);
102
103
  try {
103
104
  JSONArray deletedFiles = diffManifest.getJSONArray("deletedFiles");
@@ -67,7 +67,9 @@ public class CodePushUtils {
67
67
  String key = it.next();
68
68
  Object obj = null;
69
69
  try {
70
- obj = jsonObj.get(key);
70
+ if (!jsonObj.isNull(key)) {
71
+ obj = jsonObj.get(key);
72
+ }
71
73
  } catch (JSONException jsonException) {
72
74
  // Should not happen.
73
75
  throw new CodePushUnknownException("Key " + key + " should exist in " + jsonObj.toString() + ".", jsonException);
@@ -123,14 +123,13 @@ public class FileUtils {
123
123
  }
124
124
  }
125
125
 
126
- private static String validateFileName(String fileName, String targetDirectory) throws IOException {
127
- File file = new File(fileName);
128
- String canonicalPath = file.getCanonicalPath();
126
+ private static String validateFileName(String fileName, File destinationFolder) throws IOException {
127
+ String destinationFolderCanonicalPath = destinationFolder.getCanonicalPath() + File.separator;
129
128
 
130
- File targetFile = new File(targetDirectory);
131
- String targetCanonicalPath = targetFile.getCanonicalPath();
129
+ File file = new File(destinationFolderCanonicalPath, fileName);
130
+ String canonicalPath = file.getCanonicalPath();
132
131
 
133
- if (!canonicalPath.startsWith(targetCanonicalPath)) {
132
+ if (!canonicalPath.startsWith(destinationFolderCanonicalPath)) {
134
133
  throw new IllegalStateException("File is outside extraction target directory.");
135
134
  }
136
135
 
@@ -151,13 +150,13 @@ public class FileUtils {
151
150
  if (destinationFolder.exists()) {
152
151
  deleteFileOrFolderSilently(destinationFolder);
153
152
  }
154
-
153
+
155
154
  destinationFolder.mkdirs();
156
155
 
157
156
  byte[] buffer = new byte[WRITE_BUFFER_SIZE];
158
157
  while ((entry = zipStream.getNextEntry()) != null) {
159
- String fileName = validateFileName(entry.getName(), ".");
160
- File file = new File(destinationFolder, fileName);
158
+ String fileName = validateFileName(entry.getName(), destinationFolder);
159
+ File file = new File(fileName);
161
160
  if (entry.isDirectory()) {
162
161
  file.mkdirs();
163
162
  } else {