react-native-windows 0.68.3 → 0.69.0-preview.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (378) hide show
  1. package/.flowconfig +1 -3
  2. package/Chakra/ChakraHelpers.cpp +0 -1
  3. package/Directory.Build.props +3 -0
  4. package/Directory.Build.targets +1 -1
  5. package/Folly/TEMP_UntilFollyUpdate/dynamic-inl.h +1411 -0
  6. package/Folly/TEMP_UntilFollyUpdate/lang/ToAscii.cpp +336 -0
  7. package/Folly/TEMP_UntilFollyUpdate/lang/ToAscii.h +182 -0
  8. package/Libraries/ActionSheetIOS/ActionSheetIOS.js +7 -0
  9. package/Libraries/ActionSheetIOS/NativeActionSheetManager.js +1 -0
  10. package/Libraries/Alert/Alert.windows.js +2 -2
  11. package/Libraries/Animated/AnimatedImplementation.js +1 -1
  12. package/Libraries/Animated/NativeAnimatedHelper.js +55 -9
  13. package/Libraries/Animated/NativeAnimatedModule.js +1 -0
  14. package/Libraries/Animated/NativeAnimatedTurboModule.js +1 -0
  15. package/Libraries/Animated/animations/TimingAnimation.js +6 -11
  16. package/Libraries/Animated/createAnimatedComponent.js +2 -2
  17. package/Libraries/Animated/nodes/AnimatedColor.js +95 -29
  18. package/Libraries/Animated/nodes/AnimatedInterpolation.js +19 -22
  19. package/Libraries/Animated/nodes/AnimatedNode.js +2 -2
  20. package/Libraries/Animated/nodes/AnimatedValue.js +1 -1
  21. package/Libraries/AppState/AppState.js +1 -1
  22. package/Libraries/Blob/URL.js +7 -1
  23. package/Libraries/Components/Button.js +3 -0
  24. package/Libraries/Components/Button.windows.js +4 -0
  25. package/Libraries/Components/DatePickerAndroid/NativeDatePickerAndroid.js +5 -0
  26. package/Libraries/Components/Pressable/Pressable.js +3 -3
  27. package/Libraries/Components/Pressable/Pressable.windows.js +3 -3
  28. package/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js +47 -38
  29. package/Libraries/Components/ScrollView/ScrollContentViewNativeComponent.js +15 -7
  30. package/Libraries/Components/ScrollView/ScrollView.js +1 -1
  31. package/Libraries/Components/ScrollView/ScrollViewNativeComponent.js +16 -3
  32. package/Libraries/Components/ScrollView/ScrollViewStickyHeader.js +3 -1
  33. package/Libraries/Components/Slider/Slider.js +0 -2
  34. package/Libraries/Components/Slider/SliderNativeComponent.js +0 -1
  35. package/Libraries/Components/StatusBar/StatusBar.js +6 -1
  36. package/Libraries/Components/Switch/Switch.js +11 -1
  37. package/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js +114 -109
  38. package/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js +17 -9
  39. package/Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js +13 -5
  40. package/Libraries/Components/TextInput/RCTTextInputViewConfig.js +10 -0
  41. package/Libraries/Components/TextInput/TextInput.js +1 -8
  42. package/Libraries/Components/TextInput/TextInput.windows.js +4 -9
  43. package/Libraries/Components/TextInput/TextInputState.js +10 -2
  44. package/Libraries/Components/TextInput/TextInputState.windows.js +10 -3
  45. package/Libraries/Components/TextInput/WindowsTextInputNativeComponent.js +1 -1
  46. package/Libraries/Components/Touchable/TouchableBounce.js +1 -0
  47. package/Libraries/Components/Touchable/TouchableHighlight.js +1 -0
  48. package/Libraries/Components/Touchable/TouchableHighlight.windows.js +6 -5
  49. package/Libraries/Components/Touchable/TouchableNativeFeedback.js +1 -0
  50. package/Libraries/Components/Touchable/TouchableOpacity.js +7 -1
  51. package/Libraries/Components/Touchable/TouchableOpacity.windows.js +11 -5
  52. package/Libraries/Components/Touchable/TouchableWithoutFeedback.js +2 -0
  53. package/Libraries/Components/Touchable/TouchableWithoutFeedback.windows.js +2 -0
  54. package/Libraries/Components/View/ReactNativeViewAttributes.js +1 -0
  55. package/Libraries/Components/View/ReactNativeViewAttributes.windows.js +1 -0
  56. package/Libraries/Components/View/View.windows.js +33 -1
  57. package/Libraries/Components/View/ViewNativeComponent.js +68 -8
  58. package/Libraries/Components/View/ViewPropTypes.js +36 -4
  59. package/Libraries/Components/View/ViewPropTypes.windows.js +36 -4
  60. package/Libraries/Core/Devtools/parseHermesStack.js +1 -1
  61. package/Libraries/Core/ExceptionsManager.js +1 -1
  62. package/Libraries/Core/RawEventEmitter.js +38 -0
  63. package/Libraries/Core/ReactNativeVersion.js +2 -2
  64. package/Libraries/Core/polyfillPromise.js +32 -0
  65. package/Libraries/Core/setUpReactDevTools.js +3 -2
  66. package/Libraries/EventEmitter/NativeEventEmitter.js +3 -3
  67. package/Libraries/EventEmitter/RCTDeviceEventEmitter.js +2 -1
  68. package/Libraries/EventEmitter/__mocks__/NativeEventEmitter.js +3 -3
  69. package/Libraries/Events/CustomEvent.js +32 -0
  70. package/Libraries/Events/EventPolyfill.js +239 -0
  71. package/Libraries/Image/Image.android.js +0 -6
  72. package/Libraries/Image/Image.ios.js +0 -6
  73. package/Libraries/Image/Image.windows.js +2 -8
  74. package/Libraries/Image/ImageViewNativeComponent.js +18 -3
  75. package/Libraries/Image/TextInlineImageNativeComponent.js +23 -15
  76. package/Libraries/Inspector/Inspector.js +2 -4
  77. package/Libraries/Interaction/BridgeSpyStallHandler.js +4 -3
  78. package/Libraries/Interaction/InteractionManager.js +1 -12
  79. package/Libraries/Interaction/TaskQueue.js +5 -4
  80. package/Libraries/LayoutAnimation/LayoutAnimation.js +13 -0
  81. package/Libraries/Linking/Linking.js +1 -1
  82. package/Libraries/Lists/FlatList.js +27 -6
  83. package/Libraries/Lists/VirtualizedList.js +71 -55
  84. package/Libraries/Lists/VirtualizedListContext.js +7 -3
  85. package/Libraries/Lists/VirtualizedSectionList.js +2 -2
  86. package/Libraries/Lists/__tests__/{FillRateHelper-test.windows.js → FillRateHelper-test.js} +2 -2
  87. package/Libraries/Lists/__tests__/{FlatList-test.windows.js → FlatList-test.js} +2 -2
  88. package/Libraries/Lists/__tests__/{SectionList-test.windows.js → SectionList-test.js} +14 -14
  89. package/Libraries/Lists/__tests__/{VirtualizeUtils-test.windows.js → VirtualizeUtils-test.js} +3 -3
  90. package/Libraries/Lists/__tests__/{VirtualizedList-test.windows.js → VirtualizedList-test.js} +91 -42
  91. package/Libraries/Lists/__tests__/{VirtualizedSectionList-test.windows.js → VirtualizedSectionList-test.js} +13 -13
  92. package/Libraries/LogBox/Data/LogBoxData.js +2 -2
  93. package/Libraries/LogBox/Data/LogBoxLog.js +1 -1
  94. package/Libraries/LogBox/Data/LogBoxSymbolication.js +1 -1
  95. package/Libraries/LogBox/Data/parseLogBoxLog.js +1 -1
  96. package/Libraries/LogBox/LogBox.js +2 -21
  97. package/Libraries/LogBox/UI/LogBoxInspectorFooter.js +1 -0
  98. package/Libraries/LogBox/UI/LogBoxInspectorHeader.js +2 -1
  99. package/Libraries/NativeComponent/BaseViewConfig.android.js +295 -0
  100. package/Libraries/NativeComponent/BaseViewConfig.ios.js +333 -0
  101. package/Libraries/NativeComponent/BaseViewConfig.windows.js +334 -0
  102. package/Libraries/NativeComponent/NativeComponentRegistry.js +0 -2
  103. package/Libraries/NativeComponent/PlatformBaseViewConfig.js +24 -0
  104. package/Libraries/NativeComponent/StaticViewConfigValidator.js +7 -42
  105. package/Libraries/NativeComponent/ViewConfig.js +4 -4
  106. package/Libraries/NativeComponent/ViewConfigIgnore.js +54 -0
  107. package/Libraries/Network/FormData.js +7 -1
  108. package/Libraries/Pressability/Pressability.js +115 -46
  109. package/Libraries/Pressability/Pressability.windows.js +190 -74
  110. package/Libraries/Pressability/PressabilityDebug.js +5 -9
  111. package/Libraries/PushNotificationIOS/NativePushNotificationManagerIOS.js +1 -0
  112. package/Libraries/ReactNative/AppContainer.js +1 -1
  113. package/Libraries/ReactNative/{DummyUIManager.js → BridgelessUIManager.js} +62 -40
  114. package/Libraries/ReactNative/PaperUIManager.windows.js +5 -5
  115. package/Libraries/ReactNative/ReactNativeFeatureFlags.js +39 -0
  116. package/Libraries/ReactNative/UIManager.js +2 -3
  117. package/Libraries/ReactNative/renderApplication.js +4 -0
  118. package/Libraries/ReactPrivate/ReactNativePrivateInterface.js +8 -0
  119. package/Libraries/Renderer/implementations/ReactFabric-dev.js +5908 -4906
  120. package/Libraries/Renderer/implementations/ReactFabric-prod.js +2100 -1918
  121. package/Libraries/Renderer/implementations/ReactFabric-profiling.js +2567 -2352
  122. package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +5610 -4844
  123. package/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +1710 -1556
  124. package/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +1830 -1639
  125. package/Libraries/Renderer/shims/ReactNativeTypes.js +2 -1
  126. package/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +2 -1
  127. package/Libraries/StyleSheet/EdgeInsetsPropType.js +4 -1
  128. package/Libraries/StyleSheet/StyleSheetTypes.js +59 -66
  129. package/Libraries/StyleSheet/normalizeColor.js +1 -1
  130. package/Libraries/StyleSheet/private/_StyleSheetTypesOverrides.js +15 -0
  131. package/Libraries/StyleSheet/private/_TransformStyle.js +53 -0
  132. package/Libraries/StyleSheet/processTransform.windows.js +272 -0
  133. package/Libraries/Text/Text.js +13 -7
  134. package/Libraries/Text/Text.windows.js +16 -7
  135. package/Libraries/Text/TextNativeComponent.js +2 -0
  136. package/Libraries/Text/TextProps.js +10 -0
  137. package/Libraries/Types/CoreEventTypes.js +13 -1
  138. package/Libraries/Types/CoreEventTypes.windows.js +26 -1
  139. package/Libraries/Utilities/Appearance.js +0 -8
  140. package/Libraries/Utilities/HMRClient.js +1 -1
  141. package/Libraries/Utilities/ReactNativeTestTools.js +1 -0
  142. package/Libraries/Utilities/codegenNativeComponent.js +17 -6
  143. package/Libraries/Utilities/stringifySafe.js +4 -1
  144. package/Libraries/Utilities/verifyComponentAttributeEquivalence.js +3 -3
  145. package/Libraries/WebSocket/WebSocket.js +1 -1
  146. package/Libraries/vendor/emitter/_EmitterSubscription.js +1 -1
  147. package/Libraries/vendor/emitter/_EventEmitter.js +1 -1
  148. package/Libraries/vendor/emitter/_EventSubscription.js +1 -1
  149. package/Microsoft.ReactNative/DynamicReader.cpp +3 -3
  150. package/Microsoft.ReactNative/Fabric/ComponentView.h +1 -0
  151. package/Microsoft.ReactNative/Fabric/ComponentViewRegistry.cpp +36 -2
  152. package/Microsoft.ReactNative/Fabric/ComponentViewRegistry.h +1 -0
  153. package/Microsoft.ReactNative/Fabric/DWriteHelpers.cpp +19 -0
  154. package/Microsoft.ReactNative/Fabric/DWriteHelpers.h +13 -0
  155. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +65 -19
  156. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.h +2 -0
  157. package/Microsoft.ReactNative/Fabric/ParagraphComponentView.cpp +36 -10
  158. package/Microsoft.ReactNative/Fabric/ScrollViewComponentView.cpp +2 -0
  159. package/Microsoft.ReactNative/Fabric/SliderComponentView.cpp +107 -0
  160. package/Microsoft.ReactNative/Fabric/SliderComponentView.h +51 -0
  161. package/Microsoft.ReactNative/Fabric/SwitchComponentView.cpp +109 -0
  162. package/Microsoft.ReactNative/Fabric/SwitchComponentView.h +52 -0
  163. package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputComponentDescriptor.h +197 -0
  164. package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputComponentView.cpp +308 -0
  165. package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputComponentView.h +52 -0
  166. package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputEventEmitter.cpp +31 -0
  167. package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputEventEmitter.h +33 -0
  168. package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputProps.cpp +81 -0
  169. package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputProps.h +132 -0
  170. package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputShadowNode.cpp +193 -0
  171. package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputShadowNode.h +85 -0
  172. package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputState.cpp +76 -0
  173. package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputState.h +99 -0
  174. package/Microsoft.ReactNative/Fabric/ViewComponentView.cpp +35 -3
  175. package/Microsoft.ReactNative/Fabric/ViewComponentView.h +1 -0
  176. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/rncore/EventEmitters.h +5 -0
  177. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/rncore/Props.h +5 -0
  178. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/slider/SliderMeasurementsManager.cpp +46 -0
  179. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/slider/SliderMeasurementsManager.h +30 -0
  180. package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/Color.cpp +2 -0
  181. package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/conversions.h +1 -9
  182. package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/platform/cxx/react/renderer/graphics/Color.h +3 -1
  183. package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/TextLayoutManager.cpp +119 -57
  184. package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/TextLayoutManager.h +18 -1
  185. package/Microsoft.ReactNative/IViewManager.idl +3 -3
  186. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +13 -107
  187. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters +2 -2
  188. package/Microsoft.ReactNative/Modules/AppStateModule.cpp +2 -0
  189. package/Microsoft.ReactNative/Modules/AppStateModule.h +2 -0
  190. package/Microsoft.ReactNative/Modules/CreateModules.cpp +3 -3
  191. package/Microsoft.ReactNative/Modules/NativeUIManager.cpp +7 -5
  192. package/Microsoft.ReactNative/Modules/TimingModule.cpp +2 -2
  193. package/Microsoft.ReactNative/Modules/TimingModule.h +2 -2
  194. package/Microsoft.ReactNative/ReactHost/{ReactContext.cpp → MsoReactContext.cpp} +1 -1
  195. package/Microsoft.ReactNative/ReactHost/{ReactContext.h → MsoReactContext.h} +0 -0
  196. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +14 -1
  197. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +1 -1
  198. package/Microsoft.ReactNative/ReactHost/ReactNativeHeaders.h +1 -1
  199. package/Microsoft.ReactNative/ReactRootView.cpp +2 -1
  200. package/Microsoft.ReactNative/RedBox.cpp +3 -2
  201. package/Microsoft.ReactNative/Utils/ValueUtils.cpp +3 -2
  202. package/Microsoft.ReactNative/Views/ControlViewManager.cpp +32 -0
  203. package/Microsoft.ReactNative/Views/ControlViewManager.h +11 -0
  204. package/Microsoft.ReactNative/Views/DevMenu.cpp +2 -2
  205. package/Microsoft.ReactNative/Views/FrameworkElementTransferProperties.cpp +13 -2
  206. package/Microsoft.ReactNative/Views/FrameworkElementViewManager.cpp +149 -22
  207. package/Microsoft.ReactNative/Views/Image/ImageViewManager.cpp +1 -1
  208. package/Microsoft.ReactNative/Views/Image/Microsoft.UI.Composition.Effects_Impl.h +5 -11
  209. package/Microsoft.ReactNative/Views/Image/ReactImage.cpp +2 -1
  210. package/Microsoft.ReactNative/Views/SliderViewManager.cpp +12 -4
  211. package/Microsoft.ReactNative/Views/TextInputViewManager.cpp +1 -1
  212. package/Microsoft.ReactNative/Views/TextViewManager.cpp +2 -2
  213. package/Microsoft.ReactNative/Views/TouchEventHandler.cpp +163 -37
  214. package/Microsoft.ReactNative/Views/TouchEventHandler.h +11 -4
  215. package/Microsoft.ReactNative/Views/ViewPanel.cpp +3 -23
  216. package/Microsoft.ReactNative/Views/ViewPanel.h +2 -3
  217. package/Microsoft.ReactNative/Views/ViewViewManager.cpp +21 -0
  218. package/Microsoft.ReactNative/XamlUIService.cpp +1 -1
  219. package/Microsoft.ReactNative/XamlView.h +8 -3
  220. package/Microsoft.ReactNative.Cxx/CppWinRTIncludes.h +3 -5
  221. package/Microsoft.ReactNative.Cxx/DesktopWindowBridge.h +1 -1
  222. package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.cpp +11 -2
  223. package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.h +1 -0
  224. package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiRuntime.cpp +10 -1
  225. package/Microsoft.ReactNative.Cxx/JSValueReader.h +2 -2
  226. package/Microsoft.ReactNative.Cxx/JSValueWriter.h +5 -5
  227. package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +5 -1
  228. package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems.filters +2 -3
  229. package/Microsoft.ReactNative.Cxx/NativeModules.h +1 -1
  230. package/Microsoft.ReactNative.Cxx/ReactContext.h +3 -3
  231. package/Microsoft.ReactNative.Cxx/ReactNonAbiValue.h +3 -3
  232. package/Microsoft.ReactNative.Cxx/XamlUtils.h +44 -5
  233. package/Microsoft.ReactNative.Managed/Microsoft.ReactNative.Managed.csproj +0 -6
  234. package/Mso/activeObject/activeObject.h +2 -2
  235. package/Mso/compilerAdapters/cppMacros.h +3 -5
  236. package/Mso/errorCode/errorProvider.h +2 -2
  237. package/Mso/errorCode/maybe.h +4 -4
  238. package/Mso/functional/functor.h +6 -6
  239. package/Mso/functional/functorRef.h +2 -2
  240. package/Mso/future/details/executor.h +2 -2
  241. package/Mso/future/details/futureFuncInl.h +4 -4
  242. package/Mso/future/details/ifuture.h +3 -3
  243. package/Mso/future/details/maybeInvoker.h +6 -6
  244. package/Mso/future/details/promiseGroupInl.h +4 -4
  245. package/Mso/future/details/promiseInl.h +4 -4
  246. package/Mso/future/details/resultTraits.h +4 -4
  247. package/Mso/future/details/whenAllInl.h +1 -1
  248. package/Mso/future/future.h +13 -13
  249. package/Mso/guid/msoGuidDetails.h +1 -1
  250. package/Mso/memoryApi/memoryApi.h +13 -7
  251. package/Mso/motifCpp/gTestAdapter.h +1 -1
  252. package/Mso/motifCpp/testInfo.h +7 -9
  253. package/Mso/object/make.h +8 -8
  254. package/Mso/object/objectRefCount.h +3 -5
  255. package/Mso/object/objectWithWeakRef.h +10 -14
  256. package/Mso/object/queryCast.h +4 -4
  257. package/Mso/object/refCountedObject.h +4 -4
  258. package/Mso/object/unknownObject.h +7 -7
  259. package/Mso/platformAdapters/windowsFirst.h +1 -1
  260. package/Mso/smartPtr/cntPtr.h +8 -8
  261. package/Mso/src/dispatchQueue/uiScheduler_winrt.cpp +2 -2
  262. package/Mso/src/future/futureImpl.h +1 -1
  263. package/Mso/src/memoryApi/memoryApi.cpp +4 -4
  264. package/PropertySheets/CppAppConsumeCSharpModule.props +3 -0
  265. package/PropertySheets/External/Microsoft.ReactNative.WinAppSDK.CSharpApp.props +26 -0
  266. package/PropertySheets/External/Microsoft.ReactNative.WinAppSDK.Common.props +12 -0
  267. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  268. package/PropertySheets/React.Cpp.props +13 -0
  269. package/PropertySheets/WinUI.props +3 -6
  270. package/ReactCommon/ReactCommon.vcxproj +2 -4
  271. package/ReactCommon/ReactCommon.vcxproj.filters +4 -1
  272. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/JSCRuntime.cpp +1480 -0
  273. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/decorator.h +753 -0
  274. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/jsi.h +1331 -0
  275. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/test/testlib.cpp +1431 -0
  276. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/bridging/CallbackWrapper.h +103 -0
  277. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/nativemodule/core/ReactCommon/TurboModule.h +87 -0
  278. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/nativemodule/core/ReactCommon/TurboModuleUtils.h +61 -0
  279. package/ReactCommon/Yoga.cpp +1 -1
  280. package/Scripts/{Microsoft.ReactNative.ProjectReunion.nuspec → Microsoft.ReactNative.WindowsAppSDK.nuspec} +7 -9
  281. package/Scripts/OfficeReact.Win32.nuspec +1 -3
  282. package/Scripts/Tfs/Layout-MSRN-Headers.ps1 +2 -1
  283. package/Scripts/copyRNLibraries.js +8 -8
  284. package/Scripts/just.js +1 -1
  285. package/Scripts/rnw-dependencies.ps1 +41 -10
  286. package/Scripts/run-desktop-integration-tests.js +6 -6
  287. package/Shared/AbiSafe.h +3 -3
  288. package/Shared/BaseScriptStoreImpl.cpp +1 -1
  289. package/Shared/CppRuntimeOptions.h +50 -0
  290. package/Shared/DevSupportManager.cpp +32 -36
  291. package/Shared/DevSupportManager.h +1 -2
  292. package/Shared/HermesRuntimeHolder.cpp +23 -14
  293. package/Shared/HermesRuntimeHolder.h +8 -2
  294. package/Shared/IDevSupportManager.h +1 -2
  295. package/Shared/InspectorPackagerConnection.cpp +7 -5
  296. package/Shared/InspectorPackagerConnection.h +2 -2
  297. package/Shared/JSI/ChakraApi.cpp +0 -1
  298. package/Shared/JSI/ChakraRuntime.cpp +1 -2
  299. package/Shared/JSI/RuntimeHolder.h +2 -0
  300. package/Shared/Modules/HttpModule.cpp +1 -1
  301. package/Shared/Modules/HttpModule.h +2 -2
  302. package/Shared/Modules/WebSocketModule.cpp +1 -1
  303. package/Shared/Modules/WebSocketModule.h +8 -5
  304. package/Shared/{IHttpResource.h → Networking/IHttpResource.h} +4 -4
  305. package/Shared/{IWebSocketResource.h → Networking/IWebSocketResource.h} +2 -2
  306. package/Shared/Networking/OriginPolicy.h +15 -0
  307. package/Shared/Networking/OriginPolicyHttpFilter.cpp +746 -0
  308. package/Shared/Networking/OriginPolicyHttpFilter.h +112 -0
  309. package/Shared/{WinRTHttpResource.cpp → Networking/WinRTHttpResource.cpp} +129 -99
  310. package/Shared/{WinRTHttpResource.h → Networking/WinRTHttpResource.h} +8 -12
  311. package/Shared/Networking/WinRTTypes.h +30 -0
  312. package/Shared/{WinRTWebSocketResource.cpp → Networking/WinRTWebSocketResource.cpp} +2 -2
  313. package/Shared/{WinRTWebSocketResource.h → Networking/WinRTWebSocketResource.h} +3 -3
  314. package/Shared/OInstance.cpp +5 -5
  315. package/Shared/RuntimeOptions.cpp +93 -15
  316. package/Shared/RuntimeOptions.h +22 -9
  317. package/Shared/Shared.vcxitems +122 -7
  318. package/Shared/Shared.vcxitems.filters +40 -21
  319. package/Shared/Threading/BatchingQueueThread.cpp +1 -1
  320. package/Shared/tracing/fbsystrace.h +2 -2
  321. package/codegen/NativeActionSheetManagerSpec.g.h +6 -0
  322. package/codegen/NativeAnimatedModuleSpec.g.h +43 -37
  323. package/codegen/NativeAnimatedTurboModuleSpec.g.h +43 -37
  324. package/codegen/NativePushNotificationManagerIOSSpec.g.h +2 -0
  325. package/codegen/react/components/rnwcore/ComponentDescriptors.h +0 -1
  326. package/codegen/react/components/rnwcore/EventEmitters.cpp +133 -0
  327. package/codegen/react/components/rnwcore/EventEmitters.h +0 -18
  328. package/codegen/react/components/rnwcore/Props.cpp +0 -13
  329. package/codegen/react/components/rnwcore/Props.h +0 -16
  330. package/codegen/react/components/rnwcore/ShadowNodes.cpp +0 -1
  331. package/codegen/react/components/rnwcore/ShadowNodes.h +0 -10
  332. package/include/Shared/cdebug.h +9 -9
  333. package/index.js +30 -25
  334. package/index.windows.js +30 -25
  335. package/jest/preprocessor.js +24 -107
  336. package/jest/preprocessor_DO_NOT_USE.js +122 -0
  337. package/metro.config.js +3 -70
  338. package/package.json +29 -28
  339. package/react-native.config.js +40 -6
  340. package/rntypes/index.d.ts +19 -7
  341. package/stubs/glog/logging.h +1 -1
  342. package/template/cpp-app/src/App.h +0 -4
  343. package/template/cs-app/src/App.xaml.cs +0 -5
  344. package/template/cs-app/src/MainPage.xaml.cs +1 -10
  345. package/template/cs-app-WinAppSDK/MyApp/App.xaml +16 -0
  346. package/template/cs-app-WinAppSDK/MyApp/App.xaml.cs +70 -0
  347. package/template/cs-app-WinAppSDK/MyApp/MainWindow.xaml +14 -0
  348. package/template/cs-app-WinAppSDK/MyApp/MainWindow.xaml.cs +38 -0
  349. package/template/cs-app-WinAppSDK/MyApp/Package.appxmanifest +48 -0
  350. package/template/cs-app-WinAppSDK/MyApp/Properties/PublishProfiles/win10-arm64.pubxml +19 -0
  351. package/template/cs-app-WinAppSDK/MyApp/Properties/PublishProfiles/win10-x64.pubxml +19 -0
  352. package/template/cs-app-WinAppSDK/MyApp/Properties/PublishProfiles/win10-x86.pubxml +19 -0
  353. package/template/cs-app-WinAppSDK/MyApp/Properties/launchSettings.json +10 -0
  354. package/template/cs-app-WinAppSDK/MyApp/app.manifest +15 -0
  355. package/template/cs-app-WinAppSDK/proj/ExperimentalFeatures.props +23 -0
  356. package/template/cs-app-WinAppSDK/proj/MyApp.csproj +49 -0
  357. package/template/cs-app-WinAppSDK/proj/MyApp.sln +43 -0
  358. package/template/cs-app-WinAppSDK/proj/NuGet.Config +17 -0
  359. package/template/metro.devMode.config.js +2 -51
  360. package/typings-index.js +5 -1
  361. package/typings-index.js.map +1 -1
  362. package/Libraries/Components/SegmentedControlIOS/RCTSegmentedControlNativeComponent.js +0 -44
  363. package/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.android.js +0 -45
  364. package/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.ios.js +0 -123
  365. package/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.windows.js +0 -45
  366. package/Libraries/Components/View/ReactNativeViewViewConfig.js +0 -360
  367. package/Libraries/Components/View/ReactNativeViewViewConfig.windows.js +0 -390
  368. package/Libraries/Components/View/ReactNativeViewViewConfigAndroid.js +0 -83
  369. package/Libraries/ReactNative/UIManagerInjection.js +0 -15
  370. package/Libraries/Renderer/implementations/ReactFabric-dev.fb.js +0 -24527
  371. package/Libraries/Renderer/implementations/ReactFabric-prod.fb.js +0 -8309
  372. package/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js +0 -8961
  373. package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js +0 -24948
  374. package/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js +0 -8400
  375. package/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js +0 -9049
  376. package/PropertySheets/CppEnablePackageReferences.props +0 -13
  377. package/Shared/cdebug.cpp +0 -6
  378. package/include/Shared/ViewManager.h +0 -34
