@onekeyfe/react-native-jpush 0.0.0-stage → 6.7.0-22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +56 -2
  3. package/ReactNativeJpush.podspec +66 -0
  4. package/android/CMakeLists.txt +24 -0
  5. package/android/build.gradle +144 -0
  6. package/android/fcm/build.gradle +36 -0
  7. package/android/fcm/consumer-rules.pro +2 -0
  8. package/android/fcm/src/main/AndroidManifest.xml +25 -0
  9. package/android/fcm/src/main/java/com/onekey/jpush/fcm/FcmInitProvider.java +25 -0
  10. package/android/fcm/src/main/java/com/onekey/jpush/fcm/FcmMessagingService.java +84 -0
  11. package/android/fcm/src/main/java/com/onekey/jpush/fcm/FcmPushManager.java +69 -0
  12. package/android/fcm/src/test/java/com/onekey/jpush/fcm/FcmAdapterTest.java +684 -0
  13. package/android/fcm/src/test/java/com/onekey/jpush/fcm/FcmManifestTest.java +54 -0
  14. package/android/gradle.properties +4 -0
  15. package/android/src/main/AndroidManifest.xml +143 -0
  16. package/android/src/main/cpp/cpp-adapter.cpp +6 -0
  17. package/android/src/main/java/cn/android/service/JTransitActivity.java +19 -0
  18. package/android/src/main/java/cn/jiguang/android/BuildConfig.java +10 -0
  19. package/android/src/main/java/cn/jiguang/android/IDataShare.java +190 -0
  20. package/android/src/main/java/cn/jiguang/api/BaseLogger.java +82 -0
  21. package/android/src/main/java/cn/jiguang/api/JAction.java +22 -0
  22. package/android/src/main/java/cn/jiguang/api/JActionExtra.java +21 -0
  23. package/android/src/main/java/cn/jiguang/api/JAnalyticsAction.java +11 -0
  24. package/android/src/main/java/cn/jiguang/api/JCoreInterface.java +228 -0
  25. package/android/src/main/java/cn/jiguang/api/JCoreManager.java +156 -0
  26. package/android/src/main/java/cn/jiguang/api/JDispatchAction.java +66 -0
  27. package/android/src/main/java/cn/jiguang/api/MultiSpHelper.java +114 -0
  28. package/android/src/main/java/cn/jiguang/api/ReportCallBack.java +9 -0
  29. package/android/src/main/java/cn/jiguang/api/SdkType.java +13 -0
  30. package/android/src/main/java/cn/jiguang/api/utils/JCollectionAuth.java +28 -0
  31. package/android/src/main/java/cn/jiguang/core/JCoreCrypto.java +545 -0
  32. package/android/src/main/java/cn/jiguang/core/JCoreStorage.java +737 -0
  33. package/android/src/main/java/cn/jiguang/core/JCoreTcpEngine.java +1395 -0
  34. package/android/src/main/java/cn/jiguang/core/JCoreWireCodec.java +1716 -0
  35. package/android/src/main/java/cn/jiguang/internal/ActionManager.java +63 -0
  36. package/android/src/main/java/cn/jiguang/internal/JConstants.java +61 -0
  37. package/android/src/main/java/cn/jiguang/internal/JCoreHelperAction.java +12 -0
  38. package/android/src/main/java/cn/jiguang/internal/JCoreInternalHelper.java +102 -0
  39. package/android/src/main/java/cn/jiguang/net/DefaultHostVerifier.java +40 -0
  40. package/android/src/main/java/cn/jiguang/net/HttpRequest.java +78 -0
  41. package/android/src/main/java/cn/jiguang/net/HttpResponse.java +48 -0
  42. package/android/src/main/java/cn/jiguang/net/HttpUtils.java +106 -0
  43. package/android/src/main/java/cn/jiguang/plugins/core/JCoreModule.java +91 -0
  44. package/android/src/main/java/cn/jiguang/plugins/core/JCorePackage.java +27 -0
  45. package/android/src/main/java/cn/jiguang/plugins/push/JPushModule.java +773 -0
  46. package/android/src/main/java/cn/jiguang/plugins/push/JPushPackage.java +25 -0
  47. package/android/src/main/java/cn/jiguang/plugins/push/common/JConstants.java +88 -0
  48. package/android/src/main/java/cn/jiguang/plugins/push/common/JLogger.java +122 -0
  49. package/android/src/main/java/cn/jiguang/plugins/push/helper/JPushHelper.java +710 -0
  50. package/android/src/main/java/cn/jiguang/plugins/push/receiver/JPushBroadcastReceiver.java +37 -0
  51. package/android/src/main/java/cn/jiguang/plugins/push/receiver/JPushModuleReceiver.java +264 -0
  52. package/android/src/main/java/cn/jiguang/plugins/service/JCoreModuleService.java +7 -0
  53. package/android/src/main/java/cn/jpush/android/api/BasicPushNotificationBuilder.java +83 -0
  54. package/android/src/main/java/cn/jpush/android/api/CallBackParams.java +50 -0
  55. package/android/src/main/java/cn/jpush/android/api/CmdMessage.java +33 -0
  56. package/android/src/main/java/cn/jpush/android/api/CustomMessage.java +28 -0
  57. package/android/src/main/java/cn/jpush/android/api/CustomPushNotificationBuilder.java +81 -0
  58. package/android/src/main/java/cn/jpush/android/api/DefaultPushNotificationBuilder.java +90 -0
  59. package/android/src/main/java/cn/jpush/android/api/InAppSlotParams.java +65 -0
  60. package/android/src/main/java/cn/jpush/android/api/InstrumentedActivity.java +17 -0
  61. package/android/src/main/java/cn/jpush/android/api/InstrumentedListActivity.java +17 -0
  62. package/android/src/main/java/cn/jpush/android/api/JPushInterface.java +490 -0
  63. package/android/src/main/java/cn/jpush/android/api/JPushMessage.java +121 -0
  64. package/android/src/main/java/cn/jpush/android/api/JThirdPlatFormInterface.java +247 -0
  65. package/android/src/main/java/cn/jpush/android/api/MultiActionsNotificationBuilder.java +72 -0
  66. package/android/src/main/java/cn/jpush/android/api/NotificationCustomButton.java +50 -0
  67. package/android/src/main/java/cn/jpush/android/api/NotificationMessage.java +67 -0
  68. package/android/src/main/java/cn/jpush/android/api/PushNotificationBuilder.java +13 -0
  69. package/android/src/main/java/cn/jpush/android/api/TagAliasCallback.java +8 -0
  70. package/android/src/main/java/cn/jpush/android/data/JPushCollectControl.java +96 -0
  71. package/android/src/main/java/cn/jpush/android/data/JPushConfig.java +79 -0
  72. package/android/src/main/java/cn/jpush/android/data/JPushConfigEx.java +41 -0
  73. package/android/src/main/java/cn/jpush/android/data/JPushLocalNotification.java +155 -0
  74. package/android/src/main/java/cn/jpush/android/helper/JCoreHelper.java +70 -0
  75. package/android/src/main/java/cn/jpush/android/helper/Logger.java +82 -0
  76. package/android/src/main/java/cn/jpush/android/local/ActionHelper.java +1293 -0
  77. package/android/src/main/java/cn/jpush/android/local/ActivityLifeCallBack.java +47 -0
  78. package/android/src/main/java/cn/jpush/android/local/JPushAction.java +67 -0
  79. package/android/src/main/java/cn/jpush/android/local/JPushConstants.java +34 -0
  80. package/android/src/main/java/cn/jpush/android/local/JPushResponse.java +26 -0
  81. package/android/src/main/java/cn/jpush/android/local/ProxyActivityAction.java +34 -0
  82. package/android/src/main/java/cn/jpush/android/service/AlarmReceiver.java +15 -0
  83. package/android/src/main/java/cn/jpush/android/service/BActivity.java +19 -0
  84. package/android/src/main/java/cn/jpush/android/service/DActivity.java +19 -0
  85. package/android/src/main/java/cn/jpush/android/service/DaemonService.java +17 -0
  86. package/android/src/main/java/cn/jpush/android/service/DataProvider.java +136 -0
  87. package/android/src/main/java/cn/jpush/android/service/DataShare.java +129 -0
  88. package/android/src/main/java/cn/jpush/android/service/DownloadProvider.java +139 -0
  89. package/android/src/main/java/cn/jpush/android/service/InitProvider.java +48 -0
  90. package/android/src/main/java/cn/jpush/android/service/JCommonService.java +79 -0
  91. package/android/src/main/java/cn/jpush/android/service/JNotifyActivity.java +28 -0
  92. package/android/src/main/java/cn/jpush/android/service/JPushMessageReceiver.java +94 -0
  93. package/android/src/main/java/cn/jpush/android/service/PushReceiver.java +26 -0
  94. package/android/src/main/java/cn/jpush/android/service/PushService.java +28 -0
  95. package/android/src/main/java/cn/jpush/android/service/SchedulerReceiver.java +17 -0
  96. package/android/src/main/java/cn/jpush/android/service/TagAliasReceiver.java +11 -0
  97. package/android/src/main/java/cn/jpush/android/service/WakedResultReceiver.java +24 -0
  98. package/android/src/main/java/cn/jpush/android/ui/FullScreenView.java +11 -0
  99. package/android/src/main/java/cn/jpush/android/ui/PopWinActivity.java +16 -0
  100. package/android/src/main/java/cn/jpush/android/ui/PushActivity.java +27 -0
  101. package/android/src/main/java/cn/jpush/android/ui/RoundedImageView.java +63 -0
  102. package/android/src/main/java/cn/jpush/android/ui/ShadowViewCard.java +56 -0
  103. package/android/src/main/java/cn/jpush/android/ups/ICallbackResult.java +5 -0
  104. package/android/src/main/java/cn/jpush/android/ups/JPushUPSManager.java +37 -0
  105. package/android/src/main/java/cn/jpush/android/ups/TokenResult.java +47 -0
  106. package/android/src/main/java/cn/jpush/android/ups/UPSRegisterCallBack.java +4 -0
  107. package/android/src/main/java/cn/jpush/android/ups/UPSTurnCallBack.java +4 -0
  108. package/android/src/main/java/cn/jpush/android/ups/UPSUnRegisterCallBack.java +4 -0
  109. package/android/src/main/java/com/margelo/nitro/reactnativejpush/ReactNativeJpush.kt +455 -0
  110. package/android/src/main/java/com/margelo/nitro/reactnativejpush/ReactNativeJpushPackage.kt +50 -0
  111. package/android/src/main/res/values/jpush_string.xml +7 -0
  112. package/android/src/main/res/values/jpush_style.xml +22 -0
  113. package/android/src/test/java/com/margelo/nitro/reactnativejpush/JPushCloudHandshakeTest.java +110 -0
  114. package/android/src/test/java/com/margelo/nitro/reactnativejpush/JPushHandshakeFailureTest.java +73 -0
  115. package/android/src/test/java/com/margelo/nitro/reactnativejpush/ReactNativeJpushProtocolTest.java +908 -0
  116. package/ios/ReactNativeJpush.swift +522 -0
  117. package/ios/bridge/RCTJCoreModule.h +5 -0
  118. package/ios/bridge/RCTJCoreModule.m +31 -0
  119. package/ios/bridge/RCTJPushEventQueue.h +14 -0
  120. package/ios/bridge/RCTJPushEventQueue.m +23 -0
  121. package/ios/bridge/RCTJPushModule.h +37 -0
  122. package/ios/bridge/RCTJPushModule.m +1165 -0
  123. package/ios/include/JCOREService.h +3 -0
  124. package/ios/include/JGCOREAPI.h +14 -0
  125. package/ios/include/JGInforCollectionAuth.h +17 -0
  126. package/ios/include/JGInforCollectionAuthItems.h +2 -0
  127. package/ios/include/JGPushNotificationTrigger.h +2 -0
  128. package/ios/include/JPUSHService.h +359 -0
  129. package/ios/jcore/JCOREConfiguration.h +141 -0
  130. package/ios/jcore/JCOREConfiguration.m +703 -0
  131. package/ios/jcore/JCORECrypto.h +73 -0
  132. package/ios/jcore/JCORECrypto.m +649 -0
  133. package/ios/jcore/JCORESisResolver.h +56 -0
  134. package/ios/jcore/JCORESisResolver.m +525 -0
  135. package/ios/jcore/JCORETcpSession.h +42 -0
  136. package/ios/jcore/JCORETcpSession.m +956 -0
  137. package/ios/jcore/JCOREWireProtocol.h +274 -0
  138. package/ios/jcore/JCOREWireProtocol.m +1453 -0
  139. package/ios/jpush/JPUSHModels.m +214 -0
  140. package/ios/jpush/JPUSHNotificationManager.h +34 -0
  141. package/ios/jpush/JPUSHNotificationManager.m +360 -0
  142. package/ios/jpush/JPUSHService.m +794 -0
  143. package/ios/tests/ReactNativeJpushTests.m +148 -0
  144. package/lib/module/ReactNativeJpush.nitro.js +4 -0
  145. package/lib/module/ReactNativeJpush.nitro.js.map +1 -0
  146. package/lib/module/index.js +801 -0
  147. package/lib/module/index.js.map +1 -0
  148. package/lib/module/package.json +1 -0
  149. package/lib/typescript/package.json +1 -0
  150. package/lib/typescript/src/ReactNativeJpush.nitro.d.ts +60 -0
  151. package/lib/typescript/src/ReactNativeJpush.nitro.d.ts.map +1 -0
  152. package/lib/typescript/src/index.d.ts +235 -0
  153. package/lib/typescript/src/index.d.ts.map +1 -0
  154. package/nitro.json +23 -0
  155. package/nitrogen/generated/android/c++/JFunc_void_bool.hpp +75 -0
  156. package/nitrogen/generated/android/c++/JFunc_void_std__string_std__string.hpp +76 -0
  157. package/nitrogen/generated/android/c++/JHybridReactNativeJpushSpec.cpp +310 -0
  158. package/nitrogen/generated/android/c++/JHybridReactNativeJpushSpec.hpp +115 -0
  159. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativejpush/Func_void_bool.kt +78 -0
  160. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativejpush/Func_void_std__string_std__string.kt +78 -0
  161. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativejpush/HybridReactNativeJpushSpec.kt +274 -0
  162. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativejpush/reactnativejpushOnLoad.kt +35 -0
  163. package/nitrogen/generated/android/reactnativejpush+autolinking.cmake +81 -0
  164. package/nitrogen/generated/android/reactnativejpush+autolinking.gradle +27 -0
  165. package/nitrogen/generated/android/reactnativejpushOnLoad.cpp +58 -0
  166. package/nitrogen/generated/android/reactnativejpushOnLoad.hpp +34 -0
  167. package/nitrogen/generated/ios/ReactNativeJpush+autolinking.rb +62 -0
  168. package/nitrogen/generated/ios/ReactNativeJpush-Swift-Cxx-Bridge.cpp +49 -0
  169. package/nitrogen/generated/ios/ReactNativeJpush-Swift-Cxx-Bridge.hpp +147 -0
  170. package/nitrogen/generated/ios/ReactNativeJpush-Swift-Cxx-Umbrella.hpp +46 -0
  171. package/nitrogen/generated/ios/ReactNativeJpushAutolinking.mm +33 -0
  172. package/nitrogen/generated/ios/ReactNativeJpushAutolinking.swift +26 -0
  173. package/nitrogen/generated/ios/c++/HybridReactNativeJpushSpecSwift.cpp +11 -0
  174. package/nitrogen/generated/ios/c++/HybridReactNativeJpushSpecSwift.hpp +402 -0
  175. package/nitrogen/generated/ios/swift/Func_void_bool.swift +46 -0
  176. package/nitrogen/generated/ios/swift/Func_void_std__string_std__string.swift +46 -0
  177. package/nitrogen/generated/ios/swift/HybridReactNativeJpushSpec.swift +107 -0
  178. package/nitrogen/generated/ios/swift/HybridReactNativeJpushSpec_cxx.swift +723 -0
  179. package/nitrogen/generated/shared/c++/HybridReactNativeJpushSpec.cpp +73 -0
  180. package/nitrogen/generated/shared/c++/HybridReactNativeJpushSpec.hpp +116 -0
  181. package/package.json +174 -4
  182. package/src/ReactNativeJpush.nitro.ts +93 -0
  183. package/src/index.tsx +1090 -0
