diff --git a/node_modules/react-native/Libraries/Lists/VirtualizedList.js b/node_modules/react-native/Libraries/Lists/VirtualizedList.js index 7dffc17..548e7bb 100644 --- a/node_modules/react-native/Libraries/Lists/VirtualizedList.js +++ b/node_modules/react-native/Libraries/Lists/VirtualizedList.js @@ -8,6 +8,7 @@ * @format */ 'use strict'; +const Platform = require('../Utilities/Platform'); const Batchinator = require('../Interaction/Batchinator'); const FillRateHelper = require('./FillRateHelper'); @@ -1965,7 +1966,7 @@ class VirtualizedCellWrapper extends React.Component<{ const styles = StyleSheet.create({ verticallyInverted: { - transform: [{scaleY: -1}], + ...Platform.select({android: {transform: [{perspective: 1}, {scaleY: -1}]}, ios: {transform: [{scaleY: -1}]}}), }, horizontallyInverted: { transform: [{scaleX: -1}], diff --git a/node_modules/react-native/Libraries/WebSocket/RCTSRWebSocket.h b/node_modules/react-native/Libraries/WebSocket/RCTSRWebSocket.h index 1b17cff..9efa98e 100644 --- a/node_modules/react-native/Libraries/WebSocket/RCTSRWebSocket.h +++ b/node_modules/react-native/Libraries/WebSocket/RCTSRWebSocket.h @@ -54,13 +54,14 @@ extern NSString *const RCTSRHTTPResponseErrorKey; @property (nonatomic, readonly) RCTSRReadyState readyState; @property (nonatomic, readonly, strong) NSURL *url; +@property (nonatomic, readonly, strong) NSString *certificate; // This returns the negotiated protocol. // It will be nil until after the handshake completes. @property (nonatomic, readonly, copy) NSString *protocol; // Protocols should be an array of strings that turn into Sec-WebSocket-Protocol. -- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray *)protocols NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray *)protocols certificate:(NSString *)certificate NS_DESIGNATED_INITIALIZER; - (instancetype)initWithURLRequest:(NSURLRequest *)request; // Some helper constructors. @@ -88,6 +89,8 @@ extern NSString *const RCTSRHTTPResponseErrorKey; // Send Data (can be nil) in a ping message. - (void)sendPing:(NSData *)data; +// Get the certificate identity from the keyChain by name +- (SecIdentityRef) GetIdentityByName:(NSString *)name; @end #pragma mark - RCTSRWebSocketDelegate diff --git a/node_modules/react-native/Libraries/WebSocket/RCTSRWebSocket.m b/node_modules/react-native/Libraries/WebSocket/RCTSRWebSocket.m index a134d2e..e815938 100644 --- a/node_modules/react-native/Libraries/WebSocket/RCTSRWebSocket.m +++ b/node_modules/react-native/Libraries/WebSocket/RCTSRWebSocket.m @@ -231,7 +231,7 @@ @implementation RCTSRWebSocket RCTSRIOConsumerPool *_consumerPool; } -- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray *)protocols +- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray *)protocols certificate:(NSString *)certificate { RCTAssertParam(request); @@ -241,6 +241,10 @@ - (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray *)protoc NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:components.URL]; [request setAllHTTPHeaderFields:[NSHTTPCookie requestHeaderFieldsWithCookies:cookies]]; } - return [self initWithURLRequest:request protocols:protocols]; + return [self initWithURLRequest:request protocols:protocols certificate:self.certificate]; } - (void)_RCTSR_commonInit; @@ -518,6 +522,24 @@ - (void)_initializeStreams; RCTLogInfo(@"SocketRocket: In debug mode. Allowing connection to any root cert"); #endif + if (_certificate) { + SecIdentityRef identity = [self GetIdentityByName:_certificate]; + if (identity != nil) { + SecCertificateRef certificate = NULL; + OSStatus status = SecIdentityCopyCertificate(identity, &certificate); + if (!status) { + NSArray *myCerts = [[NSArray alloc] initWithObjects:(__bridge id)identity, (__bridge id)certificate, nil]; + + [SSLOptions setObject:[NSNumber numberWithBool:NO] forKey:(NSString *)kCFStreamSSLValidatesCertificateChain]; + [SSLOptions setObject:[NSString stringWithFormat:@"%@:%d", host, port] forKey:(NSString *)kCFStreamSSLPeerName]; + [SSLOptions setObject:(NSString *)kCFStreamSocketSecurityLevelNegotiatedSSL forKey:(NSString*)kCFStreamSSLLevel]; + [SSLOptions setObject:(NSString *)kCFStreamSocketSecurityLevelNegotiatedSSL forKey:(NSString*)kCFStreamPropertySocketSecurityLevel]; + [SSLOptions setObject:myCerts forKey:(NSString *)kCFStreamSSLCertificates]; + [SSLOptions setObject:[NSNumber numberWithBool:NO] forKey:(NSString *)kCFStreamSSLIsServer]; + } + } + } + [_outputStream setProperty:SSLOptions forKey:(__bridge id)kCFStreamPropertySSLSettings]; } diff --git a/node_modules/react-native/Libraries/WebSocket/RCTWebSocketModule.m b/node_modules/react-native/Libraries/WebSocket/RCTWebSocketModule.m index d9387c4..93481be 100644 --- a/node_modules/react-native/Libraries/WebSocket/RCTWebSocketModule.m +++ b/node_modules/react-native/Libraries/WebSocket/RCTWebSocketModule.m @@ -81,7 +81,7 @@ - (void)invalidate [request addValue:[RCTConvert NSString:value] forHTTPHeaderField:key]; }]; - RCTSRWebSocket *webSocket = [[RCTSRWebSocket alloc] initWithURLRequest:request protocols:protocols]; + RCTSRWebSocket *webSocket = [[RCTSRWebSocket alloc] initWithURLRequest:request protocols:protocols certificate:options[@"certificate"]]; [webSocket setDelegateDispatchQueue:_methodQueue]; webSocket.delegate = self; webSocket.reactTag = socketID; diff --git a/node_modules/react-native/Libraries/WebSocket/WebSocket.js b/node_modules/react-native/Libraries/WebSocket/WebSocket.js index 35f0757..a0205fc 100644 --- a/node_modules/react-native/Libraries/WebSocket/WebSocket.js +++ b/node_modules/react-native/Libraries/WebSocket/WebSocket.js @@ -92,7 +92,7 @@ class WebSocket extends (EventTarget(...WEBSOCKET_EVENTS): any) { protocols = [protocols]; } - const {headers = {}, ...unrecognized} = options || {}; + const {headers = {}, certificate = {}, ...unrecognized} = options || {}; // Preserve deprecated backwards compatibility for the 'origin' option /* $FlowFixMe(>=0.68.0 site=react_native_fb) This comment suppresses an @@ -129,7 +129,7 @@ class WebSocket extends (EventTarget(...WEBSOCKET_EVENTS): any) { this._eventEmitter = new NativeEventEmitter(NativeWebSocketModule); this._socketId = nextWebSocketId++; this._registerEvents(); - NativeWebSocketModule.connect(url, protocols, {headers}, this._socketId); + NativeWebSocketModule.connect(url, protocols, {headers, certificate}, this._socketId); } get binaryType(): ?BinaryType {