@capgo/capacitor-updater 8.0.1 → 8.1.0

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 (55) hide show
  1. package/CapgoCapacitorUpdater.podspec +7 -5
  2. package/Package.swift +9 -7
  3. package/README.md +984 -215
  4. package/android/build.gradle +24 -12
  5. package/android/proguard-rules.pro +22 -5
  6. package/android/src/main/java/ee/forgr/capacitor_updater/BundleInfo.java +110 -22
  7. package/android/src/main/java/ee/forgr/capacitor_updater/Callback.java +2 -2
  8. package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +1310 -488
  9. package/android/src/main/java/ee/forgr/capacitor_updater/{CapacitorUpdater.java → CapgoUpdater.java} +640 -203
  10. package/android/src/main/java/ee/forgr/capacitor_updater/{CryptoCipherV2.java → CryptoCipher.java} +119 -33
  11. package/android/src/main/java/ee/forgr/capacitor_updater/DelayCondition.java +0 -3
  12. package/android/src/main/java/ee/forgr/capacitor_updater/DelayUpdateUtils.java +260 -0
  13. package/android/src/main/java/ee/forgr/capacitor_updater/DeviceIdHelper.java +221 -0
  14. package/android/src/main/java/ee/forgr/capacitor_updater/DownloadService.java +497 -133
  15. package/android/src/main/java/ee/forgr/capacitor_updater/DownloadWorkerManager.java +80 -25
  16. package/android/src/main/java/ee/forgr/capacitor_updater/Logger.java +338 -0
  17. package/android/src/main/java/ee/forgr/capacitor_updater/ShakeDetector.java +72 -0
  18. package/android/src/main/java/ee/forgr/capacitor_updater/ShakeMenu.java +169 -0
  19. package/dist/docs.json +873 -154
  20. package/dist/esm/definitions.d.ts +881 -114
  21. package/dist/esm/definitions.js.map +1 -1
  22. package/dist/esm/history.d.ts +1 -0
  23. package/dist/esm/history.js +283 -0
  24. package/dist/esm/history.js.map +1 -0
  25. package/dist/esm/index.d.ts +1 -0
  26. package/dist/esm/index.js +1 -0
  27. package/dist/esm/index.js.map +1 -1
  28. package/dist/esm/web.d.ts +12 -1
  29. package/dist/esm/web.js +29 -2
  30. package/dist/esm/web.js.map +1 -1
  31. package/dist/plugin.cjs.js +311 -2
  32. package/dist/plugin.cjs.js.map +1 -1
  33. package/dist/plugin.js +311 -2
  34. package/dist/plugin.js.map +1 -1
  35. package/ios/Sources/CapacitorUpdaterPlugin/AES.swift +69 -0
  36. package/ios/Sources/CapacitorUpdaterPlugin/BigInt.swift +55 -0
  37. package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/BundleInfo.swift +37 -10
  38. package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/BundleStatus.swift +1 -1
  39. package/ios/Sources/CapacitorUpdaterPlugin/CapacitorUpdaterPlugin.swift +1605 -0
  40. package/ios/{Plugin/CapacitorUpdater.swift → Sources/CapacitorUpdaterPlugin/CapgoUpdater.swift} +523 -230
  41. package/ios/Sources/CapacitorUpdaterPlugin/CryptoCipher.swift +267 -0
  42. package/ios/Sources/CapacitorUpdaterPlugin/DelayUpdateUtils.swift +220 -0
  43. package/ios/Sources/CapacitorUpdaterPlugin/DeviceIdHelper.swift +120 -0
  44. package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/InternalUtils.swift +53 -0
  45. package/ios/Sources/CapacitorUpdaterPlugin/Logger.swift +310 -0
  46. package/ios/Sources/CapacitorUpdaterPlugin/RSA.swift +274 -0
  47. package/ios/Sources/CapacitorUpdaterPlugin/ShakeMenu.swift +112 -0
  48. package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/UserDefaultsExtension.swift +0 -2
  49. package/package.json +21 -19
  50. package/ios/Plugin/CapacitorUpdaterPlugin.swift +0 -975
  51. package/ios/Plugin/CryptoCipherV2.swift +0 -310
  52. /package/{LICENCE → LICENSE} +0 -0
  53. /package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/DelayCondition.swift +0 -0
  54. /package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/DelayUntilNext.swift +0 -0
  55. /package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/Info.plist +0 -0
@@ -1,8 +1,8 @@
1
1
  ext {
2
2
  junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
3
- androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.0'
4
- androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.2.1'
5
- androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.6.1'
3
+ androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.1'
4
+ androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.3.0'
5
+ androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.7.0'
6
6
  }
7
7
 
