@hot-updater/react-native 0.22.1 → 0.23.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 (39) hide show
  1. package/android/src/main/java/com/hotupdater/BundleFileStorageService.kt +17 -12
  2. package/android/src/main/java/com/hotupdater/HotUpdater.kt +1 -1
  3. package/android/src/main/java/com/hotupdater/HotUpdaterFactory.kt +1 -0
  4. package/android/src/main/java/com/hotupdater/HotUpdaterImpl.kt +1 -1
  5. package/android/src/main/java/com/hotupdater/SignatureVerifier.kt +346 -0
  6. package/ios/HotUpdater/Internal/BundleFileStorageService.swift +26 -18
  7. package/ios/HotUpdater/Internal/SignatureVerifier.swift +339 -0
  8. package/lib/commonjs/checkForUpdate.js +1 -1
  9. package/lib/commonjs/checkForUpdate.js.map +1 -1
  10. package/lib/commonjs/index.js +16 -1
  11. package/lib/commonjs/index.js.map +1 -1
  12. package/lib/commonjs/specs/NativeHotUpdater.js.map +1 -1
  13. package/lib/commonjs/types.js +45 -0
  14. package/lib/commonjs/types.js.map +1 -0
  15. package/lib/module/checkForUpdate.js +1 -1
  16. package/lib/module/checkForUpdate.js.map +1 -1
  17. package/lib/module/index.js +1 -0
  18. package/lib/module/index.js.map +1 -1
  19. package/lib/module/specs/NativeHotUpdater.js.map +1 -1
  20. package/lib/module/types.js +40 -0
  21. package/lib/module/types.js.map +1 -0
  22. package/lib/typescript/commonjs/index.d.ts +1 -0
  23. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  24. package/lib/typescript/commonjs/specs/NativeHotUpdater.d.ts +7 -2
  25. package/lib/typescript/commonjs/specs/NativeHotUpdater.d.ts.map +1 -1
  26. package/lib/typescript/commonjs/types.d.ts +34 -0
  27. package/lib/typescript/commonjs/types.d.ts.map +1 -0
  28. package/lib/typescript/module/index.d.ts +1 -0
  29. package/lib/typescript/module/index.d.ts.map +1 -1
  30. package/lib/typescript/module/specs/NativeHotUpdater.d.ts +7 -2
  31. package/lib/typescript/module/specs/NativeHotUpdater.d.ts.map +1 -1
  32. package/lib/typescript/module/types.d.ts +34 -0
  33. package/lib/typescript/module/types.d.ts.map +1 -0
  34. package/package.json +7 -7
  35. package/plugin/build/transformers.js +269 -0
  36. package/src/checkForUpdate.ts +1 -1
  37. package/src/index.ts +5 -0
  38. package/src/specs/NativeHotUpdater.ts +7 -2
  39. package/src/types.ts +63 -0
