@otakit/capacitor-updater 1.0.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/LICENSE +21 -0
- package/README.md +183 -0
- package/UpdatekitUpdater.podspec +18 -0
- package/android/build.gradle +49 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/java/com/updatekit/updater/BundleInfo.java +100 -0
- package/android/src/main/java/com/updatekit/updater/BundleStatus.java +28 -0
- package/android/src/main/java/com/updatekit/updater/BundleStore.java +264 -0
- package/android/src/main/java/com/updatekit/updater/DateUtils.java +17 -0
- package/android/src/main/java/com/updatekit/updater/HashUtils.java +32 -0
- package/android/src/main/java/com/updatekit/updater/HostedManifestKeys.java +37 -0
- package/android/src/main/java/com/updatekit/updater/ManifestClient.java +209 -0
- package/android/src/main/java/com/updatekit/updater/ManifestVerifier.java +146 -0
- package/android/src/main/java/com/updatekit/updater/StatsClient.java +80 -0
- package/android/src/main/java/com/updatekit/updater/UpdaterPlugin.java +963 -0
- package/android/src/main/java/com/updatekit/updater/ZipUtils.java +72 -0
- package/dist/esm/definitions.d.ts +229 -0
- package/dist/esm/definitions.d.ts.map +1 -0
- package/dist/esm/definitions.js +17 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +85 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +25 -0
- package/dist/esm/web.d.ts.map +1 -0
- package/dist/esm/web.js +56 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +165 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +168 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Sources/UpdaterPlugin/BundleInfo.swift +39 -0
- package/ios/Sources/UpdaterPlugin/BundleStatus.swift +9 -0
- package/ios/Sources/UpdaterPlugin/BundleStore.swift +233 -0
- package/ios/Sources/UpdaterPlugin/Downloader.swift +120 -0
- package/ios/Sources/UpdaterPlugin/HashUtils.swift +33 -0
- package/ios/Sources/UpdaterPlugin/HostedManifestKeys.swift +23 -0
- package/ios/Sources/UpdaterPlugin/ManifestClient.swift +161 -0
- package/ios/Sources/UpdaterPlugin/ManifestVerifier.swift +115 -0
- package/ios/Sources/UpdaterPlugin/StatsClient.swift +66 -0
- package/ios/Sources/UpdaterPlugin/UpdaterPlugin.m +15 -0
- package/ios/Sources/UpdaterPlugin/UpdaterPlugin.swift +913 -0
- package/ios/Sources/UpdaterPlugin/ZipUtils.swift +90 -0
- package/package.json +85 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import ZIPFoundation
|
|
3
|
+
|
|
4
|
+
enum ZipUtilsError: Error {
|
|
5
|
+
case invalidZip
|
|
6
|
+
case pathTraversal(String)
|
|
7
|
+
case absolutePath(String)
|
|
8
|
+
case symlinkNotAllowed(String)
|
|
9
|
+
case unsupportedEntry(String)
|
|
10
|
+
case fileCountExceeded(Int)
|
|
11
|
+
case totalSizeExceeded(UInt64)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
final class ZipUtils {
|
|
15
|
+
private let maxFiles = 10_000
|
|
16
|
+
private let maxTotalSize: UInt64 = 500_000_000 // 500 MB
|
|
17
|
+
|
|
18
|
+
func extractSecurely(zipURL: URL, to destination: URL) throws {
|
|
19
|
+
guard let archive = Archive(url: zipURL, accessMode: .read) else {
|
|
20
|
+
throw ZipUtilsError.invalidZip
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let destinationPath = destination.standardizedFileURL.path
|
|
24
|
+
let destinationPrefix =
|
|
25
|
+
destinationPath.hasSuffix("/") ? destinationPath : "\(destinationPath)/"
|
|
26
|
+
|
|
27
|
+
var fileCount = 0
|
|
28
|
+
var totalSize: UInt64 = 0
|
|
29
|
+
|
|
30
|
+
for entry in archive {
|
|
31
|
+
if entry.path.hasPrefix("/") {
|
|
32
|
+
throw ZipUtilsError.absolutePath(entry.path)
|
|
33
|
+
}
|
|
34
|
+
if entry.path.contains("..") {
|
|
35
|
+
throw ZipUtilsError.pathTraversal(entry.path)
|
|
36
|
+
}
|
|
37
|
+
if entry.type == .symlink {
|
|
38
|
+
throw ZipUtilsError.symlinkNotAllowed(entry.path)
|
|
39
|
+
}
|
|
40
|
+
if entry.type != .directory && entry.type != .file {
|
|
41
|
+
throw ZipUtilsError.unsupportedEntry(entry.path)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let outputURL = destination
|
|
45
|
+
.appendingPathComponent(entry.path)
|
|
46
|
+
.standardizedFileURL
|
|
47
|
+
let outputPath = outputURL.path
|
|
48
|
+
if !(outputPath == destinationPath || outputPath.hasPrefix(destinationPrefix))
|
|
49
|
+
{
|
|
50
|
+
throw ZipUtilsError.pathTraversal(entry.path)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if entry.type == .file {
|
|
54
|
+
fileCount += 1
|
|
55
|
+
if fileCount > maxFiles {
|
|
56
|
+
throw ZipUtilsError.fileCountExceeded(fileCount)
|
|
57
|
+
}
|
|
58
|
+
totalSize += entry.uncompressedSize
|
|
59
|
+
if totalSize > maxTotalSize {
|
|
60
|
+
throw ZipUtilsError.totalSizeExceeded(totalSize)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
try FileManager.default.createDirectory(
|
|
66
|
+
at: destination,
|
|
67
|
+
withIntermediateDirectories: true
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
for entry in archive {
|
|
71
|
+
let outputURL = destination.appendingPathComponent(entry.path)
|
|
72
|
+
switch entry.type {
|
|
73
|
+
case .directory:
|
|
74
|
+
try FileManager.default.createDirectory(
|
|
75
|
+
at: outputURL,
|
|
76
|
+
withIntermediateDirectories: true
|
|
77
|
+
)
|
|
78
|
+
case .file:
|
|
79
|
+
let parent = outputURL.deletingLastPathComponent()
|
|
80
|
+
try FileManager.default.createDirectory(
|
|
81
|
+
at: parent,
|
|
82
|
+
withIntermediateDirectories: true
|
|
83
|
+
)
|
|
84
|
+
_ = try archive.extract(entry, to: outputURL)
|
|
85
|
+
default:
|
|
86
|
+
throw ZipUtilsError.unsupportedEntry(entry.path)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@otakit/capacitor-updater",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Capacitor plugin for OTA updates",
|
|
5
|
+
"main": "dist/plugin.cjs.js",
|
|
6
|
+
"module": "dist/esm/index.js",
|
|
7
|
+
"types": "dist/esm/index.d.ts",
|
|
8
|
+
"unpkg": "dist/plugin.js",
|
|
9
|
+
"publishConfig": {
|
|
10
|
+
"access": "public"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"LICENSE",
|
|
14
|
+
"android/src/main/",
|
|
15
|
+
"android/build.gradle",
|
|
16
|
+
"dist/",
|
|
17
|
+
"ios/Sources/",
|
|
18
|
+
"ios/Tests/",
|
|
19
|
+
"UpdatekitUpdater.podspec"
|
|
20
|
+
],
|
|
21
|
+
"author": "OtaKit",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/OtaKit/otakit.git"
|
|
26
|
+
},
|
|
27
|
+
"bugs": {
|
|
28
|
+
"url": "https://github.com/OtaKit/otakit/issues"
|
|
29
|
+
},
|
|
30
|
+
"homepage": "https://github.com/OtaKit/otakit/tree/main/packages/capacitor-plugin#readme",
|
|
31
|
+
"keywords": [
|
|
32
|
+
"capacitor",
|
|
33
|
+
"plugin",
|
|
34
|
+
"native",
|
|
35
|
+
"ota",
|
|
36
|
+
"update"
|
|
37
|
+
],
|
|
38
|
+
"scripts": {
|
|
39
|
+
"verify": "npm run verify:minimal",
|
|
40
|
+
"verify:minimal": "node -e \"console.log('Native verification is not wired yet')\"",
|
|
41
|
+
"verify:web": "npm run build",
|
|
42
|
+
"lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint",
|
|
43
|
+
"fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --fix --format",
|
|
44
|
+
"eslint": "eslint src",
|
|
45
|
+
"prettier": "prettier \"src/**/*.{ts,js}\" \"android/src/main/java/**/*.java\" --plugin=prettier-plugin-java",
|
|
46
|
+
"swiftlint": "node-swiftlint",
|
|
47
|
+
"docgen": "docgen --api UpdaterPlugin --output-readme README.md --output-json dist/docs.json",
|
|
48
|
+
"build": "npm run clean && tsc && rollup -c rollup.config.mjs",
|
|
49
|
+
"clean": "rimraf ./dist",
|
|
50
|
+
"watch": "tsc --watch",
|
|
51
|
+
"prepublishOnly": "npm run build",
|
|
52
|
+
"typecheck": "tsc --noEmit"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@capacitor/android": "^8.0.2",
|
|
56
|
+
"@capacitor/core": "8.0.2",
|
|
57
|
+
"@capacitor/docgen": "^0.3.1",
|
|
58
|
+
"@capacitor/ios": "^8.0.2",
|
|
59
|
+
"@eslint/js": "^9.18.0",
|
|
60
|
+
"@ionic/prettier-config": "^4.0.0",
|
|
61
|
+
"@ionic/swiftlint-config": "^2.0.0",
|
|
62
|
+
"eslint": "^9.39.2",
|
|
63
|
+
"typescript-eslint": "^8.32.1",
|
|
64
|
+
"prettier": "^3.8.1",
|
|
65
|
+
"prettier-plugin-java": "^2.8.1",
|
|
66
|
+
"rimraf": "^6.1.2",
|
|
67
|
+
"rollup": "^4.57.1",
|
|
68
|
+
"swiftlint": "^2.0.0",
|
|
69
|
+
"typescript": "^5.9.3"
|
|
70
|
+
},
|
|
71
|
+
"peerDependencies": {
|
|
72
|
+
"@capacitor/core": "^8.0.2"
|
|
73
|
+
},
|
|
74
|
+
"engines": {
|
|
75
|
+
"node": ">=20.0.0"
|
|
76
|
+
},
|
|
77
|
+
"capacitor": {
|
|
78
|
+
"ios": {
|
|
79
|
+
"src": "ios"
|
|
80
|
+
},
|
|
81
|
+
"android": {
|
|
82
|
+
"src": "android"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|