8
8
  buildscript {
@@ -11,18 +11,18 @@ buildscript {
11
11
  mavenCentral()
12
12
  }
13
13
  dependencies {
14
- classpath 'com.android.tools.build:gradle:8.7.2'
14
+ classpath 'com.android.tools.build:gradle:8.13.0'
15
15
  }
16
16
  }
17
17
 
18
18
  apply plugin: 'com.android.library'
19
19
 
20
20
  android {
21
- namespace "ee.forgr.capacitor_updater"
22
- compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 35
21
+ namespace = "ee.forgr.capacitor_updater"
22
+ compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 36
23
23
  defaultConfig {
24
- minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 23
25
- targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 35
24
+ minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 24
25
+ targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 36
26
26
  versionCode 1
27
27
  versionName "1.0"
28
28
  testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -49,18 +49,30 @@ repositories {
49
49
 
50
50
 
51
51
  dependencies {
52
- def work_version = "2.10.0"
52
+ def work_version = "2.10.5"
53
53
  implementation "androidx.work:work-runtime:$work_version"
54
- implementation "com.google.android.gms:play-services-tasks:18.2.0"
55
- implementation "com.google.guava:guava:32.1.3-jre"
54
+ implementation "com.google.android.gms:play-services-tasks:18.4.0"
55
+ implementation "com.google.guava:guava:33.5.0-android"
56
56
  implementation fileTree(dir: 'libs', include: ['*.jar'])
57
57
  implementation project(':capacitor-android')
58
58
  implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
59
59
  implementation 'io.github.g00fy2:versioncompare:1.5.0'
60
- implementation 'com.google.code.gson:gson:2.11.0'
61
60
  testImplementation "junit:junit:$junitVersion"
61
+ testImplementation 'org.mockito:mockito-core:5.20.0'
62
+ testImplementation 'org.json:json:20250517'
63
+ testImplementation 'org.robolectric:robolectric:4.13'
62
64
  androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
63
65
  androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
64
66
  implementation 'org.brotli:dec:0.1.2'
65
67
  implementation 'com.squareup.okhttp3:okhttp:4.12.0'
66
68
  }
69
+
70
+ tasks.withType(Test) {
71
+ testLogging {
72
+ events "passed", "skipped", "failed", "standardOut", "standardError"
73
+ exceptionFormat "full"
74
+ showStandardStreams = true
75
+ showCauses = true
76
+ showStackTraces = true
77
+ }
78
+ }
@@ -20,9 +20,26 @@
20
20
  # hide the original source file name.
21
21
  #-renamesourcefileattribute SourceFile
22
22
 
23
- # Necessary for Gson Deserialization
24
- -keepattributes *Annotation*
23
+ # Preserve annotation and signature metadata used by runtime checks
24
+ -keepattributes *Annotation*, Signature
25
25
 
26
- # Necessary for Gson Deserialization
27
- -keep class ee.forgr.capacitor_updater.DelayCondition { *; }
28
- -keepattributes Signature
26
+ # Preserve the entire Capgo plugin package
27
+ -keep class ee.forgr.capacitor_updater.** { *; }
28
+
29
+ # Preserve Capacitor classes and members accessed via reflection for autoSplashscreen
30
+ # These rules are safe even if SplashScreen plugin is not present - they only reference core Capacitor classes
31
+ -keep class com.getcapacitor.Bridge {
32
+ com.getcapacitor.MessageHandler msgHandler;
33
+ }
34
+
35
+ -keep class com.getcapacitor.MessageHandler { *; }
36
+
37
+ -keep class com.getcapacitor.PluginCall {
38
+ <init>(com.getcapacitor.MessageHandler, java.lang.String, java.lang.String, java.lang.String, com.getcapacitor.JSObject);
39
+ }
40
+
41
+ # Keep SplashScreen plugin methods that are called via reflection
42
+ # This applies to any plugin, not just SplashScreen
43
+ -keep class * implements com.getcapacitor.PluginHandle {
44
+ public void invoke(java.lang.String, com.getcapacitor.PluginCall);
45
+ }
@@ -6,9 +6,10 @@
6
6
 
7
7
  package ee.forgr.capacitor_updater;
8
8
 
9
- import com.getcapacitor.JSObject;
10
9
  import java.text.SimpleDateFormat;
11
10
  import java.util.Date;
11
+ import java.util.HashMap;
12
+ import java.util.Map;
12
13
  import java.util.Objects;
13
14
  import java.util.TimeZone;
14
15
  import org.json.JSONException;
@@ -28,25 +29,53 @@ public class BundleInfo {
28
29
  private final String version;
29
30
  private final String checksum;
30
31
  private final BundleStatus status;
32
+ private final String link;
33
+ private final String comment;
31
34
 
32
35
  static {
33
36
  sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
34
37
  }
35
38
 
36
39
  public BundleInfo(final BundleInfo source) {
37
- this(source.id, source.version, source.status, source.downloaded, source.checksum);
40
+ this(source.id, source.version, source.status, source.downloaded, source.checksum, source.link, source.comment);
38
41
  }
39
42
 
40
43
  public BundleInfo(final String id, final String version, final BundleStatus status, final Date downloaded, final String checksum) {
41
- this(id, version, status, sdf.format(downloaded), checksum);
44
+ this(id, version, status, sdf.format(downloaded), checksum, null, null);
45
+ }
46
+
47
+ public BundleInfo(
48
+ final String id,
49
+ final String version,
50
+ final BundleStatus status,
51
+ final Date downloaded,
52
+ final String checksum,
53
+ final String link,
54
+ final String comment
55
+ ) {
56
+ this(id, version, status, sdf.format(downloaded), checksum, link, comment);
42
57
  }
43
58
 
44
59
  public BundleInfo(final String id, final String version, final BundleStatus status, final String downloaded, final String checksum) {
45
- this.downloaded = downloaded.trim();
46
- this.id = id;
60
+ this(id, version, status, downloaded, checksum, null, null);
61
+ }
62
+
63
+ public BundleInfo(
64
+ final String id,
65
+ final String version,
66
+ final BundleStatus status,
67
+ final String downloaded,
68
+ final String checksum,
69
+ final String link,
70
+ final String comment
71
+ ) {
72
+ this.downloaded = downloaded != null ? downloaded.trim() : "";
73
+ this.id = id != null ? id : "";
47
74
  this.version = version;
48
- this.checksum = checksum;
49
- this.status = status;
75
+ this.checksum = checksum != null ? checksum : "";
76
+ this.status = status != null ? status : BundleStatus.ERROR;
77
+ this.link = link;
78
+ this.comment = comment;
50
79
  }
51
80
 
52
81
  public Boolean isBuiltin() {
@@ -70,19 +99,19 @@ public class BundleInfo {
70
99
  }
71
100
 
72
101
  public String getDownloaded() {
73
- return this.isBuiltin() ? DOWNLOADED_BUILTIN : this.downloaded;
102
+ return this.isBuiltin() ? DOWNLOADED_BUILTIN : (this.downloaded != null ? this.downloaded : "");
74
103
  }
75
104
 
76
105
  public BundleInfo setDownloaded(Date downloaded) {
77
- return new BundleInfo(this.id, this.version, this.status, downloaded, this.checksum);
106
+ return new BundleInfo(this.id, this.version, this.status, downloaded, this.checksum, this.link, this.comment);
78
107
  }
79
108
 
80
109
  public String getChecksum() {
81
- return this.isBuiltin() ? "" : this.checksum;
110
+ return this.isBuiltin() ? "" : (this.checksum != null ? this.checksum : "");
82
111
  }
83
112
 
84
113
  public BundleInfo setChecksum(String checksum) {
85
- return new BundleInfo(this.id, this.version, this.status, this.downloaded, checksum);
114
+ return new BundleInfo(this.id, this.version, this.status, this.downloaded, checksum, this.link, this.comment);
86
115
  }
87
116
 
88
117
  public String getId() {
@@ -90,7 +119,7 @@ public class BundleInfo {
90
119
  }
91
120
 
92
121
  public BundleInfo setId(String id) {
93
- return new BundleInfo(id, this.version, this.status, this.downloaded, this.checksum);
122
+ return new BundleInfo(id, this.version, this.status, this.downloaded, this.checksum, this.link, this.comment);
94
123
  }
95
124
 
96
125
  public String getVersionName() {
@@ -98,19 +127,34 @@ public class BundleInfo {
98
127
  }
99
128
 
100
129
  public BundleInfo setVersionName(String version) {
101
- return new BundleInfo(this.id, version, this.status, this.downloaded, this.checksum);
130
+ return new BundleInfo(this.id, version, this.status, this.downloaded, this.checksum, this.link, this.comment);
102
131
  }
103
132
 
104
133
  public BundleStatus getStatus() {
105
- return this.isBuiltin() ? BundleStatus.SUCCESS : this.status;
134
+ if (this.isBuiltin()) {
135
+ return BundleStatus.SUCCESS;
136
+ }
137
+ return this.status != null ? this.status : BundleStatus.ERROR;
106
138
  }
107
139
 
108
140
  public BundleInfo setStatus(BundleStatus status) {
109
- return new BundleInfo(this.id, this.version, status, this.downloaded, this.checksum);
141
+ return new BundleInfo(this.id, this.version, status, this.downloaded, this.checksum, this.link, this.comment);
142
+ }
143
+
144
+ public String getLink() {
145
+ return this.link;
146
+ }
147
+
148
+ public BundleInfo setLink(String link) {
149
+ return new BundleInfo(this.id, this.version, this.status, this.downloaded, this.checksum, link, this.comment);
150
+ }
151
+
152
+ public String getComment() {
153
+ return this.comment;
110
154
  }
111
155
 
112
- public static BundleInfo fromJSON(final JSObject json) throws JSONException {
113
- return BundleInfo.fromJSON(json.toString());
156
+ public BundleInfo setComment(String comment) {
157
+ return new BundleInfo(this.id, this.version, this.status, this.downloaded, this.checksum, this.link, comment);
114
158
  }
115
159
 
116
160
  public static BundleInfo fromJSON(final String jsonString) throws JSONException {
@@ -120,17 +164,25 @@ public class BundleInfo {
120
164
  json.has("version") ? json.getString("version") : BundleInfo.VERSION_UNKNOWN,
121
165
  json.has("status") ? BundleStatus.fromString(json.getString("status")) : BundleStatus.PENDING,
122
166
  json.has("downloaded") ? json.getString("downloaded") : "",
123
- json.has("checksum") ? json.getString("checksum") : ""
167
+ json.has("checksum") ? json.getString("checksum") : "",
168
+ json.has("link") ? json.getString("link") : null,
169
+ json.has("comment") ? json.getString("comment") : null
124
170
  );
125
171
  }
126
172
 
127
- public JSObject toJSON() {
128
- final JSObject result = new JSObject();
173
+ public Map<String, Object> toJSONMap() {
174
+ final Map<String, Object> result = new HashMap<>();
129
175
  result.put("id", this.getId());
130
176
  result.put("version", this.getVersionName());
131
177
  result.put("downloaded", this.getDownloaded());
132
178
  result.put("checksum", this.getChecksum());
133
- result.put("status", this.getStatus());
179
+ result.put("status", this.getStatus().toString());
180
+ if (this.link != null && !this.link.isEmpty()) {
181
+ result.put("link", this.link);
182
+ }
183
+ if (this.comment != null && !this.comment.isEmpty()) {
184
+ result.put("comment", this.comment);
185
+ }
134
186
  return result;
135
187
  }
136
188
 
@@ -149,6 +201,42 @@ public class BundleInfo {
149
201
 
150
202
  @Override
151
203
  public String toString() {
152
- return this.toJSON().toString();
204
+ try {
205
+ // Build JSON manually with extra safety checks
206
+ StringBuilder json = new StringBuilder();
207
+ json.append("{");
208
+
209
+ // Safe ID access
210
+ String safeId = this.id != null ? this.id : "";
211
+ if (this.isBuiltin()) safeId = ID_BUILTIN;
212
+ json.append("\"id\":\"").append(safeId).append("\",");
213
+
214
+ // Safe version access
215
+ String safeVersion = this.version != null ? this.version : ID_BUILTIN;
216
+ json.append("\"version\":\"").append(safeVersion).append("\",");
217
+
218
+ // Safe downloaded access
219
+ String safeDownloaded = this.downloaded != null ? this.downloaded : "";
220
+ if (this.isBuiltin()) safeDownloaded = DOWNLOADED_BUILTIN;
221
+ json.append("\"downloaded\":\"").append(safeDownloaded).append("\",");
222
+
223
+ // Safe checksum access
224
+ String safeChecksum = this.checksum != null ? this.checksum : "";
225
+ json.append("\"checksum\":\"").append(safeChecksum).append("\",");
226
+
227
+ // Safe status access
228
+ BundleStatus safeStatus = this.status != null ? this.status : BundleStatus.ERROR;
229
+ if (this.isBuiltin()) safeStatus = BundleStatus.SUCCESS;
230
+ json.append("\"status\":\"").append(safeStatus.toString()).append("\"");
231
+
232
+ json.append("}");
233
+ return json.toString();
234
+ } catch (Exception e) {
235
+ // Log the error for debugging but still return valid JSON
236
+ System.err.println("BundleInfo toString() error: " + e.getMessage());
237
+ e.printStackTrace();
238
+ // Return absolute minimal JSON
239
+ return "{\"id\":\"" + (this.id != null ? this.id : "unknown") + "\",\"status\":\"error\"}";
240
+ }
153
241
  }
154
242
  }
@@ -6,8 +6,8 @@
6
6
 
7
7
  package ee.forgr.capacitor_updater;
8
8
 
9
- import com.getcapacitor.JSObject;
9
+ import java.util.Map;
10
10
 
11
11
  public interface Callback {
12
- void callback(JSObject jsoObject);
12
+ void callback(Map<String, Object> result);
13
13
  }