@@ -0,0 +1,746 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #include "OriginPolicyHttpFilter.h"
5
+
6
+ // React Native Windows
7
+ #include <CppRuntimeOptions.h>
8
+ #include "WinRTTypes.h"
9
+
10
+ // Boost Library
11
+ #include <boost/algorithm/string.hpp>
12
+ #include <boost/lexical_cast/try_lexical_convert.hpp>
13
+
14
+ // Windows API
15
+ #include <winrt/Windows.Web.Http.Headers.h>
16
+
17
+ // Standard Library
18
+ #include <queue>
19
+ #include <regex>
20
+
21
+ using std::set;
22
+ using std::wstring;
23
+
24
+ using winrt::hresult_error;
25
+ using winrt::hstring;
26
+ using winrt::to_hstring;
27
+ using winrt::Windows::Foundation::IInspectable;
28
+ using winrt::Windows::Foundation::IPropertyValue;
29
+ using winrt::Windows::Foundation::Uri;
30
+ using winrt::Windows::Web::Http::HttpMethod;
31
+ using winrt::Windows::Web::Http::HttpRequestMessage;
32
+ using winrt::Windows::Web::Http::HttpResponseMessage;
33
+ using winrt::Windows::Web::Http::Filters::IHttpBaseProtocolFilter;
34
+ using winrt::Windows::Web::Http::Filters::IHttpFilter;
35
+ using winrt::Windows::Web::Http::Headers::HttpMediaTypeHeaderValue;
36
+ using winrt::Windows::Web::Http::Headers::HttpRequestHeaderCollection;
37
+
38
+ namespace Microsoft::React::Networking {
39
+
40
+ #pragma region OriginPolicyHttpFilter
41
+
42
+ #pragma region ConstWcharComparer
43
+
44
+ bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, const wchar_t *b) const {
45
+ return _wcsicmp(a, b) < 0;
46
+ }
47
+
48
+ #pragma endregion ConstWcharComparer
49
+
50
+ // https://fetch.spec.whatwg.org/#forbidden-method
51
+ /*static*/ set<const wchar_t *, OriginPolicyHttpFilter::ConstWcharComparer> OriginPolicyHttpFilter::s_forbiddenMethods =
52
+ {L"CONNECT", L"TRACE", L"TRACK"};
53
+
54
+ /*static*/ set<const wchar_t *, OriginPolicyHttpFilter::ConstWcharComparer>
55
+ OriginPolicyHttpFilter::s_simpleCorsMethods = {L"GET", L"HEAD", L"POST"};
56
+
57
+ /*static*/ set<const wchar_t *, OriginPolicyHttpFilter::ConstWcharComparer>
58
+ OriginPolicyHttpFilter::s_simpleCorsRequestHeaderNames = {
59
+ L"Accept",
60
+ L"Accept-Language",
61
+ L"Content-Language",
62
+ L"Content-Type",
63
+ L"DPR",
64
+ L"Downlink",
65
+ L"Save-Data",
66
+ L"Viewport-Width",
67
+ L"Width"};
68
+
69
+ /*static*/ set<const wchar_t *, OriginPolicyHttpFilter::ConstWcharComparer>
70
+ OriginPolicyHttpFilter::s_simpleCorsResponseHeaderNames =
71
+ {L"Cache-Control", L"Content-Language", L"Content-Type", L"Expires", L"Last-Modified", L"Pragma"};
72
+
73
+ /*static*/ set<const wchar_t *, OriginPolicyHttpFilter::ConstWcharComparer>
74
+ OriginPolicyHttpFilter::s_simpleCorsContentTypeValues = {
75
+ L"application/x-www-form-urlencoded",
76
+ L"multipart/form-data",
77
+ L"text/plain"};
78
+
79
+ // https://fetch.spec.whatwg.org/#forbidden-header-name
80
+ // Chromium still bans "User-Agent" due to https://crbug.com/571722
81
+ /*static*/ set<const wchar_t *, OriginPolicyHttpFilter::ConstWcharComparer>
82
+ OriginPolicyHttpFilter::s_corsForbiddenRequestHeaderNames = {
83
+ L"Accept-Charset",
84
+ L"Accept-Encoding",
85
+ L"Access-Control-Request-Headers",
86
+ L"Access-Control-Request-Method",
87
+ L"Connection",
88
+ L"Content-Length",
89
+ L"Cookie",
90
+ L"Cookie2",
91
+ L"Date",
92
+ L"DNT",
93
+ L"Expect",
94
+ L"Host",
95
+ L"Keep-Alive",
96
+ L"Origin",
97
+ L"Referer",
98
+ L"TE",
99
+ L"Trailer",
100
+ L"Transfer-Encoding",
101
+ L"Upgrade",
102
+ L"Via"};
103
+
104
+ /*static*/ set<const wchar_t *, OriginPolicyHttpFilter::ConstWcharComparer>
105
+ OriginPolicyHttpFilter::s_cookieSettingResponseHeaders = {
106
+ L"Set-Cookie",
107
+ L"Set-Cookie2", // Deprecated by the spec, but probably still used
108
+ };
109
+
110
+ /*static*/ set<const wchar_t *, OriginPolicyHttpFilter::ConstWcharComparer>
111
+ OriginPolicyHttpFilter::s_corsForbiddenRequestHeaderNamePrefixes = {L"Proxy-", L"Sec-"};
112
+
113
+ /*static*/ Uri OriginPolicyHttpFilter::s_origin{nullptr};
114
+
115
+ /*static*/ void OriginPolicyHttpFilter::SetStaticOrigin(std::string &&url) {
116
+ if (!url.empty())
117
+ s_origin = Uri{to_hstring(url)};
118
+ }
119
+
120
+ /*static*/ bool OriginPolicyHttpFilter::IsSameOrigin(Uri const &u1, Uri const &u2) noexcept {
121
+ return u1.SchemeName() == u2.SchemeName() && u1.Host() == u2.Host() && u1.Port() == u2.Port();
122
+ }
123
+
124
+ /*static*/ bool OriginPolicyHttpFilter::IsSimpleCorsRequest(HttpRequestMessage const &request) noexcept {
125
+ // Ensure header is in Simple CORS white list
126
+ for (const auto &header : request.Headers()) {
127
+ if (s_simpleCorsRequestHeaderNames.find(header.Key().c_str()) == s_simpleCorsRequestHeaderNames.cend())
128
+ return false;
129
+
130
+ // Ensure Content-Type value is in Simple CORS white list, if present
131
+ if (boost::iequals(header.Key(), L"Content-Type")) {
132
+ if (s_simpleCorsContentTypeValues.find(header.Value().c_str()) != s_simpleCorsContentTypeValues.cend())
133
+ return false;
134
+ }
135
+ }
136
+
137
+ // WinRT separates request headers from request content headers
138
+ if (auto content = request.Content()) {
139
+ for (const auto &header : content.Headers()) {
140
+ // WinRT automatically appends non-whitelisted header Content-Length when Content-Type is set. Skip it.
141
+ if (s_simpleCorsRequestHeaderNames.find(header.Key().c_str()) == s_simpleCorsRequestHeaderNames.cend() &&
142
+ !boost::iequals(header.Key(), "Content-Length"))
143
+ return false;
144
+
145
+ // Ensure Content-Type value is in Simple CORS white list, if present
146
+ if (boost::iequals(header.Key(), L"Content-Type")) {
147
+ if (s_simpleCorsContentTypeValues.find(header.Value().c_str()) == s_simpleCorsContentTypeValues.cend())
148
+ return false;
149
+ }
150
+ }
151
+ }
152
+
153
+ // Ensure method is in Simple CORS white list
154
+ return s_simpleCorsMethods.find(request.Method().ToString().c_str()) != s_simpleCorsMethods.cend();
155
+ }
156
+
157
+ /*static*/ Uri OriginPolicyHttpFilter::GetOrigin(Uri const &uri) noexcept {
158
+ return Uri{uri.SchemeName() + L"://" + uri.Host() + L":" + to_hstring(uri.Port())};
159
+ }
160
+
161
+ /*static*/ bool OriginPolicyHttpFilter::AreSafeRequestHeaders(
162
+ winrt::Windows::Web::Http::Headers::HttpRequestHeaderCollection const &headers) noexcept {
163
+ for (const auto &header : headers) {
164
+ if (s_corsForbiddenRequestHeaderNames.find(header.Key().c_str()) != s_corsForbiddenRequestHeaderNames.cend())
165
+ return false;
166
+
167
+ for (const auto &prefix : s_corsForbiddenRequestHeaderNamePrefixes) {
168
+ if (boost::istarts_with(header.Key(), prefix))
169
+ return false;
170
+ }
171
+ }
172
+
173
+ return true;
174
+ }
175
+
176
+ // See https://fetch.spec.whatwg.org/#cors-safelisted-request-header
177
+ // "A CORS-safelisted header is a header whose name is either one of 'Accept', 'Accept-Language', and
178
+ // 'Content-Language', or whose name is 'Content-Type' and value is one of 'application/x-www-form-urlencoded',
179
+ // 'multipart/form-data', and 'text/plain'
180
+ /*static*/ bool OriginPolicyHttpFilter::IsCorsSafelistedRequestHeader(
181
+ hstring const &name,
182
+ hstring const &value) noexcept {
183
+ // 1. If value's length is greater than 128, then return false.
184
+ if (value.size() > 128)
185
+ return false;
186
+
187
+ // 2. Byte-lowercase name and switch on the result:
188
+ static const wchar_t *const safeHeaderNames[] = {
189
+ // The following four headers are from the CORS spec
190
+ L"accept",
191
+ L"accept-language",
192
+ L"content-language",
193
+ L"content-type",
194
+
195
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Save-Data
196
+ L"save-data",
197
+
198
+ // https://w3c.github.io/device-memory/#sec-device-memory-client-hint-header
199
+ L"device-memory",
200
+ L"dpr",
201
+ L"width",
202
+ L"viewport-width",
203
+
204
+ // https://tools.ietf.org/html/draft-west-lang-client-hint
205
+ L"sec-ch-lang",
206
+
207
+ // https://tools.ietf.org/html/draft-west-ua-client-hints
208
+ L"sec-ch-ua",
209
+ L"sec-ch-ua-platform",
210
+ L"sec-ch-ua-arch",
211
+ L"sec-ch-ua-model",
212
+ L"sec-ch-ua-mobile",
213
+ L"sec-ch-ua-full-version",
214
+ L"sec-ch-ua-platform-version",
215
+ };
216
+
217
+ auto nameLower = boost::to_lower_copy(wstring{name.c_str()});
218
+ if (std::find(std::cbegin(safeHeaderNames), std::cend(safeHeaderNames), nameLower) == std::end(safeHeaderNames))
219
+ return false;
220
+
221
+ double doubleHolder;
222
+ if (nameLower == L"device-memory" || nameLower == L"dpr")
223
+ return boost::conversion::try_lexical_convert<double, wstring>(value.c_str(), doubleHolder);
224
+
225
+ int intHolder;
226
+ if (nameLower == L"width" || nameLower == L"viewport-width")
227
+ return boost::conversion::try_lexical_convert<int, wstring>(value.c_str(), intHolder);
228
+
229
+ auto valueLower = boost::to_lower_copy(wstring{value.c_str()});
230
+ if (nameLower == L"save-data")
231
+ return valueLower == L"on";
232
+
233
+ if (nameLower == L"accept")
234
+ return !std::any_of(valueLower.cbegin(), valueLower.cend(), IsCorsUnsafeRequestHeaderByte);
235
+
236
+ if (nameLower == L"accept-language" || nameLower == L"content-language") {
237
+ return std::all_of(valueLower.cbegin(), valueLower.cend(), [](wchar_t c) noexcept {
238
+ return (0x30 <= c && c <= 0x39) || // 0-9
239
+ (0x41 <= c && c <= 0x5A) || // A-Z
240
+ (0x61 <= c && c <= 0x7A) || // a-z
241
+ c == 0x20 || c == 0x2A || c == 0x2C || c == 0x2D || c == 0x2E || c == 0x3B || c == 0x3D; // *,-.;=
242
+ });
243
+ }
244
+
245
+ if (nameLower == L"content-type") {
246
+ if (std::any_of(valueLower.cbegin(), valueLower.cend(), IsCorsUnsafeRequestHeaderByte))
247
+ return false;
248
+
249
+ // https://mimesniff.spec.whatwg.org/#parse-a-mime-type
250
+ HttpMediaTypeHeaderValue mediaType{nullptr};
251
+ if (HttpMediaTypeHeaderValue::TryParse(valueLower, mediaType))
252
+ return mediaType.ToString() == L"application/x-www-form-urlencoded" ||
253
+ mediaType.ToString() == L"multipart/form-data" || mediaType.ToString() == L"text/plain";
254
+
255
+ return false;
256
+ }
257
+
258
+ return true;
259
+ }
260
+
261
+ // https://fetch.spec.whatwg.org/#cors-unsafe-request-header-byte
262
+ /*static*/ bool OriginPolicyHttpFilter::IsCorsUnsafeRequestHeaderByte(wchar_t c) noexcept {
263
+ return (c < 0x20 && c != 0x09) || c == 0x22 || c == 0x28 || c == 0x29 || c == 0x3a || c == 0x3c || c == 0x3e ||
264
+ c == 0x3f || c == 0x40 || c == 0x5b || c == 0x5c || c == 0x5d || c == 0x7b || c == 0x7d || c == 0x7f;
265
+ }
266
+
267
+ /*static*/ set<const wchar_t *> OriginPolicyHttpFilter::CorsUnsafeNotForbiddenRequestHeaderNames(
268
+ HttpRequestHeaderCollection const &headers) noexcept {
269
+ constexpr size_t maxSafelistValueSize = 1024;
270
+ size_t safelistValueSize = 0;
271
+ std::vector<const wchar_t *> potentiallyUnsafeNames;
272
+ set<const wchar_t *> result;
273
+ for (const auto &header : headers) {
274
+ const auto headerName = header.Key().c_str();
275
+
276
+ // If header is not safe
277
+ if (boost::istarts_with(headerName, L"Proxy-") || boost::istarts_with(headerName, L"Sec-") ||
278
+ s_corsForbiddenRequestHeaderNames.find(headerName) != s_corsForbiddenRequestHeaderNames.cend())
279
+ continue;
280
+
281
+ if (!IsCorsSafelistedRequestHeader(header.Key(), header.Value())) {
282
+ result.emplace(header.Key().c_str());
283
+ } else {
284
+ potentiallyUnsafeNames.emplace_back(std::wstring_view{header.Key()}.data());
285
+ safelistValueSize += header.Value().size();
286
+ }
287
+ }
288
+
289
+ if (safelistValueSize > maxSafelistValueSize)
290
+ result.insert(potentiallyUnsafeNames.begin(), potentiallyUnsafeNames.end());
291
+
292
+ return result;
293
+ }
294
+
295
+ /*static*/ OriginPolicyHttpFilter::AccessControlValues OriginPolicyHttpFilter::ExtractAccessControlValues(
296
+ winrt::Windows::Foundation::Collections::IMap<hstring, hstring> const &headers) {
297
+ using std::wregex;
298
+ using std::wsregex_token_iterator;
299
+
300
+ // https://tools.ietf.org/html/rfc2616#section-4.2
301
+ wregex rgx{L"\\s*,\\s*"};
302
+ AccessControlValues result;
303
+
304
+ auto ciStrCmp = [](const wstring &a, const wstring &b) { return _wcsicmp(a.c_str(), b.c_str()) < 0; };
305
+ set<wstring, decltype(ciStrCmp)> allowedHeaders{ciStrCmp};
306
+ set<wstring, decltype(ciStrCmp)> allowedMethods{ciStrCmp};
307
+ set<wstring, decltype(ciStrCmp)> exposedHeaders{ciStrCmp};
308
+
309
+ for (const auto &header : headers) {
310
+ if (boost::iequals(header.Key(), L"Access-Control-Allow-Headers")) {
311
+ auto value = wstring{header.Value().c_str()};
312
+
313
+ // TODO: Avoid redundant comparison.
314
+ auto parsed = set<wstring, decltype(ciStrCmp)>{
315
+ wsregex_token_iterator{value.cbegin(), value.cend(), rgx, -1}, wsregex_token_iterator{}, ciStrCmp};
316
+ allowedHeaders.insert(parsed.cbegin(), parsed.cend());
317
+ result.AllowedHeaders.insert(allowedHeaders.cbegin(), allowedHeaders.cend());
318
+ } else if (boost::iequals(header.Key(), L"Access-Control-Allow-Methods")) {
319
+ auto value = wstring{header.Value().c_str()};
320
+
321
+ // TODO: Avoid redundant comparison.
322
+ auto parsed = set<wstring, decltype(ciStrCmp)>{
323
+ wsregex_token_iterator{value.cbegin(), value.cend(), rgx, -1}, wsregex_token_iterator{}, ciStrCmp};
324
+ allowedMethods.insert(parsed.cbegin(), parsed.cend());
325
+ result.AllowedMethods.insert(allowedMethods.cbegin(), allowedMethods.cend());
326
+ } else if (boost::iequals(header.Key(), L"Access-Control-Allow-Origin")) {
327
+ result.AllowedOrigin = header.Value();
328
+ } else if (boost::iequals(header.Key(), L"Access-Control-Expose-Headers")) {
329
+ auto value = wstring{header.Value().c_str()};
330
+
331
+ // TODO: Avoid redundant comparison.
332
+ auto parsed = set<wstring, decltype(ciStrCmp)>{
333
+ wsregex_token_iterator{value.cbegin(), value.cend(), rgx, -1}, wsregex_token_iterator{}, ciStrCmp};
334
+ exposedHeaders.insert(parsed.cbegin(), parsed.cend());
335
+ result.ExposedHeaders.insert(exposedHeaders.cbegin(), exposedHeaders.cend());
336
+ } else if (boost::iequals(header.Key(), L"Access-Control-Allow-Credentials")) {
337
+ result.AllowedCredentials = header.Value();
338
+ } else if (boost::iequals(header.Key(), L"Access-Control-Max-Age")) {
339
+ result.MaxAge = _wtoi(header.Value().c_str());
340
+ }
341
+ }
342
+
343
+ return result;
344
+ } // ExtractAccessControlValues
345
+
346
+ /*static*/ void OriginPolicyHttpFilter::RemoveHttpOnlyCookiesFromResponseHeaders(
347
+ HttpResponseMessage const &response,
348
+ bool removeAll) {
349
+ // Example: "Set-Cookie", L"id=a3fWa; Expires=Wed, 21 Oct 2020 07:28:00 GMT; HttpOnly"
350
+ std::queue<hstring> httpOnlyCookies;
351
+ for (const auto &header : response.Headers()) {
352
+ if (s_cookieSettingResponseHeaders.find(header.Key().c_str()) == s_cookieSettingResponseHeaders.cend())
353
+ continue;
354
+
355
+ if (removeAll) {
356
+ httpOnlyCookies.push(header.Key());
357
+ continue;
358
+ }
359
+
360
+ // Anchors (^$) can't be part of bracket expressions ([]).
361
+ // Create 3 matching groups: 1. Beginning of string 2. Between delimiters 3. End of string
362
+ const std::wregex re(L"(^HttpOnly\\s*;)|(;\\s*HttpOnly\\s*;)|(;\\s*HttpOnly$)", std::regex_constants::icase);
363
+ if (!std::regex_search(header.Value().c_str(), re))
364
+ continue;
365
+
366
+ // HttpOnly cookie detected. Removing.
367
+ httpOnlyCookies.push(header.Key());
368
+ } // const auto &header : response.Headers()
369
+
370
+ while (!httpOnlyCookies.empty()) {
371
+ response.Headers().Remove(httpOnlyCookies.front());
372
+ httpOnlyCookies.pop();
373
+ }
374
+ }
375
+
376
+ OriginPolicyHttpFilter::OriginPolicyHttpFilter(IHttpFilter &&innerFilter) : m_innerFilter{std::move(innerFilter)} {}
377
+
378
+ OriginPolicyHttpFilter::OriginPolicyHttpFilter()
379
+ : OriginPolicyHttpFilter(winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter{}) {}
380
+
381
+ OriginPolicy OriginPolicyHttpFilter::ValidateRequest(HttpRequestMessage const &request) {
382
+ auto effectiveOriginPolicy =
383
+ static_cast<OriginPolicy>(request.Properties().Lookup(L"OriginPolicy").as<IPropertyValue>().GetUInt64());
384
+ switch (effectiveOriginPolicy) {
385
+ case OriginPolicy::None:
386
+ return effectiveOriginPolicy;
387
+
388
+ case OriginPolicy::SameOrigin:
389
+ if (!IsSameOrigin(s_origin, request.RequestUri()))
390
+ throw hresult_error{E_INVALIDARG, L"SOP (same-origin policy) is enforced"};
391
+ break;
392
+
393
+ case OriginPolicy::SimpleCrossOriginResourceSharing:
394
+ // Check for disallowed mixed content
395
+ if (GetRuntimeOptionBool("Http.BlockMixedContentSimpleCors") &&
396
+ s_origin.SchemeName() != request.RequestUri().SchemeName())
397
+ throw hresult_error{E_INVALIDARG, L"The origin and request URLs must have the same scheme"};
398
+
399
+ if (IsSameOrigin(s_origin, request.RequestUri()))
400
+ // Same origin. Therefore, skip Cross-Origin handling.
401
+ effectiveOriginPolicy = OriginPolicy::SameOrigin;
402
+ else if (!IsSimpleCorsRequest(request))
403
+ throw hresult_error{
404
+ E_INVALIDARG,
405
+ L"The request does not meet the requirements for Same-Origin policy or Simple Cross-Origin resource sharing"};
406
+ break;
407
+
408
+ case OriginPolicy::CrossOriginResourceSharing:
409
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests
410
+ // Refer to CorsURLLoaderFactory::IsValidRequest in chrome\src\services\network\cors\cors_url_loader_factory.cc.
411
+ // Forbidden headers should be blocked regardless of origins.
412
+ // Example: On the Edge browser, an XHR request with the "Host" header set gets rejected as unsafe.
413
+ // https://fetch.spec.whatwg.org/#forbidden-header-name
414
+
415
+ if (s_origin.SchemeName() != request.RequestUri().SchemeName())
416
+ throw hresult_error{E_INVALIDARG, L"The origin and request URLs must have the same scheme"};
417
+
418
+ if (!AreSafeRequestHeaders(request.Headers()))
419
+ throw hresult_error{E_INVALIDARG, L"Request header not allowed in cross-origin resource sharing"};
420
+
421
+ if (s_forbiddenMethods.find(request.Method().ToString().c_str()) != s_forbiddenMethods.cend())
422
+ throw hresult_error{E_INVALIDARG, L"Request method not allowed in cross-origin resource sharing"};
423
+
424
+ if (IsSameOrigin(s_origin, request.RequestUri()))
425
+ effectiveOriginPolicy = OriginPolicy::SameOrigin;
426
+ else if (IsSimpleCorsRequest(request))
427
+ effectiveOriginPolicy = OriginPolicy::SimpleCrossOriginResourceSharing;
428
+ else
429
+ effectiveOriginPolicy = OriginPolicy::CrossOriginResourceSharing;
430
+
431
+ break;
432
+
433
+ default:
434
+ throw hresult_error{
435
+ E_INVALIDARG, L"Invalid OriginPolicy type: " + to_hstring(static_cast<size_t>(effectiveOriginPolicy))};
436
+ }
437
+
438
+ return effectiveOriginPolicy;
439
+ }
440
+
441
+ // See https://fetch.spec.whatwg.org/#cors-check
442
+ void OriginPolicyHttpFilter::ValidateAllowOrigin(
443
+ hstring const &allowedOrigin,
444
+ hstring const &allowCredentials,
445
+ IInspectable const &iRequestArgs) const {
446
+ // 4.10.1-2 - null allow origin
447
+ if (L"null" == allowedOrigin)
448
+ throw hresult_error{
449
+ E_INVALIDARG,
450
+ L"Response header Access-Control-Allow-Origin has a value of [null] which differs from the supplied origin"};
451
+
452
+ bool withCredentials = iRequestArgs.as<RequestArgs>()->WithCredentials;
453
+ // 4.10.3 - valid wild card allow origin
454
+ if (!withCredentials && L"*" == allowedOrigin)
455
+ return;
456
+
457
+ // We assume the source (request) origin is not "*", "null", or empty string. Valid URI is expected
458
+ // 4.10.4 - Mismatched allow origin
459
+ if (allowedOrigin.empty() || !IsSameOrigin(s_origin, Uri{allowedOrigin})) {
460
+ hstring errorMessage;
461
+ if (allowedOrigin.empty())
462
+ errorMessage = L"No valid origin in response";
463
+
464
+ // See https://fetch.spec.whatwg.org/#http-access-control-allow-origin.
465
+ else if (boost::contains(allowedOrigin, L" ,"))
466
+ errorMessage = L"Response header Access-Control-Allow-Origin can not have multiple values";
467
+
468
+ // A wildcard Access-Control-Allow-Origin can not be used if credentials are to be sent,
469
+ // even with Access-Control-Allow-Credentials set to true
470
+ // See https://fetch.spec.whatwg.org/#cors-protocol-and-credentials
471
+ else if (L"*" == allowedOrigin)
472
+ errorMessage =
473
+ L"Response header Access-Control-Allow-Origin can not have a wildcard value when the request includes credentials";
474
+
475
+ else
476
+ errorMessage = L"The Access-Control-Allow-Origin header has a value of [" + allowedOrigin +
477
+ L"] which differs from the supplied origin";
478
+
479
+ throw hresult_error{E_INVALIDARG, errorMessage};
480
+ }
481
+
482
+ // 4.10.5
483
+ if (!withCredentials)
484
+ return;
485
+
486
+ // 4.10.6-8
487
+ // https://fetch.spec.whatwg.org/#http-access-control-allow-credentials
488
+ // This check should be case sensitive.
489
+ // See also https://fetch.spec.whatwg.org/#http-new-header-syntax
490
+ if (L"true" != allowCredentials)
491
+ throw hresult_error{
492
+ E_INVALIDARG,
493
+ L"Access-Control-Allow-Credentials value must be \"true\" when the response includes credentials"};
494
+ };
495
+
496
+ void OriginPolicyHttpFilter::ValidatePreflightResponse(
497
+ HttpRequestMessage const &request,
498
+ HttpResponseMessage const &response) const {
499
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSExternalRedirectNotAllowed
500
+ using winrt::Windows::Web::Http::HttpStatusCode;
501
+ switch (response.StatusCode()) {
502
+ case HttpStatusCode::MovedPermanently:
503
+ case HttpStatusCode::TemporaryRedirect:
504
+ case HttpStatusCode::PermanentRedirect:
505
+ throw hresult_error{INET_E_REDIRECTING, L"Redirect is not allowed in a preflight request"};
506
+
507
+ default:
508
+ break;
509
+ }
510
+
511
+ auto controlValues = ExtractAccessControlValues(response.Headers());
512
+
513
+ auto iRequestArgs = request.Properties().Lookup(L"RequestArgs");
514
+ // Check if the origin is allowed in conjuction with the withCredentials flag
515
+ // CORS preflight should always exclude credentials although the subsequent CORS request may include credentials.
516
+ ValidateAllowOrigin(controlValues.AllowedOrigin, controlValues.AllowedCredentials, iRequestArgs);
517
+
518
+ // See https://fetch.spec.whatwg.org/#cors-preflight-fetch, section 4.8.7.5
519
+ // Check if the request method is allowed
520
+ bool withCredentials = iRequestArgs.as<RequestArgs>()->WithCredentials;
521
+ bool requestMethodAllowed = false;
522
+ for (const auto &method : controlValues.AllowedMethods) {
523
+ if (L"*" == method) {
524
+ if (!withCredentials) {
525
+ requestMethodAllowed = true;
526
+ break;
527
+ }
528
+ } else if (boost::iequals(method, request.Method().ToString())) {
529
+ requestMethodAllowed = true;
530
+ break;
531
+ }
532
+ }
533
+
534
+ // Preflight should always allow simple CORS methods
535
+ requestMethodAllowed |= s_simpleCorsMethods.find(request.Method().ToString().c_str()) != s_simpleCorsMethods.cend();
536
+
537
+ if (!requestMethodAllowed)
538
+ throw hresult_error{
539
+ E_INVALIDARG,
540
+ L"Method [" + request.Method().ToString() +
541
+ L"] is not allowed by Access-Control-Allow-Methods in preflight response"};
542
+
543
+ // Check if request headers are allowed
544
+ // See https://fetch.spec.whatwg.org/#cors-preflight-fetch, section 4.8.7.6-7
545
+ // Check if the header should be allowed through wildcard, if the request does not have credentials.
546
+ bool requestHeadersAllowed = false;
547
+ if (!withCredentials && controlValues.AllowedHeaders.find(L"*") != controlValues.AllowedHeaders.cend()) {
548
+ // "Authorization" header cannot be allowed through wildcard alone.
549
+ // "Authorization" is the only member of https://fetch.spec.whatwg.org/#cors-non-wildcard-request-header-name.
550
+ if (request.Headers().HasKey(L"Authorization") &&
551
+ controlValues.AllowedHeaders.find(L"Authorization") == controlValues.AllowedHeaders.cend())
552
+ throw hresult_error{
553
+ E_INVALIDARG,
554
+ L"Request header field [Authorization] is not allowed by Access-Control-Allow-Headers in preflight response"};
555
+
556
+ requestHeadersAllowed = true;
557
+ }
558
+ if (!requestHeadersAllowed) {
559
+ // Forbidden headers are excluded from the JavaScript layer.
560
+ // User agents may use these headers internally.
561
+ const set unsafeNotForbidenHeaderNames = CorsUnsafeNotForbiddenRequestHeaderNames(request.Headers());
562
+ for (const auto name : unsafeNotForbidenHeaderNames) {
563
+ if (controlValues.AllowedHeaders.find(name) == controlValues.AllowedHeaders.cend())
564
+ throw hresult_error{
565
+ E_INVALIDARG,
566
+ L"Request header field [" + to_hstring(name) +
567
+ L"] is not allowed by Access-Control-Allow-Headers in preflight response"};
568
+ }
569
+ }
570
+
571
+ // #9770 - insert into preflight cache
572
+ }
573
+
574
+ // See 10.7.4 of https://fetch.spec.whatwg.org/#http-network-or-cache-fetch
575
+ void OriginPolicyHttpFilter::ValidateResponse(HttpResponseMessage const &response, const OriginPolicy originPolicy)
576
+ const {
577
+ bool removeAllCookies = false;
578
+ if (originPolicy == OriginPolicy::SimpleCrossOriginResourceSharing ||
579
+ originPolicy == OriginPolicy::CrossOriginResourceSharing) {
580
+ auto controlValues = ExtractAccessControlValues(response.Headers());
581
+ auto withCredentials =
582
+ response.RequestMessage().Properties().Lookup(L"RequestArgs").try_as<RequestArgs>()->WithCredentials;
583
+
584
+ if (GetRuntimeOptionBool("Http.StrictOriginCheckSimpleCors") &&
585
+ originPolicy == OriginPolicy::SimpleCrossOriginResourceSharing) {
586
+ bool originAllowed = false;
587
+ for (const auto &header : response.Headers()) {
588
+ if (boost::iequals(header.Key(), L"Access-Control-Allow-Origin")) {
589
+ originAllowed |= L"*" == header.Value() || s_origin == Uri{header.Value()};
590
+ }
591
+ }
592
+
593
+ if (!originAllowed) {
594
+ throw hresult_error{E_INVALIDARG, L"The server does not support CORS or the origin is not allowed"};
595
+ }
596
+ } else {
597
+ auto iRequestArgs = response.RequestMessage().Properties().Lookup(L"RequestArgs");
598
+ ValidateAllowOrigin(controlValues.AllowedOrigin, controlValues.AllowedCredentials, iRequestArgs);
599
+ }
600
+
601
+ if (originPolicy == OriginPolicy::SimpleCrossOriginResourceSharing) {
602
+ // Filter out response headers that are not in the Simple CORS whitelist
603
+ std::queue<hstring> nonSimpleNames;
604
+ for (const auto &header : response.Headers().GetView()) {
605
+ if (s_simpleCorsResponseHeaderNames.find(header.Key().c_str()) == s_simpleCorsResponseHeaderNames.cend())
606
+ nonSimpleNames.push(header.Key());
607
+ }
608
+
609
+ while (!nonSimpleNames.empty()) {
610
+ response.Headers().Remove(nonSimpleNames.front());
611
+ nonSimpleNames.pop();
612
+ }
613
+ } else {
614
+ // Filter out response headers that are not simple headers and not in expose list
615
+
616
+ // Keep simple headers and those found in the expose header list.
617
+ if (withCredentials || controlValues.ExposedHeaders.find(L"*") == controlValues.ExposedHeaders.cend()) {
618
+ std::queue<hstring> nonSimpleNonExposedHeaders;
619
+
620
+ for (const auto &header : response.Headers().GetView()) {
621
+ if (s_simpleCorsResponseHeaderNames.find(header.Key().c_str()) == s_simpleCorsResponseHeaderNames.cend() &&
622
+ controlValues.ExposedHeaders.find(header.Key().c_str()) == controlValues.ExposedHeaders.cend()) {
623
+ nonSimpleNonExposedHeaders.push(header.Key());
624
+ }
625
+ }
626
+
627
+ while (!nonSimpleNonExposedHeaders.empty()) {
628
+ response.Headers().Remove(nonSimpleNonExposedHeaders.front());
629
+ nonSimpleNonExposedHeaders.pop();
630
+ }
631
+ }
632
+ }
633
+
634
+ // When withCredentials is false, request cannot include cookies. Also, cookies will be ignored in responses.
635
+ removeAllCookies = !withCredentials && GetRuntimeOptionBool("Http.RemoveCookiesFromResponse");
636
+ } // originPolicy == SimpleCrossOriginResourceSharing || CrossOriginResourceSharing
637
+
638
+ // Don't expose HttpOnly cookies to JavaScript
639
+ RemoveHttpOnlyCookiesFromResponseHeaders(response, removeAllCookies);
640
+ }
641
+
642
+ ResponseOperation OriginPolicyHttpFilter::SendPreflightAsync(HttpRequestMessage const &request) const {
643
+ // TODO: Inject user agent?
644
+
645
+ auto coRequest = request;
646
+
647
+ HttpRequestMessage preflightRequest;
648
+
649
+ // Section 4.8.2 https://fetch.spec.whatwg.org/#cors-preflight-fetch
650
+ preflightRequest.Method(HttpMethod::Options());
651
+ preflightRequest.RequestUri(coRequest.RequestUri());
652
+ preflightRequest.Headers().Insert(L"Accept", L"*/*");
653
+ preflightRequest.Headers().Insert(L"Access-Control-Request-Method", coRequest.Method().ToString());
654
+
655
+ auto headerNames = wstring{};
656
+ auto headerItr = coRequest.Headers().begin();
657
+ if (headerItr != coRequest.Headers().end()) {
658
+ headerNames += (*headerItr).Key();
659
+
660
+ while (++headerItr != coRequest.Headers().end())
661
+ headerNames += L", " + (*headerItr).Key();
662
+ }
663
+
664
+ if (coRequest.Content()) {
665
+ headerItr = coRequest.Content().Headers().begin();
666
+ if (headerItr != coRequest.Content().Headers().end()) {
667
+ headerNames += (*headerItr).Key();
668
+
669
+ while (++headerItr != coRequest.Content().Headers().end())
670
+ headerNames += L", " + (*headerItr).Key();
671
+ }
672
+ }
673
+
674
+ preflightRequest.Headers().Insert(L"Access-Control-Request-Headers", headerNames);
675
+ preflightRequest.Headers().Insert(L"Origin", s_origin.AbsoluteCanonicalUri());
676
+ preflightRequest.Headers().Insert(L"Sec-Fetch-Mode", L"CORS");
677
+
678
+ co_return {co_await m_innerFilter.SendRequestAsync(preflightRequest)};
679
+ }
680
+
681
+ #pragma region IHttpFilter
682
+
683
+ ResponseOperation OriginPolicyHttpFilter::SendRequestAsync(HttpRequestMessage const &request) {
684
+ auto coRequest = request;
685
+
686
+ // Set initial origin policy to global runtime option.
687
+ request.Properties().Insert(L"OriginPolicy", winrt::box_value(GetRuntimeOptionInt("Http.OriginPolicy")));
688
+
689
+ // Allow only HTTP or HTTPS schemes
690
+ if (GetRuntimeOptionBool("Http.StrictScheme") && coRequest.RequestUri().SchemeName() != L"https" &&
691
+ coRequest.RequestUri().SchemeName() != L"http")
692
+ throw hresult_error{E_INVALIDARG, L"Invalid URL scheme: [" + s_origin.SchemeName() + L"]"};
693
+
694
+ if (!GetRuntimeOptionBool("Http.OmitCredentials")) {
695
+ coRequest.Properties().Lookup(L"RequestArgs").as<RequestArgs>()->WithCredentials = false;
696
+ }
697
+
698
+ // Ensure absolute URL
699
+ coRequest.RequestUri(Uri{coRequest.RequestUri().AbsoluteCanonicalUri()});
700
+
701
+ auto originPolicy = ValidateRequest(coRequest);
702
+ if (originPolicy == OriginPolicy::SimpleCrossOriginResourceSharing ||
703
+ originPolicy == OriginPolicy::CrossOriginResourceSharing) {
704
+ if (coRequest.RequestUri().UserName().size() > 0 || coRequest.RequestUri().Password().size() > 0) {
705
+ coRequest.RequestUri(Uri{coRequest.RequestUri().DisplayUri()});
706
+ }
707
+ }
708
+
709
+ try {
710
+ // #9770 - Validate preflight cache
711
+ if (originPolicy == OriginPolicy::CrossOriginResourceSharing) {
712
+ // If inner filter can AllowRedirect, disable for preflight.
713
+ winrt::impl::com_ref<IHttpBaseProtocolFilter> baseFilter;
714
+ if (baseFilter = m_innerFilter.try_as<IHttpBaseProtocolFilter>()) {
715
+ baseFilter.AllowAutoRedirect(false);
716
+ }
717
+
718
+ auto preflightResponse = co_await SendPreflightAsync(coRequest);
719
+
720
+ if (baseFilter) {
721
+ baseFilter.AllowAutoRedirect(true);
722
+ }
723
+
724
+ ValidatePreflightResponse(coRequest, preflightResponse);
725
+ }
726
+
727
+ auto response = co_await m_innerFilter.SendRequestAsync(coRequest);
728
+
729
+ ValidateResponse(response, originPolicy);
730
+
731
+ co_return response;
732
+
733
+ } catch (hresult_error const &e) {
734
+ throw e;
735
+ } catch (const std::exception &e) {
736
+ throw hresult_error{E_FAIL, to_hstring(e.what())};
737
+ } catch (...) {
738
+ throw hresult_error{E_FAIL, L"Unspecified error processing Origin Policy request"};
739
+ }
740
+ }
741
+
742
+ #pragma endregion IHttpFilter
743
+
744
+ #pragma endregion OriginPolicyHttpFilter
745
+
746
+ } // namespace Microsoft::React::Networking