@@ -0,0 +1,339 @@
1
+ import Foundation
2
+ import Security
3
+
4
+ /// Prefix for signed file hash format.
5
+ private let SIGNED_HASH_PREFIX = "sig:"
6
+
7
+ /// Error types for signature verification failures.
8
+ ///
9
+ /// **IMPORTANT**: The error messages in `errorUserInfo` are used by the JavaScript layer
10
+ /// (`packages/react-native/src/types.ts`) to detect signature verification failures.
11
+ /// If you change these messages, update `isSignatureVerificationError()` in types.ts accordingly.
12
+ public enum SignatureVerificationError: Error, CustomNSError {
13
+ case publicKeyNotConfigured
14
+ case invalidPublicKeyFormat
15
+ case invalidSignatureFormat
16
+ case verificationFailed
17
+ case hashMismatch
18
+ case hashCalculationFailed
19
+ case unsignedNotAllowed
20
+ case securityFrameworkError(OSStatus)
21
+
22
+ // CustomNSError protocol implementation
23
+ public static var errorDomain: String {
24
+ return "com.hotupdater.SignatureVerificationError"
25
+ }
26
+
27
+ public var errorCode: Int {
28
+ switch self {
29
+ case .publicKeyNotConfigured: return 2001
30
+ case .invalidPublicKeyFormat: return 2002
31
+ case .invalidSignatureFormat: return 2003
32
+ case .verificationFailed: return 2004
33
+ case .hashMismatch: return 2005
34
+ case .hashCalculationFailed: return 2006
35
+ case .unsignedNotAllowed: return 2007
36
+ case .securityFrameworkError: return 2099
37
+ }
38
+ }
39
+
40
+ public var errorUserInfo: [String: Any] {
41
+ var userInfo: [String: Any] = [:]
42
+
43
+ switch self {
44
+ case .publicKeyNotConfigured:
45
+ userInfo[NSLocalizedDescriptionKey] = "Public key not configured for signature verification"
46
+ userInfo[NSLocalizedRecoverySuggestionErrorKey] = "Add HOT_UPDATER_PUBLIC_KEY to Info.plist with your RSA public key"
47
+
48
+ case .invalidPublicKeyFormat:
49
+ userInfo[NSLocalizedDescriptionKey] = "Public key format is invalid"
50
+ userInfo[NSLocalizedRecoverySuggestionErrorKey] = "Ensure the public key is in PEM format (BEGIN PUBLIC KEY)"
51
+
52
+ case .invalidSignatureFormat:
53
+ userInfo[NSLocalizedDescriptionKey] = "Signature format is invalid"
54
+ userInfo[NSLocalizedRecoverySuggestionErrorKey] = "The signature must be base64-encoded"
55
+
56
+ case .verificationFailed:
57
+ userInfo[NSLocalizedDescriptionKey] = "Bundle signature verification failed"
58
+ userInfo[NSLocalizedRecoverySuggestionErrorKey] = "The bundle may be corrupted or tampered with. Rejecting update for security"
59
+
60
+ case .hashMismatch:
61
+ userInfo[NSLocalizedDescriptionKey] = "Bundle hash verification failed"
62
+ userInfo[NSLocalizedRecoverySuggestionErrorKey] = "The bundle file hash does not match. File may be corrupted"
63
+
64
+ case .hashCalculationFailed:
65
+ userInfo[NSLocalizedDescriptionKey] = "Failed to calculate file hash"
66
+ userInfo[NSLocalizedRecoverySuggestionErrorKey] = "Could not read file for hash verification"
67
+
68
+ case .unsignedNotAllowed:
69
+ userInfo[NSLocalizedDescriptionKey] = "Unsigned bundle not allowed when signing is enabled"
70
+ userInfo[NSLocalizedRecoverySuggestionErrorKey] = "Public key is configured but bundle is not signed. Rejecting update"
71
+
72
+ case .securityFrameworkError(let status):
73
+ userInfo[NSLocalizedDescriptionKey] = "Security framework error during verification (OSStatus: \(status))"
74
+ userInfo[NSLocalizedRecoverySuggestionErrorKey] = "Check public key format and signature data"
75
+ }
76
+
77
+ return userInfo
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Service for verifying bundle integrity through hash or RSA-SHA256 signature verification.
83
+ * Uses iOS Security framework for cryptographic operations.
84
+ *
85
+ * fileHash format:
86
+ * - Signed: `sig:<base64_signature>` - Verify signature (implicitly verifies hash)
87
+ * - Unsigned: `<hex_hash>` - Verify SHA256 hash only
88
+ *
89
+ * Security rules:
90
+ * - null/empty fileHash → REJECT
91
+ * - sig:... + public key configured → verify signature → Install/REJECT
92
+ * - sig:... + public key NOT configured → REJECT (can't verify)
93
+ * - <hash> + public key configured → REJECT (unsigned not allowed)
94
+ * - <hash> + public key NOT configured → verify hash → Install/REJECT
95
+ */
96
+ public class SignatureVerifier {
97
+
98
+ /**
99
+ * Reads public key from Info.plist configuration.
100
+ * @return Public key PEM string or nil if not configured
101
+ */
102
+ private static func getPublicKeyFromConfig() -> String? {
103
+ guard let publicKeyPEM = Bundle.main.object(forInfoDictionaryKey: "HOT_UPDATER_PUBLIC_KEY") as? String else {
104
+ NSLog("[SignatureVerifier] HOT_UPDATER_PUBLIC_KEY not found in Info.plist")
105
+ return nil
106
+ }
107
+ return publicKeyPEM
108
+ }
109
+
110
+ /**
111
+ * Checks if signing is enabled (public key is configured).
112
+ * @return true if public key is configured
113
+ */
114
+ public static func isSigningEnabled() -> Bool {
115
+ return getPublicKeyFromConfig() != nil
116
+ }
117
+
118
+ /**
119
+ * Checks if fileHash is in signed format (starts with "sig:").
120
+ * @param fileHash The file hash string to check
121
+ * @return true if signed format
122
+ */
123
+ public static func isSignedFormat(_ fileHash: String?) -> Bool {
124
+ guard let hash = fileHash else { return false }
125
+ return hash.hasPrefix(SIGNED_HASH_PREFIX)
126
+ }
127
+
128
+ /**
129
+ * Extracts signature from signed format fileHash.
130
+ * @param fileHash The signed file hash (sig:<signature>)
131
+ * @return Base64-encoded signature or nil if not signed format
132
+ */
133
+ public static func extractSignature(_ fileHash: String?) -> String? {
134
+ guard let hash = fileHash, isSignedFormat(hash) else { return nil }
135
+ return String(hash.dropFirst(SIGNED_HASH_PREFIX.count))
136
+ }
137
+
138
+ /**
139
+ * Verifies bundle integrity based on fileHash format.
140
+ * Determines verification mode by checking for "sig:" prefix.
141
+ *
142
+ * @param fileURL URL of the bundle file to verify
143
+ * @param fileHash Combined hash string (sig:<signature> or <hex_hash>)
144
+ * @return Result indicating verification success or failure with error
145
+ */
146
+ public static func verifyBundle(fileURL: URL, fileHash: String?) -> Result<Void, SignatureVerificationError> {
147
+ let signingEnabled = isSigningEnabled()
148
+
149
+ // Rule: null/empty fileHash → REJECT
150
+ guard let hash = fileHash, !hash.isEmpty else {
151
+ NSLog("[SignatureVerifier] fileHash is null or empty. Rejecting update.")
152
+ return .failure(.verificationFailed)
153
+ }
154
+
155
+ if isSignedFormat(hash) {
156
+ // Signed format: sig:<signature>
157
+ guard let signature = extractSignature(hash) else {
158
+ NSLog("[SignatureVerifier] Failed to extract signature from fileHash")
159
+ return .failure(.invalidSignatureFormat)
160
+ }
161
+
162
+ // Rule: sig:... + public key NOT configured → REJECT
163
+ guard signingEnabled else {
164
+ NSLog("[SignatureVerifier] Signed bundle but public key not configured. Cannot verify.")
165
+ return .failure(.publicKeyNotConfigured)
166
+ }
167
+
168
+ // Rule: sig:... + public key configured → verify signature
169
+ return verifySignature(fileURL: fileURL, signatureBase64: signature)
170
+ } else {
171
+ // Unsigned format: <hex_hash>
172
+
173
+ // Rule: <hash> + public key configured → REJECT
174
+ if signingEnabled {
175
+ NSLog("[SignatureVerifier] Unsigned bundle not allowed when signing is enabled. Rejecting.")
176
+ return .failure(.unsignedNotAllowed)
177
+ }
178
+
179
+ // Rule: <hash> + public key NOT configured → verify hash
180
+ return verifyHash(fileURL: fileURL, expectedHash: hash)
181
+ }
182
+ }
183
+
184
+ /**
185
+ * Verifies SHA256 hash of a file.
186
+ * @param fileURL URL of the file to verify
187
+ * @param expectedHash Expected SHA256 hash (hex string)
188
+ * @return Result indicating verification success or failure
189
+ */
190
+ public static func verifyHash(fileURL: URL, expectedHash: String) -> Result<Void, SignatureVerificationError> {
191
+ NSLog("[SignatureVerifier] Verifying hash for file: \(fileURL.lastPathComponent)")
192
+
193
+ guard HashUtils.verifyHash(fileURL: fileURL, expectedHash: expectedHash) else {
194
+ NSLog("[SignatureVerifier] Hash mismatch!")
195
+ return .failure(.hashMismatch)
196
+ }
197
+
198
+ NSLog("[SignatureVerifier] ✅ Hash verified successfully")
199
+ return .success(())
200
+ }
201
+
202
+ /**
203
+ * Verifies RSA-SHA256 signature of a file.
204
+ * Calculates the file hash internally and verifies the signature.
205
+ *
206
+ * @param fileURL URL of the file to verify
207
+ * @param signatureBase64 Base64-encoded RSA-SHA256 signature
208
+ * @return Result indicating verification success or failure with error
209
+ */
210
+ public static func verifySignature(fileURL: URL, signatureBase64: String) -> Result<Void, SignatureVerificationError> {
211
+ NSLog("[SignatureVerifier] Verifying signature for file: \(fileURL.lastPathComponent)")
212
+
213
+ // Get public key from config
214
+ guard let publicKeyPEM = getPublicKeyFromConfig() else {
215
+ NSLog("[SignatureVerifier] Cannot verify signature: public key not configured in Info.plist")
216
+ return .failure(.publicKeyNotConfigured)
217
+ }
218
+
219
+ // Convert PEM to SecKey
220
+ let publicKeyResult = createPublicKey(from: publicKeyPEM)
221
+ guard case .success(let publicKey) = publicKeyResult else {
222
+ if case .failure(let error) = publicKeyResult {
223
+ return .failure(error)
224
+ }
225
+ return .failure(.invalidPublicKeyFormat)
226
+ }
227
+
228
+ // Calculate file hash
229
+ guard let fileHashHex = HashUtils.calculateSHA256(fileURL: fileURL) else {
230
+ NSLog("[SignatureVerifier] Failed to calculate file hash")
231
+ return .failure(.hashCalculationFailed)
232
+ }
233
+
234
+ NSLog("[SignatureVerifier] Calculated file hash: \(fileHashHex)")
235
+
236
+ // Decode signature from base64
237
+ guard let signatureData = Data(base64Encoded: signatureBase64) else {
238
+ NSLog("[SignatureVerifier] Failed to decode signature from base64")
239
+ return .failure(.invalidSignatureFormat)
240
+ }
241
+
242
+ // Convert hex fileHash to data
243
+ guard let fileHashData = dataFromHexString(fileHashHex) else {
244
+ NSLog("[SignatureVerifier] Failed to convert fileHash from hex")
245
+ return .failure(.invalidSignatureFormat)
246
+ }
247
+
248
+ // Verify signature
249
+ let algorithm: SecKeyAlgorithm = .rsaSignatureMessagePKCS1v15SHA256
250
+
251
+ guard SecKeyIsAlgorithmSupported(publicKey, .verify, algorithm) else {
252
+ NSLog("[SignatureVerifier] RSA-SHA256 algorithm not supported")
253
+ return .failure(.securityFrameworkError(-1))
254
+ }
255
+
256
+ var error: Unmanaged<CFError>?
257
+ let verified = SecKeyVerifySignature(
258
+ publicKey,
259
+ algorithm,
260
+ fileHashData as CFData,
261
+ signatureData as CFData,
262
+ &error
263
+ )
264
+
265
+ if let err = error?.takeRetainedValue() {
266
+ NSLog("[SignatureVerifier] Verification failed: \(err)")
267
+ return .failure(.verificationFailed)
268
+ }
269
+
270
+ if verified {
271
+ NSLog("[SignatureVerifier] ✅ Signature verified successfully")
272
+ return .success(())
273
+ } else {
274
+ NSLog("[SignatureVerifier] ❌ Signature verification failed")
275
+ return .failure(.verificationFailed)
276
+ }
277
+ }
278
+
279
+ /**
280
+ * Converts PEM-formatted public key to SecKey.
281
+ * @param publicKeyPEM Public key in PEM format
282
+ * @return SecKey or error
283
+ */
284
+ private static func createPublicKey(from publicKeyPEM: String) -> Result<SecKey, SignatureVerificationError> {
285
+ // Remove PEM headers/footers and whitespace
286
+ var keyString = publicKeyPEM
287
+ .replacingOccurrences(of: "-----BEGIN PUBLIC KEY-----", with: "")
288
+ .replacingOccurrences(of: "-----END PUBLIC KEY-----", with: "")
289
+ .replacingOccurrences(of: "\\n", with: "")
290
+ .replacingOccurrences(of: "\n", with: "")
291
+ .replacingOccurrences(of: " ", with: "")
292
+
293
+ // Decode base64
294
+ guard let keyData = Data(base64Encoded: keyString) else {
295
+ NSLog("[SignatureVerifier] Failed to decode public key from base64")
296
+ return .failure(.invalidPublicKeyFormat)
297
+ }
298
+
299
+ // SecKeyCreateWithData auto-detects key size from SPKI-formatted key data.
300
+ // This supports any valid RSA key size (2048, 3072, 4096-bit, etc.)
301
+ let attributes: [String: Any] = [
302
+ kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
303
+ kSecAttrKeyClass as String: kSecAttrKeyClassPublic
304
+ ]
305
+
306
+ var error: Unmanaged<CFError>?
307
+ guard let secKey = SecKeyCreateWithData(keyData as CFData, attributes as CFDictionary, &error) else {
308
+ if let err = error?.takeRetainedValue() {
309
+ NSLog("[SignatureVerifier] SecKeyCreateWithData failed: \(err)")
310
+ }
311
+ return .failure(.invalidPublicKeyFormat)
312
+ }
313
+
314
+ return .success(secKey)
315
+ }
316
+
317
+ /**
318
+ * Converts hex string to Data.
319
+ * @param hexString Hex-encoded string
320
+ * @return Data or nil if invalid format
321
+ */
322
+ private static func dataFromHexString(_ hexString: String) -> Data? {
323
+ var data = Data(capacity: hexString.count / 2)
324
+
325
+ var index = hexString.startIndex
326
+ while index < hexString.endIndex {
327
+ let nextIndex = hexString.index(index, offsetBy: 2)
328
+ guard nextIndex <= hexString.endIndex else { return nil }
329
+
330
+ let byteString = hexString[index..<nextIndex]
331
+ guard let byte = UInt8(byteString, radix: 16) else { return nil }
332
+
333
+ data.append(byte)
334
+ index = nextIndex
335
+ }
336
+
337
+ return data
338
+ }
339
+ }
@@ -50,7 +50,7 @@ async function checkForUpdate(options) {
50
50
  return (0, _native.updateBundle)({
51
51
  bundleId: updateInfo.id,
52
52
  fileUrl: updateInfo.fileUrl,
53
- fileHash: updateInfo?.fileHash ?? null,
53
+ fileHash: updateInfo.fileHash,
54
54
  status: updateInfo.status
55
55
  });
56
56
  }
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNative","require","_error","_fetchUpdateInfo","_native","checkForUpdate","options","__DEV__","includes","Platform","OS","onError","HotUpdaterError","currentAppVersion","getAppVersion","platform","currentBundleId","getBundleId","minBundleId","getMinBundleId","channel","getChannel","fingerprintHash","getFingerprintHash","fetchUpdateInfo","source","params","bundleId","appVersion","requestHeaders","requestTimeout","then","updateInfo","updateBundle","id","fileUrl","fileHash","status","getUpdateSource","baseUrl","updateStrategy","exports"],"sourceRoot":"../../src","sources":["checkForUpdate.ts"],"mappings":";;;;;;;AACA,IAAAA,YAAA,GAAAC,OAAA;AACA,IAAAC,MAAA,GAAAD,OAAA;AACA,IAAAE,gBAAA,GAAAF,OAAA;AACA,IAAAG,OAAA,GAAAH,OAAA;AA4BO,eAAeI,cAAcA,CAClCC,OAA8B,EACQ;EACtC,IAAIC,OAAO,EAAE;IACX,OAAO,IAAI;EACb;EAEA,IAAI,CAAC,CAAC,KAAK,EAAE,SAAS,CAAC,CAACC,QAAQ,CAACC,qBAAQ,CAACC,EAAE,CAAC,EAAE;IAC7CJ,OAAO,CAACK,OAAO,GACb,IAAIC,sBAAe,CAAC,iDAAiD,CACvE,CAAC;IACD,OAAO,IAAI;EACb;EAEA,MAAMC,iBAAiB,GAAG,IAAAC,qBAAa,EAAC,CAAC;EACzC,MAAMC,QAAQ,GAAGN,qBAAQ,CAACC,EAAuB;EACjD,MAAMM,eAAe,GAAG,IAAAC,mBAAW,EAAC,CAAC;EACrC,MAAMC,WAAW,GAAG,IAAAC,sBAAc,EAAC,CAAC;EACpC,MAAMC,OAAO,GAAG,IAAAC,kBAAU,EAAC,CAAC;EAE5B,IAAI,CAACR,iBAAiB,EAAE;IACtBP,OAAO,CAACK,OAAO,GAAG,IAAIC,sBAAe,CAAC,2BAA2B,CAAC,CAAC;IACnE,OAAO,IAAI;EACb;EAEA,MAAMU,eAAe,GAAG,IAAAC,0BAAkB,EAAC,CAAC;EAE5C,OAAO,IAAAC,gCAAe,EAAC;IACrBC,MAAM,EAAEnB,OAAO,CAACmB,MAAM;IACtBC,MAAM,EAAE;MACNC,QAAQ,EAAEX,eAAe;MACzBY,UAAU,EAAEf,iBAAiB;MAC7BE,QAAQ;MACRG,WAAW;MACXE,OAAO;MACPE;IACF,CAAC;IACDO,cAAc,EAAEvB,OAAO,CAACuB,cAAc;IACtClB,OAAO,EAAEL,OAAO,CAACK,OAAO;IACxBmB,cAAc,EAAExB,OAAO,CAACwB;EAC1B,CAAC,CAAC,CAACC,IAAI,CAAEC,UAAU,IAAK;IACtB,IAAI,CAACA,UAAU,EAAE;MACf,OAAO,IAAI;IACb;IAEA,OAAO;MACL,GAAGA,UAAU;MACbC,YAAY,EAAE,MAAAA,CAAA,KAAY;QACxB,OAAO,IAAAA,oBAAY,EAAC;UAClBN,QAAQ,EAAEK,UAAU,CAACE,EAAE;UACvBC,OAAO,EAAEH,UAAU,CAACG,OAAO;UAC3BC,QAAQ,EAAEJ,UAAU,EAAEI,QAAQ,IAAI,IAAI;UACtCC,MAAM,EAAEL,UAAU,CAACK;QACrB,CAAC,CAAC;MACJ;IACF,CAAC;EACH,CAAC,CAAC;AACJ;AAYO,MAAMC,eAAe,GAC1BA,CAACC,OAAe,EAAEjC,OAA+B,KAChDoB,MAA0B,IAAK;EAC9B,QAAQpB,OAAO,CAACkC,cAAc;IAC5B,KAAK,aAAa;MAAE;QAClB,IAAI,CAACd,MAAM,CAACJ,eAAe,EAAE;UAC3B,MAAM,IAAIV,sBAAe,CAAC,8BAA8B,CAAC;QAC3D;QACA,OAAO,GAAG2B,OAAO,gBAAgBb,MAAM,CAACX,QAAQ,IAAIW,MAAM,CAACJ,eAAe,IAAII,MAAM,CAACN,OAAO,IAAIM,MAAM,CAACR,WAAW,IAAIQ,MAAM,CAACC,QAAQ,EAAE;MACzI;IACA,KAAK,YAAY;MAAE;QACjB,OAAO,GAAGY,OAAO,gBAAgBb,MAAM,CAACX,QAAQ,IAAIW,MAAM,CAACE,UAAU,IAAIF,MAAM,CAACN,OAAO,IAAIM,MAAM,CAACR,WAAW,IAAIQ,MAAM,CAACC,QAAQ,EAAE;MACpI;IACA;MACE,OAAOY,OAAO;EAClB;AACF,CAAC;AAACE,OAAA,CAAAH,eAAA,GAAAA,eAAA","ignoreList":[]}
1
+ {"version":3,"names":["_reactNative","require","_error","_fetchUpdateInfo","_native","checkForUpdate","options","__DEV__","includes","Platform","OS","onError","HotUpdaterError","currentAppVersion","getAppVersion","platform","currentBundleId","getBundleId","minBundleId","getMinBundleId","channel","getChannel","fingerprintHash","getFingerprintHash","fetchUpdateInfo","source","params","bundleId","appVersion","requestHeaders","requestTimeout","then","updateInfo","updateBundle","id","fileUrl","fileHash","status","getUpdateSource","baseUrl","updateStrategy","exports"],"sourceRoot":"../../src","sources":["checkForUpdate.ts"],"mappings":";;;;;;;AACA,IAAAA,YAAA,GAAAC,OAAA;AACA,IAAAC,MAAA,GAAAD,OAAA;AACA,IAAAE,gBAAA,GAAAF,OAAA;AACA,IAAAG,OAAA,GAAAH,OAAA;AA4BO,eAAeI,cAAcA,CAClCC,OAA8B,EACQ;EACtC,IAAIC,OAAO,EAAE;IACX,OAAO,IAAI;EACb;EAEA,IAAI,CAAC,CAAC,KAAK,EAAE,SAAS,CAAC,CAACC,QAAQ,CAACC,qBAAQ,CAACC,EAAE,CAAC,EAAE;IAC7CJ,OAAO,CAACK,OAAO,GACb,IAAIC,sBAAe,CAAC,iDAAiD,CACvE,CAAC;IACD,OAAO,IAAI;EACb;EAEA,MAAMC,iBAAiB,GAAG,IAAAC,qBAAa,EAAC,CAAC;EACzC,MAAMC,QAAQ,GAAGN,qBAAQ,CAACC,EAAuB;EACjD,MAAMM,eAAe,GAAG,IAAAC,mBAAW,EAAC,CAAC;EACrC,MAAMC,WAAW,GAAG,IAAAC,sBAAc,EAAC,CAAC;EACpC,MAAMC,OAAO,GAAG,IAAAC,kBAAU,EAAC,CAAC;EAE5B,IAAI,CAACR,iBAAiB,EAAE;IACtBP,OAAO,CAACK,OAAO,GAAG,IAAIC,sBAAe,CAAC,2BAA2B,CAAC,CAAC;IACnE,OAAO,IAAI;EACb;EAEA,MAAMU,eAAe,GAAG,IAAAC,0BAAkB,EAAC,CAAC;EAE5C,OAAO,IAAAC,gCAAe,EAAC;IACrBC,MAAM,EAAEnB,OAAO,CAACmB,MAAM;IACtBC,MAAM,EAAE;MACNC,QAAQ,EAAEX,eAAe;MACzBY,UAAU,EAAEf,iBAAiB;MAC7BE,QAAQ;MACRG,WAAW;MACXE,OAAO;MACPE;IACF,CAAC;IACDO,cAAc,EAAEvB,OAAO,CAACuB,cAAc;IACtClB,OAAO,EAAEL,OAAO,CAACK,OAAO;IACxBmB,cAAc,EAAExB,OAAO,CAACwB;EAC1B,CAAC,CAAC,CAACC,IAAI,CAAEC,UAAU,IAAK;IACtB,IAAI,CAACA,UAAU,EAAE;MACf,OAAO,IAAI;IACb;IAEA,OAAO;MACL,GAAGA,UAAU;MACbC,YAAY,EAAE,MAAAA,CAAA,KAAY;QACxB,OAAO,IAAAA,oBAAY,EAAC;UAClBN,QAAQ,EAAEK,UAAU,CAACE,EAAE;UACvBC,OAAO,EAAEH,UAAU,CAACG,OAAO;UAC3BC,QAAQ,EAAEJ,UAAU,CAACI,QAAQ;UAC7BC,MAAM,EAAEL,UAAU,CAACK;QACrB,CAAC,CAAC;MACJ;IACF,CAAC;EACH,CAAC,CAAC;AACJ;AAYO,MAAMC,eAAe,GAC1BA,CAACC,OAAe,EAAEjC,OAA+B,KAChDoB,MAA0B,IAAK;EAC9B,QAAQpB,OAAO,CAACkC,cAAc;IAC5B,KAAK,aAAa;MAAE;QAClB,IAAI,CAACd,MAAM,CAACJ,eAAe,EAAE;UAC3B,MAAM,IAAIV,sBAAe,CAAC,8BAA8B,CAAC;QAC3D;QACA,OAAO,GAAG2B,OAAO,gBAAgBb,MAAM,CAACX,QAAQ,IAAIW,MAAM,CAACJ,eAAe,IAAII,MAAM,CAACN,OAAO,IAAIM,MAAM,CAACR,WAAW,IAAIQ,MAAM,CAACC,QAAQ,EAAE;MACzI;IACA,KAAK,YAAY;MAAE;QACjB,OAAO,GAAGY,OAAO,gBAAgBb,MAAM,CAACX,QAAQ,IAAIW,MAAM,CAACE,UAAU,IAAIF,MAAM,CAACN,OAAO,IAAIM,MAAM,CAACR,WAAW,IAAIQ,MAAM,CAACC,QAAQ,EAAE;MACpI;IACA;MACE,OAAOY,OAAO;EAClB;AACF,CAAC;AAACE,OAAA,CAAAH,eAAA,GAAAA,eAAA","ignoreList":[]}
@@ -5,15 +5,29 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  var _exportNames = {
7
7
  HotUpdater: true,
8
- getUpdateSource: true
8
+ getUpdateSource: true,
9
+ extractSignatureFailure: true,
10
+ isSignatureVerificationError: true
9
11
  };
10
12
  exports.HotUpdater = void 0;
13
+ Object.defineProperty(exports, "extractSignatureFailure", {
14
+ enumerable: true,
15
+ get: function () {
16
+ return _types.extractSignatureFailure;
17
+ }
18
+ });
11
19
  Object.defineProperty(exports, "getUpdateSource", {
12
20
  enumerable: true,
13
21
  get: function () {
14
22
  return _checkForUpdate.getUpdateSource;
15
23
  }
16
24
  });
25
+ Object.defineProperty(exports, "isSignatureVerificationError", {
26
+ enumerable: true,
27
+ get: function () {
28
+ return _types.isSignatureVerificationError;
29
+ }
30
+ });
17
31
  var _checkForUpdate = require("./checkForUpdate.js");
18
32
  var _native = require("./native.js");
19
33
  var _runUpdateProcess = require("./runUpdateProcess.js");
@@ -30,6 +44,7 @@ Object.keys(_store).forEach(function (key) {
30
44
  });
31
45
  });
32
46
  var _wrap = require("./wrap.js");
47
+ var _types = require("./types.js");
33
48
  (0, _native.addListener)("onProgress", ({
34
49
  progress
35
50
  }) => {
@@ -1 +1 @@
1
- {"version":3,"names":["_checkForUpdate","require","_native","_runUpdateProcess","_store","Object","keys","forEach","key","prototype","hasOwnProperty","call","_exportNames","exports","defineProperty","enumerable","get","_wrap","addListener","progress","hotUpdaterStore","setState","HotUpdater","wrap","reload","isUpdateDownloaded","getSnapshot","getAppVersion","getBundleId","getMinBundleId","getChannel","checkForUpdate","runUpdateProcess","updateBundle","getFingerprintHash"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;;;;;;;;;;;;;;;AAAA,IAAAA,eAAA,GAAAC,OAAA;AACA,IAAAC,OAAA,GAAAD,OAAA;AAUA,IAAAE,iBAAA,GAAAF,OAAA;AACA,IAAAG,MAAA,GAAAH,OAAA;AAIAI,MAAA,CAAAC,IAAA,CAAAF,MAAA,EAAAG,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAH,MAAA,CAAAI,SAAA,CAAAC,cAAA,CAAAC,IAAA,CAAAC,YAAA,EAAAJ,GAAA;EAAA,IAAAA,GAAA,IAAAK,OAAA,IAAAA,OAAA,CAAAL,GAAA,MAAAJ,MAAA,CAAAI,GAAA;EAAAH,MAAA,CAAAS,cAAA,CAAAD,OAAA,EAAAL,GAAA;IAAAO,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAZ,MAAA,CAAAI,GAAA;IAAA;EAAA;AAAA;AAHA,IAAAS,KAAA,GAAAhB,OAAA;AAMA,IAAAiB,mBAAW,EAAC,YAAY,EAAE,CAAC;EAAEC;AAAS,CAAC,KAAK;EAC1CC,sBAAe,CAACC,QAAQ,CAAC;IACvBF;EACF,CAAC,CAAC;AACJ,CAAC,CAAC;AAEK,MAAMG,UAAU,GAAAT,OAAA,CAAAS,UAAA,GAAG;EACxB;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEC,IAAI,EAAJA,UAAI;EACJ;AACF;AACA;EACEC,MAAM,EAANA,cAAM;EACN;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEC,kBAAkB,EAAEA,CAAA,KAAML,sBAAe,CAACM,WAAW,CAAC,CAAC,CAACD,kBAAkB;EAC1E;AACF;AACA;EACEE,aAAa,EAAbA,qBAAa;EACb;AACF;AACA;EACEC,WAAW,EAAXA,mBAAW;EACX;AACF;AACA;EACEC,cAAc,EAAdA,sBAAc;EACd;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEC,UAAU,EAAVA,kBAAU;EACV;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEZ,WAAW,EAAXA,mBAAW;EACX;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEa,cAAc,EAAdA,8BAAc;EACd;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEC,gBAAgB,EAAhBA,kCAAgB;EAChB;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEC,YAAY,EAAZA,oBAAY;EACZ;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEC,kBAAkB,EAAlBA;AACF,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["_checkForUpdate","require","_native","_runUpdateProcess","_store","Object","keys","forEach","key","prototype","hasOwnProperty","call","_exportNames","exports","defineProperty","enumerable","get","_wrap","_types","addListener","progress","hotUpdaterStore","setState","HotUpdater","wrap","reload","isUpdateDownloaded","getSnapshot","getAppVersion","getBundleId","getMinBundleId","getChannel","checkForUpdate","runUpdateProcess","updateBundle","getFingerprintHash"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,eAAA,GAAAC,OAAA;AACA,IAAAC,OAAA,GAAAD,OAAA;AAUA,IAAAE,iBAAA,GAAAF,OAAA;AACA,IAAAG,MAAA,GAAAH,OAAA;AAIAI,MAAA,CAAAC,IAAA,CAAAF,MAAA,EAAAG,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAH,MAAA,CAAAI,SAAA,CAAAC,cAAA,CAAAC,IAAA,CAAAC,YAAA,EAAAJ,GAAA;EAAA,IAAAA,GAAA,IAAAK,OAAA,IAAAA,OAAA,CAAAL,GAAA,MAAAJ,MAAA,CAAAI,GAAA;EAAAH,MAAA,CAAAS,cAAA,CAAAD,OAAA,EAAAL,GAAA;IAAAO,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAZ,MAAA,CAAAI,GAAA;IAAA;EAAA;AAAA;AAHA,IAAAS,KAAA,GAAAhB,OAAA;AAIA,IAAAiB,MAAA,GAAAjB,OAAA;AAOA,IAAAkB,mBAAW,EAAC,YAAY,EAAE,CAAC;EAAEC;AAAS,CAAC,KAAK;EAC1CC,sBAAe,CAACC,QAAQ,CAAC;IACvBF;EACF,CAAC,CAAC;AACJ,CAAC,CAAC;AAEK,MAAMG,UAAU,GAAAV,OAAA,CAAAU,UAAA,GAAG;EACxB;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEC,IAAI,EAAJA,UAAI;EACJ;AACF;AACA;EACEC,MAAM,EAANA,cAAM;EACN;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEC,kBAAkB,EAAEA,CAAA,KAAML,sBAAe,CAACM,WAAW,CAAC,CAAC,CAACD,kBAAkB;EAC1E;AACF;AACA;EACEE,aAAa,EAAbA,qBAAa;EACb;AACF;AACA;EACEC,WAAW,EAAXA,mBAAW;EACX;AACF;AACA;EACEC,cAAc,EAAdA,sBAAc;EACd;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEC,UAAU,EAAVA,kBAAU;EACV;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEZ,WAAW,EAAXA,mBAAW;EACX;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEa,cAAc,EAAdA,8BAAc;EACd;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEC,gBAAgB,EAAhBA,kCAAgB;EAChB;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEC,YAAY,EAAZA,oBAAY;EACZ;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEC,kBAAkB,EAAlBA;AACF,CAAC","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNative","require","_default","exports","default","TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../../src","sources":["specs/NativeHotUpdater.ts"],"mappings":";;;;;;AACA,IAAAA,YAAA,GAAAC,OAAA;AAAmD,IAAAC,QAAA,GAAAC,OAAA,CAAAC,OAAA,GA4BpCC,gCAAmB,CAACC,YAAY,CAAO,YAAY,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["_reactNative","require","_default","exports","default","TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../../src","sources":["specs/NativeHotUpdater.ts"],"mappings":";;;;;;AACA,IAAAA,YAAA,GAAAC,OAAA;AAAmD,IAAAC,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAiCpCC,gCAAmB,CAACC,YAAY,CAAO,YAAY,CAAC","ignoreList":[]}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.extractSignatureFailure = extractSignatureFailure;
7
+ exports.isSignatureVerificationError = isSignatureVerificationError;
8
+ /**
9
+ * Information about a signature verification failure.
10
+ * This is a security-critical event that indicates the bundle
11
+ * may have been tampered with or the public key is misconfigured.
12
+ */
13
+
14
+ /**
15
+ * Checks if an error is a signature verification failure.
16
+ * Matches error messages from both iOS and Android native implementations.
17
+ *
18
+ * **IMPORTANT**: This function relies on specific error message patterns from native code.
19
+ * If you change the error messages in the native implementations, update these patterns:
20
+ * - iOS: `ios/HotUpdater/Internal/SignatureVerifier.swift` (SignatureVerificationError)
21
+ * - Android: `android/src/main/java/com/hotupdater/SignatureVerifier.kt` (SignatureVerificationException)
22
+ */
23
+ function isSignatureVerificationError(error) {
24
+ if (!(error instanceof Error)) {
25
+ return false;
26
+ }
27
+ const message = error.message.toLowerCase();
28
+
29
+ // Match iOS SignatureVerificationError messages
30
+ // Match Android SignatureVerificationException messages
31
+ return message.includes("signature verification") || message.includes("public key not configured") || message.includes("public key format is invalid") || message.includes("signature format is invalid") || message.includes("bundle may be corrupted or tampered");
32
+ }
33
+
34
+ /**
35
+ * Extracts signature verification failure details from an error.
36
+ */
37
+ function extractSignatureFailure(error, bundleId) {
38
+ const normalizedError = error instanceof Error ? error : new Error(String(error));
39
+ return {
40
+ bundleId,
41
+ message: normalizedError.message,
42
+ error: normalizedError
43
+ };
44
+ }
45
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["isSignatureVerificationError","error","Error","message","toLowerCase","includes","extractSignatureFailure","bundleId","normalizedError","String"],"sourceRoot":"../../src","sources":["types.ts"],"mappings":";;;;;;;AAAA;AACA;AACA;AACA;AACA;;AAgBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASA,4BAA4BA,CAACC,KAAc,EAAW;EACpE,IAAI,EAAEA,KAAK,YAAYC,KAAK,CAAC,EAAE;IAC7B,OAAO,KAAK;EACd;EAEA,MAAMC,OAAO,GAAGF,KAAK,CAACE,OAAO,CAACC,WAAW,CAAC,CAAC;;EAE3C;EACA;EACA,OACED,OAAO,CAACE,QAAQ,CAAC,wBAAwB,CAAC,IAC1CF,OAAO,CAACE,QAAQ,CAAC,2BAA2B,CAAC,IAC7CF,OAAO,CAACE,QAAQ,CAAC,8BAA8B,CAAC,IAChDF,OAAO,CAACE,QAAQ,CAAC,6BAA6B,CAAC,IAC/CF,OAAO,CAACE,QAAQ,CAAC,qCAAqC,CAAC;AAE3D;;AAEA;AACA;AACA;AACO,SAASC,uBAAuBA,CACrCL,KAAc,EACdM,QAAgB,EACc;EAC9B,MAAMC,eAAe,GACnBP,KAAK,YAAYC,KAAK,GAAGD,KAAK,GAAG,IAAIC,KAAK,CAACO,MAAM,CAACR,KAAK,CAAC,CAAC;EAE3D,OAAO;IACLM,QAAQ;IACRJ,OAAO,EAAEK,eAAe,CAACL,OAAO;IAChCF,KAAK,EAAEO;EACT,CAAC;AACH","ignoreList":[]}
@@ -45,7 +45,7 @@ export async function checkForUpdate(options) {
45
45
  return updateBundle({
46
46
  bundleId: updateInfo.id,
47
47
  fileUrl: updateInfo.fileUrl,
48
- fileHash: updateInfo?.fileHash ?? null,
48
+ fileHash: updateInfo.fileHash,
49
49
  status: updateInfo.status
50
50
  });
51
51
  }
@@ -1 +1 @@
1
- {"version":3,"names":["Platform","HotUpdaterError","fetchUpdateInfo","getAppVersion","getBundleId","getChannel","getFingerprintHash","getMinBundleId","updateBundle","checkForUpdate","options","__DEV__","includes","OS","onError","currentAppVersion","platform","currentBundleId","minBundleId","channel","fingerprintHash","source","params","bundleId","appVersion","requestHeaders","requestTimeout","then","updateInfo","id","fileUrl","fileHash","status","getUpdateSource","baseUrl","updateStrategy"],"sourceRoot":"../../src","sources":["checkForUpdate.ts"],"mappings":";;AACA,SAASA,QAAQ,QAAQ,cAAc;AACvC,SAASC,eAAe,QAAQ,YAAS;AACzC,SAASC,eAAe,QAA2B,sBAAmB;AACtE,SACEC,aAAa,EACbC,WAAW,EACXC,UAAU,EACVC,kBAAkB,EAClBC,cAAc,EACdC,YAAY,QACP,aAAU;AAqBjB,OAAO,eAAeC,cAAcA,CAClCC,OAA8B,EACQ;EACtC,IAAIC,OAAO,EAAE;IACX,OAAO,IAAI;EACb;EAEA,IAAI,CAAC,CAAC,KAAK,EAAE,SAAS,CAAC,CAACC,QAAQ,CAACZ,QAAQ,CAACa,EAAE,CAAC,EAAE;IAC7CH,OAAO,CAACI,OAAO,GACb,IAAIb,eAAe,CAAC,iDAAiD,CACvE,CAAC;IACD,OAAO,IAAI;EACb;EAEA,MAAMc,iBAAiB,GAAGZ,aAAa,CAAC,CAAC;EACzC,MAAMa,QAAQ,GAAGhB,QAAQ,CAACa,EAAuB;EACjD,MAAMI,eAAe,GAAGb,WAAW,CAAC,CAAC;EACrC,MAAMc,WAAW,GAAGX,cAAc,CAAC,CAAC;EACpC,MAAMY,OAAO,GAAGd,UAAU,CAAC,CAAC;EAE5B,IAAI,CAACU,iBAAiB,EAAE;IACtBL,OAAO,CAACI,OAAO,GAAG,IAAIb,eAAe,CAAC,2BAA2B,CAAC,CAAC;IACnE,OAAO,IAAI;EACb;EAEA,MAAMmB,eAAe,GAAGd,kBAAkB,CAAC,CAAC;EAE5C,OAAOJ,eAAe,CAAC;IACrBmB,MAAM,EAAEX,OAAO,CAACW,MAAM;IACtBC,MAAM,EAAE;MACNC,QAAQ,EAAEN,eAAe;MACzBO,UAAU,EAAET,iBAAiB;MAC7BC,QAAQ;MACRE,WAAW;MACXC,OAAO;MACPC;IACF,CAAC;IACDK,cAAc,EAAEf,OAAO,CAACe,cAAc;IACtCX,OAAO,EAAEJ,OAAO,CAACI,OAAO;IACxBY,cAAc,EAAEhB,OAAO,CAACgB;EAC1B,CAAC,CAAC,CAACC,IAAI,CAAEC,UAAU,IAAK;IACtB,IAAI,CAACA,UAAU,EAAE;MACf,OAAO,IAAI;IACb;IAEA,OAAO;MACL,GAAGA,UAAU;MACbpB,YAAY,EAAE,MAAAA,CAAA,KAAY;QACxB,OAAOA,YAAY,CAAC;UAClBe,QAAQ,EAAEK,UAAU,CAACC,EAAE;UACvBC,OAAO,EAAEF,UAAU,CAACE,OAAO;UAC3BC,QAAQ,EAAEH,UAAU,EAAEG,QAAQ,IAAI,IAAI;UACtCC,MAAM,EAAEJ,UAAU,CAACI;QACrB,CAAC,CAAC;MACJ;IACF,CAAC;EACH,CAAC,CAAC;AACJ;AAYA,OAAO,MAAMC,eAAe,GAC1BA,CAACC,OAAe,EAAExB,OAA+B,KAChDY,MAA0B,IAAK;EAC9B,QAAQZ,OAAO,CAACyB,cAAc;IAC5B,KAAK,aAAa;MAAE;QAClB,IAAI,CAACb,MAAM,CAACF,eAAe,EAAE;UAC3B,MAAM,IAAInB,eAAe,CAAC,8BAA8B,CAAC;QAC3D;QACA,OAAO,GAAGiC,OAAO,gBAAgBZ,MAAM,CAACN,QAAQ,IAAIM,MAAM,CAACF,eAAe,IAAIE,MAAM,CAACH,OAAO,IAAIG,MAAM,CAACJ,WAAW,IAAII,MAAM,CAACC,QAAQ,EAAE;MACzI;IACA,KAAK,YAAY;MAAE;QACjB,OAAO,GAAGW,OAAO,gBAAgBZ,MAAM,CAACN,QAAQ,IAAIM,MAAM,CAACE,UAAU,IAAIF,MAAM,CAACH,OAAO,IAAIG,MAAM,CAACJ,WAAW,IAAII,MAAM,CAACC,QAAQ,EAAE;MACpI;IACA;MACE,OAAOW,OAAO;EAClB;AACF,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["Platform","HotUpdaterError","fetchUpdateInfo","getAppVersion","getBundleId","getChannel","getFingerprintHash","getMinBundleId","updateBundle","checkForUpdate","options","__DEV__","includes","OS","onError","currentAppVersion","platform","currentBundleId","minBundleId","channel","fingerprintHash","source","params","bundleId","appVersion","requestHeaders","requestTimeout","then","updateInfo","id","fileUrl","fileHash","status","getUpdateSource","baseUrl","updateStrategy"],"sourceRoot":"../../src","sources":["checkForUpdate.ts"],"mappings":";;AACA,SAASA,QAAQ,QAAQ,cAAc;AACvC,SAASC,eAAe,QAAQ,YAAS;AACzC,SAASC,eAAe,QAA2B,sBAAmB;AACtE,SACEC,aAAa,EACbC,WAAW,EACXC,UAAU,EACVC,kBAAkB,EAClBC,cAAc,EACdC,YAAY,QACP,aAAU;AAqBjB,OAAO,eAAeC,cAAcA,CAClCC,OAA8B,EACQ;EACtC,IAAIC,OAAO,EAAE;IACX,OAAO,IAAI;EACb;EAEA,IAAI,CAAC,CAAC,KAAK,EAAE,SAAS,CAAC,CAACC,QAAQ,CAACZ,QAAQ,CAACa,EAAE,CAAC,EAAE;IAC7CH,OAAO,CAACI,OAAO,GACb,IAAIb,eAAe,CAAC,iDAAiD,CACvE,CAAC;IACD,OAAO,IAAI;EACb;EAEA,MAAMc,iBAAiB,GAAGZ,aAAa,CAAC,CAAC;EACzC,MAAMa,QAAQ,GAAGhB,QAAQ,CAACa,EAAuB;EACjD,MAAMI,eAAe,GAAGb,WAAW,CAAC,CAAC;EACrC,MAAMc,WAAW,GAAGX,cAAc,CAAC,CAAC;EACpC,MAAMY,OAAO,GAAGd,UAAU,CAAC,CAAC;EAE5B,IAAI,CAACU,iBAAiB,EAAE;IACtBL,OAAO,CAACI,OAAO,GAAG,IAAIb,eAAe,CAAC,2BAA2B,CAAC,CAAC;IACnE,OAAO,IAAI;EACb;EAEA,MAAMmB,eAAe,GAAGd,kBAAkB,CAAC,CAAC;EAE5C,OAAOJ,eAAe,CAAC;IACrBmB,MAAM,EAAEX,OAAO,CAACW,MAAM;IACtBC,MAAM,EAAE;MACNC,QAAQ,EAAEN,eAAe;MACzBO,UAAU,EAAET,iBAAiB;MAC7BC,QAAQ;MACRE,WAAW;MACXC,OAAO;MACPC;IACF,CAAC;IACDK,cAAc,EAAEf,OAAO,CAACe,cAAc;IACtCX,OAAO,EAAEJ,OAAO,CAACI,OAAO;IACxBY,cAAc,EAAEhB,OAAO,CAACgB;EAC1B,CAAC,CAAC,CAACC,IAAI,CAAEC,UAAU,IAAK;IACtB,IAAI,CAACA,UAAU,EAAE;MACf,OAAO,IAAI;IACb;IAEA,OAAO;MACL,GAAGA,UAAU;MACbpB,YAAY,EAAE,MAAAA,CAAA,KAAY;QACxB,OAAOA,YAAY,CAAC;UAClBe,QAAQ,EAAEK,UAAU,CAACC,EAAE;UACvBC,OAAO,EAAEF,UAAU,CAACE,OAAO;UAC3BC,QAAQ,EAAEH,UAAU,CAACG,QAAQ;UAC7BC,MAAM,EAAEJ,UAAU,CAACI;QACrB,CAAC,CAAC;MACJ;IACF,CAAC;EACH,CAAC,CAAC;AACJ;AAYA,OAAO,MAAMC,eAAe,GAC1BA,CAACC,OAAe,EAAExB,OAA+B,KAChDY,MAA0B,IAAK;EAC9B,QAAQZ,OAAO,CAACyB,cAAc;IAC5B,KAAK,aAAa;MAAE;QAClB,IAAI,CAACb,MAAM,CAACF,eAAe,EAAE;UAC3B,MAAM,IAAInB,eAAe,CAAC,8BAA8B,CAAC;QAC3D;QACA,OAAO,GAAGiC,OAAO,gBAAgBZ,MAAM,CAACN,QAAQ,IAAIM,MAAM,CAACF,eAAe,IAAIE,MAAM,CAACH,OAAO,IAAIG,MAAM,CAACJ,WAAW,IAAII,MAAM,CAACC,QAAQ,EAAE;MACzI;IACA,KAAK,YAAY;MAAE;QACjB,OAAO,GAAGW,OAAO,gBAAgBZ,MAAM,CAACN,QAAQ,IAAIM,MAAM,CAACE,UAAU,IAAIF,MAAM,CAACH,OAAO,IAAIG,MAAM,CAACJ,WAAW,IAAII,MAAM,CAACC,QAAQ,EAAE;MACpI;IACA;MACE,OAAOW,OAAO;EAClB;AACF,CAAC","ignoreList":[]}
@@ -6,6 +6,7 @@ import { runUpdateProcess } from "./runUpdateProcess.js";
6
6
  import { hotUpdaterStore } from "./store.js";
7
7
  import { wrap } from "./wrap.js";
8
8
  export * from "./store.js";
9
+ export { extractSignatureFailure, isSignatureVerificationError } from "./types.js";
9
10
  addListener("onProgress", ({
10
11
  progress
11
12
  }) => {
@@ -1 +1 @@
1
- {"version":3,"names":["checkForUpdate","addListener","getAppVersion","getBundleId","getChannel","getFingerprintHash","getMinBundleId","reload","updateBundle","runUpdateProcess","hotUpdaterStore","wrap","progress","setState","HotUpdater","isUpdateDownloaded","getSnapshot","getUpdateSource"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA,SAASA,cAAc,QAAQ,qBAAkB;AACjD,SACEC,WAAW,EACXC,aAAa,EACbC,WAAW,EACXC,UAAU,EACVC,kBAAkB,EAClBC,cAAc,EACdC,MAAM,EACNC,YAAY,QACP,aAAU;AACjB,SAASC,gBAAgB,QAAQ,uBAAoB;AACrD,SAASC,eAAe,QAAQ,YAAS;AACzC,SAASC,IAAI,QAAQ,WAAQ;AAG7B,cAAc,YAAS;AAGvBV,WAAW,CAAC,YAAY,EAAE,CAAC;EAAEW;AAAS,CAAC,KAAK;EAC1CF,eAAe,CAACG,QAAQ,CAAC;IACvBD;EACF,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,OAAO,MAAME,UAAU,GAAG;EACxB;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEH,IAAI;EACJ;AACF;AACA;EACEJ,MAAM;EACN;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEQ,kBAAkB,EAAEA,CAAA,KAAML,eAAe,CAACM,WAAW,CAAC,CAAC,CAACD,kBAAkB;EAC1E;AACF;AACA;EACEb,aAAa;EACb;AACF;AACA;EACEC,WAAW;EACX;AACF;AACA;EACEG,cAAc;EACd;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEF,UAAU;EACV;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEH,WAAW;EACX;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACED,cAAc;EACd;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACES,gBAAgB;EAChB;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACED,YAAY;EACZ;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEH;AACF,CAAC;AAED,SAASY,eAAe,QAAQ,qBAAkB","ignoreList":[]}
1
+ {"version":3,"names":["checkForUpdate","addListener","getAppVersion","getBundleId","getChannel","getFingerprintHash","getMinBundleId","reload","updateBundle","runUpdateProcess","hotUpdaterStore","wrap","extractSignatureFailure","isSignatureVerificationError","progress","setState","HotUpdater","isUpdateDownloaded","getSnapshot","getUpdateSource"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA,SAASA,cAAc,QAAQ,qBAAkB;AACjD,SACEC,WAAW,EACXC,aAAa,EACbC,WAAW,EACXC,UAAU,EACVC,kBAAkB,EAClBC,cAAc,EACdC,MAAM,EACNC,YAAY,QACP,aAAU;AACjB,SAASC,gBAAgB,QAAQ,uBAAoB;AACrD,SAASC,eAAe,QAAQ,YAAS;AACzC,SAASC,IAAI,QAAQ,WAAQ;AAG7B,cAAc,YAAS;AACvB,SACEC,uBAAuB,EACvBC,4BAA4B,QAEvB,YAAS;AAGhBZ,WAAW,CAAC,YAAY,EAAE,CAAC;EAAEa;AAAS,CAAC,KAAK;EAC1CJ,eAAe,CAACK,QAAQ,CAAC;IACvBD;EACF,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,OAAO,MAAME,UAAU,GAAG;EACxB;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEL,IAAI;EACJ;AACF;AACA;EACEJ,MAAM;EACN;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEU,kBAAkB,EAAEA,CAAA,KAAMP,eAAe,CAACQ,WAAW,CAAC,CAAC,CAACD,kBAAkB;EAC1E;AACF;AACA;EACEf,aAAa;EACb;AACF;AACA;EACEC,WAAW;EACX;AACF;AACA;EACEG,cAAc;EACd;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEF,UAAU;EACV;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEH,WAAW;EACX;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACED,cAAc;EACd;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACES,gBAAgB;EAChB;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACED,YAAY;EACZ;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEH;AACF,CAAC;AAED,SAASc,eAAe,QAAQ,qBAAkB","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../../src","sources":["specs/NativeHotUpdater.ts"],"mappings":";;AACA,SAASA,mBAAmB,QAAQ,cAAc;AA4BlD,eAAeA,mBAAmB,CAACC,YAAY,CAAO,YAAY,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../../src","sources":["specs/NativeHotUpdater.ts"],"mappings":";;AACA,SAASA,mBAAmB,QAAQ,cAAc;AAiClD,eAAeA,mBAAmB,CAACC,YAAY,CAAO,YAAY,CAAC","ignoreList":[]}
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Information about a signature verification failure.
5
+ * This is a security-critical event that indicates the bundle
6
+ * may have been tampered with or the public key is misconfigured.
7
+ */
8
+
9
+ /**
10
+ * Checks if an error is a signature verification failure.
11
+ * Matches error messages from both iOS and Android native implementations.
12
+ *
13
+ * **IMPORTANT**: This function relies on specific error message patterns from native code.
14
+ * If you change the error messages in the native implementations, update these patterns:
15
+ * - iOS: `ios/HotUpdater/Internal/SignatureVerifier.swift` (SignatureVerificationError)
16
+ * - Android: `android/src/main/java/com/hotupdater/SignatureVerifier.kt` (SignatureVerificationException)
17
+ */
18
+ export function isSignatureVerificationError(error) {
19
+ if (!(error instanceof Error)) {
20
+ return false;
21
+ }
22
+ const message = error.message.toLowerCase();
23
+
24
+ // Match iOS SignatureVerificationError messages
25
+ // Match Android SignatureVerificationException messages
26
+ return message.includes("signature verification") || message.includes("public key not configured") || message.includes("public key format is invalid") || message.includes("signature format is invalid") || message.includes("bundle may be corrupted or tampered");
27
+ }
28
+
29
+ /**
30
+ * Extracts signature verification failure details from an error.
31
+ */
32
+ export function extractSignatureFailure(error, bundleId) {
33
+ const normalizedError = error instanceof Error ? error : new Error(String(error));
34
+ return {
35
+ bundleId,
36
+ message: normalizedError.message,
37
+ error: normalizedError
38
+ };
39
+ }
40
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["isSignatureVerificationError","error","Error","message","toLowerCase","includes","extractSignatureFailure","bundleId","normalizedError","String"],"sourceRoot":"../../src","sources":["types.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;;AAgBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASA,4BAA4BA,CAACC,KAAc,EAAW;EACpE,IAAI,EAAEA,KAAK,YAAYC,KAAK,CAAC,EAAE;IAC7B,OAAO,KAAK;EACd;EAEA,MAAMC,OAAO,GAAGF,KAAK,CAACE,OAAO,CAACC,WAAW,CAAC,CAAC;;EAE3C;EACA;EACA,OACED,OAAO,CAACE,QAAQ,CAAC,wBAAwB,CAAC,IAC1CF,OAAO,CAACE,QAAQ,CAAC,2BAA2B,CAAC,IAC7CF,OAAO,CAACE,QAAQ,CAAC,8BAA8B,CAAC,IAChDF,OAAO,CAACE,QAAQ,CAAC,6BAA6B,CAAC,IAC/CF,OAAO,CAACE,QAAQ,CAAC,qCAAqC,CAAC;AAE3D;;AAEA;AACA;AACA;AACA,OAAO,SAASC,uBAAuBA,CACrCL,KAAc,EACdM,QAAgB,EACc;EAC9B,MAAMC,eAAe,GACnBP,KAAK,YAAYC,KAAK,GAAGD,KAAK,GAAG,IAAIC,KAAK,CAACO,MAAM,CAACR,KAAK,CAAC,CAAC;EAE3D,OAAO;IACLM,QAAQ;IACRJ,OAAO,EAAEK,eAAe,CAACL,OAAO;IAChCF,KAAK,EAAEO;EACT,CAAC;AACH","ignoreList":[]}
@@ -3,6 +3,7 @@ import { updateBundle } from "./native";
3
3
  import { wrap } from "./wrap";
4
4
  export type { HotUpdaterEvent } from "./native";
5
5
  export * from "./store";
6
+ export { extractSignatureFailure, isSignatureVerificationError, type SignatureVerificationFailure, } from "./types";
6
7
  export type { HotUpdaterOptions } from "./wrap";
7
8
  export declare const HotUpdater: {
8
9
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAQL,YAAY,EACb,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE9B,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,cAAc,SAAS,CAAC;AACxB,YAAY,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAQhD,eAAO,MAAM,UAAU;IACrB;;;;;;;;;;;;;;;;;;;;;OAqBG;;IAEH;;OAEG;;IAEH;;;;;;;;;;;;;;;;OAgBG;;IAEH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAEH;;;;;;;;;;;;OAYG;;IAEH;;;;;;;;;;;;;;;;OAgBG;;IAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;;IAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;;IAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;;IAEH;;;;;;;;;;OAUG;;CAEJ,CAAC;AAEF,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAQL,YAAY,EACb,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE9B,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,cAAc,SAAS,CAAC;AACxB,OAAO,EACL,uBAAuB,EACvB,4BAA4B,EAC5B,KAAK,4BAA4B,GAClC,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAQhD,eAAO,MAAM,UAAU;IACrB;;;;;;;;;;;;;;;;;;;;;OAqBG;;IAEH;;OAEG;;IAEH;;;;;;;;;;;;;;;;OAgBG;;IAEH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAEH;;;;;;;;;;;;OAYG;;IAEH;;;;;;;;;;;;;;;;OAgBG;;IAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;;IAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;;IAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;;IAEH;;;;;;;;;;OAUG;;CAEJ,CAAC;AAEF,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC"}
@@ -3,8 +3,13 @@ export interface UpdateBundleParams {
3
3
  bundleId: string;
4
4
  fileUrl: string | null;
5
5
  /**
6
- * SHA256 hash of the bundle file for integrity verification.
7
- * If provided, the native layer will verify the downloaded file's hash.
6
+ * File hash for integrity/signature verification.
7
+ *
8
+ * Format depends on signing configuration:
9
+ * - Signed: `sig:<base64_signature>` - Native will verify signature (and implicitly hash)
10
+ * - Unsigned: `<hex_hash>` - Native will verify SHA256 hash only
11
+ *
12
+ * Native determines verification mode by checking for "sig:" prefix.
8
13
  */
9
14
  fileHash: string | null;
10
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"NativeHotUpdater.d.ts","sourceRoot":"","sources":["../../../../src/specs/NativeHotUpdater.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB;;;OAGG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,IAAK,SAAQ,WAAW;IAEvC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAG3D,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,YAAY,EAAE,MAAM;QAC3B,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,OAAO,EAAE,MAAM,CAAC;QAChB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;KACjC,CAAC;CACH;;AAED,wBAAoE"}
1
+ {"version":3,"file":"NativeHotUpdater.d.ts","sourceRoot":"","sources":["../../../../src/specs/NativeHotUpdater.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB;;;;;;;;OAQG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,IAAK,SAAQ,WAAW;IAEvC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAG3D,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,YAAY,EAAE,MAAM;QAC3B,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,OAAO,EAAE,MAAM,CAAC;QAChB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;KACjC,CAAC;CACH;;AAED,wBAAoE"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Information about a signature verification failure.
3
+ * This is a security-critical event that indicates the bundle
4
+ * may have been tampered with or the public key is misconfigured.
5
+ */
6
+ export interface SignatureVerificationFailure {
7
+ /**
8
+ * The bundle ID that failed verification.
9
+ */
10
+ bundleId: string;
11
+ /**
12
+ * Human-readable error message from the native layer.
13
+ */
14
+ message: string;
15
+ /**
16
+ * The underlying error object.
17
+ */
18
+ error: Error;
19
+ }
20
+ /**
21
+ * Checks if an error is a signature verification failure.
22
+ * Matches error messages from both iOS and Android native implementations.
23
+ *
24
+ * **IMPORTANT**: This function relies on specific error message patterns from native code.
25
+ * If you change the error messages in the native implementations, update these patterns:
26
+ * - iOS: `ios/HotUpdater/Internal/SignatureVerifier.swift` (SignatureVerificationError)
27
+ * - Android: `android/src/main/java/com/hotupdater/SignatureVerifier.kt` (SignatureVerificationException)
28
+ */
29
+ export declare function isSignatureVerificationError(error: unknown): boolean;
30
+ /**
31
+ * Extracts signature verification failure details from an error.
32
+ */
33
+ export declare function extractSignatureFailure(error: unknown, bundleId: string): SignatureVerificationFailure;
34
+ //# sourceMappingURL=types.d.ts.map