@capgo/cordova-updater 8.1.1
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/LICENSE +373 -0
- package/README.md +82 -0
- package/dist/esm/definitions.d.ts +2684 -0
- package/dist/esm/definitions.js +109 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/exec.d.ts +4 -0
- package/dist/esm/exec.js +25 -0
- package/dist/esm/exec.js.map +1 -0
- package/dist/esm/history.d.ts +1 -0
- package/dist/esm/history.js +283 -0
- package/dist/esm/history.js.map +1 -0
- package/dist/esm/index.d.ts +57 -0
- package/dist/esm/index.js +68 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/plugin.d.ts +57 -0
- package/dist/esm/plugin.js +15 -0
- package/dist/esm/plugin.js.map +1 -0
- package/dist/plugin.cjs.js +217 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +222 -0
- package/dist/plugin.js.map +1 -0
- package/package.json +96 -0
- package/plugin.xml +207 -0
- package/src/android/CordovaUpdaterPlugin.java +5662 -0
- package/src/android/UpdaterPathHandler.java +99 -0
- package/src/android/app/capgo/cordova/updater/AndroidAppExitReporter.java +92 -0
- package/src/android/app/capgo/cordova/updater/AppLifecycleObserver.java +115 -0
- package/src/android/app/capgo/cordova/updater/BundleInfo.java +246 -0
- package/src/android/app/capgo/cordova/updater/BundleStatus.java +45 -0
- package/src/android/app/capgo/cordova/updater/Callback.java +13 -0
- package/src/android/app/capgo/cordova/updater/CapgoUpdater.java +3404 -0
- package/src/android/app/capgo/cordova/updater/CordovaUpdaterConfig.java +56 -0
- package/src/android/app/capgo/cordova/updater/CryptoCipher.java +462 -0
- package/src/android/app/capgo/cordova/updater/DataManager.java +44 -0
- package/src/android/app/capgo/cordova/updater/DelayCondition.java +56 -0
- package/src/android/app/capgo/cordova/updater/DelayUntilNext.java +14 -0
- package/src/android/app/capgo/cordova/updater/DelayUpdateUtils.java +307 -0
- package/src/android/app/capgo/cordova/updater/DeviceIdHelper.java +230 -0
- package/src/android/app/capgo/cordova/updater/DownloadService.java +1219 -0
- package/src/android/app/capgo/cordova/updater/DownloadWorkerManager.java +260 -0
- package/src/android/app/capgo/cordova/updater/InternalUtils.java +54 -0
- package/src/android/app/capgo/cordova/updater/Logger.java +345 -0
- package/src/android/app/capgo/cordova/updater/ShakeDetector.java +72 -0
- package/src/android/app/capgo/cordova/updater/ShakeMenu.java +39 -0
- package/src/android/app/capgo/cordova/updater/ThreeFingerPinchDetector.java +323 -0
- package/src/android/app/capgo/cordova/updater/compat/JSArray.java +9 -0
- package/src/android/app/capgo/cordova/updater/compat/JSObject.java +83 -0
- package/src/android/app/capgo/cordova/updater/compat/PluginCall.java +165 -0
- package/src/android/capgo-cordova-updater.gradle +19 -0
- package/src/android/capgo-updater.xml +3 -0
- package/src/android/test/app/capgo/cordova/updater/CapacitorUpdaterUnitTest.java.skip +3039 -0
- package/src/android/test/app/capgo/cordova/updater/DelayUpdateUtilsTest.java +177 -0
- package/src/android/test/app/capgo/cordova/updater/NativeContractTest.java +105 -0
- package/src/ios/AES.swift +216 -0
- package/src/ios/AppHealthTracker.swift +82 -0
- package/src/ios/BundleInfo.swift +185 -0
- package/src/ios/BundleStatus.swift +127 -0
- package/src/ios/CapgoRawRsa.swift +36 -0
- package/src/ios/CapgoUpdater.swift +3544 -0
- package/src/ios/CordovaCompat.swift +11 -0
- package/src/ios/CordovaPluginCall.swift +190 -0
- package/src/ios/CordovaUpdaterCommands.swift +270 -0
- package/src/ios/CordovaUpdaterPlugin.swift +4706 -0
- package/src/ios/CryptoCipher.swift +326 -0
- package/src/ios/DelayCondition.swift +74 -0
- package/src/ios/DelayUntilNext.swift +30 -0
- package/src/ios/DelayUpdateUtils.swift +257 -0
- package/src/ios/DeviceIdHelper.swift +120 -0
- package/src/ios/Info.plist +28 -0
- package/src/ios/InternalUtils.swift +471 -0
- package/src/ios/Logger.swift +283 -0
- package/src/ios/RSA.swift +96 -0
- package/src/ios/ShakeMenu.swift +52 -0
- package/src/ios/UpdaterSchemeHandler.swift +81 -0
- package/src/ios/UserDefaultsExtension.swift +46 -0
- package/src/ios/WebViewStatsReporter.swift +303 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
3
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
4
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import Foundation
|
|
8
|
+
|
|
9
|
+
@objc public class BundleInfo: NSObject, Decodable, Encodable {
|
|
10
|
+
// swiftlint:disable identifier_name
|
|
11
|
+
public static let ID_BUILTIN: String = "builtin"
|
|
12
|
+
public static let VERSION_UNKNOWN: String = "unknown"
|
|
13
|
+
public static let DOWNLOADED_BUILTIN: String = "1970-01-01T00:00:00.000Z"
|
|
14
|
+
// swiftlint:enable identifier_name
|
|
15
|
+
|
|
16
|
+
private let downloaded: String
|
|
17
|
+
private let id: String
|
|
18
|
+
private let version: String
|
|
19
|
+
private let checksum: String
|
|
20
|
+
private let status: BundleStatus
|
|
21
|
+
private let link: String?
|
|
22
|
+
private let comment: String?
|
|
23
|
+
|
|
24
|
+
convenience init(
|
|
25
|
+
id: String, version: String, status: BundleStatus, downloaded: Date,
|
|
26
|
+
checksum: String, link: String? = nil, comment: String? = nil
|
|
27
|
+
) {
|
|
28
|
+
self.init(
|
|
29
|
+
id: id, version: version, status: status,
|
|
30
|
+
downloaded: downloaded.iso8601withFractionalSeconds,
|
|
31
|
+
checksum: checksum, link: link, comment: comment)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
init(
|
|
35
|
+
id: String, version: String, status: BundleStatus,
|
|
36
|
+
downloaded: String = BundleInfo.DOWNLOADED_BUILTIN, checksum: String,
|
|
37
|
+
link: String? = nil, comment: String? = nil
|
|
38
|
+
) {
|
|
39
|
+
self.downloaded = downloaded.trim()
|
|
40
|
+
self.id = id
|
|
41
|
+
self.version = version
|
|
42
|
+
self.checksum = checksum
|
|
43
|
+
self.status = status
|
|
44
|
+
self.link = link
|
|
45
|
+
self.comment = comment
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
enum CodingKeys: String, CodingKey {
|
|
49
|
+
case downloaded, id, version, status, checksum, link, comment
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public func isBuiltin() -> Bool {
|
|
53
|
+
return BundleInfo.ID_BUILTIN == self.id
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public func isUnknown() -> Bool {
|
|
57
|
+
return BundleInfo.VERSION_UNKNOWN == self.id
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public func isErrorStatus() -> Bool {
|
|
61
|
+
return BundleStatus.ERROR == self.status
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public func isDeleted() -> Bool {
|
|
65
|
+
return BundleStatus.DELETED == self.status
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public func isDeleting() -> Bool {
|
|
69
|
+
return BundleStatus.DELETING == self.status
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
public func isDownloading() -> Bool {
|
|
73
|
+
return BundleStatus.DOWNLOADING == self.status
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
public func isDownloaded() -> Bool {
|
|
77
|
+
return !self.isBuiltin() && self.downloaded != "" &&
|
|
78
|
+
self.downloaded != BundleInfo.DOWNLOADED_BUILTIN && !self.isDeleted() && !self.isDeleting()
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
public func getDownloaded() -> String {
|
|
82
|
+
return self.isBuiltin() ? BundleInfo.DOWNLOADED_BUILTIN : self.downloaded
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
public func getChecksum() -> String {
|
|
86
|
+
return self.isBuiltin() ? "" : self.checksum
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
public func setChecksum(checksum: String) -> BundleInfo {
|
|
90
|
+
return BundleInfo(
|
|
91
|
+
id: self.id, version: self.version, status: self.status,
|
|
92
|
+
downloaded: self.downloaded, checksum: checksum,
|
|
93
|
+
link: self.link, comment: self.comment)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
public func setDownloaded(downloaded: Date) -> BundleInfo {
|
|
97
|
+
return BundleInfo(
|
|
98
|
+
id: self.id, version: self.version, status: self.status,
|
|
99
|
+
downloaded: downloaded, checksum: self.checksum,
|
|
100
|
+
link: self.link, comment: self.comment)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
public func getId() -> String {
|
|
104
|
+
return self.isBuiltin() ? BundleInfo.ID_BUILTIN : self.id
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
public func setId(id: String) -> BundleInfo {
|
|
108
|
+
return BundleInfo(
|
|
109
|
+
id: id, version: self.version, status: self.status,
|
|
110
|
+
downloaded: self.downloaded, checksum: self.checksum,
|
|
111
|
+
link: self.link, comment: self.comment)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
public func getVersionName() -> String {
|
|
115
|
+
return self.version.isEmpty ? BundleInfo.ID_BUILTIN : self.version
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
public func setVersionName(version: String) -> BundleInfo {
|
|
119
|
+
return BundleInfo(
|
|
120
|
+
id: self.id, version: version, status: self.status,
|
|
121
|
+
downloaded: self.downloaded, checksum: self.checksum,
|
|
122
|
+
link: self.link, comment: self.comment)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
public func getStatus() -> String {
|
|
126
|
+
return self.isBuiltin() ?
|
|
127
|
+
BundleStatus.SUCCESS.storedValue : self.status.storedValue
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
public func setStatus(status: String) -> BundleInfo {
|
|
131
|
+
return BundleInfo(
|
|
132
|
+
id: self.id, version: self.version,
|
|
133
|
+
status: BundleStatus(storedValue: status)!,
|
|
134
|
+
downloaded: self.downloaded, checksum: self.checksum,
|
|
135
|
+
link: self.link, comment: self.comment)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
public func getLink() -> String? {
|
|
139
|
+
return self.link
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
public func setLink(link: String?) -> BundleInfo {
|
|
143
|
+
return BundleInfo(
|
|
144
|
+
id: self.id, version: self.version, status: self.status,
|
|
145
|
+
downloaded: self.downloaded, checksum: self.checksum,
|
|
146
|
+
link: link, comment: self.comment)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
public func getComment() -> String? {
|
|
150
|
+
return self.comment
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
public func setComment(comment: String?) -> BundleInfo {
|
|
154
|
+
return BundleInfo(
|
|
155
|
+
id: self.id, version: self.version, status: self.status,
|
|
156
|
+
downloaded: self.downloaded, checksum: self.checksum,
|
|
157
|
+
link: self.link, comment: comment)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
public func toJSON() -> [String: String] {
|
|
161
|
+
var result: [String: String] = [
|
|
162
|
+
"id": self.getId(),
|
|
163
|
+
"version": self.getVersionName(),
|
|
164
|
+
"downloaded": self.getDownloaded(),
|
|
165
|
+
"checksum": self.getChecksum(),
|
|
166
|
+
"status": self.getStatus()
|
|
167
|
+
]
|
|
168
|
+
if let link = self.link {
|
|
169
|
+
result["link"] = link
|
|
170
|
+
}
|
|
171
|
+
if let comment = self.comment {
|
|
172
|
+
result["comment"] = comment
|
|
173
|
+
}
|
|
174
|
+
return result
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
public static func == (lhs: BundleInfo, rhs: BundleInfo) -> Bool {
|
|
178
|
+
return lhs.getVersionName() == rhs.getVersionName()
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
public func toString() -> String {
|
|
182
|
+
// swiftlint:disable:next line_length
|
|
183
|
+
return "{ \"id\": \"\(self.getId())\", \"version\": \"\(self.getVersionName())\", \"downloaded\": \"\(self.getDownloaded())\", \"checksum\": \"\(self.getChecksum())\", \"status\": \"\(self.getStatus())\"}"
|
|
184
|
+
}
|
|
185
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
3
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
4
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import Foundation
|
|
8
|
+
|
|
9
|
+
struct LocalizedString: ExpressibleByStringLiteral, Equatable {
|
|
10
|
+
|
|
11
|
+
let value: String
|
|
12
|
+
|
|
13
|
+
init(key: String) {
|
|
14
|
+
self.value = NSLocalizedString(key, comment: "")
|
|
15
|
+
}
|
|
16
|
+
init(localized: String) {
|
|
17
|
+
self.value = localized
|
|
18
|
+
}
|
|
19
|
+
init(stringLiteral val: String) {
|
|
20
|
+
self.init(key: val)
|
|
21
|
+
}
|
|
22
|
+
init(extendedGraphemeClusterLiteral val: String) {
|
|
23
|
+
self.init(key: val)
|
|
24
|
+
}
|
|
25
|
+
init(unicodeScalarLiteral val: String) {
|
|
26
|
+
self.init(key: val)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
func == (lhs: LocalizedString, rhs: LocalizedString) -> Bool {
|
|
31
|
+
return lhs.value == rhs.value
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
enum BundleStatus: LocalizedString, CaseIterable, Decodable, Encodable {
|
|
35
|
+
case SUCCESS = "success"
|
|
36
|
+
case ERROR = "error"
|
|
37
|
+
case PENDING = "pending"
|
|
38
|
+
case DELETED = "deleted"
|
|
39
|
+
case DELETING = "deleting"
|
|
40
|
+
case DOWNLOADING = "downloading"
|
|
41
|
+
|
|
42
|
+
var storedValue: String {
|
|
43
|
+
switch self {
|
|
44
|
+
case .SUCCESS:
|
|
45
|
+
return "success"
|
|
46
|
+
case .ERROR:
|
|
47
|
+
return "error"
|
|
48
|
+
case .PENDING:
|
|
49
|
+
return "pending"
|
|
50
|
+
case .DELETED:
|
|
51
|
+
return "deleted"
|
|
52
|
+
case .DELETING:
|
|
53
|
+
return "deleting"
|
|
54
|
+
case .DOWNLOADING:
|
|
55
|
+
return "downloading"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
var localizedString: String {
|
|
60
|
+
return self.rawValue.value
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
init?(localizedString: String) {
|
|
64
|
+
let normalized = localizedString.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
65
|
+
guard let status = BundleStatus.allCases.first(where: { $0.localizedString == normalized }) else {
|
|
66
|
+
return nil
|
|
67
|
+
}
|
|
68
|
+
self = status
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
init?(storedValue: String) {
|
|
72
|
+
guard let status = BundleStatus.fromStoredValue(storedValue) else {
|
|
73
|
+
return nil
|
|
74
|
+
}
|
|
75
|
+
self = status
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
private static func fromStoredValue(_ value: String) -> BundleStatus? {
|
|
79
|
+
let normalized = value.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
80
|
+
if let status = BundleStatus(localizedString: normalized) {
|
|
81
|
+
return status
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
let storedValue = normalized.lowercased()
|
|
85
|
+
return BundleStatus.allCases.first(where: { $0.storedValue == storedValue })
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
init(from decoder: Decoder) throws {
|
|
89
|
+
if let container = try? decoder.singleValueContainer(),
|
|
90
|
+
let value = try? container.decode(String.self),
|
|
91
|
+
let status = BundleStatus.fromStoredValue(value) {
|
|
92
|
+
self = status
|
|
93
|
+
return
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if let container = try? decoder.container(keyedBy: DynamicCodingKey.self),
|
|
97
|
+
let key = container.allKeys.first,
|
|
98
|
+
let status = BundleStatus.fromStoredValue(key.stringValue) {
|
|
99
|
+
self = status
|
|
100
|
+
return
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
throw DecodingError.dataCorrupted(
|
|
104
|
+
DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Invalid bundle status")
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
func encode(to encoder: Encoder) throws {
|
|
109
|
+
var container = encoder.singleValueContainer()
|
|
110
|
+
try container.encode(self.storedValue)
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
private struct DynamicCodingKey: CodingKey {
|
|
115
|
+
var stringValue: String
|
|
116
|
+
var intValue: Int?
|
|
117
|
+
|
|
118
|
+
init?(stringValue: String) {
|
|
119
|
+
self.stringValue = stringValue
|
|
120
|
+
self.intValue = nil
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
init?(intValue: Int) {
|
|
124
|
+
self.stringValue = String(intValue)
|
|
125
|
+
self.intValue = intValue
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
3
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
4
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import Foundation
|
|
8
|
+
import Security
|
|
9
|
+
import os.log
|
|
10
|
+
|
|
11
|
+
/// Isolated raw RSA primitives for Capgo v2 checksum/session-key recovery.
|
|
12
|
+
/// SonarCloud automatic analysis has no Swift // NOSONAR; swift:S5542 is ignored
|
|
13
|
+
/// via `.sonarcloud.properties` multicriteria because `.rsaEncryptionRaw` is
|
|
14
|
+
/// intentional wire compatibility with Node `privateEncrypt` / `publicDecrypt`.
|
|
15
|
+
enum CapgoRawRsa {
|
|
16
|
+
private static let log = OSLog(subsystem: "app.capgo.cordova.updater", category: "RSA")
|
|
17
|
+
|
|
18
|
+
static func supportsCapgoRecovery(key: SecKey) -> Bool {
|
|
19
|
+
SecKeyGetBlockSize(key) == 256
|
|
20
|
+
&& SecKeyIsAlgorithmSupported(key, .encrypt, .rsaEncryptionRaw) // NOSONAR intentional raw RSA for Node privateEncrypt / Capgo checksum recovery
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
static func recoverSignatureBlock(key: SecKey, data: Data) -> Data? {
|
|
24
|
+
var error: Unmanaged<CFError>?
|
|
25
|
+
guard let recovered = SecKeyCreateEncryptedData(key, .rsaEncryptionRaw, data as CFData, &error) as Data? else { // NOSONAR intentional raw RSA for Node privateEncrypt / Capgo checksum recovery
|
|
26
|
+
os_log(
|
|
27
|
+
"RSA raw recovery failed: %{public}@",
|
|
28
|
+
log: log,
|
|
29
|
+
type: .error,
|
|
30
|
+
String(describing: error?.takeRetainedValue())
|
|
31
|
+
)
|
|
32
|
+
return nil
|
|
33
|
+
}
|
|
34
|
+
return recovered
|
|
35
|
+
}
|
|
36
|
+
}
|