catalyst-core-internal 0.1.0 → 0.1.2

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 (27) hide show
  1. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/BridgeMessageValidator.kt +10 -2
  2. package/dist/native/bridge/hooks.js +4 -4
  3. package/dist/native/bridge/useBaseHook.js +3 -4
  4. package/dist/native/bridge/utils/NativeBridge.js +4 -4
  5. package/dist/native/iosnativeWebView/Sources/Core/Utils/CacheManager.swift +2 -13
  6. package/dist/native/iosnativeWebView/iosnativeWebView.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +0 -36
  7. package/dist/native/iosnativeWebView/iosnativeWebView.xctestplan +0 -1
  8. package/dist/native/iosnativeWebView/iosnativeWebViewTests/FrameworkServerUtilsTests.swift +4 -14
  9. package/dist/native/iosnativeWebView/iosnativeWebViewTests/WebViewTests.swift +21 -9
  10. package/mcp_v2/conversion-tasks.json +371 -0
  11. package/mcp_v2/knowledge-base.json +1450 -0
  12. package/mcp_v2/lib/helpers.js +145 -0
  13. package/mcp_v2/mcp.js +366 -0
  14. package/mcp_v2/package.json +13 -0
  15. package/mcp_v2/schema.sql +88 -0
  16. package/mcp_v2/setup.js +262 -0
  17. package/mcp_v2/tools/build.js +449 -0
  18. package/mcp_v2/tools/config.js +262 -0
  19. package/mcp_v2/tools/conversion.js +492 -0
  20. package/mcp_v2/tools/debug.js +62 -0
  21. package/mcp_v2/tools/knowledge.js +213 -0
  22. package/mcp_v2/tools/sync.js +21 -0
  23. package/mcp_v2/tools/tasks.js +844 -0
  24. package/package.json +1 -1
  25. package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/SecurityBridgeTest.kt +0 -199
  26. package/dist/native/iosnativeWebView/iosnativeWebViewTests/BridgeCommandHandlerSecurityTests.swift +0 -212
  27. package/dist/native/iosnativeWebView/iosnativeWebViewTests/ScreenSecureManagerTests.swift +0 -121
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "catalyst-core-internal",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "main": "index.js",
5
5
  "description": "Web framework that provides great performance out of the box",
