update core
This commit is contained in:
parent
a76183d129
commit
80ab33db45
@ -27,8 +27,6 @@
|
||||
88D1FBE11FCCCBA100338A3A /* MVMCoreMainSplitViewProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 88D1FBDF1FCCCADC00338A3A /* MVMCoreMainSplitViewProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
88D1FBE21FCCCBA500338A3A /* PanelProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 88D1FBE01FCCCB2C00338A3A /* PanelProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
AF26DDAE1FCE6A37004E8F65 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = AF26DDB01FCE6A37004E8F65 /* Localizable.strings */; };
|
||||
AF26DDB51FCE7C76004E8F65 /* VeriSignClass3PublicPrimaryCertificationAuthority-G5.cer in Resources */ = {isa = PBXBuildFile; fileRef = AF26DDB31FCE7C76004E8F65 /* VeriSignClass3PublicPrimaryCertificationAuthority-G5.cer */; };
|
||||
AF26DDB71FCE802D004E8F65 /* DigiCertGlobalRootCA.cer in Resources */ = {isa = PBXBuildFile; fileRef = AF26DDB61FCE802D004E8F65 /* DigiCertGlobalRootCA.cer */; };
|
||||
AF43A5771FBA5B7C008E9347 /* MVMCoreJSONConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = AF43A5751FBA5B7C008E9347 /* MVMCoreJSONConstants.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
AF43A5781FBA5B7C008E9347 /* MVMCoreJSONConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = AF43A5761FBA5B7C008E9347 /* MVMCoreJSONConstants.m */; };
|
||||
AF43A57B1FBA5E6A008E9347 /* MVMCoreHardcodedStringsConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = AF43A5791FBA5E6A008E9347 /* MVMCoreHardcodedStringsConstants.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
@ -71,10 +69,6 @@
|
||||
AFBB96621FBA3A570008D868 /* MVMCoreRequestParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = AFBB96491FBA3A560008D868 /* MVMCoreRequestParameters.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
AFBB96631FBA3A570008D868 /* MVMCoreLoadRequestOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = AFBB964A1FBA3A560008D868 /* MVMCoreLoadRequestOperation.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
AFBB96641FBA3A570008D868 /* MVMCoreLoadHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = AFBB964B1FBA3A560008D868 /* MVMCoreLoadHandler.m */; };
|
||||
AFBB96651FBA3A570008D868 /* MFSSLPinningHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = AFBB964D1FBA3A560008D868 /* MFSSLPinningHandler.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
AFBB96661FBA3A570008D868 /* MFSSLPinningHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = AFBB964E1FBA3A560008D868 /* MFSSLPinningHandler.m */; };
|
||||
AFBB96671FBA3A570008D868 /* MFURLSessionChallengeResult.h in Headers */ = {isa = PBXBuildFile; fileRef = AFBB964F1FBA3A560008D868 /* MFURLSessionChallengeResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
AFBB96681FBA3A570008D868 /* MFURLSessionChallengeResult.m in Sources */ = {isa = PBXBuildFile; fileRef = AFBB96501FBA3A560008D868 /* MFURLSessionChallengeResult.m */; };
|
||||
AFBB96691FBA3A570008D868 /* MVMCoreRequestParameters.m in Sources */ = {isa = PBXBuildFile; fileRef = AFBB96511FBA3A560008D868 /* MVMCoreRequestParameters.m */; };
|
||||
AFBB966A1FBA3A570008D868 /* MVMCoreLoadRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = AFBB96521FBA3A570008D868 /* MVMCoreLoadRequestOperation.m */; };
|
||||
AFBB968B1FBA3A9A0008D868 /* MVMCoreDismissViewControllerOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = AFBB966D1FBA3A9A0008D868 /* MVMCoreDismissViewControllerOperation.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
@ -156,8 +150,6 @@
|
||||
88D1FBDF1FCCCADC00338A3A /* MVMCoreMainSplitViewProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreMainSplitViewProtocol.h; sourceTree = "<group>"; };
|
||||
88D1FBE01FCCCB2C00338A3A /* PanelProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PanelProtocol.h; sourceTree = "<group>"; };
|
||||
AF26DDAF1FCE6A37004E8F65 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
AF26DDB31FCE7C76004E8F65 /* VeriSignClass3PublicPrimaryCertificationAuthority-G5.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = "VeriSignClass3PublicPrimaryCertificationAuthority-G5.cer"; sourceTree = "<group>"; };
|
||||
AF26DDB61FCE802D004E8F65 /* DigiCertGlobalRootCA.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = DigiCertGlobalRootCA.cer; sourceTree = "<group>"; };
|
||||
AF43A5751FBA5B7C008E9347 /* MVMCoreJSONConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreJSONConstants.h; sourceTree = "<group>"; };
|
||||
AF43A5761FBA5B7C008E9347 /* MVMCoreJSONConstants.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreJSONConstants.m; sourceTree = "<group>"; };
|
||||
AF43A5791FBA5E6A008E9347 /* MVMCoreHardcodedStringsConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreHardcodedStringsConstants.h; sourceTree = "<group>"; };
|
||||
@ -203,10 +195,6 @@
|
||||
AFBB96491FBA3A560008D868 /* MVMCoreRequestParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreRequestParameters.h; sourceTree = "<group>"; };
|
||||
AFBB964A1FBA3A560008D868 /* MVMCoreLoadRequestOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreLoadRequestOperation.h; sourceTree = "<group>"; };
|
||||
AFBB964B1FBA3A560008D868 /* MVMCoreLoadHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreLoadHandler.m; sourceTree = "<group>"; };
|
||||
AFBB964D1FBA3A560008D868 /* MFSSLPinningHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFSSLPinningHandler.h; sourceTree = "<group>"; };
|
||||
AFBB964E1FBA3A560008D868 /* MFSSLPinningHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFSSLPinningHandler.m; sourceTree = "<group>"; };
|
||||
AFBB964F1FBA3A560008D868 /* MFURLSessionChallengeResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFURLSessionChallengeResult.h; sourceTree = "<group>"; };
|
||||
AFBB96501FBA3A560008D868 /* MFURLSessionChallengeResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFURLSessionChallengeResult.m; sourceTree = "<group>"; };
|
||||
AFBB96511FBA3A560008D868 /* MVMCoreRequestParameters.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreRequestParameters.m; sourceTree = "<group>"; };
|
||||
AFBB96521FBA3A570008D868 /* MVMCoreLoadRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreLoadRequestOperation.m; sourceTree = "<group>"; };
|
||||
AFBB966D1FBA3A9A0008D868 /* MVMCoreDismissViewControllerOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreDismissViewControllerOperation.h; sourceTree = "<group>"; };
|
||||
@ -356,15 +344,6 @@
|
||||
path = Strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
AF26DDB11FCE7C76004E8F65 /* Certificates */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
AF26DDB61FCE802D004E8F65 /* DigiCertGlobalRootCA.cer */,
|
||||
AF26DDB31FCE7C76004E8F65 /* VeriSignClass3PublicPrimaryCertificationAuthority-G5.cer */,
|
||||
);
|
||||
path = Certificates;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
AF43A5941FBB700D008E9347 /* MainStructure */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -445,7 +424,6 @@
|
||||
children = (
|
||||
AFFCFA601FCCC0D600FD0730 /* LoadingOverlay */,
|
||||
AFBB963C1FBA3A550008D868 /* FreeBee */,
|
||||
AFBB964C1FBA3A560008D868 /* SSLPinning */,
|
||||
AFBB96371FBA39E70008D868 /* MVMCoreLoadDelegateProtocol.h */,
|
||||
AFBB96391FBA3A550008D868 /* MVMCoreLoadHandler.h */,
|
||||
AFBB964B1FBA3A560008D868 /* MVMCoreLoadHandler.m */,
|
||||
@ -476,18 +454,6 @@
|
||||
path = FreeBee;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
AFBB964C1FBA3A560008D868 /* SSLPinning */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
AF26DDB11FCE7C76004E8F65 /* Certificates */,
|
||||
AFBB964D1FBA3A560008D868 /* MFSSLPinningHandler.h */,
|
||||
AFBB964E1FBA3A560008D868 /* MFSSLPinningHandler.m */,
|
||||
AFBB964F1FBA3A560008D868 /* MFURLSessionChallengeResult.h */,
|
||||
AFBB96501FBA3A560008D868 /* MFURLSessionChallengeResult.m */,
|
||||
);
|
||||
path = SSLPinning;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
AFBB966B1FBA3A9A0008D868 /* PresentationHandling */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -645,12 +611,10 @@
|
||||
AFBB96601FBA3A570008D868 /* MVMCoreLoadObject.h in Headers */,
|
||||
AF43A7061FC4D7A2008E9347 /* MVMCoreObject.h in Headers */,
|
||||
AFED77A11FCCA29400BAE689 /* MVMCoreViewControllerNibMappingObject.h in Headers */,
|
||||
AFBB96671FBA3A570008D868 /* MFURLSessionChallengeResult.h in Headers */,
|
||||
AFBB969F1FBA3A9A0008D868 /* MVMCoreAlertOperation.h in Headers */,
|
||||
AFBB965A1FBA3A570008D868 /* FreeBeeUrlObject.h in Headers */,
|
||||
AF43A71B1FC5BEBB008E9347 /* MVMCoreViewControllerProtocol.h in Headers */,
|
||||
AFBB96571FBA3A570008D868 /* FreeBeeAuthObject.h in Headers */,
|
||||
AFBB96651FBA3A570008D868 /* MFSSLPinningHandler.h in Headers */,
|
||||
AFBB96381FBA39E70008D868 /* MVMCoreLoadDelegateProtocol.h in Headers */,
|
||||
AFBB96B01FBA3B590008D868 /* MVMCoreDispatchUtility.h in Headers */,
|
||||
8876D5E81FB50AB000EB2E3D /* NSArray+MFConvenience.h in Headers */,
|
||||
@ -744,10 +708,8 @@
|
||||
files = (
|
||||
AFBB96EB1FBA4A260008D868 /* canned.json in Resources */,
|
||||
AF26DDAE1FCE6A37004E8F65 /* Localizable.strings in Resources */,
|
||||
AF26DDB71FCE802D004E8F65 /* DigiCertGlobalRootCA.cer in Resources */,
|
||||
AFBB96561FBA3A570008D868 /* freebee.json in Resources */,
|
||||
AFBB96591FBA3A570008D868 /* freebeelaunchApp.json in Resources */,
|
||||
AF26DDB51FCE7C76004E8F65 /* VeriSignClass3PublicPrimaryCertificationAuthority-G5.cer in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -778,7 +740,6 @@
|
||||
881D26931FCC9D180079C521 /* MVMCoreErrorObject.m in Sources */,
|
||||
30349BF21FCCA78A00546A1E /* MVMCoreSessionTimeHandler.m in Sources */,
|
||||
8876D5E91FB50AB000EB2E3D /* NSArray+MFConvenience.m in Sources */,
|
||||
AFBB96661FBA3A570008D868 /* MFSSLPinningHandler.m in Sources */,
|
||||
AFBB96971FBA3A9A0008D868 /* MVMCorePresentViewControllerOperation.m in Sources */,
|
||||
AFBB96581FBA3A570008D868 /* FreeBeeAuthObject.m in Sources */,
|
||||
AF43A5781FBA5B7C008E9347 /* MVMCoreJSONConstants.m in Sources */,
|
||||
@ -791,7 +752,6 @@
|
||||
AF43A5881FBB67D6008E9347 /* MVMCoreActionUtility.m in Sources */,
|
||||
AFED77A61FCCA29400BAE689 /* MVMCoreViewControllerStoryBoardMappingObject.m in Sources */,
|
||||
AF43A57C1FBA5E6A008E9347 /* MVMCoreHardcodedStringsConstants.m in Sources */,
|
||||
AFBB96681FBA3A570008D868 /* MFURLSessionChallengeResult.m in Sources */,
|
||||
AFBB965D1FBA3A570008D868 /* MFFreebeeHandler.m in Sources */,
|
||||
AFEEE81F1FCDF3CA00B5EDD0 /* MVMCoreLoggingHandler.m in Sources */,
|
||||
AFBB969E1FBA3A9A0008D868 /* MVMCoreAlertObject.m in Sources */,
|
||||
@ -946,10 +906,7 @@
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(PROJECT_DIR)/../../SharedFrameworks",
|
||||
"\"$(SRCROOT)/../../SharedFrameworks\"",
|
||||
);
|
||||
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../../SharedFrameworks";
|
||||
INFOPLIST_FILE = MVMCore/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
@ -977,10 +934,7 @@
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(PROJECT_DIR)/../../SharedFrameworks",
|
||||
"\"$(SRCROOT)/../../SharedFrameworks\"",
|
||||
);
|
||||
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../../SharedFrameworks";
|
||||
INFOPLIST_FILE = MVMCore/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
|
||||
@ -4,10 +4,15 @@
|
||||
<dict>
|
||||
<key>SchemeUserState</key>
|
||||
<dict>
|
||||
<key>MVMCore.xcscheme</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>17</integer>
|
||||
</dict>
|
||||
<key>MVMCore.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>11</integer>
|
||||
<integer>6</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
|
||||
@ -15,11 +15,3 @@ extern NSString * const HardcodedOK;
|
||||
extern NSString * const HardcodedErrorCritical;
|
||||
extern NSString * const HardcodedErrorUnableToProcess;
|
||||
|
||||
// SSL Pinning error strings
|
||||
extern NSString * const ERROR_SSL_TITLE;
|
||||
extern NSString * const ERROR_SSL_MESSAGE_PREFIX_KEY;
|
||||
extern NSString * const ERROR_SSL_MESSAGE_TITLE_KEY;
|
||||
extern NSString * const ERROR_SSL_MESSAGE_POSTFIX_KEY;
|
||||
extern NSString * const ERROR_SSL_UPDATE_TITLE_KEY;
|
||||
extern NSString * const ERROR_SSL_UPDATE_MESSAGE_KEY;
|
||||
|
||||
|
||||
@ -15,11 +15,3 @@ NSString * const HardcodedOK = @"okCaps";
|
||||
NSString * const HardcodedErrorCritical = @"Error Message Critical Key";
|
||||
NSString * const HardcodedErrorUnableToProcess = @"Error Message Unable To Process Request Key";
|
||||
|
||||
// SSL Pinning error strings
|
||||
NSString * const ERROR_SSL_TITLE = @"SSL Error Title";
|
||||
NSString * const ERROR_SSL_MESSAGE_PREFIX_KEY = @"SSL Error Message Prefix";
|
||||
NSString * const ERROR_SSL_MESSAGE_TITLE_KEY = @"SSL Error Message Title";
|
||||
NSString * const ERROR_SSL_MESSAGE_POSTFIX_KEY = @"SSL Error Message Postfix";
|
||||
NSString * const ERROR_SSL_UPDATE_TITLE_KEY = @"SSL Update Title";
|
||||
NSString * const ERROR_SSL_UPDATE_MESSAGE_KEY = @"SSL Update Message";
|
||||
|
||||
|
||||
@ -34,6 +34,7 @@ typedef void(^FreebeeLoadFinishedHandler)(MVMCoreOperation* _Nullable freebeeOpe
|
||||
- (void)enableFreeBeeForCurrentModule:(BOOL)enable;
|
||||
- (BOOL)isFreeBeeEnabledForCurrentModule;
|
||||
- (BOOL)isExcludedModule:(nullable NSString*)parentPageType;
|
||||
- (BOOL)isAllowedPage:(nullable NSString*)pageType;
|
||||
|
||||
- (void)printStatusDescription;
|
||||
|
||||
|
||||
@ -27,6 +27,7 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
FreeBeeCampaignStateExpired,
|
||||
};
|
||||
|
||||
#define ENABLE_FREEBEE_LOCAL_TEST 0
|
||||
@interface MFFreebeeHandler()<FreeBeeTaskFinished>
|
||||
|
||||
@property(nonatomic, strong) NSString* authString;
|
||||
@ -36,6 +37,7 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
@property(nonatomic, assign) FreeBeeCampaignState currentFreeBeeCampaignState;
|
||||
@property(nonatomic, strong) NSMutableArray* freeBeeUrls;
|
||||
@property(nonatomic, strong) NSArray* excludedModulesForFreeBee;
|
||||
@property(nonatomic, strong) NSArray* enabledRootPagesForFreebee;
|
||||
|
||||
@property(nonatomic, strong) NSMutableDictionary* configDictionary;
|
||||
@property(nonatomic) BOOL freeBeeEnabled;
|
||||
@ -60,7 +62,7 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
|
||||
- (FreeBeeCampaignState)processResponse:(NSData*)data withExtraParams:(NSDictionary*)extraParams;
|
||||
- (void)configureMFFreeBeeSession;
|
||||
+ (NSData *)sendSynchronousRequest:(NSURL *)url
|
||||
- (NSData *)sendSynchronousRequest:(NSURL *)url
|
||||
returningResponse:(__autoreleasing NSURLResponse **)response
|
||||
error:(__autoreleasing NSError **)error;
|
||||
@end
|
||||
@ -78,7 +80,7 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
sharedHandler.freeBeeAuthObj = nil;
|
||||
sharedHandler.currentFreeBeeCampaignState = FreeBeeCampaignStateNotDetermined;
|
||||
sharedHandler.excludedModulesForFreeBee = nil;
|
||||
sharedHandler.freeBeeEnabledForCurrentModule = YES;
|
||||
sharedHandler.freeBeeEnabledForCurrentModule = NO;
|
||||
sharedHandler.requestTimeoutInterval = 1;
|
||||
sharedHandler.isFreeBeeServerEnabled = NO;
|
||||
|
||||
@ -109,7 +111,6 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
|
||||
MVMCoreLog(@"FreeBee State Invalidated");
|
||||
if (self.currentFreeBeeCampaignState != FreeBeeCampaignStateBusy) {
|
||||
|
||||
self.currentFreeBeeCampaignState = FreeBeeCampaignStateNotDetermined;
|
||||
[[MVMCoreSessionObject sharedGlobal].freeBeeSession invalidateAndCancel];
|
||||
[MVMCoreSessionObject sharedGlobal].freeBeeSession = nil;
|
||||
@ -117,16 +118,10 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
}
|
||||
|
||||
- (void)processFreeBeeAuthRequestWithCompletionHandler:(nullable FreebeeLoadFinishedHandler)completionHandler {
|
||||
|
||||
if ([self canProceedWithFreebeeAuthRequest]) {
|
||||
|
||||
// check if self timer based mechanism can be used
|
||||
if([self isExpired]) {
|
||||
|
||||
[self invalidateFreeBeeState];
|
||||
}
|
||||
|
||||
if ([self isExpired]) {
|
||||
[self invalidateFreeBeeState];
|
||||
}
|
||||
|
||||
[self processFreeBeeState:completionHandler];
|
||||
}
|
||||
|
||||
@ -139,33 +134,26 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
}
|
||||
|
||||
- (BOOL)isFreeBeeEnabled {
|
||||
|
||||
return self.freeBeeEnabled;
|
||||
}
|
||||
|
||||
- (BOOL)isValidCampaign {
|
||||
|
||||
if (self.currentFreeBeeCampaignState == FreeBeeCampaignStateValid ) {
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)isExpired {
|
||||
|
||||
return [self.freeBeeAuthObj isExpired];
|
||||
}
|
||||
|
||||
- (void)enableFreeBeeForCurrentModule:(BOOL)enable {
|
||||
|
||||
if (self.isFreeBeeEnabled)
|
||||
self.freeBeeEnabledForCurrentModule = enable;
|
||||
}
|
||||
|
||||
- (BOOL)isFreeBeeEnabledForCurrentModule {
|
||||
|
||||
return self.freeBeeEnabledForCurrentModule;
|
||||
}
|
||||
|
||||
@ -175,7 +163,6 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
return NO;
|
||||
|
||||
if (parentPageType.length) {
|
||||
|
||||
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"%@ =[cd] SELF", parentPageType];
|
||||
NSArray* subArray = [self.excludedModulesForFreeBee filteredArrayUsingPredicate:predicate];
|
||||
if (subArray.count)
|
||||
@ -186,14 +173,22 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)isAllowedPage:(nullable NSString*)pageType {
|
||||
|
||||
if (!self.enabledRootPagesForFreebee.count) {
|
||||
return NO;
|
||||
}
|
||||
if (pageType.length) {
|
||||
return [self.enabledRootPagesForFreebee containsObject:pageType];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)printStatusDescription {
|
||||
|
||||
if ([[MFFreebeeHandler sharedHandler] isValidCampaign]) {
|
||||
|
||||
MVMCoreLog(@"FreeBee Valid Campaign");
|
||||
}
|
||||
else {
|
||||
|
||||
} else {
|
||||
MVMCoreLog(@"FreeBee Invalid Campaign");
|
||||
}
|
||||
}
|
||||
@ -240,27 +235,23 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
NSData* data = nil;
|
||||
NSDictionary* proxyDict = [self proxyDictionaryforUrl:url];
|
||||
|
||||
if (YES == [self isFreeBeeEnabled] &&
|
||||
YES == [self isValidCampaign] && proxyDict &&
|
||||
YES == [self isFreeBeeEnabledForCurrentModule]) {
|
||||
|
||||
MVMCoreLog(@"Free Data Url, %@", url);
|
||||
|
||||
NSURLResponse* response = nil;
|
||||
NSError* error = nil;
|
||||
data = [self sendSynchronousRequest:url returningResponse:&response error:&error];
|
||||
|
||||
if(error)
|
||||
data = nil;
|
||||
|
||||
MVMCoreLog(@"freebee_dataWithContentsOfURL:Free Data, %lu", (unsigned long)data.length);
|
||||
}
|
||||
else {
|
||||
|
||||
if ([self isFreeBeeEnabled] &&
|
||||
[self isValidCampaign] && proxyDict &&
|
||||
![self isExpired] && [self isFreeBeeEnabledForCurrentModule]) {
|
||||
|
||||
MVMCoreLog(@"Free Data Url, %@", url);
|
||||
NSURLResponse* response = nil;
|
||||
NSError* error = nil;
|
||||
data = [self sendSynchronousRequest:url returningResponse:&response error:&error];
|
||||
|
||||
if (error)
|
||||
data = nil;
|
||||
|
||||
MVMCoreLog(@"freebee_dataWithContentsOfURL:Free Data, %lu", (unsigned long)data.length);
|
||||
} else {
|
||||
data = [NSData dataWithContentsOfURL:url];
|
||||
}
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - FreeBee Registration
|
||||
@ -273,7 +264,6 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
#endif
|
||||
|
||||
if (module) {
|
||||
|
||||
// Enable for testing hardcoded response
|
||||
#if ENABLE_FREEBEE_LOCAL_TEST
|
||||
NSString *plistPath = [[MVMCoreUtility bundleForMVMCore] pathForResource:@"freebeelaunchApp" ofType:@"json"];
|
||||
@ -297,18 +287,17 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
NSDictionary* configDict = [module dictionaryForKey:@"freeBeeData"];
|
||||
[self configureFreeBeeWithDict:configDict withSessionReset:NO];
|
||||
self.excludedModulesForFreeBee = [module arrayForKey:@"disabledModules"];
|
||||
self.enabledRootPagesForFreebee = [module arrayForKey:@"enabledPages"];
|
||||
|
||||
NSString* timeOut = [module stringForKey:@"authRequestTimeOut"];
|
||||
NSTimeInterval time = [timeOut doubleValue];
|
||||
if (time > 0.f)
|
||||
self.requestTimeoutInterval = time;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
|
||||
[self configureFreeBeeWithDict:nil withSessionReset:NO];
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
|
||||
[self configureFreeBeeWithDict:nil withSessionReset:NO];
|
||||
}
|
||||
@ -321,8 +310,7 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
|
||||
[self updateWithConfigDictionary:configDict];
|
||||
[self enableReachability:YES];
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
|
||||
[self invalidateFreeBeeState];
|
||||
[self updateWithConfigDictionary:nil];
|
||||
@ -349,6 +337,7 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
break;
|
||||
|
||||
case FreeBeeCampaignStateValid:
|
||||
[self enableReachability:YES];
|
||||
self.completionHandler(nil, YES);
|
||||
self.completionHandler = nil;
|
||||
//start a timer request
|
||||
@ -366,9 +355,7 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
}
|
||||
|
||||
- (void)processBusyState {
|
||||
|
||||
if (nil == self.configDictionary) {
|
||||
|
||||
if (!self.configDictionary) {
|
||||
MVMCoreLog(@"FreeBee Response failed with error configDictionary:Empty");
|
||||
self.freeBeeAuthObj = nil;
|
||||
self.currentFreeBeeCampaignState = FreeBeeCampaignStateInvalid;
|
||||
@ -398,9 +385,7 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
self.currentFreeBeeCampaignState = FreeBeeCampaignStateBusy;
|
||||
|
||||
NSURLRequest* request = [self authRequestWithConfigDict:self.configDictionary];
|
||||
|
||||
if (request == nil) {
|
||||
|
||||
if (!request) {
|
||||
[MVMCoreLoggingHandler logWithDelegateWithObject:nil withName:@"freeBeeError" withExtraInfo:nil];
|
||||
wSelf.currentFreeBeeCampaignState = FreeBeeCampaignStateInvalid;
|
||||
[self processFreeBeeState:nil];
|
||||
@ -414,14 +399,16 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
|
||||
- (void)updateWithConfigDictionary:(nullable NSDictionary*)configDict {
|
||||
|
||||
if (configDict && configDict.count)
|
||||
if (configDict && configDict.count) {
|
||||
self.configDictionary = [NSMutableDictionary dictionaryWithDictionary:configDict];
|
||||
else {
|
||||
} else {
|
||||
|
||||
[self.configDictionary removeAllObjects];
|
||||
self.isFreeBeeServerEnabled = NO;
|
||||
self.freeBeeEnabled = NO;
|
||||
self.freeBeeEnabledForCurrentModule = NO;
|
||||
self.enabledRootPagesForFreebee = nil;
|
||||
self.excludedModulesForFreeBee = nil;
|
||||
}
|
||||
}
|
||||
|
||||
@ -458,7 +445,6 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
|
||||
if (self.currentFreeBeeCampaignState == FreeBeeCampaignStateNotDetermined)
|
||||
return YES;
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
@ -466,16 +452,18 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
- (void)updateWithResponse:(NSData*)data Error:(NSError*)error ExtraParams:(NSDictionary*) extraParams {
|
||||
|
||||
if (data.length > 0) {
|
||||
|
||||
self.currentFreeBeeCampaignState = [self processResponse:data withExtraParams:extraParams];
|
||||
[self processFreeBeeState:nil];
|
||||
|
||||
} else {
|
||||
|
||||
// Empty response.
|
||||
MVMCoreLog(@"FreeBee Auth Request failed with empty response");
|
||||
self.currentFreeBeeCampaignState = FreeBeeCampaignStateInvalid;
|
||||
[MVMCoreLoggingHandler logWithDelegateWithObject:nil withName:@"freeBeeError" withExtraInfo:extraParams];
|
||||
|
||||
if (error.description) {
|
||||
[MVMCoreLoggingHandler logWithDelegateWithObject:nil withName:@"freeBeeError" withExtraInfo:@{@"description":error.description}];
|
||||
} else {
|
||||
[MVMCoreLoggingHandler logWithDelegateWithObject:nil withName:@"freeBeeError" withExtraInfo:extraParams];
|
||||
}
|
||||
[self processFreeBeeState:nil];
|
||||
}
|
||||
self.freebeeOperation = nil;
|
||||
@ -496,13 +484,10 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
if ([jsonDictionary isKindOfClass:[NSDictionary class]]) {
|
||||
|
||||
if (!self.freeBeeAuthObj) {
|
||||
|
||||
//warning:this needs to be modified for multiple urls
|
||||
wSelf.freeBeeAuthObj = [[FreeBeeAuthObject alloc] init];
|
||||
[wSelf.freeBeeAuthObj updateWithDictionary:jsonDictionary];
|
||||
}
|
||||
else {
|
||||
|
||||
} else {
|
||||
[wSelf.freeBeeAuthObj updateWithDictionary:jsonDictionary];
|
||||
}
|
||||
|
||||
@ -515,9 +500,7 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
[logDict addEntriesFromDictionary:extraParams];
|
||||
|
||||
if ([self.freeBeeAuthObj isValidFreeBeeSessionAuthObject]) {
|
||||
|
||||
[MVMCoreLoggingHandler logWithDelegateWithObject:nil withName:@"freeBeeSuccess" withExtraInfo:logDict];
|
||||
|
||||
MVMCoreLog(@"FreeBee Response Validated");
|
||||
[self configureMFFreeBeeSession];
|
||||
return FreeBeeCampaignStateValid;
|
||||
@ -531,11 +514,8 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
}
|
||||
|
||||
if (error.description) {
|
||||
|
||||
[MVMCoreLoggingHandler logWithDelegateWithObject:nil withName:@"freeBeeError" withExtraInfo:@{@"description":error.description}];
|
||||
}
|
||||
else {
|
||||
|
||||
} else {
|
||||
[MVMCoreLoggingHandler logWithDelegateWithObject:nil withName:@"freeBeeError" withExtraInfo:nil];
|
||||
}
|
||||
|
||||
@ -545,7 +525,7 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
- (void)configureMFFreeBeeSession {
|
||||
|
||||
MVMCoreLog(@"FreeBee Configure Session");
|
||||
|
||||
|
||||
//Assign The new Session Configuration sice its not possible to modify the existing session, we need to
|
||||
MVMCoreSessionObject *sessionSingleton = [MVMCoreSessionObject sharedGlobal];
|
||||
NSURLSession* session = sessionSingleton.session;
|
||||
@ -586,11 +566,9 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
|
||||
NSDictionary* campaignDictionary = [[MFFreebeeHandler sharedHandler] campaignHeaderforUrl:url];
|
||||
if (campaignDictionary) {
|
||||
|
||||
[request addValue:campaignDictionary[@"Proxy-Authorization"] forHTTPHeaderField:@"Proxy-Authorization"];
|
||||
}
|
||||
|
||||
|
||||
|
||||
[[session dataTaskWithRequest:request
|
||||
completionHandler:^(NSData* _data, NSURLResponse* _response, NSError* _error) {
|
||||
|
||||
@ -604,12 +582,10 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
|
||||
|
||||
if (response) {
|
||||
|
||||
*response = resp;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
|
||||
*error = err;
|
||||
}
|
||||
|
||||
@ -620,22 +596,14 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) {
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (enable) {
|
||||
|
||||
_reachability = [Reachability reachabilityForInternetConnection];
|
||||
|
||||
// Observe the kNetworkReachabilityChangedNotification. When that notification is posted, the method reachabilityChanged will be called.
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityDidChange:) name:kReachabilityChangedNotification object:nil];
|
||||
[_reachability startNotifier];
|
||||
}
|
||||
else {
|
||||
|
||||
if (_reachability) {
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:kReachabilityChangedNotification object:nil];
|
||||
[_reachability stopNotifier];
|
||||
_reachability = nil;
|
||||
}
|
||||
} else if (_reachability) {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:kReachabilityChangedNotification object:nil];
|
||||
[_reachability stopNotifier];
|
||||
_reachability = nil;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
|
||||
@interface MFFreebeeOperation()
|
||||
|
||||
@property(nonatomic, strong) NSURLRequest* freeBeeAuthRequest;
|
||||
@property(nonatomic, strong) NSURLRequest *freeBeeAuthRequest;
|
||||
@property(weak) id<FreeBeeTaskFinished> delegate;
|
||||
@property(nonatomic) dispatch_semaphore_t semaphore;
|
||||
|
||||
@ -52,21 +52,22 @@
|
||||
NSURLRequest *request = self.freeBeeAuthRequest;
|
||||
|
||||
if (request == nil) {
|
||||
|
||||
[self.delegate updateWithResponse:nil Error:nil ExtraParams:nil];
|
||||
return;
|
||||
}
|
||||
|
||||
MVMCoreLog(@"*********************************FreeBee Auth Call Start**********************************");
|
||||
NSDate* date = [NSDate date];
|
||||
NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:date];
|
||||
|
||||
|
||||
NSURLResponse *response = nil;
|
||||
NSError *error = nil;
|
||||
|
||||
NSDate *date = [NSDate date];
|
||||
NSData *data = [self sendSynchronousRequest:request returningResponse:&response error:&error];
|
||||
NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:date];
|
||||
|
||||
MVMCoreLog(@"Freebee Auth Call Request Time response for freebee is %f", interval);
|
||||
NSDictionary *timeForRequest = @{@"ResponseTime":@(interval)};
|
||||
[self.delegate updateWithResponse:[data copy] Error:error ExtraParams:timeForRequest];
|
||||
NSDictionary *extraParams = @{@"ResponseTime":@(interval)};
|
||||
[self.delegate updateWithResponse:[data copy] Error:error ExtraParams:extraParams];
|
||||
}
|
||||
|
||||
- (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response
|
||||
@ -93,12 +94,10 @@
|
||||
dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER);
|
||||
|
||||
if (response) {
|
||||
|
||||
*response = resp;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
|
||||
*error = err;
|
||||
}
|
||||
|
||||
|
||||
@ -1,14 +1,15 @@
|
||||
{
|
||||
"statusCode": 200,
|
||||
"vidToken": "xlO5qbqZLp68J7OBHqumyN693FfDAdY6rC3T51haBxM=",
|
||||
"sdAuthResp": [
|
||||
{
|
||||
"urlId": "1",
|
||||
"authRespCode": 1200,
|
||||
"httpsProxyIP": "68.128.201.128",
|
||||
"sdUrl": "mobile.vzw.com:443?vzSvc=xlO5qbqZLp68J7OBHqumyN693FfDAdY6rC3T51haBxM=&vispVzKey=70421425&vispIconFg=1&vispUsr=70421425:A4WgVNAcwIdx8EVgt4QjyQ==&vispAuthSid=CIAAACAKJwE&vispExpTime=1492803669&vispAuthKey=46700746&vispAuthSign=0.19.sC5AhLOaDdDXZWz3gYx0MoxjNJLxb6IcV-e5ZBxNS8s",
|
||||
"sdConfExpiry": 1697567906,
|
||||
"sdPort": 22779
|
||||
}
|
||||
]
|
||||
"statusCode": 200,
|
||||
"message": "Success",
|
||||
"vidToken": "OAlTpG0WFQ_qKHdnjBQueUB_SjZk46rjTGxxSGppKd8=",
|
||||
"sdAuthResp": [
|
||||
{
|
||||
"urlId": "1",
|
||||
"authRespCode": 1200,
|
||||
"httpsProxyIP": "152.198.7.159",
|
||||
"sdPort": 22779,
|
||||
"sdUrl": "mobile-eqa6.vzw.com:443?vzSvc=OAlTpG0WFQ_qKHdnjBQueUB_SjZk46rjTGxxSGppKd8=&vispVzKey=44595039&vispIconFg=1&vispUsr=44595039:sNNHcJP2nYGtcuiCaVZcHQ==&vispAuthSid=CIAAACAKJwE&vispExpTime=1511370770&vispAuthKey=25858536&vispAuthSign=0.19._y9flLw7123TMhTcHUe7IVUmzJZK4MhC5kC3A6FTvXw",
|
||||
"sdConfExpiry": 1512370770
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -14,12 +14,15 @@
|
||||
"authUrls": [
|
||||
{
|
||||
"urlId": "1",
|
||||
"authUrl": "mobile.vzw.com:443"
|
||||
"authUrl": "mobile-eqa6.vzw.com:443"
|
||||
}
|
||||
]
|
||||
},
|
||||
"disabledModules": [
|
||||
"disabledModules": ["gridwall"
|
||||
],
|
||||
"enabledPages": ["billOverview","myData","accountLanding", "deviceLanding"
|
||||
],
|
||||
|
||||
"proxyServerUrl": "https://auth.svcs.verizon.com:22790/sd/v2/sdAuthorization/httpsProxy"
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,7 +62,4 @@
|
||||
// By default, returns continue loading and decides not to throw an error.
|
||||
+ (BOOL)defaultHandleModuleError:(nonnull NSString *)module loadObject:(nonnull MVMCoreLoadObject *)loadObject error:(nonnull MVMCoreErrorObject *)error;
|
||||
|
||||
// Tracks that it has finished..
|
||||
+ (void)defaultLoadFinished:(nullable MVMCoreLoadObject *)loadObject loadedViewController:(nullable UIViewController <MVMCoreViewControllerProtocol> *)loadedViewController error:(nullable MVMCoreErrorObject *)error;
|
||||
|
||||
@end
|
||||
|
||||
@ -14,7 +14,6 @@
|
||||
#import "MFHardCodedServerResponse.h"
|
||||
#import "MFFreebeeHandler.h"
|
||||
#import "MVMCoreNavigationHandler.h"
|
||||
#import "MFSSLPinningHandler.h"
|
||||
#import "MVMCoreLoadObject.h"
|
||||
#import "MVMCoreSessionObject.h"
|
||||
#import "MVMCoreJSONConstants.h"
|
||||
@ -159,14 +158,7 @@
|
||||
|
||||
// Create and send post request, adding params as http body.
|
||||
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:timeOutInterval];
|
||||
|
||||
[request setHTTPMethod:@"POST"];
|
||||
[request setValue:@"no-cache, no-store" forHTTPHeaderField:@"Cache-Control"];
|
||||
|
||||
// Either adds the params to the body or the header.
|
||||
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
|
||||
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
|
||||
|
||||
[self setHeadersForRequest:request requestParameters:requestParameters];
|
||||
|
||||
NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
|
||||
|
||||
@ -179,7 +171,7 @@
|
||||
}
|
||||
|
||||
// Adds request specific parameters
|
||||
if (requestParameters.parameters.count > 0) {
|
||||
if (requestParameters.parameters.count) {
|
||||
[parameters setObject:requestParameters.parameters forKey:@"RequestParams"];
|
||||
}
|
||||
|
||||
@ -191,28 +183,28 @@
|
||||
}
|
||||
|
||||
//adding Free Bee header
|
||||
if(YES == [[MFFreebeeHandler sharedHandler] isFreeBeeEnabled]
|
||||
&& YES == [[MFFreebeeHandler sharedHandler] isValidCampaign]) {
|
||||
if ([[MFFreebeeHandler sharedHandler] isFreeBeeEnabled]
|
||||
&& [[MFFreebeeHandler sharedHandler] isValidCampaign]) {
|
||||
BOOL isAllowedPage = [[MFFreebeeHandler sharedHandler] isAllowedPage:requestParameters.pageType];
|
||||
if (requestParameters.parentPageType.length) {
|
||||
BOOL isExcluded = [[MFFreebeeHandler sharedHandler] isExcludedModule:requestParameters.parentPageType];
|
||||
[[MFFreebeeHandler sharedHandler] enableFreeBeeForCurrentModule:!isExcluded];
|
||||
}
|
||||
|
||||
BOOL isExcluded = [[MFFreebeeHandler sharedHandler] isExcludedModule:requestParameters.parentPageType];
|
||||
[[MFFreebeeHandler sharedHandler] enableFreeBeeForCurrentModule:!isExcluded];
|
||||
|
||||
// to enable only for self server module
|
||||
if(NO == isExcluded){
|
||||
if (isAllowedPage || (!isAllowedPage && [[MFFreebeeHandler sharedHandler] isFreeBeeEnabledForCurrentModule])) {
|
||||
|
||||
NSDictionary* campaignDictionary = [[MFFreebeeHandler sharedHandler] campaignHeaderforUrl:request.URL];
|
||||
if(campaignDictionary) {
|
||||
|
||||
if (campaignDictionary) {
|
||||
MVMCoreLog(@"Freebee Request Campaign Dictionary : %@", campaignDictionary);
|
||||
[request addValue:campaignDictionary[@"Proxy-Authorization"] forHTTPHeaderField:@"Proxy-Authorization"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NSError *error = nil;
|
||||
NSData *data = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:&error];
|
||||
if (data) {
|
||||
[request setHTTPBody:data];
|
||||
|
||||
NSError *error;
|
||||
NSData *body = [self createBodyForRequestUsingParameters:parameters requestParameters:requestParameters error:&error];
|
||||
if (body) {
|
||||
[request setHTTPBody:body];
|
||||
} else {
|
||||
// Log the json error
|
||||
MVMCoreErrorObject *errorObject = [[MVMCoreErrorObject alloc] initWithTitle:nil message:nil code:ErrorCodeParsingJSON domain:ErrorDomainNative location:[NSString stringWithFormat:@"requestWithParameters_%@",requestParameters.pageType]];
|
||||
@ -222,6 +214,72 @@
|
||||
return request;
|
||||
}
|
||||
|
||||
- (NSString *)boundaryForMultipartRequest {
|
||||
|
||||
static NSString *boundary;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
boundary = [NSString stringWithFormat:@"MFBoundary-%@",[NSUUID UUID]];
|
||||
});
|
||||
return boundary;
|
||||
}
|
||||
|
||||
- (void)setHeadersForRequest:(NSMutableURLRequest *)request requestParameters:(MVMCoreRequestParameters *)requestParameters {
|
||||
|
||||
[request setHTTPMethod:@"POST"];
|
||||
[request setValue:@"no-cache, no-store" forHTTPHeaderField:@"Cache-Control"];
|
||||
|
||||
// If we're uploading an image, create a multipart request, else create the normal json request
|
||||
if (requestParameters.imageData) {
|
||||
|
||||
NSString *boundary = [self boundaryForMultipartRequest];
|
||||
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
|
||||
[request setValue:contentType forHTTPHeaderField:@"Content-Type"];
|
||||
} else {
|
||||
|
||||
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
|
||||
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSData *)createBodyForRequestUsingParameters:(NSDictionary *)parameters requestParameters:(MVMCoreRequestParameters *)requestParameters error:(NSError **)error {
|
||||
|
||||
NSMutableData *body = [[NSMutableData alloc] init];
|
||||
|
||||
if (requestParameters.imageData) {
|
||||
|
||||
NSData *imageData = requestParameters.imageData;
|
||||
NSString *boundary = [self boundaryForMultipartRequest];
|
||||
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n", @"mfRequest"] dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[body appendData:[@"Content-Type: application/json\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:error];
|
||||
if (jsonData) {
|
||||
[body appendData:jsonData];
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
[body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"profileImage.png\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[body appendData:[@"Content-Type: image/png\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[body appendData:[@"Content-Transfer-Encoding: base64\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[body appendData:imageData];
|
||||
[body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[body appendData:[[NSString stringWithFormat:@"--%@--", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
} else {
|
||||
NSData *data = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:error];
|
||||
if (data) {
|
||||
[body appendData:data];
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
- (nonnull NSURLSessionTask *)sendRequest:(nonnull MVMCoreRequestParameters *)requestParameters locationForError:(nonnull NSString *)locationForError requestFinished:(nullable void (^)(id _Nullable jsonObject, MVMCoreErrorObject *_Nullable error))requestFinished {
|
||||
|
||||
#if ENABLE_HARD_CODED_RESPONSE
|
||||
@ -237,17 +295,18 @@
|
||||
NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate];
|
||||
NSURLRequest *request = [self requestWithParameters:requestParameters];
|
||||
NSURLSession *session = [MVMCoreSessionObject sharedGlobal].session;
|
||||
|
||||
|
||||
//In case of error for time out, we need to revert to normal session object
|
||||
if(YES == [[MFFreebeeHandler sharedHandler] isFreeBeeEnabled] &&
|
||||
YES == [[MFFreebeeHandler sharedHandler] isValidCampaign] &&
|
||||
YES == [[MFFreebeeHandler sharedHandler] isFreeBeeEnabledForCurrentModule]) {
|
||||
|
||||
// to enable only for self server module
|
||||
if([MVMCoreSessionObject sharedGlobal].freeBeeSession != nil) {
|
||||
session = [MVMCoreSessionObject sharedGlobal].freeBeeSession;
|
||||
MVMCoreLog(@"*********************************FreeBee Sponsored Request Start**********************************");
|
||||
|
||||
if ([[MFFreebeeHandler sharedHandler] isFreeBeeEnabled]
|
||||
&& [[MFFreebeeHandler sharedHandler] isValidCampaign]) {
|
||||
BOOL isAllowedPage = [[MFFreebeeHandler sharedHandler] isAllowedPage:requestParameters.pageType];
|
||||
//In case of error for time out, we need to revert to normal session object
|
||||
if (isAllowedPage || (!isAllowedPage && [[MFFreebeeHandler sharedHandler] isFreeBeeEnabledForCurrentModule])) {
|
||||
|
||||
// to enable only for self server module
|
||||
if ([MVMCoreSessionObject sharedGlobal].freeBeeSession) {
|
||||
session = [MVMCoreSessionObject sharedGlobal].freeBeeSession;
|
||||
MVMCoreLog(@"*********************************FreeBee Sponsored Request Start**********************************");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -296,10 +355,13 @@
|
||||
// Empty response.
|
||||
errorObject = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorTitle] message:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorCritical] code:ErrorCodeEmptyResponse domain:ErrorDomainNative location:locationForError];
|
||||
}
|
||||
} else if ([[MVMCoreObject sharedInstance].globalLoadDelegate respondsToSelector:@selector(createErrorObjectForRequestNSError:forRequest:location:)]) {
|
||||
|
||||
// Delegate handles the load error
|
||||
errorObject = [[MVMCoreObject sharedInstance].globalLoadDelegate createErrorObjectForRequestNSError:error forRequest:request location:locationForError];
|
||||
} else {
|
||||
// If the request was cancelled due to SSL error or other issues.
|
||||
// Error with the request.
|
||||
errorObject = [MFSSLPinningHandler createErrorObjectForNSErrorAndVerifySSLErrors:error location:locationForError];
|
||||
errorObject = [MVMCoreErrorObject createErrorObjectForNSError:error location:locationForError];
|
||||
}
|
||||
|
||||
if (requestFinished) {
|
||||
@ -357,8 +419,4 @@
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (void)defaultLoadFinished:(nullable MVMCoreLoadObject *)loadObject loadedViewController:(nullable UIViewController <MVMCoreViewControllerProtocol> *)loadedViewController error:(nullable MVMCoreErrorObject *)error {
|
||||
// [[MFAdobeTracker sharedTracker] trackResponseInfo:loadObject.responseInfoMap forPagetype:loadObject.pageType];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -12,7 +12,6 @@
|
||||
#import <MVMCore/MVMCorePresentationDelegateProtocol.h>
|
||||
#import <MVMCore/MVMCoreActionDelegateProtocol.h>
|
||||
|
||||
|
||||
@class MVMCoreLoadRequestOperation;
|
||||
@class MVMCoreRequestParameters;
|
||||
|
||||
|
||||
@ -17,9 +17,6 @@
|
||||
#import "MVMCoreViewControllerMappingObject.h"
|
||||
#import "MVMCoreNavigationHandler.h"
|
||||
#import "MVMCoreAlertObject.h"
|
||||
#import "MFFreebeeHandler.h"
|
||||
#import "FreeBeeAuthObject.h"
|
||||
#import "MFSSLPinningHandler.h"
|
||||
#import <MVMCore/MVMCoreDispatchUtility.h>
|
||||
#import "MVMCoreLoadObject.h"
|
||||
#import "MVMCoreRequestParameters.h"
|
||||
@ -329,7 +326,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)notifyListenersOfNewResponse:(NSDictionary *)pages modules:(NSDictionary *)modules systemParameters:(NSDictionary *)systemParameters {
|
||||
+ (void)notifyListenersOfNewResponse:(NSDictionary *)pages modules:(NSDictionary *)modules systemParameters:(NSDictionary *)systemParameters loadObject:(nonnull MVMCoreLoadObject *)loadObject {
|
||||
|
||||
NSMutableDictionary *userInfo = nil;
|
||||
if (pages.count > 0 || modules.count > 0 || systemParameters.count > 0) {
|
||||
@ -343,6 +340,9 @@
|
||||
if (systemParameters.count > 0) {
|
||||
[userInfo setObject:systemParameters forKey:KeySystemParameters];
|
||||
}
|
||||
if (loadObject) {
|
||||
[userInfo setObject:loadObject forKey:NSStringFromClass([MVMCoreLoadObject class])];
|
||||
}
|
||||
}
|
||||
|
||||
if (userInfo) {
|
||||
@ -389,7 +389,7 @@
|
||||
[MVMCoreLoadRequestOperation handleShouldContinue:shouldContinue error:moduleCachingError loadObject:loadObject errorBlock:^{
|
||||
|
||||
// Notify of system parameters if error.
|
||||
[MVMCoreLoadRequestOperation notifyListenersOfNewResponse:nil modules:nil systemParameters:systemParameters];
|
||||
[MVMCoreLoadRequestOperation notifyListenersOfNewResponse:nil modules:nil systemParameters:systemParameters loadObject:loadObject];
|
||||
} continueBlock:^{
|
||||
|
||||
// Handle any module caching error and continue load.
|
||||
@ -404,7 +404,7 @@
|
||||
[MVMCoreLoadRequestOperation handleShouldContinue:shouldContinue error:pagesCachingError loadObject:loadObject errorBlock:^{
|
||||
|
||||
// Notify of module updates if we are erroring out.
|
||||
[MVMCoreLoadRequestOperation notifyListenersOfNewResponse:nil modules:modules systemParameters:systemParameters];
|
||||
[MVMCoreLoadRequestOperation notifyListenersOfNewResponse:nil modules:modules systemParameters:systemParameters loadObject:loadObject];
|
||||
} continueBlock:^{
|
||||
|
||||
// Handle any page caching error and continue load.
|
||||
@ -417,7 +417,7 @@
|
||||
[MVMCoreLoadRequestOperation handleShouldContinue:shouldContinueLoad error:error loadObject:loadObject errorBlock:^{
|
||||
|
||||
// Notify of module/pages updates if we are erroring out.
|
||||
[MVMCoreLoadRequestOperation notifyListenersOfNewResponse:pages modules:modules systemParameters:systemParameters];
|
||||
[MVMCoreLoadRequestOperation notifyListenersOfNewResponse:pages modules:modules systemParameters:systemParameters loadObject:loadObject];
|
||||
} continueBlock:^{
|
||||
if (error) {
|
||||
// Hold onto any error until we establish a delegate
|
||||
@ -435,7 +435,7 @@
|
||||
if (loadObject.pageDataFromCache) {
|
||||
|
||||
// Notify listeners of module/pages loaded.
|
||||
[MVMCoreLoadRequestOperation notifyListenersOfNewResponse:pages modules:modules systemParameters:systemParameters];
|
||||
[MVMCoreLoadRequestOperation notifyListenersOfNewResponse:pages modules:modules systemParameters:systemParameters loadObject:loadObject];
|
||||
|
||||
// Just continue if coming from cache.
|
||||
completionHandler(loadObject,error);
|
||||
@ -447,7 +447,7 @@
|
||||
}];
|
||||
|
||||
// Notify listeners of module/pages loaded.
|
||||
[MVMCoreLoadRequestOperation notifyListenersOfNewResponse:pages modules:modules systemParameters:systemParameters];
|
||||
[MVMCoreLoadRequestOperation notifyListenersOfNewResponse:pages modules:modules systemParameters:systemParameters loadObject:loadObject];
|
||||
} else {
|
||||
|
||||
NSDictionary *pagesLoaded = pages;
|
||||
@ -465,7 +465,7 @@
|
||||
}
|
||||
|
||||
// Notify listeners of things loaded.
|
||||
[MVMCoreLoadRequestOperation notifyListenersOfNewResponse:pagesLoaded modules:modules systemParameters:systemParameters];
|
||||
[MVMCoreLoadRequestOperation notifyListenersOfNewResponse:pagesLoaded modules:modules systemParameters:systemParameters loadObject:loadObject];
|
||||
|
||||
completionHandler(loadObject,error);
|
||||
}
|
||||
@ -755,32 +755,9 @@
|
||||
}
|
||||
|
||||
// Once displyed, we are finished.
|
||||
void (^completionBlock)(void) = ^{
|
||||
[MVMCoreActionUtility displayViewController:viewController forLoadObject:loadObject presentationDelegate:loadObject.operation completionHandler:^{
|
||||
[MVMCoreLoadRequestOperation loadFinished:loadObject loadedViewController:viewController errorObject:error];
|
||||
};
|
||||
|
||||
// Lets the server determine the presentation style if not explicitely set by developer.
|
||||
if (loadObject.requestParameters.loadStyle == MFLoadStyleDefault) {
|
||||
|
||||
// Sets it first based on the action map.
|
||||
NSString *presentationStyle = [loadObject.requestParameters.actionMap stringForKey:KeyPresentationStyle];
|
||||
[loadObject.requestParameters setMFLoadStyleBasedOnPresentationStyle:presentationStyle];
|
||||
|
||||
// Let's the response override if needed.
|
||||
presentationStyle = [loadObject.pageJSON stringForKey:KeyPresentationStyle];
|
||||
[loadObject.requestParameters setMFLoadStyleBasedOnPresentationStyle:presentationStyle];
|
||||
}
|
||||
|
||||
// Check if we need to load on another control
|
||||
__block UIViewController *viewControllerToLoad = nil;
|
||||
if ([[MVMCoreObject sharedInstance].globalLoadDelegate respondsToSelector:@selector(getViewManagerWithViewController:loadObject:)]) {
|
||||
[MVMCoreDispatchUtility performSyncBlockOnMainThread:^{
|
||||
viewControllerToLoad = [[MVMCoreObject sharedInstance].globalLoadDelegate getViewManagerWithViewController:viewController loadObject:loadObject];
|
||||
}];
|
||||
}
|
||||
|
||||
// Navigates
|
||||
[[MVMCoreNavigationHandler sharedNavigationHandler] navigateWithLoadObject:loadObject viewController:(viewControllerToLoad ?: viewController) delegate:loadObject.operation completionHandler:completionBlock];
|
||||
}];
|
||||
}
|
||||
|
||||
+ (void)handleError:(nonnull MVMCoreErrorObject *)error loadObject:(nonnull MVMCoreLoadObject *)loadObject showAlertForErrorIfApplicable:(BOOL)showAlertForErrorIfApplicable {
|
||||
@ -856,7 +833,7 @@
|
||||
if ([loadObject.delegate respondsToSelector:@selector(loadFinished:loadedViewController:error:)]) {
|
||||
[loadObject.delegate loadFinished:loadObject loadedViewController:loadedViewController error:errorObject];
|
||||
} else {
|
||||
[MVMCoreLoadHandler defaultLoadFinished:loadObject loadedViewController:loadedViewController error:errorObject];
|
||||
[MVMCoreLoggingHandler logWithDelegateLoadFinished:loadObject loadedViewController:loadedViewController error:errorObject];
|
||||
}
|
||||
[loadObject.operation markAsFinished];
|
||||
}
|
||||
@ -904,5 +881,4 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@ -31,6 +31,7 @@ typedef NS_ENUM(NSInteger, MFLoadStyle) {
|
||||
@property (nullable, strong, nonatomic) NSString *pageType;
|
||||
@property (nullable, strong, nonatomic) NSArray *modules;
|
||||
@property (nullable, strong, nonatomic) NSDictionary *parameters;
|
||||
@property (nullable, strong, nonatomic) NSData *imageData;
|
||||
|
||||
// adding parent pageType for freebee
|
||||
@property (nullable, strong, nonatomic) NSString *parentPageType;
|
||||
|
||||
@ -130,6 +130,7 @@
|
||||
copyObject.allowAlertsIfBackgroundRequest = self.allowAlertsIfBackgroundRequest;
|
||||
copyObject.alternateBaseURL = self.alternateBaseURL;
|
||||
copyObject.openSupportPanel = self.openSupportPanel;
|
||||
copyObject.imageData = self.imageData;
|
||||
return copyObject;
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@ -1,44 +0,0 @@
|
||||
//
|
||||
// MFSSLPinningHandler.h
|
||||
// mobilefirst
|
||||
//
|
||||
// Created by Pfeil, Scott Robert on 8/3/17.
|
||||
// Copyright © 2017 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class MVMCoreErrorObject;
|
||||
@class MVMCoreRequestParameters;
|
||||
@class MFURLSessionChallengeResult;
|
||||
|
||||
@interface MFSSLPinningHandler : NSObject
|
||||
|
||||
#pragma mark - SSL Data
|
||||
|
||||
// To setup SSL pinning status.
|
||||
+ (void)setupSSLData:(NSString *_Nullable)status;
|
||||
|
||||
#pragma mark NSURLSessionDelegate methods
|
||||
|
||||
// Handles like the delegate function for the URLSession
|
||||
+ (MFURLSessionChallengeResult * _Nonnull)getResultForURLSession:(NSURLSession *_Nonnull)session didReceiveChallenge:(NSURLAuthenticationChallenge *_Nonnull)challenge;
|
||||
|
||||
#pragma mark - Error Handling
|
||||
|
||||
// Creates and returns SSL error object for the NSError.
|
||||
+ (nonnull MVMCoreErrorObject *)errorObjectForSSLErrors:(nullable NSString *)locationForError;
|
||||
|
||||
// Creates and returns either an SSL error object or normal error object for the NSError.
|
||||
+ (nonnull MVMCoreErrorObject *)createErrorObjectForNSErrorAndVerifySSLErrors:(nonnull NSError *)error location:(nullable NSString *)locationForError;
|
||||
|
||||
// To invoke SSL Error Handling flow, when error code:NSURLErrorCancelled is thrown while connecting to server API's for each session.
|
||||
// it is used for redirection flows
|
||||
+ (void)handleSSLErrors:(nullable MVMCoreErrorObject *)errorObject requestParameters:(nonnull MVMCoreRequestParameters *)requestParameters;
|
||||
|
||||
#pragma mark - SSL Logging
|
||||
|
||||
// To log SSL error on MF Server
|
||||
+ (void)logSSLError:(NSString *_Nonnull)tag;
|
||||
|
||||
@end
|
||||
@ -1,585 +0,0 @@
|
||||
//
|
||||
// MFSSLPinningHandler.m
|
||||
// mobilefirst
|
||||
//
|
||||
// To handle SSL pinning:
|
||||
// It will be pinning client and server root certificate/public key to secure app
|
||||
//
|
||||
// Created by Pfeil, Scott Robert on 8/3/17.
|
||||
// Updated by Khan, Arshad on 8/23/17
|
||||
// Copyright © 2017 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MFSSLPinningHandler.h"
|
||||
#import "MVMCoreErrorObject.h"
|
||||
#import "MVMCoreRequestParameters.h"
|
||||
#import "MVMCoreNavigationHandler.h"
|
||||
#import "MVMCoreSessionObject.h"
|
||||
#import "MVMCoreLoadHandler.h"
|
||||
#import "MVMCoreLoggingHandler.h"
|
||||
#import "MFURLSessionChallengeResult.h"
|
||||
#import <MVMCore/MVMCoreDispatchUtility.h>
|
||||
#import "MVMCoreJSONConstants.h"
|
||||
#import "MVMCoreActionUtility.h"
|
||||
#import "MVMCoreGetterUtility.h"
|
||||
#import "MVMCoreLoadObject.h"
|
||||
#import "MVMCoreErrorConstants.h"
|
||||
#import "MVMCoreHardcodedStringsConstants.h"
|
||||
#import "MVMCoreObject.h"
|
||||
|
||||
NSString * const MF_IOS_SSL_CERT_PATH_NOT_FOUND = @"MF_IOS_SSL_CERT_PATH_NOT_FOUND";
|
||||
NSString * const MF_IOS_SSL_CERT_PINNED = @"MF_IOS_SSL_CERT_PINNED";
|
||||
NSString * const MF_IOS_SSL_PUBLIC_KEY_PINNED = @"MF_IOS_SSL_PUBLIC_KEY_PINNED";
|
||||
NSString * const MF_IOS_SSL_CERT_MISMATCH = @"MF_IOS_SSL_CERT_MISMATCH";
|
||||
NSString * const MF_IOS_SSL_SERVER_CERT_DATA_NULL = @"MF_IOS_SSL_SERVER_CERT_DATA_NULL";
|
||||
NSString * const MF_IOS_SSL_CLIENT_CERT_NULL = @"MF_IOS_SSL_CLIENT_CERT_NULL";
|
||||
NSString * const MF_IOS_SSL_PINNING_SUCCESS = @"MF_IOS_SSL_PINNING_SUCCESS";
|
||||
NSString * const MF_IOS_SSL_PINNING_FAILED = @"MF_IOS_SSL_PINNING_FAILED";
|
||||
NSString * const MF_IOS_SSL_SERVER_CERT_NULL = @"MF_IOS_SSL_SERVER_CERT_NULL";
|
||||
NSString * const MF_IOS_SSL_PINNING_SWITCHED_OFF = @"MF_IOS_SSL_PINNING_SWITCHED_OFF";
|
||||
NSString * const MF_IOS_SSL_MANDATORY_UPGRADE_PAGE = @"MF_IOS_SSL_MANDATORY_UPGRADE_PAGE";
|
||||
NSString * const MF_IOS_SSL_ERROR_PAGE = @"MF_IOS_SSL_ERROR_PAGE";
|
||||
|
||||
@interface MFSSLPinningHandler ()
|
||||
|
||||
// Stores the ssl dictionary in the user defaults or removes.
|
||||
+ (void)setupSSLData:(NSString *_Nullable)status;
|
||||
|
||||
// The challenge on the request is allowed, get the result.
|
||||
+ (MFURLSessionChallengeResult *)allowChallenge:(NSURLAuthenticationChallenge *)challenge;
|
||||
|
||||
// Returns the path of the certificate.
|
||||
+ (NSString *)getCertificatePath:(NSString *_Nullable)commonName;
|
||||
|
||||
// To check expiry of pinned certificate
|
||||
// we can use SecTrustSetVerifyDate as well, if below function gives any problem in future
|
||||
+ (BOOL)isCertificateExpiredAtPath:(NSString*)path;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MFSSLPinningHandler
|
||||
|
||||
#pragma mark - SSL Data setup
|
||||
|
||||
+ (BOOL)shouldBeSSLPinned {
|
||||
NSString *hashedSslStatus = [[NSUserDefaults standardUserDefaults] stringForKey:CLIENT_SSL_STATUS_KEY];
|
||||
if (hashedSslStatus && [hashedSslStatus isEqualToString:[MVMCoreActionUtility hashStringWithSHA256:@"true"]]) {
|
||||
return YES;
|
||||
} else {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)storeSSLStatus:(NSString *_Nullable)sslStatus {
|
||||
[MVMCoreDispatchUtility performBlockOnMainThread:^{
|
||||
if (sslStatus.length > 0) {
|
||||
// Explicitly turning OFF SSL Pinning
|
||||
[[NSUserDefaults standardUserDefaults] setObject:[MVMCoreActionUtility hashStringWithSHA256:@"false"] forKey:CLIENT_SSL_STATUS_KEY];
|
||||
} else {
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:CLIENT_SSL_STATUS_KEY];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
// Updates the ssl pinning status.
|
||||
+ (void)updateSSLData:(NSString *_Nullable)sslStatus {
|
||||
if (sslStatus.length>0) {
|
||||
[MFSSLPinningHandler storeSSLStatus:sslStatus];
|
||||
}
|
||||
}
|
||||
|
||||
// Gets the ssl pinning status (if we are using or not)
|
||||
+ (void)setupSSLData:(NSString *_Nullable)status {
|
||||
|
||||
NSString *sslStatus = [[NSUserDefaults standardUserDefaults] stringForKey:CLIENT_SSL_STATUS_KEY];
|
||||
if (sslStatus==nil || sslStatus.length==0) {
|
||||
|
||||
// None previously stored...
|
||||
// By default SSL status would be true
|
||||
// can be switched off from test screen
|
||||
// using 'true' string for hashing and stroing this SSL status securely
|
||||
sslStatus = [MVMCoreActionUtility hashStringWithSHA256:@"false"];
|
||||
// store this status for future use
|
||||
[MFSSLPinningHandler storeSSLStatus:sslStatus];
|
||||
|
||||
} else if (status) {
|
||||
|
||||
// Found previously stored, update.
|
||||
[MFSSLPinningHandler updateSSLData:status];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark- SSL Pinning functions
|
||||
|
||||
BOOL evaluateCertificate(SecTrustRef secTrust) {
|
||||
SecTrustResultType trustResult;
|
||||
SecTrustEvaluate(secTrust, &trustResult);
|
||||
BOOL isCertificateTrusted = NO;
|
||||
switch (trustResult) {
|
||||
case kSecTrustResultUnspecified:
|
||||
case kSecTrustResultProceed:
|
||||
{
|
||||
isCertificateTrusted = YES;
|
||||
MVMCoreLog(@"Pass: certificate is trusted");
|
||||
}
|
||||
break;
|
||||
case kSecTrustResultRecoverableTrustFailure:
|
||||
MVMCoreLog(@"Failure: certificate is not trusted or kSecTrustResultRecoverableTrustFailure");
|
||||
default:
|
||||
MVMCoreLog(@"Failure: certificate is invalid or not trustable:%u",trustResult);
|
||||
break;
|
||||
}
|
||||
return isCertificateTrusted;
|
||||
}
|
||||
|
||||
SecKeyRef getPublicKeyForCertificate(SecCertificateRef clientProdCert) {
|
||||
SecKeyRef aPublicKeyRef = NULL;
|
||||
if (clientProdCert != NULL) {
|
||||
|
||||
SecTrustRef aTrustRef = NULL;
|
||||
SecPolicyRef aPolicyRef = SecPolicyCreateBasicX509();
|
||||
|
||||
if (aPolicyRef) {
|
||||
if (SecTrustCreateWithCertificates((CFTypeRef)clientProdCert, aPolicyRef, &aTrustRef) == noErr) {
|
||||
SecTrustResultType result;
|
||||
if (aTrustRef) {
|
||||
if (SecTrustEvaluate(aTrustRef, &result) == noErr) {
|
||||
aPublicKeyRef = (SecKeyRef)CFBridgingRetain(CFBridgingRelease(SecTrustCopyPublicKey(aTrustRef)));
|
||||
MVMCoreLog(@"Public key fetching success.");
|
||||
} else {
|
||||
MVMCoreLog(@"Public key fetching failed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aPolicyRef) CFRelease(aPolicyRef);
|
||||
if (aTrustRef) CFRelease(aTrustRef);
|
||||
}
|
||||
return aPublicKeyRef;
|
||||
}
|
||||
|
||||
#pragma mark- SSL Pinning methods
|
||||
|
||||
+ (MFURLSessionChallengeResult *)allowChallenge:(NSURLAuthenticationChallenge *)challenge {
|
||||
SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust];
|
||||
NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
|
||||
return [MFURLSessionChallengeResult createChallengeResultWithDisposition:NSURLSessionAuthChallengeUseCredential credential:credential];
|
||||
}
|
||||
|
||||
+ (NSString *)getCertificatePath:(NSString *_Nullable)commonName {
|
||||
NSString *resourcePath = nil;
|
||||
if (commonName.length>0) {
|
||||
resourcePath = [commonName stringByReplacingOccurrencesOfString:@" " withString:@""];
|
||||
MVMCoreLog(@"Server Certificate Common Name: %@",commonName);
|
||||
}
|
||||
// prod root certificate
|
||||
NSString *pathToProdCert = nil;
|
||||
if (resourcePath.length>0) {
|
||||
MVMCoreLog(@"Name of Certificate Resource: %@",resourcePath);
|
||||
// To fetch exact certificate stored in MF bundle
|
||||
// like, if digi is root certificate from server,
|
||||
// then get respective certificate from local
|
||||
pathToProdCert = [[MVMCoreGetterUtility bundleForMVMCore] pathForResource:resourcePath ofType:@"cer"];
|
||||
} else {
|
||||
// Default is verisign
|
||||
pathToProdCert = [[MVMCoreGetterUtility bundleForMVMCore] pathForResource:@"VeriSignClass3PublicPrimaryCertificationAuthority-G5" ofType:@"cer"];
|
||||
}
|
||||
MVMCoreLog(@"Client Certificate Path Prod Cert: %@",pathToProdCert);
|
||||
return pathToProdCert;
|
||||
}
|
||||
|
||||
+ (BOOL)isCertificateExpiredAtPath:(NSString *)path {
|
||||
if (path) {
|
||||
|
||||
// Gets the certificate and creates an object for it.
|
||||
NSData *certificateData = [[NSFileManager defaultManager] contentsAtPath:path];
|
||||
SecCertificateRef certificateRef = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)certificateData);
|
||||
if (certificateRef != NULL) {
|
||||
|
||||
// Creates a policy.
|
||||
SecTrustRef trustRef = NULL;
|
||||
SecPolicyRef policyRef = SecPolicyCreateBasicX509();
|
||||
if (policyRef) {
|
||||
|
||||
// Creates a trust
|
||||
if (SecTrustCreateWithCertificates((CFTypeRef)certificateRef, policyRef, &trustRef) == noErr) {
|
||||
|
||||
// Set SSL policies for domain name check
|
||||
NSMutableArray *policies = [NSMutableArray array];
|
||||
CFDataRef clientCertDataRef = (__bridge_retained CFDataRef)certificateData;
|
||||
SecCertificateRef clientProdCert = SecCertificateCreateWithData(NULL, clientCertDataRef);
|
||||
|
||||
CFStringRef clientHostName = SecCertificateCopySubjectSummary(clientProdCert);
|
||||
|
||||
[policies addObject:(__bridge_transfer id)SecPolicyCreateSSL(true, clientHostName)];
|
||||
SecTrustSetPolicies(trustRef, (__bridge CFArrayRef)policies);
|
||||
|
||||
// release clientHostName, because it is no logner needed
|
||||
if (clientHostName) {
|
||||
CFRelease(clientHostName);
|
||||
}
|
||||
if (clientCertDataRef) {
|
||||
CFRelease(clientCertDataRef);
|
||||
}
|
||||
|
||||
OSStatus status = SecTrustSetVerifyDate(trustRef, (CFDateRef)[NSDate date]);
|
||||
MVMCoreLog(@"Client certificate status:%d",(int)status);
|
||||
if (status == errSecSuccess) {
|
||||
MVMCoreLog(@"Client Certificate is not Expired");
|
||||
return NO;
|
||||
} else {
|
||||
MVMCoreLog(@"Client Certificate Expired");
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (policyRef) CFRelease(policyRef);
|
||||
if (trustRef) CFRelease(trustRef);
|
||||
if (certificateRef) CFRelease(certificateRef);
|
||||
}
|
||||
return NO;
|
||||
} else {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark- helpers
|
||||
|
||||
+ (BOOL)checkCertificatePinning:(BOOL)certificatesPinned serverPublicKey:(SecKeyRef)serverPublicKey clientPublicKey:(SecKeyRef)clientPublicKey clientProdRootCertificateData:(NSData *_Nullable)clientProdRootCertificateData serverRootCertificateData:(NSData *_Nullable)serverRootCertificateData extraInfo:(NSMutableDictionary *_Nonnull)extraInfo {
|
||||
// Check equality of root certificates
|
||||
if ([serverRootCertificateData isEqualToData:clientProdRootCertificateData]) {
|
||||
MVMCoreLog(@"Root Certificates are equal.");
|
||||
certificatesPinned = YES;
|
||||
// [MFSSLPinningHandler logSSLError:MF_IOS_SSL_CERT_PINNED];
|
||||
[MVMCoreLoggingHandler logWithDelegateWithObject:(id)self withName:MF_IOS_SSL_CERT_PINNED withExtraInfo:extraInfo];
|
||||
MVMCoreLog(@"Certificate is successfully pinned");
|
||||
} else if ( (clientPublicKey != NULL) && (serverPublicKey != NULL) && [(__bridge id)clientPublicKey isEqual:(__bridge id)serverPublicKey] ) {
|
||||
// Publick key fallback flow to extend certificate pinning, even if root certificate expired.
|
||||
// certificate expire fall back flow-1
|
||||
MVMCoreLog(@"public key fall back flow-1");
|
||||
certificatesPinned = YES;
|
||||
// [MFSSLPinningHandler logSSLError:MF_IOS_SSL_PUBLIC_KEY_PINNED];
|
||||
[MVMCoreLoggingHandler logWithDelegateWithObject:(id)self withName:MF_IOS_SSL_PUBLIC_KEY_PINNED withExtraInfo:extraInfo];
|
||||
MVMCoreLog(@"Certificate public key is successfully pinned");
|
||||
} else {
|
||||
// Genuine failure case
|
||||
certificatesPinned = NO;
|
||||
[MFSSLPinningHandler logSSLError:MF_IOS_SSL_CERT_MISMATCH];
|
||||
[MVMCoreLoggingHandler logWithDelegateWithObject:(id)self withName:MF_IOS_SSL_CERT_MISMATCH withExtraInfo:extraInfo];
|
||||
MVMCoreLog(@"Failure Case:Client certificates data is nil or not matching with server certificate");
|
||||
}
|
||||
return certificatesPinned;
|
||||
}
|
||||
|
||||
+ (BOOL)processClientCertificate:(BOOL)certificatesPinned extraInfo:(NSMutableDictionary *_Nonnull)extraInfo serverRootCertificateData:(NSData *_Nullable)serverRootCertificateData clientProdRootCertificateData:(NSData *_Nullable)clientProdRootCertificateData serverRootCertificate:(SecCertificateRef)serverRootCertificate serverHostNameStr:(NSString *)serverHostNameStr {
|
||||
// Check, client root certificate data should not be nil
|
||||
if (clientProdRootCertificateData != nil) {
|
||||
// Get client certificate ref
|
||||
CFDataRef clientCertDataRef = (__bridge_retained CFDataRef)clientProdRootCertificateData;
|
||||
SecCertificateRef clientProdRootCert = SecCertificateCreateWithData(NULL, clientCertDataRef);
|
||||
|
||||
CFStringRef clientHostName = SecCertificateCopySubjectSummary(clientProdRootCert);
|
||||
NSString *clientHostNameStr = (__bridge NSString *)clientHostName;
|
||||
if (clientHostNameStr) {
|
||||
[extraInfo setObject:clientHostNameStr forKey:@"clientHostNameStr"];
|
||||
MVMCoreLog(@"client certificate Distinguished common Name: %@",clientHostNameStr);
|
||||
} else {
|
||||
MVMCoreLog(@"Failure Case:client common name is not found.");
|
||||
[extraInfo setObject:@"client common name is not found" forKey:@"clientHostNameStr"];
|
||||
}
|
||||
|
||||
// To log, client and server certificate's common name mismatch case
|
||||
if ([serverHostNameStr isEqualToString:clientHostNameStr]) {
|
||||
MVMCoreLog(@"Server Certificate is valid");
|
||||
} else {
|
||||
MVMCoreLog(@"Failure Case:certificate Common name mismatch.");
|
||||
[extraInfo setObject:@"certificate Common name mismatch" forKey:@"commonNameMismatch"];
|
||||
}
|
||||
|
||||
// release clientHostName, because it is no logner needed
|
||||
if (clientHostName) {
|
||||
CFRelease(clientHostName);
|
||||
}
|
||||
// release clientCertDataRef, because it is no logner needed
|
||||
if (clientCertDataRef) {
|
||||
CFRelease(clientCertDataRef);
|
||||
}
|
||||
|
||||
// Get client root certificate public key.
|
||||
// To extend certificate pinning, even if root certificate expired.
|
||||
SecKeyRef clientPublicKey = (__bridge_retained SecKeyRef)(CFBridgingRelease(getPublicKeyForCertificate(clientProdRootCert)));
|
||||
// To log, if public key is null
|
||||
if (!clientPublicKey) {
|
||||
MVMCoreLog(@"Failure Case:client public key is null.");
|
||||
[extraInfo setObject:@"client public key is null" forKey:@"clientPublicKey"];
|
||||
}
|
||||
// Get server root certificate public key.
|
||||
SecKeyRef serverPublicKey = (__bridge_retained SecKeyRef)(CFBridgingRelease(getPublicKeyForCertificate(serverRootCertificate)));
|
||||
// To log, if public key is null
|
||||
if (!serverPublicKey) {
|
||||
MVMCoreLog(@"Failure Case:server public key is null.");
|
||||
[extraInfo setObject:@"server public key is null" forKey:@"serverPublicKey"];
|
||||
}
|
||||
|
||||
// Check, server root certificate data should not be nil
|
||||
if (serverRootCertificateData) {
|
||||
certificatesPinned = [MFSSLPinningHandler checkCertificatePinning:certificatesPinned serverPublicKey:serverPublicKey clientPublicKey:clientPublicKey clientProdRootCertificateData:clientProdRootCertificateData serverRootCertificateData:serverRootCertificateData extraInfo:extraInfo];
|
||||
} else {
|
||||
// Server Certificate Data is nil, this would not happen.
|
||||
// But if happens then it is client side issue. So, bypass SSL Pinning
|
||||
certificatesPinned = YES;
|
||||
MVMCoreLog(@"Failure Case:Server Certificate Data is nil.");
|
||||
[extraInfo setObject:@"serverCertificateData null" forKey:@"serverCertificateData"];
|
||||
[MFSSLPinningHandler logSSLError:MF_IOS_SSL_SERVER_CERT_DATA_NULL];
|
||||
[MVMCoreLoggingHandler logWithDelegateWithObject:(id)self withName:MF_IOS_SSL_SERVER_CERT_DATA_NULL withExtraInfo:extraInfo];
|
||||
}
|
||||
// Release clientPublicKey, because it is no logner needed
|
||||
if (clientPublicKey) {
|
||||
CFRelease(clientPublicKey);
|
||||
}
|
||||
// Release serverPublicKey, because it is no logner needed
|
||||
if (serverPublicKey) {
|
||||
CFRelease(serverPublicKey);
|
||||
}
|
||||
} else {
|
||||
// Client certificate data is nil, this would not happen
|
||||
MVMCoreLog(@"Failure Case:Client certificate data is nil.");
|
||||
[extraInfo setObject:@"clientProdCertificateData null" forKey:@"clientProdCertificateData"];
|
||||
// But if happens then it is client side issue.
|
||||
// So, bypass SSL Pinning. Developer need to fix this.
|
||||
// It should not block user.
|
||||
certificatesPinned = YES;
|
||||
[MFSSLPinningHandler logSSLError:MF_IOS_SSL_CLIENT_CERT_NULL];
|
||||
[MVMCoreLoggingHandler logWithDelegateWithObject:(id)self withName:MF_IOS_SSL_CLIENT_CERT_NULL withExtraInfo:extraInfo];
|
||||
}
|
||||
return certificatesPinned;
|
||||
}
|
||||
|
||||
+ (void)checkSSLTesting:(BOOL *)isServerCertificateTrusted withCertificatesPinned:(BOOL *)isCertificatesPinned {
|
||||
// For testing, SSL error scenario
|
||||
if ([[MVMCoreSessionObject sharedGlobal] testingSSLError] || [[MVMCoreSessionObject sharedGlobal] sslCertificateExpired]) {
|
||||
MVMCoreLog(@"SSL Pinning Testing Error: certificate is not pinned explicitly, for testing SSL error scenarios.");
|
||||
NSString *testCase = [[MVMCoreSessionObject sharedGlobal] testingSSLError] ? @"Test Case: SSL Error validated successfully." : @"Test Case: SSL Certificate expired validated successfully.";
|
||||
MVMCoreLog(@"%@",testCase);
|
||||
*isCertificatesPinned = NO;
|
||||
*isServerCertificateTrusted = NO;
|
||||
}
|
||||
}
|
||||
|
||||
+ (MFURLSessionChallengeResult * _Nonnull)processPinningStatus:(SecTrustRef)serverTrust isServerCertificateTrusted:(BOOL)isServerCertificateTrusted certificatesPinned:(BOOL)certificatesPinned extraInfo:(NSMutableDictionary *_Nonnull)extraInfo {
|
||||
// The pinnning check
|
||||
if (certificatesPinned && isServerCertificateTrusted) {
|
||||
NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
|
||||
// [MFSSLPinningHandler logSSLError:MF_IOS_SSL_PINNING_SUCCESS];
|
||||
[MVMCoreLoggingHandler logWithDelegateWithObject:(id)self withName:MF_IOS_SSL_PINNING_SUCCESS withExtraInfo:extraInfo];
|
||||
MVMCoreLog(@"**********************SSL Pinning End: Pinning Successfully Completed******************************");
|
||||
return [MFURLSessionChallengeResult createChallengeResultWithDisposition:NSURLSessionAuthChallengeUseCredential credential:credential];
|
||||
} else {
|
||||
[MVMCoreSessionObject sharedGlobal].connectionCancelledForSSLError = YES;
|
||||
// either no connection or wrong SSL certificate.
|
||||
[MFSSLPinningHandler logSSLError:MF_IOS_SSL_PINNING_FAILED];
|
||||
[MVMCoreLoggingHandler logWithDelegateWithObject:(id)self withName:MF_IOS_SSL_PINNING_FAILED withExtraInfo:extraInfo];
|
||||
MVMCoreLog(@"SSL extraInfo:%@",extraInfo);
|
||||
MVMCoreLog(@"**********************SSL Pinning End: Pinning Failed******************************");
|
||||
return [MFURLSessionChallengeResult createChallengeResultWithDisposition:NSURLSessionAuthChallengeCancelAuthenticationChallenge credential:NULL];
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSData *)clientCertificateData:(NSMutableDictionary *_Nonnull)extraInfo withCommonName:(NSString *_Nullable)commonName {
|
||||
NSData *clientProdRootCertificateData = nil;
|
||||
NSString *pathToProdCert = [MFSSLPinningHandler getCertificatePath:commonName];
|
||||
if (pathToProdCert.length > 0) {
|
||||
MVMCoreLog(@"Certificate path is found.");
|
||||
clientProdRootCertificateData = [NSData dataWithContentsOfFile:pathToProdCert];
|
||||
// if not testing SSL expiry
|
||||
if (!([MVMCoreSessionObject sharedGlobal].sslCertificateExpired)) {
|
||||
// To check, if client root certificate is expired
|
||||
[MVMCoreSessionObject sharedGlobal].sslCertificateExpired = [MFSSLPinningHandler isCertificateExpiredAtPath:pathToProdCert];
|
||||
[extraInfo setValue:[NSNumber numberWithBool:[MVMCoreSessionObject sharedGlobal].sslCertificateExpired] forKey:@"sslCertificateExpired"];
|
||||
}
|
||||
} else {
|
||||
MVMCoreLog(@"Failure Case:Not able to find client root certificate path");
|
||||
// log this failure with extra info
|
||||
[extraInfo setObject:@"pathToProdCert is nil" forKey:@"pathToProdCert"];
|
||||
[MFSSLPinningHandler logSSLError:MF_IOS_SSL_CERT_PATH_NOT_FOUND];
|
||||
[MVMCoreLoggingHandler logWithDelegateWithObject:(id)self withName:MF_IOS_SSL_CERT_PATH_NOT_FOUND withExtraInfo:extraInfo];
|
||||
}
|
||||
return clientProdRootCertificateData;
|
||||
}
|
||||
|
||||
#pragma mark- NSURLSessionDelegate methods
|
||||
|
||||
+ (MFURLSessionChallengeResult * _Nonnull)getResultForURLSession:(NSURLSession *_Nonnull)session didReceiveChallenge:(NSURLAuthenticationChallenge *_Nonnull)challenge {
|
||||
|
||||
MVMCoreLog(@"**********************SSL Pinning started******************************");
|
||||
NSMutableDictionary *extraInfo = [NSMutableDictionary dictionary];
|
||||
[extraInfo setObject:[[UIDevice currentDevice] systemVersion] forKey:ParameterOSVersion];
|
||||
|
||||
// SSL status will always be true until turned off from Test screen
|
||||
if ([MFSSLPinningHandler shouldBeSSLPinned]) {
|
||||
|
||||
// First, check authenticationMethod, it should be NSURLAuthenticationMethodServerTrust
|
||||
if ([[[challenge protectionSpace] authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust]) {
|
||||
|
||||
// Get server trust reference
|
||||
SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust];
|
||||
|
||||
// Evaluate server trust or chain of certificates
|
||||
MVMCoreLog(@"Evaluating server certificate");
|
||||
BOOL isServerCertificateTrusted = evaluateCertificate(serverTrust);
|
||||
if (isServerCertificateTrusted) {
|
||||
MVMCoreLog(@"Server certificate is Trusted.");
|
||||
[extraInfo setObject:@"YES" forKey:@"isServerCertificateTrusted"];
|
||||
} else {
|
||||
MVMCoreLog(@"Failure Case:Server certificate is not Trusted.");
|
||||
[extraInfo setObject:@"NO" forKey:@"isServerCertificateTrusted"];
|
||||
}
|
||||
|
||||
// Get certificate count from network
|
||||
CFIndex certificateCount = 0;
|
||||
if (serverTrust) {
|
||||
certificateCount = SecTrustGetCertificateCount(serverTrust);
|
||||
MVMCoreLog(@"serverCertificateCount:%ld",certificateCount);
|
||||
[extraInfo setObject:[NSNumber numberWithLong:certificateCount] forKey:@"serverCertificateCount"];
|
||||
} else {
|
||||
MVMCoreLog(@"Failure Case:serverTrust is nil.");
|
||||
[extraInfo setObject:@"serverTrust is nil" forKey:@"serverTrust"];
|
||||
[extraInfo setObject:[NSNumber numberWithLong:certificateCount] forKey:@"serverCertificateCount"];
|
||||
}
|
||||
|
||||
// Get server root certificate
|
||||
SecCertificateRef serverRootCertificate = NULL;
|
||||
// check certificate count to avoid crash
|
||||
if (certificateCount>0) {
|
||||
serverRootCertificate = SecTrustGetCertificateAtIndex(serverTrust, certificateCount-1);
|
||||
}
|
||||
|
||||
if (serverRootCertificate != NULL) {
|
||||
|
||||
MVMCoreLog(@"Server Root Certificate:%@",serverRootCertificate);
|
||||
// To check the validity of server certificate, that we are communicating to our designated mobile.vzw.com server
|
||||
CFStringRef serverHostName = SecCertificateCopySubjectSummary(serverRootCertificate);
|
||||
NSString *serverHostNameStr = (__bridge NSString *)serverHostName;
|
||||
if (serverHostNameStr) {
|
||||
MVMCoreLog(@"Server certificate distinguished common Name: %@",serverHostNameStr);
|
||||
[extraInfo setObject:serverHostNameStr forKey:@"serverHostNameStr"];
|
||||
} else {
|
||||
MVMCoreLog(@"Failure Case:server host name is nil.");
|
||||
[extraInfo setObject:@"server host name is nil" forKey:@"serverHostNameStr"];
|
||||
}
|
||||
|
||||
// release serverHostName, because it is no logner needed
|
||||
if (serverHostName) {
|
||||
CFRelease(serverHostName);
|
||||
}
|
||||
|
||||
// Get server root certficate data
|
||||
CFDataRef serverCertificateDataRef = SecCertificateCopyData(serverRootCertificate);
|
||||
NSData *serverRootCertificateData = (__bridge_transfer NSData*)serverCertificateDataRef;
|
||||
|
||||
// Get/load client root certificate
|
||||
NSData *clientProdRootCertificateData = [MFSSLPinningHandler clientCertificateData:extraInfo withCommonName:serverHostNameStr];
|
||||
|
||||
// To track certificate is pinned or not
|
||||
BOOL certificatesPinned = NO;
|
||||
|
||||
certificatesPinned = [MFSSLPinningHandler processClientCertificate:certificatesPinned extraInfo:extraInfo serverRootCertificateData:serverRootCertificateData clientProdRootCertificateData:clientProdRootCertificateData serverRootCertificate:serverRootCertificate serverHostNameStr:serverHostNameStr];
|
||||
|
||||
[MFSSLPinningHandler checkSSLTesting:&isServerCertificateTrusted withCertificatesPinned:&certificatesPinned];
|
||||
|
||||
// add extra info to analytics
|
||||
[extraInfo setObject:[NSNumber numberWithBool:certificatesPinned] forKey:@"certificatesPinned"];
|
||||
[extraInfo setObject:[NSNumber numberWithBool:isServerCertificateTrusted] forKey:@"isServerCertificateTrusted"];
|
||||
|
||||
return [MFSSLPinningHandler processPinningStatus:serverTrust isServerCertificateTrusted:isServerCertificateTrusted certificatesPinned:certificatesPinned extraInfo:extraInfo];
|
||||
} else {
|
||||
// this is should not happen, if happening then either client or apple bug
|
||||
// server certificate is nil, track this and inform to server
|
||||
// bcoz it is client/apple issue, then bypass SSL Pinning
|
||||
MVMCoreLog(@"Failure: Server root certificate is null.");
|
||||
[extraInfo setObject:@"server root Certificate null" forKey:@"serverCertificate"];
|
||||
NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
|
||||
[MFSSLPinningHandler logSSLError:MF_IOS_SSL_SERVER_CERT_NULL];
|
||||
[MVMCoreLoggingHandler logWithDelegateWithObject:(id)self withName:MF_IOS_SSL_SERVER_CERT_NULL withExtraInfo:extraInfo];
|
||||
MVMCoreLog(@"SSL extraInfo:%@",extraInfo);
|
||||
MVMCoreLog(@"**********************SSL Pinning End: Pinning Failed******************************");
|
||||
return [MFURLSessionChallengeResult createChallengeResultWithDisposition:NSURLSessionAuthChallengeUseCredential credential:credential];
|
||||
}
|
||||
} else {
|
||||
// authenticationMethod is different
|
||||
// FYI: NSURLAuthenticationMethodNTLM mean network issue
|
||||
MVMCoreLog(@"Protection space authenticationMethod is different:%@",[[challenge protectionSpace] authenticationMethod]);
|
||||
NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;
|
||||
if ([[[challenge protectionSpace] authenticationMethod] isEqualToString:NSURLAuthenticationMethodNTLM]) {
|
||||
disposition = NSURLSessionAuthChallengePerformDefaultHandling;
|
||||
}
|
||||
MVMCoreLog(@"If authentication Method is NSURLAuthenticationMethodNTLM, then it is network issue in your device, please referesh you internet and retry.");
|
||||
MVMCoreLog(@"**********************SSL Pinning End: Pinning Failed******************************");
|
||||
return [MFURLSessionChallengeResult createChallengeResultWithDisposition:disposition credential:NULL];
|
||||
}
|
||||
} else {
|
||||
MVMCoreLog(@"SSL Pinning is switched off.");
|
||||
[extraInfo setObject:@"Switched off" forKey:@"SSL_Status"];
|
||||
[MFSSLPinningHandler logSSLError:MF_IOS_SSL_PINNING_SWITCHED_OFF];
|
||||
[MVMCoreLoggingHandler logWithDelegateWithObject:(id)self withName:MF_IOS_SSL_PINNING_SWITCHED_OFF withExtraInfo:extraInfo];
|
||||
MVMCoreLog(@"SSL extraInfo:%@",extraInfo);
|
||||
MVMCoreLog(@"**********************SSL Pinning End: Pinning is turned off ******************************");
|
||||
return [MFSSLPinningHandler allowChallenge:challenge];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark- SSL Pinning Error Handling
|
||||
|
||||
+ (nonnull MVMCoreErrorObject *)errorObjectForSSLErrors:(nullable NSString *)locationForError {
|
||||
MVMCoreErrorObject *error = nil;
|
||||
if ([MVMCoreSessionObject sharedGlobal].sslCertificateExpired) {
|
||||
// SSL upgrade screen error object
|
||||
error = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:ERROR_SSL_UPDATE_TITLE_KEY] message:[MVMCoreGetterUtility hardcodedStringWithKey:ERROR_SSL_UPDATE_MESSAGE_KEY] messageToLog:[MVMCoreGetterUtility hardcodedStringWithKey:ERROR_SSL_UPDATE_MESSAGE_KEY] code:ErrorCodeSSL domain:ErrorDomainNative location:locationForError];
|
||||
} else {
|
||||
// SSL Error object
|
||||
NSString *message = [NSString stringWithFormat:@"%@ %@ %@",[MVMCoreGetterUtility hardcodedStringWithKey:ERROR_SSL_MESSAGE_PREFIX_KEY],[MVMCoreGetterUtility hardcodedStringWithKey:ERROR_SSL_MESSAGE_TITLE_KEY],[MVMCoreGetterUtility hardcodedStringWithKey:ERROR_SSL_MESSAGE_POSTFIX_KEY]];
|
||||
error = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorTitle] message:message messageToLog:message code:ErrorCodeSSL domain:ErrorDomainNative location:locationForError];
|
||||
}
|
||||
error.sslError = YES;
|
||||
error.errorScreenError = YES;
|
||||
return error;
|
||||
}
|
||||
|
||||
+ (nonnull MVMCoreErrorObject *)createErrorObjectForNSErrorAndVerifySSLErrors:(nonnull NSError *)error location:(nullable NSString *)locationForError {
|
||||
MVMCoreErrorObject *errorObject = nil;
|
||||
// If the request was cancelled due to SSL error.
|
||||
if ([error code] == NSURLErrorCancelled && [MVMCoreSessionObject sharedGlobal].connectionCancelledForSSLError) {
|
||||
errorObject = [MFSSLPinningHandler errorObjectForSSLErrors:locationForError];
|
||||
} else {
|
||||
// Error with the request.
|
||||
errorObject = [MVMCoreErrorObject createErrorObjectForNSError:error location:locationForError];
|
||||
}
|
||||
return errorObject;
|
||||
}
|
||||
|
||||
+ (void)handleSSLErrors:(nullable MVMCoreErrorObject *)errorObject requestParameters:(nonnull MVMCoreRequestParameters *)requestParameters {
|
||||
|
||||
// If the request was cancelled due to SSL error.
|
||||
if (errorObject.code == NSURLErrorCancelled && [MVMCoreSessionObject sharedGlobal].connectionCancelledForSSLError) {
|
||||
|
||||
// show SSL error screen's
|
||||
MVMCoreErrorObject *sslError = [MFSSLPinningHandler errorObjectForSSLErrors:[[MVMCoreLoadHandler sharedGlobal] errorLocationForRequest:self pageType:requestParameters.pageType modules:[NSString stringWithFormat:@"%@",requestParameters.modules]]];
|
||||
[MVMCoreDispatchUtility performBlockOnMainThread:^{
|
||||
UIViewController *viewController = [[MVMCoreObject sharedInstance].globalLoadDelegate getNativeScreenForRequestError:sslError requestObject:requestParameters];
|
||||
if (viewController) {
|
||||
[[MVMCoreNavigationHandler sharedNavigationHandler] setViewControllers:@[viewController] navigationController:nil animated:YES delegate:nil replaceInStack:NO completionHandler:nil];
|
||||
|
||||
}
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - SSL Logging
|
||||
|
||||
+ (void)logSSLError:(NSString *_Nonnull)tag {
|
||||
MVMCoreErrorObject *errorObject = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:ERROR_SSL_TITLE] message:tag code:ErrorCodeSSL domain:ErrorDomainNative location:[[MVMCoreLoadHandler sharedGlobal] errorLocationForRequest:self pageType:@"SSL" modules:@""]];
|
||||
[MVMCoreLoggingHandler addErrorToLog:errorObject];
|
||||
}
|
||||
|
||||
@end
|
||||
@ -1,18 +0,0 @@
|
||||
//
|
||||
// MFURLSessionChallengeResult.h
|
||||
// mobilefirst
|
||||
//
|
||||
// Created by Pfeil, Scott Robert on 8/4/17.
|
||||
// Copyright © 2017 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface MFURLSessionChallengeResult : NSObject
|
||||
|
||||
@property (nonatomic) NSURLSessionAuthChallengeDisposition disposition;
|
||||
@property (nonatomic, nullable, strong) NSURLCredential *credential;
|
||||
|
||||
+ (instancetype _Nullable )createChallengeResultWithDisposition:(NSURLSessionAuthChallengeDisposition)disposition credential:(NSURLCredential * _Nullable)credential;
|
||||
|
||||
@end
|
||||
@ -1,20 +0,0 @@
|
||||
//
|
||||
// MFURLSessionChallengeResult.m
|
||||
// mobilefirst
|
||||
//
|
||||
// Created by Pfeil, Scott Robert on 8/4/17.
|
||||
// Copyright © 2017 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MFURLSessionChallengeResult.h"
|
||||
|
||||
@implementation MFURLSessionChallengeResult
|
||||
|
||||
+ (instancetype _Nullable )createChallengeResultWithDisposition:(NSURLSessionAuthChallengeDisposition)disposition credential:(NSURLCredential * _Nullable)credential {
|
||||
MFURLSessionChallengeResult *result = [[MFURLSessionChallengeResult alloc] init];
|
||||
result.disposition = disposition;
|
||||
result.credential = credential;
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
||||
@ -92,7 +92,6 @@ FOUNDATION_EXPORT const unsigned char MVMCoreVersionString[];
|
||||
// Other Handlers and Protocols
|
||||
#import <MVMCore/MobileFirstProtocol.h>
|
||||
#import <MVMCore/MVMCoreLoggingHandler.h>
|
||||
#import <MVMCore/MFSSLPinningHandler.h>
|
||||
|
||||
// Singletons
|
||||
#import <MVMCore/MVMCoreCache.h>
|
||||
@ -104,6 +103,3 @@ FOUNDATION_EXPORT const unsigned char MVMCoreVersionString[];
|
||||
|
||||
//Freebee
|
||||
#import <MVMCore/MFFreebeeHandler.h>
|
||||
|
||||
//SSL
|
||||
#import <MVMCore/MFURLSessionChallengeResult.h>
|
||||
|
||||
@ -32,4 +32,7 @@
|
||||
// Can overwrite to set the request time out time.
|
||||
- (NSTimeInterval)timeOutIntervalForRequest:(nullable MVMCoreRequestParameters *)request;
|
||||
|
||||
// Can return an error object.
|
||||
+ (nonnull MVMCoreErrorObject *)createErrorObjectForRequestNSError:(nonnull NSError *)error forRequest:(nonnull NSURLRequest *)request location:(nullable NSString *)locationForError;
|
||||
|
||||
@end
|
||||
|
||||
@ -21,4 +21,7 @@
|
||||
// Can be used to choose how to log error objects.
|
||||
- (void)addErrorToLog:(nonnull MVMCoreErrorObject *)errorObject;
|
||||
|
||||
// Log that the load has finished.
|
||||
- (void)logLoadFinished:(nullable MVMCoreLoadObject *)loadObject loadedViewController:(nullable UIViewController <MVMCoreViewControllerProtocol> *)loadedViewController error:(nullable MVMCoreErrorObject *)error;
|
||||
|
||||
@end
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
@property (nonatomic) BOOL masterShouldBeAccessible;
|
||||
@property (nonatomic) BOOL supportShouldBeAccessible;
|
||||
@property (nonatomic) BOOL cartShouldBeAccessible;
|
||||
@property (nonatomic) BOOL communityShouldBeAccessible;
|
||||
@property (nonatomic) BOOL closeButtonAccessible;
|
||||
@property (nullable, nonatomic, readonly) NSDictionary *closeButtonActionMap;
|
||||
|
||||
|
||||
@ -129,6 +129,9 @@
|
||||
- (void)addImageToCache:(nonnull UIImage *)image withName:(nonnull NSString *)imageName;
|
||||
- (void)addDataToCache:(nonnull NSData *)data withName:(nonnull NSString *)imageName;
|
||||
|
||||
// Removes image from cache if we need to update
|
||||
- (void)removeImageFromCache:(nonnull NSString *)imageName;
|
||||
|
||||
// clears the image cache
|
||||
- (void)clearImageCache;
|
||||
|
||||
|
||||
@ -624,4 +624,29 @@ static NSString * const STATIC_CACHE_COMPONENT = @"StaticCache.txt";
|
||||
});
|
||||
}
|
||||
|
||||
- (void)removeImageFromCache:(nonnull NSString *)imageName {
|
||||
|
||||
if (imageName) {
|
||||
dispatch_barrier_async(self.imageCacheQueue, ^{
|
||||
|
||||
if ([imageName hasPrefix:@"http"]) {
|
||||
for (NSString *key in self.imgCache.allKeys) {
|
||||
NSURLComponents *components = [[NSURLComponents alloc] initWithString:key];
|
||||
if (components) {
|
||||
components.fragment = nil;
|
||||
components.query = nil;
|
||||
NSString *urlWithoutParams = [components URL].absoluteString;
|
||||
|
||||
if ([imageName isEqualToString:urlWithoutParams]) {
|
||||
[self.imgCache removeObjectForKey:key];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
[self.imgCache removeObjectForKey:imageName];
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -8,6 +8,8 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <MVMCore/MVMCoreErrorObject.h>
|
||||
#import <MVMCore/MVMCoreViewControllerProtocol.h>
|
||||
#import <MVMCore/MVMCoreLoadObject.h>
|
||||
|
||||
#define MVMCoreLog(fmt, ...) \
|
||||
[MVMCoreLoggingHandler logDebugMessageWithDelegate:[NSString stringWithFormat:(@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__]];
|
||||
@ -17,5 +19,6 @@
|
||||
+ (void)addErrorToLog:(nonnull MVMCoreErrorObject *)errorObject;
|
||||
+ (void)logDebugMessageWithDelegate:(nullable NSString *)message;
|
||||
+ (void)logWithDelegateWithObject:(nullable id)object withName:(nullable NSString *)name withExtraInfo:(nullable NSDictionary *)extra;
|
||||
+ (void)logWithDelegateLoadFinished:(nullable MVMCoreLoadObject *)loadObject loadedViewController:(nullable UIViewController <MVMCoreViewControllerProtocol> *)loadedViewController error:(nullable MVMCoreErrorObject *)error;
|
||||
|
||||
@end
|
||||
|
||||
@ -29,4 +29,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)logWithDelegateLoadFinished:(nullable MVMCoreLoadObject *)loadObject loadedViewController:(nullable UIViewController <MVMCoreViewControllerProtocol> *)loadedViewController error:(nullable MVMCoreErrorObject *)error {
|
||||
if ([[MVMCoreObject sharedInstance].loggingDelegate respondsToSelector:@selector(logWithDelegateLoadFinished:loadedViewController:error:)]) {
|
||||
[[MVMCoreObject sharedInstance].loggingDelegate logLoadFinished:loadObject loadedViewController:loadedViewController error:error];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@ -50,10 +50,10 @@
|
||||
|
||||
// Check if tab control.
|
||||
NSString *pageType = [self.navigationObject.viewController performSelector:@selector(pageType)];
|
||||
if ([self.navigationObject.viewController conformsToProtocol:@protocol(MVMCoreViewManagerProtocol)]) {
|
||||
if ([controller conformsToProtocol:@protocol(MVMCoreViewManagerProtocol)] && [self.navigationObject.viewController conformsToProtocol:@protocol(MVMCoreViewManagerProtocol)]) {
|
||||
|
||||
// Check if page is in view manager, if so, replace it.
|
||||
if ([((UIViewController <MVMCoreViewManagerProtocol>*)self.navigationObject.viewController) containsPageWithPageType:pageType]) {
|
||||
if ([((UIViewController <MVMCoreViewManagerProtocol>*)controller) containsPageWithPageType:pageType]) {
|
||||
location = i;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -22,12 +22,6 @@
|
||||
// The context root to use on the base url.
|
||||
@property (nullable, strong, nonatomic) NSString *contextRoot;
|
||||
|
||||
// SSL error
|
||||
@property (assign, nonatomic) BOOL sslCertificateExpired;
|
||||
@property (assign, nonatomic) BOOL testingSSLError;
|
||||
@property (assign, nonatomic) BOOL connectionCancelledForSSLError;
|
||||
@property (assign, nonatomic) BOOL isClientPulling;
|
||||
|
||||
|
||||
// Returns the shared instance of this singleton
|
||||
+ (nullable instancetype)sharedGlobal;
|
||||
|
||||
@ -141,7 +141,7 @@
|
||||
if (self.sessionBeingTimed || self.sessionTimedOut) {
|
||||
|
||||
NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate];
|
||||
if ((!fequal(0, self.secondsUntilWarning) && now > self.timeTimerStarted + self.secondsUntilWarning) || (!fequal(0, self.secondsUntilTimeout) && now > self.timeTimerStarted + self.secondsUntilTimeout)) {
|
||||
if ((!fequal(0, self.secondsUntilWarning) && now > self.timeTimerStarted + self.secondsUntilWarning) || (fequal(0, self.secondsUntilWarning) && !fequal(0, self.secondsUntilTimeout) && now > self.timeTimerStarted + self.secondsUntilTimeout)) {
|
||||
|
||||
// Timeout if we are passed the warning.
|
||||
[[MVMCoreAlertHandler sharedAlertHandler] removeAllAlertViews];
|
||||
|
||||
@ -13,11 +13,3 @@
|
||||
"Error Message Critical Key" = "Unable to process your request at this time. Please contact Customer Service by dialing *611. Thank you.";
|
||||
"Error Message Unable To Process Request Key" = "Unable to process your request. Please try again later.";
|
||||
|
||||
//SSL Pinning
|
||||
"SSL Error Message Prefix" = "Sorry; you're unable to login to My Verizon App at this time. Please check your network connection or try again later or visit";
|
||||
"SSL Error Message Title" = "verizonwireless.com";
|
||||
"SSL Error Message Postfix" = "(SSL Cerificate Verification Failed).";
|
||||
"SSL Update Title" = "Help us keep you safe.";
|
||||
"SSL Update Message" = "Update your My Verizon App to ensure it's aligned with our latest security standards.";
|
||||
"SSL Error Title" = "SSL Error";
|
||||
|
||||
|
||||
@ -8,6 +8,9 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <MVMCore/MVMCoreViewControllerProtocol.h>
|
||||
#import <MVMCore/MVMCoreLoadObject.h>
|
||||
#import <MVMCore/MVMCorePresentationDelegateProtocol.h>
|
||||
|
||||
@interface MVMCoreActionUtility : NSObject
|
||||
|
||||
@ -17,8 +20,8 @@
|
||||
// Links away to safari or another app. Returns if successful.
|
||||
+ (BOOL)linkAway:(nullable NSString *)safariURLString appURLString:(nullable NSString *)appURLString;
|
||||
|
||||
// Hashes the passed in string with SHA256. Returns the hashed string.
|
||||
+ (nullable NSString *)hashStringWithSHA256:(nullable NSString *)stringToHash;
|
||||
// Can call to display a view controller based on the load object in the same way the architecture does it. Will check the presentation style of the page, action, and request. Will check if needs a view manager.
|
||||
+ (void)displayViewController:(nonnull UIViewController <MVMCoreViewControllerProtocol> *)viewController forLoadObject:(nullable MVMCoreLoadObject *)loadObject presentationDelegate:(nullable NSObject<MVMCorePresentationDelegateProtocol>*)delegate completionHandler:(nullable void (^)(void))completionBlock;
|
||||
|
||||
#pragma mark - keyboard
|
||||
|
||||
|
||||
@ -9,7 +9,14 @@
|
||||
#import "MVMCoreActionUtility.h"
|
||||
#import "MVMCoreDispatchUtility.h"
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <CommonCrypto/CommonDigest.h>
|
||||
#import "MVMCoreViewControllerProtocol.h"
|
||||
#import "MVMCorePresentationDelegateProtocol.h"
|
||||
#import "MVMCoreLoadObject.h"
|
||||
#import "MVMCoreRequestParameters.h"
|
||||
#import "NSDictionary+MFConvenience.h"
|
||||
#import "MVMCoreJSONConstants.h"
|
||||
#import "MVMCoreObject.h"
|
||||
#import "MVMCoreNavigationHandler.h"
|
||||
|
||||
@implementation MVMCoreActionUtility
|
||||
|
||||
@ -104,19 +111,30 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSString *)hashStringWithSHA256:(NSString *)stringToHash {
|
||||
+ (void)displayViewController:(nonnull UIViewController <MVMCoreViewControllerProtocol> *)viewController forLoadObject:(nullable MVMCoreLoadObject *)loadObject presentationDelegate:(nullable NSObject<MVMCorePresentationDelegateProtocol>*)delegate completionHandler:(nullable void (^)(void))completionBlock {
|
||||
|
||||
NSString *hashedString = nil;
|
||||
if (stringToHash) {
|
||||
NSData *data = [stringToHash dataUsingEncoding:NSUTF8StringEncoding];
|
||||
// Lets the server determine the presentation style if not explicitely set by developer.
|
||||
if (loadObject.requestParameters.loadStyle == MFLoadStyleDefault) {
|
||||
|
||||
unsigned char hashedBytes[CC_SHA256_DIGEST_LENGTH];
|
||||
CC_SHA256([data bytes],(uint)[data length], hashedBytes);
|
||||
// Sets it first based on the action map.
|
||||
NSString *presentationStyle = [loadObject.requestParameters.actionMap stringForKey:KeyPresentationStyle];
|
||||
[loadObject.requestParameters setMFLoadStyleBasedOnPresentationStyle:presentationStyle];
|
||||
|
||||
NSData *hashedData = [NSData dataWithBytes:hashedBytes length:CC_SHA256_DIGEST_LENGTH];
|
||||
hashedString = [hashedData base64EncodedStringWithOptions:0];
|
||||
// Let's the response override if needed.
|
||||
presentationStyle = [loadObject.pageJSON stringForKey:KeyPresentationStyle];
|
||||
[loadObject.requestParameters setMFLoadStyleBasedOnPresentationStyle:presentationStyle];
|
||||
}
|
||||
return hashedString;
|
||||
|
||||
// Check if we need to load on another control
|
||||
__block UIViewController *viewControllerToLoad = nil;
|
||||
if ([[MVMCoreObject sharedInstance].globalLoadDelegate respondsToSelector:@selector(getViewManagerWithViewController:loadObject:)]) {
|
||||
[MVMCoreDispatchUtility performSyncBlockOnMainThread:^{
|
||||
viewControllerToLoad = [[MVMCoreObject sharedInstance].globalLoadDelegate getViewManagerWithViewController:viewController loadObject:loadObject];
|
||||
}];
|
||||
}
|
||||
|
||||
// Navigates
|
||||
[[MVMCoreNavigationHandler sharedNavigationHandler] navigateWithLoadObject:loadObject viewController:(viewControllerToLoad ?: viewController) delegate:delegate completionHandler:completionBlock];
|
||||
}
|
||||
|
||||
#pragma mark - keyboard
|
||||
|
||||
Loading…
Reference in New Issue
Block a user