@capgo/capacitor-updater 6.11.1 → 6.12.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.
- package/Package.swift +3 -3
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdater.java +9 -196
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +1 -1
- package/android/src/main/java/ee/forgr/capacitor_updater/CryptoCipher.java +85 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/CryptoCipherV2.java +147 -1
- package/android/src/main/java/ee/forgr/capacitor_updater/DownloadService.java +24 -4
- package/android/src/main/java/ee/forgr/capacitor_updater/DownloadWorkerManager.java +2 -0
- package/ios/Plugin/CapacitorUpdater.swift +124 -495
- package/ios/Plugin/CapacitorUpdaterPlugin.swift +106 -96
- package/ios/Plugin/CryptoCipher.swift +77 -0
- package/ios/Plugin/CryptoCipherV2.swift +95 -1
- package/ios/Plugin/InternalUtils.swift +258 -0
- package/package.json +2 -1
|
@@ -45,7 +45,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
45
45
|
CAPPluginMethod(name: "getNextBundle", returnType: CAPPluginReturnPromise)
|
|
46
46
|
]
|
|
47
47
|
public var implementation = CapacitorUpdater()
|
|
48
|
-
private let PLUGIN_VERSION: String = "6.
|
|
48
|
+
private let PLUGIN_VERSION: String = "6.12.0"
|
|
49
49
|
static let updateUrlDefault = "https://plugin.capgo.app/updates"
|
|
50
50
|
static let statsUrlDefault = "https://plugin.capgo.app/stats"
|
|
51
51
|
static let channelUrlDefault = "https://plugin.capgo.app/channel_self"
|
|
@@ -69,26 +69,26 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
69
69
|
|
|
70
70
|
override public func load() {
|
|
71
71
|
#if targetEnvironment(simulator)
|
|
72
|
-
print("\(
|
|
73
|
-
print("\(
|
|
72
|
+
print("\(CapacitorUpdater.TAG) ::::: SIMULATOR :::::")
|
|
73
|
+
print("\(CapacitorUpdater.TAG) Application directory: \(NSHomeDirectory())")
|
|
74
74
|
#endif
|
|
75
75
|
|
|
76
76
|
self.semaphoreUp()
|
|
77
77
|
self.implementation.deviceID = (UserDefaults.standard.string(forKey: "appUUID") ?? UUID().uuidString).lowercased()
|
|
78
78
|
UserDefaults.standard.set( self.implementation.deviceID, forKey: "appUUID")
|
|
79
79
|
UserDefaults.standard.synchronize()
|
|
80
|
-
print("\(
|
|
80
|
+
print("\(CapacitorUpdater.TAG) init for device \(self.implementation.deviceID)")
|
|
81
81
|
guard let versionName = getConfig().getString("version", Bundle.main.versionName) else {
|
|
82
|
-
print("\(
|
|
82
|
+
print("\(CapacitorUpdater.TAG) Cannot get version name")
|
|
83
83
|
// crash the app
|
|
84
84
|
fatalError("Cannot get version name")
|
|
85
85
|
}
|
|
86
86
|
do {
|
|
87
87
|
currentVersionNative = try Version(versionName)
|
|
88
88
|
} catch {
|
|
89
|
-
print("\(
|
|
89
|
+
print("\(CapacitorUpdater.TAG) Cannot parse versionName \(versionName)")
|
|
90
90
|
}
|
|
91
|
-
print("\(
|
|
91
|
+
print("\(CapacitorUpdater.TAG) version native \(self.currentVersionNative.description)")
|
|
92
92
|
implementation.versionBuild = getConfig().getString("version", Bundle.main.versionName)!
|
|
93
93
|
autoDeleteFailed = getConfig().getBoolean("autoDeleteFailed", true)
|
|
94
94
|
autoDeletePrevious = getConfig().getBoolean("autoDeletePrevious", true)
|
|
@@ -120,7 +120,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
120
120
|
if implementation.appId == "" {
|
|
121
121
|
fatalError("appId is missing in capacitor.config.json or plugin config, and cannot be retrieved from the native app, please add it globally or in the plugin config")
|
|
122
122
|
}
|
|
123
|
-
print("\(
|
|
123
|
+
print("\(CapacitorUpdater.TAG) appId \(implementation.appId)")
|
|
124
124
|
implementation.statsUrl = getConfig().getString("statsUrl", CapacitorUpdaterPlugin.statsUrlDefault)!
|
|
125
125
|
implementation.channelUrl = getConfig().getString("channelUrl", CapacitorUpdaterPlugin.channelUrlDefault)!
|
|
126
126
|
implementation.defaultChannel = getConfig().getString("defaultChannel", "")!
|
|
@@ -138,7 +138,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
138
138
|
// According to martin it is not possible to use serverBasePath on ios in a way that allows us to store the bundle once
|
|
139
139
|
|
|
140
140
|
if !self.initialLoad() {
|
|
141
|
-
print("\(
|
|
141
|
+
print("\(CapacitorUpdater.TAG) unable to force reload, the plugin might fallback to the builtin version")
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
let nc = NotificationCenter.default
|
|
@@ -161,18 +161,18 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
if !FileManager.default.fileExists(atPath: dest.path) {
|
|
164
|
-
print("\(
|
|
164
|
+
print("\(CapacitorUpdater.TAG) Initial load fail - file at path \(dest.path) doesn't exist. Defaulting to buildin!! \(id)")
|
|
165
165
|
dest = Bundle.main.resourceURL!.appendingPathComponent("public")
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
-
print("\(
|
|
168
|
+
print("\(CapacitorUpdater.TAG) Initial load \(id)")
|
|
169
169
|
// We don't use the viewcontroller here as it does not work during the initial load state
|
|
170
170
|
bridge.setServerBasePath(dest.path)
|
|
171
171
|
return true
|
|
172
172
|
}
|
|
173
173
|
|
|
174
174
|
private func semaphoreWait(waitTime: Int) {
|
|
175
|
-
print("\(
|
|
175
|
+
print("\(CapacitorUpdater.TAG) semaphoreWait \(waitTime)")
|
|
176
176
|
_ = semaphoreReady.wait(timeout: .now() + .milliseconds(waitTime))
|
|
177
177
|
}
|
|
178
178
|
|
|
@@ -191,16 +191,16 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
191
191
|
do {
|
|
192
192
|
LatestVersionNative = try Version(UserDefaults.standard.string(forKey: "LatestVersionNative") ?? "0.0.0")
|
|
193
193
|
} catch {
|
|
194
|
-
print("\(
|
|
194
|
+
print("\(CapacitorUpdater.TAG) Cannot get version native \(currentVersionNative)")
|
|
195
195
|
}
|
|
196
196
|
if LatestVersionNative != "0.0.0" && self.currentVersionNative.description != LatestVersionNative.description {
|
|
197
197
|
_ = self._reset(toLastSuccessful: false)
|
|
198
198
|
let res = implementation.list()
|
|
199
199
|
res.forEach { version in
|
|
200
|
-
print("\(
|
|
200
|
+
print("\(CapacitorUpdater.TAG) Deleting obsolete bundle: \(version.getId())")
|
|
201
201
|
let res = implementation.delete(id: version.getId())
|
|
202
202
|
if !res {
|
|
203
|
-
print("\(
|
|
203
|
+
print("\(CapacitorUpdater.TAG) Delete failed, id \(version.getId()) doesn't exist")
|
|
204
204
|
}
|
|
205
205
|
}
|
|
206
206
|
}
|
|
@@ -221,12 +221,12 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
221
221
|
|
|
222
222
|
@objc func setUpdateUrl(_ call: CAPPluginCall) {
|
|
223
223
|
if !getConfig().getBoolean("allowModifyUrl", false) {
|
|
224
|
-
print("\(
|
|
224
|
+
print("\(CapacitorUpdater.TAG) setUpdateUrl called without allowModifyUrl")
|
|
225
225
|
call.reject("setUpdateUrl called without allowModifyUrl set allowModifyUrl in your config to true to allow it")
|
|
226
226
|
return
|
|
227
227
|
}
|
|
228
228
|
guard let url = call.getString("url") else {
|
|
229
|
-
print("\(
|
|
229
|
+
print("\(CapacitorUpdater.TAG) setUpdateUrl called without url")
|
|
230
230
|
call.reject("setUpdateUrl called without url")
|
|
231
231
|
return
|
|
232
232
|
}
|
|
@@ -236,12 +236,12 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
236
236
|
|
|
237
237
|
@objc func setStatsUrl(_ call: CAPPluginCall) {
|
|
238
238
|
if !getConfig().getBoolean("allowModifyUrl", false) {
|
|
239
|
-
print("\(
|
|
239
|
+
print("\(CapacitorUpdater.TAG) setStatsUrl called without allowModifyUrl")
|
|
240
240
|
call.reject("setStatsUrl called without allowModifyUrl set allowModifyUrl in your config to true to allow it")
|
|
241
241
|
return
|
|
242
242
|
}
|
|
243
243
|
guard let url = call.getString("url") else {
|
|
244
|
-
print("\(
|
|
244
|
+
print("\(CapacitorUpdater.TAG) setStatsUrl called without url")
|
|
245
245
|
call.reject("setStatsUrl called without url")
|
|
246
246
|
return
|
|
247
247
|
}
|
|
@@ -251,12 +251,12 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
251
251
|
|
|
252
252
|
@objc func setChannelUrl(_ call: CAPPluginCall) {
|
|
253
253
|
if !getConfig().getBoolean("allowModifyUrl", false) {
|
|
254
|
-
print("\(
|
|
254
|
+
print("\(CapacitorUpdater.TAG) setChannelUrl called without allowModifyUrl")
|
|
255
255
|
call.reject("setChannelUrl called without allowModifyUrl set allowModifyUrl in your config to true to allow it")
|
|
256
256
|
return
|
|
257
257
|
}
|
|
258
258
|
guard let url = call.getString("url") else {
|
|
259
|
-
print("\(
|
|
259
|
+
print("\(CapacitorUpdater.TAG) setChannelUrl called without url")
|
|
260
260
|
call.reject("setChannelUrl called without url")
|
|
261
261
|
return
|
|
262
262
|
}
|
|
@@ -278,12 +278,12 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
278
278
|
|
|
279
279
|
@objc func download(_ call: CAPPluginCall) {
|
|
280
280
|
guard let urlString = call.getString("url") else {
|
|
281
|
-
print("\(
|
|
281
|
+
print("\(CapacitorUpdater.TAG) Download called without url")
|
|
282
282
|
call.reject("Download called without url")
|
|
283
283
|
return
|
|
284
284
|
}
|
|
285
285
|
guard let version = call.getString("version") else {
|
|
286
|
-
print("\(
|
|
286
|
+
print("\(CapacitorUpdater.TAG) Download called without version")
|
|
287
287
|
call.reject("Download called without version")
|
|
288
288
|
return
|
|
289
289
|
}
|
|
@@ -291,29 +291,34 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
291
291
|
let sessionKey = call.getString("sessionKey", "")
|
|
292
292
|
var checksum = call.getString("checksum", "")
|
|
293
293
|
let url = URL(string: urlString)
|
|
294
|
-
print("\(
|
|
294
|
+
print("\(CapacitorUpdater.TAG) Downloading \(String(describing: url))")
|
|
295
295
|
DispatchQueue.global(qos: .background).async {
|
|
296
296
|
do {
|
|
297
297
|
let next = try self.implementation.download(url: url!, version: version, sessionKey: sessionKey)
|
|
298
298
|
if !self.implementation.hasOldPrivateKeyPropertyInConfig {
|
|
299
|
-
|
|
299
|
+
do {
|
|
300
|
+
checksum = try CryptoCipherV2.decryptChecksum(checksum: checksum, publicKey: self.implementation.publicKey, version: version)
|
|
301
|
+
} catch {
|
|
302
|
+
self.implementation.sendStats(action: "decrypt_fail", versionName: version)
|
|
303
|
+
throw error
|
|
304
|
+
}
|
|
300
305
|
}
|
|
301
306
|
if (checksum != "" || self.implementation.publicKey != "") && next.getChecksum() != checksum {
|
|
302
|
-
print("\(
|
|
307
|
+
print("\(CapacitorUpdater.TAG) Error checksum", next.getChecksum(), checksum)
|
|
303
308
|
self.implementation.sendStats(action: "checksum_fail", versionName: next.getVersionName())
|
|
304
309
|
let id = next.getId()
|
|
305
310
|
let resDel = self.implementation.delete(id: id)
|
|
306
311
|
if !resDel {
|
|
307
|
-
print("\(
|
|
312
|
+
print("\(CapacitorUpdater.TAG) Delete failed, id \(id) doesn't exist")
|
|
308
313
|
}
|
|
309
314
|
throw ObjectSavableError.checksum
|
|
310
315
|
} else {
|
|
311
|
-
print("\(
|
|
316
|
+
print("\(CapacitorUpdater.TAG) Good checksum", next.getChecksum(), checksum)
|
|
312
317
|
}
|
|
313
318
|
self.notifyListeners("updateAvailable", data: ["bundle": next.toJSON()])
|
|
314
319
|
call.resolve(next.toJSON())
|
|
315
320
|
} catch {
|
|
316
|
-
print("\(
|
|
321
|
+
print("\(CapacitorUpdater.TAG) Failed to download from: \(String(describing: url)) \(error.localizedDescription)")
|
|
317
322
|
self.notifyListeners("downloadFailed", data: ["version": version])
|
|
318
323
|
self.implementation.sendStats(action: "download_fail")
|
|
319
324
|
call.reject("Failed to download from: \(url!)", error.localizedDescription)
|
|
@@ -331,16 +336,16 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
331
336
|
} else {
|
|
332
337
|
dest = self.implementation.getBundleDirectory(id: id)
|
|
333
338
|
}
|
|
334
|
-
print("\(
|
|
339
|
+
print("\(CapacitorUpdater.TAG) Reloading \(id)")
|
|
335
340
|
if let vc = bridge.viewController as? CAPBridgeViewController {
|
|
336
341
|
guard let capBridge = vc.bridge else {
|
|
337
|
-
print("\(
|
|
342
|
+
print("\(CapacitorUpdater.TAG) Cannot get capBridge")
|
|
338
343
|
return false
|
|
339
344
|
}
|
|
340
345
|
if keepUrlPathAfterReload {
|
|
341
346
|
DispatchQueue.main.async {
|
|
342
347
|
guard let url = vc.webView?.url else {
|
|
343
|
-
print("\(
|
|
348
|
+
print("\(CapacitorUpdater.TAG) vc.webView?.url is null?")
|
|
344
349
|
return
|
|
345
350
|
}
|
|
346
351
|
capBridge.setServerBasePath(dest.path)
|
|
@@ -367,20 +372,20 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
367
372
|
if self._reload() {
|
|
368
373
|
call.resolve()
|
|
369
374
|
} else {
|
|
370
|
-
print("\(
|
|
375
|
+
print("\(CapacitorUpdater.TAG) Reload failed")
|
|
371
376
|
call.reject("Reload failed")
|
|
372
377
|
}
|
|
373
378
|
}
|
|
374
379
|
|
|
375
380
|
@objc func next(_ call: CAPPluginCall) {
|
|
376
381
|
guard let id = call.getString("id") else {
|
|
377
|
-
print("\(
|
|
382
|
+
print("\(CapacitorUpdater.TAG) Next called without id")
|
|
378
383
|
call.reject("Next called without id")
|
|
379
384
|
return
|
|
380
385
|
}
|
|
381
|
-
print("\(
|
|
386
|
+
print("\(CapacitorUpdater.TAG) Setting next active id \(id)")
|
|
382
387
|
if !self.implementation.setNextBundle(next: id) {
|
|
383
|
-
print("\(
|
|
388
|
+
print("\(CapacitorUpdater.TAG) Set next version failed. id \(id) does not exist.")
|
|
384
389
|
call.reject("Set next version failed. id \(id) does not exist.")
|
|
385
390
|
} else {
|
|
386
391
|
call.resolve(self.implementation.getBundleInfo(id: id).toJSON())
|
|
@@ -389,14 +394,14 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
389
394
|
|
|
390
395
|
@objc func set(_ call: CAPPluginCall) {
|
|
391
396
|
guard let id = call.getString("id") else {
|
|
392
|
-
print("\(
|
|
397
|
+
print("\(CapacitorUpdater.TAG) Set called without id")
|
|
393
398
|
call.reject("Set called without id")
|
|
394
399
|
return
|
|
395
400
|
}
|
|
396
401
|
let res = implementation.set(id: id)
|
|
397
|
-
print("\(
|
|
402
|
+
print("\(CapacitorUpdater.TAG) Set active bundle: \(id)")
|
|
398
403
|
if !res {
|
|
399
|
-
print("\(
|
|
404
|
+
print("\(CapacitorUpdater.TAG) Bundle successfully set to: \(id) ")
|
|
400
405
|
call.reject("Update failed, id \(id) doesn't exist")
|
|
401
406
|
} else {
|
|
402
407
|
self.reload(call)
|
|
@@ -405,7 +410,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
405
410
|
|
|
406
411
|
@objc func delete(_ call: CAPPluginCall) {
|
|
407
412
|
guard let id = call.getString("id") else {
|
|
408
|
-
print("\(
|
|
413
|
+
print("\(CapacitorUpdater.TAG) Delete called without version")
|
|
409
414
|
call.reject("Delete called without id")
|
|
410
415
|
return
|
|
411
416
|
}
|
|
@@ -413,7 +418,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
413
418
|
if res {
|
|
414
419
|
call.resolve()
|
|
415
420
|
} else {
|
|
416
|
-
print("\(
|
|
421
|
+
print("\(CapacitorUpdater.TAG) Delete failed, id \(id) doesn't exist or it cannot be deleted (perhaps it is the 'next' bundle)")
|
|
417
422
|
call.reject("Delete failed, id \(id) does not exist or it cannot be deleted (perhaps it is the 'next' bundle)")
|
|
418
423
|
}
|
|
419
424
|
}
|
|
@@ -451,7 +456,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
451
456
|
call.reject(res.error)
|
|
452
457
|
} else {
|
|
453
458
|
if self._isAutoUpdateEnabled() && triggerAutoUpdate {
|
|
454
|
-
print("\(
|
|
459
|
+
print("\(CapacitorUpdater.TAG) Calling autoupdater after channel change!")
|
|
455
460
|
self.backgroundDownload()
|
|
456
461
|
}
|
|
457
462
|
call.resolve(res.toDict())
|
|
@@ -461,7 +466,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
461
466
|
|
|
462
467
|
@objc func setChannel(_ call: CAPPluginCall) {
|
|
463
468
|
guard let channel = call.getString("channel") else {
|
|
464
|
-
print("\(
|
|
469
|
+
print("\(CapacitorUpdater.TAG) setChannel called without channel")
|
|
465
470
|
call.reject("setChannel called without channel")
|
|
466
471
|
return
|
|
467
472
|
}
|
|
@@ -472,7 +477,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
472
477
|
call.reject(res.error)
|
|
473
478
|
} else {
|
|
474
479
|
if self._isAutoUpdateEnabled() && triggerAutoUpdate {
|
|
475
|
-
print("\(
|
|
480
|
+
print("\(CapacitorUpdater.TAG) Calling autoupdater after channel change!")
|
|
476
481
|
self.backgroundDownload()
|
|
477
482
|
}
|
|
478
483
|
call.resolve(res.toDict())
|
|
@@ -492,7 +497,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
492
497
|
}
|
|
493
498
|
@objc func setCustomId(_ call: CAPPluginCall) {
|
|
494
499
|
guard let customId = call.getString("customId") else {
|
|
495
|
-
print("\(
|
|
500
|
+
print("\(CapacitorUpdater.TAG) setCustomId called without customId")
|
|
496
501
|
call.reject("setCustomId called without customId")
|
|
497
502
|
return
|
|
498
503
|
}
|
|
@@ -508,11 +513,11 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
508
513
|
// If developer wants to reset to the last successful bundle, and that bundle is not
|
|
509
514
|
// the built-in bundle, set it as the bundle to use and reload.
|
|
510
515
|
if toLastSuccessful && !fallback.isBuiltin() {
|
|
511
|
-
print("\(
|
|
516
|
+
print("\(CapacitorUpdater.TAG) Resetting to: \(fallback.toString())")
|
|
512
517
|
return self.implementation.set(bundle: fallback) && self._reload()
|
|
513
518
|
}
|
|
514
519
|
|
|
515
|
-
print("\(
|
|
520
|
+
print("\(CapacitorUpdater.TAG) Resetting to builtin version")
|
|
516
521
|
|
|
517
522
|
// Otherwise, reset back to the built-in bundle and reload.
|
|
518
523
|
self.implementation.reset()
|
|
@@ -527,8 +532,8 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
527
532
|
if self._reset(toLastSuccessful: toLastSuccessful) {
|
|
528
533
|
call.resolve()
|
|
529
534
|
} else {
|
|
530
|
-
print("\(
|
|
531
|
-
call.reject("\(
|
|
535
|
+
print("\(CapacitorUpdater.TAG) Reset failed")
|
|
536
|
+
call.reject("\(CapacitorUpdater.TAG) Reset failed")
|
|
532
537
|
}
|
|
533
538
|
}
|
|
534
539
|
|
|
@@ -544,13 +549,13 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
544
549
|
self.semaphoreDown()
|
|
545
550
|
let bundle = self.implementation.getCurrentBundle()
|
|
546
551
|
self.implementation.setSuccess(bundle: bundle, autoDeletePrevious: self.autoDeletePrevious)
|
|
547
|
-
print("\(
|
|
552
|
+
print("\(CapacitorUpdater.TAG) Current bundle loaded successfully. ['notifyAppReady()' was called] \(bundle.toString())")
|
|
548
553
|
call.resolve(["bundle": bundle.toJSON()])
|
|
549
554
|
}
|
|
550
555
|
|
|
551
556
|
@objc func setMultiDelay(_ call: CAPPluginCall) {
|
|
552
557
|
guard let delayConditionList = call.getValue("delayConditions") else {
|
|
553
|
-
print("\(
|
|
558
|
+
print("\(CapacitorUpdater.TAG) setMultiDelay called without delayCondition")
|
|
554
559
|
call.reject("setMultiDelay called without delayCondition")
|
|
555
560
|
return
|
|
556
561
|
}
|
|
@@ -566,16 +571,16 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
566
571
|
if delayConditions != nil && "" != delayConditions {
|
|
567
572
|
UserDefaults.standard.set(delayConditions, forKey: DELAY_CONDITION_PREFERENCES)
|
|
568
573
|
UserDefaults.standard.synchronize()
|
|
569
|
-
print("\(
|
|
574
|
+
print("\(CapacitorUpdater.TAG) Delay update saved.")
|
|
570
575
|
return true
|
|
571
576
|
} else {
|
|
572
|
-
print("\(
|
|
577
|
+
print("\(CapacitorUpdater.TAG) Failed to delay update, [Error calling '_setMultiDelay()']")
|
|
573
578
|
return false
|
|
574
579
|
}
|
|
575
580
|
}
|
|
576
581
|
|
|
577
582
|
private func _cancelDelay(source: String) {
|
|
578
|
-
print("\(
|
|
583
|
+
print("\(CapacitorUpdater.TAG) delay Canceled from \(source)")
|
|
579
584
|
UserDefaults.standard.removeObject(forKey: DELAY_CONDITION_PREFERENCES)
|
|
580
585
|
UserDefaults.standard.synchronize()
|
|
581
586
|
}
|
|
@@ -635,9 +640,9 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
635
640
|
self._cancelDelay(source: "delayVal absent")
|
|
636
641
|
}
|
|
637
642
|
case .none:
|
|
638
|
-
print("\(
|
|
643
|
+
print("\(CapacitorUpdater.TAG) _checkCancelDelay switch case none error")
|
|
639
644
|
case .some:
|
|
640
|
-
print("\(
|
|
645
|
+
print("\(CapacitorUpdater.TAG) _checkCancelDelay switch case some error")
|
|
641
646
|
}
|
|
642
647
|
}
|
|
643
648
|
}
|
|
@@ -647,7 +652,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
647
652
|
private func _isAutoUpdateEnabled() -> Bool {
|
|
648
653
|
let instanceDescriptor = (self.bridge?.viewController as? CAPBridgeViewController)?.instanceDescriptor()
|
|
649
654
|
if instanceDescriptor?.serverURL != nil {
|
|
650
|
-
print("⚠️ \(
|
|
655
|
+
print("⚠️ \(CapacitorUpdater.TAG) AutoUpdate is automatic disabled when serverUrl is set.")
|
|
651
656
|
}
|
|
652
657
|
return self.autoUpdate && self.updateUrl != "" && instanceDescriptor?.serverURL == nil
|
|
653
658
|
}
|
|
@@ -671,7 +676,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
671
676
|
self.appReadyCheck = DispatchWorkItem(block: {
|
|
672
677
|
self.DeferredNotifyAppReadyCheck()
|
|
673
678
|
})
|
|
674
|
-
print("\(
|
|
679
|
+
print("\(CapacitorUpdater.TAG) Wait for \(self.appReadyTimeout) ms, then check for notifyAppReady")
|
|
675
680
|
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(self.appReadyTimeout), execute: self.appReadyCheck!)
|
|
676
681
|
}
|
|
677
682
|
|
|
@@ -679,15 +684,15 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
679
684
|
// Automatically roll back to fallback version if notifyAppReady has not been called yet
|
|
680
685
|
let current: BundleInfo = self.implementation.getCurrentBundle()
|
|
681
686
|
if current.isBuiltin() {
|
|
682
|
-
print("\(
|
|
687
|
+
print("\(CapacitorUpdater.TAG) Built-in bundle is active. We skip the check for notifyAppReady.")
|
|
683
688
|
return
|
|
684
689
|
}
|
|
685
690
|
|
|
686
|
-
print("\(
|
|
691
|
+
print("\(CapacitorUpdater.TAG) Current bundle is: \(current.toString())")
|
|
687
692
|
|
|
688
693
|
if BundleStatus.SUCCESS.localizedString != current.getStatus() {
|
|
689
|
-
print("\(
|
|
690
|
-
print("\(
|
|
694
|
+
print("\(CapacitorUpdater.TAG) notifyAppReady was not called, roll back current bundle: \(current.toString())")
|
|
695
|
+
print("\(CapacitorUpdater.TAG) Did you forget to call 'notifyAppReady()' in your Capacitor App code?")
|
|
691
696
|
self.notifyListeners("updateFailed", data: [
|
|
692
697
|
"bundle": current.toJSON()
|
|
693
698
|
])
|
|
@@ -695,16 +700,16 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
695
700
|
self.implementation.setError(bundle: current)
|
|
696
701
|
_ = self._reset(toLastSuccessful: true)
|
|
697
702
|
if self.autoDeleteFailed && !current.isBuiltin() {
|
|
698
|
-
print("\(
|
|
703
|
+
print("\(CapacitorUpdater.TAG) Deleting failing bundle: \(current.toString())")
|
|
699
704
|
let res = self.implementation.delete(id: current.getId(), removeInfo: false)
|
|
700
705
|
if !res {
|
|
701
|
-
print("\(
|
|
706
|
+
print("\(CapacitorUpdater.TAG) Delete version deleted: \(current.toString())")
|
|
702
707
|
} else {
|
|
703
|
-
print("\(
|
|
708
|
+
print("\(CapacitorUpdater.TAG) Failed to delete failed bundle: \(current.toString())")
|
|
704
709
|
}
|
|
705
710
|
}
|
|
706
711
|
} else {
|
|
707
|
-
print("\(
|
|
712
|
+
print("\(CapacitorUpdater.TAG) notifyAppReady was called. This is fine: \(current.toString())")
|
|
708
713
|
}
|
|
709
714
|
}
|
|
710
715
|
|
|
@@ -719,7 +724,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
719
724
|
}
|
|
720
725
|
|
|
721
726
|
func sendReadyToJs(current: BundleInfo, msg: String) {
|
|
722
|
-
print("\(
|
|
727
|
+
print("\(CapacitorUpdater.TAG) sendReadyToJs")
|
|
723
728
|
DispatchQueue.global().async {
|
|
724
729
|
self.semaphoreWait(waitTime: self.appReadyTimeout)
|
|
725
730
|
self.notifyListeners("appReady", data: ["bundle": current.toJSON(), "status": msg])
|
|
@@ -733,14 +738,14 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
733
738
|
}
|
|
734
739
|
self.notifyListeners("noNeedUpdate", data: ["bundle": current.toJSON()])
|
|
735
740
|
self.sendReadyToJs(current: current, msg: msg)
|
|
736
|
-
print("\(
|
|
741
|
+
print("\(CapacitorUpdater.TAG) endBackGroundTaskWithNotif \(msg) current: \(current.getVersionName()) latestVersionName: \(latestVersionName)")
|
|
737
742
|
self.endBackGroundTask()
|
|
738
743
|
}
|
|
739
744
|
|
|
740
745
|
func backgroundDownload() {
|
|
741
746
|
let messageUpdate = self.directUpdate ? "Update will occur now." : "Update will occur next time app moves to background."
|
|
742
747
|
guard let url = URL(string: self.updateUrl) else {
|
|
743
|
-
print("\(
|
|
748
|
+
print("\(CapacitorUpdater.TAG) Error no url or wrong format")
|
|
744
749
|
return
|
|
745
750
|
}
|
|
746
751
|
DispatchQueue.global(qos: .background).async {
|
|
@@ -748,12 +753,12 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
748
753
|
// End the task if time expires.
|
|
749
754
|
self.endBackGroundTask()
|
|
750
755
|
}
|
|
751
|
-
print("\(
|
|
756
|
+
print("\(CapacitorUpdater.TAG) Check for update via \(self.updateUrl)")
|
|
752
757
|
let res = self.implementation.getLatest(url: url, channel: nil)
|
|
753
758
|
let current = self.implementation.getCurrentBundle()
|
|
754
759
|
|
|
755
760
|
if (res.message) != nil {
|
|
756
|
-
print("\(
|
|
761
|
+
print("\(CapacitorUpdater.TAG) API message: \(res.message ?? "")")
|
|
757
762
|
if res.major == true {
|
|
758
763
|
self.notifyListeners("majorAvailable", data: ["version": res.version])
|
|
759
764
|
}
|
|
@@ -761,13 +766,13 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
761
766
|
return
|
|
762
767
|
}
|
|
763
768
|
if res.version == "builtin" {
|
|
764
|
-
print("\(
|
|
769
|
+
print("\(CapacitorUpdater.TAG) Latest version is builtin")
|
|
765
770
|
if self.directUpdate {
|
|
766
|
-
print("\(
|
|
771
|
+
print("\(CapacitorUpdater.TAG) Direct update to builtin version")
|
|
767
772
|
_ = self._reset(toLastSuccessful: false)
|
|
768
773
|
self.endBackGroundTaskWithNotif(msg: "Updated to builtin version", latestVersionName: res.version, current: self.implementation.getCurrentBundle(), error: false)
|
|
769
774
|
} else {
|
|
770
|
-
print("\(
|
|
775
|
+
print("\(CapacitorUpdater.TAG) Setting next bundle to builtin")
|
|
771
776
|
_ = self.implementation.setNextBundle(next: BundleInfo.ID_BUILTIN)
|
|
772
777
|
self.endBackGroundTaskWithNotif(msg: "Next update will be to builtin version", latestVersionName: res.version, current: current, error: false)
|
|
773
778
|
}
|
|
@@ -775,23 +780,23 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
775
780
|
}
|
|
776
781
|
let sessionKey = res.sessionKey ?? ""
|
|
777
782
|
guard let downloadUrl = URL(string: res.url) else {
|
|
778
|
-
print("\(
|
|
783
|
+
print("\(CapacitorUpdater.TAG) Error no url or wrong format")
|
|
779
784
|
self.endBackGroundTaskWithNotif(msg: "Error no url or wrong format", latestVersionName: res.version, current: current)
|
|
780
785
|
return
|
|
781
786
|
}
|
|
782
787
|
let latestVersionName = res.version
|
|
783
788
|
if latestVersionName != "" && current.getVersionName() != latestVersionName {
|
|
784
789
|
do {
|
|
785
|
-
print("\(
|
|
790
|
+
print("\(CapacitorUpdater.TAG) New bundle: \(latestVersionName) found. Current is: \(current.getVersionName()). \(messageUpdate)")
|
|
786
791
|
var nextImpl = self.implementation.getBundleInfoByVersionName(version: latestVersionName)
|
|
787
792
|
if nextImpl == nil || nextImpl?.isDeleted() == true {
|
|
788
793
|
if nextImpl?.isDeleted() == true {
|
|
789
|
-
print("\(
|
|
794
|
+
print("\(CapacitorUpdater.TAG) Latest bundle already exists and will be deleted, download will overwrite it.")
|
|
790
795
|
let res = self.implementation.delete(id: nextImpl!.getId(), removeInfo: true)
|
|
791
796
|
if res {
|
|
792
|
-
print("\(
|
|
797
|
+
print("\(CapacitorUpdater.TAG) Failed bundle deleted: \(nextImpl!.toString())")
|
|
793
798
|
} else {
|
|
794
|
-
print("\(
|
|
799
|
+
print("\(CapacitorUpdater.TAG) Failed to delete failed bundle: \(nextImpl!.toString())")
|
|
795
800
|
}
|
|
796
801
|
}
|
|
797
802
|
if res.manifest != nil {
|
|
@@ -801,25 +806,30 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
801
806
|
}
|
|
802
807
|
}
|
|
803
808
|
guard let next = nextImpl else {
|
|
804
|
-
print("\(
|
|
809
|
+
print("\(CapacitorUpdater.TAG) Error downloading file")
|
|
805
810
|
self.endBackGroundTaskWithNotif(msg: "Error downloading file", latestVersionName: latestVersionName, current: current)
|
|
806
811
|
return
|
|
807
812
|
}
|
|
808
813
|
if next.isErrorStatus() {
|
|
809
|
-
print("\(
|
|
814
|
+
print("\(CapacitorUpdater.TAG) Latest bundle already exists and is in error state. Aborting update.")
|
|
810
815
|
self.endBackGroundTaskWithNotif(msg: "Latest version is in error state. Aborting update.", latestVersionName: latestVersionName, current: current)
|
|
811
816
|
return
|
|
812
817
|
}
|
|
813
818
|
if !self.implementation.hasOldPrivateKeyPropertyInConfig {
|
|
814
|
-
|
|
819
|
+
do {
|
|
820
|
+
res.checksum = try CryptoCipherV2.decryptChecksum(checksum: res.checksum, publicKey: self.implementation.publicKey, version: latestVersionName)
|
|
821
|
+
} catch {
|
|
822
|
+
self.implementation.sendStats(action: "decrypt_fail", versionName: latestVersionName)
|
|
823
|
+
throw error
|
|
824
|
+
}
|
|
815
825
|
}
|
|
816
826
|
if res.checksum != "" && next.getChecksum() != res.checksum && res.manifest == nil {
|
|
817
|
-
print("\(
|
|
827
|
+
print("\(CapacitorUpdater.TAG) Error checksum", next.getChecksum(), res.checksum)
|
|
818
828
|
self.implementation.sendStats(action: "checksum_fail", versionName: next.getVersionName())
|
|
819
829
|
let id = next.getId()
|
|
820
830
|
let resDel = self.implementation.delete(id: id)
|
|
821
831
|
if !resDel {
|
|
822
|
-
print("\(
|
|
832
|
+
print("\(CapacitorUpdater.TAG) Delete failed, id \(id) doesn't exist")
|
|
823
833
|
}
|
|
824
834
|
self.endBackGroundTaskWithNotif(msg: "Error checksum", latestVersionName: latestVersionName, current: current)
|
|
825
835
|
return
|
|
@@ -836,13 +846,13 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
836
846
|
}
|
|
837
847
|
return
|
|
838
848
|
} catch {
|
|
839
|
-
print("\(
|
|
849
|
+
print("\(CapacitorUpdater.TAG) Error downloading file", error.localizedDescription)
|
|
840
850
|
let current: BundleInfo = self.implementation.getCurrentBundle()
|
|
841
851
|
self.endBackGroundTaskWithNotif(msg: "Error downloading file", latestVersionName: latestVersionName, current: current)
|
|
842
852
|
return
|
|
843
853
|
}
|
|
844
854
|
} else {
|
|
845
|
-
print("\(
|
|
855
|
+
print("\(CapacitorUpdater.TAG) No need to update, \(current.getId()) is the latest bundle.")
|
|
846
856
|
self.endBackGroundTaskWithNotif(msg: "No need to update, \(current.getId()) is the latest bundle.", latestVersionName: latestVersionName, current: current, error: false)
|
|
847
857
|
return
|
|
848
858
|
}
|
|
@@ -850,7 +860,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
850
860
|
}
|
|
851
861
|
|
|
852
862
|
@objc func appKilled() {
|
|
853
|
-
print("\(
|
|
863
|
+
print("\(CapacitorUpdater.TAG) onActivityDestroyed: all activity destroyed")
|
|
854
864
|
self._checkCancelDelay(killed: true)
|
|
855
865
|
}
|
|
856
866
|
|
|
@@ -862,19 +872,19 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
862
872
|
return DelayCondition(kind: kind, value: value)
|
|
863
873
|
}
|
|
864
874
|
if delayConditionList != nil && delayConditionList?.capacity != 0 {
|
|
865
|
-
print("\(
|
|
875
|
+
print("\(CapacitorUpdater.TAG) Update delayed until delay conditions met")
|
|
866
876
|
return
|
|
867
877
|
}
|
|
868
878
|
let current: BundleInfo = self.implementation.getCurrentBundle()
|
|
869
879
|
let next: BundleInfo? = self.implementation.getNextBundle()
|
|
870
880
|
|
|
871
881
|
if next != nil && !next!.isErrorStatus() && next!.getVersionName() != current.getVersionName() {
|
|
872
|
-
print("\(
|
|
882
|
+
print("\(CapacitorUpdater.TAG) Next bundle is: \(next!.toString())")
|
|
873
883
|
if self.implementation.set(bundle: next!) && self._reload() {
|
|
874
|
-
print("\(
|
|
884
|
+
print("\(CapacitorUpdater.TAG) Updated to bundle: \(next!.toString())")
|
|
875
885
|
_ = self.implementation.setNextBundle(next: Optional<String>.none)
|
|
876
886
|
} else {
|
|
877
|
-
print("\(
|
|
887
|
+
print("\(CapacitorUpdater.TAG) Update to bundle: \(next!.toString()) Failed!")
|
|
878
888
|
}
|
|
879
889
|
}
|
|
880
890
|
}
|
|
@@ -902,12 +912,12 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
902
912
|
self.implementation.sendStats(action: "app_moved_to_foreground", versionName: current.getVersionName())
|
|
903
913
|
if backgroundWork != nil && taskRunning {
|
|
904
914
|
backgroundWork!.cancel()
|
|
905
|
-
print("\(
|
|
915
|
+
print("\(CapacitorUpdater.TAG) Background Timer Task canceled, Activity resumed before timer completes")
|
|
906
916
|
}
|
|
907
917
|
if self._isAutoUpdateEnabled() {
|
|
908
918
|
self.backgroundDownload()
|
|
909
919
|
} else {
|
|
910
|
-
print("\(
|
|
920
|
+
print("\(CapacitorUpdater.TAG) Auto update is disabled")
|
|
911
921
|
self.sendReadyToJs(current: current, msg: "disabled")
|
|
912
922
|
}
|
|
913
923
|
self.checkAppReady()
|
|
@@ -918,7 +928,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
918
928
|
return
|
|
919
929
|
}
|
|
920
930
|
guard let url = URL(string: self.updateUrl) else {
|
|
921
|
-
print("\(
|
|
931
|
+
print("\(CapacitorUpdater.TAG) Error no url or wrong format")
|
|
922
932
|
return
|
|
923
933
|
}
|
|
924
934
|
let timer = Timer.scheduledTimer(withTimeInterval: TimeInterval(periodCheckDelay), repeats: true) { _ in
|
|
@@ -927,7 +937,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
927
937
|
let current = self.implementation.getCurrentBundle()
|
|
928
938
|
|
|
929
939
|
if res.version != current.getVersionName() {
|
|
930
|
-
print("\(
|
|
940
|
+
print("\(CapacitorUpdater.TAG) New version found: \(res.version)")
|
|
931
941
|
self.backgroundDownload()
|
|
932
942
|
}
|
|
933
943
|
}
|
|
@@ -937,7 +947,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
937
947
|
|
|
938
948
|
@objc func appMovedToBackground() {
|
|
939
949
|
self.implementation.sendStats(action: "app_moved_to_background")
|
|
940
|
-
print("\(
|
|
950
|
+
print("\(CapacitorUpdater.TAG) Check for pending update")
|
|
941
951
|
let delayUpdatePreferences = UserDefaults.standard.string(forKey: DELAY_CONDITION_PREFERENCES) ?? "[]"
|
|
942
952
|
|
|
943
953
|
let delayConditionList: [DelayCondition] = fromJsonArr(json: delayUpdatePreferences).map { obj -> DelayCondition in
|