6
6
  "bin": {
@@ -1,199 +0,0 @@
1
- package io.yourname.androidproject
2
-
3
- import org.json.JSONObject
4
- import org.junit.Assert.*
5
- import org.junit.Test
6
-
7
- /**
8
- * Unit tests for security bridge command routing and JSON injection safety.
9
- *
10
- * Coverage:
11
- * - setScreenSecure command routing (5 tests)
12
- * - getScreenSecure command routing (2 tests)
13
- * - clearWebData command routing (2 tests)
14
- * - JSON injection safety in error responses (3 tests)
15
- *
16
- * Total: 12 tests
17
- *
18
- * Note: These tests operate on static parsing/validation logic and JSON data
19
- * structures. Full lifecycle (FLAG_SECURE, CookieManager) is exercised in
20
- * device integration tests; here we confirm command acceptance, param parsing,
21
- * and that error payloads produced via JSONObject cannot carry injected content.
22
- */
23
- class SecurityBridgeTest {
24
-
25
- // ============================================================
26
- // CATEGORY 1: setScreenSecure COMMAND ROUTING (5 tests)
27
- // ============================================================
28
-
29
- @Test
30
- fun `test setScreenSecure command is accepted by validator`() {
31
- val messageJson = """{"command": "setScreenSecure", "data": {"enable": true}}"""
32
-
33
- val result = NativeBridge.parseAndValidateMessage(messageJson)
34
-
35
- assertTrue("setScreenSecure should be a valid command", result.isValid)
36
- assertEquals("setScreenSecure", result.command)
37
- assertNull(result.error)
38
- }
39
-
40
- @Test
41
- fun `test setScreenSecure enable true parsed from params`() {
42
- val params = JSONObject().apply { put("enable", true) }
43
-
44
- val enable = params.optBoolean("enable", false)
45
-
46
- assertTrue("enable should be true", enable)
47
- }
48
-
49
- @Test
50
- fun `test setScreenSecure enable false parsed from params`() {
51
- val params = JSONObject().apply { put("enable", false) }
52
-
53
- val enable = params.optBoolean("enable", true)
54
-
55
- assertFalse("enable should be false", enable)
56
- }
57
-
58
- @Test
59
- fun `test setScreenSecure defaults to true when params are malformed`() {
60
- // NativeBridge.setScreenSecure falls back to true when JSON parse fails
61
- val malformedParams = "not-json"
62
- val enable = try {
63
- JSONObject(malformedParams).optBoolean("enable", true)
64
- } catch (e: Exception) {
65
- true
66
- }
67
-
68
- assertTrue("Malformed params should default to enable=true", enable)
69
- }
70
-
71
- @Test
72
- fun `test setScreenSecure success response shape`() {
73
- val enable = true
74
- val response = JSONObject().apply {
75
- put("secure", enable)
76
- put("success", true)
77
- }
78
-
79
- assertTrue(response.getBoolean("secure"))
80
- assertTrue(response.getBoolean("success"))
81
- // Verify no extra fields bleed in
82
- assertEquals(2, response.length())
83
- }
84
-
85
- // ============================================================
86
- // CATEGORY 2: getScreenSecure COMMAND ROUTING (2 tests)
87
- // ============================================================
88
-
89
- @Test
90
- fun `test getScreenSecure command is accepted by validator`() {
91
- val messageJson = """{"command": "getScreenSecure", "data": {}}"""
92
-
93
- val result = NativeBridge.parseAndValidateMessage(messageJson)
94
-
95
- assertTrue("getScreenSecure should be a valid command", result.isValid)
96
- assertEquals("getScreenSecure", result.command)
97
- assertNull(result.error)
98
- }
99
-
100
- @Test
101
- fun `test getScreenSecure status response shape`() {
102
- // Validate that the JSON payload produced by getScreenSecure is well-formed
103
- val isSecure = false
104
- val response = JSONObject().apply {
105
- put("secure", isSecure)
106
- put("success", true)
107
- }
108
-
109
- assertFalse(response.getBoolean("secure"))
110
- assertTrue(response.getBoolean("success"))
111
- assertEquals(2, response.length())
112
- }
113
-
114
- // ============================================================
115
- // CATEGORY 3: clearWebData COMMAND ROUTING (2 tests)
116
- // ============================================================
117
-
118
- @Test
119
- fun `test clearWebData command is accepted by validator`() {
120
- val messageJson = """{"command": "clearWebData", "data": {}}"""
121
-
122
- val result = NativeBridge.parseAndValidateMessage(messageJson)
123
-
124
- assertTrue("clearWebData should be a valid command", result.isValid)
125
- assertEquals("clearWebData", result.command)
126
- assertNull(result.error)
127
- }
128
-
129
- @Test
130
- fun `test clearWebData success response shape`() {
131
- val cookiesRemoved = true
132
- val response = JSONObject().apply {
133
- put("success", true)
134
- put("cookiesRemoved", cookiesRemoved)
135
- }
136
-
137
- assertTrue(response.getBoolean("success"))
138
- assertTrue(response.getBoolean("cookiesRemoved"))
139
- assertEquals(2, response.length())
140
- }
141
-
142
- // ============================================================
143
- // CATEGORY 4: JSON INJECTION SAFETY (3 tests)
144
- // ============================================================
145
-
146
- @Test
147
- fun `test error message with injection characters is safe via JSONObject`() {
148
- // Simulate an exception message that contains characters dangerous in naive JS
149
- // string interpolation: double-quotes and backslashes.
150
- // JSONObject must escape them so the serialized JSON stays valid and cannot
151
- // break out of the surrounding JS string literal in notifyWebJson.
152
- val injectionPayload = "failed\"; window[\"evil\"]=\"injected"
153
-
154
- val response = JSONObject().apply {
155
- put("success", false)
156
- put("error", injectionPayload)
157
- }
158
-
159
- val serialized = response.toString()
160
-
161
- // The raw unescaped double-quote sequence that would break JS must not appear
162
- assertFalse(
163
- "Unescaped double-quote injection sequence must not appear in serialized JSON",
164
- serialized.contains("\"evil\"")
165
- )
166
- // The value must survive a round-trip intact
167
- assertEquals(injectionPayload, JSONObject(serialized).getString("error"))
168
- }
169
-
170
- @Test
171
- fun `test error message with backslash sequences is safe via JSONObject`() {
172
- val backslashPayload = "err\\\"injected\\\""
173
-
174
- val response = JSONObject().apply {
175
- put("success", false)
176
- put("error", backslashPayload)
177
- }
178
-
179
- // Round-trip must survive without throwing
180
- val roundTripped = JSONObject(response.toString()).getString("error")
181
- assertEquals(backslashPayload, roundTripped)
182
- }
183
-
184
- @Test
185
- fun `test setScreenSecure and clearWebData commands are in VALID_COMMANDS whitelist`() {
186
- assertTrue(
187
- "setScreenSecure must be whitelisted",
188
- CatalystConstants.Bridge.VALID_COMMANDS.contains("setScreenSecure")
189
- )
190
- assertTrue(
191
- "getScreenSecure must be whitelisted",
192
- CatalystConstants.Bridge.VALID_COMMANDS.contains("getScreenSecure")
193
- )
194
- assertTrue(
195
- "clearWebData must be whitelisted",
196
- CatalystConstants.Bridge.VALID_COMMANDS.contains("clearWebData")
197
- )
198
- }
199
- }
@@ -1,212 +0,0 @@
1
- import XCTest
2
- import WebKit
3
- @testable import CatalystCore
4
-
5
- /**
6
- * Unit tests for BridgeCommandHandler — security commands.
7
- *
8
- * Coverage:
9
- * 1. setScreenSecure routing (3 tests)
10
- * 2. getScreenSecure routing (2 tests)
11
- * 3. clearWebData routing (3 tests)
12
- *
13
- * Total: 8 tests
14
- *
15
- * Each test drives the full bridge pipeline (NativeBridge → BridgeCommandHandler)
16
- * via a MockWKWebView and captures the evaluateJavaScript call that the delegate
17
- * would fire back to the web layer.
18
- *
19
- * MockWKWebView and MockWKScriptMessage are defined in NativeBridgeTests.swift
20
- * and BridgeMessageValidatorTests.swift respectively (shared across the test target).
21
- */
22
- final class BridgeCommandHandlerSecurityTests: XCTestCase {
23
-
24
- var bridge: NativeBridge!
25
- var mockWebView: MockWKWebView!
26
- var mockViewController: UIViewController!
27
-
28
- override func setUp() {
29
- super.setUp()
30
- mockWebView = MockWKWebView()
31
- mockViewController = UIViewController()
32
- bridge = NativeBridge(webView: mockWebView, viewController: mockViewController)
33
- bridge.register()
34
- // Ensure a clean screen-secure state before each test
35
- ScreenSecureManager.shared.setScreenSecure(false)
36
- }
37
-
38
- override func tearDown() {
39
- bridge.unregister()
40
- bridge = nil
41
- mockWebView = nil
42
- mockViewController = nil
43
- ScreenSecureManager.shared.setScreenSecure(false)
44
- super.tearDown()
45
- }
46
-
47
- // ============================================================
48
- // CATEGORY 1: setScreenSecure routing (3 tests)
49
- // ============================================================
50
-
51
- func testSetScreenSecure_Enable_FiresOnScreenSecureSetCallback() {
52
- let exp = expectation(description: "ON_SCREEN_SECURE_SET callback fired")
53
-
54
- mockWebView.onEvaluateJavaScript = { script in
55
- if script.contains("ON_SCREEN_SECURE_SET") {
56
- exp.fulfill()
57
- }
58
- }
59
-
60
- let message = createMessage(command: "setScreenSecure", data: ["enable": true])
61
- bridge.userContentController(mockWebView.configuration.userContentController,
62
- didReceive: message)
63
-
64
- wait(for: [exp], timeout: 2.0)
65
- }
66
-
67
- func testSetScreenSecure_Enable_CallbackContainsSecureTrue() {
68
- let exp = expectation(description: "ON_SCREEN_SECURE_SET payload has secure:true")
69
-
70
- mockWebView.onEvaluateJavaScript = { script in
71
- if script.contains("ON_SCREEN_SECURE_SET") {
72
- XCTAssertTrue(
73
- script.contains("\"secure\"") || script.contains("secure"),
74
- "Callback should include secure field"
75
- )
76
- XCTAssertTrue(
77
- script.contains("true"),
78
- "secure should be true after enabling"
79
- )
80
- exp.fulfill()
81
- }
82
- }
83
-
84
- let message = createMessage(command: "setScreenSecure", data: ["enable": true])
85
- bridge.userContentController(mockWebView.configuration.userContentController,
86
- didReceive: message)
87
-
88
- wait(for: [exp], timeout: 2.0)
89
- }
90
-
91
- func testSetScreenSecure_InvalidParams_FiresErrorCallback() {
92
- // Passing a non-dict, non-string param is handled by the fallback in
93
- // BridgeCommandHandler.setScreenSecure — it fires ON_SCREEN_SECURE_ERROR.
94
- let exp = expectation(description: "ON_SCREEN_SECURE_ERROR fired for nil params")
95
-
96
- mockWebView.onEvaluateJavaScript = { script in
97
- if script.contains("ON_SCREEN_SECURE_ERROR") {
98
- exp.fulfill()
99
- }
100
- }
101
-
102
- // Route via bridge with data that contains no "enable" key at all
103
- let message = createMessage(command: "setScreenSecure", data: [:])
104
- bridge.userContentController(mockWebView.configuration.userContentController,
105
- didReceive: message)
106
-
107
- // The empty dict triggers the else branch → ON_SCREEN_SECURE_ERROR
108
- wait(for: [exp], timeout: 2.0)
109
- }
110
-
111
- // ============================================================
112
- // CATEGORY 2: getScreenSecure routing (2 tests)
113
- // ============================================================
114
-
115
- func testGetScreenSecure_FiresOnScreenSecureStatusCallback() {
116
- let exp = expectation(description: "ON_SCREEN_SECURE_STATUS callback fired")
117
-
118
- mockWebView.onEvaluateJavaScript = { script in
119
- if script.contains("ON_SCREEN_SECURE_STATUS") {
120
- exp.fulfill()
121
- }
122
- }
123
-
124
- let message = createMessage(command: "getScreenSecure", data: [:])
125
- bridge.userContentController(mockWebView.configuration.userContentController,
126
- didReceive: message)
127
-
128
- wait(for: [exp], timeout: 2.0)
129
- }
130
-
131
- func testGetScreenSecure_ReflectsCurrentState() {
132
- // Set state first, then query it via the bridge
133
- ScreenSecureManager.shared.setScreenSecure(true)
134
-
135
- let exp = expectation(description: "ON_SCREEN_SECURE_STATUS reflects secure:true")
136
-
137
- mockWebView.onEvaluateJavaScript = { script in
138
- if script.contains("ON_SCREEN_SECURE_STATUS") {
139
- XCTAssertTrue(script.contains("true"),
140
- "Status callback should reflect secure=true")
141
- exp.fulfill()
142
- }
143
- }
144
-
145
- let message = createMessage(command: "getScreenSecure", data: [:])
146
- bridge.userContentController(mockWebView.configuration.userContentController,
147
- didReceive: message)
148
-
149
- wait(for: [exp], timeout: 2.0)
150
- }
151
-
152
- // ============================================================
153
- // CATEGORY 3: clearWebData routing (3 tests)
154
- // ============================================================
155
-
156
- func testClearWebData_WhenWebViewPresent_FiresOnWebDataClearedCallback() {
157
- // BridgeCommandHandler needs a webView injected to proceed past the guard
158
- // NativeBridge injects it during register(), so the mock is already set.
159
- let exp = expectation(description: "ON_WEB_DATA_CLEARED callback fired")
160
-
161
- mockWebView.onEvaluateJavaScript = { script in
162
- if script.contains("ON_WEB_DATA_CLEARED") {
163
- exp.fulfill()
164
- }
165
- }
166
-
167
- let message = createMessage(command: "clearWebData", data: [:])
168
- bridge.userContentController(mockWebView.configuration.userContentController,
169
- didReceive: message)
170
-
171
- // clearWebData is async (WKWebsiteDataStore removal) — allow extra time
172
- wait(for: [exp], timeout: 5.0)
173
- }
174
-
175
- func testClearWebData_SuccessPayloadContainsSuccessTrue() {
176
- let exp = expectation(description: "clearWebData success payload has success:true")
177
-
178
- mockWebView.onEvaluateJavaScript = { script in
179
- if script.contains("ON_WEB_DATA_CLEARED") {
180
- XCTAssertTrue(script.contains("true"),
181
- "success field should be true in cleared callback")
182
- exp.fulfill()
183
- }
184
- }
185
-
186
- let message = createMessage(command: "clearWebData", data: [:])
187
- bridge.userContentController(mockWebView.configuration.userContentController,
188
- didReceive: message)
189
-
190
- wait(for: [exp], timeout: 5.0)
191
- }
192
-
193
- func testClearWebData_CommandAcceptedByValidator() {
194
- // Validates command reaches the handler without being rejected by BridgeMessageValidator
195
- let messageBody: [String: Any] = ["command": "clearWebData", "data": [:]]
196
- let message = MockWKScriptMessage(name: "NativeBridge", body: messageBody)
197
- let result = BridgeMessageValidator.validate(message: message)
198
-
199
- XCTAssertTrue(result.isValid, "clearWebData should pass BridgeMessageValidator")
200
- XCTAssertEqual(result.command, "clearWebData")
201
- XCTAssertNil(result.error)
202
- }
203
-
204
- // ============================================================
205
- // Helpers
206
- // ============================================================
207
-
208
- private func createMessage(command: String, data: [String: Any]) -> WKScriptMessage {
209
- let body: [String: Any] = ["command": command, "data": data]
210
- return MockWKScriptMessage(name: "NativeBridge", body: body)
211
- }
212
- }
@@ -1,121 +0,0 @@
1
- import XCTest
2
- @testable import CatalystCore
3
-
4
- /**
5
- * Unit tests for ScreenSecureManager
6
- *
7
- * Coverage:
8
- * 1. State management (3 tests)
9
- * 2. setScreenSecure behaviour (3 tests)
10
- * 3. Overlay race condition guard (2 tests)
11
- *
12
- * Total: 8 tests
13
- *
14
- * Note: UIWindow creation and scene observation require a running app / UI host.
15
- * Tests here focus on the state machine and guard logic that can be exercised
16
- * without a UIWindowScene. Overlay installation side-effects are verified
17
- * indirectly via the guard flags and isScreenSecure state.
18
- */
19
- final class ScreenSecureManagerTests: XCTestCase {
20
-
21
- var manager: ScreenSecureManager!
22
-
23
- override func setUp() {
24
- super.setUp()
25
- // Use the shared singleton; reset state by disabling screen security
26
- manager = ScreenSecureManager.shared
27
- manager.setScreenSecure(false)
28
- }
29
-
30
- override func tearDown() {
31
- // Leave the singleton clean for other tests
32
- manager.setScreenSecure(false)
33
- super.tearDown()
34
- }
35
-
36
- // ============================================================
37
- // CATEGORY 1: State management (3 tests)
38
- // ============================================================
39
-
40
- func testInitialState_IsNotSecure() {
41
- // After setUp calls setScreenSecure(false), isScreenSecure must be false
42
- XCTAssertFalse(manager.isScreenSecure, "Initial state should not be secure")
43
- }
44
-
45
- func testSetScreenSecure_True_UpdatesState() {
46
- manager.setScreenSecure(true)
47
-
48
- XCTAssertTrue(manager.isScreenSecure, "isScreenSecure should be true after enabling")
49
- }
50
-
51
- func testSetScreenSecure_False_UpdatesState() {
52
- manager.setScreenSecure(true)
53
- manager.setScreenSecure(false)
54
-
55
- XCTAssertFalse(manager.isScreenSecure, "isScreenSecure should be false after disabling")
56
- }
57
-
58
- // ============================================================
59
- // CATEGORY 2: setScreenSecure behaviour (3 tests)
60
- // ============================================================
61
-
62
- func testSetScreenSecure_EnableThenDisable_StateIsConsistent() {
63
- manager.setScreenSecure(true)
64
- XCTAssertTrue(manager.isScreenSecure)
65
-
66
- manager.setScreenSecure(false)
67
- XCTAssertFalse(manager.isScreenSecure)
68
-
69
- // Re-enable
70
- manager.setScreenSecure(true)
71
- XCTAssertTrue(manager.isScreenSecure)
72
- }
73
-
74
- func testSetScreenSecure_DisableWhenAlreadyDisabled_NoStateChange() {
75
- // Should be a no-op and not throw
76
- manager.setScreenSecure(false)
77
- manager.setScreenSecure(false)
78
-
79
- XCTAssertFalse(manager.isScreenSecure, "Repeated disable should leave state as false")
80
- }
81
-
82
- func testSetScreenSecure_EnableWhenAlreadyEnabled_NoStateChange() {
83
- manager.setScreenSecure(true)
84
- manager.setScreenSecure(true)
85
-
86
- XCTAssertTrue(manager.isScreenSecure, "Repeated enable should leave state as true")
87
- }
88
-
89
- // ============================================================
90
- // CATEGORY 3: Overlay race condition guard (2 tests)
91
- // ============================================================
92
-
93
- func testSceneWillDeactivate_WhenNotSecure_OverlayNotInstalled() {
94
- // When isScreenSecure is false, sceneWillDeactivate must be a no-op.
95
- // We verify by checking state is still false after the notification fires.
96
- manager.setScreenSecure(false)
97
-
98
- NotificationCenter.default.post(
99
- name: UIScene.willDeactivateNotification,
100
- object: nil
101
- )
102
-
103
- // State must not have changed
104
- XCTAssertFalse(manager.isScreenSecure,
105
- "State should remain false when secure mode is off")
106
- }
107
-
108
- func testSceneDidActivate_AfterEnable_StateUnchanged() {
109
- // sceneDidActivate removes the overlay but does NOT reset isScreenSecure.
110
- manager.setScreenSecure(true)
111
-
112
- NotificationCenter.default.post(
113
- name: UIScene.didActivateNotification,
114
- object: nil
115
- )
116
-
117
- // The secure flag must survive a return-to-foreground event
118
- XCTAssertTrue(manager.isScreenSecure,
119
- "isScreenSecure should remain true after scene reactivation")
120
- }
121
- }