@@ -0,0 +1,525 @@
1
+ #import "JCORESisResolver.h"
2
+ #import "JCOREConfiguration.h"
3
+ #import "JCORECrypto.h"
4
+ #import <Network/Network.h>
5
+ #import <arpa/inet.h>
6
+
7
+ static NSString *const kJCoreSisRsaPublicKey =
8
+ @"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCi0v4VEUhOdfIEfFCrPC72pcDsQF/"
9
+ @"luTmr4q34NY0EZYGKzfQuTrUAm916P52HCgF+342gjZ/Nvijts5543qYNyoLvgtu4NRcHJmuGI/"
10
+ @"w7qifhfsivYeoEj9wYphXOyB9HUjzwn1BtAih+1RyUrcErCi249yabUOIKQygPZ9OXXQIDAQAB";
11
+
12
+ static const char *const kJCoreHttpSisIv = "0102030405060708";
13
+
14
+ @implementation JCORESisEndpoint
15
+
16
+ + (instancetype)endpointFromString:(NSString *)addressString useSSL:(BOOL)useSSL {
17
+ if (addressString.length == 0) {
18
+ return nil;
19
+ }
20
+ NSRange lastColon = [addressString rangeOfString:@":" options:NSBackwardsSearch];
21
+ if (lastColon.location == NSNotFound || lastColon.location == 0 || lastColon.location + 1 >= addressString.length) {
22
+ return nil;
23
+ }
24
+ NSString *hostPart = [addressString substringToIndex:lastColon.location];
25
+ hostPart = [hostPart stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"[] "]];
26
+ NSInteger portVal = [[addressString substringFromIndex:lastColon.location + 1] integerValue];
27
+ if (hostPart.length == 0 || portVal <= 0 || portVal > UINT16_MAX) {
28
+ return nil;
29
+ }
30
+ JCORESisEndpoint *endpoint = [[JCORESisEndpoint alloc] init];
31
+ endpoint.host = hostPart;
32
+ endpoint.port = (uint16_t)portVal;
33
+ endpoint.useSSL = useSSL;
34
+ return endpoint;
35
+ }
36
+
37
+ - (NSString *)addressString {
38
+ return [NSString stringWithFormat:@"%@:%u", self.host ?: @"", self.port];
39
+ }
40
+
41
+ @end
42
+
43
+ @interface JCORESisResolver ()
44
+ @property (nonatomic, strong) NSURLSession *urlSession;
45
+ @end
46
+
47
+ @implementation JCORESisResolver
48
+
49
+ + (instancetype)shared {
50
+ static JCORESisResolver *instance = nil;
51
+ static dispatch_once_t onceToken;
52
+ dispatch_once(&onceToken, ^{
53
+ instance = [[JCORESisResolver alloc] init];
54
+ });
55
+ return instance;
56
+ }
57
+
58
+ - (instancetype)init {
59
+ self = [super init];
60
+ if (self) {
61
+ NSURLSessionConfiguration *config = [NSURLSessionConfiguration ephemeralSessionConfiguration];
62
+ config.timeoutIntervalForRequest = 6.0;
63
+ config.timeoutIntervalForResource = 8.0;
64
+ _urlSession = [NSURLSession sessionWithConfiguration:config];
65
+ }
66
+ return self;
67
+ }
68
+
69
+ - (void)setCustomConnectHost:(NSString *)host
70
+ port:(uint16_t)port
71
+ useSSL:(BOOL)useSSL {
72
+ [[JCOREConfiguration shared] setCustomConnectHost:host port:port useSSL:useSSL];
73
+ }
74
+
75
+ - (void)setCustomConnectAddresses:(NSArray<NSString *> *)addresses {
76
+ [JCOREConfiguration shared].customConnectAddresses = addresses;
77
+ }
78
+
79
+ - (void)clearCustomConnectEndpoint {
80
+ [[JCOREConfiguration shared] clearCustomConnectEndpoint];
81
+ self.customSisHost = nil;
82
+ self.customSisPort = 0;
83
+ }
84
+
85
+ + (NSData *)assembleUdpSisPacketWithPayload:(NSDictionary *)payload
86
+ magic:(char)magic
87
+ seed:(uint32_t)seed {
88
+ if (![payload isKindOfClass:[NSDictionary class]] || ![NSJSONSerialization isValidJSONObject:payload]) {
89
+ return nil;
90
+ }
91
+ NSData *jsonData = [NSJSONSerialization dataWithJSONObject:payload options:0 error:nil];
92
+ if (jsonData.length == 0) {
93
+ return nil;
94
+ }
95
+ NSData *compressed = [JCORECrypto gzipCompress:jsonData];
96
+ if (compressed.length == 0 || compressed.length > UINT16_MAX) {
97
+ return nil;
98
+ }
99
+ uint32_t seed24 = seed & 0x00FFFFFFU;
100
+ if (seed24 == 0) {
101
+ seed24 = 1U;
102
+ }
103
+ NSString *secret = [JCORECrypto generateSeedKey:seed24];
104
+ if (secret.length < 16) {
105
+ return nil;
106
+ }
107
+ NSString *iv = [secret substringToIndex:16];
108
+ NSData *encrypted = [JCORECrypto aesCbcEncrypt:compressed
109
+ key:secret
110
+ iv:iv.UTF8String
111
+ keySize:32];
112
+ if (encrypted.length == 0 || encrypted.length + 10 > UINT16_MAX) {
113
+ return nil;
114
+ }
115
+
116
+ uint16_t totalLengthBE = htons((uint16_t)(10 + encrypted.length));
117
+ uint8_t magic0 = (uint8_t)(magic == 'M' ? 'M' : 'U');
118
+ uint8_t magic1 = (uint8_t)'G';
119
+ uint32_t keyFieldBE = htonl(seed24 | 0x11000000U);
120
+ uint16_t declaredLengthBE = htons((uint16_t)compressed.length);
121
+
122
+ NSMutableData *packet = [NSMutableData dataWithCapacity:10 + encrypted.length];
123
+ [packet appendBytes:&totalLengthBE length:sizeof(uint16_t)];
124
+ [packet appendBytes:&magic0 length:sizeof(uint8_t)];
125
+ [packet appendBytes:&magic1 length:sizeof(uint8_t)];
126
+ [packet appendBytes:&keyFieldBE length:sizeof(uint32_t)];
127
+ [packet appendBytes:&declaredLengthBE length:sizeof(uint16_t)];
128
+ [packet appendData:encrypted];
129
+ return packet;
130
+ }
131
+
132
+ + (NSDictionary *)parseUdpSisPacket:(NSData *)packetData {
133
+ if (packetData.length < 10) {
134
+ return nil;
135
+ }
136
+ const uint8_t *bytes = packetData.bytes;
137
+ uint16_t rawTotalLen = 0;
138
+ memcpy(&rawTotalLen, bytes, sizeof(uint16_t));
139
+ uint16_t totalLen = ntohs(rawTotalLen);
140
+ if (totalLen < 10 || totalLen > packetData.length) {
141
+ return nil;
142
+ }
143
+ uint8_t magic0 = bytes[2];
144
+ uint8_t magic1 = bytes[3];
145
+ if ((magic0 != 'U' && magic0 != 'M') || magic1 != 'G') {
146
+ return nil;
147
+ }
148
+ uint32_t rawKey = 0;
149
+ memcpy(&rawKey, bytes + 4, sizeof(uint32_t));
150
+ uint32_t hostKey = ntohl(rawKey);
151
+ uint8_t flags = (uint8_t)((hostKey >> 24) & 0xFF);
152
+ uint32_t seed24 = hostKey & 0x00FFFFFFU;
153
+
154
+ uint16_t rawDeclaredLen = 0;
155
+ memcpy(&rawDeclaredLen, bytes + 8, sizeof(uint16_t));
156
+ uint16_t declaredLen = ntohs(rawDeclaredLen);
157
+ if (declaredLen == 0) {
158
+ return nil;
159
+ }
160
+ NSData *encrypted = [packetData subdataWithRange:NSMakeRange(10, totalLen - 10)];
161
+ if (encrypted.length == 0) {
162
+ return nil;
163
+ }
164
+
165
+ NSString *secret = [JCORECrypto generateSeedKey:seed24];
166
+ if (secret.length < 16) {
167
+ return nil;
168
+ }
169
+ NSString *iv = [secret substringToIndex:16];
170
+ NSData *decrypted = [JCORECrypto aesCbcDecrypt:encrypted
171
+ key:secret
172
+ iv:iv.UTF8String
173
+ keySize:32];
174
+ if (decrypted.length == 0) {
175
+ return nil;
176
+ }
177
+ NSUInteger sliceLen = MIN(decrypted.length, (NSUInteger)declaredLen);
178
+ decrypted = [decrypted subdataWithRange:NSMakeRange(0, sliceLen)];
179
+
180
+ NSData *plainData = decrypted;
181
+ const uint8_t *decBytes = decrypted.bytes;
182
+ BOOL hasGzipMagic = (decrypted.length >= 2 && decBytes[0] == 0x1F && decBytes[1] == 0x8B);
183
+ if ((flags & 0x01) != 0 || (rawKey & 0x01) != 0 || hasGzipMagic) {
184
+ plainData = [JCORECrypto gzipDecompress:decrypted] ?: decrypted;
185
+ }
186
+ if (plainData.length == 0) {
187
+ return nil;
188
+ }
189
+ id json = [NSJSONSerialization JSONObjectWithData:plainData options:0 error:nil];
190
+ if ([json isKindOfClass:[NSDictionary class]]) {
191
+ [[JCOREConfiguration shared] updateWithSisDictionary:json];
192
+ return json;
193
+ }
194
+ return nil;
195
+ }
196
+
197
+ + (NSData *)encryptHttpSisPayload:(NSDictionary *)payload
198
+ aesKey:(NSString *)aesKey
199
+ outAuthHeader:(NSString **)outAuthHeader {
200
+ if (![payload isKindOfClass:[NSDictionary class]] || aesKey.length == 0) {
201
+ return nil;
202
+ }
203
+ NSData *jsonData = [NSJSONSerialization dataWithJSONObject:payload options:0 error:nil];
204
+ NSData *compressed = [JCORECrypto gzipCompress:jsonData];
205
+ NSData *encrypted = [JCORECrypto aesCbcEncrypt:compressed key:aesKey iv:kJCoreHttpSisIv keySize:32];
206
+ NSString *authHeader = [JCORECrypto rsaEncryptString:aesKey publicKeyBase64:kJCoreSisRsaPublicKey];
207
+ if (outAuthHeader != NULL) {
208
+ *outAuthHeader = authHeader;
209
+ }
210
+ return encrypted;
211
+ }
212
+
213
+ + (NSDictionary *)decryptHttpSisResponse:(NSData *)responseData
214
+ aesKey:(NSString *)aesKey {
215
+ if (responseData.length == 0 || aesKey.length == 0) {
216
+ return nil;
217
+ }
218
+ NSData *decrypted = [JCORECrypto aesCbcDecrypt:responseData key:aesKey iv:kJCoreHttpSisIv keySize:32];
219
+ NSData *plain = [JCORECrypto gzipDecompress:decrypted] ?: decrypted;
220
+ if (plain.length == 0) {
221
+ return nil;
222
+ }
223
+ id json = [NSJSONSerialization JSONObjectWithData:plain options:0 error:nil];
224
+ if ([json isKindOfClass:[NSDictionary class]]) {
225
+ [[JCOREConfiguration shared] updateWithSisDictionary:json];
226
+ return json;
227
+ }
228
+ return nil;
229
+ }
230
+
231
+ - (NSDictionary *)buildSisRequestPayload {
232
+ JCOREConfiguration *config = [JCOREConfiguration shared];
233
+ return @{
234
+ @"type": @1,
235
+ @"opera": @"",
236
+ @"uid": @(config.uid),
237
+ @"appkey": config.appKey ?: @"",
238
+ @"sdkver": @"5.2.0",
239
+ @"lat": @0,
240
+ @"lng": @0,
241
+ @"time": @0,
242
+ @"platform": @1,
243
+ @"fail_ips": config.failedIps ?: @[],
244
+ @"ips_flag": @0,
245
+ @"report_flag": @0,
246
+ @"cert_ver": @(config.certVer > 0 ? config.certVer : 1),
247
+ };
248
+ }
249
+
250
+ - (NSArray<JCORESisEndpoint *> *)defaultFallbackEndpoints {
251
+ JCOREConfiguration *config = [JCOREConfiguration shared];
252
+ if (config.customConnectAddresses.count > 0) {
253
+ NSMutableArray<JCORESisEndpoint *> *customList = [NSMutableArray array];
254
+ for (NSString *addr in config.customConnectAddresses) {
255
+ JCORESisEndpoint *ep = [JCORESisEndpoint endpointFromString:addr useSSL:config.customConnectUseSSL];
256
+ if (ep != nil) {
257
+ [customList addObject:ep];
258
+ }
259
+ }
260
+ if (customList.count > 0) {
261
+ return customList;
262
+ }
263
+ }
264
+ if (config.customConnectHost.length > 0 && config.customConnectPort > 0) {
265
+ JCORESisEndpoint *custom = [[JCORESisEndpoint alloc] init];
266
+ custom.host = config.customConnectHost;
267
+ custom.port = config.customConnectPort;
268
+ custom.useSSL = config.customConnectUseSSL;
269
+ return @[ custom ];
270
+ }
271
+ NSMutableArray<JCORESisEndpoint *> *endpoints = [NSMutableArray array];
272
+ NSMutableArray<JCORESisEndpoint *> *deprioritizedFailed = [NSMutableArray array];
273
+ NSSet<NSString *> *failedSet = [NSSet setWithArray:(config.failedIps ?: @[])];
274
+ for (NSString *addr in config.ips) {
275
+ JCORESisEndpoint *ep = [JCORESisEndpoint endpointFromString:addr useSSL:NO];
276
+ if (ep != nil) {
277
+ if ([failedSet containsObject:ep.addressString]) {
278
+ [deprioritizedFailed addObject:ep];
279
+ } else {
280
+ [endpoints addObject:ep];
281
+ }
282
+ }
283
+ }
284
+ for (NSString *addr in config.sslIps) {
285
+ JCORESisEndpoint *ep = [JCORESisEndpoint endpointFromString:addr useSSL:YES];
286
+ if (ep != nil) {
287
+ if ([failedSet containsObject:ep.addressString]) {
288
+ [deprioritizedFailed addObject:ep];
289
+ } else {
290
+ [endpoints addObject:ep];
291
+ }
292
+ }
293
+ }
294
+ [endpoints addObjectsFromArray:deprioritizedFailed];
295
+ for (NSNumber *portNum in config.defaultConnectPorts) {
296
+ JCORESisEndpoint *ep = [[JCORESisEndpoint alloc] init];
297
+ ep.host = config.defaultConnectHost;
298
+ ep.port = portNum.unsignedShortValue;
299
+ ep.useSSL = (ep.port == 443);
300
+ [endpoints addObject:ep];
301
+ }
302
+ return endpoints;
303
+ }
304
+
305
+ - (NSArray<JCORESisEndpoint *> *)parseSisResponseDictionary:(NSDictionary *)dict {
306
+ if (![dict isKindOfClass:[NSDictionary class]]) {
307
+ return @[];
308
+ }
309
+ [[JCOREConfiguration shared] updateWithSisDictionary:dict];
310
+
311
+ NSMutableArray<JCORESisEndpoint *> *results = [NSMutableArray array];
312
+ NSArray<NSString *> *ips = [dict[@"ips"] isKindOfClass:[NSArray class]] ? dict[@"ips"] : @[];
313
+ for (NSString *addr in ips) {
314
+ if ([addr isKindOfClass:[NSString class]]) {
315
+ JCORESisEndpoint *ep = [JCORESisEndpoint endpointFromString:addr useSSL:NO];
316
+ if (ep != nil) {
317
+ [results addObject:ep];
318
+ }
319
+ }
320
+ }
321
+ NSArray<NSString *> *sslIps = [dict[@"ssl_ips"] isKindOfClass:[NSArray class]] ? dict[@"ssl_ips"] : @[];
322
+ for (NSString *addr in sslIps) {
323
+ if ([addr isKindOfClass:[NSString class]]) {
324
+ JCORESisEndpoint *ep = [JCORESisEndpoint endpointFromString:addr useSSL:YES];
325
+ if (ep != nil) {
326
+ [results addObject:ep];
327
+ }
328
+ }
329
+ }
330
+ return results;
331
+ }
332
+
333
+ - (void)resolveUdpSisWithHost:(NSString *)host
334
+ port:(uint16_t)port
335
+ timeout:(NSTimeInterval)timeout
336
+ completion:(void (^)(NSArray<JCORESisEndpoint *> *endpoints))completion {
337
+ if (host.length == 0) {
338
+ completion(@[]);
339
+ return;
340
+ }
341
+ uint16_t actualPort = port > 0 ? port : 19000;
342
+ uint32_t seed = arc4random() & 0x00FFFFFFU;
343
+ if (seed == 0) {
344
+ seed = 1U;
345
+ }
346
+ NSData *packet = [JCORESisResolver assembleUdpSisPacketWithPayload:[self buildSisRequestPayload]
347
+ magic:'U'
348
+ seed:seed];
349
+ if (packet.length == 0) {
350
+ completion(@[]);
351
+ return;
352
+ }
353
+
354
+ dispatch_queue_t udpQueue = dispatch_queue_create("cn.jiguang.jcore.udp.sis", DISPATCH_QUEUE_SERIAL);
355
+ NSString *portStr = [NSString stringWithFormat:@"%u", actualPort];
356
+ nw_endpoint_t endpoint = nw_endpoint_create_host(host.UTF8String, portStr.UTF8String);
357
+ nw_parameters_t params = nw_parameters_create_secure_udp(NW_PARAMETERS_DISABLE_PROTOCOL,
358
+ NW_PARAMETERS_DEFAULT_CONFIGURATION);
359
+ nw_connection_t conn = nw_connection_create(endpoint, params);
360
+ nw_connection_set_queue(conn, udpQueue);
361
+
362
+ __block BOOL finished = NO;
363
+ void (^finishOnce)(NSArray<JCORESisEndpoint *> *) = ^(NSArray<JCORESisEndpoint *> *eps) {
364
+ if (finished) {
365
+ return;
366
+ }
367
+ finished = YES;
368
+ nw_connection_cancel(conn);
369
+ completion(eps ?: @[]);
370
+ };
371
+
372
+ NSTimeInterval effectiveTimeout = timeout > 0 ? timeout : 3.0;
373
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(effectiveTimeout * NSEC_PER_SEC)), udpQueue, ^{
374
+ finishOnce(@[]);
375
+ });
376
+
377
+ nw_connection_set_state_changed_handler(conn, ^(nw_connection_state_t state, nw_error_t error) {
378
+ if (state == nw_connection_state_ready) {
379
+ dispatch_data_t ddata = dispatch_data_create(packet.bytes,
380
+ packet.length,
381
+ udpQueue,
382
+ DISPATCH_DATA_DESTRUCTOR_DEFAULT);
383
+ nw_connection_send(conn, ddata, NW_CONNECTION_DEFAULT_MESSAGE_CONTEXT, true, ^(nw_error_t sendErr) {
384
+ if (sendErr != nil) {
385
+ finishOnce(@[]);
386
+ }
387
+ });
388
+ nw_connection_receive_message(conn, ^(dispatch_data_t content, nw_content_context_t context, bool is_complete, nw_error_t recvErr) {
389
+ if (recvErr == nil && content != nil) {
390
+ NSData *respData = (NSData *)content;
391
+ NSDictionary *dict = [JCORESisResolver parseUdpSisPacket:respData];
392
+ NSArray<JCORESisEndpoint *> *parsed = [self parseSisResponseDictionary:dict];
393
+ if (parsed.count > 0) {
394
+ [[JCOREConfiguration shared] addLastSuccessSisIp:[NSString stringWithFormat:@"%@:%u", host, actualPort]];
395
+ [[JCOREConfiguration shared] clearFailedIps];
396
+ }
397
+ finishOnce(parsed);
398
+ } else {
399
+ finishOnce(@[]);
400
+ }
401
+ });
402
+ } else if (state == nw_connection_state_failed || state == nw_connection_state_cancelled) {
403
+ finishOnce(@[]);
404
+ }
405
+ });
406
+
407
+ nw_connection_start(conn);
408
+ }
409
+
410
+ - (BOOL)hasHealthyCachedSisEndpoint {
411
+ JCOREConfiguration *config = [JCOREConfiguration shared];
412
+ NSSet<NSString *> *failedSet = [NSSet setWithArray:(config.failedIps ?: @[])];
413
+ for (NSString *addr in config.ips) {
414
+ JCORESisEndpoint *ep = [JCORESisEndpoint endpointFromString:addr useSSL:NO];
415
+ if (ep != nil && ![failedSet containsObject:ep.addressString]) {
416
+ return YES;
417
+ }
418
+ }
419
+ for (NSString *addr in config.sslIps) {
420
+ JCORESisEndpoint *ep = [JCORESisEndpoint endpointFromString:addr useSSL:YES];
421
+ if (ep != nil && ![failedSet containsObject:ep.addressString]) {
422
+ return YES;
423
+ }
424
+ }
425
+ return NO;
426
+ }
427
+
428
+ - (void)resolveEndpointsWithCompletion:(void (^)(NSArray<JCORESisEndpoint *> *endpoints))completion {
429
+ JCOREConfiguration *config = [JCOREConfiguration shared];
430
+ if (config.customConnectAddresses.count > 0) {
431
+ completion([self defaultFallbackEndpoints]);
432
+ return;
433
+ }
434
+ if (config.customConnectHost.length > 0 && config.customConnectPort > 0) {
435
+ JCORESisEndpoint *custom = [[JCORESisEndpoint alloc] init];
436
+ custom.host = config.customConnectHost;
437
+ custom.port = config.customConnectPort;
438
+ custom.useSSL = config.customConnectUseSSL;
439
+ completion(@[ custom ]);
440
+ return;
441
+ }
442
+
443
+ if (self.customSisHost.length > 0 && self.customSisPort > 0) {
444
+ [self resolveUdpSisWithHost:self.customSisHost
445
+ port:self.customSisPort
446
+ timeout:3.0
447
+ completion:^(NSArray<JCORESisEndpoint *> *udpEndpoints) {
448
+ if (udpEndpoints.count > 0) {
449
+ completion(udpEndpoints);
450
+ } else {
451
+ completion([self defaultFallbackEndpoints]);
452
+ }
453
+ }];
454
+ return;
455
+ }
456
+
457
+ if ([self hasHealthyCachedSisEndpoint]) {
458
+ completion([self defaultFallbackEndpoints]);
459
+ return;
460
+ }
461
+
462
+ if (config.appKey.length == 0) {
463
+ completion([self defaultFallbackEndpoints]);
464
+ return;
465
+ }
466
+
467
+ void (^fallbackToUdpSis)(void) = ^{
468
+ NSString *udpHostStr = config.sisIps.firstObject ?: config.sisDefaultIps.firstObject ?: config.sisHostDomains.firstObject;
469
+ if (udpHostStr.length > 0) {
470
+ JCORESisEndpoint *udpEp = [JCORESisEndpoint endpointFromString:udpHostStr useSSL:NO];
471
+ NSString *resolvedHost = udpEp != nil ? udpEp.host : udpHostStr;
472
+ uint16_t resolvedPort = (udpEp != nil && udpEp.port > 0) ? udpEp.port : 19000;
473
+ [self resolveUdpSisWithHost:resolvedHost port:resolvedPort timeout:2.5 completion:^(NSArray<JCORESisEndpoint *> *udpEndpoints) {
474
+ if (udpEndpoints.count > 0) {
475
+ completion(udpEndpoints);
476
+ } else {
477
+ completion([self defaultFallbackEndpoints]);
478
+ }
479
+ }];
480
+ return;
481
+ }
482
+ completion([self defaultFallbackEndpoints]);
483
+ };
484
+
485
+ NSString *firstHttpsUrl = config.httpsSisUrls.firstObject;
486
+ if (firstHttpsUrl.length == 0) {
487
+ fallbackToUdpSis();
488
+ return;
489
+ }
490
+
491
+ NSString *aesKey = [JCORECrypto httpSeedKeyWithOutSeed:NULL];
492
+ NSString *authHeader = nil;
493
+ NSData *encrypted = [JCORESisResolver encryptHttpSisPayload:[self buildSisRequestPayload]
494
+ aesKey:aesKey
495
+ outAuthHeader:&authHeader];
496
+
497
+ NSURL *url = [NSURL URLWithString:[firstHttpsUrl stringByAppendingString:@"/v3/srv"]];
498
+ if (url == nil || encrypted.length == 0 || authHeader.length == 0) {
499
+ fallbackToUdpSis();
500
+ return;
501
+ }
502
+
503
+ NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
504
+ request.HTTPMethod = @"POST";
505
+ request.HTTPBody = encrypted;
506
+ [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
507
+ [request setValue:authHeader forHTTPHeaderField:@"Authorization"];
508
+ request.timeoutInterval = 6.0;
509
+
510
+ NSURLSessionDataTask *task = [self.urlSession dataTaskWithRequest:request
511
+ completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
512
+ if (error == nil && data.length > 0) {
513
+ NSDictionary *json = [JCORESisResolver decryptHttpSisResponse:data aesKey:aesKey];
514
+ NSArray<JCORESisEndpoint *> *parsed = [self parseSisResponseDictionary:json];
515
+ if (parsed.count > 0) {
516
+ completion(parsed);
517
+ return;
518
+ }
519
+ }
520
+ fallbackToUdpSis();
521
+ }];
522
+ [task resume];
523
+ }
524
+
525
+ @end
@@ -0,0 +1,42 @@
1
+ #import <Foundation/Foundation.h>
2
+ #import "JCOREWireProtocol.h"
3
+
4
+ NS_ASSUME_NONNULL_BEGIN
5
+
6
+ typedef void (^JCORETcpResponseHandler)(JCOREWireFrame *_Nullable responseFrame, NSError *_Nullable error);
7
+
8
+ @interface JCORETcpSession : NSObject
9
+
10
+ + (instancetype)shared;
11
+
12
+ @property (nonatomic, assign, readonly, getter=isConnected) BOOL connected;
13
+ @property (nonatomic, assign, readonly, getter=isLoggedIn) BOOL loggedIn;
14
+ @property (nonatomic, assign, readonly) uint32_t sessionId;
15
+ @property (nonatomic, assign, readonly) uint16_t serverVersion;
16
+ @property (nonatomic, assign, readonly) uint32_t serverTimestamp;
17
+ @property (nonatomic, assign, readonly) NSUInteger reconnectAttemptCount;
18
+
19
+ - (void)setCustomConnectHost:(nullable NSString *)host
20
+ port:(uint16_t)port
21
+ useSSL:(BOOL)useSSL;
22
+
23
+ - (void)startIfNeeded;
24
+ - (void)reconnect;
25
+ - (void)disconnect;
26
+
27
+ - (void)reportDeviceTokenIfNeeded;
28
+ - (void)reportVoipTokenIfNeeded;
29
+ - (void)sendHeartbeatNowWithCompletion:(nullable JCORETcpResponseHandler)completion;
30
+ - (void)sendReceiptForMessageType:(uint8_t)messageType messageId:(uint64_t)messageId;
31
+
32
+ - (void)sendCommand:(uint8_t)command
33
+ version:(uint8_t)version
34
+ bodyData:(NSData *)bodyData
35
+ completion:(nullable JCORETcpResponseHandler)completion;
36
+
37
+ @end
38
+
39
+ @interface JCORETcpClient : JCORETcpSession
40
+ @end
41
+
42
+ NS_ASSUME_NONNULL_END