@appzung/react-native-code-push 5.7.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/AlertAdapter.js +24 -0
- package/CONTRIBUTING.md +136 -0
- package/CodePush.js +666 -0
- package/CodePush.podspec +27 -0
- package/LICENSE.md +13 -0
- package/README.md +386 -0
- package/RestartManager.js +59 -0
- package/android/app/build.gradle +31 -0
- package/android/app/proguard-rules.pro +25 -0
- package/android/app/src/main/AndroidManifest.xml +10 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java +395 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushBuilder.java +37 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushConstants.java +34 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushDialog.java +102 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushInstallMode.java +16 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushInvalidPublicKeyException.java +12 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushInvalidUpdateException.java +7 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushMalformedDataException.java +12 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushNativeModule.java +641 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushNotInitializedException.java +12 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushTelemetryManager.java +175 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUnknownException.java +12 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateManager.java +369 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateState.java +15 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateUtils.java +267 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUtils.java +236 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/DownloadProgress.java +30 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/DownloadProgressCallback.java +5 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java +190 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/ReactInstanceHolder.java +17 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/SettingsManager.java +173 -0
- package/android/build.gradle +20 -0
- package/android/codepush.gradle +113 -0
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +5 -0
- package/android/gradle.properties +20 -0
- package/android/gradlew +164 -0
- package/android/gradlew.bat +90 -0
- package/android/settings.gradle +1 -0
- package/docs/api-android.md +65 -0
- package/docs/api-ios.md +31 -0
- package/docs/api-js.md +592 -0
- package/docs/multi-deployment-testing-android.md +107 -0
- package/docs/multi-deployment-testing-ios.md +53 -0
- package/docs/setup-android.md +406 -0
- package/docs/setup-ios.md +229 -0
- package/docs/setup-windows.md +65 -0
- package/gulpfile.js +302 -0
- package/ios/CodePush/Base64/Base64/MF_Base64Additions.h +34 -0
- package/ios/CodePush/Base64/Base64/MF_Base64Additions.m +252 -0
- package/ios/CodePush/Base64/README.md +47 -0
- package/ios/CodePush/CodePush.h +235 -0
- package/ios/CodePush/CodePush.m +1041 -0
- package/ios/CodePush/CodePushConfig.m +116 -0
- package/ios/CodePush/CodePushDownloadHandler.m +130 -0
- package/ios/CodePush/CodePushErrorUtils.m +20 -0
- package/ios/CodePush/CodePushPackage.m +598 -0
- package/ios/CodePush/CodePushTelemetryManager.m +175 -0
- package/ios/CodePush/CodePushUpdateUtils.m +376 -0
- package/ios/CodePush/CodePushUtils.m +9 -0
- package/ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithm.h +69 -0
- package/ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithmFactory.h +16 -0
- package/ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithmFactory.m +51 -0
- package/ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithmNone.h +15 -0
- package/ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithmNone.m +55 -0
- package/ios/CodePush/JWT/Core/Algorithms/ESFamily/JWTAlgorithmESBase.h +24 -0
- package/ios/CodePush/JWT/Core/Algorithms/ESFamily/JWTAlgorithmESBase.m +41 -0
- package/ios/CodePush/JWT/Core/Algorithms/HSFamily/JWTAlgorithmHSBase.h +28 -0
- package/ios/CodePush/JWT/Core/Algorithms/HSFamily/JWTAlgorithmHSBase.m +205 -0
- package/ios/CodePush/JWT/Core/Algorithms/Holders/JWTAlgorithmDataHolder.h +103 -0
- package/ios/CodePush/JWT/Core/Algorithms/Holders/JWTAlgorithmDataHolder.m +322 -0
- package/ios/CodePush/JWT/Core/Algorithms/Holders/JWTAlgorithmDataHolderChain.h +37 -0
- package/ios/CodePush/JWT/Core/Algorithms/Holders/JWTAlgorithmDataHolderChain.m +145 -0
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/JWTAlgorithmRSBase.h +35 -0
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/JWTAlgorithmRSBase.m +551 -0
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/JWTRSAlgorithm.h +23 -0
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoKey.h +43 -0
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoKey.m +230 -0
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoKeyExtractor.h +31 -0
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoKeyExtractor.m +113 -0
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoSecurity.h +38 -0
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoSecurity.m +500 -0
- package/ios/CodePush/JWT/Core/ClaimSet/JWTClaim.h +18 -0
- package/ios/CodePush/JWT/Core/ClaimSet/JWTClaim.m +214 -0
- package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSet.h +23 -0
- package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSet.m +29 -0
- package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSetSerializer.h +19 -0
- package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSetSerializer.m +68 -0
- package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSetVerifier.h +18 -0
- package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSetVerifier.m +72 -0
- package/ios/CodePush/JWT/Core/Coding/JWTCoding+ResultTypes.h +67 -0
- package/ios/CodePush/JWT/Core/Coding/JWTCoding+ResultTypes.m +111 -0
- package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionOne.h +119 -0
- package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionOne.m +307 -0
- package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionThree.h +94 -0
- package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionThree.m +619 -0
- package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionTwo.h +164 -0
- package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionTwo.m +514 -0
- package/ios/CodePush/JWT/Core/Coding/JWTCoding.h +24 -0
- package/ios/CodePush/JWT/Core/Coding/JWTCoding.m +11 -0
- package/ios/CodePush/JWT/Core/FrameworkSupplement/JWT.h +52 -0
- package/ios/CodePush/JWT/Core/FrameworkSupplement/Map.modulemap +5 -0
- package/ios/CodePush/JWT/Core/Supplement/JWTBase64Coder.h +28 -0
- package/ios/CodePush/JWT/Core/Supplement/JWTBase64Coder.m +70 -0
- package/ios/CodePush/JWT/Core/Supplement/JWTDeprecations.h +22 -0
- package/ios/CodePush/JWT/Core/Supplement/JWTErrorDescription.h +34 -0
- package/ios/CodePush/JWT/Core/Supplement/JWTErrorDescription.m +73 -0
- package/ios/CodePush/JWT/LICENSE +19 -0
- package/ios/CodePush/JWT/README.md +489 -0
- package/ios/CodePush/RCTConvert+CodePushInstallMode.m +20 -0
- package/ios/CodePush/RCTConvert+CodePushUpdateState.m +20 -0
- package/ios/CodePush/SSZipArchive/Common.h +81 -0
- package/ios/CodePush/SSZipArchive/README.md +1 -0
- package/ios/CodePush/SSZipArchive/SSZipArchive.h +76 -0
- package/ios/CodePush/SSZipArchive/SSZipArchive.m +691 -0
- package/ios/CodePush/SSZipArchive/aes/aes.h +198 -0
- package/ios/CodePush/SSZipArchive/aes/aes_via_ace.h +541 -0
- package/ios/CodePush/SSZipArchive/aes/aescrypt.c +294 -0
- package/ios/CodePush/SSZipArchive/aes/aeskey.c +548 -0
- package/ios/CodePush/SSZipArchive/aes/aesopt.h +739 -0
- package/ios/CodePush/SSZipArchive/aes/aestab.c +391 -0
- package/ios/CodePush/SSZipArchive/aes/aestab.h +173 -0
- package/ios/CodePush/SSZipArchive/aes/brg_endian.h +126 -0
- package/ios/CodePush/SSZipArchive/aes/brg_types.h +219 -0
- package/ios/CodePush/SSZipArchive/aes/entropy.c +54 -0
- package/ios/CodePush/SSZipArchive/aes/entropy.h +16 -0
- package/ios/CodePush/SSZipArchive/aes/fileenc.c +144 -0
- package/ios/CodePush/SSZipArchive/aes/fileenc.h +121 -0
- package/ios/CodePush/SSZipArchive/aes/hmac.c +145 -0
- package/ios/CodePush/SSZipArchive/aes/hmac.h +103 -0
- package/ios/CodePush/SSZipArchive/aes/prng.c +155 -0
- package/ios/CodePush/SSZipArchive/aes/prng.h +82 -0
- package/ios/CodePush/SSZipArchive/aes/pwd2key.c +103 -0
- package/ios/CodePush/SSZipArchive/aes/pwd2key.h +57 -0
- package/ios/CodePush/SSZipArchive/aes/sha1.c +258 -0
- package/ios/CodePush/SSZipArchive/aes/sha1.h +73 -0
- package/ios/CodePush/SSZipArchive/minizip/crypt.h +130 -0
- package/ios/CodePush/SSZipArchive/minizip/ioapi.c +369 -0
- package/ios/CodePush/SSZipArchive/minizip/ioapi.h +175 -0
- package/ios/CodePush/SSZipArchive/minizip/mztools.c +284 -0
- package/ios/CodePush/SSZipArchive/minizip/mztools.h +31 -0
- package/ios/CodePush/SSZipArchive/minizip/unzip.c +1839 -0
- package/ios/CodePush/SSZipArchive/minizip/unzip.h +248 -0
- package/ios/CodePush/SSZipArchive/minizip/zip.c +1910 -0
- package/ios/CodePush/SSZipArchive/minizip/zip.h +202 -0
- package/ios/CodePush.xcodeproj/project.pbxproj +937 -0
- package/ios/CodePush.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- package/ios/CodePush.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/logging.js +6 -0
- package/package-mixins.js +69 -0
- package/package.json +47 -0
- package/request-fetch-adapter.js +52 -0
- package/scripts/generateBundledResourcesHash.js +125 -0
- package/scripts/getFilesInFolder.js +19 -0
- package/scripts/postlink/android/postlink.js +87 -0
- package/scripts/postlink/ios/postlink.js +116 -0
- package/scripts/postlink/run.js +11 -0
- package/scripts/postunlink/android/postunlink.js +74 -0
- package/scripts/postunlink/ios/postunlink.js +87 -0
- package/scripts/postunlink/run.js +11 -0
- package/scripts/recordFilesBeforeBundleCommand.js +41 -0
- package/scripts/tools/linkToolsAndroid.js +57 -0
- package/scripts/tools/linkToolsIos.js +130 -0
- package/typings/react-native-code-push.d.ts +446 -0
- package/windows/CodePush/CodePush.csproj +128 -0
- package/windows/CodePush/CodePushUtils.cs +47 -0
- package/windows/CodePush/FileUtils.cs +40 -0
- package/windows/CodePush/Properties/AssemblyInfo.cs +29 -0
- package/windows/CodePush/Properties/CodePush.rd.xml +33 -0
- package/windows/CodePush/UpdateManager.cs +305 -0
- package/windows/CodePush/UpdateUtils.cs +46 -0
- package/windows/CodePush.Net46/Adapters/Http/HttpProgress.cs +28 -0
- package/windows/CodePush.Net46/Adapters/Storage/ApplicationDataContainer.cs +106 -0
- package/windows/CodePush.Net46/CodePush.Net46.csproj +103 -0
- package/windows/CodePush.Net46/CodePushUtils.cs +158 -0
- package/windows/CodePush.Net46/FileUtils.cs +55 -0
- package/windows/CodePush.Net46/Properties/AssemblyInfo.cs +36 -0
- package/windows/CodePush.Net46/UpdateManager.cs +330 -0
- package/windows/CodePush.Net46/UpdateUtils.cs +70 -0
- package/windows/CodePush.Net46/packages.config +5 -0
- package/windows/CodePush.Shared/CodePush.Shared.projitems +22 -0
- package/windows/CodePush.Shared/CodePush.Shared.shproj +13 -0
- package/windows/CodePush.Shared/CodePushConstants.cs +35 -0
- package/windows/CodePush.Shared/CodePushNativeModule.cs +329 -0
- package/windows/CodePush.Shared/CodePushReactPackage.cs +235 -0
- package/windows/CodePush.Shared/CodePushUtils.cs +70 -0
- package/windows/CodePush.Shared/InstallMode.cs +9 -0
- package/windows/CodePush.Shared/MinimumBackgroundListener.cs +44 -0
- package/windows/CodePush.Shared/SettingsManager.cs +148 -0
- package/windows/CodePush.Shared/TelemetryManager.cs +250 -0
- package/windows/CodePush.Shared/UpdateState.cs +9 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
#import "CodePush.h"
|
|
2
|
+
|
|
3
|
+
static NSString *const AppVersionKey = @"appVersion";
|
|
4
|
+
static NSString *const DeploymentFailed = @"DeploymentFailed";
|
|
5
|
+
static NSString *const DeploymentKeyKey = @"deploymentKey";
|
|
6
|
+
static NSString *const DeploymentSucceeded = @"DeploymentSucceeded";
|
|
7
|
+
static NSString *const LabelKey = @"label";
|
|
8
|
+
static NSString *const LastDeploymentReportKey = @"CODE_PUSH_LAST_DEPLOYMENT_REPORT";
|
|
9
|
+
static NSString *const PackageKey = @"package";
|
|
10
|
+
static NSString *const PreviousDeploymentKeyKey = @"previousDeploymentKey";
|
|
11
|
+
static NSString *const PreviousLabelOrAppVersionKey = @"previousLabelOrAppVersion";
|
|
12
|
+
static NSString *const RetryDeploymentReportKey = @"CODE_PUSH_RETRY_DEPLOYMENT_REPORT";
|
|
13
|
+
static NSString *const StatusKey = @"status";
|
|
14
|
+
|
|
15
|
+
@implementation CodePushTelemetryManager
|
|
16
|
+
|
|
17
|
+
+ (NSDictionary *)getBinaryUpdateReport:(NSString *)appVersion
|
|
18
|
+
{
|
|
19
|
+
NSString *previousStatusReportIdentifier = [self getPreviousStatusReportIdentifier];
|
|
20
|
+
if (previousStatusReportIdentifier == nil) {
|
|
21
|
+
[self clearRetryStatusReport];
|
|
22
|
+
return @{ AppVersionKey: appVersion };
|
|
23
|
+
} else if (![previousStatusReportIdentifier isEqualToString:appVersion]) {
|
|
24
|
+
if ([self isStatusReportIdentifierCodePushLabel:previousStatusReportIdentifier]) {
|
|
25
|
+
NSString *previousDeploymentKey = [self getDeploymentKeyFromStatusReportIdentifier:previousStatusReportIdentifier];
|
|
26
|
+
NSString *previousLabel = [self getVersionLabelFromStatusReportIdentifier:previousStatusReportIdentifier];
|
|
27
|
+
[self clearRetryStatusReport];
|
|
28
|
+
return @{
|
|
29
|
+
AppVersionKey: appVersion,
|
|
30
|
+
PreviousDeploymentKeyKey: previousDeploymentKey,
|
|
31
|
+
PreviousLabelOrAppVersionKey: previousLabel
|
|
32
|
+
};
|
|
33
|
+
} else {
|
|
34
|
+
[self clearRetryStatusReport];
|
|
35
|
+
// Previous status report was with a binary app version.
|
|
36
|
+
return @{
|
|
37
|
+
AppVersionKey: appVersion,
|
|
38
|
+
PreviousLabelOrAppVersionKey: previousStatusReportIdentifier
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return nil;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
+ (NSDictionary *)getRetryStatusReport
|
|
47
|
+
{
|
|
48
|
+
NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
|
|
49
|
+
NSDictionary *retryStatusReport = [preferences objectForKey:RetryDeploymentReportKey];
|
|
50
|
+
if (retryStatusReport) {
|
|
51
|
+
[self clearRetryStatusReport];
|
|
52
|
+
return retryStatusReport;
|
|
53
|
+
} else {
|
|
54
|
+
return nil;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
+ (NSDictionary *)getRollbackReport:(NSDictionary *)lastFailedPackage
|
|
59
|
+
{
|
|
60
|
+
return @{
|
|
61
|
+
PackageKey: lastFailedPackage,
|
|
62
|
+
StatusKey: DeploymentFailed
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
+ (NSDictionary *)getUpdateReport:(NSDictionary *)currentPackage
|
|
67
|
+
{
|
|
68
|
+
NSString *currentPackageIdentifier = [self getPackageStatusReportIdentifier:currentPackage];
|
|
69
|
+
NSString *previousStatusReportIdentifier = [self getPreviousStatusReportIdentifier];
|
|
70
|
+
if (currentPackageIdentifier) {
|
|
71
|
+
if (previousStatusReportIdentifier == nil) {
|
|
72
|
+
[self clearRetryStatusReport];
|
|
73
|
+
return @{
|
|
74
|
+
PackageKey: currentPackage,
|
|
75
|
+
StatusKey: DeploymentSucceeded
|
|
76
|
+
};
|
|
77
|
+
} else if (![previousStatusReportIdentifier isEqualToString:currentPackageIdentifier]) {
|
|
78
|
+
[self clearRetryStatusReport];
|
|
79
|
+
if ([self isStatusReportIdentifierCodePushLabel:previousStatusReportIdentifier]) {
|
|
80
|
+
NSString *previousDeploymentKey = [self getDeploymentKeyFromStatusReportIdentifier:previousStatusReportIdentifier];
|
|
81
|
+
NSString *previousLabel = [self getVersionLabelFromStatusReportIdentifier:previousStatusReportIdentifier];
|
|
82
|
+
return @{
|
|
83
|
+
PackageKey: currentPackage,
|
|
84
|
+
StatusKey: DeploymentSucceeded,
|
|
85
|
+
PreviousDeploymentKeyKey: previousDeploymentKey,
|
|
86
|
+
PreviousLabelOrAppVersionKey: previousLabel
|
|
87
|
+
};
|
|
88
|
+
} else {
|
|
89
|
+
// Previous status report was with a binary app version.
|
|
90
|
+
return @{
|
|
91
|
+
PackageKey: currentPackage,
|
|
92
|
+
StatusKey: DeploymentSucceeded,
|
|
93
|
+
PreviousLabelOrAppVersionKey: previousStatusReportIdentifier
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return nil;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
+ (void)recordStatusReported:(NSDictionary *)statusReport
|
|
103
|
+
{
|
|
104
|
+
// We don't need to record rollback reports, so exit early if that's what was specified.
|
|
105
|
+
if ([DeploymentFailed isEqualToString:statusReport[StatusKey]]) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (statusReport[AppVersionKey]) {
|
|
110
|
+
[self saveStatusReportedForIdentifier:statusReport[AppVersionKey]];
|
|
111
|
+
} else if (statusReport[PackageKey]) {
|
|
112
|
+
NSString *packageIdentifier = [self getPackageStatusReportIdentifier:statusReport[PackageKey]];
|
|
113
|
+
[self saveStatusReportedForIdentifier:packageIdentifier];
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
+ (void)saveStatusReportForRetry:(NSDictionary *)statusReport
|
|
118
|
+
{
|
|
119
|
+
NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
|
|
120
|
+
[preferences setValue:statusReport forKey:RetryDeploymentReportKey];
|
|
121
|
+
[preferences synchronize];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
#pragma mark - private methods
|
|
125
|
+
|
|
126
|
+
+ (void)clearRetryStatusReport
|
|
127
|
+
{
|
|
128
|
+
NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
|
|
129
|
+
[preferences setValue:nil forKey:RetryDeploymentReportKey];
|
|
130
|
+
[preferences synchronize];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
+ (NSString *)getDeploymentKeyFromStatusReportIdentifier:(NSString *)statusReportIdentifier
|
|
134
|
+
{
|
|
135
|
+
return [[statusReportIdentifier componentsSeparatedByString:@":"] firstObject];
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
+ (NSString *)getPackageStatusReportIdentifier:(NSDictionary *)package
|
|
139
|
+
{
|
|
140
|
+
// Because deploymentKeys can be dynamically switched, we use a
|
|
141
|
+
// combination of the deploymentKey and label as the packageIdentifier.
|
|
142
|
+
NSString *deploymentKey = [package objectForKey:DeploymentKeyKey];
|
|
143
|
+
NSString *label = [package objectForKey:LabelKey];
|
|
144
|
+
if (deploymentKey && label) {
|
|
145
|
+
return [[deploymentKey stringByAppendingString:@":"] stringByAppendingString:label];
|
|
146
|
+
} else {
|
|
147
|
+
return nil;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
+ (NSString *)getPreviousStatusReportIdentifier
|
|
152
|
+
{
|
|
153
|
+
NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
|
|
154
|
+
NSString *sentStatusReportIdentifier = [preferences objectForKey:LastDeploymentReportKey];
|
|
155
|
+
return sentStatusReportIdentifier;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
+ (NSString *)getVersionLabelFromStatusReportIdentifier:(NSString *)statusReportIdentifier
|
|
159
|
+
{
|
|
160
|
+
return [[statusReportIdentifier componentsSeparatedByString:@":"] lastObject];
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
+ (BOOL)isStatusReportIdentifierCodePushLabel:(NSString *)statusReportIdentifier
|
|
164
|
+
{
|
|
165
|
+
return statusReportIdentifier != nil && [statusReportIdentifier rangeOfString:@":"].location != NSNotFound;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
+ (void)saveStatusReportedForIdentifier:(NSString *)appVersionOrPackageIdentifier
|
|
169
|
+
{
|
|
170
|
+
NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
|
|
171
|
+
[preferences setValue:appVersionOrPackageIdentifier forKey:LastDeploymentReportKey];
|
|
172
|
+
[preferences synchronize];
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
@end
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
#import "CodePush.h"
|
|
2
|
+
#include <CommonCrypto/CommonDigest.h>
|
|
3
|
+
#import "JWT.h"
|
|
4
|
+
|
|
5
|
+
@implementation CodePushUpdateUtils
|
|
6
|
+
|
|
7
|
+
NSString * const AssetsFolderName = @"assets";
|
|
8
|
+
NSString * const BinaryHashKey = @"CodePushBinaryHash";
|
|
9
|
+
NSString * const ManifestFolderPrefix = @"CodePush";
|
|
10
|
+
NSString * const BundleJWTFile = @".codepushrelease";
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
Ignore list for hashing
|
|
14
|
+
*/
|
|
15
|
+
NSString * const IgnoreMacOSX= @"__MACOSX/";
|
|
16
|
+
NSString * const IgnoreDSStore = @".DS_Store";
|
|
17
|
+
NSString * const IgnoreCodePushMetadata = @".codepushrelease";
|
|
18
|
+
|
|
19
|
+
+ (BOOL)isHashIgnoredFor:(NSString *) relativePath
|
|
20
|
+
{
|
|
21
|
+
return [relativePath hasPrefix:IgnoreMacOSX]
|
|
22
|
+
|| [relativePath isEqualToString:IgnoreDSStore]
|
|
23
|
+
|| [relativePath hasSuffix:[NSString stringWithFormat:@"/%@", IgnoreDSStore]]
|
|
24
|
+
|| [relativePath isEqualToString:IgnoreCodePushMetadata]
|
|
25
|
+
|| [relativePath hasSuffix:[NSString stringWithFormat:@"/%@", IgnoreCodePushMetadata]];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
+ (BOOL)addContentsOfFolderToManifest:(NSString *)folderPath
|
|
29
|
+
pathPrefix:(NSString *)pathPrefix
|
|
30
|
+
manifest:(NSMutableArray *)manifest
|
|
31
|
+
error:(NSError **)error
|
|
32
|
+
{
|
|
33
|
+
NSArray *folderFiles = [[NSFileManager defaultManager]
|
|
34
|
+
contentsOfDirectoryAtPath:folderPath
|
|
35
|
+
error:error];
|
|
36
|
+
if (!folderFiles) {
|
|
37
|
+
return NO;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
for (NSString *fileName in folderFiles) {
|
|
41
|
+
|
|
42
|
+
NSString *fullFilePath = [folderPath stringByAppendingPathComponent:fileName];
|
|
43
|
+
NSString *relativePath = [pathPrefix stringByAppendingPathComponent:fileName];
|
|
44
|
+
|
|
45
|
+
if([self isHashIgnoredFor:relativePath]){
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
BOOL isDir = NO;
|
|
50
|
+
if ([[NSFileManager defaultManager] fileExistsAtPath:fullFilePath
|
|
51
|
+
isDirectory:&isDir] && isDir) {
|
|
52
|
+
BOOL result = [self addContentsOfFolderToManifest:fullFilePath
|
|
53
|
+
pathPrefix:relativePath
|
|
54
|
+
manifest:manifest
|
|
55
|
+
error:error];
|
|
56
|
+
if (!result) {
|
|
57
|
+
return NO;
|
|
58
|
+
}
|
|
59
|
+
} else {
|
|
60
|
+
NSData *fileContents = [NSData dataWithContentsOfFile:fullFilePath];
|
|
61
|
+
NSString *fileContentsHash = [self computeHashForData:fileContents];
|
|
62
|
+
[manifest addObject:[[relativePath stringByAppendingString:@":"] stringByAppendingString:fileContentsHash]];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return YES;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
+ (void)addFileToManifest:(NSURL *)fileURL
|
|
70
|
+
manifest:(NSMutableArray *)manifest
|
|
71
|
+
{
|
|
72
|
+
if ([[NSFileManager defaultManager] fileExistsAtPath:[fileURL path]]) {
|
|
73
|
+
NSData *fileContents = [NSData dataWithContentsOfURL:fileURL];
|
|
74
|
+
NSString *fileContentsHash = [self computeHashForData:fileContents];
|
|
75
|
+
[manifest addObject:[NSString stringWithFormat:@"%@/%@:%@", [self manifestFolderPrefix], [fileURL lastPathComponent], fileContentsHash]];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
+ (NSString *)computeFinalHashFromManifest:(NSMutableArray *)manifest
|
|
80
|
+
error:(NSError **)error
|
|
81
|
+
{
|
|
82
|
+
//sort manifest strings to make sure, that they are completely equal with manifest strings has been generated in cli!
|
|
83
|
+
NSArray *sortedManifest = [manifest sortedArrayUsingSelector:@selector(compare:)];
|
|
84
|
+
NSData *manifestData = [NSJSONSerialization dataWithJSONObject:sortedManifest
|
|
85
|
+
options:kNilOptions
|
|
86
|
+
error:error];
|
|
87
|
+
if (!manifestData) {
|
|
88
|
+
return nil;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
NSString *manifestString = [[NSString alloc] initWithData:manifestData
|
|
92
|
+
encoding:NSUTF8StringEncoding];
|
|
93
|
+
// The JSON serialization turns path separators into "\/", e.g. "CodePush\/assets\/image.png"
|
|
94
|
+
manifestString = [manifestString stringByReplacingOccurrencesOfString:@"\\/"
|
|
95
|
+
withString:@"/"];
|
|
96
|
+
return [self computeHashForData:[NSData dataWithBytes:manifestString.UTF8String length:manifestString.length]];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
+ (NSString *)computeHashForData:(NSData *)inputData
|
|
100
|
+
{
|
|
101
|
+
uint8_t digest[CC_SHA256_DIGEST_LENGTH];
|
|
102
|
+
CC_SHA256(inputData.bytes, (CC_LONG)inputData.length, digest);
|
|
103
|
+
NSMutableString* inputHash = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2];
|
|
104
|
+
for (int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {
|
|
105
|
+
[inputHash appendFormat:@"%02x", digest[i]];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return inputHash;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
+ (BOOL)copyEntriesInFolder:(NSString *)sourceFolder
|
|
112
|
+
destFolder:(NSString *)destFolder
|
|
113
|
+
error:(NSError **)error
|
|
114
|
+
{
|
|
115
|
+
NSArray *files = [[NSFileManager defaultManager]
|
|
116
|
+
contentsOfDirectoryAtPath:sourceFolder
|
|
117
|
+
error:error];
|
|
118
|
+
if (!files) {
|
|
119
|
+
return NO;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
for (NSString *fileName in files) {
|
|
123
|
+
NSString * fullFilePath = [sourceFolder stringByAppendingPathComponent:fileName];
|
|
124
|
+
BOOL isDir = NO;
|
|
125
|
+
if ([[NSFileManager defaultManager] fileExistsAtPath:fullFilePath
|
|
126
|
+
isDirectory:&isDir] && isDir) {
|
|
127
|
+
NSString *nestedDestFolder = [destFolder stringByAppendingPathComponent:fileName];
|
|
128
|
+
BOOL result = [self copyEntriesInFolder:fullFilePath
|
|
129
|
+
destFolder:nestedDestFolder
|
|
130
|
+
error:error];
|
|
131
|
+
|
|
132
|
+
if (!result) {
|
|
133
|
+
return NO;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
} else {
|
|
137
|
+
NSString *destFileName = [destFolder stringByAppendingPathComponent:fileName];
|
|
138
|
+
if ([[NSFileManager defaultManager] fileExistsAtPath:destFileName]) {
|
|
139
|
+
BOOL result = [[NSFileManager defaultManager] removeItemAtPath:destFileName error:error];
|
|
140
|
+
if (!result) {
|
|
141
|
+
return NO;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (![[NSFileManager defaultManager] fileExistsAtPath:destFolder]) {
|
|
145
|
+
BOOL result = [[NSFileManager defaultManager] createDirectoryAtPath:destFolder
|
|
146
|
+
withIntermediateDirectories:YES
|
|
147
|
+
attributes:nil
|
|
148
|
+
error:error];
|
|
149
|
+
if (!result) {
|
|
150
|
+
return NO;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
BOOL result = [[NSFileManager defaultManager] copyItemAtPath:fullFilePath toPath:destFileName error:error];
|
|
155
|
+
if (!result) {
|
|
156
|
+
return NO;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return YES;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
+ (NSString *)findMainBundleInFolder:(NSString *)folderPath
|
|
164
|
+
expectedFileName:(NSString *)expectedFileName
|
|
165
|
+
error:(NSError **)error
|
|
166
|
+
{
|
|
167
|
+
NSArray* folderFiles = [[NSFileManager defaultManager]
|
|
168
|
+
contentsOfDirectoryAtPath:folderPath
|
|
169
|
+
error:error];
|
|
170
|
+
if (!folderFiles) {
|
|
171
|
+
return nil;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
for (NSString *fileName in folderFiles) {
|
|
175
|
+
NSString *fullFilePath = [folderPath stringByAppendingPathComponent:fileName];
|
|
176
|
+
BOOL isDir = NO;
|
|
177
|
+
if ([[NSFileManager defaultManager] fileExistsAtPath:fullFilePath
|
|
178
|
+
isDirectory:&isDir] && isDir) {
|
|
179
|
+
NSString *mainBundlePathInFolder = [self findMainBundleInFolder:fullFilePath
|
|
180
|
+
expectedFileName:expectedFileName
|
|
181
|
+
error:error];
|
|
182
|
+
if (mainBundlePathInFolder) {
|
|
183
|
+
return [fileName stringByAppendingPathComponent:mainBundlePathInFolder];
|
|
184
|
+
}
|
|
185
|
+
} else if ([fileName isEqualToString:expectedFileName]) {
|
|
186
|
+
return fileName;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return nil;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
+ (NSString *)assetsFolderName
|
|
194
|
+
{
|
|
195
|
+
return AssetsFolderName;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
+ (NSString *)getHashForBinaryContents:(NSURL *)binaryBundleUrl
|
|
199
|
+
error:(NSError **)error
|
|
200
|
+
{
|
|
201
|
+
// Get the cached hash from user preferences if it exists.
|
|
202
|
+
NSString *binaryModifiedDate = [self modifiedDateStringOfFileAtURL:binaryBundleUrl];
|
|
203
|
+
NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
|
|
204
|
+
NSMutableDictionary *binaryHashDictionary = [preferences objectForKey:BinaryHashKey];
|
|
205
|
+
NSString *binaryHash = nil;
|
|
206
|
+
if (binaryHashDictionary != nil) {
|
|
207
|
+
binaryHash = [binaryHashDictionary objectForKey:binaryModifiedDate];
|
|
208
|
+
if (binaryHash == nil) {
|
|
209
|
+
[preferences removeObjectForKey:BinaryHashKey];
|
|
210
|
+
[preferences synchronize];
|
|
211
|
+
} else {
|
|
212
|
+
return binaryHash;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
binaryHashDictionary = [NSMutableDictionary dictionary];
|
|
217
|
+
NSMutableArray *manifest = [NSMutableArray array];
|
|
218
|
+
|
|
219
|
+
// If the app is using assets, then add
|
|
220
|
+
// them to the generated content manifest.
|
|
221
|
+
NSString *assetsPath = [CodePush bundleAssetsPath];
|
|
222
|
+
if ([[NSFileManager defaultManager] fileExistsAtPath:assetsPath]) {
|
|
223
|
+
|
|
224
|
+
BOOL result = [self addContentsOfFolderToManifest:assetsPath
|
|
225
|
+
pathPrefix:[NSString stringWithFormat:@"%@/%@", [self manifestFolderPrefix], @"assets"]
|
|
226
|
+
manifest:manifest
|
|
227
|
+
error:error];
|
|
228
|
+
if (!result) {
|
|
229
|
+
return nil;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
[self addFileToManifest:binaryBundleUrl manifest:manifest];
|
|
234
|
+
[self addFileToManifest:[binaryBundleUrl URLByAppendingPathExtension:@"meta"] manifest:manifest];
|
|
235
|
+
|
|
236
|
+
binaryHash = [self computeFinalHashFromManifest:manifest error:error];
|
|
237
|
+
|
|
238
|
+
// Cache the hash in user preferences. This assumes that the modified date for the
|
|
239
|
+
// JS bundle changes every time a new bundle is generated by the packager.
|
|
240
|
+
[binaryHashDictionary setObject:binaryHash forKey:binaryModifiedDate];
|
|
241
|
+
[preferences setObject:binaryHashDictionary forKey:BinaryHashKey];
|
|
242
|
+
[preferences synchronize];
|
|
243
|
+
return binaryHash;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
+ (NSString *)manifestFolderPrefix
|
|
247
|
+
{
|
|
248
|
+
return ManifestFolderPrefix;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
+ (NSString *)modifiedDateStringOfFileAtURL:(NSURL *)fileURL
|
|
252
|
+
{
|
|
253
|
+
if (fileURL != nil) {
|
|
254
|
+
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[fileURL path] error:nil];
|
|
255
|
+
NSDate *modifiedDate = [fileAttributes objectForKey:NSFileModificationDate];
|
|
256
|
+
return [NSString stringWithFormat:@"%f", [modifiedDate timeIntervalSince1970]];
|
|
257
|
+
} else {
|
|
258
|
+
return nil;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
+ (BOOL)verifyFolderHash:(NSString *)finalUpdateFolder
|
|
263
|
+
expectedHash:(NSString *)expectedHash
|
|
264
|
+
error:(NSError **)error
|
|
265
|
+
{
|
|
266
|
+
CPLog(@"Verifying hash for folder path: %@", finalUpdateFolder);
|
|
267
|
+
|
|
268
|
+
NSMutableArray *updateContentsManifest = [NSMutableArray array];
|
|
269
|
+
BOOL result = [self addContentsOfFolderToManifest:finalUpdateFolder
|
|
270
|
+
pathPrefix:@""
|
|
271
|
+
manifest:updateContentsManifest
|
|
272
|
+
error:error];
|
|
273
|
+
|
|
274
|
+
CPLog(@"Manifest string: %@", updateContentsManifest);
|
|
275
|
+
|
|
276
|
+
if (!result) {
|
|
277
|
+
return NO;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
NSString *updateContentsManifestHash = [self computeFinalHashFromManifest:updateContentsManifest
|
|
281
|
+
error:error];
|
|
282
|
+
if (!updateContentsManifestHash) {
|
|
283
|
+
return NO;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
CPLog(@"Expected hash: %@, actual hash: %@", expectedHash, updateContentsManifestHash);
|
|
287
|
+
|
|
288
|
+
return [updateContentsManifestHash isEqualToString:expectedHash];
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// remove BEGIN / END tags and line breaks from public key string
|
|
292
|
+
+ (NSString *)getKeyValueFromPublicKeyString:(NSString *)publicKeyString
|
|
293
|
+
{
|
|
294
|
+
publicKeyString = [publicKeyString stringByReplacingOccurrencesOfString:@"-----BEGIN PUBLIC KEY-----\n"
|
|
295
|
+
withString:@""];
|
|
296
|
+
publicKeyString = [publicKeyString stringByReplacingOccurrencesOfString:@"-----END PUBLIC KEY-----"
|
|
297
|
+
withString:@""];
|
|
298
|
+
publicKeyString = [publicKeyString stringByReplacingOccurrencesOfString:@"\n"
|
|
299
|
+
withString:@""];
|
|
300
|
+
|
|
301
|
+
return publicKeyString;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
+ (NSString *)getSignatureFilePath:(NSString *)updateFolderPath
|
|
305
|
+
{
|
|
306
|
+
return [NSString stringWithFormat:@"%@/%@/%@", updateFolderPath, ManifestFolderPrefix, BundleJWTFile];
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
+ (NSString *)getSignatureFor:(NSString *)folderPath
|
|
310
|
+
error:(NSError **)error
|
|
311
|
+
{
|
|
312
|
+
NSString *signatureFilePath = [self getSignatureFilePath:folderPath];
|
|
313
|
+
if ([[NSFileManager defaultManager] fileExistsAtPath:signatureFilePath]) {
|
|
314
|
+
return [NSString stringWithContentsOfFile:signatureFilePath encoding:NSUTF8StringEncoding error:error];
|
|
315
|
+
} else {
|
|
316
|
+
*error = [CodePushErrorUtils errorWithMessage:[NSString stringWithFormat: @"Cannot find signature at %@", signatureFilePath]];
|
|
317
|
+
return nil;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
+ (NSDictionary *) verifyAndDecodeJWT:(NSString *)jwt
|
|
322
|
+
withPublicKey:(NSString *)publicKey
|
|
323
|
+
error:(NSError **)error
|
|
324
|
+
{
|
|
325
|
+
id <JWTAlgorithmDataHolderProtocol> verifyDataHolder = [JWTAlgorithmRSFamilyDataHolder new].keyExtractorType([JWTCryptoKeyExtractor publicKeyWithPEMBase64].type).algorithmName(@"RS256").secret(publicKey);
|
|
326
|
+
|
|
327
|
+
JWTCodingBuilder *verifyBuilder = [JWTDecodingBuilder decodeMessage:jwt].addHolder(verifyDataHolder);
|
|
328
|
+
JWTCodingResultType *verifyResult = verifyBuilder.result;
|
|
329
|
+
if (verifyResult.successResult) {
|
|
330
|
+
return verifyResult.successResult.payload;
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
*error = verifyResult.errorResult.error;
|
|
334
|
+
return nil;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
+ (BOOL)verifyUpdateSignatureFor:(NSString *)folderPath
|
|
339
|
+
expectedHash:(NSString *)newUpdateHash
|
|
340
|
+
withPublicKey:(NSString *)publicKeyString
|
|
341
|
+
error:(NSError **)error
|
|
342
|
+
{
|
|
343
|
+
NSLog(@"Verifying signature for folder path: %@", folderPath);
|
|
344
|
+
|
|
345
|
+
NSString *publicKey = [self getKeyValueFromPublicKeyString: publicKeyString];
|
|
346
|
+
|
|
347
|
+
NSError *signatureVerificationError;
|
|
348
|
+
NSString *signature = [self getSignatureFor: folderPath
|
|
349
|
+
error: &signatureVerificationError];
|
|
350
|
+
if (signatureVerificationError) {
|
|
351
|
+
CPLog(@"The update could not be verified because no signature was found. %@", signatureVerificationError);
|
|
352
|
+
*error = signatureVerificationError;
|
|
353
|
+
return false;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
NSError *payloadDecodingError;
|
|
357
|
+
NSDictionary *envelopedPayload = [self verifyAndDecodeJWT:signature withPublicKey:publicKey error:&payloadDecodingError];
|
|
358
|
+
if(payloadDecodingError){
|
|
359
|
+
CPLog(@"The update could not be verified because it was not signed by a trusted party. %@", payloadDecodingError);
|
|
360
|
+
*error = payloadDecodingError;
|
|
361
|
+
return false;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
CPLog(@"JWT signature verification succeeded, payload content: %@", envelopedPayload);
|
|
365
|
+
|
|
366
|
+
if(![envelopedPayload objectForKey:@"contentHash"]){
|
|
367
|
+
CPLog(@"The update could not be verified because the signature did not specify a content hash.");
|
|
368
|
+
return false;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
NSString *contentHash = envelopedPayload[@"contentHash"];
|
|
372
|
+
|
|
373
|
+
return [contentHash isEqualToString:newUpdateHash];
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
@end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#import "CodePush.h"
|
|
2
|
+
|
|
3
|
+
void CPLog(NSString *formatString, ...) {
|
|
4
|
+
va_list args;
|
|
5
|
+
va_start(args, formatString);
|
|
6
|
+
NSString *prependedFormatString = [NSString stringWithFormat:@"\n[CodePush] %@", formatString];
|
|
7
|
+
NSLogv(prependedFormatString, args);
|
|
8
|
+
va_end(args);
|
|
9
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
//
|
|
2
|
+
// JWTAlgorithm.h
|
|
3
|
+
// JWT
|
|
4
|
+
//
|
|
5
|
+
// Created by Klaas Pieter Annema on 31-05-13.
|
|
6
|
+
// Copyright (c) 2013 Karma. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#import <Foundation/Foundation.h>
|
|
10
|
+
#import "JWTDeprecations.h"
|
|
11
|
+
|
|
12
|
+
@protocol JWTAlgorithm <NSObject>
|
|
13
|
+
|
|
14
|
+
@required
|
|
15
|
+
/**
|
|
16
|
+
Signs data using provided secret data.
|
|
17
|
+
@param hash The data to sign.
|
|
18
|
+
@param key The secret to use for signing.
|
|
19
|
+
@param error The inout error.
|
|
20
|
+
*/
|
|
21
|
+
- (NSData *)signHash:(NSData *)hash key:(NSData *)key error:(NSError *__autoreleasing*)error;
|
|
22
|
+
/**
|
|
23
|
+
Verifies data using.
|
|
24
|
+
@param hash The data to sign.
|
|
25
|
+
@param signature The secret to use for signing.
|
|
26
|
+
@param error The inout error.
|
|
27
|
+
*/
|
|
28
|
+
- (BOOL)verifyHash:(NSData *)hash signature:(NSData *)signature key:(NSData *)key error:(NSError *__autoreleasing*)error;
|
|
29
|
+
|
|
30
|
+
//@required
|
|
31
|
+
|
|
32
|
+
@property (nonatomic, readonly, copy) NSString *name;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
Encodes and encrypts the provided payload using the provided secret key
|
|
36
|
+
@param theString The string to encode
|
|
37
|
+
@param theSecret The secret to use for encryption
|
|
38
|
+
@return An NSData object containing the encrypted payload, or nil if something went wrong.
|
|
39
|
+
*/
|
|
40
|
+
- (NSData *)encodePayload:(NSString *)theString withSecret:(NSString *)theSecret __deprecated_and_will_be_removed_in_release_version(JWTVersion_3_0_0);
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
Verifies the provided signature using the signed input and verification key
|
|
44
|
+
@param input The header and payload encoded string
|
|
45
|
+
@param signature The JWT provided signature
|
|
46
|
+
@param verificationKey The key to use for verifying the signature
|
|
47
|
+
@return YES if the provided signature is valid, NO otherwise
|
|
48
|
+
*/
|
|
49
|
+
- (BOOL)verifySignedInput:(NSString *)input withSignature:(NSString *)signature verificationKey:(NSString *)verificationKey __deprecated_and_will_be_removed_in_release_version(JWTVersion_3_0_0);
|
|
50
|
+
|
|
51
|
+
@optional
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
Encodes and encrypts the provided payload using the provided secret key
|
|
55
|
+
@param theStringData The data to encode
|
|
56
|
+
@param theSecretData The secret data to use for encryption
|
|
57
|
+
@return An NSData object containing the encrypted payload, or nil if something went wrong.
|
|
58
|
+
*/
|
|
59
|
+
- (NSData *)encodePayloadData:(NSData *)theStringData withSecret:(NSData *)theSecretData;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
Verifies the provided signature using the signed input and verification key (as data)
|
|
63
|
+
@param input The header and payload encoded string
|
|
64
|
+
@param signature The JWT provided signature
|
|
65
|
+
@param verificationKeyData The key data to use for verifying the signature
|
|
66
|
+
@return YES if the provided signature is valid, NO otherwise
|
|
67
|
+
*/
|
|
68
|
+
- (BOOL)verifySignedInput:(NSString *)input withSignature:(NSString *)signature verificationKeyData:(NSData *)verificationKeyData;
|
|
69
|
+
@end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//
|
|
2
|
+
// JWTAlgorithmFactory.h
|
|
3
|
+
// JWT
|
|
4
|
+
//
|
|
5
|
+
// Created by Lobanov Dmitry on 07.10.15.
|
|
6
|
+
// Copyright © 2015 Karma. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#import <Foundation/Foundation.h>
|
|
10
|
+
#import "JWTAlgorithm.h"
|
|
11
|
+
@interface JWTAlgorithmFactory : NSObject
|
|
12
|
+
|
|
13
|
+
+ (NSArray *)algorithms;
|
|
14
|
+
+ (id<JWTAlgorithm>)algorithmByName:(NSString *)name;
|
|
15
|
+
|
|
16
|
+
@end
|